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. Re: [PATCH] [Pacrunner]: Domains are looked up to match host
      of URL. (Atul Anand)
   2. Re: connman-vpnd does not reconnect after resume (Vasiliy Tolstov)


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

Message: 1
Date: Wed, 15 Jun 2016 15:41:44 +0530
From: Atul Anand <[email protected]>
To: Patrik Flykt <[email protected]>
Cc: David Woodhouse <[email protected]>, [email protected]
Subject: Re: [PATCH] [Pacrunner]: Domains are looked up to match host
        of URL.
Message-ID:
        <cabywktkgumbbyh+drvttq7h_2te4tpvbhgm03u4th8gx9x2...@mail.gmail.com>
Content-Type: text/plain; charset=UTF-8

>From 2ac42df5f5f68c31ee48a27797805290730e70bc Mon Sep 17 00:00:00 2001
From: Atul Anand <[email protected]>
Date: Wed, 15 Jun 2016 15:10:09 +0530
Subject: [PATCH 3/3] Fixes: Domains are looked up to match host of URL

---
 src/manager.c   |   7 +-
 src/pacrunner.h |   2 +
 src/proxy.c     | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 211 insertions(+), 12 deletions(-)

diff --git a/src/manager.c b/src/manager.c
index 1676466..5a8b4fd 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -35,7 +35,6 @@ struct proxy_config {
     DBusConnection *conn;
     guint watch;

-    char **domains;
     char **nameservers;

     struct pacrunner_proxy *proxy;
@@ -58,7 +57,6 @@ static void destroy_config(gpointer data)
     if (config->watch > 0)
         g_dbus_remove_watch(config->conn, config->watch);

-    g_strfreev(config->domains);
     g_strfreev(config->nameservers);

     g_free(config->sender);
@@ -224,12 +222,13 @@ static DBusMessage
*create_proxy_config(DBusConnection *conn,
         goto done;
     }

-    config->domains = domains;
     config->nameservers = nameservers;

-    domains = NULL;
     nameservers = NULL;

+    if (pacrunner_proxy_set_domains(config->proxy, domains) < 0)
+        pacrunner_error("Failed to set proxy domains");
+
     if (g_str_equal(method, "direct")) {
         if (pacrunner_proxy_set_direct(config->proxy) < 0)
             pacrunner_error("Failed to set direct proxy");
diff --git a/src/pacrunner.h b/src/pacrunner.h
index 6731d7c..db534cf 100644
--- a/src/pacrunner.h
+++ b/src/pacrunner.h
@@ -63,6 +63,8 @@ void pacrunner_proxy_unref(struct pacrunner_proxy *proxy);
 const char *pacrunner_proxy_get_interface(struct pacrunner_proxy *proxy);
 const char *pacrunner_proxy_get_script(struct pacrunner_proxy *proxy);

+int pacrunner_proxy_set_domains(struct pacrunner_proxy *proxy,
+                    char **domains);
 int pacrunner_proxy_set_direct(struct pacrunner_proxy *proxy);
 int pacrunner_proxy_set_manual(struct pacrunner_proxy *proxy,
                     char **servers, char **excludes);
diff --git a/src/proxy.c b/src/proxy.c
index 8bb03af..2ebc75d 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -23,6 +23,9 @@
 #include <config.h>
 #endif

+#include <string.h>
+#include <stdlib.h>
+#include <arpa/inet.h>
 #include <errno.h>
 #include <pthread.h>

@@ -37,6 +40,17 @@ struct pacrunner_proxy {
     char *script;
     GList **servers;
     GList **excludes;
+    GList *domains;
+};
+
+struct proxy_domain {
+    char *domain;
+    int proto;
+    union {
+        struct in_addr ip4;
+        struct in6_addr ip6;
+    } addr;
+    int mask;
 };

 static GList *proxy_list = NULL;
@@ -77,6 +91,15 @@ struct pacrunner_proxy *pacrunner_proxy_ref(struct
pacrunner_proxy *proxy)
     return proxy;
 }

+static void proxy_domain_destroy(gpointer data)
+{
+    struct proxy_domain *domain = data;
+    g_return_if_fail(domain != NULL);
+
+    g_free(domain->domain);
+    g_free(domain);
+}
+
 static void reset_proxy(struct pacrunner_proxy *proxy)
 {
     DBG("proxy %p", proxy);
@@ -92,6 +115,10 @@ static void reset_proxy(struct pacrunner_proxy *proxy)

     __pacrunner_manual_destroy_excludes(proxy->excludes);
     proxy->excludes = NULL;
+
+    if (proxy->domains)
+        g_list_free_full(proxy->domains, proxy_domain_destroy);
+    proxy->domains = NULL;
 }

 void pacrunner_proxy_unref(struct pacrunner_proxy *proxy)
@@ -130,6 +157,76 @@ const char *pacrunner_proxy_get_script(struct
pacrunner_proxy *proxy)
     return proxy->script;
 }

