~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_bsd.c

  • Committer: Package Import Robot
  • Author(s): Francois Marier, Francois Marier, Mark Purcell
  • Date: 2014-10-18 15:08:50 UTC
  • mfrom: (1.1.12)
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20141018150850-2exfk34ckb15pcwi
Tags: 1.4.1-0.1
[ Francois Marier ]
* Non-maintainer upload
* New upstream release (closes: #759576, #741130)
  - debian/rules +PJPROJECT_VERSION := 2.2.1
  - add upstream patch to fix broken TLS support
  - add patch to fix pjproject regression

[ Mark Purcell ]
* Build-Depends:
  - sflphone-daemon + libavformat-dev, libavcodec-dev, libswscale-dev,
  libavdevice-dev, libavutil-dev
  - sflphone-gnome + libclutter-gtk-1.0-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: sock_bsd.c 4233 2012-08-21 11:16:06Z 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 <pj/sock.h>
21
 
#include <pj/os.h>
22
 
#include <pj/assert.h>
23
 
#include <pj/string.h>
24
 
#include <pj/compat/socket.h>
25
 
#include <pj/addr_resolv.h>
26
 
#include <pj/errno.h>
27
 
#include <pj/unicode.h>
28
 
 
29
 
/*
30
 
 * Address families conversion.
31
 
 * The values here are indexed based on pj_addr_family.
32
 
 */
33
 
const pj_uint16_t PJ_AF_UNSPEC  = AF_UNSPEC;
34
 
const pj_uint16_t PJ_AF_UNIX    = AF_UNIX;
35
 
const pj_uint16_t PJ_AF_INET    = AF_INET;
36
 
const pj_uint16_t PJ_AF_INET6   = AF_INET6;
37
 
#ifdef AF_PACKET
38
 
const pj_uint16_t PJ_AF_PACKET  = AF_PACKET;
39
 
#else
40
 
const pj_uint16_t PJ_AF_PACKET  = 0xFFFF;
41
 
#endif
42
 
#ifdef AF_IRDA
43
 
const pj_uint16_t PJ_AF_IRDA    = AF_IRDA;
44
 
#else
45
 
const pj_uint16_t PJ_AF_IRDA    = 0xFFFF;
46
 
#endif
47
 
 
48
 
/*
49
 
 * Socket types conversion.
50
 
 * The values here are indexed based on pj_sock_type
51
 
 */
52
 
const pj_uint16_t PJ_SOCK_STREAM= SOCK_STREAM;
53
 
const pj_uint16_t PJ_SOCK_DGRAM = SOCK_DGRAM;
54
 
const pj_uint16_t PJ_SOCK_RAW   = SOCK_RAW;
55
 
const pj_uint16_t PJ_SOCK_RDM   = SOCK_RDM;
56
 
 
57
 
/*
58
 
 * Socket level values.
59
 
 */
60
 
const pj_uint16_t PJ_SOL_SOCKET = SOL_SOCKET;
61
 
#ifdef SOL_IP
62
 
const pj_uint16_t PJ_SOL_IP     = SOL_IP;
63
 
#elif defined(PJ_WIN32) && PJ_WIN32
64
 
const pj_uint16_t PJ_SOL_IP     = IPPROTO_IP;
65
 
#else
66
 
const pj_uint16_t PJ_SOL_IP     = 0;
67
 
#endif /* SOL_IP */
68
 
 
69
 
#if defined(SOL_TCP)
70
 
const pj_uint16_t PJ_SOL_TCP    = SOL_TCP;
71
 
#elif defined(IPPROTO_TCP)
72
 
const pj_uint16_t PJ_SOL_TCP    = IPPROTO_TCP;
73
 
#elif defined(PJ_WIN32) && PJ_WIN32
74
 
const pj_uint16_t PJ_SOL_TCP    = IPPROTO_TCP;
75
 
#else
76
 
const pj_uint16_t PJ_SOL_TCP    = 6;
77
 
#endif /* SOL_TCP */
78
 
 
79
 
#ifdef SOL_UDP
80
 
const pj_uint16_t PJ_SOL_UDP    = SOL_UDP;
81
 
#elif defined(IPPROTO_UDP)
82
 
const pj_uint16_t PJ_SOL_UDP    = IPPROTO_UDP;
83
 
#elif defined(PJ_WIN32) && PJ_WIN32
84
 
const pj_uint16_t PJ_SOL_UDP    = IPPROTO_UDP;
85
 
#else
86
 
const pj_uint16_t PJ_SOL_UDP    = 17;
87
 
#endif /* SOL_UDP */
88
 
 
89
 
#ifdef SOL_IPV6
90
 
const pj_uint16_t PJ_SOL_IPV6   = SOL_IPV6;
91
 
#elif defined(PJ_WIN32) && PJ_WIN32
92
 
#   if defined(IPPROTO_IPV6) || (_WIN32_WINNT >= 0x0501)
93
 
        const pj_uint16_t PJ_SOL_IPV6   = IPPROTO_IPV6;
94
 
#   else
95
 
        const pj_uint16_t PJ_SOL_IPV6   = 41;
96
 
#   endif
97
 
#else
98
 
const pj_uint16_t PJ_SOL_IPV6   = 41;
99
 
#endif /* SOL_IPV6 */
100
 
 
101
 
/* IP_TOS */
102
 
#ifdef IP_TOS
103
 
const pj_uint16_t PJ_IP_TOS     = IP_TOS;
104
 
#else
105
 
const pj_uint16_t PJ_IP_TOS     = 1;
106
 
#endif
107
 
 
108
 
 
109
 
/* TOS settings (declared in netinet/ip.h) */
110
 
#ifdef IPTOS_LOWDELAY
111
 
const pj_uint16_t PJ_IPTOS_LOWDELAY     = IPTOS_LOWDELAY;
112
 
#else
113
 
const pj_uint16_t PJ_IPTOS_LOWDELAY     = 0x10;
114
 
#endif
115
 
#ifdef IPTOS_THROUGHPUT
116
 
const pj_uint16_t PJ_IPTOS_THROUGHPUT   = IPTOS_THROUGHPUT;
117
 
#else
118
 
const pj_uint16_t PJ_IPTOS_THROUGHPUT   = 0x08;
119
 
#endif
120
 
#ifdef IPTOS_RELIABILITY
121
 
const pj_uint16_t PJ_IPTOS_RELIABILITY  = IPTOS_RELIABILITY;
122
 
#else
123
 
const pj_uint16_t PJ_IPTOS_RELIABILITY  = 0x04;
124
 
#endif
125
 
#ifdef IPTOS_MINCOST
126
 
const pj_uint16_t PJ_IPTOS_MINCOST      = IPTOS_MINCOST;
127
 
#else
128
 
const pj_uint16_t PJ_IPTOS_MINCOST      = 0x02;
129
 
#endif
130
 
 
131
 
 
132
 
/* optname values. */
133
 
const pj_uint16_t PJ_SO_TYPE    = SO_TYPE;
134
 
const pj_uint16_t PJ_SO_RCVBUF  = SO_RCVBUF;
135
 
const pj_uint16_t PJ_SO_SNDBUF  = SO_SNDBUF;
136
 
const pj_uint16_t PJ_TCP_NODELAY= TCP_NODELAY;
137
 
const pj_uint16_t PJ_SO_REUSEADDR= SO_REUSEADDR;
138
 
#ifdef SO_NOSIGPIPE
139
 
const pj_uint16_t PJ_SO_NOSIGPIPE = SO_NOSIGPIPE;
140
 
#else
141
 
const pj_uint16_t PJ_SO_NOSIGPIPE = 0xFFFF;
142
 
#endif
143
 
#if defined(SO_PRIORITY)
144
 
const pj_uint16_t PJ_SO_PRIORITY = SO_PRIORITY;
145
 
#else
146
 
/* This is from Linux, YMMV */
147
 
const pj_uint16_t PJ_SO_PRIORITY = 12;
148
 
#endif
149
 
 
150
 
/* Multicasting is not supported e.g. in PocketPC 2003 SDK */
151
 
#ifdef IP_MULTICAST_IF
152
 
const pj_uint16_t PJ_IP_MULTICAST_IF    = IP_MULTICAST_IF;
153
 
const pj_uint16_t PJ_IP_MULTICAST_TTL   = IP_MULTICAST_TTL;
154
 
const pj_uint16_t PJ_IP_MULTICAST_LOOP  = IP_MULTICAST_LOOP;
155
 
const pj_uint16_t PJ_IP_ADD_MEMBERSHIP  = IP_ADD_MEMBERSHIP;
156
 
const pj_uint16_t PJ_IP_DROP_MEMBERSHIP = IP_DROP_MEMBERSHIP;
157
 
#else
158
 
const pj_uint16_t PJ_IP_MULTICAST_IF    = 0xFFFF;
159
 
const pj_uint16_t PJ_IP_MULTICAST_TTL   = 0xFFFF;
160
 
const pj_uint16_t PJ_IP_MULTICAST_LOOP  = 0xFFFF;
161
 
const pj_uint16_t PJ_IP_ADD_MEMBERSHIP  = 0xFFFF;
162
 
const pj_uint16_t PJ_IP_DROP_MEMBERSHIP = 0xFFFF;
163
 
#endif
164
 
 
165
 
/* recv() and send() flags */
166
 
const int PJ_MSG_OOB            = MSG_OOB;
167
 
const int PJ_MSG_PEEK           = MSG_PEEK;
168
 
const int PJ_MSG_DONTROUTE      = MSG_DONTROUTE;
169
 
 
170
 
 
171
 
#if 0
172
 
static void CHECK_ADDR_LEN(const pj_sockaddr *addr, int len)
173
 
{
174
 
    pj_sockaddr *a = (pj_sockaddr*)addr;
175
 
    pj_assert((a->addr.sa_family==PJ_AF_INET && len==sizeof(pj_sockaddr_in)) ||
176
 
              (a->addr.sa_family==PJ_AF_INET6 && len==sizeof(pj_sockaddr_in6)));
177
 
 
178
 
}
179
 
#else
180
 
#define CHECK_ADDR_LEN(addr,len)
181
 
#endif
182
 
 
183
 
/*
184
 
 * Convert 16-bit value from network byte order to host byte order.
185
 
 */
186
 
PJ_DEF(pj_uint16_t) pj_ntohs(pj_uint16_t netshort)
187
 
{
188
 
    return ntohs(netshort);
189
 
}
190
 
 
191
 
/*
192
 
 * Convert 16-bit value from host byte order to network byte order.
193
 
 */
194
 
PJ_DEF(pj_uint16_t) pj_htons(pj_uint16_t hostshort)
195
 
{
196
 
    return htons(hostshort);
197
 
}
198
 
 
199
 
/*
200
 
 * Convert 32-bit value from network byte order to host byte order.
201
 
 */
202
 
PJ_DEF(pj_uint32_t) pj_ntohl(pj_uint32_t netlong)
203
 
{
204
 
    return ntohl(netlong);
205
 
}
206
 
 
207
 
/*
208
 
 * Convert 32-bit value from host byte order to network byte order.
209
 
 */
210
 
PJ_DEF(pj_uint32_t) pj_htonl(pj_uint32_t hostlong)
211
 
{
212
 
    return htonl(hostlong);
213
 
}
214
 
 
215
 
/*
216
 
 * Convert an Internet host address given in network byte order
217
 
 * to string in standard numbers and dots notation.
218
 
 */
219
 
PJ_DEF(char*) pj_inet_ntoa(pj_in_addr inaddr)
220
 
{
221
 
#if !defined(PJ_LINUX) && !defined(PJ_LINUX_KERNEL)
222
 
    return inet_ntoa(*(struct in_addr*)&inaddr);
223
 
#else
224
 
    struct in_addr addr;
225
 
    addr.s_addr = inaddr.s_addr;
226
 
    return inet_ntoa(addr);
227
 
#endif
228
 
}
229
 
 
230
 
/*
231
 
 * This function converts the Internet host address cp from the standard
232
 
 * numbers-and-dots notation into binary data and stores it in the structure
233
 
 * that inp points to. 
234
 
 */
235
 
PJ_DEF(int) pj_inet_aton(const pj_str_t *cp, struct pj_in_addr *inp)
236
 
{
237
 
    char tempaddr[PJ_INET_ADDRSTRLEN];
238
 
 
239
 
    /* Initialize output with PJ_INADDR_NONE.
240
 
     * Some apps relies on this instead of the return value
241
 
     * (and anyway the return value is quite confusing!)
242
 
     */
243
 
    inp->s_addr = PJ_INADDR_NONE;
244
 
 
245
 
    /* Caution:
246
 
     *  this function might be called with cp->slen >= 16
247
 
     *  (i.e. when called with hostname to check if it's an IP addr).
248
 
     */
249
 
    PJ_ASSERT_RETURN(cp && cp->slen && inp, 0);
250
 
    if (cp->slen >= PJ_INET_ADDRSTRLEN) {
251
 
        return 0;
252
 
    }
253
 
 
254
 
    pj_memcpy(tempaddr, cp->ptr, cp->slen);
255
 
    tempaddr[cp->slen] = '\0';
256
 
 
257
 
#if defined(PJ_SOCK_HAS_INET_ATON) && PJ_SOCK_HAS_INET_ATON != 0
258
 
    return inet_aton(tempaddr, (struct in_addr*)inp);
259
 
#else
260
 
    inp->s_addr = inet_addr(tempaddr);
261
 
    return inp->s_addr == PJ_INADDR_NONE ? 0 : 1;
262
 
#endif
263
 
}
264
 
 
265
 
/*
266
 
 * Convert text to IPv4/IPv6 address.
267
 
 */
268
 
PJ_DEF(pj_status_t) pj_inet_pton(int af, const pj_str_t *src, void *dst)
269
 
{
270
 
    char tempaddr[PJ_INET6_ADDRSTRLEN];
271
 
 
272
 
    PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EAFNOTSUP);
273
 
    PJ_ASSERT_RETURN(src && src->slen && dst, PJ_EINVAL);
274
 
 
275
 
    /* Initialize output with PJ_IN_ADDR_NONE for IPv4 (to be 
276
 
     * compatible with pj_inet_aton()
277
 
     */
278
 
    if (af==PJ_AF_INET) {
279
 
        ((pj_in_addr*)dst)->s_addr = PJ_INADDR_NONE;
280
 
    }
281
 
 
282
 
    /* Caution:
283
 
     *  this function might be called with cp->slen >= 46
284
 
     *  (i.e. when called with hostname to check if it's an IP addr).
285
 
     */
286
 
    if (src->slen >= PJ_INET6_ADDRSTRLEN) {
287
 
        return PJ_ENAMETOOLONG;
288
 
    }
289
 
 
290
 
    pj_memcpy(tempaddr, src->ptr, src->slen);
291
 
    tempaddr[src->slen] = '\0';
292
 
 
293
 
#if defined(PJ_SOCK_HAS_INET_PTON) && PJ_SOCK_HAS_INET_PTON != 0
294
 
    /*
295
 
     * Implementation using inet_pton()
296
 
     */
297
 
    if (inet_pton(af, tempaddr, dst) != 1) {
298
 
        pj_status_t status = pj_get_netos_error();
299
 
        if (status == PJ_SUCCESS)
300
 
            status = PJ_EUNKNOWN;
301
 
 
302
 
        return status;
303
 
    }
304
 
 
305
 
    return PJ_SUCCESS;
306
 
 
307
 
#elif defined(PJ_WIN32) || defined(PJ_WIN32_WINCE)
308
 
    /*
309
 
     * Implementation on Windows, using WSAStringToAddress().
310
 
     * Should also work on Unicode systems.
311
 
     */
312
 
    {
313
 
        PJ_DECL_UNICODE_TEMP_BUF(wtempaddr,PJ_INET6_ADDRSTRLEN)
314
 
        pj_sockaddr sock_addr;
315
 
        int addr_len = sizeof(sock_addr);
316
 
        int rc;
317
 
 
318
 
        sock_addr.addr.sa_family = (pj_uint16_t)af;
319
 
        rc = WSAStringToAddress(
320
 
                PJ_STRING_TO_NATIVE(tempaddr,wtempaddr,sizeof(wtempaddr)), 
321
 
                af, NULL, (LPSOCKADDR)&sock_addr, &addr_len);
322
 
        if (rc != 0) {
323
 
            /* If you get rc 130022 Invalid argument (WSAEINVAL) with IPv6,
324
 
             * check that you have IPv6 enabled (install it in the network
325
 
             * adapter).
326
 
             */
327
 
            pj_status_t status = pj_get_netos_error();
328
 
            if (status == PJ_SUCCESS)
329
 
                status = PJ_EUNKNOWN;
330
 
 
331
 
            return status;
332
 
        }
333
 
 
334
 
        if (sock_addr.addr.sa_family == PJ_AF_INET) {
335
 
            pj_memcpy(dst, &sock_addr.ipv4.sin_addr, 4);
336
 
            return PJ_SUCCESS;
337
 
        } else if (sock_addr.addr.sa_family == PJ_AF_INET6) {
338
 
            pj_memcpy(dst, &sock_addr.ipv6.sin6_addr, 16);
339
 
            return PJ_SUCCESS;
340
 
        } else {
341
 
            pj_assert(!"Shouldn't happen");
342
 
            return PJ_EBUG;
343
 
        }
344
 
    }
345
 
#elif !defined(PJ_HAS_IPV6) || PJ_HAS_IPV6==0
346
 
    /* IPv6 support is disabled, just return error without raising assertion */
347
 
    return PJ_EIPV6NOTSUP;
348
 
#else
349
 
    pj_assert(!"Not supported");
350
 
    return PJ_EIPV6NOTSUP;
351
 
#endif
352
 
}
353
 
 
354
 
