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

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.1.0/pjlib/src/pjlib-test/sock.c

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (1.1.11)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: package-import@ubuntu.com-20140128182336-3xenud1kbnwmf3mz
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: sock.c 3841 2011-10-24 09:28:13Z ming $ */
 
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 <pjlib.h>
 
21
#include "test.h"
 
22
 
 
23
 
 
24
/**
 
25
 * \page page_pjlib_sock_test Test: Socket
 
26
 *
 
27
 * This file provides implementation of \b sock_test(). It tests the
 
28
 * various aspects of the socket API.
 
29
 *
 
30
 * \section sock_test_scope_sec Scope of the Test
 
31
 *
 
32
 * The scope of the test:
 
33
 *  - verify the validity of the address structs.
 
34
 *  - verify that address manipulation API works.
 
35
 *  - simple socket creation and destruction.
 
36
 *  - simple socket send/recv and sendto/recvfrom.
 
37
 *  - UDP connect()
 
38
 *  - send/recv big data.
 
39
 *  - all for both UDP and TCP.
 
40
 *
 
41
 * The APIs tested in this test:
 
42
 *  - pj_inet_aton()
 
43
 *  - pj_inet_ntoa()
 
44
 *  - pj_inet_pton()  (only if IPv6 is enabled)
 
45
 *  - pj_inet_ntop()  (only if IPv6 is enabled)
 
46
 *  - pj_gethostname()
 
47
 *  - pj_sock_socket()
 
48
 *  - pj_sock_close()
 
49
 *  - pj_sock_send()
 
50
 *  - pj_sock_sendto()
 
51
 *  - pj_sock_recv()
 
52
 *  - pj_sock_recvfrom()
 
53
 *  - pj_sock_bind()
 
54
 *  - pj_sock_connect()
 
55
 *  - pj_sock_listen()
 
56
 *  - pj_sock_accept()
 
57
 *  - pj_gethostbyname()
 
58
 *
 
59
 *
 
60
 * This file is <b>pjlib-test/sock.c</b>
 
61
 *
 
62
 * \include pjlib-test/sock.c
 
63
 */
 
64
 
 
65
#if INCLUDE_SOCK_TEST
 
66
 
 
67
#define UDP_PORT        51234
 
68
#define TCP_PORT        (UDP_PORT+10)
 
69
#define BIG_DATA_LEN    8192
 
70
#define ADDRESS         "127.0.0.1"
 
71
 
 
72
static char bigdata[BIG_DATA_LEN];
 
73
static char bigbuffer[BIG_DATA_LEN];
 
74
 
 
75
/* Macro for checking the value of "sin_len" member of sockaddr
 
76
 * (it must always be zero).
 
77
 */
 
78
#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0
 
79
#   define CHECK_SA_ZERO_LEN(addr, ret) \
 
80
        if (((pj_addr_hdr*)(addr))->sa_zero_len != 0) \
 
81
            return ret
 
82
#else
 
83
#   define CHECK_SA_ZERO_LEN(addr, ret)
 
84
#endif
 
85
 
 
86
 
 
87
static int format_test(void)
 
