"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/forward.c" between
dnsmasq-2.81.tar.xz and dnsmasq-2.82.tar.xz

About: Dnsmasq is a lightweight caching DNS forwarder and DHCP server.

forward.c  (dnsmasq-2.81.tar.xz):forward.c  (dnsmasq-2.82.tar.xz)
skipping to change at line 678 skipping to change at line 678
a.log.rcode = rcode; a.log.rcode = rcode;
log_query(F_UPSTREAM | F_RCODE, "error", &a, NULL); log_query(F_UPSTREAM | F_RCODE, "error", &a, NULL);
return resize_packet(header, n, pheader, plen); return resize_packet(header, n, pheader, plen);
} }
/* Complain loudly if the upstream server is non-recursive. */ /* Complain loudly if the upstream server is non-recursive. */
if (!(header->hb4 & HB4_RA) && rcode == NOERROR && if (!(header->hb4 & HB4_RA) && rcode == NOERROR &&
server && !(server->flags & SERV_WARNED_RECURSIVE)) server && !(server->flags & SERV_WARNED_RECURSIVE))
{ {
prettyprint_addr(&server->addr, daemon->namebuff); (void)prettyprint_addr(&server->addr, daemon->namebuff);
my_syslog(LOG_WARNING, _("nameserver %s refused to do a recursive query"), daemon->namebuff); my_syslog(LOG_WARNING, _("nameserver %s refused to do a recursive query"), daemon->namebuff);
if (!option_bool(OPT_LOG)) if (!option_bool(OPT_LOG))
server->flags |= SERV_WARNED_RECURSIVE; server->flags |= SERV_WARNED_RECURSIVE;
} }
if (daemon->bogus_addr && rcode != NXDOMAIN && if (daemon->bogus_addr && rcode != NXDOMAIN &&
check_for_bogus_wildcard(header, n, daemon->namebuff, daemon->bogus_addr, now)) check_for_bogus_wildcard(header, n, daemon->namebuff, daemon->bogus_addr, now))
{ {
munged = 1; munged = 1;
SET_RCODE(header, NXDOMAIN); SET_RCODE(header, NXDOMAIN);
skipping to change at line 961 skipping to change at line 961
} }
/* We tried resending to this server with a smaller maximum size and got an an swer. /* We tried resending to this server with a smaller maximum size and got an an swer.
Make that permanent. To avoid reduxing the packet size for a single dropped packet, Make that permanent. To avoid reduxing the packet size for a single dropped packet,
only do this when we get a truncated answer, or one larger than the safe si ze. */ only do this when we get a truncated answer, or one larger than the safe si ze. */
if (forward->sentto->edns_pktsz > SAFE_PKTSZ && (forward->flags & FREC_TEST_PK TSZ) && if (forward->sentto->edns_pktsz > SAFE_PKTSZ && (forward->flags & FREC_TEST_PK TSZ) &&
((header->hb3 & HB3_TC) || n >= SAFE_PKTSZ)) ((header->hb3 & HB3_TC) || n >= SAFE_PKTSZ))
{ {
forward->sentto->edns_pktsz = SAFE_PKTSZ; forward->sentto->edns_pktsz = SAFE_PKTSZ;
forward->sentto->pktsz_reduced = now; forward->sentto->pktsz_reduced = now;
prettyprint_addr(&forward->sentto->addr, daemon->addrbuff); (void)prettyprint_addr(&forward->sentto->addr, daemon->addrbuff);
my_syslog(LOG_WARNING, _("reducing DNS packet size for nameserver %s to %d "), daemon->addrbuff, SAFE_PKTSZ); my_syslog(LOG_WARNING, _("reducing DNS packet size for nameserver %s to %d "), daemon->addrbuff, SAFE_PKTSZ);
} }
/* If the answer is an error, keep the forward record in place in case /* If the answer is an error, keep the forward record in place in case
we get a good reply from another server. Kill it when we've we get a good reply from another server. Kill it when we've
had replies from all to avoid filling the forwarding table when had replies from all to avoid filling the forwarding table when
everything is broken */ everything is broken */
if (forward->forwardall == 0 || --forward->forwardall == 1 || RCODE(header) != REFUSED) if (forward->forwardall == 0 || --forward->forwardall == 1 || RCODE(header) != REFUSED)
{ {
int check_rebind = 0, no_cache_dnssec = 0, cache_secure = 0, bogusanswer = 0; int check_rebind = 0, no_cache_dnssec = 0, cache_secure = 0, bogusanswer = 0;
skipping to change at line 1282 skipping to change at line 1282
#if defined(HAVE_LINUX_NETWORK) #if defined(HAVE_LINUX_NETWORK)
char control[CMSG_SPACE(sizeof(struct in_pktinfo))]; char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
#elif defined(IP_RECVDSTADDR) && defined(HAVE_SOLARIS_NETWORK) #elif defined(IP_RECVDSTADDR) && defined(HAVE_SOLARIS_NETWORK)
char control[CMSG_SPACE(sizeof(struct in_addr)) + char control[CMSG_SPACE(sizeof(struct in_addr)) +
CMSG_SPACE(sizeof(unsigned int))]; CMSG_SPACE(sizeof(unsigned int))];
#elif defined(IP_RECVDSTADDR) #elif defined(IP_RECVDSTADDR)
char control[CMSG_SPACE(sizeof(struct in_addr)) + char control[CMSG_SPACE(sizeof(struct in_addr)) +
CMSG_SPACE(sizeof(struct sockaddr_dl))]; CMSG_SPACE(sizeof(struct sockaddr_dl))];
#endif #endif
} control_u; } control_u;
int family = listen->addr.sa.sa_family;
/* Can always get recvd interface for IPv6 */ /* Can always get recvd interface for IPv6 */
int check_dst = !option_bool(OPT_NOWILD) || listen->family == AF_INET6; int check_dst = !option_bool(OPT_NOWILD) || family == AF_INET6;
/* packet buffer overwritten */ /* packet buffer overwritten */
daemon->srv_save = NULL; daemon->srv_save = NULL;
dst_addr_4.s_addr = dst_addr.addr4.s_addr = 0; dst_addr_4.s_addr = dst_addr.addr4.s_addr = 0;
netmask.s_addr = 0; netmask.s_addr = 0;
if (option_bool(OPT_NOWILD) && listen->iface) if (option_bool(OPT_NOWILD) && listen->iface)
{ {
auth_dns = listen->iface->dns_auth; auth_dns = listen->iface->dns_auth;
if (listen->family == AF_INET) if (family == AF_INET)
{ {
dst_addr_4 = dst_addr.addr4 = listen->iface->addr.in.sin_addr; dst_addr_4 = dst_addr.addr4 = listen->iface->addr.in.sin_addr;
netmask = listen->iface->netmask; netmask = listen->iface->netmask;
} }
} }
iov[0].iov_base = daemon->packet; iov[0].iov_base = daemon->packet;
iov[0].iov_len = daemon->edns_pktsz; iov[0].iov_len = daemon->edns_pktsz;
msg.msg_control = control_u.control; msg.msg_control = control_u.control;
skipping to change at line 1325 skipping to change at line 1326
if (n < (int)sizeof(struct dns_header) || if (n < (int)sizeof(struct dns_header) ||
(msg.msg_flags & MSG_TRUNC) || (msg.msg_flags & MSG_TRUNC) ||
(header->hb3 & HB3_QR)) (header->hb3 & HB3_QR))
return; return;
/* Clear buffer beyond request to avoid risk of /* Clear buffer beyond request to avoid risk of
information disclosure. */ information disclosure. */
memset(daemon->packet + n, 0, daemon->edns_pktsz - n); memset(daemon->packet + n, 0, daemon->edns_pktsz - n);
source_addr.sa.sa_family = listen->family; source_addr.sa.sa_family = family;
if (listen->family == AF_INET) if (family == AF_INET)
{ {
/* Source-port == 0 is an error, we can't send back to that. /* Source-port == 0 is an error, we can't send back to that.
http://www.ietf.org/mail-archive/web/dnsop/current/msg11441.html */ http://www.ietf.org/mail-archive/web/dnsop/current/msg11441.html */
if (source_addr.in.sin_port == 0) if (source_addr.in.sin_port == 0)
return; return;
} }
else else
{ {
/* Source-port == 0 is an error, we can't send back to that. */ /* Source-port == 0 is an error, we can't send back to that. */
if (source_addr.in6.sin6_port == 0) if (source_addr.in6.sin6_port == 0)
return; return;
source_addr.in6.sin6_flowinfo = 0; source_addr.in6.sin6_flowinfo = 0;
} }
/* We can be configured to only accept queries from at-most-one-hop-away addre sses. */ /* We can be configured to only accept queries from at-most-one-hop-away addre sses. */
if (option_bool(OPT_LOCAL_SERVICE)) if (option_bool(OPT_LOCAL_SERVICE))
{ {
struct addrlist *addr; struct addrlist *addr;
if (listen->family == AF_INET6) if (family == AF_INET6)
{ {
for (addr = daemon->interface_addrs; addr; addr = addr->next) for (addr = daemon->interface_addrs; addr; addr = addr->next)
if ((addr->flags & ADDRLIST_IPV6) && if ((addr->flags & ADDRLIST_IPV6) &&
is_same_net6(&addr->addr.addr6, &source_addr.in6.sin6_addr, addr- >prefixlen)) is_same_net6(&addr->addr.addr6, &source_addr.in6.sin6_addr, addr- >prefixlen))
break; break;
} }
else else
{ {
struct in_addr netmask; struct in_addr netmask;
for (addr = daemon->interface_addrs; addr; addr = addr->next) for (addr = daemon->interface_addrs; addr; addr = addr->next)
skipping to change at line 1385 skipping to change at line 1386
} }
if (check_dst) if (check_dst)
{ {
struct ifreq ifr; struct ifreq ifr;
if (msg.msg_controllen < sizeof(struct cmsghdr)) if (msg.msg_controllen < sizeof(struct cmsghdr))
return; return;
#if defined(HAVE_LINUX_NETWORK) #if defined(HAVE_LINUX_NETWORK)
if (listen->family == AF_INET) if (family == AF_INET)
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr) ) for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr) )
if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO) if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
{ {
union { union {
unsigned char *c; unsigned char *c;
struct in_pktinfo *p; struct in_pktinfo *p;
} p; } p;
p.c = CMSG_DATA(cmptr); p.c = CMSG_DATA(cmptr);
dst_addr_4 = dst_addr.addr4 = p.p->ipi_spec_dst; dst_addr_4 = dst_addr.addr4 = p.p->ipi_spec_dst;
if_index = p.p->ipi_ifindex; if_index = p.p->ipi_ifindex;
} }
#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF) #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
if (listen->family == AF_INET) if (family == AF_INET)
{ {
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmpt r)) for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmpt r))
{ {
union { union {
unsigned char *c; unsigned char *c;
unsigned int *i; unsigned int *i;
struct in_addr *a; struct in_addr *a;
#ifndef HAVE_SOLARIS_NETWORK #ifndef HAVE_SOLARIS_NETWORK
struct sockaddr_dl *s; struct sockaddr_dl *s;
#endif #endif
skipping to change at line 1423 skipping to change at line 1424
else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP _RECVIF) else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP _RECVIF)
#ifdef HAVE_SOLARIS_NETWORK #ifdef HAVE_SOLARIS_NETWORK
if_index = *(p.i); if_index = *(p.i);
#else #else
if_index = p.s->sdl_index; if_index = p.s->sdl_index;
#endif #endif
} }
} }
#endif #endif
if (listen->family == AF_INET6) if (family == AF_INET6)
{ {
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmpt r)) for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmpt r))
if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon-> v6pktinfo) if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon-> v6pktinfo)
{ {
union { union {
unsigned char *c; unsigned char *c;
struct in6_pktinfo *p; struct in6_pktinfo *p;
} p; } p;
p.c = CMSG_DATA(cmptr); p.c = CMSG_DATA(cmptr);
dst_addr.addr6 = p.p->ipi6_addr; dst_addr.addr6 = p.p->ipi6_addr;
if_index = p.p->ipi6_ifindex; if_index = p.p->ipi6_ifindex;
} }
} }
/* enforce available interface configuration */ /* enforce available interface configuration */
if (!indextoname(listen->fd, if_index, ifr.ifr_name)) if (!indextoname(listen->fd, if_index, ifr.ifr_name))
return; return;
if (!iface_check(listen->family, &dst_addr, ifr.ifr_name, &auth_dns)) if (!iface_check(family, &dst_addr, ifr.ifr_name, &auth_dns))
{ {
if (!option_bool(OPT_CLEVERBIND)) if (!option_bool(OPT_CLEVERBIND))
enumerate_interfaces(0); enumerate_interfaces(0);
if (!loopback_exception(listen->fd, listen->family, &dst_addr, ifr.ifr if (!loopback_exception(listen->fd, family, &dst_addr, ifr.ifr_name) &
_name) && &
!label_exception(if_index, listen->family, &dst_addr)) !label_exception(if_index, family, &dst_addr))
return; return;
} }
if (listen->family == AF_INET && option_bool(OPT_LOCALISE)) if (family == AF_INET && option_bool(OPT_LOCALISE))
{ {
struct irec *iface; struct irec *iface;
/* get the netmask of the interface which has the address we were sent to. /* get the netmask of the interface which has the address we were sent to.
This is no necessarily the interface we arrived on. */ This is no necessarily the interface we arrived on. */
for (iface = daemon->interfaces; iface; iface = iface->next) for (iface = daemon->interfaces; iface; iface = iface->next)
if (iface->addr.sa.sa_family == AF_INET && if (iface->addr.sa.sa_family == AF_INET &&
iface->addr.in.sin_addr.s_addr == dst_addr_4.s_addr) iface->addr.in.sin_addr.s_addr == dst_addr_4.s_addr)
break; break;
skipping to change at line 1498 skipping to change at line 1499
dump_packet(DUMP_QUERY, daemon->packet, (size_t)n, &source_addr, NULL); dump_packet(DUMP_QUERY, daemon->packet, (size_t)n, &source_addr, NULL);
#endif #endif
if (extract_request(header, (size_t)n, daemon->namebuff, &type)) if (extract_request(header, (size_t)n, daemon->namebuff, &type))
{ {
#ifdef HAVE_AUTH #ifdef HAVE_AUTH
struct auth_zone *zone; struct auth_zone *zone;
#endif #endif
char *types = querystr(auth_dns ? "auth" : "query", type); char *types = querystr(auth_dns ? "auth" : "query", type);
if (listen->family == AF_INET) if (family == AF_INET)
log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff, log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff,
(union all_addr *)&source_addr.in.sin_addr, types); (union all_addr *)&source_addr.in.sin_addr, types);
else else
log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff, log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff,
(union all_addr *)&source_addr.in6.sin6_addr, types); (union all_addr *)&source_addr.in6.sin6_addr, types);
#ifdef HAVE_AUTH #ifdef HAVE_AUTH
/* find queries for zones we're authoritative for, and answer them directl y */ /* find queries for zones we're authoritative for, and answer them directl y */
if (!auth_dns && !option_bool(OPT_LOCALISE)) if (!auth_dns && !option_bool(OPT_LOCALISE))
for (zone = daemon->auth_zones; zone; zone = zone->next) for (zone = daemon->auth_zones; zone; zone = zone->next)
 End of changes. 15 change blocks. 
16 lines changed or deleted 17 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)