summaryrefslogtreecommitdiff
path: root/vpn/plugins
diff options
context:
space:
mode:
authorNishant Chaprana <n.chaprana@samsung.com>2019-07-04 17:41:09 +0530
committerNishant Chaprana <n.chaprana@samsung.com>2019-07-04 17:41:17 +0530
commit6b2381a2adabea7d8309ff158ef675ff88184305 (patch)
tree2c9b2bb6d8b214acc18b8e784e6841f468a5a040 /vpn/plugins
parent9362752a471a5c892d679548fbf2828d5fc5684b (diff)
downloadconnman-6b2381a2adabea7d8309ff158ef675ff88184305.tar.gz
connman-6b2381a2adabea7d8309ff158ef675ff88184305.tar.bz2
connman-6b2381a2adabea7d8309ff158ef675ff88184305.zip
Imported Upstream version 1.37upstream/1.37
Change-Id: Ib5957e7ee3a9315ee86a331189bc3e9e71751ee8 Signed-off-by: Nishant Chaprana <n.chaprana@samsung.com>
Diffstat (limited to 'vpn/plugins')
-rw-r--r--vpn/plugins/l2tp.c1
-rw-r--r--vpn/plugins/openconnect.c30
-rw-r--r--vpn/plugins/openvpn.c25
-rw-r--r--vpn/plugins/pptp.c1
-rw-r--r--vpn/plugins/vpn.c59
-rw-r--r--vpn/plugins/vpn.h4
6 files changed, 114 insertions, 6 deletions
diff --git a/vpn/plugins/l2tp.c b/vpn/plugins/l2tp.c
index a0d22c4d..5d83eb88 100644
--- a/vpn/plugins/l2tp.c
+++ b/vpn/plugins/l2tp.c
@@ -382,6 +382,7 @@ static int write_pppd_option(struct vpn_provider *provider, int fd)
l2tp_write_option(fd, "nodetach", NULL);
l2tp_write_option(fd, "lock", NULL);
+ l2tp_write_option(fd, "logfd", "2");
l2tp_write_option(fd, "usepeerdns", NULL);
l2tp_write_option(fd, "noipdefault", NULL);
l2tp_write_option(fd, "noauth", NULL);
diff --git a/vpn/plugins/openconnect.c b/vpn/plugins/openconnect.c
index 87679bfa..8e74479f 100644
--- a/vpn/plugins/openconnect.c
+++ b/vpn/plugins/openconnect.c
@@ -561,11 +561,41 @@ static int oc_error_code(struct vpn_provider *provider, int exit_code)
}
}
+static int oc_route_env_parse(struct vpn_provider *provider, const char *key,
+ int *family, unsigned long *idx, enum vpn_provider_route_type *type)
+{
+ char *end;
+ const char *start;
+
+ if (g_str_has_prefix(key, "CISCO_SPLIT_INC_")) {
+ *family = AF_INET;
+ start = key + strlen("CISCO_SPLIT_INC_");
+ } else if (g_str_has_prefix(key, "CISCO_IPV6_SPLIT_INC_")) {
+ *family = AF_INET6;
+ start = key + strlen("CISCO_IPV6_SPLIT_INC_");
+ } else
+ return -EINVAL;
+
+ *idx = g_ascii_strtoull(start, &end, 10);
+
+ if (strncmp(end, "_ADDR", 5) == 0)
+ *type = VPN_PROVIDER_ROUTE_TYPE_ADDR;
+ else if (strncmp(end, "_MASK", 5) == 0)
+ *type = VPN_PROVIDER_ROUTE_TYPE_MASK;
+ else if (strncmp(end, "_MASKLEN", 8) == 0 && *family == AF_INET6)
+ *type = VPN_PROVIDER_ROUTE_TYPE_MASK;
+ else
+ return -EINVAL;
+
+ return 0;
+}
+
static struct vpn_driver vpn_driver = {
.notify = oc_notify,
.connect = oc_connect,
.error_code = oc_error_code,
.save = oc_save,
+ .route_env_parse = oc_route_env_parse,
};
static int openconnect_init(void)
diff --git a/vpn/plugins/openvpn.c b/vpn/plugins/openvpn.c
index e3395097..f38c0c36 100644
--- a/vpn/plugins/openvpn.c
+++ b/vpn/plugins/openvpn.c
@@ -470,11 +470,36 @@ static int ov_device_flags(struct vpn_provider *provider)
return IFF_TUN;
}
+static int ov_route_env_parse(struct vpn_provider *provider, const char *key,
+ int *family, unsigned long *idx, enum vpn_provider_route_type *type)
+{
+ char *end;
+ const char *start;
+
+ if (g_str_has_prefix(key, "route_network_")) {
+ start = key + strlen("route_network_");
+ *type = VPN_PROVIDER_ROUTE_TYPE_ADDR;
+ } else if (g_str_has_prefix(key, "route_netmask_")) {
+ start = key + strlen("route_netmask_");
+ *type = VPN_PROVIDER_ROUTE_TYPE_MASK;
+ } else if (g_str_has_prefix(key, "route_gateway_")) {
+ start = key + strlen("route_gateway_");
+ *type = VPN_PROVIDER_ROUTE_TYPE_GW;
+ } else
+ return -EINVAL;
+
+ *family = AF_INET;
+ *idx = g_ascii_strtoull(start, &end, 10);
+
+ return 0;
+}
+
static struct vpn_driver vpn_driver = {
.notify = ov_notify,
.connect = ov_connect,
.save = ov_save,
.device_flags = ov_device_flags,
+ .route_env_parse = ov_route_env_parse,
};
static int openvpn_init(void)
diff --git a/vpn/plugins/pptp.c b/vpn/plugins/pptp.c
index 27b1d508..3dc93b03 100644
--- a/vpn/plugins/pptp.c
+++ b/vpn/plugins/pptp.c
@@ -453,6 +453,7 @@ static int run_connect(struct vpn_provider *provider,
connman_task_add_argument(task, "nodetach", NULL);
connman_task_add_argument(task, "lock", NULL);
+ connman_task_add_argument(task, "logfd", "2");
connman_task_add_argument(task, "usepeerdns", NULL);
connman_task_add_argument(task, "noipdefault", NULL);
connman_task_add_argument(task, "noauth", NULL);
diff --git a/vpn/plugins/vpn.c b/vpn/plugins/vpn.c
index 9a423850..acede747 100644
--- a/vpn/plugins/vpn.c
+++ b/vpn/plugins/vpn.c
@@ -23,7 +23,6 @@
#include <config.h>
#endif
-#define _GNU_SOURCE
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
@@ -133,6 +132,10 @@ void vpn_died(struct connman_task *task, int exit_code, void *user_data)
if (!data)
goto vpn_exit;
+ /* The task may die after we have already started the new one */
+ if (data->task != task)
+ goto done;
+
state = data->state;
stop_vpn(provider);
@@ -172,6 +175,7 @@ vpn_exit:
g_free(data);
}
+done:
connman_task_destroy(task);
}
@@ -303,19 +307,22 @@ static DBusMessage *vpn_notify(struct connman_task *task,
vpn_newlink, provider);
err = connman_inet_ifup(index);
if (err < 0) {
- if (err == -EALREADY)
+ if (err == -EALREADY) {
/*
* So the interface is up already, that is just
* great. Unfortunately in this case the
* newlink watch might not have been called at
* all. We must manually call it here so that
* the provider can go to ready state and the
- * routes are setup properly.
+ * routes are setup properly. Also reset flags
+ * so vpn_newlink() can handle the change.
*/
+ data->flags = 0;
vpn_newlink(IFF_UP, 0, provider);
- else
+ } else {
DBG("Cannot take interface %d up err %d/%s",
index, -err, strerror(-err));
+ }
}
break;
@@ -373,6 +380,7 @@ static int vpn_create_tun(struct vpn_provider *provider, int flags)
}
data->tun_flags = flags;
+ g_free(data->if_name);
data->if_name = (char *)g_strdup(ifr.ifr_name);
if (!data->if_name) {
connman_error("Failed to allocate memory");
@@ -553,10 +561,15 @@ static int vpn_disconnect(struct vpn_provider *provider)
static int vpn_remove(struct vpn_provider *provider)
{
struct vpn_data *data;
+ struct vpn_driver_data *driver_data;
+ const char *name;
+ int err = 0;
data = vpn_provider_get_data(provider);
+ name = vpn_provider_get_driver_name(provider);
+
if (!data)
- return 0;
+ goto call_remove;
if (data->watch != 0) {
vpn_provider_unref(provider);
@@ -568,7 +581,20 @@ static int vpn_remove(struct vpn_provider *provider)
g_usleep(G_USEC_PER_SEC);
stop_vpn(provider);
- return 0;
+
+call_remove:
+ if (!name)
+ return 0;
+
+ driver_data = g_hash_table_lookup(driver_hash, name);
+
+ if (driver_data && driver_data->vpn_driver->remove)
+ err = driver_data->vpn_driver->remove(provider);
+
+ if (err)
+ DBG("%p vpn_driver->remove() returned %d", provider, err);
+
+ return err;
}
static int vpn_save(struct vpn_provider *provider, GKeyFile *keyfile)
@@ -585,6 +611,26 @@ static int vpn_save(struct vpn_provider *provider, GKeyFile *keyfile)
return 0;
}
+static int vpn_route_env_parse(struct vpn_provider *provider, const char *key,
+ int *family, unsigned long *idx,
+ enum vpn_provider_route_type *type)
+{
+ struct vpn_driver_data *vpn_driver_data = NULL;
+ const char *name = NULL;
+
+ if (!provider)
+ return -EINVAL;
+
+ name = vpn_provider_get_driver_name(provider);
+ vpn_driver_data = g_hash_table_lookup(driver_hash, name);
+
+ if (vpn_driver_data && vpn_driver_data->vpn_driver->route_env_parse)
+ return vpn_driver_data->vpn_driver->route_env_parse(provider, key,
+ family, idx, type);
+
+ return 0;
+}
+
int vpn_register(const char *name, struct vpn_driver *vpn_driver,
const char *program)
{
@@ -606,6 +652,7 @@ int vpn_register(const char *name, struct vpn_driver *vpn_driver,
data->provider_driver.remove = vpn_remove;
data->provider_driver.save = vpn_save;
data->provider_driver.set_state = vpn_set_state;
+ data->provider_driver.route_env_parse = vpn_route_env_parse;
if (!driver_hash)
driver_hash = g_hash_table_new_full(g_str_hash,
diff --git a/vpn/plugins/vpn.h b/vpn/plugins/vpn.h
index cb94bdcd..265fd82f 100644
--- a/vpn/plugins/vpn.h
+++ b/vpn/plugins/vpn.h
@@ -48,9 +48,13 @@ struct vpn_driver {
vpn_provider_connect_cb_t cb, const char *dbus_sender,
void *user_data);
void (*disconnect) (struct vpn_provider *provider);
+ int (*remove) (struct vpn_provider *provider);
int (*error_code) (struct vpn_provider *provider, int exit_code);
int (*save) (struct vpn_provider *provider, GKeyFile *keyfile);
int (*device_flags) (struct vpn_provider *provider);
+ int (*route_env_parse) (struct vpn_provider *provider, const char *key,
+ int *family, unsigned long *idx,
+ enum vpn_provider_route_type *type);
};
int vpn_register(const char *name, struct vpn_driver *driver,