88
{
 
89
    pj_str_t s = pj_str(ADDRESS);
 
90
    unsigned char *p;
 
91
    pj_in_addr addr;
 
92
    char zero[64];
 
93
    pj_sockaddr_in addr2;
 
94
    const pj_str_t *hostname;
 
95
    const unsigned char A[] = {127, 0, 0, 1};
 
96
 
 
97
    PJ_LOG(3,("test", "...format_test()"));
 
98
    
 
99
    /* pj_inet_aton() */
 
100
    if (pj_inet_aton(&s, &addr) != 1)
 
101
        return -10;
 
102
    
 
103
    /* Check the result. */
 
104
    p = (unsigned char*)&addr;
 
105
    if (p[0]!=A[0] || p[1]!=A[1] || p[2]!=A[2] || p[3]!=A[3]) {
 
106
        PJ_LOG(3,("test", "  error: mismatched address. p0=%d, p1=%d, "
 
107
                          "p2=%d, p3=%d", p[0] & 0xFF, p[1] & 0xFF, 
 
108
                           p[2] & 0xFF, p[3] & 0xFF));
 
109
        return -15;
 
110
    }
 
111
 
 
112
    /* pj_inet_ntoa() */
 
113
    p = (unsigned char*) pj_inet_ntoa(addr);
 
114
    if (!p)
 
115
        return -20;
 
116
 
 
117
    if (pj_strcmp2(&s, (char*)p) != 0)
 
118
        return -22;
 
119
 
 
120
#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6!=0
 
121
    /* pj_inet_pton() */
 
122
    /* pj_inet_ntop() */
 
123
    {
 
124
        const pj_str_t s_ipv4 = pj_str("127.0.0.1");
 
125
        const pj_str_t s_ipv6 = pj_str("fe80::2ff:83ff:fe7c:8b42");
 
126
        char buf_ipv4[PJ_INET_ADDRSTRLEN];
 
127
        char buf_ipv6[PJ_INET6_ADDRSTRLEN];
 
128
        pj_in_addr ipv4;
 
129
        pj_in6_addr ipv6;
 
130
 
 
131
        if (pj_inet_pton(pj_AF_INET(), &s_ipv4, &ipv4) != PJ_SUCCESS)
 
132
            return -24;
 
133
 
 
134
        p = (unsigned char*)&ipv4;
 
135
        if (p[0]!=A[0] || p[1]!=A[1] || p[2]!=A[2] || p[3]!=A[3]) {
 
136
            return -25;
 
137
        }
 
138
 
 
139
        if (pj_inet_pton(pj_AF_INET6(), &s_ipv6, &ipv6) != PJ_SUCCESS)
 
140
            return -26;
 
141
 
 
142
        p = (unsigned char*)&ipv6;
 
143
        if (p[0] != 0xfe || p[1] != 0x80 || p[2] != 0 || p[3] != 0 ||
 
144
            p[4] != 0 || p[5] != 0 || p[6] != 0 || p[7] != 0 ||
 
145
            p[8] != 0x02 || p[9] != 0xff || p[10] != 0x83 || p[11] != 0xff ||
 
146
            p[12]!=0xfe || p[13]!=0x7c || p[14] != 0x8b || p[15]!=0x42)
 
147
        {
 
148
            return -27;
 
149
        }
 
150
 
 
151
        if (pj_inet_ntop(pj_AF_INET(), &ipv4, buf_ipv4, sizeof(buf_ipv4)) != PJ_SUCCESS)
 
152
            return -28;
 
153
        if (pj_stricmp2(&s_ipv4, buf_ipv4) != 0)
 
154
            return -29;
 
155
 
 
156
        if (pj_inet_ntop(pj_AF_INET6(), &ipv6, buf_ipv6, sizeof(buf_ipv6)) != PJ_SUCCESS)
 
157
            return -30;
 
158
        if (pj_stricmp2(&s_ipv6, buf_ipv6) != 0)
 
159
            return -31;
 
160
    }
 
161
 
 
162
#endif  /* PJ_HAS_IPV6 */
 
163
 
 
164
    /* Test that pj_sockaddr_in_init() initialize the whole structure, 
 
165
     * including sin_zero.
 
166
     */
 
167
    pj_sockaddr_in_init(&addr2, 0, 1000);
 
168
    pj_bzero(zero, sizeof(zero));
 
169
    if (pj_memcmp(addr2.sin_zero, zero, sizeof(addr2.sin_zero)) != 0)
 
170
        return -35;
 
171
 
 
172
    /* pj_gethostname() */
 
173
    hostname = pj_gethostname();
 
174
    if (!hostname || !hostname->ptr || !hostname->slen)
 
175
        return -40;
 
176
 
 
177
    PJ_LOG(3,("test", "....hostname is %.*s", 
 
178
              (int)hostname->slen, hostname->ptr));
 
179
 
 
180
    /* pj_gethostaddr() */
 
181
 
 
182
    /* Various constants */
 
183
#if !defined(PJ_SYMBIAN) || PJ_SYMBIAN==0
 
184
    if (PJ_AF_INET==0xFFFF) return -5500;
 
185
    if (PJ_AF_INET6==0xFFFF) return -5501;
 
186
    
 
187
    /* 0xFFFF could be a valid SOL_SOCKET (e.g: on some Win or Mac) */
 
188
    //if (PJ_SOL_SOCKET==0xFFFF) return -5503;
 
189
    
 
190
    if (PJ_SOL_IP==0xFFFF) return -5502;
 
191
    if (PJ_SOL_TCP==0xFFFF) return -5510;
 
192
    if (PJ_SOL_UDP==0xFFFF) return -5520;
 
193
    if (PJ_SOL_IPV6==0xFFFF) return -5530;
 
194
 
 
195
    if (PJ_SO_TYPE==0xFFFF) return -5540;
 
196
    if (PJ_SO_RCVBUF==0xFFFF) return -5550;
 
197
    if (PJ_SO_SNDBUF==0xFFFF) return -5560;
 
198
    if (PJ_TCP_NODELAY==0xFFFF) return -5570;
 
199
    if (PJ_SO_REUSEADDR==0xFFFF) return -5580;
 
200
 
 
201
    if (PJ_MSG_OOB==0xFFFF) return -5590;
 
202
    if (PJ_MSG_PEEK==0xFFFF) return -5600;
 
203
#endif
 
204
 
 
205
    return 0;
 
206
}
 
207
 
 
208
static int parse_test(void)
 
