return 0;
}
+static void dns_label_mark(fr_dns_labels_t *lb, uint8_t const *p)
+{
+ if (!lb || !lb->mark) return;
+
+ fr_assert(p >= (lb->start + 12)); /* can't point to the packet header */
+ fr_assert(!lb->end || (p < lb->end));
+
+ lb->mark[p - lb->start] = 1;
+}
+
+
static bool dns_pointer_valid(fr_dns_labels_t *lb, uint16_t offset)
{
int i;
if (!lb) return true; /* we have no idea, so allow it */
+ if (lb->mark) return (lb->mark[offset] != 0);
+
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;
+ dns_label_mark(lb, p);
+
/*
* Account for the '.' on every label after the
* first one.
typedef struct {
uint8_t const *start; //!< start of packet
+ uint8_t const *end; //!< end of the packet
+ uint8_t *mark; //!< markup buffer
int num; //!< number of used labels
int max; //! maximum number of labels
fr_dns_block_t blocks[]; //!< array holding "max" labels
lb->blocks[0].start = 12;
lb->blocks[0].end = 12;
lb->num = 1;
+
+ 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);
fr_assert(packet_ctx->lb != NULL);
+
+ packet_ctx->lb->end = data + data_len;
+ packet_ctx->lb->mark = talloc_zero_array(packet_ctx->lb, uint8_t, 65535);
}
return fr_dns_decode(ctx, out, data, data_len, packet_ctx);