Changeset View
Changeset View
Standalone View
Standalone View
src/seeder/dns.cpp
Show All 40 Lines | typedef enum { | ||||
TYPE_CNAME = 5, | TYPE_CNAME = 5, | ||||
TYPE_SOA = 6, | TYPE_SOA = 6, | ||||
TYPE_MX = 15, | TYPE_MX = 15, | ||||
TYPE_AAAA = 28, | TYPE_AAAA = 28, | ||||
TYPE_SRV = 33, | TYPE_SRV = 33, | ||||
QTYPE_ANY = 255 | QTYPE_ANY = 255 | ||||
} dns_type; | } dns_type; | ||||
// 0: ok | int parse_name(const uint8_t **inpos, const uint8_t *inend, | ||||
// -1: premature end of input, forward reference, component > 63 char, invalid | |||||
// character | |||||
// -2: insufficient space in output | |||||
static int parse_name(const uint8_t **inpos, const uint8_t *inend, | |||||
const uint8_t *inbuf, char *buf, size_t bufsize) { | const uint8_t *inbuf, char *buf, size_t bufsize) { | ||||
size_t bufused = 0; | size_t bufused = 0; | ||||
int init = 1; | int init = 1; | ||||
do { | do { | ||||
if (*inpos == inend) return -1; | if (*inpos == inend) { | ||||
return -1; | |||||
} | |||||
// read length of next component | // read length of next component | ||||
int octet = *((*inpos)++); | int octet = *((*inpos)++); | ||||
if (octet == 0) { | if (octet == 0) { | ||||
buf[bufused] = 0; | buf[bufused] = 0; | ||||
return 0; | return 0; | ||||
} | } | ||||
// add dot in output | // add dot in output | ||||
if (!init) { | if (!init) { | ||||
if (bufused == bufsize - 1) return -2; | if (bufused == bufsize - 1) { | ||||
return -2; | |||||
} | |||||
buf[bufused++] = '.'; | buf[bufused++] = '.'; | ||||
} else | } else | ||||
init = 0; | init = 0; | ||||
// handle references | // handle references | ||||
if ((octet & 0xC0) == 0xC0) { | if ((octet & 0xC0) == 0xC0) { | ||||
if (*inpos == inend) return -1; | if (*inpos == inend) { | ||||
return -1; | |||||
} | |||||
int ref = ((octet - 0xC0) << 8) + *((*inpos)++); | int ref = ((octet - 0xC0) << 8) + *((*inpos)++); | ||||
if (ref < 0 || ref >= (*inpos) - inbuf - 2) return -1; | if (ref < 0 || ref >= (*inpos) - inbuf - 2) { | ||||
return -1; | |||||
} | |||||
const uint8_t *newbuf = inbuf + ref; | const uint8_t *newbuf = inbuf + ref; | ||||
return parse_name(&newbuf, (*inpos) - 2, inbuf, buf + bufused, | return parse_name(&newbuf, (*inpos) - 2, inbuf, buf + bufused, | ||||
bufsize - bufused); | bufsize - bufused); | ||||
} | } | ||||
if (octet > 63) return -1; | if (octet > 63) { | ||||
return -1; | |||||
} | |||||
// copy label | // copy label | ||||
while (octet) { | while (octet) { | ||||
if (*inpos == inend) return -1; | if (*inpos == inend) { | ||||
if (bufused == bufsize - 1) return -2; | return -1; | ||||
} | |||||
if (bufused == bufsize - 1) { | |||||
return -2; | |||||
} | |||||
int c = *((*inpos)++); | int c = *((*inpos)++); | ||||
if (c == '.') return -1; | if (c == '.') { | ||||
return -1; | |||||
} | |||||
octet--; | octet--; | ||||
buf[bufused++] = c; | buf[bufused++] = c; | ||||
} | } | ||||
} while (1); | } while (1); | ||||
} | } | ||||
// 0: k | // 0: k | ||||
// -1: component > 63 characters | // -1: component > 63 characters | ||||
▲ Show 20 Lines • Show All 479 Lines • ▼ Show 20 Lines | int dnsserver(dns_opt_t *opt) { | ||||
msg.msg_namelen = sizeof(si_other); | msg.msg_namelen = sizeof(si_other); | ||||
msg.msg_iov = iov; | msg.msg_iov = iov; | ||||
msg.msg_iovlen = 1; | msg.msg_iovlen = 1; | ||||
msg.msg_control = &cmsg; | msg.msg_control = &cmsg; | ||||
msg.msg_controllen = sizeof(cmsg); | msg.msg_controllen = sizeof(cmsg); | ||||
for (; 1; ++(opt->nRequests)) { | for (; 1; ++(opt->nRequests)) { | ||||
ssize_t insize = recvmsg(listenSocket, &msg, 0); | ssize_t insize = recvmsg(listenSocket, &msg, 0); | ||||
// uint8_t *addr = (uint8_t*)&si_other.sin_addr.s_addr; | // uint8_t *addr = (uint8_t*)&si_other.sin6_addr.s6_addr; | ||||
// fprintf(stdout, "DNS: Request %llu from %i.%i.%i.%i:%i of %i | // fprintf(stdout, "DNS: Request %llu from %i.%i.%i.%i:%i of %i | ||||
// bytes\n", (unsigned long long)(opt->nRequests), addr[0], addr[1], | // bytes\n", (unsigned long long)(opt->nRequests), addr[0], addr[1], | ||||
// addr[2], addr[3], ntohs(si_other.sin_port), (int)insize); | // addr[2], addr[3], ntohs(si_other.sin6_port), (int)insize); | ||||
if (insize <= 0) continue; | if (insize <= 0) continue; | ||||
ssize_t ret = dnshandle(opt, inbuf, insize, outbuf); | ssize_t ret = dnshandle(opt, inbuf, insize, outbuf); | ||||
if (ret <= 0) continue; | if (ret <= 0) continue; | ||||
bool handled = false; | bool handled = false; | ||||
for (struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); hdr; | for (struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); hdr; | ||||
hdr = CMSG_NXTHDR(&msg, hdr)) { | hdr = CMSG_NXTHDR(&msg, hdr)) { | ||||
Show All 16 Lines |