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

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.1.0/pjlib/src/pj/sock_common.c

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2015-01-07 14:51:16 UTC
  • mfrom: (4.3.5 sid)
  • Revision ID: package-import@ubuntu.com-20150107145116-yxnafinf4lrdvrmx
Tags: 1.4.1-0.1ubuntu1
* Merge with Debian, remaining changes:
 - Drop soprano, nepomuk build-dep
* Drop ubuntu patches, now upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: sock_common.c 4343 2013-02-07 09:35:34Z 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 <pj/sock.h>
21
 
#include <pj/assert.h>
22
 
#include <pj/ctype.h>
23
 
#include <pj/errno.h>
24
 
#include <pj/ip_helper.h>
25
 
#include <pj/os.h>
26
 
#include <pj/addr_resolv.h>
27
 
#include <pj/rand.h>
28
 
#include <pj/string.h>
29
 
#include <pj/compat/socket.h>
30
 
 
31
 
#if 0
32
 
    /* Enable some tracing */
33
 
    #include <pj/log.h>
34
 
    #define THIS_FILE   "sock_common.c"
35
 
    #define TRACE_(arg) PJ_LOG(4,arg)
36
 
#else
37
 
    #define TRACE_(arg)
38
 
#endif
39
 
 
40
 
 
41
 
/*
42
 
 * Convert address string with numbers and dots to binary IP address.
43
 
 */ 
44
 
PJ_DEF(pj_in_addr) pj_inet_addr(const pj_str_t *cp)
45
 
{
46
 
    pj_in_addr addr;
47
 
 
48
 
    pj_inet_aton(cp, &addr);
49
 
    return addr;
50
 
}
51
 
 
52
 
/*
53
 
 * Convert address string with numbers and dots to binary IP address.
54
 
 */ 
55
 
PJ_DEF(pj_in_addr) pj_inet_addr2(const char *cp)
56
 
{
57
 
    pj_str_t str = pj_str((char*)cp);
58
 
    return pj_inet_addr(&str);
59
 
}
60
 
 
61
 
/*
62
 
 * Get text representation.
63
 
 */
64
 
PJ_DEF(char*) pj_inet_ntop2( int af, const void *src,
65
 
                             char *dst, int size)
66
 
{
67
 
    pj_status_t status;
68
 
 
69
 
    status = pj_inet_ntop(af, src, dst, size);
70
 
    return (status==PJ_SUCCESS)? dst : NULL;
71
 
}
72
 
 
73
 
/*
74
 
 * Print socket address.
75
 
 */
76
 
PJ_DEF(char*) pj_sockaddr_print( const pj_sockaddr_t *addr,
77
 
                                 char *buf, int size,
78
 
                                 unsigned flags)
79
 
{
80
 
    enum {
81
 
        WITH_PORT = 1,
82
 
        WITH_BRACKETS = 2
83
 
    };
84
 
 
85
 
    char txt[PJ_INET6_ADDRSTRLEN];
86
 
    char port[32];
87
 
    const pj_addr_hdr *h = (const pj_addr_hdr*)addr;
88
 
    char *bquote, *equote;
89
 
    pj_status_t status;
90
 
 
91
 
    status = pj_inet_ntop(h->sa_family, pj_sockaddr_get_addr(addr),
92
 
                          txt, sizeof(txt));
93
 
    if (status != PJ_SUCCESS)
94
 
        return "";
95
 
 
96
 
    if (h->sa_family != PJ_AF_INET6 || (flags & WITH_BRACKETS)==0) {
97
 
        bquote = ""; equote = "";
98
 
    } else {
99
 
        bquote = "["; equote = "]";
100
 
    }
101
 
 
102
 
    if (flags & WITH_PORT) {
103
 
        pj_ansi_snprintf(port, sizeof(port), ":%d",
104
 
                         pj_sockaddr_get_port(addr));
105
 
    } else {
106
 
        port[0] = '\0';
107
 
    }
108
 
 
109
 
    pj_ansi_snprintf(buf, size, "%s%s%s%s",
110
 
                     bquote, txt, equote, port);
111
 
 
112
 
    return buf;
113
 
}
114
 
 
115
 
/*
116
 
 * Set the IP address of an IP socket address from string address, 
117
 
 * with resolving the host if necessary. The string address may be in a
118
 
 * standard numbers and dots notation or may be a hostname. If hostname
119
 
 * is specified, then the function will resolve the host into the IP
120
 
 * address.
121
 
 */
122
 
PJ_DEF(pj_status_t) pj_sockaddr_in_set_str_addr( pj_sockaddr_in *addr,
123
 
                                                 const pj_str_t *str_addr)
124
 
{
125
 
    PJ_CHECK_STACK();
126
 
 
127
 
    PJ_ASSERT_RETURN(!str_addr || str_addr->slen < PJ_MAX_HOSTNAME, 
128
 
                     (addr->sin_addr.s_addr=PJ_INADDR_NONE, PJ_EINVAL));
129
 
 
130
 
    PJ_SOCKADDR_RESET_LEN(addr);
131
 
    addr->sin_family = AF_INET;
132
 
    pj_bzero(addr->sin_zero, sizeof(addr->sin_zero));
133
 
 
134
 
    if (str_addr && str_addr->slen) {
135
 
        addr->sin_addr = pj_inet_addr(str_addr);
136
 
        if (addr->sin_addr.s_addr == PJ_INADDR_NONE) {
137
 
            pj_hostent he;
138
 
            pj_status_t rc;
139
 
 
140
 
            rc = pj_gethostbyname(str_addr, &he);
141
 
            if (rc == 0) {
142
 
                addr->sin_addr.s_addr = *(pj_uint32_t*)he.h_addr;
143
 
            } else {
144
 
                addr->sin_addr.s_addr = PJ_INADDR_NONE;
145
 
                return rc;
146
 
            }
147
 
        }
148
 
 
149
 
    } else {
150
 
        addr->sin_addr.s_addr = 0;
151
 
    }
152
 
 
153
 
    return PJ_SUCCESS;
154
 
}
155
 
 
156
 
/* Set address from a name */
157
 
PJ_DEF(pj_status_t) pj_sockaddr_set_str_addr(int af,
158
 
                                             pj_sockaddr *addr,
159
 
                                             const pj_str_t *str_addr)
160
 
