Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ipv6/src/external/enet/unix.c @ 7389

Last change on this file since 7389 was 7389, checked in by adrfried, 15 years ago

fix some stuff

File size: 11.6 KB
RevLine 
[7328]1/**
2 @file  unix.c
3 @brief ENet Unix system specific functions
4*/
5#ifndef WIN32
6
7#include <sys/types.h>
8#include <sys/socket.h>
9#include <sys/ioctl.h>
10#include <sys/time.h>
11#include <arpa/inet.h>
12#include <netdb.h>
13#include <unistd.h>
14#include <string.h>
15#include <errno.h>
16#include <time.h>
17
18#define ENET_BUILDING_LIB 1
19#include "enet/enet.h"
20
21#ifdef HAS_FCNTL
22#include <fcntl.h>
23#endif
24
25#ifdef __APPLE__
26#undef HAS_POLL
27#endif
28
29#ifdef HAS_POLL
30#include <sys/poll.h>
31#endif
32
33#ifndef HAS_SOCKLEN_T
34typedef int socklen_t;
35#endif
36
37#ifndef MSG_NOSIGNAL
38#define MSG_NOSIGNAL 0
39#endif
40
41static enet_uint32 timeBase = 0;
42
43int
44enet_initialize (void)
45{
46    return 0;
47}
48
49void
50enet_deinitialize (void)
51{
52}
53
54enet_uint32
55enet_time_get (void)
56{
57    struct timeval timeVal;
58
59    gettimeofday (& timeVal, NULL);
60
61    return timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - timeBase;
62}
63
64void
65enet_time_set (enet_uint32 newTimeBase)
66{
67    struct timeval timeVal;
68
69    gettimeofday (& timeVal, NULL);
70   
71    timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
72}
73
[7377]74static enet_uint16
75enet_af (ENetAddressFamily family)
76{
77    if (family == ENET_IPV4)
78        return AF_INET;
79    if (family == ENET_IPV6)
80        return AF_INET6;
81    return 0;
82}
83
84static socklen_t
85enet_sa_size (ENetAddressFamily family)
86{
87    if (family == ENET_IPV4)
88        return sizeof (struct sockaddr_in);
89    if (family == ENET_IPV6)
90        return sizeof (struct sockaddr_in6);
91    return 0;
92}
93
94
95static ENetAddressFamily
96enet_address_set_address (ENetAddress * address, const struct sockaddr * sin)
97{
98    memset (address, 0, sizeof (ENetAddress));
99    if (sin -> sa_family == AF_INET)
100    {
101        address -> host = enet_address_map4 ((((struct sockaddr_in *) sin) -> sin_addr.s_addr));
102        //address -> scopeID = 0;
103        address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in *) sin) -> sin_port);
104        return ENET_IPV4;
105    }
106    if (sin -> sa_family == AF_INET6)
107    {
108        address -> host = * (ENetHostAddress *) & ((struct sockaddr_in6 *) sin) -> sin6_addr;
109        address -> scopeID = ((struct sockaddr_in6 *) sin) -> sin6_scope_id;
110        address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in6 *) sin) -> sin6_port);
111        return ENET_IPV6;
112    }
113    return ENET_NO_ADDRESS_FAMILY;
114}
115
116static int
117enet_address_set_sin (struct sockaddr * sin, const ENetAddress * address, ENetAddressFamily family)
118{
119    memset (sin, 0, enet_sa_size(family));
120    if (family == ENET_IPV4 &&
121      (enet_get_address_family (address) == ENET_IPV4 ||
[7389]122      !memcmp (& address -> host, & ENET_HOST_ANY, sizeof(ENetHostAddress))))
[7377]123    {
124        ((struct sockaddr_in *) sin) -> sin_family = AF_INET;
125        ((struct sockaddr_in *) sin) -> sin_addr = * (struct in_addr *) & address -> host.addr[12];
126        ((struct sockaddr_in *) sin) -> sin_port = ENET_HOST_TO_NET_16 (address -> port);
127        return 0;
128    }
129    else if (family == ENET_IPV6)
130    {
131        ((struct sockaddr_in6 *) sin) -> sin6_family = AF_INET6;
132        ((struct sockaddr_in6 *) sin) -> sin6_addr = * (struct in6_addr *) & address -> host;
133        ((struct sockaddr_in6 *) sin) -> sin6_scope_id = address -> scopeID;
134        ((struct sockaddr_in6 *) sin) -> sin6_port = ENET_HOST_TO_NET_16 (address -> port);
135        return 0;
136    }
137    return -1;
138}
139
[7328]140int
141enet_address_set_host (ENetAddress * address, const char * name)
142{
[7377]143    enet_uint16 port = address -> port;
[7330]144    struct addrinfo hints;
145    struct addrinfo * result;
146    struct addrinfo * res;
[7328]147
[7330]148    memset(& hints, 0, sizeof (hints));
149    hints.ai_flags = AI_NUMERICSERV | AI_ADDRCONFIG;
150    hints.ai_family = AF_UNSPEC;
[7328]151
[7330]152    if ( getaddrinfo(name, NULL, &hints, &result) )
153        return -1;
[7328]154
[7330]155    for (res = result; res != NULL; res = res -> ai_next)
156    {
[7377]157        if ( enet_address_set_address(address, res -> ai_addr) != ENET_NO_ADDRESS_FAMILY )
[7330]158            break;
159    }
[7377]160
161    address -> port = port;
[7330]162    freeaddrinfo(result);
163    if (res == NULL) return -1;
[7328]164
165    return 0;
166}
167
[7330]168static int
169enet_address_get_host_x (const ENetAddress * address, char * name, size_t nameLength, int flags)
[7328]170{
[7377]171    struct sockaddr_storage sin;
172    enet_address_set_sin((struct sockaddr *) & sin, address, ENET_IPV6);
[7330]173
[7377]174    if ( getnameinfo((struct sockaddr *) & sin, enet_sa_size (ENET_IPV6), name, nameLength, NULL, 0, flags))
[7328]175        return -1;
[7330]176
[7328]177    return 0;
178}
179
180int
[7330]181enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
182{
183    return enet_address_get_host_x(address, name, nameLength, NI_NUMERICHOST);
184}
185
186int
[7328]187enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
188{
[7330]189    return enet_address_get_host_x(address, name, nameLength, 0);
[7328]190}
191
192int
[7377]193enet_socket_bind (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
[7328]194{
[7377]195    struct sockaddr_storage sin;
[7328]196
197    if (address != NULL)
198    {
[7377]199        enet_address_set_sin((struct sockaddr *) & sin, address, family);
[7328]200    }
201    else
202    {
[7377]203        ENetAddress address_ = { ENET_HOST_ANY, 0, 0 };
204        enet_address_set_sin((struct sockaddr *) & sin, & address_, family);
[7328]205    }
206
[7377]207    return bind (socket, (struct sockaddr *) & sin, enet_sa_size(family));
[7328]208}
209
[7377]210int
[7328]211enet_socket_listen (ENetSocket socket, int backlog)
212{
213    return listen (socket, backlog < 0 ? SOMAXCONN : backlog);
214}
215
216ENetSocket
[7377]217enet_socket_create (ENetSocketType type, ENetAddressFamily family)
[7328]218{
[7377]219    ENetSocket sock = socket (enet_af (family), type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
220
221#ifdef IPV6_V6ONLY
222    if (family == ENET_IPV6)
223    {
224        int value = 1;
225        setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, & value, sizeof (int));
226    }
227#endif // IPV6_V6ONLY
228
229    return sock;
[7328]230}
231
232int
233enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
234{
235    int result = -1;
236    switch (option)
237    {
238        case ENET_SOCKOPT_NONBLOCK:
239#ifdef HAS_FCNTL
240            result = fcntl (socket, F_SETFL, O_NONBLOCK | fcntl (socket, F_GETFL));
241#else
242            result = ioctl (socket, FIONBIO, & value);
243#endif
244            break;
245
246        case ENET_SOCKOPT_BROADCAST:
247            result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
248            break;
249
250        case ENET_SOCKOPT_REUSEADDR:
251            result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
252            break;
253
254        case ENET_SOCKOPT_RCVBUF:
255            result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
256            break;
257
258        case ENET_SOCKOPT_SNDBUF:
259            result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
260            break;
261
262        default:
263            break;
264    }
265    return result == -1 ? -1 : 0;
266}
267
268int
[7377]269enet_socket_connect (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
[7328]270{
[7377]271    struct sockaddr_storage sin;
272    enet_address_set_sin((struct sockaddr *) & sin, address, family);
[7328]273
[7377]274    return connect (socket, (struct sockaddr *) & sin, enet_sa_size (family));
[7328]275}
276
277ENetSocket
[7377]278enet_socket_accept (ENetSocket socket, ENetAddress * address, ENetAddressFamily family)
[7328]279{
280    int result;
[7377]281    struct sockaddr_storage sin;
282    socklen_t sinLength = enet_sa_size (family);
[7328]283
284    result = accept (socket, 
285                     address != NULL ? (struct sockaddr *) & sin : NULL, 
286                     address != NULL ? & sinLength : NULL);
[7377]287
[7328]288    if (result == -1)
289      return ENET_SOCKET_NULL;
290
291    if (address != NULL)
292    {
[7377]293        enet_address_set_address(address, (struct sockaddr *) & sin);
[7328]294    }
295
296    return result;
297} 
298   
299void
300enet_socket_destroy (ENetSocket socket)
301{
302    close (socket);
303}
304
305int
306enet_socket_send (ENetSocket socket,
307                  const ENetAddress * address,
308                  const ENetBuffer * buffers,
[7377]309                  size_t bufferCount,
310                  ENetAddressFamily family)
[7328]311{
312    struct msghdr msgHdr;
[7377]313    struct sockaddr_storage sin;
[7328]314    int sentLength;
315
316    memset (& msgHdr, 0, sizeof (struct msghdr));
317
318    if (address != NULL)
319    {
[7377]320        enet_address_set_sin((struct sockaddr *) & sin, address, family);
[7328]321        msgHdr.msg_name = & sin;
[7377]322        msgHdr.msg_namelen = enet_sa_size (family);
[7328]323    }
324
325    msgHdr.msg_iov = (struct iovec *) buffers;
326    msgHdr.msg_iovlen = bufferCount;
327
328    sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL);
329   
330    if (sentLength == -1)
331    {
332       if (errno == EWOULDBLOCK)
333         return 0;
334
335       return -1;
336    }
337
338    return sentLength;
339}
340
341int
342enet_socket_receive (ENetSocket socket,
343                     ENetAddress * address,
344                     ENetBuffer * buffers,
[7377]345                     size_t bufferCount,
346                     ENetAddressFamily family)
[7328]347{
348    struct msghdr msgHdr;
[7377]349    struct sockaddr_storage sin;
[7328]350    int recvLength;
351
352    memset (& msgHdr, 0, sizeof (struct msghdr));
353
354    if (address != NULL)
355    {
356        msgHdr.msg_name = & sin;
[7377]357        msgHdr.msg_namelen = enet_sa_size (family);
[7328]358    }
359
360    msgHdr.msg_iov = (struct iovec *) buffers;
361    msgHdr.msg_iovlen = bufferCount;
362
363    recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL);
364
365    if (recvLength == -1)
366    {
367       if (errno == EWOULDBLOCK)
368         return 0;
369
370       return -1;
371    }
372
373#ifdef HAS_MSGHDR_FLAGS
374    if (msgHdr.msg_flags & MSG_TRUNC)
375      return -1;
376#endif
377
378    if (address != NULL)
379    {
[7377]380        enet_address_set_address(address, (struct sockaddr *) & sin);
[7328]381    }
382
383    return recvLength;
384}
385
386int
387enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
388{
389    struct timeval timeVal;
390
391    timeVal.tv_sec = timeout / 1000;
392    timeVal.tv_usec = (timeout % 1000) * 1000;
393
394    return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
395}
396
397int
[7377]398enet_socket_wait (ENetSocket socket4, ENetSocket socket6, enet_uint32 * condition, enet_uint32 timeout)
[7328]399{
[7377]400//#ifdef HAS_POLL
401    struct pollfd pollSocket[2];
[7328]402    int pollCount;
[7389]403
[7377]404    pollSocket[0].fd = socket4;
405    pollSocket[1].fd = socket6;
406    pollSocket[0].events = 0;
407    pollSocket[1].events = 0;
[7389]408    //pollSocket[0].revents = 0;
409    pollSocket[1].revents = 0;
[7328]410
[7389]411    if (pollSocket[0].fd == ENET_SOCKET_NULL)
412    {
413        pollSocket[0].fd = pollSocket[1].fd;
414        pollSocket[1].fd = ENET_SOCKET_NULL;
415    }
416
[7328]417    if (* condition & ENET_SOCKET_WAIT_SEND)
[7377]418    {
419        pollSocket[0].events |= POLLOUT;
420        pollSocket[1].events |= POLLOUT;
421    }
[7328]422
423    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
[7377]424    {
425        pollSocket[0].events |= POLLIN;
426        pollSocket[1].events |= POLLIN;
427    }
[7328]428
[7389]429    pollCount = poll (pollSocket, pollSocket[1].fd != ENET_SOCKET_NULL ? 2 : 1, timeout);
[7328]430
431    if (pollCount < 0)
432      return -1;
433
434    * condition = ENET_SOCKET_WAIT_NONE;
435
436    if (pollCount == 0)
437      return 0;
438
[7377]439    if ((pollSocket[0].revents | pollSocket[1].revents) & POLLOUT)
[7328]440      * condition |= ENET_SOCKET_WAIT_SEND;
441   
[7377]442    if ((pollSocket[0].revents | pollSocket[1].revents) & POLLIN)
[7328]443      * condition |= ENET_SOCKET_WAIT_RECEIVE;
444
445    return 0;
[7377]446/*
[7389]447FIXME: implement or remove this
[7328]448#else
449    fd_set readSet, writeSet;
450    struct timeval timeVal;
451    int selectCount;
452
453    timeVal.tv_sec = timeout / 1000;
454    timeVal.tv_usec = (timeout % 1000) * 1000;
455
456    FD_ZERO (& readSet);
457    FD_ZERO (& writeSet);
458
459    if (* condition & ENET_SOCKET_WAIT_SEND)
460      FD_SET (socket, & writeSet);
461
462    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
463      FD_SET (socket, & readSet);
464
465    selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
466
467    if (selectCount < 0)
468      return -1;
469
470    * condition = ENET_SOCKET_WAIT_NONE;
471
472    if (selectCount == 0)
473      return 0;
474
475    if (FD_ISSET (socket, & writeSet))
476      * condition |= ENET_SOCKET_WAIT_SEND;
477
478    if (FD_ISSET (socket, & readSet))
479      * condition |= ENET_SOCKET_WAIT_RECEIVE;
480
481    return 0;
482#endif
[7377]483*/
[7328]484}
485
486#endif
487
Note: See TracBrowser for help on using the repository browser.