diff --git a/Knot.files b/Knot.files index 552f82c4b59d30831b4ceef92837d62ffc056901..c9c1621931e06182686c16328f034f465d6911c1 100644 --- a/Knot.files +++ b/Knot.files @@ -216,3 +216,17 @@ src/dnslib/dname-table.h src/dnslib/dname-table.c src/common/general-tree.h src/common/general-tree.c +src/dnslib/tests/dnslib/dname_table_tests.h +src/dnslib/tests/dnslib/dname_table_tests.c +src/dnslib/tests/dnslib/packet_tests.c +src/dnslib/tests/dnslib/packet_tests.h +src/dnslib/tests/realdata/dnslib/packet_tests_realdata.c +src/dnslib/tests/realdata/dnslib/packet_tests_realdata.h +src/dnslib/tests/dnslib/response2_tests.c +src/dnslib/tests/dnslib/response2_tests.h +src/dnslib/tests/realdata/dnslib/response2_tests_realdata.c +src/dnslib/tests/realdata/dnslib/response2_tests_realdata.h +src/dnslib/tests/dnslib/query_tests.c +src/dnslib/tests/dnslib/query_tests.h +src/dnslib/tests/dnslib/nsec3_tests.c +src/dnslib/tests/dnslib/nsec3_tests.h diff --git a/scripts/parse_dump.py b/scripts/parse_dump.py index 7f71950d7a843dfa035b30dc565e7022e6488107..d9cc44b6998ca68fad2f8d4c2e32ae97ebac5020 100755 --- a/scripts/parse_dump.py +++ b/scripts/parse_dump.py @@ -106,6 +106,9 @@ def chop_and_write_packet(packet): fp.write(pack('H', packet.ancount)) fp.write(pack('H', packet.nscount)) fp.write(pack('H', packet.arcount)) + +#write query flag + fp.write(pack('H', packet.qr)) chop_and_write_section_query(packet.qd) chop_and_write_section_response(packet.an) @@ -122,6 +125,7 @@ fp.write(pack('L', total_length)) for packet in packets: try: data = a2b_hex(str(packet['DNS']).encode('hex')) + fr.write(pack('H', packet.qr)) fr.write(pack('H', len(data))) fr.write(data) chop_and_write_packet(packet['DNS']) diff --git a/src/Makefile.am b/src/Makefile.am index d4866d5c09a4f5734975a6d1c1c716034a42cdfe..8e7957c7e9998cf35e3f399f68771e4a9b490e11 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,15 +11,19 @@ libknotd_la_LFLAGS = # TODO: reentrant parser, prefix BUILT_SOURCES = \ dnslib/tests/parsed_data.rc \ + dnslib/tests/realdata/parsed_data.rc \ dnslib/tests/raw_data_queries.rc \ dnslib/tests/raw_data.rc \ + dnslib/tests/realdata/raw_data.rc \ dnslib/tests/parsed_data_queries.rc \ tests/sample_conf.rc CLEANFILES = \ dnslib/tests/parsed_data.rc \ + dnslib/tests/realdata/parsed_data.rc \ dnslib/tests/raw_data_queries.rc \ dnslib/tests/raw_data.rc \ + dnslib/tests/realdata/raw_data.rc \ dnslib/tests/parsed_data_queries.rc \ tests/sample_conf.rc \ zparser.h \ @@ -70,9 +74,12 @@ unittests_dnslib_realdata_SOURCES = \ dnslib/tests/realdata/dnslib/node_tests_realdata.c \ dnslib/tests/realdata/dnslib/rdata_tests_realdata.c \ dnslib/tests/realdata/dnslib/response_tests_realdata.c \ + dnslib/tests/realdata/dnslib/response2_tests_realdata.c \ dnslib/tests/realdata/dnslib/rrset_tests_realdata.c \ dnslib/tests/realdata/dnslib/zone_tests_realdata.c \ dnslib/tests/realdata/dnslib/zonedb_tests_realdata.c \ + dnslib/tests/realdata/dnslib/packet_tests_realdata.h \ + dnslib/tests/realdata/dnslib/packet_tests_realdata.c \ dnslib/tests/realdata/dnslib_tests_loader_realdata.h \ dnslib/tests/realdata/dnslib_tests_loader_realdata.c \ dnslib/tests/realdata/unittests_dnslib_realdata.c @@ -82,6 +89,14 @@ unittests_dnslib_SOURCES = \ dnslib/tests/dnslib/cuckoo_tests.h \ dnslib/tests/dnslib/dname_tests.c \ dnslib/tests/dnslib/dname_tests.h \ + dnslib/tests/dnslib/dname_table_tests.h \ + dnslib/tests/dnslib/dname_table_tests.c \ + dnslib/tests/dnslib/nsec3_tests.h \ + dnslib/tests/dnslib/nsec3_tests.c \ + dnslib/tests/dnslib/packet_tests.h \ + dnslib/tests/dnslib/packet_tests.c \ + dnslib/tests/dnslib/query_tests.h \ + dnslib/tests/dnslib/query_tests.c \ dnslib/tests/dnslib/edns_tests.c \ dnslib/tests/dnslib/edns_tests.h \ dnslib/tests/dnslib/node_tests.c \ @@ -90,6 +105,8 @@ unittests_dnslib_SOURCES = \ dnslib/tests/dnslib/rdata_tests.h \ dnslib/tests/dnslib/rrset_tests.c \ dnslib/tests/dnslib/rrset_tests.h \ + dnslib/tests/dnslib/response2_tests.h \ + dnslib/tests/dnslib/response2_tests.c \ dnslib/tests/dnslib/zone_tests.c \ dnslib/tests/dnslib/zone_tests.h \ dnslib/tests/dnslib/zonedb_tests.c \ @@ -273,6 +290,9 @@ unittests_dnslib_realdata_LDADD = libknot.la libknots.la @LIBOBJS@ dnslib/tests/parsed_data.rc: dnslib/tests/files/parsed_data ../resource.sh dnslib/tests/files/parsed_data >$@ +dnslib/tests/realdata/parsed_data.rc: dnslib/tests/realdata/files/parsed_data + ../resource.sh dnslib/tests/realdata/files/parsed_data >$@ + dnslib/tests/parsed_data_queries.rc: dnslib/tests/files/parsed_data_queries ../resource.sh dnslib/tests/files/parsed_data_queries >$@ @@ -282,6 +302,9 @@ dnslib/tests/raw_data_queries.rc: dnslib/tests/files/raw_data_queries dnslib/tests/raw_data.rc: dnslib/tests/files/raw_data ../resource.sh dnslib/tests/files/raw_data >$@ +dnslib/tests/realdata/raw_data.rc: dnslib/tests/realdata/files/raw_data + ../resource.sh dnslib/tests/realdata/files/raw_data >$@ + tests/sample_conf.rc: tests/files/sample_conf ../resource.sh tests/files/sample_conf >$@ diff --git a/src/common/evqueue.c b/src/common/evqueue.c index 54f1f6da0e2d53e7374bab65eb53ce1eca243b9d..e70998b3953f1d6ac8a5c3171fb9a54034b145bf 100644 --- a/src/common/evqueue.c +++ b/src/common/evqueue.c @@ -37,6 +37,11 @@ void evqueue_free(evqueue_t **q) free(eq); } +int evqueue_pollfd(evqueue_t *q) +{ + return q->fds[EVQUEUE_READFD]; +} + int evqueue_poll(evqueue_t *q, const struct timespec *ts, const sigset_t *sigmask) { diff --git a/src/common/evqueue.h b/src/common/evqueue.h index d5eed9d0b931384248cbbdc9107473dce0dc1cc3..c5d9205448aaeee38a1ec330b3046bead8447ff1 100644 --- a/src/common/evqueue.h +++ b/src/common/evqueue.h @@ -83,6 +83,16 @@ evqueue_t *evqueue_new(); */ void evqueue_free(evqueue_t **q); +/*! + * \brief Return evqueue pollable fd. + * + * \param q Event queue. + * + * \retval File descriptor available for polling. + * \retval -1 On error. + */ +int evqueue_pollfd(evqueue_t *q); + /*! * \brief Poll for new events. * diff --git a/src/dnslib/dname.c b/src/dnslib/dname.c index fb51b80d1d42914f41163ed9cdccbd1846b77eb4..e0edd8a0920313d7db40e2da5f08f2dc52dfc2a1 100644 --- a/src/dnslib/dname.c +++ b/src/dnslib/dname.c @@ -680,6 +680,13 @@ void dnslib_dname_update_node(dnslib_dname_t *dname) /*----------------------------------------------------------------------------*/ +void dnslib_dname_set_node(dnslib_dname_t *dname, dnslib_node_t *node) +{ + dname->node = node; +} + +/*----------------------------------------------------------------------------*/ + int dnslib_dname_is_fqdn(const dnslib_dname_t *dname) { return (dname->name[dname->size - 1] == '\0'); diff --git a/src/dnslib/dname.h b/src/dnslib/dname.h index df2d6feece3f49466cade28b64c38acbf811e6ac..739142fb320d27836de39be9805f926acdbc1484 100644 --- a/src/dnslib/dname.h +++ b/src/dnslib/dname.h @@ -204,6 +204,8 @@ void dnslib_dname_set_node(dnslib_dname_t *dname, struct dnslib_node *node); void dnslib_dname_update_node(dnslib_dname_t *dname); +void dnslib_dname_set_node(dnslib_dname_t *dname, struct dnslib_node *node); + /*! * \brief Checks if the given domain name is a fully-qualified domain name. * diff --git a/src/dnslib/edns.c b/src/dnslib/edns.c index 6f51044c16e0bdcefed5748d44a5113568412055..e240d7e48059a5369483fb21b0acefac5ec8c0af 100644 --- a/src/dnslib/edns.c +++ b/src/dnslib/edns.c @@ -182,6 +182,7 @@ int dnslib_edns_new_from_rr(dnslib_opt_rr_t *opt_rr, uint16_t dnslib_edns_get_payload(const dnslib_opt_rr_t *opt_rr) { + assert(opt_rr != NULL); return opt_rr->payload; } @@ -190,6 +191,7 @@ uint16_t dnslib_edns_get_payload(const dnslib_opt_rr_t *opt_rr) void dnslib_edns_set_payload(dnslib_opt_rr_t *opt_rr, uint16_t payload) { + assert(opt_rr != NULL); opt_rr->payload = payload; } @@ -203,8 +205,9 @@ uint8_t dnslib_edns_get_ext_rcode(const dnslib_opt_rr_t *opt_rr) /*----------------------------------------------------------------------------*/ void dnslib_edns_set_ext_rcode(dnslib_opt_rr_t *opt_rr, - uint8_t ext_rcode) + uint8_t ext_rcode) { + assert(opt_rr != NULL); opt_rr->ext_rcode = ext_rcode; } @@ -212,6 +215,7 @@ void dnslib_edns_set_ext_rcode(dnslib_opt_rr_t *opt_rr, uint8_t dnslib_edns_get_version(const dnslib_opt_rr_t *opt_rr) { + assert(opt_rr != NULL); return opt_rr->version; } @@ -220,6 +224,7 @@ uint8_t dnslib_edns_get_version(const dnslib_opt_rr_t *opt_rr) void dnslib_edns_set_version(dnslib_opt_rr_t *opt_rr, uint8_t version) { + assert(opt_rr != NULL); opt_rr->version = version; } @@ -227,6 +232,7 @@ void dnslib_edns_set_version(dnslib_opt_rr_t *opt_rr, uint16_t dnslib_edns_get_flags(const dnslib_opt_rr_t *opt_rr) { + assert(opt_rr != NULL); return opt_rr->flags; } @@ -234,6 +240,10 @@ uint16_t dnslib_edns_get_flags(const dnslib_opt_rr_t *opt_rr) int dnslib_edns_do(const dnslib_opt_rr_t *opt_rr) { + if (opt_rr == NULL) { + return DNSLIB_EBADARG; + } + debug_dnslib_edns("Flags: %u\n", opt_rr->flags); return (opt_rr->flags & DNSLIB_EDNS_DO_MASK); } @@ -242,6 +252,10 @@ int dnslib_edns_do(const dnslib_opt_rr_t *opt_rr) void dnslib_edns_set_do(dnslib_opt_rr_t *opt_rr) { + if (opt_rr == NULL) { + return; + } + opt_rr->flags |= DNSLIB_EDNS_DO_MASK; } @@ -250,6 +264,10 @@ void dnslib_edns_set_do(dnslib_opt_rr_t *opt_rr) int dnslib_edns_add_option(dnslib_opt_rr_t *opt_rr, uint16_t code, uint16_t length, const uint8_t *data) { + if (opt_rr == NULL) { + return DNSLIB_EBADARG; + } + if (opt_rr->option_count == opt_rr->options_max) { dnslib_opt_option_t *options_new = (dnslib_opt_option_t *)calloc( @@ -283,6 +301,10 @@ int dnslib_edns_add_option(dnslib_opt_rr_t *opt_rr, uint16_t code, int dnslib_edns_has_option(const dnslib_opt_rr_t *opt_rr, uint16_t code) { + if (opt_rr == NULL) { + return DNSLIB_EBADARG; + } + int i = 0; while (i < opt_rr->option_count && opt_rr->options[i].code != code) { ++i; @@ -298,6 +320,10 @@ int dnslib_edns_has_option(const dnslib_opt_rr_t *opt_rr, uint16_t code) short dnslib_edns_to_wire(const dnslib_opt_rr_t *opt_rr, uint8_t *wire, size_t max_size) { + if (opt_rr == NULL) { + return DNSLIB_EBADARG; + } + assert(DNSLIB_EDNS_MIN_SIZE <= max_size); if (max_size < opt_rr->size) { @@ -340,6 +366,10 @@ short dnslib_edns_to_wire(const dnslib_opt_rr_t *opt_rr, uint8_t *wire, short dnslib_edns_size(dnslib_opt_rr_t *opt_rr) { + if (opt_rr == NULL) { + return DNSLIB_EBADARG; + } + return opt_rr->size; } diff --git a/src/dnslib/edns.h b/src/dnslib/edns.h index 491e841cad5002be0a33889909da1dbb58028f3d..0983a10082368475eca47fc0e8033c7c1ac1fee7 100644 --- a/src/dnslib/edns.h +++ b/src/dnslib/edns.h @@ -97,6 +97,10 @@ int dnslib_edns_new_from_rr(dnslib_opt_rr_t *opt_rr, /*! * \brief Returns the UDP payload stored in the OPT RR. * + * \warning This function does not check the parameter, so ensure to check it + * before calling the function. It must not be NULL. + * \note There is an assert() for debug checking of the parameter. + * * \param opt_rr OPT RR structure to get the payload from. * * \return UDP payload in bytes. @@ -106,6 +110,10 @@ uint16_t dnslib_edns_get_payload(const dnslib_opt_rr_t *opt_rr); /*! * \brief Sets the UDP payload field in the OPT RR. * + * \warning This function does not check the parameter, so ensure to check it + * before calling the function. It must not be NULL. + * \note There is an assert() for debug checking of the parameter. + * * \param opt_rr OPT RR structure to set the payload to. * \param payload UDP payload in bytes. */ @@ -114,6 +122,10 @@ void dnslib_edns_set_payload(dnslib_opt_rr_t *opt_rr, uint16_t payload); /*! * \brief Returns the Extended RCODE stored in the OPT RR. * + * \warning This function does not check the parameter, so ensure to check it + * before calling the function. It must not be NULL. + * \note There is an assert() for debug checking of the parameter. + * * \param opt_rr OPT RR structure to get the Extended RCODE from. * * \return Extended RCODE. @@ -123,6 +135,10 @@ uint8_t dnslib_edns_get_ext_rcode(const dnslib_opt_rr_t *opt_rr); /*! * \brief Sets the Extended RCODE field in the OPT RR. * + * \warning This function does not check the parameter, so ensure to check it + * before calling the function. It must not be NULL. + * \note There is an assert() for debug checking of the parameter. + * * \param opt_rr OPT RR structure to set the Extended RCODE to. * \param ext_rcode Extended RCODE to set. */ @@ -131,6 +147,10 @@ void dnslib_edns_set_ext_rcode(dnslib_opt_rr_t *opt_rr, uint8_t ext_rcode); /*! * \brief Returns the EDNS version stored in the OPT RR. * + * \warning This function does not check the parameter, so ensure to check it + * before calling the function. It must not be NULL. + * \note There is an assert() for debug checking of the parameter. + * * \param opt_rr OPT RR structure to get the EDNS version from. * * \return EDNS version. @@ -140,6 +160,10 @@ uint8_t dnslib_edns_get_version(const dnslib_opt_rr_t *opt_rr); /*! * \brief Sets the EDNS version field in the OPT RR. * + * \warning This function does not check the parameter, so ensure to check it + * before calling the function. It must not be NULL. + * \note There is an assert() for debug checking of the parameter. + * * \param opt_rr OPT RR structure to set the EDNS version to. * \param version EDNS version to set. */ @@ -148,6 +172,10 @@ void dnslib_edns_set_version(dnslib_opt_rr_t *opt_rr, uint8_t version); /*! * \brief Returns the flags stored in the OPT RR. * + * \warning This function does not check the parameter, so ensure to check it + * before calling the function. It must not be NULL. + * \note There is an assert() for debug checking of the parameter. + * * \param opt_rr OPT RR structure to get the flags from. * * \return EDNS flags. diff --git a/src/dnslib/packet.c b/src/dnslib/packet.c index d7b5aa45bb7863d4cf8d15a6b6c2c9397260fc21..563fd6526f118199a77513098055d00be4dc510a 100644 --- a/src/dnslib/packet.c +++ b/src/dnslib/packet.c @@ -815,6 +815,10 @@ int dnslib_packet_parse_from_wire(dnslib_packet_t *packet, int dnslib_packet_parse_rest(dnslib_packet_t *packet) { + if (packet == NULL) { + return DNSLIB_EBADARG; + } + if (packet->parsed >= packet->size) { return DNSLIB_EOK; } @@ -829,7 +833,7 @@ int dnslib_packet_parse_rest(dnslib_packet_t *packet) int dnslib_packet_parse_next_rr_answer(dnslib_packet_t *packet, dnslib_rrset_t **rr) { - if (packet == NULL) { + if (packet == NULL || rr == NULL) { return DNSLIB_EBADARG; } @@ -893,6 +897,7 @@ int dnslib_packet_set_max_size(dnslib_packet_t *packet, int max_size) uint16_t dnslib_packet_id(const dnslib_packet_t *packet) { + assert(packet != NULL); return packet->header.id; } @@ -900,6 +905,7 @@ uint16_t dnslib_packet_id(const dnslib_packet_t *packet) uint8_t dnslib_packet_opcode(const dnslib_packet_t *packet) { + assert(packet != NULL); return dnslib_wire_flags_get_opcode(packet->header.flags1); } @@ -907,6 +913,10 @@ uint8_t dnslib_packet_opcode(const dnslib_packet_t *packet) const dnslib_dname_t *dnslib_packet_qname(const dnslib_packet_t *packet) { + if (packet == NULL) { + return NULL; + } + return packet->question.qname; } @@ -914,6 +924,7 @@ const dnslib_dname_t *dnslib_packet_qname(const dnslib_packet_t *packet) uint16_t dnslib_packet_qtype(const dnslib_packet_t *packet) { + assert(packet != NULL); return packet->question.qtype; } @@ -921,6 +932,7 @@ uint16_t dnslib_packet_qtype(const dnslib_packet_t *packet) uint16_t dnslib_packet_qclass(const dnslib_packet_t *packet) { + assert(packet != NULL); return packet->question.qclass; } @@ -928,6 +940,10 @@ uint16_t dnslib_packet_qclass(const dnslib_packet_t *packet) int dnslib_packet_is_query(const dnslib_packet_t *packet) { + if (packet == NULL) { + return DNSLIB_EBADARG; + } + return (dnslib_wire_flags_get_qr(packet->header.flags1) == 0); } @@ -935,6 +951,10 @@ int dnslib_packet_is_query(const dnslib_packet_t *packet) const dnslib_packet_t *dnslib_packet_query(const dnslib_packet_t *packet) { + if (packet == NULL) { + return NULL; + } + return packet->query; } @@ -942,6 +962,10 @@ const dnslib_packet_t *dnslib_packet_query(const dnslib_packet_t *packet) short dnslib_packet_answer_rrset_count(const dnslib_packet_t *packet) { + if (packet == NULL) { + return DNSLIB_EBADARG; + } + return packet->an_rrsets; } @@ -949,6 +973,10 @@ short dnslib_packet_answer_rrset_count(const dnslib_packet_t *packet) short dnslib_packet_authority_rrset_count(const dnslib_packet_t *packet) { + if (packet == NULL) { + return DNSLIB_EBADARG; + } + return packet->ns_rrsets; } @@ -956,6 +984,10 @@ short dnslib_packet_authority_rrset_count(const dnslib_packet_t *packet) short dnslib_packet_additional_rrset_count(const dnslib_packet_t *packet) { + if (packet == NULL) { + return DNSLIB_EBADARG; + } + return packet->ar_rrsets; } @@ -964,7 +996,7 @@ short dnslib_packet_additional_rrset_count(const dnslib_packet_t *packet) const dnslib_rrset_t *dnslib_packet_answer_rrset( const dnslib_packet_t *packet, short pos) { - if (pos > packet->an_rrsets) { + if (packet == NULL || pos > packet->an_rrsets) { return NULL; } @@ -976,7 +1008,7 @@ const dnslib_rrset_t *dnslib_packet_answer_rrset( const dnslib_rrset_t *dnslib_packet_authority_rrset( dnslib_packet_t *packet, short pos) { - if (pos > packet->ns_rrsets) { + if (packet == NULL || pos > packet->ns_rrsets) { return NULL; } @@ -988,7 +1020,7 @@ const dnslib_rrset_t *dnslib_packet_authority_rrset( const dnslib_rrset_t *dnslib_packet_additional_rrset( dnslib_packet_t *packet, short pos) { - if (pos > packet->ar_rrsets) { + if (packet == NULL || pos > packet->ar_rrsets) { return NULL; } @@ -1001,6 +1033,10 @@ int dnslib_packet_contains(const dnslib_packet_t *packet, const dnslib_rrset_t *rrset, dnslib_rrset_compare_type_t cmp) { + if (packet == NULL || rrset == NULL) { + return DNSLIB_EBADARG; + } + for (int i = 0; i < packet->header.ancount; ++i) { if (dnslib_rrset_compare(packet->answer[i], rrset, cmp)) { return 1; @@ -1027,6 +1063,10 @@ int dnslib_packet_contains(const dnslib_packet_t *packet, int dnslib_packet_add_tmp_rrset(dnslib_packet_t *packet, dnslib_rrset_t *tmp_rrset) { + if (packet == NULL || tmp_rrset == NULL) { + return DNSLIB_EBADARG; + } + if (packet->tmp_rrsets_count == packet->tmp_rrsets_max && dnslib_packet_realloc_rrsets(&packet->tmp_rrsets, &packet->tmp_rrsets_max, @@ -1050,6 +1090,10 @@ int dnslib_packet_add_tmp_rrset(dnslib_packet_t *packet, */ void dnslib_packet_free_tmp_rrsets(dnslib_packet_t *pkt) { + if (pkt == NULL) { + return; + } + for (int i = 0; i < pkt->tmp_rrsets_count; ++i) { DEBUG_DNSLIB_PACKET( char *name = dnslib_dname_to_str( @@ -1075,6 +1119,10 @@ DEBUG_DNSLIB_PACKET( void dnslib_packet_header_to_wire(const dnslib_header_t *header, uint8_t **pos, size_t *size) { + if (header == NULL || pos == NULL || *pos == NULL || size == NULL) { + return; + } + dnslib_wire_set_id(*pos, header->id); dnslib_wire_set_flags1(*pos, header->flags1); dnslib_wire_set_flags2(*pos, header->flags2); @@ -1091,6 +1139,10 @@ void dnslib_packet_header_to_wire(const dnslib_header_t *header, int dnslib_packet_question_to_wire(dnslib_packet_t *packet) { + if (packet == NULL) { + return DNSLIB_EBADARG; + } + if (packet->size > DNSLIB_WIRE_HEADER_SIZE) { return DNSLIB_ERROR; } @@ -1126,13 +1178,19 @@ int dnslib_packet_question_to_wire(dnslib_packet_t *packet) /*----------------------------------------------------------------------------*/ -void dnslib_packet_edns_to_wire(dnslib_packet_t *packet) +int dnslib_packet_edns_to_wire(dnslib_packet_t *packet) { + if (packet == NULL) { + return DNSLIB_EBADARG; + } + packet->size += dnslib_edns_to_wire(&packet->opt_rr, packet->wireformat + packet->size, packet->max_size - packet->size); packet->header.arcount += 1; + + return DNSLIB_EOK; } /*----------------------------------------------------------------------------*/ @@ -1202,47 +1260,10 @@ void dnslib_packet_free(dnslib_packet_t **packet) static void dnslib_packet_dump_rrsets(const dnslib_rrset_t **rrsets, int count) { + assert(rrsets != NULL && *rrsets != NULL); + for (int i = 0; i < count; ++i) { - debug_dnslib_packet(" RRSet %d:\n", i + 1); - char *name = dnslib_dname_to_str(rrsets[i]->owner); - debug_dnslib_packet(" Owner: %s\n", name); - free(name); - debug_dnslib_packet(" Type: %s\n", - dnslib_rrtype_to_string(rrsets[i]->type)); - debug_dnslib_packet(" Class: %s\n", - dnslib_rrclass_to_string(rrsets[i]->rclass)); - debug_dnslib_packet(" TTL: %d\n", rrsets[i]->ttl); - debug_dnslib_packet(" RDATA: "); - - dnslib_rrtype_descriptor_t *desc = - dnslib_rrtype_descriptor_by_type(rrsets[i]->type); - - const dnslib_rdata_t *rdata = dnslib_rrset_rdata(rrsets[i]); - while (rdata != NULL) { - for (int j = 0; j < rdata->count; ++j) { - switch (desc->wireformat[j]) { - case DNSLIB_RDATA_WF_COMPRESSED_DNAME: - case DNSLIB_RDATA_WF_LITERAL_DNAME: - case DNSLIB_RDATA_WF_UNCOMPRESSED_DNAME: - name = dnslib_dname_to_str( - rdata->items[j].dname); - debug_dnslib_packet("%s \n",name); - free(name); - break; - case DNSLIB_RDATA_WF_BINARYWITHLENGTH: - debug_dnslib_packet_hex( - (char *)rdata->items[j].raw_data, - rdata->items[j].raw_data[0]); - break; - default: - debug_dnslib_packet_hex( - (char *)&rdata->items[j].raw_data[1], - rdata->items[j].raw_data[0]); - break; - } - } - rdata = dnslib_rrset_rdata_next(rrsets[i], rdata); - } + dnslib_rrset_dump(rrsets[i], 0); } } #endif @@ -1250,6 +1271,10 @@ static void dnslib_packet_dump_rrsets(const dnslib_rrset_t **rrsets, void dnslib_packet_dump(const dnslib_packet_t *packet) { + if (packet == NULL) { + return; + } + #ifdef DNSLIB_PACKET_DEBUG debug_dnslib_packet("DNS packet:\n-----------------------------\n"); diff --git a/src/dnslib/packet.h b/src/dnslib/packet.h index 3d91b1849ac4515b66490dc65f61646ae342db29..1f4f439e9658e90cfbc76a427118f1db18aaa581 100644 --- a/src/dnslib/packet.h +++ b/src/dnslib/packet.h @@ -430,7 +430,8 @@ void dnslib_packet_free_tmp_rrsets(dnslib_packet_t *pkt); * the size of the converted wire format. * * \param[in] header DNS header structure to convert. - * \param[out] pos Position where to put the converted header. + * \param[out] pos Position where to put the converted header. The space has + * to be allocated before calling this function. * \param[out] size Size of the wire format of the header in bytes. */ void dnslib_packet_header_to_wire(const dnslib_header_t *header, @@ -444,7 +445,7 @@ int dnslib_packet_question_to_wire(dnslib_packet_t *packet); * * \param resp Response structure. */ -void dnslib_packet_edns_to_wire(dnslib_packet_t *packet); +int dnslib_packet_edns_to_wire(dnslib_packet_t *packet); /*! * \brief Converts the packet to wire format. diff --git a/src/dnslib/response2.c b/src/dnslib/response2.c index cceafe1b699604c9b4cc187d02783c85010e7cdc..53448373b7c158a5484c912325d72784c8a7c979 100644 --- a/src/dnslib/response2.c +++ b/src/dnslib/response2.c @@ -186,7 +186,7 @@ DEBUG_DNSLIB_RESPONSE( size_t parent_pos = pos; int i = 0; - while (to_save != NULL) { + while (to_save != NULL && i < dnslib_dname_label_count(dname)) { if (i == not_matched) { parent_pos = unmatched_offset; } @@ -782,6 +782,10 @@ static int dnslib_response_realloc_rrsets(const dnslib_rrset_t ***rrsets, int dnslib_response2_init(dnslib_packet_t *response) { + if (response == NULL) { + return DNSLIB_EBADARG; + } + if (response->max_size < DNSLIB_WIRE_HEADER_SIZE) { return DNSLIB_ESPACE; } @@ -801,6 +805,10 @@ int dnslib_response2_init(dnslib_packet_t *response) int dnslib_response2_init_from_query(dnslib_packet_t *response, dnslib_packet_t *query) { + if (response == NULL || query == NULL) { + return DNSLIB_EBADARG; + } + // copy the header from the query memcpy(&response->header, &query->header, sizeof(dnslib_header_t)); @@ -842,6 +850,10 @@ int dnslib_response2_init_from_query(dnslib_packet_t *response, void dnslib_response2_clear(dnslib_packet_t *resp, int clear_question) { + if (resp == NULL) { + return; + } + resp->size = (clear_question) ? DNSLIB_WIRE_HEADER_SIZE : DNSLIB_WIRE_HEADER_SIZE + 4 + dnslib_dname_size(resp->question.qname); @@ -985,10 +997,13 @@ int dnslib_response2_add_rrset_additional(dnslib_packet_t *response, return DNSLIB_EBADARG; } + int ret; + // if this is the first additional RRSet, add EDNS OPT RR first if (response->header.arcount == 0 - && response->opt_rr.version != EDNS_NOT_SUPPORTED) { - dnslib_packet_edns_to_wire(response); + && response->opt_rr.version != EDNS_NOT_SUPPORTED + && (ret = dnslib_packet_edns_to_wire(response)) != DNSLIB_EOK) { + return ret; } if (response->ar_rrsets == response->max_ar_rrsets @@ -1023,6 +1038,10 @@ int dnslib_response2_add_rrset_additional(dnslib_packet_t *response, void dnslib_response2_set_rcode(dnslib_packet_t *response, short rcode) { + if (response == NULL) { + return; + } + dnslib_wire_flags_set_rcode(&response->header.flags2, rcode); dnslib_wire_set_rcode(response->wireformat, rcode); } @@ -1031,6 +1050,10 @@ void dnslib_response2_set_rcode(dnslib_packet_t *response, short rcode) void dnslib_response2_set_aa(dnslib_packet_t *response) { + if (response == NULL) { + return; + } + dnslib_wire_flags_set_aa(&response->header.flags1); dnslib_wire_set_aa(response->wireformat); } @@ -1039,6 +1062,10 @@ void dnslib_response2_set_aa(dnslib_packet_t *response) void dnslib_response2_set_tc(dnslib_packet_t *response) { + if (response == NULL) { + return; + } + dnslib_wire_flags_set_tc(&response->header.flags1); dnslib_wire_set_tc(response->wireformat); } @@ -1048,6 +1075,10 @@ void dnslib_response2_set_tc(dnslib_packet_t *response) int dnslib_response2_add_nsid(dnslib_packet_t *response, const uint8_t *data, uint16_t length) { + if (response == NULL) { + return DNSLIB_EBADARG; + } + return dnslib_edns_add_option(&response->opt_rr, EDNS_OPTION_NSID, length, data); } diff --git a/src/dnslib/tests/dnslib/dname_table_tests.c b/src/dnslib/tests/dnslib/dname_table_tests.c new file mode 100644 index 0000000000000000000000000000000000000000..3c263a851383549437b2f707755e9c936381b517 --- /dev/null +++ b/src/dnslib/tests/dnslib/dname_table_tests.c @@ -0,0 +1,378 @@ +/* blame: jan.kadlec@nic.cz */ + +#include <assert.h> + +#include "dname_table_tests.h" +#include "dnslib/error.h" +#include "dnslib/dname-table.h" +/* *test_t structures */ +#include "dnslib/tests/realdata/dnslib_tests_loader_realdata.h" + +static int dnslib_dname_table_tests_count(int argc, char *argv[]); +static int dnslib_dname_table_tests_run(int argc, char *argv[]); + +/*! Exported unit API. + */ +unit_api dname_table_tests_api = { + "Dname table", //! Unit name + &dnslib_dname_table_tests_count, //! Count scheduled tests + &dnslib_dname_table_tests_run //! Run scheduled tests +}; + +/* Helper functions. */ +static dnslib_dname_t *dname_from_test_dname_str(const test_dname_t *test_dname) +{ + assert(test_dname != NULL); + dnslib_dname_t *ret = dnslib_dname_new_from_str (test_dname->str, + strlen(test_dname->str), + NULL); + CHECK_ALLOC(ret, NULL); + + return ret; +} + +static int dname_compare_sort_wrapper(const void *ptr1, const void *ptr2) +{ + const dnslib_dname_t *dname1 = + dname_from_test_dname_str((const test_dname_t *)ptr1); + const dnslib_dname_t *dname2 = + dname_from_test_dname_str((const test_dname_t *)ptr2); + assert(dname1 && dname2); + return dnslib_dname_compare(dname1, dname2); +} + +/* Unit implementation. */ +enum {DNAME_TABLE_DNAME_COUNT = 3}; + +/* Strings are enough, we're not testing dname here ... */ +static test_dname_t DNAME_TABLE_DNAMES[DNAME_TABLE_DNAME_COUNT] = { + /* list ptr, string, wire, length, labels, label_count */ + {NULL, NULL, ".", NULL, 1, NULL, 0}, + {NULL, NULL, "a.ns.nic.cz.", NULL, 13, NULL, 0}, + {NULL, NULL, "b.ns.nic.cz.", NULL, 13, NULL, 0} +}; + +static int test_dname_table_new() +{ + dnslib_dname_table_t *table = dnslib_dname_table_new(); + if (table == NULL) { + return 0; + } + + dnslib_dname_table_free(&table); + return 1; +} + +struct test_dname_table_arg { + /* Times two - safety measure. */ + dnslib_dname_t *array[DNAME_TABLE_DNAME_COUNT * 2]; + uint count; +}; + +static void save_dname_to_array(struct dname_table_node *node, void *data) +{ + assert(data); + struct test_dname_table_arg *arg = (struct test_dname_table_arg *)data; + arg->array[arg->count] = node->dname; + arg->count++; +} + +static int test_dname_table_adding() +{ + int errors = 0; + dnslib_dname_table_t *table = dnslib_dname_table_new(); + CHECK_ALLOC(table, 0); + + /* Add NULL */ + if (dnslib_dname_table_add_dname(table, NULL) != DNSLIB_EBADARG) { + diag("Adding NULL dname did not result in an error!"); + errors++; + } + + /* Add to NULL table*/ + if (dnslib_dname_table_add_dname(NULL, NULL) != DNSLIB_EBADARG) { + diag("Adding to NULL table did not result in an error!"); + errors++; + } + + /* Add NULL */ + if (dnslib_dname_table_add_dname2(table, NULL) != DNSLIB_EBADARG) { + diag("Adding NULL dname did not result in an error!"); + errors++; + } + + /* Add to NULL table*/ + if (dnslib_dname_table_add_dname2(NULL, NULL) != DNSLIB_EBADARG) { + diag("Adding to NULL table did not result in an error!"); + errors++; + } + + + /* Add valid dnames. */ + for (int i = 0; i < DNAME_TABLE_DNAME_COUNT; i++) { + dnslib_dname_t *dname = + dname_from_test_dname_str(&DNAME_TABLE_DNAMES[i]); + if (!dname) { + diag("Could not create dname from test dname!"); + errors++; + continue; + } + if (dnslib_dname_table_add_dname(table, dname) != DNSLIB_EOK) { + diag("Could not add dname! (%s)", + DNAME_TABLE_DNAMES[i].str); + errors++; + } + } + + /* + * Using inorder traversal of the table, + * create array containing dnames. + */ + + struct test_dname_table_arg arg; + arg.count = 0; + + dnslib_dname_table_tree_inorder_apply(table, save_dname_to_array, &arg); + + if (arg.count != DNAME_TABLE_DNAME_COUNT) { + diag("Table contains too many dnames!"); + /* No sense in continuing. */ + dnslib_dname_table_deep_free(&table); + return 0; + } + + /* + * Check that inordered array is really sorted + * and contains valid dnames. + */ + for (int i = 0; i < DNAME_TABLE_DNAME_COUNT; i++) { + assert(arg.array[i]); + const char *str = dnslib_dname_to_str(arg.array[i]); + if (str == NULL) { + diag("Wrong dname in table!"); + errors++; + continue; + } + + if (arg.array[i]->size != + DNAME_TABLE_DNAMES[i].size) { + diag("Wrong dname size in table!"); + diag("Is: %u should be %u.", + arg.array[i]->size, + DNAME_TABLE_DNAMES[i].size); + errors++; + continue; + } + + if (strncmp(str, DNAME_TABLE_DNAMES[i].str, + DNAME_TABLE_DNAMES[i].size) != 0) { + diag("Wrong dname wire in table!"); + errors++; + } + } + + /* Now add one dname once again. It has to be the first item! */ + + if (dnslib_dname_table_add_dname(table, + dname_from_test_dname_str(&DNAME_TABLE_DNAMES[0])) != + DNSLIB_EOK) { + diag("Could not add dname to table once it's already there!"); + /* Next test would not make sense. */ + dnslib_dname_table_deep_free(&table); + return 0; + } + + /* + * After walking the table, there should now be + * DNAME_TABLE_DNAME_COUNT + 1 items, with 2 identical + * items at the beginning. + */ + + memset(arg.array, 0, + sizeof(dnslib_dname_t *) * DNAME_TABLE_DNAME_COUNT * 2); + arg.count = 0; + dnslib_dname_table_tree_inorder_apply(table, save_dname_to_array, &arg); + + if (arg.count != DNAME_TABLE_DNAME_COUNT + 1) { + diag("Identical dname was not added!"); + /* Again, next test would not make any sense. */ + dnslib_dname_table_deep_free(&table); + return 0; + } + + if (dnslib_dname_compare(arg.array[0], arg.array[1]) != 0) { + diag("First two dnames in table are not identical!"); + errors++; + } + + /* Delete table, wipe out array. */ + dnslib_dname_table_deep_free(&table); + memset(arg.array, 0, + sizeof(dnslib_dname_t *) * DNAME_TABLE_DNAME_COUNT * 2); + arg.count = 0; + + table = dnslib_dname_table_new(); + assert(table); + + /* + * Add dname with same content twice using dnslib_dname_table_add2 - + * table should now only contain one item. + */ + + dnslib_dname_t *tmp_dname = + dname_from_test_dname_str(&DNAME_TABLE_DNAMES[0]); + assert(tmp_dname); + + if (dnslib_dname_table_add_dname2(table, &tmp_dname) != DNSLIB_EOK) { + diag("Could not add dname using dname_table_add_dname2!"); + dnslib_dname_table_deep_free(&table); + dnslib_dname_free(&tmp_dname); + return 0; + } + + tmp_dname = dname_from_test_dname_str(&DNAME_TABLE_DNAMES[0]); + assert(tmp_dname); + + dnslib_dname_t *dname_before_add = tmp_dname; + + if (dnslib_dname_table_add_dname2(table, &tmp_dname) != 1) { + diag("Could not add dname again using dname_table_add_dname2!"); + dnslib_dname_table_deep_free(&table); + return 0; + } + + if (tmp_dname == dname_before_add) { + diag("Dname was not freed after insertion!"); + errors++; + } + + dnslib_dname_table_tree_inorder_apply(table, save_dname_to_array, &arg); + + if (arg.count != 1) { + diag("Add_dname2 has added dname when it shouldn't!"); + errors++; + } + + if (dnslib_dname_compare(tmp_dname, arg.array[0]) != 0) { + diag("Add_dname2 has added wrong dname!"); + errors++; + } + + dnslib_dname_table_deep_free(&table); + return (errors == 0); +} + +static int test_dname_table_find() +{ + int errors = 0; + dnslib_dname_table_t *table = dnslib_dname_table_new(); + assert(table); + + if (dnslib_dname_table_find_dname(table, NULL) != NULL) { + diag("Dname table did not return NULL when searching NULL!"); + errors++; + } + + if (dnslib_dname_table_find_dname(NULL, NULL) != NULL) { + diag("Passing NULL instead of dname table did not " + "return NULL!"); + errors++; + } + + /* Add all dnames but the last one. */ + for (int i = 0; i < DNAME_TABLE_DNAME_COUNT - 1; i++) { + dnslib_dname_t *dname = + dname_from_test_dname_str(&DNAME_TABLE_DNAMES[i]); + if (!dname) { + diag("Could not create dname from test dname!"); + errors++; + continue; + } + if (dnslib_dname_table_add_dname(table, dname) != DNSLIB_EOK) { + diag("Could not add dname! (%s)", + DNAME_TABLE_DNAMES[i].str); + errors++; + } + } + + /* Search for added dnames. */ + for (int i = 0; i < DNAME_TABLE_DNAME_COUNT - 1; i++) { + dnslib_dname_t *dname = + dname_from_test_dname_str(&DNAME_TABLE_DNAMES[i]); + if (!dname) { + diag("Could not create dname from test dname!"); + errors++; + continue; + } + + dnslib_dname_t *found_dname = + dnslib_dname_table_find_dname(table, dname); + + if (found_dname == NULL) { + diag("Dname table did not return " + "dname when it should!"); + errors++; + continue; + } + + if (dnslib_dname_compare(found_dname, dname) != 0) { + diag("Returned dname did not match!"); + errors++; + continue; + } + } + + /* Search for last dname, it should return NULL. */ + dnslib_dname_t *dname = + dname_from_test_dname_str( + &DNAME_TABLE_DNAMES[DNAME_TABLE_DNAME_COUNT]); + assert(dname); + + if (dnslib_dname_table_find_dname(table, dname) != NULL) { + diag("Dname table returned dname when it " + "should not be there!"); + errors++; + } + + dnslib_dname_free(&dname); + dnslib_dname_table_deep_free(&table); + + return (errors == 0); +} + +static const int DNSLIB_DNAME_TABLE_TEST_COUNT = 3; + +/*! This helper routine should report number of + * scheduled tests for given parameters. + */ +static int dnslib_dname_table_tests_count(int argc, char *argv[]) +{ + return DNSLIB_DNAME_TABLE_TEST_COUNT; +} + +/*! Run all scheduled tests for given parameters. + */ +static int dnslib_dname_table_tests_run(int argc, char *argv[]) +{ + int final_res = 1; + int res = 0; + + /* Sort array containing test dnames. */ + qsort(DNAME_TABLE_DNAMES, DNAME_TABLE_DNAME_COUNT, + sizeof(test_dname_t), dname_compare_sort_wrapper); + + ok((res = test_dname_table_new()), "dname table: new"); + final_res *= res; + + skip(!res, 2); + + ok((res = test_dname_table_adding()), "dname table: adding"); + final_res *= res; + + ok((res = test_dname_table_find()), "dname table: searching"); + final_res *= res; + + endskip; + + return final_res; +} diff --git a/src/dnslib/tests/dnslib/dname_table_tests.h b/src/dnslib/tests/dnslib/dname_table_tests.h new file mode 100644 index 0000000000000000000000000000000000000000..52ae3998c7c03db886b2ecc339ad10a28bf044d9 --- /dev/null +++ b/src/dnslib/tests/dnslib/dname_table_tests.h @@ -0,0 +1,9 @@ +#ifndef _KNOT_DNAME_TABLE_TESTS_H_ +#define _KNOT_DNAME_TABLE_TESTS_H_ + +#include "common/libtap/tap_unit.h" + +/* Unit API. */ +unit_api dname_table_tests_api; + +#endif /* _KNOT_DNAME_TABLE_TESTS_H_ */ diff --git a/src/dnslib/tests/dnslib/nsec3_tests.c b/src/dnslib/tests/dnslib/nsec3_tests.c new file mode 100644 index 0000000000000000000000000000000000000000..f76c1d1240a12c7599e53d33914f1ec0fb0c0fa2 --- /dev/null +++ b/src/dnslib/tests/dnslib/nsec3_tests.c @@ -0,0 +1,235 @@ +/* blame: jan.kadlec@nic.cz */ + +#include <assert.h> + +#include "dnslib/dnslib-common.h" +#include "dnslib/error.h" +#include "dnslib/nsec3.h" +#include "dnslib/utils.h" +#include "common/base32hex.h" +#include "nsec3_tests.h" + +#ifdef TEST_WITH_LDNS +#include "ldns/ldns.h" +#endif + +static int dnslib_nsec3_tests_count(int argc, char *argv[]); +static int dnslib_nsec3_tests_run(int argc, char *argv[]); + +/*! Exported unit API. + */ +unit_api nsec3_tests_api = { + "NSEC3", //! Unit name + &dnslib_nsec3_tests_count, //! Count scheduled tests + &dnslib_nsec3_tests_run //! Run scheduled tests +}; + +extern int compare_wires_simple(uint8_t *w1, uint8_t *w2, uint count); + +static dnslib_nsec3_params_t nsec3_test_params; + +static int test_nsec3_params_from_wire() +{ + /* Create sample NSEC3PARAM rdata */ + dnslib_rdata_item_t items[4]; + dnslib_rdata_t *rdata = dnslib_rdata_new(); + rdata->items = items; + rdata->count = 4; + dnslib_rdata_item_set_raw_data(rdata, 0, (uint16_t *)"\x1\x0\x1"); + dnslib_rdata_item_set_raw_data(rdata, 1, (uint16_t *)"\x1\x0\x0"); + dnslib_rdata_item_set_raw_data(rdata, 2, (uint16_t *)"\x2\x0\x0\x64"); + dnslib_rdata_item_set_raw_data(rdata, 3, + (uint16_t *)"\xF\x0\xE\xF\xF\xF\xF\xF\xF\xF\xF\xF\xF\xF\xF\xF"); + + dnslib_rrset_t *rrset = + dnslib_rrset_new(dnslib_dname_new_from_str("cz.", + strlen("cz."), NULL), + DNSLIB_RRTYPE_NSEC3PARAM, + DNSLIB_CLASS_IN, + 3600); + assert(rrset); + assert(dnslib_rrset_add_rdata(rrset, rdata) == DNSLIB_EOK); + + dnslib_nsec3_params_t nsec3_tests_params; + UNUSED(nsec3_tests_params); + + int errors = 0; + int lived = 0; + lives_ok({ + if (dnslib_nsec3_params_from_wire(NULL, NULL) != + DNSLIB_EBADARG) { + errors++; + } + lived = 1; + + lived = 0; + if (dnslib_nsec3_params_from_wire(&nsec3_test_params, NULL) != + DNSLIB_EBADARG) { + errors++; + } + lived = 1; + + lived = 0; + if (dnslib_nsec3_params_from_wire(NULL, rrset) != + DNSLIB_EBADARG) { + errors++; + } + lived = 1; + + }, "nsec3 params from wire NULL tests"); + errors += lived != 1; + + if (dnslib_nsec3_params_from_wire(&nsec3_test_params, +rrset) != DNSLIB_EOK) { + diag("Could not convert nsec3 params to wire!"); + return 0; + } + + if (nsec3_test_params.algorithm != 1) { + diag("Algorithm error"); + errors++; + } + + if (nsec3_test_params.flags != 2) { + diag("Flags error"); + errors++; + } + + if (nsec3_test_params.iterations != 15) { + diag("Iterations error"); + errors++; + } + + if (nsec3_test_params.salt_length != 8) { + diag("Salt length error"); + return 0; + } + + if (compare_wires_simple((uint8_t *)nsec3_test_params.salt, + (uint8_t *)"\xF\xF\xF\xF\xF\xF\xF\xF\xF\xF\xF\xF\xF\xF", + 15) != 0) { + diag("Salt wire error"); + errors++; + } + + dnslib_rrset_free(&rrset); + return (errors == 0); +} + +static int test_nsec3_sha1() +{ + int errors = 0; + int lived = 0; + + lives_ok({ + if (dnslib_nsec3_sha1(NULL, NULL, 1, NULL, NULL) != + DNSLIB_EBADARG) { + errors++; + } + lived = 1; + lived = 0; + if (dnslib_nsec3_sha1(&nsec3_test_params, + NULL, 1, NULL, NULL) != + DNSLIB_EBADARG) { + errors++; + } + uint8_t data[20]; + lived = 1; + lived = 0; + if (dnslib_nsec3_sha1(&nsec3_test_params, + data, 20, NULL, NULL) != + DNSLIB_EBADARG) { + errors++; + } + uint8_t *digest = NULL; + lived = 1; + lived = 0; + if (dnslib_nsec3_sha1(&nsec3_test_params, + data, 20, &digest, NULL) != + DNSLIB_EBADARG) { + errors++; + } + size_t size = 0; + lived = 1; + lived = 0; + if (dnslib_nsec3_sha1(&nsec3_test_params, + data, 20, &digest, &size) != + DNSLIB_EBADARG) { + errors++; + } + lived = 1; + }, "NSEC3: nsec3 sha1 NULL tests"); + if (errors) { + diag("Does not return DNSLIB_EBADARG after " + "execution with wrong arguments!"); + } + + errors += lived != 1; + + uint8_t *digest = NULL; + size_t digest_size = 0; + if (dnslib_nsec3_sha1(&nsec3_test_params, + (uint8_t *)"\2ns\3nic\2cz", + strlen("\2ns\3nic\2cz"), &digest, + &digest_size) != DNSLIB_EOK) { + diag("Could not hash name!"); + return 0; + } + +#ifdef TEST_WITH_LDNS + ldns_rdf *name = ldns_dname_new_frm_str("ns.nic.cz."); + assert(name); + ldns_rdf *hashed_name = ldns_nsec3_hash_name(name, + nsec3_test_params.algorithm, + nsec3_test_params.iterations, + nsec3_test_params.salt_length, + nsec3_test_params.salt); + assert(hashed_name); +// dnslib_dname_t *dname_from_ldns = +// dnslib_dname_new_from_wire(ldns_rdf_data(hashed_name), +// ldns_rdf_size(hashed_name), +// NULL); + + char *name_b32 = NULL; + size_t size_b32 = base32hex_encode_alloc((char *)digest, digest_size, + &name_b32); + +// hex_print(name_b32, size_b32); +// hex_print(ldns_rdf_data(hashed_name), ldns_rdf_size(hashed_name)); + if (ldns_rdf_size(hashed_name) != size_b32) { + diag("Wrong hashed name length! Should be: %d is: %d", + ldns_rdf_size(hashed_name), size_b32); + return 0; + } + + if (compare_wires_simple(ldns_rdf_data(hashed_name), + (uint8_t *)name_b32, size_b32) != 0) { + diag("Wrong hashed name wire!"); + errors++; + } +#endif + +#ifndef TEST_WITH_LDNS + diag("Warning: without ldns this test is only partial!"); +#endif + return (errors == 0); +} + +static const int DNSLIB_NSEC3_TESTS_COUNT = 2; + +/*! This helper routine should report number of + * scheduled tests for given parameters. + */ +static int dnslib_nsec3_tests_count(int argc, char *argv[]) +{ + return DNSLIB_NSEC3_TESTS_COUNT; +} + +/*! Run all scheduled tests for given parameters. + */ +static int dnslib_nsec3_tests_run(int argc, char *argv[]) +{ + ok(test_nsec3_params_from_wire(), "nsec3: params from wire"); + ok(test_nsec3_sha1(), "nsec3: sha1"); + return 1; +} diff --git a/src/dnslib/tests/dnslib/nsec3_tests.h b/src/dnslib/tests/dnslib/nsec3_tests.h new file mode 100644 index 0000000000000000000000000000000000000000..90d377d71fbda9a81550a2eb554411681663b704 --- /dev/null +++ b/src/dnslib/tests/dnslib/nsec3_tests.h @@ -0,0 +1,9 @@ +#ifndef _KNOT_NSEC3_TESTS_H_ +#define _KNOT_NSEC3_TESTS_H_ + +#include "common/libtap/tap_unit.h" + +/* Unit API. */ +unit_api nsec3_tests_api; + +#endif /* _KNOT_NSEC3_TESTS_H_ */ diff --git a/src/dnslib/tests/dnslib/packet_tests.c b/src/dnslib/tests/dnslib/packet_tests.c new file mode 100644 index 0000000000000000000000000000000000000000..6b7643b507cd5353f7338d5461e6901399c69aee --- /dev/null +++ b/src/dnslib/tests/dnslib/packet_tests.c @@ -0,0 +1,408 @@ +/* blame: jan.kadlec@nic.cz */ + +#include <assert.h> +#include <stdint.h> + +#include "packet_tests.h" +#include "dnslib/error.h" +#include "dnslib/packet.h" +#include "dnslib/wire.h" +/* *test_t structures */ +#include "dnslib/tests/realdata/dnslib_tests_loader_realdata.h" + +static int packet_tests_count(int argc, char *argv[]); +static int packet_tests_run(int argc, char *argv[]); + +/*! Exported unit API. + */ +unit_api packet_tests_api = { + "packet", //! Unit name + &packet_tests_count, //! Count scheduled tests + &packet_tests_run //! Run scheduled tests +}; + +static int test_packet_new() +{ + int errors = 0; + dnslib_packet_t *packet = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_NONE); + if (packet == NULL) { + diag("Could not create packet using prealloc_node constant!"); + errors++; + } + dnslib_packet_free(&packet); + + packet = dnslib_packet_new(DNSLIB_PACKET_PREALLOC_QUERY); + if (packet == NULL) { + diag("Could not create packet using prealloc_query constant!"); + errors++; + } + dnslib_packet_free(&packet); + + packet = dnslib_packet_new(DNSLIB_PACKET_PREALLOC_RESPONSE); + if (packet == NULL) { + diag("Could not create packet using prealloc_resp constant!"); + errors++; + } + dnslib_packet_free(&packet); + + /*!< \todo Should it create packet using any size? */ + + return (errors == 0); +} + +static int test_packet_parse_from_wire() +{ + int errors = 0; + dnslib_packet_t *packet = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_QUERY); + + int tmp = 0; + lives_ok({ + if (dnslib_packet_parse_from_wire(NULL, NULL, 0, 0) != + DNSLIB_EBADARG) { + diag("Trying to parse NULL packet with NULL wire " + "did not return DNSLIB_EBADARG!"); + errors++; + } + tmp = 1; + tmp = 0; + if (dnslib_packet_parse_from_wire(packet, NULL, 0, 0) != + DNSLIB_EBADARG) { + diag("Trying to parse with NULL wire " + "did not return DNSLIB_EBADARG!"); + errors++; + } + tmp = 1; + tmp = 0; + if (dnslib_packet_parse_from_wire(packet, (uint8_t *)0xbeef, + 0, 0) != + DNSLIB_EFEWDATA) { + diag("Trying to parse 0 lengt" + "did not return DNSLIB_EOK!"); + errors++; + } + tmp = 1; + }, "packet: parse from wire NULL tests."); + errors += tmp != 1; + + dnslib_packet_free(&packet); + + return (errors == 0); +} + +static int test_packet_parse_next_rr_answer() +{ + int errors = 0; + dnslib_packet_t *packet = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_RESPONSE); + assert(packet); + + int tmp = 0; + lives_ok({ + int ret = 0; + if (dnslib_packet_parse_next_rr_answer(NULL, NULL) != + DNSLIB_EBADARG) { + diag("Trying to parse next RR answer with " + "NULL packet with and NULL RRSet " + "did not return DNSLIB_EBADARG!"); + errors++; + } + tmp = 1; + tmp = 0; + if ((ret = dnslib_packet_parse_next_rr_answer(packet, + NULL)) != + DNSLIB_EBADARG) { + diag("Trying to parse next RR with NULL RRSet pointer " + "did not return DNSLIB_EBADARG! Got %d.", + ret); + errors++; + } + tmp = 1; + dnslib_rrset_t *rrset = (dnslib_rrset_t *)0xaaaa; + tmp = 0; + if (dnslib_packet_parse_next_rr_answer(packet, + &rrset) != + DNSLIB_EBADARG) { + diag("Trying to parse next RR answer with rrset pointer" + " not pointing to NULL did not " + "return DNSLIB_EBADARG!"); + errors++; + } + tmp = 1; + }, "packet: parse next rr answer NULL tests."); + errors += tmp != 1; + + dnslib_packet_free(&packet); + + return (errors == 0); +} + +static int test_packet_parse_rest() +{ + int res = 0; + lives_ok({res *= dnslib_packet_parse_rest(NULL);}, + "packet: parse rest NULL test"); + + dnslib_packet_t *packet = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_NONE); + assert(packet); + + lives_ok({res *= dnslib_packet_parse_rest(packet);}, + "packet: parser rest empty packet"); + + dnslib_packet_free(&packet); + + return res; +} + + +static int test_packet_set_max_size() +{ + int errors = 0; + dnslib_packet_t *packet = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_NONE); + assert(packet); + + int lived = 0; + + lives_ok({ + lived = 0; + if (dnslib_packet_set_max_size(NULL, 1) != DNSLIB_EBADARG) { + diag("Calling packet_set_max() with NULL packet " + "did not return DNSLIB_EBADARG"); + errors++; + } + lived = 1; + }, "packet: set max size NULL test"); + + errors += lived != 1; + + if (dnslib_packet_set_max_size(packet, 0) != DNSLIB_EBADARG) { + diag("Calling packet_set_max() with size eqeal to 0 did not " + "return DNSLIB_EBADARG"); + errors++; + } + + if (dnslib_packet_set_max_size(packet, 10) != DNSLIB_EOK) { + diag("Calling packet_set_max() with valid arguments did not " + "return DNSLIB_EOK"); + errors++; + } + + dnslib_packet_free(&packet); + + return (errors == 0); +} + +static int test_packet_add_tmp_rrset() +{ + int errors = 0; + int lived = 0; + + /* dnslib_packet_add_tmp_rrset only works with pointers. */ + dnslib_rrset_t *rrset = (dnslib_rrset_t *)0xabcdef; + + dnslib_packet_t *packet = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_RESPONSE); + assert(packet); + + lives_ok({ + if (dnslib_packet_add_tmp_rrset(NULL, rrset) != + DNSLIB_EBADARG) { + diag("Trying to add to NULL packet did not return " + "DNSLIB_EBADARG!"); + errors++; + } + lived = 1; + + lived = 0; + if (dnslib_packet_add_tmp_rrset(packet, NULL) != + DNSLIB_EBADARG) { + diag("Trying to add NULL rrset did not return " + "DNSLIB_EBADARG!"); + errors++; + } + lived = 1; + + lived = 0; + if (dnslib_packet_add_tmp_rrset(NULL, NULL) != + DNSLIB_EBADARG) { + diag("Trying to add NULL rrset to NULL packet " + "did not return DNSLIB_EBADARG!"); + errors++; + } + lived = 1; + }, "packet: add tmp rrset NULL test"); + errors += lived != 1; + + if (dnslib_packet_add_tmp_rrset(packet, rrset) != DNSLIB_EOK) { + diag("Could not add valid RRSet to packet!"); + errors++; + } + + /* Not freeing because RRSet is fake. */ +// dnslib_packet_free(&packet); + + free(packet->wireformat); + free(packet); + + return (errors == 0); +} + +//static int test_packet_contains() +//{ +// int errors = 0; +// int lives = 0; + +// dnslib_packet_t *packet = +// dnslib_packet_new(DNSLIB_PACKET_PREALLOC_RESPONSE); +// assert(packet); + +// lives_ok({ +// if (dnslib_packet_contains(packet, NULL, +// DNSLIB_RRSET_COMPARE_PTR) != +// DNSLIB_EBADARG{ +// diag(); +// } +// }, "packet: contains NULL tests); + +// dnslib_packet_contains() + +//} + +static int test_packet_header_to_wire() +{ + int errors = 0; + int lived = 0; + dnslib_packet_t *packet = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_RESPONSE); + assert(packet); + size_t size; + + lives_ok({ + dnslib_packet_header_to_wire(NULL, NULL, NULL); + lived = 1; + lived = 0; + dnslib_packet_header_to_wire(&packet->header, NULL, &size); + lived = 1; + }, "packet: header to wire NULL tests"); + errors += lived != 1; + + dnslib_packet_free(&packet); + return (errors == 0); +} + +static int test_packet_question_to_wire() +{ + int errors = 0 ; + int lived = 0; + dnslib_packet_t *packet = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_RESPONSE); + assert(packet); + + lives_ok({ + if (dnslib_packet_question_to_wire(NULL) != DNSLIB_EBADARG) { + diag("Calling packet_question_to_wire with " + "NULL pointer did not result to DNSLIB_EBADARG!"); + errors++; + } + lived = 1; + }, "packet: question to wire NULL tests"); + errors += lived != 1; + + packet->size = DNSLIB_WIRE_HEADER_SIZE + 1; + if (dnslib_packet_question_to_wire(packet) != DNSLIB_ERROR) { + diag("Calling packet_question_to_wire with oversized packet " + "did not return DNSLIB_ERROR!"); + errors++; + } + + dnslib_packet_free(&packet); + return (errors == 0); +} + +static int test_packet_edns_to_wire() +{ + int errors = 0 ; + int lived = 0; + dnslib_packet_t *packet = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_RESPONSE); + assert(packet); + + lives_ok({ + dnslib_packet_edns_to_wire(NULL); + lived = 1; + }, "packet: question to wire NULL tests"); + errors += lived != 1; + + dnslib_packet_free(&packet); + return (errors == 0); +} + +static int test_packet_to_wire() +{ + int errors = 0 ; + int lived = 0; + dnslib_packet_t *packet = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_RESPONSE); + assert(packet); + + lives_ok({ + if (dnslib_packet_to_wire(NULL, NULL, NULL) != DNSLIB_EBADARG) { + diag("Calling packet_to_wire with " + "NULL pointers did not return DNSLIB_EBADARG!"); + errors++; + } + lived = 1; + size_t size; + lived = 0; + if (dnslib_packet_to_wire(packet, NULL, &size) != + DNSLIB_EBADARG) { + diag("Calling packet_to_wire with " + "NULL wire did not return DNSLIB_EBADARG!"); + errors++; + } + lived = 1; + uint8_t *wire = (uint8_t *)0xabcdef; + lived = 0; + if (dnslib_packet_to_wire(packet, &wire, &size) != + DNSLIB_EBADARG) { + diag("Calling packet_to_wire with " + "wire not pointing to NULL did not return" + " DNSLIB_EBADARG!"); + errors++; + } + lived = 1; + }, "packet: to wire NULL tests"); + errors += lived != 1; + + dnslib_packet_free(&packet); + return (errors == 0); +} + +static const uint DNSLIB_PACKET_TEST_COUNT = 21; + +static int packet_tests_count(int argc, char *argv[]) +{ + return DNSLIB_PACKET_TEST_COUNT; +} + +static int packet_tests_run(int argc, char *argv[]) +{ + int res = 0; + ok(res = test_packet_new(), "packet: new"); + skip(!res, 20); + ok(test_packet_parse_rest(), "packet: parse rest"); + ok(test_packet_parse_from_wire(), "packet: parse from wire"); + ok(test_packet_parse_next_rr_answer(), "packet: parse next rr answer"); + ok(test_packet_set_max_size(), "packet: set max size"); + ok(test_packet_add_tmp_rrset(), "packet: add tmp rrset"); + ok(test_packet_header_to_wire(), "packet: header to wire"); + ok(test_packet_question_to_wire(), "packet: header to wire"); + ok(test_packet_edns_to_wire(), "packet: header to wire"); + ok(test_packet_to_wire(), "packet: to wire"); +// ok(res = test_packet_contains(), "Packet: contains"); + endskip; + return 1; +} diff --git a/src/dnslib/tests/dnslib/packet_tests.h b/src/dnslib/tests/dnslib/packet_tests.h new file mode 100644 index 0000000000000000000000000000000000000000..6189dc038f79f37b32aacb7b08403c29d0bc4477 --- /dev/null +++ b/src/dnslib/tests/dnslib/packet_tests.h @@ -0,0 +1,9 @@ +#ifndef _KNOT_PACKET_TESTS_H_ +#define _KNOT_PACKET_TESTS_H_ + +#include "common/libtap/tap_unit.h" + +/* Unit API. */ +unit_api packet_tests_api; + +#endif /* _KNOT_PACKET_TESTS_H_ */ diff --git a/src/dnslib/tests/dnslib/query_tests.c b/src/dnslib/tests/dnslib/query_tests.c new file mode 100644 index 0000000000000000000000000000000000000000..1d433a8a020c40074dc1a527af66eb34d5e5d442 --- /dev/null +++ b/src/dnslib/tests/dnslib/query_tests.c @@ -0,0 +1,145 @@ +/* blame: jan.kadlec@nic.cz */ + +#include <assert.h> +#include <stdint.h> + +#include "packet_tests.h" +#include "dnslib/error.h" +#include "dnslib/packet.h" +#include "dnslib/wire.h" +#include "dnslib/query.h" +/* *test_t structures */ +#include "dnslib/tests/realdata/dnslib_tests_loader_realdata.h" + +static int query_tests_count(int argc, char *argv[]); +static int query_tests_run(int argc, char *argv[]); + +/*! Exported unit API. + */ +unit_api query_tests_api = { + "query", //! Unit name + &query_tests_count, //! Count scheduled tests + &query_tests_run //! Run scheduled tests +}; + +static const uint DNSLIB_QUERY_TEST_COUNT = 1; + +static int query_tests_count(int argc, char *argv[]) +{ + return DNSLIB_QUERY_TEST_COUNT; +} + +static int test_query_init() +{ + int errors = 0; + int lived = 0; + dnslib_packet_t *query = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_QUERY); + assert(query); + lives_ok({ + if (dnslib_query_init(NULL) != DNSLIB_EBADARG) { + diag("Calling query_init with NULL query did " + "not return DNSLIB_EBADARG!"); + errors++; + } + lived = 1; + }, "query: init NULL tests"); + errors += lived != 1; + + assert(dnslib_packet_set_max_size(query, 1024 * 10) == DNSLIB_EOK); + if (dnslib_query_init(query) != DNSLIB_EOK) { + diag("Calling query_init with valid query did not return " + "DNSLIB_EOK!"); + errors++; + } + + if (!dnslib_packet_is_query(query)) { + diag("QR flag was not set!"); + errors++; + } + + return (errors == 0); +} + +static int test_query_set_question() +{ + int errors = 0; + int lived = 0; + + dnslib_packet_t *query = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_QUERY); + assert(query); + assert(dnslib_packet_set_max_size(query, 1024 * 10) == DNSLIB_EOK); + dnslib_query_init(query); + + dnslib_rrset_t *rrset = + dnslib_rrset_new(dnslib_dname_new_from_str("a.ns.cz.", + strlen("a.ns.cz."), + NULL), + DNSLIB_RRTYPE_A, DNSLIB_CLASS_IN, 3600); + assert(rrset); + + dnslib_question_t *question = malloc(sizeof(dnslib_question_t)); + assert(question); + question->qname = rrset->owner; + question->qtype = rrset->type; + question->qclass = rrset->rclass; + + lives_ok({ + if (dnslib_query_set_question(NULL, NULL) != DNSLIB_EBADARG) { + diag("Calling query_set_question with NULL"); + errors++; + } + lived = 1; + lived = 0; + if (dnslib_query_set_question(query, NULL) != DNSLIB_EBADARG) { + diag("Calling query_set_question with NULL"); + errors++; + } + lived = 1; + lived = 0; + if (dnslib_query_set_question(NULL, question) != DNSLIB_EBADARG) { + diag("Calling query_set_question with NULL"); + errors++; + } + lived = 1; + }, "query: set question NULL tests"); + errors += lived != 1; + + if (dnslib_query_set_question(query, question) != DNSLIB_EOK) { + diag("Calling query_set_question with valid arguments "); + errors++; + } + + if (query->question.qname != rrset->owner) { + diag("Qname was not set right!"); + errors++; + } + + if (query->question.qtype != rrset->type) { + diag("Qtype was not set right!"); + errors++; + } + + if (query->question.qclass != rrset->rclass) { + diag("Qclass was not set right!"); + errors++; + } + + if (query->header.qdcount != 1) { + diag("Qdcount was not set right!"); + errors++; + } + + dnslib_packet_free(&query); + dnslib_rrset_deep_free(&rrset, 1, 0, 0); + + return (errors == 0); +} + +static int query_tests_run(int argc, char *argv[]) +{ + ok(test_query_init(), "query: init"); + ok(test_query_set_question(), "query: set question"); + return 1; +} diff --git a/src/dnslib/tests/dnslib/query_tests.h b/src/dnslib/tests/dnslib/query_tests.h new file mode 100644 index 0000000000000000000000000000000000000000..590259659ec018e13dabf1eb89c60a2da323ee09 --- /dev/null +++ b/src/dnslib/tests/dnslib/query_tests.h @@ -0,0 +1,9 @@ +#ifndef _KNOT_QUERY_TESTS_H_ +#define _KNOT_QUERY_TESTS_H_ + +#include "common/libtap/tap_unit.h" + +/* Unit API. */ +unit_api query_tests_api; + +#endif /* _KNOT_QUERY_TESTS_H_ */ diff --git a/src/dnslib/tests/dnslib/response2_tests.c b/src/dnslib/tests/dnslib/response2_tests.c new file mode 100644 index 0000000000000000000000000000000000000000..1a2e8b3a43c12e71406614d38a43c3c77bac223f --- /dev/null +++ b/src/dnslib/tests/dnslib/response2_tests.c @@ -0,0 +1,433 @@ +#include <assert.h> +#include <inttypes.h> + +//#define RESP_TEST_DEBUG +#include "dnslib/tests/realdata/dnslib_tests_loader_realdata.h" +#include "dnslib/tests/dnslib/response2_tests.h" +#include "common/lists.h" +#include "dnslib/dnslib-common.h" +#include "dnslib/error.h" +#include "dnslib/response2.h" +#include "dnslib/rdata.h" +#include "dnslib/rrset.h" +#include "dnslib/dname.h" +#include "dnslib/wire.h" +#include "dnslib/descriptor.h" +#include "dnslib/edns.h" + +#ifdef TEST_WITH_LDNS +#include "ldns/ldns.h" +#endif + +static int dnslib_response2_tests_count(int argc, char *argv[]); +static int dnslib_response2_tests_run(int argc, char *argv[]); + +/*! Exported unit API. + */ +unit_api response2_tests_api = { + "DNS library - response", //! Unit name + &dnslib_response2_tests_count, //! Count scheduled tests + &dnslib_response2_tests_run //! Run scheduled tests +}; + +static int test_response_init() +{ + int errors = 0; + int lived = 0; + lives_ok({ + if (dnslib_response2_init(NULL) != DNSLIB_EBADARG) { + diag("Calling response_init with NULL packet did " + "not return DNSLIB_EBADARG!"); + errors++; + } + lived = 1; + }, "response2: init NULL tests"); + errors += lived != 1; + + dnslib_packet_t *response = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_QUERY); + response->max_size = DNSLIB_WIRE_HEADER_SIZE - 1; + if (dnslib_response2_init(response) != DNSLIB_ESPACE) { + diag("Calling response_init too small packet did " + "not return DNSLIB_ESPACE!"); + errors++; + } + + return (errors == 0); +} + +static int test_response_init_query() +{ + int errors = 0; + int lived = 0; + lives_ok({ + if (dnslib_response2_init_from_query(NULL, NULL) != + DNSLIB_EBADARG) { + diag("Calling response_init_query with NULL packet and " + "NULL query did not return DNSLIB_EBADARG!"); + errors++; + } + lived = 1; + dnslib_packet_t *response = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_RESPONSE); + assert(response); + dnslib_packet_set_max_size(response, + DNSLIB_PACKET_PREALLOC_RESPONSE); + dnslib_response2_init(response); + lived = 0; + if (dnslib_response2_init_from_query(response, NULL) != + DNSLIB_EBADARG) { + diag("Calling response_init_query with NULL query " + "did not return DNSLIB_EBADARG!"); + errors++; + } + lived = 1; + dnslib_packet_t *query = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_QUERY); + if (dnslib_response2_init_from_query(NULL, query) != + DNSLIB_EBADARG) { + diag("Calling response_init_query with NULL response " + "did not return DNSLIB_EBADARG!"); + errors++; + } + }, "response2: init from query NULL tests"); + errors += lived != 1; + + /* Cannot test the rest of return values, since there is now constant + * controlling value that could return DNSLIB_EDNAMEPTR */ + + return (errors == 0); +} + +int compare_wires_simple(uint8_t *wire1, uint8_t *wire2, uint count) +{ + int i = 0; + while (i < count && + wire1[i] == wire2[i]) { + i++; + } + return (!(count == i)); +} + + +//static int test_response_clear() +//{ +// int errors = 0; +// int lived = 0; +// lives_ok({ +// dnslib_response2_clear(NULL, 1); +// lived = 1; +// }, "response2: clear NULL tests"); +// errors += lived != 1; + +// /* +// * Create new response, convert to wire, then add something, clear +// * the response, convert to wire again and compare wires. +// */ + +// dnslib_packet_t *response = +// dnslib_packet_new(DNSLIB_PACKET_PREALLOC_RESPONSE); +// dnslib_packet_set_max_size(response, DNSLIB_WIRE_HEADER_SIZE * 100); +// assert(dnslib_response2_init(response) == DNSLIB_EOK); + +// uint8_t *original_wire = NULL; +// size_t original_size = 0; +// assert(dnslib_packet_to_wire(response, &original_wire, +// &original_size) == +// DNSLIB_EOK); +// /* Do something in question section. */ +//// test_dname_t test_dname; +//// test_dname.str = "ns8.nic.cz."; +//// dnslib_dname_t *dname = dname_from_test_dname_str(&test_dname); +//// assert(dname); + +// response->question.qtype = DNSLIB_RRTYPE_HINFO; +// response->question.qclass = DNSLIB_CLASS_CH; + +// uint8_t *question_changed_wire = NULL; +// size_t question_changed_size = 0; +// assert(dnslib_packet_to_wire(response, +// &question_changed_wire, +// &question_changed_size) == +// DNSLIB_EOK); + +// dnslib_response2_set_aa(response); +// dnslib_response2_set_tc(response); +// dnslib_response2_set_rcode(response, dnslib_quick_rand()); + +// dnslib_response2_clear(response, 0); +// uint8_t *new_wire = NULL; +// size_t new_size = 0; +// assert(dnslib_packet_to_wire(response, &new_wire, &new_size) == +// DNSLIB_EOK); +// if (question_changed_size != new_size) { +// diag("Wrong wire size after calling response_clear! " +// "got %d should be %d", new_size, question_changed_size); +// errors++; +// } else { +// if (compare_wires_simple(question_changed_wire, +// new_wire, new_size)) { +// diag("Wrong wire after calling response_clear! "); +// errors++; +// } +// } +// free(new_wire); + +// new_wire = NULL; +// new_size = 0; + +// /*!< \todo figure out this segfault! */ + +//// dnslib_response2_clear(response, 1); +//// assert(dnslib_packet_to_wire(response, &new_wire, &new_size) == +//// DNSLIB_EOK); + +//// if (original_size != new_size) { +//// diag("Wrong wire size after calling response_clear!"); +//// errors++; +//// } else { +//// if (compare_wires_simple(original_wire, +//// new_wire, new_size)) { +//// diag("Wrong wire after calling response_clear!"); +//// errors++; +//// } +//// } + +//// free(new_wire); +//// free(original_wire); +//// free(question_changed_wire); +//// dnslib_packet_free(&response); + +// return (errors == 0); +//} + +static int test_response_add_opt() +{ + int errors = 0; + int lived = 0; + + dnslib_opt_rr_t opt; + opt.payload = 512; + opt.ext_rcode = 0; + opt.version = EDNS_VERSION_0; + opt.flags = 0; + opt.options = NULL; + opt.option_count = 0; + opt.options_max = 0; + opt.size = 25; // does it matter? + + lives_ok({ + if (dnslib_response2_add_opt(NULL, NULL, 0) != DNSLIB_EBADARG) { + diag("Calling response add opt with NULL arguments " + "did not result to DNSLIB_EBADARG"); + errors++; + } + lived = 1; + dnslib_packet_t *response = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_RESPONSE); + assert(response); + lived = 0; + if (dnslib_response2_add_opt(response, + NULL, 0) != DNSLIB_EBADARG) { + diag("Calling response add opt with NULL OPT RR " + "did not result to DNSLIB_EBADARG"); + errors++; + } + lived = 1; + + lived = 0; + if (dnslib_response2_add_opt(NULL, + &opt, 0) != DNSLIB_EBADARG) { + diag("Calling response add opt with NULL response " + "did not result to DNSLIB_EBADARG"); + errors++; + } + lived = 1; + dnslib_packet_free(&response); + }, "response2: add opt NULL tests"); + errors += lived != 1; + + dnslib_packet_t *response = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_RESPONSE); + assert(response); + dnslib_packet_set_max_size(response, DNSLIB_PACKET_PREALLOC_RESPONSE * 100); + assert(dnslib_response2_init(response) == DNSLIB_EOK);; + + if (dnslib_response2_add_opt(response, &opt, 0) != DNSLIB_EOK) { + diag("Adding valid OPT RR to response " + "did not return DNSLIB_EOK"); + errors++; + } + + opt.payload = response->max_size + 1; + if (dnslib_response2_add_opt(response, &opt, 1) != DNSLIB_EPAYLOAD) { + diag("If OPT RR payload is bigger than response max size " + "response_add_opt does not return DNSLIB_EPAYLOAD!"); + errors++; + } + + opt.payload = 0; + if (dnslib_response2_add_opt(response, &opt, 1) != DNSLIB_EBADARG) { + diag("Calling response_add_opt with OPT RR payload set to 0 " + "did not return DNSLIB_EBADARG"); + } + + dnslib_packet_free(&response); + return (errors == 0); +} + +static int test_response_add_generic(int (*func)(dnslib_packet_t *, + const dnslib_rrset_t *, + int, int, int)) +{ + int errors = 0; + int lived = 0; + + lives_ok({ + if (func(NULL, NULL, 0, 0, 0) != DNSLIB_EBADARG) { + diag("Calling response add rrset with NULL " + "arguments did not return DNSLIB_EBADARG!"); + errors++; + } + lived = 1; + dnslib_packet_t *response = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_RESPONSE); + assert(response); + lived = 0; + if (func(response, NULL, 0, 0, 0) != DNSLIB_EBADARG) { + diag("Calling response add rrset with NULL rrset " + "did not return DNSLIB_EBADARG!"); + errors++; + } + lived = 1; + dnslib_dname_t *owner = + dnslib_dname_new_from_str("ns.nic.cz.", + strlen("ns.nic.cz."), + NULL); + assert(owner); + dnslib_rrset_t *rrset = + dnslib_rrset_new(owner, DNSLIB_RRTYPE_A, + DNSLIB_CLASS_IN, 3600); + assert(rrset); + lived = 0; + if (func(NULL, rrset, 0, 0, 0) != DNSLIB_EBADARG) { + diag("Calling response add rrset with NULL response " + "did not return DNSLIB_EBADARG!"); + errors++; + } + lived = 1; + dnslib_rrset_deep_free(&rrset, 1, 0, 0); + dnslib_packet_free(&response); + }, "response2: rrset adding NULL tests"); + errors += lived != 1; + + /*!< \todo Test case when DNSLIB_ESPACE should be returned. */ + /*!< \todo Compression and so on - should it be tested here? */ + + dnslib_packet_t *response = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_RESPONSE); + assert(response); + + dnslib_dname_t *owner = + dnslib_dname_new_from_str("ns12.nic.cz.", + strlen("ns12.nic.cz."), + NULL); + assert(owner); + dnslib_rrset_t *rrset = + dnslib_rrset_new(owner, DNSLIB_RRTYPE_NS, + DNSLIB_CLASS_IN, 3600); + assert(rrset); + if (func(response, rrset, 0, 0, 0) != DNSLIB_EOK) { + diag("Adding valid RRSet to response did not result to " + "DNSLIB_EOK"); + errors++; + } + + dnslib_rrset_deep_free(&rrset, 1, 0, 0); + dnslib_packet_free(&response); + + return (errors == 0); +} + +static void test_response_add_rrset() +{ + ok(test_response_add_generic(dnslib_response2_add_rrset_answer), + "response: add answer rrset"); + ok(test_response_add_generic(dnslib_response2_add_rrset_authority), + "response: add answer authority"); + ok(test_response_add_generic(dnslib_response2_add_rrset_additional), + "response: add answer additional"); +} + +static int test_response_add_nsid() +{ + int errors = 0; + int lived = 0; + + dnslib_packet_t *response = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_RESPONSE); + assert(response); + + uint8_t *nsid = (uint8_t *)"knotDNS"; + uint16_t nsid_size = strlen((char *)nsid); + lives_ok({ + if (dnslib_response2_add_nsid(NULL, + NULL, 1) != DNSLIB_EBADARG) { + diag("Calling response add nsid with NULL arguments " + "did not return DNSLIB_EBADARG"); + errors++; + } + lived = 1; + + lived = 0; + if (dnslib_response2_add_nsid(NULL, nsid, + nsid_size) != DNSLIB_EBADARG) { + diag("Calling response add nsid with NULL response " + "did not return DNSLIB_EBADARG"); + errors++; + } + lived = 1; + lived = 0; + if (dnslib_response2_add_nsid(response, nsid, + 0) != DNSLIB_EBADARG) { + diag("Calling response add nsid with zero size " + "did not return DNSLIB_EBADARG"); + errors++; + } + lived = 1; + }, "response: add nsid NULL tests"); + errors += lived != 1; + + if (dnslib_response2_add_nsid(response, nsid, + nsid_size) != DNSLIB_EOK) { + diag("Adding valid nsid to response did not return DNSLIB_EOK"); + errors++; + } + + dnslib_packet_free(&response); + return (errors == 0); +} + +static const int DNSLIB_RESPONSE2_TEST_COUNT = 14; + +/*! This helper routine should report number of + * scheduled tests for given parameters. + */ +static int dnslib_response2_tests_count(int argc, char *argv[]) +{ + return DNSLIB_RESPONSE2_TEST_COUNT; +} + + +/*! Run all scheduled tests for given parameters. + */ +static int dnslib_response2_tests_run(int argc, char *argv[]) +{ + ok(test_response_init(), "response: init"); + ok(test_response_init_query(), "response: init from query"); +// ok(test_response_clear(), "response: clear"); + ok(test_response_add_opt(), "response: add opt"); + test_response_add_rrset(); + ok(test_response_add_nsid(), "response: add nsid"); + return 1; +} diff --git a/src/dnslib/tests/dnslib/response2_tests.h b/src/dnslib/tests/dnslib/response2_tests.h new file mode 100644 index 0000000000000000000000000000000000000000..d9dbdfc97667ac1c05b1ba3093b8c54e6e8d1cb6 --- /dev/null +++ b/src/dnslib/tests/dnslib/response2_tests.h @@ -0,0 +1,9 @@ +#ifndef _KNOT_RESPONSE2_TESTS_H_ +#define _KNOT_RESPONSE2_TESTS_H_ + +#include "common/libtap/tap_unit.h" + +/* Unit API. */ +unit_api response2_tests_api; + +#endif /* _KNOT_RESPONSE2_TESTS_H_ */ diff --git a/src/dnslib/tests/dnslib/response_tests.c b/src/dnslib/tests/dnslib/response_tests.c index 1c45a4f1299cb8a66fb637b58c9ad79b81875434..55f04df368e4968db7754ad98e9973d6b8d808be 100644 --- a/src/dnslib/tests/dnslib/response_tests.c +++ b/src/dnslib/tests/dnslib/response_tests.c @@ -1092,7 +1092,7 @@ static int test_response_parse_query(test_response_t **responses, #ifdef TEST_WITH_LDNS /* count1 == count2 */ -static int compare_wires_simple(uint8_t *wire1, uint8_t *wire2, uint count) +int compare_wires_simple(uint8_t *wire1, uint8_t *wire2, uint count) { int i = 0; while (i < count && @@ -1106,7 +1106,7 @@ static int compare_wires_simple(uint8_t *wire1, uint8_t *wire2, uint count) * Comparison is done through comparing wireformats. * Returns 0 if rdata are the same, 1 otherwise */ -static int compare_rr_rdata(dnslib_rdata_t *rdata, ldns_rr *rr, +int compare_rr_rdata(dnslib_rdata_t *rdata, ldns_rr *rr, uint16_t type) { dnslib_rrtype_descriptor_t *desc = @@ -1174,7 +1174,7 @@ static int compare_rr_rdata(dnslib_rdata_t *rdata, ldns_rr *rr, return 0; } -static int compare_rrset_w_ldns_rr(const dnslib_rrset_t *rrset, +int compare_rrset_w_ldns_rr(const dnslib_rrset_t *rrset, ldns_rr *rr, char check_rdata) { /* We should have only one rrset from ldns, although it is @@ -1271,7 +1271,7 @@ static int compare_rrset_w_ldns_rr(const dnslib_rrset_t *rrset, return 0; } -static int compare_rrsets_w_ldns_rrlist(const dnslib_rrset_t **rrsets, +int compare_rrsets_w_ldns_rrlist(const dnslib_rrset_t **rrsets, ldns_rr_list *rrlist, int count) { int errors = 0; @@ -1309,7 +1309,7 @@ static int compare_rrsets_w_ldns_rrlist(const dnslib_rrset_t **rrsets, * different. * TODO well, call it "check" then */ -static int compare_response_w_ldns_packet(dnslib_response_t *response, +int compare_response_w_ldns_packet(dnslib_response_t *response, ldns_pkt *packet) { if (response->header.id != ldns_pkt_id(packet)) { diff --git a/src/dnslib/tests/dnslib/zone_tests.c b/src/dnslib/tests/dnslib/zone_tests.c index db8c982ee5325ff917a488ab98058c1d1060109f..8c04567eebe0c26c9ce6de279540245489d8c6f8 100644 --- a/src/dnslib/tests/dnslib/zone_tests.c +++ b/src/dnslib/tests/dnslib/zone_tests.c @@ -2,6 +2,7 @@ #include "dnslib/tests/dnslib/zone_tests.h" #include "dnslib/dnslib-common.h" +#include "dnslib/dname-table.h" #include "dnslib/zone.h" #include "dnslib/error.h" #include "dnslib/node.h" @@ -338,12 +339,12 @@ static int test_zone_find_node(dnslib_zone_t *zone, int nsec3) return (errors == 0); } -static void test_zone_destroy_node_from_tree(dnslib_node_t *node, - void *data) -{ - UNUSED(data); - dnslib_node_free(&node, 0, 0); -} +//static void test_zone_destroy_node_from_tree(dnslib_node_t *node, +// void *data) +//{ +// UNUSED(data); +// dnslib_node_free(&node, 0); +//} /* explained below */ static size_t node_index = 0; @@ -471,19 +472,283 @@ static int test_zone_traversals(dnslib_zone_t *zone) return 1; } -static int test_zone_free(dnslib_zone_t **zone) +struct zone_test_param { + /* Times 2 so that we don't have to mess with mallocs. */ + dnslib_node_t *dnslib_node_array[TEST_NODES_GOOD * 2]; + dnslib_dname_t *table_node_array[TEST_NODES_GOOD * 2]; + int count; +}; + +static void tree_node_to_array(dnslib_node_t *node, void *data) +{ + struct zone_test_param *param = (struct zone_test_param *)data; + param->dnslib_node_array[param->count++] = node; +} + +static void tree_dname_node_to_array(struct dname_table_node *node, + void *data) +{ + struct zone_test_param *param = (struct zone_test_param *)data; + param->table_node_array[param->count++] = node->dname; +} + +extern int compare_wires_simple(uint8_t *w1, uint8_t *w2, uint count); +static int test_zone_shallow_copy() { - dnslib_zone_tree_apply_postorder(*zone, - test_zone_destroy_node_from_tree, - NULL); - dnslib_zone_nsec3_apply_postorder(*zone, - test_zone_destroy_node_from_tree, - NULL); - dnslib_zone_free(zone); - return (*zone == NULL); + int errors = 0; + int lived = 0; + dnslib_dname_t *apex_dname = + dnslib_dname_new_from_str("a.ns.nic.cz.", + strlen("a.ns.nic.cz"), NULL); + assert(apex_dname); + dnslib_node_t *apex_node = + dnslib_node_new(apex_dname, NULL); + assert(apex_node); + lives_ok({ + if (dnslib_zone_shallow_copy(NULL, NULL) != DNSLIB_EBADARG) { + diag("Calling zone_shallow_copy with NULL " + "arguments did not return DNSLIB_EBADARG!"); + errors++; + } + lived = 1; + lived = 0; + dnslib_zone_t *zone = dnslib_zone_new(apex_node, 0, 1); + if (dnslib_zone_shallow_copy(zone, NULL) != DNSLIB_EBADARG) { + diag("Calling zone_shallow_copy with NULL destination " + "zone argument did not return DNSLIB_EBADARG!"); + errors++; + } + lived = 1; + lived = 0; + if (dnslib_zone_shallow_copy(NULL, &zone) != DNSLIB_EBADARG) { + diag("Calling zone_shallow_copy with NULL source " + "zone argument did not return DNSLIB_EBADARG!"); + errors++; + } + lived = 1; + lived = 0; + if (dnslib_zone_shallow_copy(zone, &zone) != DNSLIB_EBADARG) { + diag("Calling zone_shallow_copy with identical source " + "and destination zone did not return DNSLIB_EBADARG!"); + errors++; + } + lived = 1; + dnslib_zone_free(&zone); + }, "zone: shallow copy NULL tests"); + errors += lived != 1; + + /* example.com. */ + dnslib_zone_t *from = + dnslib_zone_new(dnslib_node_new(&test_nodes_good[0].owner, + test_nodes_good[0].parent), 10, 1); + + /* Add nodes to zone. */ + for (int i = 1; i < TEST_NODES_GOOD; ++i) { + dnslib_node_t *node = dnslib_node_new(&test_nodes_good[i].owner, + test_nodes_good[i].parent); + if (node == NULL) { + diag("zone: Could not create node."); + return 0; + } + + if (dnslib_zone_add_node(from, node, 1, 1) != DNSLIB_EOK) { + diag("zone: Could not add node. %s", + dnslib_dname_to_str(node->owner)); +// return 0; + } + } + + /* Make a copy of zone */ + dnslib_zone_t *to = NULL; + int ret = 0; + if ((ret = dnslib_zone_shallow_copy(from, &to) != DNSLIB_EOK)) { + diag("Could not copy zone! %s", dnslib_strerror(ret)); + return 0; + } + + assert(to); + + /* Compare non-tree parts of the zone. */ + if (from->data != to->data) { + diag("Zone data field wrong after shallow copy!"); + errors++; + } + + if (from->dtor != to->dtor) { + diag("Zone data destructor field wrong after shallow copy!"); + errors++; + } + + if (from->node_count != to->node_count) { + diag("Zone node count data field wrong after shallow copy!"); + errors++; + } + + if (from->version != to->version) { + diag("Zone version data field wrong after shallow copy!"); + errors++; + } + + if (from->apex != to->apex) { + diag("Zone apex differ after shallow copy!"); + } + + if (compare_wires_simple((uint8_t *)(&from->nsec3_params), + (uint8_t *)(&to->nsec3_params), + sizeof(from->nsec3_params)) != 0) { + diag("Nsec3_params data field wrong after shallow copy!"); + errors++; + } + + if (from->nodes == to->nodes) { + diag("Copied zones have identical trees!"); + errors++; + } + + if (from->nsec3_nodes == to->nsec3_nodes) { + diag("Copied zones have identical trees!"); + errors++; + } + + /* Compare nodes, convert tree to array then compare those arrays. */ + struct zone_test_param param1; + param1.count = 0; + dnslib_zone_tree_apply_inorder(from, tree_node_to_array, + (void *)¶m1); + + struct zone_test_param param2; + param2.count = 0; + dnslib_zone_tree_apply_inorder(to, tree_node_to_array, + (void *)¶m2); + + if (param1.count != param2.count) { + diag("wrong tree"); + return 0; + } + + for (int i = 0; i < param1.count; i++) { + if (param1.dnslib_node_array[i] != + param2.dnslib_node_array[i]) { + diag("wrong tree"); + return 0; + } + } + + param1.count = 0; + dnslib_dname_table_tree_inorder_apply(from->dname_table, + tree_dname_node_to_array, + (void *)¶m1); + + param2.count = 0; + dnslib_dname_table_tree_inorder_apply(to->dname_table, + tree_dname_node_to_array, + (void *)¶m2); + + if (param1.count != param2.count) { + diag("wrong table count"); + return 0; + } + + for (int i = 0; i < param1.count; i++) { + if (param1.table_node_array[i] != param2.table_node_array[i]) { + diag("wrong table nodes"); + errors++; + } + } + +#ifdef USE_HASH_TABLE + if (from->table) { + if (from->table == to->table) { + diag("hash tables after shallow copy are identical!"); + return 0; + } + uint i; + if (hashsize(from->table->table_size_exp) != + hashsize(to->table->table_size_exp)) { + diag("hash tables after shallow copy error!"); + return 0; + } + + if (from->table->table_count != to->table->table_count) { + diag("hash tables after shallow copy error!"); + return 0; + } + + for (uint t = 0; t < from->table->table_count; ++t) { + for (i = 0; i < + hashsize(from->table->table_size_exp); i++) { + if (from->table->tables[t][i] == NULL) { + if (to->table->tables[t][i] != NULL) { + diag("hash table item error"); + } + continue; + } + if ((from->table->tables[t])[i]->key_length != + (to->table->tables[t])[i]->key_length) { + diag("hash table key lengths error!"); + return 0; + } + if ((from->table->tables[t])[i]->key != + (to->table->tables[t])[i]->key) { + diag("hash table key error!"); + return 0; + } + if ((from->table->tables[t])[i]->value != + (to->table->tables[t])[i]->value) { + diag("hash table value error!"); + return 0; + } + } + } + + ck_stash_item_t *item1 = from->table->stash2; + ck_stash_item_t *item2 = to->table->stash2; + while (item1 != NULL && item2 != NULL) { + if (item1->item->key_length != + item2->item->key_length) { + diag("hash stash key length error!"); + return 0; + } + if (item1->item->key != item2->item->key) { + diag("hash stash key error!"); + return 0; + } + if (item1->item->value != item2->item->value) { + diag("hash stash value error!"); + return 0; + } + + item1 = item1->next; + item2 = item2->next; + } + } else { + if (to->table) { + diag("Hash table is not set to NULL " + "after shallow copy!"); + errors++; + } + } +#endif + + dnslib_zone_free(&from); + dnslib_zone_free(&to); + return (errors == 0); + } -static const int DNSLIB_ZONE_TEST_COUNT = 9; +//static int test_zone_free(dnslib_zone_t **zone) +//{ +// dnslib_zone_tree_apply_postorder(*zone, +// test_zone_destroy_node_from_tree, +// NULL); +// dnslib_zone_nsec3_apply_postorder(*zone, +// test_zone_destroy_node_from_tree, +// NULL); +// dnslib_zone_free(zone); +// return (*zone == NULL); +//} + +static const int DNSLIB_ZONE_TEST_COUNT = 10; /*! This helper routine should report number of * scheduled tests for given parameters. @@ -544,9 +809,12 @@ static int dnslib_zone_tests_run(int argc, char *argv[]) ok(res = test_zone_traversals(zone), "zone: traversals"); res_final *= res; - ok((res = test_zone_free(&zone)), "zone: free"); + ok((res = test_zone_shallow_copy()), "zone: shallow copy"); res_final *= res; +// ok((res = test_zone_free(&zone)), "zone: free"); +// res_final *= res; + endskip; // create failed return res_final; diff --git a/src/dnslib/tests/realdata/dnslib/packet_tests_realdata.c b/src/dnslib/tests/realdata/dnslib/packet_tests_realdata.c new file mode 100644 index 0000000000000000000000000000000000000000..1045990ae5e3d8b52c0b201eb6e1f8491012988d --- /dev/null +++ b/src/dnslib/tests/realdata/dnslib/packet_tests_realdata.c @@ -0,0 +1,435 @@ +/* blame: jan.kadlec@nic.cz */ + +#include <assert.h> + +#include "packet_tests_realdata.h" +#include "dnslib/error.h" +#include "dnslib/packet.h" +#include "dnslib/response2.h" +/* *test_t structures */ +#include "dnslib/tests/realdata/dnslib_tests_loader_realdata.h" +#ifdef TEST_WITH_LDNS +#include "ldns/ldns.h" +#endif + +static int packet_tests_count(int argc, char *argv[]); +static int packet_tests_run(int argc, char *argv[]); + +/*! Exported unit API. + */ +unit_api packet_tests_api = { + "DNS library - packet", //! Unit name + &packet_tests_count, //! Count scheduled tests + &packet_tests_run //! Run scheduled tests +}; + +#ifdef TEST_WITH_LDNS +extern int compare_wires_simple(uint8_t *wire1, uint8_t *wire2, uint count); +extern int compare_rr_rdata(dnslib_rdata_t *rdata, ldns_rr *rr, uint16_t type); +extern int compare_rrset_w_ldns_rr(const dnslib_rrset_t *rrset, + ldns_rr *rr, char check_rdata); +extern int compare_rrsets_w_ldns_rrlist(const dnslib_rrset_t **rrsets, + ldns_rr_list *rrlist, int count); + +int check_packet_w_ldns_packet(dnslib_packet_t *packet, + ldns_pkt *ldns_packet, + int check_header, + int check_question, + int check_body, + int check_edns) +{ + int errors = 0; + if (check_header) { + if (packet->header.id != ldns_pkt_id(ldns_packet)) { + diag("response ID does not match"); + errors++; + } + + /* qdcount is always 1 in dnslib's case */ + + /* TODO check flags1 and flags2 - no API for that, + * write my own */ + + if (packet->header.ancount != + ldns_pkt_ancount(ldns_packet)) { + diag("Answer RRSet count wrongly converted"); + errors++; + } + + if (packet->header.nscount != + ldns_pkt_nscount(ldns_packet)) { + diag("Authority RRSet count wrongly converted.\n" + "got %d should be %d", + dnslib_packet_authority_rrset_count(packet), + ldns_pkt_nscount(ldns_packet)); + errors++; + } + + /* - 1 because ldns does not include OPT_RR to additional " + "section */ + int minus = (packet->opt_rr.version == 0) ? 1 : 0; + + if ((packet->header.arcount - minus) != + ldns_pkt_arcount(ldns_packet)) { + diag("Additional RRSet count wrongly converted.\n" + "got %d should be %d", + dnslib_packet_additional_rrset_count(packet) - + minus, + ldns_pkt_arcount(ldns_packet)); + errors++; + } + + if (errors) { + return errors; + } + } + /* Header checked */ + + /* Question section */ + + int ret = 0; + if (check_question) { + dnslib_rrset_t *question_rrset = + dnslib_rrset_new(packet-> + question.qname, + packet-> + question.qtype, + packet-> + question.qclass, + 3600); + + if ((ret = compare_rrset_w_ldns_rr(question_rrset, + ldns_rr_list_rr(ldns_pkt_question(ldns_packet), + 0), 0)) != 0) { + diag("Question rrsets wrongly converted"); + errors++; + } + dnslib_rrset_free(&question_rrset); + } + + if (check_body) { + + /* other RRSets */ + + if ((ret = + compare_rrsets_w_ldns_rrlist(packet->answer, + ldns_pkt_answer(ldns_packet), + dnslib_packet_answer_rrset_count(packet))) != 0) { + diag("Answer rrsets wrongly converted"); + errors++; + } + + + + if ((ret = compare_rrsets_w_ldns_rrlist(packet->authority, + ldns_pkt_authority(ldns_packet), + dnslib_packet_authority_rrset_count(packet))) != 0) { + diag("Authority rrsets wrongly converted - %d", ret); + errors++; + } + + /* We don't want to test OPT RR, which is the last rrset + * in the additional section */ + + if ((ret = compare_rrsets_w_ldns_rrlist(packet->additional, + ldns_pkt_additional(ldns_packet), + dnslib_packet_additional_rrset_count(packet) - 1)) != 0) { + diag("Additional rrsets wrongly converted"); + errors++; + } + + } + + if (check_edns) { + + /* OPT RR */ + + if (ldns_pkt_edns(ldns_packet)) { + /* if (packet->edns_packet == NULL) { + diag("ldns has edns section, dnslib has not"); + return 1; + } */ + + dnslib_opt_rr_t *opt = &(packet->opt_rr); + + if (ldns_pkt_edns_udp_size(ldns_packet) != + dnslib_edns_get_payload(opt)) { + diag("Payloads in EDNS are different"); + errors++; + } + + if (ldns_pkt_edns_version(ldns_packet) != + dnslib_edns_get_version(opt)) { + diag("Versions in EDNS are different"); + errors++; + } + + if (ldns_pkt_edns_extended_rcode(ldns_packet) != + dnslib_edns_get_ext_rcode(opt)) { + diag("Extended rcodes in EDNS are different"); + errors++; + } + + /* TODO parse flags do bit, z value ... */ + } + } + + return errors; +} +#endif + +extern dnslib_rrset_t *rrset_from_test_rrset(const test_rrset_t *test_rrset); +extern dnslib_dname_t *dname_from_test_dname(const test_dname_t *test_dname); + +/* Converts dnslib_rrset_t to dnslib_opt_rr */ +static dnslib_opt_rr_t *opt_rrset_to_opt_rr(dnslib_rrset_t *rrset) +{ + if (rrset == NULL) { + return NULL; + } + + dnslib_opt_rr_t *opt_rr = dnslib_edns_new(); + assert(opt_rr); + + dnslib_edns_set_payload(opt_rr, rrset->rclass); + + dnslib_edns_set_ext_rcode(opt_rr, rrset->ttl); + + /* TODO rdata? mostly empty, I guess, but should be done */ + + return opt_rr; +} + +dnslib_packet_t *packet_from_test_response(test_response_t *test_packet) +{ + dnslib_rrset_t *parsed_opt = NULL; + + for (int j = 0; j < test_packet->arcount; j++) { + if (test_packet->additional[j]->type == + DNSLIB_RRTYPE_OPT) { + parsed_opt = + rrset_from_test_rrset( + test_packet->additional[j]); + assert(parsed_opt); + break; + } + } + + dnslib_opt_rr_t *opt_rr = NULL; + if (parsed_opt != NULL) { + opt_rr = + opt_rrset_to_opt_rr(parsed_opt); + assert(opt_rr); + } else { + opt_rr = NULL; + } + + dnslib_packet_t *packet = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_RESPONSE); + assert(packet); + dnslib_packet_set_max_size(packet, 1024 * 10); + + if (opt_rr != NULL) { + packet->opt_rr = *opt_rr; + } + + packet->header.id = test_packet->id; + packet->header.qdcount = test_packet->qdcount; + + packet->question.qname = dname_from_test_dname(test_packet->qname); + packet->size += test_packet->qname->size; + packet->question.qtype = test_packet->qtype; + packet->question.qclass = test_packet->qclass; + + packet->size += 4; + + packet->answer = + malloc(sizeof(dnslib_rrset_t *) * test_packet->ancount); + assert(packet->answer); + + for (int j = 0; j < test_packet->ancount; j++) { + if (&(test_packet->answer[j])) { + packet->answer[packet->an_rrsets++] = + rrset_from_test_rrset(test_packet->answer[j]); + } + } + + packet->authority = + malloc(sizeof(dnslib_rrset_t *) * test_packet->nscount); + assert(packet->answer); + + for (int j = 0; j < test_packet->nscount; j++) { + if (&(test_packet->authority[j])) { + packet->authority[packet->ns_rrsets++] = + rrset_from_test_rrset(test_packet->authority[j]); + } + } + + packet->authority = + malloc(sizeof(dnslib_rrset_t *) * test_packet->arcount); + assert(packet->answer); + + for (int j = 0; j < test_packet->arcount; j++) { + if (&(test_packet->additional[j])) { + if (test_packet->additional[j]->type == + DNSLIB_RRTYPE_OPT) { + continue; + } + packet->additional[packet->ar_rrsets++] = + rrset_from_test_rrset(test_packet->additional[j]); + } + } + + return packet; +} + +static int test_packet_parse_from_wire(list raw_response_list) +{ + int errors = 0; + + node *n = NULL; + WALK_LIST(n ,raw_response_list) { + test_raw_packet_t *raw_packet = (test_raw_packet_t *)n; + dnslib_packet_t *packet = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_RESPONSE); + int ret = 0; + if ((ret = + dnslib_packet_parse_from_wire(packet, raw_packet->data, + raw_packet->size, 0)) != + DNSLIB_EOK) { + diag("Warning: could not parse wire! " + "(might be caused by malformed dump) - " + "dnslib error: %s", dnslib_strerror(ret)); +// hex_print(raw_packet->data, +// raw_packet->size); + continue; + } + + ldns_pkt *ldns_packet = NULL; + + if (ldns_wire2pkt(&ldns_packet, raw_packet->data, + raw_packet->size) != LDNS_STATUS_OK) { + diag("Could not parse wire using ldns"); + diag("%s", + ldns_get_errorstr_by_id(ldns_wire2pkt(&ldns_packet, + raw_packet->data, + raw_packet->size))); + return 0; + } + + if (check_packet_w_ldns_packet(packet, ldns_packet, 1, + 1, 1, 1) != 0) { + diag("Wrongly created packet"); + errors++; + } + + ldns_pkt_free(ldns_packet); + dnslib_packet_free(&packet); + } + + return (errors == 0); +} + +static int test_packet_to_wire(list raw_response_list) +{ + int errors = 0; + /*!< \todo test queries too! */ +// /* We'll need data from both lists. */ +// test_packet_t **test_packets = NULL; +// uint test_packet_count = 0; +// node *n = NULL; +// WALK_LIST(n, response_list) { +// test_packet_count++; +// } + +// test_packets = +// malloc(sizeof(test_packet_t *) * test_packet_count); +// assert(test_packets); +// int i = 0; +// WALK_LIST(n, response_list) { +// test_packets[i++] = (test_response_t *)n; +// } + +// test_raw_packet_t **test_packets = NULL; +// uint test_packet_count = 0; +// n = NULL; +// WALK_LIST(n, raw_response_list) { +// test_packet_count++; +// } + +// test_packets = +// malloc(sizeof(test_raw_packet_t *) * test_packet_count); +// assert(test_packets); +// i = 0; +// WALK_LIST(n, raw_response_list) { +// test_packets[i++] = (test_raw_packet_t *)n; +// } + +// assert(test_response_count == test_packet_count); + node *n = NULL; + WALK_LIST(n, raw_response_list) { + /* Create packet from raw response. */ + dnslib_packet_t *packet = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_RESPONSE); + assert(packet); + test_raw_packet_t *raw_packet = (test_raw_packet_t *)n; + if (dnslib_packet_parse_from_wire(packet, raw_packet->data, + raw_packet->size, 0) != + DNSLIB_EOK) { + diag("Warning: could not parse wire! " + "(might be caused be malformed dump)"); + continue; + } + /* Use this packet to create wire */ + uint8_t *wire = NULL; + size_t size = 0; + if (dnslib_packet_to_wire(packet, &wire ,&size) != DNSLIB_EOK) { + diag("Could not convert packet to wire"); + } + /* Create ldns packet from created wire */ + ldns_pkt *ldns_packet = NULL; + + if (ldns_wire2pkt(&ldns_packet, wire, + size) != LDNS_STATUS_OK) { + diag("Could not parse wire using ldns"); + /*!< \todo get rid of this */ + diag("%s", + ldns_get_errorstr_by_id(ldns_wire2pkt(&ldns_packet, + wire, + size))); + return 0; + } + + if (check_packet_w_ldns_packet(packet, ldns_packet, 1, 1, 1, + 1) != 0) { + diag("Packet wrongly converted to wire!"); + errors++; + } + dnslib_packet_free(&packet); + ldns_pkt_free(ldns_packet); + } + + return (errors == 0); +} + +static const uint DNSLIB_PACKET_TEST_COUNT = 2; + +static int packet_tests_count(int argc, char *argv[]) +{ + return DNSLIB_PACKET_TEST_COUNT; +} + +static int packet_tests_run(int argc, char *argv[]) +{ + const test_data_t *data = data_for_dnslib_tests; + + int res = 0; + ok(res = test_packet_parse_from_wire(data->raw_packet_list), + "packet: from wire"); + skip(!res, 1); + ok(test_packet_to_wire(data->raw_packet_list), "packet: to wire"); + endskip; + + return 1; +} + diff --git a/src/dnslib/tests/realdata/dnslib/packet_tests_realdata.h b/src/dnslib/tests/realdata/dnslib/packet_tests_realdata.h new file mode 100644 index 0000000000000000000000000000000000000000..91b9116d3dda7fb7b5b64a7d913f134ac69cdc47 --- /dev/null +++ b/src/dnslib/tests/realdata/dnslib/packet_tests_realdata.h @@ -0,0 +1,9 @@ +#ifndef _KNOT_PACKET_REALDATA_TESTS_H_ +#define _KNOT_PACKET_REALDATA_TESTS_H_ + +#include "common/libtap/tap_unit.h" + +/* Unit API. */ +unit_api packet_tests_api; + +#endif /* _KNOT_PACKET_REALDATA_TESTS_H_ */ diff --git a/src/dnslib/tests/realdata/dnslib/response2_tests_realdata.c b/src/dnslib/tests/realdata/dnslib/response2_tests_realdata.c new file mode 100644 index 0000000000000000000000000000000000000000..6e92bd7c38818f61ab0ba19aeae4e4849ef6667c --- /dev/null +++ b/src/dnslib/tests/realdata/dnslib/response2_tests_realdata.c @@ -0,0 +1,157 @@ +/* blame: jan.kadlec@nic.cz */ + +#include <assert.h> + +#include "packet_tests_realdata.h" +#include "dnslib/error.h" +#include "dnslib/packet.h" +#include "dnslib/response2.h" +/* *test_t structures */ +#include "dnslib/tests/realdata/dnslib_tests_loader_realdata.h" +#ifdef TEST_WITH_LDNS +#include "ldns/packet.h" +#endif + +static int response2_tests_count(int argc, char *argv[]); +static int response2_tests_run(int argc, char *argv[]); + +/*! Exported unit API. + */ +unit_api response2_tests_api = { + "DNS library - response2", //! Unit name + &response2_tests_count, //! Count scheduled tests + &response2_tests_run //! Run scheduled tests +}; + +#ifdef TEST_WITH_LDNS +extern int compare_wires_simple(uint8_t *wire1, uint8_t *wire2, uint count); +extern int compare_rr_rdata(dnslib_rdata_t *rdata, ldns_rr *rr, uint16_t type); +extern int compare_rrset_w_ldns_rr(const dnslib_rrset_t *rrset, + ldns_rr *rr, char check_rdata); +extern int compare_rrsets_w_ldns_rrlist(const dnslib_rrset_t **rrsets, + ldns_rr_list *rrlist, int count); + +extern int check_packet_w_ldns_packet(dnslib_packet_t *packet, + ldns_pkt *ldns_packet, + int check_header, + int check_question, + int check_body, + int check_edns); +#endif + +extern dnslib_packet_t *packet_from_test_response(test_response_t *response); + +static int test_response_init_from_query(list query_list) +{ + int errors = 0; + node *n = NULL; + WALK_LIST(n, query_list) { + dnslib_packet_t *response = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_RESPONSE); + assert(response); + dnslib_packet_t *query = + packet_from_test_response((test_response_t *)n); + assert(query); + dnslib_packet_set_max_size(response, 1024 * 10); + if (dnslib_response2_init_from_query(response, + query) != DNSLIB_EOK) { + diag("Could not init response from query!"); + errors++; + } + dnslib_packet_free(&response); + dnslib_packet_free(&query); + } + return (errors == 0); +} + +//static int test_response_add_opt(list opt_list) +//{ +// int errors = 0; +// node *n = NULL; +// WALK_LIST(n, query_list) { +// dnslib_packet_t *response = +// dnslib_packet_new(DNSLIB_PACKET_PREALLOC_RESPONSE); +// assert(response); +// dnslib_opt_rr_t *opt = +// opt_from_test_opt((test_opt_t *)n); +// assert(query); +// if (dnslib_response2_add_opt(response, +// opt, 1)!= DNSLIB_EOK) { +// diag("Could not add OPT RR to response!"); +// errors++; +// } +// dnslib_packet_free(&response); +// dnslib_opt_rr_free(&opt); +// } +// return (errors == 0); +//} + +extern dnslib_rrset_t *rrset_from_test_rrset(test_rrset_t *test_rrset); + +static int test_response_add_generic(int (*func)(dnslib_packet_t *, + const dnslib_rrset_t *, + int, int, int), + list rrset_list) +{ + /*!< \todo Now adding only one RRSet at the time, try more, use nodes */ + int errors = 0; + node *n = NULL; + WALK_LIST(n, rrset_list) { + dnslib_packet_t *response = + dnslib_packet_new(DNSLIB_PACKET_PREALLOC_RESPONSE); + assert(response); + dnslib_packet_set_max_size(response, + DNSLIB_PACKET_PREALLOC_RESPONSE * 100); + assert(dnslib_response2_init(response) == DNSLIB_EOK); + + dnslib_rrset_t *rrset = + rrset_from_test_rrset((test_rrset_t *)n); + assert(rrset); + + int ret = 0; + if ((ret = func(response, rrset, 0, 1, 0)) != DNSLIB_EOK) { + diag("Could not add RRSet to response! Returned: %d", + ret); + diag("(owner: %s type %s)", + ((test_rrset_t *)n)->owner->str, + dnslib_rrtype_to_string(( + (test_rrset_t *)n)->type)); + errors++; + } + dnslib_packet_free(&response); + dnslib_rrset_deep_free(&rrset, 1, 1, 1); + } + + return (errors == 0); +} + +static void test_response_add_rrset(list rrset_list) +{ + ok(test_response_add_generic(dnslib_response2_add_rrset_answer, + rrset_list), + "response: add answer rrset"); + ok(test_response_add_generic(dnslib_response2_add_rrset_authority, + rrset_list), + "response: add authority rrset"); + ok(test_response_add_generic(dnslib_response2_add_rrset_additional, + rrset_list), + "response: add additional rrset"); +} + +static const uint DNSLIB_RESPONSE2_TEST_COUNT = 4; + +static int response2_tests_count(int argc, char *argv[]) +{ + return DNSLIB_RESPONSE2_TEST_COUNT; +} + +static int response2_tests_run(int argc, char *argv[]) +{ + const test_data_t *data = data_for_dnslib_tests; + +// int res = 0; + ok(test_response_init_from_query(data->query_list), + "response: init from query"); + test_response_add_rrset(data->rrset_list); + return 1; +} diff --git a/src/dnslib/tests/realdata/dnslib/response2_tests_realdata.h b/src/dnslib/tests/realdata/dnslib/response2_tests_realdata.h new file mode 100644 index 0000000000000000000000000000000000000000..d693e26a7ad57a92048e4208c2767730b3b60fe3 --- /dev/null +++ b/src/dnslib/tests/realdata/dnslib/response2_tests_realdata.h @@ -0,0 +1,9 @@ +#ifndef _KNOT_PACKET_RESPONSE2_TESTS_H_ +#define _KNOT_PACKET_RESPONSE2_TESTS_H_ + +#include "common/libtap/tap_unit.h" + +/* Unit API. */ +unit_api response2_tests_api; + +#endif /* _KNOT_PACKET_RESPONSE2_TESTS_H_ */ diff --git a/src/dnslib/tests/realdata/dnslib/response_tests_realdata.c b/src/dnslib/tests/realdata/dnslib/response_tests_realdata.c index dfc982db1c8d339f68b9239c1d231c2a2f469f9f..fcd6038aba8f1298f57f562c4c93049c31dbbcdb 100644 --- a/src/dnslib/tests/realdata/dnslib/response_tests_realdata.c +++ b/src/dnslib/tests/realdata/dnslib/response_tests_realdata.c @@ -58,14 +58,6 @@ static int mem_read(void *dst, size_t n, const char **src, * Unit implementation. */ -/* Parsed raw packet*/ -struct test_raw_packet { - uint size; - uint8_t *data; -}; - -typedef struct test_raw_packet test_raw_packet_t; - enum { DNAME_MAX_WIRE_LENGTH = 256 }; static int load_raw_packets(test_raw_packet_t ***raw_packets, uint32_t *count, @@ -198,164 +190,164 @@ static dnslib_dname_t *dname_from_test_dname(const test_dname_t *test_dname) NULL); } -static int check_response(dnslib_response_t *resp, test_response_t *test_resp, - int check_header, int check_question, - int check_answer, int check_additional, - int check_authority) -{ - int errors = 0; /* TODO maybe use it everywhere, or not use it at all */ - - if (check_question) { - /* again, in case of dnames, pointer would probably suffice */ - if (dnslib_dname_compare(resp->question.qname, - dname_from_test_dname(test_resp->qname)) != 0) { - char *tmp_dname; - tmp_dname = dnslib_dname_to_str(resp->question.qname); - diag("Qname in response is wrong:\ - should be: %s is: %s\n", - tmp_dname, test_resp->qname->str); - free(tmp_dname); - return 0; - } - - if (resp->question.qtype != test_resp->qtype) { - diag("Qtype value is wrong: is %u should be %u\n", - resp->question.qtype, test_resp->qtype); - return 0; - } - if (resp->question.qclass != test_resp->qclass) { - diag("Qclass value is wrong: is %u should be %u\n", - resp->question.qclass, test_resp->qclass); - return 0; - } - } - - if (check_header) { - /* Disabled, since these check make no sense - * if we have parsed the query, flags are now set to - * the ones response should have */ - - /* - if (resp->header.flags1 != test_resp->flags1) { - diag("Flags1 value is wrong: is %u should be %u\n", - resp->header.flags1, test_resp->flags1); - //return 0; - } - if (resp->header.flags2 != test_resp->flags2) { - diag("Flags2 value is wrong: is %u should be %u\n", - resp->header.flags2, test_resp->flags2); - return 0; - } - */ - - if (resp->header.qdcount != test_resp->qdcount) { - diag("Qdcount value is wrong: is %u should be %u\n", - resp->header.qdcount, test_resp->qdcount); - return 0; - } - if (resp->header.ancount != test_resp->ancount) { - diag("Ancount value is wrong: is %u should be %u\n", - resp->header.ancount, test_resp->ancount); - return 0; - } - if (resp->header.nscount != test_resp->nscount) { - diag("Nscount value is wrong: is %u should be %u\n", - resp->header.nscount, test_resp->nscount); - return 0; - } - if (resp->header.arcount != test_resp->arcount) { - diag("Arcount value is different: is %u should be %u\n", - resp->header.arcount, test_resp->arcount); +//static int check_response(dnslib_response_t *resp, test_response_t *test_resp, +// int check_header, int check_question, +// int check_answer, int check_additional, +// int check_authority) +//{ +// int errors = 0; /* TODO maybe use it everywhere, or not use it at all */ + +// if (check_question) { +// /* again, in case of dnames, pointer would probably suffice */ +// if (dnslib_dname_compare(resp->question.qname, +// dname_from_test_dname(test_resp->qname)) != 0) { +// char *tmp_dname; +// tmp_dname = dnslib_dname_to_str(resp->question.qname); +// diag("Qname in response is wrong: " +// "should be: %s is: %s\n", +// tmp_dname, test_resp->qname->str); +// free(tmp_dname); // return 0; - } - } - - if (check_question) { - /* Currently just one question RRSET allowed */ - if (dnslib_dname_compare(resp->question.qname, - dname_from_test_dname(test_resp->qname)) != 0) { - diag("Qname is wrongly set"); - errors++; - } - - if (resp->question.qtype != test_resp->qtype) { - diag("Qtype is wrongly set"); - errors++; - } +// } - if (resp->question.qclass != test_resp->qclass) { - diag("Qclass is wrongly set"); - errors++; - } +// if (resp->question.qtype != test_resp->qtype) { +// diag("Qtype value is wrong: is %u should be %u\n", +// resp->question.qtype, test_resp->qtype); +// return 0; +// } +// if (resp->question.qclass != test_resp->qclass) { +// diag("Qclass value is wrong: is %u should be %u\n", +// resp->question.qclass, test_resp->qclass); +// return 0; +// } +// } - } +// if (check_header) { +// /* Disabled, since these check make no sense +// * if we have parsed the query, flags are now set to +// * the ones response should have */ - /* Following code is not used anywhere currently. */ +// /* +// if (resp->header.flags1 != test_resp->flags1) { +// diag("Flags1 value is wrong: is %u should be %u\n", +// resp->header.flags1, test_resp->flags1); +// //return 0; +// } +// if (resp->header.flags2 != test_resp->flags2) { +// diag("Flags2 value is wrong: is %u should be %u\n", +// resp->header.flags2, test_resp->flags2); +// return 0; +// } +// */ -// if (check_authority) { -// for (int i = 0; (i < resp->header.arcount) && !errors; i++) { -// if (resp->authority[i] != (test_resp->authority[i])) { -// diag("Authority rrset #%d is wrongly set.\n", -// i); -// errors++; -// } +// if (resp->header.qdcount != test_resp->qdcount) { +// diag("Qdcount value is wrong: is %u should be %u\n", +// resp->header.qdcount, test_resp->qdcount); +// return 0; +// } +// if (resp->header.ancount != test_resp->ancount) { +// diag("Ancount value is wrong: is %u should be %u\n", +// resp->header.ancount, test_resp->ancount); +// return 0; +// } +// if (resp->header.nscount != test_resp->nscount) { +// diag("Nscount value is wrong: is %u should be %u\n", +// resp->header.nscount, test_resp->nscount); +// return 0; +// } +// if (resp->header.arcount != test_resp->arcount) { +// diag("Arcount value is different: is %u should be %u\n", +// resp->header.arcount, test_resp->arcount); +//// return 0; // } // } -// if (check_answer) { -// for (int i = 0; (i < resp->header.arcount) && !errors; i++) { -// if (resp->authority[i] != (test_resp->authority[i])) { -// diag("Authority rrset #%d is wrongly set.\n", -// i); -// errors++; -// } +// if (check_question) { +// /* Currently just one question RRSET allowed */ +// if (dnslib_dname_compare(resp->question.qname, +// dname_from_test_dname(test_resp->qname)) != 0) { +// diag("Qname is wrongly set"); +// errors++; // } -// } -// if (check_additional) { -// for (int i = 0; (i < resp->header.arcount) && !errors; i++) { -// if (resp->authority[i] != (test_resp->authority[i])) { -// diag("Authority rrset #%d is wrongly set.\n", -// i); -// errors++; -// } +// if (resp->question.qtype != test_resp->qtype) { +// diag("Qtype is wrongly set"); +// errors++; // } -// } - return (errors == 0); -} +// if (resp->question.qclass != test_resp->qclass) { +// diag("Qclass is wrongly set"); +// errors++; +// } -static int test_response_parse_query(list response_list, - test_raw_packet_t **raw_queries, - uint count) -{ - assert(raw_queries); +// } - int errors = 0; - dnslib_response_t *resp = NULL; - node *n = NULL; - int i = 0; - WALK_LIST(n, response_list) { - assert(i < count); - test_response_t *test_response = (test_response_t *)n; - resp = dnslib_response_new_empty(NULL); - assert(resp); +// /* Following code is not used anywhere currently. */ + +//// if (check_authority) { +//// for (int i = 0; (i < resp->header.arcount) && !errors; i++) { +//// if (resp->authority[i] != (test_resp->authority[i])) { +//// diag("Authority rrset #%d is wrongly set.\n", +//// i); +//// errors++; +//// } +//// } +//// } + +//// if (check_answer) { +//// for (int i = 0; (i < resp->header.arcount) && !errors; i++) { +//// if (resp->authority[i] != (test_resp->authority[i])) { +//// diag("Authority rrset #%d is wrongly set.\n", +//// i); +//// errors++; +//// } +//// } +//// } + +//// if (check_additional) { +//// for (int i = 0; (i < resp->header.arcount) && !errors; i++) { +//// if (resp->authority[i] != (test_resp->authority[i])) { +//// diag("Authority rrset #%d is wrongly set.\n", +//// i); +//// errors++; +//// } +//// } +//// } + +// return (errors == 0); +//} -// hex_print(raw_queries[i]->data, raw_queries[i]->size); +//static int test_response_parse_query(list response_list, +// test_raw_packet_t **raw_queries, +// uint count) +//{ +// assert(raw_queries); - if (dnslib_response_parse_query(resp, - raw_queries[i]->data, - raw_queries[i]->size) != 0) { - diag("Could not parse query\n"); - errors++; - } - errors += !check_response(resp, test_response, 1, 1, 0, 0, 0); - dnslib_response_free(&resp); - i++; - } +// int errors = 0; +// dnslib_response_t *resp = NULL; +// node *n = NULL; +// int i = 0; +// WALK_LIST(n, response_list) { +// assert(i < count); +// test_response_t *test_response = (test_response_t *)n; +// resp = dnslib_response_new_empty(NULL); +// assert(resp); + +//// hex_print(raw_queries[i]->data, raw_queries[i]->size); + +// if (dnslib_response_parse_query(resp, +// raw_queries[i]->data, +// raw_queries[i]->size) != 0) { +// diag("Could not parse query\n"); +// errors++; +// } +// errors += !check_response(resp, test_response, 1, 1, 0, 0, 0); +// dnslib_response_free(&resp); +// i++; +// } - return (errors == 0); -} +// return (errors == 0); +//} #ifndef TEST_WITH_LDNS /*! \note disabled */ @@ -398,7 +390,7 @@ int compare_wires_simple(uint8_t *wire1, uint8_t *wire2, uint count) * Comparison is done through comparing wireformats. * Returns 0 if rdata are the same, 1 otherwise */ -static int compare_rr_rdata(dnslib_rdata_t *rdata, ldns_rr *rr, +int compare_rr_rdata(dnslib_rdata_t *rdata, ldns_rr *rr, uint16_t type) { dnslib_rrtype_descriptor_t *desc = @@ -449,12 +441,12 @@ static int compare_rr_rdata(dnslib_rdata_t *rdata, ldns_rr *rr, (rdata->items[i].raw_data + 1), ldns_rdf_data(ldns_rr_rdf(rr, i)), rdata->items[i].raw_data[0]) != 0) { - hex_print((char *) - (rdata->items[i].raw_data + 1), - rdata->items[i].raw_data[0]); - hex_print((char *) - ldns_rdf_data(ldns_rr_rdf(rr, i)), - rdata->items[i].raw_data[0]); +// hex_print((char *) +// (rdata->items[i].raw_data + 1), +// rdata->items[i].raw_data[0]); +// hex_print((char *) +// ldns_rdf_data(ldns_rr_rdf(rr, i)), +// rdata->items[i].raw_data[0]); diag("Raw data wires in rdata differ in item " "%d", i); @@ -466,12 +458,14 @@ static int compare_rr_rdata(dnslib_rdata_t *rdata, ldns_rr *rr, return 0; } -static int compare_rrset_w_ldns_rr(const dnslib_rrset_t *rrset, +int compare_rrset_w_ldns_rr(const dnslib_rrset_t *rrset, ldns_rr *rr, char check_rdata) { /* We should have only one rrset from ldns, although it is * represented as rr_list ... */ + int errors = 0; + assert(rr); assert(rrset); @@ -485,32 +479,32 @@ static int compare_rrset_w_ldns_rr(const dnslib_rrset_t *rrset, diag("%s", tmp_dname); diag("%s", ldns_rdf_data(ldns_rr_owner(rr))); free(tmp_dname); - return 1; + errors++; } if (compare_wires_simple(rrset->owner->name, ldns_rdf_data(ldns_rr_owner(rr)), rrset->owner->size) != 0) { diag("RRSet owner wireformats differ"); - return 1; + errors++; } if (rrset->type != ldns_rr_get_type(rr)) { diag("RRset types differ"); diag("Dnslib type: %d Ldns type: %d", rrset->type, ldns_rr_get_type(rr)); - return 1; + errors++; } if (rrset->rclass != ldns_rr_get_class(rr)) { diag("RRset classes differ"); - return 1; + errors++; } if (rrset->ttl != ldns_rr_ttl(rr)) { diag("RRset TTLs differ"); diag("dnslib: %d ldns: %d", rrset->ttl, ldns_rr_ttl(rr)); - return 1; + errors++; } /* compare rdatas */ @@ -556,14 +550,14 @@ static int compare_rrset_w_ldns_rr(const dnslib_rrset_t *rrset, if (check_rdata) { if (compare_rr_rdata(rrset->rdata, rr, rrset->type) != 0) { diag("Rdata differ"); - return 1; + errors++; } } - return 0; + return errors; } -static int compare_rrsets_w_ldns_rrlist(const dnslib_rrset_t **rrsets, +int compare_rrsets_w_ldns_rrlist(const dnslib_rrset_t **rrsets, ldns_rr_list *rrlist, int count) { int errors = 0; diff --git a/src/dnslib/tests/realdata/dnslib_tests_loader_realdata.c b/src/dnslib/tests/realdata/dnslib_tests_loader_realdata.c index 5e50ae9338d3552dd99db1168181a42d934b4fae..fbda077ff330f0e56e36427d3cd6b85e98fe5b1f 100644 --- a/src/dnslib/tests/realdata/dnslib_tests_loader_realdata.c +++ b/src/dnslib/tests/realdata/dnslib_tests_loader_realdata.c @@ -6,7 +6,8 @@ #include "dnslib/tests/realdata/dnslib_tests_loader_realdata.h" #include "dnslib/descriptor.h" -#include "dnslib/tests/parsed_data.rc" +#include "dnslib/tests/realdata/parsed_data.rc" +#include "dnslib/tests/realdata/raw_data.rc" TREE_DEFINE(test_node, avl); /* Virtual I/O over memory. */ @@ -26,6 +27,56 @@ static int mem_read(void *dst, size_t n, const char **src, return 1; } +static int load_raw_packets(test_data_t *data, uint32_t *count, + const char *src, unsigned src_size) +{ + + uint16_t tmp_size = 0; + + /* Packets are stored like this: [size][packet_data]+ */ + + if(!mem_read(count, sizeof(uint32_t), &src, &src_size)) { + return -1; + } + + for (int i = 0; i < *count; i++) { + uint16_t query = 0; + if (!mem_read(&query, sizeof(query), &src, &src_size)) { + return -1; + } + + if(!mem_read(&tmp_size, sizeof(uint16_t), &src, &src_size)) { + return -1; + } + + test_raw_packet_t *packet = malloc(sizeof(test_raw_packet_t)); + + + packet->size = tmp_size; + packet->data = malloc(sizeof(uint8_t) * (tmp_size)); + if(!mem_read(packet->data, + sizeof(uint8_t) * tmp_size, &src, &src_size)) { + return -1; + } + + if (query) { + add_tail(&data->raw_query_list, (void *)packet); + } else { + add_tail(&data->raw_response_list, (void *)packet); + } + + test_raw_packet_t *new_packet = + malloc(sizeof(test_raw_packet_t)); + assert(new_packet); + new_packet->data = packet->data; + new_packet->size = packet->size; + + add_tail(&data->raw_packet_list, (void *)new_packet); + } + + return 0; +} + /* Returns size of type where avalailable */ size_t wireformat_size_load(uint wire_type) { @@ -368,7 +419,7 @@ static test_rdata_t *load_response_rdata(uint16_t type, items[i].raw_data) + 3, sizeof(uint8_t) * (raw_data_length), src, src_size)) { - diag("Wrong read 3!"); + fprintf(stderr, "Wrong read!\n"); return NULL; } @@ -444,7 +495,7 @@ static test_rdata_t *load_response_rdata(uint16_t type, if (!mem_read(items[i].raw_data + 1, size_fr_desc, src, src_size)) { - diag("Wrong read 4!"); + fprintf(stderr, "Wrong read\n!"); return NULL; } @@ -572,7 +623,8 @@ static test_rrset_t *load_response_rrset(const char **src, unsigned *src_size, tmp_rdata = load_response_rdata(rrset->type, src, src_size); if (tmp_rdata == NULL) { - diag("Could not load rrset rdata - type: %d", + fprintf(stderr, + "Could not load rrset rdata - type: %d", rrset->type); free(rrset); return NULL; @@ -645,6 +697,11 @@ static test_response_t *load_parsed_response(const char **src, fprintf(stderr, "arcount: %d\n", resp->arcount); #endif + if (!mem_read(&resp->query, sizeof(resp->query), src, src_size)) { + free(resp); + return NULL; + } + test_rrset_t **question_rrsets; question_rrsets = malloc(sizeof(test_rrset_t *) * resp->qdcount); @@ -995,7 +1052,6 @@ static void get_and_save_data_from_response(const test_response_t *response, static int load_parsed_responses(test_data_t *data, uint32_t *count, const char* src, unsigned src_size) { - if (!mem_read(count, sizeof(*count), &src, &src_size)) { fprintf(stderr, "Wrong read\n"); return -1; @@ -1014,8 +1070,18 @@ static int load_parsed_responses(test_data_t *data, uint32_t *count, return -1; } - add_tail(&data->response_list, - (node *)tmp_response); + if (tmp_response->query) { + add_tail(&data->query_list, (node *)tmp_response); + } else { + add_tail(&data->response_list, (node *)tmp_response); + } + + /* Create new node */ + test_response_t *resp = malloc(sizeof(test_response_t)); + assert(resp); + memcpy(resp, tmp_response, sizeof(test_response_t)); + add_tail(&data->packet_list, + (node *)resp); } return 0; @@ -1052,6 +1118,11 @@ static int init_data(test_data_t *data) init_list(&data->rdata_list); init_list(&data->rrset_list); init_list(&data->item_list); + init_list(&data->raw_response_list); + init_list(&data->raw_query_list); + init_list(&data->raw_packet_list); + init_list(&data->query_list); + init_list(&data->packet_list); data->node_tree = malloc(sizeof(avl_tree_test_t)); CHECK_ALLOC_LOG(data->node_tree, 0); @@ -1063,8 +1134,10 @@ static int init_data(test_data_t *data) static void print_stats(test_data_t *data) { - uint resp_count = 0, dname_count = 0, edns_count = 0, node_count = 0, - rdata_count = 0, rrset_count = 0, item_count = 0; + uint resp_count = 0, dname_count = 0, node_count = 0, + rdata_count = 0, rrset_count = 0, item_count = 0, query_count = 0, + raw_query_count = 0, response_count = 0, packet_count = 0, + raw_packet_count = 0, raw_response_count = 0; node *n = NULL; /* Will not be used */ @@ -1073,12 +1146,12 @@ static void print_stats(test_data_t *data) } WALK_LIST(n, data->rrset_list) { - node *tmp = NULL; - assert(((test_rrset_t *)n)->owner); - WALK_LIST(tmp, ((test_rrset_t *)n)->rdata_list) { - test_rdata_t *rdata = (test_rdata_t *)tmp; - assert(rdata->type == ((test_rrset_t *)n)->type); - } +// node *tmp = NULL; +// assert(((test_rrset_t *)n)->owner); +// WALK_LIST(tmp, ((test_rrset_t *)n)->rdata_list) { +// test_rdata_t *rdata = (test_rdata_t *)tmp; +// assert(rdata->type == ((test_rrset_t *)n)->type); +// } rrset_count++; } @@ -1098,8 +1171,36 @@ static void print_stats(test_data_t *data) item_count++; } - printf("Loaded: Responses: %d RRSets: %d RDATAs: %d Dnames: %d Nodes: %d Items: %d\n", resp_count, rrset_count, - rdata_count, dname_count, node_count, item_count); + WALK_LIST(n, data->raw_response_list) { + raw_response_count++; + } + + WALK_LIST(n, data->query_list) { + query_count++; + } + + WALK_LIST(n, data->response_list) { + response_count++; + } + + WALK_LIST(n, data->raw_query_list) { + raw_query_count++; + } + + WALK_LIST(n, data->packet_list) { + packet_count++; + } + + WALK_LIST(n, data->raw_packet_list) { + raw_packet_count++; + } + + printf("Loaded: Responses: %d RRSets: %d RDATAs: %d Dnames: %d " + "Nodes: %d Items: %d Raw_responses: %d Queries: %d \n" + "Raw_queries; %d Total packets: %d Total_raw_packets: %d\n", resp_count, rrset_count, + rdata_count, dname_count, node_count, item_count, + raw_response_count, query_count, raw_query_count, packet_count, + raw_packet_count); } static void save_node_to_list(test_node_t *n, void *p) @@ -1111,7 +1212,7 @@ static void save_node_to_list(test_node_t *n, void *p) static void del_node(test_node_t *n, void *p) { - test_data_t *data = (test_data_t *)p; +// test_data_t *data = (test_data_t *)p; free(n); } @@ -1148,7 +1249,17 @@ test_data_t *create_test_data_from_dump() return NULL; } - uint response_count; + uint32_t raw_packet_count = 0; + + if (load_raw_packets(ret, &raw_packet_count, raw_data_rc, + raw_data_rc_size) != 0) { + fprintf(stderr, "Could not load raw_data, quitting"); + /* TODO walk the lists*/ + free(ret); + return NULL; + } + + uint32_t response_count = 0; if (load_parsed_responses(ret, &response_count, parsed_data_rc, parsed_data_rc_size) != 0) { diff --git a/src/dnslib/tests/realdata/dnslib_tests_loader_realdata.h b/src/dnslib/tests/realdata/dnslib_tests_loader_realdata.h index 69c9be591de47a422eb1900562a3805d3493ecc8..0fa0a555840734a12e28e8dcea5fd57f1cf96c79 100644 --- a/src/dnslib/tests/realdata/dnslib_tests_loader_realdata.h +++ b/src/dnslib/tests/realdata/dnslib_tests_loader_realdata.h @@ -9,12 +9,13 @@ /* Parsed raw packet*/ -//struct test_raw_packet { -// uint size; -// uint8_t *data; -//}; +struct test_raw_packet { + struct node *next, *prev; + uint size; + uint8_t *data; +}; -/*typedef struct test_raw_packet test_raw_packet_t*/; +typedef struct test_raw_packet test_raw_packet_t; /* Test type definitions */ @@ -105,6 +106,7 @@ typedef struct test_rrset test_rrset_t; struct test_response { struct node *next, *prev; /* This is basically same thing as actual response structure */ + uint16_t query; test_dname_t *qname; uint16_t qclass; uint16_t qtype; @@ -140,7 +142,13 @@ struct test_data { list node_list; list rrset_list; list response_list; + list raw_response_list; + list query_list; + list raw_query_list; list item_list; + /* responses and queries together */ + list packet_list; + list raw_packet_list; avl_tree_test_t *node_tree; }; diff --git a/src/dnslib/tests/realdata/files/parsed_data b/src/dnslib/tests/realdata/files/parsed_data index 4027c920d2d6372d570efbb2798f40ec194c8135..fe22b9017fc6ee4e1dca6a23bf5bd4e1e639d54b 100644 Binary files a/src/dnslib/tests/realdata/files/parsed_data and b/src/dnslib/tests/realdata/files/parsed_data differ diff --git a/src/dnslib/tests/realdata/files/raw_data b/src/dnslib/tests/realdata/files/raw_data index f94236b9fc5d70073b843252366d7436bea4c503..502005e96b582b149f611e1a1e1feab1d7a696cc 100644 Binary files a/src/dnslib/tests/realdata/files/raw_data and b/src/dnslib/tests/realdata/files/raw_data differ diff --git a/src/dnslib/tests/realdata/unittests_dnslib_realdata.c b/src/dnslib/tests/realdata/unittests_dnslib_realdata.c index e5f81825451d36c7b3849434b35977364cac17be..d48eee05f3e19eeaa78f10e9da375925a491e15f 100644 --- a/src/dnslib/tests/realdata/unittests_dnslib_realdata.c +++ b/src/dnslib/tests/realdata/unittests_dnslib_realdata.c @@ -9,10 +9,12 @@ //#include "dnslib/edns_tests.h" #include "dnslib/node_tests_realdata.h" #include "dnslib/rdata_tests_realdata.h" -#include "dnslib/response_tests_realdata.h" +//#include "dnslib/response_tests_realdata.h" +#include "dnslib/response2_tests_realdata.h" #include "dnslib/rrset_tests_realdata.h" //#include "dnslib/zone_tests_realdata.h" #include "dnslib/zonedb_tests_realdata.h" +#include "dnslib/packet_tests_realdata.h" #include "common/lists.h" // Run all loaded units @@ -37,7 +39,9 @@ int main(int argc, char *argv[]) // &edns_tests_api, //! DNS library (EDNS0) unit &node_tests_api, //! DNS library (node) unit &rdata_tests_api, //! DNS library (rdata) unit - &response_tests_api, //! DNS library (response) unit + &packet_tests_api, +// &response_tests_api, //! DNS library (response) unit + &response2_tests_api, //! DNS library (response) unit &rrset_tests_api, //! DNS library (rrset) unit // &zone_tests_api, //! DNS library (zone) unit // &zonedb_tests_api, //! DNS library (zonedb) unit diff --git a/src/dnslib/tests/unittests_dnslib.c b/src/dnslib/tests/unittests_dnslib.c index 860fd2e265b956410948dc6e9fa7f221a7394d57..3b6a496a7b9dd8ad228a037c4f2959c82935b544 100644 --- a/src/dnslib/tests/unittests_dnslib.c +++ b/src/dnslib/tests/unittests_dnslib.c @@ -8,9 +8,13 @@ #include "dnslib/edns_tests.h" #include "dnslib/node_tests.h" #include "dnslib/rdata_tests.h" -//#include "dnslib/response_tests.h" +#include "dnslib/response2_tests.h" #include "dnslib/rrset_tests.h" #include "dnslib/zone_tests.h" +#include "dnslib/dname_table_tests.h" +#include "dnslib/nsec3_tests.h" +#include "dnslib/packet_tests.h" +#include "dnslib/query_tests.h" #include "dnslib/zonedb_tests.h" // Run all loaded units @@ -26,12 +30,16 @@ int main(int argc, char *argv[]) &cuckoo_tests_api, //! Cuckoo hashing unit &dname_tests_api, //! DNS library (dname) unit &edns_tests_api, //! DNS library (EDNS0) unit - &node_tests_api, //! DNS library (node) unit +// &node_tests_api, //! DNS library (node) unit &rdata_tests_api, //! DNS library (rdata) unit -// &response_tests_api, //! DNS library (response) unit + &response2_tests_api, //! DNS library (response) unit &rrset_tests_api, //! DNS library (rrset) unit - &zone_tests_api, //! DNS library (zone) unit + &dname_table_tests_api, + &nsec3_tests_api, + &packet_tests_api, + &query_tests_api, &zonedb_tests_api, //! DNS library (zonedb) unit + &zone_tests_api, //! DNS library (zone) unit NULL }; diff --git a/src/dnslib/zone-dump.h b/src/dnslib/zone-dump.h index 11b7014f2b3e37cfd4c39d99243c95319b941df0..4f24f59f296eba1238f47d0137f20779f6cf2596 100644 --- a/src/dnslib/zone-dump.h +++ b/src/dnslib/zone-dump.h @@ -53,6 +53,21 @@ int dnslib_zdump_binary(dnslib_zone_contents_t *zone, const char *filename, int dnslib_zdump_rrset_serialize(const dnslib_rrset_t *rrset, uint8_t **stream, size_t *size); +/*! + * \brief Serializes RRSet into binary stream. Expects NULL pointer, memory + * is handled inside function. + * + * \param rrset RRSet to be serialized. + * \param stream Stream containing serialized RRSet. + * \param size Length of created stream. + * + * \retval DNSLIB_EOK on success. + * \retval DNSLIB_EBADARG if wrong arguments are supplied. + * \retval DNSLIB_ENOMEM on memory error. + */ +int dnslib_zdump_rrset_serialize(const dnslib_rrset_t *rrset, uint8_t **stream, + size_t *size); + #endif /* _DNSLIB_ZONEDUMP_H_ */ /*! @} */