Make extract_name() easier to call operating on first name in message.

This commit is contained in:
Simon Kelley
2025-02-07 22:13:31 +00:00
parent 57f0489f38
commit 0ccbdf8087
2 changed files with 22 additions and 24 deletions

View File

@@ -329,8 +329,6 @@ static void forward_query(int udpfd, union mysockaddr *udpaddr,
/* new query */
if (!forward)
{
unsigned char *p;
if (OPCODE(header) != QUERY)
{
flags = F_RCODE;
@@ -393,8 +391,7 @@ static void forward_query(int udpfd, union mysockaddr *udpaddr,
forward->frec_src.encode_bitmap = (!option_bool(OPT_NO_0x20) && option_bool(OPT_DO_0x20)) ? rand32() : 0;
forward->frec_src.encode_bigmap = NULL;
p = (unsigned char *)(header+1);
if (!extract_name(header, plen, &p, (char *)&forward->frec_src.encode_bitmap, EXTR_NAME_FLIP, 1))
if (!extract_name(header, plen, NULL, (char *)&forward->frec_src.encode_bitmap, EXTR_NAME_FLIP, 1))
goto reply;
/* Keep copy of query for retries and move to TCP */
@@ -1270,8 +1267,7 @@ void reply_query(int fd, time_t now)
server->query_latency = server->mma_latency/128;
/* Flip the bits back in the query name. */
p = (unsigned char *)(header+1);
if (!extract_name(header, n, &p, (char *)&forward->frec_src.encode_bitmap, EXTR_NAME_FLIP, 1))
if (!extract_name(header, n, NULL, (char *)&forward->frec_src.encode_bitmap, EXTR_NAME_FLIP, 1))
return;
#ifdef HAVE_DNSSEC
@@ -1304,8 +1300,7 @@ static void xor_array(unsigned int *arg1, unsigned int *arg2, unsigned int len)
/* Call extract_name() to flip case of query in packet according to the XOR of the bit maps help in arg1 and arg2 */
static void flip_queryname(struct dns_header *header, ssize_t len, struct frec_src *arg1, struct frec_src *arg2)
{
unsigned char *p = (unsigned char *)(header+1);
unsigned int *arg1p, *arg2p, arg1len, arg2len, *swapp, swap;
unsigned int *arg1p, *arg2p, arg1len, arg2len;
/* Two cases: bitmap is single 32 bit int, or it's arbitrary-length array of 32bit ints.
The two args may be different and of different lengths.
@@ -1324,17 +1319,14 @@ static void flip_queryname(struct dns_header *header, ssize_t len, struct frec_s
/* make arg1 the longer, if they differ. */
if (arg2len > arg1len)
{
swap = arg1len;
swapp = arg1p;
arg1len = arg2len;
arg1p = arg2p;
arg2len = swap;
arg2p = swapp;
unsigned int swapl = arg1len, *swapp = arg1p;
arg1len = arg2len, arg1p = arg2p;
arg2len = swapl, arg2p = swapp;
}
/* XOR on shorter length, flip on longer, operate on longer */
xor_array(arg1p, arg2p, arg2len);
extract_name(header, len, &p, (char *)arg1p, EXTR_NAME_FLIP, arg1len);
extract_name(header, len, NULL, (char *)arg1p, EXTR_NAME_FLIP, arg1len);
xor_array(arg1p, arg2p, arg2len); /* restore */
}
@@ -2129,7 +2121,7 @@ static ssize_t tcp_talk(int first, int last, int start, unsigned char *packet,
/* We us the _ONCE veriant of read_write() here because we've set a timeout on the tcp socket
and wish to abort if the whole data is not read/written within the timeout. */
if ((!data_sent && !read_write(serv->tcpfd, (unsigned char *)packet, qsize + sizeof(u16), RW_WRITE_ONCE)) ||
if ((!data_sent && !read_write(serv->tcpfd, (unsigned char *)packet, qsize + sizeof(u16), RW_WRITE_ONCE)) ||
!read_write(serv->tcpfd, (unsigned char *)length, sizeof (*length), RW_READ_ONCE) ||
!read_write(serv->tcpfd, payload, (rsize = ntohs(*length)), RW_READ_ONCE))
{
@@ -2145,7 +2137,7 @@ static ssize_t tcp_talk(int first, int last, int start, unsigned char *packet,
else
goto failed;
}
/* If the question section of the reply doesn't match the question we sent, then
someone might be attempting to insert bogus values into the cache by
sending replies containing questions and bogus answers.

View File

@@ -29,16 +29,19 @@
return = 1 -> extract OK, compare OK, flip OK
return = 2 -> extract OK, compare failed.
return = 3 -> extract OK, compare failed but only on case.
If pp == NULL, operate on the query name in the packet.
*/
int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
char *name, int func, unsigned int parm)
{
unsigned char *cp = (unsigned char *)name, *p = *pp, *p1 = NULL;
unsigned char *cp = (unsigned char *)name, *p1 = NULL;
unsigned int j, l, namelen = 0, hops = 0;
unsigned int bigmap_counter = 0, bigmap_posn = 0, bigmap_size = parm, bitmap = 0;
int retvalue = 1, case_insens = 1, isExtract = 0, flip = 0, extrabytes = (int)parm;
unsigned int *bigmap = (unsigned int *)name;
unsigned char *p = pp ? *pp : (unsigned char *)(header+1);
if (func == EXTR_NAME_EXTRACT)
isExtract = 1, *cp = 0;
else if (func == EXTR_NAME_NOCASE)
@@ -71,11 +74,14 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
}
else if (!flip && *cp != 0)
retvalue = 2;
if (p1) /* we jumped via compression */
*pp = p1;
else
*pp = p;
if (pp)
{
if (p1) /* we jumped via compression */
*pp = p1;
else
*pp = p;
}
return retvalue;
}