forked from asterisk/asterisk
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
dns_txt: Add TXT record parsing support
Change-Id: Ie0eca23b8e6f4c7d9846b6013d79099314d90ef5
- Loading branch information
1 parent
98d10d0
commit d68f940
Showing
4 changed files
with
218 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/* | ||
* Asterisk -- An open source telephony toolkit. | ||
* | ||
* Copyright (C) 2020, Sean Bright | ||
* | ||
* Sean Bright <[email protected]> | ||
* | ||
* See http://www.asterisk.org for more information about | ||
* the Asterisk project. Please do not directly contact | ||
* any of the maintainers of this project for assistance; | ||
* the project provides a web site, mailing lists and IRC | ||
* channels for your use. | ||
* | ||
* This program is free software, distributed under the terms of | ||
* the GNU General Public License Version 2. See the LICENSE file | ||
* at the top of the source tree. | ||
*/ | ||
|
||
/*! \file | ||
* \brief DNS TXT Record Parsing API | ||
* \author Sean Bright <[email protected]> | ||
*/ | ||
|
||
#ifndef ASTERISK_DNS_TXT_H | ||
#define ASTERISK_DNS_TXT_H | ||
|
||
#if defined(__cplusplus) || defined(c_plusplus) | ||
extern "C" { | ||
#endif | ||
|
||
/*! | ||
* \brief Get the number of character strings in a TXT record | ||
* \since 16.10.0, 17.4.0 | ||
* | ||
* \param record The DNS record | ||
* | ||
* \return the number of character strings in this TXT record | ||
*/ | ||
size_t ast_dns_txt_get_count(const struct ast_dns_record *record); | ||
|
||
/*! | ||
* \brief Get the character strings from this TXT record | ||
* \since 16.10.0, 17.4.0 | ||
* | ||
* \param record The DNS record | ||
* | ||
* \retval NULL Unable to allocate memory | ||
* \return Vector of strings. Free with ast_dns_txt_free_strings | ||
*/ | ||
struct ast_vector_string *ast_dns_txt_get_strings(const struct ast_dns_record *record); | ||
|
||
/*! | ||
* \brief Free strings returned by ast_dns_txt_get_strings | ||
* \since 16.10.0, 17.4.0 | ||
* | ||
* \param strings The vector to free | ||
*/ | ||
void ast_dns_txt_free_strings(struct ast_vector_string *strings); | ||
|
||
#if defined(__cplusplus) || defined(c_plusplus) | ||
} | ||
#endif | ||
|
||
#endif /* ASTERISK_DNS_TXT_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
/* | ||
* Asterisk -- An open source telephony toolkit. | ||
* | ||
* Copyright (C) 2020, Sean Bright | ||
* | ||
* Sean Bright <[email protected]> | ||
* | ||
* See http://www.asterisk.org for more information about | ||
* the Asterisk project. Please do not directly contact | ||
* any of the maintainers of this project for assistance; | ||
* the project provides a web site, mailing lists and IRC | ||
* channels for your use. | ||
* | ||
* This program is free software, distributed under the terms of | ||
* the GNU General Public License Version 2. See the LICENSE file | ||
* at the top of the source tree. | ||
*/ | ||
|
||
/*! \file | ||
* \brief DNS TXT Record Parsing API | ||
* \author Sean Bright <[email protected]> | ||
*/ | ||
|
||
/*** MODULEINFO | ||
<support_level>core</support_level> | ||
***/ | ||
|
||
#include "asterisk.h" | ||
|
||
#include <resolv.h> | ||
|
||
#include "asterisk/dns_core.h" | ||
#include "asterisk/dns_txt.h" | ||
#include "asterisk/dns_internal.h" | ||
#include "asterisk/utils.h" | ||
|
||
struct ast_dns_record *dns_txt_alloc(struct ast_dns_query *query, const char *data, const size_t size) | ||
{ | ||
struct ast_dns_txt_record *txt; | ||
const char *end_of_record = data + size; | ||
size_t count = 0; | ||
|
||
/* Because we can't allocate additional memory, the best we can do here is just | ||
* validate that this conforms to a TXT record. */ | ||
while (data < end_of_record) { | ||
uint8_t byte_count = (uint8_t) *data; | ||
count++; | ||
data += byte_count + 1; | ||
} | ||
|
||
if (data != end_of_record) { | ||
/* This is not a valid TXT record, so we can bail out */ | ||
return NULL; | ||
} | ||
|
||
txt = ast_calloc(1, sizeof(*txt) + size); | ||
if (!txt) { | ||
return NULL; | ||
} | ||
|
||
txt->count = count; | ||
txt->generic.data_ptr = txt->data; | ||
|
||
return (struct ast_dns_record *) txt; | ||
} | ||
|
||
size_t ast_dns_txt_get_count(const struct ast_dns_record *record) | ||
{ | ||
struct ast_dns_txt_record *txt = (struct ast_dns_txt_record *) record; | ||
ast_assert(ast_dns_record_get_rr_type(record) == T_TXT); | ||
return txt->count; | ||
} | ||
|
||
struct ast_vector_string *ast_dns_txt_get_strings(const struct ast_dns_record *record) | ||
{ | ||
struct ast_vector_string *strings; | ||
|
||
const size_t size = ast_dns_record_get_data_size(record); | ||
const char *data = ast_dns_record_get_data(record); | ||
const char *end_of_record = data + size; | ||
|
||
ast_assert(ast_dns_record_get_rr_type(record) == T_TXT); | ||
|
||
strings = ast_malloc(sizeof(struct ast_vector_const_string)); | ||
if (!strings) { | ||
return NULL; | ||
} | ||
|
||
if (AST_VECTOR_INIT(strings, ast_dns_txt_get_count(record))) { | ||
ast_free(strings); | ||
return NULL; | ||
} | ||
|
||
while (data < end_of_record) { | ||
char *s; | ||
uint8_t bytes = (uint8_t) *data; | ||
|
||
s = ast_malloc(bytes + 1); | ||
if (!s) { | ||
ast_dns_txt_free_strings(strings); | ||
return NULL; | ||
} | ||
|
||
memcpy(s, &data[1], bytes); | ||
s[bytes] = 0; | ||
|
||
/* We know the size in advance so this can't fail */ | ||
AST_VECTOR_APPEND(strings, s); | ||
|
||
data += bytes + 1; | ||
} | ||
|
||
/* Sanity check */ | ||
if (data != end_of_record) { | ||
ast_dns_txt_free_strings(strings); | ||
return NULL; | ||
} | ||
|
||
return strings; | ||
} | ||
|
||
void ast_dns_txt_free_strings(struct ast_vector_string *strings) | ||
{ | ||
AST_VECTOR_CALLBACK_VOID(strings, ast_free); | ||
AST_VECTOR_PTR_FREE(strings); | ||
} |