209
{
 
210
#define IPv4    1
 
211
#define IPv6    2
 
212
 
 
213
    struct test_t {
 
214
        const char  *input;
 
215
        int          result_af;
 
216
        const char  *result_ip;
 
217
        pj_uint16_t  result_port;
 
218
    };
 
219
    struct test_t valid_tests[] = 
 
220
    {
 
221
        /* IPv4 */
 
222
        { "10.0.0.1:80", IPv4, "10.0.0.1", 80},
 
223
        { "10.0.0.1", IPv4, "10.0.0.1", 0},
 
224
        { "10.0.0.1:", IPv4, "10.0.0.1", 0},
 
225
        { "10.0.0.1:0", IPv4, "10.0.0.1", 0},
 
226
        { ":80", IPv4, "0.0.0.0", 80},
 
227
        { ":", IPv4, "0.0.0.0", 0},
 
228
#if !PJ_SYMBIAN
 
229
        { "localhost", IPv4, "127.0.0.1", 0},
 
230
        { "localhost:", IPv4, "127.0.0.1", 0},
 
231
        { "localhost:80", IPv4, "127.0.0.1", 80},
 
232
#endif
 
233
 
 
234
#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6
 
235
        { "fe::01:80", IPv6, "fe::01:80", 0},
 
236
        { "[fe::01]:80", IPv6, "fe::01", 80},
 
237
        { "fe::01", IPv6, "fe::01", 0},
 
238
        { "[fe::01]", IPv6, "fe::01", 0},
 
239
        { "fe::01:", IPv6, "fe::01", 0},
 
240
        { "[fe::01]:", IPv6, "fe::01", 0},
 
241
        { "::", IPv6, "::0", 0},
 
242
        { "[::]", IPv6, "::", 0},
 
243
        { ":::", IPv6, "::", 0},
 
244
        { "[::]:", IPv6, "::", 0},
 
245
        { ":::80", IPv6, "::", 80},
 
246
        { "[::]:80", IPv6, "::", 80},
 
247
#endif
 
248
    };
 
249
    struct test_t invalid_tests[] = 
 
250
    {
 
251
        /* IPv4 */
 
252
        { "10.0.0.1:abcd", IPv4},   /* port not numeric */
 
253
        { "10.0.0.1:-1", IPv4},     /* port contains illegal character */
 
254
        { "10.0.0.1:123456", IPv4}, /* port too big     */
 
255
        { "1.2.3.4.5:80", IPv4},    /* invalid IP */
 
256
        { "10:0:80", IPv4},         /* hostname has colon */
 
257
 
 
258
#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6
 
259
        { "[fe::01]:abcd", IPv6},   /* port not numeric */
 
260
        { "[fe::01]:-1", IPv6},     /* port contains illegal character */
 
261
        { "[fe::01]:123456", IPv6}, /* port too big     */
 
262
        { "fe::01:02::03:04:80", IPv6},     /* invalid IP */
 
263
        { "[fe::01:02::03:04]:80", IPv6},   /* invalid IP */
 
264
        { "[fe:01", IPv6},          /* Unterminated bracket */
 
265
#endif
 
266
    };
 
267
 
 
268
    unsigned i;
 
269
 
 
270
    PJ_LOG(3,("test", "...IP address parsing"));
 
271
 
 
272
    for (i=0; i<PJ_ARRAY_SIZE(valid_tests); ++i) {
 
273
        pj_status_t status;
 
274
        pj_str_t input;
 
275
        pj_sockaddr addr, result;
 
276
 
 
277
        switch (valid_tests[i].result_af) {
 
278
        case IPv4:
 
279
            valid_tests[i].result_af = PJ_AF_INET;
 
280
            break;
 
281
        case IPv6:
 
282
            valid_tests[i].result_af = PJ_AF_INET6;
 
283
            break;
 
284
        default:
 
285
            pj_assert(!"Invalid AF!");
 
286
            continue;
 
287
        }
 
288
 
 
289
        /* Try parsing with PJ_AF_UNSPEC */
 
290
        status = pj_sockaddr_parse(PJ_AF_UNSPEC, 0, 
 
291
                                   pj_cstr(&input, valid_tests[i].input), 
 
292
                                   &addr);
 
293
        if (status != PJ_SUCCESS) {
 
294
            PJ_LOG(1,("test", ".... failed when parsing %s (i=%d)", 
 
295
                      valid_tests[i].input, i));
 
296
            return -10;
 
297
        }
 
298
 
 
299
        /* Check "sin_len" member of parse result */
 
300
        CHECK_SA_ZERO_LEN(&addr, -20);
 
301
 
 
302
        /* Build the correct result */
 
303
        status = pj_sockaddr_init(valid_tests[i].result_af,
 
304
                                  &result,
 
305
                                  pj_cstr(&input, valid_tests[i].result_ip), 
 
306
                                  valid_tests[i].result_port);
 
307
        if (status != PJ_SUCCESS) {
 
308
            PJ_LOG(1,("test", ".... error building IP address %s", 
 
309
                      valid_tests[i].input));
 
310
            return -30;
 
311
        }
 
312
 
 
313
        /* Compare the result */
 
314
        if (pj_sockaddr_cmp(&addr, &result) != 0) {
 
315
            PJ_LOG(1,("test", ".... parsed result mismatched for %s", 
 
316
                      valid_tests[i].input));
 
317
            return -40;
 
318
        }
 
319
 
 
320
        /* Parse again with the specified af */
 
321
        status = pj_sockaddr_parse(valid_tests[i].result_af, 0, 
 
322
                                   pj_cstr(&input, valid_tests[i].input), 
 
323
                                   &addr);
 
324
        if (status != PJ_SUCCESS) {
 
325
            PJ_LOG(1,("test", ".... failed when parsing %s", 
 
326
                      valid_tests[i].input));
 
327
            return -50;
 
328
        }
 
329
 
 
330
        /* Check "sin_len" member of parse result */
 
331
        CHECK_SA_ZERO_LEN(&addr, -55);
 
332
 
 
333
        /* Compare the result again */
 
334
        if (pj_sockaddr_cmp(&addr, &result) != 0) {
 
335
            PJ_LOG(1,("test", ".... parsed result mismatched for %s", 
 
336
                      valid_tests[i].input));
 
337
            return -60;
 
338
        }
 
339
    }
 
340
 
 
341
    for (i=0; i<PJ_ARRAY_SIZE(invalid_tests); ++i) {
 
342
        pj_status_t status;
 
343
        pj_str_t input;
 
344
        pj_sockaddr addr;
 
345
 
 
346
        switch (invalid_tests[i].result_af) {
 
347
        case IPv4:
 
348
            invalid_tests[i].result_af = PJ_AF_INET;
 
349
            break;
 
350
        case IPv6:
 
351
            invalid_tests[i].result_af = PJ_AF_INET6;
 
352
            break;
 
353
        default:
 
354
            pj_assert(!"Invalid AF!");
 
355
            continue;
 
356
        }
 
357
 
 
358
        /* Try parsing with PJ_AF_UNSPEC */
 
359
        status = pj_sockaddr_parse(PJ_AF_UNSPEC, 0, 
 
360
                                   pj_cstr(&input, invalid_tests[i].input), 
 
361
                                   &addr);
 
362
        if (status == PJ_SUCCESS) {
 
363
            PJ_LOG(1,("test", ".... expecting failure when parsing %s", 
 
364
                      invalid_tests[i].input));
 
365
            return -100;
 
366
        }
 
367
    }
 
368
 
 
369
    return 0;
 
370
}
 
