]> git.ipfire.org Git - thirdparty/ldns.git/commitdiff
HIP rdata as RDF type
authorWillem Toorop <willem@nlnetlabs.nl>
Fri, 27 Sep 2013 09:26:05 +0000 (11:26 +0200)
committerWillem Toorop <willem@nlnetlabs.nl>
Fri, 27 Sep 2013 09:26:05 +0000 (11:26 +0200)
Todo accessor functions for algorithm, hit and pk

examples/ldns-dpa.c
host2str.c
host2wire.c
ldns/host2str.h
ldns/str2host.h
rdata.c
rr.c
str2host.c
wire2host.c

index c5717b245e9e7e1a2ff3d86aed8e0b87cf1817af..0bc8a84032969e0fa91bff3de758f3ea7bc14087 100644 (file)
@@ -2823,13 +2823,13 @@ int main(int argc, char *argv[]) {
 }
 
 #else
-int main() {
+int main(void) {
        fprintf(stderr, "ldns-dpa was not built because there is no pcap library on this system, or there was no pcap header file at compilation time. Please install pcap and rebuild.\n");
        return 1;
 }
 #endif
 #else
-int main() {
+int main(void) {
        fprintf(stderr, "ldns-dpa was not built because there is no pcap library on this system, or there was no pcap header file at compilation time. Please install pcap and rebuild.\n");
        return 1;
 }
index d28da4b0d4c6997149d85a97a0a55ad02e51fd02..264aa11b86f4a1da2014b19a4544086a1dc46ec4 100644 (file)
@@ -1237,6 +1237,49 @@ ldns_rdf2buffer_str_long_str(ldns_buffer *output, const ldns_rdf *rdf)
        return ldns_buffer_status(output);
 }
 
+ldns_status
+ldns_rdf2buffer_str_hip(ldns_buffer *output, const ldns_rdf *rdf)
+{
+       uint8_t *data = ldns_rdf_data(rdf);
+       size_t rdf_size = ldns_rdf_size(rdf);
+       uint8_t hit_size;
+       uint16_t pk_size;
+       int written;
+       
+       if (rdf_size < 6) {
+               return LDNS_STATUS_WIRE_RDATA_ERR;
+       }
+       if ((hit_size = data[0]) == 0 ||
+                       (pk_size = ldns_read_uint16(data + 2)) == 0 ||
+                       rdf_size < (size_t) hit_size + pk_size + 4) {
+
+               return LDNS_STATUS_WIRE_RDATA_ERR;
+       }
+
+       ldns_buffer_printf(output, "%d ", (int) data[1]);
+
+       for (data += 4; hit_size > 0; hit_size--, data++) {
+
+               ldns_buffer_printf(output, "%02x", (int) *data);
+       }
+       ldns_buffer_write_u8(output, ' ');
+
+       if (ldns_buffer_reserve(output,
+                               ldns_b64_ntop_calculate_size(pk_size))) {
+
+               written = ldns_b64_ntop(data, pk_size,
+                               (char *) ldns_buffer_current(output),
+                               ldns_buffer_remaining(output));
+
+               if (written > 0 &&
+                               written < (int) ldns_buffer_remaining(output)) {
+
+                       output->_position += written;
+               }
+       }
+       return ldns_buffer_status(output);
+}
+
 ldns_status
 ldns_rdf2buffer_str_fmt(ldns_buffer *buffer,
                const ldns_output_format* fmt, const ldns_rdf *rdf)
@@ -1311,6 +1354,9 @@ ldns_rdf2buffer_str_fmt(ldns_buffer *buffer,
                case LDNS_RDF_TYPE_TIME:
                        res = ldns_rdf2buffer_str_time(buffer, rdf);
                        break;
+               case LDNS_RDF_TYPE_HIP:
+                       res = ldns_rdf2buffer_str_hip(buffer, rdf);
+                       break;
                case LDNS_RDF_TYPE_LOC:
                        res = ldns_rdf2buffer_str_loc(buffer, rdf);
                        break;
index b529e83305e8cfe1b9a19b2358fe6f1898b020a8..8fb5c3a2ba598f8618065a075d4578324d06fb67 100644 (file)
@@ -81,63 +81,6 @@ ldns_rr_list2buffer_wire(ldns_buffer *buffer,const ldns_rr_list *rr_list)
        return ldns_buffer_status(buffer);
 }
 
-static ldns_status
-ldns_hip_rdata2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr)
-{
-       uint16_t i;
-
-       assert(ldns_rr_get_type(rr) == LDNS_RR_TYPE_HIP);
-
-       if (ldns_rr_rd_count(rr) >= 3 &&
-           ldns_rdf_get_type(ldns_rr_rdf(rr, 0)) == LDNS_RDF_TYPE_INT8 &&
-           ldns_rdf_get_type(ldns_rr_rdf(rr, 1)) == LDNS_RDF_TYPE_HEX  &&
-               ldns_rdf_size(ldns_rr_rdf(rr, 1)) >    0 &&
-               ldns_rdf_size(ldns_rr_rdf(rr, 1)) <= 255 &&
-           ldns_rdf_get_type(ldns_rr_rdf(rr, 2)) == LDNS_RDF_TYPE_B64) {
-
-               /* From RFC 5205 section 5. HIP RR Storage Format:
-                *************************************************
-
-       0                   1                   2                   3
-       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |  HIT length   | PK algorithm  |          PK length            |
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |                                                               |
-       ~                           HIT                                 ~
-       |                                                               |
-       +                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |                     |                                         |
-       +-+-+-+-+-+-+-+-+-+-+-+                                         +
-       |                           Public Key                          |
-       ~                                                               ~
-       |                                                               |
-       +                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |                               |                               |
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
-       |                                                               |
-       ~                       Rendezvous Servers                      ~
-       |                                                               |
-       +             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |             |
-       +-+-+-+-+-+-+-+                                                    */
-
-               ldns_buffer_write_u8(buffer,
-                                (uint8_t) ldns_rdf_size(ldns_rr_rdf(rr, 1)));
-               (void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr, 0));
-               ldns_buffer_write_u16(buffer,
-                               (uint16_t) ldns_rdf_size(ldns_rr_rdf(rr, 2)));
-               i = 1;
-       } else {
-               i = 0;
-       }
-       while (i < ldns_rr_rd_count(rr)) {
-               (void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr, i));
-               i++;
-       }
-       return ldns_buffer_status(buffer);
-}
-
 
 ldns_status
 ldns_rr2buffer_wire_canonical(ldns_buffer *buffer,
@@ -194,18 +137,13 @@ ldns_rr2buffer_wire_canonical(ldns_buffer *buffer,
                        rdl_pos = ldns_buffer_position(buffer);
                        ldns_buffer_write_u16(buffer, 0);
                }       
-
-               if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_HIP) {
-                       (void) ldns_hip_rdata2buffer_wire(buffer, rr);
-               } else {
-                       for (i = 0; i < ldns_rr_rd_count(rr); i++) {
-                               if (pre_rfc3597) {
-                                       (void) ldns_rdf2buffer_wire_canonical(
-                                               buffer, ldns_rr_rdf(rr, i));
-                               } else {
-                                       (void) ldns_rdf2buffer_wire(
-                                               buffer, ldns_rr_rdf(rr, i));
-                               }
+               for (i = 0; i < ldns_rr_rd_count(rr); i++) {
+                       if (pre_rfc3597) {
+                               (void) ldns_rdf2buffer_wire_canonical(
+                                       buffer, ldns_rr_rdf(rr, i));
+                       } else {
+                               (void) ldns_rdf2buffer_wire(
+                                       buffer, ldns_rr_rdf(rr, i));
                        }
                }
                if (rdl_pos != 0) {
@@ -239,13 +177,9 @@ ldns_rr2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr, int section)
                        rdl_pos = ldns_buffer_position(buffer);
                        ldns_buffer_write_u16(buffer, 0);
                }
-               if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_HIP) {
-                       (void) ldns_hip_rdata2buffer_wire(buffer, rr);
-               } else {
-                       for (i = 0; i < ldns_rr_rd_count(rr); i++) {
-                               (void) ldns_rdf2buffer_wire(
-                                               buffer, ldns_rr_rdf(rr, i));
-                       }
+               for (i = 0; i < ldns_rr_rd_count(rr); i++) {
+                       (void) ldns_rdf2buffer_wire(
+                                       buffer, ldns_rr_rdf(rr, i));
                }
                if (rdl_pos != 0) {
                        ldns_buffer_write_u16_at(buffer, rdl_pos,
@@ -269,7 +203,8 @@ ldns_rrsig2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr)
        /* Convert all the rdfs, except the actual signature data
         * rdf number 8  - the last, hence: -1 */
        for (i = 0; i < ldns_rr_rd_count(rr) - 1; i++) {
-               (void) ldns_rdf2buffer_wire_canonical(buffer, ldns_rr_rdf(rr, i));
+               (void) ldns_rdf2buffer_wire_canonical(buffer, 
+                               ldns_rr_rdf(rr, i));
        }
 
        return ldns_buffer_status(buffer);
@@ -279,9 +214,6 @@ ldns_status
 ldns_rr_rdata2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr)
 {
        uint16_t i;
-       if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_HIP) {
-               return ldns_hip_rdata2buffer_wire(buffer, rr);
-       }
        /* convert all the rdf's */
        for (i = 0; i < ldns_rr_rd_count(rr); i++) {
                (void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr,i));
@@ -310,7 +242,8 @@ ldns_hdr2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet)
                flags = ldns_pkt_ra(packet) << 7
                        /*| ldns_pkt_z(packet) << 6*/
                        | ldns_pkt_ad(packet) << 5