/*
355
 
 * Convert IPv4/IPv6 address to text.
356
 
 */
357
 
PJ_DEF(pj_status_t) pj_inet_ntop(int af, const void *src,
358
 
                                 char *dst, int size)
359
 
 
360
 
{
361
 
    PJ_ASSERT_RETURN(src && dst && size, PJ_EINVAL);
362
 
 
363
 
    *dst = '\0';
364
 
 
365
 
    PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EAFNOTSUP);
366
 
 
367
 
#if defined(PJ_SOCK_HAS_INET_NTOP) && PJ_SOCK_HAS_INET_NTOP != 0
368
 
    /*
369
 
     * Implementation using inet_ntop()
370
 
     */
371
 
    if (inet_ntop(af, src, dst, size) == NULL) {
372
 
        pj_status_t status = pj_get_netos_error();
373
 
        if (status == PJ_SUCCESS)
374
 
            status = PJ_EUNKNOWN;
375
 
 
376
 
        return status;
377
 
    }
378
 
 
379
 
    return PJ_SUCCESS;
380
 
 
381
 
#elif defined(PJ_WIN32) || defined(PJ_WIN32_WINCE)
382
 
    /*
383
 
     * Implementation on Windows, using WSAAddressToString().
384
 
     * Should also work on Unicode systems.
385
 
     */
