Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions | Variables
test_dns.c File Reference
#include "asterisk.h"
#include <arpa/nameser.h>
#include <arpa/inet.h>
#include "asterisk/test.h"
#include "asterisk/module.h"
#include "asterisk/dns_core.h"
#include "asterisk/dns_resolver.h"
#include "asterisk/dns_internal.h"
Include dependency graph for test_dns.c:

Go to the source code of this file.

Data Structures

struct  async_resolution_data
 Data used by async result callback. More...
 
struct  resolver_data
 File-scoped data used during resolver tests. More...
 

Macros

#define DNS_ANSWER   "Grumble Grumble"
 
#define DNS_ANSWER_SIZE   strlen(DNS_ANSWER)
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
 AST_TEST_DEFINE (resolver_register_unregister)
 
 AST_TEST_DEFINE (resolver_register_off_nominal)
 
 AST_TEST_DEFINE (resolver_unregister_off_nominal)
 
 AST_TEST_DEFINE (resolver_data)
 
 AST_TEST_DEFINE (resolver_set_result)
 
 AST_TEST_DEFINE (resolver_set_result_off_nominal)
 
 AST_TEST_DEFINE (resolver_add_record)
 
 AST_TEST_DEFINE (resolver_add_record_off_nominal)
 
 AST_TEST_DEFINE (resolver_resolve_sync)
 
 AST_TEST_DEFINE (resolver_resolve_sync_off_nominal)
 
 AST_TEST_DEFINE (resolver_resolve_async)
 
 AST_TEST_DEFINE (resolver_resolve_async_off_nominal)
 
 AST_TEST_DEFINE (resolver_resolve_async_cancel)
 
static void async_callback (const struct ast_dns_query *query)
 Async DNS callback. More...
 
static struct async_resolution_dataasync_data_alloc (void)
 Allocation/initialization for async_resolution_data. More...
 
static void async_data_destructor (void *obj)
 Destructor for async_resolution_data. More...
 
static int fail_resolve (struct ast_dns_query *query)
 A resolve() method that simply fails. More...
 
static int load_module (void)
 
static void * resolution_thread (void *dns_query)
 Thread spawned by the mock resolver. More...
 
static void resolver_data_cleanup (void)
 Cleanup global mock resolver data. More...
 
static void resolver_data_init (void)
 Initialize global mock resolver data. More...
 
static void stub_callback (const struct ast_dns_query *query)
 
static int stub_cancel (struct ast_dns_query *query)
 
static int stub_resolve (struct ast_dns_query *query)
 
static int test_cancel (struct ast_dns_query *query)
 Mock resolver's cancel method. More...
 
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 int test_resolve (struct ast_dns_query *query)
 Mock resolver's resolve method. More...
 
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 int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "DNS API Tests" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_dns_resolver test_resolver
 The mock resolver. More...
 
static struct resolver_data test_resolver_data
 

Macro Definition Documentation

◆ DNS_ANSWER

#define DNS_ANSWER   "Grumble Grumble"

Definition at line 294 of file test_dns.c.

Referenced by AST_TEST_DEFINE(), and resolution_thread().

◆ DNS_ANSWER_SIZE

#define DNS_ANSWER_SIZE   strlen(DNS_ANSWER)

Definition at line 295 of file test_dns.c.

Referenced by AST_TEST_DEFINE(), and resolution_thread().

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1337 of file test_dns.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1337 of file test_dns.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 1337 of file test_dns.c.

◆ AST_TEST_DEFINE() [1/13]

AST_TEST_DEFINE ( resolver_register_unregister  )

Definition at line 47 of file test_dns.c.

References ast_dns_resolver_register(), ast_dns_resolver_unregister(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), ast_dns_resolver::name, stub_cancel(), stub_resolve(), TEST_EXECUTE, and TEST_INIT.

48 {
49  struct ast_dns_resolver cool_guy_resolver = {
50  .name = "A snake that swallowed a deer",
51  .priority = 19890504,
52  .resolve = stub_resolve,
53  .cancel = stub_cancel,
54  };
55 
56  switch (cmd) {
57  case TEST_INIT:
58  info->name = "resolver_register_unregister";
59  info->category = "/main/dns/";
60  info->summary = "Test nominal resolver registration and unregistration";
61  info->description =
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";
66  return AST_TEST_NOT_RUN;
67  case TEST_EXECUTE:
68  break;
69  }
70 
71  if (ast_dns_resolver_register(&cool_guy_resolver)) {
72  ast_test_status_update(test, "Unable to register a perfectly good resolver\n");
73  return AST_TEST_FAIL;
74  }
75 
76  ast_dns_resolver_unregister(&cool_guy_resolver);
77 
78  return AST_TEST_PASS;
79 }
void ast_dns_resolver_unregister(struct ast_dns_resolver *resolver)
Unregister a DNS resolver.
Definition: dns_core.c:680
static int stub_cancel(struct ast_dns_query *query)
Definition: test_dns.c:42
const char * name
The name of the resolver implementation.
Definition: dns_resolver.h:34
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
int ast_dns_resolver_register(struct ast_dns_resolver *resolver)
Register a DNS resolver.
Definition: dns_core.c:630
def info(msg)
DNS resolver implementation.
Definition: dns_resolver.h:32
static int stub_resolve(struct ast_dns_query *query)
Definition: test_dns.c:36

◆ AST_TEST_DEFINE() [2/13]

AST_TEST_DEFINE ( resolver_register_off_nominal  )

Definition at line 81 of file test_dns.c.

References ast_dns_resolver_register(), ast_dns_resolver_unregister(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), ast_dns_resolver::name, NULL, stub_cancel(), stub_resolve(), TEST_EXECUTE, and TEST_INIT.

82 {
83  struct ast_dns_resolver valid = {
84  .name = "valid",
85  .resolve = stub_resolve,
86  .cancel = stub_cancel,
87  };
88 
89  struct ast_dns_resolver incomplete1 = {
90  .name = NULL,
91  .resolve = stub_resolve,
92  .cancel = stub_cancel,
93  };
94 
95  struct ast_dns_resolver incomplete2 = {
96  .name = "incomplete2",
97  .resolve = NULL,
98  .cancel = stub_cancel,
99  };
100 
101  struct ast_dns_resolver incomplete3 = {
102  .name = "incomplete3",
103  .resolve = stub_resolve,
104  .cancel = NULL,
105  };
106 
107  switch (cmd) {
108  case TEST_INIT:
109  info->name = "resolver_register_off_nominal";
110  info->category = "/main/dns/";
111  info->summary = "Test off-nominal resolver registration";
112  info->description =
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";
118  return AST_TEST_NOT_RUN;
119  case TEST_EXECUTE:
120  break;
121  }
122 
123  if (ast_dns_resolver_register(&valid)) {
124  ast_test_status_update(test, "Failed to register valid resolver\n");
125  return AST_TEST_FAIL;
126  }
127 
128  if (!ast_dns_resolver_register(&valid)) {
129  ast_test_status_update(test, "Successfully registered the same resolver multiple times\n");
130  return AST_TEST_FAIL;
131  }
132 
134 
136  ast_test_status_update(test, "Successfully registered a NULL resolver\n");
137  return AST_TEST_FAIL;
138  }
139 
140  if (!ast_dns_resolver_register(&incomplete1)) {
141  ast_test_status_update(test, "Successfully registered a DNS resolver with no name\n");
142  return AST_TEST_FAIL;
143  }
144 
145  if (!ast_dns_resolver_register(&incomplete2)) {
146  ast_test_status_update(test, "Successfully registered a DNS resolver with no resolve() method\n");
147  return AST_TEST_FAIL;
148  }
149 
150  if (!ast_dns_resolver_register(&incomplete3)) {
151  ast_test_status_update(test, "Successfully registered a DNS resolver with no cancel() method\n");
152  return AST_TEST_FAIL;
153  }
154 
155  return AST_TEST_PASS;
156 }
void ast_dns_resolver_unregister(struct ast_dns_resolver *resolver)
Unregister a DNS resolver.
Definition: dns_core.c:680
static int stub_cancel(struct ast_dns_query *query)
Definition: test_dns.c:42
#define NULL
Definition: resample.c:96
const char * name
The name of the resolver implementation.
Definition: dns_resolver.h:34
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
int ast_dns_resolver_register(struct ast_dns_resolver *resolver)
Register a DNS resolver.
Definition: dns_core.c:630
def info(msg)
DNS resolver implementation.
Definition: dns_resolver.h:32
static int stub_resolve(struct ast_dns_query *query)
Definition: test_dns.c:36

◆ AST_TEST_DEFINE() [3/13]

AST_TEST_DEFINE ( resolver_unregister_off_nominal  )

