diff --git a/src/Makefile.am b/src/Makefile.am index d4890476a4ccb73806c7e014c649f1c5b5b16e42..0942c967b1fce2eb2c6981a45e4bc907740b10be 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -28,6 +28,9 @@ knot_zcompile_SOURCES = \ libknot/util/utils.h \ libknot/util/tolower.h \ libknot/util/tolower.c \ + libknot/util/wire.h \ + libknot/packet/packet.h \ + libknot/packet/packet.c \ libknot/zone/zone.c \ libknot/zone/zone-contents.c \ libknot/zone/zone-tree.c \ @@ -38,12 +41,18 @@ knot_zcompile_SOURCES = \ libknot/zone/node.c \ libknot/zone/dname-table.h \ libknot/zone/dname-table.c \ + libknot/zone/zonedb.h \ + libknot/zone/zonedb.c \ libknot/dname.c \ libknot/dname.h \ libknot/nsec3.h \ libknot/nsec3.c \ libknot/edns.h \ libknot/edns.c \ + libknot/tsig.h \ + libknot/tsig.c \ + libknot/tsig-op.h \ + libknot/tsig-op.c \ common/slab/slab.h \ common/libtap/tap.c \ common/libtap/tap.h \ diff --git a/src/libknot/packet/packet.c b/src/libknot/packet/packet.c index 5cda0716f0b4a84cfd7e075f9a9e40c334e494e6..88b6efa2a576ffe4d10ec1fffd9c5641ba51ad45 100644 --- a/src/libknot/packet/packet.c +++ b/src/libknot/packet/packet.c @@ -355,26 +355,65 @@ static int knot_packet_realloc_rrsets(const knot_rrset_t ***rrsets, /*----------------------------------------------------------------------------*/ -static knot_rdata_t *knot_packet_parse_rdata(const uint8_t *wire, - size_t *pos, size_t total_size, size_t rdlength, - const knot_rrtype_descriptor_t *desc) +static int knot_packet_parse_rdata(knot_rrset_t *rr, const uint8_t *wire, + size_t *pos, size_t total_size, + size_t rdlength) { - knot_rdata_t *rdata = knot_rdata_new(); - if (rdata == NULL) { - return NULL; + if (!rr || !wire || !pos || rdlength == 0) { + return KNOT_EINVAL; + } + + /*! \todo As I'm revising it, seems highly inefficient to me. + * We just need to skim through the packet, + * check if it is in valid format and store pointers to various + * parts in rdata instead of copying memory blocks and + * parsing domain names (with additional allocation) and then + * use use the wireformat for lookup again. Compression could + * be handled in-situ without additional memory allocs... + */ + + uint8_t* rd = knot_rrset_create_rdata(rr, rdlength); + if (!rd) { + return KNOT_ERROR; + } + uint8_t* np = rd + rdlength; + + const rdata_descriptor_t *desc = get_rdata_descriptor(knot_rrset_type(rr)); + if (!desc) { + /*! \todo Free rdata mem ? Not essential, but nice. */ + return KNOT_EINVAL; } - int rc = knot_rdata_from_wire(rdata, wire, pos, total_size, rdlength, - desc); - - if (rc != KNOT_EOK) { - dbg_packet("rdata_from_wire() returned: %s\n", - knot_strerror(rc)); - knot_rdata_free(&rdata); - return NULL; + for (int i = 0; desc->block_types[i] != KNOT_RDATA_WF_END; i++) { + const int id = desc->block_types[i]; + if (descriptor_item_is_dname(id)) { + knot_dname_t *dn = NULL; + dn = knot_dname_parse_from_wire(wire, pos, total_size, NULL); + if (dn == NULL) { + return KNOT_EMALF; + } + /* Store ptr in rdata. */ + *((knot_dname_t**)rd) = dn; + rd += sizeof(knot_dname_t*); + } else if (descriptor_item_is_fixed(id)) { + memcpy(rd, wire + *pos, id); + rd += id; /* Item represents fixed len here */ + *pos += id; + } else if (descriptor_item_is_remainder(id)) { + size_t rchunk = np - rd; + memcpy(rd, wire + *pos, rchunk); + rd += rchunk; + *pos += rchunk; + break; + } else { + //NAPTR + assert(knot_rrset_type(rr) == KNOT_RRTYPE_NAPTR); + assert(0); + } + } - return rdata; + return KNOT_EOK; } /*----------------------------------------------------------------------------*/ @@ -434,7 +473,7 @@ dbg_packet_exec_verb( if (size - *pos < rdlength) { dbg_packet("Malformed RR: Not enough data to parse RR" " RDATA (size: %zu, position: %zu).\n", size, *pos); - knot_rrset_deep_free(&rrset, 1, 1, 0); + knot_rrset_deep_free(&rrset, 1, 1); return NULL; } @@ -443,21 +482,15 @@ dbg_packet_exec_verb( if (rdlength == 0) { return rrset; } - + + // parse RDATA - knot_rdata_t *rdata = knot_packet_parse_rdata(wire, pos, size, - rdlength, - knot_rrtype_descriptor_by_type(rrset->type)); - if (rdata == NULL) { + /*! \todo Merge with add_rdata_to_rr in zcompile, should be a rrset func + * probably. */ + int ret = knot_packet_parse_rdata(rrset, wire, pos, size, rdlength); + if (ret != KNOT_EOK) { dbg_packet("Malformed RR: Could not parse RDATA.\n"); - knot_rrset_deep_free(&rrset, 1, 1, 0); - return NULL; - } - - if (knot_rrset_add_rdata(rrset, rdata) != KNOT_EOK) { - dbg_packet("Malformed RR: Could not add RDATA to RRSet.\n"); - knot_rdata_free(&rdata); - knot_rrset_deep_free(&rrset, 1, 1, 0); + knot_rrset_deep_free(&rrset, 1, 1); return NULL; } @@ -577,7 +610,7 @@ static int knot_packet_parse_rrs(const uint8_t *wire, size_t *pos, break; } else if (err > 0) { // merged dbg_packet_detail("RRSet merged, freeing.\n"); - knot_rrset_deep_free(&rrset, 1, 0, 0); // TODO: ok?? + knot_rrset_deep_free(&rrset, 1, 0); // TODO: ok?? continue; } @@ -586,7 +619,7 @@ static int knot_packet_parse_rrs(const uint8_t *wire, size_t *pos, // remove the last RRSet from the list of RRSets // - just decrement the count --(*rrset_count); - knot_rrset_deep_free(&rrset, 1, 1, 1); + knot_rrset_deep_free(&rrset, 1, 1); break; } @@ -1085,7 +1118,7 @@ uint16_t knot_packet_qtype(const knot_packet_t *packet) /*----------------------------------------------------------------------------*/ -void knot_packet_set_qtype(knot_packet_t *packet, knot_rr_type_t qtype) +void knot_packet_set_qtype(knot_packet_t *packet, uint16_t qtype) { assert(packet != NULL); packet->question.qtype = qtype; @@ -1359,7 +1392,7 @@ dbg_packet_exec( // TODO: this is quite ugly, but better than copying whole // function (for reallocating rrset array) knot_rrset_deep_free( - &(((knot_rrset_t **)(pkt->tmp_rrsets))[i]), 1, 1, 1); + &(((knot_rrset_t **)(pkt->tmp_rrsets))[i]), 1, 1); } } diff --git a/src/libknot/packet/packet.h b/src/libknot/packet/packet.h index cd12370e6ed87298b7734c2dead1fcbc08324630..eb936278a42d3b0657a5a7ad843b2abc41cafd25 100644 --- a/src/libknot/packet/packet.h +++ b/src/libknot/packet/packet.h @@ -370,7 +370,7 @@ uint16_t knot_packet_qtype(const knot_packet_t *packet); * \param packet Packet containing question. * \param qtype New QTYPE for question. */ -void knot_packet_set_qtype(knot_packet_t *packet, int qtype); +void knot_packet_set_qtype(knot_packet_t *packet, uint16_t qtype); /*!