Rather than registering the new nameserver as we hit the RDNSS option, gather
all the information first and then register the nameservers after the loop.
That way, we can gather the search domains while we're looping, and provide
them when we register the nameservers.
---
 src/rtnl.c |   43 ++++++++++++++++++++++++++++---------------
 1 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/src/rtnl.c b/src/rtnl.c
index b10d835..b56a80d 100644
--- a/src/rtnl.c
+++ b/src/rtnl.c
@@ -1024,32 +1024,33 @@ static void rtnl_delroute(struct nlmsghdr *hdr)
                                                msg, RTM_PAYLOAD(hdr));
 }
 
-static void rtnl_nd_opt_rdnss(char *interface, struct nd_opt_hdr *opt)
+static void *rtnl_nd_opt_rdnss(struct nd_opt_hdr *opt, guint32 *lifetime,
+                              int *nr_servers)
 {
        guint32 *optint = (void *)opt;
-       guint32 lifetime;
-       char buf[80];
-       int i;
 
        if (opt->nd_opt_len < 3)
-               return;
+               return NULL;
 
-       lifetime = ntohl(optint[1]);
-       if (!lifetime)
-               return;
+       if (*lifetime > ntohl(optint[1]))
+               *lifetime = ntohl(optint[1]);
 
-       optint += 2;
-       for (i = 0; i < opt->nd_opt_len / 2; i++, optint += 4) {
-               if (inet_ntop(AF_INET6, optint, buf, sizeof(buf)))
-                       connman_resolver_append_lifetime(interface, NULL,
-                                                        buf, lifetime);
-       }
+       /* nd_opt_len is in units of 8 bytes. The header is 1 unit (8 bytes)
+          and each address is another 2 units (16 bytes).
+          So the number of addresses (given rounding) is nd_opt_len/2 */
+       *nr_servers = opt->nd_opt_len / 2;
+
+       /* And they start 8 bytes into the packet, or two guint32s in. */
+       return optint + 2;
 }
 
 static void rtnl_newnduseropt(struct nlmsghdr *hdr)
 {
        struct nduseroptmsg *msg = (struct nduseroptmsg *) NLMSG_DATA(hdr);
        struct nd_opt_hdr *opt = (void *)&msg[1];
+       guint32 lifetime = -1;
+       struct in6_addr *servers;
+       int nr_servers = 0;
        int msglen = msg->nduseropt_opts_len;
        char *interface;
 
@@ -1076,7 +1077,19 @@ static void rtnl_newnduseropt(struct nlmsghdr *hdr)
                    opt->nd_opt_type, opt->nd_opt_len);
 
                if (opt->nd_opt_type == 25)
-                       rtnl_nd_opt_rdnss(interface, opt);
+                       servers = rtnl_nd_opt_rdnss(opt, &lifetime,
+                                                   &nr_servers);
+       }
+
+       if (nr_servers) {
+               int i;
+               char buf[40];
+
+               for (i = 0; i < nr_servers; i++) {
+                       if (inet_ntop(AF_INET6, servers + i, buf, sizeof(buf)))
+                               connman_resolver_append_lifetime(interface,
+                                                       NULL, buf, lifetime);
+               }
        }
        g_free(interface);
 }
-- 
1.7.3.3



_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman

Reply via email to