return SVCB_KEY_IPV6HINT;
break;
+ case sizeof("dohpath")-1:
+ if (!strncmp(key, "dohpath", sizeof("dohpath")-1))
+ return SVCB_KEY_DOHPATH;
+ break;
+
case sizeof("ech")-1:
if (!strncmp(key, "ech", sizeof("ech")-1))
return SVCB_KEY_ECH;
return LDNS_WIREPARSE_ERR_OK;
}
+static int
+sldns_str2wire_svcbparam_dohpath_value(const char* val,
+ uint8_t* rd, size_t* rd_len)
+{
+ size_t val_len;
+
+ /* RFC6570#section-2.1
+ * "The characters outside of expressions in a URI Template string are
+ * intended to be copied literally"
+ * Practically this means we do not have to look for "double escapes"
+ * like in the alpn value list.
+ */
+
+ val_len = strlen(val);
+
+ if (*rd_len < 4 + val_len) {
+ return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
+ }
+
+ /* draft-ietf-add-svcb-dns-06#section-5.1
+ * The URI Template MUST contain a "dns" variable
+ */
+ if (!(strstr(val, "?dns"))) {
+ return LDNS_WIREPARSE_ERR_SVCB_NO_DNS_VAR_IN_DOHPATH;
+ }
+
+ sldns_write_uint16(rd, SVCB_KEY_DOHPATH);
+ sldns_write_uint16(rd + 2, val_len);
+ memcpy(rd + 4, val, val_len);
+ *rd_len = 4 + val_len;
+
+ return LDNS_WIREPARSE_ERR_OK;
+}
+
static int
sldns_str2wire_svcparam_value(const char *key, size_t key_len,
const char *val, uint8_t* rd, size_t* rd_len)
case SVCB_KEY_PORT:
case SVCB_KEY_IPV4HINT:
case SVCB_KEY_IPV6HINT:
+ case SVCB_KEY_DOHPATH:
return LDNS_WIREPARSE_ERR_SVCB_MISSING_PARAM;
#endif
default:
return sldns_str2wire_svcbparam_ech_value(val, rd, rd_len);
case SVCB_KEY_ALPN:
return sldns_str2wire_svcbparam_alpn_value(val, rd, rd_len);
+ case SVCB_KEY_DOHPATH:
+ return sldns_str2wire_svcbparam_dohpath_value(val, rd, rd_len);
default:
str_len = strlen(val);
if (*rd_len < 4 + str_len)
#define SVCB_KEY_IPV4HINT 4
#define SVCB_KEY_ECH 5
#define SVCB_KEY_IPV6HINT 6
-#define SVCPARAMKEY_COUNT 7
+#define SVCB_KEY_DOHPATH 7
+#define SVCPARAMKEY_COUNT 8
#define MAX_NUMBER_OF_SVCPARAMS 64
#define LDNS_WIREPARSE_ERR_SVCB_IPV6_TOO_MANY_ADDRESSES 383
#define LDNS_WIREPARSE_ERR_SVCB_ALPN_KEY_TOO_LARGE 384
#define LDNS_WIREPARSE_ERR_SVCB_NO_DEFAULT_ALPN_VALUE 385
-#define LDNS_WIREPARSE_ERR_SVCPARAM_BROKEN_RDATA 386
+#define LDNS_WIREPARSE_ERR_SVCB_NO_DNS_VAR_IN_DOHPATH 386
+#define LDNS_WIREPARSE_ERR_SVCPARAM_BROKEN_RDATA 387
+
/**
* Get reference to a constant string for the (parse) error.
"Alpn strings need to be smaller than 255 chars"},
{ LDNS_WIREPARSE_ERR_SVCB_NO_DEFAULT_ALPN_VALUE,
"No-default-alpn should not have a value" },
+ { LDNS_WIREPARSE_ERR_SVCB_NO_DNS_VAR_IN_DOHPATH,
+ "Dohpath must have '?dns' in the URI template variable" },
{ LDNS_WIREPARSE_ERR_SVCPARAM_BROKEN_RDATA,
"General SVCParam error" },
{ 0, NULL }
/* draft-ietf-dnsop-svcb-https-06: 6. Initial SvcParamKeys */
const char *svcparamkey_strs[] = {
"mandatory", "alpn", "no-default-alpn", "port",
- "ipv4hint", "ech", "ipv6hint"
+ "ipv4hint", "ech", "ipv6hint", "dohpath"
};
char* sldns_wire2str_pkt(uint8_t* data, size_t len)
return w + size;
}
+static int sldns_wire2str_svcparam_dohpath2str(char** s,
+ size_t* slen, uint16_t data_len, uint8_t* data)
+{
+ int w = 0;
+ uint16_t i;
+
+ assert(data_len > 0); /* Guaranteed by sldns_wire2str_svcparam_scan */
+
+ w += sldns_str_print(s, slen, "=\"");
+
+ /* RC6570#section-2.1 specifies that the '\' (and other non-letter
+ * characters in the URI) are "intended to be copied literally" */
+ for (i = 0; i < data_len; i++) {
+ // @TODO do a check like isprint()?
+
+ w += sldns_str_print(s, slen, "%c", data[i]);
+ }
+
+ w += sldns_str_print(s, slen, "\"");
+
+ return w;
+}
+
int sldns_wire2str_svcparam_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen)
{
uint8_t ch;
case SVCB_KEY_IPV4HINT:
case SVCB_KEY_IPV6HINT:
case SVCB_KEY_MANDATORY:
+ case SVCB_KEY_DOHPATH:
return -1;
default:
return written_chars;
case SVCB_KEY_ECH:
r = sldns_wire2str_svcparam_ech2str(s, slen, data_len, *d);
break;
+ case SVCB_KEY_DOHPATH:
+ r = sldns_wire2str_svcparam_dohpath2str(s, slen, data_len, *d);
+ break;
default:
r = sldns_str_print(s, slen, "=\"");