diff --git a/ChangeLog b/ChangeLog index 46d797a..b8f8684 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +ENet - (current): + +* added thin wrapper around select() for portable usage +* added ENET_SOCKOPT_REUSEADDR socket option +* factored enet_socket_bind()/enet_socket_listen() out of enet_socket_create() + ENet 1.2 (February 12, 2008): * fixed bug in VERIFY_CONNECT acknowledgement that could cause connect diff --git a/configure.in b/configure.in index 47da5fe..f0fd703 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ -AC_INIT(libenet, 1-8-2008) -AM_INIT_AUTOMAKE(libenet.a, 1-8-2008) +AC_INIT(libenet, 9-15-2008) +AM_INIT_AUTOMAKE(libenet.a, 9-15-2008) AC_PROG_CC AC_PROG_RANLIB diff --git a/host.c b/host.c index 9bab1a8..30eaded 100644 --- a/host.c +++ b/host.c @@ -36,9 +36,12 @@ enet_host_create (const ENetAddress * address, size_t peerCount, enet_uint32 inc host -> peers = (ENetPeer *) enet_malloc (peerCount * sizeof (ENetPeer)); memset (host -> peers, 0, peerCount * sizeof (ENetPeer)); - host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM, address); - if (host -> socket == ENET_SOCKET_NULL) + host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM); + if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0)) { + if (host -> socket != ENET_SOCKET_NULL) + enet_socket_destroy (host -> socket); + enet_free (host -> peers); enet_free (host); diff --git a/include/enet/enet.h b/include/enet/enet.h index 14106aa..cf7b2d0 100644 --- a/include/enet/enet.h +++ b/include/enet/enet.h @@ -46,7 +46,8 @@ typedef enum ENET_SOCKOPT_NONBLOCK = 1, ENET_SOCKOPT_BROADCAST = 2, ENET_SOCKOPT_RCVBUF = 3, - ENET_SOCKOPT_SNDBUF = 4 + ENET_SOCKOPT_SNDBUF = 4, + ENET_SOCKOPT_REUSEADDR = 5 } ENetSocketOption; enum @@ -403,7 +404,9 @@ ENET_API void enet_time_set (enet_uint32); /** @defgroup socket ENet socket functions @{ */ -ENET_API ENetSocket enet_socket_create (ENetSocketType, const ENetAddress *); +ENET_API ENetSocket enet_socket_create (ENetSocketType); +ENET_API int enet_socket_bind (ENetSocket, const ENetAddress *); +ENET_API int enet_socket_listen (ENetSocket, int); ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *); ENET_API int enet_socket_connect (ENetSocket, const ENetAddress *); ENET_API int enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t); @@ -411,6 +414,7 @@ ENET_API int enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer * ENET_API int enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32); ENET_API int enet_socket_set_option (ENetSocket, ENetSocketOption, int); ENET_API void enet_socket_destroy (ENetSocket); +ENET_API int enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSocketSet *, enet_uint32); /** @} */ diff --git a/include/enet/unix.h b/include/enet/unix.h index b20fecd..087015e 100644 --- a/include/enet/unix.h +++ b/include/enet/unix.h @@ -6,8 +6,10 @@ #define __ENET_UNIX_H__ #include +#include #include #include +#include typedef int ENetSocket; @@ -32,5 +34,12 @@ typedef struct #define ENET_API extern +typedef fd_set ENetSocketSet; + +#define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset)) +#define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset)) +#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset)) +#define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset)) + #endif /* __ENET_UNIX_H__ */ diff --git a/include/enet/win32.h b/include/enet/win32.h index 310ecd5..0e1cf0c 100644 --- a/include/enet/win32.h +++ b/include/enet/win32.h @@ -46,6 +46,13 @@ typedef struct #define ENET_API extern #endif /* ENET_DLL */ +typedef fd_set ENetSocketSet; + +#define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset)) +#define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset)) +#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset)) +#define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset)) + #endif /* __ENET_WIN32_H__ */ diff --git a/unix.c b/unix.c index 132ca1a..0bf794f 100644 --- a/unix.c +++ b/unix.c @@ -152,37 +152,39 @@ enet_address_get_host (const ENetAddress * address, char * name, size_t nameLeng return 0; } -ENetSocket -enet_socket_create (ENetSocketType type, const ENetAddress * address) +int +enet_socket_bind (ENetSocket socket, const ENetAddress * address) { - ENetSocket newSocket = socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); struct sockaddr_in sin; - if (newSocket == ENET_SOCKET_NULL) - return ENET_SOCKET_NULL; - - if (address == NULL) - return newSocket; - memset (& sin, 0, sizeof (struct sockaddr_in)); - sin.sin_family = AF_INET; - sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); - sin.sin_addr.s_addr = address -> host; - - if (bind (newSocket, - (struct sockaddr *) & sin, - sizeof (struct sockaddr_in)) == -1 || - (type == ENET_SOCKET_TYPE_STREAM && - address -> port != ENET_PORT_ANY && - listen (newSocket, SOMAXCONN) == -1)) + if (address != NULL) { - close (newSocket); - - return ENET_SOCKET_NULL; + sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); + sin.sin_addr.s_addr = address -> host; + } + else + { + sin.sin_port = 0; + sin.sin_addr.s_addr = INADDR_ANY; } - return newSocket; + return bind (socket, + (struct sockaddr *) & sin, + sizeof (struct sockaddr_in)); +} + +int +enet_socket_listen (ENetSocket socket, int backlog) +{ + return listen (socket, backlog < 0 ? SOMAXCONN : backlog); +} + +ENetSocket +enet_socket_create (ENetSocketType type) +{ + return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); } int @@ -203,6 +205,10 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value) result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int)); break; + case ENET_SOCKOPT_REUSEADDR: + result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int)); + break; + case ENET_SOCKOPT_RCVBUF: result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int)); break; @@ -345,6 +351,17 @@ enet_socket_receive (ENetSocket socket, return recvLength; } +int +enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout) +{ + struct timeval timeVal; + + timeVal.tv_sec = timeout / 1000; + timeVal.tv_usec = (timeout % 1000) * 1000; + + return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal); +} + int enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout) { diff --git a/win32.c b/win32.c index b8b2aa7..e1fae23 100644 --- a/win32.c +++ b/win32.c @@ -100,19 +100,15 @@ enet_address_get_host (const ENetAddress * address, char * name, size_t nameLeng return 0; } -ENetSocket -enet_socket_create (ENetSocketType type, const ENetAddress * address) +int +enet_socket_bind (ENetSocket socket, const ENetAddress * address) { - ENetSocket newSocket = socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); struct sockaddr_in sin; - if (newSocket == ENET_SOCKET_NULL) - return ENET_SOCKET_NULL; - memset (& sin, 0, sizeof (struct sockaddr_in)); sin.sin_family = AF_INET; - + if (address != NULL) { sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); @@ -124,20 +120,21 @@ enet_socket_create (ENetSocketType type, const ENetAddress * address) sin.sin_addr.s_addr = INADDR_ANY; } - if (bind (newSocket, - (struct sockaddr *) & sin, - sizeof (struct sockaddr_in)) == SOCKET_ERROR || - (type == ENET_SOCKET_TYPE_STREAM && - address != NULL && - address -> port != ENET_PORT_ANY && - listen (newSocket, SOMAXCONN) == SOCKET_ERROR)) - { - closesocket (newSocket); + return bind (socket, + (struct sockaddr *) & sin, + sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0; +} - return ENET_SOCKET_NULL; - } +int +enet_socket_listen (ENetSocket socket, int backlog) +{ + return listen (socket, backlog < 0 ? SOMAXCONN : backlog) == SOCKET_ERROR ? -1 : 0; +} - return newSocket; +ENetSocket +enet_socket_create (ENetSocketType type) +{ + return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); } int @@ -157,6 +154,10 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value) result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int)); break; + case ENET_SOCKOPT_REUSEADDR: + result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int)); + break; + case ENET_SOCKOPT_RCVBUF: result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int)); break; @@ -182,7 +183,7 @@ enet_socket_connect (ENetSocket socket, const ENetAddress * address) sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); sin.sin_addr.s_addr = address -> host; - return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)); + return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0; } ENetSocket @@ -294,6 +295,17 @@ enet_socket_receive (ENetSocket socket, return (int) recvLength; } +int +enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout) +{ + struct timeval timeVal; + + timeVal.tv_sec = timeout / 1000; + timeVal.tv_usec = (timeout % 1000) * 1000; + + return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal); +} + int enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout) {