Chromium Code Reviews| Index: plugins/vpn.c |
| diff --git a/plugins/vpn.c b/plugins/vpn.c |
| index af0e082c7276f9424023b3ad2274df21e5867fe2..e4d389bf62a089fc1057068ee2315eba3d8be418 100644 |
| --- a/plugins/vpn.c |
| +++ b/plugins/vpn.c |
| @@ -77,27 +77,40 @@ struct vpn_driver_data { |
| static GHashTable *driver_hash = NULL; |
| -static int kill_tun(char *tun_name) |
| +static int kill_tun(struct connman_provider *provider) |
| { |
| + struct vpn_data *data = connman_provider_get_data(provider); |
| + struct vpn_driver_data *vpn_driver_data; |
| + const char *name; |
| struct ifreq ifr; |
| int fd, err; |
| + if (data == NULL) |
| + return -1; |
| + |
| + name = connman_provider_get_driver_name(provider); |
| + vpn_driver_data = g_hash_table_lookup(driver_hash, name); |
| + |
| + if (vpn_driver_data && vpn_driver_data->vpn_driver && |
|
Sam Leffler
2011/03/04 17:47:45
check ptr's against NULL
kmixter1
2011/03/05 09:30:51
Done.
|
| + vpn_driver_data->vpn_driver->flags == VPN_FLAG_NO_TUN) |
| + return 0; |
| + |
| memset(&ifr, 0, sizeof(ifr)); |
| ifr.ifr_flags = IFF_TUN | IFF_NO_PI; |
| - strncpy(ifr.ifr_name, tun_name, sizeof(ifr.ifr_name)); |
| + strncpy(ifr.ifr_name, data->if_name, sizeof(ifr.ifr_name)); |
| fd = open("/dev/net/tun", O_RDWR); |
| if (fd < 0) { |
| err = -errno; |
| connman_error("Failed to open /dev/net/tun to device %s: %s", |
| - tun_name, strerror(errno)); |
| + data->if_name, strerror(errno)); |
| return err; |
| } |
| if (ioctl(fd, TUNSETIFF, (void *)&ifr)) { |
| err = -errno; |
| connman_error("Failed to TUNSETIFF for device %s to it: %s", |
| - tun_name, strerror(errno)); |
| + data->if_name, strerror(errno)); |
| close(fd); |
| return err; |
| } |
| @@ -105,12 +118,12 @@ static int kill_tun(char *tun_name) |
| if (ioctl(fd, TUNSETPERSIST, 0)) { |
| err = -errno; |
| connman_error("Failed to set tun device %s nonpersistent: %s", |
| - tun_name, strerror(errno)); |
| + data->if_name, strerror(errno)); |
| close(fd); |
| return err; |
| } |
| close(fd); |
| - _DBG_VPN("Killed tun device %s", tun_name); |
| + _DBG_VPN("Killed tun device %s", data->if_name); |
| return 0; |
| } |
| @@ -125,7 +138,7 @@ void vpn_died(struct connman_task *task, void *user_data) |
| if (!data) |
| goto vpn_exit; |
| - kill_tun(data->if_name); |
| + kill_tun(provider); |
| connman_provider_set_data(provider, NULL); |
| connman_rtnl_remove_watch(data->watch); |
| @@ -144,6 +157,24 @@ vpn_exit: |
| connman_task_destroy(task); |
| } |
| +int vpn_set_ifname(struct connman_provider *provider, const char *ifname) |
| +{ |
| + struct vpn_data *data = connman_provider_get_data(provider); |
| + int index; |
| + |
| + if (ifname == NULL || data == NULL) |
|
Sam Leffler
2011/03/04 17:47:45
need debug/error msgs
kmixter1
2011/03/05 09:30:51
Done.
|
| + return -EIO; |
| + |
| + index = connman_inet_ifindex(ifname); |
| + if (index < 0) |
|
Sam Leffler
2011/03/04 17:47:45
need msg unless connman_inet_ifindex already compl
kmixter1
2011/03/05 09:30:51
It doesn't, so added.
|
| + return -EIO; |
| + |
| + data->if_name = (char *)g_strdup(ifname); |
| + connman_provider_set_index(provider, index); |
| + |
| + return 0; |
| +} |
| + |
| static void vpn_newlink(const char *ifname, unsigned flags, unsigned change, void *user_data) |
| { |
| struct connman_provider *provider = user_data; |
| @@ -159,7 +190,7 @@ static void vpn_newlink(const char *ifname, unsigned flags, unsigned change, |
| data->flags = flags; |
| } |
| -static void vpn_notify(struct connman_task *task, |
| +static DBusMessage *vpn_notify(struct connman_task *task, |
| DBusMessage *msg, void *user_data) |
| { |
| struct connman_provider *provider = user_data; |
| @@ -173,7 +204,7 @@ static void vpn_notify(struct connman_task *task, |
| name = connman_provider_get_driver_name(provider); |
| vpn_driver_data = g_hash_table_lookup(driver_hash, name); |
| if (vpn_driver_data == NULL) |
| - return; |
| + return NULL; |
| state = vpn_driver_data->vpn_driver->notify(msg, provider); |
| switch (state) { |
| @@ -193,34 +224,19 @@ static void vpn_notify(struct connman_task *task, |
| CONNMAN_PROVIDER_STATE_DISCONNECT); |
| break; |
| } |
| + |
| + return NULL; |
| } |
| -static int vpn_connect(struct connman_provider *provider) |
| +static int vpn_create_tun(struct connman_provider *provider) |
| { |
| struct vpn_data *data = connman_provider_get_data(provider); |
| - struct vpn_driver_data *vpn_driver_data; |
| struct ifreq ifr; |
| - const char *name; |
| int i, fd, index; |
| int ret = 0; |
| - if (data != NULL) |
| - return -EISCONN; |
| - |
| - data = g_try_new0(struct vpn_data, 1); |
| if (data == NULL) |
| - return -ENOMEM; |
| - |
| - data->provider = connman_provider_ref(provider); |
| - data->watch = 0; |
| - data->flags = 0; |
| - data->task = NULL; |
| - data->state = VPN_STATE_IDLE; |
| - |
| - connman_provider_set_data(provider, data); |
| - |
| - name = connman_provider_get_driver_name(provider); |
| - vpn_driver_data = g_hash_table_lookup(driver_hash, name); |
| + return -EISCONN; |
| fd = open("/dev/net/tun", O_RDWR); |
| if (fd < 0) { |
| @@ -269,24 +285,63 @@ static int vpn_connect(struct connman_provider *provider) |
| index = connman_inet_ifindex(data->if_name); |
| if (index < 0) { |
| connman_error("%s: failed to get tun ifindex", __func__); |
| - kill_tun(data->if_name); |
| + kill_tun(provider); |
| ret = -EIO; |
| goto exist_err; |
| } |
| connman_provider_set_index(provider, index); |
| + return 0; |
| + |
| +exist_err: |
| + return ret; |
| +} |
| + |
| +static int vpn_connect(struct connman_provider *provider) |
| +{ |
| + struct vpn_data *data = connman_provider_get_data(provider); |
| + struct vpn_driver_data *vpn_driver_data; |
| + const char *name; |
| + int ret = 0; |
| + |
| + if (data != NULL) |
|
Sam Leffler
2011/03/04 17:47:45
please add debug msg
kmixter1
2011/03/05 09:30:51
Done.
|
| + return -EISCONN; |
| + |
| + data = g_try_new0(struct vpn_data, 1); |
| + if (data == NULL) |
| + return -ENOMEM; |
| + |
| + data->provider = connman_provider_ref(provider); |
| + data->watch = 0; |
| + data->flags = 0; |
| + data->task = NULL; |
| + data->state = VPN_STATE_IDLE; |
| + |
| + connman_provider_set_data(provider, data); |
| + |
| + name = connman_provider_get_driver_name(provider); |
| + vpn_driver_data = g_hash_table_lookup(driver_hash, name); |
| + |
| + if (vpn_driver_data && vpn_driver_data->vpn_driver && |
|
Sam Leffler
2011/03/04 17:47:45
ptr cmp to NULL
kmixter1
2011/03/05 09:30:51
Done.
|
| + vpn_driver_data->vpn_driver->flags != VPN_FLAG_NO_TUN) { |
| + |
| + ret = vpn_create_tun(provider); |
| + if (ret < 0) |
| + goto exist_err; |
| + } |
| + |
| data->task = connman_task_create(vpn_driver_data->program); |
| if (data->task == NULL) { |
| ret = -ENOMEM; |
| - kill_tun(data->if_name); |
| + kill_tun(provider); |
| goto exist_err; |
| } |
| if (connman_task_set_notify(data->task, "notify", |
| vpn_notify, provider)) { |
| ret = -ENOMEM; |
| - kill_tun(data->if_name); |
| + kill_tun(provider); |
| connman_task_destroy(data->task); |
| data->task = NULL; |
| goto exist_err; |
| @@ -295,7 +350,7 @@ static int vpn_connect(struct connman_provider *provider) |
| ret = vpn_driver_data->vpn_driver->connect(provider, data->task, |
| data->if_name); |
| if (ret < 0) { |
| - kill_tun(data->if_name); |
| + kill_tun(provider); |
| connman_task_destroy(data->task); |
| data->task = NULL; |
| goto exist_err; |
| @@ -355,7 +410,6 @@ static int vpn_remove(struct connman_provider *provider) |
| struct vpn_data *data; |
| data = connman_provider_get_data(provider); |
|
Sam Leffler
2011/03/04 17:47:45
not sure i follow why it's ok to drop set_data cal
kmixter1
2011/03/05 09:30:51
This is from upstream, but I agree. I see why it
|
| - connman_provider_set_data(provider, NULL); |
| if (data == NULL) |
| return 0; |
| @@ -365,7 +419,7 @@ static int vpn_remove(struct connman_provider *provider) |
| connman_task_stop(data->task); |
| g_usleep(G_USEC_PER_SEC); |
| - kill_tun(data->if_name); |
| + kill_tun(provider); |
| return 0; |
| } |