blob: 805d70d12def329ea45fa29ee492dcecbe7c844e [file] [log] [blame]
Benny Prijonofa9e5b12006-10-08 12:39:34 +00001/* $Id$ */
2/*
Benny Prijono32177c02008-06-20 22:44:47 +00003 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
Benny Prijonofa9e5b12006-10-08 12:39:34 +00004 *
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
24/* For logging purpose. */
25#define THIS_FILE "dns_test.c"
26
27struct result
28{
29 pj_status_t status;
30 pjsip_server_addresses servers;
31};
32
33
34static void cb(pj_status_t status,
35 void *token,
36 const struct pjsip_server_addresses *addr)
37{
Benny Prijonoa1e69682007-05-11 15:14:34 +000038 struct result *result = (struct result*) token;
Benny Prijonofa9e5b12006-10-08 12:39:34 +000039
40 result->status = status;
41 if (status == PJ_SUCCESS)
42 pj_memcpy(&result->servers, addr, sizeof(*addr));
43}
44
45
46static void add_dns_entries(pj_dns_resolver *resv)
47{
48 /* Inject DNS SRV entry */
49 pj_dns_parsed_packet pkt;
Benny Prijonod4791af2007-06-19 08:46:02 +000050 pj_dns_parsed_query q;
Benny Prijonofa9e5b12006-10-08 12:39:34 +000051 pj_dns_parsed_rr ans[4];
52 pj_dns_parsed_rr ar[5];
Benny Prijono91475442007-03-03 02:13:55 +000053 pj_str_t tmp;
Benny Prijonofa9e5b12006-10-08 12:39:34 +000054 unsigned i;
55
56 /*
57 * This is answer to SRV query to "example.com" domain, and
58 * the answer contains full reference to the A records of
59 * the server. The full DNS records is :
60
61 _sip._udp.example.com 3600 IN SRV 0 0 5060 sip01.example.com.
62 _sip._udp.example.com 3600 IN SRV 0 20 5060 sip02.example.com.
63 _sip._udp.example.com 3600 IN SRV 0 10 5060 sip03.example.com.
64 _sip._udp.example.com 3600 IN SRV 1 0 5060 sip04.example.com.
65
66 sip01.example.com. 3600 IN A 1.1.1.1
67 sip02.example.com. 3600 IN A 2.2.2.2
68 sip03.example.com. 3600 IN A 3.3.3.3
69 sip04.example.com. 3600 IN A 4.4.4.4
70
71 ; Additionally, add A record for "example.com"
72 example.com. 3600 IN A 5.5.5.5
73
74 */
75 pj_bzero(&pkt, sizeof(pkt));
76 pj_bzero(ans, sizeof(ans));
77 pj_bzero(ar, sizeof(ar));
78
79 pkt.hdr.flags = PJ_DNS_SET_QR(1);
80 pkt.hdr.anscount = PJ_ARRAY_SIZE(ans);
81 pkt.hdr.arcount = 0;
82 pkt.ans = ans;
83 pkt.arr = ar;
84
85 ans[0].name = pj_str("_sip._udp.example.com");
86 ans[0].type = PJ_DNS_TYPE_SRV;
87 ans[0].dnsclass = PJ_DNS_CLASS_IN;
88 ans[0].ttl = 3600;
89 ans[0].rdata.srv.prio = 0;
90 ans[0].rdata.srv.weight = 0;
91 ans[0].rdata.srv.port = 5060;
92 ans[0].rdata.srv.target = pj_str("sip01.example.com");
93
94 ans[1].name = pj_str("_sip._udp.example.com");
95 ans[1].type = PJ_DNS_TYPE_SRV;
96 ans[1].dnsclass = PJ_DNS_CLASS_IN;
97 ans[1].ttl = 3600;
98 ans[1].rdata.srv.prio = 0;
99 ans[1].rdata.srv.weight = 20;
100 ans[1].rdata.srv.port = 5060;
101 ans[1].rdata.srv.target = pj_str("sip02.example.com");
102
103 ans[2].name = pj_str("_sip._udp.example.com");
104 ans[2].type = PJ_DNS_TYPE_SRV;
105 ans[2].dnsclass = PJ_DNS_CLASS_IN;
106 ans[2].ttl = 3600;
107 ans[2].rdata.srv.prio = 0;
108 ans[2].rdata.srv.weight = 10;
109 ans[2].rdata.srv.port = 5060;
110 ans[2].rdata.srv.target = pj_str("sip03.example.com");
111
112 ans[3].name = pj_str("_sip._udp.example.com");
113 ans[3].type = PJ_DNS_TYPE_SRV;
114 ans[3].dnsclass = PJ_DNS_CLASS_IN;
115 ans[3].ttl = 3600;
116 ans[3].rdata.srv.prio = 1;
117 ans[3].rdata.srv.weight = 0;
118 ans[3].rdata.srv.port = 5060;
119 ans[3].rdata.srv.target = pj_str("sip04.example.com");
120
121 pj_dns_resolver_add_entry( resv, &pkt, PJ_FALSE);
122
123 ar[0].name = pj_str("sip01.example.com");
124 ar[0].type = PJ_DNS_TYPE_A;
125 ar[0].dnsclass = PJ_DNS_CLASS_IN;
126 ar[0].ttl = 3600;
Benny Prijono91475442007-03-03 02:13:55 +0000127 ar[0].rdata.a.ip_addr = pj_inet_addr(pj_cstr(&tmp, "1.1.1.1"));
Benny Prijonofa9e5b12006-10-08 12:39:34 +0000128
129 ar[1].name = pj_str("sip02.example.com");
130 ar[1].type = PJ_DNS_TYPE_A;
131 ar[1].dnsclass = PJ_DNS_CLASS_IN;
132 ar[1].ttl = 3600;
Benny Prijono91475442007-03-03 02:13:55 +0000133 ar[1].rdata.a.ip_addr = pj_inet_addr(pj_cstr(&tmp, "2.2.2.2"));
Benny Prijonofa9e5b12006-10-08 12:39:34 +0000134
135 ar[2].name = pj_str("sip03.example.com");
136 ar[2].type = PJ_DNS_TYPE_A;
137 ar[2].dnsclass = PJ_DNS_CLASS_IN;
138 ar[2].ttl = 3600;
Benny Prijono91475442007-03-03 02:13:55 +0000139 ar[2].rdata.a.ip_addr = pj_inet_addr(pj_cstr(&tmp, "3.3.3.3"));
Benny Prijonofa9e5b12006-10-08 12:39:34 +0000140
141 ar[3].name = pj_str("sip04.example.com");
142 ar[3].type = PJ_DNS_TYPE_A;
143 ar[3].dnsclass = PJ_DNS_CLASS_IN;
144 ar[3].ttl = 3600;
Benny Prijono91475442007-03-03 02:13:55 +0000145 ar[3].rdata.a.ip_addr = pj_inet_addr(pj_cstr(&tmp, "4.4.4.4"));
Benny Prijonofa9e5b12006-10-08 12:39:34 +0000146
147 ar[4].name = pj_str("example.com");
148 ar[4].type = PJ_DNS_TYPE_A;
149 ar[4].dnsclass = PJ_DNS_CLASS_IN;
150 ar[4].ttl = 3600;
Benny Prijono91475442007-03-03 02:13:55 +0000151 ar[4].rdata.a.ip_addr = pj_inet_addr(pj_cstr(&tmp, "5.5.5.5"));
Benny Prijonofa9e5b12006-10-08 12:39:34 +0000152
153 /*
154 * Create individual A records for all hosts in "example.com" domain.
155 */
156 for (i=0; i<PJ_ARRAY_SIZE(ar); ++i) {
157 pj_bzero(&pkt, sizeof(pkt));
Benny Prijonofa9e5b12006-10-08 12:39:34 +0000158 pkt.hdr.flags = PJ_DNS_SET_QR(1);
Benny Prijonod4791af2007-06-19 08:46:02 +0000159 pkt.hdr.qdcount = 1;
160 pkt.q = &q;
161 q.name = ar[i].name;
162 q.type = ar[i].type;
163 q.dnsclass = PJ_DNS_CLASS_IN;
164 pkt.hdr.anscount = 1;
Benny Prijonofa9e5b12006-10-08 12:39:34 +0000165 pkt.ans = &ar[i];
166
167 pj_dns_resolver_add_entry( resv, &pkt, PJ_FALSE);
168 }
169
170 /*
171 * Simulate DNS error response by creating these answers.
172 * Sample of invalid SRV records: _sip._udp.sip01.example.com.
173 */
174 for (i=0; i<PJ_ARRAY_SIZE(ans); ++i) {
175 pj_dns_parsed_query q;
176 char buf[128];
177 char *services[] = { "_sip._udp.", "_sip._tcp.", "_sips._tcp."};
178 unsigned j;
179
180 for (j=0; j<PJ_ARRAY_SIZE(services); ++j) {
181 q.dnsclass = PJ_DNS_CLASS_IN;
182 q.type = PJ_DNS_TYPE_SRV;
183
184 q.name.ptr = buf;
185 pj_bzero(buf, sizeof(buf));
186 pj_strcpy2(&q.name, services[j]);
187 pj_strcat(&q.name, &ans[i].rdata.srv.target);
188
189 pj_bzero(&pkt, sizeof(pkt));
190 pkt.hdr.qdcount = 1;
191 pkt.hdr.flags = PJ_DNS_SET_QR(1) |
192 PJ_DNS_SET_RCODE(PJ_DNS_RCODE_NXDOMAIN);
193 pkt.q = &q;
194
195 pj_dns_resolver_add_entry( resv, &pkt, PJ_FALSE);
196 }
197 }
198
199
200 /*
201 * ANOTHER DOMAIN.
202 *
203 * This time we let SRV and A get answered in different DNS
204 * query.
205 */
206
207 /* The "domain.com" DNS records (note the different the port):
208
209 _sip._tcp.domain.com 3600 IN SRV 1 0 50060 sip06.domain.com.
210 _sip._tcp.domain.com 3600 IN SRV 2 0 50060 sip07.domain.com.
211
212 sip06.domain.com. 3600 IN A 6.6.6.6
213 sip07.domain.com. 3600 IN A 7.7.7.7
214 */
215
216 pj_bzero(&pkt, sizeof(pkt));
217 pj_bzero(&ans, sizeof(ans));
218 pkt.hdr.flags = PJ_DNS_SET_QR(1);
219 pkt.hdr.anscount = 2;
220 pkt.ans = ans;
221
222 /* Add the SRV records, with reverse priority (to test that sorting
223 * works.
224 */
225 ans[0].name = pj_str("_sip._tcp.domain.com");
226 ans[0].type = PJ_DNS_TYPE_SRV;
227 ans[0].dnsclass = PJ_DNS_CLASS_IN;
228 ans[0].ttl = 3600;
229 ans[0].rdata.srv.prio = 2;
230 ans[0].rdata.srv.weight = 0;
231 ans[0].rdata.srv.port = 50060;
232 ans[0].rdata.srv.target = pj_str("SIP07.DOMAIN.COM");
233
234 ans[1].name = pj_str("_sip._tcp.domain.com");
235 ans[1].type = PJ_DNS_TYPE_SRV;
236 ans[1].dnsclass = PJ_DNS_CLASS_IN;
237 ans[1].ttl = 3600;
238 ans[1].rdata.srv.prio = 1;
239 ans[1].rdata.srv.weight = 0;
240 ans[1].rdata.srv.port = 50060;
241 ans[1].rdata.srv.target = pj_str("SIP06.DOMAIN.COM");
242
243 pj_dns_resolver_add_entry( resv, &pkt, PJ_FALSE);
244
245 /* From herein there is only one answer */
246 pkt.hdr.anscount = 1;
247
248 /* Add a single SRV for UDP */
249 ans[0].name = pj_str("_sip._udp.domain.com");
250 ans[0].type = PJ_DNS_TYPE_SRV;
251 ans[0].dnsclass = PJ_DNS_CLASS_IN;
252 ans[0].ttl = 3600;
253 ans[0].rdata.srv.prio = 0;
254 ans[0].rdata.srv.weight = 0;
255 ans[0].rdata.srv.port = 50060;
256 ans[0].rdata.srv.target = pj_str("SIP06.DOMAIN.COM");
257
258 pj_dns_resolver_add_entry( resv, &pkt, PJ_FALSE);
259
260
261 /* Add the A record for sip06.domain.com */
262 ans[0].name = pj_str("sip06.domain.com");
263 ans[0].type = PJ_DNS_TYPE_A;
264 ans[0].dnsclass = PJ_DNS_CLASS_IN;
265 ans[0].ttl = 3600;
Benny Prijono91475442007-03-03 02:13:55 +0000266 ans[0].rdata.a.ip_addr = pj_inet_addr(pj_cstr(&tmp, "6.6.6.6"));
Benny Prijonofa9e5b12006-10-08 12:39:34 +0000267
Benny Prijonod4791af2007-06-19 08:46:02 +0000268 pkt.hdr.qdcount = 1;
269 pkt.q = &q;
270 q.name = ans[0].name;
271 q.type = ans[0].type;
272 q.dnsclass = ans[0].dnsclass;
273
Benny Prijonofa9e5b12006-10-08 12:39:34 +0000274 pj_dns_resolver_add_entry( resv, &pkt, PJ_FALSE);
275
276 /* Add the A record for sip07.domain.com */
277 ans[0].name = pj_str("sip07.domain.com");
278 ans[0].type = PJ_DNS_TYPE_A;
279 ans[0].dnsclass = PJ_DNS_CLASS_IN;
280 ans[0].ttl = 3600;
Benny Prijono91475442007-03-03 02:13:55 +0000281 ans[0].rdata.a.ip_addr = pj_inet_addr(pj_cstr(&tmp, "7.7.7.7"));
Benny Prijonofa9e5b12006-10-08 12:39:34 +0000282
Benny Prijonod4791af2007-06-19 08:46:02 +0000283 pkt.hdr.qdcount = 1;
284 pkt.q = &q;
285 q.name = ans[0].name;
286 q.type = ans[0].type;
287 q.dnsclass = ans[0].dnsclass;
288
Benny Prijonofa9e5b12006-10-08 12:39:34 +0000289 pj_dns_resolver_add_entry( resv, &pkt, PJ_FALSE);
Benny Prijonod4791af2007-06-19 08:46:02 +0000290
291 pkt.hdr.qdcount = 0;
Benny Prijonofa9e5b12006-10-08 12:39:34 +0000292}
293
294
295/*
296 * Perform server resolution where the results are expected to
297 * come in strict order.
298 */
299static int test_resolve(const char *title,
300 pj_pool_t *pool,
301 pjsip_transport_type_e type,
302 char *name,
303 int port,
304 pjsip_server_addresses *ref)
305{
306 pjsip_host_info dest;
307 struct result result;
308
309 PJ_LOG(3,(THIS_FILE, " test_resolve(): %s", title));
310
311 dest.type = type;
312 dest.flag = pjsip_transport_get_flag_from_type(type);
313 dest.addr.host = pj_str(name);
314 dest.addr.port = port;
315
316 result.status = 0x12345678;
317
318 pjsip_endpt_resolve(endpt, pool, &dest, &result, &cb);
319
320 while (result.status == 0x12345678) {
321 int i = 0;
322 pj_time_val timeout = { 1, 0 };
323 pjsip_endpt_handle_events(endpt, &timeout);
324 if (i == 1)
325 pj_dns_resolver_dump(pjsip_endpt_get_resolver(endpt), PJ_TRUE);
326 }
327
328 if (result.status != PJ_SUCCESS) {
329 app_perror(" pjsip_endpt_resolve() error", result.status);
330 return result.status;
331 }
332
333 if (ref) {
334 unsigned i;
335
336 if (ref->count != result.servers.count) {
337 PJ_LOG(3,(THIS_FILE, " test_resolve() error 10: result count mismatch"));
338 return 10;
339 }
340
341 for (i=0; i<ref->count; ++i) {
342 pj_sockaddr_in *ra = (pj_sockaddr_in *)&ref->entry[i].addr;
343 pj_sockaddr_in *rb = (pj_sockaddr_in *)&result.servers.entry[i].addr;
344
345 if (ra->sin_addr.s_addr != rb->sin_addr.s_addr) {
346 PJ_LOG(3,(THIS_FILE, " test_resolve() error 20: IP address mismatch"));
347 return 20;
348 }
349 if (ra->sin_port != rb->sin_port) {
350 PJ_LOG(3,(THIS_FILE, " test_resolve() error 30: port mismatch"));
351 return 30;
352 }
353 if (ref->entry[i].addr_len != result.servers.entry[i].addr_len) {
354 PJ_LOG(3,(THIS_FILE, " test_resolve() error 40: addr_len mismatch"));
355 return 40;
356 }
357 if (ref->entry[i].type != result.servers.entry[i].type) {
358 PJ_LOG(3,(THIS_FILE, " test_resolve() error 50: transport type mismatch"));
359 return 50;
360 }
361 }
362 }
363
364 return PJ_SUCCESS;
365}
366
367/*
368 * Perform round-robin/load balance test.
369 */
370static int round_robin_test(pj_pool_t *pool)
371{
372 enum { COUNT = 400, PCT_ALLOWANCE = 5 };
373 unsigned i;
374 struct server_hit
375 {
376 char *ip_addr;
377 unsigned percent;
378 unsigned hits;
379 } server_hit[] =
380 {
381 { "1.1.1.1", 3, 0 },
382 { "2.2.2.2", 65, 0 },
383 { "3.3.3.3", 32, 0 },
384 { "4.4.4.4", 0, 0 }
385 };
386
387 PJ_LOG(3,(THIS_FILE, " Performing round-robin/load-balance test.."));
388
389 /* Do multiple resolve request to "example.com".
390 * The resolver should select the server based on the weight proportion
391 * the the servers in the SRV entry.
392 */
393 for (i=0; i<COUNT; ++i) {
394 pjsip_host_info dest;
395 struct result result;
396 unsigned j;
397
398 dest.type = PJSIP_TRANSPORT_UDP;
399 dest.flag = pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_UDP);
400 dest.addr.host = pj_str("example.com");
401 dest.addr.port = 0;
402
403 result.status = 0x12345678;
404
405 pjsip_endpt_resolve(endpt, pool, &dest, &result, &cb);
406
407 while (result.status == 0x12345678) {
408 int i = 0;
409 pj_time_val timeout = { 1, 0 };
410 pjsip_endpt_handle_events(endpt, &timeout);
411 if (i == 1)
412 pj_dns_resolver_dump(pjsip_endpt_get_resolver(endpt), PJ_TRUE);
413 }
414
415 /* Find which server was "hit" */
416 for (j=0; j<PJ_ARRAY_SIZE(server_hit); ++j) {
417 pj_str_t tmp;
418 pj_in_addr a1;
419 pj_sockaddr_in *a2;
420
421 tmp = pj_str(server_hit[j].ip_addr);
422 a1 = pj_inet_addr(&tmp);
423 a2 = (pj_sockaddr_in*) &result.servers.entry[0].addr;
424
425 if (a1.s_addr == a2->sin_addr.s_addr) {
426 server_hit[j].hits++;
427 break;
428 }
429 }
430
431 if (j == PJ_ARRAY_SIZE(server_hit)) {
432 PJ_LOG(1,(THIS_FILE, "..round_robin_test() error 10: returned address mismatch"));
433 return 10;
434 }
435 }
436
437 /* Print the actual hit rate */
438 for (i=0; i<PJ_ARRAY_SIZE(server_hit); ++i) {
439 PJ_LOG(3,(THIS_FILE, " ..Server %s: weight=%d%%, hit %d%% times",
440 server_hit[i].ip_addr, server_hit[i].percent,
441 (server_hit[i].hits * 100) / COUNT));
442 }
443
444 /* Compare the actual hit with the weight proportion */
445 for (i=0; i<PJ_ARRAY_SIZE(server_hit); ++i) {
446 int actual_pct = (server_hit[i].hits * 100) / COUNT;
447
448 if (actual_pct + PCT_ALLOWANCE < (int)server_hit[i].percent ||
449 actual_pct - PCT_ALLOWANCE > (int)server_hit[i].percent)
450 {
451 PJ_LOG(1,(THIS_FILE,
452 "..round_robin_test() error 20: "
453 "hit rate difference for server %s (%d%%) is more than "
454 "tolerable allowance (%d%%)",
455 server_hit[i].ip_addr,
456 actual_pct - server_hit[i].percent,
457 PCT_ALLOWANCE));
458 return 20;
459 }
460 }
461
462 PJ_LOG(3,(THIS_FILE,
463 " Load balance test success, hit-rate is "
464 "within %d%% allowance", PCT_ALLOWANCE));
465 return PJ_SUCCESS;
466}
467
468
469#define C(expr) status = expr; \
470 if (status != PJ_SUCCESS) app_perror(THIS_FILE, "Error", status);
471
472static void add_ref(pjsip_server_addresses *r,
473 pjsip_transport_type_e type,
474 char *addr,
475 int port)
476{
477 pj_sockaddr_in *a;
478 pj_str_t tmp;
479
480 r->entry[r->count].type = type;
481 r->entry[r->count].priority = 0;
482 r->entry[r->count].weight = 0;
483 r->entry[r->count].addr_len = sizeof(pj_sockaddr_in);
484
485 a = (pj_sockaddr_in *)&r->entry[r->count].addr;
Benny Prijono8ab968f2007-07-20 08:08:30 +0000486 a->sin_family = pj_AF_INET();
Benny Prijonofa9e5b12006-10-08 12:39:34 +0000487 tmp = pj_str(addr);
488 a->sin_addr = pj_inet_addr(&tmp);
489 a->sin_port = pj_htons((pj_uint16_t)port);
490
491 r->count++;
492}
493
494static void create_ref(pjsip_server_addresses *r,
495 pjsip_transport_type_e type,
496 char *addr,
497 int port)
498{
499 r->count = 0;
500 add_ref(r, type, addr, port);
501}
502
503
504/*
505 * Main test entry.
506 */
507int resolve_test(void)
508{
509 pj_pool_t *pool;
510 pj_dns_resolver *resv;
511 pj_str_t nameserver;
512 pj_uint16_t port = 5353;
513 pj_status_t status;
514
515 pool = pjsip_endpt_create_pool(endpt, NULL, 4000, 4000);
516
517 status = pjsip_endpt_create_resolver(endpt, &resv);
518
519 nameserver = pj_str("192.168.0.106");
520 pj_dns_resolver_set_ns(resv, 1, &nameserver, &port);
521 pjsip_endpt_set_resolver(endpt, resv);
522
523 add_dns_entries(resv);
524
525 /* These all should be resolved as IP addresses (DNS A query) */
526 {
527 pjsip_server_addresses ref;
528 create_ref(&ref, PJSIP_TRANSPORT_UDP, "1.1.1.1", 5060);
529 status = test_resolve("IP address without transport and port", pool, PJSIP_TRANSPORT_UNSPECIFIED, "1.1.1.1", 0, &ref);
530 if (status != PJ_SUCCESS)
531 return -100;
532 }
533 {
534 pjsip_server_addresses ref;
535 create_ref(&ref, PJSIP_TRANSPORT_UDP, "1.1.1.1", 5060);
536 status = test_resolve("IP address with explicit port", pool, PJSIP_TRANSPORT_UNSPECIFIED, "1.1.1.1", 5060, &ref);
537 if (status != PJ_SUCCESS)
538 return -110;
539 }
540 {
541 pjsip_server_addresses ref;
542 create_ref(&ref, PJSIP_TRANSPORT_TCP, "1.1.1.1", 5060);
543 status = test_resolve("IP address without port (TCP)", pool, PJSIP_TRANSPORT_TCP,"1.1.1.1", 0, &ref);
544 if (status != PJ_SUCCESS)
545 return -120;
546 }
547 {
548 pjsip_server_addresses ref;
549 create_ref(&ref, PJSIP_TRANSPORT_TLS, "1.1.1.1", 5061);
550 status = test_resolve("IP address without port (TLS)", pool, PJSIP_TRANSPORT_TLS, "1.1.1.1", 0, &ref);
551 if (status != PJ_SUCCESS)
552 return -130;
553 }
554
555 /* This should be resolved as DNS A record (because port is present) */
556 {
557 pjsip_server_addresses ref;
558 create_ref(&ref, PJSIP_TRANSPORT_UDP, "5.5.5.5", 5060);
559 status = test_resolve("domain name with port should resolve to A record", pool, PJSIP_TRANSPORT_UNSPECIFIED, "example.com", 5060, &ref);
560 if (status != PJ_SUCCESS)
561 return -140;
562 }
563
564 /* This will fail to be resolved as SRV, resolver should fallback to
565 * resolving to A record.
566 */
567 {
568 pjsip_server_addresses ref;
569 create_ref(&ref, PJSIP_TRANSPORT_UDP, "2.2.2.2", 5060);
570 status = test_resolve("failure with SRV fallback to A record", pool, PJSIP_TRANSPORT_UNSPECIFIED, "sip02.example.com", 0, &ref);
571 if (status != PJ_SUCCESS)
572 return -150;
573 }
574
575 /* Same as above, but explicitly for TLS. */
576 {
577 pjsip_server_addresses ref;
578 create_ref(&ref, PJSIP_TRANSPORT_TLS, "2.2.2.2", 5061);
579 status = test_resolve("failure with SRV fallback to A record (for TLS)", pool, PJSIP_TRANSPORT_TLS, "sip02.example.com", 0, &ref);
580 if (status != PJ_SUCCESS)
581 return -150;
582 }
583
584 /* Standard DNS SRV followed by A recolution */
585 {
586 pjsip_server_addresses ref;
587 create_ref(&ref, PJSIP_TRANSPORT_UDP, "6.6.6.6", 50060);
588 status = test_resolve("standard SRV resolution", pool, PJSIP_TRANSPORT_UNSPECIFIED, "domain.com", 0, &ref);
589 if (status != PJ_SUCCESS)
590 return -155;
591 }
592
593 /* Standard DNS SRV followed by A recolution (explicit transport) */
594 {
595 pjsip_server_addresses ref;
596 create_ref(&ref, PJSIP_TRANSPORT_TCP, "6.6.6.6", 50060);
597 add_ref(&ref, PJSIP_TRANSPORT_TCP, "7.7.7.7", 50060);
598 status = test_resolve("standard SRV resolution with explicit transport (TCP)", pool, PJSIP_TRANSPORT_TCP, "domain.com", 0, &ref);
599 if (status != PJ_SUCCESS)
600 return -160;
601 }
602
603
604 /* Round robin/load balance test */
605 if (round_robin_test(pool) != 0)
606 return -170;
607
608 /* Timeout test */
609 {
610 status = test_resolve("timeout test", pool, PJSIP_TRANSPORT_UNSPECIFIED, "an.invalid.address", 0, NULL);
611 if (status == PJ_SUCCESS)
612 return -150;
613 }
614
615 return 0;
616}
617