Definition at line 158 of file test_dns.c.

References ast_dns_resolver_unregister(), AST_TEST_NOT_RUN, AST_TEST_PASS, sip_to_pjsip::info(), ast_dns_resolver::name, NULL, stub_cancel(), stub_resolve(), TEST_EXECUTE, and TEST_INIT.

159 {
160  struct ast_dns_resolver non_existent = {
161  .name = "I do not exist",
162  .priority = 20141004,
163  .resolve = stub_resolve,
164  .cancel = stub_cancel,
165  };
166 
167  switch (cmd) {
168  case TEST_INIT:
169  info->name = "resolver_unregister_off_nominal";
170  info->category = "/main/dns/";
171  info->summary = "Test off-nominal DNS resolver unregister";
172  info->description =
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.";
178  return AST_TEST_NOT_RUN;
179  case TEST_EXECUTE:
180  break;
181  }
182 
183  ast_dns_resolver_unregister(&non_existent);
185 
186  return AST_TEST_PASS;
187 }
void ast_dns_resolver_unregister(struct ast_dns_resolver *resolver)
Unregister a DNS resolver.
Definition: dns_core.c:680
static int stub_cancel(struct ast_dns_query *query)
Definition: test_dns.c:42
#define NULL
Definition: resample.c:96
const char * name
The name of the resolver implementation.
Definition: dns_resolver.h:34
def info(msg)
DNS resolver implementation.
Definition: dns_resolver.h:32
static int stub_resolve(struct ast_dns_query *query)
Definition: test_dns.c:36

◆ AST_TEST_DEFINE() [4/13]

AST_TEST_DEFINE ( resolver_data  )

Definition at line 189 of file test_dns.c.

