]> git.ipfire.org Git - thirdparty/ldns.git/commitdiff
AMTRELAY draft rr type
authorWillem Toorop <willem@nlnetlabs.nl>
Wed, 10 Jul 2019 10:53:38 +0000 (12:53 +0200)
committerWillem Toorop <willem@nlnetlabs.nl>
Wed, 10 Jul 2019 10:53:38 +0000 (12:53 +0200)
enable with --enable-rrtype-amtrelay

configure.ac
host2str.c
ldns/host2str.h
ldns/rdata.h
ldns/rr.h
ldns/str2host.h
rdata.c
rr.c
str2host.c
wire2host.c

index 9368c370f79386157bd7bc93f90dfd4be8821dee..401902970dc9a08709e91af41b11e30bb1534b0d 100644 (file)
@@ -647,6 +647,15 @@ case "$enable_rrtype_doa" in
        no|*)
                ;;
 esac
+AC_ARG_ENABLE(rrtype-amtrelay, AC_HELP_STRING([--enable-rrtype-amtrelay], [Enable draft RR type AMTRELAY.]))
+case "$enable_rrtype_amtrelay" in
+       yes)
+               AC_DEFINE_UNQUOTED([RRTYPE_AMTRELAY], [], [Define this to enable RR type AMTRELAY.])
+               ;;
+       no|*)
+               ;;
+esac
+
 
 
 AC_SUBST(LIBSSL_CPPFLAGS)
index 154504c80629bf56102ef793831bb71f34e38757..474ab9930b5bd96ae4a53438a85751fa6e8454f6 100644 (file)
@@ -1290,6 +1290,93 @@ ldns_rdf2buffer_str_hip(ldns_buffer *output, const ldns_rdf *rdf)
        return ldns_buffer_status(output);
 }
 
+/* implementation mimiced from ldns_rdf2buffer_str_ipseckey */
+ldns_status
+ldns_rdf2buffer_str_amtrelay(ldns_buffer *output, const ldns_rdf *rdf)
+{
+       /* wire format from
+        * draft-ietf-mboned-driad-amt-discovery Section 4.2  
+        */
+       uint8_t *data = ldns_rdf_data(rdf);
+       uint8_t precedence;
+       uint8_t discovery_optional;
+       uint8_t relay_type;
+
+       ldns_rdf *relay = NULL;
+       uint8_t *relay_data;
+
+       size_t offset = 0;
+       ldns_status status;
+
+       if (ldns_rdf_size(rdf) < 2) {
+               return LDNS_STATUS_WIRE_RDATA_ERR;
+       }
+       precedence = data[0];
+       discovery_optional = ((data[1] & 0x80) >> 7);
+       relay_type = data[1] & 0x7F;
+       offset = 2;
+
+       switch (relay_type) {
+               case 0:
+                       /* no relay */
+                       break;
+               case 1:
+                       relay_data = LDNS_XMALLOC(uint8_t, LDNS_IP4ADDRLEN);
+                        if(!relay_data)
+                                return LDNS_STATUS_MEM_ERR;
+                       if (ldns_rdf_size(rdf) < offset + LDNS_IP4ADDRLEN) {
+                               return LDNS_STATUS_ERR;
+                       }
+                       memcpy(relay_data, &data[offset], LDNS_IP4ADDRLEN);
+                       relay = ldns_rdf_new(LDNS_RDF_TYPE_A,
+                                       LDNS_IP4ADDRLEN , relay_data);
+                       offset += LDNS_IP4ADDRLEN;
+                        if(!relay) {
+                                LDNS_FREE(relay_data);
+                                return LDNS_STATUS_MEM_ERR;
+                        }
+                       break;
+               case 2:
+                       relay_data = LDNS_XMALLOC(uint8_t, LDNS_IP6ADDRLEN);
+                        if(!relay_data)
+                                return LDNS_STATUS_MEM_ERR;
+                       if (ldns_rdf_size(rdf) < offset + LDNS_IP6ADDRLEN) {
+                               return LDNS_STATUS_ERR;
+                       }
+                       memcpy(relay_data, &data[offset], LDNS_IP6ADDRLEN);
+                       offset += LDNS_IP6ADDRLEN;
+                       relay =
+                               ldns_rdf_new(LDNS_RDF_TYPE_AAAA,
+                                               LDNS_IP6ADDRLEN, relay_data);
+                        if(!relay) {
+                                LDNS_FREE(relay_data);
+                                return LDNS_STATUS_MEM_ERR;
+                        }
+                       break;
+               case 3:
+                       status = ldns_wire2dname(&relay, data,
+                                       ldns_rdf_size(rdf), &offset);
+                        if(status != LDNS_STATUS_OK)
+                                return status;
+                       break;
+               default:
+                       /* error? */
+                       break;
+       }
+
+       if (ldns_rdf_size(rdf) != offset) {
+               return LDNS_STATUS_ERR;
+       }
+       ldns_buffer_printf(output, "%u %u %u ",
+                       precedence, discovery_optional, relay_type);
+       if (relay)
+               (void) ldns_rdf2buffer_str(output, relay);
+
+       ldns_rdf_deep_free(relay);
+       return ldns_buffer_status(output);
+}
+
+
 static ldns_status
 ldns_rdf2buffer_str_fmt(ldns_buffer *buffer,
                const ldns_output_format* fmt, const ldns_rdf *rdf)
