Needed for agent VPN support.
}
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;
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");
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");
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);
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)
}
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,
&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)
}
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) {
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 = {
}
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);
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)
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;
}
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);
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);
}
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);
&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;
}
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;
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;
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);
};