vpn: Add initial support for async connect
authorJukka Rissanen <jukka.rissanen@linux.intel.com>
Fri, 30 Nov 2012 09:30:35 +0000 (11:30 +0200)
committerPatrik Flykt <patrik.flykt@linux.intel.com>
Fri, 30 Nov 2012 13:01:18 +0000 (15:01 +0200)
Needed for agent VPN support.

vpn/plugins/l2tp.c
vpn/plugins/openconnect.c
vpn/plugins/openvpn.c
vpn/plugins/pptp.c
vpn/plugins/vpn.c
vpn/plugins/vpn.h
vpn/plugins/vpnc.c
vpn/vpn-provider.c
vpn/vpn-provider.h

index 4cb4b6a..05341d5 100644 (file)
@@ -447,7 +447,8 @@ static void l2tp_died(struct connman_task *task, int exit_code, void *user_data)
 }
 
 static int l2tp_connect(struct vpn_provider *provider,
-               struct connman_task *task, const char *if_name)
+                       struct connman_task *task, const char *if_name,
+                       vpn_provider_connect_cb_t cb, void *user_data)
 {
        const char *host;
        char *l2tp_name, *pppd_name;
@@ -455,13 +456,16 @@ static int l2tp_connect(struct vpn_provider *provider,
        int err;
 
        if (connman_task_set_notify(task, "getsec",
-                                       l2tp_get_sec, provider))
-               return -ENOMEM;
+                                       l2tp_get_sec, provider) != 0) {
+               err = -ENOMEM;
+               goto done;
+       }
 
        host = vpn_provider_get_string(provider, "Host");
        if (host == NULL) {
                connman_error("Host not set; cannot enable VPN");
-               return -EINVAL;
+               err = -EINVAL;
+               goto done;
        }
 
        l2tp_name = g_strdup_printf("/var/run/connman/connman-xl2tpd.conf");
@@ -470,7 +474,8 @@ static int l2tp_connect(struct vpn_provider *provider,
        if (l2tp_fd < 0) {
                g_free(l2tp_name);
                connman_error("Error writing l2tp config");
-               return -EIO;
+               err = -EIO;
+               goto done;
        }
 
        pppd_name = g_strdup_printf("/var/run/connman/connman-ppp-option.conf");
@@ -481,7 +486,8 @@ static int l2tp_connect(struct vpn_provider *provider,
                g_free(l2tp_name);
                g_free(pppd_name);
                close(l2tp_fd);
-               return -EIO;
+               err = -EIO;
+               goto done;
        }
 
        l2tp_write_config(provider, pppd_name, l2tp_fd);
@@ -498,10 +504,15 @@ static int l2tp_connect(struct vpn_provider *provider,
                                NULL, NULL, NULL);
        if (err < 0) {
                connman_error("l2tp failed to start");
-               return -EIO;
+               err = -EIO;
+               goto done;
        }
 
-       return 0;
+done:
+       if (cb != NULL)
+               cb(provider, user_data, err);
+
+       return err;
 }
 
 static int l2tp_error_code(int exit_code)