{
161
 
    pj_status_t status;
162
 
 
163
 
    if (af == PJ_AF_INET) {
164
 
        return pj_sockaddr_in_set_str_addr(&addr->ipv4, str_addr);
165
 
    }
166
 
 
167
 
    PJ_ASSERT_RETURN(af==PJ_AF_INET6, PJ_EAFNOTSUP);
168
 
 
169
 
    /* IPv6 specific */
170
 
 
171
 
    addr->ipv6.sin6_family = PJ_AF_INET6;
172
 
    PJ_SOCKADDR_RESET_LEN(addr);
173
 
 
174
 
    if (str_addr && str_addr->slen) {
175
 
        status = pj_inet_pton(PJ_AF_INET6, str_addr, &addr->ipv6.sin6_addr);
176
 
        if (status != PJ_SUCCESS) {
177
 
            pj_addrinfo ai;
178
 
            unsigned count = 1;
179
 
 
180
 
            status = pj_getaddrinfo(PJ_AF_INET6, str_addr, &count, &ai);
181
 
            if (status==PJ_SUCCESS) {
182
 
                pj_memcpy(&addr->ipv6.sin6_addr, &ai.ai_addr.ipv6.sin6_addr,
183
 
                          sizeof(pj_sockaddr_in6));
184
 
            }
185
 
        }
186
 
    } else {
187
 
        status = PJ_SUCCESS;
188
 
    }
189
 
 
190
 
    return status;
191
 
}
192
 
 
193
 
/*
194
 
 * Set the IP address and port of an IP socket address.
195
 
 * The string address may be in a standard numbers and dots notation or 
196
 
 * may be a hostname. If hostname is specified, then the function will 
197
 
 * resolve the host into the IP address.
198
 
 */
199
 
PJ_DEF(pj_status_t) pj_sockaddr_in_init( pj_sockaddr_in *addr,
200
 
                                         const pj_str_t *str_addr,
201
 
                                         pj_uint16_t port)
202
 
{
203
 
    PJ_ASSERT_RETURN(addr, (addr->sin_addr.s_addr=PJ_INADDR_NONE, PJ_EINVAL));
204
 
 
205
 
    PJ_SOCKADDR_RESET_LEN(addr);
206
 
    addr->sin_family = PJ_AF_INET;
207
 
    pj_bzero(addr->sin_zero, sizeof(addr->sin_zero));
208
 
    pj_sockaddr_in_set_port(addr, port);
209
 
    return pj_sockaddr_in_set_str_addr(addr, str_addr);
210
 
}
211
 
 
212
 
/*
213
 
 * Initialize IP socket address based on the address and port info.
214
 
 */
215
 
PJ_DEF(pj_status_t) pj_sockaddr_init(int af, 
216
 
                                     pj_sockaddr *addr,
217
 
                                     const pj_str_t *cp,
218
 
                                     pj_uint16_t port)
219
 
{
220
 
    pj_status_t status;
221
 
 
222
 
    if (af == PJ_AF_INET) {
223
 
        return pj_sockaddr_in_init(&addr->ipv4, cp, port);
224
 
    }
225
 
 
226
 
    /* IPv6 specific */
227
 
    PJ_ASSERT_RETURN(af==PJ_AF_INET6, PJ_EAFNOTSUP);
228
 
 
229
 
    pj_bzero(addr, sizeof(pj_sockaddr_in6));
230
 
    addr->addr.sa_family = PJ_AF_INET6;
231
 
    
232
 
    status = pj_sockaddr_set_str_addr(af, addr, cp);
233
 
    if (status != PJ_SUCCESS)
234
 
        return status;
235
 
 
236
 
    addr->ipv6.sin6_port = pj_htons(port);
237
 
    return PJ_SUCCESS;
238
 
}
239
 
 
240
 
/*
241
 
 * Compare two socket addresses.
242
 
 */
243
 
PJ_DEF(int) pj_sockaddr_cmp( const pj_sockaddr_t *addr1,
244
 
                             const pj_sockaddr_t *addr2)
245
 
{
246
 
    const pj_sockaddr *a1 = (const pj_sockaddr*) addr1;
247
 
    const pj_sockaddr *a2 = (const pj_sockaddr*) addr2;
248
 
    int port1, port2;
249
 
    int result;
250
 
 
251
 
    /* Compare address family */
252
 
    if (a1->addr.sa_family < a2->addr.sa_family)
253
 
        return -1;
254
 
    else if (a1->addr.sa_family > a2->addr.sa_family)
255
 
        return 1;
256
 
 
257
 
    /* Compare addresses */
258
 
    result = pj_memcmp(pj_sockaddr_get_addr(a1),
259
 
                       pj_sockaddr_get_addr(a2),
260
 
                       pj_sockaddr_get_addr_len(a1));
261
 
    if (result != 0)
262
 
        return result;
263
 
 
264
 
    /* Compare port number */
265
 
    port1 = pj_sockaddr_get_port(a1);
266
 
    port2 = pj_sockaddr_get_port(a2);
267
 
 
268
 
    if (port1 < port2)
269
 
        return -1;
270
 
    else if (port1 > port2)
271
 
        return 1;
272
 
 
273
 
    /* TODO:
274
 
     *  Do we need to compare flow label and scope id in IPv6? 
275
 
     */
276
 
    
277
 
    /* Looks equal */
278
 
    return 0;
279
 
}
280
 
 
281
 
/*
282
 
 * Get first IP address associated with the hostname.
283
 
 */
284
 
PJ_DEF(pj_in_addr) pj_gethostaddr(void)
285
 
{
286
 
    pj_sockaddr_in addr;
287
 
    const pj_str_t *hostname = pj_gethostname();
288
 
 
289
 
    pj_sockaddr_in_set_str_addr(&addr, hostname);
290
 
    return addr.sin_addr;
291
 
}
292
 
 
293
 
/*
294
 
 * Get port number of a pj_sockaddr_in
295
 
 */
296
 
PJ_DEF(pj_uint16_t) pj_sockaddr_in_get_port(const pj_sockaddr_in *addr)
297
 
{
298
 
    return pj_ntohs(addr->sin_port);
299
 
}
300
 
 
301
 
/*
302
 
 * Get the address part
303
 
 */
304
 
PJ_DEF(void*) pj_sockaddr_get_addr(const pj_sockaddr_t *addr)
305
 
{
306
 
    const pj_sockaddr *a = (const pj_sockaddr*)addr;
307
 
 
308
 
    PJ_ASSERT_RETURN(a->addr.sa_family == PJ_AF_INET ||
309
 
                     a->addr.sa_family == PJ_AF_INET6, NULL);
310
 
 
311
 
    if (a->addr.sa_family == PJ_AF_INET6)
312
 
        return (void*) &a->ipv6.sin6_addr;
313
 
    else
314
 
        return (void*) &a->ipv4.sin_addr;
315
 
}
316
 
 
317
 
/*
318
 
 * Check if sockaddr contains a non-zero address
319
 
 */
320
 
PJ_DEF(pj_bool_t) pj_sockaddr_has_addr(const pj_sockaddr_t *addr)
321
 