References ao2_alloc, ao2_cleanup, ao2_ref, ast_dns_resolver_get_data(), ast_dns_resolver_set_data(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, RAII_VAR, TEST_EXECUTE, and TEST_INIT.

190 {
191  struct ast_dns_query some_query;
192 
193  struct digits {
194  int fingers;
195  int toes;
196  };
197 
198  RAII_VAR(struct digits *, average, NULL, ao2_cleanup);
199  RAII_VAR(struct digits *, polydactyl, NULL, ao2_cleanup);
200 
201  struct digits *data_ptr;
202 
203  switch (cmd) {
204  case TEST_INIT:
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";
214  return AST_TEST_NOT_RUN;
215  case TEST_EXECUTE:
216  break;
217  }
218 
219  memset(&some_query, 0, sizeof(some_query));
220 
221  average = ao2_alloc(sizeof(*average), NULL);
222  polydactyl = ao2_alloc(sizeof(*average), NULL);
223 
224  if (!average || !polydactyl) {
225  ast_test_status_update(test, "Allocation failure during unit test\n");
226  return AST_TEST_FAIL;
227  }
228 
229  /* Ensure that NULL is retrieved if we haven't set anything on the query */
230  data_ptr = ast_dns_resolver_get_data(&some_query);
231  if (data_ptr) {
232  ast_test_status_update(test, "Retrieved non-NULL resolver data from query unexpectedly\n");
233  return AST_TEST_FAIL;
234  }
235 
236  if (ast_dns_resolver_set_data(&some_query, average)) {
237  ast_test_status_update(test, "Failed to set resolver data on query\n");
238  return AST_TEST_FAIL;
239  }
240 
241  /* Go ahead now and remove the query's reference to the resolver data to prevent memory leaks */
242  ao2_ref(average, -1);
243 
244  /* Ensure that data can be set and retrieved */
245  data_ptr = ast_dns_resolver_get_data(&some_query);
246  if (!data_ptr) {
247  ast_test_status_update(test, "Unable to retrieve resolver data from DNS query\n");
248  return AST_TEST_FAIL;
249  }
250 
251  if (data_ptr != average) {
252  ast_test_status_update(test, "Unexpected resolver data retrieved from DNS query\n");
253  return AST_TEST_FAIL;
254  }
255 
256  /* Ensure that attempting to set new resolver data on the query fails */
257  if (!ast_dns_resolver_set_data(&some_query, polydactyl)) {
258  ast_test_status_update(test, "Successfully overwrote resolver data on a query. We shouldn't be able to do that\n");
259  return AST_TEST_FAIL;
260  }
261 
262  return AST_TEST_PASS;
263 }
#define NULL
Definition: resample.c:96
void * ast_dns_resolver_get_data(const struct ast_dns_query *query)
Retrieve resolver specific data.
Definition: dns_core.c:451
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
#define ao2_ref(o, delta)
Definition: astobj2.h:464
int ast_dns_resolver_set_data(struct ast_dns_query *query, void *data)
Set resolver specific data on a query.
Definition: dns_core.c:440
def info(msg)
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
A DNS query.
Definition: dns_internal.h:137
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ AST_TEST_DEFINE() [5/13]

AST_TEST_DEFINE ( resolver_set_result  )

Definition at line 297 of file test_dns.c.

References ARRAY_LEN, ast_dns_query_get_result(), ast_dns_resolver_set_result(), ast_dns_result_free(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, DNS_ANSWER, DNS_ANSWER_SIZE, sip_to_pjsip::info(), result, TEST_EXECUTE, TEST_INIT, and test_results().

298 {
299  struct ast_dns_query some_query;
300  struct ast_dns_result *result;
301 
302  struct dns_result {
303  unsigned int secure;
304  unsigned int bogus;
305  unsigned int rcode;
306  } results[] = {
307  { 0, 0, NOERROR, },
308  { 0, 1, NOERROR, },
309  { 1, 0, NOERROR, },
310  { 0, 0, NXDOMAIN, },
311  };
312  int i;
314 
315  switch (cmd) {
316  case TEST_INIT:
317  info->name = "resolver_set_result";
318  info->category = "/main/dns/";
319  info->summary = "Test setting and getting results on DNS queries";
320  info->description =
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.";
328  return AST_TEST_NOT_RUN;
329  case TEST_EXECUTE:
330  break;
331  }
332 
333  memset(&some_query, 0, sizeof(some_query));
334 
335  for (i = 0; i < ARRAY_LEN(results); ++i) {
336  if (ast_dns_resolver_set_result(&some_query, results[i].secure, results[i].bogus,
337  results[i].rcode, "asterisk.org", DNS_ANSWER, DNS_ANSWER_SIZE)) {
338  ast_test_status_update(test, "Unable to add DNS result to query\n");
339  res = AST_TEST_FAIL;
340  }
341 
342  if (test_results(test, &some_query, results[i].secure, results[i].bogus,
343  results[i].rcode, "asterisk.org", DNS_ANSWER, DNS_ANSWER_SIZE)) {
344  res = AST_TEST_FAIL;
345  }
346  }
347 
348  /* The final result we set needs to be freed */
349  result = ast_dns_query_get_result(&some_query);
350  ast_dns_result_free(result);
351 
352  return res;
353 }
#define DNS_ANSWER
Definition: test_dns.c:294
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
void ast_dns_result_free(struct ast_dns_result *result)
Free the DNS result information.
Definition: dns_core.c:130
#define DNS_ANSWER_SIZE
Definition: test_dns.c:295
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
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)
Definition: test_dns.c:265
The result of a DNS query.
Definition: dns_internal.h:117
struct ast_dns_result * ast_dns_query_get_result(const struct ast_dns_query *query)
Get the result information for a DNS query.
Definition: dns_core.c:77
def info(msg)
A DNS query.
Definition: dns_internal.h:137
static PGresult * result
Definition: cel_pgsql.c:88
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.
Definition: dns_core.c:456
ast_test_result_state
Definition: test.h:200

◆ AST_TEST_DEFINE() [6/13]

AST_TEST_DEFINE ( resolver_set_result_off_nominal  )

Definition at line 355 of file test_dns.c.

References ast_dns_query_get_result(), ast_dns_resolver_set_result(), ast_dns_result_free(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, DNS_ANSWER, DNS_ANSWER_SIZE, sip_to_pjsip::info(), NULL, result, TEST_EXECUTE, and TEST_INIT.

356 {
357  struct ast_dns_query some_query;
358  struct ast_dns_result *result;
359 
360  switch (cmd) {
361  case TEST_INIT:
362  info->name = "resolver_set_result_off_nominal";
363  info->category = "/main/dns/";
364  info->summary = "Test setting off-nominal DNS results";
365  info->description =
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";
369  return AST_TEST_NOT_RUN;
370  case TEST_EXECUTE:
371  break;
372  }
373 
374  memset(&some_query, 0, sizeof(some_query));
375 
376  if (!ast_dns_resolver_set_result(&some_query, 1, 1, NOERROR, "asterisk.org",
378  ast_test_status_update(test, "Successfully added a result that was both secure and bogus\n");
379  result = ast_dns_query_get_result(&some_query);
380  ast_dns_result_free(result);
381  return AST_TEST_FAIL;
382  }
383 
384  if (!ast_dns_resolver_set_result(&some_query, 0, 0, NOERROR, NULL,
386  ast_test_status_update(test, "Successfully added result with no canonical name\n");
387  result = ast_dns_query_get_result(&some_query);
388  ast_dns_result_free(result);
389  return AST_TEST_FAIL;
390  }
391 
392  return AST_TEST_PASS;
393 }
#define DNS_ANSWER
Definition: test_dns.c:294
void ast_dns_result_free(struct ast_dns_result *result)
Free the DNS result information.
Definition: dns_core.c:130
#define DNS_ANSWER_SIZE
Definition: test_dns.c:295
#define NULL
Definition: resample.c:96
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
The result of a DNS query.
Definition: dns_internal.h:117
struct ast_dns_result * ast_dns_query_get_result(const struct ast_dns_query *query)
Get the result information for a DNS query.
Definition: dns_core.c:77
def info(msg)
A DNS query.
Definition: dns_internal.h:137
static PGresult * result
Definition: cel_pgsql.c:88
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.
Definition: dns_core.c:456

◆ AST_TEST_DEFINE() [7/13]

AST_TEST_DEFINE ( resolver_add_record  )

Definition at line 421 of file test_dns.c.

References ARRAY_LEN, ast_dns_query_get_result(), ast_dns_record_get_next(), ast_dns_record_get_rr_type(), ast_dns_resolver_add_record(), ast_dns_resolver_set_result(), ast_dns_result_free(), ast_dns_result_get_records(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, DNS_ANSWER, DNS_ANSWER_SIZE, sip_to_pjsip::info(), NULL, RAII_VAR, records, result, TEST_EXECUTE, TEST_INIT, test_record(), and type.

422 {
424  struct ast_dns_query some_query;
425  const struct ast_dns_record *record;
426 
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];
430 
431  static const char *V6 = "::1";
432  static const size_t V6_BUFSIZE = sizeof(struct in6_addr);
433  char v6_buf[V6_BUFSIZE];
434 
435  struct dns_record_details {
436  int type;
437  int class;
438  int ttl;
439  const char *data;
440  const size_t size;
441  int visited;
442  } records[] = {
443  { T_A, C_IN, 12345, v4_buf, V4_BUFSIZE, 0, },
444  { T_AAAA, C_IN, 12345, v6_buf, V6_BUFSIZE, 0, },
445  };
446 
447  int num_records_visited = 0;
448 
449  switch (cmd) {
450  case TEST_INIT:
451  info->name = "resolver_add_record";
452  info->category = "/main/dns/";
453  info->summary = "Test adding DNS records to a query";
454  info->description =
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";
460  return AST_TEST_NOT_RUN;
461  case TEST_EXECUTE:
462  break;
463  }
464 
465  memset(&some_query, 0, sizeof(some_query));
466 
467  if (ast_dns_resolver_set_result(&some_query, 0, 0, NOERROR, "asterisk.org",
469  ast_test_status_update(test, "Unable to set result for DNS query\n");
470  return AST_TEST_FAIL;
471  }
472 
473  result = ast_dns_query_get_result(&some_query);
474  if (!result) {
475  ast_test_status_update(test, "Unable to retrieve result from query\n");
476  return AST_TEST_FAIL;
477  }
478 
479  inet_pton(AF_INET, V4, v4_buf);
480 
481  /* Nominal Record */
482  if (ast_dns_resolver_add_record(&some_query, records[0].type, records[0].class,
483  records[0].ttl, records[0].data, records[0].size)) {
484  ast_test_status_update(test, "Unable to add nominal record to query result\n");
485  return AST_TEST_FAIL;
486  }
487 
488  /* I should only be able to retrieve one record */
490  if (!record) {
491  ast_test_status_update(test, "Unable to retrieve record from result\n");
492  return AST_TEST_FAIL;
493  }
494 
495  if (test_record(test, record, records[0].type, records[0].class, records[0].ttl,
496  records[0].data, records[0].size)) {
497  return AST_TEST_FAIL;
498  }
499 
500  if (ast_dns_record_get_next(record)) {
501  ast_test_status_update(test, "Multiple records returned when only one was expected\n");
502  return AST_TEST_FAIL;
503  }
504 
505  inet_pton(AF_INET6, V6, v6_buf);
506 
507  if (ast_dns_resolver_add_record(&some_query, records[1].type, records[1].class,
508  records[1].ttl, records[1].data, records[1].size)) {
509  ast_test_status_update(test, "Unable to add second record to query result\n");
510  return AST_TEST_FAIL;
511  }
512 
513  for (record = ast_dns_result_get_records(result); record; record = ast_dns_record_get_next(record)) {
514  int res;
515 
516  /* The order of returned records is not specified by the API. We use the record type
517  * as the discriminator to determine which record data to expect.
518  */
519  if (ast_dns_record_get_rr_type(record) == records[0].type) {
520  res = test_record(test, record, records[0].type, records[0].class, records[0].ttl, records[0].data, records[0].size);
521  records[0].visited = 1;
522  } else if (ast_dns_record_get_rr_type(record) == records[1].type) {
523  res = test_record(test, record, records[1].type, records[1].class, records[1].ttl, records[1].data, records[1].size);
524  records[1].visited = 1;
525  } else {
526  ast_test_status_update(test, "Unknown record type found in DNS results\n");
527  return AST_TEST_FAIL;
528  }
529 
530  if (res) {
531  return AST_TEST_FAIL;
532  }
533 
534  ++num_records_visited;
535  }
536 
537  if (!records[0].visited || !records[1].visited) {
538  ast_test_status_update(test, "Did not visit all added DNS records\n");
539  return AST_TEST_FAIL;
540  }
541 
542  if (num_records_visited != ARRAY_LEN(records)) {
543  ast_test_status_update(test, "Did not visit the expected number of DNS records\n");
544  return AST_TEST_FAIL;
545  }
546 
547  return AST_TEST_PASS;
548 }
static const char type[]
Definition: chan_ooh323.c:109
static int records
Definition: cdr_mysql.c:84
const struct ast_dns_record * ast_dns_record_get_next(const struct ast_dns_record *record)
Get the next DNS record.
Definition: dns_core.c:170
#define DNS_ANSWER
Definition: test_dns.c:294
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
void ast_dns_result_free(struct ast_dns_result *result)
Free the DNS result information.
Definition: dns_core.c:130
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.
Definition: dns_core.c:535
#define DNS_ANSWER_SIZE
Definition: test_dns.c:295
For AST_LIST.
Definition: dns_internal.h:39
#define NULL
Definition: resample.c:96
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
The result of a DNS query.
Definition: dns_internal.h:117
struct ast_dns_result * ast_dns_query_get_result(const struct ast_dns_query *query)
Get the result information for a DNS query.
Definition: dns_core.c:77
def info(msg)
A DNS query.
Definition: dns_internal.h:137
const struct ast_dns_record * ast_dns_result_get_records(const struct ast_dns_result *result)
Get the first record of a DNS Result.
Definition: dns_core.c:102
static PGresult * result
Definition: cel_pgsql.c:88
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
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.
Definition: dns_core.c:456
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)
Definition: test_dns.c:395

◆ AST_TEST_DEFINE() [8/13]

AST_TEST_DEFINE ( resolver_add_record_off_nominal  )

Definition at line 550 of file test_dns.c.

References ast_dns_query_get_result(), ast_dns_resolver_add_record(), ast_dns_resolver_set_result(), ast_dns_result_free(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, DNS_ANSWER, DNS_ANSWER_SIZE, sip_to_pjsip::info(), NULL, RAII_VAR, result, TEST_EXECUTE, and TEST_INIT.

551 {
553  struct ast_dns_query some_query;
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];
557 
558  switch (cmd) {
559  case TEST_INIT:
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";
563  info->description =
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";
571  return AST_TEST_NOT_RUN;
572  case TEST_EXECUTE:
573  break;
574  }
575 
576  memset(&some_query, 0, sizeof(some_query));
577 
578  inet_ntop(AF_INET, V4, v4_buf, V4_BUFSIZE);
579 
580  /* Add record before setting result */
581  if (!ast_dns_resolver_add_record(&some_query, T_A, C_IN, 12345, v4_buf, V4_BUFSIZE)) {
582  ast_test_status_update(test, "Successfully added DNS record to query before setting a result\n");
583  return AST_TEST_FAIL;
584  }
585 
586  if (ast_dns_resolver_set_result(&some_query, 0, 0, NOERROR, "asterisk.org",
588  ast_test_status_update(test, "Unable to set result for DNS query\n");
589  return AST_TEST_FAIL;
590  }
591 
592  /* We get the result so it will be cleaned up when the function exits */
593  result = ast_dns_query_get_result(&some_query);
594 
595  /* Invalid RR types */
596  if (!ast_dns_resolver_add_record(&some_query, -1, C_IN, 12345, v4_buf, V4_BUFSIZE)) {
597  ast_test_status_update(test, "Successfully added DNS record with negative RR type\n");
598  return AST_TEST_FAIL;
599  }
600 
601  if (!ast_dns_resolver_add_record(&some_query, 65536 + 1, C_IN, 12345, v4_buf, V4_BUFSIZE)) {
602  ast_test_status_update(test, "Successfully added DNS record with too large RR type\n");
603  return AST_TEST_FAIL;
604  }
605 
606  /* Invalid RR classes */
607  if (!ast_dns_resolver_add_record(&some_query, T_A, -1, 12345, v4_buf, V4_BUFSIZE)) {
608  ast_test_status_update(test, "Successfully added DNS record with negative RR class\n");
609  return AST_TEST_FAIL;
610  }
611 
612  if (!ast_dns_resolver_add_record(&some_query, T_A, 65536 + 1, 12345, v4_buf, V4_BUFSIZE)) {
613  ast_test_status_update(test, "Successfully added DNS record with too large RR class\n");
614  return AST_TEST_FAIL;
615  }
616 
617  /* Invalid TTL */
618  if (!ast_dns_resolver_add_record(&some_query, T_A, C_IN, -1, v4_buf, V4_BUFSIZE)) {
619  ast_test_status_update(test, "Successfully added DNS record with negative TTL\n");
620  return AST_TEST_FAIL;
621  }
622 
623  /* No data */
624  if (!ast_dns_resolver_add_record(&some_query, T_A, C_IN, 12345, NULL, 0)) {
625  ast_test_status_update(test, "Successfully added a DNS record with no data\n");
626  return AST_TEST_FAIL;
627  }
628 
629  /* Lie about the length */
630  if (!ast_dns_resolver_add_record(&some_query, T_A, C_IN, 12345, v4_buf, 0)) {
631  ast_test_status_update(test, "Successfully added a DNS record with length zero\n");
632  return AST_TEST_FAIL;
633  }
634 
635  return AST_TEST_PASS;
636 }
#define DNS_ANSWER
Definition: test_dns.c:294
void ast_dns_result_free(struct ast_dns_result *result)
Free the DNS result information.
Definition: dns_core.c:130
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.
Definition: dns_core.c:535
#define DNS_ANSWER_SIZE
Definition: test_dns.c:295
#define NULL
Definition: resample.c:96
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
The result of a DNS query.
Definition: dns_internal.h:117
struct ast_dns_result * ast_dns_query_get_result(const struct ast_dns_query *query)
Get the result information for a DNS query.
Definition: dns_core.c:77
def info(msg)
A DNS query.
Definition: dns_internal.h:137
static PGresult * result
Definition: cel_pgsql.c:88
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.
Definition: dns_core.c:456

◆ AST_TEST_DEFINE() [9/13]

AST_TEST_DEFINE ( resolver_resolve_sync  )

Definition at line 781 of file test_dns.c.

References ast_dns_resolve(), ast_dns_resolver_register(), ast_dns_resolver_unregister(), ast_dns_result_free(), ast_dns_result_get_records(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, resolver_data::canceled, cleanup(), sip_to_pjsip::info(), NULL, RAII_VAR, resolver_data::resolution_complete, resolver_data::resolve_called, resolver_data_cleanup(), resolver_data_init(), result, TEST_EXECUTE, TEST_INIT, and test_resolver_data.

782 {
785 
786  switch (cmd) {
787  case TEST_INIT:
788  info->name = "resolver_resolve_sync";
789  info->category = "/main/dns/";
790  info->summary = "Test a nominal synchronous DNS resolution";
791  info->description =
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.";
797  return AST_TEST_NOT_RUN;
798  case TEST_EXECUTE:
799  break;
800  }
801 
803  ast_test_status_update(test, "Unable to register test resolver\n");
804  return AST_TEST_FAIL;
805  }
806 
808 
809  if (ast_dns_resolve("asterisk.org", T_A, C_IN, &result)) {
810  ast_test_status_update(test, "Resolution of address failed\n");
811  res = AST_TEST_FAIL;
812  goto cleanup;
813  }
814 
815  if (!result) {
816  ast_test_status_update(test, "DNS resolution returned a NULL result\n");
817  res = AST_TEST_FAIL;
818  goto cleanup;
819  }
820 
822  ast_test_status_update(test, "DNS resolution did not call resolver's resolve() method\n");
823  res = AST_TEST_FAIL;
824  goto cleanup;
825  }
826 
828  ast_test_status_update(test, "Resolver's cancel() method called for no reason\n");
829  res = AST_TEST_FAIL;
830  goto cleanup;
831  }
832 
834  ast_test_status_update(test, "Synchronous resolution completed early?\n");
835  res = AST_TEST_FAIL;
836  goto cleanup;
837  }
838 
840  ast_test_status_update(test, "Synchronous resolution yielded no records.\n");
841  res = AST_TEST_FAIL;
842  goto cleanup;
843  }
844 
845 cleanup:
848  return res;
849 }
int ast_dns_resolve(const char *name, int rr_type, int rr_class, struct ast_dns_result **result)
Synchronously resolve a DNS query.
Definition: dns_core.c:314
void ast_dns_result_free(struct ast_dns_result *result)
Free the DNS result information.
Definition: dns_core.c:130
static void resolver_data_init(void)
Initialize global mock resolver data.
Definition: test_dns.c:746
static struct resolver_data test_resolver_data
int resolve_called
Definition: test_dns.c:646
void ast_dns_resolver_unregister(struct ast_dns_resolver *resolver)
Unregister a DNS resolver.
Definition: dns_core.c:680
static struct ast_dns_resolver test_resolver
The mock resolver.
Definition: test_dns.c:774
#define NULL
Definition: resample.c:96
int resolution_complete
Definition: test_dns.c:650
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
int ast_dns_resolver_register(struct ast_dns_resolver *resolver)
Register a DNS resolver.
Definition: dns_core.c:630
The result of a DNS query.
Definition: dns_internal.h:117
def info(msg)
const struct ast_dns_record * ast_dns_result_get_records(const struct ast_dns_result *result)
Get the first record of a DNS Result.
Definition: dns_core.c:102
static void * cleanup(void *unused)
Definition: pbx_realtime.c:124
static PGresult * result
Definition: cel_pgsql.c:88
static void resolver_data_cleanup(void)
Cleanup global mock resolver data.
Definition: test_dns.c:761
ast_test_result_state
Definition: test.h:200

◆ AST_TEST_DEFINE() [10/13]

AST_TEST_DEFINE ( resolver_resolve_sync_off_nominal  )

Definition at line 862 of file test_dns.c.

References ARRAY_LEN, ast_dns_resolve(), ast_dns_resolver_register(), ast_dns_resolver_unregister(), ast_dns_result_free(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, fail_resolve(), sip_to_pjsip::info(), ast_dns_resolver::name, name, NULL, result, stub_cancel(), TEST_EXECUTE, and TEST_INIT.

863 {
864  struct ast_dns_resolver terrible_resolver = {
865  .name = "Uwe Boll's Filmography",
866  .priority = 0,
867  .resolve = fail_resolve,
868  .cancel = stub_cancel,
869  };
870 
871  struct ast_dns_result *result = NULL;
872 
873  struct dns_resolve_data {
874  const char *name;
875  int rr_type;
876  int rr_class;
877  struct ast_dns_result **result;
878  } resolves [] = {
879  { NULL, T_A, C_IN, &result },
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 },
885  };
886 
887  int i;
888 
890 
891  switch (cmd) {
892  case TEST_INIT:
893  info->name = "resolver_resolve_sync_off_nominal";
894  info->category = "/main/dns/";
895  info->summary = "Test off-nominal synchronous DNS resolution";
896  info->description =
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";
903  return AST_TEST_NOT_RUN;
904  case TEST_EXECUTE:
905  break;
906  }
907 
909  ast_test_status_update(test, "Failed to register test resolver\n");
910  return AST_TEST_FAIL;
911  }
912 
913  for (i = 0; i < ARRAY_LEN(resolves); ++i) {
914  if (!ast_dns_resolve(resolves[i].name, resolves[i].rr_type, resolves[i].rr_class, resolves[i].result)) {
915  ast_test_status_update(test, "Successfully resolved DNS query with invalid parameters\n");
916  res = AST_TEST_FAIL;
917  } else if (result) {
918  ast_test_status_update(test, "Failed resolution set a non-NULL result\n");
919  ast_dns_result_free(result);
920  res = AST_TEST_FAIL;
921  }
922  }
923 
925 
926  /* As a final test, try a legitimate query with a bad resolver */
927  if (ast_dns_resolver_register(&terrible_resolver)) {
928  ast_test_status_update(test, "Failed to register the terrible resolver\n");
929  return AST_TEST_FAIL;
930  }
931 
932  if (!ast_dns_resolve("asterisk.org", T_A, C_IN, &result)) {
933  ast_test_status_update(test, "DNS resolution succeeded when we expected it not to\n");
934  ast_dns_resolver_unregister(&terrible_resolver);
935  return AST_TEST_FAIL;
936  }
937 
938  ast_dns_resolver_unregister(&terrible_resolver);
939 
940  if (result) {
941  ast_test_status_update(test, "Failed DNS resolution set the result to something non-NULL\n");
942  ast_dns_result_free(result);
943  return AST_TEST_FAIL;
944  }
945 
946  return res;
947 }
int ast_dns_resolve(const char *name, int rr_type, int rr_class, struct ast_dns_result **result)
Synchronously resolve a DNS query.
Definition: dns_core.c:314
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
void ast_dns_result_free(struct ast_dns_result *result)
Free the DNS result information.
Definition: dns_core.c:130
void ast_dns_resolver_unregister(struct ast_dns_resolver *resolver)
Unregister a DNS resolver.
Definition: dns_core.c:680
static struct ast_dns_resolver test_resolver
The mock resolver.
Definition: test_dns.c:774
static int stub_cancel(struct ast_dns_query *query)
Definition: test_dns.c:42
#define NULL
Definition: resample.c:96
const char * name
The name of the resolver implementation.
Definition: dns_resolver.h:34
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
int ast_dns_resolver_register(struct ast_dns_resolver *resolver)
Register a DNS resolver.
Definition: dns_core.c:630
The result of a DNS query.
Definition: dns_internal.h:117
def info(msg)
DNS resolver implementation.
Definition: dns_resolver.h:32
static const char name[]
Definition: cdr_mysql.c:74
static PGresult * result
Definition: cel_pgsql.c:88
static int fail_resolve(struct ast_dns_query *query)
A resolve() method that simply fails.
Definition: test_dns.c:857
ast_test_result_state
Definition: test.h:200

