diff options
-rw-r--r-- | configure.in | 6 | ||||
-rwxr-xr-x | docs/mainpage.dox | 11 | ||||
-rwxr-xr-x | docs/tutorial.dox | 2 | ||||
-rw-r--r-- | include/enet/enet.h | 32 | ||||
-rw-r--r-- | include/enet/protocol.h | 1 | ||||
-rw-r--r-- | include/enet/win32.h | 7 | ||||
-rw-r--r-- | peer.c | 10 | ||||
-rw-r--r-- | protocol.c | 154 | ||||
-rw-r--r-- | unix.c | 28 | ||||
-rw-r--r-- | win32.c | 20 |
10 files changed, 173 insertions, 98 deletions
diff --git a/configure.in b/configure.in index 67fe2ca..bd626c8 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ -AC_INIT(libenet, 7-18-2005) -AM_INIT_AUTOMAKE(libenet.a, 7-18-2005) +AC_INIT(libenet, 1.0) +AM_INIT_AUTOMAKE(libenet.a, 1.0) AC_PROG_CC AC_PROG_RANLIB @@ -8,6 +8,8 @@ AC_CHECK_FUNC(gethostbyaddr_r, [AC_DEFINE(HAS_GETHOSTBYADDR_R)]) AC_CHECK_FUNC(gethostbyname_r, [AC_DEFINE(HAS_GETHOSTBYNAME_R)]) AC_CHECK_FUNC(poll, [AC_DEFINE(HAS_POLL)]) AC_CHECK_FUNC(fcntl, [AC_DEFINE(HAS_FCNTL)]) +AC_CHECK_FUNC(inet_pton, [AC_DEFINE(HAS_INET_PTON)]) +AC_CHECK_FUNC(inet_ntop, [AC_DEFINE(HAS_INET_NTOP)]) AC_CHECK_MEMBER(struct msghdr.msg_flags, [AC_DEFINE(HAS_MSGHDR_FLAGS)], , [#include <sys/socket.h>]) diff --git a/docs/mainpage.dox b/docs/mainpage.dox index 3e36262..2380196 100755 --- a/docs/mainpage.dox +++ b/docs/mainpage.dox @@ -20,8 +20,6 @@ or dependent tasks. @ref Tutorial -@ref DiscussionForum - @ref MailingList @ref Extending @@ -71,15 +69,6 @@ appropriate functions in memory.c */ /** -@page DiscussionForum ENet Discussion Forum - -The <a href="http://jbserver.com/forums/ForumHome.asp?ForumId=6"> -ENet discussion forum</a> provides a convenient place to ask for help, -share code and ideas, or report bugs. - -*/ - -/** @page MailingList ENet Related Mailing Lists The <a diff --git a/docs/tutorial.dox b/docs/tutorial.dox index 0cf29fd..7829d6c 100755 --- a/docs/tutorial.dox +++ b/docs/tutorial.dox @@ -262,7 +262,7 @@ foreign host. No event is generated. @code ENetEvent event; - enet_peer_disconnect (peer); + enet_peer_disconnect (peer, 0); /* Allow up to 3 seconds for the disconnect to succeed * and drop any packets received packets. diff --git a/include/enet/enet.h b/include/enet/enet.h index 4966a1a..4c48a92 100644 --- a/include/enet/enet.h +++ b/include/enet/enet.h @@ -12,7 +12,6 @@ extern "C" #include <stdlib.h> - #ifdef WIN32 #include "enet/win32.h" #else @@ -144,10 +143,11 @@ typedef enum ENET_PEER_STATE_DISCONNECTED = 0, ENET_PEER_STATE_CONNECTING = 1, ENET_PEER_STATE_ACKNOWLEDGING_CONNECT = 2, - ENET_PEER_STATE_CONNECTED = 3, - ENET_PEER_STATE_DISCONNECTING = 4, - ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT = 5, - ENET_PEER_STATE_ZOMBIE = 6 + ENET_PEER_STATE_CONNECTION_PENDING = 3, + ENET_PEER_STATE_CONNECTED = 4, + ENET_PEER_STATE_DISCONNECTING = 5, + ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT = 6, + ENET_PEER_STATE_ZOMBIE = 7 } ENetPeerState; #ifndef ENET_BUFFER_MAXIMUM @@ -171,7 +171,7 @@ enum ENET_PEER_PACKET_LOSS_INTERVAL = 10000, ENET_PEER_WINDOW_SIZE_SCALE = 64 * 1024, ENET_PEER_TIMEOUT_LIMIT = 32, - ENET_PEER_TIMEOUT_MINIMUM = 3000, + ENET_PEER_TIMEOUT_MINIMUM = 5000, ENET_PEER_TIMEOUT_MAXIMUM = 30000, ENET_PEER_PING_INTERVAL = 500, ENET_PEER_UNSEQUENCED_WINDOW_SIZE = 4 * 32, @@ -243,6 +243,7 @@ typedef struct _ENetPeer enet_uint32 incomingUnsequencedGroup; enet_uint32 outgoingUnsequencedGroup; enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32]; + enet_uint32 disconnectData; } ENetPeer; /** An ENet host for communicating with peers. @@ -297,7 +298,8 @@ typedef enum * completion of a disconnect initiated by enet_pper_disconnect, if * a peer has timed out, or if a connection request intialized by * enet_host_connect has timed out. The peer field contains the peer - * which disconnected. + * which disconnected. The data field contains user supplied data + * describing the disconnection, or 0, if none is available. */ ENET_EVENT_TYPE_DISCONNECT = 2, @@ -319,8 +321,9 @@ typedef struct _ENetEvent { ENetEventType type; /**< type of the event */ ENetPeer * peer; /**< peer that generated a connect, disconnect or receive event */ - enet_uint8 channelID; - ENetPacket * packet; + enet_uint8 channelID; /**< channel on the peer that generated the event, if appropriate */ + enet_uint32 data; /**< data associated with the event, if appropriate */ + ENetPacket * packet; /**< packet associated with the event, if appropriate */ } ENetEvent; /** @defgroup global ENet global functions @@ -334,13 +337,6 @@ typedef struct _ENetEvent */ ENET_API int enet_initialize (void); -/** - Initializes ENet and sets the callbacks provided in the ENetCallbacks structure. - Callbacks that are set to NULL will simply use the default ENet functions. - ENET_VERSION should be passed in as the first argument so that ENet may verify the - callbacks available. - @returns 0 on success, < 0 on failure -*/ ENET_API int enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits); /** @@ -419,8 +415,8 @@ ENET_API int enet_peer_send (ENetPeer *, enet_uint8, ENetPacket ENET_API ENetPacket * enet_peer_receive (ENetPeer *, enet_uint8); ENET_API void enet_peer_ping (ENetPeer *); ENET_API void enet_peer_reset (ENetPeer *); -ENET_API void enet_peer_disconnect (ENetPeer *); -ENET_API void enet_peer_disconnect_now (ENetPeer *); +ENET_API void enet_peer_disconnect (ENetPeer *, enet_uint32); +ENET_API void enet_peer_disconnect_now (ENetPeer *, enet_uint32); ENET_API void enet_peer_throttle_configure (ENetPeer *, enet_uint32, enet_uint32, enet_uint32); extern int enet_peer_throttle (ENetPeer *, enet_uint32); extern void enet_peer_reset_queues (ENetPeer *); diff --git a/include/enet/protocol.h b/include/enet/protocol.h index 9a61498..6d4dae9 100644 --- a/include/enet/protocol.h +++ b/include/enet/protocol.h @@ -112,6 +112,7 @@ typedef struct typedef struct { ENetProtocolCommandHeader header; + enet_uint32 data; } ENetProtocolDisconnect; typedef struct diff --git a/include/enet/win32.h b/include/enet/win32.h index ae231c2..310ecd5 100644 --- a/include/enet/win32.h +++ b/include/enet/win32.h @@ -5,6 +5,13 @@ #ifndef __ENET_WIN32_H__ #define __ENET_WIN32_H__ +#ifdef ENET_BUILDING_LIB +#pragma warning (disable: 4996) // 'strncpy' was declared deprecated +#pragma warning (disable: 4267) // size_t to int conversion +#pragma warning (disable: 4244) // 64bit to 32bit int +#pragma warning (disable: 4018) // signed/unsigned mismatch +#endif + #include <stdlib.h> #include <winsock2.h> @@ -2,6 +2,7 @@ @file peer.c @brief ENet peer management functions */ +#include <string.h> #define ENET_BUILDING_LIB 1 #include "enet/enet.h" @@ -379,6 +380,7 @@ enet_peer_reset (ENetPeer * peer) peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; peer -> incomingUnsequencedGroup = 0; peer -> outgoingUnsequencedGroup = 0; + peer -> disconnectData = 0; memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow)); @@ -410,12 +412,13 @@ enet_peer_ping (ENetPeer * peer) /** Force an immediate disconnection from a peer. @param peer peer to disconnect + @param data data describing the disconnection @remarks No ENET_EVENT_DISCONNECT event will be generated. The foreign peer is not guarenteed to receive the disconnect notification, and is reset immediately upon return from this function. */ void -enet_peer_disconnect_now (ENetPeer * peer) +enet_peer_disconnect_now (ENetPeer * peer, enet_uint32 data) { ENetProtocol command; @@ -431,6 +434,7 @@ enet_peer_disconnect_now (ENetPeer * peer) command.header.channelID = 0xFF; command.header.flags = ENET_PROTOCOL_FLAG_UNSEQUENCED; command.header.commandLength = sizeof (ENetProtocolDisconnect); + command.disconnect.data = data; enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); @@ -442,11 +446,12 @@ enet_peer_disconnect_now (ENetPeer * peer) /** Request a disconnection from a peer. @param peer peer to request a disconnection + @param data data describing the disconnection @remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service() once the disconnection is complete. */ void -enet_peer_disconnect (ENetPeer * peer) +enet_peer_disconnect (ENetPeer * peer, enet_uint32 data) { ENetProtocol command; @@ -461,6 +466,7 @@ enet_peer_disconnect (ENetPeer * peer) command.header.channelID = 0xFF; command.header.flags = ENET_PROTOCOL_FLAG_UNSEQUENCED; command.header.commandLength = sizeof (ENetProtocolDisconnect); + command.disconnect.data = data; if (peer -> state == ENET_PEER_STATE_CONNECTED) command.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE; @@ -24,12 +24,22 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event) if (currentPeer >= & host -> peers [host -> peerCount]) currentPeer = host -> peers; - if (currentPeer -> state == ENET_PEER_STATE_ZOMBIE) + switch (currentPeer -> state) { + case ENET_PEER_STATE_CONNECTION_PENDING: + currentPeer -> state = ENET_PEER_STATE_CONNECTED; + + event -> type = ENET_EVENT_TYPE_CONNECT; + event -> peer = currentPeer; + + return 1; + + case ENET_PEER_STATE_ZOMBIE: host -> recalculateBandwidthLimits = 1; event -> type = ENET_EVENT_TYPE_DISCONNECT; event -> peer = currentPeer; + event -> data = currentPeer -> disconnectData; enet_peer_reset (currentPeer); @@ -67,6 +77,43 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event) } static void +enet_protocol_notify_connect (ENetHost * host, ENetPeer * peer, ENetEvent * event) +{ + host -> recalculateBandwidthLimits = 1; + + if (event == NULL) + peer -> state = ENET_PEER_STATE_CONNECTION_PENDING; + else + { + peer -> state = ENET_PEER_STATE_CONNECTED; + + event -> type = ENET_EVENT_TYPE_CONNECT; + event -> peer = peer; + } +} + +static void +enet_protocol_notify_disconnect (ENetHost * host, ENetPeer * peer, ENetEvent * event) +{ + if (peer -> state >= ENET_PEER_STATE_CONNECTION_PENDING) + host -> recalculateBandwidthLimits = 1; + + if (peer -> state < ENET_PEER_STATE_CONNECTED) + enet_peer_reset (peer); + else + if (event == NULL) + peer -> state = ENET_PEER_STATE_ZOMBIE; + else + { + event -> type = ENET_EVENT_TYPE_DISCONNECT; + event -> peer = peer; + event -> data = 0; + + enet_peer_reset (peer); + } +} + +static void enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer) { ENetOutgoingCommand * outgoingCommand; @@ -461,12 +508,18 @@ enet_protocol_handle_disconnect (ENetHost * host, ENetPeer * peer, const ENetPro enet_peer_reset_queues (peer); if (peer -> state != ENET_PEER_STATE_CONNECTED) - enet_peer_reset (peer); + { + if (peer -> state == ENET_PEER_STATE_CONNECTION_PENDING) host -> recalculateBandwidthLimits = 1; + + enet_peer_reset (peer); + } else if (command -> header.flags & ENET_PROTOCOL_FLAG_ACKNOWLEDGE) peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT; else peer -> state = ENET_PEER_STATE_ZOMBIE; + + peer -> disconnectData = command -> disconnect.data; } static int @@ -531,12 +584,7 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * if (commandNumber != ENET_PROTOCOL_COMMAND_VERIFY_CONNECT) return 0; - host -> recalculateBandwidthLimits = 1; - - peer -> state = ENET_PEER_STATE_CONNECTED; - - event -> type = ENET_EVENT_TYPE_CONNECT; - event -> peer = peer; + enet_protocol_notify_connect (host, peer, event); return 1; @@ -544,17 +592,9 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * if (commandNumber != ENET_PROTOCOL_COMMAND_DISCONNECT) return 0; - host -> recalculateBandwidthLimits = 1; - - event -> type = ENET_EVENT_TYPE_DISCONNECT; - event -> peer = peer; - - enet_peer_reset (peer); + enet_protocol_notify_disconnect (host, peer, event); return 1; - - default: - break; } return 0; @@ -566,7 +606,8 @@ enet_protocol_handle_verify_connect (ENetHost * host, ENetEvent * event, ENetPee enet_uint16 mtu; enet_uint32 windowSize; - if (command -> header.commandLength < sizeof (ENetProtocolVerifyConnect) || + if (event == NULL || + command -> header.commandLength < sizeof (ENetProtocolVerifyConnect) || peer -> state != ENET_PEER_STATE_CONNECTING) return; @@ -607,12 +648,7 @@ enet_protocol_handle_verify_connect (ENetHost * host, ENetEvent * event, ENetPee peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.incomingBandwidth); peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.outgoingBandwidth); - host -> recalculateBandwidthLimits = 1; - - peer -> state = ENET_PEER_STATE_CONNECTED; - - event -> type = ENET_EVENT_TYPE_CONNECT; - event -> peer = peer; + enet_protocol_notify_connect (host, peer, event); } static int @@ -666,21 +702,19 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) command = (ENetProtocol *) currentData; if (currentData + sizeof (ENetProtocolCommandHeader) > & host -> receivedData [host -> receivedDataLength]) - return 0; + break; command -> header.commandLength = ENET_NET_TO_HOST_32 (command -> header.commandLength); - if (currentData + command -> header.commandLength > & host -> receivedData [host -> receivedDataLength]) - return 0; + if (command -> header.commandLength <= 0 || + command -> header.commandLength > & host -> receivedData [host -> receivedDataLength] - currentData) + break; -- commandCount; currentData += command -> header.commandLength; - if (peer == NULL) - { - if (command -> header.command != ENET_PROTOCOL_COMMAND_CONNECT) - return 0; - } + if (peer == NULL && command -> header.command != ENET_PROTOCOL_COMMAND_CONNECT) + break; command -> header.reliableSequenceNumber = ENET_NET_TO_HOST_32 (command -> header.reliableSequenceNumber); @@ -765,7 +799,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) } } - if (event -> type != ENET_EVENT_TYPE_NONE) + if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE) return 1; return 0; @@ -962,10 +996,7 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even (outgoingCommand -> roundTripTimeout >= outgoingCommand -> roundTripTimeoutLimit && ENET_TIME_DIFFERENCE(timeCurrent, peer -> earliestTimeout) >= ENET_PEER_TIMEOUT_MINIMUM))) { - event -> type = ENET_EVENT_TYPE_DISCONNECT; - event -> peer = peer; - - enet_peer_reset (peer); + enet_protocol_notify_disconnect (host, peer, event); return 1; } @@ -1198,6 +1229,7 @@ enet_host_flush (ENetHost * host) @param host host to service @param event an event structure where event details will be placed if one occurs + if event == NULL then no events will be delivered @param timeout number of milliseconds that ENet should wait for events @retval > 0 if an event occurred within the specified time limit @retval 0 if no event occurred @@ -1210,24 +1242,27 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout) { enet_uint32 waitCondition; - event -> type = ENET_EVENT_TYPE_NONE; - event -> peer = NULL; - event -> packet = NULL; - - switch (enet_protocol_dispatch_incoming_commands (host, event)) + if (event != NULL) { - case 1: - return 1; + event -> type = ENET_EVENT_TYPE_NONE; + event -> peer = NULL; + event -> packet = NULL; + + switch (enet_protocol_dispatch_incoming_commands (host, event)) + { + case 1: + return 1; - case -1: - perror ("Error dispatching incoming packets"); + case -1: + perror ("Error dispatching incoming packets"); - return -1; + return -1; - default: - break; + default: + break; + } } - + timeCurrent = enet_time_get (); timeout += timeCurrent; @@ -1279,18 +1314,21 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout) break; } - switch (enet_protocol_dispatch_incoming_commands (host, event)) + if (event != NULL) { - case 1: - return 1; + switch (enet_protocol_dispatch_incoming_commands (host, event)) + { + case 1: + return 1; - case -1: - perror ("Error dispatching incoming packets"); + case -1: + perror ("Error dispatching incoming packets"); - return -1; + return -1; - default: - break; + default: + break; + } } timeCurrent = enet_time_get (); @@ -8,6 +8,7 @@ #include <sys/socket.h> #include <sys/ioctl.h> #include <sys/time.h> +#include <arpa/inet.h> #include <netdb.h> #include <unistd.h> #include <string.h> @@ -21,6 +22,10 @@ #include <fcntl.h> #endif +#ifdef __APPLE__ +#undef HAS_POLL +#endif + #ifdef HAS_POLL #include <sys/poll.h> #endif @@ -86,7 +91,15 @@ enet_address_set_host (ENetAddress * address, const char * name) if (hostEntry == NULL || hostEntry -> h_addrtype != AF_INET) - return -1; + { +#ifdef HAS_INET_PTON + if (! inet_pton (AF_INET, name, & address -> host)) +#else + if (! inet_aton (name, (struct in_addr *) & address -> host)) +#endif + return -1; + return 0; + } address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0]; @@ -117,7 +130,18 @@ enet_address_get_host (const ENetAddress * address, char * name, size_t nameLeng #endif if (hostEntry == NULL) - return -1; + { +#ifdef HAS_INET_NTOP + if (inet_ntop (AF_INET, & address -> host, name, nameLength) == NULL) +#else + char * addr = inet_ntoa (* (struct in_addr *) & address -> host); + if (addr != NULL) + strncpy (name, addr, nameLength); + else +#endif + return -1; + return 0; + } strncpy (name, hostEntry -> h_name, nameLength); @@ -60,7 +60,13 @@ enet_address_set_host (ENetAddress * address, const char * name) hostEntry = gethostbyname (name); if (hostEntry == NULL || hostEntry -> h_addrtype != AF_INET) - return -1; + { + unsigned long host = inet_addr (name); + if (host == INADDR_NONE) + return -1; + address -> host = host; + return 0; + } address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0]; @@ -77,7 +83,13 @@ enet_address_get_host (const ENetAddress * address, char * name, size_t nameLeng hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET); if (hostEntry == NULL) - return -1; + { + char * addr = inet_ntoa (* (struct in_addr *) & address -> host); + if (addr == NULL) + return -1; + strncpy (name, addr, nameLength); + return 0; + } strncpy (name, hostEntry -> h_name, nameLength); @@ -151,7 +163,7 @@ enet_socket_connect (ENetSocket socket, const ENetAddress * address) ENetSocket enet_socket_accept (ENetSocket socket, ENetAddress * address) { - int result; + SOCKET result; struct sockaddr_in sin; int sinLength = sizeof (struct sockaddr_in); @@ -159,7 +171,7 @@ enet_socket_accept (ENetSocket socket, ENetAddress * address) address != NULL ? (struct sockaddr *) & sin : NULL, address != NULL ? & sinLength : NULL); - if (result == -1) + if (result == INVALID_SOCKET) return ENET_SOCKET_NULL; if (address != NULL) |