{
322
 
    const pj_sockaddr *a = (const pj_sockaddr*)addr;
323
 
 
324
 
    /* It's probably not wise to raise assertion here if
325
 
     * the address doesn't contain a valid address family, and
326
 
     * just return PJ_FALSE instead.
327
 
     * 
328
 
     * The reason is because application may need to distinguish 
329
 
     * these three conditions with sockaddr:
330
 
     *  a) sockaddr is not initialized. This is by convention
331
 
     *     indicated by sa_family==0.
332
 
     *  b) sockaddr is initialized with zero address. This is
333
 
     *     indicated with the address field having zero address.
334
 
     *  c) sockaddr is initialized with valid address/port.
335
 
     *
336
 
     * If we enable this assertion, then application will loose
337
 
     * the capability to specify condition a), since it will be
338
 
     * forced to always initialize sockaddr (even with zero address).
339
 
     * This may break some parts of upper layer libraries.
340
 
     */
341
 
    //PJ_ASSERT_RETURN(a->addr.sa_family == PJ_AF_INET ||
342
 
    //               a->addr.sa_family == PJ_AF_INET6, PJ_FALSE);
343
 
 
344
 
    if (a->addr.sa_family!=PJ_AF_INET && a->addr.sa_family!=PJ_AF_INET6) {
345
 
        return PJ_FALSE;
346
 
    } else if (a->addr.sa_family == PJ_AF_INET6) {
347
 
        pj_uint8_t zero[24];
348
 
        pj_bzero(zero, sizeof(zero));
349
 
        return pj_memcmp(a->ipv6.sin6_addr.s6_addr, zero, 
350
 
                         sizeof(pj_in6_addr)) != 0;
351
 
    } else
352
 
        return a->ipv4.sin_addr.s_addr != PJ_INADDR_ANY;
353
 
}
354
 
 
355
 
/*
356
 
 * Get port number
357
 
 */
358
 
PJ_DEF(pj_uint16_t) pj_sockaddr_get_port(const pj_sockaddr_t *addr)
359
 
{
360
 
    const pj_sockaddr *a = (const pj_sockaddr*) addr;
361
 
 
362
 
    PJ_ASSERT_RETURN(a->addr.sa_family == PJ_AF_INET ||
363
 
                     a->addr.sa_family == PJ_AF_INET6, (pj_uint16_t)0xFFFF);
364
 
 
365
 
    return pj_ntohs((pj_uint16_t)(a->addr.sa_family == PJ_AF_INET6 ?
366
 
                                    a->ipv6.sin6_port : a->ipv4.sin_port));
367
 
}
368
 
 
369
 
/*
370
 
 * Get the length of the address part.
371
 
 */
372
 
PJ_DEF(unsigned) pj_sockaddr_get_addr_len(const pj_sockaddr_t *addr)
373
 
{
374
 
    const pj_sockaddr *a = (const pj_sockaddr*) addr;
375
 
    PJ_ASSERT_RETURN(a->addr.sa_family == PJ_AF_INET ||
376
 
                     a->addr.sa_family == PJ_AF_INET6, 0);
377
 
    return a->addr.sa_family == PJ_AF_INET6 ?
378
 
            sizeof(pj_in6_addr) : sizeof(pj_in_addr);
379
 
}
380
 
 
381
 
/*
382
 
 * Get socket address length.
383
 
 */
384
 
PJ_DEF(unsigned) pj_sockaddr_get_len(const pj_sockaddr_t *addr)
385
 
{
386
 
    const pj_sockaddr *a = (const pj_sockaddr*) addr;
387
 
    PJ_ASSERT_RETURN(a->addr.sa_family == PJ_AF_INET ||
388
 
                     a->addr.sa_family == PJ_AF_INET6, 0);
389
 
    return a->addr.sa_family == PJ_AF_INET6 ?
390
 
            sizeof(pj_sockaddr_in6) : sizeof(pj_sockaddr_in);
391
 
}
392
 
 
393
 
/*
394
 
 * Copy only the address part (sin_addr/sin6_addr) of a socket address.
395
 
 */
396
 
PJ_DEF(void) pj_sockaddr_copy_addr( pj_sockaddr *dst,
397
 
                                    const pj_sockaddr *src)
398
 
{
399
 
    /* Destination sockaddr might not be initialized */
400
 
    const char *srcbuf = (char*)pj_sockaddr_get_addr(src);
401
 
    char *dstbuf = ((char*)dst) + (srcbuf - (char*)src);
402
 
    pj_memcpy(dstbuf, srcbuf, pj_sockaddr_get_addr_len(src));
403
 
}
404
 
 
405
 
/*
406
 
 * Copy socket address.
407
 
 */
408
 
PJ_DEF(void) pj_sockaddr_cp(pj_sockaddr_t *dst, const pj_sockaddr_t *src)
409
 
{
410
 
    pj_memcpy(dst, src, pj_sockaddr_get_len(src));
411
 
}
412
 
 
413
 
/*
414
 
 * Set port number of pj_sockaddr_in
415
 
 */
416
 
PJ_DEF(void) pj_sockaddr_in_set_port(pj_sockaddr_in *addr, 
417
 
                                     pj_uint16_t hostport)
418
 
{
419
 
    addr->sin_port = pj_htons(hostport);
420
 
}
421
 
 
422
 
/*
423
 
 * Set port number of pj_sockaddr
424
 
 */
425
 
PJ_DEF(pj_status_t) pj_sockaddr_set_port(pj_sockaddr *addr, 
426
 
                                         pj_uint16_t hostport)
427
 
{
428
 
    int af = addr->addr.sa_family;
429
 
 
430
 
    PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EINVAL);
431
 
 
432
 
    if (af == PJ_AF_INET6)
433
 
        addr->ipv6.sin6_port = pj_htons(hostport);
434
 
    else
435
 
        addr->ipv4.sin_port = pj_htons(hostport);
436
 
 
437
 
    return PJ_SUCCESS;
438
 
}
439
 
 
440
 
/*
441
 
 * Get IPv4 address
442
 
 */
443
 
PJ_DEF(pj_in_addr) pj_sockaddr_in_get_addr(const pj_sockaddr_in *addr)
444
 
{
445
 
    pj_in_addr in_addr;
446
 
    in_addr.s_addr = pj_ntohl(addr->sin_addr.s_addr);
447
 
    return in_addr;
448
 
}
449
 
 
450
 
/*
451
 
 * Set IPv4 address
452
 
 */
453
 
PJ_DEF(void) pj_sockaddr_in_set_addr(pj_sockaddr_in *addr,
454
 
                                     pj_uint32_t hostaddr)
455
 
{
456
 
    addr->sin_addr.s_addr = pj_htonl(hostaddr);
457
 
}
458
 
 
459
 
/*
460
 
 * Parse address
461
 
 */
462
 
PJ_DEF(pj_status_t) pj_sockaddr_parse2(int af, unsigned options,
463
 
                                       const pj_str_t *str,
464
 
                                       pj_str_t *p_hostpart,
465
 
                                       pj_uint16_t *p_port,
466
 
                                       int *raf)
