RETURN_OK_WITH_ERROR();
}
- ret = fr_value_box_to_dns_label(&need, dns_label, sizeof(dns_label), where, box);
+ ret = fr_value_box_to_dns_label(&need, dns_label, sizeof(dns_label), where, true, box);
talloc_free(box);
if (ret < 0) RETURN_OK_WITH_ERROR();
* @param[out] buf Buffer where labels are stored
* @param[in] buf_len The length of the output buffer
* @param[out] where Where to write this label
+ * @param[in] compression Whether or not to do DNS label compression.
* @param[in] value to encode.
* @return
- * - 0 no bytes were written, see need value to determine if it was because
- * the fr_value_box_t was #FR_TYPE_OCTETS/#FR_TYPE_STRING and was
- * NULL (which is unfortunately valid)
+ * - 0 no bytes were written, see need value to determine
* - >0 the number of bytes written to "where", NOT "buf + where + outlen"
* - <0 on error.
*/
-ssize_t fr_value_box_to_dns_label(size_t *need, uint8_t *buf, size_t buf_len, uint8_t *where, fr_value_box_t const *value)
+ssize_t fr_value_box_to_dns_label(size_t *need, uint8_t *buf, size_t buf_len, uint8_t *where, bool compression,
+ fr_value_box_t const *value)
{
uint8_t *label;
uint8_t *end = buf + buf_len;
uint8_t *data;
int namelen = 0;
- if (!buf || !buf_len || !where || !value) return -1;
+ if (!buf || !buf_len || !where || !value) {
+ fr_strerror_printf("Invalid input");
+ return -1;
+ }
/*
* Don't allow stupidities
*/
- if (!((where >= buf) && (where < (buf + buf_len)))) return -1;
+ if (!((where >= buf) && (where < (buf + buf_len)))) {
+ fr_strerror_printf("Label is outside of buffer");
+ return -1;
+ }
/*
* We can only encode strings.
*/
- if (value->type != FR_TYPE_STRING) return -1;
+ if (value->type != FR_TYPE_STRING) {
+ fr_strerror_printf("Asked to encode non-string type");
+ return -1;
+ }
if (value->vb_length > 255) {
fr_strerror_printf("Label is too long");
}
/*
- * Allow [-0-9a-zA-Z]
+ * Only encode [-0-9a-zA-Z]. Anything else is forbidden.
*/
if (!((*q == '-') || ((*q >= '0') && (*q <= '9')) ||
((*q >= 'A') && (*q <= 'Z')) || ((*q >= 'a') && (*q <= 'z')))) {
* Only one label, don't compress it. Or, the label is
* already compressed.
*/
- if ((buf == where) || ((data - where) <= 2)) goto done;
+ if (!compression || (buf == where) || ((data - where) <= 2)) goto done;
/*
* Do label compression on the resulting string, starting
fr_value_box_t *dst, fr_type_t type, fr_dict_attr_t const *enumv,
uint8_t const *src, size_t len, bool tainted);
-ssize_t fr_value_box_to_dns_label(size_t *need, uint8_t *buf, size_t buflen, uint8_t *where, fr_value_box_t const *value);
+ssize_t fr_value_box_to_dns_label(size_t *need, uint8_t *buf, size_t buflen, uint8_t *where, bool compression, fr_value_box_t const *value);
ssize_t fr_dns_label_length(uint8_t const *buf, size_t buf_len, uint8_t const **p_label);
*/
case FR_TYPE_STRING:
/*
- * DNS labels get a special encoder.
+ * DNS labels get a special encoder. Since we're
+ * only encoding one value, it's always
+ * uncompressed.
*/
- if (da->flags.subtype == FLAG_ENCODE_DNS_LABEL) {
- slen = fr_value_box_to_dns_label(NULL, p, outlen, p, &vp->data);
+ if ((da->flags.subtype == FLAG_ENCODE_DNS_LABEL) ||
+ (da->flags.subtype == FLAG_ENCODE_UNCOMPRESSED_DNS_LABEL)) {
+ slen = fr_value_box_to_dns_label(NULL, p, outlen, p, false, &vp->data);
/*
* @todo - check for free space, etc.
* DNS labels have internalized length, so we don't need
* length headers.
*/
- if ((da->type == FR_TYPE_STRING) && (da->flags.subtype == FLAG_ENCODE_DNS_LABEL)) {
+ if ((da->type == FR_TYPE_STRING) && da->flags.subtype){
+ bool compression = (da->flags.subtype == FLAG_ENCODE_DNS_LABEL);
+
while (p < end) {
vp = fr_cursor_current(cursor);
/*
* @todo - encode length and stuff
*/
- slen = fr_value_box_to_dns_label(NULL, out, outlen, p, &vp->data);
+ slen = fr_value_box_to_dns_label(NULL, out, outlen, p, compression, &vp->data);
if (slen <= 0) return PAIR_ENCODE_ERROR;
p += slen;
#data foo
#
-# DNS labels WITHOUT compression
+# DNS labels
#
encode-dns-label foo.com
match 03 66 6f 6f 03 63 6f 6d 00
encode-pair SIP-Server-Domain-Name-List = "www.example.com", SIP-Server-Domain-Name-List = "ftp.example.com"
match 00 15 00 17 03 77 77 77 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 03 66 74 70 c0 04
+encode-pair SIP-Server-Domain-Name-List = "www.example.com", SIP-Server-Domain-Name-List = "ftp.example.com", SIP-Server-Domain-Name-List = "ns.example.com"
+match 00 15 00 1c 03 77 77 77 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 03 66 74 70 c0 04 02 6e 73 c0 04
+
+#
+# This attribute is NOT compressed!
+#
+encode-pair BCMCS-Server-Domain-Name-List = "www.example.com"
+match 00 21 00 11 03 77 77 77 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00
+
+encode-pair BCMCS-Server-Domain-Name-List = "www.example.com", BCMCS-Server-Domain-Name-List = "ftp.example.com"
+match 00 21 00 22 03 77 77 77 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 03 66 74 70 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00
+
+encode-pair BCMCS-Server-Domain-Name-List = "www.example.com", BCMCS-Server-Domain-Name-List = "ftp.example.com", BCMCS-Server-Domain-Name-List = "ns.example.com"
+match 00 21 00 32 03 77 77 77 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 03 66 74 70 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 02 6e 73 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00
+
count
-match 82
+match 90