diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2016-05-11 18:43:41 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2016-05-13 11:47:58 +0200 |
commit | 8da51a55106176e91d6e4a3c727a825b4c094bc6 (patch) | |
tree | 49a4ce28d6c5ad2572b866202b6b9c2281929fe0 | |
parent | 5620619b6a2784574457b23d65c6eab4c9d76f39 (diff) | |
download | NetworkManager-bg/dnsmasq-interfaces-bgo765153.tar.gz |
dns: specify egress interface for each dnsmasq upstream serverbg/dnsmasq-interfaces-bgo765153
Currently we don't specify to dnsmasq which interface must be used to
contact a given nameserver and so requests can be sent through the
wrong interface.
Fix this by concatenating a @interface prefix to each server (unless
an IPv6 interface scope-id is already present).
https://bugzilla.gnome.org/show_bug.cgi?id=765153
-rw-r--r-- | src/dns-manager/nm-dns-dnsmasq.c | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/src/dns-manager/nm-dns-dnsmasq.c b/src/dns-manager/nm-dns-dnsmasq.c index 203441100a..5cafb27cf4 100644 --- a/src/dns-manager/nm-dns-dnsmasq.c +++ b/src/dns-manager/nm-dns-dnsmasq.c @@ -26,6 +26,7 @@ #include <sys/wait.h> #include <arpa/inet.h> #include <sys/stat.h> +#include <linux/if.h> #include "nm-dns-dnsmasq.h" #include "nm-utils.h" @@ -89,13 +90,16 @@ add_dnsmasq_nameserver (NMDnsDnsmasq *self, } static gboolean -add_ip4_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP4Config *ip4, gboolean split) +add_ip4_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP4Config *ip4, + const char *iface, gboolean split) { - char buf[INET_ADDRSTRLEN]; + char buf[INET_ADDRSTRLEN + 1 + IFNAMSIZ]; + char buf2[INET_ADDRSTRLEN]; in_addr_t addr; int nnameservers, i_nameserver, n, i; gboolean added = FALSE; + g_return_val_if_fail (iface, FALSE); nnameservers = nm_ip4_config_get_num_nameservers (ip4); if (split) { @@ -106,7 +110,8 @@ add_ip4_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP4Config *ip4, for (i_nameserver = 0; i_nameserver < nnameservers; i_nameserver++) { addr = nm_ip4_config_get_nameserver (ip4, i_nameserver); - nm_utils_inet4_ntop (addr, buf); + g_snprintf (buf, sizeof (buf), "%s@%s", + nm_utils_inet4_ntop (addr, buf2), iface); /* searches are preferred over domains */ n = nm_ip4_config_get_num_searches (ip4); @@ -147,8 +152,9 @@ add_ip4_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP4Config *ip4, if (!added) { for (i = 0; i < nnameservers; i++) { addr = nm_ip4_config_get_nameserver (ip4, i); - add_dnsmasq_nameserver (self, servers, - nm_utils_inet4_ntop (addr, NULL), NULL); + g_snprintf (buf, sizeof (buf), "%s@%s", + nm_utils_inet4_ntop (addr, buf2), iface); + add_dnsmasq_nameserver (self, servers, buf, NULL); } } @@ -158,23 +164,22 @@ add_ip4_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP4Config *ip4, static char * ip6_addr_to_string (const struct in6_addr *addr, const char *iface) { - char *buf; + char buf[NM_UTILS_INET_ADDRSTRLEN]; - if (IN6_IS_ADDR_V4MAPPED (addr)) { - buf = g_malloc (INET_ADDRSTRLEN); + if (IN6_IS_ADDR_V4MAPPED (addr)) nm_utils_inet4_ntop (addr->s6_addr32[3], buf); - } else if (!IN6_IS_ADDR_LINKLOCAL (addr)) { - buf = g_malloc (INET6_ADDRSTRLEN); + else nm_utils_inet6_ntop (addr, buf); - } else { - /* Need to scope the address with %<zone-id>. Before dnsmasq 2.58, - * only '@' was supported as delimiter. Since 2.58, '@' and '%' - * are supported. Due to a bug, since 2.73 only '%' works properly - * as "server" address. - */ - buf = g_strconcat (nm_utils_inet6_ntop (addr, NULL), "%", iface, NULL); - } - return buf; + + /* Need to scope link-local addresses with %<zone-id>. Before dnsmasq 2.58, + * only '@' was supported as delimiter. Since 2.58, '@' and '%' are + * supported. Due to a bug, since 2.73 only '%' works properly as "server" + * address. + */ + return g_strdup_printf ("%s%c%s", + buf, + IN6_IS_ADDR_LINKLOCAL (addr) ? '%' : '@', + iface); } static void @@ -247,7 +252,7 @@ add_ip6_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP6Config *ip6, } } - /* If no searches or domains, just add the namservers */ + /* If no searches or domains, just add the nameservers */ if (!added) { for (i = 0; i < nnameservers; i++) { addr = nm_ip6_config_get_nameserver (ip6, i); @@ -269,6 +274,7 @@ add_ip_config_data (NMDnsDnsmasq *self, GVariantBuilder *servers, const NMDnsIPC return add_ip4_config (self, servers, (NMIP4Config *) data->config, + data->iface, data->type == NM_DNS_IP_CONFIG_TYPE_VPN); } else if (NM_IS_IP6_CONFIG (data->config)) { return add_ip6_config (self, |