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

« back to all changes in this revision

Viewing changes to sflphone-common/libs/pjproject/pjlib/src/pj/sock_bsd.c

  • Committer: Package Import Robot
  • Author(s): Francois Marier
  • Date: 2011-11-25 13:24:12 UTC
  • mfrom: (4.1.10 sid)
  • Revision ID: package-import@ubuntu.com-20111125132412-dc4qvhyosk74cd42
Tags: 1.0.1-4
Don't assume that arch:all packages will get built (closes: #649726)

Show diffs side-by-side

added added

removed removed

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