~ubuntu-branches/ubuntu/vivid/sflphone/vivid

« 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): Mark Purcell
  • Date: 2013-06-30 11:40:56 UTC
  • mfrom: (4.1.18 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130630114056-0np50jkyqo6vnmii
Tags: 1.2.3-2
* changeset_r92d62cfc54732bbbcfff2b1d36c096b120b981a5.diff 
  - fixes automatic endian detection 
* Update Vcs: fixes vcs-field-not-canonical

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