Send connman mailing list submissions to
        [email protected]

To subscribe or unsubscribe via the World Wide Web, visit
        https://lists.01.org/mailman/listinfo/connman
or, via email, send a message with subject or body 'help' to
        [email protected]

You can reach the person managing the list at
        [email protected]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of connman digest..."


Today's Topics:

   1. [PATCH 0/2] Fix connections to VPN servers on local network
      (Santtu Lakkala)
   2. [PATCH 1/2] inet: Add connman_inet_compare_ipv6_subnet()
      (Santtu Lakkala)
   3. [PATCH 2/2] connection: Fix connections to local VPN servers
      (Santtu Lakkala)


----------------------------------------------------------------------

Message: 1
Date: Fri, 13 Sep 2019 15:30:29 +0300
From: Santtu Lakkala <[email protected]>
To: [email protected]
Subject: [PATCH 0/2] Fix connections to VPN servers on local network
Message-ID: <[email protected]>

When VPN server resides on local network, a route via default gateway
must not be added for it to remain reachale.

Add a check using existing IPv4 helper, and introduce a new helper for
IPv6.

Santtu Lakkala (2):
  inet: Add connman_inet_compare_ipv6_subnet()
  connection: Fix connections to local VPN servers

 include/inet.h   |  1 +
 src/connection.c | 13 +++++++++++
 src/inet.c       | 59 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 73 insertions(+)

-- 
2.20.1



------------------------------

Message: 2
Date: Fri, 13 Sep 2019 15:30:30 +0300
From: Santtu Lakkala <[email protected]>
To: [email protected]
Subject: [PATCH 1/2] inet: Add connman_inet_compare_ipv6_subnet()
Message-ID: <[email protected]>

Add a helper to check if a IPv6 address is in the local network, similar
to connman_inet_compare_subnet() for IPv4.
---
 include/inet.h |  1 +
 src/inet.c     | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)

diff --git a/include/inet.h b/include/inet.h
index 9c1918f3..fdc2155f 100644
--- a/include/inet.h
+++ b/include/inet.h
@@ -51,6 +51,7 @@ int connman_inet_clear_gateway_address(int index, const char 
*gateway);
 int connman_inet_set_gateway_interface(int index);
 int connman_inet_clear_gateway_interface(int index);
 bool connman_inet_compare_subnet(int index, const char *host);
+bool connman_inet_compare_ipv6_subnet(int index, const char *host);
 int connman_inet_set_ipv6_address(int index,
                struct connman_ipaddress *ipaddress);
 int connman_inet_clear_ipv6_address(int index,
diff --git a/src/inet.c b/src/inet.c
index b128e578..ff32fce2 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -1116,6 +1116,65 @@ bool connman_inet_compare_subnet(int index, const char 
*host)
        return ((if_addr & netmask_addr) == (host_addr & netmask_addr));
 }
 
+static bool mem_mask_equal(const void *a, const void *b,
+                                       const void *mask, size_t n)
+{
+       size_t i;
+
+       for (i = 0; i < n; i++) {
+               if ((((unsigned char *)a)[i] ^ ((unsigned char *)b)[i]) &
+                                               ((unsigned char *)mask)[i])
+                       return false;
+       }
+
+       return true;
+}
+
+bool connman_inet_compare_ipv6_subnet(int index, const char *host)
+{
+       struct ifaddrs *ifaddr, *ifa;
+       bool rv = false;
+       char name[IF_NAMESIZE];
+       struct in6_addr haddr;
+
+       if (inet_pton(AF_INET6, host, &haddr) <= 0)
+               return false;
+
+       if (!if_indextoname(index, name))
+               return false;
+
+       DBG("index %d interface %s", index, name);
+
+       if (getifaddrs(&ifaddr) < 0) {
+               DBG("Cannot get addresses err %d/%s", errno, strerror(errno));
+               return false;
+       }
+
+       for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
+               struct sockaddr_in6 *iaddr;
+               struct sockaddr_in6 *imask;
+
+               if (!ifa->ifa_addr)
+                       continue;
+
+               if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) != 0 ||
+                                       ifa->ifa_addr->sa_family != AF_INET6)
+                       continue;
+
+               iaddr = (struct sockaddr_in6 *)ifa->ifa_addr;
+               imask = (struct sockaddr_in6 *)ifa->ifa_netmask;
+
+               rv = mem_mask_equal(&iaddr->sin6_addr, &haddr,
+                                       &imask->sin6_addr,
+                                       sizeof(haddr));
+               goto out;
+       }
+
+out:
+       freeifaddrs(ifaddr);
+       return rv;
+}
+
 int connman_inet_remove_from_bridge(int index, const char *bridge)
 {
        struct ifreq ifr;
-- 
2.20.1



------------------------------

Message: 3
Date: Fri, 13 Sep 2019 15:30:31 +0300
From: Santtu Lakkala <[email protected]>
To: [email protected]
Subject: [PATCH 2/2] connection: Fix connections to local VPN servers
Message-ID: <[email protected]>

Skip adding an explicit route via gateway to VPN servers on the local
network.
---
 src/connection.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/connection.c b/src/connection.c
index 7a1fbcee..bc8dcb2c 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -234,6 +234,15 @@ static void set_vpn_routes(struct gateway_data 
*new_gateway,
                if (!active_gateway->ipv4_gateway)
                        return;
 
+
+               /*
+                * If VPN server is on same subnet as we are, skip adding
+                * route.
+                */
+               if (connman_inet_compare_subnet(active_gateway->index,
+                                                               gateway))
+                       return;
+
                DBG("active gw %s", active_gateway->ipv4_gateway->gateway);
 
                if (g_strcmp0(active_gateway->ipv4_gateway->gateway,
@@ -250,6 +259,10 @@ static void set_vpn_routes(struct gateway_data 
*new_gateway,
                if (!active_gateway->ipv6_gateway)
                        return;
 
+               if (connman_inet_compare_ipv6_subnet(active_gateway->index,
+                                                               gateway))
+                       return;
+
                DBG("active gw %s", active_gateway->ipv6_gateway->gateway);
 
                if (g_strcmp0(active_gateway->ipv6_gateway->gateway,
-- 
2.20.1



------------------------------

Subject: Digest Footer

_______________________________________________
connman mailing list
[email protected]
https://lists.01.org/mailman/listinfo/connman


------------------------------

End of connman Digest, Vol 47, Issue 7
**************************************

Reply via email to