467
 
{
468
 
    const char *end = str->ptr + str->slen;
469
 
    const char *last_colon_pos = NULL;
470
 
    unsigned colon_cnt = 0;
471
 
    const char *p;
472
 
 
473
 
    PJ_ASSERT_RETURN((af==PJ_AF_INET || af==PJ_AF_INET6 || af==PJ_AF_UNSPEC) &&
474
 
                     options==0 &&
475
 
                     str!=NULL, PJ_EINVAL);
476
 
 
477
 
    /* Special handling for empty input */
478
 
    if (str->slen==0 || str->ptr==NULL) {
479
 
        if (p_hostpart)
480
 
            p_hostpart->slen = 0;
481
 
        if (p_port)
482
 
            *p_port = 0;
483
 
        if (raf)
484
 
            *raf = PJ_AF_INET;
485
 
        return PJ_SUCCESS;
486
 
    }
487
 
 
488
 
    /* Count the colon and get the last colon */
489
 
    for (p=str->ptr; p!=end; ++p) {
490
 
        if (*p == ':') {
491
 
            ++colon_cnt;
492
 
            last_colon_pos = p;
493
 
        }
494
 
    }
495
 
 
496
 
    /* Deduce address family if it's not given */
497
 
    if (af == PJ_AF_UNSPEC) {
498
 
        if (colon_cnt > 1)
499
 
            af = PJ_AF_INET6;
500
 
        else
501
 
            af = PJ_AF_INET;
502
 
    } else if (af == PJ_AF_INET && colon_cnt > 1)
503
 
        return PJ_EINVAL;
504
 
 
505
 
    if (raf)
506
 
        *raf = af;
507
 
 
508
 
    if (af == PJ_AF_INET) {
509
 
        /* Parse as IPv4. Supported formats:
510
 
         *  - "10.0.0.1:80"
511
 
         *  - "10.0.0.1"
512
 
         *  - "10.0.0.1:"
513
 
         *  - ":80"
514
 
         *  - ":"
515
 
         */
516
 
        pj_str_t hostpart;
517
 
        unsigned long port;
518
 
 
519
 
        hostpart.ptr = (char*)str->ptr;
520
 
 
521
 
        if (last_colon_pos) {
522
 
            pj_str_t port_part;
523
 
            int i;
524
 
 
525
 
            hostpart.slen = last_colon_pos - str->ptr;
526
 
 
527
 
            port_part.ptr = (char*)last_colon_pos + 1;
528
 
            port_part.slen = end - port_part.ptr;
529
 
 
530
 
            /* Make sure port number is valid */
531
 
            for (i=0; i<port_part.slen; ++i) {
532
 
                if (!pj_isdigit(port_part.ptr[i]))
533
 
                    return PJ_EINVAL;
534
 
            }
535
 
            port = pj_strtoul(&port_part);
536
 
            if (port > 65535)
537
 
                return PJ_EINVAL;
538
 
        } else {
539
 
            hostpart.slen = str->slen;
540
 
            port = 0;
541
 
        }
542
 
 
543
 
        if (p_hostpart)
544
 
            *p_hostpart = hostpart;
545
 
        if (p_port)
546
 
            *p_port = (pj_uint16_t)port;
547
 
 
548
 
        return PJ_SUCCESS;
549
 
 
550
 
    } else if (af == PJ_AF_INET6) {
551
 
 
552
 
        /* Parse as IPv6. Supported formats:
553
 
         *  - "fe::01:80"  ==> note: port number is zero in this case, not 80!
554
 
         *  - "[fe::01]:80"
555
 
         *  - "fe::01"
556
 
         *  - "fe::01:"
557
 
         *  - "[fe::01]"
558
 
         *  - "[fe::01]:"
559
 
         *  - "[::]:80"
560
 
         *  - ":::80"
561
 
         *  - "[::]"
562
 
         *  - "[::]:"
563
 
         *  - ":::"
564
 
         *  - "::"
565
 
         */
566
 
        pj_str_t hostpart, port_part;
567
 
 
568
 
        if (*str->ptr == '[') {
569
 
            char *end_bracket;
570
 
            int i;
571
 
            unsigned long port;
572
 
 
573
 
            if (last_colon_pos == NULL)
574
 
                return PJ_EINVAL;
575
 
 
576
 
            end_bracket = pj_strchr(str, ']');
577
 
            if (end_bracket == NULL)
578
 
                return PJ_EINVAL;
579
 
 
580
 
            hostpart.ptr = (char*)str->ptr + 1;
581
 
            hostpart.slen = end_bracket - hostpart.ptr;
582
 
 
583
 
            if (last_colon_pos < end_bracket) {
584
 
                port_part.ptr = NULL;
585
 
                port_part.slen = 0;
586
 
            } else {
587
 
                port_part.ptr = (char*)last_colon_pos + 1;
588
 
                port_part.slen = end - port_part.ptr;
589
 
            }
590
 
 
591
 
            /* Make sure port number is valid */
592
 
            for (i=0; i<port_part.slen; ++i) {
593
 
                if (!pj_isdigit(port_part.ptr[i]))
594
 
                    return PJ_EINVAL;
595
 
            }
596
 
            port = pj_strtoul(&port_part);
597
 
            if (port > 65535)
598
 
                return PJ_EINVAL;
599
 
 
600
 
            if (p_hostpart)
601
 
                *p_hostpart = hostpart;
602
 
            if (p_port)
603
 
                *p_port = (pj_uint16_t)port;
604
 
 
605
 
            return PJ_SUCCESS;
606
 
 
607
 
        } else {
608
 
            /* Treat everything as part of the IPv6 IP address */
609
 
            if (p_hostpart)
610
 
                *p_hostpart = *str;
611
 
            if (p_port)
612
 
                *p_port = 0;
613
 
 
614
 
            return PJ_SUCCESS;
615
 
        }
616
 
 
617
 
    } else {
618
 
        return PJ_EAFNOTSUP;
619
 
    }
620
 
 
621
 
}
622
 
 
623
 
/*
624
 
 * Parse address
625
 
 */
626
 
PJ_DEF(pj_status_t) pj_sockaddr_parse( int af, unsigned options,
627
 
                                       const pj_str_t *str,
628
 
                                       pj_sockaddr *addr)
629
 