386
 
    {
387
 
        PJ_DECL_UNICODE_TEMP_BUF(wtempaddr,PJ_INET6_ADDRSTRLEN)
388
 
        pj_sockaddr sock_addr;
389
 
        DWORD addr_len, addr_str_len;
390
 
        int rc;
391
 
 
392
 
        pj_bzero(&sock_addr, sizeof(sock_addr));
393
 
        sock_addr.addr.sa_family = (pj_uint16_t)af;
394
 
        if (af == PJ_AF_INET) {
395
 
            if (size < PJ_INET_ADDRSTRLEN)
396
 
                return PJ_ETOOSMALL;
397
 
            pj_memcpy(&sock_addr.ipv4.sin_addr, src, 4);
398
 
            addr_len = sizeof(pj_sockaddr_in);
399
 
            addr_str_len = PJ_INET_ADDRSTRLEN;
400
 
        } else if (af == PJ_AF_INET6) {
401
 
            if (size < PJ_INET6_ADDRSTRLEN)
402
 
                return PJ_ETOOSMALL;
403
 
            pj_memcpy(&sock_addr.ipv6.sin6_addr, src, 16);
404
 
            addr_len = sizeof(pj_sockaddr_in6);
405
 
            addr_str_len = PJ_INET6_ADDRSTRLEN;
406
 
        } else {
407
 
            pj_assert(!"Unsupported address family");
408
 
            return PJ_EAFNOTSUP;
409
 
        }
410
 
 
411
 
#if PJ_NATIVE_STRING_IS_UNICODE
412
 
        rc = WSAAddressToString((LPSOCKADDR)&sock_addr, addr_len,
413
 
                                NULL, wtempaddr, &addr_str_len);
414
 
        if (rc == 0) {
415
 
            pj_unicode_to_ansi(wtempaddr, wcslen(wtempaddr), dst, size);
416
 
        }
417
 
#else
418
 
        rc = WSAAddressToString((LPSOCKADDR)&sock_addr, addr_len,
419
 
                                NULL, dst, &addr_str_len);
420
 
#endif
421
 
 
422
 
        if (rc != 0) {
423
 
            pj_status_t status = pj_get_netos_error();
424
 
            if (status == PJ_SUCCESS)
425
 
                status = PJ_EUNKNOWN;
426
 
 
427
 
            return status;
428
 
        }
429
 
 
430
 
        return PJ_SUCCESS;
431
 
    }