-                       | ldns_pkt_cd(packet) << 4 | ldns_pkt_get_rcode(packet);
+                       | ldns_pkt_cd(packet) << 4
+                       | ldns_pkt_get_rcode(packet);
                ldns_buffer_write_u8(buffer, flags);
                
                ldns_buffer_write_u16(buffer, ldns_pkt_qdcount(packet));
index 18e3d15f6fc393c278bd2b9340d372bd294eb6a2..d9497406a7784851e1be7fd2c7140c157e38ad34 100644 (file)
@@ -606,6 +606,15 @@ ldns_status ldns_rdf2buffer_str_eui48(ldns_buffer *output,
 ldns_status ldns_rdf2buffer_str_eui64(ldns_buffer *output,
                const ldns_rdf *rdf);
 
+ldns_status ldns_rdf2buffer_str_tag(ldns_buffer *output,
+               const ldns_rdf *rdf);
+
+ldns_status ldns_rdf2buffer_str_long_str(ldns_buffer *output,
+               const ldns_rdf *rdf);
+
+ldns_status ldns_rdf2buffer_str_hip(ldns_buffer *output,
+               const ldns_rdf *rdf);
+
 /**
  * Converts the data in the rdata field to presentation format and
  * returns that as a char *.
index 6dbf68a5f4b411c0cd65b2e5889fb16b2a1fb922..341aa248195856d4e14ed1c7e48ff292f4e8a541 100644 (file)
@@ -277,6 +277,17 @@ ldns_status ldns_str2rdf_tag(ldns_rdf **rd, const char *str);
  */
 ldns_status ldns_str2rdf_long_str(ldns_rdf **rd, const char *str);
 
+/**
+ * Convert a "<algorithm> <hit> <pk>" encoding of the value field as specified 
+ * in Section 6. of [RFC5205], encoded as wireformat as specified in Section 5.
+ * of [RFC5205].
+ * \param[in] rd the rdf where to put the data
+ * \param[in] str the string to be converted
+ * \return ldns_status
+ */
+ldns_status ldns_str2rdf_hip(ldns_rdf **rd, const char *str);
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/rdata.c b/rdata.c
index 9b3236dbaa54d75eb94a4d3fb541bbcae7953d47..2af1ee1e0c426a33a05b22535b5ae4b4ff5f274e 100644 (file)
--- a/rdata.c
+++ b/rdata.c
@@ -309,6 +309,9 @@ ldns_rdf_new_frm_str(ldns_rdf_type type, const char *str)
        case LDNS_RDF_TYPE_PERIOD:
                status = ldns_str2rdf_period(&rdf, str);
                break;
+       case LDNS_RDF_TYPE_HIP:
+               status = ldns_str2rdf_hip(&rdf, str);
+               break;
        case LDNS_RDF_TYPE_SERVICE:
                status = ldns_str2rdf_service(&rdf, str);
                break;
diff --git a/rr.c b/rr.c
index 14d3bb27d09dace409973be6e5b478fbd45f02e2..4b28f4de93f2bc96d57697b3f0e49a03489e9ab1 100644 (file)
--- a/rr.c
+++ b/rr.c
@@ -127,7 +127,7 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
        char  *type = NULL;
        char  *rdata = NULL;
        char  *rd = NULL;
-       char  * b64 = NULL;
+       char  *xtok = NULL; /* For RDF types with spaces (i.e. extra tokens) */
        size_t rd_strlen;
        const char *delimiters;
        ssize_t c;
@@ -161,7 +161,7 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
        rr_buf = LDNS_MALLOC(ldns_buffer);
        rd_buf = LDNS_MALLOC(ldns_buffer);
        rd = LDNS_XMALLOC(char, LDNS_MAX_RDFLEN);
-       b64 = LDNS_XMALLOC(char, LDNS_MAX_RDFLEN);
+       xtok = LDNS_XMALLOC(char, LDNS_MAX_RDFLEN);
        if (rr_buf) {
                rr_buf->_data = NULL;
        }
@@ -169,7 +169,7 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
                rd_buf->_data = NULL;
        }
        if (!new || !owner || !ttl || !clas || !rdata ||
-                       !rr_buf || !rd_buf || !rd || !b64) {
+                       !rr_buf || !rd_buf || !rd || !xtok) {
 
                goto memerror;
        }
