streamtcp, implement NOTIFY[=N] that sends a notify packet.

This commit is contained in:
W.C.A. Wijngaards 2023-04-26 11:57:10 +02:00
parent 4bcc0a0a7a
commit 15a2add0f8
2 changed files with 47 additions and 17 deletions

View File

@ -68,6 +68,10 @@ to include in PROXYv2.
.TP
.B IXFR=serial
Pass the type of the query as IXFR=N to send an IXFR query with serial N.
.TP
.B NOTIFY[=serial]
Pass the type of the query as NOTIFY[=N] to send a notify packet. The serial N
of the new zone can be included.
.SH "EXAMPLES"
.LP
Some examples of use.

View File

@ -80,6 +80,7 @@ static void usage(char* argv[])
printf("-s use ssl\n");
printf("-h this help text\n");
printf("IXFR=N for the type, sends ixfr query with serial N.\n");
printf("NOTIFY[=N] for the type, sends notify. Can set new zone serial N.\n");
exit(1);
}
@ -116,6 +117,29 @@ open_svr(const char* svr, int udp, struct sockaddr_storage* addr,
return fd;
}
/** Append a SOA record with serial number */
static void
write_soa_serial_to_buf(sldns_buffer* buf, struct query_info* qinfo,
uint32_t serial)
{
sldns_buffer_set_position(buf, sldns_buffer_limit(buf));
sldns_buffer_set_limit(buf, sldns_buffer_capacity(buf));
/* Write compressed reference to the query */
sldns_buffer_write_u16(buf, PTR_CREATE(LDNS_HEADER_SIZE));
sldns_buffer_write_u16(buf, LDNS_RR_TYPE_SOA);
sldns_buffer_write_u16(buf, qinfo->qclass);
sldns_buffer_write_u32(buf, 3600); /* TTL */
sldns_buffer_write_u16(buf, 1+1+4*5); /* rdatalen */
sldns_buffer_write_u8(buf, 0); /* primary "." */
sldns_buffer_write_u8(buf, 0); /* email "." */
sldns_buffer_write_u32(buf, serial); /* serial */
sldns_buffer_write_u32(buf, 0); /* refresh */
sldns_buffer_write_u32(buf, 0); /* retry */
sldns_buffer_write_u32(buf, 0); /* expire */
sldns_buffer_write_u32(buf, 0); /* minimum */
sldns_buffer_flip(buf);
}
/** write a query over the TCP fd */
static void
write_q(int fd, int udp, SSL* ssl, sldns_buffer* buf, uint16_t id,
@ -124,7 +148,7 @@ write_q(int fd, int udp, SSL* ssl, sldns_buffer* buf, uint16_t id,
{
struct query_info qinfo;
size_t proxy_buf_limit = sldns_buffer_limit(proxy_buf);
int have_serial = 0;
int have_serial = 0, is_notify = 0;
uint32_t serial = 0;
/* qname */
qinfo.qname = sldns_str2wire_dname(strname, &qinfo.qname_len);
@ -138,6 +162,14 @@ write_q(int fd, int udp, SSL* ssl, sldns_buffer* buf, uint16_t id,
serial = (uint32_t)atoi(strtype+5);
have_serial = 1;
qinfo.qtype = LDNS_RR_TYPE_IXFR;
} else if(strcasecmp(strtype, "NOTIFY") == 0) {
is_notify = 1;
qinfo.qtype = LDNS_RR_TYPE_SOA;
} else if(strncasecmp(strtype, "NOTIFY=", 7) == 0) {
serial = (uint32_t)atoi(strtype+7);
have_serial = 1;
is_notify = 1;
qinfo.qtype = LDNS_RR_TYPE_SOA;
} else {
qinfo.qtype = sldns_get_rr_type_by_name(strtype);
}
@ -153,23 +185,17 @@ write_q(int fd, int udp, SSL* ssl, sldns_buffer* buf, uint16_t id,
if(have_serial && qinfo.qtype == LDNS_RR_TYPE_IXFR) {
/* Attach serial to SOA record in the authority section. */
sldns_buffer_set_position(buf, sldns_buffer_limit(buf));
sldns_buffer_set_limit(buf, sldns_buffer_capacity(buf));
/* Write compressed reference to the query */
sldns_buffer_write_u16(buf, PTR_CREATE(LDNS_HEADER_SIZE));
sldns_buffer_write_u16(buf, LDNS_RR_TYPE_SOA);
sldns_buffer_write_u16(buf, qinfo.qclass);
sldns_buffer_write_u32(buf, 3600); /* TTL */
sldns_buffer_write_u16(buf, 1+1+4*5); /* rdatalen */
sldns_buffer_write_u8(buf, 0); /* primary "." */
sldns_buffer_write_u8(buf, 0); /* email "." */
sldns_buffer_write_u32(buf, serial); /* serial */
sldns_buffer_write_u32(buf, 0); /* refresh */
sldns_buffer_write_u32(buf, 0); /* retry */
sldns_buffer_write_u32(buf, 0); /* expire */
sldns_buffer_write_u32(buf, 0); /* minimum */
write_soa_serial_to_buf(buf, &qinfo, serial);
LDNS_NSCOUNT_SET(sldns_buffer_begin(buf), 1);
sldns_buffer_flip(buf);
}
if(is_notify) {
LDNS_OPCODE_SET(sldns_buffer_begin(buf), LDNS_PACKET_NOTIFY);
LDNS_RD_CLR(sldns_buffer_begin(buf));
LDNS_AA_SET(sldns_buffer_begin(buf));
if(have_serial) {
write_soa_serial_to_buf(buf, &qinfo, serial);
LDNS_ANCOUNT_SET(sldns_buffer_begin(buf), 1);
}
}
if(1) {