summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2010-07-12 18:45:59 +0200
committerSamuel Ortiz <sameo@linux.intel.com>2010-07-12 20:44:27 +0200
commit57cecbcc89e3df31600b6a769be6255c5916529f (patch)
treec39e767ca0599e1b05b87a001478beda58e6d2eb
parent5c00b517f7dfcd8edef4819580fa21c38d19c2bc (diff)
downloadconnman-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.h1
-rw-r--r--src/inet.c47
-rw-r--r--src/service.c17
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
}
diff --git a/src/inet.c b/src/inet.c
index cfb7f92f..094c7880 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -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);
}
}