~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject/pjsip/src/test/dns_test.c

  • Committer: Package Import Robot
  • Author(s): Francois Marier
  • Date: 2011-11-25 13:24:12 UTC
  • mfrom: (4.1.10 sid)
  • Revision ID: package-import@ubuntu.com-20111125132412-dc4qvhyosk74cd42
Tags: 1.0.1-4
Don't assume that arch:all packages will get built (closes: #649726)

Show diffs side-by-side

added added

removed removed

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