diff options
author | Zhang zhengguang <zhengguang.zhang@intel.com> | 2014-10-29 11:03:47 +0800 |
---|---|---|
committer | Zhang zhengguang <zhengguang.zhang@intel.com> | 2014-10-29 11:03:47 +0800 |
commit | bcae74da8fa2958b3fec9153fc33e41f0e0317bf (patch) | |
tree | 06a00f6457307467fee4f6580dce4a1a857751c1 /vpn | |
parent | 1b9d0a62f59bb48c8deb2f0b98d9acdffdd9abe7 (diff) | |
download | connman-bcae74da8fa2958b3fec9153fc33e41f0e0317bf.tar.gz connman-bcae74da8fa2958b3fec9153fc33e41f0e0317bf.tar.bz2 connman-bcae74da8fa2958b3fec9153fc33e41f0e0317bf.zip |
Imported Upstream version 1.26upstream/1.26
Diffstat (limited to 'vpn')
-rw-r--r-- | vpn/plugins/l2tp.c | 2 | ||||
-rw-r--r-- | vpn/plugins/openconnect.c | 1 | ||||
-rw-r--r-- | vpn/plugins/openvpn.c | 2 | ||||
-rw-r--r-- | vpn/plugins/pptp.c | 2 | ||||
-rw-r--r-- | vpn/plugins/vpn.c | 29 | ||||
-rw-r--r-- | vpn/plugins/vpn.h | 2 | ||||
-rw-r--r-- | vpn/plugins/vpnc.c | 2 | ||||
-rw-r--r-- | vpn/vpn-ipconfig.c | 24 | ||||
-rw-r--r-- | vpn/vpn-provider.c | 117 | ||||
-rw-r--r-- | vpn/vpn-provider.h | 2 | ||||
-rw-r--r-- | vpn/vpn.h | 2 |
11 files changed, 136 insertions, 49 deletions
diff --git a/vpn/plugins/l2tp.c b/vpn/plugins/l2tp.c index 91acc85f..22f9dcf8 100644 --- a/vpn/plugins/l2tp.c +++ b/vpn/plugins/l2tp.c @@ -2,7 +2,7 @@ * * ConnMan VPN daemon * - * Copyright (C) 2010,2013 BMW Car IT GmbH. All rights reserved. + * Copyright (C) 2010,2013 BMW Car IT GmbH. * Copyright (C) 2012-2013 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify diff --git a/vpn/plugins/openconnect.c b/vpn/plugins/openconnect.c index c6b9cd65..5feaed9d 100644 --- a/vpn/plugins/openconnect.c +++ b/vpn/plugins/openconnect.c @@ -552,7 +552,6 @@ static int oc_error_code(struct vpn_provider *provider, int exit_code) switch (exit_code) { case 1: - return VPN_PROVIDER_ERROR_CONNECT_FAILED; case 2: vpn_provider_set_string_hide_value(provider, "OpenConnect.Cookie", NULL); diff --git a/vpn/plugins/openvpn.c b/vpn/plugins/openvpn.c index 35013c40..9ee5795c 100644 --- a/vpn/plugins/openvpn.c +++ b/vpn/plugins/openvpn.c @@ -2,7 +2,7 @@ * * ConnMan VPN daemon * - * Copyright (C) 2010 BMW Car IT GmbH. All rights reserved. + * Copyright (C) 2010-2014 BMW Car IT GmbH. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/vpn/plugins/pptp.c b/vpn/plugins/pptp.c index a6e51e79..9f2a214d 100644 --- a/vpn/plugins/pptp.c +++ b/vpn/plugins/pptp.c @@ -2,7 +2,7 @@ * * ConnMan VPN daemon * - * Copyright (C) 2010,2013 BMW Car IT GmbH. All rights reserved. + * Copyright (C) 2010,2013-2014 BMW Car IT GmbH. * Copyright (C) 2012-2013 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify diff --git a/vpn/plugins/vpn.c b/vpn/plugins/vpn.c index b407573e..b438d06e 100644 --- a/vpn/plugins/vpn.c +++ b/vpn/plugins/vpn.c @@ -138,9 +138,9 @@ void vpn_died(struct connman_task *task, int exit_code, void *user_data) vpn_provider_set_data(provider, NULL); if (data->watch != 0) { - vpn_provider_unref(provider); vpn_rtnl_remove_watch(data->watch); data->watch = 0; + vpn_provider_unref(provider); } vpn_exit: @@ -160,8 +160,6 @@ vpn_exit: ret = VPN_PROVIDER_ERROR_UNKNOWN; vpn_provider_indicate_error(provider, ret); - - vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE); } else vpn_provider_set_state(provider, VPN_PROVIDER_STATE_IDLE); @@ -245,6 +243,31 @@ static DBusMessage *vpn_notify(struct connman_task *task, switch (state) { case VPN_STATE_CONNECT: case VPN_STATE_READY: + if (data->state == VPN_STATE_READY) { + /* + * This is the restart case, in which case we must + * just set the IP address. + * + * We need to remove first the old address, just + * replacing the old address will not work as expected + * because the old address will linger in the interface + * and not disapper so the clearing is needed here. + * + * Also the state must change, otherwise the routes + * will not be set properly. + */ + vpn_provider_set_state(provider, + VPN_PROVIDER_STATE_CONNECT); + + vpn_provider_clear_address(provider, AF_INET); + vpn_provider_clear_address(provider, AF_INET6); + + vpn_provider_change_address(provider); + vpn_provider_set_state(provider, + VPN_PROVIDER_STATE_READY); + break; + } + index = vpn_provider_get_index(provider); vpn_provider_ref(provider); data->watch = vpn_rtnl_add_newlink_watch(index, diff --git a/vpn/plugins/vpn.h b/vpn/plugins/vpn.h index 3d2b66c5..bf56728d 100644 --- a/vpn/plugins/vpn.h +++ b/vpn/plugins/vpn.h @@ -2,7 +2,7 @@ * * ConnMan VPN daemon * - * Copyright (C) 2010 BMW Car IT GmbH. All rights reserved. + * Copyright (C) 2010,2014 BMW Car IT GmbH. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/vpn/plugins/vpnc.c b/vpn/plugins/vpnc.c index 04235c86..09674bd8 100644 --- a/vpn/plugins/vpnc.c +++ b/vpn/plugins/vpnc.c @@ -2,7 +2,7 @@ * * ConnMan VPN daemon * - * Copyright (C) 2010,2013 BMW Car IT GmbH. All rights reserved. + * Copyright (C) 2010,2013 BMW Car IT GmbH. * Copyright (C) 2010,2012-2013 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify diff --git a/vpn/vpn-ipconfig.c b/vpn/vpn-ipconfig.c index c3e61453..c096fa37 100644 --- a/vpn/vpn-ipconfig.c +++ b/vpn/vpn-ipconfig.c @@ -69,27 +69,13 @@ struct vpn_ipdevice { static GHashTable *ipdevice_hash = NULL; -unsigned char __vpn_ipconfig_netmask_prefix_len(const char *netmask) +struct connman_ipaddress * +__vpn_ipconfig_get_address(struct vpn_ipconfig *ipconfig) { - unsigned char bits; - in_addr_t mask; - in_addr_t host; - - if (!netmask) - return 32; - - mask = inet_network(netmask); - host = ~mask; - - /* a valid netmask must be 2^n - 1 */ - if ((host & (host + 1)) != 0) - return -1; - - bits = 0; - for (; mask; mask <<= 1) - ++bits; + if (!ipconfig) + return NULL; - return bits; + return ipconfig->address; } const char *__vpn_ipconfig_get_peer(struct vpn_ipconfig *ipconfig) diff --git a/vpn/vpn-provider.c b/vpn/vpn-provider.c index c39ebf9d..16c0c2be 100644 --- a/vpn/vpn-provider.c +++ b/vpn/vpn-provider.c @@ -84,6 +84,8 @@ struct vpn_provider { char *config_file; char *config_entry; bool immutable; + struct connman_ipaddress *prev_ipv4_addr; + struct connman_ipaddress *prev_ipv6_addr; }; static void append_properties(DBusMessageIter *iter, @@ -1000,6 +1002,8 @@ static void provider_destruct(struct vpn_provider *provider) g_strfreev(provider->host_ip); g_free(provider->config_file); g_free(provider->config_entry); + connman_ipaddress_free(provider->prev_ipv4_addr); + connman_ipaddress_free(provider->prev_ipv6_addr); g_free(provider); } @@ -1307,13 +1311,6 @@ static int provider_indicate_state(struct vpn_provider *provider, VPN_CONNECTION_INTERFACE, "State", DBUS_TYPE_STRING, &str); - /* - * We do not stay in failure state as clients like connmand can - * get confused about our current state. - */ - if (provider->state == VPN_PROVIDER_STATE_FAILURE) - provider->state = VPN_PROVIDER_STATE_IDLE; - return 0; } @@ -1550,15 +1547,16 @@ int vpn_provider_indicate_error(struct vpn_provider *provider, DBG("provider %p id %s error %d", provider, provider->identifier, error); + vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE); + switch (error) { - case VPN_PROVIDER_ERROR_LOGIN_FAILED: - break; - case VPN_PROVIDER_ERROR_AUTH_FAILED: - vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE); - break; + case VPN_PROVIDER_ERROR_UNKNOWN: case VPN_PROVIDER_ERROR_CONNECT_FAILED: break; - default: + + case VPN_PROVIDER_ERROR_LOGIN_FAILED: + case VPN_PROVIDER_ERROR_AUTH_FAILED: + vpn_provider_set_state(provider, VPN_PROVIDER_STATE_IDLE); break; } @@ -2304,19 +2302,41 @@ int vpn_provider_set_ipaddress(struct vpn_provider *provider, break; } - DBG("provider %p ipconfig %p family %d", provider, ipconfig, - ipaddress->family); + DBG("provider %p state %d ipconfig %p family %d", provider, + provider->state, ipconfig, ipaddress->family); if (!ipconfig) return -EINVAL; provider->family = ipaddress->family; - __vpn_ipconfig_set_local(ipconfig, ipaddress->local); - __vpn_ipconfig_set_peer(ipconfig, ipaddress->peer); - __vpn_ipconfig_set_broadcast(ipconfig, ipaddress->broadcast); - __vpn_ipconfig_set_gateway(ipconfig, ipaddress->gateway); - __vpn_ipconfig_set_prefixlen(ipconfig, ipaddress->prefixlen); + if (provider->state == VPN_PROVIDER_STATE_CONNECT || + provider->state == VPN_PROVIDER_STATE_READY) { + struct connman_ipaddress *addr = + __vpn_ipconfig_get_address(ipconfig); + + /* + * Remember the old address so that we can remove it in notify + * function in plugins/vpn.c if we ever restart + */ + if (ipaddress->family == AF_INET6) { + connman_ipaddress_free(provider->prev_ipv6_addr); + provider->prev_ipv6_addr = + connman_ipaddress_copy(addr); + } else { + connman_ipaddress_free(provider->prev_ipv4_addr); + provider->prev_ipv4_addr = + connman_ipaddress_copy(addr); + } + } + + if (ipaddress->local) { + __vpn_ipconfig_set_local(ipconfig, ipaddress->local); + __vpn_ipconfig_set_peer(ipconfig, ipaddress->peer); + __vpn_ipconfig_set_broadcast(ipconfig, ipaddress->broadcast); + __vpn_ipconfig_set_gateway(ipconfig, ipaddress->gateway); + __vpn_ipconfig_set_prefixlen(ipconfig, ipaddress->prefixlen); + } return 0; } @@ -2544,6 +2564,63 @@ const char *vpn_provider_get_path(struct vpn_provider *provider) return provider->path; } +void vpn_provider_change_address(struct vpn_provider *provider) +{ + switch (provider->family) { + case AF_INET: + connman_inet_set_address(provider->index, + __vpn_ipconfig_get_address(provider->ipconfig_ipv4)); + break; + case AF_INET6: + connman_inet_set_ipv6_address(provider->index, + __vpn_ipconfig_get_address(provider->ipconfig_ipv6)); + break; + default: + break; + } +} + +void vpn_provider_clear_address(struct vpn_provider *provider, int family) +{ + const char *address; + unsigned char len; + + DBG("provider %p family %d ipv4 %p ipv6 %p", provider, family, + provider->prev_ipv4_addr, provider->prev_ipv6_addr); + + switch (family) { + case AF_INET: + if (provider->prev_ipv4_addr) { + connman_ipaddress_get_ip(provider->prev_ipv4_addr, + &address, &len); + + DBG("ipv4 %s/%d", address, len); + + connman_inet_clear_address(provider->index, + provider->prev_ipv4_addr); + connman_ipaddress_free(provider->prev_ipv4_addr); + provider->prev_ipv4_addr = NULL; + } + break; + case AF_INET6: + if (provider->prev_ipv6_addr) { + connman_ipaddress_get_ip(provider->prev_ipv6_addr, + &address, &len); + + DBG("ipv6 %s/%d", address, len); + + connman_inet_clear_ipv6_address(provider->index, + address, len); + + connman_ipaddress_free(provider->prev_ipv6_addr); + provider->prev_ipv6_addr = NULL; + } + break; + default: + break; + } +} + static int agent_probe(struct connman_agent *agent) { DBG("agent %p", agent); diff --git a/vpn/vpn-provider.h b/vpn/vpn-provider.h index 22b2062d..8105d7f1 100644 --- a/vpn/vpn-provider.h +++ b/vpn/vpn-provider.h @@ -107,6 +107,8 @@ const char *vpn_provider_get_save_group(struct vpn_provider *provider); const char *vpn_provider_get_name(struct vpn_provider *provider); const char *vpn_provider_get_host(struct vpn_provider *provider); const char *vpn_provider_get_path(struct vpn_provider *provider); +void vpn_provider_change_address(struct vpn_provider *provider); +void vpn_provider_clear_address(struct vpn_provider *provider, int family); typedef void (* vpn_provider_connect_cb_t) (struct vpn_provider *provider, void *user_data, int error); @@ -32,7 +32,7 @@ void __vpn_manager_cleanup(void); struct vpn_ipconfig; -unsigned char __vpn_ipconfig_netmask_prefix_len(const char *netmask); +struct connman_ipaddress *__vpn_ipconfig_get_address(struct vpn_ipconfig *ipconfig); unsigned short __vpn_ipconfig_get_type_from_index(int index); unsigned int __vpn_ipconfig_get_flags_from_index(int index); void __vpn_ipconfig_foreach(void (*function) (int index, |