371
 
 
372
static int purity_test(void)
 
373
{
 
374
    PJ_LOG(3,("test", "...purity_test()"));
 
375
 
 
376
#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0
 
377
    /* Check on "sin_len" member of sockaddr */
 
378
    {
 
379
        const pj_str_t str_ip = {"1.1.1.1", 7};
 
380
        pj_sockaddr addr[16];
 
381
        pj_addrinfo ai[16];
 
382
        unsigned cnt;
 
383
        pj_status_t rc;
 
384
 
 
385
        /* pj_enum_ip_interface() */
 
386
        cnt = PJ_ARRAY_SIZE(addr);
 
387
        rc = pj_enum_ip_interface(pj_AF_UNSPEC(), &cnt, addr);
 
388
        if (rc == PJ_SUCCESS) {
 
389
            while (cnt--)
 
390
                CHECK_SA_ZERO_LEN(&addr[cnt], -10);
 
391
        }
 
392
 
 
393
        /* pj_gethostip() on IPv4 */
 
394
        rc = pj_gethostip(pj_AF_INET(), &addr[0]);
 
395
        if (rc == PJ_SUCCESS)
 
396
            CHECK_SA_ZERO_LEN(&addr[0], -20);
 
397
 
 
398
        /* pj_gethostip() on IPv6 */
 
399
        rc = pj_gethostip(pj_AF_INET6(), &addr[0]);
 
400
        if (rc == PJ_SUCCESS)
 
401
            CHECK_SA_ZERO_LEN(&addr[0], -30);
 
402
 
 
403
        /* pj_getdefaultipinterface() on IPv4 */
 
404
        rc = pj_getdefaultipinterface(pj_AF_INET(), &addr[0]);
 
405
        if (rc == PJ_SUCCESS)
 
406
            CHECK_SA_ZERO_LEN(&addr[0], -40);
 
407
 
 
408
        /* pj_getdefaultipinterface() on IPv6 */
 
409
        rc = pj_getdefaultipinterface(pj_AF_INET6(), &addr[0]);
 
410
        if (rc == PJ_SUCCESS)
 
411
            CHECK_SA_ZERO_LEN(&addr[0], -50);
 
412
 
 
413
        /* pj_getaddrinfo() on a host name */
 
414
        cnt = PJ_ARRAY_SIZE(ai);
 
415
        rc = pj_getaddrinfo(pj_AF_UNSPEC(), pj_gethostname(), &cnt, ai);
 
416
        if (rc == PJ_SUCCESS) {
 
417
            while (cnt--)
 
418
                CHECK_SA_ZERO_LEN(&ai[cnt].ai_addr, -60);
 
419
        }
 
420
 
 
421
        /* pj_getaddrinfo() on an IP address */
 
422
        cnt = PJ_ARRAY_SIZE(ai);
 
423
        rc = pj_getaddrinfo(pj_AF_UNSPEC(), &str_ip, &cnt, ai);
 
424
        if (rc == PJ_SUCCESS) {
 
425
            pj_assert(cnt == 1);
 
426
            CHECK_SA_ZERO_LEN(&ai[0].ai_addr, -70);
 
427
        }
 
428
    }
 
429
#endif
 
430
 
 
431
    return 0;
 
432
}
 
