3 @brief ENet Unix system specific functions
8 #include <sys/socket.h>
11 #include <sys/param.h>
12 #include <arpa/inet.h>
19 #define ENET_BUILDING_LIB 1
20 #include "enet/enet.h"
35 typedef int socklen_t
;
39 #define MSG_NOSIGNAL 0
42 static enet_uint32 timeBase
= 0;
45 enet_initialize (void)
51 enet_deinitialize (void)
58 struct timeval timeVal
;
60 gettimeofday (& timeVal
, NULL
);
62 return timeVal
.tv_sec
* 1000 + timeVal
.tv_usec
/ 1000 - timeBase
;
66 enet_time_set (enet_uint32 newTimeBase
)
68 struct timeval timeVal
;
70 gettimeofday (& timeVal
, NULL
);
72 timeBase
= timeVal
.tv_sec
* 1000 + timeVal
.tv_usec
/ 1000 - newTimeBase
;
76 enet_address_set_host (ENetAddress
* address
, const char * name
)
78 struct hostent
* hostEntry
= NULL
;
79 #ifdef HAS_GETHOSTBYNAME_R
80 struct hostent hostData
;
84 #if defined(linux) || defined(__GLIBC__) || defined(__GNU__) || (defined(__DragonFly__) && __DragonFly_version >= 200202)
85 gethostbyname_r (name
, & hostData
, buffer
, sizeof (buffer
), & hostEntry
, & errnum
);
87 hostEntry
= gethostbyname_r (name
, & hostData
, buffer
, sizeof (buffer
), & errnum
);
90 hostEntry
= gethostbyname (name
);
93 if (hostEntry
== NULL
||
94 hostEntry
-> h_addrtype
!= AF_INET
)
97 if (! inet_pton (AF_INET
, name
, & address
-> host
))
99 if (! inet_aton (name
, (struct in_addr
*) & address
-> host
))
105 address
-> host
= * (enet_uint32
*) hostEntry
-> h_addr_list
[0];
111 enet_address_get_host (const ENetAddress
* address
, char * name
, size_t nameLength
)
114 struct hostent
* hostEntry
= NULL
;
115 #ifdef HAS_GETHOSTBYADDR_R
116 struct hostent hostData
;
120 in
.s_addr
= address
-> host
;
122 #if defined(linux) || defined(__GLIBC__) || defined(__GNU__) || (defined(__DragonFly__) && __DragonFly_version >= 200202)
123 gethostbyaddr_r ((char *) & in
, sizeof (struct in_addr
), AF_INET
, & hostData
, buffer
, sizeof (buffer
), & hostEntry
, & errnum
);
125 hostEntry
= gethostbyaddr_r ((char *) & in
, sizeof (struct in_addr
), AF_INET
, & hostData
, buffer
, sizeof (buffer
), & errnum
);
128 in
.s_addr
= address
-> host
;
130 hostEntry
= gethostbyaddr ((char *) & in
, sizeof (struct in_addr
), AF_INET
);
133 if (hostEntry
== NULL
)
136 if (inet_ntop (AF_INET
, & address
-> host
, name
, nameLength
) == NULL
)
138 char * addr
= inet_ntoa (* (struct in_addr
*) & address
-> host
);
140 strncpy (name
, addr
, nameLength
);
147 strncpy (name
, hostEntry
-> h_name
, nameLength
);
153 enet_socket_create (ENetSocketType type
, const ENetAddress
* address
)
155 ENetSocket newSocket
= socket (PF_INET
, type
== ENET_SOCKET_TYPE_DATAGRAM
? SOCK_DGRAM
: SOCK_STREAM
, 0);
156 int receiveBufferSize
= ENET_HOST_RECEIVE_BUFFER_SIZE
,
157 allowBroadcasting
= 1;
161 struct sockaddr_in sin
;
163 if (newSocket
== ENET_SOCKET_NULL
)
164 return ENET_SOCKET_NULL
;
166 if (type
== ENET_SOCKET_TYPE_DATAGRAM
)
169 fcntl (newSocket
, F_SETFL
, O_NONBLOCK
| fcntl (newSocket
, F_GETFL
));
171 ioctl (newSocket
, FIONBIO
, & nonBlocking
);
174 setsockopt (newSocket
, SOL_SOCKET
, SO_RCVBUF
, (char *) & receiveBufferSize
, sizeof (int));
175 setsockopt (newSocket
, SOL_SOCKET
, SO_BROADCAST
, (char *) & allowBroadcasting
, sizeof (int));
181 memset (& sin
, 0, sizeof (struct sockaddr_in
));
183 sin
.sin_family
= AF_INET
;
184 sin
.sin_port
= ENET_HOST_TO_NET_16 (address
-> port
);
185 sin
.sin_addr
.s_addr
= address
-> host
;
188 (struct sockaddr
*) & sin
,
189 sizeof (struct sockaddr_in
)) == -1 ||
190 (type
== ENET_SOCKET_TYPE_STREAM
&&
191 listen (newSocket
, SOMAXCONN
) == -1))
195 return ENET_SOCKET_NULL
;
202 enet_socket_connect (ENetSocket socket
, const ENetAddress
* address
)
204 struct sockaddr_in sin
;
206 memset (& sin
, 0, sizeof (struct sockaddr_in
));
208 sin
.sin_family
= AF_INET
;
209 sin
.sin_port
= ENET_HOST_TO_NET_16 (address
-> port
);
210 sin
.sin_addr
.s_addr
= address
-> host
;
212 return connect (socket
, (struct sockaddr
*) & sin
, sizeof (struct sockaddr_in
));
216 enet_socket_accept (ENetSocket socket
, ENetAddress
* address
)
219 struct sockaddr_in sin
;
220 socklen_t sinLength
= sizeof (struct sockaddr_in
);
222 result
= accept (socket
,
223 address
!= NULL
? (struct sockaddr
*) & sin
: NULL
,
224 address
!= NULL
? & sinLength
: NULL
);
227 return ENET_SOCKET_NULL
;
231 address
-> host
= (enet_uint32
) sin
.sin_addr
.s_addr
;
232 address
-> port
= ENET_NET_TO_HOST_16 (sin
.sin_port
);
239 enet_socket_destroy (ENetSocket socket
)
245 enet_socket_send (ENetSocket socket
,
246 const ENetAddress
* address
,
247 const ENetBuffer
* buffers
,
250 struct msghdr msgHdr
;
251 struct sockaddr_in sin
;
254 memset (& msgHdr
, 0, sizeof (struct msghdr
));
258 sin
.sin_family
= AF_INET
;
259 sin
.sin_port
= ENET_HOST_TO_NET_16 (address
-> port
);
260 sin
.sin_addr
.s_addr
= address
-> host
;
262 msgHdr
.msg_name
= & sin
;
263 msgHdr
.msg_namelen
= sizeof (struct sockaddr_in
);
266 msgHdr
.msg_iov
= (struct iovec
*) buffers
;
267 msgHdr
.msg_iovlen
= bufferCount
;
269 sentLength
= sendmsg (socket
, & msgHdr
, MSG_NOSIGNAL
);
271 if (sentLength
== -1)
273 if (errno
== EWOULDBLOCK
)
283 enet_socket_receive (ENetSocket socket
,
284 ENetAddress
* address
,
285 ENetBuffer
* buffers
,
288 struct msghdr msgHdr
;
289 struct sockaddr_in sin
;
292 memset (& msgHdr
, 0, sizeof (struct msghdr
));
296 msgHdr
.msg_name
= & sin
;
297 msgHdr
.msg_namelen
= sizeof (struct sockaddr_in
);
300 msgHdr
.msg_iov
= (struct iovec
*) buffers
;
301 msgHdr
.msg_iovlen
= bufferCount
;
303 recvLength
= recvmsg (socket
, & msgHdr
, MSG_NOSIGNAL
);
305 if (recvLength
== -1)
307 if (errno
== EWOULDBLOCK
)
313 #ifdef HAS_MSGHDR_FLAGS
314 if (msgHdr
.msg_flags
& MSG_TRUNC
)
320 address
-> host
= (enet_uint32
) sin
.sin_addr
.s_addr
;
321 address
-> port
= ENET_NET_TO_HOST_16 (sin
.sin_port
);
328 enet_socket_wait (ENetSocket socket
, enet_uint32
* condition
, enet_uint32 timeout
)
331 struct pollfd pollSocket
;
334 pollSocket
.fd
= socket
;
335 pollSocket
.events
= 0;
337 if (* condition
& ENET_SOCKET_WAIT_SEND
)
338 pollSocket
.events
|= POLLOUT
;
340 if (* condition
& ENET_SOCKET_WAIT_RECEIVE
)
341 pollSocket
.events
|= POLLIN
;
343 pollCount
= poll (& pollSocket
, 1, timeout
);
348 * condition
= ENET_SOCKET_WAIT_NONE
;
353 if (pollSocket
.revents
& POLLOUT
)
354 * condition
|= ENET_SOCKET_WAIT_SEND
;
356 if (pollSocket
.revents
& POLLIN
)
357 * condition
|= ENET_SOCKET_WAIT_RECEIVE
;
361 fd_set readSet
, writeSet
;
362 struct timeval timeVal
;
365 timeVal
.tv_sec
= timeout
/ 1000;
366 timeVal
.tv_usec
= (timeout
% 1000) * 1000;
369 FD_ZERO (& writeSet
);
371 if (* condition
& ENET_SOCKET_WAIT_SEND
)
372 FD_SET (socket
, & writeSet
);
374 if (* condition
& ENET_SOCKET_WAIT_RECEIVE
)
375 FD_SET (socket
, & readSet
);
377 selectCount
= select (socket
+ 1, & readSet
, & writeSet
, NULL
, & timeVal
);
382 * condition
= ENET_SOCKET_WAIT_NONE
;
384 if (selectCount
== 0)
387 if (FD_ISSET (socket
, & writeSet
))
388 * condition
|= ENET_SOCKET_WAIT_SEND
;
390 if (FD_ISSET (socket
, & readSet
))
391 * condition
|= ENET_SOCKET_WAIT_RECEIVE
;