{
630
 
    pj_str_t hostpart;
631
 
    pj_uint16_t port;
632
 
    pj_status_t status;
633
 
 
634
 
    PJ_ASSERT_RETURN(addr, PJ_EINVAL);
635
 
    PJ_ASSERT_RETURN(af==PJ_AF_UNSPEC ||
636
 
                     af==PJ_AF_INET ||
637
 
                     af==PJ_AF_INET6, PJ_EINVAL);
638
 
    PJ_ASSERT_RETURN(options == 0, PJ_EINVAL);
639
 
 
640
 
    status = pj_sockaddr_parse2(af, options, str, &hostpart, &port, &af);
641
 
    if (status != PJ_SUCCESS)
642
 
        return status;
643
 
    
644
 
#if !defined(PJ_HAS_IPV6) || !PJ_HAS_IPV6
645
 
    if (af==PJ_AF_INET6)
646
 
        return PJ_EIPV6NOTSUP;
647
 
#endif
648
 
 
649
 
    status = pj_sockaddr_init(af, addr, &hostpart, port);
650
 
#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6
651
 
    if (status != PJ_SUCCESS && af == PJ_AF_INET6) {
652
 
        /* Parsing does not yield valid address. Try to treat the last 
653
 
         * portion after the colon as port number.
654
 
         */
655
 
        const char *last_colon_pos=NULL, *p;
656
 
        const char *end = str->ptr + str->slen;
657
 
        unsigned long long_port;
658
 
        pj_str_t port_part;
659
 
        int i;
660
 
 
661
 
        /* Parse as IPv6:port */
662
 
        for (p=str->ptr; p!=end; ++p) {
663
 
            if (*p == ':')
664
 
                last_colon_pos = p;
665
 
        }
666
 
 
667
 
        if (last_colon_pos == NULL)
668
 
            return status;
669
 
 
670
 
        hostpart.ptr = (char*)str->ptr;
671
 
        hostpart.slen = last_colon_pos - str->ptr;
672
 
 
673
 
        port_part.ptr = (char*)last_colon_pos + 1;
674
 
        port_part.slen = end - port_part.ptr;
675
 
 
676
 
        /* Make sure port number is valid */
677
 
        for (i=0; i<port_part.slen; ++i) {
678
 
            if (!pj_isdigit(port_part.ptr[i]))
679
 
                return status;
680
 
        }
681
 
        long_port = pj_strtoul(&port_part);
682
 
        if (long_port > 65535)
683
 
            return status;
684
 
 
685
 
        port = (pj_uint16_t)long_port;
686
 
 
687
 
        status = pj_sockaddr_init(PJ_AF_INET6, addr, &hostpart, port);
688
 
    }
689
 
#endif
690
 
    
691
 
    return status;
692
 
}
693
 
 
694
 
/* Resolve the IP address of local machine */
695
 
PJ_DEF(pj_status_t) pj_gethostip(int af, pj_sockaddr *addr)
696
 