433
 
 
434
static int simple_sock_test(void)
 
435
{
 
436
    int types[2];
 
437
    pj_sock_t sock;
 
438
    int i;
 
439
    pj_status_t rc = PJ_SUCCESS;
 
440
 
 
441
    types[0] = pj_SOCK_STREAM();
 
442
    types[1] = pj_SOCK_DGRAM();
 
443
 
 
444
    PJ_LOG(3,("test", "...simple_sock_test()"));
 
445
 
 
446
    for (i=0; i<(int)(sizeof(types)/sizeof(types[0])); ++i) {
 
447
        
 
448
        rc = pj_sock_socket(pj_AF_INET(), types[i], 0, &sock);
 
449
        if (rc != PJ_SUCCESS) {
 
450
            app_perror("...error: unable to create socket", rc);
 
451
            break;
 
452
        } else {
 
453
            rc = pj_sock_close(sock);
 
454
            if (rc != 0) {
 
455
                app_perror("...error: close socket", rc);
 
456
                break;
 
457
            }
 
458
        }
 
459
    }
 
460
    return rc;
 
461
}
 
462
 
 
463
 
 
464
static int send_recv_test(int sock_type,
 
465
                          pj_sock_t ss, pj_sock_t cs,
 
466
                          pj_sockaddr_in *dstaddr, pj_sockaddr_in *srcaddr, 
 
467
                          int addrlen)
 
