Asterisk - The Open Source Telephony Project GIT-master-a358458
dns_txt.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2020, Sean Bright
5 *
6 * Sean Bright <sean.bright@gmail.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19/*! \file
20 * \brief DNS TXT Record Parsing API
21 * \author Sean Bright <sean.bright@gmail.com>
22 */
23
24/*** MODULEINFO
25 <support_level>core</support_level>
26 ***/
27
28#include "asterisk.h"
29
30#include <netinet/in.h>
31#include <resolv.h>
32
33#include "asterisk/dns_core.h"
34#include "asterisk/dns_txt.h"
36#include "asterisk/utils.h"
37
38struct ast_dns_record *dns_txt_alloc(struct ast_dns_query *query, const char *data, const size_t size)
39{
40 struct ast_dns_txt_record *txt;
41 const char *end_of_record = data + size;
42 size_t count = 0;
43
44 /* Because we can't allocate additional memory, the best we can do here is just
45 * validate that this conforms to a TXT record. */
46 while (data < end_of_record) {
47 uint8_t byte_count = (uint8_t) *data;
48 count++;
49 data += byte_count + 1;
50 }
51
52 if (data != end_of_record) {
53 /* This is not a valid TXT record, so we can bail out */
54 return NULL;
55 }
56
57 txt = ast_calloc(1, sizeof(*txt) + size);
58 if (!txt) {
59 return NULL;
60 }
61
62 txt->count = count;
63 txt->generic.data_ptr = txt->data;
64
65 return (struct ast_dns_record *) txt;
66}
67
68size_t ast_dns_txt_get_count(const struct ast_dns_record *record)
69{
70 struct ast_dns_txt_record *txt = (struct ast_dns_txt_record *) record;
71 ast_assert(ast_dns_record_get_rr_type(record) == T_TXT);
72 return txt->count;
73}
74
76{
77 struct ast_vector_string *strings;
78
79 const size_t size = ast_dns_record_get_data_size(record);
80 const char *data = ast_dns_record_get_data(record);
81 const char *end_of_record = data + size;
82
83 ast_assert(ast_dns_record_get_rr_type(record) == T_TXT);
84
85 strings = ast_malloc(sizeof(struct ast_vector_const_string));
86 if (!strings) {
87 return NULL;
88 }
89
90 if (AST_VECTOR_INIT(strings, ast_dns_txt_get_count(record))) {
91 ast_free(strings);
92 return NULL;
93 }
94
95 while (data < end_of_record) {
96 char *s;
97 uint8_t bytes = (uint8_t) *data;
98
99 s = ast_malloc(bytes + 1);
100 if (!s) {
102 return NULL;
103 }
104
105 memcpy(s, &data[1], bytes);
106 s[bytes] = 0;
107
108 /* We know the size in advance so this can't fail */
109 AST_VECTOR_APPEND(strings, s);
110
111 data += bytes + 1;
112 }
113
114 /* Sanity check */
115 if (data != end_of_record) {
117 return NULL;
118 }
119
120 return strings;
121}
122
124{
126 AST_VECTOR_PTR_FREE(strings);
127}
Asterisk main include file. File version handling, generic pbx functions.
#define ast_free(a)
Definition: astmm.h:180
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
Core DNS API.
const char * ast_dns_record_get_data(const struct ast_dns_record *record)
Retrieve the raw DNS record.
Definition: dns_core.c:160
int ast_dns_record_get_rr_type(const struct ast_dns_record *record)
Get the resource record type of a DNS record.
Definition: dns_core.c:145
size_t ast_dns_record_get_data_size(const struct ast_dns_record *record)
Retrieve the size of the raw DNS record.
Definition: dns_core.c:165
Internal DNS structure definitions.
size_t ast_dns_txt_get_count(const struct ast_dns_record *record)
Get the number of character strings in a TXT record.
Definition: dns_txt.c:68
struct ast_vector_string * ast_dns_txt_get_strings(const struct ast_dns_record *record)
Get the character strings from this TXT record.
Definition: dns_txt.c:75
void ast_dns_txt_free_strings(struct ast_vector_string *strings)
Free strings returned by ast_dns_txt_get_strings.
Definition: dns_txt.c:123
struct ast_dns_record * dns_txt_alloc(struct ast_dns_query *query, const char *data, const size_t size)
Allocate and parse a DNS TXT record.
Definition: dns_txt.c:38
DNS TXT Record Parsing API.
#define NULL
Definition: resample.c:96
A DNS query.
Definition: dns_internal.h:137
For AST_LIST.
Definition: dns_internal.h:39
char data[0]
The raw DNS record.
Definition: dns_internal.h:60
char * data_ptr
pointer to record-specific data.
Definition: dns_internal.h:58
A TXT record.
Definition: dns_internal.h:64
struct ast_dns_record generic
Generic DNS record information.
Definition: dns_internal.h:66
size_t count
The number of character strings in the TXT record.
Definition: dns_internal.h:68
char data[0]
The raw DNS record.
Definition: dns_internal.h:70
String vector definitions.
Definition: vector.h:55
Utility functions.
#define ast_assert(a)
Definition: utils.h:739
#define AST_VECTOR_PTR_FREE(vec)
Deallocates this vector pointer.
Definition: vector.h:189
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
Definition: vector.h:862