◆ AST_TEST_DEFINE() [11/13]

AST_TEST_DEFINE ( resolver_resolve_async  )

Definition at line 1018 of file test_dns.c.

References ao2_cleanup, ast_cond_timedwait, ast_dns_query_get_result(), ast_dns_resolve_async(), ast_dns_resolver_register(), ast_dns_resolver_unregister(), ast_dns_result_get_records(), ast_mutex_lock, ast_mutex_unlock, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_tsnow(), async_callback(), async_data_alloc(), resolver_data::canceled, cleanup(), async_data::complete, async_data::cond, sip_to_pjsip::info(), async_data::lock, NULL, RAII_VAR, resolver_data::resolution_complete, resolver_data::resolve_called, resolver_data_cleanup(), resolver_data_init(), result, TEST_EXECUTE, TEST_INIT, and test_resolver_data.

1019 {
1021  RAII_VAR(struct ast_dns_query_active *, active, NULL, ao2_cleanup);
1022  struct ast_dns_result *result;
1024  struct timespec timeout;
1025 
1026  switch (cmd) {
1027  case TEST_INIT:
1028  info->name = "resolver_resolve_async";
1029  info->category = "/main/dns/";
1030  info->summary = "Test a nominal asynchronous DNS resolution";
1031  info->description =
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.";
1036  return AST_TEST_NOT_RUN;
1037  case TEST_EXECUTE:
1038  break;
1039  }
1040 
1042  ast_test_status_update(test, "Unable to register test resolver\n");
1043  return AST_TEST_FAIL;
1044  }
1045 
1047 
1049  if (!async_data) {
1050  ast_test_status_update(test, "Failed to allocate asynchronous data\n");
1051  res = AST_TEST_FAIL;
1052  goto cleanup;
1053  }
1054 
1055  active = ast_dns_resolve_async("asterisk.org", T_A, C_IN, async_callback, async_data);
1056  if (!active) {
1057  ast_test_status_update(test, "Asynchronous resolution of address failed\n");
1058  res = AST_TEST_FAIL;
1059  goto cleanup;
1060  }
1061 
1063  ast_test_status_update(test, "DNS resolution did not call resolver's resolve() method\n");
1064  res = AST_TEST_FAIL;
1065  goto cleanup;
1066  }
1067 
1069  ast_test_status_update(test, "Resolver's cancel() method called for no reason\n");
1070  res = AST_TEST_FAIL;
1071  goto cleanup;
1072  }
1073 
1074  timeout = ast_tsnow();
1075  timeout.tv_sec += 10;
1077  while (!async_data->complete) {
1078  if (ast_cond_timedwait(&async_data->cond, &async_data->lock, &timeout) == ETIMEDOUT) {
1079  break;
1080  }
1081  }
1083 
1084  if (!async_data->complete) {
1085  ast_test_status_update(test, "Asynchronous resolution timed out\n");
1086  res = AST_TEST_FAIL;
1087  goto cleanup;
1088  }
1089 
1091  ast_test_status_update(test, "Asynchronous resolution completed early?\n");
1092  res = AST_TEST_FAIL;
1093  goto cleanup;
1094  }
1095 
1096  result = ast_dns_query_get_result(active->query);
1097  if (!result) {
1098  ast_test_status_update(test, "Asynchronous resolution yielded no result\n");
1099  res = AST_TEST_FAIL;
1100  goto cleanup;
1101  }
1102 
1103  if (!ast_dns_result_get_records(result)) {
1104  ast_test_status_update(test, "Asynchronous result had no records\n");
1105  res = AST_TEST_FAIL;
1106  goto cleanup;
1107  }
1108 
1109 cleanup:
1112  return res;
1113 }
Data required for an asynchronous callback.
Data used by async result callback.
Definition: test_dns.c:957
static void resolver_data_init(void)
Initialize global mock resolver data.
Definition: test_dns.c:746
static struct resolver_data test_resolver_data
int resolve_called
Definition: test_dns.c:646
void ast_dns_resolver_unregister(struct ast_dns_resolver *resolver)
Unregister a DNS resolver.
Definition: dns_core.c:680
ast_mutex_t lock
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.
Definition: dns_core.c:247
static int timeout
Definition: cdr_mysql.c:86
static struct ast_dns_resolver test_resolver
The mock resolver.
Definition: test_dns.c:774
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
int resolution_complete
Definition: test_dns.c:650
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
int ast_dns_resolver_register(struct ast_dns_resolver *resolver)
Register a DNS resolver.
Definition: dns_core.c:630
static void async_callback(const struct ast_dns_query *query)
Async DNS callback.
Definition: test_dns.c:1008
static struct async_resolution_data * async_data_alloc(void)
Allocation/initialization for async_resolution_data.
Definition: test_dns.c:983
The result of a DNS query.
Definition: dns_internal.h:117
An active DNS query.
Definition: dns_internal.h:201
struct ast_dns_result * ast_dns_query_get_result(const struct ast_dns_query *query)
Get the result information for a DNS query.
Definition: dns_core.c:77
def info(msg)
const struct ast_dns_record * ast_dns_result_get_records(const struct ast_dns_result *result)
Get the first record of a DNS Result.
Definition: dns_core.c:102
static void * cleanup(void *unused)
Definition: pbx_realtime.c:124
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static PGresult * result
Definition: cel_pgsql.c:88
struct timespec ast_tsnow(void)
Returns current timespec. Meant to avoid calling ast_tvnow() just to create a timespec from the timev...
Definition: time.h:177
static void resolver_data_cleanup(void)
Cleanup global mock resolver data.
Definition: test_dns.c:761
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:204
ast_test_result_state
Definition: test.h:200
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ AST_TEST_DEFINE() [12/13]

