Skip to content

Commit

Permalink
service: Sort VPNs using the transport service if connected
Browse files Browse the repository at this point in the history
[service] Sort VPNs using the transport service if connected. JB#48769

Use the transport to verify the order of the connected VPN services. If
there is a transport service in use that ranks lower than an another
service it means that the order must be changed based on comparing the
transport and the service instead of comparing VPN and the service. This
is because the higher ranking service should then become the transport
of the VPN.

This ensures that when the list is sorted the transport check in
plugins/vpn.c will make VPN to switch to the new transport that is
enabled to be the default. Use of the service ident from hash table for
searching is used because the index cannot be retrieved from the list
while sorting the list.
  • Loading branch information
LaakkonenJussi committed Mar 17, 2021
1 parent 0d574b0 commit f839c26
Showing 1 changed file with 45 additions and 0 deletions.
45 changes: 45 additions & 0 deletions connman/src/service.c
Expand Up @@ -6698,6 +6698,40 @@ static int service_preferred_over(struct connman_service *a,
return 0;
}

static gint service_compare(gconstpointer a, gconstpointer b);

static gint service_compare_vpn(struct connman_service *a,
struct connman_service *b)
{
struct connman_provider *provider;
struct connman_service *service;
struct connman_service *transport;
const char *ident;
bool reverse;

if (a->provider) {
provider = a->provider;
service = b;
reverse = false;
} else if (b->provider) {
provider = b->provider;
service = a;
reverse = true;
} else {
return 0;
}

ident = __connman_provider_get_transport_ident(provider);
transport = connman_service_lookup_from_identifier(ident);
if (!transport)
return 0;

if (reverse)
return service_compare(service, transport);

return service_compare(transport, service);
}

static gint service_compare(gconstpointer a, gconstpointer b)
{
struct connman_service *service_a = (void *) a;
Expand All @@ -6721,6 +6755,17 @@ static gint service_compare(gconstpointer a, gconstpointer b)
b_connected = is_connected(service_b);

if (a_connected && b_connected) {
int rval;

/* Compare the VPN transport and the service */
if ((service_a->type == CONNMAN_SERVICE_TYPE_VPN ||
service_b->type == CONNMAN_SERVICE_TYPE_VPN) &&
service_b->type != service_a->type) {
rval = service_compare_vpn(service_a, service_b);
if (rval)
return rval;
}

if (state_a == state_b) {
int preference;

Expand Down

0 comments on commit f839c26

Please sign in to comment.