index 0f54108..143e175 100644 (file)
@@ -161,21 +161,24 @@ static int oc_notify(DBusMessage *msg, struct vpn_provider *provider)
 }
 
 static int oc_connect(struct vpn_provider *provider,
-                       struct connman_task *task, const char *if_name)
+                       struct connman_task *task, const char *if_name,
+                       vpn_provider_connect_cb_t cb, void *user_data)
 {
        const char *vpnhost, *vpncookie, *cafile, *certsha1, *mtu;
-       int fd, err;
+       int fd, err = 0;
 
        vpnhost = vpn_provider_get_string(provider, "Host");
        if (!vpnhost) {
                connman_error("Host not set; cannot enable VPN");
-               return -EINVAL;
+               err = -EINVAL;
+               goto done;
        }
 
        vpncookie = vpn_provider_get_string(provider, "OpenConnect.Cookie");
        if (!vpncookie) {
                connman_error("OpenConnect.Cookie not set; cannot enable VPN");
-               return -EINVAL;
+               err = -EINVAL;
+               goto done;
        }
 
        certsha1 = vpn_provider_get_string(provider,
@@ -207,17 +210,23 @@ static int oc_connect(struct vpn_provider *provider,
                               &fd, NULL, NULL);
        if (err < 0) {
                connman_error("openconnect failed to start");
-               return -EIO;
+               err = -EIO;
+               goto done;
        }
 
        if (write(fd, vpncookie, strlen(vpncookie)) !=
                        (ssize_t)strlen(vpncookie) ||
                        write(fd, "\n", 1) != 1) {
                connman_error("openconnect failed to take cookie on stdin");
-               return -EIO;
+               err = -EIO;
+               goto done;
        }
 
-       return 0;
+done:
+       if (cb != NULL)
+               cb(provider, user_data, err);
+
+       return err;
 }
 
 static int oc_save(struct vpn_provider *provider, GKeyFile *keyfile)
index 84583cd..87549ca 100644 (file)
@@ -229,10 +229,11 @@ static int task_append_config_data(struct vpn_provider *provider,
 }
 
 static int ov_connect(struct vpn_provider *provider,
-               struct connman_task *task, const char *if_name)
+                       struct connman_task *task, const char *if_name,
+                       vpn_provider_connect_cb_t cb, void *user_data)
 {
        const char *option;
-       int err, fd;
+       int err = 0, fd;
 
        option = vpn_provider_get_string(provider, "Host");
        if (option == NULL) {
@@ -304,10 +305,15 @@ static int ov_connect(struct vpn_provider *provider,
                        NULL, &fd, &fd);
        if (err < 0) {
                connman_error("openvpn failed to start");
-               return -EIO;
+               err = -EIO;
+               goto done;
        }
 
-       return 0;
+done:
+       if (cb != NULL)
+               cb(provider, user_data, err);
+
+       return err;
 }
 
 static struct vpn_driver vpn_driver = {
index 6843793..1da5144 100644 (file)
@@ -241,27 +241,32 @@ static void pptp_write_bool_option(struct connman_task *task,
 }
 
 static int pptp_connect(struct vpn_provider *provider,
-               struct connman_task *task, const char *if_name)
+                       struct connman_task *task, const char *if_name,
+                       vpn_provider_connect_cb_t cb, void *user_data)
 {
        const char *opt_s, *host;
        char *str;
        int err, i;
 
        if (connman_task_set_notify(task, "getsec",
-                                       pptp_get_sec, provider))
-               return -ENOMEM;
+                                       pptp_get_sec, provider)) {
+               err = -ENOMEM;
+               goto done;
+       }
 
        host = vpn_provider_get_string(provider, "Host");
        if (host == NULL) {
                connman_error("Host not set; cannot enable VPN");
-               return -EINVAL;
+               err = -EINVAL;
+               goto done;
        }
 
        str = g_strdup_printf("%s %s --nolaunchpppd --loglevel 2",
                                PPTP, host);
        if (str == NULL) {
                connman_error("can not allocate memory");
-               return -ENOMEM;
+               err = -ENOMEM;
+               goto done;
        }
 
        connman_task_add_argument(task, "pty", str);
@@ -299,10 +304,15 @@ static int pptp_connect(struct vpn_provider *provider,
                                NULL, NULL, NULL);
        if (err < 0) {
                connman_error("pptp failed to start");
-               return -EIO;
+               err = -EIO;
+               goto done;
        }
 
-       return 0;
+done:
+       if (cb != NULL)
+               cb(provider, user_data, err);
+
+       return err;
 }
 
 static int pptp_error_code(int exit_code)
index d0b3381..66a75d2 100644 (file)
@@ -353,7 +353,8 @@ exist_err:
        return ret;
 }
 
