26 #include <arpa/nameser.h>
33 #include "asterisk/dns_test.h"
41 const char *replacement;
58 static int generate_naptr_record(
void *dns_record,
char *buf)
61 uint16_t net_order = htons(record->order);
62 uint16_t net_preference = htons(record->preference);
65 memcpy(ptr, &net_order,
sizeof(net_order));
66 ptr +=
sizeof(net_order);
68 memcpy(ptr, &net_preference,
sizeof(net_preference));
69 ptr +=
sizeof(net_preference);
71 ptr += ast_dns_test_write_string(&record->flags, ptr);
72 ptr += ast_dns_test_write_string(&record->services, ptr);
73 ptr += ast_dns_test_write_string(&record->regexp, ptr);
74 ptr += ast_dns_test_write_domain(record->replacement, ptr);
94 static int num_test_records;
101 static char ans_buffer[1024];
110 static void *naptr_thread(
void *dns_query)
116 ans_size = ast_dns_test_generate_result(query, test_records, num_test_records,
117 sizeof(
struct naptr_record), generate_naptr_record, ans_buffer);
121 for (i = 0; i < num_test_records; ++i) {
125 naptr_size = generate_naptr_record(&test_records[i], record);
144 return ast_pthread_create_detached(&thread, NULL, naptr_thread,
ao2_bump(query));
159 .
name =
"naptr_test",
161 .resolve = naptr_resolve,
162 .cancel = naptr_cancel,
171 { 200, 100, {1,
"A"}, {4,
"BLAH"}, {0,
""},
"goose.down" },
173 { 300, 8, {0,
""}, {4,
"BLAH"}, {0,
""},
"goose.down" },
174 { 300, 6, {1,
"3"}, {4,
"BLAH"}, {0,
""},
"goose.down" },
175 { 100, 2, {2,
"32"}, {4,
"BLAH"}, {0,
""},
"goose.down" },
176 { 400, 100, {3,
"A32"}, {4,
"BLAH"}, {0,
""},
"goose.down" },
178 { 100, 700, {0,
""}, {0,
""}, {0,
""},
"goose.down" },
179 { 500, 102, {1,
"A"}, {42,
"A+B12+C+D+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"}, {0,
""},
"goose.down" },
180 { 500, 100, {1,
"A"}, {14,
"A+B12+C+D+EEEE"}, {0,
""},
"goose.down" },
182 { 500, 101, {1,
"A"}, {4,
"BLAH"}, {15,
"!.*!horse.mane!"},
"" },
183 { 500, 99, {1,
"A"}, {4,
"BLAH"}, {15,
"0.*0horse.mane0"},
"" },
184 { 10, 100, {1,
"A"}, {4,
"BLAH"}, {11,
"!.*!\\!\\!\\!!"},
"" },
185 { 700, 999, {1,
"A"}, {4,
"BLAH"}, {30,
"!(.)(.)(.)(.)!\\1.m.\\2.n\\3.o\\4!"},
"" },
188 int naptr_record_order[] = { 10, 3, 5, 0, 2, 1, 4, 9, 7, 8, 6, 11};
189 enum ast_test_result_state res = AST_TEST_PASS;
194 info->name =
"naptr_resolve";
195 info->category =
"/main/dns/naptr/";
196 info->summary =
"Test nominal resolution of NAPTR records";
197 info->description =
"This test defines four valid NAPTR records and\n"
198 "performs a resolution of the domain to which they belong. The test\n"
199 "ensures that all fields of the NAPTR records are parsed correctly\n"
200 "and that the records are returned in sorted order";
201 return AST_TEST_NOT_RUN;
206 test_records = records;
207 num_test_records = ARRAY_LEN(records);
208 memset(ans_buffer, 0,
sizeof(ans_buffer));
213 ast_test_status_update(
test,
"DNS resolution failed\n");
219 ast_test_status_update(
test,
"DNS resolution returned no result\n");
227 ast_test_status_update(
test,
"Expected order %hu, got order %hu from NAPTR record\n",
232 ast_test_status_update(
test,
"Expected preference %hu, got preference %hu from NAPTR record\n",
237 ast_test_status_update(
test,
"Expected flags %s, got flags %s from NAPTR record\n",
242 ast_test_status_update(
test,
"Expected services %s, got services %s from NAPTR record\n",
247 ast_test_status_update(
test,
"Expected regexp %s, got regexp %s from NAPTR record\n",
252 ast_test_status_update(
test,
"Expected replacement %s, got replacement %s from NAPTR record\n",
259 if (i != ARRAY_LEN(records)) {
260 ast_test_status_update(
test,
"Unexpected number of records returned in NAPTR lookup\n");
269 num_test_records = 0;
270 memset(ans_buffer, 0,
sizeof(ans_buffer));
275 static enum ast_test_result_state off_nominal_test(
struct ast_test *
test,
struct naptr_record *records,
int num_records)
278 enum ast_test_result_state res = AST_TEST_PASS;
281 test_records = records;
282 num_test_records = num_records;
283 memset(ans_buffer, 0,
sizeof(ans_buffer));
288 ast_test_status_update(test,
"Failed to perform DNS resolution, despite using valid inputs\n");
294 ast_test_status_update(test,
"Synchronous DNS resolution failed to set a result\n");
301 ast_test_status_update(test,
"DNS resolution returned records when it was not expected to\n");
310 num_test_records = 0;
311 memset(ans_buffer, 0,
sizeof(ans_buffer));
319 { 100, 100, {255,
"A"}, {4,
"BLAH"}, {15,
"!.*!horse.mane!"},
"" },
320 { 100, 100, {0,
"A"}, {4,
"BLAH"}, {15,
"!.*!horse.mane!"},
"" },
321 { 100, 100, {1,
"A"}, {255,
"BLAH"}, {15,
"!.*!horse.mane!"},
"" },
322 { 100, 100, {1,
"A"}, {2,
"BLAH"}, {15,
"!.*!horse.mane!"},
"" },
323 { 100, 100, {1,
"A"}, {4,
"BLAH"}, {255,
"!.*!horse.mane!"},
"" },
324 { 100, 100, {1,
"A"}, {4,
"BLAH"}, {3,
"!.*!horse.mane!"},
"" },
325 { 100, 100, {255,
"A"}, {255,
"BLAH"}, {255,
"!.*!horse.mane!"},
"" },
326 { 100, 100, {0,
"A"}, {2,
"BLAH"}, {3,
"!.*!horse.mane!"},
"" },
331 info->name =
"naptr_resolve_off_nominal_length";
332 info->category =
"/main/dns/naptr/";
333 info->summary =
"Test resolution of NAPTR records with off-nominal lengths";
334 info->description =
"This test defines a set of records where the strings provided\n"
335 "within the record are valid, but the lengths of the strings in the record are\n"
336 "invalid, either too large or too small. The goal of this test is to ensure that\n"
337 "these invalid lengths result in resolution failures";
338 return AST_TEST_NOT_RUN;
343 return off_nominal_test(test, records, ARRAY_LEN(records));
350 { 100, 100, {1,
"!"}, {4,
"BLAH"}, {15,
"!.*!horse.mane!"},
""},
352 { 100, 100, {2,
"A!"}, {4,
"BLAH"}, {15,
"!.*!horse.mane!"},
""},
353 { 100, 100, {2,
"!A"}, {4,
"BLAH"}, {15,
"!.*!horse.mane!"},
""},
355 { 100, 100, {2,
"sa"}, {4,
"BLAH"}, {15,
"!.*!horse.mane!"},
""},
356 { 100, 100, {2,
"su"}, {4,
"BLAH"}, {15,
"!.*!horse.mane!"},
""},
357 { 100, 100, {2,
"sp"}, {4,
"BLAH"}, {15,
"!.*!horse.mane!"},
""},
358 { 100, 100, {2,
"as"}, {4,
"BLAH"}, {15,
"!.*!horse.mane!"},
""},
359 { 100, 100, {2,
"au"}, {4,
"BLAH"}, {15,
"!.*!horse.mane!"},
""},
360 { 100, 100, {2,
"ap"}, {4,
"BLAH"}, {15,
"!.*!horse.mane!"},
""},
361 { 100, 100, {2,
"ua"}, {4,
"BLAH"}, {15,
"!.*!horse.mane!"},
""},
362 { 100, 100, {2,
"us"}, {4,
"BLAH"}, {15,
"!.*!horse.mane!"},
""},
363 { 100, 100, {2,
"up"}, {4,
"BLAH"}, {15,
"!.*!horse.mane!"},
""},
364 { 100, 100, {2,
"pa"}, {4,
"BLAH"}, {15,
"!.*!horse.mane!"},
""},
365 { 100, 100, {2,
"ps"}, {4,
"BLAH"}, {15,
"!.*!horse.mane!"},
""},
366 { 100, 100, {2,
"pu"}, {4,
"BLAH"}, {15,
"!.*!horse.mane!"},
""},
371 info->name =
"naptr_resolve_off_nominal_flags";
372 info->category =
"/main/dns/naptr/";
373 info->summary =
"Ensure that NAPTR records with invalid flags are not presented in results";
374 info->description =
"This test defines a set of records where the flags provided are\n"
375 "invalid in some way. This may be due to providing non-alphanumeric characters or\n"
376 "by providing clashing flags. The result should be that none of the defined records\n"
377 "are returned by the resolver";
378 return AST_TEST_NOT_RUN;
383 return off_nominal_test(test, records, ARRAY_LEN(records));
389 { 100, 100, {1,
"A"}, {5,
"BLAH!"}, {15,
"!.*!horse.mane!"},
""},
390 { 100, 100, {1,
"A"}, {5,
"BL!AH"}, {15,
"!.*!horse.mane!"},
""},
391 { 100, 100, {1,
"A"}, {8,
"1SIP+D2U"}, {15,
"!.*!horse.mane!"},
""},
392 { 100, 100, {1,
"A"}, {8,
"SIP+1D2U"}, {15,
"!.*!horse.mane!"},
""},
393 { 100, 100, {1,
"A"}, {4,
"+D2U"}, {15,
"!.*!horse.mane!"},
""},
394 { 100, 100, {1,
"A"}, {4,
"SIP+"}, {15,
"!.*!horse.mane!"},
""},
395 { 100, 100, {1,
"A"}, {8,
"SIP++D2U"}, {15,
"!.*!horse.mane!"},
""},
396 { 100, 100, {1,
"A"}, {37,
"SIPSIPSIPSIPSIPSIPSIPSIPSIPSIPSIP+D2U"}, {15,
"!.*!horse.mane!"},
""},
397 { 100, 100, {1,
"A"}, {37,
"SIP+D2UD2UD2UD2UD2UD2UD2UD2UD2UD2UD2U"}, {15,
"!.*!horse.mane!"},
""},
402 info->name =
"naptr_resolve_off_nominal_services";
403 info->category =
"/main/dns/naptr/";
404 info->summary =
"Ensure that NAPTR records with invalid services are not presented in results";
405 info->description =
"This test defines a set of records where the services provided are\n"
406 "invalid in some way. This may be due to providing non-alphanumeric characters, providing\n"
407 "protocols or resolution services that start with a non-alphabetic character, or\n"
408 "providing fields that are too long.";
409 return AST_TEST_NOT_RUN;
414 return off_nominal_test(test, records, ARRAY_LEN(records));
421 { 100, 100, {1,
"A"}, {4,
"BLAH"}, {15,
"1.*1horse.mane1"},
""},
423 { 100, 100, {1,
"A"}, {4,
"BLAH"}, {14,
"!.*!horse.mane"},
""},
425 { 100, 100, {1,
"A"}, {4,
"BLAH"}, {16,
"!.*!horse.mane\\!"},
""},
427 { 100, 100, {1,
"A"}, {4,
"BLAH"}, {15,
"!.*!horse!mane!"},
""},
429 { 100, 100, {1,
"A"}, {4,
"BLAH"}, {16,
"!.*!horse.mane!o"},
""},
431 { 100, 100, {1,
"A"}, {4,
"BLAH"}, {13,
"!.*!horse.\\0!"},
""},
433 { 100, 100, {1,
"A"}, {4,
"BLAH"}, {16,
"!(.*!horse.mane!"},
""},
438 info->name =
"naptr_resolve_off_nominal_regexp";
439 info->category =
"/main/dns/naptr/";
440 info->summary =
"Ensure that NAPTR records with invalid regexps are not presented in results";
441 info->description =
"This test defines a set of records where the regexps provided are\n"
442 "invalid in some way. The test ensures that none of the invalid records are returned\n"
443 "when performing a NAPTR lookup";
444 return AST_TEST_NOT_RUN;
449 return off_nominal_test(test, records, ARRAY_LEN(records));
456 { 100, 100, {1,
"A"}, {4,
"BLAH"}, {15,
"!.*!horse.mane!"},
"goose.down"},
465 info->name =
"naptr_resolve_off_nominal_interactions";
466 info->category =
"/main/dns/naptr/";
467 info->summary =
"Ensure that NAPTR records with invalid interactions are not presented in results";
468 info->description =
"This test defines a set of records where all parts are individually valid,\n"
469 "but when combined do not make sense and are thus invalid.";
470 return AST_TEST_NOT_RUN;
475 return off_nominal_test(test, records, ARRAY_LEN(records));
478 static int unload_module(
void)
480 AST_TEST_UNREGISTER(naptr_resolve_nominal);
481 AST_TEST_UNREGISTER(naptr_resolve_off_nominal_length);
482 AST_TEST_UNREGISTER(naptr_resolve_off_nominal_flags);
483 AST_TEST_UNREGISTER(naptr_resolve_off_nominal_services);
484 AST_TEST_UNREGISTER(naptr_resolve_off_nominal_regexp);
485 AST_TEST_UNREGISTER(naptr_resolve_off_nominal_interactions);
490 static int load_module(
void)
492 AST_TEST_REGISTER(naptr_resolve_nominal);
493 AST_TEST_REGISTER(naptr_resolve_off_nominal_length);
494 AST_TEST_REGISTER(naptr_resolve_off_nominal_flags);
495 AST_TEST_REGISTER(naptr_resolve_off_nominal_services);
496 AST_TEST_REGISTER(naptr_resolve_off_nominal_regexp);
497 AST_TEST_REGISTER(naptr_resolve_off_nominal_interactions);
const struct ast_dns_record * ast_dns_record_get_next(const struct ast_dns_record *record)
Get the next DNS record.
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.
void ast_dns_result_free(struct ast_dns_result *result)
Free the DNS result information.
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.
Representation of a string in DNS.
void ast_dns_resolver_unregister(struct ast_dns_resolver *resolver)
Unregister a DNS resolver.
const char * ast_dns_naptr_get_regexp(const struct ast_dns_record *record)
Get the regular expression from a NAPTR record.
unsigned short ast_dns_naptr_get_preference(const struct ast_dns_record *record)
Get the preference from a NAPTR record.
const char * ast_dns_naptr_get_service(const struct ast_dns_record *record)
Get the service from a NAPTR record.
const char * name
The name of the resolver implementation.
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
static void cleanup(void)
Clean up any old apps that we don't need any more.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
int ast_dns_resolver_register(struct ast_dns_resolver *resolver)
Register a DNS resolver.
The result of a DNS query.
void ast_dns_resolver_completed(struct ast_dns_query *query)
Mark a DNS query as having been completed.
const char * ast_dns_naptr_get_flags(const struct ast_dns_record *record)
Get the flags from a NAPTR record.
DNS resolver implementation.
const struct ast_dns_record * ast_dns_result_get_records(const struct ast_dns_result *result)
Get the first record of a DNS Result.
DNS NAPTR Record Parsing API.
unsigned short ast_dns_naptr_get_order(const struct ast_dns_record *record)
Get the order from a NAPTR record.
#define AST_TEST_DEFINE(hdr)
const char * ast_dns_naptr_get_replacement(const struct ast_dns_record *record)
Get the replacement value from a NAPTR record.
#define ASTERISK_GPL_KEY
The text the key() function should return.
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.
Asterisk module definitions.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.