432
 
 
433
 
#elif !defined(PJ_HAS_IPV6) || PJ_HAS_IPV6==0
434
 
    /* IPv6 support is disabled, just return error without raising assertion */
435
 
    return PJ_EIPV6NOTSUP;
436
 
#else
437
 
    pj_assert(!"Not supported");
438
 
    return PJ_EIPV6NOTSUP;
439
 
#endif
440
 
}
441
 
 
442
 
/*
443
 
 * Get hostname.
444
 
 */
445
 
PJ_DEF(const pj_str_t*) pj_gethostname(void)
446
 
{
447
 
    static char buf[PJ_MAX_HOSTNAME];
448
 
    static pj_str_t hostname;
449
 
 
450
 
    PJ_CHECK_STACK();
451
 
 
452
 
    if (hostname.ptr == NULL) {
453
 
        hostname.ptr = buf;
454
 
        if (gethostname(buf, sizeof(buf)) != 0) {
455
 
            hostname.ptr[0] = '\0';
456
 
            hostname.slen = 0;
457
 
        } else {
458
 
            hostname.slen = strlen(buf);
459
 
        }
460
 
    }
461
 
    return &hostname;
462
 
}
463
 
 
464
 
#if defined(PJ_WIN32)
465
 
/*
466
 
 * Create new socket/endpoint for communication and returns a descriptor.
467
 
 */
