diff options
author | Jukka Rissanen <jukka.rissanen@linux.intel.com> | 2012-04-03 14:07:24 +0300 |
---|---|---|
committer | Patrik Flykt <patrik.flykt@linux.intel.com> | 2012-04-12 11:00:42 +0300 |
commit | 709aaebeaca495292306f95d3fb1bc346f331d67 (patch) | |
tree | 476e790b61bf7b7fae4645828029abadcf38d3ff /src | |
parent | 4ca9544819ca979354dabdf24f4f4f42c2a416d5 (diff) | |
download | connman-709aaebeaca495292306f95d3fb1bc346f331d67.tar.gz connman-709aaebeaca495292306f95d3fb1bc346f331d67.tar.bz2 connman-709aaebeaca495292306f95d3fb1bc346f331d67.zip |
provider: Disconnect VPN when phy service is disconnected
If the VPN is connected and the underlaying service is
disconnected, then we must also disconnect the VPN if it
is still connected.
Diffstat (limited to 'src')
-rw-r--r-- | src/connection.c | 22 | ||||
-rw-r--r-- | src/connman.h | 1 | ||||
-rw-r--r-- | src/provider.c | 62 |
3 files changed, 85 insertions, 0 deletions
diff --git a/src/connection.c b/src/connection.c index 3747c051..8b1b689d 100644 --- a/src/connection.c +++ b/src/connection.c @@ -1025,6 +1025,28 @@ gboolean __connman_connection_update_gateway(void) return updated; } +int __connman_connection_get_vpn_index(int phy_index) +{ + GHashTableIter iter; + gpointer value, key; + + g_hash_table_iter_init(&iter, gateway_hash); + + while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) { + struct gateway_data *data = value; + + if (data->ipv4_gateway != NULL && + data->ipv4_gateway->vpn_phy_index == phy_index) + return data->index; + + if (data->ipv6_gateway != NULL && + data->ipv6_gateway->vpn_phy_index == phy_index) + return data->index; + } + + return -1; +} + int __connman_connection_init(void) { int err; diff --git a/src/connman.h b/src/connman.h index 306e9d66..7f42bc99 100644 --- a/src/connman.h +++ b/src/connman.h @@ -402,6 +402,7 @@ int __connman_connection_gateway_add(struct connman_service *service, const char *peer); void __connman_connection_gateway_remove(struct connman_service *service, enum connman_ipconfig_type type); +int __connman_connection_get_vpn_index(int phy_index); gboolean __connman_connection_update_gateway(void); void __connman_connection_gateway_activate(struct connman_service *service, diff --git a/src/provider.c b/src/provider.c index 42fd112f..00f3f4c5 100644 --- a/src/provider.c +++ b/src/provider.c @@ -1281,9 +1281,71 @@ static void provider_offline_mode(connman_bool_t enabled) } +static struct connman_provider *provider_get(int index) +{ + GHashTableIter iter; + gpointer value, key; + + g_hash_table_iter_init(&iter, provider_hash); + + while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) { + struct connman_provider *provider = value; + + if (provider->index == index) + return provider; + } + + return NULL; +} + +static void provider_service_changed(struct connman_service *service, + enum connman_service_state state) +{ + struct connman_provider *provider; + int vpn_index, service_index; + + if (service == NULL) + return; + + switch (state) { + case CONNMAN_SERVICE_STATE_UNKNOWN: + case CONNMAN_SERVICE_STATE_IDLE: + case CONNMAN_SERVICE_STATE_ASSOCIATION: + case CONNMAN_SERVICE_STATE_CONFIGURATION: + case CONNMAN_SERVICE_STATE_READY: + case CONNMAN_SERVICE_STATE_ONLINE: + return; + case CONNMAN_SERVICE_STATE_DISCONNECT: + case CONNMAN_SERVICE_STATE_FAILURE: + break; + } + + service_index = __connman_service_get_index(service); + + vpn_index = __connman_connection_get_vpn_index(service_index); + + DBG("service %p %s state %d index %d/%d", service, + __connman_service_get_ident(service), + state, service_index, vpn_index); + + if (vpn_index < 0) + return; + + provider = provider_get(vpn_index); + if (provider == NULL) + return; + + DBG("disconnect %p index %d", provider, vpn_index); + + __connman_provider_disconnect(provider); + + return; +} + static struct connman_notifier provider_notifier = { .name = "provider", .offline_mode = provider_offline_mode, + .service_state_changed = provider_service_changed, }; int __connman_provider_init(void) |