add support for CAA lmao
This commit is contained in:
parent
d77ec85675
commit
1155274a32
66
src/dns.c
66
src/dns.c
|
@ -227,6 +227,72 @@ int dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr,
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Only used when iodined gets a CAA type query */
|
||||||
|
/* Mostly same as dns_encode_ns_response() below */
|
||||||
|
int dns_encode_caa_response(char *buf, size_t buflen, struct query *q,
|
||||||
|
char *topdomain)
|
||||||
|
{
|
||||||
|
HEADER *header;
|
||||||
|
int len;
|
||||||
|
short name;
|
||||||
|
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(1);
|
||||||
|
|
||||||
|
/* pointer to start of name */
|
||||||
|
name = 0xc000 | ((p - buf) & 0x3fff);
|
||||||
|
|
||||||
|
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 */
|
||||||
|
|
||||||
|
/* Answer section */
|
||||||
|
CHECKLEN(12);
|
||||||
|
putshort(&p, name); /* Name */
|
||||||
|
putshort(&p, q->type); /* Type */
|
||||||
|
putshort(&p, C_IN); /* Class */
|
||||||
|
putlong(&p, 3600); /* TTL */
|
||||||
|
putshort(&p, 22); /* Data length */
|
||||||
|
|
||||||
|
/* caa record */
|
||||||
|
CHECKLEN(22);
|
||||||
|
memcpy(p, "\x00\x05\x69\x73\x73\x75\x65\x6c\x65\x74\x73\x65\x6e\x63\x72\x79\x70" \
|
||||||
|
"\x74\x2e\x6f\x72\x67", 22);
|
||||||
|
p += 22;
|
||||||
|
|
||||||
|
len = p - buf;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
/* Only used when iodined gets an NS type query */
|
/* Only used when iodined gets an NS type query */
|
||||||
/* Mostly same as dns_encode_a_response() below */
|
/* Mostly same as dns_encode_a_response() below */
|
||||||
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,
|
||||||
|
|
|
@ -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_caa_response(char *buf, size_t buflen, struct query *q,
|
||||||
|
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,
|
||||||
char *topdomain);
|
char *topdomain);
|
||||||
int dns_encode_a_response(char *buf, size_t buflen, struct query *q);
|
int dns_encode_a_response(char *buf, size_t buflen, struct query *q);
|
||||||
|
|
|
@ -1522,6 +1522,30 @@ handle_null_request(int tun_fd, int dns_fd, struct dnsfd *dns_fds, struct query
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_caa_request(int dns_fd, struct query *q, int topdomain_offset)
|
||||||
|
/* Mostly identical to handle_caa_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);
|
||||||
|
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
|
static void
|
||||||
handle_ns_request(int dns_fd, struct query *q, int topdomain_offset)
|
handle_ns_request(int dns_fd, struct query *q, int topdomain_offset)
|
||||||
/* Mostly identical to handle_a_request() below */
|
/* Mostly identical to handle_a_request() below */
|
||||||
|
@ -1689,12 +1713,13 @@ tunnel_dns(int tun_fd, int dns_fd, struct dnsfd *dns_fds, int bind_fd)
|
||||||
if ((read = read_dns(dns_fd, dns_fds, tun_fd, &q)) <= 0)
|
if ((read = read_dns(dns_fd, dns_fds, tun_fd, &q)) <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
domain_len = query_datalen(q.name, topdomain);
|
||||||
|
|
||||||
if (debug >= 2) {
|
if (debug >= 2) {
|
||||||
fprintf(stderr, "RX: client %s, type %d, name %s\n",
|
fprintf(stderr, "RX: client %s, type %d, name %s, domain_len=%d\n",
|
||||||
format_addr(&q.from, q.fromlen), q.type, q.name);
|
format_addr(&q.from, q.fromlen), q.type, q.name, domain_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
domain_len = query_datalen(q.name, topdomain);
|
|
||||||
if (domain_len >= 0) {
|
if (domain_len >= 0) {
|
||||||
/* This is a query we can handle */
|
/* This is a query we can handle */
|
||||||
|
|
||||||
|
@ -1740,10 +1765,19 @@ tunnel_dns(int tun_fd, int dns_fd, struct dnsfd *dns_fds, int bind_fd)
|
||||||
case T_NS:
|
case T_NS:
|
||||||
handle_ns_request(dns_fd, &q, domain_len);
|
handle_ns_request(dns_fd, &q, domain_len);
|
||||||
break;
|
break;
|
||||||
|
case T_CAA:
|
||||||
|
handle_caa_request(dns_fd, &q, domain_len);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
if (debug >= 0) {
|
||||||
|
fprintf(stderr, "WARN: can't handle request of type: %d\n", q.type);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (debug >= 0) {
|
||||||
|
fprintf(stderr, "WARN: can't handle non-authoritiative domain request");
|
||||||
|
}
|
||||||
/* Forward query to other port ? */
|
/* Forward query to other port ? */
|
||||||
if (bind_fd) {
|
if (bind_fd) {
|
||||||
forward_query(bind_fd, &q);
|
forward_query(bind_fd, &q);
|
||||||
|
|
Loading…
Reference in New Issue