468
 
PJ_DEF(pj_status_t) pj_sock_socket(int af, 
469
 
                                   int type, 
470
 
                                   int proto,
471
 
                                   pj_sock_t *sock)
472
 
{
473
 
    PJ_CHECK_STACK();
474
 
 
475
 
    /* Sanity checks. */
476
 
    PJ_ASSERT_RETURN(sock!=NULL, PJ_EINVAL);
477
 
    PJ_ASSERT_RETURN((unsigned)PJ_INVALID_SOCKET==INVALID_SOCKET, 
478
 
                     (*sock=PJ_INVALID_SOCKET, PJ_EINVAL));
479
 
 
480
 
    *sock = WSASocket(af, type, proto, NULL, 0, WSA_FLAG_OVERLAPPED);
481
 
 
482
 
    if (*sock == PJ_INVALID_SOCKET) 
483
 
        return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
484
 
    
485
 
#if PJ_SOCK_DISABLE_WSAECONNRESET && \
486
 
    (!defined(PJ_WIN32_WINCE) || PJ_WIN32_WINCE==0)
487
 
 
488
 
#ifndef SIO_UDP_CONNRESET
489
 
    #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
490
 
#endif
491
 
 
492
 
    /* Disable WSAECONNRESET for UDP.
493
 
     * See https://trac.pjsip.org/repos/ticket/1197
494
 
     */
495
 
    if (type==PJ_SOCK_DGRAM) {
496
 
        DWORD dwBytesReturned = 0;
497
 
        BOOL bNewBehavior = FALSE;
498
 
        DWORD rc;
499
 
 
500
 
        rc = WSAIoctl(*sock, SIO_UDP_CONNRESET,
501
 
                      &bNewBehavior, sizeof(bNewBehavior),
502
 
                      NULL, 0, &dwBytesReturned,
503
 
                      NULL, NULL);
504
 
 
505
 
        if (rc==SOCKET_ERROR) {
506
 
            // Ignored..
507
 
        }
508
 
    }
509
 
#endif
510
 
 
511
 
    return PJ_SUCCESS;
512
 
}
513
 
 
514
 
