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