From 15a2add0f85f6807ed8db67982e1689cb11c4a27 Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 26 Apr 2023 11:57:10 +0200 Subject: [PATCH] streamtcp, implement NOTIFY[=N] that sends a notify packet. --- testcode/streamtcp.1 | 4 +++ testcode/streamtcp.c | 60 +++++++++++++++++++++++++++++++------------- 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/testcode/streamtcp.1 b/testcode/streamtcp.1 index 629e69570..55ed4a279 100644 --- a/testcode/streamtcp.1 +++ b/testcode/streamtcp.1 @@ -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. diff --git a/testcode/streamtcp.c b/testcode/streamtcp.c index ea9b3cf49..0cd9f185f 100644 --- a/testcode/streamtcp.c +++ b/testcode/streamtcp.c @@ -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) {