-static int vpn_connect(struct vpn_provider *provider)
+static int vpn_connect(struct vpn_provider *provider,
+                       vpn_provider_connect_cb_t cb, void *user_data)
 {
        struct vpn_data *data = vpn_provider_get_data(provider);
        struct vpn_driver_data *vpn_driver_data;
@@ -410,7 +411,7 @@ static int vpn_connect(struct vpn_provider *provider)
        }
 
        ret = vpn_driver_data->vpn_driver->connect(provider, data->task,
-                                                       data->if_name);
+                                               data->if_name, cb, user_data);
        if (ret < 0) {
                stop_vpn(provider);
                connman_task_destroy(data->task);
index 6693cdb..d1e322c 100644 (file)
@@ -44,7 +44,8 @@ struct vpn_driver {
        int flags;
        int (*notify) (DBusMessage *msg, struct vpn_provider *provider);
        int (*connect) (struct vpn_provider *provider,
-                       struct connman_task *task, const char *if_name);
+                       struct connman_task *task, const char *if_name,
+                       vpn_provider_connect_cb_t cb, void *user_data);
        void (*disconnect) (void);
        int (*error_code) (int exit_code);
        int (*save) (struct vpn_provider *provider, GKeyFile *keyfile);
index 9fd1dec..9f69850 100644 (file)
@@ -263,20 +263,23 @@ static int vc_save(struct vpn_provider *provider, GKeyFile *keyfile)
 }
 
 static int vc_connect(struct vpn_provider *provider,
-               struct connman_task *task, const char *if_name)
+                       struct connman_task *task, const char *if_name,
+                       vpn_provider_connect_cb_t cb, void *user_data)
 {
        const char *option;
-       int err, fd;
+       int err = 0, fd;
 
        option = vpn_provider_get_string(provider, "Host");
        if (option == NULL) {
                connman_error("Host not set; cannot enable VPN");
-               return -EINVAL;
+               err = -EINVAL;
+               goto done;
        }
        option = vpn_provider_get_string(provider, "VPNC.IPSec.ID");
        if (option == NULL) {
                connman_error("Group not set; cannot enable VPN");
-               return -EINVAL;
+               err = -EINVAL;
+               goto done;
        }
 
        connman_task_add_argument(task, "--non-inter", NULL);
@@ -298,13 +301,18 @@ static int vc_connect(struct vpn_provider *provider,
                                &fd, NULL, NULL);
        if (err < 0) {
                connman_error("vpnc failed to start");
-               return -EIO;
+               err = -EIO;
+               goto done;
        }
 
        err = vc_write_config_data(provider, fd);
 
        close(fd);
 
+done:
+       if (cb != NULL)
+               cb(provider, user_data, err);
+
        return err;
 }
 
index f529122..1630dad 100644 (file)
@@ -975,6 +975,12 @@ int __vpn_provider_disconnect(struct vpn_provider *provider)
        return 0;
 }
 
+static void connect_cb(struct vpn_provider *provider, void *user_data,
+                                                               int error)
+{
+       DBG("provider %p user %p error %d", provider, user_data, error);
+}
+
 int __vpn_provider_connect(struct vpn_provider *provider)
 {
        int err;
@@ -982,7 +988,8 @@ int __vpn_provider_connect(struct vpn_provider *provider)
        DBG("provider %p", provider);
 
        if (provider->driver != NULL && provider->driver->connect != NULL)
-               err = provider->driver->connect(provider);
+               err = provider->driver->connect(provider,
+                                               connect_cb, NULL);
        else
                return -EOPNOTSUPP;
 
index 0f139b0..b462042 100644 (file)
@@ -101,12 +101,16 @@ int vpn_provider_append_route(struct vpn_provider *provider,
 const char *vpn_provider_get_driver_name(struct vpn_provider *provider);
 const char *vpn_provider_get_save_group(struct vpn_provider *provider);
 
+typedef void (* vpn_provider_connect_cb_t) (struct vpn_provider *provider,
+                                       void *user_data, int error);
+
 struct vpn_provider_driver {
        const char *name;
        enum vpn_provider_type type;
        int (*probe) (struct vpn_provider *provider);
        int (*remove) (struct vpn_provider *provider);
-       int (*connect) (struct vpn_provider *provider);
+       int (*connect) (struct vpn_provider *provider,
+                       vpn_provider_connect_cb_t cb, void *user_data);
        int (*disconnect) (struct vpn_provider *provider);
        int (*save) (struct vpn_provider *provider, GKeyFile *keyfile);
 };