#else
515
 
/*
516
 
 * Create new socket/endpoint for communication and returns a descriptor.
517
 
 */
518
 
PJ_DEF(pj_status_t) pj_sock_socket(int af, 
519
 
                                   int type, 
520
 
                                   int proto, 
521
 
                                   pj_sock_t *sock)
522
 
{
523
 
 
524
 
    PJ_CHECK_STACK();
525
 
 
526
 
    /* Sanity checks. */
527
 
    PJ_ASSERT_RETURN(sock!=NULL, PJ_EINVAL);
528
 
    PJ_ASSERT_RETURN(PJ_INVALID_SOCKET==-1, 
529
 
                     (*sock=PJ_INVALID_SOCKET, PJ_EINVAL));
530
 
    
531
 
    *sock = socket(af, type, proto);
532
 
    if (*sock == PJ_INVALID_SOCKET)
533
 
        return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
534
 
    else {
535
 
        pj_int32_t val = 1;
536
 
        if (type == pj_SOCK_STREAM()) {
537
 
            pj_sock_setsockopt(*sock, pj_SOL_SOCKET(), pj_SO_NOSIGPIPE(),
538
 
                               &val, sizeof(val));
539
 
        }
540
 
#if defined(PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT) && \
541
 
    PJ_IPHONE_OS_HAS_MULTITASKING_SUPPORT!=0
542
 
        if (type == pj_SOCK_DGRAM()) {
543
 
            pj_sock_setsockopt(*sock, pj_SOL_SOCKET(), SO_NOSIGPIPE, 
544
 
                               &val, sizeof(val));
545
 
        }
546
 
#endif
547
 
        return PJ_SUCCESS;
548
 
    }
549
 
}
550
 
#endif
551
 
 
552
 
/*
553
 
 * Bind socket.
554
 
 */
555
 
PJ_DEF(pj_status_t) pj_sock_bind( pj_sock_t sock, 
556
 
                                  const pj_sockaddr_t *addr,
557
 
                                  int len)
558
 
{
559
 
    PJ_CHECK_STACK();
560
 
 
561
 
    PJ_ASSERT_RETURN(addr && len >= (int)sizeof(struct sockaddr_in), PJ_EINVAL);
562
 
 
563
 
    CHECK_ADDR_LEN(addr, len);
564
 
 
565
 
    if (bind(sock, (struct sockaddr*)addr, len) != 0)
566
 
        return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
567
 
    else
568
 
        return PJ_SUCCESS;
569
 
}
570
 
 
571
 
 
572
 
/*
573
 
 * Bind socket.
574
 
 */
575
 
PJ_DEF(pj_status_t) pj_sock_bind_in( pj_sock_t sock, 
576
 
                                     pj_uint32_t addr32,
577
 
                                     pj_uint16_t port)
578
 
{
579
 
    pj_sockaddr_in addr;
580
 
 
581
 
    PJ_CHECK_STACK();
582
 
 
583
 
    PJ_SOCKADDR_SET_LEN(&addr, sizeof(pj_sockaddr_in));
584
 
    addr.sin_family = PJ_AF_INET;
585
 
    pj_bzero(addr.sin_zero, sizeof(addr.sin_zero));
586
 
    addr.sin_addr.s_addr = pj_htonl(addr32);
587
 
    addr.sin_port = pj_htons(port);
588
 
 
589
 
    return pj_sock_bind(sock, &addr, sizeof(pj_sockaddr_in));
590
 
}
591
 
 
592
 
 
593
 
/*
594
 
 * Close socket.
595
 
 */
