When autoconnecting a VPN, check whether existing VPN services mandate
the service to have split routing capabilities. For autoconnection to
work, VPN services must be marked favorite.
Ignore VPNs when a normal autoconnect is run.
---
src/service.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 63 insertions(+), 2 deletions(-)
diff --git a/src/service.c b/src/service.c
index 26e5f04..b0b1d68 100644
--- a/src/service.c
+++ b/src/service.c
@@ -45,6 +45,7 @@ static GList *service_list = NULL;
static GHashTable *service_hash = NULL;
static GSList *counter_list = NULL;
static unsigned int autoconnect_timeout = 0;
+static unsigned int vpn_autoconnect_timeout = 0;
static struct connman_service *current_default = NULL;
static bool services_dirty = false;
@@ -3523,6 +3524,8 @@ static bool auto_connect_service(GList *services, bool
preferred)
DBG("preferred %d sessions %d", preferred, active_count);
+ ignore[CONNMAN_SERVICE_TYPE_VPN] = true;
+
for (list = services; list; list = list->next) {
service = list->data;
@@ -3610,6 +3613,57 @@ void __connman_service_auto_connect(void)
autoconnect_timeout = g_timeout_add_seconds(0, run_auto_connect, NULL);
}
+static gboolean run_vpn_auto_connect(gpointer data) {
+ GList *list;
+
+ vpn_autoconnect_timeout = 0;
+
+ for (list = service_list; list; list = list->next) {
+ struct connman_service *service = list->data;
+ bool need_split = false;
+ int res;
+
+ if (service->type != CONNMAN_SERVICE_TYPE_VPN)
+ continue;
+
+ if (is_connected(service) || is_connecting(service)) {
+ if (!service->do_split_routing)
+ need_split = true;
+ continue;
+ }
+
+ if (is_ignore(service) || !service->favorite)
+ continue;
+
+ if (need_split && !service->do_split_routing) {
+ DBG("service %p no split routing", service);
+ continue;
+ }
+
+ DBG("service %p %s %s", service, service->name,
+ (service->do_split_routing) ?
+ "split routing" : "");
+
+ res = __connman_service_connect(service);
+ if (res < 0 && res != -EINPROGRESS)
+ continue;
+
+ if (!service->do_split_routing)
+ need_split = true;
+ }
+
+ return FALSE;
+}
+
+static void vpn_auto_connect(void)
+{
+ if (vpn_autoconnect_timeout)
+ return;
+
+ vpn_autoconnect_timeout =
+ g_timeout_add_seconds(0, run_vpn_auto_connect, NULL);
+}
+
static void remove_timeout(struct connman_service *service)
{
if (service->timeout > 0) {
@@ -5299,9 +5353,10 @@ static int service_indicate_state(struct connman_service
*service)
__connman_ipconfig_disable_ipv6(
service->ipconfig_ipv6);
- if (connman_setting_get_bool("SingleConnectedTechnology")
- )
+ if (connman_setting_get_bool("SingleConnectedTechnology"))
single_connected_tech(service);
+ else if (service->type != CONNMAN_SERVICE_TYPE_VPN)
+ vpn_auto_connect();
} else if (new_state == CONNMAN_SERVICE_STATE_DISCONNECT) {
def_service = __connman_service_get_default();
@@ -6775,6 +6830,7 @@ __connman_service_create_from_provider(struct
connman_provider *provider)
service->provider = connman_provider_ref(provider);
service->autoconnect = false;
service->userconnect = true;
+ service->favorite = true;
service->state_ipv4 = service->state_ipv6 = CONNMAN_SERVICE_STATE_IDLE;
service->state = combine_state(service->state_ipv4,
service->state_ipv6);
@@ -6933,6 +6989,11 @@ void __connman_service_cleanup(void)
{
DBG("");
+ if (vpn_autoconnect_timeout) {
+ g_source_remove(vpn_autoconnect_timeout);
+ vpn_autoconnect_timeout = 0;
+ }
+
if (autoconnect_timeout != 0) {
g_source_remove(autoconnect_timeout);
autoconnect_timeout = 0;
--
1.7.10.4
_______________________________________________
connman mailing list
[email protected]
https://lists.connman.net/mailman/listinfo/connman