~ubuntu-branches/ubuntu/trusty/sflphone/trusty

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (4.3.4 sid)
  • Revision ID: package-import@ubuntu.com-20140128182336-jrsv0k9u6cawc068
Tags: 1.3.0-1
* 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 */