AST_TEST_DEFINE ( resolver_resolve_async_off_nominal  )

Definition at line 1121 of file test_dns.c.

References ao2_ref, ARRAY_LEN, ast_dns_resolve_async(), ast_dns_resolver_register(), ast_dns_resolver_unregister(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, fail_resolve(), sip_to_pjsip::info(), ast_dns_resolver::name, name, NULL, stub_callback(), stub_cancel(), TEST_EXECUTE, and TEST_INIT.

1122 {
1123  struct ast_dns_resolver terrible_resolver = {
1124  .name = "Ed Wood's Filmography",
1125  .priority = 0,
1126  .resolve = fail_resolve,
1127  .cancel = stub_cancel,
1128  };
1129 
1130  struct dns_resolve_data {
1131  const char *name;
1132  int rr_type;
1133  int rr_class;
1134  ast_dns_resolve_callback callback;
1135  } resolves [] = {
1136  { NULL, T_A, C_IN, stub_callback },
1137  { "asterisk.org", -1, C_IN, stub_callback },
1138  { "asterisk.org", 65536 + 1, C_IN, stub_callback },
1139  { "asterisk.org", T_A, -1, stub_callback },
1140  { "asterisk.org", T_A, 65536 + 1, stub_callback },
1141  { "asterisk.org", T_A, C_IN, NULL },
1142  };
1143 
1144  struct ast_dns_query_active *active;
1146  int i;
1147 
1148  switch (cmd) {
1149  case TEST_INIT:
1150  info->name = "resolver_resolve_async_off_nominal";
1151  info->category = "/main/dns/";
1152  info->summary = "Test off-nominal asynchronous DNS resolution";
1153  info->description =
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";
1160  return AST_TEST_NOT_RUN;
1161  case TEST_EXECUTE:
1162  break;
1163  }
1164 
1166  ast_test_status_update(test, "Failed to register test resolver\n");
1167  return AST_TEST_FAIL;
1168  }
1169 
1170  for (i = 0; i < ARRAY_LEN(resolves); ++i) {
1171  active = ast_dns_resolve_async(resolves[i].name, resolves[i].rr_type, resolves[i].rr_class,
1172  resolves[i].callback, NULL);
1173  if (active) {
1174  ast_test_status_update(test, "Successfully performed asynchronous resolution with invalid data\n");
1175  ao2_ref(active, -1);
1176  res = AST_TEST_FAIL;
1177  }
1178  }
1179 
1181 
1182  if (ast_dns_resolver_register(&terrible_resolver)) {
1183  ast_test_status_update(test, "Failed to register the DNS resolver\n");
1184  return AST_TEST_FAIL;
1185  }
1186 
1187  active = ast_dns_resolve_async("asterisk.org", T_A, C_IN, stub_callback, NULL);
1188 
1189  ast_dns_resolver_unregister(&terrible_resolver);
1190 
1191  if (active) {
1192  ast_test_status_update(test, "Successfully performed asynchronous resolution with invalid data\n");
1193  ao2_ref(active, -1);
1194  return AST_TEST_FAIL;
1195  }
1196 
1197  return res;
1198 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
void ast_dns_resolver_unregister(struct ast_dns_resolver *resolver)
Unregister a DNS resolver.
Definition: dns_core.c:680
void(* ast_dns_resolve_callback)(const struct ast_dns_query *query)
Callback invoked when a query completes.
Definition: dns_core.h:171
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.
Definition: dns_core.c:247
static void stub_callback(const struct ast_dns_query *query)
Definition: test_dns.c:1116
static struct ast_dns_resolver test_resolver
The mock resolver.
Definition: test_dns.c:774
static int stub_cancel(struct ast_dns_query *query)
Definition: test_dns.c:42
#define NULL
Definition: resample.c:96
const char * name
The name of the resolver implementation.
Definition: dns_resolver.h:34
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
int ast_dns_resolver_register(struct ast_dns_resolver *resolver)
Register a DNS resolver.
Definition: dns_core.c:630
#define ao2_ref(o, delta)
Definition: astobj2.h:464
An active DNS query.
Definition: dns_internal.h:201
def info(msg)
DNS resolver implementation.
Definition: dns_resolver.h:32
static const char name[]
Definition: cdr_mysql.c:74
static int fail_resolve(struct ast_dns_query *query)
A resolve() method that simply fails.
Definition: test_dns.c:857
ast_test_result_state
Definition: test.h:200

◆ AST_TEST_DEFINE() [13/13]

AST_TEST_DEFINE ( resolver_resolve_async_cancel  )

Definition at line 1200 of file test_dns.c.

References ao2_cleanup, ast_cond_timedwait, ast_dns_query_get_result(), ast_dns_resolve_async(), ast_dns_resolve_cancel(), ast_dns_resolver_register(), ast_dns_resolver_unregister(), ast_mutex_lock, ast_mutex_unlock, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ast_tsnow(), async_callback(), async_data_alloc(), resolver_data::canceled, cleanup(), async_data::complete, async_data::cond, sip_to_pjsip::info(), async_data::lock, NULL, RAII_VAR, resolver_data::resolution_complete, resolver_data::resolve_called, resolver_data_cleanup(), resolver_data_init(), result, TEST_EXECUTE, TEST_INIT, and test_resolver_data.

1201 {
1203  RAII_VAR(struct ast_dns_query_active *, active, NULL, ao2_cleanup);
1204  struct ast_dns_result *result;
1206  struct timespec timeout;
1207 
1208  switch (cmd) {
1209  case TEST_INIT:
1210  info->name = "resolver_resolve_async_cancel";
1211  info->category = "/main/dns/";
1212  info->summary = "Test canceling an asynchronous DNS resolution";
1213  info->description =
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.";
1218  return AST_TEST_NOT_RUN;
1219  case TEST_EXECUTE:
1220  break;
1221  }
1222 
1224  ast_test_status_update(test, "Unable to register test resolver\n");
1225  return AST_TEST_FAIL;
1226  }
1227 
1229 
1231  if (!async_data) {
1232  ast_test_status_update(test, "Failed to allocate asynchronous data\n");
1233  res = AST_TEST_FAIL;
1234  goto cleanup;
1235  }
1236 
1237  active = ast_dns_resolve_async("asterisk.org", T_A, C_IN, async_callback, async_data);
1238  if (!active) {
1239  ast_test_status_update(test, "Asynchronous resolution of address failed\n");
1240  res = AST_TEST_FAIL;
1241  goto cleanup;
1242  }
1243 
1245  ast_test_status_update(test, "DNS resolution did not call resolver's resolve() method\n");
1246  res = AST_TEST_FAIL;
1247  goto cleanup;
1248  }
1249 
1251  ast_test_status_update(test, "Resolver's cancel() method called for no reason\n");
1252  res = AST_TEST_FAIL;
1253  goto cleanup;
1254  }
1255 
1256  ast_dns_resolve_cancel(active);
1257 
1259  ast_test_status_update(test, "Resolver's cancel() method was not called\n");
1260  res = AST_TEST_FAIL;
1261  goto cleanup;
1262  }
1263 
1264  timeout = ast_tsnow();
1265  timeout.tv_sec += 10;
1267  while (!async_data->complete) {
1268  if (ast_cond_timedwait(&async_data->cond, &async_data->lock, &timeout) == ETIMEDOUT) {
1269  break;
1270  }
1271  }
1273 
1274  if (!async_data->complete) {
1275  ast_test_status_update(test, "Asynchronous resolution timed out\n");
1276  res = AST_TEST_FAIL;
1277  goto cleanup;
1278  }
1279 
1281  ast_test_status_update(test, "Resolution completed without cancelation\n");
1282  res = AST_TEST_FAIL;
1283  goto cleanup;
1284  }
1285 
1286  result = ast_dns_query_get_result(active->query);
1287  if (result) {
1288  ast_test_status_update(test, "Canceled resolution had a result\n");
1289  res = AST_TEST_FAIL;
1290  goto cleanup;
1291  }
1292 
1293 cleanup:
1296  return res;
1297 }
Data required for an asynchronous callback.
Data used by async result callback.
Definition: test_dns.c:957
static void resolver_data_init(void)
Initialize global mock resolver data.
Definition: test_dns.c:746
static struct resolver_data test_resolver_data
int resolve_called
Definition: test_dns.c:646
void ast_dns_resolver_unregister(struct ast_dns_resolver *resolver)
Unregister a DNS resolver.
Definition: dns_core.c:680
ast_mutex_t lock
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.
Definition: dns_core.c:247
static int timeout
Definition: cdr_mysql.c:86
static struct ast_dns_resolver test_resolver
The mock resolver.
Definition: test_dns.c:774
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
int resolution_complete
Definition: test_dns.c:650
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
int ast_dns_resolver_register(struct ast_dns_resolver *resolver)
Register a DNS resolver.
Definition: dns_core.c:630
static void async_callback(const struct ast_dns_query *query)
Async DNS callback.
Definition: test_dns.c:1008
static struct async_resolution_data * async_data_alloc(void)
Allocation/initialization for async_resolution_data.
Definition: test_dns.c:983
The result of a DNS query.
Definition: dns_internal.h:117
An active DNS query.
Definition: dns_internal.h:201
struct ast_dns_result * ast_dns_query_get_result(const struct ast_dns_query *query)
Get the result information for a DNS query.
Definition: dns_core.c:77
def info(msg)
static void * cleanup(void *unused)
Definition: pbx_realtime.c:124
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int ast_dns_resolve_cancel(struct ast_dns_query_active *active)
Cancel an asynchronous DNS resolution.
Definition: dns_core.c:272
static PGresult * result
Definition: cel_pgsql.c:88
struct timespec ast_tsnow(void)
Returns current timespec. Meant to avoid calling ast_tvnow() just to create a timespec from the timev...
Definition: time.h:177
static void resolver_data_cleanup(void)
Cleanup global mock resolver data.
Definition: test_dns.c:761
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:204
ast_test_result_state
Definition: test.h:200
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ async_callback()