+int pacrunner_proxy_set_domains(struct pacrunner_proxy *proxy, char **domains)
+{
+    int len;
+    char *slash, **domain;
+    char ip[INET6_ADDRSTRLEN + 1];
+
+    DBG("proxy %p domains %p", proxy, domains);
+
+    if (!proxy)
+        return -EINVAL;
+
+    if (!domains)
+        return -EINVAL;
+
+    for (domain = domains; *domain; domain++) {
+        struct proxy_domain *data;
+
+        data = g_malloc0(sizeof(struct proxy_domain));
+
+        slash = strchr(*domain, '/');
+        if (!slash) {
+            data->domain = g_strdup(*domain);
+            data->proto = 0;
+
+            proxy->domains = g_list_append(proxy->domains, data);
+            continue;
+        }
+
+        len = slash - *domain;
+        if (len > INET6_ADDRSTRLEN) {
+            g_free(data);
+            continue;
+        }
+
+        strncpy(ip, *domain, len);
+        ip[len] = '\0';
+
+        if (inet_pton(AF_INET, ip, &(data->addr.ip4)) == 1) {
+            data->domain = NULL;
+            data->proto = 4;
+
+            errno = 0;
+            data->mask = strtol(slash + 1, NULL, 10);
+            if (errno || data->mask < 0 || data->mask > 32) {
+                g_free(data);
+                continue;
+            }
+
+            proxy->domains = g_list_append(proxy->domains, data);
+        } else if (inet_pton(AF_INET6, ip, &(data->addr.ip6)) == 1) {
+            data->domain = NULL;
+            data->proto = 6;
+
+            errno = 0;
+            data->mask = strtol(slash + 1, NULL, 10);
+            if (errno || data->mask < 0 || data->mask > 128) {
+                g_free(data);
+                continue;
+            }
+
+            proxy->domains = g_list_append(proxy->domains, data);
+        } else {
+            g_free(data);
+            continue;
+        }
+    }
+
+    return 0;
+}
+
 static int set_method(struct pacrunner_proxy *proxy,
                     enum pacrunner_proxy_method method)
 {
@@ -324,10 +421,61 @@ int pacrunner_proxy_disable(struct pacrunner_proxy *proxy)
     return 0;
 }

+static int compare_legacy_ip_in_net(struct in_addr *host,
+                    struct proxy_domain *match)
+{
+    if (ntohl(host->s_addr ^ match->addr.ip4.s_addr) >> (32 - match->mask))
+        return -1;
+
+    return 0;
+}
+
+static int compare_ipv6_in_net(struct in6_addr *host,
+                    struct proxy_domain *match)
+{
+    int i, shift;
+
+    for (i = 0; i < (match->mask)/8; i++) {
+        if (host->s6_addr[i] != match->addr.ip6.s6_addr[i])
+            return -1;
+    }
+
+    if ((match->mask) % 8) {
+        /**
+         * If mask bits are not multiple of 8 , 1-7 bits are left
+         * to be compared.
+         */
+        shift = 8 - (match->mask - (i*8));
+
+        if ((host->s6_addr[i] >> shift) !=
+            (match->addr.ip6.s6_addr[i] >> shift))
+            return -1;
+    }
+
+    return 0;
+}
+
+static int compare_host_in_domain(const char *host, struct proxy_domain *match)
+{
+    size_t hlen = strlen(host);
+    size_t dlen = strlen(match->domain);
+
+    if ((hlen >= dlen) && (strcmp(host + (hlen - dlen),
+                        match->domain) == 0)) {
+        if (hlen == dlen || host[hlen - dlen - 1] == '.')
+            return 0;
+    }
+
+    return -1;
+}
+
 char *pacrunner_proxy_lookup(const char *url, const char *host)
 {
-    GList *list;
-    struct pacrunner_proxy *selected_proxy = NULL;
+    GList *l, *list;
+    struct in_addr ip4_addr;
+    struct in6_addr ip6_addr;
+    struct pacrunner_proxy *selected_proxy = NULL, *default_proxy = NULL;
+    int protocol = 0;

     DBG("url %s host %s", url, host);

@@ -340,17 +488,67 @@ char *pacrunner_proxy_lookup(const char *url,
const char *host)
         return NULL;
     }

