#include <freeradius-devel/util/dns.h>
#include <freeradius-devel/util/proto.h>
-fr_dns_labels_t *fr_dns_labels_init(TALLOC_CTX *ctx, uint8_t const *packet, int max_labels)
+fr_dns_labels_t *fr_dns_labels_init(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_len, int max_labels)
{
fr_dns_labels_t *lb;
+ if (max_labels <= 0) max_labels = 0;
+
lb = (fr_dns_labels_t *) talloc_zero_array(ctx, uint8_t, sizeof(fr_dns_labels_t) + sizeof(lb->blocks[0]) * max_labels);
if (!lb) return NULL;
talloc_set_name_const(lb, "fr_dns_labels_t");
lb->start = packet;
+ lb->end = packet + packet_len;
lb->max = max_labels;
/*
*/
if ((offset + size) >= MAX_OFFSET) return 0;
+ /*
+ * We're not tracking labels, so don't do anything.
+ */
+ if (lb->max == 1) return 0;
+
FR_PROTO_TRACE("adding label at offset %zu", offset);
/*
if (lb->mark) return (lb->mark[offset] != 0);
+ /*
+ * Brute-force searching.
+ */
for (i = 0; i < lb->num; i++) {
FR_PROTO_TRACE("Checking block %d %u..%u against %u",
i, lb->blocks[i].start, lb->blocks[i].end, offset);
*/
if ((p + *p + 1) > end) goto overflow;
+ /*
+ * It's a valid label. Mark it as such.
+ */
dns_label_mark(lb, p);
/*
*/
if (!already_set_next) *next = p; /* should be <='end' */
- (void) dns_label_add(lb, start, *next);
+ /*
+ * Add the label, only if we're not using the markup field.
+ */
+ if (lb && !lb->mark) (void) dns_label_add(lb, start, *next);
return length;
}
uint8_t const *src, size_t len, uint8_t const *label,
bool tainted, fr_dns_labels_t *lb);
-fr_dns_labels_t *fr_dns_labels_init(TALLOC_CTX *ctx, uint8_t const *packet, int max_labels) CC_HINT(nonnull);
+fr_dns_labels_t *fr_dns_labels_init(TALLOC_CTX *ctx, uint8_t const *packet, size_t packet_len, int max_labels) CC_HINT(nonnull);
#ifdef __cplusplus
}
packet_ctx.packet = request->packet->data;
packet_ctx.packet_len = data_len;
- packet_ctx.lb = fr_dns_labels_init(packet_ctx.tmp_ctx, packet_ctx.packet, 256);
+ packet_ctx.lb = fr_dns_labels_init(packet_ctx.tmp_ctx, packet_ctx.packet, data_len, 0);
fr_assert(packet_ctx.lb != NULL);
-
+ packet_ctx.lb->mark = talloc_zero_array(packet_ctx.lb, uint8_t, data_len);
/*
* Note that we don't set a limit on max_attributes here.
packet_ctx.packet = buffer;
packet_ctx.packet_len = buffer_len;
- packet_ctx.lb = fr_dns_labels_init(packet_ctx.tmp_ctx, buffer, 256);
+ packet_ctx.lb = fr_dns_labels_init(packet_ctx.tmp_ctx, buffer, buffer_len, 256);
fr_assert(packet_ctx.lb != NULL);
+ /* no need to set "mark" here, as that field is only used for decoding */
data_len = fr_dns_encode(&FR_DBUFF_TMP(buffer, buffer_len), &request->reply_pairs, &packet_ctx);
talloc_free(packet_ctx.tmp_ctx);
fr_dns_labels_t *lb = packet_ctx->lb;
lb->start = data;
+ lb->end = data + data_len;
/*
* Always skip the DNS packet header.
memset(packet_ctx->lb->mark, 0, talloc_array_length(packet_ctx->lb->mark));
} else {
- packet_ctx->lb = fr_dns_labels_init(packet_ctx, data, 256);
+ packet_ctx->lb = fr_dns_labels_init(packet_ctx, data, data_len, 256);
fr_assert(packet_ctx->lb != NULL);
packet_ctx->lb->end = data + data_len;
packet_ctx->packet = data;
packet_ctx->packet_len = data_len;
- packet_ctx->lb = fr_dns_labels_init(packet_ctx, data, 256);
+ packet_ctx->lb = fr_dns_labels_init(packet_ctx, data, data_len, 256);
fr_assert(packet_ctx->lb != NULL);
slen = fr_dns_encode(&FR_DBUFF_TMP(data, data_len), vps, packet_ctx);