@@ -1405,6 +1492,9 @@ ldns_rdf2buffer_str_fmt(ldns_buffer *buffer,
                case LDNS_RDF_TYPE_LONG_STR:
                        res = ldns_rdf2buffer_str_long_str(buffer, rdf);
                        break;
+               case LDNS_RDF_TYPE_AMTRELAY:
+                       res = ldns_rdf2buffer_str_amtrelay(buffer, rdf);
+                       break;
                }
        } else {
                /** This will write mangled RRs */
index 325c562f5f49ecbb9d5461d6d3834b842f608c92..4b443d05f480db176093398e222b2713ea423933 100644 (file)
@@ -636,6 +636,17 @@ ldns_status ldns_rdf2buffer_str_long_str(ldns_buffer *output,
 ldns_status ldns_rdf2buffer_str_hip(ldns_buffer *output,
                const ldns_rdf *rdf);
 
+/** 
+ * Converts an LDNS_RDF_TYPE_AMTRELAY rdata element to presentation format for
+ * the precedence, D-bit, type and relay and adds it to the output buffer 
+ * \param[in] *rdf The rdata to convert
+ * \param[in] *output The buffer to add the data to
+ * \return LDNS_STATUS_OK on success, and error status on failure
+ */
+ldns_status ldns_rdf2buffer_str_amtrelay(ldns_buffer *output,
+               const ldns_rdf *rdf);
+
+
 /**
  * Converts the data in the rdata field to presentation format and
  * returns that as a char *.
index 981dd94a048479bc85dfe1e7316522f6e8e30b3a..2767e8b00b30f229049ea90e5c7209653facee4a 100644 (file)
@@ -139,6 +139,9 @@ enum ldns_enum_rdf_type
        LDNS_RDF_TYPE_SELECTOR,
        LDNS_RDF_TYPE_MATCHING_TYPE,
 
+       /** draft-ietf-mboned-driad-amt-discovery **/
+       LDNS_RDF_TYPE_AMTRELAY,
+
        /* Aliases */
        LDNS_RDF_TYPE_BITMAP = LDNS_RDF_TYPE_NSEC
 };
index 5039d73c5fc1f64f9c14a3da235bffc516446e12..89cc0b6f0046dbc2a0ca978148e889625cd4f49e 100644 (file)
--- a/ldns/rr.h
+++ b/ldns/rr.h
@@ -223,6 +223,9 @@ enum ldns_enum_rr_type
        LDNS_RR_TYPE_AVC = 258, /* Cisco's DNS-AS RR, see www.dns-as.org */
        LDNS_RR_TYPE_DOA = 259, /* draft-durand-doa-over-dns */
 
+       /** draft-ietf-mboned-driad-amt-discovery **/
+       LDNS_RR_TYPE_AMTRELAY = 260,
+
        /** DNSSEC Trust Authorities */
        LDNS_RR_TYPE_TA = 32768,
        /* RFC 4431, 5074, DNSSEC Lookaside Validation */
@@ -238,7 +241,7 @@ enum ldns_enum_rr_type
 typedef enum ldns_enum_rr_type ldns_rr_type;
 
 /* The first fields are contiguous and can be referenced instantly */
-#define LDNS_RDATA_FIELD_DESCRIPTORS_COMMON (LDNS_RR_TYPE_DOA + 1)
+#define LDNS_RDATA_FIELD_DESCRIPTORS_COMMON (LDNS_RR_TYPE_AMTRELAY + 1)
 
 /**
  * Resource Record
index d639970546ad68508226d5e6f06a2c830490eefe..e6f7004366b3c8d7443329c10e0ff3152f54069d 100644 (file)
@@ -311,6 +311,16 @@ ldns_status ldns_str2rdf_long_str(ldns_rdf **rd, const char *str);
  */
 ldns_status ldns_str2rdf_hip(ldns_rdf **rd, const char *str);
 
+/**
+ * Concert a"<precedence> <D-bit> <type> <relay>" encoding
+ * of the value field as specified in Section  4.3.1 of
+ * [draft-ietf-mboned-driad-amt-discovery], encoded as wireformat as specified in
+ * ection 4.2 of [draft-ietf-mboned-driad-amt-discovery]
+ * \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_amtrelay(ldns_rdf **rd, const char *str);
 
 #ifdef __cplusplus
 }
diff --git a/rdata.c b/rdata.c
index 3bc4b391e339a3475a2e85ecba133726233c7df2..caf853d618c8ca8c2fa77d04ee9cb6eb80376475 100644 (file)
--- a/rdata.c
+++ b/rdata.c
@@ -360,6 +360,9 @@ ldns_rdf_new_frm_str(ldns_rdf_type type, const char *str)
        case LDNS_RDF_TYPE_MATCHING_TYPE:
                status = ldns_str2rdf_matching_type(&rdf, str);
                break;
+       case LDNS_RDF_TYPE_AMTRELAY:
+               status = ldns_str2rdf_amtrelay(&rdf, str);
+               break;
        case LDNS_RDF_TYPE_NONE:
        default:
                /* default default ??? */
diff --git a/rr.c b/rr.c
index a6bf8da51aeac628d106861f80ae805ae8d1a422..ec73b007e89e9e066e4bbb2f703387118a471e4d 100644 (file)
--- a/rr.c
+++ b/rr.c
@@ -347,6 +347,7 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
                case LDNS_RDF_TYPE_LOC        : /* tain whitespace, only if */
                case LDNS_RDF_TYPE_WKS        : /* it is the last rd field. */
                case LDNS_RDF_TYPE_IPSECKEY   :
+               case LDNS_RDF_TYPE_AMTRELAY   :
                case LDNS_RDF_TYPE_NSEC       : if (r_cnt == r_max - 1) {
                                                        delimiters = "\n";
                                                        break;
@@ -2052,6 +2053,12 @@ static const ldns_rdf_type type_doa_wireformat[] = {
        LDNS_RDF_TYPE_B64
 };
 #endif
+#ifdef RRTYPE_AMTRELAY
+static const ldns_rdf_type type_amtrelay_wireformat[] = {
+       LDNS_RDF_TYPE_AMTRELAY
+};
+#endif
+
 
 /** \endcond */
 
@@ -2447,6 +2454,12 @@ static ldns_rr_descriptor rdata_field_descriptors[] = {
 #else
 {LDNS_RR_TYPE_NULL, "TYPE259", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 #endif
+#ifdef RRTYPE_AMTRELAY
+       /* 260 */
+       {LDNS_RR_TYPE_AMTRELAY, "AMTRELAY", 1, 1, type_amtrelay_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+#else
+{LDNS_RR_TYPE_NULL, "TYPE260", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+#endif
 
 /* split in array, no longer contiguous */
 
index 8a382e2bcf441aa72dfe8a02c8cc58650c2a329d..231453edbf7aff9d8c21f688103b1ee6725a1f6c 100644 (file)
@@ -1657,3 +1657,144 @@ ldns_str2rdf_hip(ldns_rdf **rd, const char *str)
        }
        return LDNS_STATUS_OK;
 }
+
+
+/* Implementation mimics ldns_str2rdf_ipseckey */
+ldns_status
+ldns_str2rdf_amtrelay(ldns_rdf **rd, const char *str)
+{
+       /* From draft-ietf-mboned-driad-amt-discovery
+        *      Section 4.2. AMTRELAY RData 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
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |   precedence  |D|    type     |                               |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
+       ~                            relay                              ~
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  */
+
+       uint8_t precedence = 0;
+       uint8_t relay_type = 0;
+       uint8_t discovery_optional = 0;
+       char* relay = NULL;
+       uint8_t *data;
+       ldns_buffer *str_buf;
+       char *token;
+       int token_count = 0;
+       int amtrelay_len = 0;
+       ldns_rdf* relay_rdf = NULL;
+       ldns_status status = LDNS_STATUS_OK;
+       
+       if(strlen(str) == 0)
+               token = LDNS_XMALLOC(char, 256);
+       else    token = LDNS_XMALLOC(char, strlen(str)+2);
+       if(!token) return LDNS_STATUS_MEM_ERR;
+
+       str_buf = LDNS_MALLOC(ldns_buffer);
+       if(!str_buf) {LDNS_FREE(token); return LDNS_STATUS_MEM_ERR;}
+       ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
+       if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
+               LDNS_FREE(str_buf);
+               LDNS_FREE(token);
+               return LDNS_STATUS_MEM_ERR;
+       }
+       while(ldns_bget_token(str_buf, token, "\t\n ", strlen(str)) > 0) {
+               switch (token_count) {
+               case 0:
+                       precedence = (uint8_t)atoi(token);
+                       break;
+               case 1:
+                       discovery_optional = (uint8_t)atoi(token);
+                       if (discovery_optional != 0 &&
+                           discovery_optional != 1) {
+                               LDNS_FREE(relay);
+                               LDNS_FREE(token);
+                               ldns_buffer_free(str_buf);
+                               return LDNS_STATUS_INVALID_STR;
+                       }
+                       break;
+               case 2:
+                       relay_type = (uint8_t)atoi(token);
+                       break;
+               case 3:
+                       relay = strdup(token);
+                       if (!relay || (relay_type == 0 &&
+                                       (token[0] != '.' || token[1] != '\0'))) {
+                               LDNS_FREE(relay);
+                               LDNS_FREE(token);
+                               ldns_buffer_free(str_buf);
+                               return LDNS_STATUS_INVALID_STR;
+                       }
+                       break;
+               default:
+                       LDNS_FREE(token);
+                       ldns_buffer_free(str_buf);
+                       return LDNS_STATUS_INVALID_STR;
+                       break;
+               }
+               token_count++;
+       }
+       if (!relay && relay_type > 0) {
+               if (relay)
+                       LDNS_FREE(relay);
+               LDNS_FREE(token);
+               ldns_buffer_free(str_buf);
+               return LDNS_STATUS_INVALID_STR;
+       }
+
+       if (relay_type == 1) {
+               status = ldns_str2rdf_a(&relay_rdf, relay);
+       } else if (relay_type == 2) {
+               status = ldns_str2rdf_aaaa(&relay_rdf, relay);
+       } else if (relay_type == 3) {
+               status = ldns_str2rdf_dname(&relay_rdf, relay);
+       } else if (relay_type > 3) {
+               status = LDNS_STATUS_INVALID_STR;
+       }
+
+       if (status != LDNS_STATUS_OK) {
+               if (relay)
+                       LDNS_FREE(relay);
+               LDNS_FREE(token);
+               ldns_buffer_free(str_buf);
+               return LDNS_STATUS_INVALID_STR;
+       }
+
+       /* now copy all into one amtrelay rdf */
+       if (relay_type)
+               amtrelay_len = 2 + (int)ldns_rdf_size(relay_rdf);
+       else
+               amtrelay_len = 2;
+
+       data = LDNS_XMALLOC(uint8_t, amtrelay_len);
+       if(!data) {
+               if (relay)
+                       LDNS_FREE(relay);
+               LDNS_FREE(token);
+               ldns_buffer_free(str_buf);
+               if (relay_rdf) ldns_rdf_free(relay_rdf);
+               return LDNS_STATUS_MEM_ERR;
+       }
+
+       data[0] = precedence;
+       data[1] = relay_type;
+       data[1] |= (discovery_optional << 7);
+
+       if (relay_type) {
+               memcpy(data + 2,
+                       ldns_rdf_data(relay_rdf), ldns_rdf_size(relay_rdf));
+       }
+       *rd = ldns_rdf_new_frm_data( LDNS_RDF_TYPE_AMTRELAY
+                                  , (uint16_t) amtrelay_len, data);
+
+       if (relay)
+               LDNS_FREE(relay);
+       LDNS_FREE(token);
+       ldns_buffer_free(str_buf);
+       ldns_rdf_free(relay_rdf);
+       LDNS_FREE(data);
+       if(!*rd) return LDNS_STATUS_MEM_ERR;
+       return LDNS_STATUS_OK;
+}
index a30e89e745913b667d5ae85f44a6f0461cc9ec8f..1473a9478dfb44afd425db58f467d0b428f5b252 100644 (file)
@@ -272,6 +272,7 @@ ldns_wire2rdf(ldns_rr *rr, const uint8_t *wire, size_t max, size_t *pos)
                case LDNS_RDF_TYPE_ATMA:
                case LDNS_RDF_TYPE_IPSECKEY:
                case LDNS_RDF_TYPE_LONG_STR:
+               case LDNS_RDF_TYPE_AMTRELAY:
                case LDNS_RDF_TYPE_NONE:
                        /*
                         * Read to end of rr rdata