diff options
Diffstat (limited to 'testcode')
33 files changed, 2650 insertions, 2787 deletions
diff --git a/testcode/asynclook.c b/testcode/asynclook.c index 7ec013c0cb9f..7e9ee77580a3 100644 --- a/testcode/asynclook.c +++ b/testcode/asynclook.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -48,6 +48,7 @@ #include "libunbound/context.h" #include "util/locks.h" #include "util/log.h" +#include "ldns/rrdef.h" #ifdef UNBOUND_ALLOC_LITE #undef malloc #undef calloc @@ -334,6 +335,11 @@ ext_thread(void* arg) r = ub_wait(inf->ctx); checkerr("ub_ctx_wait", r); } + if(async_ids) { + for(i=0; i<inf->numq; i++) { + lock_basic_destroy(&async_ids[i].lock); + } + } free(async_ids); return NULL; @@ -354,7 +360,7 @@ ext_test(struct ub_ctx* ctx, int argc, char** argv) inf[i].ctx = ctx; inf[i].argc = argc; inf[i].argv = argv; - inf[i].numq = 1000; + inf[i].numq = 100; ub_thread_create(&inf[i].tid, ext_thread, &inf[i]); } /* the work happens here */ diff --git a/testcode/checklocks.c b/testcode/checklocks.c index 71a86a4912d2..ba020e70a79d 100644 --- a/testcode/checklocks.c +++ b/testcode/checklocks.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" diff --git a/testcode/checklocks.h b/testcode/checklocks.h index de901da9afba..936f282756f7 100644 --- a/testcode/checklocks.h +++ b/testcode/checklocks.h @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef TESTCODE_CHECK_LOCKS_H diff --git a/testcode/delayer.c b/testcode/delayer.c index b42a3b1aa7cd..7a90fc04ce78 100644 --- a/testcode/delayer.c +++ b/testcode/delayer.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -50,6 +50,7 @@ #include <sys/time.h> #include "util/net_help.h" #include "util/config_file.h" +#include "ldns/sbuffer.h" #include <signal.h> /** number of reads per select for delayer */ @@ -221,15 +222,15 @@ ring_delete(struct ringbuf* r) /** add entry to ringbuffer */ static void -ring_add(struct ringbuf* r, ldns_buffer* pkt, struct timeval* now, +ring_add(struct ringbuf* r, sldns_buffer* pkt, struct timeval* now, struct timeval* delay, struct proxy* p) { /* time -- proxy* -- 16bitlen -- message */ - uint16_t len = (uint16_t)ldns_buffer_limit(pkt); + uint16_t len = (uint16_t)sldns_buffer_limit(pkt); struct timeval when; size_t needed; uint8_t* where = NULL; - log_assert(ldns_buffer_limit(pkt) <= 65535); + log_assert(sldns_buffer_limit(pkt) <= 65535); needed = sizeof(when) + sizeof(p) + sizeof(len) + len; /* put item into ringbuffer */ if(r->low < r->high) { @@ -278,7 +279,7 @@ ring_add(struct ringbuf* r, ldns_buffer* pkt, struct timeval* now, memmove(where+sizeof(when), &p, sizeof(p)); memmove(where+sizeof(when)+sizeof(p), &len, sizeof(len)); memmove(where+sizeof(when)+sizeof(p)+sizeof(len), - ldns_buffer_begin(pkt), len); + sldns_buffer_begin(pkt), len); } /** see if the ringbuffer is empty */ @@ -299,7 +300,7 @@ ring_peek_time(struct ringbuf* r) /** get entry from ringbuffer */ static int -ring_pop(struct ringbuf* r, ldns_buffer* pkt, struct timeval* tv, +ring_pop(struct ringbuf* r, sldns_buffer* pkt, struct timeval* tv, struct proxy** p) { /* time -- proxy* -- 16bitlen -- message */ @@ -312,9 +313,9 @@ ring_pop(struct ringbuf* r, ldns_buffer* pkt, struct timeval* tv, memmove(tv, where, sizeof(*tv)); memmove(p, where+sizeof(*tv), sizeof(*p)); memmove(&len, where+sizeof(*tv)+sizeof(*p), sizeof(len)); - memmove(ldns_buffer_begin(pkt), + memmove(sldns_buffer_begin(pkt), where+sizeof(*tv)+sizeof(*p)+sizeof(len), len); - ldns_buffer_set_limit(pkt, (size_t)len); + sldns_buffer_set_limit(pkt, (size_t)len); done = sizeof(*tv)+sizeof(*p)+sizeof(len)+len; /* move lowmark */ if(r->low < r->high) { @@ -352,7 +353,7 @@ static RETSIGTYPE delayer_sigh(int sig) /** send out waiting packets */ static void -service_send(struct ringbuf* ring, struct timeval* now, ldns_buffer* pkt, +service_send(struct ringbuf* ring, struct timeval* now, sldns_buffer* pkt, struct sockaddr_storage* srv_addr, socklen_t srv_len) { struct proxy* p; @@ -367,8 +368,8 @@ service_send(struct ringbuf* ring, struct timeval* now, ldns_buffer* pkt, (unsigned)tv.tv_sec, (unsigned)tv.tv_usec); log_addr(1, "from client", &p->addr, p->addr_len); /* send it */ - sent = sendto(p->s, (void*)ldns_buffer_begin(pkt), - ldns_buffer_limit(pkt), 0, + sent = sendto(p->s, (void*)sldns_buffer_begin(pkt), + sldns_buffer_limit(pkt), 0, (struct sockaddr*)srv_addr, srv_len); if(sent == -1) { #ifndef USE_WINSOCK @@ -376,7 +377,7 @@ service_send(struct ringbuf* ring, struct timeval* now, ldns_buffer* pkt, #else log_err("sendto: %s", wsa_strerror(WSAGetLastError())); #endif - } else if(sent != (ssize_t)ldns_buffer_limit(pkt)) { + } else if(sent != (ssize_t)sldns_buffer_limit(pkt)) { log_err("sendto: partial send"); } p->lastuse = *now; @@ -386,13 +387,13 @@ service_send(struct ringbuf* ring, struct timeval* now, ldns_buffer* pkt, /** do proxy for one readable client */ static void -do_proxy(struct proxy* p, int retsock, ldns_buffer* pkt) +do_proxy(struct proxy* p, int retsock, sldns_buffer* pkt) { int i; ssize_t r; for(i=0; i<TRIES_PER_SELECT; i++) { - r = recv(p->s, (void*)ldns_buffer_begin(pkt), - ldns_buffer_capacity(pkt), 0); + r = recv(p->s, (void*)sldns_buffer_begin(pkt), + sldns_buffer_capacity(pkt), 0); if(r == -1) { #ifndef USE_WINSOCK if(errno == EAGAIN || errno == EINTR) @@ -406,11 +407,11 @@ do_proxy(struct proxy* p, int retsock, ldns_buffer* pkt) #endif return; } - ldns_buffer_set_limit(pkt, (size_t)r); + sldns_buffer_set_limit(pkt, (size_t)r); log_addr(1, "return reply to client", &p->addr, p->addr_len); /* send reply back to the real client */ p->numreturn++; - r = sendto(retsock, (void*)ldns_buffer_begin(pkt), (size_t)r, + r = sendto(retsock, (void*)sldns_buffer_begin(pkt), (size_t)r, 0, (struct sockaddr*)&p->addr, p->addr_len); if(r == -1) { #ifndef USE_WINSOCK @@ -425,7 +426,7 @@ do_proxy(struct proxy* p, int retsock, ldns_buffer* pkt) /** proxy return replies to clients */ static void service_proxy(fd_set* rset, int retsock, struct proxy* proxies, - ldns_buffer* pkt, struct timeval* now) + sldns_buffer* pkt, struct timeval* now) { struct proxy* p; for(p = proxies; p; p = p->next) { @@ -487,7 +488,7 @@ find_create_proxy(struct sockaddr_storage* from, socklen_t from_len, /** recv new waiting packets */ static void -service_recv(int s, struct ringbuf* ring, ldns_buffer* pkt, +service_recv(int s, struct ringbuf* ring, sldns_buffer* pkt, fd_set* rorig, int* max, struct proxy** proxies, struct sockaddr_storage* srv_addr, socklen_t srv_len, struct timeval* now, struct timeval* delay, struct timeval* reuse) @@ -499,8 +500,8 @@ service_recv(int s, struct ringbuf* ring, ldns_buffer* pkt, struct proxy* p; for(i=0; i<TRIES_PER_SELECT; i++) { from_len = (socklen_t)sizeof(from); - len = recvfrom(s, (void*)ldns_buffer_begin(pkt), - ldns_buffer_capacity(pkt), 0, + len = recvfrom(s, (void*)sldns_buffer_begin(pkt), + sldns_buffer_capacity(pkt), 0, (struct sockaddr*)&from, &from_len); if(len < 0) { #ifndef USE_WINSOCK @@ -515,7 +516,7 @@ service_recv(int s, struct ringbuf* ring, ldns_buffer* pkt, wsa_strerror(WSAGetLastError())); #endif } - ldns_buffer_set_limit(pkt, (size_t)len); + sldns_buffer_set_limit(pkt, (size_t)len); /* find its proxy element */ p = find_create_proxy(&from, from_len, rorig, max, proxies, addr_is_ip6(srv_addr, srv_len), now, reuse); @@ -640,11 +641,11 @@ service_tcp_listen(int s, fd_set* rorig, int* max, struct tcp_proxy** proxies, static int tcp_relay_read(int s, struct tcp_send_list** first, struct tcp_send_list** last, struct timeval* now, - struct timeval* delay, ldns_buffer* pkt) + struct timeval* delay, sldns_buffer* pkt) { struct tcp_send_list* item; - ssize_t r = recv(s, (void*)ldns_buffer_begin(pkt), - ldns_buffer_capacity(pkt), 0); + ssize_t r = recv(s, (void*)sldns_buffer_begin(pkt), + sldns_buffer_capacity(pkt), 0); if(r == -1) { #ifndef USE_WINSOCK if(errno == EINTR || errno == EAGAIN) @@ -668,7 +669,7 @@ tcp_relay_read(int s, struct tcp_send_list** first, } verbose(1, "read item len %d", (int)r); item->len = (size_t)r; - item->item = memdup(ldns_buffer_begin(pkt), item->len); + item->item = memdup(sldns_buffer_begin(pkt), item->len); if(!item->item) { free(item); log_err("out of memory"); @@ -740,7 +741,7 @@ tcp_relay_write(int s, struct tcp_send_list** first, /** perform TCP relaying */ static void service_tcp_relay(struct tcp_proxy** tcp_proxies, struct timeval* now, - struct timeval* delay, struct timeval* tcp_timeout, ldns_buffer* pkt, + struct timeval* delay, struct timeval* tcp_timeout, sldns_buffer* pkt, fd_set* rset, fd_set* rorig, fd_set* worig) { struct tcp_proxy* p, **prev; @@ -889,12 +890,12 @@ proxy_list_clear(struct proxy* p) if(inet_ntop(AF_INET6, &((struct sockaddr_in6*)&p->addr)->sin6_addr, from, (socklen_t)sizeof(from)) == 0) - strncpy(from, "err", sizeof(from)); + (void)strlcpy(from, "err", sizeof(from)); } else { if(inet_ntop(AF_INET, &((struct sockaddr_in*)&p->addr)->sin_addr, from, (socklen_t)sizeof(from)) == 0) - strncpy(from, "err", sizeof(from)); + (void)strlcpy(from, "err", sizeof(from)); } printf("client[%d]: last %s@%d of %d : %u in, %u out, " "%u returned\n", i++, from, port, (int)p->numreuse+1, @@ -927,7 +928,7 @@ static void service_loop(int udp_s, int listen_s, struct ringbuf* ring, struct timeval* delay, struct timeval* reuse, struct sockaddr_storage* srv_addr, socklen_t srv_len, - ldns_buffer* pkt) + sldns_buffer* pkt) { fd_set rset, rorig; fd_set wset, worig; @@ -996,7 +997,7 @@ service(const char* bind_str, int bindport, const char* serv_str, socklen_t bind_len, srv_len; struct ringbuf* ring = ring_create(memsize); struct timeval delay, reuse; - ldns_buffer* pkt; + sldns_buffer* pkt; int i, s, listen_s; #ifndef S_SPLINT_S delay.tv_sec = delay_msec / 1000; @@ -1012,7 +1013,7 @@ service(const char* bind_str, int bindport, const char* serv_str, printf("cannot parse forward address: %s\n", serv_str); exit(1); } - pkt = ldns_buffer_new(65535); + pkt = sldns_buffer_new(65535); if(!pkt) fatal_exit("out of memory"); if( signal(SIGINT, delayer_sigh) == SIG_ERR || @@ -1115,7 +1116,7 @@ service(const char* bind_str, int bindport, const char* serv_str, closesocket(s); closesocket(listen_s); #endif - ldns_buffer_free(pkt); + sldns_buffer_free(pkt); ring_delete(ring); } diff --git a/testcode/fake_event.c b/testcode/fake_event.c index 085068c67c56..47e4b78da0bf 100644 --- a/testcode/fake_event.c +++ b/testcode/fake_event.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -57,9 +57,12 @@ #include "services/outside_network.h" #include "services/cache/infra.h" #include "testcode/replay.h" -#include "testcode/ldns-testpkts.h" +#include "testcode/testpkts.h" #include "util/log.h" #include "util/fptr_wlist.h" +#include "ldns/sbuffer.h" +#include "ldns/wire2str.h" +#include "ldns/str2wire.h" #include <signal.h> struct worker; struct daemon_remote; @@ -106,13 +109,13 @@ fake_event_cleanup(void) saved_scenario = NULL; } -/** helper function that logs a ldns_pkt packet to logfile */ +/** helper function that logs a sldns_pkt packet to logfile */ static void -log_pkt(const char* desc, ldns_pkt* pkt) +log_pkt(const char* desc, uint8_t* pkt, size_t len) { - char* str = ldns_pkt2str(pkt); + char* str = sldns_wire2str_pkt(pkt, len); if(!str) - log_info("%s: (failed)", desc); + fatal_exit("%s: (failed out of memory wire2str_pkt)", desc); else { log_info("%s%s", desc, str); free(str); @@ -149,8 +152,8 @@ delete_fake_pending(struct fake_pending* pend) if(!pend) return; free(pend->zone); - ldns_buffer_free(pend->buffer); - ldns_pkt_free(pend->pkt); + sldns_buffer_free(pend->buffer); + free(pend->pkt); free(pend); } @@ -161,10 +164,10 @@ delete_replay_answer(struct replay_answer* a) if(!a) return; if(a->repinfo.c) { - ldns_buffer_free(a->repinfo.c->buffer); + sldns_buffer_free(a->repinfo.c->buffer); free(a->repinfo.c); } - ldns_pkt_free(a->pkt); + free(a->pkt); free(a); } @@ -186,7 +189,8 @@ pending_matches_current(struct replay_runtime* runtime, sockaddr_cmp(&p->addr, p->addrlen, &runtime->now->addr, runtime->now->addrlen) != 0) continue; - if((e=find_match(runtime->now->match, p->pkt, p->transport))) { + if((e=find_match(runtime->now->match, p->pkt, p->pkt_len, + p->transport))) { *entry = e; *pend = p; return 1; @@ -212,13 +216,16 @@ pending_find_match(struct replay_runtime* runtime, struct entry** entry, if(p->start_step <= timenow && timenow <= p->end_step && (p->addrlen == 0 || sockaddr_cmp(&p->addr, p->addrlen, &pend->addr, pend->addrlen) == 0) && - (*entry = find_match(p->match, pend->pkt, pend->transport))) { + (*entry = find_match(p->match, pend->pkt, pend->pkt_len, + pend->transport))) { log_info("matched query time %d in range [%d, %d] " "with entry line %d", timenow, p->start_step, p->end_step, (*entry)->lineno); if(p->addrlen != 0) log_addr(0, "matched ip", &p->addr, p->addrlen); - log_pkt("matched pkt: ", (*entry)->reply_list->reply); + log_pkt("matched pkt: ", + (*entry)->reply_list->reply_pkt, + (*entry)->reply_list->reply_len); return 1; } p = p->next_range; @@ -275,32 +282,27 @@ pending_list_delete(struct replay_runtime* runtime, struct fake_pending* pend) * Fill buffer with reply from the entry. */ static void -fill_buffer_with_reply(ldns_buffer* buffer, struct entry* entry, ldns_pkt* q) +fill_buffer_with_reply(sldns_buffer* buffer, struct entry* entry, uint8_t* q, + size_t qlen) { - ldns_status status; - ldns_pkt* answer_pkt = NULL; + uint8_t* c; + size_t clen; log_assert(entry && entry->reply_list); - ldns_buffer_clear(buffer); + sldns_buffer_clear(buffer); if(entry->reply_list->reply_from_hex) { - status = ldns_buffer2pkt_wire(&answer_pkt, - entry->reply_list->reply_from_hex); - if(status != LDNS_STATUS_OK) { - log_err("testbound: hex packet unparsable, used asis."); - ldns_buffer_write(buffer, - ldns_buffer_begin(entry->reply_list->reply_from_hex), - ldns_buffer_limit(entry->reply_list->reply_from_hex)); - } + c = sldns_buffer_begin(entry->reply_list->reply_from_hex); + clen = sldns_buffer_limit(entry->reply_list->reply_from_hex); + if(!c) fatal_exit("out of memory"); } else { - answer_pkt = ldns_pkt_clone(entry->reply_list->reply); + c = entry->reply_list->reply_pkt; + clen = entry->reply_list->reply_len; } - if(answer_pkt) { - if(q) adjust_packet(entry, answer_pkt, q); - status = ldns_pkt2buffer_wire(buffer, answer_pkt); - if(status != LDNS_STATUS_OK) - fatal_exit("ldns: cannot pkt2buffer_wire parsed pkt"); + if(c) { + if(q) adjust_packet(entry, &c, &clen, q, qlen); + sldns_buffer_write(buffer, c, clen); + if(q) free(c); } - ldns_pkt_free(answer_pkt); - ldns_buffer_flip(buffer); + sldns_buffer_flip(buffer); } /** @@ -320,11 +322,11 @@ answer_callback_from_entry(struct replay_runtime* runtime, memset(&c, 0, sizeof(c)); c.fd = -1; - c.buffer = ldns_buffer_new(runtime->bufsize); + c.buffer = sldns_buffer_new(runtime->bufsize); c.type = comm_udp; if(pend->transport == transport_tcp) c.type = comm_tcp; - fill_buffer_with_reply(c.buffer, entry, pend->pkt); + fill_buffer_with_reply(c.buffer, entry, pend->pkt, pend->pkt_len); repinfo.c = &c; repinfo.addrlen = pend->addrlen; memcpy(&repinfo.addr, &pend->addr, pend->addrlen); @@ -333,7 +335,7 @@ answer_callback_from_entry(struct replay_runtime* runtime, if((*cb)(&c, cb_arg, NETEVENT_NOERROR, &repinfo)) { fatal_exit("testbound: unexpected: callback returned 1"); } - ldns_buffer_free(c.buffer); + sldns_buffer_free(c.buffer); } /** Check the now moment answer check event */ @@ -351,7 +353,8 @@ answer_check_it(struct replay_runtime* runtime) if((runtime->now->addrlen == 0 || sockaddr_cmp( &runtime->now->addr, runtime->now->addrlen, &ans->repinfo.addr, ans->repinfo.addrlen) == 0) && - find_match(runtime->now->match, ans->pkt, tr)) { + find_match(runtime->now->match, ans->pkt, + ans->pkt_len, tr)) { log_info("testbound matched event entry from line %d", runtime->now->match->lineno); log_info("testbound: do STEP %d %s", @@ -390,13 +393,14 @@ fake_front_query(struct replay_runtime* runtime, struct replay_moment *todo) } repinfo.c->fd = -1; repinfo.c->ev = (struct internal_event*)runtime; - repinfo.c->buffer = ldns_buffer_new(runtime->bufsize); + repinfo.c->buffer = sldns_buffer_new(runtime->bufsize); if(todo->match->match_transport == transport_tcp) repinfo.c->type = comm_tcp; else repinfo.c->type = comm_udp; - fill_buffer_with_reply(repinfo.c->buffer, todo->match, NULL); + fill_buffer_with_reply(repinfo.c->buffer, todo->match, NULL, 0); log_info("testbound: incoming QUERY"); - log_pkt("query pkt", todo->match->reply_list->reply); + log_pkt("query pkt", todo->match->reply_list->reply_pkt, + todo->match->reply_list->reply_len); /* call the callback for incoming queries */ if((*runtime->callback_query)(repinfo.c, runtime->cb_arg, NETEVENT_NOERROR, &repinfo)) { @@ -424,13 +428,13 @@ fake_pending_callback(struct replay_runtime* runtime, if(!p) fatal_exit("No pending queries."); cb_arg = p->cb_arg; cb = p->callback; - log_assert(todo->qname == NULL); /* or find that one */ - c.buffer = ldns_buffer_new(runtime->bufsize); + c.buffer = sldns_buffer_new(runtime->bufsize); c.type = comm_udp; if(p->transport == transport_tcp) c.type = comm_tcp; if(todo->evt_type == repevt_back_reply && todo->match) { - fill_buffer_with_reply(c.buffer, todo->match, p->pkt); + fill_buffer_with_reply(c.buffer, todo->match, p->pkt, + p->pkt_len); } repinfo.c = &c; repinfo.addrlen = p->addrlen; @@ -441,7 +445,7 @@ fake_pending_callback(struct replay_runtime* runtime, fatal_exit("unexpected: pending callback returned 1"); } /* delete the pending item. */ - ldns_buffer_free(c.buffer); + sldns_buffer_free(c.buffer); } /** pass time */ @@ -552,16 +556,17 @@ do_infra_rtt(struct replay_runtime* runtime) { struct replay_moment* now = runtime->now; int rto; - ldns_rdf* dp = ldns_dname_new_frm_str(now->variable); + size_t dplen = 0; + uint8_t* dp = sldns_str2wire_dname(now->variable, &dplen); if(!dp) fatal_exit("cannot parse %s", now->variable); - rto = infra_rtt_update(runtime->infra, &now->addr, - now->addrlen, ldns_rdf_data(dp), ldns_rdf_size(dp), - LDNS_RR_TYPE_A, atoi(now->string), -1, runtime->now_secs); + rto = infra_rtt_update(runtime->infra, &now->addr, now->addrlen, + dp, dplen, LDNS_RR_TYPE_A, atoi(now->string), + -1, runtime->now_secs); log_addr(0, "INFRA_RTT for", &now->addr, now->addrlen); log_info("INFRA_RTT(%s roundtrip %d): rto of %d", now->variable, atoi(now->string), rto); if(rto == 0) fatal_exit("infra_rtt_update failed"); - ldns_rdf_deep_free(dp); + free(dp); } /** perform exponential backoff on the timout */ @@ -712,7 +717,7 @@ run_scenario(struct replay_runtime* runtime) struct fake_pending* p; log_err("testbound: there are still messages pending."); for(p = runtime->pending_list; p; p=p->next) { - log_pkt("pending msg", p->pkt); + log_pkt("pending msg", p->pkt, p->pkt_len); log_addr(0, "pending to", &p->addr, p->addrlen); } fatal_exit("testbound: there are still messages pending."); @@ -736,7 +741,7 @@ listen_create(struct comm_base* base, struct listen_port* ATTR_UNUSED(ports), if(!l) return NULL; l->base = base; - l->udp_buff = ldns_buffer_new(bufsize); + l->udp_buff = sldns_buffer_new(bufsize); if(!l->udp_buff) { free(l); return NULL; @@ -752,7 +757,7 @@ listen_delete(struct listen_dnsport* listen) { if(!listen) return; - ldns_buffer_free(listen->udp_buff); + sldns_buffer_free(listen->udp_buff); free(listen); } @@ -856,7 +861,6 @@ comm_point_send_reply(struct comm_reply* repinfo) { struct replay_answer* ans = (struct replay_answer*)calloc(1, sizeof(struct replay_answer)); - ldns_status status; struct replay_runtime* runtime = (struct replay_runtime*)repinfo->c->ev; log_info("testbound: comm_point_send_reply fake"); /* dump it into the todo list */ @@ -869,13 +873,11 @@ comm_point_send_reply(struct comm_reply* repinfo) runtime->answer_last = ans; /* try to parse packet */ - status = ldns_buffer2pkt_wire(&ans->pkt, ans->repinfo.c->buffer); - if(status != LDNS_STATUS_OK) { - log_err("ldns error parsing packet: %s", - ldns_get_errorstr_by_id(status)); - fatal_exit("Sending unparseable DNS replies to clients!"); - } - log_pkt("reply pkt: ", ans->pkt); + ans->pkt = memdup(sldns_buffer_begin(ans->repinfo.c->buffer), + sldns_buffer_limit(ans->repinfo.c->buffer)); + ans->pkt_len = sldns_buffer_limit(ans->repinfo.c->buffer); + if(!ans->pkt) fatal_exit("out of memory"); + log_pkt("reply pkt: ", ans->pkt, ans->pkt_len); } void @@ -883,7 +885,7 @@ comm_point_drop_reply(struct comm_reply* repinfo) { log_info("comm_point_drop_reply fake"); if(repinfo->c) { - ldns_buffer_free(repinfo->c->buffer); + sldns_buffer_free(repinfo->c->buffer); free(repinfo->c); } } @@ -898,7 +900,8 @@ outside_network_create(struct comm_base* base, size_t bufsize, int ATTR_UNUSED(use_caps_for_id), int* ATTR_UNUSED(availports), int ATTR_UNUSED(numavailports), size_t ATTR_UNUSED(unwanted_threshold), void (*unwanted_action)(void*), void* ATTR_UNUSED(unwanted_param), - int ATTR_UNUSED(do_udp), void* ATTR_UNUSED(sslctx)) + int ATTR_UNUSED(do_udp), void* ATTR_UNUSED(sslctx), + int ATTR_UNUSED(delayclose)) { struct replay_runtime* runtime = (struct replay_runtime*)base; struct outside_network* outnet = calloc(1, @@ -908,7 +911,7 @@ outside_network_create(struct comm_base* base, size_t bufsize, return NULL; runtime->infra = infra; outnet->base = base; - outnet->udp_buff = ldns_buffer_new(bufsize); + outnet->udp_buff = sldns_buffer_new(bufsize); if(!outnet->udp_buff) { free(outnet); return NULL; @@ -921,7 +924,7 @@ outside_network_delete(struct outside_network* outnet) { if(!outnet) return; - ldns_buffer_free(outnet->udp_buff); + sldns_buffer_free(outnet->udp_buff); free(outnet); } @@ -931,20 +934,19 @@ outside_network_quit_prepare(struct outside_network* ATTR_UNUSED(outnet)) } struct pending* -pending_udp_query(struct outside_network* outnet, ldns_buffer* packet, +pending_udp_query(struct outside_network* outnet, sldns_buffer* packet, struct sockaddr_storage* addr, socklen_t addrlen, int timeout, comm_point_callback_t* callback, void* callback_arg) { struct replay_runtime* runtime = (struct replay_runtime*)outnet->base; struct fake_pending* pend = (struct fake_pending*)calloc(1, sizeof(struct fake_pending)); - ldns_status status; log_assert(pend); - pend->buffer = ldns_buffer_new(ldns_buffer_capacity(packet)); + pend->buffer = sldns_buffer_new(sldns_buffer_capacity(packet)); log_assert(pend->buffer); - ldns_buffer_write(pend->buffer, ldns_buffer_begin(packet), - ldns_buffer_limit(packet)); - ldns_buffer_flip(pend->buffer); + sldns_buffer_write(pend->buffer, sldns_buffer_begin(packet), + sldns_buffer_limit(packet)); + sldns_buffer_flip(pend->buffer); memcpy(&pend->addr, addr, addrlen); pend->addrlen = addrlen; pend->callback = callback; @@ -955,20 +957,18 @@ pending_udp_query(struct outside_network* outnet, ldns_buffer* packet, pend->zone = NULL; pend->serviced = 0; pend->runtime = runtime; - status = ldns_buffer2pkt_wire(&pend->pkt, packet); - if(status != LDNS_STATUS_OK) { - log_err("ldns error parsing udp output packet: %s", - ldns_get_errorstr_by_id(status)); - fatal_exit("Sending unparseable DNS packets to servers!"); - } - log_pkt("pending udp pkt: ", pend->pkt); + pend->pkt_len = sldns_buffer_limit(packet); + pend->pkt = memdup(sldns_buffer_begin(packet), pend->pkt_len); + if(!pend->pkt) fatal_exit("out of memory"); + log_pkt("pending udp pkt: ", pend->pkt, pend->pkt_len); /* see if it matches the current moment */ if(runtime->now && runtime->now->evt_type == repevt_back_query && (runtime->now->addrlen == 0 || sockaddr_cmp( &runtime->now->addr, runtime->now->addrlen, &pend->addr, pend->addrlen) == 0) && - find_match(runtime->now->match, pend->pkt, pend->transport)) { + find_match(runtime->now->match, pend->pkt, pend->pkt_len, + pend->transport)) { log_info("testbound: matched pending to event. " "advance time between events."); log_info("testbound: do STEP %d %s", runtime->now->time_step, @@ -984,7 +984,7 @@ pending_udp_query(struct outside_network* outnet, ldns_buffer* packet, } struct waiting_tcp* -pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet, +pending_tcp_query(struct outside_network* outnet, sldns_buffer* packet, struct sockaddr_storage* addr, socklen_t addrlen, int timeout, comm_point_callback_t* callback, void* callback_arg, int ATTR_UNUSED(ssl_upstream)) @@ -992,13 +992,12 @@ pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet, struct replay_runtime* runtime = (struct replay_runtime*)outnet->base; struct fake_pending* pend = (struct fake_pending*)calloc(1, sizeof(struct fake_pending)); - ldns_status status; log_assert(pend); - pend->buffer = ldns_buffer_new(ldns_buffer_capacity(packet)); + pend->buffer = sldns_buffer_new(sldns_buffer_capacity(packet)); log_assert(pend->buffer); - ldns_buffer_write(pend->buffer, ldns_buffer_begin(packet), - ldns_buffer_limit(packet)); - ldns_buffer_flip(pend->buffer); + sldns_buffer_write(pend->buffer, sldns_buffer_begin(packet), + sldns_buffer_limit(packet)); + sldns_buffer_flip(pend->buffer); memcpy(&pend->addr, addr, addrlen); pend->addrlen = addrlen; pend->callback = callback; @@ -1009,20 +1008,18 @@ pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet, pend->zone = NULL; pend->runtime = runtime; pend->serviced = 0; - status = ldns_buffer2pkt_wire(&pend->pkt, packet); - if(status != LDNS_STATUS_OK) { - log_err("ldns error parsing tcp output packet: %s", - ldns_get_errorstr_by_id(status)); - fatal_exit("Sending unparseable DNS packets to servers!"); - } - log_pkt("pending tcp pkt: ", pend->pkt); + pend->pkt_len = sldns_buffer_limit(packet); + pend->pkt = memdup(sldns_buffer_begin(packet), pend->pkt_len); + if(!pend->pkt) fatal_exit("out of memory"); + log_pkt("pending tcp pkt: ", pend->pkt, pend->pkt_len); /* see if it matches the current moment */ if(runtime->now && runtime->now->evt_type == repevt_back_query && (runtime->now->addrlen == 0 || sockaddr_cmp( &runtime->now->addr, runtime->now->addrlen, &pend->addr, pend->addrlen) == 0) && - find_match(runtime->now->match, pend->pkt, pend->transport)) { + find_match(runtime->now->match, pend->pkt, pend->pkt_len, + pend->transport)) { log_info("testbound: matched pending to event. " "advance time between events."); log_info("testbound: do STEP %d %s", runtime->now->time_step, @@ -1043,13 +1040,12 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet, int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream), struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, size_t zonelen, comm_point_callback_t* callback, void* callback_arg, - ldns_buffer* ATTR_UNUSED(buff)) + sldns_buffer* ATTR_UNUSED(buff)) { struct replay_runtime* runtime = (struct replay_runtime*)outnet->base; struct fake_pending* pend = (struct fake_pending*)calloc(1, sizeof(struct fake_pending)); char z[256]; - ldns_status status; log_assert(pend); log_nametypeclass(VERB_OPS, "pending serviced query", qname, qtype, qclass); @@ -1059,18 +1055,18 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet, (flags&~(BIT_RD|BIT_CD))?" MORE":"", (dnssec)?" DO":""); /* create packet with EDNS */ - pend->buffer = ldns_buffer_new(512); + pend->buffer = sldns_buffer_new(512); log_assert(pend->buffer); - ldns_buffer_write_u16(pend->buffer, 0); /* id */ - ldns_buffer_write_u16(pend->buffer, flags); - ldns_buffer_write_u16(pend->buffer, 1); /* qdcount */ - ldns_buffer_write_u16(pend->buffer, 0); /* ancount */ - ldns_buffer_write_u16(pend->buffer, 0); /* nscount */ - ldns_buffer_write_u16(pend->buffer, 0); /* arcount */ - ldns_buffer_write(pend->buffer, qname, qnamelen); - ldns_buffer_write_u16(pend->buffer, qtype); - ldns_buffer_write_u16(pend->buffer, qclass); - ldns_buffer_flip(pend->buffer); + sldns_buffer_write_u16(pend->buffer, 0); /* id */ + sldns_buffer_write_u16(pend->buffer, flags); + sldns_buffer_write_u16(pend->buffer, 1); /* qdcount */ + sldns_buffer_write_u16(pend->buffer, 0); /* ancount */ + sldns_buffer_write_u16(pend->buffer, 0); /* nscount */ + sldns_buffer_write_u16(pend->buffer, 0); /* arcount */ + sldns_buffer_write(pend->buffer, qname, qnamelen); + sldns_buffer_write_u16(pend->buffer, qtype); + sldns_buffer_write_u16(pend->buffer, qclass); + sldns_buffer_flip(pend->buffer); if(1) { /* add edns */ struct edns_data edns; @@ -1096,20 +1092,18 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet, pend->pkt = NULL; pend->runtime = runtime; pend->serviced = 1; - status = ldns_buffer2pkt_wire(&pend->pkt, pend->buffer); - if(status != LDNS_STATUS_OK) { - log_err("ldns error parsing serviced output packet: %s", - ldns_get_errorstr_by_id(status)); - fatal_exit("internal error"); - } - /*log_pkt("pending serviced query: ", pend->pkt);*/ + pend->pkt_len = sldns_buffer_limit(pend->buffer); + pend->pkt = memdup(sldns_buffer_begin(pend->buffer), pend->pkt_len); + if(!pend->pkt) fatal_exit("out of memory"); + /*log_pkt("pending serviced query: ", pend->pkt, pend->pkt_len);*/ /* see if it matches the current moment */ if(runtime->now && runtime->now->evt_type == repevt_back_query && (runtime->now->addrlen == 0 || sockaddr_cmp( &runtime->now->addr, runtime->now->addrlen, &pend->addr, pend->addrlen) == 0) && - find_match(runtime->now->match, pend->pkt, pend->transport)) { + find_match(runtime->now->match, pend->pkt, pend->pkt_len, + pend->transport)) { log_info("testbound: matched pending to event. " "advance time between events."); log_info("testbound: do STEP %d %s", runtime->now->time_step, @@ -1137,8 +1131,8 @@ void outnet_serviced_query_stop(struct serviced_query* sq, void* cb_arg) if(prev) prev->next = p->next; else runtime->pending_list = p->next; - ldns_buffer_free(p->buffer); - ldns_pkt_free(p->pkt); + sldns_buffer_free(p->buffer); + free(p->pkt); free(p->zone); free(p); return; @@ -1149,7 +1143,8 @@ void outnet_serviced_query_stop(struct serviced_query* sq, void* cb_arg) log_info("double delete of pending serviced query"); } -struct listen_port* listening_ports_open(struct config_file* ATTR_UNUSED(cfg)) +struct listen_port* listening_ports_open(struct config_file* ATTR_UNUSED(cfg), + int* ATTR_UNUSED(reuseport)) { return calloc(1, 1); } @@ -1235,6 +1230,11 @@ void pending_udp_timer_cb(void *ATTR_UNUSED(arg)) log_assert(0); } +void pending_udp_timer_delay_cb(void *ATTR_UNUSED(arg)) +{ + log_assert(0); +} + void outnet_tcptimer(void* ATTR_UNUSED(arg)) { log_assert(0); diff --git a/testcode/fake_event.h b/testcode/fake_event.h index 1a73de824c11..97ebb41cba0c 100644 --- a/testcode/fake_event.h +++ b/testcode/fake_event.h @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/testcode/harvest.c b/testcode/harvest.c deleted file mode 100644 index 1952dc2a221f..000000000000 --- a/testcode/harvest.c +++ /dev/null @@ -1,857 +0,0 @@ -/* - * testcode/harvest.c - debug program to get relevant data to a set of queries. - * - * Copyright (c) 2008, NLnet Labs. All rights reserved. - * - * This software is open source. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of the NLNET LABS nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * \file - * - * This program downloads relevant DNS data to a set of queries. - * This means that the queries are asked to root, TLD, SLD servers and - * the results stored per zone. - * The following data is pertinent: - * - * At each label: - * SOA - * NS - * DNSKEY - * DS - * For the whole query: - * the result. - * For NS-records: - * their label data - * and the A and AAAA records for it. - * (as if the name, with A and AAAA query type is in the list, - * referred to as recursion depth+1) - * Any NSEC, NSEC3, SOA records or additional data found in answers. - * - * All of this is data that would be encountered during an iterative lookup - * for the queries in the list. It is saved to enable a replay of iterative - * lookups for performance testing. - * - * A number of assumptions are made. - * 1) configuration is correct. - * The parent has the same NS records as the child. - * All nameservers carry the same data. - * 2) EDNS/nonEDNS responses and other behaviour is ignored. - * Only the data is saved. - * This creates a snapshot that represents the data as this resolver saw it. - */ - -#include "config.h" -#ifdef HAVE_GETOPT_H -#include <getopt.h> -#endif -#include <ldns/ldns.h> -#include <signal.h> -#include "libunbound/unbound.h" -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif -#ifdef UNBOUND_ALLOC_LITE -#undef malloc -#undef calloc -#undef realloc -#undef free -#undef strdup -#define unbound_lite_wrapstr(s) s -#endif -struct todo_item; -struct labdata; - -/** this represents the data that has been collected - * as well as a todo list and some settings */ -struct harvest_data { - /** the unbound context */ - struct ub_ctx* ctx; - - /** a tree per label; thus this first one is one root entry, - * that has a tree of TLD labels. Those have trees of SLD labels. */ - struct labdata* root; - /** the original query list */ - struct todo_item* orig_list; - /** the query list todo */ - struct todo_item* todo_list; - /** last item in todo list */ - struct todo_item* todo_last; - /** number of todo items */ - int numtodo; - - /** where to store the results */ - char* resultdir; - /** maximum recursion depth */ - int maxdepth; - /** current recursion depth */ - int curdepth; - - /** max depth of labels */ - int maxlabels; - /** number of RRs stored */ - int num_rrs; - /** number of zones written */ - int num_zones; -}; - -/** - * Todo item - */ -struct todo_item { - /** the next item */ - struct todo_item* next; - - /** query as rdf */ - ldns_rdf* qname; - /** the query type */ - int qtype; - /** query class */ - int qclass; - - /** recursion depth of todo item (orig list is 0) */ - int depth; - /** the label associated with the query */ - struct labdata* lab; -}; - -/** - * Every label has a sest of sublabels, that have sets of sublabels ... - * Per label is stored also a set of data items, and todo information - */ -struct labdata { - /** node in ldns rbtree */ - ldns_rbnode_t node; - /** the name of this label */ - ldns_rdf* label; - /** full name of point in domain tree */ - ldns_rdf* name; - - /** parent in label tree (NULL for root) */ - struct labdata* parent; - /** tree of sublabels (if any) */ - ldns_rbtree_t* sublabels; - - /** list of RRs for this label */ - ldns_rr_list* rrlist; - /** have queries for this label been queued */ - int done; -}; - -/** usage information for harvest */ -static void usage(char* nm) -{ - printf("usage: %s [options]\n", nm); - printf("-f fnm query list to read from file\n"); - printf(" every line has format: qname qclass qtype\n"); - printf("-v verbose (-v -v even more)\n"); - printf("-C cfg config file with resolver options\n"); - exit(1); -} - -/** verbosity for harvest */ -static int hverb = 0; - -/** exit with error */ -static void error_exit(const char* str) -{ - printf("error: %s\n", str); - exit(1); -} - -/** read a query file */ -static void -qlist_read_file(struct harvest_data* data, char* fname) -{ - char buf[1024]; - char nm[1024], cl[1024], tp[1024]; - int r; - int num = 0; - FILE* in = fopen(fname, "r"); - struct todo_item* t; - if(!in) { - perror(fname); - error_exit("could not open file"); - } - while(fgets(buf, (int)sizeof(buf), in)) { - if(buf[0] == 0) continue; - if(buf[0] == '\n') continue; - /* allow some comments */ - if(buf[0] == ';') continue; - if(buf[0] == '#') continue; - nm[0] = 0; cl[0] = 0; tp[0] = 0; - r = sscanf(buf, " %1023s %1023s %1023s", nm, cl, tp); - if(r == 0) continue; - t = (struct todo_item*)calloc(1, sizeof(*t)); - if(!t) error_exit("out of memory"); - t->qname = ldns_dname_new_frm_str(nm); - if(!t->qname) { - printf("parse error: %s\n", nm); - error_exit("bad qname"); - } - t->depth = 0; - t->qtype = LDNS_RR_TYPE_A; - t->qclass = LDNS_RR_CLASS_IN; - if(r >= 2) { - if(strcmp(cl, "IN") == 0 || strcmp(cl, "CH") == 0) - t->qclass = ldns_get_rr_class_by_name(cl); - else t->qtype = ldns_get_rr_type_by_name(cl); - } - if(r >= 3) { - if(strcmp(tp, "IN") == 0 || strcmp(tp, "CH") == 0) - t->qclass = ldns_get_rr_class_by_name(tp); - else t->qtype = ldns_get_rr_type_by_name(tp); - } - num++; - - t->next = data->orig_list; - data->orig_list = t; - } - printf("read %s: %d queries\n", fname, num); - fclose(in); -} - -/** compare two labels */ -static int -lab_cmp(const void *x, const void *y) -{ - return ldns_dname_compare((const ldns_rdf*)x, (const ldns_rdf*)y); -} - -/** create label entry */ -static struct labdata* -lab_create(const char* name) -{ - struct labdata* lab = (struct labdata*)calloc(1, sizeof(*lab)); - if(!lab) error_exit("out of memory"); - lab->label = ldns_dname_new_frm_str(name); - if(!lab->label) error_exit("out of memory"); - lab->name = ldns_dname_new_frm_str(name); - if(!lab->name) error_exit("out of memory"); - lab->node.key = lab->label; - lab->node.data = lab; - lab->sublabels = ldns_rbtree_create(lab_cmp); - if(!lab->sublabels) error_exit("out of memory"); - lab->rrlist = ldns_rr_list_new(); - if(!lab->rrlist) error_exit("out of memory"); - - return lab; -} - -/** for this name, lookup the label, create if does not exist */ -static struct labdata* -find_create_lab(struct harvest_data* data, ldns_rdf* name) -{ - struct labdata* lab = data->root; - struct labdata* nextlab; - ldns_rdf* next; - uint8_t numlab = ldns_dname_label_count(name); - if((int)numlab > data->maxlabels) - data->maxlabels = (int)numlab; - while(numlab--) { - next = ldns_dname_label(name, numlab); - if(!next) error_exit("ldns_dname_label"); - - nextlab = (struct labdata*) - ldns_rbtree_search(lab->sublabels, next); - if(!nextlab) { - /* create it */ - nextlab = (struct labdata*)calloc(1, sizeof(*lab)); - if(!nextlab) error_exit("out of memory"); - nextlab->label = ldns_rdf_clone(next); - if(!nextlab->label) error_exit("out of memory"); - nextlab->node.key = nextlab->label; - nextlab->node.data = nextlab; - nextlab->sublabels = ldns_rbtree_create(lab_cmp); - if(!nextlab->sublabels) error_exit("out of memory"); - nextlab->parent = lab; - nextlab->name = ldns_rdf_clone(next); - if(!nextlab->name) error_exit("out of memory"); - if(ldns_dname_cat(nextlab->name, lab->name) - != LDNS_STATUS_OK) error_exit("outofmem"); - nextlab->rrlist = ldns_rr_list_new(); - if(!nextlab->rrlist) error_exit("out of memory"); - (void)ldns_rbtree_insert(lab->sublabels, - &nextlab->node); - if(hverb) { - printf("new label: "); - ldns_rdf_print(stdout, nextlab->name); - printf("\n"); - } - } - lab = nextlab; - ldns_rdf_deep_free(next); - } - return lab; -} - -/** for given query, create todo items, and labels if needed */ -static void -new_todo_item(struct harvest_data* data, ldns_rdf* qname, int qtype, - int qclass, int depth) -{ - struct labdata* lab = find_create_lab(data, qname); - struct todo_item* it; - if(!lab) error_exit("out of memory creating new label"); - it = (struct todo_item*)calloc(1, sizeof(*it)); - it->qname = ldns_rdf_clone(qname); - it->qtype = qtype; - it->qclass = qclass; - it->depth = depth; - it->lab = lab; - it->next = NULL; - if(data->todo_last) - data->todo_last->next = it; - else data->todo_list = it; - data->todo_last = it; - data->numtodo ++; - if(hverb >= 2) { - printf("new todo: "); - ldns_rdf_print(stdout, it->qname); - if(ldns_rr_descript((uint16_t)it->qtype) && - ldns_rr_descript((uint16_t)it->qtype)->_name) - printf(" %s", ldns_rr_descript((uint16_t) - it->qtype)->_name); - if(ldns_lookup_by_id(ldns_rr_classes, it->qclass) && - ldns_lookup_by_id(ldns_rr_classes, it->qclass)->name) - printf(" %s", ldns_lookup_by_id(ldns_rr_classes, - it->qclass)->name); - printf("\n"); - } -} - -/** add infra todo items for this query */ -static void -new_todo_infra(struct harvest_data* data, struct labdata* startlab, int depth) -{ - struct labdata* lab; - for(lab = startlab; lab; lab = lab->parent) { - if(lab->done) - return; - new_todo_item(data, lab->name, LDNS_RR_TYPE_NS, - LDNS_RR_CLASS_IN, depth); - new_todo_item(data, lab->name, LDNS_RR_TYPE_SOA, - LDNS_RR_CLASS_IN, depth); - new_todo_item(data, lab->name, LDNS_RR_TYPE_DNSKEY, - LDNS_RR_CLASS_IN, depth); - new_todo_item(data, lab->name, LDNS_RR_TYPE_DS, - LDNS_RR_CLASS_IN, depth); - new_todo_item(data, lab->name, LDNS_RR_TYPE_A, - LDNS_RR_CLASS_IN, depth); - new_todo_item(data, lab->name, LDNS_RR_TYPE_AAAA, - LDNS_RR_CLASS_IN, depth); - lab->done = 1; - } -} - -/** make todo items for initial data */ -static void -make_todo(struct harvest_data* data) -{ - struct todo_item* it; - for(it=data->orig_list; it; it = it->next) { - /* create todo item for this query itself */ - new_todo_item(data, it->qname, it->qtype, it->qclass, 0); - /* create todo items for infra queries to support it */ - new_todo_infra(data, data->todo_list->lab, - data->todo_list->depth); - } -} - -/** store RR and make new work items for it if needed */ -static void -process_rr(struct harvest_data* data, ldns_rr* rr, int depth) -{ - /* must free or store rr */ - struct labdata* lab = find_create_lab(data, ldns_rr_owner(rr)); - if(!lab) error_exit("cannot find/create label"); - /* generate extra queries */ - if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_NS) { - new_todo_infra(data, find_create_lab(data, - ldns_rr_ns_nsdname(rr)), depth+1); - } else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_MX) { - new_todo_infra(data, find_create_lab(data, - ldns_rr_mx_exchange(rr)), depth+1); - } else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) { - new_todo_infra(data, find_create_lab(data, - ldns_rr_rdf(rr, 0)), depth+1); - } else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_CNAME) { - int t = ldns_rr_get_type(rr); - if(t!=LDNS_RR_TYPE_A && t!=LDNS_RR_TYPE_AAAA && - t!=LDNS_RR_TYPE_SOA && t!=LDNS_RR_TYPE_NS && - t!=LDNS_RR_TYPE_DS && t!=LDNS_RR_TYPE_DNSKEY) - new_todo_item(data, ldns_rr_rdf(rr, 0), t, - ldns_rr_get_class(rr), depth+1); - /* can get caught in CNAME loop, but depth will - * catch that; unbound cache helps too(servfails on - * a cname loop) */ - new_todo_infra(data, find_create_lab(data, - ldns_rr_rdf(rr, 0)), depth+1); - } - /* store it */ - if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC) { - /* find correct zone to store NSEC in (for delegation zones) */ - if(ldns_dname_compare(ldns_rr_rdf(rr, 0), ldns_rr_owner(rr)) - == 0) { - /* store at the single name = apex */ - } else if(!ldns_dname_is_subdomain(ldns_rr_rdf(rr, 0), - ldns_rr_owner(rr)) && lab->parent) { - /* if owner NSEC subdomain-of-owner then - * store at owner (owner is apex or empty nonterminal). - * Otherwise at owner parent. */ - lab = lab->parent; - } - } else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_DS) { - /* store DSes in parent zone */ - if(lab->parent) - lab = lab->parent; - } else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3) { - /* store NSEC3s one label up at zone apex */ - if(lab->parent) - lab = lab->parent; - } - /* we assume NS set is equal across parent-child border. */ - - if(!ldns_rr_list_contains_rr(lab->rrlist, rr)) { - if(hverb >= 2) { - printf("store RR "); - ldns_rr_print(stdout, rr); - printf("\n"); - } - if(!ldns_rr_list_push_rr(lab->rrlist, rr)) - error_exit("outofmem ldns_rr_list_push_rr"); - data->num_rrs++; - } else { - if(hverb >= 2) { - printf("duplicate RR "); - ldns_rr_print(stdout, rr); - printf("\n"); - } - ldns_rr_free(rr); - } -} - -/** store RRs and make new work items if needed */ -static void -process_pkt(struct harvest_data* data, ldns_pkt* pkt, int depth) -{ - size_t i; - ldns_rr_list* list; - list = ldns_pkt_get_section_clone(pkt, LDNS_SECTION_ANY_NOQUESTION); - if(!list) error_exit("outofmemory"); - for(i=0; i<ldns_rr_list_rr_count(list); i++) { - process_rr(data, ldns_rr_list_rr(list, i), depth); - } - ldns_rr_list_free(list); -} - -/** process a todo item */ -static void -process(struct harvest_data* data, struct todo_item* it) -{ - int r; - char* nm; - struct ub_result* result = NULL; - ldns_pkt* pkt = NULL; - ldns_status s; - if(hverb) { - printf("process: "); - ldns_rdf_print(stdout, it->qname); - if(ldns_rr_descript((uint16_t)it->qtype) && - ldns_rr_descript((uint16_t)it->qtype)->_name) - printf(" %s", ldns_rr_descript((uint16_t) - it->qtype)->_name); - if(ldns_lookup_by_id(ldns_rr_classes, it->qclass) && - ldns_lookup_by_id(ldns_rr_classes, it->qclass)->name) - printf(" %s", ldns_lookup_by_id(ldns_rr_classes, - it->qclass)->name); - printf("\n"); - } - /* do lookup */ - nm = ldns_rdf2str(it->qname); - if(!nm) error_exit("ldns_rdf2str"); - r = ub_resolve(data->ctx, nm, it->qtype, it->qclass, &result); - if(r != 0) { - printf("ub_resolve(%s, %d, %d): %s\n", nm, it->qtype, - it->qclass, ub_strerror(r)); - free(nm); - return; - } - if(result->rcode == LDNS_RCODE_SERVFAIL) { - free(nm); - return; - } - /* even if result is a negative, try to store resulting SOA/NSEC */ - - /* create ldns pkt */ - s = ldns_wire2pkt(&pkt, result->answer_packet, - (size_t)result->answer_len); - if(s != LDNS_STATUS_OK) { - printf("ldns_wire2pkt failed! %s %d %d %s %d\n", nm, - it->qtype, it->qclass, ldns_get_errorstr_by_id(s), - result->answer_len); - free(nm); - return; - } - if(hverb >= 2) { - printf("answer: "); - ldns_pkt_print(stdout, pkt); - printf("\n"); - } - /* process results */ - process_pkt(data, pkt, it->depth); - - ldns_pkt_free(pkt); - free(nm); - ub_resolve_free(result); -} - -/** perform main harvesting */ -static void -harvest_main(struct harvest_data* data) -{ - struct todo_item* it; - int numdone = 0; - /* register todo queries for all original queries */ - make_todo(data); - printf("depth 0: done %d todo %d\n", 0, data->numtodo); - /* pick up a todo item and process it */ - while(data->todo_list) { - numdone++; - it = data->todo_list; - data->todo_list = it->next; - if(!data->todo_list) data->todo_last = NULL; - if(numdone%1000==0 || it->depth > data->curdepth) { - data->curdepth = it->depth; - printf("depth %d: done %d todo %d, %d rrs\n", - it->depth, numdone, data->numtodo, - data->num_rrs); - } - if(it->depth >= data->maxdepth) { - printf("obtained %d rrs to a max of %d labels.\n", - data->num_rrs, data->maxlabels); - return; - } - data->numtodo--; - process(data, it); - usleep(1000000/100); - } -} - -/** create directory if it does not exist */ -static void -hv_mkdir(char* dir) -{ -#ifdef MKDIR_HAS_ONE_ARG - if(mkdir(dir) == -1) { -#else - if(mkdir(dir, 0755) == -1) { -#endif - if(errno == EEXIST) - return; - perror(dir); - error_exit("mkdir failed"); - } -} - - -/** see if rrlist contains a SOA record */ -static ldns_rr* -has_SOA(ldns_rr_list* list) -{ - size_t i; - for(i=0; i<ldns_rr_list_rr_count(list); i++) { - if(ldns_rr_get_type(ldns_rr_list_rr(list, i)) - == LDNS_RR_TYPE_SOA) - return ldns_rr_list_rr(list, i); - } - return NULL; -} - -/** write moredata for a zone*/ -static void -write_moredata(struct harvest_data* data, struct labdata* zone, - FILE *f, struct labdata* thislab, ldns_rr* nslist) -{ - struct labdata* lab; - size_t i; - ldns_rr* ns; - LDNS_RBTREE_FOR(lab, struct labdata*, thislab->sublabels) { - if(has_SOA(lab->rrlist)) { - /* copy only NS glue */ - for(i=0; i<ldns_rr_list_rr_count(lab->rrlist); i++) { - ns = ldns_rr_list_rr(lab->rrlist, i); - if(ldns_rr_get_type(ns) == LDNS_RR_TYPE_NS) { - ldns_rr_print(f, ns); - if(ldns_dname_is_subdomain( - ldns_rr_ns_nsdname(ns), - lab->name)) { - ldns_rr_push_rdf(nslist, - ldns_rdf_clone( - ldns_rr_ns_nsdname(ns))); - } - } - } - } else { - /* copy all, recurse */ - for(i=0; i<ldns_rr_list_rr_count(lab->rrlist); i++) { - ldns_rr_print(f, - ldns_rr_list_rr(lab->rrlist, i)); - } - write_moredata(data, zone, f, lab, nslist); - } - } -} - -/** find and write glue into zone file */ -static void -write_glue(struct harvest_data* data, struct labdata* thislab, FILE* f, - ldns_rdf* name, int dep) -{ - size_t i; - struct labdata* lab; - ldns_rr* rr; - if(ldns_dname_compare(name, thislab->name) == 0) { - /* this is it! Did we go outside the zone? */ - if(dep == 0) - return; - /* find A and AAAA */ - for(i=0; i<ldns_rr_list_rr_count(thislab->rrlist); i++) { - rr = ldns_rr_list_rr(thislab->rrlist, i); - if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_A || - ldns_rr_get_type(rr) == LDNS_RR_TYPE_AAAA) { - ldns_rr_print(f, rr); - } - } - return; - } - /* recurse deeper */ - LDNS_RBTREE_FOR(lab, struct labdata*, thislab->sublabels) { - if(has_SOA(lab->rrlist)) { - write_glue(data, lab, f, name, dep+1); - } else { - write_glue(data, lab, f, name, dep); - } - } -} - -/** write zonefile for zone at this apex */ -static void -write_zonefile(struct harvest_data* data, int dep, FILE* zlist, - struct labdata* apex, ldns_rr* soa) -{ - FILE *f; - char fname[1024]; - char* zname = ldns_rdf2str(apex->name); - time_t tm = time(NULL); - size_t i; - ldns_rr* nslist; - if(!zname) error_exit("out of mem ldns_rdf2str"); - if(strcmp(zname, ".") == 0) - snprintf(fname, sizeof(fname), "l%d/root.zone", dep); - else snprintf(fname, sizeof(fname), "l%d/%szone", dep, zname); - - fprintf(zlist, "zone: name: \"%s\" %s%szonefile: \"%s\"\n", - zname, - strlen(zname)/8<1?"\t":"", - strlen(zname)/8<2?"\t":"", - fname); - - if(hverb) printf("writing %s\n", fname); - f = fopen(fname, "w"); - if(!f) { - perror(fname); - error_exit("cannot open zone file"); - } - fprintf(f, "; %s - generated by harvest program.\n", fname); - fprintf(f, "; zone name %s - this is a partial snapshot of " - "data relevant to the query list.\n", zname); - fprintf(f, "; created %u - date %s\n", (unsigned)tm, ctime(&tm)); - ldns_rr_print(f, soa); - fprintf(f, "\n"); - for(i=0; i<ldns_rr_list_rr_count(apex->rrlist); i++) { - if(ldns_rr_get_type(ldns_rr_list_rr(apex->rrlist, i)) - == LDNS_RR_TYPE_SOA) continue; - ldns_rr_print(f, ldns_rr_list_rr(apex->rrlist, i)); - } - /* search for more data - subdomains inside the zone, NS glue */ - nslist = ldns_rr_new(); - if(!nslist) error_exit("out of memory"); - fprintf(f, "; end of apex, more data follows\n"); - write_moredata(data, apex, f, apex, nslist); - - /* add NS from apex that need glue too */ - for(i=0; i<ldns_rr_list_rr_count(apex->rrlist); i++) { - if(ldns_rr_get_type(ldns_rr_list_rr(apex->rrlist, i)) != - LDNS_RR_TYPE_NS) - continue; - /* these are only added again if in a subzone */ - if(ldns_dname_is_subdomain(ldns_rr_ns_nsdname( - ldns_rr_list_rr(apex->rrlist, i)), apex->name)) { - ldns_rr_push_rdf(nslist, ldns_rdf_clone( - ldns_rr_ns_nsdname(ldns_rr_list_rr( - apex->rrlist, i)))); - } - } - - fprintf(f, "; glue data follows\n"); - /* lookup and add glue (if not already in zone) */ - for(i=0; i<ldns_rr_rd_count(nslist); i++) { - write_glue(data, apex, f, ldns_rr_rdf(nslist, i), 0); - } - - fclose(f); - ldns_rr_free(nslist); - free(zname); -} - -/** create zones at depth d in label tree */ -static void -create_zones(struct harvest_data* data, int dep, FILE* zlist, - struct labdata* labnow, int depnow) -{ - struct labdata* s; - ldns_rr* soa; - if(depnow == dep) { - /* see if this is a zone start - a SOA */ - if((soa=has_SOA(labnow->rrlist))) { - write_zonefile(data, dep, zlist, labnow, soa); - data->num_zones++; - } - return; - } - /* recurse */ - LDNS_RBTREE_FOR(s, struct labdata*, labnow->sublabels) { - create_zones(data, dep, zlist, s, depnow+1); - } -} - -/** sort rrlists */ -static void -harvest_sort(struct labdata* lab) -{ - struct labdata* s; - /* prettier output if sorted here */ - ldns_rr_list_sort(lab->rrlist); - /* and recurse */ - LDNS_RBTREE_FOR(s, struct labdata*, lab->sublabels) { - harvest_sort(s); - } -} - -/** output harvested results */ -static void -harvest_output(struct harvest_data* data) -{ - int d; - char buf[20]; - FILE* zlist; - int lastzones; - hv_mkdir(data->resultdir); - if(chdir(data->resultdir) == -1) { - perror(data->resultdir); - error_exit("cannot chdir"); - } - harvest_sort(data->root); - /* create zones */ - for(d = 0; d<data->maxlabels; d++) { - lastzones = data->num_zones; - printf("creating zones %d\n", d); - snprintf(buf, sizeof(buf), "l%d", d); - hv_mkdir(buf); - snprintf(buf, sizeof(buf), "l%d.zones", d); - zlist = fopen(buf, "w"); - if(!zlist) { - perror(buf); - error_exit("cannot write zonelist file"); - } - fprintf(zlist, "# partial zones at depth %d\n", d); - create_zones(data, d, zlist, data->root, 0); - fclose(zlist); - printf("creating zones %d - %d zones written\n", d, - data->num_zones - lastzones); - } -} - -/** getopt global, in case header files fail to declare it. */ -extern int optind; -/** getopt global, in case header files fail to declare it. */ -extern char* optarg; - -/** main program for harvest */ -int main(int argc, char* argv[]) -{ - struct harvest_data data; - char* nm = argv[0]; - int c; - - /* defaults */ - memset(&data, 0, sizeof(data)); - data.ctx = ub_ctx_create(); - data.resultdir = strdup("harvested_zones"); - if(!data.resultdir) error_exit("out of memory"); - data.maxdepth = 2; - - /* parse the options */ - while( (c=getopt(argc, argv, "hf:vC:")) != -1) { - switch(c) { - case 'C': - if(ub_ctx_config(data.ctx, optarg) != 0) - error_exit("config read failed"); - break; - case 'f': - qlist_read_file(&data, optarg); - break; - case 'v': - hverb++; - break; - case '?': - case 'h': - default: - usage(nm); - } - } - argc -= optind; - argv += optind; - if(argc != 0) - usage(nm); - if(data.orig_list == NULL) - error_exit("No queries to make, use -f (help with -h)."); - data.root = lab_create("."); - if(!data.root) error_exit("out of memory"); - - /* harvest the data */ - harvest_main(&data); - harvest_output(&data); - - /* no cleanup except the context (to close open sockets) */ - ub_ctx_delete(data.ctx); - return 0; -} diff --git a/testcode/ldns-testpkts.c b/testcode/ldns-testpkts.c deleted file mode 100644 index be94eb2fe438..000000000000 --- a/testcode/ldns-testpkts.c +++ /dev/null @@ -1,898 +0,0 @@ -/* - * ldns-testpkts. Data file parse for test packets, and query matching. - * - * Data storage for specially crafted replies for testing purposes. - * - * (c) NLnet Labs, 2005, 2006, 2007, 2008 - * See the file LICENSE for the license - */ - -/** - * \file - * This is a debugging aid. It is not efficient, especially - * with a long config file, but it can give any reply to any query. - * This can help the developer pre-script replies for queries. - * - * You can specify a packet RR by RR with header flags to return. - * - * Missing features: - * - matching content different from reply content. - * - find way to adjust mangled packets? - */ - -#include "config.h" -struct sockaddr_storage; -#include <ldns/ldns.h> -#include <errno.h> -#include "ldns-testpkts.h" - -/** max line length */ -#define MAX_LINE 10240 -/** string to show in warnings and errors */ -static const char* prog_name = "ldns-testpkts"; - -#ifndef UTIL_LOG_H -/** verbosity definition for compat */ -enum verbosity_value { NO_VERBOSE=0 }; -#endif -/** logging routine, provided by caller */ -void verbose(enum verbosity_value lvl, const char* msg, ...) ATTR_FORMAT(printf, 2, 3); - -/** print error and exit */ -static void error(const char* msg, ...) -{ - va_list args; - va_start(args, msg); - fprintf(stderr, "%s error: ", prog_name); - vfprintf(stderr, msg, args); - fprintf(stderr, "\n"); - fflush(stderr); - va_end(args); - exit(EXIT_FAILURE); -} - -/** return if string is empty or comment */ -static bool isendline(char c) -{ - if(c == ';' || c == '#' - || c == '\n' || c == 0) - return true; - return false; -} - -/** true if the string starts with the keyword given. Moves the str ahead. - * @param str: before keyword, afterwards after keyword and spaces. - * @param keyword: the keyword to match - * @return: true if keyword present. False otherwise, and str unchanged. -*/ -static bool str_keyword(char** str, const char* keyword) -{ - size_t len = strlen(keyword); - assert(str && keyword); - if(strncmp(*str, keyword, len) != 0) - return false; - *str += len; - while(isspace((int)**str)) - (*str)++; - return true; -} - -/** Add reply packet to entry */ -static struct reply_packet* -entry_add_reply(struct entry* entry) -{ - struct reply_packet* pkt = (struct reply_packet*)malloc( - sizeof(struct reply_packet)); - struct reply_packet ** p = &entry->reply_list; - pkt->next = NULL; - pkt->packet_sleep = 0; - pkt->reply = ldns_pkt_new(); - pkt->reply_from_hex = NULL; - /* link at end */ - while(*p) - p = &((*p)->next); - *p = pkt; - return pkt; -} - -/** parse MATCH line */ -static void matchline(char* line, struct entry* e) -{ - char* parse = line; - while(*parse) { - if(isendline(*parse)) - return; - if(str_keyword(&parse, "opcode")) { - e->match_opcode = true; - } else if(str_keyword(&parse, "qtype")) { - e->match_qtype = true; - } else if(str_keyword(&parse, "qname")) { - e->match_qname = true; - } else if(str_keyword(&parse, "subdomain")) { - e->match_subdomain = true; - } else if(str_keyword(&parse, "all")) { - e->match_all = true; - } else if(str_keyword(&parse, "ttl")) { - e->match_ttl = true; - } else if(str_keyword(&parse, "DO")) { - e->match_do = true; - } else if(str_keyword(&parse, "noedns")) { - e->match_noedns = true; - } else if(str_keyword(&parse, "UDP")) { - e->match_transport = transport_udp; - } else if(str_keyword(&parse, "TCP")) { - e->match_transport = transport_tcp; - } else if(str_keyword(&parse, "serial")) { - e->match_serial = true; - if(*parse != '=' && *parse != ':') - error("expected = or : in MATCH: %s", line); - parse++; - e->ixfr_soa_serial = (uint32_t)strtol(parse, (char**)&parse, 10); - while(isspace((int)*parse)) - parse++; - } else { - error("could not parse MATCH: '%s'", parse); - } - } -} - -/** parse REPLY line */ -static void replyline(char* line, ldns_pkt *reply) -{ - char* parse = line; - while(*parse) { - if(isendline(*parse)) - return; - /* opcodes */ - if(str_keyword(&parse, "QUERY")) { - ldns_pkt_set_opcode(reply, LDNS_PACKET_QUERY); - } else if(str_keyword(&parse, "IQUERY")) { - ldns_pkt_set_opcode(reply, LDNS_PACKET_IQUERY); - } else if(str_keyword(&parse, "STATUS")) { - ldns_pkt_set_opcode(reply, LDNS_PACKET_STATUS); - } else if(str_keyword(&parse, "NOTIFY")) { - ldns_pkt_set_opcode(reply, LDNS_PACKET_NOTIFY); - } else if(str_keyword(&parse, "UPDATE")) { - ldns_pkt_set_opcode(reply, LDNS_PACKET_UPDATE); - /* rcodes */ - } else if(str_keyword(&parse, "NOERROR")) { - ldns_pkt_set_rcode(reply, LDNS_RCODE_NOERROR); - } else if(str_keyword(&parse, "FORMERR")) { - ldns_pkt_set_rcode(reply, LDNS_RCODE_FORMERR); - } else if(str_keyword(&parse, "SERVFAIL")) { - ldns_pkt_set_rcode(reply, LDNS_RCODE_SERVFAIL); - } else if(str_keyword(&parse, "NXDOMAIN")) { - ldns_pkt_set_rcode(reply, LDNS_RCODE_NXDOMAIN); - } else if(str_keyword(&parse, "NOTIMPL")) { - ldns_pkt_set_rcode(reply, LDNS_RCODE_NOTIMPL); - } else if(str_keyword(&parse, "REFUSED")) { - ldns_pkt_set_rcode(reply, LDNS_RCODE_REFUSED); - } else if(str_keyword(&parse, "YXDOMAIN")) { - ldns_pkt_set_rcode(reply, LDNS_RCODE_YXDOMAIN); - } else if(str_keyword(&parse, "YXRRSET")) { - ldns_pkt_set_rcode(reply, LDNS_RCODE_YXRRSET); - } else if(str_keyword(&parse, "NXRRSET")) { - ldns_pkt_set_rcode(reply, LDNS_RCODE_NXRRSET); - } else if(str_keyword(&parse, "NOTAUTH")) { - ldns_pkt_set_rcode(reply, LDNS_RCODE_NOTAUTH); - } else if(str_keyword(&parse, "NOTZONE")) { - ldns_pkt_set_rcode(reply, LDNS_RCODE_NOTZONE); - /* flags */ - } else if(str_keyword(&parse, "QR")) { - ldns_pkt_set_qr(reply, true); - } else if(str_keyword(&parse, "AA")) { - ldns_pkt_set_aa(reply, true); - } else if(str_keyword(&parse, "TC")) { - ldns_pkt_set_tc(reply, true); - } else if(str_keyword(&parse, "RD")) { - ldns_pkt_set_rd(reply, true); - } else if(str_keyword(&parse, "CD")) { - ldns_pkt_set_cd(reply, true); - } else if(str_keyword(&parse, "RA")) { - ldns_pkt_set_ra(reply, true); - } else if(str_keyword(&parse, "AD")) { - ldns_pkt_set_ad(reply, true); - } else if(str_keyword(&parse, "DO")) { - ldns_pkt_set_edns_udp_size(reply, 4096); - ldns_pkt_set_edns_do(reply, true); - } else { - error("could not parse REPLY: '%s'", parse); - } - } -} - -/** parse ADJUST line */ -static void adjustline(char* line, struct entry* e, - struct reply_packet* pkt) -{ - char* parse = line; - while(*parse) { - if(isendline(*parse)) - return; - if(str_keyword(&parse, "copy_id")) { - e->copy_id = true; - } else if(str_keyword(&parse, "copy_query")) { - e->copy_query = true; - } else if(str_keyword(&parse, "sleep=")) { - e->sleeptime = (unsigned int) strtol(parse, (char**)&parse, 10); - while(isspace((int)*parse)) - parse++; - } else if(str_keyword(&parse, "packet_sleep=")) { - pkt->packet_sleep = (unsigned int) strtol(parse, (char**)&parse, 10); - while(isspace((int)*parse)) - parse++; - } else { - error("could not parse ADJUST: '%s'", parse); - } - } -} - -/** create new entry */ -static struct entry* new_entry() -{ - struct entry* e = LDNS_MALLOC(struct entry); - memset(e, 0, sizeof(*e)); - e->match_opcode = false; - e->match_qtype = false; - e->match_qname = false; - e->match_subdomain = false; - e->match_all = false; - e->match_ttl = false; - e->match_do = false; - e->match_noedns = false; - e->match_serial = false; - e->ixfr_soa_serial = 0; - e->match_transport = transport_any; - e->reply_list = NULL; - e->copy_id = false; - e->copy_query = false; - e->sleeptime = 0; - e->next = NULL; - return e; -} - -/** - * Converts a hex string to binary data - * @param hexstr: string of hex. - * @param len: is the length of the string - * @param buf: is the buffer to store the result in - * @param offset: is the starting position in the result buffer - * @param buf_len: is the length of buf. - * @return This function returns the length of the result - */ -static size_t -hexstr2bin(char *hexstr, int len, uint8_t *buf, size_t offset, size_t buf_len) -{ - char c; - int i; - uint8_t int8 = 0; - int sec = 0; - size_t bufpos = 0; - - if (len % 2 != 0) { - return 0; - } - - for (i=0; i<len; i++) { - c = hexstr[i]; - - /* case insensitive, skip spaces */ - if (c != ' ') { - if (c >= '0' && c <= '9') { - int8 += c & 0x0f; - } else if (c >= 'a' && c <= 'z') { - int8 += (c & 0x0f) + 9; - } else if (c >= 'A' && c <= 'Z') { - int8 += (c & 0x0f) + 9; - } else { - return 0; - } - - if (sec == 0) { - int8 = int8 << 4; - sec = 1; - } else { - if (bufpos + offset + 1 <= buf_len) { - buf[bufpos+offset] = int8; - int8 = 0; - sec = 0; - bufpos++; - } else { - fprintf(stderr, "Buffer too small in hexstr2bin"); - } - } - } - } - return bufpos; -} - -/** convert hex buffer to binary buffer */ -static ldns_buffer * -data_buffer2wire(ldns_buffer *data_buffer) -{ - ldns_buffer *wire_buffer = NULL; - int c; - - /* stat hack - * 0 = normal - * 1 = comment (skip to end of line) - * 2 = unprintable character found, read binary data directly - */ - size_t data_buf_pos = 0; - int state = 0; - uint8_t *hexbuf; - int hexbufpos = 0; - size_t wirelen; - uint8_t *data_wire = (uint8_t *) ldns_buffer_begin(data_buffer); - uint8_t *wire = LDNS_XMALLOC(uint8_t, LDNS_MAX_PACKETLEN); - - hexbuf = LDNS_XMALLOC(uint8_t, LDNS_MAX_PACKETLEN); - for (data_buf_pos = 0; data_buf_pos < ldns_buffer_position(data_buffer); data_buf_pos++) { - c = (int) data_wire[data_buf_pos]; - - if (state < 2 && !isascii(c)) { - /*verbose("non ascii character found in file: (%d) switching to raw mode\n", c);*/ - state = 2; - } - switch (state) { - case 0: - if ( (c >= '0' && c <= '9') || - (c >= 'a' && c <= 'f') || - (c >= 'A' && c <= 'F') ) - { - if (hexbufpos >= LDNS_MAX_PACKETLEN) { - error("buffer overflow"); - LDNS_FREE(hexbuf); - return 0; - - } - hexbuf[hexbufpos] = (uint8_t) c; - hexbufpos++; - } else if (c == ';') { - state = 1; - } else if (c == ' ' || c == '\t' || c == '\n') { - /* skip whitespace */ - } - break; - case 1: - if (c == '\n' || c == EOF) { - state = 0; - } - break; - case 2: - if (hexbufpos >= LDNS_MAX_PACKETLEN) { - error("buffer overflow"); - LDNS_FREE(hexbuf); - return 0; - } - hexbuf[hexbufpos] = (uint8_t) c; - hexbufpos++; - break; - } - } - - if (hexbufpos >= LDNS_MAX_PACKETLEN) { - /*verbose("packet size reached\n");*/ - } - - /* lenient mode: length must be multiple of 2 */ - if (hexbufpos % 2 != 0) { - if (hexbufpos >= LDNS_MAX_PACKETLEN) { - error("buffer overflow"); - LDNS_FREE(hexbuf); - return 0; - } - hexbuf[hexbufpos] = (uint8_t) '0'; - hexbufpos++; - } - - if (state < 2) { - wirelen = hexstr2bin((char *) hexbuf, hexbufpos, wire, 0, LDNS_MAX_PACKETLEN); - wire_buffer = ldns_buffer_new(wirelen); - ldns_buffer_new_frm_data(wire_buffer, wire, wirelen); - } else { - error("Incomplete hex data, not at byte boundary\n"); - } - LDNS_FREE(wire); - LDNS_FREE(hexbuf); - return wire_buffer; -} - -/** parse ORIGIN */ -static void -get_origin(const char* name, int lineno, ldns_rdf** origin, char* parse) -{ - /* snip off rest of the text so as to make the parse work in ldns */ - char* end; - char store; - ldns_status status; - - ldns_rdf_free(*origin); - *origin = NULL; - - end=parse; - while(!isspace((int)*end) && !isendline(*end)) - end++; - store = *end; - *end = 0; - verbose(3, "parsing '%s'\n", parse); - status = ldns_str2rdf_dname(origin, parse); - *end = store; - if (status != LDNS_STATUS_OK) - error("%s line %d:\n\t%s: %s", name, lineno, - ldns_get_errorstr_by_id(status), parse); -} - -/* Reads one entry from file. Returns entry or NULL on error. */ -struct entry* -read_entry(FILE* in, const char* name, int *lineno, uint32_t* default_ttl, - ldns_rdf** origin, ldns_rdf** prev_rr, int skip_whitespace) -{ - struct entry* current = NULL; - char line[MAX_LINE]; - char* parse; - ldns_pkt_section add_section = LDNS_SECTION_QUESTION; - struct reply_packet *cur_reply = NULL; - bool reading_hex = false; - ldns_buffer* hex_data_buffer = NULL; - - while(fgets(line, (int)sizeof(line), in) != NULL) { - line[MAX_LINE-1] = 0; - parse = line; - (*lineno) ++; - - while(isspace((int)*parse)) - parse++; - /* test for keywords */ - if(isendline(*parse)) - continue; /* skip comment and empty lines */ - if(str_keyword(&parse, "ENTRY_BEGIN")) { - if(current) { - error("%s line %d: previous entry does not ENTRY_END", - name, *lineno); - } - current = new_entry(); - current->lineno = *lineno; - cur_reply = entry_add_reply(current); - continue; - } else if(str_keyword(&parse, "$ORIGIN")) { - get_origin(name, *lineno, origin, parse); - continue; - } else if(str_keyword(&parse, "$TTL")) { - *default_ttl = (uint32_t)atoi(parse); - continue; - } - - /* working inside an entry */ - if(!current) { - error("%s line %d: expected ENTRY_BEGIN but got %s", - name, *lineno, line); - } - if(str_keyword(&parse, "MATCH")) { - matchline(parse, current); - } else if(str_keyword(&parse, "REPLY")) { - replyline(parse, cur_reply->reply); - } else if(str_keyword(&parse, "ADJUST")) { - adjustline(parse, current, cur_reply); - } else if(str_keyword(&parse, "EXTRA_PACKET")) { - cur_reply = entry_add_reply(current); - } else if(str_keyword(&parse, "SECTION")) { - if(str_keyword(&parse, "QUESTION")) - add_section = LDNS_SECTION_QUESTION; - else if(str_keyword(&parse, "ANSWER")) - add_section = LDNS_SECTION_ANSWER; - else if(str_keyword(&parse, "AUTHORITY")) - add_section = LDNS_SECTION_AUTHORITY; - else if(str_keyword(&parse, "ADDITIONAL")) - add_section = LDNS_SECTION_ADDITIONAL; - else error("%s line %d: bad section %s", name, *lineno, parse); - } else if(str_keyword(&parse, "HEX_ANSWER_BEGIN")) { - hex_data_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN); - reading_hex = true; - } else if(str_keyword(&parse, "HEX_ANSWER_END")) { - if (!reading_hex) { - error("%s line %d: HEX_ANSWER_END read but no HEX_ANSWER_BEGIN keyword seen", name, *lineno); - } - reading_hex = false; - cur_reply->reply_from_hex = data_buffer2wire(hex_data_buffer); - ldns_buffer_free(hex_data_buffer); - hex_data_buffer = NULL; - } else if(str_keyword(&parse, "ENTRY_END")) { - if (hex_data_buffer) - ldns_buffer_free(hex_data_buffer); - return current; - } else if(reading_hex) { - ldns_buffer_printf(hex_data_buffer, line); - } else { - /* it must be a RR, parse and add to packet. */ - ldns_rr* n = NULL; - ldns_status status; - char* rrstr = line; - if (skip_whitespace) - rrstr = parse; - if(add_section == LDNS_SECTION_QUESTION) - status = ldns_rr_new_question_frm_str( - &n, rrstr, *origin, prev_rr); - else status = ldns_rr_new_frm_str(&n, rrstr, - *default_ttl, *origin, prev_rr); - if(status != LDNS_STATUS_OK) - error("%s line %d:\n\t%s: %s", name, *lineno, - ldns_get_errorstr_by_id(status), rrstr); - ldns_pkt_push_rr(cur_reply->reply, add_section, n); - } - - } - if (reading_hex) { - error("%s: End of file reached while still reading hex, " - "missing HEX_ANSWER_END\n", name); - } - if(current) { - error("%s: End of file reached while reading entry. " - "missing ENTRY_END\n", name); - } - return 0; -} - -/* reads the canned reply file and returns a list of structs */ -struct entry* -read_datafile(const char* name, int skip_whitespace) -{ - struct entry* list = NULL; - struct entry* last = NULL; - struct entry* current = NULL; - FILE *in; - int lineno = 0; - uint32_t default_ttl = 0; - ldns_rdf* origin = NULL; - ldns_rdf* prev_rr = NULL; - int entry_num = 0; - - if((in=fopen(name, "r")) == NULL) { - error("could not open file %s: %s", name, strerror(errno)); - } - - while((current = read_entry(in, name, &lineno, &default_ttl, - &origin, &prev_rr, skip_whitespace))) - { - if(last) - last->next = current; - else list = current; - last = current; - entry_num ++; - } - verbose(1, "%s: Read %d entries\n", prog_name, entry_num); - - fclose(in); - ldns_rdf_deep_free(origin); - ldns_rdf_deep_free(prev_rr); - return list; -} - -/** get qtype from rr */ -static ldns_rr_type get_qtype(ldns_pkt* p) -{ - if(!ldns_rr_list_rr(ldns_pkt_question(p), 0)) - return 0; - return ldns_rr_get_type(ldns_rr_list_rr(ldns_pkt_question(p), 0)); -} - -/** returns owner from rr */ -static ldns_rdf* get_owner(ldns_pkt* p) -{ - if(!ldns_rr_list_rr(ldns_pkt_question(p), 0)) - return NULL; - return ldns_rr_owner(ldns_rr_list_rr(ldns_pkt_question(p), 0)); -} - -/** get authority section SOA serial value */ -static uint32_t get_serial(ldns_pkt* p) -{ - ldns_rr *rr = ldns_rr_list_rr(ldns_pkt_authority(p), 0); - ldns_rdf *rdf; - uint32_t val; - if(!rr) return 0; - rdf = ldns_rr_rdf(rr, 2); - if(!rdf) return 0; - val = ldns_rdf2native_int32(rdf); - verbose(3, "found serial %u in msg. ", (int)val); - return val; -} - -/** match two rr lists */ -static int -match_list(ldns_rr_list* q, ldns_rr_list *p, bool mttl) -{ - size_t i; - if(ldns_rr_list_rr_count(q) != ldns_rr_list_rr_count(p)) - return 0; - for(i=0; i<ldns_rr_list_rr_count(q); i++) - { - if(ldns_rr_compare(ldns_rr_list_rr(q, i), - ldns_rr_list_rr(p, i)) != 0) { - verbose(3, "rr %d different", (int)i); - return 0; - } - if(mttl && ldns_rr_ttl(ldns_rr_list_rr(q, i)) != - ldns_rr_ttl(ldns_rr_list_rr(p, i))) { - verbose(3, "rr %d ttl different", (int)i); - return 0; - } - } - return 1; -} - -/** compare two booleans */ -static int -cmp_bool(int x, int y) -{ - if(!x && !y) return 0; - if(x && y) return 0; - if(!x) return -1; - return 1; -} - -/** match all of the packet */ -static int -match_all(ldns_pkt* q, ldns_pkt* p, bool mttl) -{ - if(ldns_pkt_get_opcode(q) != ldns_pkt_get_opcode(p)) - { verbose(3, "allmatch: opcode different"); return 0;} - if(ldns_pkt_get_rcode(q) != ldns_pkt_get_rcode(p)) - { verbose(3, "allmatch: rcode different"); return 0;} - if(ldns_pkt_id(q) != ldns_pkt_id(p)) - { verbose(3, "allmatch: id different"); return 0;} - if(cmp_bool(ldns_pkt_qr(q), ldns_pkt_qr(p)) != 0) - { verbose(3, "allmatch: qr different"); return 0;} - if(cmp_bool(ldns_pkt_aa(q), ldns_pkt_aa(p)) != 0) - { verbose(3, "allmatch: aa different"); return 0;} - if(cmp_bool(ldns_pkt_tc(q), ldns_pkt_tc(p)) != 0) - { verbose(3, "allmatch: tc different"); return 0;} - if(cmp_bool(ldns_pkt_rd(q), ldns_pkt_rd(p)) != 0) - { verbose(3, "allmatch: rd different"); return 0;} - if(cmp_bool(ldns_pkt_cd(q), ldns_pkt_cd(p)) != 0) - { verbose(3, "allmatch: cd different"); return 0;} - if(cmp_bool(ldns_pkt_ra(q), ldns_pkt_ra(p)) != 0) - { verbose(3, "allmatch: ra different"); return 0;} - if(cmp_bool(ldns_pkt_ad(q), ldns_pkt_ad(p)) != 0) - { verbose(3, "allmatch: ad different"); return 0;} - if(ldns_pkt_qdcount(q) != ldns_pkt_qdcount(p)) - { verbose(3, "allmatch: qdcount different"); return 0;} - if(ldns_pkt_ancount(q) != ldns_pkt_ancount(p)) - { verbose(3, "allmatch: ancount different"); return 0;} - if(ldns_pkt_nscount(q) != ldns_pkt_nscount(p)) - { verbose(3, "allmatch: nscount different"); return 0;} - if(ldns_pkt_arcount(q) != ldns_pkt_arcount(p)) - { verbose(3, "allmatch: arcount different"); return 0;} - if(!match_list(ldns_pkt_question(q), ldns_pkt_question(p), 0)) - { verbose(3, "allmatch: qd section different"); return 0;} - if(!match_list(ldns_pkt_answer(q), ldns_pkt_answer(p), mttl)) - { verbose(3, "allmatch: an section different"); return 0;} - if(!match_list(ldns_pkt_authority(q), ldns_pkt_authority(p), mttl)) - { verbose(3, "allmatch: ar section different"); return 0;} - if(!match_list(ldns_pkt_additional(q), ldns_pkt_additional(p), mttl)) - { verbose(3, "allmatch: ns section different"); return 0;} - return 1; -} - -/* finds entry in list, or returns NULL */ -struct entry* -find_match(struct entry* entries, ldns_pkt* query_pkt, - enum transport_type transport) -{ - struct entry* p = entries; - ldns_pkt* reply = NULL; - for(p=entries; p; p=p->next) { - verbose(3, "comparepkt: "); - reply = p->reply_list->reply; - if(p->match_opcode && ldns_pkt_get_opcode(query_pkt) != - ldns_pkt_get_opcode(reply)) { - verbose(3, "bad opcode\n"); - continue; - } - if(p->match_qtype && get_qtype(query_pkt) != get_qtype(reply)) { - verbose(3, "bad qtype\n"); - continue; - } - if(p->match_qname) { - if(!get_owner(query_pkt) || !get_owner(reply) || - ldns_dname_compare( - get_owner(query_pkt), get_owner(reply)) != 0) { - verbose(3, "bad qname\n"); - continue; - } - } - if(p->match_subdomain) { - if(!get_owner(query_pkt) || !get_owner(reply) || - (ldns_dname_compare(get_owner(query_pkt), - get_owner(reply)) != 0 && - !ldns_dname_is_subdomain( - get_owner(query_pkt), get_owner(reply)))) - { - verbose(3, "bad subdomain\n"); - continue; - } - } - if(p->match_serial && get_serial(query_pkt) != p->ixfr_soa_serial) { - verbose(3, "bad serial\n"); - continue; - } - if(p->match_do && !ldns_pkt_edns_do(query_pkt)) { - verbose(3, "no DO bit set\n"); - continue; - } - if(p->match_noedns && ldns_pkt_edns(query_pkt)) { - verbose(3, "bad; EDNS OPT present\n"); - continue; - } - if(p->match_transport != transport_any && p->match_transport != transport) { - verbose(3, "bad transport\n"); - continue; - } - if(p->match_all && !match_all(query_pkt, reply, p->match_ttl)) { - verbose(3, "bad allmatch\n"); - continue; - } - verbose(3, "match!\n"); - return p; - } - return NULL; -} - -void -adjust_packet(struct entry* match, ldns_pkt* answer_pkt, ldns_pkt* query_pkt) -{ - /* copy & adjust packet */ - if(match->copy_id) - ldns_pkt_set_id(answer_pkt, ldns_pkt_id(query_pkt)); - if(match->copy_query) { - ldns_rr_list* list = ldns_pkt_get_section_clone(query_pkt, - LDNS_SECTION_QUESTION); - ldns_rr_list_deep_free(ldns_pkt_question(answer_pkt)); - ldns_pkt_set_question(answer_pkt, list); - } - if(match->sleeptime > 0) { - verbose(3, "sleeping for %d seconds\n", match->sleeptime); -#ifdef HAVE_SLEEP - sleep(match->sleeptime); -#else - Sleep(match->sleeptime * 1000); -#endif - } -} - -/* - * Parses data buffer to a query, finds the correct answer - * and calls the given function for every packet to send. - */ -void -handle_query(uint8_t* inbuf, ssize_t inlen, struct entry* entries, int* count, - enum transport_type transport, void (*sendfunc)(uint8_t*, size_t, void*), - void* userdata, FILE* verbose_out) -{ - ldns_status status; - ldns_pkt *query_pkt = NULL; - ldns_pkt *answer_pkt = NULL; - struct reply_packet *p; - ldns_rr *query_rr = NULL; - uint8_t *outbuf = NULL; - size_t answer_size = 0; - struct entry* entry = NULL; - ldns_rdf *stop_command = ldns_dname_new_frm_str("server.stop."); - - status = ldns_wire2pkt(&query_pkt, inbuf, (size_t)inlen); - if (status != LDNS_STATUS_OK) { - verbose(1, "Got bad packet: %s\n", ldns_get_errorstr_by_id(status)); - ldns_rdf_free(stop_command); - return; - } - - query_rr = ldns_rr_list_rr(ldns_pkt_question(query_pkt), 0); - verbose(1, "query %d: id %d: %s %d bytes: ", ++(*count), (int)ldns_pkt_id(query_pkt), - (transport==transport_tcp)?"TCP":"UDP", (int)inlen); - if(verbose_out) ldns_rr_print(verbose_out, query_rr); - if(verbose_out) ldns_pkt_print(verbose_out, query_pkt); - - if (ldns_rr_get_type(query_rr) == LDNS_RR_TYPE_TXT && - ldns_rr_get_class(query_rr) == LDNS_RR_CLASS_CH && - ldns_dname_compare(ldns_rr_owner(query_rr), stop_command) == 0) { - exit(0); - } - - /* fill up answer packet */ - entry = find_match(entries, query_pkt, transport); - if(!entry || !entry->reply_list) { - verbose(1, "no answer packet for this query, no reply.\n"); - ldns_pkt_free(query_pkt); - ldns_rdf_free(stop_command); - return; - } - for(p = entry->reply_list; p; p = p->next) - { - verbose(3, "Answer pkt:\n"); - if (p->reply_from_hex) { - /* try to parse the hex packet, if it can be - * parsed, we can use adjust rules. if not, - * send packet literally */ - status = ldns_buffer2pkt_wire(&answer_pkt, p->reply_from_hex); - if (status == LDNS_STATUS_OK) { - adjust_packet(entry, answer_pkt, query_pkt); - if(verbose_out) ldns_pkt_print(verbose_out, answer_pkt); - status = ldns_pkt2wire(&outbuf, answer_pkt, &answer_size); - verbose(2, "Answer packet size: %u bytes.\n", (unsigned int)answer_size); - if (status != LDNS_STATUS_OK) { - verbose(1, "Error creating answer: %s\n", ldns_get_errorstr_by_id(status)); - ldns_pkt_free(query_pkt); - ldns_rdf_free(stop_command); - return; - } - ldns_pkt_free(answer_pkt); - answer_pkt = NULL; - } else { - verbose(3, "Could not parse hex data (%s), sending hex data directly.\n", ldns_get_errorstr_by_id(status)); - /* still try to adjust ID */ - answer_size = ldns_buffer_capacity(p->reply_from_hex); - outbuf = LDNS_XMALLOC(uint8_t, answer_size); - memcpy(outbuf, ldns_buffer_begin(p->reply_from_hex), answer_size); - if(entry->copy_id) { - ldns_write_uint16(outbuf, - ldns_pkt_id(query_pkt)); - } - } - } else { - answer_pkt = ldns_pkt_clone(p->reply); - adjust_packet(entry, answer_pkt, query_pkt); - if(verbose_out) ldns_pkt_print(verbose_out, answer_pkt); - status = ldns_pkt2wire(&outbuf, answer_pkt, &answer_size); - verbose(1, "Answer packet size: %u bytes.\n", (unsigned int)answer_size); - if (status != LDNS_STATUS_OK) { - verbose(1, "Error creating answer: %s\n", ldns_get_errorstr_by_id(status)); - ldns_pkt_free(query_pkt); - ldns_rdf_free(stop_command); - return; - } - ldns_pkt_free(answer_pkt); - answer_pkt = NULL; - } - if(p->packet_sleep) { - verbose(3, "sleeping for next packet %d secs\n", - p->packet_sleep); -#ifdef HAVE_SLEEP - sleep(p->packet_sleep); -#else - Sleep(p->packet_sleep * 1000); -#endif - verbose(3, "wakeup for next packet " - "(slept %d secs)\n", p->packet_sleep); - } - sendfunc(outbuf, answer_size, userdata); - LDNS_FREE(outbuf); - outbuf = NULL; - answer_size = 0; - } - ldns_pkt_free(query_pkt); - ldns_rdf_free(stop_command); -} - -/** delete the list of reply packets */ -void delete_replylist(struct reply_packet* replist) -{ - struct reply_packet *p=replist, *np; - while(p) { - np = p->next; - ldns_pkt_free(p->reply); - ldns_buffer_free(p->reply_from_hex); - free(p); - p=np; - } -} - -void delete_entry(struct entry* list) -{ - struct entry *p=list, *np; - while(p) { - np = p->next; - delete_replylist(p->reply_list); - free(p); - p = np; - } -} diff --git a/testcode/lock_verify.c b/testcode/lock_verify.c index 9f51c3385a6b..365fd6e4af0c 100644 --- a/testcode/lock_verify.c +++ b/testcode/lock_verify.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/testcode/memstats.c b/testcode/memstats.c index 8cbd9f546e0d..fc56c0d3c1af 100644 --- a/testcode/memstats.c +++ b/testcode/memstats.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -189,7 +189,7 @@ readfile(rbtree_t* tree, const char* fname) char buf[102400]; if(!in) fatal_exit("could not open %s: %s", fname, strerror(errno)); - printf("Reading %s of size %lld\n", fname, (long long)total); + printf("Reading %s of size " ARG_LL "d\n", fname, (long long)total); while(fgets(buf, 102400, in)) { buf[102400-1] = 0; done += (off_t)strlen(buf); diff --git a/testcode/perf.c b/testcode/perf.c index cc892efa99fa..c51eee4b161d 100644 --- a/testcode/perf.c +++ b/testcode/perf.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -43,7 +43,6 @@ #ifdef HAVE_GETOPT_H #include <getopt.h> #endif -#include <ldns/ldns.h> #include <signal.h> #include "util/log.h" #include "util/locks.h" @@ -51,6 +50,10 @@ #include "util/data/msgencode.h" #include "util/data/msgreply.h" #include "util/data/msgparse.h" +#include "ldns/sbuffer.h" +#include "ldns/wire2str.h" +#include "ldns/str2wire.h" +#include <sys/time.h> /** usage information for perf */ static void usage(char* nm) @@ -75,7 +78,7 @@ struct perfinfo { /** need to exit */ volatile int exit; /** all purpose buffer (for UDP send and receive) */ - ldns_buffer* buf; + sldns_buffer* buf; /** destination */ struct sockaddr_storage dest; @@ -303,8 +306,8 @@ static void perfreply(struct perfinfo* info, size_t n, struct timeval* now) { ssize_t r; - r = recv(info->io[n].fd, (void*)ldns_buffer_begin(info->buf), - ldns_buffer_capacity(info->buf), 0); + r = recv(info->io[n].fd, (void*)sldns_buffer_begin(info->buf), + sldns_buffer_capacity(info->buf), 0); if(r == -1) { #ifndef USE_WINSOCK log_err("recv: %s", strerror(errno)); @@ -312,11 +315,11 @@ perfreply(struct perfinfo* info, size_t n, struct timeval* now) log_err("recv: %s", wsa_strerror(WSAGetLastError())); #endif } else { - info->by_rcode[LDNS_RCODE_WIRE(ldns_buffer_begin( + info->by_rcode[LDNS_RCODE_WIRE(sldns_buffer_begin( info->buf))]++; info->numrecv++; } - /*ldns_buffer_set_limit(info->buf, r); + /*sldns_buffer_set_limit(info->buf, r); log_buf(0, "reply", info->buf);*/ perfsend(info, n, now); } @@ -434,11 +437,10 @@ perfendstats(struct perfinfo* info) for(i=0; i<(int)(sizeof(info->by_rcode)/sizeof(size_t)); i++) { if(info->by_rcode[i] > 0) { + char rc[16]; + sldns_wire2str_rcode_buf(i, rc, sizeof(rc)); printf("%d(%5s): %u replies\n", - i, ldns_lookup_by_id(ldns_rcodes, i)? - ldns_lookup_by_id(ldns_rcodes, - i)->name:"??", - (unsigned)info->by_rcode[i]); + i, rc, (unsigned)info->by_rcode[i]); } } } @@ -459,38 +461,35 @@ perfmain(struct perfinfo* info) /** parse a query line to a packet into buffer */ static int -qlist_parse_line(ldns_buffer* buf, char* p) +qlist_parse_line(sldns_buffer* buf, char* p) { char nm[1024], cl[1024], tp[1024], fl[1024]; int r; int rec = 1, edns = 0; struct query_info qinfo; - ldns_rdf* rdf; nm[0] = 0; cl[0] = 0; tp[0] = 0; fl[0] = 0; r = sscanf(p, " %1023s %1023s %1023s %1023s", nm, cl, tp, fl); if(r != 3 && r != 4) return 0; /*printf("nm='%s', cl='%s', tp='%s', fl='%s'\n", nm, cl, tp, fl);*/ if(strcmp(tp, "IN") == 0 || strcmp(tp, "CH") == 0) { - qinfo.qtype = ldns_get_rr_type_by_name(cl); - qinfo.qclass = ldns_get_rr_class_by_name(tp); + qinfo.qtype = sldns_get_rr_type_by_name(cl); + qinfo.qclass = sldns_get_rr_class_by_name(tp); } else { - qinfo.qtype = ldns_get_rr_type_by_name(tp); - qinfo.qclass = ldns_get_rr_class_by_name(cl); + qinfo.qtype = sldns_get_rr_type_by_name(tp); + qinfo.qclass = sldns_get_rr_class_by_name(cl); } if(fl[0] == '+') rec = 1; else if(fl[0] == '-') rec = 0; else if(fl[0] == 'E') edns = 1; if((fl[0] == '+' || fl[0] == '-') && fl[1] == 'E') edns = 1; - rdf = ldns_dname_new_frm_str(nm); - if(!rdf) + qinfo.qname = sldns_str2wire_dname(nm, &qinfo.qname_len); + if(!qinfo.qname) return 0; - qinfo.qname = ldns_rdf_data(rdf); - qinfo.qname_len = ldns_rdf_size(rdf); qinfo_query_encode(buf, &qinfo); - ldns_buffer_write_u16_at(buf, 0, 0); /* zero ID */ - if(rec) LDNS_RD_SET(ldns_buffer_begin(buf)); + sldns_buffer_write_u16_at(buf, 0, 0); /* zero ID */ + if(rec) LDNS_RD_SET(sldns_buffer_begin(buf)); if(edns) { struct edns_data ed; memset(&ed, 0, sizeof(ed)); @@ -500,7 +499,7 @@ qlist_parse_line(ldns_buffer* buf, char* p) ed.bits = EDNS_DO; attach_edns_record(buf, &ed); } - ldns_rdf_deep_free(rdf); + free(qinfo.qname); return 1; } @@ -532,13 +531,13 @@ qlist_add_line(struct perfinfo* info, char* line, int no) printf("error parsing query %d: %s\n", no, line); exit(1); } - ldns_buffer_write_u16_at(info->buf, 0, (uint16_t)info->qlist_size); + sldns_buffer_write_u16_at(info->buf, 0, (uint16_t)info->qlist_size); if(info->qlist_size + 1 > info->qlist_capacity) { qlist_grow_capacity(info); } - info->qlist_len[info->qlist_size] = ldns_buffer_limit(info->buf); + info->qlist_len[info->qlist_size] = sldns_buffer_limit(info->buf); info->qlist_data[info->qlist_size] = memdup( - ldns_buffer_begin(info->buf), ldns_buffer_limit(info->buf)); + sldns_buffer_begin(info->buf), sldns_buffer_limit(info->buf)); if(!info->qlist_data[info->qlist_size]) fatal_exit("out of memory"); info->qlist_size ++; @@ -598,7 +597,7 @@ int main(int argc, char* argv[]) fatal_exit("WSAStartup failed: %s", wsa_strerror(r)); #endif - info.buf = ldns_buffer_new(65553); + info.buf = sldns_buffer_new(65553); if(!info.buf) fatal_exit("out of memory"); /* parse the options */ @@ -645,7 +644,7 @@ int main(int argc, char* argv[]) /* do the performance test */ perfmain(&info); - ldns_buffer_free(info.buf); + sldns_buffer_free(info.buf); #ifdef USE_WINSOCK WSACleanup(); #endif diff --git a/testcode/petal.c b/testcode/petal.c index 61f8250d89ec..0bdcc4190e01 100644 --- a/testcode/petal.c +++ b/testcode/petal.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/testcode/pktview.c b/testcode/pktview.c index 3cbdfc395810..e59283fa854c 100644 --- a/testcode/pktview.c +++ b/testcode/pktview.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -40,12 +40,13 @@ */ #include "config.h" -#include <ldns/ldns.h> #include "util/log.h" #include "util/data/dname.h" #include "util/data/msgparse.h" #include "testcode/unitmain.h" #include "testcode/readhex.h" +#include "ldns/sbuffer.h" +#include "ldns/parseutil.h" /** usage information for pktview */ static void usage(char* argv[]) @@ -56,7 +57,7 @@ static void usage(char* argv[]) } /** read hex input */ -static void read_input(ldns_buffer* pkt, FILE* in) +static void read_input(sldns_buffer* pkt, FILE* in) { char buf[102400]; char* np = buf; @@ -69,22 +70,22 @@ static void read_input(ldns_buffer* pkt, FILE* in) } /** analyze domain name in packet, possibly compressed */ -static void analyze_dname(ldns_buffer* pkt) +static void analyze_dname(sldns_buffer* pkt) { - size_t oldpos = ldns_buffer_position(pkt); + size_t oldpos = sldns_buffer_position(pkt); size_t len; printf("[pos %d] dname: ", (int)oldpos); - dname_print(stdout, pkt, ldns_buffer_current(pkt)); + dname_print(stdout, pkt, sldns_buffer_current(pkt)); len = pkt_dname_len(pkt); printf(" len=%d", (int)len); - if(ldns_buffer_position(pkt)-oldpos != len) + if(sldns_buffer_position(pkt)-oldpos != len) printf(" comprlen=%d\n", - (int)(ldns_buffer_position(pkt)-oldpos)); + (int)(sldns_buffer_position(pkt)-oldpos)); else printf("\n"); } /** analyze rdata in packet */ -static void analyze_rdata(ldns_buffer*pkt, const ldns_rr_descriptor* desc, +static void analyze_rdata(sldns_buffer*pkt, const sldns_rr_descriptor* desc, uint16_t rdlen) { int rdf = 0; @@ -93,21 +94,21 @@ static void analyze_rdata(ldns_buffer*pkt, const ldns_rr_descriptor* desc, while(rdlen > 0 && count) { switch(desc->_wireformat[rdf]) { case LDNS_RDF_TYPE_DNAME: - oldpos = ldns_buffer_position(pkt); + oldpos = sldns_buffer_position(pkt); analyze_dname(pkt); - rdlen -= ldns_buffer_position(pkt)-oldpos; + rdlen -= sldns_buffer_position(pkt)-oldpos; count --; len = 0; break; case LDNS_RDF_TYPE_STR: - len = ldns_buffer_current(pkt)[0] + 1; + len = sldns_buffer_current(pkt)[0] + 1; break; default: len = get_rdf_size(desc->_wireformat[rdf]); } if(len) { printf(" wf[%d]", (int)len); - ldns_buffer_skip(pkt, (ssize_t)len); + sldns_buffer_skip(pkt, (ssize_t)len); rdlen -= len; } rdf++; @@ -116,62 +117,62 @@ static void analyze_rdata(ldns_buffer*pkt, const ldns_rr_descriptor* desc, size_t i; printf(" remain[%d]\n", (int)rdlen); for(i=0; i<rdlen; i++) - printf(" %2.2X", (unsigned)ldns_buffer_current(pkt)[i]); + printf(" %2.2X", (unsigned)sldns_buffer_current(pkt)[i]); printf("\n"); } else printf("\n"); - ldns_buffer_skip(pkt, (ssize_t)rdlen); + sldns_buffer_skip(pkt, (ssize_t)rdlen); } /** analyze rr in packet */ -static void analyze_rr(ldns_buffer* pkt, int q) +static void analyze_rr(sldns_buffer* pkt, int q) { uint16_t type, dclass, len; uint32_t ttl; analyze_dname(pkt); - type = ldns_buffer_read_u16(pkt); - dclass = ldns_buffer_read_u16(pkt); - printf("type %s(%d)", ldns_rr_descript(type)? - ldns_rr_descript(type)->_name: "??" , (int)type); - printf(" class %s(%d) ", ldns_lookup_by_id(ldns_rr_classes, - (int)dclass)?ldns_lookup_by_id( ldns_rr_classes, + type = sldns_buffer_read_u16(pkt); + dclass = sldns_buffer_read_u16(pkt); + printf("type %s(%d)", sldns_rr_descript(type)? + sldns_rr_descript(type)->_name: "??" , (int)type); + printf(" class %s(%d) ", sldns_lookup_by_id(sldns_rr_classes, + (int)dclass)?sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name:"??", (int)dclass); if(q) { printf("\n"); } else { - ttl = ldns_buffer_read_u32(pkt); + ttl = sldns_buffer_read_u32(pkt); printf(" ttl %d (0x%x)", (int)ttl, (unsigned)ttl); - len = ldns_buffer_read_u16(pkt); + len = sldns_buffer_read_u16(pkt); printf(" rdata len %d:\n", (int)len); - if(ldns_rr_descript(type)) - analyze_rdata(pkt, ldns_rr_descript(type), len); - else ldns_buffer_skip(pkt, (ssize_t)len); + if(sldns_rr_descript(type)) + analyze_rdata(pkt, sldns_rr_descript(type), len); + else sldns_buffer_skip(pkt, (ssize_t)len); } } /** analyse pkt */ -static void analyze(ldns_buffer* pkt) +static void analyze(sldns_buffer* pkt) { uint16_t i, f, qd, an, ns, ar; int rrnum = 0; - printf("packet length %d\n", (int)ldns_buffer_limit(pkt)); - if(ldns_buffer_limit(pkt) < 12) return; + printf("packet length %d\n", (int)sldns_buffer_limit(pkt)); + if(sldns_buffer_limit(pkt) < 12) return; - i = ldns_buffer_read_u16(pkt); + i = sldns_buffer_read_u16(pkt); printf("id (hostorder): %d (0x%x)\n", (int)i, (unsigned)i); - f = ldns_buffer_read_u16(pkt); + f = sldns_buffer_read_u16(pkt); printf("flags: 0x%x\n", (unsigned)f); - qd = ldns_buffer_read_u16(pkt); + qd = sldns_buffer_read_u16(pkt); printf("qdcount: %d\n", (int)qd); - an = ldns_buffer_read_u16(pkt); + an = sldns_buffer_read_u16(pkt); printf("ancount: %d\n", (int)an); - ns = ldns_buffer_read_u16(pkt); + ns = sldns_buffer_read_u16(pkt); printf("nscount: %d\n", (int)ns); - ar = ldns_buffer_read_u16(pkt); + ar = sldns_buffer_read_u16(pkt); printf("arcount: %d\n", (int)ar); printf(";-- query section\n"); - while(ldns_buffer_remaining(pkt) > 0) { + while(sldns_buffer_remaining(pkt) > 0) { if(rrnum == (int)qd) printf(";-- answer section\n"); if(rrnum == (int)qd+(int)an) @@ -187,7 +188,7 @@ static void analyze(ldns_buffer* pkt) /** main program for pktview */ int main(int argc, char* argv[]) { - ldns_buffer* pkt = ldns_buffer_new(65553); + sldns_buffer* pkt = sldns_buffer_new(65553); if(argc != 1) { usage(argv); } @@ -196,6 +197,6 @@ int main(int argc, char* argv[]) read_input(pkt, stdin); analyze(pkt); - ldns_buffer_free(pkt); + sldns_buffer_free(pkt); return 0; } diff --git a/testcode/readhex.c b/testcode/readhex.c index f212ddd747c8..b986efdebc1b 100644 --- a/testcode/readhex.c +++ b/testcode/readhex.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** @@ -41,6 +41,8 @@ #include <ctype.h> #include "testcode/readhex.h" #include "util/log.h" +#include "ldns/sbuffer.h" +#include "ldns/parseutil.h" /** skip whitespace */ static void @@ -60,24 +62,24 @@ skip_whites(const char** p) } /* takes a hex string and puts into buffer */ -void hex_to_buf(ldns_buffer* pkt, const char* hex) +void hex_to_buf(sldns_buffer* pkt, const char* hex) { const char* p = hex; int val; - ldns_buffer_clear(pkt); + sldns_buffer_clear(pkt); while(*p) { skip_whites(&p); - if(ldns_buffer_position(pkt) == ldns_buffer_limit(pkt)) + if(sldns_buffer_position(pkt) == sldns_buffer_limit(pkt)) fatal_exit("hex_to_buf: buffer too small"); if(!isalnum((int)*p)) break; - val = ldns_hexdigit_to_int(*p++) << 4; + val = sldns_hexdigit_to_int(*p++) << 4; skip_whites(&p); log_assert(*p && isalnum((int)*p)); - val |= ldns_hexdigit_to_int(*p++); - ldns_buffer_write_u8(pkt, (uint8_t)val); + val |= sldns_hexdigit_to_int(*p++); + sldns_buffer_write_u8(pkt, (uint8_t)val); skip_whites(&p); } - ldns_buffer_flip(pkt); + sldns_buffer_flip(pkt); } diff --git a/testcode/readhex.h b/testcode/readhex.h index 5ae3f4dbd510..be6424539e39 100644 --- a/testcode/readhex.h +++ b/testcode/readhex.h @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** @@ -40,13 +40,13 @@ #ifndef TESTCODE_READHEX_H #define TESTCODE_READHEX_H -#include <ldns/buffer.h> +struct sldns_buffer; /** * Helper to convert hex string to packet buffer. * @param pkt: buffer to put result in. * @param hex: string of hex data. Spaces and ';...' comments are skipped. */ -void hex_to_buf(ldns_buffer* pkt, const char* hex); +void hex_to_buf(struct sldns_buffer* pkt, const char* hex); #endif /* TESTCODE_READHEX_H */ diff --git a/testcode/replay.c b/testcode/replay.c index ce050ed0ad15..ee87b1a88fb7 100644 --- a/testcode/replay.c +++ b/testcode/replay.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -42,12 +42,15 @@ #include "config.h" /* for strtod prototype */ #include <math.h> +#include <ctype.h> +#include <time.h> #include "util/log.h" #include "util/net_help.h" #include "util/config_file.h" #include "testcode/replay.h" -#include "testcode/ldns-testpkts.h" +#include "testcode/testpkts.h" #include "testcode/fake_event.h" +#include "ldns/str2wire.h" /** max length of lines in file */ #define MAX_LINE_LEN 10240 @@ -138,16 +141,15 @@ strip_end_white(char* p) * @param remain: Rest of line (after RANGE keyword). * @param in: file to read from. * @param name: name to print in errors. - * @param lineno: incremented as lines are read. + * @param pstate: read state structure with + * with lineno : incremented as lines are read. + * ttl, origin, prev for readentry. * @param line: line buffer. - * @param ttl: for readentry - * @param or: for readentry - * @param prev: for readentry * @return: range object to add to list, or NULL on error. */ static struct replay_range* -replay_range_read(char* remain, FILE* in, const char* name, int* lineno, - char* line, uint32_t* ttl, ldns_rdf** or, ldns_rdf** prev) +replay_range_read(char* remain, FILE* in, const char* name, + struct sldns_file_parse_state* pstate, char* line) { struct replay_range* rng = (struct replay_range*)malloc( sizeof(struct replay_range)); @@ -166,7 +168,7 @@ replay_range_read(char* remain, FILE* in, const char* name, int* lineno, /* read entries */ pos = ftello(in); while(fgets(line, MAX_LINE_LEN-1, in)) { - (*lineno)++; + pstate->lineno++; parse = line; while(isspace((int)*parse)) parse++; @@ -180,7 +182,7 @@ replay_range_read(char* remain, FILE* in, const char* name, int* lineno, strip_end_white(parse); if(!extstrtoaddr(parse, &rng->addr, &rng->addrlen)) { log_err("Line %d: could not read ADDRESS: %s", - *lineno, parse); + pstate->lineno, parse); free(rng); return NULL; } @@ -191,11 +193,11 @@ replay_range_read(char* remain, FILE* in, const char* name, int* lineno, return rng; } /* set position before line; read entry */ - (*lineno)--; + pstate->lineno--; fseeko(in, pos, SEEK_SET); - entry = read_entry(in, name, lineno, ttl, or, prev, 1); + entry = read_entry(in, name, pstate, 1); if(!entry) - fatal_exit("%d: bad entry", *lineno); + fatal_exit("%d: bad entry", pstate->lineno); entry->next = NULL; if(last) last->next = entry; @@ -258,15 +260,13 @@ read_assign_step(char* remain, struct replay_moment* mom) * @param remain: Rest of line (after STEP keyword). * @param in: file to read from. * @param name: name to print in errors. - * @param lineno: incremented as lines are read. - * @param ttl: for readentry - * @param or: for readentry - * @param prev: for readentry + * @param pstate: with lineno, ttl, origin, prev for parse state. + * lineno is incremented. * @return: range object to add to list, or NULL on error. */ static struct replay_moment* -replay_moment_read(char* remain, FILE* in, const char* name, int* lineno, - uint32_t* ttl, ldns_rdf** or, ldns_rdf** prev) +replay_moment_read(char* remain, FILE* in, const char* name, + struct sldns_file_parse_state* pstate) { struct replay_moment* mom = (struct replay_moment*)malloc( sizeof(struct replay_moment)); @@ -276,7 +276,7 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno, return NULL; memset(mom, 0, sizeof(*mom)); if(sscanf(remain, " %d%n", &mom->time_step, &skip) != 1) { - log_err("%d: cannot read number: %s", *lineno, remain); + log_err("%d: cannot read number: %s", pstate->lineno, remain); free(mom); return NULL; } @@ -322,7 +322,7 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno, remain[strlen(remain)-1] = 0; mom->autotrust_id = strdup(remain); if(!mom->autotrust_id) fatal_exit("out of memory"); - read_file_content(in, lineno, mom); + read_file_content(in, &pstate->lineno, mom); } else if(parse_keyword(&remain, "ERROR")) { mom->evt_type = repevt_error; } else if(parse_keyword(&remain, "TRAFFIC")) { @@ -357,7 +357,7 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno, if(!mom->string) fatal_exit("out of memory"); if(!mom->variable) fatal_exit("out of memory"); } else { - log_err("%d: unknown event type %s", *lineno, remain); + log_err("%d: unknown event type %s", pstate->lineno, remain); free(mom); return NULL; } @@ -370,7 +370,7 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno, remain[strlen(remain)-1] = 0; if(!extstrtoaddr(remain, &mom->addr, &mom->addrlen)) { log_err("line %d: could not parse ADDRESS: %s", - *lineno, remain); + pstate->lineno, remain); free(mom); return NULL; } @@ -381,7 +381,7 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno, sec = strtod(remain, &remain); if(sec == 0. && errno != 0) { log_err("line %d: could not parse ELAPSE: %s (%s)", - *lineno, remain, strerror(errno)); + pstate->lineno, remain, strerror(errno)); free(mom); return NULL; } @@ -393,7 +393,7 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno, } if(readentry) { - mom->match = read_entry(in, name, lineno, ttl, or, prev, 1); + mom->match = read_entry(in, name, pstate, 1); if(!mom->match) { free(mom); return NULL; @@ -432,13 +432,15 @@ replay_scenario_read(FILE* in, const char* name, int* lineno) char line[MAX_LINE_LEN]; char *parse; struct replay_scenario* scen = NULL; - uint32_t ttl = 3600; - ldns_rdf* or = NULL; - ldns_rdf* prev = NULL; + struct sldns_file_parse_state pstate; line[MAX_LINE_LEN-1]=0; + memset(&pstate, 0, sizeof(pstate)); + pstate.default_ttl = 3600; + pstate.lineno = *lineno; while(fgets(line, MAX_LINE_LEN-1, in)) { parse=line; + pstate.lineno++; (*lineno)++; while(isspace((int)*parse)) parse++; @@ -456,16 +458,18 @@ replay_scenario_read(FILE* in, const char* name, int* lineno) fatal_exit("%d: expected SCENARIO", *lineno); if(parse_keyword(&parse, "RANGE_BEGIN")) { struct replay_range* newr = replay_range_read(parse, - in, name, lineno, line, &ttl, &or, &prev); + in, name, &pstate, line); if(!newr) - fatal_exit("%d: bad range", *lineno); + fatal_exit("%d: bad range", pstate.lineno); + *lineno = pstate.lineno; newr->next_range = scen->range_list; scen->range_list = newr; } else if(parse_keyword(&parse, "STEP")) { struct replay_moment* mom = replay_moment_read(parse, - in, name, lineno, &ttl, &or, &prev); + in, name, &pstate); if(!mom) - fatal_exit("%d: bad moment", *lineno); + fatal_exit("%d: bad moment", pstate.lineno); + *lineno = pstate.lineno; if(scen->mom_last && scen->mom_last->time_step >= mom->time_step) fatal_exit("%d: time goes backwards", *lineno); @@ -481,13 +485,9 @@ replay_scenario_read(FILE* in, const char* name, int* lineno) p = p->mom_next; } log_info("Scenario has %d steps", num); - ldns_rdf_deep_free(or); - ldns_rdf_deep_free(prev); return scen; } } - ldns_rdf_deep_free(or); - ldns_rdf_deep_free(prev); replay_scenario_delete(scen); return NULL; } @@ -792,7 +792,7 @@ macro_expand(rbtree_t* store, struct replay_runtime* runtime, char** text) /* check for functions */ if(strcmp(buf, "time") == 0) { - snprintf(buf, sizeof(buf), "%lld", (long long)runtime->now_secs); + snprintf(buf, sizeof(buf), ARG_LL "d", (long long)runtime->now_secs); *text += len; return strdup(buf); } else if(strcmp(buf, "timeout") == 0) { @@ -800,7 +800,7 @@ macro_expand(rbtree_t* store, struct replay_runtime* runtime, char** text) struct fake_timer* t = first_timer(runtime); if(t && (time_t)t->tv.tv_sec >= runtime->now_secs) res = (time_t)t->tv.tv_sec - runtime->now_secs; - snprintf(buf, sizeof(buf), "%lld", (long long)res); + snprintf(buf, sizeof(buf), ARG_LL "d", (long long)res); *text += len; return strdup(buf); } else if(strncmp(buf, "ctime ", 6) == 0 || diff --git a/testcode/replay.h b/testcode/replay.h index beac3ce839d2..05bd442f57f5 100644 --- a/testcode/replay.h +++ b/testcode/replay.h @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -129,7 +129,7 @@ #ifndef TESTCODE_REPLAY_H #define TESTCODE_REPLAY_H #include "util/netevent.h" -#include "testcode/ldns-testpkts.h" +#include "testcode/testpkts.h" #include "util/rbtree.h" struct replay_answer; struct replay_moment; @@ -138,6 +138,7 @@ struct fake_pending; struct fake_timer; struct replay_var; struct infra_cache; +struct sldns_buffer; /** * A replay scenario. @@ -217,12 +218,6 @@ struct replay_moment { /** length of addr, if 0, then any address will do */ socklen_t addrlen; - /** what pending query should timeout or is answered. or - * NULL for last sent query. - * Unused at this time. - */ - ldns_rr* qname; - /** macro name, for assign. */ char* variable; /** string argument, for assign. */ @@ -318,7 +313,7 @@ struct replay_runtime { */ struct fake_pending { /** what is important only that we remember the query, copied here. */ - ldns_buffer* buffer; + struct sldns_buffer* buffer; /** and to what address this is sent to. */ struct sockaddr_storage addr; /** len of addr */ @@ -338,8 +333,9 @@ struct fake_pending { /** next in pending list */ struct fake_pending* next; - /** the buffer parsed into a ldns_pkt */ - ldns_pkt* pkt; + /** the buffer parsed into a sldns_pkt */ + uint8_t* pkt; + size_t pkt_len; /** by what transport was the query sent out */ enum transport_type transport; /** if this is a serviced query */ @@ -357,7 +353,8 @@ struct replay_answer { /** reply information */ struct comm_reply repinfo; /** the answer preparsed as ldns pkt */ - ldns_pkt* pkt; + uint8_t* pkt; + size_t pkt_len; }; /** diff --git a/testcode/signit.c b/testcode/signit.c index 49256e707d31..719687b8bd93 100644 --- a/testcode/signit.c +++ b/testcode/signit.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -41,9 +41,9 @@ */ #include "config.h" #include <ldns/ldns.h> -#include "util/log.h" -#include "util/config_file.h" -#include "util/net_help.h" +#include <assert.h> + +#define DNSKEY_BIT_ZSK 0x0100 /** * Key settings @@ -74,26 +74,61 @@ usage() exit(1); } +static time_t +convert_timeval(const char* str) +{ + time_t t; + struct tm tm; + memset(&tm, 0, sizeof(tm)); + if(strlen(str) < 14) + return 0; + if(sscanf(str, "%4d%2d%2d%2d%2d%2d", &tm.tm_year, &tm.tm_mon, + &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) + return 0; + tm.tm_year -= 1900; + tm.tm_mon--; + /* Check values */ + if (tm.tm_year < 70) return 0; + if (tm.tm_mon < 0 || tm.tm_mon > 11) return 0; + if (tm.tm_mday < 1 || tm.tm_mday > 31) return 0; + if (tm.tm_hour < 0 || tm.tm_hour > 23) return 0; + if (tm.tm_min < 0 || tm.tm_min > 59) return 0; + if (tm.tm_sec < 0 || tm.tm_sec > 59) return 0; + /* call ldns conversion function */ + t = sldns_mktime_from_utc(&tm); + return t; +} + +static void fatal_exit(const char* format, ...) +{ + va_list args; + va_start(args, format); + printf("fatal exit: "); + vprintf(format, args); + va_end(args); + exit(1); +} + /** read expi ince keytag owner from cmdline */ static void parse_cmdline(char *argv[], struct keysets* s) { - s->expi = cfg_convert_timeval(argv[1]); - s->incep = cfg_convert_timeval(argv[2]); + s->expi = convert_timeval(argv[1]); + s->incep = convert_timeval(argv[2]); s->keytag = (uint16_t)atoi(argv[3]); s->owner = argv[4]; s->flags = DNSKEY_BIT_ZSK; /* to enforce signing */ } /** read all key files, exit on error */ -static ldns_key_list* +static sldns_key_list* read_keys(int num, char* names[], struct keysets* set) { int i; - ldns_key_list* keys = ldns_key_list_new(); - ldns_key* k; - ldns_rdf* rdf; - ldns_status s; + sldns_key_list* keys = sldns_key_list_new(); + sldns_key* k; + sldns_rdf* rdf; + sldns_status s; int b; FILE* in; @@ -103,45 +138,45 @@ read_keys(int num, char* names[], struct keysets* set) in = fopen(names[i], "r"); if(!in) fatal_exit("could not open %s: %s", names[i], strerror(errno)); - s = ldns_key_new_frm_fp(&k, in); + s = sldns_key_new_frm_fp(&k, in); fclose(in); if(s != LDNS_STATUS_OK) fatal_exit("bad keyfile %s: %s", names[i], - ldns_get_errorstr_by_id(s)); - ldns_key_set_expiration(k, set->expi); - ldns_key_set_inception(k, set->incep); - s = ldns_str2rdf_dname(&rdf, set->owner); + sldns_get_errorstr_by_id(s)); + sldns_key_set_expiration(k, set->expi); + sldns_key_set_inception(k, set->incep); + s = sldns_str2rdf_dname(&rdf, set->owner); if(s != LDNS_STATUS_OK) fatal_exit("bad owner name %s: %s", set->owner, - ldns_get_errorstr_by_id(s)); - ldns_key_set_pubkey_owner(k, rdf); - ldns_key_set_flags(k, set->flags); - ldns_key_set_keytag(k, set->keytag); - b = ldns_key_list_push_key(keys, k); - log_assert(b); + sldns_get_errorstr_by_id(s)); + sldns_key_set_pubkey_owner(k, rdf); + sldns_key_set_flags(k, set->flags); + sldns_key_set_keytag(k, set->keytag); + b = sldns_key_list_push_key(keys, k); + assert(b); } return keys; } /** read list of rrs from the file */ -static ldns_rr_list* +static sldns_rr_list* read_rrs(FILE* in) { uint32_t my_ttl = 3600; - ldns_rdf *my_origin = NULL; - ldns_rdf *my_prev = NULL; - ldns_status s; + sldns_rdf *my_origin = NULL; + sldns_rdf *my_prev = NULL; + sldns_status s; int line_nr = 1; int b; - ldns_rr_list* list; - ldns_rr *rr; + sldns_rr_list* list; + sldns_rr *rr; - list = ldns_rr_list_new(); + list = sldns_rr_list_new(); if(!list) fatal_exit("alloc error"); while(!feof(in)) { - s = ldns_rr_new_frm_fp_l(&rr, in, &my_ttl, &my_origin, + s = sldns_rr_new_frm_fp_l(&rr, in, &my_ttl, &my_origin, &my_prev, &line_nr); if(s == LDNS_STATUS_SYNTAX_TTL || s == LDNS_STATUS_SYNTAX_ORIGIN || @@ -149,9 +184,9 @@ read_rrs(FILE* in) continue; else if(s != LDNS_STATUS_OK) fatal_exit("parse error in line %d: %s", line_nr, - ldns_get_errorstr_by_id(s)); - b = ldns_rr_list_push_rr(list, rr); - log_assert(b); + sldns_get_errorstr_by_id(s)); + b = sldns_rr_list_push_rr(list, rr); + assert(b); } printf("read %d lines\n", line_nr); @@ -160,21 +195,21 @@ read_rrs(FILE* in) /** sign the rrs with the keys */ static void -signit(ldns_rr_list* rrs, ldns_key_list* keys) +signit(sldns_rr_list* rrs, sldns_key_list* keys) { - ldns_rr_list* rrset; - ldns_rr_list* sigs; + sldns_rr_list* rrset; + sldns_rr_list* sigs; - while(ldns_rr_list_rr_count(rrs) > 0) { - rrset = ldns_rr_list_pop_rrset(rrs); + while(sldns_rr_list_rr_count(rrs) > 0) { + rrset = sldns_rr_list_pop_rrset(rrs); if(!rrset) fatal_exit("copy alloc failure"); - sigs = ldns_sign_public(rrset, keys); + sigs = sldns_sign_public(rrset, keys); if(!sigs) fatal_exit("failed to sign"); - ldns_rr_list_print(stdout, rrset); - ldns_rr_list_print(stdout, sigs); + sldns_rr_list_print(stdout, rrset); + sldns_rr_list_print(stdout, sigs); printf("\n"); - ldns_rr_list_free(rrset); - ldns_rr_list_free(sigs); + sldns_rr_list_free(rrset); + sldns_rr_list_free(sigs); } } @@ -182,18 +217,18 @@ signit(ldns_rr_list* rrs, ldns_key_list* keys) static void process_keys(int argc, char* argv[]) { - ldns_rr_list* rrs; - ldns_key_list* keys; + sldns_rr_list* rrs; + sldns_key_list* keys; struct keysets settings; - log_assert(argc == 6); + assert(argc == 6); parse_cmdline(argv, &settings); keys = read_keys(1, argv+5, &settings); rrs = read_rrs(stdin); signit(rrs, keys); - ldns_rr_list_deep_free(rrs); - ldns_key_list_free(keys); + sldns_rr_list_deep_free(rrs); + sldns_key_list_free(keys); } /** process nsec3 params and perform hashing */ @@ -201,43 +236,42 @@ static void process_nsec3(int argc, char* argv[]) { char line[10240]; - ldns_rdf* salt; - ldns_rdf* in, *out; - ldns_status status; - status = ldns_str2rdf_nsec3_salt(&salt, argv[5]); + sldns_rdf* salt; + sldns_rdf* in, *out; + sldns_status status; + status = sldns_str2rdf_nsec3_salt(&salt, argv[5]); if(status != LDNS_STATUS_OK) fatal_exit("Could not parse salt %s: %s", argv[5], - ldns_get_errorstr_by_id(status)); - log_assert(argc == 6); + sldns_get_errorstr_by_id(status)); + assert(argc == 6); while(fgets(line, (int)sizeof(line), stdin)) { if(strlen(line) > 0) line[strlen(line)-1] = 0; /* remove trailing newline */ if(line[0]==0) continue; - status = ldns_str2rdf_dname(&in, line); + status = sldns_str2rdf_dname(&in, line); if(status != LDNS_STATUS_OK) fatal_exit("Could not parse name %s: %s", line, - ldns_get_errorstr_by_id(status)); - ldns_rdf_print(stdout, in); + sldns_get_errorstr_by_id(status)); + sldns_rdf_print(stdout, in); printf(" -> "); /* arg 3 is flags, unused */ - out = ldns_nsec3_hash_name(in, (uint8_t)atoi(argv[2]), + out = sldns_nsec3_hash_name(in, (uint8_t)atoi(argv[2]), (uint16_t)atoi(argv[4]), - ldns_rdf_data(salt)[0], ldns_rdf_data(salt)+1); + sldns_rdf_data(salt)[0], sldns_rdf_data(salt)+1); if(!out) fatal_exit("Could not hash %s", line); - ldns_rdf_print(stdout, out); + sldns_rdf_print(stdout, out); printf("\n"); - ldns_rdf_deep_free(in); - ldns_rdf_deep_free(out); + sldns_rdf_deep_free(in); + sldns_rdf_deep_free(out); } - ldns_rdf_deep_free(salt); + sldns_rdf_deep_free(salt); } /** main program */ int main(int argc, char* argv[]) { - log_init(NULL, 0, NULL); if(argc != 6) { usage(); } diff --git a/testcode/streamtcp.c b/testcode/streamtcp.c index 06a18e4cfafb..d93ab966d564 100644 --- a/testcode/streamtcp.c +++ b/testcode/streamtcp.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -43,7 +43,6 @@ #ifdef HAVE_GETOPT_H #include <getopt.h> #endif -#include <ldns/ldns.h> #include <signal.h> #include "util/locks.h" #include "util/log.h" @@ -52,6 +51,11 @@ #include "util/data/msgparse.h" #include "util/data/msgreply.h" #include "util/data/dname.h" +#include "ldns/sbuffer.h" +#include "ldns/str2wire.h" +#include "ldns/wire2str.h" +#include <openssl/ssl.h> +#include <openssl/rand.h> #include <openssl/err.h> #ifndef PF_INET6 @@ -108,31 +112,26 @@ open_svr(const char* svr, int udp) /** write a query over the TCP fd */ static void -write_q(int fd, int udp, SSL* ssl, ldns_buffer* buf, uint16_t id, +write_q(int fd, int udp, SSL* ssl, sldns_buffer* buf, uint16_t id, const char* strname, const char* strtype, const char* strclass) { struct query_info qinfo; - ldns_rdf* rdf; uint16_t len; /* qname */ - rdf = ldns_dname_new_frm_str(strname); - if(!rdf) { + qinfo.qname = sldns_str2wire_dname(strname, &qinfo.qname_len); + if(!qinfo.qname) { printf("cannot parse query name: '%s'\n", strname); exit(1); } - qinfo.qname = memdup(ldns_rdf_data(rdf), ldns_rdf_size(rdf)); - if(!qinfo.qname) fatal_exit("out of memory"); - (void)dname_count_size_labels(qinfo.qname, &qinfo.qname_len); - ldns_rdf_deep_free(rdf); /* qtype and qclass */ - qinfo.qtype = ldns_get_rr_type_by_name(strtype); - qinfo.qclass = ldns_get_rr_class_by_name(strclass); + qinfo.qtype = sldns_get_rr_type_by_name(strtype); + qinfo.qclass = sldns_get_rr_class_by_name(strclass); /* make query */ qinfo_query_encode(buf, &qinfo); - ldns_buffer_write_u16_at(buf, 0, id); - ldns_buffer_write_u16_at(buf, 2, BIT_RD); + sldns_buffer_write_u16_at(buf, 0, id); + sldns_buffer_write_u16_at(buf, 2, BIT_RD); if(1) { /* add EDNS DO */ @@ -146,7 +145,7 @@ write_q(int fd, int udp, SSL* ssl, ldns_buffer* buf, uint16_t id, /* send it */ if(!udp) { - len = (uint16_t)ldns_buffer_limit(buf); + len = (uint16_t)sldns_buffer_limit(buf); len = htons(len); if(ssl) { if(SSL_write(ssl, (void*)&len, (int)sizeof(len)) <= 0) { @@ -167,15 +166,15 @@ write_q(int fd, int udp, SSL* ssl, ldns_buffer* buf, uint16_t id, } } if(ssl) { - if(SSL_write(ssl, (void*)ldns_buffer_begin(buf), - (int)ldns_buffer_limit(buf)) <= 0) { + if(SSL_write(ssl, (void*)sldns_buffer_begin(buf), + (int)sldns_buffer_limit(buf)) <= 0) { log_crypto_err("cannot SSL_write"); exit(1); } } else { - if(send(fd, (void*)ldns_buffer_begin(buf), - ldns_buffer_limit(buf), 0) < - (ssize_t)ldns_buffer_limit(buf)) { + if(send(fd, (void*)sldns_buffer_begin(buf), + sldns_buffer_limit(buf), 0) < + (ssize_t)sldns_buffer_limit(buf)) { #ifndef USE_WINSOCK perror("send() data failed"); #else @@ -190,11 +189,10 @@ write_q(int fd, int udp, SSL* ssl, ldns_buffer* buf, uint16_t id, /** receive DNS datagram over TCP and print it */ static void -recv_one(int fd, int udp, SSL* ssl, ldns_buffer* buf) +recv_one(int fd, int udp, SSL* ssl, sldns_buffer* buf) { + char* pktstr; uint16_t len; - ldns_pkt* pkt; - ldns_status status; if(!udp) { if(ssl) { if(SSL_read(ssl, (void*)&len, (int)sizeof(len)) <= 0) { @@ -214,10 +212,10 @@ recv_one(int fd, int udp, SSL* ssl, ldns_buffer* buf) } } len = ntohs(len); - ldns_buffer_clear(buf); - ldns_buffer_set_limit(buf, len); + sldns_buffer_clear(buf); + sldns_buffer_set_limit(buf, len); if(ssl) { - int r = SSL_read(ssl, (void*)ldns_buffer_begin(buf), + int r = SSL_read(ssl, (void*)sldns_buffer_begin(buf), (int)len); if(r <= 0) { log_crypto_err("could not SSL_read"); @@ -226,7 +224,7 @@ recv_one(int fd, int udp, SSL* ssl, ldns_buffer* buf) if(r != (int)len) fatal_exit("ssl_read %d of %d", r, len); } else { - if(recv(fd, (void*)ldns_buffer_begin(buf), len, 0) < + if(recv(fd, (void*)sldns_buffer_begin(buf), len, 0) < (ssize_t)len) { #ifndef USE_WINSOCK perror("read() data failed"); @@ -239,9 +237,9 @@ recv_one(int fd, int udp, SSL* ssl, ldns_buffer* buf) } } else { ssize_t l; - ldns_buffer_clear(buf); - if((l=recv(fd, (void*)ldns_buffer_begin(buf), - ldns_buffer_capacity(buf), 0)) < 0) { + sldns_buffer_clear(buf); + if((l=recv(fd, (void*)sldns_buffer_begin(buf), + sldns_buffer_capacity(buf), 0)) < 0) { #ifndef USE_WINSOCK perror("read() data failed"); #else @@ -250,28 +248,31 @@ recv_one(int fd, int udp, SSL* ssl, ldns_buffer* buf) #endif exit(1); } - ldns_buffer_set_limit(buf, (size_t)l); + sldns_buffer_set_limit(buf, (size_t)l); len = (size_t)l; } printf("\nnext received packet\n"); log_buf(0, "data", buf); - status = ldns_wire2pkt(&pkt, ldns_buffer_begin(buf), len); - if(status != LDNS_STATUS_OK) { - printf("could not parse incoming packet: %s\n", - ldns_get_errorstr_by_id(status)); - log_buf(0, "data was", buf); - exit(1); + pktstr = sldns_wire2str_pkt(sldns_buffer_begin(buf), len); + printf("%s", pktstr); + free(pktstr); +} + +static int get_random(void) +{ + int r; + if (RAND_bytes((unsigned char*)&r, (int)sizeof(r)) == 1) { + return r; } - ldns_pkt_print(stdout, pkt); - ldns_pkt_free(pkt); + return (int)random(); } /** send the TCP queries and print answers */ static void send_em(const char* svr, int udp, int usessl, int noanswer, int num, char** qs) { - ldns_buffer* buf = ldns_buffer_new(65553); + sldns_buffer* buf = sldns_buffer_new(65553); int fd = open_svr(svr, udp); int i; SSL_CTX* ctx = NULL; @@ -305,7 +306,7 @@ send_em(const char* svr, int udp, int usessl, int noanswer, int num, char** qs) } for(i=0; i<num; i+=3) { printf("\nNext query is %s %s %s\n", qs[i], qs[i+1], qs[i+2]); - write_q(fd, udp, ssl, buf, ldns_get_random(), qs[i], + write_q(fd, udp, ssl, buf, (uint16_t)get_random(), qs[i], qs[i+1], qs[i+2]); /* print at least one result */ if(!noanswer) @@ -322,7 +323,7 @@ send_em(const char* svr, int udp, int usessl, int noanswer, int num, char** qs) #else closesocket(fd); #endif - ldns_buffer_free(buf); + sldns_buffer_free(buf); printf("orderly exit\n"); } diff --git a/testcode/testbound.c b/testcode/testbound.c index 6e88edf22e62..c5e2d4d61fd4 100644 --- a/testcode/testbound.c +++ b/testcode/testbound.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** @@ -39,11 +39,16 @@ */ #include "config.h" -#include "testcode/ldns-testpkts.h" +#ifdef HAVE_TIME_H +# include <time.h> +#endif +#include "testcode/testpkts.h" #include "testcode/replay.h" #include "testcode/fake_event.h" #include "daemon/remote.h" #include "util/config_file.h" +#include "ldns/keyraw.h" +#include <ctype.h> /** signal that this is a testbound compile */ #define unbound_testbound 1 @@ -300,7 +305,7 @@ main(int argc, char* argv[]) break; case 'g': #ifdef USE_GOST - if(ldns_key_EVP_load_gost_id()) { + if(sldns_key_EVP_load_gost_id()) { printf("GOST supported\n"); exit(0); } else { diff --git a/testcode/testpkts.c b/testcode/testpkts.c new file mode 100644 index 000000000000..c5aa2445374e --- /dev/null +++ b/testcode/testpkts.c @@ -0,0 +1,1427 @@ +/* + * testpkts. Data file parse for test packets, and query matching. + * + * Data storage for specially crafted replies for testing purposes. + * + * (c) NLnet Labs, 2005, 2006, 2007, 2008 + * See the file LICENSE for the license + */ + +/** + * \file + * This is a debugging aid. It is not efficient, especially + * with a long config file, but it can give any reply to any query. + * This can help the developer pre-script replies for queries. + * + * You can specify a packet RR by RR with header flags to return. + * + * Missing features: + * - matching content different from reply content. + * - find way to adjust mangled packets? + */ + +#include "config.h" +struct sockaddr_storage; +#include <errno.h> +#include <stdarg.h> +#include <ctype.h> +#include "testcode/testpkts.h" +#include "util/net_help.h" +#include "ldns/sbuffer.h" +#include "ldns/rrdef.h" +#include "ldns/pkthdr.h" +#include "ldns/str2wire.h" +#include "ldns/wire2str.h" + +/** max size of a packet */ +#define MAX_PACKETLEN 65536 +/** max line length */ +#define MAX_LINE 10240 +/** string to show in warnings and errors */ +static const char* prog_name = "testpkts"; + +#ifndef UTIL_LOG_H +/** verbosity definition for compat */ +enum verbosity_value { NO_VERBOSE=0 }; +#endif +/** logging routine, provided by caller */ +void verbose(enum verbosity_value lvl, const char* msg, ...) ATTR_FORMAT(printf, 2, 3); + +/** print error and exit */ +static void error(const char* msg, ...) +{ + va_list args; + va_start(args, msg); + fprintf(stderr, "%s error: ", prog_name); + vfprintf(stderr, msg, args); + fprintf(stderr, "\n"); + fflush(stderr); + va_end(args); + exit(EXIT_FAILURE); +} + +/** return if string is empty or comment */ +static int isendline(char c) +{ + if(c == ';' || c == '#' + || c == '\n' || c == 0) + return 1; + return 0; +} + +/** true if the string starts with the keyword given. Moves the str ahead. + * @param str: before keyword, afterwards after keyword and spaces. + * @param keyword: the keyword to match + * @return: true if keyword present. False otherwise, and str unchanged. +*/ +static int str_keyword(char** str, const char* keyword) +{ + size_t len = strlen(keyword); + assert(str && keyword); + if(strncmp(*str, keyword, len) != 0) + return 0; + *str += len; + while(isspace((int)**str)) + (*str)++; + return 1; +} + +/** Add reply packet to entry */ +static struct reply_packet* +entry_add_reply(struct entry* entry) +{ + struct reply_packet* pkt = (struct reply_packet*)malloc( + sizeof(struct reply_packet)); + struct reply_packet ** p = &entry->reply_list; + if(!pkt) error("out of memory"); + pkt->next = NULL; + pkt->packet_sleep = 0; + pkt->reply_pkt = NULL; + pkt->reply_from_hex = NULL; + /* link at end */ + while(*p) + p = &((*p)->next); + *p = pkt; + return pkt; +} + +/** parse MATCH line */ +static void matchline(char* line, struct entry* e) +{ + char* parse = line; + while(*parse) { + if(isendline(*parse)) + return; + if(str_keyword(&parse, "opcode")) { + e->match_opcode = 1; + } else if(str_keyword(&parse, "qtype")) { + e->match_qtype = 1; + } else if(str_keyword(&parse, "qname")) { + e->match_qname = 1; + } else if(str_keyword(&parse, "subdomain")) { + e->match_subdomain = 1; + } else if(str_keyword(&parse, "all")) { + e->match_all = 1; + } else if(str_keyword(&parse, "ttl")) { + e->match_ttl = 1; + } else if(str_keyword(&parse, "DO")) { + e->match_do = 1; + } else if(str_keyword(&parse, "noedns")) { + e->match_noedns = 1; + } else if(str_keyword(&parse, "UDP")) { + e->match_transport = transport_udp; + } else if(str_keyword(&parse, "TCP")) { + e->match_transport = transport_tcp; + } else if(str_keyword(&parse, "serial")) { + e->match_serial = 1; + if(*parse != '=' && *parse != ':') + error("expected = or : in MATCH: %s", line); + parse++; + e->ixfr_soa_serial = (uint32_t)strtol(parse, (char**)&parse, 10); + while(isspace((int)*parse)) + parse++; + } else { + error("could not parse MATCH: '%s'", parse); + } + } +} + +/** parse REPLY line */ +static void replyline(char* line, uint8_t* reply, size_t reply_len, + int* do_flag) +{ + char* parse = line; + if(reply_len < LDNS_HEADER_SIZE) error("packet too short for header"); + while(*parse) { + if(isendline(*parse)) + return; + /* opcodes */ + if(str_keyword(&parse, "QUERY")) { + LDNS_OPCODE_SET(reply, LDNS_PACKET_QUERY); + } else if(str_keyword(&parse, "IQUERY")) { + LDNS_OPCODE_SET(reply, LDNS_PACKET_IQUERY); + } else if(str_keyword(&parse, "STATUS")) { + LDNS_OPCODE_SET(reply, LDNS_PACKET_STATUS); + } else if(str_keyword(&parse, "NOTIFY")) { + LDNS_OPCODE_SET(reply, LDNS_PACKET_NOTIFY); + } else if(str_keyword(&parse, "UPDATE")) { + LDNS_OPCODE_SET(reply, LDNS_PACKET_UPDATE); + /* rcodes */ + } else if(str_keyword(&parse, "NOERROR")) { + LDNS_RCODE_SET(reply, LDNS_RCODE_NOERROR); + } else if(str_keyword(&parse, "FORMERR")) { + LDNS_RCODE_SET(reply, LDNS_RCODE_FORMERR); + } else if(str_keyword(&parse, "SERVFAIL")) { + LDNS_RCODE_SET(reply, LDNS_RCODE_SERVFAIL); + } else if(str_keyword(&parse, "NXDOMAIN")) { + LDNS_RCODE_SET(reply, LDNS_RCODE_NXDOMAIN); + } else if(str_keyword(&parse, "NOTIMPL")) { + LDNS_RCODE_SET(reply, LDNS_RCODE_NOTIMPL); + } else if(str_keyword(&parse, "REFUSED")) { + LDNS_RCODE_SET(reply, LDNS_RCODE_REFUSED); + } else if(str_keyword(&parse, "YXDOMAIN")) { + LDNS_RCODE_SET(reply, LDNS_RCODE_YXDOMAIN); + } else if(str_keyword(&parse, "YXRRSET")) { + LDNS_RCODE_SET(reply, LDNS_RCODE_YXRRSET); + } else if(str_keyword(&parse, "NXRRSET")) { + LDNS_RCODE_SET(reply, LDNS_RCODE_NXRRSET); + } else if(str_keyword(&parse, "NOTAUTH")) { + LDNS_RCODE_SET(reply, LDNS_RCODE_NOTAUTH); + } else if(str_keyword(&parse, "NOTZONE")) { + LDNS_RCODE_SET(reply, LDNS_RCODE_NOTZONE); + /* flags */ + } else if(str_keyword(&parse, "QR")) { + LDNS_QR_SET(reply); + } else if(str_keyword(&parse, "AA")) { + LDNS_AA_SET(reply); + } else if(str_keyword(&parse, "TC")) { + LDNS_TC_SET(reply); + } else if(str_keyword(&parse, "RD")) { + LDNS_RD_SET(reply); + } else if(str_keyword(&parse, "CD")) { + LDNS_CD_SET(reply); + } else if(str_keyword(&parse, "RA")) { + LDNS_RA_SET(reply); + } else if(str_keyword(&parse, "AD")) { + LDNS_AD_SET(reply); + } else if(str_keyword(&parse, "DO")) { + *do_flag = 1; + } else { + error("could not parse REPLY: '%s'", parse); + } + } +} + +/** parse ADJUST line */ +static void adjustline(char* line, struct entry* e, + struct reply_packet* pkt) +{ + char* parse = line; + while(*parse) { + if(isendline(*parse)) + return; + if(str_keyword(&parse, "copy_id")) { + e->copy_id = 1; + } else if(str_keyword(&parse, "copy_query")) { + e->copy_query = 1; + } else if(str_keyword(&parse, "sleep=")) { + e->sleeptime = (unsigned int) strtol(parse, (char**)&parse, 10); + while(isspace((int)*parse)) + parse++; + } else if(str_keyword(&parse, "packet_sleep=")) { + pkt->packet_sleep = (unsigned int) strtol(parse, (char**)&parse, 10); + while(isspace((int)*parse)) + parse++; + } else { + error("could not parse ADJUST: '%s'", parse); + } + } +} + +/** create new entry */ +static struct entry* new_entry() +{ + struct entry* e = (struct entry*)malloc(sizeof(struct entry)); + if(!e) error("out of memory"); + memset(e, 0, sizeof(*e)); + e->match_opcode = 0; + e->match_qtype = 0; + e->match_qname = 0; + e->match_subdomain = 0; + e->match_all = 0; + e->match_ttl = 0; + e->match_do = 0; + e->match_noedns = 0; + e->match_serial = 0; + e->ixfr_soa_serial = 0; + e->match_transport = transport_any; + e->reply_list = NULL; + e->copy_id = 0; + e->copy_query = 0; + e->sleeptime = 0; + e->next = NULL; + return e; +} + +/** + * Converts a hex string to binary data + * @param hexstr: string of hex. + * @param len: is the length of the string + * @param buf: is the buffer to store the result in + * @param offset: is the starting position in the result buffer + * @param buf_len: is the length of buf. + * @return This function returns the length of the result + */ +static size_t +hexstr2bin(char *hexstr, int len, uint8_t *buf, size_t offset, size_t buf_len) +{ + char c; + int i; + uint8_t int8 = 0; + int sec = 0; + size_t bufpos = 0; + + if (len % 2 != 0) { + return 0; + } + + for (i=0; i<len; i++) { + c = hexstr[i]; + + /* case insensitive, skip spaces */ + if (c != ' ') { + if (c >= '0' && c <= '9') { + int8 += c & 0x0f; + } else if (c >= 'a' && c <= 'z') { + int8 += (c & 0x0f) + 9; + } else if (c >= 'A' && c <= 'Z') { + int8 += (c & 0x0f) + 9; + } else { + return 0; + } + + if (sec == 0) { + int8 = int8 << 4; + sec = 1; + } else { + if (bufpos + offset + 1 <= buf_len) { + buf[bufpos+offset] = int8; + int8 = 0; + sec = 0; + bufpos++; + } else { + fprintf(stderr, "Buffer too small in hexstr2bin"); + } + } + } + } + return bufpos; +} + +/** convert hex buffer to binary buffer */ +static sldns_buffer * +hex_buffer2wire(sldns_buffer *data_buffer) +{ + sldns_buffer *wire_buffer = NULL; + int c; + + /* stat hack + * 0 = normal + * 1 = comment (skip to end of line) + * 2 = unprintable character found, read binary data directly + */ + size_t data_buf_pos = 0; + int state = 0; + uint8_t *hexbuf; + int hexbufpos = 0; + size_t wirelen; + uint8_t *data_wire = (uint8_t *) sldns_buffer_begin(data_buffer); + uint8_t *wire = (uint8_t*)malloc(MAX_PACKETLEN); + if(!wire) error("out of memory"); + + hexbuf = (uint8_t*)malloc(MAX_PACKETLEN); + if(!hexbuf) error("out of memory"); + for (data_buf_pos = 0; data_buf_pos < sldns_buffer_position(data_buffer); data_buf_pos++) { + c = (int) data_wire[data_buf_pos]; + + if (state < 2 && !isascii(c)) { + /*verbose("non ascii character found in file: (%d) switching to raw mode\n", c);*/ + state = 2; + } + switch (state) { + case 0: + if ( (c >= '0' && c <= '9') || + (c >= 'a' && c <= 'f') || + (c >= 'A' && c <= 'F') ) + { + if (hexbufpos >= MAX_PACKETLEN) { + error("buffer overflow"); + free(hexbuf); + return 0; + + } + hexbuf[hexbufpos] = (uint8_t) c; + hexbufpos++; + } else if (c == ';') { + state = 1; + } else if (c == ' ' || c == '\t' || c == '\n') { + /* skip whitespace */ + } + break; + case 1: + if (c == '\n' || c == EOF) { + state = 0; + } + break; + case 2: + if (hexbufpos >= MAX_PACKETLEN) { + error("buffer overflow"); + free(hexbuf); + return 0; + } + hexbuf[hexbufpos] = (uint8_t) c; + hexbufpos++; + break; + } + } + + if (hexbufpos >= MAX_PACKETLEN) { + /*verbose("packet size reached\n");*/ + } + + /* lenient mode: length must be multiple of 2 */ + if (hexbufpos % 2 != 0) { + if (hexbufpos >= MAX_PACKETLEN) { + error("buffer overflow"); + free(hexbuf); + return 0; + } + hexbuf[hexbufpos] = (uint8_t) '0'; + hexbufpos++; + } + + if (state < 2) { + wirelen = hexstr2bin((char *) hexbuf, hexbufpos, wire, 0, MAX_PACKETLEN); + wire_buffer = sldns_buffer_new(wirelen); + sldns_buffer_new_frm_data(wire_buffer, wire, wirelen); + } else { + error("Incomplete hex data, not at byte boundary\n"); + } + free(wire); + free(hexbuf); + return wire_buffer; +} + +/** parse ORIGIN */ +static void +get_origin(const char* name, struct sldns_file_parse_state* pstate, char* parse) +{ + /* snip off rest of the text so as to make the parse work in ldns */ + char* end; + char store; + int status; + + end=parse; + while(!isspace((int)*end) && !isendline(*end)) + end++; + store = *end; + *end = 0; + verbose(3, "parsing '%s'\n", parse); + status = sldns_str2wire_dname_buf(parse, pstate->origin, + &pstate->origin_len); + *end = store; + if(status != 0) + error("%s line %d:\n\t%s: %s", name, pstate->lineno, + sldns_get_errorstr_parse(status), parse); +} + +/** add RR to packet */ +static void add_rr(char* rrstr, uint8_t* pktbuf, size_t pktsize, + size_t* pktlen, struct sldns_file_parse_state* pstate, + sldns_pkt_section add_section, const char* fname) +{ + /* it must be a RR, parse and add to packet. */ + size_t rr_len = pktsize - *pktlen; + size_t dname_len = 0; + int status; + uint8_t* origin = pstate->origin_len?pstate->origin:0; + uint8_t* prev = pstate->prev_rr_len?pstate->prev_rr:0; + if(*pktlen > pktsize || *pktlen < LDNS_HEADER_SIZE) + error("packet overflow"); + + /* parse RR */ + if(add_section == LDNS_SECTION_QUESTION) + status = sldns_str2wire_rr_question_buf(rrstr, pktbuf+*pktlen, + &rr_len, &dname_len, origin, pstate->origin_len, + prev, pstate->prev_rr_len); + else status = sldns_str2wire_rr_buf(rrstr, pktbuf+*pktlen, &rr_len, + &dname_len, pstate->default_ttl, origin, + pstate->origin_len, prev, pstate->prev_rr_len); + if(status != 0) + error("%s line %d:%d %s\n\t%s", fname, pstate->lineno, + LDNS_WIREPARSE_OFFSET(status), + sldns_get_errorstr_parse(status), rrstr); + *pktlen += rr_len; + + /* increase RR count */ + if(add_section == LDNS_SECTION_QUESTION) + sldns_write_uint16(pktbuf+4, LDNS_QDCOUNT(pktbuf)+1); + else if(add_section == LDNS_SECTION_ANSWER) + sldns_write_uint16(pktbuf+6, LDNS_ANCOUNT(pktbuf)+1); + else if(add_section == LDNS_SECTION_AUTHORITY) + sldns_write_uint16(pktbuf+8, LDNS_NSCOUNT(pktbuf)+1); + else if(add_section == LDNS_SECTION_ADDITIONAL) + sldns_write_uint16(pktbuf+10, LDNS_ARCOUNT(pktbuf)+1); + else error("internal error bad section %d", (int)add_section); +} + +/* add EDNS 4096 DO opt record */ +static void +add_do_flag(uint8_t* pktbuf, size_t pktsize, size_t* pktlen) +{ + uint8_t edns[] = {0x00, /* root label */ + 0x00, LDNS_RR_TYPE_OPT, /* type */ + 0x10, 0x00, /* class is UDPSIZE 4096 */ + 0x00, /* TTL[0] is ext rcode */ + 0x00, /* TTL[1] is edns version */ + 0x80, 0x00, /* TTL[2-3] is edns flags, DO */ + 0x00, 0x00 /* rdatalength (0 options) */ + }; + if(*pktlen < LDNS_HEADER_SIZE) + return; + if(*pktlen + sizeof(edns) > pktsize) + error("not enough space for EDNS OPT record"); + memmove(pktbuf+*pktlen, edns, sizeof(edns)); + sldns_write_uint16(pktbuf+10, LDNS_ARCOUNT(pktbuf)+1); + *pktlen += sizeof(edns); +} + +/* Reads one entry from file. Returns entry or NULL on error. */ +struct entry* +read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate, + int skip_whitespace) +{ + struct entry* current = NULL; + char line[MAX_LINE]; + char* parse; + sldns_pkt_section add_section = LDNS_SECTION_QUESTION; + struct reply_packet *cur_reply = NULL; + int reading_hex = 0; + sldns_buffer* hex_data_buffer = NULL; + uint8_t pktbuf[MAX_PACKETLEN]; + size_t pktlen = LDNS_HEADER_SIZE; + int do_flag = 0; /* DO flag in EDNS */ + memset(pktbuf, 0, pktlen); /* ID = 0, FLAGS="", and rr counts 0 */ + + while(fgets(line, (int)sizeof(line), in) != NULL) { + line[MAX_LINE-1] = 0; + parse = line; + pstate->lineno++; + + while(isspace((int)*parse)) + parse++; + /* test for keywords */ + if(isendline(*parse)) + continue; /* skip comment and empty lines */ + if(str_keyword(&parse, "ENTRY_BEGIN")) { + if(current) { + error("%s line %d: previous entry does not ENTRY_END", + name, pstate->lineno); + } + current = new_entry(); + current->lineno = pstate->lineno; + cur_reply = entry_add_reply(current); + continue; + } else if(str_keyword(&parse, "$ORIGIN")) { + get_origin(name, pstate, parse); + continue; + } else if(str_keyword(&parse, "$TTL")) { + pstate->default_ttl = (uint32_t)atoi(parse); + continue; + } + + /* working inside an entry */ + if(!current) { + error("%s line %d: expected ENTRY_BEGIN but got %s", + name, pstate->lineno, line); + } + if(str_keyword(&parse, "MATCH")) { + matchline(parse, current); + } else if(str_keyword(&parse, "REPLY")) { + replyline(parse, pktbuf, pktlen, &do_flag); + } else if(str_keyword(&parse, "ADJUST")) { + adjustline(parse, current, cur_reply); + } else if(str_keyword(&parse, "EXTRA_PACKET")) { + cur_reply = entry_add_reply(current); + } else if(str_keyword(&parse, "SECTION")) { + if(str_keyword(&parse, "QUESTION")) + add_section = LDNS_SECTION_QUESTION; + else if(str_keyword(&parse, "ANSWER")) + add_section = LDNS_SECTION_ANSWER; + else if(str_keyword(&parse, "AUTHORITY")) + add_section = LDNS_SECTION_AUTHORITY; + else if(str_keyword(&parse, "ADDITIONAL")) + add_section = LDNS_SECTION_ADDITIONAL; + else error("%s line %d: bad section %s", name, pstate->lineno, parse); + } else if(str_keyword(&parse, "HEX_ANSWER_BEGIN")) { + hex_data_buffer = sldns_buffer_new(MAX_PACKETLEN); + reading_hex = 1; + } else if(str_keyword(&parse, "HEX_ANSWER_END")) { + if(!reading_hex) { + error("%s line %d: HEX_ANSWER_END read but no HEX_ANSWER_BEGIN keyword seen", name, pstate->lineno); + } + reading_hex = 0; + cur_reply->reply_from_hex = hex_buffer2wire(hex_data_buffer); + sldns_buffer_free(hex_data_buffer); + hex_data_buffer = NULL; + } else if(str_keyword(&parse, "ENTRY_END")) { + if(hex_data_buffer) + sldns_buffer_free(hex_data_buffer); + if(pktlen != 0) { + if(do_flag) + add_do_flag(pktbuf, sizeof(pktbuf), + &pktlen); + cur_reply->reply_pkt = memdup(pktbuf, pktlen); + cur_reply->reply_len = pktlen; + if(!cur_reply->reply_pkt) + error("out of memory"); + } + return current; + } else if(reading_hex) { + sldns_buffer_printf(hex_data_buffer, "%s", line); + } else { + add_rr(skip_whitespace?parse:line, pktbuf, + sizeof(pktbuf), &pktlen, pstate, add_section, + name); + } + + } + if (reading_hex) { + error("%s: End of file reached while still reading hex, " + "missing HEX_ANSWER_END\n", name); + } + if(current) { + error("%s: End of file reached while reading entry. " + "missing ENTRY_END\n", name); + } + return 0; +} + +/* reads the canned reply file and returns a list of structs */ +struct entry* +read_datafile(const char* name, int skip_whitespace) +{ + struct entry* list = NULL; + struct entry* last = NULL; + struct entry* current = NULL; + FILE *in; + struct sldns_file_parse_state pstate; + int entry_num = 0; + memset(&pstate, 0, sizeof(pstate)); + + if((in=fopen(name, "r")) == NULL) { + error("could not open file %s: %s", name, strerror(errno)); + } + + while((current = read_entry(in, name, &pstate, skip_whitespace))) + { + if(last) + last->next = current; + else list = current; + last = current; + entry_num ++; + } + verbose(1, "%s: Read %d entries\n", prog_name, entry_num); + + fclose(in); + return list; +} + +/** get qtype from packet */ +static sldns_rr_type get_qtype(uint8_t* pkt, size_t pktlen) +{ + uint8_t* d; + size_t dl, sl=0; + char* snull = NULL; + if(pktlen < LDNS_HEADER_SIZE) + return 0; + if(LDNS_QDCOUNT(pkt) == 0) + return 0; + /* skip over dname with dname-scan routine */ + d = pkt+LDNS_HEADER_SIZE; + dl = pktlen-LDNS_HEADER_SIZE; + (void)sldns_wire2str_dname_scan(&d, &dl, &snull, &sl, pkt, pktlen); + if(dl < 2) + return 0; + return sldns_read_uint16(d); +} + +/** get qtype from packet */ +static size_t get_qname_len(uint8_t* pkt, size_t pktlen) +{ + uint8_t* d; + size_t dl, sl=0; + char* snull = NULL; + if(pktlen < LDNS_HEADER_SIZE) + return 0; + if(LDNS_QDCOUNT(pkt) == 0) + return 0; + /* skip over dname with dname-scan routine */ + d = pkt+LDNS_HEADER_SIZE; + dl = pktlen-LDNS_HEADER_SIZE; + (void)sldns_wire2str_dname_scan(&d, &dl, &snull, &sl, pkt, pktlen); + return pktlen-dl-LDNS_HEADER_SIZE; +} + +/** returns owner from packet */ +static uint8_t* get_qname(uint8_t* pkt, size_t pktlen) +{ + if(pktlen < LDNS_HEADER_SIZE) + return NULL; + if(LDNS_QDCOUNT(pkt) == 0) + return NULL; + return pkt+LDNS_HEADER_SIZE; +} + +/** returns opcode from packet */ +static int get_opcode(uint8_t* pkt, size_t pktlen) +{ + if(pktlen < LDNS_HEADER_SIZE) + return 0; + return (int)LDNS_OPCODE_WIRE(pkt); +} + +/** get authority section SOA serial value */ +static uint32_t get_serial(uint8_t* p, size_t plen) +{ + uint8_t* walk = p; + size_t walk_len = plen, sl=0; + char* snull = NULL; + uint16_t i; + + if(walk_len < LDNS_HEADER_SIZE) + return 0; + walk += LDNS_HEADER_SIZE; + walk_len -= LDNS_HEADER_SIZE; + + /* skip other records with wire2str_scan */ + for(i=0; i < LDNS_QDCOUNT(p); i++) + (void)sldns_wire2str_rrquestion_scan(&walk, &walk_len, + &snull, &sl, p, plen); + for(i=0; i < LDNS_ANCOUNT(p); i++) + (void)sldns_wire2str_rr_scan(&walk, &walk_len, &snull, &sl, + p, plen); + + /* walk through authority section */ + for(i=0; i < LDNS_NSCOUNT(p); i++) { + /* if this is SOA then get serial, skip compressed dname */ + uint8_t* dstart = walk; + size_t dlen = walk_len; + (void)sldns_wire2str_dname_scan(&dstart, &dlen, &snull, &sl, + p, plen); + if(dlen >= 2 && sldns_read_uint16(dstart) == LDNS_RR_TYPE_SOA) { + /* skip type, class, TTL, rdatalen */ + if(dlen < 10) + return 0; + if(dlen < 10 + (size_t)sldns_read_uint16(dstart+8)) + return 0; + dstart += 10; + dlen -= 10; + /* check third rdf */ + (void)sldns_wire2str_dname_scan(&dstart, &dlen, &snull, + &sl, p, plen); + (void)sldns_wire2str_dname_scan(&dstart, &dlen, &snull, + &sl, p, plen); + if(dlen < 4) + return 0; + verbose(3, "found serial %u in msg. ", + (int)sldns_read_uint32(dstart)); + return sldns_read_uint32(dstart); + } + /* move to next RR */ + (void)sldns_wire2str_rr_scan(&walk, &walk_len, &snull, &sl, + p, plen); + } + return 0; +} + +/** get ptr to EDNS OPT record (and remaining length); behind the type u16 */ +static int +pkt_find_edns_opt(uint8_t** p, size_t* plen) +{ + /* walk over the packet with scan routines */ + uint8_t* w = *p; + size_t wlen = *plen, sl=0; + char* snull = NULL; + uint16_t i; + + if(wlen < LDNS_HEADER_SIZE) + return 0; + w += LDNS_HEADER_SIZE; + wlen -= LDNS_HEADER_SIZE; + + /* skip other records with wire2str_scan */ + for(i=0; i < LDNS_QDCOUNT(p); i++) + (void)sldns_wire2str_rrquestion_scan(&w, &wlen, &snull, &sl, + *p, *plen); + for(i=0; i < LDNS_ANCOUNT(p); i++) + (void)sldns_wire2str_rr_scan(&w, &wlen, &snull, &sl, *p, *plen); + for(i=0; i < LDNS_NSCOUNT(p); i++) + (void)sldns_wire2str_rr_scan(&w, &wlen, &snull, &sl, *p, *plen); + + /* walk through additional section */ + for(i=0; i < LDNS_ARCOUNT(p); i++) { + /* if this is OPT then done */ + uint8_t* dstart = w; + size_t dlen = wlen; + (void)sldns_wire2str_dname_scan(&dstart, &dlen, &snull, &sl, + *p, *plen); + if(dlen >= 2 && sldns_read_uint16(dstart) == LDNS_RR_TYPE_OPT) { + *p = dstart+2; + *plen = dlen-2; + return 1; + } + /* move to next RR */ + (void)sldns_wire2str_rr_scan(&w, &wlen, &snull, &sl, *p, *plen); + } + return 0; +} + +/** return true if the packet has EDNS OPT record */ +static int +get_has_edns(uint8_t* pkt, size_t len) +{ + /* use arguments as temporary variables */ + return pkt_find_edns_opt(&pkt, &len); +} + +/** return true if the DO flag is set */ +static int +get_do_flag(uint8_t* pkt, size_t len) +{ + uint16_t edns_bits; + uint8_t* walk = pkt; + size_t walk_len = len; + if(pkt_find_edns_opt(&walk, &walk_len)) { + return 1; + } + if(walk_len < 6) + return 0; /* malformed */ + edns_bits = sldns_read_uint16(walk+4); + return (int)(edns_bits&LDNS_EDNS_MASK_DO_BIT); +} + +/** zero TTLs in packet */ +static void +zerottls(uint8_t* pkt, size_t pktlen) +{ + uint8_t* walk = pkt; + size_t walk_len = pktlen, sl=0; + char* snull = NULL; + uint16_t i; + uint16_t num = LDNS_ANCOUNT(pkt)+LDNS_NSCOUNT(pkt)+LDNS_ARCOUNT(pkt); + if(walk_len < LDNS_HEADER_SIZE) + return; + walk += LDNS_HEADER_SIZE; + walk_len -= LDNS_HEADER_SIZE; + for(i=0; i < LDNS_QDCOUNT(pkt); i++) + (void)sldns_wire2str_rrquestion_scan(&walk, &walk_len, + &snull, &sl, pkt, pktlen); + for(i=0; i < num; i++) { + /* wipe TTL */ + uint8_t* dstart = walk; + size_t dlen = walk_len; + (void)sldns_wire2str_dname_scan(&dstart, &dlen, &snull, &sl, + pkt, pktlen); + if(dlen < 8) + return; + sldns_write_uint32(dstart+4, 0); + /* go to next RR */ + (void)sldns_wire2str_rr_scan(&walk, &walk_len, &snull, &sl, + pkt, pktlen); + } +} + +/** get one line (\n) from a string, move next to after the \n, zero \n */ +static int +get_line(char** s, char** n) +{ + /* at end of string? end */ + if(*n == NULL || **n == 0) + return 0; + /* result starts at next string */ + *s = *n; + /* find \n after that */ + *n = strchr(*s, '\n'); + if(*n && **n != 0) { + /* terminate line */ + (*n)[0] = 0; + (*n)++; + } + return 1; +} + +/** match two RR sections without ordering */ +static int +match_noloc_section(char** q, char** nq, char** p, char** np, uint16_t num) +{ + /* for max number of RRs in packet */ + const uint16_t numarray = 3000; + char* qlines[numarray], *plines[numarray]; + uint16_t i, j, numq=0, nump=0; + if(num > numarray) fatal_exit("too many RRs"); + /* gather lines */ + for(i=0; i<num; i++) { + get_line(q, nq); + get_line(p, np); + qlines[numq++] = *q; + plines[nump++] = *p; + } + /* see if they are all present in the other */ + for(i=0; i<num; i++) { + int found = 0; + for(j=0; j<num; j++) { + if(strcmp(qlines[i], plines[j]) == 0) { + found = 1; + break; + } + } + if(!found) { + verbose(3, "comparenoloc: failed for %s", qlines[i]); + return 0; + } + } + return 1; +} + +/** match two strings for unordered equality of RRs and everything else */ +static int +match_noloc(char* q, char* p, uint8_t* q_pkt, size_t q_pkt_len, + uint8_t* p_pkt, size_t p_pkt_len) +{ + char* nq = q, *np = p; + /* if no header, compare bytes */ + if(p_pkt_len < LDNS_HEADER_SIZE || q_pkt_len < LDNS_HEADER_SIZE) { + if(p_pkt_len != q_pkt_len) return 0; + return memcmp(p, q, p_pkt_len); + } + /* compare RR counts */ + if(LDNS_QDCOUNT(p_pkt) != LDNS_QDCOUNT(q_pkt)) + return 0; + if(LDNS_ANCOUNT(p_pkt) != LDNS_ANCOUNT(q_pkt)) + return 0; + if(LDNS_NSCOUNT(p_pkt) != LDNS_NSCOUNT(q_pkt)) + return 0; + if(LDNS_ARCOUNT(p_pkt) != LDNS_ARCOUNT(q_pkt)) + return 0; + /* get a line from both; compare; at sections do section */ + get_line(&q, &nq); + get_line(&p, &np); + if(strcmp(q, p) != 0) { + /* header line opcode, rcode, id */ + return 0; + } + get_line(&q, &nq); + get_line(&p, &np); + if(strcmp(q, p) != 0) { + /* header flags, rr counts */ + return 0; + } + /* ;; QUESTION SECTION */ + get_line(&q, &nq); + get_line(&p, &np); + if(strcmp(q, p) != 0) return 0; + if(!match_noloc_section(&q, &nq, &p, &np, LDNS_QDCOUNT(p_pkt))) + return 0; + + /* empty line and ;; ANSWER SECTION */ + get_line(&q, &nq); + get_line(&p, &np); + if(strcmp(q, p) != 0) return 0; + get_line(&q, &nq); + get_line(&p, &np); + if(strcmp(q, p) != 0) return 0; + if(!match_noloc_section(&q, &nq, &p, &np, LDNS_ANCOUNT(p_pkt))) + return 0; + + /* empty line and ;; AUTHORITY SECTION */ + get_line(&q, &nq); + get_line(&p, &np); + if(strcmp(q, p) != 0) return 0; + get_line(&q, &nq); + get_line(&p, &np); + if(strcmp(q, p) != 0) return 0; + if(!match_noloc_section(&q, &nq, &p, &np, LDNS_NSCOUNT(p_pkt))) + return 0; + + /* empty line and ;; ADDITIONAL SECTION */ + get_line(&q, &nq); + get_line(&p, &np); + if(strcmp(q, p) != 0) return 0; + get_line(&q, &nq); + get_line(&p, &np); + if(strcmp(q, p) != 0) return 0; + if(!match_noloc_section(&q, &nq, &p, &np, LDNS_ARCOUNT(p_pkt))) + return 0; + + return 1; +} + +/** lowercase domain name - does not follow compression pointers */ +static void lowercase_dname(uint8_t** p, size_t* remain) +{ + unsigned i, llen; + if(*remain == 0) return; + while(**p != 0) { + /* compressed? */ + if((**p & 0xc0) == 0xc0) { + *p += 2; + *remain -= 2; + return; + } + llen = (unsigned int)**p; + *p += 1; + *remain -= 1; + if(*remain < llen) + llen = (unsigned int)*remain; + for(i=0; i<llen; i++) { + (*p)[i] = (uint8_t)tolower((int)(*p)[i]); + } + *p += llen; + *remain -= llen; + if(*remain == 0) return; + } + /* skip root label */ + *p += 1; + *remain -= 1; +} + +/** lowercase rdata of type */ +static void lowercase_rdata(uint8_t** p, size_t* remain, + uint16_t rdatalen, uint16_t t) +{ + const sldns_rr_descriptor *desc = sldns_rr_descript(t); + uint8_t dname_count = 0; + size_t i = 0; + size_t rdataremain = rdatalen; + if(!desc) { + /* unknown type */ + *p += rdatalen; + *remain -= rdatalen; + return; + } + while(dname_count < desc->_dname_count) { + sldns_rdf_type f = sldns_rr_descriptor_field_type(desc, i++); + if(f == LDNS_RDF_TYPE_DNAME) { + lowercase_dname(p, &rdataremain); + dname_count++; + } else if(f == LDNS_RDF_TYPE_STR) { + uint8_t len; + if(rdataremain == 0) return; + len = **p; + *p += len+1; + rdataremain -= len+1; + } else { + int len = 0; + switch(f) { + case LDNS_RDF_TYPE_CLASS: + case LDNS_RDF_TYPE_ALG: + case LDNS_RDF_TYPE_INT8: + len = 1; + break; + case LDNS_RDF_TYPE_INT16: + case LDNS_RDF_TYPE_TYPE: + case LDNS_RDF_TYPE_CERT_ALG: + len = 2; + break; + case LDNS_RDF_TYPE_INT32: + case LDNS_RDF_TYPE_TIME: + case LDNS_RDF_TYPE_A: + case LDNS_RDF_TYPE_PERIOD: + len = 4; + break; + case LDNS_RDF_TYPE_TSIGTIME: + len = 6; + break; + case LDNS_RDF_TYPE_AAAA: + len = 16; + break; + default: error("bad rdf type in lowercase %d", (int)f); + } + *p += len; + rdataremain -= len; + } + } + /* skip remainder of rdata */ + *p += rdataremain; + *remain -= rdatalen; +} + +/** lowercase all names in the message */ +static void lowercase_pkt(uint8_t* pkt, size_t pktlen) +{ + uint16_t i; + uint8_t* p = pkt; + size_t remain = pktlen; + uint16_t t, rdatalen; + if(pktlen < LDNS_HEADER_SIZE) + return; + p += LDNS_HEADER_SIZE; + remain -= LDNS_HEADER_SIZE; + for(i=0; i<LDNS_QDCOUNT(pkt); i++) { + lowercase_dname(&p, &remain); + if(remain < 4) return; + p += 4; + remain -= 4; + } + for(i=0; i<LDNS_ANCOUNT(pkt)+LDNS_NSCOUNT(pkt)+LDNS_ARCOUNT(pkt); i++) { + lowercase_dname(&p, &remain); + if(remain < 10) return; + t = sldns_read_uint16(p); + rdatalen = sldns_read_uint16(p+8); + p += 10; + remain -= 10; + if(remain < rdatalen) return; + lowercase_rdata(&p, &remain, rdatalen, t); + } +} + +/** match all of the packet */ +int +match_all(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl, + int noloc) +{ + char* qstr, *pstr; + uint8_t* qb = q, *pb = p; + int r; + /* zero TTLs */ + qb = memdup(q, qlen); + pb = memdup(p, plen); + if(!qb || !pb) error("out of memory"); + if(!mttl) { + zerottls(qb, qlen); + zerottls(pb, plen); + } + lowercase_pkt(qb, qlen); + lowercase_pkt(pb, plen); + qstr = sldns_wire2str_pkt(qb, qlen); + pstr = sldns_wire2str_pkt(pb, plen); + if(!qstr || !pstr) error("cannot pkt2string"); + r = (strcmp(qstr, pstr) == 0); + if(!r) { + /* remove ;; MSG SIZE (at end of string) */ + char* s = strstr(qstr, ";; MSG SIZE"); + if(s) *s=0; + s = strstr(pstr, ";; MSG SIZE"); + if(s) *s=0; + r = (strcmp(qstr, pstr) == 0); + if(!r && !noloc) { + /* we are going to fail see if it is because of EDNS */ + char* a = strstr(qstr, "; EDNS"); + char* b = strstr(pstr, "; EDNS"); + if( (a&&!b) || (b&&!a) ) { + verbose(3, "mismatch in EDNS\n"); + } + } + } + if(!r && noloc) { + /* check for reordered sections */ + r = match_noloc(qstr, pstr, q, qlen, p, plen); + } + free(qstr); + free(pstr); + free(qb); + free(pb); + return r; +} + +/** see if domain names are equal */ +static int equal_dname(uint8_t* q, size_t qlen, uint8_t* p, size_t plen) +{ + uint8_t* qn = get_qname(q, qlen); + uint8_t* pn = get_qname(p, plen); + char qs[512], ps[512]; + size_t qslen = sizeof(qs), pslen = sizeof(ps); + char* qss = qs, *pss = ps; + if(!qn || !pn) + return 0; + (void)sldns_wire2str_dname_scan(&qn, &qlen, &qss, &qslen, q, qlen); + (void)sldns_wire2str_dname_scan(&pn, &plen, &pss, &pslen, p, plen); + return (strcmp(qs, ps) == 0); +} + +/** see if domain names are subdomain q of p */ +static int subdomain_dname(uint8_t* q, size_t qlen, uint8_t* p, size_t plen) +{ + /* we use the tostring routines so as to test unbound's routines + * with something else */ + uint8_t* qn = get_qname(q, qlen); + uint8_t* pn = get_qname(p, plen); + char qs[5120], ps[5120]; + size_t qslen = sizeof(qs), pslen = sizeof(ps); + char* qss = qs, *pss = ps; + if(!qn || !pn) + return 0; + /* decompresses domain names */ + (void)sldns_wire2str_dname_scan(&qn, &qlen, &qss, &qslen, q, qlen); + (void)sldns_wire2str_dname_scan(&pn, &plen, &pss, &pslen, p, plen); + /* same: false, (strict subdomain check)??? */ + if(strcmp(qs, ps) == 0) + return 1; + /* qs must end in ps, at a dot, without \ in front */ + qslen = strlen(qs); + pslen = strlen(ps); + if(qslen > pslen && strcmp(qs + (qslen-pslen), ps) == 0 && + qslen + 2 >= pslen && /* space for label and dot */ + qs[qslen-pslen-1] == '.') { + unsigned int slashcount = 0; + size_t i = qslen-pslen-2; + while(i>0 && qs[i]=='\\') { + i++; + slashcount++; + } + if(slashcount%1 == 1) return 0; /* . preceded by \ */ + return 1; + } + return 0; +} + +/* finds entry in list, or returns NULL */ +struct entry* +find_match(struct entry* entries, uint8_t* query_pkt, size_t len, + enum transport_type transport) +{ + struct entry* p = entries; + uint8_t* reply; + size_t rlen; + for(p=entries; p; p=p->next) { + verbose(3, "comparepkt: "); + reply = p->reply_list->reply_pkt; + rlen = p->reply_list->reply_len; + if(p->match_opcode && get_opcode(query_pkt, len) != + get_opcode(reply, rlen)) { + verbose(3, "bad opcode\n"); + continue; + } + if(p->match_qtype && get_qtype(query_pkt, len) != + get_qtype(reply, rlen)) { + verbose(3, "bad qtype %d %d\n", get_qtype(query_pkt, len), get_qtype(reply, rlen)); + continue; + } + if(p->match_qname) { + if(!equal_dname(query_pkt, len, reply, rlen)) { + verbose(3, "bad qname\n"); + continue; + } + } + if(p->match_subdomain) { + if(!subdomain_dname(query_pkt, len, reply, rlen)) { + verbose(3, "bad subdomain\n"); + continue; + } + } + if(p->match_serial && get_serial(query_pkt, len) != p->ixfr_soa_serial) { + verbose(3, "bad serial\n"); + continue; + } + if(p->match_do && !get_do_flag(query_pkt, len)) { + verbose(3, "no DO bit set\n"); + continue; + } + if(p->match_noedns && get_has_edns(query_pkt, len)) { + verbose(3, "bad; EDNS OPT present\n"); + continue; + } + if(p->match_transport != transport_any && p->match_transport != transport) { + verbose(3, "bad transport\n"); + continue; + } + if(p->match_all && !match_all(query_pkt, len, reply, rlen, + (int)p->match_ttl, 0)) { + verbose(3, "bad allmatch\n"); + continue; + } + verbose(3, "match!\n"); + return p; + } + return NULL; +} + +void +adjust_packet(struct entry* match, uint8_t** answer_pkt, size_t *answer_len, + uint8_t* query_pkt, size_t query_len) +{ + uint8_t* orig = *answer_pkt; + size_t origlen = *answer_len; + uint8_t* res; + size_t reslen; + + /* perform the copy; if possible; must be uncompressed */ + if(match->copy_query && origlen >= LDNS_HEADER_SIZE && + query_len >= LDNS_HEADER_SIZE && LDNS_QDCOUNT(query_pkt)!=0 + && LDNS_QDCOUNT(orig)==0) { + /* no qname in output packet, insert it */ + size_t dlen = get_qname_len(query_pkt, query_len); + reslen = origlen + dlen + 4; + res = (uint8_t*)malloc(reslen); + if(!res) { + verbose(1, "out of memory; send without adjust\n"); + return; + } + /* copy the header, query, remainder */ + memcpy(res, orig, LDNS_HEADER_SIZE); + memmove(res+LDNS_HEADER_SIZE, query_pkt+LDNS_HEADER_SIZE, + dlen+4); + memmove(res+LDNS_HEADER_SIZE+dlen+4, orig+LDNS_HEADER_SIZE, + reslen-(LDNS_HEADER_SIZE+dlen+4)); + /* set QDCOUNT */ + sldns_write_uint16(res+4, 1); + } else if(match->copy_query && origlen >= LDNS_HEADER_SIZE && + query_len >= LDNS_HEADER_SIZE && LDNS_QDCOUNT(query_pkt)!=0 + && get_qname_len(orig, origlen) == 0) { + /* QDCOUNT(orig)!=0 but qlen == 0, therefore, an error */ + verbose(1, "error: malformed qname; send without adjust\n"); + res = memdup(orig, origlen); + reslen = origlen; + } else if(match->copy_query && origlen >= LDNS_HEADER_SIZE && + query_len >= LDNS_HEADER_SIZE && LDNS_QDCOUNT(query_pkt)!=0 + && LDNS_QDCOUNT(orig)!=0) { + /* in this case olen != 0 and QDCOUNT(orig)!=0 */ + /* copy query section */ + size_t dlen = get_qname_len(query_pkt, query_len); + size_t olen = get_qname_len(orig, origlen); + reslen = origlen + dlen - olen; + res = (uint8_t*)malloc(reslen); + if(!res) { + verbose(1, "out of memory; send without adjust\n"); + return; + } + /* copy the header, query, remainder */ + memcpy(res, orig, LDNS_HEADER_SIZE); + memmove(res+LDNS_HEADER_SIZE, query_pkt+LDNS_HEADER_SIZE, + dlen+4); + memmove(res+LDNS_HEADER_SIZE+dlen+4, + orig+LDNS_HEADER_SIZE+olen+4, + reslen-(LDNS_HEADER_SIZE+dlen+4)); + } else { + res = memdup(orig, origlen); + reslen = origlen; + } + if(!res) { + verbose(1, "out of memory; send without adjust\n"); + return; + } + /* copy the ID */ + if(match->copy_id && reslen >= 2) + res[1] = orig[1]; + if(match->copy_id && reslen >= 1) + res[0] = orig[0]; + + if(match->sleeptime > 0) { + verbose(3, "sleeping for %d seconds\n", match->sleeptime); +#ifdef HAVE_SLEEP + sleep(match->sleeptime); +#else + Sleep(match->sleeptime * 1000); +#endif + } + *answer_pkt = res; + *answer_len = reslen; +} + +/* + * Parses data buffer to a query, finds the correct answer + * and calls the given function for every packet to send. + */ +void +handle_query(uint8_t* inbuf, ssize_t inlen, struct entry* entries, int* count, + enum transport_type transport, void (*sendfunc)(uint8_t*, size_t, void*), + void* userdata, FILE* verbose_out) +{ + struct reply_packet *p; + uint8_t *outbuf = NULL; + size_t outlen = 0; + struct entry* entry = NULL; + + verbose(1, "query %d: id %d: %s %d bytes: ", ++(*count), + (int)(inlen>=2?LDNS_ID_WIRE(inbuf):0), + (transport==transport_tcp)?"TCP":"UDP", (int)inlen); + if(verbose_out) { + char* out = sldns_wire2str_pkt(inbuf, (size_t)inlen); + printf("%s\n", out); + free(out); + } + + /* fill up answer packet */ + entry = find_match(entries, inbuf, (size_t)inlen, transport); + if(!entry || !entry->reply_list) { + verbose(1, "no answer packet for this query, no reply.\n"); + return; + } + for(p = entry->reply_list; p; p = p->next) + { + verbose(3, "Answer pkt:\n"); + if (p->reply_from_hex) { + /* try to adjust the hex packet, if it can be + * parsed, we can use adjust rules. if not, + * send packet literally */ + /* still try to adjust ID if others fail */ + outlen = sldns_buffer_limit(p->reply_from_hex); + outbuf = sldns_buffer_begin(p->reply_from_hex); + } else { + outbuf = p->reply_pkt; + outlen = p->reply_len; + } + if(!outbuf) { + verbose(1, "out of memory\n"); + return; + } + /* copies outbuf in memory allocation */ + adjust_packet(entry, &outbuf, &outlen, inbuf, (size_t)inlen); + verbose(1, "Answer packet size: %u bytes.\n", (unsigned int)outlen); + if(verbose_out) { + char* out = sldns_wire2str_pkt(outbuf, outlen); + printf("%s\n", out); + free(out); + } + if(p->packet_sleep) { + verbose(3, "sleeping for next packet %d secs\n", + p->packet_sleep); +#ifdef HAVE_SLEEP + sleep(p->packet_sleep); +#else + Sleep(p->packet_sleep * 1000); +#endif + verbose(3, "wakeup for next packet " + "(slept %d secs)\n", p->packet_sleep); + } + sendfunc(outbuf, outlen, userdata); + free(outbuf); + outbuf = NULL; + outlen = 0; + } +} + +/** delete the list of reply packets */ +void delete_replylist(struct reply_packet* replist) +{ + struct reply_packet *p=replist, *np; + while(p) { + np = p->next; + free(p->reply_pkt); + sldns_buffer_free(p->reply_from_hex); + free(p); + p=np; + } +} + +void delete_entry(struct entry* list) +{ + struct entry *p=list, *np; + while(p) { + np = p->next; + delete_replylist(p->reply_list); + free(p); + p = np; + } +} diff --git a/testcode/ldns-testpkts.h b/testcode/testpkts.h index 2431e2e1e17d..864f33fee6dc 100644 --- a/testcode/ldns-testpkts.h +++ b/testcode/testpkts.h @@ -1,5 +1,5 @@ /* - * ldns-testpkts. Data file parse for test packets, and query matching. + * testpkts. Data file parse for test packets, and query matching. * * Data storage for specially crafted replies for testing purposes. * @@ -7,8 +7,10 @@ * See the file LICENSE for the license */ -#ifndef LDNS_TESTPKTS_H -#define LDNS_TESTPKTS_H +#ifndef TESTPKTS_H +#define TESTPKTS_H +struct sldns_buffer; +struct sldns_file_parse_state; /** * \file @@ -131,8 +133,6 @@ ENTRY_END void verbose(int level, char* format, ...); output function. */ -#include <ldns/ldns.h> - /** Type of transport, since some entries match based on UDP or TCP of query */ enum transport_type {transport_any = 0, transport_udp, transport_tcp }; @@ -141,9 +141,11 @@ struct reply_packet { /** next in list of reply packets, for TCP multiple pkts on wire */ struct reply_packet* next; /** the reply pkt */ - ldns_pkt* reply; + uint8_t* reply_pkt; + /** length of reply pkt */ + size_t reply_len; /** or reply pkt in hex if not parsable */ - ldns_buffer* reply_from_hex; + struct sldns_buffer* reply_from_hex; /** seconds to sleep before giving packet */ unsigned int packet_sleep; }; @@ -154,23 +156,23 @@ struct entry { /* match */ /* How to match an incoming query with this canned reply */ /** match query opcode with answer opcode */ - bool match_opcode; + uint8_t match_opcode; /** match qtype with answer qtype */ - bool match_qtype; + uint8_t match_qtype; /** match qname with answer qname */ - bool match_qname; + uint8_t match_qname; /** match qname as subdomain of answer qname */ - bool match_subdomain; + uint8_t match_subdomain; /** match SOA serial number, from auth section */ - bool match_serial; + uint8_t match_serial; /** match all of the packet */ - bool match_all; + uint8_t match_all; /** match ttls in the packet */ - bool match_ttl; + uint8_t match_ttl; /** match DO bit */ - bool match_do; + uint8_t match_do; /** match absence of EDNS OPT record in query */ - bool match_noedns; + uint8_t match_noedns; /** match query serial with this value. */ uint32_t ixfr_soa_serial; /** match on UDP/TCP */ @@ -181,9 +183,9 @@ struct entry { /** how to adjust the reply packet */ /** copy over the ID from the query into the answer */ - bool copy_id; + uint8_t copy_id; /** copy the query nametypeclass from query into the answer */ - bool copy_query; + uint8_t copy_query; /** in seconds */ unsigned int sleeptime; @@ -211,32 +213,39 @@ void delete_entry(struct entry* list); * Read one entry from the data file. * @param in: file to read from. Filepos must be at the start of a new line. * @param name: name of the file for prettier errors. - * @param lineno: line number in file, incremented as lines are read. - * for prettier errors. - * @param default_ttl: on first call set to default TTL for entries, - * later it stores the $TTL value last seen. Try 3600 first call. - * @param origin: domain name for origin appending. Can be &NULL on first call. - * later it stores the $ORIGIN value last seen. Often &NULL or the zone - * name on first call. - * @param prev_rr: previous rr name for correcter parsing. &NULL on first call. + * @param pstate: file parse state with lineno, default_ttl, + * oirigin and prev_rr name. * @param skip_whitespace: skip leftside whitespace. * @return: The entry read (malloced) or NULL if no entry could be read. */ -struct entry* read_entry(FILE* in, const char* name, int *lineno, - uint32_t* default_ttl, ldns_rdf** origin, ldns_rdf** prev_rr, - int skip_whitespace); +struct entry* read_entry(FILE* in, const char* name, + struct sldns_file_parse_state* pstate, int skip_whitespace); /** * finds entry in list, or returns NULL. */ -struct entry* find_match(struct entry* entries, ldns_pkt* query_pkt, - enum transport_type transport); +struct entry* find_match(struct entry* entries, uint8_t* query_pkt, + size_t query_pkt_len, enum transport_type transport); + +/** + * match two packets, all must match + * @param q: packet 1 + * @param qlen: length of q. + * @param p: packet 2 + * @param plen: length of p. + * @param mttl: if true, ttls must match, if false, ttls do not need to match + * @param noloc: if true, rrs may be reordered in their packet-section. + * rrs are then matches without location of the rr being important. + * @return true if matched. + */ +int match_all(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl, + int noloc); /** - * copy & adjust packet + * copy & adjust packet, mallocs a copy. */ -void adjust_packet(struct entry* match, ldns_pkt* answer_pkt, - ldns_pkt* query_pkt); +void adjust_packet(struct entry* match, uint8_t** answer_pkt, + size_t* answer_pkt_len, uint8_t* query_pkt, size_t query_pkt_len); /** * Parses data buffer to a query, finds the correct answer @@ -256,4 +265,4 @@ void handle_query(uint8_t* inbuf, ssize_t inlen, struct entry* entries, void (*sendfunc)(uint8_t*, size_t, void*), void* userdata, FILE* verbose_out); -#endif /* LDNS_TESTPKTS_H */ +#endif /* TESTPKTS_H */ diff --git a/testcode/unitanchor.c b/testcode/unitanchor.c index de4106a8081f..8047eb2bf988 100644 --- a/testcode/unitanchor.c +++ b/testcode/unitanchor.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** @@ -39,11 +39,12 @@ */ #include "config.h" -#include <ldns/rr.h> #include "util/log.h" #include "util/data/dname.h" #include "testcode/unitmain.h" #include "validator/val_anchor.h" +#include "ldns/sbuffer.h" +#include "ldns/rrdef.h" /** test empty set */ static void @@ -63,7 +64,7 @@ test_anchor_empty(struct val_anchors* a) /** test set of one anchor */ static void -test_anchor_one(ldns_buffer* buff, struct val_anchors* a) +test_anchor_one(sldns_buffer* buff, struct val_anchors* a) { struct trust_anchor* ta; uint16_t c = LDNS_RR_CLASS_IN; @@ -91,7 +92,7 @@ test_anchor_one(ldns_buffer* buff, struct val_anchors* a) /** test with several anchors */ static void -test_anchors(ldns_buffer* buff, struct val_anchors* a) +test_anchors(sldns_buffer* buff, struct val_anchors* a) { struct trust_anchor* ta; uint16_t c = LDNS_RR_CLASS_IN; @@ -123,14 +124,14 @@ test_anchors(ldns_buffer* buff, struct val_anchors* a) void anchors_test(void) { - ldns_buffer* buff = ldns_buffer_new(65800); + sldns_buffer* buff = sldns_buffer_new(65800); struct val_anchors* a; unit_show_feature("trust anchor store"); unit_assert(a = anchors_create()); - ldns_buffer_flip(buff); + sldns_buffer_flip(buff); test_anchor_empty(a); test_anchor_one(buff, a); test_anchors(buff, a); anchors_delete(a); - ldns_buffer_free(buff); + sldns_buffer_free(buff); } diff --git a/testcode/unitdname.c b/testcode/unitdname.c index 3dcd8e43c207..83d829fae15b 100644 --- a/testcode/unitdname.c +++ b/testcode/unitdname.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** @@ -39,32 +39,31 @@ */ #include "config.h" -#include <ldns/dname.h> -#include <ldns/host2wire.h> #include "util/log.h" #include "testcode/unitmain.h" #include "util/data/dname.h" +#include "ldns/sbuffer.h" +#include "ldns/str2wire.h" /** put dname into buffer */ -static ldns_buffer* -dname_to_buf(ldns_buffer* b, const char* str) +static sldns_buffer* +dname_to_buf(sldns_buffer* b, const char* str) { - ldns_rdf* rdf; - ldns_status status; - ldns_buffer_clear(b); - rdf = ldns_dname_new_frm_str(str); - status = ldns_dname2buffer_wire(b, rdf); - if(status != LDNS_STATUS_OK) + int e; + size_t len = sldns_buffer_capacity(b); + sldns_buffer_clear(b); + e = sldns_str2wire_dname_buf(str, sldns_buffer_begin(b), &len); + if(e != 0) fatal_exit("%s ldns: %s", __func__, - ldns_get_errorstr_by_id(status)); - ldns_rdf_deep_free(rdf); - ldns_buffer_flip(b); + sldns_get_errorstr_parse(e)); + sldns_buffer_set_position(b, len); + sldns_buffer_flip(b); return b; } /** test query_dname_len function */ static void -dname_test_qdl(ldns_buffer* buff) +dname_test_qdl(sldns_buffer* buff) { unit_show_func("util/data/dname.c", "query_dname_len"); unit_assert( query_dname_len(buff) == 0); @@ -76,26 +75,26 @@ dname_test_qdl(ldns_buffer* buff) /** test query_dname_tolower */ static void -dname_test_qdtl(ldns_buffer* buff) +dname_test_qdtl(sldns_buffer* buff) { unit_show_func("util/data/dname.c", "query_dname_tolower"); - ldns_buffer_write_at(buff, 0, "\012abCDeaBCde\003cOm\000", 16); - query_dname_tolower(ldns_buffer_begin(buff)); - unit_assert( memcmp(ldns_buffer_begin(buff), + sldns_buffer_write_at(buff, 0, "\012abCDeaBCde\003cOm\000", 16); + query_dname_tolower(sldns_buffer_begin(buff)); + unit_assert( memcmp(sldns_buffer_begin(buff), "\012abcdeabcde\003com\000", 16) == 0); - ldns_buffer_write_at(buff, 0, "\001+\012abC{e-ZYXe\003NET\000", 18); - query_dname_tolower(ldns_buffer_begin(buff)); - unit_assert( memcmp(ldns_buffer_begin(buff), + sldns_buffer_write_at(buff, 0, "\001+\012abC{e-ZYXe\003NET\000", 18); + query_dname_tolower(sldns_buffer_begin(buff)); + unit_assert( memcmp(sldns_buffer_begin(buff), "\001+\012abc{e-zyxe\003net\000", 18) == 0); - ldns_buffer_write_at(buff, 0, "\000", 1); - query_dname_tolower(ldns_buffer_begin(buff)); - unit_assert( memcmp(ldns_buffer_begin(buff), "\000", 1) == 0); + sldns_buffer_write_at(buff, 0, "\000", 1); + query_dname_tolower(sldns_buffer_begin(buff)); + unit_assert( memcmp(sldns_buffer_begin(buff), "\000", 1) == 0); - ldns_buffer_write_at(buff, 0, "\002NL\000", 4); - query_dname_tolower(ldns_buffer_begin(buff)); - unit_assert( memcmp(ldns_buffer_begin(buff), "\002nl\000", 4) == 0); + sldns_buffer_write_at(buff, 0, "\002NL\000", 4); + query_dname_tolower(sldns_buffer_begin(buff)); + unit_assert( memcmp(sldns_buffer_begin(buff), "\002nl\000", 4) == 0); } /** test query_dname_compare */ @@ -164,62 +163,62 @@ dname_test_count_size_labels(void) /** test pkt_dname_len */ static void -dname_test_pkt_dname_len(ldns_buffer* buff) +dname_test_pkt_dname_len(sldns_buffer* buff) { unit_show_func("util/data/dname.c", "pkt_dname_len"); - ldns_buffer_clear(buff); - ldns_buffer_write(buff, "\000", 1); - ldns_buffer_flip(buff); + sldns_buffer_clear(buff); + sldns_buffer_write(buff, "\000", 1); + sldns_buffer_flip(buff); unit_assert( pkt_dname_len(buff) == 1 ); - unit_assert( ldns_buffer_position(buff) == 1); + unit_assert( sldns_buffer_position(buff) == 1); - ldns_buffer_clear(buff); - ldns_buffer_write(buff, "\003org\000", 5); - ldns_buffer_flip(buff); + sldns_buffer_clear(buff); + sldns_buffer_write(buff, "\003org\000", 5); + sldns_buffer_flip(buff); unit_assert( pkt_dname_len(buff) == 5 ); - unit_assert( ldns_buffer_position(buff) == 5); + unit_assert( sldns_buffer_position(buff) == 5); - ldns_buffer_clear(buff); - ldns_buffer_write(buff, "\002os\007example\003org\000", 16); - ldns_buffer_flip(buff); + sldns_buffer_clear(buff); + sldns_buffer_write(buff, "\002os\007example\003org\000", 16); + sldns_buffer_flip(buff); unit_assert( pkt_dname_len(buff) == 16 ); - unit_assert( ldns_buffer_position(buff) == 16); + unit_assert( sldns_buffer_position(buff) == 16); /* invalid compression pointer: to self */ - ldns_buffer_clear(buff); - ldns_buffer_write(buff, "\300\000os\007example\003org\000", 17); - ldns_buffer_flip(buff); + sldns_buffer_clear(buff); + sldns_buffer_write(buff, "\300\000os\007example\003org\000", 17); + sldns_buffer_flip(buff); unit_assert( pkt_dname_len(buff) == 0 ); /* valid compression pointer */ - ldns_buffer_clear(buff); - ldns_buffer_write(buff, "\003com\000\040\300\000", 8); - ldns_buffer_flip(buff); - ldns_buffer_set_position(buff, 6); + sldns_buffer_clear(buff); + sldns_buffer_write(buff, "\003com\000\040\300\000", 8); + sldns_buffer_flip(buff); + sldns_buffer_set_position(buff, 6); unit_assert( pkt_dname_len(buff) == 5 ); - unit_assert( ldns_buffer_position(buff) == 8); + unit_assert( sldns_buffer_position(buff) == 8); /* unknown label type */ - ldns_buffer_clear(buff); - ldns_buffer_write(buff, "\002os\107example\003org\000", 16); - ldns_buffer_flip(buff); + sldns_buffer_clear(buff); + sldns_buffer_write(buff, "\002os\107example\003org\000", 16); + sldns_buffer_flip(buff); unit_assert( pkt_dname_len(buff) == 0 ); /* label too long */ - ldns_buffer_clear(buff); - ldns_buffer_write(buff, "\002os\047example\003org\000", 16); - ldns_buffer_flip(buff); + sldns_buffer_clear(buff); + sldns_buffer_write(buff, "\002os\047example\003org\000", 16); + sldns_buffer_flip(buff); unit_assert( pkt_dname_len(buff) == 0 ); /* label exceeds packet */ - ldns_buffer_clear(buff); - ldns_buffer_write(buff, "\002os\007example\007org\004", 16); - ldns_buffer_flip(buff); + sldns_buffer_clear(buff); + sldns_buffer_write(buff, "\002os\007example\007org\004", 16); + sldns_buffer_flip(buff); unit_assert( pkt_dname_len(buff) == 0 ); /* name very long */ - ldns_buffer_clear(buff); - ldns_buffer_write(buff, + sldns_buffer_clear(buff); + sldns_buffer_write(buff, "\020a1cdef5555544444" "\020a2cdef5555544444" "\020a3cdef5555544444" @@ -237,13 +236,13 @@ dname_test_pkt_dname_len(ldns_buffer* buff) "\007aabbccd" /* 246 up to here */ "\007example\000" /* 255 to here */ , 255); - ldns_buffer_flip(buff); + sldns_buffer_flip(buff); unit_assert( pkt_dname_len(buff) == 255 ); - unit_assert( ldns_buffer_position(buff) == 255); + unit_assert( sldns_buffer_position(buff) == 255); /* name too long */ - ldns_buffer_clear(buff); - ldns_buffer_write(buff, + sldns_buffer_clear(buff); + sldns_buffer_write(buff, "\020a1cdef5555544444" "\020a2cdef5555544444" "\020a3cdef5555544444" @@ -264,7 +263,7 @@ dname_test_pkt_dname_len(ldns_buffer* buff) "\007aabbccd" /* 246 up to here */ "\007example\000" /* 255 to here */ , 255); - ldns_buffer_flip(buff); + sldns_buffer_flip(buff); unit_assert( pkt_dname_len(buff) == 0 ); } @@ -797,47 +796,47 @@ dname_test_valid(void) /** test pkt_dname_tolower */ static void -dname_test_pdtl(ldns_buffer* loopbuf, ldns_buffer* boundbuf) +dname_test_pdtl(sldns_buffer* loopbuf, sldns_buffer* boundbuf) { unit_show_func("util/data/dname.c", "pkt_dname_tolower"); - pkt_dname_tolower(loopbuf, ldns_buffer_at(loopbuf, 12)); - pkt_dname_tolower(boundbuf, ldns_buffer_at(boundbuf, 12)); + pkt_dname_tolower(loopbuf, sldns_buffer_at(loopbuf, 12)); + pkt_dname_tolower(boundbuf, sldns_buffer_at(boundbuf, 12)); } /** setup looped dname and out-of-bounds dname ptr */ static void -dname_setup_bufs(ldns_buffer* loopbuf, ldns_buffer* boundbuf) +dname_setup_bufs(sldns_buffer* loopbuf, sldns_buffer* boundbuf) { - ldns_buffer_write_u16(loopbuf, 0xd54d); /* id */ - ldns_buffer_write_u16(loopbuf, 0x12); /* flags */ - ldns_buffer_write_u16(loopbuf, 1); /* qdcount */ - ldns_buffer_write_u16(loopbuf, 0); /* ancount */ - ldns_buffer_write_u16(loopbuf, 0); /* nscount */ - ldns_buffer_write_u16(loopbuf, 0); /* arcount */ - ldns_buffer_write_u8(loopbuf, 0xc0); /* PTR back at itself */ - ldns_buffer_write_u8(loopbuf, 0x0c); - ldns_buffer_flip(loopbuf); - - ldns_buffer_write_u16(boundbuf, 0xd54d); /* id */ - ldns_buffer_write_u16(boundbuf, 0x12); /* flags */ - ldns_buffer_write_u16(boundbuf, 1); /* qdcount */ - ldns_buffer_write_u16(boundbuf, 0); /* ancount */ - ldns_buffer_write_u16(boundbuf, 0); /* nscount */ - ldns_buffer_write_u16(boundbuf, 0); /* arcount */ - ldns_buffer_write_u8(boundbuf, 0x01); /* len=1 */ - ldns_buffer_write_u8(boundbuf, (uint8_t)'A'); /* A. label */ - ldns_buffer_write_u8(boundbuf, 0xc0); /* PTR out of bounds */ - ldns_buffer_write_u8(boundbuf, 0xcc); - ldns_buffer_flip(boundbuf); + sldns_buffer_write_u16(loopbuf, 0xd54d); /* id */ + sldns_buffer_write_u16(loopbuf, 0x12); /* flags */ + sldns_buffer_write_u16(loopbuf, 1); /* qdcount */ + sldns_buffer_write_u16(loopbuf, 0); /* ancount */ + sldns_buffer_write_u16(loopbuf, 0); /* nscount */ + sldns_buffer_write_u16(loopbuf, 0); /* arcount */ + sldns_buffer_write_u8(loopbuf, 0xc0); /* PTR back at itself */ + sldns_buffer_write_u8(loopbuf, 0x0c); + sldns_buffer_flip(loopbuf); + + sldns_buffer_write_u16(boundbuf, 0xd54d); /* id */ + sldns_buffer_write_u16(boundbuf, 0x12); /* flags */ + sldns_buffer_write_u16(boundbuf, 1); /* qdcount */ + sldns_buffer_write_u16(boundbuf, 0); /* ancount */ + sldns_buffer_write_u16(boundbuf, 0); /* nscount */ + sldns_buffer_write_u16(boundbuf, 0); /* arcount */ + sldns_buffer_write_u8(boundbuf, 0x01); /* len=1 */ + sldns_buffer_write_u8(boundbuf, (uint8_t)'A'); /* A. label */ + sldns_buffer_write_u8(boundbuf, 0xc0); /* PTR out of bounds */ + sldns_buffer_write_u8(boundbuf, 0xcc); + sldns_buffer_flip(boundbuf); } void dname_test(void) { - ldns_buffer* loopbuf = ldns_buffer_new(14); - ldns_buffer* boundbuf = ldns_buffer_new(16); - ldns_buffer* buff = ldns_buffer_new(65800); + sldns_buffer* loopbuf = sldns_buffer_new(14); + sldns_buffer* boundbuf = sldns_buffer_new(16); + sldns_buffer* buff = sldns_buffer_new(65800); unit_assert(loopbuf && boundbuf && buff); - ldns_buffer_flip(buff); + sldns_buffer_flip(buff); dname_setup_bufs(loopbuf, boundbuf); dname_test_qdl(buff); dname_test_qdtl(buff); @@ -856,7 +855,7 @@ void dname_test(void) dname_test_canoncmp(); dname_test_topdomain(); dname_test_valid(); - ldns_buffer_free(buff); - ldns_buffer_free(loopbuf); - ldns_buffer_free(boundbuf); + sldns_buffer_free(buff); + sldns_buffer_free(loopbuf); + sldns_buffer_free(boundbuf); } diff --git a/testcode/unitldns.c b/testcode/unitldns.c new file mode 100644 index 000000000000..65170a82526f --- /dev/null +++ b/testcode/unitldns.c @@ -0,0 +1,218 @@ +/* + * testcode/unitldns.c - unit test for ldns routines. + * + * Copyright (c) 2014, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +/** + * \file + * Calls ldns unit tests. Exits with code 1 on a failure. + */ + +#include "config.h" +#include "util/log.h" +#include "testcode/unitmain.h" +#include "ldns/sbuffer.h" +#include "ldns/str2wire.h" +#include "ldns/wire2str.h" + +/** verbose this unit test */ +static int vbmp = 0; + +/** print buffer to hex into string */ +static void +buf_to_hex(uint8_t* b, size_t blen, char* s, size_t slen) +{ + const char* h = "0123456789ABCDEF"; + size_t i; + if(slen < blen*2+2 && vbmp) printf("hexstring buffer too small\n"); + unit_assert(slen >= blen*2+2); + for(i=0; i<blen; i++) { + s[i*2] = h[(b[i]&0xf0)>>4]; + s[i*2+1] = h[b[i]&0x0f]; + } + s[blen*2] = '\n'; + s[blen*2+1] = 0; +} + +/** Transform input. + * @param txt_in: input text format. + * @param wire1: output wireformat in hex (txt_in converted to wire). + * @param txt_out: output text format (converted from wire_out). + * @param wire2: output wireformat in hex, txt_out converted back to wireformat. + * @param bufs: size of the text buffers. + */ +static void +rr_transform(char* txt_in, char* wire1, char* txt_out, char* wire2, + size_t bufs) +{ + uint8_t b[65536]; + size_t len; + int err; + + len = sizeof(b); + err = sldns_str2wire_rr_buf(txt_in, b, &len, NULL, 3600, + NULL, 0, NULL, 0); + if(err != 0) { + if(vbmp) printf("sldns_str2wire_rr_buf, pos %d: %s\n", + LDNS_WIREPARSE_OFFSET(err), + sldns_get_errorstr_parse(err)); + } + unit_assert(err == 0); + buf_to_hex(b, len, wire1, bufs); + if(vbmp) printf("wire1: %s", wire1); + + err = sldns_wire2str_rr_buf(b, len, txt_out, bufs); + unit_assert(err < (int)bufs && err > 0); + if(vbmp) printf("txt: %s", txt_out); + + len = sizeof(b); + err = sldns_str2wire_rr_buf(txt_out, b, &len, NULL, 3600, + NULL, 0, NULL, 0); + if(err != 0) { + if(vbmp) printf("sldns_str2wire_rr_buf-2, pos %d: %s\n", + LDNS_WIREPARSE_OFFSET(err), + sldns_get_errorstr_parse(err)); + } + unit_assert(err == 0); + buf_to_hex(b, len, wire2, bufs); + if(vbmp) printf("wire2: %s", wire2); +} + +/** Check if results are correct */ +static void +rr_checks(char* wire_chk, char* txt_chk, char* txt_out, char* wire_out, + char* back) +{ +#ifdef __APPLE__ + /* the wiretostr on ipv6 is weird on apple, we cannot check it. + * skip AAAA on OSX */ + if(strstr(txt_out, "IN AAAA")) + txt_out = txt_chk; /* skip this test, but test wirefmt */ + /* so we know that txt_out back to wire is the same */ +#endif + + if(strcmp(txt_chk, txt_out) != 0 && vbmp) + printf("txt different\n"); + if(strcmp(wire_chk, wire_out) != 0 && vbmp) + printf("wire1 different\n"); + if(strcmp(wire_chk, back) != 0 && vbmp) + printf("wire2 different\n"); + + unit_assert(strcmp(txt_chk, txt_out) == 0); + unit_assert(strcmp(wire_chk, wire_out) == 0); + unit_assert(strcmp(wire_chk, back) == 0); +} + +/** read rrs to and from string, and wireformat + * Skips empty lines and comments. + * @param input: input file with text format. + * @param check: check file with hex and then textformat + */ +static void +rr_test_file(const char* input, const char* check) +{ + size_t bufs = 131072; + FILE* inf, *chf, *of; + int lineno = 0, chlineno = 0; + char* txt_in = (char*)malloc(bufs); + char* txt_out = (char*)malloc(bufs); + char* txt_chk = (char*)malloc(bufs); + char* wire_out = (char*)malloc(bufs); + char* wire_chk = (char*)malloc(bufs); + char* back = (char*)malloc(bufs); + if(!txt_in || !txt_out || !txt_chk || !wire_out || !wire_chk || !back) + fatal_exit("malloc failure"); + inf = fopen(input, "r"); + if(!inf) fatal_exit("cannot open %s: %s", input, strerror(errno)); + chf = fopen(check, "r"); + if(!chf) fatal_exit("cannot open %s: %s", check, strerror(errno)); + + of = NULL; + if(0) { + /* debug: create check file */ + of = fopen("outputfile", "w"); + if(!of) fatal_exit("cannot write output: %s", strerror(errno)); + } + + while(fgets(txt_in, (int)bufs, inf)) { + lineno++; + if(vbmp) printf("\n%s:%d %s", input, lineno, txt_in); + /* skip empty lines and comments */ + if(txt_in[0] == 0 || txt_in[0] == '\n' || txt_in[0] == ';') + continue; + /* read check lines */ + if(!fgets(wire_chk, (int)bufs, chf)) + printf("%s too short\n", check); + if(!fgets(txt_chk, (int)bufs, chf)) + printf("%s too short\n", check); + chlineno += 2; + if(vbmp) printf("%s:%d %s", check, chlineno-1, wire_chk); + if(vbmp) printf("%s:%d %s", check, chlineno, txt_chk); + /* generate results */ + rr_transform(txt_in, wire_out, txt_out, back, bufs); + /* checks */ + if(of) { + fprintf(of, "%s%s", wire_out, txt_out); + } else { + rr_checks(wire_chk, txt_chk, txt_out, wire_out, back); + } + } + + if(of) fclose(of); + fclose(inf); + fclose(chf); + free(txt_in); + free(txt_out); + free(txt_chk); + free(wire_out); + free(wire_chk); + free(back); +} + +/** read rrs to and from string, to and from wireformat */ +static void +rr_tests(void) +{ + rr_test_file("testdata/test_ldnsrr.1", "testdata/test_ldnsrr.c1"); + rr_test_file("testdata/test_ldnsrr.2", "testdata/test_ldnsrr.c2"); + rr_test_file("testdata/test_ldnsrr.3", "testdata/test_ldnsrr.c3"); + rr_test_file("testdata/test_ldnsrr.4", "testdata/test_ldnsrr.c4"); + rr_test_file("testdata/test_ldnsrr.5", "testdata/test_ldnsrr.c5"); +} + +void +ldns_test(void) +{ + unit_show_feature("sldns"); + rr_tests(); +} diff --git a/testcode/unitlruhash.c b/testcode/unitlruhash.c index 3bb7c26267d1..32d29d0af2bf 100644 --- a/testcode/unitlruhash.c +++ b/testcode/unitlruhash.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** diff --git a/testcode/unitmain.c b/testcode/unitmain.c index be4bed95eeb2..4673214adc04 100644 --- a/testcode/unitmain.c +++ b/testcode/unitmain.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** @@ -61,7 +61,8 @@ #include "nss.h" #endif -#include <ldns/ldns.h> +#include "ldns/rrdef.h" +#include "ldns/keyraw.h" #include "util/log.h" #include "testcode/unitmain.h" @@ -567,7 +568,7 @@ main(int argc, char* argv[]) OPENSSL_config("unbound"); # endif # ifdef USE_GOST - (void)ldns_key_EVP_load_gost_id(); + (void)sldns_key_EVP_load_gost_id(); # endif #elif defined(HAVE_NSS) if(NSS_NoDB_Init(".") != SECSuccess) @@ -587,12 +588,13 @@ main(int argc, char* argv[]) lruhash_test(); slabhash_test(); infra_test(); + ldns_test(); msgparse_test(); checklock_stop(); printf("%d checks ok.\n", testcount); #ifdef HAVE_SSL # if defined(USE_GOST) && defined(HAVE_LDNS_KEY_EVP_UNLOAD_GOST) - ldns_key_EVP_unload_gost(); + sldns_key_EVP_unload_gost(); # endif # ifdef HAVE_OPENSSL_CONFIG EVP_cleanup(); diff --git a/testcode/unitmain.h b/testcode/unitmain.h index 6cfad3eb545d..c27bd1437053 100644 --- a/testcode/unitmain.h +++ b/testcode/unitmain.h @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** @@ -72,5 +72,7 @@ void verify_test(void); void neg_test(void); /** unit test for regional allocator functions */ void regional_test(void); +/** unit test for ldns functions */ +void ldns_test(void); #endif /* TESTCODE_UNITMAIN_H */ diff --git a/testcode/unitmsgparse.c b/testcode/unitmsgparse.c index 72f9b63a6e09..b33a2408d4e7 100644 --- a/testcode/unitmsgparse.c +++ b/testcode/unitmsgparse.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** @@ -39,7 +39,7 @@ */ #include "config.h" -#include <ldns/ldns.h> +#include <sys/time.h> #include "util/log.h" #include "testcode/unitmain.h" #include "util/data/msgparse.h" @@ -50,6 +50,10 @@ #include "util/regional.h" #include "util/net_help.h" #include "testcode/readhex.h" +#include "testcode/testpkts.h" +#include "ldns/sbuffer.h" +#include "ldns/str2wire.h" +#include "ldns/wire2str.h" /** verbose message parse unit test */ static int vbmp = 0; @@ -62,203 +66,105 @@ static int check_rrsigs = 0; /** do not check buffer sameness */ static int check_nosameness = 0; -/** match two rr lists */ -static int -match_list(ldns_rr_list* q, ldns_rr_list *p) -{ - size_t i; - if(ldns_rr_list_rr_count(q) != ldns_rr_list_rr_count(p)) { - verbose(3, "rrlistcount different %d %d", - (int)ldns_rr_list_rr_count(q), - (int)ldns_rr_list_rr_count(p)); - return 0; - } - for(i=0; i<ldns_rr_list_rr_count(q); i++) - { - if(matches_nolocation) { - if(!ldns_rr_list_contains_rr(p, ldns_rr_list_rr(q, i))) - { - verbose(3, "rr %u not found", (unsigned)i); - return 0; - } - } else { - if(ldns_rr_compare(ldns_rr_list_rr(q, i), - ldns_rr_list_rr(p, i)) != 0) { - verbose(3, "rr %u different", (unsigned)i); - return 0; - } - /* and check the ttl */ - if(ldns_rr_ttl(ldns_rr_list_rr(q, i)) != - ldns_rr_ttl(ldns_rr_list_rr(p, i))) { - verbose(3, "rr %u ttl different", (unsigned)i); - return 0; - } - } - } - return 1; -} - -/** match edns sections */ -static int -match_edns(ldns_pkt* q, ldns_pkt* p) -{ - if(ldns_pkt_edns_udp_size(q) != ldns_pkt_edns_udp_size(p)) - return 0; - if(ldns_pkt_edns_extended_rcode(q) != ldns_pkt_edns_extended_rcode(p)) - return 0; - if(ldns_pkt_edns_version(q) != ldns_pkt_edns_version(p)) - return 0; - if(ldns_pkt_edns_do(q) != ldns_pkt_edns_do(p)) - return 0; - if(ldns_pkt_edns_z(q) != ldns_pkt_edns_z(p)) - return 0; - if(ldns_rdf_compare(ldns_pkt_edns_data(q), ldns_pkt_edns_data(p)) != 0) - return 0; - return 1; -} - -/** compare two booleans */ -static int -cmp_bool(int x, int y) -{ - if(!x && !y) return 0; - if(x && y) return 0; - if(!x) return -1; - return 1; -} - -/** match all of the packet */ -static int -match_all(ldns_pkt* q, ldns_pkt* p) -{ - if(ldns_pkt_get_opcode(q) != ldns_pkt_get_opcode(p)) - { verbose(3, "allmatch: opcode different"); return 0;} - if(ldns_pkt_get_rcode(q) != ldns_pkt_get_rcode(p)) - { verbose(3, "allmatch: rcode different"); return 0;} - if(ldns_pkt_id(q) != ldns_pkt_id(p)) - { verbose(3, "allmatch: id different"); return 0;} - if(cmp_bool(ldns_pkt_qr(q), ldns_pkt_qr(p)) != 0) - { verbose(3, "allmatch: qr different"); return 0;} - if(cmp_bool(ldns_pkt_aa(q), ldns_pkt_aa(p)) != 0) - { verbose(3, "allmatch: aa different"); return 0;} - if(cmp_bool(ldns_pkt_tc(q), ldns_pkt_tc(p)) != 0) - { verbose(3, "allmatch: tc different"); return 0;} - if(cmp_bool(ldns_pkt_rd(q), ldns_pkt_rd(p)) != 0) - { verbose(3, "allmatch: rd different"); return 0;} - if(cmp_bool(ldns_pkt_cd(q), ldns_pkt_cd(p)) != 0) - { verbose(3, "allmatch: cd different"); return 0;} - if(cmp_bool(ldns_pkt_ra(q), ldns_pkt_ra(p)) != 0) - { verbose(3, "allmatch: ra different"); return 0;} - if(cmp_bool(ldns_pkt_ad(q), ldns_pkt_ad(p)) != 0) - { verbose(3, "allmatch: ad different"); return 0;} - if(ldns_pkt_qdcount(q) != ldns_pkt_qdcount(p)) - { verbose(3, "allmatch: qdcount different"); return 0;} - if(ldns_pkt_ancount(q) != ldns_pkt_ancount(p)) - { verbose(3, "allmatch: ancount different"); return 0;} - if(ldns_pkt_nscount(q) != ldns_pkt_nscount(p)) - { verbose(3, "allmatch: nscount different"); return 0;} - if(ldns_pkt_arcount(q) != ldns_pkt_arcount(p)) - { verbose(3, "allmatch: arcount different"); return 0;} - if(!match_list(ldns_pkt_question(q), ldns_pkt_question(p))) - { verbose(3, "allmatch: qd section different"); return 0;} - if(!match_list(ldns_pkt_answer(q), ldns_pkt_answer(p))) - { verbose(3, "allmatch: an section different"); return 0;} - if(!match_list(ldns_pkt_authority(q), ldns_pkt_authority(p))) - { verbose(3, "allmatch: ns section different"); return 0;} - if(!match_list(ldns_pkt_additional(q), ldns_pkt_additional(p))) - { verbose(3, "allmatch: ar section different"); return 0;} - if(!match_edns(q, p)) - { verbose(3, "edns different."); return 0;} - return 1; -} - /** see if buffers contain the same packet */ static int -test_buffers(ldns_buffer* pkt, ldns_buffer* out) +test_buffers(sldns_buffer* pkt, sldns_buffer* out) { - ldns_pkt* p1=0, *p2=0; - ldns_status s1, s2; /* check binary same */ - if(ldns_buffer_limit(pkt) == ldns_buffer_limit(out) && - memcmp(ldns_buffer_begin(pkt), ldns_buffer_begin(out), - ldns_buffer_limit(pkt)) == 0) { + if(sldns_buffer_limit(pkt) == sldns_buffer_limit(out) && + memcmp(sldns_buffer_begin(pkt), sldns_buffer_begin(out), + sldns_buffer_limit(pkt)) == 0) { if(vbmp) printf("binary the same (length=%u)\n", - (unsigned)ldns_buffer_limit(pkt)); + (unsigned)sldns_buffer_limit(pkt)); return 1; } if(vbmp) { size_t sz = 16; size_t count; - size_t lim = ldns_buffer_limit(out); - if(ldns_buffer_limit(pkt) < lim) - lim = ldns_buffer_limit(pkt); + size_t lim = sldns_buffer_limit(out); + if(sldns_buffer_limit(pkt) < lim) + lim = sldns_buffer_limit(pkt); for(count=0; count<lim; count+=sz) { size_t rem = sz; if(lim-count < sz) rem = lim-count; - if(memcmp(ldns_buffer_at(pkt, count), - ldns_buffer_at(out, count), rem) == 0) { + if(memcmp(sldns_buffer_at(pkt, count), + sldns_buffer_at(out, count), rem) == 0) { log_info("same %d %d", (int)count, (int)rem); - log_hex("same: ", ldns_buffer_at(pkt, count), + log_hex("same: ", sldns_buffer_at(pkt, count), rem); } else { log_info("diff %d %d", (int)count, (int)rem); - log_hex("difp: ", ldns_buffer_at(pkt, count), + log_hex("difp: ", sldns_buffer_at(pkt, count), rem); - log_hex("difo: ", ldns_buffer_at(out, count), + log_hex("difo: ", sldns_buffer_at(out, count), rem); } } } + /* check if it 'means the same' */ - s1 = ldns_buffer2pkt_wire(&p1, pkt); - s2 = ldns_buffer2pkt_wire(&p2, out); if(vbmp) { + char* s1, *s2; log_buf(0, "orig in hex", pkt); log_buf(0, "unbound out in hex", out); printf("\npacket from unbound (%d):\n", - (int)ldns_buffer_limit(out)); - ldns_pkt_print(stdout, p2); + (int)sldns_buffer_limit(out)); + s1 = sldns_wire2str_pkt(sldns_buffer_begin(out), + sldns_buffer_limit(out)); + printf("%s\n", s1?s1:"null"); + free(s1); printf("\npacket original (%d):\n", - (int)ldns_buffer_limit(pkt)); - ldns_pkt_print(stdout, p1); + (int)sldns_buffer_limit(pkt)); + s2 = sldns_wire2str_pkt(sldns_buffer_begin(pkt), + sldns_buffer_limit(pkt)); + printf("%s\n", s2?s2:"null"); + free(s2); printf("\n"); } - if(s1 != s2) { - /* oops! */ - printf("input ldns parse: %s, output ldns parse: %s.\n", - ldns_get_errorstr_by_id(s1), - ldns_get_errorstr_by_id(s2)); - unit_assert(0); + /* if it had two EDNS sections, skip comparison */ + if(1) { + char* s = sldns_wire2str_pkt(sldns_buffer_begin(pkt), + sldns_buffer_limit(pkt)); + char* e1 = strstr(s, "; EDNS:"); + if(e1 && strstr(e1+4, "; EDNS:")) { + free(s); + return 0; + } + free(s); } /* compare packets */ - unit_assert(match_all(p1, p2)); - ldns_pkt_free(p1); - ldns_pkt_free(p2); + unit_assert(match_all(sldns_buffer_begin(pkt), sldns_buffer_limit(pkt), + sldns_buffer_begin(out), sldns_buffer_limit(out), 1, + matches_nolocation)); return 0; } /** check if unbound formerr equals ldns formerr */ static void -checkformerr(ldns_buffer* pkt) +checkformerr(sldns_buffer* pkt) { - ldns_pkt* p; - ldns_status status = ldns_buffer2pkt_wire(&p, pkt); - if(vbmp) printf("formerr, ldns parse is: %s\n", - ldns_get_errorstr_by_id(status)); - if(status == LDNS_STATUS_OK) { + int status = 0; + char* s = sldns_wire2str_pkt(sldns_buffer_begin(pkt), + sldns_buffer_limit(pkt)); + if(!s) fatal_exit("out of memory"); + if(strstr(s, "Error")) status = 1; + if(strstr(s, "error")) status = 1; + if(status == 0) { printf("Formerr, but ldns gives packet:\n"); - ldns_pkt_print(stdout, p); + printf("%s\n", s); + free(s); exit(1); } - unit_assert(status != LDNS_STATUS_OK); + free(s); + unit_assert(status != 0); } /** performance test message encoding */ static void perf_encode(struct query_info* qi, struct reply_info* rep, uint16_t id, - uint16_t flags, ldns_buffer* out, time_t timenow, + uint16_t flags, sldns_buffer* out, time_t timenow, struct edns_data* edns) { static int num = 0; @@ -285,13 +191,13 @@ perf_encode(struct query_info* qi, struct reply_info* rep, uint16_t id, ((double)end.tv_usec - (double)start.tv_usec)/1000.; printf("[%d] did %u in %g msec for %f encode/sec size %d\n", num++, (unsigned)max, dt, (double)max / (dt/1000.), - (int)ldns_buffer_limit(out)); + (int)sldns_buffer_limit(out)); regional_destroy(r2); } /** perf test a packet */ static void -perftestpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out, +perftestpkt(sldns_buffer* pkt, struct alloc_cache* alloc, sldns_buffer* out, const char* hex) { struct query_info qi; @@ -304,15 +210,16 @@ perftestpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out, struct edns_data edns; hex_to_buf(pkt, hex); - memmove(&id, ldns_buffer_begin(pkt), sizeof(id)); - if(ldns_buffer_limit(pkt) < 2) + memmove(&id, sldns_buffer_begin(pkt), sizeof(id)); + if(sldns_buffer_limit(pkt) < 2) flags = 0; - else memmove(&flags, ldns_buffer_at(pkt, 2), sizeof(flags)); + else memmove(&flags, sldns_buffer_at(pkt, 2), sizeof(flags)); flags = ntohs(flags); ret = reply_info_parse(pkt, alloc, &qi, &rep, region, &edns); if(ret != 0) { - if(vbmp) printf("parse code %d: %s\n", ret, - ldns_lookup_by_id(ldns_rcodes, ret)->name); + char rbuf[16]; + sldns_wire2str_rcode_buf(ret, rbuf, sizeof(rbuf)); + if(vbmp) printf("parse code %d: %s\n", ret, rbuf); if(ret == LDNS_RCODE_FORMERR) checkformerr(pkt); unit_assert(ret != LDNS_RCODE_SERVFAIL); @@ -325,37 +232,44 @@ perftestpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out, regional_destroy(region); } +/** print packed rrset */ +static void +print_rrset(struct ub_packed_rrset_key* rrset) +{ + struct packed_rrset_data* d = (struct packed_rrset_data*)rrset-> + entry.data; + char buf[65535]; + size_t i; + for(i=0; i<d->count+d->rrsig_count; i++) { + if(!packed_rr_to_string(rrset, i, 0, buf, sizeof(buf))) + printf("failedtoconvert %d\n", (int)i); + else + printf("%s\n", buf); + } +} + /** debug print a packet that failed */ static void print_packet_rrsets(struct query_info* qinfo, struct reply_info* rep) { size_t i; - ldns_rr_list* l; - ldns_buffer* buf = ldns_buffer_new(65536); log_query_info(0, "failed query", qinfo); printf(";; ANSWER SECTION (%d rrsets)\n", (int)rep->an_numrrsets); for(i=0; i<rep->an_numrrsets; i++) { - l = packed_rrset_to_rr_list(rep->rrsets[i], buf); printf("; rrset %d\n", (int)i); - ldns_rr_list_print(stdout, l); - ldns_rr_list_deep_free(l); + print_rrset(rep->rrsets[i]); } printf(";; AUTHORITY SECTION (%d rrsets)\n", (int)rep->ns_numrrsets); for(i=rep->an_numrrsets; i<rep->an_numrrsets+rep->ns_numrrsets; i++) { - l = packed_rrset_to_rr_list(rep->rrsets[i], buf); printf("; rrset %d\n", (int)i); - ldns_rr_list_print(stdout, l); - ldns_rr_list_deep_free(l); + print_rrset(rep->rrsets[i]); } printf(";; ADDITIONAL SECTION (%d rrsets)\n", (int)rep->ar_numrrsets); for(i=rep->an_numrrsets+rep->ns_numrrsets; i<rep->rrset_count; i++) { - l = packed_rrset_to_rr_list(rep->rrsets[i], buf); printf("; rrset %d\n", (int)i); - ldns_rr_list_print(stdout, l); - ldns_rr_list_deep_free(l); + print_rrset(rep->rrsets[i]); } printf(";; packet end\n"); - ldns_buffer_free(buf); } /** check that there is no data element that matches the RRSIG */ @@ -397,7 +311,7 @@ check_the_rrsigs(struct query_info* qinfo, struct reply_info* rep) /** test a packet */ static void -testpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out, +testpkt(sldns_buffer* pkt, struct alloc_cache* alloc, sldns_buffer* out, const char* hex) { struct query_info qi; @@ -410,15 +324,16 @@ testpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out, struct edns_data edns; hex_to_buf(pkt, hex); - memmove(&id, ldns_buffer_begin(pkt), sizeof(id)); - if(ldns_buffer_limit(pkt) < 2) + memmove(&id, sldns_buffer_begin(pkt), sizeof(id)); + if(sldns_buffer_limit(pkt) < 2) flags = 0; - else memmove(&flags, ldns_buffer_at(pkt, 2), sizeof(flags)); + else memmove(&flags, sldns_buffer_at(pkt, 2), sizeof(flags)); flags = ntohs(flags); ret = reply_info_parse(pkt, alloc, &qi, &rep, region, &edns); if(ret != 0) { - if(vbmp) printf("parse code %d: %s\n", ret, - ldns_lookup_by_id(ldns_rcodes, ret)->name); + char rbuf[16]; + sldns_wire2str_rcode_buf(ret, rbuf, sizeof(rbuf)); + if(vbmp) printf("parse code %d: %s\n", ret, rbuf); if(ret == LDNS_RCODE_FORMERR) { unit_assert(!check_formerr_gone); checkformerr(pkt); @@ -431,30 +346,30 @@ testpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out, unit_assert(ret != 0); /* udp packets should fit */ attach_edns_record(out, &edns); if(vbmp) printf("inlen %u outlen %u\n", - (unsigned)ldns_buffer_limit(pkt), - (unsigned)ldns_buffer_limit(out)); + (unsigned)sldns_buffer_limit(pkt), + (unsigned)sldns_buffer_limit(out)); if(!check_nosameness) test_buffers(pkt, out); if(check_rrsigs) check_the_rrsigs(&qi, rep); - if(ldns_buffer_limit(out) > lim) { + if(sldns_buffer_limit(out) > lim) { ret = reply_info_encode(&qi, rep, id, flags, out, timenow, region, lim - calc_edns_field_size(&edns), (int)(edns.bits & EDNS_DO)); unit_assert(ret != 0); /* should fit, but with TC */ attach_edns_record(out, &edns); - if( LDNS_QDCOUNT(ldns_buffer_begin(out)) != - LDNS_QDCOUNT(ldns_buffer_begin(pkt)) || - LDNS_ANCOUNT(ldns_buffer_begin(out)) != - LDNS_ANCOUNT(ldns_buffer_begin(pkt)) || - LDNS_NSCOUNT(ldns_buffer_begin(out)) != - LDNS_NSCOUNT(ldns_buffer_begin(pkt))) + if( LDNS_QDCOUNT(sldns_buffer_begin(out)) != + LDNS_QDCOUNT(sldns_buffer_begin(pkt)) || + LDNS_ANCOUNT(sldns_buffer_begin(out)) != + LDNS_ANCOUNT(sldns_buffer_begin(pkt)) || + LDNS_NSCOUNT(sldns_buffer_begin(out)) != + LDNS_NSCOUNT(sldns_buffer_begin(pkt))) unit_assert( - LDNS_TC_WIRE(ldns_buffer_begin(out))); + LDNS_TC_WIRE(sldns_buffer_begin(out))); /* must set TC bit if shortened */ - unit_assert(ldns_buffer_limit(out) <= lim); + unit_assert(sldns_buffer_limit(out) <= lim); } } @@ -465,7 +380,7 @@ testpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out, /** simple test of parsing */ static void -simpletest(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out) +simpletest(sldns_buffer* pkt, struct alloc_cache* alloc, sldns_buffer* out) { /* a root query drill -q - */ testpkt(pkt, alloc, out, @@ -522,7 +437,7 @@ simpletest(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out) /** simple test of parsing, pcat file */ static void -testfromfile(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out, +testfromfile(sldns_buffer* pkt, struct alloc_cache* alloc, sldns_buffer* out, const char* fname) { FILE* in = fopen(fname, "r"); @@ -549,8 +464,8 @@ testfromfile(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out, /** simple test of parsing, drill file */ static void -testfromdrillfile(ldns_buffer* pkt, struct alloc_cache* alloc, - ldns_buffer* out, const char* fname) +testfromdrillfile(sldns_buffer* pkt, struct alloc_cache* alloc, + sldns_buffer* out, const char* fname) { /* ;-- is used to indicate a new message */ FILE* in = fopen(fname, "r"); @@ -582,8 +497,8 @@ testfromdrillfile(ldns_buffer* pkt, struct alloc_cache* alloc, void msgparse_test(void) { - ldns_buffer* pkt = ldns_buffer_new(65553); - ldns_buffer* out = ldns_buffer_new(65553); + sldns_buffer* pkt = sldns_buffer_new(65553); + sldns_buffer* out = sldns_buffer_new(65553); struct alloc_cache super_a, alloc; /* init */ alloc_init(&super_a, NULL, 0); @@ -619,6 +534,6 @@ void msgparse_test(void) /* cleanup */ alloc_clear(&alloc); alloc_clear(&super_a); - ldns_buffer_free(pkt); - ldns_buffer_free(out); + sldns_buffer_free(pkt); + sldns_buffer_free(out); } diff --git a/testcode/unitneg.c b/testcode/unitneg.c index 686ad0086362..d3968409519e 100644 --- a/testcode/unitneg.c +++ b/testcode/unitneg.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** @@ -45,6 +45,7 @@ #include "util/data/dname.h" #include "testcode/unitmain.h" #include "validator/val_neg.h" +#include "ldns/rrdef.h" /** verbose unit test for negative cache */ static int negverbose = 0; diff --git a/testcode/unitregional.c b/testcode/unitregional.c index 93249deb4ee4..49c8147c944c 100644 --- a/testcode/unitregional.c +++ b/testcode/unitregional.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** diff --git a/testcode/unitslabhash.c b/testcode/unitslabhash.c index 70f1c58b0ecd..b4a5048e654d 100644 --- a/testcode/unitslabhash.c +++ b/testcode/unitslabhash.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** diff --git a/testcode/unitverify.c b/testcode/unitverify.c index d2d268dfdf2d..2074f3c4ee22 100644 --- a/testcode/unitverify.c +++ b/testcode/unitverify.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** @@ -46,7 +46,7 @@ #include "validator/val_nsec.h" #include "validator/val_nsec3.h" #include "validator/validator.h" -#include "testcode/ldns-testpkts.h" +#include "testcode/testpkts.h" #include "util/data/msgreply.h" #include "util/data/msgparse.h" #include "util/data/dname.h" @@ -56,39 +56,33 @@ #include "util/net_help.h" #include "util/module.h" #include "util/config_file.h" +#include "ldns/sbuffer.h" +#include "ldns/keyraw.h" +#include "ldns/str2wire.h" +#include "ldns/wire2str.h" /** verbose signature test */ static int vsig = 0; /** entry to packet buffer with wireformat */ static void -entry_to_buf(struct entry* e, ldns_buffer* pkt) +entry_to_buf(struct entry* e, sldns_buffer* pkt) { unit_assert(e->reply_list); if(e->reply_list->reply_from_hex) { - ldns_buffer_copy(pkt, e->reply_list->reply_from_hex); + sldns_buffer_copy(pkt, e->reply_list->reply_from_hex); } else { - ldns_status status; - size_t answer_size; - uint8_t* ans = NULL; - status = ldns_pkt2wire(&ans, e->reply_list->reply, - &answer_size); - if(status != LDNS_STATUS_OK) { - log_err("could not create reply: %s", - ldns_get_errorstr_by_id(status)); - fatal_exit("error in test"); - } - ldns_buffer_clear(pkt); - ldns_buffer_write(pkt, ans, answer_size); - ldns_buffer_flip(pkt); - free(ans); + sldns_buffer_clear(pkt); + sldns_buffer_write(pkt, e->reply_list->reply_pkt, + e->reply_list->reply_len); + sldns_buffer_flip(pkt); } } /** entry to reply info conversion */ static void entry_to_repinfo(struct entry* e, struct alloc_cache* alloc, - struct regional* region, ldns_buffer* pkt, struct query_info* qi, + struct regional* region, sldns_buffer* pkt, struct query_info* qi, struct reply_info** rep) { int ret; @@ -102,8 +96,9 @@ entry_to_repinfo(struct entry* e, struct alloc_cache* alloc, ret = reply_info_parse(pkt, alloc, qi, rep, region, &edns); lock_quick_unlock(&alloc->lock); if(ret != 0) { - printf("parse code %d: %s\n", ret, - ldns_lookup_by_id(ldns_rcodes, ret)->name); + char rcode[16]; + sldns_wire2str_rcode_buf(ret, rcode, sizeof(rcode)); + printf("parse code %d: %s\n", ret, rcode); unit_assert(ret != 0); } } @@ -111,7 +106,7 @@ entry_to_repinfo(struct entry* e, struct alloc_cache* alloc, /** extract DNSKEY rrset from answer and convert it */ static struct ub_packed_rrset_key* extract_keys(struct entry* e, struct alloc_cache* alloc, - struct regional* region, ldns_buffer* pkt) + struct regional* region, sldns_buffer* pkt) { struct ub_packed_rrset_key* dnskey = NULL; struct query_info qinfo; @@ -206,7 +201,7 @@ verifytest_rrset(struct module_env* env, struct val_env* ve, /** verify and test an entry - every rr in the message */ static void verifytest_entry(struct entry* e, struct alloc_cache* alloc, - struct regional* region, ldns_buffer* pkt, + struct regional* region, sldns_buffer* pkt, struct ub_packed_rrset_key* dnskey, struct module_env* env, struct val_env* ve) { @@ -216,9 +211,10 @@ verifytest_entry(struct entry* e, struct alloc_cache* alloc, regional_free_all(region); if(vsig) { - printf("verifying pkt:\n"); - ldns_pkt_print(stdout, e->reply_list->reply); - printf("\n"); + char* s = sldns_wire2str_pkt(e->reply_list->reply_pkt, + e->reply_list->reply_len); + printf("verifying pkt:\n%s\n", s?s:"outofmemory"); + free(s); } entry_to_repinfo(e, alloc, region, pkt, &qinfo, &rep); @@ -245,7 +241,7 @@ find_rrset_type(struct reply_info* rep, uint16_t type) /** DS sig test an entry - get DNSKEY and DS in entry and verify */ static void dstest_entry(struct entry* e, struct alloc_cache* alloc, - struct regional* region, ldns_buffer* pkt, struct module_env* env) + struct regional* region, sldns_buffer* pkt, struct module_env* env) { struct query_info qinfo; struct reply_info* rep = NULL; @@ -254,9 +250,10 @@ dstest_entry(struct entry* e, struct alloc_cache* alloc, regional_free_all(region); if(vsig) { - printf("verifying DS-DNSKEY match:\n"); - ldns_pkt_print(stdout, e->reply_list->reply); - printf("\n"); + char* s = sldns_wire2str_pkt(e->reply_list->reply_pkt, + e->reply_list->reply_len); + printf("verifying DS-DNSKEY match:\n%s\n", s?s:"outofmemory"); + free(s); } entry_to_repinfo(e, alloc, region, pkt, &qinfo, &rep); ds = find_rrset_type(rep, LDNS_RR_TYPE_DS); @@ -296,7 +293,7 @@ verifytest_file(const char* fname, const char* at_date) struct ub_packed_rrset_key* dnskey; struct regional* region = regional_create(); struct alloc_cache alloc; - ldns_buffer* buf = ldns_buffer_new(65535); + sldns_buffer* buf = sldns_buffer_new(65535); struct entry* e; struct entry* list = read_datafile(fname, 1); struct module_env env; @@ -326,7 +323,7 @@ verifytest_file(const char* fname, const char* at_date) delete_entry(list); regional_destroy(region); alloc_clear(&alloc); - ldns_buffer_free(buf); + sldns_buffer_free(buf); } /** verify DS matches DNSKEY from a file */ @@ -340,7 +337,7 @@ dstest_file(const char* fname) */ struct regional* region = regional_create(); struct alloc_cache alloc; - ldns_buffer* buf = ldns_buffer_new(65535); + sldns_buffer* buf = sldns_buffer_new(65535); struct entry* e; struct entry* list = read_datafile(fname, 1); struct module_env env; @@ -361,7 +358,7 @@ dstest_file(const char* fname) delete_entry(list); regional_destroy(region); alloc_clear(&alloc); - ldns_buffer_free(buf); + sldns_buffer_free(buf); } /** helper for unittest of NSEC routines */ @@ -417,7 +414,7 @@ nsectest(void) static void nsec3_hash_test_entry(struct entry* e, rbtree_t* ct, struct alloc_cache* alloc, struct regional* region, - ldns_buffer* buf) + sldns_buffer* buf) { struct query_info qinfo; struct reply_info* rep = NULL; @@ -427,9 +424,10 @@ nsec3_hash_test_entry(struct entry* e, rbtree_t* ct, uint8_t* qname; if(vsig) { - printf("verifying NSEC3 hash:\n"); - ldns_pkt_print(stdout, e->reply_list->reply); - printf("\n"); + char* s = sldns_wire2str_pkt(e->reply_list->reply_pkt, + e->reply_list->reply_len); + printf("verifying NSEC3 hash:\n%s\n", s?s:"outofmemory"); + free(s); } entry_to_repinfo(e, alloc, region, buf, &qinfo, &rep); nsec3 = find_rrset_type(rep, LDNS_RR_TYPE_NSEC3); @@ -473,7 +471,7 @@ nsec3_hash_test(const char* fname) rbtree_t ct; struct regional* region = regional_create(); struct alloc_cache alloc; - ldns_buffer* buf = ldns_buffer_new(65535); + sldns_buffer* buf = sldns_buffer_new(65535); struct entry* e; struct entry* list = read_datafile(fname, 1); @@ -491,7 +489,7 @@ nsec3_hash_test(const char* fname) delete_entry(list); regional_destroy(region); alloc_clear(&alloc); - ldns_buffer_free(buf); + sldns_buffer_free(buf); } void @@ -517,7 +515,7 @@ verify_test(void) verifytest_file("testdata/test_sigs.hinfo", "20090107100022"); verifytest_file("testdata/test_sigs.revoked", "20080414005004"); #ifdef USE_GOST - if(ldns_key_EVP_load_gost_id()) + if(sldns_key_EVP_load_gost_id()) verifytest_file("testdata/test_sigs.gost", "20090807060504"); else printf("Warning: skipped GOST, openssl does not provide gost.\n"); #endif |