static void async_callback ( const struct ast_dns_query query)
static

Async DNS callback.

This is called when an async query completes, either because it resolved or because it was canceled. In our case, this callback is used to signal to the test that it can continue

Parameters
queryThe DNS query that has completed

Definition at line 1008 of file test_dns.c.

References ast_cond_signal, ast_dns_query_get_data(), ast_mutex_lock, ast_mutex_unlock, async_resolution_data::complete, async_resolution_data::cond, and async_resolution_data::lock.

Referenced by AST_TEST_DEFINE().

1009 {
1011 
1012  ast_mutex_lock(&async_data->lock);
1013  async_data->complete = 1;
1014  ast_cond_signal(&async_data->cond);
1015  ast_mutex_unlock(&async_data->lock);
1016 }
Data required for an asynchronous callback.
Data used by async result callback.
Definition: test_dns.c:957
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ast_cond_signal(cond)
Definition: lock.h:201
void * ast_dns_query_get_data(const struct ast_dns_query *query)
Get the user specific data of a DNS query.
Definition: dns_core.c:72
ast_mutex_t lock
Definition: test_dns.c:959
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ async_data_alloc()

static struct async_resolution_data* async_data_alloc ( void  )
static

Allocation/initialization for async_resolution_data.

The DNS core mandates that a query's user data has to be ao2 allocated, so this is a helper method for doing that.