+    if (inet_pton(AF_INET, host, &ip4_addr) == 1) {
+        protocol = 4;
+    } else if (inet_pton(AF_INET6, host, &ip6_addr) == 1) {
+        protocol = 6;
+    } else if (host[0] == '[') {
+        char ip[INET6_ADDRSTRLEN + 1];
+        int len = strlen(host);
+
+        if (len < INET6_ADDRSTRLEN + 2 && host[len - 1] == ']') {
+            strncpy(ip, host + 1, len - 2);
+            ip[len - 2] = '\0';
+
+            if (inet_pton(AF_INET6, ip, &ip6_addr) == 1)
+                protocol = 6;
+        }
+    }
+
     for (list = g_list_first(proxy_list); list; list = g_list_next(list)) {
         struct pacrunner_proxy *proxy = list->data;

-        if (proxy->method == PACRUNNER_PROXY_METHOD_MANUAL ||
-                proxy->method == PACRUNNER_PROXY_METHOD_AUTO) {
-            selected_proxy = proxy;
-            break;
-        } else if (proxy->method == PACRUNNER_PROXY_METHOD_DIRECT)
-            selected_proxy = proxy;
+        if (!proxy->domains) {
+            if (!default_proxy)
+                default_proxy = proxy;
+            continue;
+        }
+
+        for (l = g_list_first(proxy->domains); l; l = g_list_next(l)) {
+            struct proxy_domain *data = l->data;
+
+            if (data->proto != protocol)
+                continue;
+
+            switch (protocol) {
+            case 4:
+                if (compare_legacy_ip_in_net(&ip4_addr,
+                                data) == 0) {
+                    selected_proxy = proxy;
+                    goto found;
+                }
+                break;
+            case 6:
+                if (compare_ipv6_in_net(&ip6_addr,
+                            data) == 0) {
+                    selected_proxy = proxy;
+                    goto found;
+                }
+                break;
+            default:
+                if (compare_host_in_domain(host, data) == 0) {
+                    selected_proxy = proxy;
+                    goto found;
+                }
+                break;
+            }
+        }
     }

+    if (!selected_proxy)
+        selected_proxy = default_proxy;
+
+found:
     pthread_mutex_unlock(&proxy_mutex);

     if (!selected_proxy)
-- 
2.5.5


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

Message: 2
Date: Wed, 15 Jun 2016 14:25:42 +0300
From: Vasiliy Tolstov <[email protected]>
To: Patrik Flykt <[email protected]>
Cc: connman <[email protected]>, Daniel Wagner <[email protected]>
Subject: Re: connman-vpnd does not reconnect after resume
Message-ID:
        <cacaajqsmgbwzqf2qt8ftfz7ehgibb_xut+nexha3dfnujzt...@mail.gmail.com>
Content-Type: text/plain; charset=UTF-8

2016-06-10 12:07 GMT+03:00 Patrik Flykt <[email protected]>:
> Due to unknown reasons this can happen, and I have seen it sometimes in
> the past with openconnect. Does a reconnect solve your problem in all
> cases? If yes, there is something going on between the VPN daemon and
> connman-vpnd that doesn't properly work or convey the state(s) the VPN
> daemon is in. Which needs more investigation, of course.


Does i need to provide more info to fix this issue?

-- 
Vasiliy Tolstov,
e-mail: [email protected]


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

Subject: Digest Footer

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


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

End of connman Digest, Vol 8, Issue 19
**************************************

Reply via email to