596
 
PJ_DEF(pj_status_t) pj_sock_close(pj_sock_t sock)
597
 
{
598
 
    int rc;
599
 
 
600
 
    PJ_CHECK_STACK();
601
 
#if defined(PJ_WIN32) && PJ_WIN32!=0 || \
602
 
    defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE!=0
603
 
    rc = closesocket(sock);
604
 
#else
605
 
    rc = close(sock);
606
 
#endif
607
 
 
608
 
    if (rc != 0)
609
 
        return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
610
 
    else
611
 
        return PJ_SUCCESS;
612
 
}
613
 
 
614
 
/*
615
 
 * Get remote's name.
616
 
 */
617
 
PJ_DEF(pj_status_t) pj_sock_getpeername( pj_sock_t sock,
618
 
                                         pj_sockaddr_t *addr,
619
 
                                         int *namelen)
620
 
{
621
 
    PJ_CHECK_STACK();
622
 
    if (getpeername(sock, (struct sockaddr*)addr, (socklen_t*)namelen) != 0)
623
 
        return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
624
 
    else {
625
 
        PJ_SOCKADDR_RESET_LEN(addr);
626
 
        return PJ_SUCCESS;
627
 
    }
628
 
}
629
 
 
630
 
/*
631
 
 * Get socket name.
632
 
 */
633
 
PJ_DEF(pj_status_t) pj_sock_getsockname( pj_sock_t sock,
634
 
                                         pj_sockaddr_t *addr,
635
 
                                         int *namelen)
636
 
{
637
 
    PJ_CHECK_STACK();
638
 
    if (getsockname(sock, (struct sockaddr*)addr, (socklen_t*)namelen) != 0)
639
 
        return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
640
 
    else {
641
 
        PJ_SOCKADDR_RESET_LEN(addr);
642
 
        return PJ_SUCCESS;
643
 
    }
644
 
}
645
 
 
646
 
/*
647
 
 * Send data
648
 
 */
649
 
PJ_DEF(pj_status_t) pj_sock_send(pj_sock_t sock,
650
 
                                 const void *buf,
651
 
                                 pj_ssize_t *len,
652
 
                                 unsigned flags)
653
 
{
654
 
    PJ_CHECK_STACK();
655
 
    PJ_ASSERT_RETURN(len, PJ_EINVAL);
656
 
 
657
 
#ifdef MSG_NOSIGNAL
658
 
    /* Suppress SIGPIPE. See https://trac.pjsip.org/repos/ticket/1538 */
659
 
    flags |= MSG_NOSIGNAL;
660
 
#endif
661
 
 
662
 
    *len = send(sock, (const char*)buf, *len, flags);
663
 
 
664
 
    if (*len < 0)
665
 
        return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
666
 
    else
667
 
        return PJ_SUCCESS;
668
 
}
669
 
 
670
 
 
671
 
/*
672
 
 * Send data.
673
 
 */
674
 
PJ_DEF(pj_status_t) pj_sock_sendto(pj_sock_t sock,
675
 
                                   const void *buf,
676
 
                                   pj_ssize_t *len,
677
 
                                   unsigned flags,
678
 
                                   const pj_sockaddr_t *to,
679
 
                                   int tolen)
680
 
{
681
 
    PJ_CHECK_STACK();
682
 
    PJ_ASSERT_RETURN(len, PJ_EINVAL);
683
 
    
684
 
    CHECK_ADDR_LEN(to, tolen);
685
 
 
686
 
    *len = sendto(sock, (const char*)buf, *len, flags, 
687
 
                  (const struct sockaddr*)to, tolen);
688
 
 
689
 
    if (*len < 0) 
690
 
        return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
691
 
    else 
692
 
        return PJ_SUCCESS;
693
 
}
694
 
 
695
 
/*
696
 
 * Receive data.
697
 
 */
698
 
PJ_DEF(pj_status_t) pj_sock_recv(pj_sock_t sock,
699
 
                                 void *buf,
700
 
                                 pj_ssize_t *len,
701
 
                                 unsigned flags)
702
 
{
703
 
    PJ_CHECK_STACK();
704
 
    PJ_ASSERT_RETURN(buf && len, PJ_EINVAL);
705
 
 
706
 
    *len = recv(sock, (char*)buf, *len, flags);
707
 
 
708
 
    if (*len < 0) 
709
 
        return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
710
 
    else
711
 
        return PJ_SUCCESS;
712
 
}
713
 
 
714
 
/*
715
 
 * Receive data.
716
 
 */
717
 
PJ_DEF(pj_status_t) pj_sock_recvfrom(pj_sock_t sock,
718
 
                                     void *buf,
719
 
                                     pj_ssize_t *len,
720
 
                                     unsigned flags,
721
 
                                     pj_sockaddr_t *from,
722
 
                                     int *fromlen)
