No host route needed for nameservers on the same subnet
authorSamuel Ortiz <sameo@linux.intel.com>
Mon, 12 Jul 2010 16:45:59 +0000 (18:45 +0200)
committerSamuel Ortiz <sameo@linux.intel.com>
Mon, 12 Jul 2010 18:44:27 +0000 (20:44 +0200)
include/inet.h
src/inet.c
src/service.c

index 207410a..389a584 100644 (file)
@@ -50,6 +50,7 @@ int connman_inet_set_gateway_address(int index, const char *gateway);
 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);
+connman_bool_t connman_inet_compare_subnet(int index, const char *host);
 
 #ifdef __cplusplus
 }
index cfb7f92..094c788 100644 (file)
@@ -898,3 +898,50 @@ int connman_inet_clear_gateway_interface(int index)
 
        return err;
 }
+
+connman_bool_t connman_inet_compare_subnet(int index, const char *host)
+{
+       struct ifreq ifr;
+       struct in_addr _host_addr;
+       in_addr_t host_addr, netmask_addr, if_addr;
+       struct sockaddr_in *netmask, *addr;
+       int sk;
+
+       DBG("host %s", host);
+
+       if (host == NULL)
+               return FALSE;
+
+       if (inet_aton(host, &_host_addr) == 0)
+               return -1;
+       host_addr = _host_addr.s_addr;
+
+       sk = socket(PF_INET, SOCK_DGRAM, 0);
+       if (sk < 0)
+               return FALSE;
+
+       memset(&ifr, 0, sizeof(ifr));
+       ifr.ifr_ifindex = index;
+
+       if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
+               close(sk);
+               return FALSE;
+       }
+
+       if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0) {
+               close(sk);
+               return FALSE;
+       }
+
+       netmask = (struct sockaddr_in *)&ifr.ifr_netmask;
+       netmask_addr = netmask->sin_addr.s_addr;
+
+       if (ioctl(sk, SIOCGIFADDR, &ifr) < 0) {
+               close(sk);
+               return FALSE;
+       }
+       addr = (struct sockaddr_in *)&ifr.ifr_addr;
+       if_addr = addr->sin_addr.s_addr;
+
+       return ((if_addr & netmask_addr) == (host_addr & netmask_addr));
+}
index 93eaa5a..057b2da 100644 (file)
@@ -384,10 +384,25 @@ void __connman_service_nameserver_add_routes(struct connman_service *service,
        if (service->nameservers != NULL) {
                int i;
 
-               for (i = 0; service->nameservers[i]; i++)
+               /*
+                * We add nameservers host routes for nameservers that
+                * are not on our subnet. For those who are, the subnet
+                * route will be installed by the time the dns proxy code
+                * tries to reach them. The subnet route is installed
+                * when setting the interface IP address.
+                */
+               for (i = 0; service->nameservers[i]; i++) {
+                       if (connman_inet_compare_subnet(index,
+                                                       service->nameservers[i]))
+                               continue;
+
                        connman_inet_add_host_route(index,
                                                service->nameservers[i], gw);
+               }
        } else if (service->nameserver != NULL) {
+               if (connman_inet_compare_subnet(index, service->nameserver))
+                       return;
+
                connman_inet_add_host_route(index, service->nameserver, gw);
        }
 }