Return values
NULLFailed allocation
non-NULLNewly allocated async_resolution_data

Definition at line 983 of file test_dns.c.

References ao2_alloc, ast_cond_init, ast_mutex_init, async_data_destructor(), async_resolution_data::complete, async_resolution_data::cond, async_resolution_data::lock, and NULL.

Referenced by AST_TEST_DEFINE().

984 {
986 
987  async_data = ao2_alloc(sizeof(*async_data), async_data_destructor);
988  if (!async_data) {
989  return NULL;
990  }
991 
992  async_data->complete = 0;
993  ast_mutex_init(&async_data->lock);
994  ast_cond_init(&async_data->cond, NULL);
995 
996  return async_data;
997 }
static void async_data_destructor(void *obj)
Destructor for async_resolution_data.
Definition: test_dns.c:966
Data required for an asynchronous callback.
Data used by async result callback.
Definition: test_dns.c:957
#define ast_cond_init(cond, attr)
Definition: lock.h:199
#define NULL
Definition: resample.c:96
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
ast_mutex_t lock
Definition: test_dns.c:959
#define ast_mutex_init(pmutex)
Definition: lock.h:184

◆ async_data_destructor()

static void async_data_destructor ( void *  obj)
static

Destructor for async_resolution_data.

Definition at line 966 of file test_dns.c.

References ast_cond_destroy, ast_mutex_destroy, async_resolution_data::cond, and async_resolution_data::lock.

Referenced by async_data_alloc().

967 {
968  struct async_resolution_data *async_data = obj;
969 
970  ast_mutex_destroy(&async_data->lock);
971  ast_cond_destroy(&async_data->cond);
972 }
Data required for an asynchronous callback.
Data used by async result callback.
Definition: test_dns.c:957
#define ast_cond_destroy(cond)
Definition: lock.h:200
ast_mutex_t lock
Definition: test_dns.c:959
#define ast_mutex_destroy(a)
Definition: lock.h:186

◆ fail_resolve()

static int fail_resolve ( struct ast_dns_query query)
static

A resolve() method that simply fails.

Parameters
queryThe DNS query to resolve. This is ignored.
Returns
-1

Definition at line 857 of file test_dns.c.

Referenced by AST_TEST_DEFINE().

858 {
859  return -1;
860 }

◆ load_module()

static int load_module ( void  )
static

Definition at line 1318 of file test_dns.c.

References AST_MODULE_LOAD_SUCCESS, and AST_TEST_REGISTER.

1319 {
1320  AST_TEST_REGISTER(resolver_register_unregister);
1321  AST_TEST_REGISTER(resolver_register_off_nominal);
1322  AST_TEST_REGISTER(resolver_unregister_off_nominal);
1324  AST_TEST_REGISTER(resolver_set_result);
1325  AST_TEST_REGISTER(resolver_set_result_off_nominal);
1326  AST_TEST_REGISTER(resolver_add_record);
1327  AST_TEST_REGISTER(resolver_add_record_off_nominal);
1328  AST_TEST_REGISTER(resolver_resolve_sync);
1329  AST_TEST_REGISTER(resolver_resolve_sync_off_nominal);
1330  AST_TEST_REGISTER(resolver_resolve_async);
1331  AST_TEST_REGISTER(resolver_resolve_async_off_nominal);
1332  AST_TEST_REGISTER(resolver_resolve_async_cancel);
1333 
1334  return AST_MODULE_LOAD_SUCCESS;
1335 }
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
File-scoped data used during resolver tests.
Definition: test_dns.c:644

◆ resolution_thread()

static void* resolution_thread ( void *  dns_query)
static

Thread spawned by the mock resolver.

All DNS resolvers are required to be asynchronous. The mock resolver spawns this thread for every DNS query that is executed.

This thread waits for 5 seconds and then returns the same A record every time. The 5 second wait is to allow for the query to be canceled if desired

Parameters
dns_queryThe ast_dns_query that is being resolved
Returns
NULL

Definition at line 670 of file test_dns.c.

References ao2_ref, ast_cond_timedwait, ast_dns_resolver_add_record(), ast_dns_resolver_completed(), ast_dns_resolver_set_result(), ast_mutex_lock, ast_mutex_unlock, ast_tsnow(), resolver_data::cancel_cond, resolver_data::canceled, DNS_ANSWER, DNS_ANSWER_SIZE, resolver_data::lock, NULL, resolver_data::resolution_complete, and test_resolver_data.

Referenced by test_resolve().

671 {
672  struct ast_dns_query *query = dns_query;
673  struct timespec timeout;
674 
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];
678 
679  timeout = ast_tsnow();
680  timeout.tv_sec += 5;
681 
683  while (!test_resolver_data.canceled) {
685  break;
686  }
687  }
689 
692  ao2_ref(query, -1);
693  return NULL;
694  }
695 
696  ast_dns_resolver_set_result(query, 0, 0, NOERROR, "asterisk.org", DNS_ANSWER, DNS_ANSWER_SIZE);
697 
698  inet_pton(AF_INET, V4, v4_buf);
699  ast_dns_resolver_add_record(query, T_A, C_IN, 12345, v4_buf, V4_BUFSIZE);
700 
703 
704  ao2_ref(query, -1);
705  return NULL;
706 }
#define DNS_ANSWER
Definition: test_dns.c:294
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.
Definition: dns_core.c:535
#define DNS_ANSWER_SIZE
Definition: test_dns.c:295
static struct resolver_data test_resolver_data
static int timeout
Definition: cdr_mysql.c:86
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
int resolution_complete
Definition: test_dns.c:650
ast_cond_t cancel_cond
Definition: test_dns.c:654
#define ao2_ref(o, delta)
Definition: astobj2.h:464
void ast_dns_resolver_completed(struct ast_dns_query *query)
Mark a DNS query as having been completed.
Definition: dns_core.c:599
A DNS query.
Definition: dns_internal.h:137
ast_mutex_t lock
Definition: test_dns.c:652
struct timespec ast_tsnow(void)
Returns current timespec. Meant to avoid calling ast_tvnow() just to create a timespec from the timev...
Definition: time.h:177
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.
Definition: dns_core.c:456
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:204
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ resolver_data_cleanup()

static void resolver_data_cleanup ( void  )
static

Cleanup global mock resolver data.

This must be called at the end of tests that use the mock resolver

Definition at line 761 of file test_dns.c.

References ast_cond_destroy, ast_mutex_destroy, resolver_data::cancel_cond, resolver_data::lock, and test_resolver_data.

Referenced by AST_TEST_DEFINE().

