handle AAAA (rather, be like idk lol)

This commit is contained in:
xenia 2022-09-13 13:55:02 -04:00
parent 1155274a32
commit 578504caef
3 changed files with 77 additions and 1 deletions

View File

@ -227,6 +227,53 @@ int dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr,
return len; return len;
} }
/* Only used when iodined gets a AAAA type query */
/* Mostly same as dns_encode_caa_response() below */
int dns_encode_aaaa_response(char *buf, size_t buflen, struct query *q,
char *topdomain)
{
HEADER *header;
int len;
int domain_len;
char *p;
if (buflen < sizeof(HEADER))
return 0;
memset(buf, 0, buflen);
header = (HEADER*)buf;
header->id = htons(q->id);
header->qr = 1;
header->opcode = 0;
header->aa = 1;
header->tc = 0;
header->rd = 0;
header->ra = 0;
p = buf + sizeof(HEADER);
header->qdcount = htons(1);
header->ancount = htons(0);
domain_len = strlen(q->name) - strlen(topdomain);
if (domain_len < 0 || domain_len == 1)
return -1;
if (strcasecmp(q->name + domain_len, topdomain))
return -1;
if (domain_len >= 1 && q->name[domain_len - 1] != '.')
return -1;
/* Query section */
putname(&p, buflen - (p - buf), q->name); /* Name */
CHECKLEN(4);
putshort(&p, q->type); /* Type */
putshort(&p, C_IN); /* Class */
len = p - buf;
return len;
}
/* Only used when iodined gets a CAA type query */ /* Only used when iodined gets a CAA type query */
/* Mostly same as dns_encode_ns_response() below */ /* Mostly same as dns_encode_ns_response() below */
int dns_encode_caa_response(char *buf, size_t buflen, struct query *q, int dns_encode_caa_response(char *buf, size_t buflen, struct query *q,

View File

@ -28,6 +28,8 @@ typedef enum {
extern int dnsc_use_edns0; extern int dnsc_use_edns0;
int dns_encode(char *, size_t, struct query *, qr_t, const char *, size_t); int dns_encode(char *, size_t, struct query *, qr_t, const char *, size_t);
int dns_encode_aaaa_response(char *buf, size_t buflen, struct query *q,
char *topdomain);
int dns_encode_caa_response(char *buf, size_t buflen, struct query *q, int dns_encode_caa_response(char *buf, size_t buflen, struct query *q,
char *topdomain); char *topdomain);
int dns_encode_ns_response(char *buf, size_t buflen, struct query *q, int dns_encode_ns_response(char *buf, size_t buflen, struct query *q,

View File

@ -1523,7 +1523,7 @@ handle_null_request(int tun_fd, int dns_fd, struct dnsfd *dns_fds, struct query
} }
static void static void
handle_caa_request(int dns_fd, struct query *q, int topdomain_offset) handle_aaaa_request(int dns_fd, struct query *q, int topdomain_offset)
/* Mostly identical to handle_caa_request() below */ /* Mostly identical to handle_caa_request() below */
{ {
char buf[64*1024]; char buf[64*1024];
@ -1531,6 +1531,30 @@ handle_caa_request(int dns_fd, struct query *q, int topdomain_offset)
/* Use possibly dynamic top domain in reply */ /* Use possibly dynamic top domain in reply */
char *resp_domain = q->name + topdomain_offset; char *resp_domain = q->name + topdomain_offset;
len = dns_encode_aaaa_response(buf, sizeof(buf), q, resp_domain);
if (len < 1) {
warnx("dns_encode_caa_response doesn't fit");
return;
}
if (debug >= 2) {
fprintf(stderr, "TX: client %s, type %d, name %s, %d bytes NS reply\n",
format_addr(&q->from, q->fromlen), q->type, q->name, len);
}
if (sendto(dns_fd, buf, len, 0, (struct sockaddr*)&q->from, q->fromlen) <= 0) {
warn("ns reply send error");
}
}
static void
handle_caa_request(int dns_fd, struct query *q, int topdomain_offset)
/* Mostly identical to handle_ns_request() below */
{
char buf[64*1024];
int len;
/* Use possibly dynamic top domain in reply */
char *resp_domain = q->name + topdomain_offset;
len = dns_encode_caa_response(buf, sizeof(buf), q, resp_domain); len = dns_encode_caa_response(buf, sizeof(buf), q, resp_domain);
if (len < 1) { if (len < 1) {
warnx("dns_encode_caa_response doesn't fit"); warnx("dns_encode_caa_response doesn't fit");
@ -1768,6 +1792,9 @@ tunnel_dns(int tun_fd, int dns_fd, struct dnsfd *dns_fds, int bind_fd)
case T_CAA: case T_CAA:
handle_caa_request(dns_fd, &q, domain_len); handle_caa_request(dns_fd, &q, domain_len);
break; break;
case T_AAAA:
handle_aaaa_request(dns_fd, &q, domain_len);
break;
default: default:
if (debug >= 0) { if (debug >= 0) {
fprintf(stderr, "WARN: can't handle request of type: %d\n", q.type); fprintf(stderr, "WARN: can't handle request of type: %d\n", q.type);