Asterisk - The Open Source Telephony Project  18.5.0
test_dns_srv.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2015, Digium, Inc.
5  *
6  * Joshua Colp <[email protected]>
7  * Mark Michelson <[email protected]>
8  *
9  * See http://www.asterisk.org for more information about
10  * the Asterisk project. Please do not directly contact
11  * any of the maintainers of this project for assistance;
12  * the project provides a web site, mailing lists and IRC
13  * channels for your use.
14  *
15  * This program is free software, distributed under the terms of
16  * the GNU General Public License Version 2. See the LICENSE file
17  * at the top of the source tree.
18  */
19 
20 /*** MODULEINFO
21  <depend>TEST_FRAMEWORK</depend>
22  <support_level>core</support_level>
23  ***/
24 
25 #include "asterisk.h"
26 
27 #include <arpa/nameser.h>
28 
29 #include "asterisk/test.h"
30 #include "asterisk/module.h"
31 #include "asterisk/dns_core.h"
32 #include "asterisk/dns_resolver.h"
33 #include "asterisk/dns_srv.h"
34 #include "asterisk/dns_test.h"
35 
36 struct srv_record {
37  uint16_t priority;
38  uint16_t weight;
39  uint16_t port;
40  const char *host;
41  unsigned int ignore_priority;
42  unsigned int ignore_weight;
43  unsigned int ignore_port;
44  unsigned int ignore_host;
45 };
46 
47 static int generate_srv_record(void *dns_record, char *buf)
48 {
49  struct srv_record *record = dns_record;
50  uint16_t priority = htons(record->priority);
51  uint16_t weight = htons(record->weight);
52  uint16_t port = htons(record->port);
53  char *ptr = buf;
54 
55  if (!record->ignore_priority) {
56  memcpy(ptr, &priority, sizeof(priority));
57  ptr += sizeof(priority);
58  }
59 
60  if (!record->ignore_weight) {
61  memcpy(ptr, &weight, sizeof(weight));
62  ptr += sizeof(weight);
63  }
64 
65  if (!record->ignore_port) {
66  memcpy(ptr, &port, sizeof(port));
67  ptr += sizeof(port);
68  }
69 
70  if (!record->ignore_host) {
71  ptr += ast_dns_test_write_domain(record->host, ptr);
72  }
73 
74  return ptr - buf;
75 }
76 
77 static struct srv_record *test_records;
78 static int num_test_records;
79 static char ans_buffer[1024];
80 
81 static void *srv_thread(void *dns_query)
82 {
83  struct ast_dns_query *query = dns_query;
84  int i;
85  int ans_size;
86 
87  ans_size = ast_dns_test_generate_result(query, test_records, num_test_records,
88  sizeof(struct srv_record), generate_srv_record, ans_buffer);
89 
90  ast_dns_resolver_set_result(query, 0, 0, NOERROR, "goose.feathers", ans_buffer, ans_size);
91 
92  for (i = 0; i < num_test_records; ++i) {
93  char record[128];
94  int srv_size;
95 
96  srv_size = generate_srv_record(&test_records[i], record);
97  ast_dns_resolver_add_record(query, T_SRV, C_IN, 12345, record, srv_size);
98  }
99 
101 
102  ao2_ref(query, -1);
103  return NULL;
104 }
105 
106 static int srv_resolve(struct ast_dns_query *query)
107 {
108  pthread_t thread;
109 
110  return ast_pthread_create_detached(&thread, NULL, srv_thread, ao2_bump(query));
111 }
112 
113 static int srv_cancel(struct ast_dns_query *query)
114 {
115  return -1;
116 }
117 
119  .name = "srv_test",
120  .priority = 0,
121  .resolve = srv_resolve,
122  .cancel = srv_cancel,
123 };
124 
126  int *srv_record_order, int num_records)
127 {
129  const struct ast_dns_record *record;
131  int i;
132 
133  test_records = records;
134  num_test_records = num_records;
135  memset(ans_buffer, 0, sizeof(ans_buffer));
136 
137  ast_dns_resolver_register(&srv_resolver);
138 
139  if (ast_dns_resolve("goose.feathers", T_SRV, C_IN, &result)) {
140  ast_test_status_update(test, "DNS resolution failed\n");
141  res = AST_TEST_FAIL;
142  goto cleanup;
143  }
144 
145  if (!result) {
146  ast_test_status_update(test, "DNS resolution returned no result\n");
147  res = AST_TEST_FAIL;
148  goto cleanup;
149  }
150 
151  i = 0;
152  for (record = ast_dns_result_get_records(result); record; record = ast_dns_record_get_next(record)) {
153  if (ast_dns_srv_get_priority(record) != records[srv_record_order[i]].priority) {
154  ast_test_status_update(test, "Unexpected priority in returned SRV record\n");
155  res = AST_TEST_FAIL;
156  }
157  if (ast_dns_srv_get_weight(record) != records[srv_record_order[i]].weight) {
158  ast_test_status_update(test, "Unexpected weight in returned SRV record\n");
159  res = AST_TEST_FAIL;
160  }
161  if (ast_dns_srv_get_port(record) != records[srv_record_order[i]].port) {
162  ast_test_status_update(test, "Unexpected port in returned SRV record\n");
163  res = AST_TEST_FAIL;
164  }
165  if (strcmp(ast_dns_srv_get_host(record), records[srv_record_order[i]].host)) {
166  ast_test_status_update(test, "Unexpected host in returned SRV record\n");
167  res = AST_TEST_FAIL;
168  }
169  ++i;
170  }
171 
172  if (i != num_records) {
173  ast_test_status_update(test, "Unexpected number of records returned in SRV lookup\n");
174  res = AST_TEST_FAIL;
175  }
176 
177 cleanup:
178 
179  ast_dns_resolver_unregister(&srv_resolver);
180 
181  test_records = NULL;
182  num_test_records = 0;
183  memset(ans_buffer, 0, sizeof(ans_buffer));
184 
185  return res;
186 }
187 
188 AST_TEST_DEFINE(srv_resolve_single_record)
189 {
190  struct srv_record records[] = {
191  { 10, 10, 5060, "goose.down" },
192  };
193 
194  int srv_record_order[] = { 0, };
195 
196  switch (cmd) {
197  case TEST_INIT:
198  info->name = "srv_resolve_single_record";
199  info->category = "/main/dns/srv/";
200  info->summary = "Test an SRV lookup which returns a single record";
201  info->description = "This test defines a single SRV record and performs a\n"
202  "resolution of the domain to which they belong. The test ensures that all\n"
203  "fields of the SRV record are parsed correctly";
204  return AST_TEST_NOT_RUN;
205  case TEST_EXECUTE:
206  break;
207  }
208 
209  return nominal_test(test, records, srv_record_order, ARRAY_LEN(records));
210 }
211 
212 AST_TEST_DEFINE(srv_resolve_sort_priority)
213 {
214  struct srv_record records[] = {
215  { 20, 10, 5060, "tacos" },
216  { 10, 10, 5060, "goose.down" },
217  };
218  int srv_record_order[] = { 1, 0};
219 
220  switch (cmd) {
221  case TEST_INIT:
222  info->name = "srv_resolve_sort_priority";
223  info->category = "/main/dns/srv/";
224  info->summary = "Test an SRV lookup which returns two records with differing priorities";
225  info->description = "This test defines two SRV records with differing priorities and\n"
226  "performs a resolution of the domain to which they belong. The test ensures that\n"
227  "the two records are sorted according to priority and that all fields of the SRV\n"
228  "records are parsed correctly";
229  return AST_TEST_NOT_RUN;
230  case TEST_EXECUTE:
231  break;
232  }
233 
234  return nominal_test(test, records, srv_record_order, ARRAY_LEN(records));
235 }
236 
237 AST_TEST_DEFINE(srv_resolve_same_priority_zero_weight)
238 {
239  struct srv_record records[] = {
240  { 10, 0, 5060, "tacos" },
241  { 10, 10, 5060, "goose.down" },
242  };
243  int srv_record_order[] = { 1, 0};
244 
245  switch (cmd) {
246  case TEST_INIT:
247  info->name = "srv_resolve_same_priority_zero_weight";
248  info->category = "/main/dns/srv/";
249  info->summary = "Test an SRV lookup which returns two records with same priority but different weights";
250  info->description = "This test defines two SRV records with same priority but different weights and\n"
251  "performs a resolution of the domain to which they belong. The test ensures that\n"
252  "the record with zero weight comes last and that all fields of the SRV\n"
253  "records are parsed correctly";
254  return AST_TEST_NOT_RUN;
255  case TEST_EXECUTE:
256  break;
257  }
258 
259  return nominal_test(test, records, srv_record_order, ARRAY_LEN(records));
260 }
261 
262 AST_TEST_DEFINE(srv_resolve_same_priority_different_weights)
263 {
264  struct srv_record records[] = {
265  { 10, 10, 5060, "tacos" },
266  { 10, 20, 5060, "goose.down" },
267  };
268 
269  int srv_record_occurence[2] = { 0, };
271  int count = 0;
272 
273  switch (cmd) {
274  case TEST_INIT:
275  info->name = "srv_resolve_same_priority_different_weights";
276  info->category = "/main/dns/srv/";
277  info->summary = "Test an SRV lookup which returns two records with same priority but different weights";
278  info->description = "This test defines two SRV records with same priority but different weights and\n"
279  "performs a resolution of the domain to which they belong. The test ensures that\n"
280  "the record with higher weight occurs more often than the one of lesser weight";
281  return AST_TEST_NOT_RUN;
282  case TEST_EXECUTE:
283  break;
284  }
285 
286  test_records = records;
287  num_test_records = ARRAY_LEN(records);
288 
289  ast_dns_resolver_register(&srv_resolver);
290 
291  for (count = 0; count < 100; count++) {
292  struct ast_dns_result *result;
293  const struct ast_dns_record *record;
294  int i;
295 
296  memset(ans_buffer, 0, sizeof(ans_buffer));
297 
298  if (ast_dns_resolve("goose.feathers", T_SRV, C_IN, &result)) {
299  ast_test_status_update(test, "DNS resolution failed\n");
300  res = AST_TEST_FAIL;
301  goto cleanup;
302  }
303 
304  if (!result) {
305  ast_test_status_update(test, "DNS resolution returned no result\n");
306  res = AST_TEST_FAIL;
307  goto cleanup;
308  }
309 
310  record = ast_dns_result_get_records(result);
311  for (i = 0; i < ARRAY_LEN(records); i++) {
312  if (ast_dns_srv_get_priority(record) != records[i].priority) {
313  continue;
314  }
315  if (ast_dns_srv_get_weight(record) != records[i].weight) {
316  continue;
317  }
318  if (ast_dns_srv_get_port(record) != records[i].port) {
319  continue;
320  }
321  if (strcmp(ast_dns_srv_get_host(record), records[i].host)) {
322  continue;
323  }
324 
325  srv_record_occurence[i]++;
326  break;
327  }
328 
329  ast_dns_result_free(result);
330  }
331 
332  if (srv_record_occurence[0] > srv_record_occurence[1]) {
333  ast_test_status_update(test, "SRV sorting resulted in lesser weight being returned more often\n");
334  res = AST_TEST_FAIL;
335  }
336 
337 cleanup:
338 
339  ast_dns_resolver_unregister(&srv_resolver);
340 
341  test_records = NULL;
342  num_test_records = 0;
343  memset(ans_buffer, 0, sizeof(ans_buffer));
344 
345  return res;
346 }
347 
348 AST_TEST_DEFINE(srv_resolve_different_priorities_different_weights)
349 {
350  struct srv_record records[] = {
351  { 10, 10, 5060, "tacos" },
352  { 10, 20, 5060, "goose.down" },
353  { 5, 80, 5060, "moo" },
354  { 5, 10, 5060, "Canada" },
355  };
356 
357  int srv_record_priority[4] = { 5, 5, 10, 10 };
358  int srv_record_occurence[4] = { 0, };
360  int count = 0;
361 
362  switch (cmd) {
363  case TEST_INIT:
364  info->name = "srv_resolve_different_priorities_different_weights";
365  info->category = "/main/dns/srv/";
366  info->summary = "Test an SRV lookup which returns four records with different priority and different weights";
367  info->description = "This test defines four SRV records, two with one priority and two with another priority,\n"
368  "and different weights and performs a resolution of the domain to which they belong.\n"
369  "The test ensures that the priorities are sorted properly and that the records with higher weight\n"
370  "occur more often than the ones of less weight.";
371  return AST_TEST_NOT_RUN;
372  case TEST_EXECUTE:
373  break;
374  }
375 
376  test_records = records;
377  num_test_records = ARRAY_LEN(records);
378 
379  ast_dns_resolver_register(&srv_resolver);
380 
381  for (count = 0; count < 100; count++) {
382  struct ast_dns_result *result;
383  const struct ast_dns_record *record;
384  int i;
385 
386  memset(ans_buffer, 0, sizeof(ans_buffer));
387 
388  if (ast_dns_resolve("goose.feathers", T_SRV, C_IN, &result)) {
389  ast_test_status_update(test, "DNS resolution failed\n");
390  res = AST_TEST_FAIL;
391  goto cleanup;
392  }
393 
394  if (!result) {
395  ast_test_status_update(test, "DNS resolution returned no result\n");
396  res = AST_TEST_FAIL;
397  goto cleanup;
398  }
399 
400  i = 0;
401  for (record = ast_dns_result_get_records(result); record; record = ast_dns_record_get_next(record)) {
402  if (ast_dns_srv_get_priority(record) != srv_record_priority[i]) {
403  ast_test_status_update(test, "Unexpected priority in returned SRV record\n");
404  res = AST_TEST_FAIL;
405  }
406  i++;
407  }
408 
409  record = ast_dns_result_get_records(result);
410  for (i = 0; i < ARRAY_LEN(records); i++) {
411  if (ast_dns_srv_get_priority(record) != records[i].priority) {
412  continue;
413  }
414  if (ast_dns_srv_get_weight(record) != records[i].weight) {
415  continue;
416  }
417  if (ast_dns_srv_get_port(record) != records[i].port) {
418  continue;
419  }
420  if (strcmp(ast_dns_srv_get_host(record), records[i].host)) {
421  continue;
422  }
423 
424  srv_record_occurence[i]++;
425  break;
426  }
427 
428  ast_dns_result_free(result);
429  }
430 
431  if (srv_record_occurence[0] > srv_record_occurence[1]) {
432  ast_test_status_update(test, "SRV sorting resulted in lesser weight being returned more often for priority 10\n");
433  res = AST_TEST_FAIL;
434  }
435 
436  if (srv_record_occurence[3] > srv_record_occurence[2]) {
437  ast_test_status_update(test, "SRV sorting resulted in lesser weight being returned more often for priority 5\n");
438  res = AST_TEST_FAIL;
439  }
440 
441 cleanup:
442 
443  ast_dns_resolver_unregister(&srv_resolver);
444 
445  test_records = NULL;
446  num_test_records = 0;
447  memset(ans_buffer, 0, sizeof(ans_buffer));
448 
449  return res;
450 }
451 
453  int num_records)
454 {
456  const struct ast_dns_record *record;
458 
459  test_records = records;
460  num_test_records = num_records;
461  memset(ans_buffer, 0, sizeof(ans_buffer));
462 
463  ast_dns_resolver_register(&srv_resolver);
464 
465  if (ast_dns_resolve("goose.feathers", T_SRV, C_IN, &result)) {
466  ast_test_status_update(test, "DNS resolution failed\n");
467  res = AST_TEST_FAIL;
468  goto cleanup;
469  }
470 
471  if (!result) {
472  ast_test_status_update(test, "DNS resolution returned no result\n");
473  res = AST_TEST_FAIL;
474  goto cleanup;
475  }
476 
478  if (record) {
479  ast_test_status_update(test, "Unexpected record returned from SRV query\n");
480  res = AST_TEST_FAIL;
481  }
482 
483 cleanup:
484 
485  ast_dns_resolver_unregister(&srv_resolver);
486 
487  test_records = NULL;
488  num_test_records = 0;
489  memset(ans_buffer, 0, sizeof(ans_buffer));
490 
491  return res;
492 }
493 
494 AST_TEST_DEFINE(srv_resolve_record_missing_weight_port_host)
495 {
496  struct srv_record records[] = {
497  { 10, 10, 5060, "tacos.com", 0, 1, 1, 1 },
498  };
499 
500  switch (cmd) {
501  case TEST_INIT:
502  info->name = "srv_resolve_record_missing_weight_port_host";
503  info->category = "/main/dns/srv/";
504  info->summary = "Test an SRV lookup which returns a single invalid record";
505  info->description = "This test defines a single SRV record and performs a\n"
506  "resolution of the domain to which they belong. The test ensures that the\n"
507  "record is determined to be corrupt as it contains only a priority";
508  return AST_TEST_NOT_RUN;
509  case TEST_EXECUTE:
510  break;
511  }
512 
513  return invalid_record_test(test, records, ARRAY_LEN(records));
514 }
515 
516 AST_TEST_DEFINE(srv_resolve_record_missing_port_host)
517 {
518  struct srv_record records[] = {
519  { 10, 10, 5060, "tacos.com", 0, 0, 1, 1 },
520  };
521 
522  switch (cmd) {
523  case TEST_INIT:
524  info->name = "srv_resolve_record_missing_port_host";
525  info->category = "/main/dns/srv/";
526  info->summary = "Test an SRV lookup which returns a single invalid record";
527  info->description = "This test defines a single SRV record and performs a\n"
528  "resolution of the domain to which they belong. The test ensures that the\n"
529  "record is determined to be corrupt as it contains only a priority and weight";
530  return AST_TEST_NOT_RUN;
531  case TEST_EXECUTE:
532  break;
533  }
534 
535  return invalid_record_test(test, records, ARRAY_LEN(records));
536 }
537 
538 AST_TEST_DEFINE(srv_resolve_record_missing_host)
539 {
540  struct srv_record records[] = {
541  { 10, 10, 5060, "tacos.com", 0, 0, 0, 1 },
542  };
543 
544  switch (cmd) {
545  case TEST_INIT:
546  info->name = "srv_resolve_record_missing_host";
547  info->category = "/main/dns/srv/";
548  info->summary = "Test an SRV lookup which returns a single invalid record";
549  info->description = "This test defines a single SRV record and performs a\n"
550  "resolution of the domain to which they belong. The test ensures that the\n"
551  "record is determined to be corrupt as it contains only a priority, weight,\n"
552  "and port";
553  return AST_TEST_NOT_RUN;
554  case TEST_EXECUTE:
555  break;
556  }
557 
558  return invalid_record_test(test, records, ARRAY_LEN(records));
559 }
560 
561 static int unload_module(void)
562 {
563  AST_TEST_UNREGISTER(srv_resolve_single_record);
564  AST_TEST_UNREGISTER(srv_resolve_sort_priority);
565  AST_TEST_UNREGISTER(srv_resolve_same_priority_zero_weight);
566  AST_TEST_UNREGISTER(srv_resolve_same_priority_different_weights);
567  AST_TEST_UNREGISTER(srv_resolve_different_priorities_different_weights);
568  AST_TEST_UNREGISTER(srv_resolve_record_missing_weight_port_host);
569  AST_TEST_UNREGISTER(srv_resolve_record_missing_port_host);
570  AST_TEST_UNREGISTER(srv_resolve_record_missing_host);
571 
572  return 0;
573 }
574 
575 static int load_module(void)
576 {
577  AST_TEST_REGISTER(srv_resolve_single_record);
578  AST_TEST_REGISTER(srv_resolve_sort_priority);
579  AST_TEST_REGISTER(srv_resolve_same_priority_zero_weight);
580  AST_TEST_REGISTER(srv_resolve_same_priority_different_weights);
581  AST_TEST_REGISTER(srv_resolve_different_priorities_different_weights);
582  AST_TEST_REGISTER(srv_resolve_record_missing_weight_port_host);
583  AST_TEST_REGISTER(srv_resolve_record_missing_port_host);
584  AST_TEST_REGISTER(srv_resolve_record_missing_host);
585 
587 }
588 
static int generate_srv_record(void *dns_record, char *buf)
Definition: test_dns_srv.c:47
unsigned int ignore_port
Definition: test_dns_srv.c:43
unsigned short ast_dns_srv_get_priority(const struct ast_dns_record *record)
Get the priority from an SRV record.
Definition: dns_srv.c:196
pthread_t thread
Definition: app_meetme.c:1089
const char * host
Definition: test_dns_srv.c:40
static int records
Definition: cdr_mysql.c:84
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:567
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
Asterisk main include file. File version handling, generic pbx functions.
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
uint16_t priority
Definition: test_dns_srv.c:37
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 ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:563
void ast_dns_resolver_unregister(struct ast_dns_resolver *resolver)
Unregister a DNS resolver.
Definition: dns_core.c:680
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
int ast_dns_test_generate_result(struct ast_dns_query *query, void *records, size_t num_records, size_t record_size, record_fn generate, char *buffer)
Generate a full DNS response for the given DNS records.
Definition: dns_test.c:222
static struct ast_dns_resolver srv_resolver
Definition: test_dns_srv.c:118
For AST_LIST.
Definition: dns_internal.h:39
AST_TEST_DEFINE(srv_resolve_single_record)
Definition: test_dns_srv.c:188
unsigned int ignore_priority
Definition: test_dns_srv.c:41
Test Framework API.
A DNS record to be used during a test.
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
static int srv_cancel(struct ast_dns_query *query)
Definition: test_dns_srv.c:113
static int num_test_records
Definition: test_dns_srv.c:78
#define NULL
Definition: resample.c:96
const char * name
The name of the resolver implementation.
Definition: dns_resolver.h:34
static enum ast_test_result_state invalid_record_test(struct ast_test *test, struct srv_record *records, int num_records)
Definition: test_dns_srv.c:452
unsigned short ast_dns_srv_get_port(const struct ast_dns_record *record)
Get the port from an SRV record.
Definition: dns_srv.c:212
const char * ast_dns_srv_get_host(const struct ast_dns_record *record)
Get the hostname from an SRV record.
Definition: dns_srv.c:188
unsigned short ast_dns_srv_get_weight(const struct ast_dns_record *record)
Get the weight from an SRV record.
Definition: dns_srv.c:204
#define ao2_bump(obj)
Definition: astobj2.h:491
static int unload_module(void)
Definition: test_dns_srv.c:561
#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
#define ao2_ref(o, delta)
Definition: astobj2.h:464
unsigned int ignore_host
Definition: test_dns_srv.c:44
static int load_module(void)
Definition: test_dns_srv.c:575
uint16_t port
Definition: test_dns_srv.c:39
The result of a DNS query.
Definition: dns_internal.h:117
void ast_dns_resolver_completed(struct ast_dns_query *query)
Mark a DNS query as having been completed.
Definition: dns_core.c:599
int ast_dns_test_write_domain(const char *string, char *buf)
Write a DNS domain to a buffer.
Definition: dns_test.c:196
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
def info(msg)
static void * srv_thread(void *dns_query)
Definition: test_dns_srv.c:81
DNS resolver implementation.
Definition: dns_resolver.h:32
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 void * cleanup(void *unused)
Definition: pbx_realtime.c:124
static enum ast_test_result_state nominal_test(struct ast_test *test, struct srv_record *records, int *srv_record_order, int num_records)
Definition: test_dns_srv.c:125
Definition: test.c:65
static struct srv_record * test_records
Definition: test_dns_srv.c:77
unsigned int ignore_weight
Definition: test_dns_srv.c:42
static PGresult * result
Definition: cel_pgsql.c:88
static char ans_buffer[1024]
Definition: test_dns_srv.c:79
DNS SRV Record Parsing API.
uint16_t weight
Definition: test_dns_srv.c:38
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
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
Asterisk module definitions.
DNS Resolver API.
static int srv_resolve(struct ast_dns_query *query)
Definition: test_dns_srv.c:106
Core DNS API.
ast_test_result_state
Definition: test.h:200