468
{
 
469
    enum { DATA_LEN = 16 };
 
470
    char senddata[DATA_LEN+4], recvdata[DATA_LEN+4];
 
471
    pj_ssize_t sent, received, total_received;
 
472
    pj_status_t rc;
 
473
 
 
474
    TRACE_(("test", "....create_random_string()"));
 
475
    pj_create_random_string(senddata, DATA_LEN);
 
476
    senddata[DATA_LEN-1] = '\0';
 
477
 
 
478
    /*
 
479
     * Test send/recv small data.
 
480
     */
 
481
    TRACE_(("test", "....sendto()"));
 
482
    if (dstaddr) {
 
483
        sent = DATA_LEN;
 
484
        rc = pj_sock_sendto(cs, senddata, &sent, 0, dstaddr, addrlen);
 
485
        if (rc != PJ_SUCCESS || sent != DATA_LEN) {
 
486
            app_perror("...sendto error", rc);
 
487
            rc = -140; goto on_error;
 
488
        }
 
489
    } else {
 
490
        sent = DATA_LEN;
 
491
        rc = pj_sock_send(cs, senddata, &sent, 0);
 
492
        if (rc != PJ_SUCCESS || sent != DATA_LEN) {
 
493
            app_perror("...send error", rc);
 
494
            rc = -145; goto on_error;
 
495
        }
 
496
    }
 
497
 
 
498
    TRACE_(("test", "....recv()"));
 
499
    if (srcaddr) {
 
500
        pj_sockaddr_in addr;
 
501
        int srclen = sizeof(addr);
 
502
        
 
503
        pj_bzero(&addr, sizeof(addr));
 
504
 
 
505
        received = DATA_LEN;
 
506
        rc = pj_sock_recvfrom(ss, recvdata, &received, 0, &addr, &srclen);
 
507
        if (rc != PJ_SUCCESS || received != DATA_LEN) {
 
508
            app_perror("...recvfrom error", rc);
 
509
            rc = -150; goto on_error;
 
510
        }
 
511
        if (srclen != addrlen)
 
512
            return -151;
 
513
        if (pj_sockaddr_cmp(&addr, srcaddr) != 0) {
 
514
            char srcaddr_str[32], addr_str[32];
 
515
            strcpy(srcaddr_str, pj_inet_ntoa(srcaddr->sin_addr));
 
516
            strcpy(addr_str, pj_inet_ntoa(addr.sin_addr));
 
517
            PJ_LOG(3,("test", "...error: src address mismatch (original=%s, "
 
518
                              "recvfrom addr=%s)", 
 
519
                              srcaddr_str, addr_str));
 
520
            return -152;
 
521
        }
 
522
        
 
523
    } else {
 
524
        /* Repeat recv() until all data is received.
 
525
         * This applies only for non-UDP of course, since for UDP
 
526
         * we would expect all data to be received in one packet.
 
527
         */
 
528
        total_received = 0;
 
529
        do {
 
530
            received = DATA_LEN-total_received;
 
531
            rc = pj_sock_recv(ss, recvdata+total_received, &received, 0);
 
532
            if (rc != PJ_SUCCESS) {
 
533
                app_perror("...recv error", rc);
 
534
                rc = -155; goto on_error;
 
535
            }
 
536
            if (received <= 0) {
 
537
                PJ_LOG(3,("", "...error: socket has closed! (received=%d)",
 
538
                          received));
 
539
                rc = -156; goto on_error;
 
540
            }
 
541
            if (received != DATA_LEN-total_received) {
 
542
                if (sock_type != pj_SOCK_STREAM()) {
 
543
                    PJ_LOG(3,("", "...error: expecting %u bytes, got %u bytes",
 
544
                              DATA_LEN-total_received, received));
 
545
                    rc = -157; goto on_error;
 
546
                }
 
547
            }
 
548
            total_received += received;
 
549
        } while (total_received < DATA_LEN);
 
550
    }
 
551
 
 
552
    TRACE_(("test", "....memcmp()"));
 
553
    if (pj_memcmp(senddata, recvdata, DATA_LEN) != 0) {
 
554
        PJ_LOG(3,("","...error: received data mismatch "
 
555
                     "(got:'%s' expecting:'%s'",
 
556
                     recvdata, senddata));
 
557
        rc = -160; goto on_error;
 
558
    }
 
559
 
 
560
    /*
 
561
     * Test send/recv big data.
 
562
     */
 
563
    TRACE_(("test", "....sendto()"));
 
564
    if (dstaddr) {
 
565
        sent = BIG_DATA_LEN;
 
566
        rc = pj_sock_sendto(cs, bigdata, &sent, 0, dstaddr, addrlen);
 
567
        if (rc != PJ_SUCCESS || sent != BIG_DATA_LEN) {
 
568
            app_perror("...sendto error", rc);
 
569
            rc = -161; goto on_error;
 
570
        }
 
571
    } else {
 
572
        sent = BIG_DATA_LEN;
 
573
        rc = pj_sock_send(cs, bigdata, &sent, 0);
 
574
        if (rc != PJ_SUCCESS || sent != BIG_DATA_LEN) {
 
575
            app_perror("...send error", rc);
 
576
            rc = -165; goto on_error;
 
577
        }
 
578
    }
 
579
 
 
580
    TRACE_(("test", "....recv()"));
 
581
 
 
582
    /* Repeat recv() until all data is received.
 
583
     * This applies only for non-UDP of course, since for UDP
 
584
     * we would expect all data to be received in one packet.
 
585
     */
 
586
    total_received = 0;
 
587
    do {
 
588
        received = BIG_DATA_LEN-total_received;
 
589
        rc = pj_sock_recv(ss, bigbuffer+total_received, &received, 0);
 
590
        if (rc != PJ_SUCCESS) {
 
591
            app_perror("...recv error", rc);
 
592
            rc = -170; goto on_error;
 
593
        }
 
594
        if (received <= 0) {
 
595
            PJ_LOG(3,("", "...error: socket has closed! (received=%d)",
 
596
                      received));
 
597
            rc = -173; goto on_error;
 
598
        }
 
599
        if (received != BIG_DATA_LEN-total_received) {
 
600
            if (sock_type != pj_SOCK_STREAM()) {
 
601
                PJ_LOG(3,("", "...error: expecting %u bytes, got %u bytes",
 
602
                          BIG_DATA_LEN-total_received, received));
 
603
                rc = -176; goto on_error;
 
604
            }
 
605
        }
 
606
        total_received += received;
 
607
    } while (total_received < BIG_DATA_LEN);
 
608
 
 
609
    TRACE_(("test", "....memcmp()"));
 
610
    if (pj_memcmp(bigdata, bigbuffer, BIG_DATA_LEN) != 0) {
 
611
        PJ_LOG(3,("", "...error: received data has been altered!"));
 
612
        rc = -180; goto on_error;
 
613
    }
 
614
    
 
615
    rc = 0;
 
616
 
 
617
on_error:
 
618
    return rc;
 
619
}
 
620
 
 
621
static int udp_test(void)
 
622
{
 
623
    pj_sock_t cs = PJ_INVALID_SOCKET, ss = PJ_INVALID_SOCKET;
 
624
    pj_sockaddr_in dstaddr, srcaddr;
 
625
    pj_str_t s;
 
626
    pj_status_t rc = 0, retval;
 
627
 
 
628
    PJ_LOG(3,("test", "...udp_test()"));
 
629
 
 
630
    rc = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &ss);
 
