26#include <arpa/nameser.h>
50 .
name =
"A snake that swallowed a deer",
58 info->name =
"resolver_register_unregister";
59 info->category =
"/main/dns/";
60 info->summary =
"Test nominal resolver registration and unregistration";
62 "The test performs the following steps:\n"
63 "\t* Register a valid resolver.\n"
64 "\t* Unregister the resolver.\n"
65 "If either step fails, the test fails";
96 .
name =
"incomplete2",
102 .
name =
"incomplete3",
109 info->name =
"resolver_register_off_nominal";
110 info->category =
"/main/dns/";
111 info->summary =
"Test off-nominal resolver registration";
113 "Test off-nominal resolver registration:\n"
114 "\t* Register a duplicate resolver\n"
115 "\t* Register a resolver without a name\n"
116 "\t* Register a resolver without a resolve() method\n"
117 "\t* Register a resolver without a cancel() method";
161 .
name =
"I do not exist",
162 .priority = 20141004,
169 info->name =
"resolver_unregister_off_nominal";
170 info->category =
"/main/dns/";
171 info->summary =
"Test off-nominal DNS resolver unregister";
173 "The test attempts the following:\n"
174 "\t* Unregister a resolver that is not registered.\n"
175 "\t* Unregister a NULL pointer.\n"
176 "Because unregistering a resolver does not return an indicator of success, the best\n"
177 "this test can do is verify that nothing blows up when this is attempted.";
201 struct digits *data_ptr;
205 info->name =
"resolver_data";
206 info->category =
"/main/dns/";
207 info->summary =
"Test getting and setting data on a DNS resolver";
208 info->description =
"This test does the following:\n"
209 "\t* Ensure that requesting resolver data results in a NULL return if no data has been set.\n"
210 "\t* Ensure that setting resolver data does not result in an error.\n"
211 "\t* Ensure that retrieving the set resolver data returns the data we expect\n"
212 "\t* Ensure that setting new resolver data on the query does not result in an error\n"
213 "\t* Ensure that retrieving the resolver data returns the new data that we set";
219 memset(&some_query, 0,
sizeof(some_query));
224 if (!average || !polydactyl) {
251 if (data_ptr != average) {
266 unsigned int expected_secure,
unsigned int expected_bogus,
267 unsigned int expected_rcode,
const char *expected_canonical,
268 const char *expected_answer,
size_t answer_size)
294#define DNS_ANSWER "Grumble Grumble"
295#define DNS_ANSWER_SIZE strlen(DNS_ANSWER)
317 info->name =
"resolver_set_result";
318 info->category =
"/main/dns/";
319 info->summary =
"Test setting and getting results on DNS queries";
321 "This test performs the following:\n"
322 "\t* Sets a result that is not secure, bogus, and has rcode 0\n"
323 "\t* Sets a result that is not secure, has rcode 0, but is secure\n"
324 "\t* Sets a result that is not bogus, has rcode 0, but is secure\n"
325 "\t* Sets a result that is not secure or bogus, but has rcode NXDOMAIN\n"
326 "After each result is set, we ensure that parameters retrieved from\n"
327 "the result have the expected values.";
333 memset(&some_query, 0,
sizeof(some_query));
335 for (i = 0; i <
ARRAY_LEN(results); ++i) {
362 info->name =
"resolver_set_result_off_nominal";
363 info->category =
"/main/dns/";
364 info->summary =
"Test setting off-nominal DNS results";
366 "This test performs the following:\n"
367 "\t* Attempt to add a DNS result that is both bogus and secure\n"
368 "\t* Attempt to add a DNS result that has no canonical name";
374 memset(&some_query, 0,
sizeof(some_query));
396 int rr_type,
int rr_class,
int ttl,
const char *data,
const size_t size)
427 static const char *V4 =
"127.0.0.1";
428 static const size_t V4_BUFSIZE =
sizeof(
struct in_addr);
429 char v4_buf[V4_BUFSIZE];
431 static const char *V6 =
"::1";
432 static const size_t V6_BUFSIZE =
sizeof(
struct in6_addr);
433 char v6_buf[V6_BUFSIZE];
435 struct dns_record_details {
443 { T_A, C_IN, 12345, v4_buf, V4_BUFSIZE, 0, },
444 { T_AAAA, C_IN, 12345, v6_buf, V6_BUFSIZE, 0, },
447 int num_records_visited = 0;
451 info->name =
"resolver_add_record";
452 info->category =
"/main/dns/";
453 info->summary =
"Test adding DNS records to a query";
455 "This test performs the following:\n"
456 "\t* Ensure a nominal A record can be added to a query result\n"
457 "\t* Ensures that the record can be retrieved\n"
458 "\t* Ensure that a second record can be added to the query result\n"
459 "\t* Ensures that both records can be retrieved";
465 memset(&some_query, 0,
sizeof(some_query));
479 inet_pton(AF_INET, V4, v4_buf);
505 inet_pton(AF_INET6, V6, v6_buf);
534 ++num_records_visited;
554 static const char *V4 =
"127.0.0.1";
555 static const size_t V4_BUFSIZE =
sizeof(
struct in_addr);
556 char v4_buf[V4_BUFSIZE];
560 info->name =
"resolver_add_record_off_nominal";
561 info->category =
"/main/dns/";
562 info->summary =
"Test adding off-nominal DNS records to a query";
564 "This test performs the following:\n"
565 "\t* Ensure a nominal A record cannot be added if no result has been set.\n"
566 "\t* Ensure that an A record with invalid RR types cannot be added to a query\n"
567 "\t* Ensure that an A record with invalid RR classes cannot be added to a query\n"
568 "\t* Ensure that an A record with invalid TTL cannot be added to a query\n"
569 "\t* Ensure that an A record with NULL data cannot be added to a query\n"
570 "\t* Ensure that an A record with invalid length cannot be added to a query";
576 memset(&some_query, 0,
sizeof(some_query));
578 inet_ntop(AF_INET, V4, v4_buf, V4_BUFSIZE);
673 struct timespec timeout;
675 static const char *V4 =
"127.0.0.1";
676 static const size_t V4_BUFSIZE =
sizeof(
struct in_addr);
677 char v4_buf[V4_BUFSIZE];
698 inet_pton(AF_INET, V4, v4_buf);
717 pthread_t resolver_thread;
788 info->name =
"resolver_resolve_sync";
789 info->category =
"/main/dns/";
790 info->summary =
"Test a nominal synchronous DNS resolution";
792 "This test performs a synchronous DNS resolution of a domain. The goal of this\n"
793 "test is not to check the records for accuracy. Rather, the goal is to ensure that\n"
794 "the resolver is called into as expected, that the query completes entirely before\n"
795 "returning from the synchronous resolution, that nothing tried to cancel the resolution\n,"
796 "and that some records were returned.";
865 .
name =
"Uwe Boll's Filmography",
873 struct dns_resolve_data {
880 {
"asterisk.org", -1, C_IN, &
result },
881 {
"asterisk.org", 65536 + 1, C_IN, &
result },
882 {
"asterisk.org", T_A, -1, &
result },
883 {
"asterisk.org", T_A, 65536 + 1, &
result },
884 {
"asterisk.org", T_A, C_IN,
NULL },
893 info->name =
"resolver_resolve_sync_off_nominal";
894 info->category =
"/main/dns/";
895 info->summary =
"Test off-nominal synchronous DNS resolution";
897 "This test performs several off-nominal synchronous DNS resolutions:\n"
898 "\t* Attempt resolution with NULL name\n"
899 "\t* Attempt resolution with invalid RR type\n"
900 "\t* Attempt resolution with invalid RR class\n"
901 "\t* Attempt resolution with NULL result pointer\n"
902 "\t* Attempt resolution with resolver that returns an error";
913 for (i = 0; i <
ARRAY_LEN(resolves); ++i) {
1024 struct timespec timeout;
1028 info->name =
"resolver_resolve_async";
1029 info->category =
"/main/dns/";
1030 info->summary =
"Test a nominal asynchronous DNS resolution";
1032 "This test performs an asynchronous DNS resolution of a domain. The goal of this\n"
1033 "test is not to check the records for accuracy. Rather, the goal is to ensure that\n"
1034 "the resolver is called into as expected, that we regain control before the query\n"
1035 "is completed, and to ensure that nothing tried to cancel the resolution.";
1075 timeout.tv_sec += 10;
1077 while (!async_data->complete) {
1078 if (
ast_cond_timedwait(&async_data->cond, &async_data->lock, &timeout) == ETIMEDOUT) {
1084 if (!async_data->complete) {
1124 .
name =
"Ed Wood's Filmography",
1130 struct dns_resolve_data {
1141 {
"asterisk.org", T_A, C_IN,
NULL },
1150 info->name =
"resolver_resolve_async_off_nominal";
1151 info->category =
"/main/dns/";
1152 info->summary =
"Test off-nominal asynchronous DNS resolution";
1154 "This test performs several off-nominal asynchronous DNS resolutions:\n"
1155 "\t* Attempt resolution with NULL name\n"
1156 "\t* Attempt resolution with invalid RR type\n"
1157 "\t* Attempt resolution with invalid RR class\n"
1158 "\t* Attempt resolution with NULL callback pointer\n"
1159 "\t* Attempt resolution with resolver that returns an error";
1170 for (i = 0; i <
ARRAY_LEN(resolves); ++i) {
1172 resolves[i].callback,
NULL);
1206 struct timespec timeout;
1210 info->name =
"resolver_resolve_async_cancel";
1211 info->category =
"/main/dns/";
1212 info->summary =
"Test canceling an asynchronous DNS resolution";
1214 "This test performs an asynchronous DNS resolution of a domain and then cancels\n"
1215 "the resolution. The goal of this test is to ensure that the cancel() callback of\n"
1216 "the resolver is called and that it properly interrupts the resolution such that no\n"
1217 "records are returned.";
1265 timeout.tv_sec += 10;
1267 while (!async_data->complete) {
1268 if (
ast_cond_timedwait(&async_data->cond, &async_data->lock, &timeout) == ETIMEDOUT) {
1274 if (!async_data->complete) {
Asterisk main include file. File version handling, generic pbx functions.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
#define ao2_alloc(data_size, destructor_fn)
int ast_dns_record_get_rr_class(const struct ast_dns_record *record)
Get the resource record class of a DNS record.
int ast_dns_record_get_ttl(const struct ast_dns_record *record)
Get the TTL of a DNS record.
const struct ast_dns_record * ast_dns_record_get_next(const struct ast_dns_record *record)
Get the next DNS record.
struct ast_dns_query_active * ast_dns_resolve_async(const char *name, int rr_type, int rr_class, ast_dns_resolve_callback callback, void *data)
Asynchronously resolve a DNS query.
int ast_dns_resolve_cancel(struct ast_dns_query_active *active)
Cancel an asynchronous DNS resolution.
const char * ast_dns_result_get_canonical(const struct ast_dns_result *result)
Get the canonical name of the result.
void(* ast_dns_resolve_callback)(const struct ast_dns_query *query)
Callback invoked when a query completes.
unsigned int ast_dns_result_get_rcode(const struct ast_dns_result *result)
Get the error rcode of a DN result.
const char * ast_dns_record_get_data(const struct ast_dns_record *record)
Retrieve the raw DNS record.
const struct ast_dns_record * ast_dns_result_get_records(const struct ast_dns_result *result)
Get the first record of a DNS Result.
void * ast_dns_query_get_data(const struct ast_dns_query *query)
Get the user specific data of a DNS query.
void ast_dns_result_free(struct ast_dns_result *result)
Free the DNS result information.
struct ast_dns_result * ast_dns_query_get_result(const struct ast_dns_query *query)
Get the result information for a DNS query.
int ast_dns_record_get_rr_type(const struct ast_dns_record *record)
Get the resource record type of a DNS record.
unsigned int ast_dns_result_get_bogus(const struct ast_dns_result *result)
Get whether the result is bogus or not.
int ast_dns_resolve(const char *name, int rr_type, int rr_class, struct ast_dns_result **result)
Synchronously resolve a DNS query.
unsigned int ast_dns_result_get_secure(const struct ast_dns_result *result)
Get whether the result is secure or not.
const char * ast_dns_result_get_answer(const struct ast_dns_result *result)
Get the raw DNS answer from a DNS result.
Internal DNS structure definitions.
int ast_dns_resolver_set_data(struct ast_dns_query *query, void *data)
Set resolver specific data on a query.
int ast_dns_resolver_set_result(struct ast_dns_query *query, unsigned int secure, unsigned int bogus, unsigned int rcode, const char *canonical, const char *answer, size_t answer_size)
Set result information for a DNS query.
void ast_dns_resolver_completed(struct ast_dns_query *query)
Mark a DNS query as having been completed.
void * ast_dns_resolver_get_data(const struct ast_dns_query *query)
Retrieve resolver specific data.
int ast_dns_resolver_register(struct ast_dns_resolver *resolver)
Register a DNS resolver.
int ast_dns_resolver_add_record(struct ast_dns_query *query, int rr_type, int rr_class, int ttl, const char *data, const size_t size)
Add a DNS record to the result of a DNS query.
void ast_dns_resolver_unregister(struct ast_dns_resolver *resolver)
Unregister a DNS resolver.
#define ast_cond_destroy(cond)
#define ast_cond_init(cond, attr)
#define ast_cond_timedwait(cond, mutex, time)
#define ast_mutex_init(pmutex)
#define ast_mutex_unlock(a)
pthread_cond_t ast_cond_t
#define ast_mutex_destroy(a)
#define ast_mutex_lock(a)
#define ast_cond_signal(cond)
Asterisk module definitions.
#define AST_MODULE_INFO_STANDARD(keystr, desc)
#define ASTERISK_GPL_KEY
The text the key() function should return.
@ AST_MODULE_LOAD_SUCCESS
static void * cleanup(void *unused)
DNS resolver implementation.
const char * name
The name of the resolver implementation.
The result of a DNS query.
size_t answer_size
The size of the raw DNS answer.
Structure for mutex and tracking information.
Data used by async result callback.
File-scoped data used during resolver tests.
#define AST_TEST_REGISTER(cb)
#define ast_test_status_update(a, b, c...)
#define AST_TEST_UNREGISTER(cb)
static int stub_resolve(struct ast_dns_query *query)
static struct async_resolution_data * async_data_alloc(void)
Allocation/initialization for async_resolution_data.
static struct ast_dns_resolver test_resolver
The mock resolver.
static int stub_cancel(struct ast_dns_query *query)
static void resolver_data_cleanup(void)
Cleanup global mock resolver data.
static int test_cancel(struct ast_dns_query *query)
Mock resolver's cancel method.
static int test_resolve(struct ast_dns_query *query)
Mock resolver's resolve method.
static struct resolver_data test_resolver_data
static void stub_callback(const struct ast_dns_query *query)
static void * resolution_thread(void *dns_query)
Thread spawned by the mock resolver.
static int test_results(struct ast_test *test, const struct ast_dns_query *query, unsigned int expected_secure, unsigned int expected_bogus, unsigned int expected_rcode, const char *expected_canonical, const char *expected_answer, size_t answer_size)
static void async_data_destructor(void *obj)
Destructor for async_resolution_data.
static void resolver_data_init(void)
Initialize global mock resolver data.
static int load_module(void)
static int unload_module(void)
static int test_record(struct ast_test *test, const struct ast_dns_record *record, int rr_type, int rr_class, int ttl, const char *data, const size_t size)
static void async_callback(const struct ast_dns_query *query)
Async DNS callback.
AST_TEST_DEFINE(resolver_register_unregister)
static int fail_resolve(struct ast_dns_query *query)
A resolve() method that simply fails.
struct timespec ast_tsnow(void)
Returns current timespec. Meant to avoid calling ast_tvnow() just to create a timespec from the timev...
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
#define ast_pthread_create_detached(a, b, c, d)