762 {
765 }
static struct resolver_data test_resolver_data
ast_cond_t cancel_cond
Definition: test_dns.c:654
#define ast_cond_destroy(cond)
Definition: lock.h:200
ast_mutex_t lock
Definition: test_dns.c:652
#define ast_mutex_destroy(a)
Definition: lock.h:186

◆ resolver_data_init()

static void resolver_data_init ( void  )
static

Initialize global mock resolver data.

This must be called at the beginning of tests that use the mock resolver

Definition at line 746 of file test_dns.c.

References ast_cond_init, ast_mutex_init, resolver_data::cancel_cond, resolver_data::canceled, resolver_data::lock, NULL, resolver_data::resolution_complete, resolver_data::resolve_called, and test_resolver_data.

Referenced by AST_TEST_DEFINE().

747 {
751 
754 }
static struct resolver_data test_resolver_data
int resolve_called
Definition: test_dns.c:646
#define ast_cond_init(cond, attr)
Definition: lock.h:199
#define NULL
Definition: resample.c:96
int resolution_complete
Definition: test_dns.c:650
ast_cond_t cancel_cond
Definition: test_dns.c:654
ast_mutex_t lock
Definition: test_dns.c:652
#define ast_mutex_init(pmutex)
Definition: lock.h:184

◆ stub_callback()

static void stub_callback ( const struct ast_dns_query query)
static

Stub async resolution callback

Definition at line 1116 of file test_dns.c.

Referenced by AST_TEST_DEFINE().

1117 {
1118  return;
1119 }

◆ stub_cancel()

static int stub_cancel ( struct ast_dns_query query)
static

Definition at line 42 of file test_dns.c.

Referenced by AST_TEST_DEFINE().

43 {
44  return 0;
45 }

◆ stub_resolve()

static int stub_resolve ( struct ast_dns_query query)
static

Definition at line 36 of file test_dns.c.

Referenced by AST_TEST_DEFINE().

37 {
38  return 0;
39 }

◆ test_cancel()

static int test_cancel ( struct ast_dns_query query)
static

Mock resolver's cancel method.

This signals the resolution thread not to return any DNS results.

Parameters
queryDNS query to cancel
Returns
0

Definition at line 731 of file test_dns.c.

References ast_cond_signal, ast_mutex_lock, ast_mutex_unlock, resolver_data::cancel_cond, resolver_data::canceled, resolver_data::lock, and test_resolver_data.

732 {
737 
738  return 0;
739 }
static struct resolver_data test_resolver_data
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ast_cond_signal(cond)
Definition: lock.h:201
ast_cond_t cancel_cond
Definition: test_dns.c:654
ast_mutex_t lock
Definition: test_dns.c:652
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ test_record()

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

Definition at line 395 of file test_dns.c.

References ast_dns_record_get_data(), ast_dns_record_get_rr_class(), ast_dns_record_get_rr_type(), ast_dns_record_get_ttl(), and ast_test_status_update.

Referenced by AST_TEST_DEFINE().

397 {
398  if (ast_dns_record_get_rr_type(record) != rr_type) {
399  ast_test_status_update(test, "Unexpected rr_type from DNS record\n");
400  return -1;
401  }
402 
403  if (ast_dns_record_get_rr_class(record) != rr_class) {
404  ast_test_status_update(test, "Unexpected rr_class from DNS record\n");
405  return -1;
406  }
407 
408  if (ast_dns_record_get_ttl(record) != ttl) {
409  ast_test_status_update(test, "Unexpected ttl from DNS record\n");
410  return -1;
411  }
412 
413  if (memcmp(ast_dns_record_get_data(record), data, size)) {
414  ast_test_status_update(test, "Unexpected data in DNS record\n");
415  return -1;
416  }
417 
418  return 0;
419 }
int ast_dns_record_get_ttl(const struct ast_dns_record *record)
Get the TTL of a DNS record.
Definition: dns_core.c:155
const char * ast_dns_record_get_data(const struct ast_dns_record *record)
Retrieve the raw DNS record.
Definition: dns_core.c:160
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
int ast_dns_record_get_rr_class(const struct ast_dns_record *record)
Get the resource record class of a DNS record.
Definition: dns_core.c:150
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

◆ test_resolve()

static int test_resolve ( struct ast_dns_query query)
static

Mock resolver's resolve method.

Parameters
queryThe query to resolve
Return values
0Successfully spawned resolution thread
non-zeroFailed to spawn the resolution thread

Definition at line 715 of file test_dns.c.

References ao2_bump, ast_pthread_create_detached, NULL, resolution_thread(), resolver_data::resolve_called, and test_resolver_data.

716 {
717  pthread_t resolver_thread;
718 
720  return ast_pthread_create_detached(&resolver_thread, NULL, resolution_thread, ao2_bump(query));
721 }
static struct resolver_data test_resolver_data
int resolve_called
Definition: test_dns.c:646
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:563
static void * resolution_thread(void *dns_query)
Thread spawned by the mock resolver.
Definition: test_dns.c:670
#define NULL
Definition: resample.c:96
#define ao2_bump(obj)
Definition: astobj2.h:491

◆ test_results()

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

Definition at line 265 of file test_dns.c.

References ast_dns_query_get_result(), ast_dns_result_get_answer(), ast_dns_result_get_bogus(), ast_dns_result_get_canonical(), ast_dns_result_get_rcode(), ast_dns_result_get_secure(), ast_test_status_update, and result.

Referenced by AST_TEST_DEFINE().

269 {
270  struct ast_dns_result *result;
271 
272  result = ast_dns_query_get_result(query);
273  if (!result) {
274  ast_test_status_update(test, "Unable to retrieve result from query\n");
275  return -1;
276  }
277 
278  if (ast_dns_result_get_secure(result) != expected_secure ||
279  ast_dns_result_get_bogus(result) != expected_bogus ||
280  ast_dns_result_get_rcode(result) != expected_rcode ||
281  strcmp(ast_dns_result_get_canonical(result), expected_canonical) ||
282  memcmp(ast_dns_result_get_answer(result), expected_answer, answer_size)) {
283  ast_test_status_update(test, "Unexpected values in result from query\n");
284  return -1;
285  }
286 
287  return 0;
288 }
unsigned int ast_dns_result_get_secure(const struct ast_dns_result *result)
Get whether the result is secure or not.
Definition: dns_core.c:82
unsigned int ast_dns_result_get_bogus(const struct ast_dns_result *result)
Get whether the result is bogus or not.
Definition: dns_core.c:87
const char * ast_dns_result_get_answer(const struct ast_dns_result *result)
Get the raw DNS answer from a DNS result.
Definition: dns_core.c:107
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
The result of a DNS query.
Definition: dns_internal.h:117
struct ast_dns_result * ast_dns_query_get_result(const struct ast_dns_query *query)
Get the result information for a DNS query.
Definition: dns_core.c:77
static PGresult * result
Definition: cel_pgsql.c:88
size_t answer_size
The size of the raw DNS answer.
Definition: dns_internal.h:131
const char * ast_dns_result_get_canonical(const struct ast_dns_result *result)
Get the canonical name of the result.
Definition: dns_core.c:97
unsigned int ast_dns_result_get_rcode(const struct ast_dns_result *result)
Get the error rcode of a DN result.
Definition: dns_core.c:92

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1299 of file test_dns.c.

References AST_TEST_UNREGISTER.

1300 {
1301  AST_TEST_UNREGISTER(resolver_register_unregister);
1302  AST_TEST_UNREGISTER(resolver_register_off_nominal);
1303  AST_TEST_UNREGISTER(resolver_unregister_off_nominal);
1305  AST_TEST_UNREGISTER(resolver_set_result);
1306  AST_TEST_UNREGISTER(resolver_set_result_off_nominal);
1307  AST_TEST_UNREGISTER(resolver_add_record);
1308  AST_TEST_UNREGISTER(resolver_add_record_off_nominal);
1309  AST_TEST_UNREGISTER(resolver_resolve_sync);
1310  AST_TEST_UNREGISTER(resolver_resolve_sync_off_nominal);
1311  AST_TEST_UNREGISTER(resolver_resolve_async);
1312  AST_TEST_UNREGISTER(resolver_resolve_async_off_nominal);
1313  AST_TEST_UNREGISTER(resolver_resolve_async_cancel);
1314 
1315  return 0;
1316 }
File-scoped data used during resolver tests.
Definition: test_dns.c:644
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "DNS API Tests" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 1337 of file test_dns.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1337 of file test_dns.c.

◆ test_resolver

struct ast_dns_resolver test_resolver
static

The mock resolver.

The mock resolver does not care about the DNS query that is actually being made on it. It simply regurgitates the same DNS record no matter what.

Definition at line 774 of file test_dns.c.

◆ test_resolver_data

struct resolver_data test_resolver_data
static