631
    if (rc != 0) {
 
632
        app_perror("...error: unable to create socket", rc);
 
633
        return -100;
 
634
    }
 
635
 
 
636
    rc = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &cs);
 
637
    if (rc != 0)
 
638
        return -110;
 
639
 
 
640
    /* Bind server socket. */
 
641
    pj_bzero(&dstaddr, sizeof(dstaddr));
 
642
    dstaddr.sin_family = pj_AF_INET();
 
643
    dstaddr.sin_port = pj_htons(UDP_PORT);
 
644
    dstaddr.sin_addr = pj_inet_addr(pj_cstr(&s, ADDRESS));
 
645
    
 
646
    if ((rc=pj_sock_bind(ss, &dstaddr, sizeof(dstaddr))) != 0) {
 
647
        app_perror("...bind error udp:"ADDRESS, rc);
 
648
        rc = -120; goto on_error;
 
649
    }
 
650
 
 
651
    /* Bind client socket. */
 
652
    pj_bzero(&srcaddr, sizeof(srcaddr));
 
653
    srcaddr.sin_family = pj_AF_INET();
 
654
    srcaddr.sin_port = pj_htons(UDP_PORT-1);
 
655
    srcaddr.sin_addr = pj_inet_addr(pj_cstr(&s, ADDRESS));
 
656
 
 
657
    if ((rc=pj_sock_bind(cs, &srcaddr, sizeof(srcaddr))) != 0) {
 
658
        app_perror("...bind error", rc);
 
659
        rc = -121; goto on_error;
 
660
    }
 
661
            
 
662
    /* Test send/recv, with sendto */
 
663
    rc = send_recv_test(pj_SOCK_DGRAM(), ss, cs, &dstaddr, NULL, 
 
664
                        sizeof(dstaddr));
 
665
    if (rc != 0)
 
666
        goto on_error;
 
667
 
 
668
    /* Test send/recv, with sendto and recvfrom */
 
669
    rc = send_recv_test(pj_SOCK_DGRAM(), ss, cs, &dstaddr, 
 
670
                        &srcaddr, sizeof(dstaddr));
 
671
    if (rc != 0)
 
672
        goto on_error;
 
673
 
 
674
    /* Disable this test on Symbian since UDP connect()/send() failed
 
675
     * with S60 3rd edition (including MR2).
 
676
     * See http://www.pjsip.org/trac/ticket/264
 
677
     */    
 
678
#if !defined(PJ_SYMBIAN) || PJ_SYMBIAN==0
 
679
    /* connect() the sockets. */
 
680
    rc = pj_sock_connect(cs, &dstaddr, sizeof(dstaddr));
 
681
    if (rc != 0) {
 
682
        app_perror("...connect() error", rc);
 
683
        rc = -122; goto on_error;
 
684
    }
 
685
 
 
686
    /* Test send/recv with send() */
 
687
    rc = send_recv_test(pj_SOCK_DGRAM(), ss, cs, NULL, NULL, 0);
 
688
    if (rc != 0)
 
689
        goto on_error;
 
690
 
 
691
    /* Test send/recv with send() and recvfrom */
 
692
    rc = send_recv_test(pj_SOCK_DGRAM(), ss, cs, NULL, &srcaddr, 
 
693
                        sizeof(srcaddr));
 
694
    if (rc != 0)
 
695
        goto on_error;
 
696
#endif
 
697
 
 
698
on_error:
 
699
    retval = rc;
 
700
    if (cs != PJ_INVALID_SOCKET) {
 
701
        rc = pj_sock_close(cs);
 
702
        if (rc != PJ_SUCCESS) {
 
703
            app_perror("...error in closing socket", rc);
 
704
            return -1000;
 
705
        }
 
706
    }
 
707
    if (ss != PJ_INVALID_SOCKET) {
 
708
        rc = pj_sock_close(ss);
 
709
        if (rc != PJ_SUCCESS) {
 
710
            app_perror("...error in closing socket", rc);
 
711
            return -1010;
 
712
        }
 
713
    }
 
714
 
 
715
    return retval;
 
716
}
 
717
 
 
718
static int tcp_test(void)
 