723
 
{
724
 
    PJ_CHECK_STACK();
725
 
    PJ_ASSERT_RETURN(buf && len, PJ_EINVAL);
726
 
 
727
 
    *len = recvfrom(sock, (char*)buf, *len, flags, 
728
 
                    (struct sockaddr*)from, (socklen_t*)fromlen);
729
 
 
730
 
    if (*len < 0) 
731
 
        return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
732
 
    else {
733
 
        if (from) {
734
 
            PJ_SOCKADDR_RESET_LEN(from);
735
 
        }
736
 
        return PJ_SUCCESS;
737
 
    }
738
 
}
739
 
 
740
 
/*
741
 
 * Get socket option.
742
 
 */
743
 
PJ_DEF(pj_status_t) pj_sock_getsockopt( pj_sock_t sock,
744
 
                                        pj_uint16_t level,
745
 
                                        pj_uint16_t optname,
746
 
                                        void *optval,
747
 
                                        int *optlen)
748
 
{
749
 
    PJ_CHECK_STACK();
750
 
    PJ_ASSERT_RETURN(optval && optlen, PJ_EINVAL);
751
 
 
752
 
    if (getsockopt(sock, level, optname, (char*)optval, (socklen_t*)optlen)!=0)
753
 
        return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
754
 
    else
755
 
        return PJ_SUCCESS;
756
 
}
757
 
 
758
 
/*
759
 
 * Set socket option.
760
 
 */
761
 
PJ_DEF(pj_status_t) pj_sock_setsockopt( pj_sock_t sock,
762
 
                                        pj_uint16_t level,
763
 
                                        pj_uint16_t optname,
764
 
                                        const void *optval,
765
 
                                        int optlen)
766
 
{
767
 
    PJ_CHECK_STACK();
768
 
    if (setsockopt(sock, level, optname, (const char*)optval, optlen) != 0)
769
 
        return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
770
 
    else
771
 
        return PJ_SUCCESS;
772
 
}
773
 
 
774
 
/*
775
 
 * Connect socket.
776
 
 */
777
 
PJ_DEF(pj_status_t) pj_sock_connect( pj_sock_t sock,
778
 
                                     const pj_sockaddr_t *addr,
779
 
                                     int namelen)
780
 
{
781
 
    PJ_CHECK_STACK();
782
 
    if (connect(sock, (struct sockaddr*)addr, namelen) != 0)
783
 
        return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
784
 
    else
785
 
        return PJ_SUCCESS;
786
 
}
787
 
 
788
 
 
789
 
/*
790
 
 * Shutdown socket.
791
 
 */
792
 
#if PJ_HAS_TCP
793
 
PJ_DEF(pj_status_t) pj_sock_shutdown( pj_sock_t sock,
794
 
                                      int how)
795
 
{
796
 
    PJ_CHECK_STACK();
797
 
    if (shutdown(sock, how) != 0)
798
 
        return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
799
 
    else
800
 
        return PJ_SUCCESS;
801
 
}
802
 
 
803
 
/*
804
 
 * Start listening to incoming connections.
805
 
 */
806
 
PJ_DEF(pj_status_t) pj_sock_listen( pj_sock_t sock,
807
 
                                    int backlog)
808
 
{
809
 
    PJ_CHECK_STACK();
810
 
    if (listen(sock, backlog) != 0)
811
 
        return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
812
 
    else
813
 
        return PJ_SUCCESS;
814
 
}
815
 
 
816
 
/*
817
 
 * Accept incoming connections
818
 
 */
819
 
PJ_DEF(pj_status_t) pj_sock_accept( pj_sock_t serverfd,
820
 
                                    pj_sock_t *newsock,
821
 
                                    pj_sockaddr_t *addr,
822
 
                                    int *addrlen)
823
 
{
824
 
    PJ_CHECK_STACK();
825
 
    PJ_ASSERT_RETURN(newsock != NULL, PJ_EINVAL);
826
 
 
827
 
#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0
828
 
    if (addr) {
829
 
        PJ_SOCKADDR_SET_LEN(addr, *addrlen);
830
 
    }
831
 
#endif
832
 
    
833
 
    *newsock = accept(serverfd, (struct sockaddr*)addr, (socklen_t*)addrlen);
834
 
    if (*newsock==PJ_INVALID_SOCKET)
835
 
        return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
836
 
    else {
837
 
        
838
 
#if defined(PJ_SOCKADDR_HAS_LEN) && PJ_SOCKADDR_HAS_LEN!=0
839
 
        if (addr) {
840
 
            PJ_SOCKADDR_RESET_LEN(addr);
841
 
        }
842
 
#endif
843
 
            
844
 
        return PJ_SUCCESS;
845
 
    }
846
 
}
847
 
#endif  /* PJ_HAS_TCP */
848
 
 
849