dns_test.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. /*
  2. * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  3. * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. */
  19. #include "test.h"
  20. #include <pjsip.h>
  21. #include <pjlib.h>
  22. #include <pjlib-util.h>
  23. /* For logging purpose. */
  24. #define THIS_FILE "dns_test.c"
  25. struct result
  26. {
  27. pj_status_t status;
  28. pjsip_server_addresses servers;
  29. };
  30. static void cb(pj_status_t status,
  31. void *token,
  32. const struct pjsip_server_addresses *addr)
  33. {
  34. struct result *result = (struct result*) token;
  35. result->status = status;
  36. if (status == PJ_SUCCESS)
  37. pj_memcpy(&result->servers, addr, sizeof(*addr));
  38. }
  39. static void add_dns_entries(pj_dns_resolver *resv)
  40. {
  41. /* Inject DNS SRV entry */
  42. pj_dns_parsed_packet pkt;
  43. pj_dns_parsed_query q;
  44. pj_dns_parsed_rr ans[4];
  45. pj_dns_parsed_rr ar[10];
  46. pj_str_t tmp;
  47. unsigned i;
  48. /*
  49. * This is answer to SRV query to "example.com" domain, and
  50. * the answer contains full reference to the A records of
  51. * the server. The full DNS records is :
  52. _sip._udp.example.com 3600 IN SRV 0 0 5060 sip01.example.com.
  53. _sip._udp.example.com 3600 IN SRV 0 20 5060 sip02.example.com.
  54. _sip._udp.example.com 3600 IN SRV 0 10 5060 sip03.example.com.
  55. _sip._udp.example.com 3600 IN SRV 1 0 5060 sip04.example.com.
  56. sip01.example.com. 3600 IN A 1.1.1.1
  57. sip02.example.com. 3600 IN A 2.2.2.2
  58. sip03.example.com. 3600 IN A 3.3.3.3
  59. sip04.example.com. 3600 IN A 4.4.4.4
  60. ; Additionally, add A record for "example.com"
  61. example.com. 3600 IN A 5.5.5.5
  62. ; Additionally, add corresponding empty AAAA records for all A records
  63. */
  64. pj_bzero(&pkt, sizeof(pkt));
  65. pj_bzero(ans, sizeof(ans));
  66. pj_bzero(ar, sizeof(ar));
  67. pkt.hdr.flags = PJ_DNS_SET_QR(1);
  68. pkt.hdr.anscount = PJ_ARRAY_SIZE(ans);
  69. pkt.hdr.arcount = 0;
  70. pkt.ans = ans;
  71. pkt.arr = ar;
  72. ans[0].name = pj_str("_sip._udp.example.com");
  73. ans[0].type = PJ_DNS_TYPE_SRV;
  74. ans[0].dnsclass = PJ_DNS_CLASS_IN;
  75. ans[0].ttl = 3600;
  76. ans[0].rdata.srv.prio = 0;
  77. ans[0].rdata.srv.weight = 0;
  78. ans[0].rdata.srv.port = 5060;
  79. ans[0].rdata.srv.target = pj_str("sip01.example.com");
  80. ans[1].name = pj_str("_sip._udp.example.com");
  81. ans[1].type = PJ_DNS_TYPE_SRV;
  82. ans[1].dnsclass = PJ_DNS_CLASS_IN;
  83. ans[1].ttl = 3600;
  84. ans[1].rdata.srv.prio = 0;
  85. ans[1].rdata.srv.weight = 20;
  86. ans[1].rdata.srv.port = 5060;
  87. ans[1].rdata.srv.target = pj_str("sip02.example.com");
  88. ans[2].name = pj_str("_sip._udp.example.com");
  89. ans[2].type = PJ_DNS_TYPE_SRV;
  90. ans[2].dnsclass = PJ_DNS_CLASS_IN;
  91. ans[2].ttl = 3600;
  92. ans[2].rdata.srv.prio = 0;
  93. ans[2].rdata.srv.weight = 10;
  94. ans[2].rdata.srv.port = 5060;
  95. ans[2].rdata.srv.target = pj_str("sip03.example.com");
  96. ans[3].name = pj_str("_sip._udp.example.com");
  97. ans[3].type = PJ_DNS_TYPE_SRV;
  98. ans[3].dnsclass = PJ_DNS_CLASS_IN;
  99. ans[3].ttl = 3600;
  100. ans[3].rdata.srv.prio = 1;
  101. ans[3].rdata.srv.weight = 0;
  102. ans[3].rdata.srv.port = 5060;
  103. ans[3].rdata.srv.target = pj_str("sip04.example.com");
  104. pj_dns_resolver_add_entry( resv, &pkt, PJ_FALSE);
  105. ar[0].name = pj_str("sip01.example.com");
  106. ar[0].type = PJ_DNS_TYPE_A;
  107. ar[0].dnsclass = PJ_DNS_CLASS_IN;
  108. ar[0].ttl = 3600;
  109. ar[0].rdata.a.ip_addr = pj_inet_addr(pj_cstr(&tmp, "1.1.1.1"));
  110. ar[1].name = pj_str("sip02.example.com");
  111. ar[1].type = PJ_DNS_TYPE_A;
  112. ar[1].dnsclass = PJ_DNS_CLASS_IN;
  113. ar[1].ttl = 3600;
  114. ar[1].rdata.a.ip_addr = pj_inet_addr(pj_cstr(&tmp, "2.2.2.2"));
  115. ar[2].name = pj_str("sip03.example.com");
  116. ar[2].type = PJ_DNS_TYPE_A;
  117. ar[2].dnsclass = PJ_DNS_CLASS_IN;
  118. ar[2].ttl = 3600;
  119. ar[2].rdata.a.ip_addr = pj_inet_addr(pj_cstr(&tmp, "3.3.3.3"));
  120. ar[3].name = pj_str("sip04.example.com");
  121. ar[3].type = PJ_DNS_TYPE_A;
  122. ar[3].dnsclass = PJ_DNS_CLASS_IN;
  123. ar[3].ttl = 3600;
  124. ar[3].rdata.a.ip_addr = pj_inet_addr(pj_cstr(&tmp, "4.4.4.4"));
  125. ar[4].name = pj_str("example.com");
  126. ar[4].type = PJ_DNS_TYPE_A;
  127. ar[4].dnsclass = PJ_DNS_CLASS_IN;
  128. ar[4].ttl = 3600;
  129. ar[4].rdata.a.ip_addr = pj_inet_addr(pj_cstr(&tmp, "5.5.5.5"));
  130. /* Add corresponding AAAA records for A records above */
  131. for (i = 0; i < 5; ++i) {
  132. ar[5+i].name = ar[i].name;
  133. ar[5+i].type = PJ_DNS_TYPE_AAAA;
  134. ar[5+i].dnsclass = PJ_DNS_CLASS_IN;
  135. ar[5+i].ttl = 3600;
  136. }
  137. /*
  138. * Create individual A records for all hosts in "example.com" domain.
  139. */
  140. for (i=0; i<PJ_ARRAY_SIZE(ar); ++i) {
  141. pj_bzero(&pkt, sizeof(pkt));
  142. pkt.hdr.flags = PJ_DNS_SET_QR(1);
  143. pkt.hdr.qdcount = 1;
  144. pkt.q = &q;
  145. q.name = ar[i].name;
  146. q.type = ar[i].type;
  147. q.dnsclass = PJ_DNS_CLASS_IN;
  148. /* For now, AAAA always contains empty record */
  149. if (ar[i].type != PJ_DNS_TYPE_AAAA) {
  150. pkt.hdr.anscount = 1;
  151. pkt.ans = &ar[i];
  152. }
  153. pj_dns_resolver_add_entry( resv, &pkt, PJ_FALSE);
  154. }
  155. /*
  156. * Simulate DNS error response by creating these answers.
  157. * Sample of invalid SRV records: _sip._udp.sip01.example.com.
  158. */
  159. for (i=0; i<PJ_ARRAY_SIZE(ans); ++i) {
  160. pj_dns_parsed_query q2;
  161. char buf[128];
  162. char *services[] = { "_sip._udp.", "_sip._tcp.", "_sips._tcp."};
  163. unsigned j;
  164. for (j=0; j<PJ_ARRAY_SIZE(services); ++j) {
  165. q2.dnsclass = PJ_DNS_CLASS_IN;
  166. q2.type = PJ_DNS_TYPE_SRV;
  167. q2.name.ptr = buf;
  168. pj_bzero(buf, sizeof(buf));
  169. pj_strcpy2(&q2.name, services[j]);
  170. pj_strcat(&q2.name, &ans[i].rdata.srv.target);
  171. pj_bzero(&pkt, sizeof(pkt));
  172. pkt.hdr.qdcount = 1;
  173. pkt.hdr.flags = PJ_DNS_SET_QR(1) |
  174. PJ_DNS_SET_RCODE(PJ_DNS_RCODE_NXDOMAIN);
  175. pkt.q = &q2;
  176. pj_dns_resolver_add_entry( resv, &pkt, PJ_FALSE);
  177. }
  178. }
  179. /*
  180. * ANOTHER DOMAIN.
  181. *
  182. * This time we let SRV and A get answered in different DNS
  183. * query.
  184. */
  185. /* The "domain.com" DNS records (note the different the port):
  186. _sip._tcp.domain.com 3600 IN SRV 1 0 50060 sip06.domain.com.
  187. _sip._tcp.domain.com 3600 IN SRV 2 0 50060 sip07.domain.com.
  188. sip06.domain.com. 3600 IN A 6.6.6.6
  189. sip07.domain.com. 3600 IN A 7.7.7.7
  190. ; Additionally, add corresponding empty AAAA records for all A records
  191. */
  192. pj_bzero(&pkt, sizeof(pkt));
  193. pj_bzero(&ans, sizeof(ans));
  194. pkt.hdr.flags = PJ_DNS_SET_QR(1);
  195. pkt.hdr.anscount = 2;
  196. pkt.ans = ans;
  197. /* Add the SRV records, with reverse priority (to test that sorting
  198. * works.
  199. */
  200. ans[0].name = pj_str("_sip._tcp.domain.com");
  201. ans[0].type = PJ_DNS_TYPE_SRV;
  202. ans[0].dnsclass = PJ_DNS_CLASS_IN;
  203. ans[0].ttl = 3600;
  204. ans[0].rdata.srv.prio = 2;
  205. ans[0].rdata.srv.weight = 0;
  206. ans[0].rdata.srv.port = 50060;
  207. ans[0].rdata.srv.target = pj_str("SIP07.DOMAIN.COM");
  208. ans[1].name = pj_str("_sip._tcp.domain.com");
  209. ans[1].type = PJ_DNS_TYPE_SRV;
  210. ans[1].dnsclass = PJ_DNS_CLASS_IN;
  211. ans[1].ttl = 3600;
  212. ans[1].rdata.srv.prio = 1;
  213. ans[1].rdata.srv.weight = 0;
  214. ans[1].rdata.srv.port = 50060;
  215. ans[1].rdata.srv.target = pj_str("SIP06.DOMAIN.COM");
  216. pj_dns_resolver_add_entry( resv, &pkt, PJ_FALSE);
  217. /* From herein there is only one answer */
  218. pkt.hdr.anscount = 1;
  219. /* Add a single SRV for UDP */
  220. ans[0].name = pj_str("_sip._udp.domain.com");
  221. ans[0].type = PJ_DNS_TYPE_SRV;
  222. ans[0].dnsclass = PJ_DNS_CLASS_IN;
  223. ans[0].ttl = 3600;
  224. ans[0].rdata.srv.prio = 0;
  225. ans[0].rdata.srv.weight = 0;
  226. ans[0].rdata.srv.port = 50060;
  227. ans[0].rdata.srv.target = pj_str("SIP06.DOMAIN.COM");
  228. pj_dns_resolver_add_entry( resv, &pkt, PJ_FALSE);
  229. /* Add the A record for sip06.domain.com */
  230. ans[0].name = pj_str("sip06.domain.com");
  231. ans[0].type = PJ_DNS_TYPE_A;
  232. ans[0].dnsclass = PJ_DNS_CLASS_IN;
  233. ans[0].ttl = 3600;
  234. ans[0].rdata.a.ip_addr = pj_inet_addr(pj_cstr(&tmp, "6.6.6.6"));
  235. pkt.hdr.qdcount = 1;
  236. pkt.hdr.anscount = 1;
  237. pkt.q = &q;
  238. q.name = ans[0].name;
  239. q.type = ans[0].type;
  240. q.dnsclass = ans[0].dnsclass;
  241. pj_dns_resolver_add_entry( resv, &pkt, PJ_FALSE);
  242. /* Add corresponding AAAA record */
  243. q.type = PJ_DNS_TYPE_AAAA;
  244. pkt.hdr.anscount = 0;
  245. pj_dns_resolver_add_entry( resv, &pkt, PJ_FALSE);
  246. /* Add the A record for sip07.domain.com */
  247. ans[0].name = pj_str("sip07.domain.com");
  248. ans[0].type = PJ_DNS_TYPE_A;
  249. ans[0].dnsclass = PJ_DNS_CLASS_IN;
  250. ans[0].ttl = 3600;
  251. ans[0].rdata.a.ip_addr = pj_inet_addr(pj_cstr(&tmp, "7.7.7.7"));
  252. pkt.hdr.qdcount = 1;
  253. pkt.hdr.anscount = 1;
  254. pkt.q = &q;
  255. q.name = ans[0].name;
  256. q.type = ans[0].type;
  257. q.dnsclass = ans[0].dnsclass;
  258. pj_dns_resolver_add_entry( resv, &pkt, PJ_FALSE);
  259. /* Add corresponding AAAA record */
  260. q.type = PJ_DNS_TYPE_AAAA;
  261. pkt.hdr.anscount = 0;
  262. pj_dns_resolver_add_entry( resv, &pkt, PJ_FALSE);
  263. pkt.hdr.qdcount = 0;
  264. }
  265. /*
  266. * Perform server resolution where the results are expected to
  267. * come in strict order.
  268. */
  269. static int test_resolve(const char *title,
  270. pj_pool_t *pool,
  271. pjsip_transport_type_e type,
  272. char *name,
  273. int port,
  274. pjsip_server_addresses *ref)
  275. {
  276. pjsip_host_info dest;
  277. struct result result;
  278. PJ_LOG(3,(THIS_FILE, " test_resolve(): %s", title));
  279. dest.type = type;
  280. dest.flag = pjsip_transport_get_flag_from_type(type);
  281. dest.addr.host = pj_str(name);
  282. dest.addr.port = port;
  283. result.status = 0x12345678;
  284. pjsip_endpt_resolve(endpt, pool, &dest, &result, &cb);
  285. while (result.status == 0x12345678) {
  286. int i = 0;
  287. pj_time_val timeout = { 1, 0 };
  288. pjsip_endpt_handle_events(endpt, &timeout);
  289. if (i == 1)
  290. pj_dns_resolver_dump(pjsip_endpt_get_resolver(endpt), PJ_TRUE);
  291. }
  292. if (result.status != PJ_SUCCESS) {
  293. app_perror(" pjsip_endpt_resolve() error", result.status);
  294. return result.status;
  295. }
  296. if (ref) {
  297. unsigned i;
  298. if (ref->count != result.servers.count) {
  299. PJ_LOG(3,(THIS_FILE, " test_resolve() error 10: result count mismatch"));
  300. return 10;
  301. }
  302. for (i=0; i<ref->count; ++i) {
  303. pj_sockaddr_in *ra = (pj_sockaddr_in *)&ref->entry[i].addr;
  304. pj_sockaddr_in *rb = (pj_sockaddr_in *)&result.servers.entry[i].addr;
  305. if (ra->sin_addr.s_addr != rb->sin_addr.s_addr) {
  306. PJ_LOG(3,(THIS_FILE, " test_resolve() error 20: IP address mismatch"));
  307. return 20;
  308. }
  309. if (ra->sin_port != rb->sin_port) {
  310. PJ_LOG(3,(THIS_FILE, " test_resolve() error 30: port mismatch"));
  311. return 30;
  312. }
  313. if (ref->entry[i].addr_len != result.servers.entry[i].addr_len) {
  314. PJ_LOG(3,(THIS_FILE, " test_resolve() error 40: addr_len mismatch"));
  315. return 40;
  316. }
  317. if (ref->entry[i].type != result.servers.entry[i].type) {
  318. PJ_LOG(3,(THIS_FILE, " test_resolve() error 50: transport type mismatch"));
  319. return 50;
  320. }
  321. }
  322. }
  323. return PJ_SUCCESS;
  324. }
  325. /*
  326. * Perform round-robin/load balance test.
  327. */
  328. static int round_robin_test(pj_pool_t *pool)
  329. {
  330. enum { COUNT = 400, PCT_ALLOWANCE = 10 };
  331. unsigned i;
  332. struct server_hit
  333. {
  334. char *ip_addr;
  335. unsigned percent;
  336. unsigned hits;
  337. } server_hit[] =
  338. {
  339. { "1.1.1.1", 3, 0 },
  340. { "2.2.2.2", 65, 0 },
  341. { "3.3.3.3", 32, 0 },
  342. { "4.4.4.4", 0, 0 }
  343. };
  344. PJ_LOG(3,(THIS_FILE, " Performing round-robin/load-balance test.."));
  345. /* Do multiple resolve request to "example.com".
  346. * The resolver should select the server based on the weight proportion
  347. * the the servers in the SRV entry.
  348. */
  349. for (i=0; i<COUNT; ++i) {
  350. pjsip_host_info dest;
  351. struct result result;
  352. unsigned j;
  353. dest.type = PJSIP_TRANSPORT_UDP;
  354. dest.flag = pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_UDP);
  355. dest.addr.host = pj_str("example.com");
  356. dest.addr.port = 0;
  357. result.status = 0x12345678;
  358. pjsip_endpt_resolve(endpt, pool, &dest, &result, &cb);
  359. while (result.status == 0x12345678) {
  360. int ii = 0;
  361. pj_time_val timeout = { 1, 0 };
  362. pjsip_endpt_handle_events(endpt, &timeout);
  363. if (ii == 1)
  364. pj_dns_resolver_dump(pjsip_endpt_get_resolver(endpt), PJ_TRUE);
  365. }
  366. /* Find which server was "hit" */
  367. for (j=0; j<PJ_ARRAY_SIZE(server_hit); ++j) {
  368. pj_str_t tmp;
  369. pj_in_addr a1;
  370. pj_sockaddr_in *a2;
  371. tmp = pj_str(server_hit[j].ip_addr);
  372. a1 = pj_inet_addr(&tmp);
  373. a2 = (pj_sockaddr_in*) &result.servers.entry[0].addr;
  374. if (a1.s_addr == a2->sin_addr.s_addr) {
  375. server_hit[j].hits++;
  376. break;
  377. }
  378. }
  379. if (j == PJ_ARRAY_SIZE(server_hit)) {
  380. PJ_LOG(1,(THIS_FILE, "..round_robin_test() error 10: returned address mismatch"));
  381. return 10;
  382. }
  383. }
  384. /* Print the actual hit rate */
  385. for (i=0; i<PJ_ARRAY_SIZE(server_hit); ++i) {
  386. PJ_LOG(3,(THIS_FILE, " ..Server %s: weight=%d%%, hit %d%% times",
  387. server_hit[i].ip_addr, server_hit[i].percent,
  388. (server_hit[i].hits * 100) / COUNT));
  389. }
  390. /* Compare the actual hit with the weight proportion */
  391. for (i=0; i<PJ_ARRAY_SIZE(server_hit); ++i) {
  392. int actual_pct = (server_hit[i].hits * 100) / COUNT;
  393. if (actual_pct + PCT_ALLOWANCE < (int)server_hit[i].percent ||
  394. actual_pct - PCT_ALLOWANCE > (int)server_hit[i].percent)
  395. {
  396. PJ_LOG(1,(THIS_FILE,
  397. "..round_robin_test() error 20: "
  398. "hit rate difference for server %s (%d%%) is more than "
  399. "tolerable allowance (%d%%)",
  400. server_hit[i].ip_addr,
  401. actual_pct - server_hit[i].percent,
  402. PCT_ALLOWANCE));
  403. return 20;
  404. }
  405. }
  406. PJ_LOG(3,(THIS_FILE,
  407. " Load balance test success, hit-rate is "
  408. "within %d%% allowance", PCT_ALLOWANCE));
  409. return PJ_SUCCESS;
  410. }
  411. #define C(expr) status = expr; \
  412. if (status != PJ_SUCCESS) app_perror(THIS_FILE, "Error", status);
  413. static void add_ref(pjsip_server_addresses *r,
  414. pjsip_transport_type_e type,
  415. char *addr,
  416. int port)
  417. {
  418. pj_sockaddr_in *a;
  419. pj_str_t tmp;
  420. r->entry[r->count].type = type;
  421. r->entry[r->count].priority = 0;
  422. r->entry[r->count].weight = 0;
  423. r->entry[r->count].addr_len = sizeof(pj_sockaddr_in);
  424. a = (pj_sockaddr_in *)&r->entry[r->count].addr;
  425. a->sin_family = pj_AF_INET();
  426. tmp = pj_str(addr);
  427. a->sin_addr = pj_inet_addr(&tmp);
  428. a->sin_port = pj_htons((pj_uint16_t)port);
  429. r->count++;
  430. }
  431. static void create_ref(pjsip_server_addresses *r,
  432. pjsip_transport_type_e type,
  433. char *addr,
  434. int port)
  435. {
  436. r->count = 0;
  437. add_ref(r, type, addr, port);
  438. }
  439. /*
  440. * Main test entry.
  441. */
  442. int resolve_test(void)
  443. {
  444. pj_pool_t *pool;
  445. pj_dns_resolver *resv;
  446. pj_str_t nameserver;
  447. pj_uint16_t port = 5353;
  448. pj_status_t status;
  449. pool = pjsip_endpt_create_pool(endpt, NULL, 4000, 4000);
  450. status = pjsip_endpt_create_resolver(endpt, &resv);
  451. nameserver = pj_str("192.168.0.106");
  452. pj_dns_resolver_set_ns(resv, 1, &nameserver, &port);
  453. pjsip_endpt_set_resolver(endpt, resv);
  454. add_dns_entries(resv);
  455. /* These all should be resolved as IP addresses (DNS A query) */
  456. {
  457. pjsip_server_addresses ref;
  458. create_ref(&ref, PJSIP_TRANSPORT_UDP, "1.1.1.1", 5060);
  459. status = test_resolve("IP address without transport and port", pool, PJSIP_TRANSPORT_UNSPECIFIED, "1.1.1.1", 0, &ref);
  460. if (status != PJ_SUCCESS)
  461. return -100;
  462. }
  463. {
  464. pjsip_server_addresses ref;
  465. create_ref(&ref, PJSIP_TRANSPORT_UDP, "1.1.1.1", 5060);
  466. status = test_resolve("IP address with explicit port", pool, PJSIP_TRANSPORT_UNSPECIFIED, "1.1.1.1", 5060, &ref);
  467. if (status != PJ_SUCCESS)
  468. return -110;
  469. }
  470. {
  471. pjsip_server_addresses ref;
  472. create_ref(&ref, PJSIP_TRANSPORT_TCP, "1.1.1.1", 5060);
  473. status = test_resolve("IP address without port (TCP)", pool, PJSIP_TRANSPORT_TCP,"1.1.1.1", 0, &ref);
  474. if (status != PJ_SUCCESS)
  475. return -120;
  476. }
  477. {
  478. pjsip_server_addresses ref;
  479. create_ref(&ref, PJSIP_TRANSPORT_TLS, "1.1.1.1", 5061);
  480. status = test_resolve("IP address without port (TLS)", pool, PJSIP_TRANSPORT_TLS, "1.1.1.1", 0, &ref);
  481. if (status != PJ_SUCCESS)
  482. return -130;
  483. }
  484. /* This should be resolved as DNS A record (because port is present) */
  485. {
  486. pjsip_server_addresses ref;
  487. create_ref(&ref, PJSIP_TRANSPORT_UDP, "5.5.5.5", 5060);
  488. status = test_resolve("domain name with port should resolve to A record", pool, PJSIP_TRANSPORT_UNSPECIFIED, "example.com", 5060, &ref);
  489. if (status != PJ_SUCCESS)
  490. return -140;
  491. }
  492. /* This will fail to be resolved as SRV, resolver should fallback to
  493. * resolving to A record.
  494. */
  495. {
  496. pjsip_server_addresses ref;
  497. create_ref(&ref, PJSIP_TRANSPORT_UDP, "2.2.2.2", 5060);
  498. status = test_resolve("failure with SRV fallback to A record", pool, PJSIP_TRANSPORT_UNSPECIFIED, "sip02.example.com", 0, &ref);
  499. if (status != PJ_SUCCESS)
  500. return -150;
  501. }
  502. /* Same as above, but explicitly for TLS. */
  503. {
  504. pjsip_server_addresses ref;
  505. create_ref(&ref, PJSIP_TRANSPORT_TLS, "2.2.2.2", 5061);
  506. status = test_resolve("failure with SRV fallback to A record (for TLS)", pool, PJSIP_TRANSPORT_TLS, "sip02.example.com", 0, &ref);
  507. if (status != PJ_SUCCESS)
  508. return -150;
  509. }
  510. /* Standard DNS SRV followed by A recolution */
  511. {
  512. pjsip_server_addresses ref;
  513. create_ref(&ref, PJSIP_TRANSPORT_UDP, "6.6.6.6", 50060);
  514. status = test_resolve("standard SRV resolution", pool, PJSIP_TRANSPORT_UNSPECIFIED, "domain.com", 0, &ref);
  515. if (status != PJ_SUCCESS)
  516. return -155;
  517. }
  518. /* Standard DNS SRV followed by A recolution (explicit transport) */
  519. {
  520. pjsip_server_addresses ref;
  521. create_ref(&ref, PJSIP_TRANSPORT_TCP, "6.6.6.6", 50060);
  522. add_ref(&ref, PJSIP_TRANSPORT_TCP, "7.7.7.7", 50060);
  523. status = test_resolve("standard SRV resolution with explicit transport (TCP)", pool, PJSIP_TRANSPORT_TCP, "domain.com", 0, &ref);
  524. if (status != PJ_SUCCESS)
  525. return -160;
  526. }
  527. /* Round robin/load balance test */
  528. if (round_robin_test(pool) != 0)
  529. return -170;
  530. /* Timeout test */
  531. {
  532. status = test_resolve("timeout test", pool, PJSIP_TRANSPORT_UNSPECIFIED, "an.invalid.address", 0, NULL);
  533. if (status == PJ_SUCCESS)
  534. return -150;
  535. }
  536. return 0;
  537. }