diff options
author | Samuel Ortiz <sameo@linux.intel.com> | 2010-07-12 18:45:59 +0200 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2010-07-12 20:44:27 +0200 |
commit | 57cecbcc89e3df31600b6a769be6255c5916529f (patch) | |
tree | c39e767ca0599e1b05b87a001478beda58e6d2eb | |
parent | 5c00b517f7dfcd8edef4819580fa21c38d19c2bc (diff) | |
download | connman-57cecbcc89e3df31600b6a769be6255c5916529f.tar.gz connman-57cecbcc89e3df31600b6a769be6255c5916529f.tar.bz2 connman-57cecbcc89e3df31600b6a769be6255c5916529f.zip |
No host route needed for nameservers on the same subnet
-rw-r--r-- | include/inet.h | 1 | ||||
-rw-r--r-- | src/inet.c | 47 | ||||
-rw-r--r-- | src/service.c | 17 |
3 files changed, 64 insertions, 1 deletions
diff --git a/include/inet.h b/include/inet.h index 207410ae..389a584c 100644 --- a/include/inet.h +++ b/include/inet.h @@ -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 } @@ -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)); +} diff --git a/src/service.c b/src/service.c index 93eaa5a1..057b2da3 100644 --- a/src/service.c +++ b/src/service.c @@ -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); } } |