719
{
 
720
    pj_sock_t cs, ss;
 
721
    pj_status_t rc = 0, retval;
 
722
 
 
723
    PJ_LOG(3,("test", "...tcp_test()"));
 
724
 
 
725
    rc = app_socketpair(pj_AF_INET(), pj_SOCK_STREAM(), 0, &ss, &cs);
 
726
    if (rc != PJ_SUCCESS) {
 
727
        app_perror("...error: app_socketpair():", rc);
 
728
        return -2000;
 
729
    }
 
730
 
 
731
    /* Test send/recv with send() and recv() */
 
732
    retval = send_recv_test(pj_SOCK_STREAM(), ss, cs, NULL, NULL, 0);
 
733
 
 
734
    rc = pj_sock_close(cs);
 
735
    if (rc != PJ_SUCCESS) {
 
736
        app_perror("...error in closing socket", rc);
 
737
        return -2000;
 
738
    }
 
739
 
 
740
    rc = pj_sock_close(ss);
 
741
    if (rc != PJ_SUCCESS) {
 
742
        app_perror("...error in closing socket", rc);
 
743
        return -2010;
 
744
    }
 
745
 
 
746
    return retval;
 
747
}
 
748
 
 
749
static int ioctl_test(void)
 
750
{
 
751
    return 0;
 
752
}
 
753
 
 
754
static int gethostbyname_test(void)
 
755
{
 
756
    pj_str_t host;
 
757
    pj_hostent he;
 
758
    pj_status_t status;
 
759
 
 
760
    /* Testing pj_gethostbyname() with invalid host */
 
761
    host = pj_str("an-invalid-host-name");
 
762
    status = pj_gethostbyname(&host, &he);
 
763
 
 
764
    /* Must return failure! */
 
765
    if (status == PJ_SUCCESS)
 
766
        return -20100;
 
767
    else
 
768
        return 0;
 
769
}
 
770
 
 
771
#if 0
 
772
#include "../pj/os_symbian.h"
 
773
static int connect_test()
 
774
{
 
775
        RSocketServ rSockServ;
 
776
        RSocket rSock;
 
777
        TInetAddr inetAddr;
 
778
        TRequestStatus reqStatus;
 
779
        char buffer[16];
 
780
        TPtrC8 data((const TUint8*)buffer, (TInt)sizeof(buffer));
 
781
        int rc;
 
782
        
 
783
        rc = rSockServ.Connect();
 
784
        if (rc != KErrNone)
 
785
                return rc;
 
786
        
 
787
        rc = rSock.Open(rSockServ, KAfInet, KSockDatagram, KProtocolInetUdp);
 
788
        if (rc != KErrNone) 
 
789
        {               
 
790
                rSockServ.Close();
 
791
                return rc;
 
792
        }
 
793
        
 
794
        inetAddr.Init(KAfInet);
 
795
        inetAddr.Input(_L("127.0.0.1"));
 
796
        inetAddr.SetPort(80);
 
797
        
 
798
        rSock.Connect(inetAddr, reqStatus);
 
799
        User::WaitForRequest(reqStatus);
 
800
 
 
801
        if (reqStatus != KErrNone) {
 
802
                rSock.Close();
 
803
                rSockServ.Close();
 
804
                return rc;
 
805
        }
 
806
    
 
807
        rSock.Send(data, 0, reqStatus);
 
808
        User::WaitForRequest(reqStatus);
 
809
        
 
810
        if (reqStatus!=KErrNone) {
 
811
                rSock.Close();
 
812
                rSockServ.Close();
 
813
                return rc;
 
814
        }
 
815
        
 
816
        rSock.Close();
 
817
        rSockServ.Close();
 
818
        return KErrNone;
 
819
}
 
820
#endif
 
821
 
 
822
int sock_test()
 
823
{
 
824
    int rc;
 
825
    
 
826
    pj_create_random_string(bigdata, BIG_DATA_LEN);
 
827
 
 
828
// Enable this to demonstrate the error witn S60 3rd Edition MR2
 
829
#if 0
 
830
    rc = connect_test();
 
831
    if (rc != 0)
 
832
        return rc;
 
833
#endif
 
834
    
 
835
    rc = format_test();
 
836
    if (rc != 0)
 
837
        return rc;
 
838
 
 
839
    rc = parse_test();
 
840
    if (rc != 0)
 
841
        return rc;
 
842
 
 
843
    rc = purity_test();
 
844
    if (rc != 0)
 
845
        return rc;
 
846
 
 
847
    rc = gethostbyname_test();
 
848
    if (rc != 0)
 
849
        return rc;
 
850
 
 
851
    rc = simple_sock_test();
 
852
    if (rc != 0)
 
853
        return rc;
 
854
 
 
855
    rc = ioctl_test();
 
856
    if (rc != 0)
 
857
        return rc;
 
858
 
 
859
    rc = udp_test();
 
860
    if (rc != 0)
 
861
        return rc;
 
862
 
 
863
    rc = tcp_test();
 
864
    if (rc != 0)
 
865
        return rc;
 
866
 
 
867
    return 0;
 
868
}
 
869
 
 
870
 
 
871
#else
 
872
/* To prevent warning about "translation unit is empty"
 
873
 * when this test is disabled. 
 
874
 */
 
875
int dummy_sock_test;
 
876
#endif  /* INCLUDE_SOCK_TEST */
 
877