{
697
 
    unsigned i, count, cand_cnt;
698
 
    enum {
699
 
        CAND_CNT = 8,
700
 
 
701
 
        /* Weighting to be applied to found addresses */
702
 
        WEIGHT_HOSTNAME = 1,    /* hostname IP is not always valid! */
703
 
        WEIGHT_DEF_ROUTE = 2,
704
 
        WEIGHT_INTERFACE = 1,
705
 
        WEIGHT_LOOPBACK = -5,
706
 
        WEIGHT_LINK_LOCAL = -4,
707
 
        WEIGHT_DISABLED = -50,
708
 
 
709
 
        MIN_WEIGHT = WEIGHT_DISABLED+1  /* minimum weight to use */
710
 
    };
711
 
    /* candidates: */
712
 
    pj_sockaddr cand_addr[CAND_CNT];
713
 
    int         cand_weight[CAND_CNT];
714
 
    int         selected_cand;
715
 
    char        strip[PJ_INET6_ADDRSTRLEN+10];
716
 
    /* Special IPv4 addresses. */
717
 
    struct spec_ipv4_t
718
 
    {
719
 
        pj_uint32_t addr;
720
 
        pj_uint32_t mask;
721
 
        int         weight;
722
 
    } spec_ipv4[] =
723
 
    {
724
 
        /* 127.0.0.0/8, loopback addr will be used if there is no other
725
 
         * addresses.
726
 
         */
727
 
        { 0x7f000000, 0xFF000000, WEIGHT_LOOPBACK },
728
 
 
729
 
        /* 0.0.0.0/8, special IP that doesn't seem to be practically useful */
730
 
        { 0x00000000, 0xFF000000, WEIGHT_DISABLED },
731
 
 
732
 
        /* 169.254.0.0/16, a zeroconf/link-local address, which has higher
733
 
         * priority than loopback and will be used if there is no other
734
 
         * valid addresses.
735
 
         */
736
 
        { 0xa9fe0000, 0xFFFF0000, WEIGHT_LINK_LOCAL }
737
 
    };
738
 
    /* Special IPv6 addresses */
739
 
    struct spec_ipv6_t
740
 
    {
741
 
        pj_uint8_t addr[16];
742
 
        pj_uint8_t mask[16];
743
 
        int        weight;
744
 
    } spec_ipv6[] =
745
 
    {
746
 
        /* Loopback address, ::1/128 */
747
 
        { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
748
 
          {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
749
 
           0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
750
 
          WEIGHT_LOOPBACK
751
 
        },
752
 
 
753
 
        /* Link local, fe80::/10 */
754
 
        { {0xfe,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
755
 
          {0xff,0xc0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
756
 
          WEIGHT_LINK_LOCAL
757
 
        },
758
 
 
759
 
        /* Disabled, ::/128 */
760
 
        { {0x0,0x0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
761
 
        { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
762
 
          0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
763
 
          WEIGHT_DISABLED
764
 
        }
765
 
    };
766
 
    pj_addrinfo ai;
767
 
    pj_status_t status;
768
 
 
769
 
    /* May not be used if TRACE_ is disabled */
770
 
    PJ_UNUSED_ARG(strip);
771
 
 
772
 
#ifdef _MSC_VER
773
 
    /* Get rid of "uninitialized he variable" with MS compilers */
774
 
    pj_bzero(&ai, sizeof(ai));
775
 
#endif
776
 
 
777
 
    cand_cnt = 0;
778
 
    pj_bzero(cand_addr, sizeof(cand_addr));
779
 
    pj_bzero(cand_weight, sizeof(cand_weight));
780
 
    for (i=0; i<PJ_ARRAY_SIZE(cand_addr); ++i) {
781
 
        cand_addr[i].addr.sa_family = (pj_uint16_t)af;
782
 
        PJ_SOCKADDR_RESET_LEN(&cand_addr[i]);
783
 
    }
784
 
 
785
 
    addr->addr.sa_family = (pj_uint16_t)af;
786
 
    PJ_SOCKADDR_RESET_LEN(addr);
787
 
 
788
 
#if !defined(PJ_GETHOSTIP_DISABLE_LOCAL_RESOLUTION) || \
789
 
    PJ_GETHOSTIP_DISABLE_LOCAL_RESOLUTION == 0
790
 
    /* Get hostname's IP address */
791
 
    count = 1;
792
 
    status = pj_getaddrinfo(af, pj_gethostname(), &count, &ai);
793
 
    if (status == PJ_SUCCESS) {
794
 
        pj_assert(ai.ai_addr.addr.sa_family == (pj_uint16_t)af);
795
 
        pj_sockaddr_copy_addr(&cand_addr[cand_cnt], &ai.ai_addr);
796
 
        pj_sockaddr_set_port(&cand_addr[cand_cnt], 0);
797
 
        cand_weight[cand_cnt] += WEIGHT_HOSTNAME;
798
 
        ++cand_cnt;
799
 
 
800
 
        TRACE_((THIS_FILE, "hostname IP is %s",
801
 
                pj_sockaddr_print(&ai.ai_addr, strip, sizeof(strip), 0)));
802
 
    }
803
 
#else
804
 
    PJ_UNUSED_ARG(ai);
805
 
    PJ_UNUSED_ARG(count);
806
 
#endif
807
 
 
808
 
    /* Get default interface (interface for default route) */
809
 
    if (cand_cnt < PJ_ARRAY_SIZE(cand_addr)) {
810
 
        status = pj_getdefaultipinterface(af, addr);
811
 
        if (status == PJ_SUCCESS) {
812
 
            TRACE_((THIS_FILE, "default IP is %s",
813
 
                    pj_sockaddr_print(addr, strip, sizeof(strip), 0)));
814
 
 
815
 
            pj_sockaddr_set_port(addr, 0);
816
 
            for (i=0; i<cand_cnt; ++i) {
817
 
                if (pj_sockaddr_cmp(&cand_addr[i], addr)==0)
818
 
                    break;
819
 
            }
820
 
 
821
 
            cand_weight[i] += WEIGHT_DEF_ROUTE;
822
 
            if (i >= cand_cnt) {
823
 
                pj_sockaddr_copy_addr(&cand_addr[i], addr);
824
 
                ++cand_cnt;
825
 
            }
826
 
        }
827
 
    }
828
 
 
829
 
 
830
 
    /* Enumerate IP interfaces */
831
 
    if (cand_cnt < PJ_ARRAY_SIZE(cand_addr)) {
832
 
        unsigned start_if = cand_cnt;
833
 
        unsigned count = PJ_ARRAY_SIZE(cand_addr) - start_if;
834
 
 
835
 
        status = pj_enum_ip_interface(af, &count, &cand_addr[start_if]);
836
 
        if (status == PJ_SUCCESS && count) {
837
 
            /* Clear the port number */
838
 
            for (i=0; i<count; ++i)
839
 
                pj_sockaddr_set_port(&cand_addr[start_if+i], 0);
840
 
 
841
 
            /* For each candidate that we found so far (that is the hostname
842
 
             * address and default interface address, check if they're found
843
 
             * in the interface list. If found, add the weight, and if not,
844
 
             * decrease the weight.
845
 
             */
846
 
            for (i=0; i<cand_cnt; ++i) {
847
 
                unsigned j;
848
 
                for (j=0; j<count; ++j) {
849
 
                    if (pj_sockaddr_cmp(&cand_addr[i], 
850
 
                                        &cand_addr[start_if+j])==0)
851
 
                        break;
852
 
                }
853
 
 
854
 
                if (j == count) {
855
 
                    /* Not found */
856
 
                    cand_weight[i] -= WEIGHT_INTERFACE;
857
 
                } else {
858
 
                    cand_weight[i] += WEIGHT_INTERFACE;
859
 
                }
860
 
            }
861
 
 
862
 
            /* Add remaining interface to candidate list. */
863
 
            for (i=0; i<count; ++i) {
864
 
                unsigned j;
865
 
                for (j=0; j<cand_cnt; ++j) {
866
 
                    if (pj_sockaddr_cmp(&cand_addr[start_if+i], 
867
 
                                        &cand_addr[j])==0)
868
 
                        break;
869
 
                }
870
 
 
871
 
                if (j == cand_cnt) {
872
 
                    pj_sockaddr_copy_addr(&cand_addr[cand_cnt], 
873
 
                                          &cand_addr[start_if+i]);
874
 
                    cand_weight[cand_cnt] += WEIGHT_INTERFACE;
875
 
                    ++cand_cnt;
876
 
                }
877
 
            }
878
 
        }
879
 
    }
880
 
 
881
 
    /* Apply weight adjustment for special IPv4/IPv6 addresses
882
 
     * See http://trac.pjsip.org/repos/ticket/1046
883
 
     */
884
 
    if (af == PJ_AF_INET) {
885
 
        for (i=0; i<cand_cnt; ++i) {
886
 
            unsigned j;
887
 
            for (j=0; j<PJ_ARRAY_SIZE(spec_ipv4); ++j) {
888
 
                    pj_uint32_t a = pj_ntohl(cand_addr[i].ipv4.sin_addr.s_addr);
889
 
                    pj_uint32_t pa = spec_ipv4[j].addr;
890
 
                    pj_uint32_t pm = spec_ipv4[j].mask;
891
 
 
892
 
                    if ((a & pm) == pa) {
893
 
                        cand_weight[i] += spec_ipv4[j].weight;
894
 
                        break;
895
 
                    }
896
 
            }
897
 
        }
898
 
    } else if (af == PJ_AF_INET6) {
899
 
        for (i=0; i<PJ_ARRAY_SIZE(spec_ipv6); ++i) {
900
 
                unsigned j;
901
 
                for (j=0; j<cand_cnt; ++j) {
902
 
                    pj_uint8_t *a = cand_addr[j].ipv6.sin6_addr.s6_addr;
903
 
                    pj_uint8_t am[16];
904
 
                    pj_uint8_t *pa = spec_ipv6[i].addr;
905
 
                    pj_uint8_t *pm = spec_ipv6[i].mask;
906
 
                    unsigned k;
907
 
 
908
 
                    for (k=0; k<16; ++k) {
909
 
                        am[k] = (pj_uint8_t)((a[k] & pm[k]) & 0xFF);
910
 
                    }
911
 
 
912
 
                    if (pj_memcmp(am, pa, 16)==0) {
913
 
                        cand_weight[j] += spec_ipv6[i].weight;
914
 
                    }
915
 
                }
916
 
        }
917
 
    } else {
918
 
        return PJ_EAFNOTSUP;
919
 
    }
920
 
 
921
 
    /* Enumerate candidates to get the best IP address to choose */
922
 
    selected_cand = -1;
923
 
    for (i=0; i<cand_cnt; ++i) {
924
 
        TRACE_((THIS_FILE, "Checking candidate IP %s, weight=%d",
925
 
                pj_sockaddr_print(&cand_addr[i], strip, sizeof(strip), 0),
926
 
                cand_weight[i]));
927
 
 
928
 
        if (cand_weight[i] < MIN_WEIGHT) {
929
 
            continue;
930
 
        }
931
 
 
932
 
        if (selected_cand == -1)
933
 
            selected_cand = i;
934
 
        else if (cand_weight[i] > cand_weight[selected_cand])
935
 
            selected_cand = i;
936
 
    }
937
 
 
938
 
    /* If else fails, returns loopback interface as the last resort */
939
 
    if (selected_cand == -1) {
940
 
        if (af==PJ_AF_INET) {
941
 
            addr->ipv4.sin_addr.s_addr = pj_htonl (0x7f000001);
942
 
        } else {
943
 
            pj_in6_addr *s6_addr;
944
 
 
945
 
            s6_addr = (pj_in6_addr*) pj_sockaddr_get_addr(addr);
946
 
            pj_bzero(s6_addr, sizeof(pj_in6_addr));
947
 
            s6_addr->s6_addr[15] = 1;
948
 
        }
949
 
        TRACE_((THIS_FILE, "Loopback IP %s returned",
950
 
                pj_sockaddr_print(addr, strip, sizeof(strip), 0)));
951
 
    } else {
952
 
        pj_sockaddr_copy_addr(addr, &cand_addr[selected_cand]);
953
 
        TRACE_((THIS_FILE, "Candidate %s selected",
954
 
                pj_sockaddr_print(addr, strip, sizeof(strip), 0)));
955
 
    }
956
 
 
957
 
    return PJ_SUCCESS;
958
 
}
959
 
 
960
 
/* Get IP interface for sending to the specified destination */
961
 
PJ_DEF(pj_status_t) pj_getipinterface(int af,
962
 
                                      const pj_str_t *dst,
963
 
                                      pj_sockaddr *itf_addr,
964
 
                                      pj_bool_t allow_resolve,
965
 
                                      pj_sockaddr *p_dst_addr)
966
 
{
967
 
    pj_sockaddr dst_addr;
968
 
    pj_sock_t fd;
969
 
    int len;
970
 
    pj_uint8_t zero[64];
971
 
    pj_status_t status;
972
 
 
973
 
    pj_sockaddr_init(af, &dst_addr, NULL, 53);
974
 
    status = pj_inet_pton(af, dst, pj_sockaddr_get_addr(&dst_addr));
975
 
    if (status != PJ_SUCCESS) {
976
 
        /* "dst" is not an IP address. */
977
 
        if (allow_resolve) {
978
 
            status = pj_sockaddr_init(af, &dst_addr, dst, 53);
979
 
        } else {
980
 
            pj_str_t cp;
981
 
 
982
 
            if (af == PJ_AF_INET) {
983
 
                cp = pj_str("1.1.1.1");
984
 
            } else {
985
 
                cp = pj_str("1::1");
986
 
            }
987
 
            status = pj_sockaddr_init(af, &dst_addr, &cp, 53);
988
 
        }
989
 
 
990
 
        if (status != PJ_SUCCESS)
991
 
            return status;
992
 
    }
993
 
 
994
 
    /* Create UDP socket and connect() to the destination IP */
995
 
    status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &fd);
996
 
    if (status != PJ_SUCCESS) {
997
 
        return status;
998
 
    }
999
 
 
1000
 
    status = pj_sock_connect(fd, &dst_addr, pj_sockaddr_get_len(&dst_addr));
1001
 
    if (status != PJ_SUCCESS) {
1002
 
        pj_sock_close(fd);
1003
 
        return status;
1004
 
    }
1005
 
 
1006
 
    len = sizeof(*itf_addr);
1007
 
    status = pj_sock_getsockname(fd, itf_addr, &len);
1008
 
    if (status != PJ_SUCCESS) {
1009
 
        pj_sock_close(fd);
1010
 
        return status;
1011
 
    }
1012
 
 
1013
 
    pj_sock_close(fd);
1014
 
 
1015
 
    /* Check that the address returned is not zero */
1016
 
    pj_bzero(zero, sizeof(zero));
1017
 
    if (pj_memcmp(pj_sockaddr_get_addr(itf_addr), zero,
1018
 
                  pj_sockaddr_get_addr_len(itf_addr))==0)
1019
 
    {
1020
 
        return PJ_ENOTFOUND;
1021
 
    }
1022
 
 
1023
 
    if (p_dst_addr)
1024
 
        *p_dst_addr = dst_addr;
1025
 
 
1026
 
    return PJ_SUCCESS;
1027
 
}
1028
 
 
1029
 
/* Get the default IP interface */
1030
 
PJ_DEF(pj_status_t) pj_getdefaultipinterface(int af, pj_sockaddr *addr)
1031
 
{
1032
 
    pj_str_t cp;
1033
 
 
1034
 
    if (af == PJ_AF_INET) {
1035
 
        cp = pj_str("1.1.1.1");
1036
 
    } else {
1037
 
        cp = pj_str("1::1");
1038
 
    }
1039
 
 
1040
 
    return pj_getipinterface(af, &cp, addr, PJ_FALSE, NULL);
1041
 
}
1042
 
 
1043
 
 
1044
 
/*
1045
 
 * Bind socket at random port.
1046
 
 */
1047
 
PJ_DEF(pj_status_t) pj_sock_bind_random(  pj_sock_t sockfd,
1048
 
                                          const pj_sockaddr_t *addr,
1049
 
                                          pj_uint16_t port_range,
1050
 
                                          pj_uint16_t max_try)
1051
 
{
1052
 
    pj_sockaddr bind_addr;
1053
 
    int addr_len;
1054
 
    pj_uint16_t base_port;
1055
 
    pj_status_t status = PJ_SUCCESS;
1056
 
 
1057
 
    PJ_CHECK_STACK();
1058
 
 
1059
 
    PJ_ASSERT_RETURN(addr, PJ_EINVAL);
1060
 
 
1061
 
    pj_sockaddr_cp(&bind_addr, addr);
1062
 
    addr_len = pj_sockaddr_get_len(addr);
1063
 
    base_port = pj_sockaddr_get_port(addr);
1064
 
 
1065
 
    if (base_port == 0 || port_range == 0) {
1066
 
        return pj_sock_bind(sockfd, &bind_addr, addr_len);
1067
 
    }
1068
 
 
1069
 
    for (; max_try; --max_try) {
1070
 
        pj_uint16_t port;
1071
 
        port = (pj_uint16_t)(base_port + pj_rand() % (port_range + 1));
1072
 
        pj_sockaddr_set_port(&bind_addr, port);
1073
 
        status = pj_sock_bind(sockfd, &bind_addr, addr_len);
1074
 
        if (status == PJ_SUCCESS)
1075
 
            break;
1076
 
    }
1077
 
 
1078
 
    return status;
1079
 
}
1080
 
 
1081
 
 
1082
 
/* Only need to implement these in DLL build */
1083
 
#if defined(PJ_DLL)
1084
 
 
1085
 
PJ_DEF(pj_uint16_t) pj_AF_UNSPEC(void)
1086
 
{
1087
 
    return PJ_AF_UNSPEC;
1088
 
}
1089
 
 
1090
 
PJ_DEF(pj_uint16_t) pj_AF_UNIX(void)
1091
 
{
1092
 
    return PJ_AF_UNIX;
1093
 
}
1094
 
 
1095
 
PJ_DEF(pj_uint16_t) pj_AF_INET(void)
1096
 
{
1097
 
    return PJ_AF_INET;
1098
 
}
1099
 
 
1100
 
PJ_DEF(pj_uint16_t) pj_AF_INET6(void)
1101
 
{
1102
 
    return PJ_AF_INET6;
1103
 
}
1104
 
 
1105
 
PJ_DEF(pj_uint16_t) pj_AF_PACKET(void)
1106
 
{
1107
 
    return PJ_AF_PACKET;
1108
 
}
1109
 
 
1110
 
PJ_DEF(pj_uint16_t) pj_AF_IRDA(void)
1111
 
{
1112
 
    return PJ_AF_IRDA;
1113
 
}
1114
 
 
1115
 
PJ_DEF(int) pj_SOCK_STREAM(void)
1116
 
{
1117
 
    return PJ_SOCK_STREAM;
1118
 
}
1119
 
 
1120
 
PJ_DEF(int) pj_SOCK_DGRAM(void)
1121
 
{
1122
 
    return PJ_SOCK_DGRAM;
1123
 
}
1124
 
 
1125
 
PJ_DEF(int) pj_SOCK_RAW(void)
1126
 
{
1127
 
    return PJ_SOCK_RAW;
1128
 
}
1129
 
 
1130
 
PJ_DEF(int) pj_SOCK_RDM(void)
1131
 
{
1132
 
    return PJ_SOCK_RDM;
1133
 
}
1134
 
 
1135
 
PJ_DEF(pj_uint16_t) pj_SOL_SOCKET(void)
1136
 
{
1137
 
    return PJ_SOL_SOCKET;
1138
 
}
1139
 
 
1140
 
PJ_DEF(pj_uint16_t) pj_SOL_IP(void)
1141
 
{
1142
 
    return PJ_SOL_IP;
1143
 
}
1144
 
 
1145
 
PJ_DEF(pj_uint16_t) pj_SOL_TCP(void)
1146
 
{
1147
 
    return PJ_SOL_TCP;
1148
 
}
1149
 
 
1150
 
PJ_DEF(pj_uint16_t) pj_SOL_UDP(void)
1151
 
{
1152
 
    return PJ_SOL_UDP;
1153
 
}
1154
 
 
1155
 
PJ_DEF(pj_uint16_t) pj_SOL_IPV6(void)
1156
 
{
1157
 
    return PJ_SOL_IPV6;
1158
 
}
1159
 
 
1160
 
PJ_DEF(int) pj_IP_TOS(void)
1161
 
{
1162
 
    return PJ_IP_TOS;
1163
 
}
1164
 
 
1165
 
PJ_DEF(int) pj_IPTOS_LOWDELAY(void)
1166
 
{
1167
 
    return PJ_IPTOS_LOWDELAY;
1168
 
}
1169
 
 
1170
 
PJ_DEF(int) pj_IPTOS_THROUGHPUT(void)
1171
 
{
1172
 
    return PJ_IPTOS_THROUGHPUT;
1173
 
}
1174
 
 
1175
 
PJ_DEF(int) pj_IPTOS_RELIABILITY(void)
1176
 
{
1177
 
    return PJ_IPTOS_RELIABILITY;
1178
 
}
1179
 
 
1180
 
PJ_DEF(int) pj_IPTOS_MINCOST(void)
1181
 
{
1182
 
    return PJ_IPTOS_MINCOST;
1183
 
}
1184
 
 
1185
 
PJ_DEF(pj_uint16_t) pj_SO_TYPE(void)
1186
 
{
1187
 
    return PJ_SO_TYPE;
1188
 
}
1189
 
 
1190
 
PJ_DEF(pj_uint16_t) pj_SO_RCVBUF(void)
1191
 
{
1192
 
    return PJ_SO_RCVBUF;
1193
 
}
1194
 
 
1195
 
PJ_DEF(pj_uint16_t) pj_SO_SNDBUF(void)
1196
 
{
1197
 
    return PJ_SO_SNDBUF;
1198
 
}
1199
 
 
1200
 
PJ_DEF(pj_uint16_t) pj_TCP_NODELAY(void)
1201
 
{
1202
 
    return PJ_TCP_NODELAY;
1203
 
}
1204
 
 
1205
 
PJ_DEF(pj_uint16_t) pj_SO_REUSEADDR(void)
1206
 
{
1207
 
    return PJ_SO_REUSEADDR;
1208
 
}
1209
 
 
1210
 
PJ_DEF(pj_uint16_t) pj_SO_NOSIGPIPE(void)
1211
 
{
1212
 
    return PJ_SO_NOSIGPIPE;
1213
 
}
1214
 
 
1215
 
PJ_DEF(pj_uint16_t) pj_SO_PRIORITY(void)
1216
 
{
1217
 
    return PJ_SO_PRIORITY;
1218
 
}
1219
 
 
1220
 
PJ_DEF(pj_uint16_t) pj_IP_MULTICAST_IF(void)
1221
 
{
1222
 
    return PJ_IP_MULTICAST_IF;
1223
 
}
1224
 
 
1225
 
PJ_DEF(pj_uint16_t) pj_IP_MULTICAST_TTL(void)
1226
 
{
1227
 
    return PJ_IP_MULTICAST_TTL;
1228
 
}
1229
 
 
1230
 
PJ_DEF(pj_uint16_t) pj_IP_MULTICAST_LOOP(void)
1231
 
{
1232
 
    return PJ_IP_MULTICAST_LOOP;
1233
 
}
1234
 
 
1235
 
PJ_DEF(pj_uint16_t) pj_IP_ADD_MEMBERSHIP(void)
1236
 
{
1237
 
    return PJ_IP_ADD_MEMBERSHIP;
1238
 
}
1239
 
 
1240
 
PJ_DEF(pj_uint16_t) pj_IP_DROP_MEMBERSHIP(void)
1241
 
{
1242
 
    return PJ_IP_DROP_MEMBERSHIP;
1243
 
}
1244
 
 
1245
 
PJ_DEF(int) pj_MSG_OOB(void)
1246
 
{
1247
 
    return PJ_MSG_OOB;
1248
 
}
1249
 
 
1250
 
PJ_DEF(int) pj_MSG_PEEK(void)
1251
 
{
1252
 
    return PJ_MSG_PEEK;
1253
 
}
1254
 
 
1255
 
PJ_DEF(int) pj_MSG_DONTROUTE(void)
1256
 
{
1257
 
    return PJ_MSG_DONTROUTE;
1258
 
}
1259
 
 
1260
 
#endif  /* PJ_DLL */
1261