Compare commits

...
4 Commits
Author SHA1 Message Date
Simon Kelley 3f535da79e Fix for 12af2b171d 2021-01-22 22:26:25 +00:00
Simon Kelley 8ebdc364af Optimise sort_rrset for the case where the RR type no canonicalisation. 2021-01-22 18:50:43 +00:00
Simon Kelley 12af2b171d Fix to 75e2f0aec33e58ef5b8d4d107d821c215a52827c 2021-01-22 18:24:03 +00:00
Simon Kelley 04490bf622 Move fd into frec_src, fixes 15b60ddf93
If identical queries from IPv4 and IPv6 sources are combined by the
new code added in 15b60ddf93 then replies
can end up being sent via the wrong family of socket. The ->fd
should be per query, not per-question.

In bind-interfaces mode, this could also result in replies being sent
via the wrong socket even when IPv4/IPV6 issues are not in play.
2021-01-22 17:30:27 +00:00
3 changed files with 32 additions and 3 deletions

No files matched your search

+2 -1
View File
@@ -664,6 +664,7 @@ struct frec {
union mysockaddr source; union mysockaddr source;
union all_addr dest; union all_addr dest;
unsigned int iface, log_id; unsigned int iface, log_id;
int fd;
unsigned short orig_id; unsigned short orig_id;
struct frec_src *next; struct frec_src *next;
} frec_src; } frec_src;
@@ -671,7 +672,7 @@ struct frec {
struct randfd *rfd4; struct randfd *rfd4;
struct randfd *rfd6; struct randfd *rfd6;
unsigned short new_id; unsigned short new_id;
int fd, forwardall, flags; int forwardall, flags;
time_t time; time_t time;
unsigned char *hash[HASH_SIZE]; unsigned char *hash[HASH_SIZE];
#ifdef HAVE_DNSSEC #ifdef HAVE_DNSSEC
+27
View File
@@ -335,6 +335,33 @@ static int sort_rrset(struct dns_header *header, size_t plen, u16 *rr_desc, int
return rrsetidx; /* short packet */ return rrsetidx; /* short packet */
state2.end = state2.ip + rdlen2; state2.end = state2.ip + rdlen2;
/* If the RR has no names in it then canonicalisation
is the identity function and we can compare
the RRs directly. If not we compare the
canonicalised RRs one byte at a time. */
if (*rr_desc == (u16)-1)
{
int rdmin = rdlen1 > rdlen2 ? rdlen2 : rdlen1;
int cmp = memcmp(state1.ip, state2.ip, rdmin);
if (cmp > 0 || (cmp == 0 && rdlen1 > rdmin))
{
unsigned char *tmp = rrset[i+1];
rrset[i+1] = rrset[i];
rrset[i] = tmp;
swap = 1;
}
else if (cmp == 0 && (rdlen1 == rdlen2))
{
/* Two RRs are equal, remove one copy. RFC 4034, para 6.3 */
for (j = i+1; j < rrsetidx-1; j++)
rrset[j] = rrset[j+1];
rrsetidx--;
i--;
}
}
else
/* Comparing canonicalised RRs, byte-at-a-time. */
while (1) while (1)
{ {
int ok1, ok2; int ok1, ok2;
+3 -2
View File
@@ -378,6 +378,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
new->dest = *dst_addr; new->dest = *dst_addr;
new->log_id = daemon->log_id; new->log_id = daemon->log_id;
new->iface = dst_iface; new->iface = dst_iface;
new->fd = udpfd;
} }
return 1; return 1;
@@ -402,8 +403,8 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
forward->frec_src.dest = *dst_addr; forward->frec_src.dest = *dst_addr;
forward->frec_src.iface = dst_iface; forward->frec_src.iface = dst_iface;
forward->frec_src.next = NULL; forward->frec_src.next = NULL;
forward->frec_src.fd = udpfd;
forward->new_id = get_id(); forward->new_id = get_id();
forward->fd = udpfd;
memcpy(forward->hash, hash, HASH_SIZE); memcpy(forward->hash, hash, HASH_SIZE);
forward->forwardall = 0; forward->forwardall = 0;
forward->flags = fwd_flags; forward->flags = fwd_flags;
@@ -1300,7 +1301,7 @@ void reply_query(int fd, int family, time_t now)
dump_packet(DUMP_REPLY, daemon->packet, (size_t)nn, NULL, &src->source); dump_packet(DUMP_REPLY, daemon->packet, (size_t)nn, NULL, &src->source);
#endif #endif
send_from(forward->fd, option_bool(OPT_NOWILD) || option_bool (OPT_CLEVERBIND), daemon->packet, nn, send_from(src->fd, option_bool(OPT_NOWILD) || option_bool (OPT_CLEVERBIND), daemon->packet, nn,
&src->source, &src->dest, src->iface); &src->source, &src->dest, src->iface);
if (option_bool(OPT_EXTRALOG) && src != &forward->frec_src) if (option_bool(OPT_EXTRALOG) && src != &forward->frec_src)