@@ -487,10 +487,10 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
                                 * rdf types may contain spaces).
                                 */
                                if (r_cnt == r_max - 1) {
-                                       c = ldns_bget_token(rd_buf, b64,
+                                       c = ldns_bget_token(rd_buf, xtok,
                                                        "\n", LDNS_MAX_RDFLEN);
                                        if (c != -1) {
-                                               rd = strncat(rd, b64,
+                                               (void) strncat(rd, xtok,
                                                        LDNS_MAX_RDFLEN -
                                                        strlen(rd) - 1);
                                        }
@@ -499,6 +499,50 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
                                                ldns_rr_descriptor_field_type(
                                                        desc, r_cnt), rd);
                                break;
+
+                       case LDNS_RDF_TYPE_HIP:
+                               /*
+                                * In presentation format this RDATA type has
+                                * three tokens: An algorithm byte, then a
+                                * variable length HIT (in hexbytes) and then
+                                * a variable length Public Key (in base64).
+                                *
+                                * We have just read the algorithm, so we need
+                                * two more tokens: HIT and Public Key.
+                                */
+                               do {
+                                       /* Read and append HIT */
+                                       if (ldns_bget_token(rd_buf,
+                                                       xtok, delimiters,
+                                                       LDNS_MAX_RDFLEN) == -1)
+                                               break;
+
+                                       (void) strncat(rd, " ",
+                                                       LDNS_MAX_RDFLEN -
+                                                       strlen(rd) - 1);
+                                       (void) strncat(rd, xtok,
+                                                       LDNS_MAX_RDFLEN -
+                                                       strlen(rd) - 1);
+
+                                       /* Read and append Public Key*/
+                                       if (ldns_bget_token(rd_buf,
+                                                       xtok, delimiters,
+                                                       LDNS_MAX_RDFLEN) == -1)
+                                               break;
+
+                                       (void) strncat(rd, " ",
+                                                       LDNS_MAX_RDFLEN -
+                                                       strlen(rd) - 1);
+                                       (void) strncat(rd, xtok,
+                                                       LDNS_MAX_RDFLEN -
+                                                       strlen(rd) - 1);
+                               } while (false);
+
+                               r = ldns_rdf_new_frm_str(
+                                               ldns_rr_descriptor_field_type(
+                                                       desc, r_cnt), rd);
+                               break;
+
                        case LDNS_RDF_TYPE_DNAME:
                                r = ldns_rdf_new_frm_str(
                                                ldns_rr_descriptor_field_type(
@@ -555,7 +599,7 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
 
        } /* for (done = false, r_cnt = 0; !done && r_cnt < r_max; r_cnt++) */
        LDNS_FREE(rd);
-       LDNS_FREE(b64);
+       LDNS_FREE(xtok);
        ldns_buffer_free(rd_buf);
        ldns_buffer_free(rr_buf);
        LDNS_FREE(rdata);
@@ -594,7 +638,7 @@ error:
        LDNS_FREE(clas);
        LDNS_FREE(hex_data);
        LDNS_FREE(hex_data_str);
-       LDNS_FREE(b64);
+       LDNS_FREE(xtok);
        LDNS_FREE(rd);
        LDNS_FREE(rdata);
        ldns_rr_free(new);
@@ -1928,37 +1972,9 @@ static const ldns_rdf_type type_tlsa_wireformat[] = {
        LDNS_RDF_TYPE_INT8,
        LDNS_RDF_TYPE_HEX
 };
-
-/** 
- * With HIP, wire and presentation format are out of step.
- * In presentation format, we have:
- * - a PK algorithm presented as integer in range [0..255]
- * - a variable length HIT field presented as hexstring
- * - a variable length Public Key field presented as Base64
- *
- * Unfortunately in the wireformat the lengths of the variable
- * length HIT and Public Key fields do not directly preceed them.
- * In stead we have:
- * - 1 byte  HIT length: h
- * - 1 byte  PK algorithm
- * - 2 bytes Public Key length: p
- * - h bytes HIT
- * - p bytes Public Key
- *
- * In ldns those deviations from the conventions for rdata fields are best 
- * tackeled by letting the array refered to by the descriptor for HIP represent
- * host format only.
- *
- * BEWARE! Unlike other RR types, actual HIP wire format does not directly
- * follow the RDF types enumerated in the array pointed to by _wireformat in
- * its descriptor record.
- */
-static const ldns_rdf_type type_hip_hostformat[] = {
-       LDNS_RDF_TYPE_INT8,
-       LDNS_RDF_TYPE_HEX,
-       LDNS_RDF_TYPE_B64
+static const ldns_rdf_type type_hip_wireformat[] = {
+       LDNS_RDF_TYPE_HIP
 };
-
 static const ldns_rdf_type type_nid_wireformat[] = {
        LDNS_RDF_TYPE_INT16,
        LDNS_RDF_TYPE_ILNP64
@@ -2115,12 +2131,8 @@ static ldns_rr_descriptor rdata_field_descriptors[] = {
         * Hip ends with 0 or more Rendezvous Servers represented as dname's.
         * Hence the LDNS_RDF_TYPE_DNAME _variable field and the _maximum field
         * set to 0.
-        *
-        * BEWARE! Unlike other RR types, actual HIP wire format does not 
-        * directly follow the RDF types enumerated in the array pointed to
-        * by _wireformat. For more info see type_hip_hostformat declaration.
         */
-       {LDNS_RR_TYPE_HIP, "HIP", 3, 3, type_hip_hostformat, LDNS_RDF_TYPE_DNAME, LDNS_RR_NO_COMPRESS, 0 },
+       {LDNS_RR_TYPE_HIP, "HIP", 1, 1, type_hip_wireformat, LDNS_RDF_TYPE_DNAME, LDNS_RR_NO_COMPRESS, 0 },
 
 #ifdef DRAFT_RRTYPES
        /* 56 */
index 3c2f95847e22f35ec207973018f526fe24a592d3..d4c33616bb275c096cb0342cb73505ce51de10b0 100644 (file)
@@ -1476,3 +1476,94 @@ ldns_str2rdf_long_str(ldns_rdf **rd, const char *str)
        return LDNS_STATUS_OK;
 }
 
+ldns_status
+ldns_str2rdf_hip(ldns_rdf **rd, const char *str)
+{
+       const char *hit = strchr(str, ' ') + 1;
+       const char *pk  = hit == NULL ? NULL : strchr(hit, ' ') + 1;
+       size_t hit_size = hit == NULL ? 0
+                       : pk  == NULL ? strlen(hit) : (size_t) (pk - hit) - 1;
+       size_t  pk_size = pk  == NULL ? 0 : strlen(pk);
+       size_t hit_wire_size = (hit_size + 1) / 2;
+       size_t  pk_wire_size = ldns_b64_pton_calculate_size(pk_size);
+       size_t rdf_size = 4 + hit_wire_size + pk_wire_size;
+
+       char *endptr; /* utility var for strtol usage */
+       int algorithm = strtol(str, &endptr, 10);
+
+       uint8_t *data, *dp;
+       int hi, lo, written;
+
+       if (hit_size == 0 || pk_size == 0 || (hit_size + 1) / 2 > 255
+                       || rdf_size > LDNS_MAX_RDFLEN
+                       || algorithm < 0 || algorithm > 255
+                       || (errno != 0 && algorithm == 0) /* out of range */
+                       || endptr == str                  /* no digits    */) {
+
+               return LDNS_STATUS_SYNTAX_ERR;
+       }
+       if ((data = LDNS_XMALLOC(uint8_t, rdf_size)) == NULL) {
+
+               return LDNS_STATUS_MEM_ERR;
+       }
+       /* From RFC 5205 section 5. HIP RR Storage Format:
+        *************************************************
+
+       0                   1                   2                   3
+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |  HIT length   | PK algorithm  |          PK length            |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                                                               |
+       ~                           HIT                                 ~
+       |                                                               |
+       +                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                     |                                         |
+       +-+-+-+-+-+-+-+-+-+-+-+                                         +
+       |                           Public Key                          |
+       ~                                                               ~
+       |                                                               |
+       +                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                               |                               |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
+       |                                                               |
+       ~                       Rendezvous Servers                      ~
+       |                                                               |
+       +             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |             |
+       +-+-+-+-+-+-+-+                                                    */
+
+       data[0] = (uint8_t) hit_wire_size;
+       data[1] = (uint8_t) algorithm;
+
+       for (dp = data + 4; *hit && *hit != ' '; dp++) {
+
+               if ((hi = ldns_hexdigit_to_int(*hit++)) == -1 ||
+                   (lo = ldns_hexdigit_to_int(*hit++)) == -1) {
+
+                       LDNS_FREE(data);
+                       return LDNS_STATUS_INVALID_HEX;
+               }
+               *dp = hi << 4 | lo;
+       }
+       if ((written = ldns_b64_pton(pk, dp, pk_wire_size)) <= 0) {
+
+               LDNS_FREE(data);
+               return LDNS_STATUS_INVALID_B64;
+       }
+
+       /* Because ldns_b64_pton_calculate_size isn't always correct:
+        * (we have to fix it at some point)
+        */
+       pk_wire_size = (uint16_t) written;
+       ldns_write_uint16(data + 2, pk_wire_size);
+       rdf_size = 4 + hit_wire_size + pk_wire_size;
+
+       /* Create rdf */
+       if (! (*rd = ldns_rdf_new(LDNS_RDF_TYPE_HIP, rdf_size, data))) {
+
+               LDNS_FREE(data);
+               return LDNS_STATUS_MEM_ERR;
+       }
+       return LDNS_STATUS_OK;
+}
index 40484c0719e1ae183d3908dde59fec74baf71142..f305808c2851105f3bfd4908b62d0b0f4eed6dde 100644 (file)
@@ -166,8 +166,6 @@ ldns_wire2rdf(ldns_rr *rr, const uint8_t *wire, size_t max, size_t *pos)
        ldns_rdf_type cur_rdf_type;
        const ldns_rr_descriptor *descriptor;
        ldns_status status;
-       uint8_t  hip_hit_length;
-       uint16_t hip_pubkey_length;
 
        assert(rr != NULL);
 
@@ -186,78 +184,7 @@ ldns_wire2rdf(ldns_rr *rr, const uint8_t *wire, size_t max, size_t *pos)
 
        end = *pos + (size_t) rd_length;
 
-       if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_HIP) {
-
-               /* From RFC 5205 section 5. HIP RR Storage Format:
-                *************************************************
-
-       0                   1                   2                   3
-       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |  HIT length   | PK algorithm  |          PK length            |
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |                                                               |
-       ~                           HIT                                 ~
-       |                                                               |
-       +                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |                     |                                         |
-       +-+-+-+-+-+-+-+-+-+-+-+                                         +
-       |                           Public Key                          |
-       ~                                                               ~
-       |                                                               |
-       +                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |                               |                               |
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
-       |                                                               |
-       ~                       Rendezvous Servers                      ~
-       |                                                               |
-       +             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |             |
-       +-+-+-+-+-+-+-+                                                    */
-
-               /* Space for HIT length, PK algorithm, PK length available? */
-               if (*pos + 4 > end) {
-                       return LDNS_STATUS_PACKET_OVERFLOW;
-               }
-               /* Get HIT length and PK length */
-               hip_hit_length = wire[*pos];
-               hip_pubkey_length = ldns_read_uint16(&wire[*pos + 2]);
-
-               /* Space for HIT length, PK algorithm, PK length, HIT and
-                * Public Key  available?
-                */
-               if (*pos + 4 + hip_hit_length + hip_pubkey_length > end) {
-                       return LDNS_STATUS_PACKET_OVERFLOW;
-               }
-               /* Read PK algorithm rdf */
-               cur_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT8,
-                               1, &wire[*pos + 1]);
-               if (cur_rdf) {
-                       ldns_rr_push_rdf(rr, cur_rdf);
-               }
-               *pos += 4;
-
-               /* Read HIT rdf */
-               cur_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX,
-                               hip_hit_length, &wire[*pos]);
-               if (cur_rdf) {
-                       ldns_rr_push_rdf(rr, cur_rdf);
-               }
-               *pos += hip_hit_length;
-
-               /* Read Public Key rdf */
-               cur_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64,
-                               hip_pubkey_length, &wire[*pos]);
-               if (cur_rdf) {
-                       ldns_rr_push_rdf(rr, cur_rdf);
-               }
-               *pos += hip_pubkey_length;
-
-               /* Variable number of Rendezvous Servers may follow */
-               rdf_index = 3;
-       } else {
-               rdf_index = 0;
-       }
+       rdf_index = 0;
        while (*pos < end &&
                        rdf_index < ldns_rr_descriptor_maximum(descriptor)) {
 
@@ -317,6 +244,14 @@ ldns_wire2rdf(ldns_rr *rr, const uint8_t *wire, size_t max, size_t *pos)
                        cur_rdf_length =
                                (size_t) ldns_read_uint16(&wire[*pos]) + 2;
                        break;
+               case LDNS_RDF_TYPE_HIP:
+                       if (*pos + 4 > end) {
+                               return LDNS_STATUS_PACKET_OVERFLOW;
+                       }
+                       cur_rdf_length =
+                               (size_t) wire[*pos] + 
+                               (size_t) ldns_read_uint16(&wire[*pos + 2]) + 4;
+                       break;
                case LDNS_RDF_TYPE_B32_EXT:
                case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER:
                        /* length is stored in first byte */