Fix data length in encoding dns queries
This commit is contained in:
parent
d4d88d2ad0
commit
5951166b36
73
src/dns.c
73
src/dns.c
|
@ -90,47 +90,41 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_
|
||||||
putshort(&p, C_IN);
|
putshort(&p, C_IN);
|
||||||
putlong(&p, 0); /* TTL */
|
putlong(&p, 0); /* TTL */
|
||||||
|
|
||||||
if (q->type == T_CNAME || q->type == T_A || q->type == T_MX)
|
if (q->type == T_CNAME || q->type == T_A || q->type == T_MX) {
|
||||||
{
|
/* data is expected to be like "Hblabla.host.name.com\0" */
|
||||||
/* data is expected to be like "Hblabla.host.name.com\0" */
|
|
||||||
|
|
||||||
char *startp = p;
|
char *startp = p;
|
||||||
int namelen;
|
int namelen;
|
||||||
|
|
||||||
p += 2; /* skip 2 bytes length */
|
p += 2; /* skip 2 bytes length */
|
||||||
CHECKLEN(2);
|
CHECKLEN(2);
|
||||||
if (q->type == T_MX)
|
if (q->type == T_MX)
|
||||||
putshort(&p, 10); /* preference */
|
putshort(&p, 10); /* preference */
|
||||||
putname(&p, buflen - (p - buf), data);
|
putname(&p, buflen - (p - buf), data);
|
||||||
CHECKLEN(0);
|
CHECKLEN(0);
|
||||||
namelen = p - startp;
|
namelen = p - startp;
|
||||||
namelen -= 2;
|
namelen -= 2;
|
||||||
putshort(&startp, namelen);
|
putshort(&startp, namelen);
|
||||||
}
|
} else if (q->type == T_TXT) {
|
||||||
else if (q->type == T_TXT)
|
/* TXT has binary or base-X data */
|
||||||
{
|
char *startp = p;
|
||||||
/* TXT has binary or base-X data */
|
int txtlen;
|
||||||
char *startp = p;
|
|
||||||
int txtlen;
|
|
||||||
|
|
||||||
p += 2; /* skip 2 bytes length */
|
|
||||||
puttxtbin(&p, buflen - (p - buf), data, datalen);
|
|
||||||
CHECKLEN(0);
|
|
||||||
txtlen = p - startp;
|
|
||||||
txtlen -= 2;
|
|
||||||
putshort(&startp, txtlen);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* NULL has raw binary data */
|
|
||||||
datalen = MIN(datalen, buflen - (p - buf));
|
|
||||||
CHECKLEN(2);
|
|
||||||
putshort(&p, datalen);
|
|
||||||
CHECKLEN(datalen);
|
|
||||||
putdata(&p, data, datalen);
|
|
||||||
CHECKLEN(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
p += 2; /* skip 2 bytes length */
|
||||||
|
puttxtbin(&p, buflen - (p - buf), data, datalen);
|
||||||
|
CHECKLEN(0);
|
||||||
|
txtlen = p - startp;
|
||||||
|
txtlen -= 2;
|
||||||
|
putshort(&startp, txtlen);
|
||||||
|
} else {
|
||||||
|
/* NULL has raw binary data */
|
||||||
|
datalen = MIN(datalen, buflen - (p - buf));
|
||||||
|
CHECKLEN(2);
|
||||||
|
putshort(&p, datalen);
|
||||||
|
CHECKLEN(datalen);
|
||||||
|
putdata(&p, data, datalen);
|
||||||
|
CHECKLEN(0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case QR_QUERY:
|
case QR_QUERY:
|
||||||
/* Note that iodined also uses this for forward queries */
|
/* Note that iodined also uses this for forward queries */
|
||||||
|
@ -138,7 +132,8 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_
|
||||||
header->qdcount = htons(1);
|
header->qdcount = htons(1);
|
||||||
header->arcount = htons(1);
|
header->arcount = htons(1);
|
||||||
|
|
||||||
putname(&p, buflen - (p - buf), data);
|
datalen = MIN(datalen, buflen - (p - buf));
|
||||||
|
putname(&p, datalen, data);
|
||||||
|
|
||||||
CHECKLEN(4);
|
CHECKLEN(4);
|
||||||
putshort(&p, q->type);
|
putshort(&p, q->type);
|
||||||
|
|
|
@ -69,8 +69,9 @@ START_TEST(test_encode_query)
|
||||||
char *d;
|
char *d;
|
||||||
size_t len;
|
size_t len;
|
||||||
int ret;
|
int ret;
|
||||||
|
int enclen;
|
||||||
|
|
||||||
len = sizeof(buf);
|
enclen = sizeof(resolv);
|
||||||
memset(&buf, 0, sizeof(buf));
|
memset(&buf, 0, sizeof(buf));
|
||||||
memset(&resolv, 0, sizeof(resolv));
|
memset(&resolv, 0, sizeof(resolv));
|
||||||
memset(&q, 0, sizeof(struct query));
|
memset(&q, 0, sizeof(struct query));
|
||||||
|
@ -80,12 +81,13 @@ START_TEST(test_encode_query)
|
||||||
enc = get_base32_encoder();
|
enc = get_base32_encoder();
|
||||||
|
|
||||||
*d++ = 'A';
|
*d++ = 'A';
|
||||||
enc->encode(d, &len, innerData, strlen(innerData));
|
enc->encode(d, &enclen, innerData, strlen(innerData));
|
||||||
d = resolv + strlen(resolv);
|
d = resolv + strlen(resolv);
|
||||||
if (*d != '.') {
|
if (*d != '.') {
|
||||||
*d++ = '.';
|
*d++ = '.';
|
||||||
}
|
}
|
||||||
strcpy(d, topdomain);
|
strcpy(d, topdomain);
|
||||||
|
len = sizeof(buf);
|
||||||
ret = dns_encode(buf, len, &q, QR_QUERY, resolv, strlen(resolv));
|
ret = dns_encode(buf, len, &q, QR_QUERY, resolv, strlen(resolv));
|
||||||
len = sizeof(query_packet) - 1; /* Skip extra null character */
|
len = sizeof(query_packet) - 1; /* Skip extra null character */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue