Asterisk - The Open Source Telephony Project  18.5.0
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 <[email protected]>
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 <[email protected]>
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"
35 #include "asterisk/dns_internal.h"
36 #include "asterisk/utils.h"
37 
38 struct 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 
68 size_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 
75 struct ast_vector_string *ast_dns_txt_get_strings(const struct ast_dns_record *record)
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) {
101  ast_dns_txt_free_strings(strings);
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) {
116  ast_dns_txt_free_strings(strings);
117  return NULL;
118  }
119 
120  return strings;
121 }
122 
123 void ast_dns_txt_free_strings(struct ast_vector_string *strings)
124 {
126  AST_VECTOR_PTR_FREE(strings);
127 }
struct ast_dns_record generic
Generic DNS record information.
Definition: dns_internal.h:66
Asterisk main include file. File version handling, generic pbx functions.
const char * ast_dns_record_get_data(const struct ast_dns_record *record)
Retrieve the raw DNS record.
Definition: dns_core.c:160
A TXT record.
Definition: dns_internal.h:64
char * data_ptr
pointer to record-specific data.
Definition: dns_internal.h:58
For AST_LIST.
Definition: dns_internal.h:39
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
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
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
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
Utility functions.
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
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
char data[0]
The raw DNS record.
Definition: dns_internal.h:70
char data[0]
The raw DNS record.
Definition: dns_internal.h:60
DNS TXT Record Parsing API.
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
Internal DNS structure definitions.
#define ast_free(a)
Definition: astmm.h:182
A DNS query.
Definition: dns_internal.h:137
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
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
#define AST_VECTOR_PTR_FREE(vec)
Deallocates this vector pointer.
Definition: vector.h:189
size_t count
The number of character strings in the TXT record.
Definition: dns_internal.h:68
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
Core DNS API.
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
Definition: vector.h:865