From 2e3c3bdc181a410e7604f98755ea4b447bf58a8e Mon Sep 17 00:00:00 2001 From: Kevin Darbyshire-Bryant Date: Wed, 23 Oct 2013 09:55:56 +0100 Subject: [PATCH] Dnsmasq 2.67rc4 + Simon's tweaks up & incl 21 Oct 2013 20:47 Also includes fix in tomato helper for non dhcpv6 compiles (thanks Shibby) Also includes an accept 'Wide Prefix' patch from Vlad http://wl500g.googlecode.com/svn/trunk/dnsmasq/020-relax-prefix.patch This allows constructed ranges to have forced larger prefixes on a smaller prefix interface - eg allow /64 on an interface that is a /48 - This patch is probably the holy grail we've been looking for and both Vlad & myself are hoping Simon accepts it. Conflicts: release/src/router/dnsmasq/VERSION release/src/router/dnsmasq/src/lease.c --- release/src/router/dnsmasq/VERSION | 2 +- release/src/router/dnsmasq/src/auth.c | 91 +++++++++++++++++----------- release/src/router/dnsmasq/src/cache.c | 3 + release/src/router/dnsmasq/src/config.h | 1 - release/src/router/dnsmasq/src/dhcp-common.c | 5 +- release/src/router/dnsmasq/src/dhcp6.c | 7 ++- release/src/router/dnsmasq/src/dnsmasq.h | 6 +- release/src/router/dnsmasq/src/forward.c | 47 +++++++++++--- release/src/router/dnsmasq/src/lease.c | 4 +- release/src/router/dnsmasq/src/radv.c | 26 ++++---- release/src/router/dnsmasq/src/rfc1035.c | 44 ++++++++------ 11 files changed, 152 insertions(+), 84 deletions(-) diff --git a/release/src/router/dnsmasq/VERSION b/release/src/router/dnsmasq/VERSION index 2f7088ef45..6660871687 100644 --- a/release/src/router/dnsmasq/VERSION +++ b/release/src/router/dnsmasq/VERSION @@ -1 +1 @@ -2.67rc4 \ No newline at end of file +v2.67rc4+21Oct13+WP diff --git a/release/src/router/dnsmasq/src/auth.c b/release/src/router/dnsmasq/src/auth.c index af2171cd4c..4a1075bf6b 100644 --- a/release/src/router/dnsmasq/src/auth.c +++ b/release/src/router/dnsmasq/src/auth.c @@ -62,7 +62,7 @@ static int filter_constructed_dhcp(struct auth_zone *zone, int flag, struct all_ return filter_zone(zone, flag, addr_u) != NULL; } -static int in_zone(struct auth_zone *zone, char *name, char **cut) +int in_zone(struct auth_zone *zone, char *name, char **cut) { size_t namelen = strlen(name); size_t domainlen = strlen(zone->domain); @@ -89,7 +89,7 @@ static int in_zone(struct auth_zone *zone, char *name, char **cut) } -size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t now, union mysockaddr *peer_addr) +size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t now, union mysockaddr *peer_addr, int local_query) { char *name = daemon->namebuff; unsigned char *p, *ansp; @@ -97,7 +97,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n int nameoffset, axfroffset = 0; int q, anscount = 0, authcount = 0; struct crec *crecp; - int auth = 1, trunc = 0, nxdomain = 1, soa = 0, ns = 0, axfr = 0; + int auth = !local_query, trunc = 0, nxdomain = 1, soa = 0, ns = 0, axfr = 0; struct auth_zone *zone = NULL; struct subnet *subnet = NULL; char *cut; @@ -110,7 +110,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY ) return 0; - + /* determine end of question section (we put answers there) */ if (!(ansp = skip_questions(header, qlen))) return 0; /* bad packet */ @@ -144,16 +144,19 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n if (!(flag = in_arpa_name_2_addr(name, &addr))) continue; - for (zone = daemon->auth_zones; zone; zone = zone->next) - if ((subnet = filter_zone(zone, flag, &addr))) - break; - - if (!zone) + if (!local_query) { - auth = 0; - continue; + for (zone = daemon->auth_zones; zone; zone = zone->next) + if ((subnet = filter_zone(zone, flag, &addr))) + break; + + if (!zone) + { + auth = 0; + continue; + } } - + intr = NULL; if (flag == F_IPV4) @@ -194,7 +197,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n if (in_zone(zone, intr->name, NULL)) { found = 1; - log_query(flag| F_REVERSE | F_CONFIG, intr->name, &addr, NULL); + log_query(flag | F_REVERSE | F_CONFIG, intr->name, &addr, NULL); if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, T_PTR, C_IN, "d", intr->name)) @@ -358,25 +361,26 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n if (hostname_isequal(name, intr->name)) { struct addrlist *addrlist; - + addrlist = intr->addr4; #ifdef HAVE_IPV6 if (qtype == T_AAAA) addrlist = intr->addr6; #endif nxdomain = 0; - - for (; addrlist; addrlist = addrlist->next) - if (filter_constructed_dhcp(zone, flag, &addrlist->addr)) - { - found = 1; - log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL); - if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, - daemon->auth_ttl, NULL, qtype, C_IN, - qtype == T_A ? "4" : "6", &addrlist->addr)) - anscount++; - } - } + + if (flag) + for (; addrlist; addrlist = addrlist->next) + if (local_query || filter_constructed_dhcp(zone, flag, &addrlist->addr)) + { + found = 1; + log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL); + if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, + daemon->auth_ttl, NULL, qtype, C_IN, + qtype == T_A ? "4" : "6", &addrlist->addr)) + anscount++; + } + } for (a = daemon->cnames; a; a = a->next) if (hostname_isequal(name, a->alias) ) @@ -390,7 +394,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n } found = 1; if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, - daemon->auth_ttl, NULL, + daemon->auth_ttl, &nameoffset, T_CNAME, C_IN, "d", name)) anscount++; @@ -403,7 +407,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n if (qtype == T_SOA) { - soa = 1; /* inhibits auth section */ + auth = soa = 1; /* inhibits auth section */ found = 1; log_query(F_RRNAME | F_AUTH, zone->domain, NULL, ""); } @@ -436,6 +440,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n return 0; } + auth = 1; soa = 1; /* inhibits auth section */ ns = 1; /* ensure we include NS records! */ axfr = 1; @@ -445,6 +450,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n } else if (qtype == T_NS) { + auth = 1; ns = 1; /* inhibits auth section */ found = 1; log_query(F_RRNAME | F_AUTH, zone->domain, NULL, ""); @@ -462,7 +468,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n { nxdomain = 0; if ((crecp->flags & flag) && - (filter_constructed_dhcp(zone, flag, &(crecp->addr.addr)))) + (local_query || filter_constructed_dhcp(zone, flag, &(crecp->addr.addr)))) { *cut = '.'; /* restore domain part */ log_query(crecp->flags, name, &crecp->addr.addr, record_source(crecp->uid)); @@ -485,7 +491,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n do { nxdomain = 0; - if ((crecp->flags & flag) && filter_constructed_dhcp(zone, flag, &(crecp->addr.addr))) + if ((crecp->flags & flag) && (local_query || filter_constructed_dhcp(zone, flag, &(crecp->addr.addr)))) { log_query(crecp->flags, name, &crecp->addr.addr, record_source(crecp->uid)); found = 1; @@ -675,14 +681,14 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n *cut = 0; for (addrlist = intr->addr4; addrlist; addrlist = addrlist->next) - if (filter_constructed_dhcp(zone, F_IPV4, &addrlist->addr) && + if ((local_query || filter_constructed_dhcp(zone, F_IPV4, &addrlist->addr)) && add_resource_record(header, limit, &trunc, -axfroffset, &ansp, daemon->auth_ttl, NULL, T_A, C_IN, "4", cut ? intr->name : NULL, &addrlist->addr)) anscount++; #ifdef HAVE_IPV6 for (addrlist = intr->addr6; addrlist; addrlist = addrlist->next) - if (filter_constructed_dhcp(zone, F_IPV6, &addrlist->addr) && + if ((local_query || filter_constructed_dhcp(zone, F_IPV6, &addrlist->addr)) && add_resource_record(header, limit, &trunc, -axfroffset, &ansp, daemon->auth_ttl, NULL, T_AAAA, C_IN, "6", cut ? intr->name : NULL, &addrlist->addr)) anscount++; @@ -722,7 +728,8 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n if ((crecp->flags & F_DHCP) && !option_bool(OPT_DHCP_FQDN)) { char *cache_name = cache_get_name(crecp); - if (!strchr(cache_name, '.') && filter_constructed_dhcp(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr.addr))) + if (!strchr(cache_name, '.') && + (local_query || filter_constructed_dhcp(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr.addr)))) { qtype = T_A; #ifdef HAVE_IPV6 @@ -739,7 +746,8 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n if ((crecp->flags & F_HOSTS) || (((crecp->flags & F_DHCP) && option_bool(OPT_DHCP_FQDN)))) { strcpy(name, cache_get_name(crecp)); - if (in_zone(zone, name, &cut) && filter_constructed_dhcp(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr.addr))) + if (in_zone(zone, name, &cut) && + (local_query || filter_constructed_dhcp(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr.addr)))) { qtype = T_A; #ifdef HAVE_IPV6 @@ -774,8 +782,17 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n /* done all questions, set up header and return length of result */ /* clear authoritative and truncated flags, set QR flag */ header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR; - /* clear RA flag */ - header->hb4 &= ~HB4_RA; + + if (local_query) + { + /* set RA flag */ + header->hb4 |= HB4_RA; + } + else + { + /* clear RA flag */ + header->hb4 &= ~HB4_RA; + } /* authoritive */ if (auth) @@ -785,7 +802,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n if (trunc) header->hb3 |= HB3_TC; - if (anscount == 0 && auth && nxdomain) + if ((auth || local_query) && nxdomain) SET_RCODE(header, NXDOMAIN); else SET_RCODE(header, NOERROR); /* no error */ diff --git a/release/src/router/dnsmasq/src/cache.c b/release/src/router/dnsmasq/src/cache.c index 6247cab7fc..d99aba6401 100644 --- a/release/src/router/dnsmasq/src/cache.c +++ b/release/src/router/dnsmasq/src/cache.c @@ -1161,6 +1161,9 @@ void dump_cache(time_t now) daemon->cachesize, cache_live_freed, cache_inserted); my_syslog(LOG_INFO, _("queries forwarded %u, queries answered locally %u"), daemon->queries_forwarded, daemon->local_answer); +#ifdef HAVE_AUTH + my_syslog(LOG_INFO, _("queries for authoritative zones %u"), daemon->auth_answer); +#endif /* sum counts from different records for same server */ for (serv = daemon->servers; serv; serv = serv->next) diff --git a/release/src/router/dnsmasq/src/config.h b/release/src/router/dnsmasq/src/config.h index ba5897a5a4..0e5a0cd011 100644 --- a/release/src/router/dnsmasq/src/config.h +++ b/release/src/router/dnsmasq/src/config.h @@ -45,7 +45,6 @@ #define SOA_REFRESH 1200 /* SOA refresh default */ #define SOA_RETRY 180 /* SOA retry default */ #define SOA_EXPIRY 1209600 /* SOA expiry default */ -#define RA_INTERVAL 600 /* Send unsolicited RA's this often when not provoked. */ /* compile-time options: uncomment below to enable or do eg. make COPTS=-DHAVE_BROKEN_RTC diff --git a/release/src/router/dnsmasq/src/dhcp-common.c b/release/src/router/dnsmasq/src/dhcp-common.c index 028178a905..a92d728e44 100644 --- a/release/src/router/dnsmasq/src/dhcp-common.c +++ b/release/src/router/dnsmasq/src/dhcp-common.c @@ -315,8 +315,9 @@ struct dhcp_config *find_config(struct dhcp_config *configs, return config; /* dhcpcd prefixes ASCII client IDs by zero which is wrong, but we try and - cope with that here */ - if (!(context->flags & CONTEXT_V6) && *clid == 0 && config->clid_len == clid_len-1 && + cope with that here. This is IPv4 only. context==NULL implies IPv4, + see lease_update_from_configs() */ + if ((!context || !(context->flags & CONTEXT_V6)) && *clid == 0 && config->clid_len == clid_len-1 && memcmp(config->clid, clid+1, clid_len-1) == 0 && is_config_in_context(context, config)) return config; diff --git a/release/src/router/dnsmasq/src/dhcp6.c b/release/src/router/dnsmasq/src/dhcp6.c index 1a7aa48fb8..7b79ee0988 100644 --- a/release/src/router/dnsmasq/src/dhcp6.c +++ b/release/src/router/dnsmasq/src/dhcp6.c @@ -330,7 +330,7 @@ static int complete_context6(struct in6_addr *local, int prefix, { if ((context->flags & CONTEXT_DHCP) && !(context->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) && - prefix == context->prefix && + prefix <= context->prefix && //KDB is_same_net6(local, &context->start6, prefix) && is_same_net6(local, &context->end6, prefix)) { @@ -615,7 +615,7 @@ static int construct_worker(struct in6_addr *local, int prefix, if (!(template->flags & CONTEXT_TEMPLATE)) { /* non-template entries, just fill in interface and local addresses */ - if (prefix == template->prefix && + if (prefix <= template->prefix && //KDB is_same_net6(local, &template->start6, prefix) && is_same_net6(local, &template->end6, prefix)) { @@ -624,7 +624,8 @@ static int construct_worker(struct in6_addr *local, int prefix, } } - else if (wildcard_match(template->template_interface, ifrn_name)) + else if (wildcard_match(template->template_interface, ifrn_name) && + template->prefix >= prefix) //KDB { start6 = *local; setaddr6part(&start6, addr6part(&template->start6)); diff --git a/release/src/router/dnsmasq/src/dnsmasq.h b/release/src/router/dnsmasq/src/dnsmasq.h index 530fe4fd04..d0e0cf2561 100644 --- a/release/src/router/dnsmasq/src/dnsmasq.h +++ b/release/src/router/dnsmasq/src/dnsmasq.h @@ -876,7 +876,7 @@ extern struct daemon { char *packet; /* packet buffer */ int packet_buff_sz; /* size of above */ char *namebuff; /* MAXDNAME size buffer */ - unsigned int local_answer, queries_forwarded; + unsigned int local_answer, queries_forwarded, auth_answer; struct frec *frec_list; struct serverfd *sfds; struct irec *interfaces; @@ -992,7 +992,9 @@ int private_net(struct in_addr addr, int ban_localhost); /* auth.c */ #ifdef HAVE_AUTH -size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t now, union mysockaddr *peer_addr); +size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, + time_t now, union mysockaddr *peer_addr, int local_query); +int in_zone(struct auth_zone *zone, char *name, char **cut); #endif /* util.c */ diff --git a/release/src/router/dnsmasq/src/forward.c b/release/src/router/dnsmasq/src/forward.c index adc4a0fc7d..7ed88801b4 100644 --- a/release/src/router/dnsmasq/src/forward.c +++ b/release/src/router/dnsmasq/src/forward.c @@ -676,7 +676,7 @@ void receive_query(struct listener *listen, time_t now) size_t m; ssize_t n; int if_index = 0; - int auth_dns = 0; + int local_auth = 0, auth_dns = 0; struct iovec iov[1]; struct msghdr msg; struct cmsghdr *cmptr; @@ -848,6 +848,9 @@ void receive_query(struct listener *listen, time_t now) if (extract_request(header, (size_t)n, daemon->namebuff, &type)) { char types[20]; +#ifdef HAVE_AUTH + struct auth_zone *zone; +#endif querystr(auth_dns ? "auth" : "query", types, type); @@ -859,15 +862,30 @@ void receive_query(struct listener *listen, time_t now) log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff, (struct all_addr *)&source_addr.in6.sin6_addr, types); #endif - } #ifdef HAVE_AUTH + /* find queries for zones we're authoritative for, and answer them directly */ + if (!auth_dns) + for (zone = daemon->auth_zones; zone; zone = zone->next) + if (in_zone(zone, daemon->namebuff, NULL)) + { + auth_dns = 1; + local_auth = 1; + break; + } +#endif + } + +#ifdef HAVE_AUTH if (auth_dns) { - m = answer_auth(header, ((char *) header) + PACKETSZ, (size_t)n, now, &source_addr); + m = answer_auth(header, ((char *) header) + PACKETSZ, (size_t)n, now, &source_addr, local_auth); if (m >= 1) - send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND), - (char *)header, m, &source_addr, &dst_addr, if_index); + { + send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND), + (char *)header, m, &source_addr, &dst_addr, if_index); + daemon->auth_answer++; + } } else #endif @@ -898,6 +916,7 @@ unsigned char *tcp_request(int confd, time_t now, { size_t size = 0; int norebind = 0; + int local_auth = 0; int checking_disabled, check_subnet; size_t m; unsigned short qtype; @@ -939,7 +958,9 @@ unsigned char *tcp_request(int confd, time_t now, if ((gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype))) { char types[20]; - +#ifdef HAVE_AUTH + struct auth_zone *zone; +#endif querystr(auth_dns ? "auth" : "query", types, qtype); if (peer_addr.sa.sa_family == AF_INET) @@ -950,6 +971,18 @@ unsigned char *tcp_request(int confd, time_t now, log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff, (struct all_addr *)&peer_addr.in6.sin6_addr, types); #endif + +#ifdef HAVE_AUTH + /* find queries for zones we're authoritative for, and answer them directly */ + if (!auth_dns) + for (zone = daemon->auth_zones; zone; zone = zone->next) + if (in_zone(zone, daemon->namebuff, NULL)) + { + auth_dns = 1; + local_auth = 1; + break; + } +#endif } if (local_addr->sa.sa_family == AF_INET) @@ -959,7 +992,7 @@ unsigned char *tcp_request(int confd, time_t now, #ifdef HAVE_AUTH if (auth_dns) - m = answer_auth(header, ((char *) header) + 65536, (size_t)size, now, &peer_addr); + m = answer_auth(header, ((char *) header) + 65536, (size_t)size, now, &peer_addr, local_auth); else #endif { diff --git a/release/src/router/dnsmasq/src/lease.c b/release/src/router/dnsmasq/src/lease.c index f719b8cde9..2975c8ed98 100644 --- a/release/src/router/dnsmasq/src/lease.c +++ b/release/src/router/dnsmasq/src/lease.c @@ -1160,11 +1160,11 @@ void tomato_helper(time_t now) if ((f = fopen("/var/tmp/dhcp/leases.!", "w")) != NULL) { for (lease = leases; lease; lease = lease->next) { if (lease->hwaddr_type == ARPHRD_ETHER) { -#ifdef HAVE_DHCP6 +#ifdef HAVE_DHCPV6 //only dump dhcpv6 if we have it if (lease->flags & (LEASE_TA | LEASE_NA)) inet_ntop(AF_INET6, &lease->addr6, buf, ADDRSTRLEN); else -#endif +#endif // Thanks to Shibby :-) inet_ntop(AF_INET, &lease->addr, buf, ADDRSTRLEN); fprintf(f, "%lu %02X:%02X:%02X:%02X:%02X:%02X %s %s\n", diff --git a/release/src/router/dnsmasq/src/radv.c b/release/src/router/dnsmasq/src/radv.c index 8e0a730746..c1b31b68d1 100644 --- a/release/src/router/dnsmasq/src/radv.c +++ b/release/src/router/dnsmasq/src/radv.c @@ -336,15 +336,15 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de if (opt_cfg->opt == OPTION6_DNS_SERVER) { struct in6_addr *a = (struct in6_addr *)opt_cfg->val; - + done_dns = 1; - if (opt_cfg->len == 0) - continue; + if (opt_cfg->len == 0 || (IN6_IS_ADDR_UNSPECIFIED(a) && parm.pref_time != 0)) + continue; put_opt6_char(ICMP6_OPT_RDNSS); put_opt6_char((opt_cfg->len/8) + 1); put_opt6_short(0); - put_opt6_long(parm.adv_interval * 2); /* lifetime - twice RA retransmit */ + put_opt6_long(parm.pref_time); /* zero means "self" */ for (i = 0; i < opt_cfg->len; i += IN6ADDRSZ, a++) if (IN6_IS_ADDR_UNSPECIFIED(a)) @@ -360,7 +360,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de put_opt6_char(ICMP6_OPT_DNSSL); put_opt6_char(len + 1); put_opt6_short(0); - put_opt6_long(parm.adv_interval * 2); /* lifetime - twice RA retransmit */ + put_opt6_long(parm.pref_time); put_opt6(opt_cfg->val, opt_cfg->len); /* pad */ @@ -369,14 +369,14 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de } } - if (daemon->port == NAMESERVER_PORT && !done_dns) + if (daemon->port == NAMESERVER_PORT && !done_dns && parm.pref_time != 0) { /* default == us, as long as we are supplying DNS service. */ put_opt6_char(ICMP6_OPT_RDNSS); put_opt6_char(3); put_opt6_short(0); - put_opt6_long(parm.adv_interval * 2); /* lifetime - twice RA retransmit */ - put_opt6(&parm.link_global, IN6ADDRSZ); + put_opt6_long(parm.pref_time); + put_opt6(&parm.link_local, IN6ADDRSZ); } /* set managed bits unless we're providing only RA on this link */ @@ -434,7 +434,7 @@ static int add_prefixes(struct in6_addr *local, int prefix, for (context = daemon->dhcp6; context; context = context->next) if (!(context->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) && - prefix == context->prefix && + prefix <= context->prefix && //KDB is_same_net6(local, &context->start6, prefix) && is_same_net6(local, &context->end6, prefix)) { @@ -491,7 +491,7 @@ static int add_prefixes(struct in6_addr *local, int prefix, if (!param->first) context->ra_time = 0; context->flags |= CONTEXT_RA_DONE; - do_prefix = 1; + do_prefix = context->prefix; //KDB } param->first = 0; @@ -524,6 +524,8 @@ static int add_prefixes(struct in6_addr *local, int prefix, if ((opt = expand(sizeof(struct prefix_opt)))) { + prefix = do_prefix; //KDB + /* zero net part of address */ setaddr6part(local, addr6part(local) & ~((prefix == 64) ? (u64)-1LL : (1LLU << (128 - prefix)) - 1LLU)); @@ -640,7 +642,7 @@ static int iface_search(struct in6_addr *local, int prefix, for (context = daemon->dhcp6; context; context = context->next) if (!(context->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) && - prefix == context->prefix && + prefix <= context->prefix && //KDB is_same_net6(local, &context->start6, prefix) && is_same_net6(local, &context->end6, prefix) && context->ra_time != 0 && @@ -665,7 +667,7 @@ static int iface_search(struct in6_addr *local, int prefix, /* zero timers for other contexts on the same subnet, so they don't timeout independently */ for (context = context->next; context; context = context->next) - if (prefix == context->prefix && + if (prefix <= context->prefix && //KDB is_same_net6(local, &context->start6, prefix) && is_same_net6(local, &context->end6, prefix)) context->ra_time = 0; diff --git a/release/src/router/dnsmasq/src/rfc1035.c b/release/src/router/dnsmasq/src/rfc1035.c index ef4a86fed4..fc6d09ca7c 100644 --- a/release/src/router/dnsmasq/src/rfc1035.c +++ b/release/src/router/dnsmasq/src/rfc1035.c @@ -1725,29 +1725,39 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen, if (intr) { struct addrlist *addrlist; + int gotit = 0; enumerate_interfaces(0); - addrlist = intr->addr4; + for (intr = daemon->int_names; intr; intr = intr->next) + if (hostname_isequal(name, intr->name)) + { + addrlist = intr->addr4; #ifdef HAVE_IPV6 - if (type == T_AAAA) - addrlist = intr->addr6; + if (type == T_AAAA) + addrlist = intr->addr6; #endif - ans = 1; - if (!dryrun) - { - if (!addrlist) - log_query(F_FORWARD | F_CONFIG | flag | F_NEG, name, NULL, NULL); - else - for (; addrlist; addrlist = addrlist->next) + ans = 1; + if (!dryrun) { - log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL); - if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, - daemon->local_ttl, NULL, type, C_IN, - type == T_A ? "4" : "6", &addrlist->addr)) - anscount++; + if (addrlist) + { + gotit = 1; + for (; addrlist; addrlist = addrlist->next) + { + log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL); + if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, + daemon->local_ttl, NULL, type, C_IN, + type == T_A ? "4" : "6", &addrlist->addr)) + anscount++; + } + } } - } + } + + if (!dryrun && !gotit) + log_query(F_FORWARD | F_CONFIG | flag | F_NEG, name, NULL, NULL); + continue; } @@ -1776,7 +1786,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen, { /* don't answer wildcard queries with data not from /etc/hosts or DHCP leases */ - if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP))) + if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))) break; if (crecp->flags & F_CNAME) -- 2.11.4.GIT