because we don't yield when decoding the DNS packet.
packet_ctx.tmp_ctx = talloc(request, uint8_t);
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, data_len, 0);
+ packet_ctx.lb = fr_dns_labels_get(request->packet->data, data_len, true);
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, buffer_len, 256);
+ packet_ctx.lb = fr_dns_labels_get(buffer, buffer_len, false);
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_dict_t const *dict_dns;
+static _Thread_local fr_dns_labels_t *fr_dns_labels;
+
extern fr_dict_autoload_t dns_dict[];
fr_dict_autoload_t dns_dict[] = {
{ .out = &dict_dns, .proto = "dns" },
}
}
+fr_dns_labels_t *fr_dns_labels_get(uint8_t const *packet, size_t packet_len, bool init_mark)
+{
+ fr_dns_labels_t *lb = fr_dns_labels;
+
+ if (!lb) return NULL;
+
+ lb->start = packet;
+ lb->end = packet + packet_len;
+
+ lb->num = 1;
+ lb->blocks[0].start = DNS_HDR_LEN;
+ lb->blocks[0].end = DNS_HDR_LEN;
+
+ if (init_mark) memset(lb->mark, 0, talloc_array_length(lb->mark));
+
+ return lb;
+}
+
+/** Cleanup the memory pool used by vlog_request
+ *
+ */
+static void _dns_labels_free(void *arg)
+{
+ talloc_free(arg);
+ fr_dns_labels = NULL;
+}
+
+
/** Resolve/cache attributes in the DNS dictionary
*
* @return
*/
int fr_dns_global_init(void)
{
+ fr_dns_labels_t *lb;
+
if (instance_count > 0) {
instance_count++;
return 0;
if (fr_dict_autoload(dns_dict) < 0) return -1;
if (fr_dict_attr_autoload(dns_dict_attr) < 0) {
+ fail:
fr_dict_autofree(dns_dict);
return -1;
}
+ lb = (fr_dns_labels_t *) talloc_zero_array(NULL, uint8_t, sizeof(*lb) + sizeof(lb->blocks[0]) * 256);
+ if (!lb) goto fail;
+
+ lb->max = 256;
+
+ lb->mark = talloc_array(lb, uint8_t, 65536);
+ if (!lb->mark) {
+ talloc_free(lb);
+ goto fail;
+ }
+
+ fr_atexit_thread_local(fr_dns_labels, _dns_labels_free, lb);
+
instance_count++;
return 0;
packet_ctx->packet = data;
packet_ctx->packet_len = data_len;
-
- if (packet_ctx->lb) {
- fr_dns_labels_t *lb = packet_ctx->lb;
-
- lb->start = data;
- lb->end = data + data_len;
-
- /*
- * Always skip the DNS packet header.
- */
- 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, data_len, 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);
- }
+ packet_ctx->lb = fr_dns_labels_get(data, data_len, true);
+ fr_assert(packet_ctx->lb != NULL);
return fr_dns_decode(ctx, out, data, data_len, packet_ctx);
}
bool fr_dns_packet_ok(uint8_t const *packet, size_t packet_len, bool query);
+fr_dns_labels_t *fr_dns_labels_get(uint8_t const *packet, size_t packet_len, bool init_mark);
+
size_t fr_dns_value_len(fr_pair_t const *vp);
ssize_t fr_dns_decode(TALLOC_CTX *ctx, fr_pair_list_t *out,
packet_ctx->packet = data;
packet_ctx->packet_len = data_len;
-
- packet_ctx->lb = fr_dns_labels_init(packet_ctx, data, data_len, 256);
+ packet_ctx->lb = fr_dns_labels_get(data, data_len, false);
fr_assert(packet_ctx->lb != NULL);
slen = fr_dns_encode(&FR_DBUFF_TMP(data, data_len), vps, packet_ctx);