diff --git a/callbacks.c b/callbacks.c index b3990af1..5cf0d559 100644 --- a/callbacks.c +++ b/callbacks.c @@ -1,4 +1,4 @@ -/** +/** @file callbacks.c @brief ENet callback functions */ @@ -21,7 +21,7 @@ enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits callbacks.malloc = inits -> malloc; callbacks.free = inits -> free; } - + if (inits -> no_memory != NULL) callbacks.no_memory = inits -> no_memory; @@ -33,7 +33,7 @@ enet_linked_version (void) { return ENET_VERSION; } - + void * enet_malloc (size_t size) { @@ -50,4 +50,3 @@ enet_free (void * memory) { callbacks.free (memory); } - diff --git a/compress.c b/compress.c index 784489a7..950baabe 100644 --- a/compress.c +++ b/compress.c @@ -1,4 +1,4 @@ -/** +/** @file compress.c @brief An adaptive order-2 PPM range coder */ @@ -18,7 +18,7 @@ typedef struct _ENetSymbol enet_uint16 symbols; enet_uint16 escapes; enet_uint16 total; - enet_uint16 parent; + enet_uint16 parent; } ENetSymbol; /* adaptation constants tuned aggressively for small packet sizes rather than large file compression */ @@ -100,7 +100,7 @@ enet_symbol_rescale (ENetSymbol * symbol) total += symbol -> under; if (! symbol -> right) break; symbol += symbol -> right; - } + } return total; } @@ -282,11 +282,11 @@ enet_range_coder_compress (void * context, const ENetBuffer * inBuffers, size_t inBufferCount --; } value = * inData ++; - - for (subcontext = & rangeCoder -> symbols [predicted]; - subcontext != root; + + for (subcontext = & rangeCoder -> symbols [predicted]; + subcontext != root; #ifdef ENET_CONTEXT_EXCLUSION - childContext = subcontext, + childContext = subcontext, #endif subcontext = & rangeCoder -> symbols [subcontext -> parent]) { @@ -304,8 +304,8 @@ enet_range_coder_compress (void * context, const ENetBuffer * inBuffers, size_t } else { - if (subcontext -> escapes > 0 && subcontext -> escapes < total) - ENET_RANGE_CODER_ENCODE (0, subcontext -> escapes, total); + if (subcontext -> escapes > 0 && subcontext -> escapes < total) + ENET_RANGE_CODER_ENCODE (0, subcontext -> escapes, total); subcontext -> escapes += ENET_SUBCONTEXT_ESCAPE_DELTA; subcontext -> total += ENET_SUBCONTEXT_ESCAPE_DELTA; } @@ -321,17 +321,17 @@ enet_range_coder_compress (void * context, const ENetBuffer * inBuffers, size_t total = root -> total; #ifdef ENET_CONTEXT_EXCLUSION if (childContext -> total > ENET_SUBCONTEXT_SYMBOL_DELTA + ENET_SUBCONTEXT_ESCAPE_DELTA) - ENET_CONTEXT_ENCODE_EXCLUDE (childContext, value, under, total, ENET_CONTEXT_SYMBOL_MINIMUM); + ENET_CONTEXT_ENCODE_EXCLUDE (childContext, value, under, total, ENET_CONTEXT_SYMBOL_MINIMUM); #endif ENET_RANGE_CODER_ENCODE (root -> escapes + under, count, total); - root -> total += ENET_CONTEXT_SYMBOL_DELTA; + root -> total += ENET_CONTEXT_SYMBOL_DELTA; if (count > 0xFF - 2*ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || root -> total > ENET_RANGE_CODER_BOTTOM - 0x100) ENET_CONTEXT_RESCALE (root, ENET_CONTEXT_SYMBOL_MINIMUM); nextInput: - if (order >= ENET_SUBCONTEXT_ORDER) + if (order >= ENET_SUBCONTEXT_ORDER) predicted = rangeCoder -> symbols [predicted].parent; - else + else order ++; ENET_RANGE_CODER_FREE_SYMBOLS; } @@ -509,7 +509,7 @@ enet_range_coder_decompress (void * context, const enet_uint8 * inData, size_t i ENetExclude excludes [256]; ENetExclude * nextExclude = excludes; #endif - + if (rangeCoder == NULL || inLimit <= 0) return 0; @@ -529,7 +529,7 @@ enet_range_coder_decompress (void * context, const enet_uint8 * inData, size_t i for (subcontext = & rangeCoder -> symbols [predicted]; subcontext != root; #ifdef ENET_CONTEXT_EXCLUSION - childContext = subcontext, + childContext = subcontext, #endif subcontext = & rangeCoder -> symbols [subcontext -> parent]) { @@ -537,27 +537,27 @@ enet_range_coder_decompress (void * context, const enet_uint8 * inData, size_t i continue; total = subcontext -> total; #ifdef ENET_CONTEXT_EXCLUSION - if (childContext -> total > 0) - ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, 0); + if (childContext -> total > 0) + ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, 0); #endif if (subcontext -> escapes >= total) continue; code = ENET_RANGE_CODER_READ (total); - if (code < subcontext -> escapes) + if (code < subcontext -> escapes) { - ENET_RANGE_CODER_DECODE (0, subcontext -> escapes, total); + ENET_RANGE_CODER_DECODE (0, subcontext -> escapes, total); continue; } code -= subcontext -> escapes; #ifdef ENET_CONTEXT_EXCLUSION if (childContext -> total > 0) { - ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_EXCLUDED); + ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_EXCLUDED); } else #endif { - ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_NOT_EXCLUDED); + ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_NOT_EXCLUDED); } bottom = symbol - rangeCoder -> symbols; ENET_RANGE_CODER_DECODE (subcontext -> escapes + under, count, total); @@ -570,7 +570,7 @@ enet_range_coder_decompress (void * context, const enet_uint8 * inData, size_t i total = root -> total; #ifdef ENET_CONTEXT_EXCLUSION if (childContext -> total > 0) - ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, ENET_CONTEXT_SYMBOL_MINIMUM); + ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, ENET_CONTEXT_SYMBOL_MINIMUM); #endif code = ENET_RANGE_CODER_READ (total); if (code < root -> escapes) @@ -582,12 +582,12 @@ enet_range_coder_decompress (void * context, const enet_uint8 * inData, size_t i #ifdef ENET_CONTEXT_EXCLUSION if (childContext -> total > 0) { - ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_EXCLUDED); + ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_EXCLUDED); } else #endif { - ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_NOT_EXCLUDED); + ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_NOT_EXCLUDED); } bottom = symbol - rangeCoder -> symbols; ENET_RANGE_CODER_DECODE (root -> escapes + under, count, total); @@ -608,7 +608,7 @@ enet_range_coder_decompress (void * context, const enet_uint8 * inData, size_t i patch -> escapes += ENET_SUBCONTEXT_ESCAPE_DELTA; patch -> total += ENET_SUBCONTEXT_ESCAPE_DELTA; } - patch -> total += ENET_SUBCONTEXT_SYMBOL_DELTA; + patch -> total += ENET_SUBCONTEXT_SYMBOL_DELTA; if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || patch -> total > ENET_RANGE_CODER_BOTTOM - 0x100) ENET_CONTEXT_RESCALE (patch, 0); } @@ -622,7 +622,7 @@ enet_range_coder_decompress (void * context, const enet_uint8 * inData, size_t i order ++; ENET_RANGE_CODER_FREE_SYMBOLS; } - + return (size_t) (outData - outStart); } @@ -648,7 +648,5 @@ enet_host_compress_with_range_coder (ENetHost * host) enet_host_compress (host, & compressor); return 0; } - + /** @} */ - - diff --git a/host.c b/host.c index f07d7148..a7bd0bdd 100644 --- a/host.c +++ b/host.c @@ -1,4 +1,4 @@ -/** +/** @file host.c @brief ENet host management functions */ @@ -11,7 +11,7 @@ @{ */ -/** Creates a host for communicating to peers. +/** Creates a host for communicating to peers. @param address the address at which other peers may connect to this host. If NULL, then no peers may connect to the host. @param peerCount the maximum number of peers that should be allocated for the host. @@ -66,7 +66,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL enet_socket_set_option (host -> socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE); enet_socket_set_option (host -> socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE); - if (address != NULL && enet_socket_get_address (host -> socket, & host -> address) < 0) + if (address != NULL && enet_socket_get_address (host -> socket, & host -> address) < 0) host -> address = * address; if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) @@ -92,11 +92,12 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL host -> commandCount = 0; host -> bufferCount = 0; host -> checksum = NULL; - host -> receivedAddress.host = ENET_HOST_ANY; + host -> receivedAddress.family = AF_INET; // IPv4 host -> receivedAddress.port = 0; + host -> receivedAddress.ip.v4.host = ENET_HOST_ANY; host -> receivedData = NULL; host -> receivedDataLength = 0; - + host -> totalSentData = 0; host -> totalSentPackets = 0; host -> totalReceivedData = 0; @@ -167,7 +168,7 @@ enet_host_destroy (ENetHost * host) @param host host seeking the connection @param address destination for the connection @param channelCount number of channels to allocate - @param data user data supplied to the receiving host + @param data user data supplied to the receiving host @returns a peer representing the foreign host on success, NULL on failure @remarks The peer returned will have not completed the connection until enet_host_service() notifies of an ENET_EVENT_TYPE_CONNECT event for the peer. @@ -208,7 +209,7 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; else currentPeer -> windowSize = (host -> outgoingBandwidth / - ENET_PEER_WINDOW_SIZE_SCALE) * + ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) @@ -216,7 +217,7 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC else if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; - + for (channel = currentPeer -> channels; channel < & currentPeer -> channels [channelCount]; ++ channel) @@ -232,7 +233,7 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC channel -> usedReliableWindows = 0; memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows)); } - + command.header.command = ENET_PROTOCOL_COMMAND_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; command.header.channelID = 0xFF; command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID); @@ -248,7 +249,7 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC command.connect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration); command.connect.connectID = currentPeer -> connectID; command.connect.data = ENET_HOST_TO_NET_32 (data); - + enet_peer_queue_outgoing_command (currentPeer, & command, NULL, 0, 0); return currentPeer; @@ -367,7 +368,7 @@ enet_host_bandwidth_throttle (ENetHost * host) while (peersRemaining > 0 && needsAdjustment != 0) { needsAdjustment = 0; - + if (dataTotal <= bandwidth) throttle = ENET_PEER_PACKET_THROTTLE_SCALE; else @@ -378,7 +379,7 @@ enet_host_bandwidth_throttle (ENetHost * host) ++ peer) { enet_uint32 peerBandwidth; - + if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) || peer -> incomingBandwidth == 0 || peer -> outgoingBandwidthThrottleEpoch == timeCurrent) @@ -388,12 +389,12 @@ enet_host_bandwidth_throttle (ENetHost * host) if ((throttle * peer -> outgoingDataTotal) / ENET_PEER_PACKET_THROTTLE_SCALE <= peerBandwidth) continue; - peer -> packetThrottleLimit = (peerBandwidth * + peer -> packetThrottleLimit = (peerBandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / peer -> outgoingDataTotal; - + if (peer -> packetThrottleLimit == 0) peer -> packetThrottleLimit = 1; - + if (peer -> packetThrottle > peer -> packetThrottleLimit) peer -> packetThrottle = peer -> packetThrottleLimit; @@ -463,7 +464,7 @@ enet_host_bandwidth_throttle (ENetHost * host) continue; peer -> incomingBandwidthThrottleEpoch = timeCurrent; - + needsAdjustment = 1; -- peersRemaining; bandwidth -= peer -> outgoingBandwidth; @@ -487,8 +488,8 @@ enet_host_bandwidth_throttle (ENetHost * host) command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (bandwidthLimit); enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); - } + } } } - + /** @} */ diff --git a/include/enet/enet.h b/include/enet/enet.h index 9c32ab83..dda28436 100644 --- a/include/enet/enet.h +++ b/include/enet/enet.h @@ -1,4 +1,4 @@ -/** +/** @file enet.h @brief ENet public header file */ @@ -79,28 +79,75 @@ enum }; /** - * Portable internet address structure. + * Better typed internet address structure. + * + * IPv4, IPv6, and other address types (mostly abandon abandoned) before are not + * stored in a union as one might expect, but are instead traditionally cast + * around. This mostly adapts the existing POSIX standard IPv4 and IPv6 address + * types, in order to minimize the bit twiddling needed to communicate with the + * sockets API, but stores each type of address in an actual union unlike the + * POSIX original. + * + * The host must be specified in network byte-order, as in the POSIX + * specification. Unlike the POSIX specification, however, the port number must + * be in host byte-order. * - * The host must be specified in network byte-order, and the port must be in host - * byte-order. The constant ENET_HOST_ANY may be used to specify the default - * server host. The constant ENET_HOST_BROADCAST may be used to specify the - * broadcast address (255.255.255.255). This makes sense for enet_host_connect, - * but not for enet_host_create. Once a server responds to a broadcast, the - * address is updated from ENET_HOST_BROADCAST to the server's actual IP address. + * The constants in the enum above, and documented in the following paragraph + * are only usable with IPv4. The constant ENET_HOST_ANY may be used to specify + * the default server host. The constant ENET_HOST_BROADCAST may be used to + * specify the broadcast address (255.255.255.255). This makes sense for + * enet_host_connect, but not for enet_host_create. Once a server responds to a + * broadcast, the address is updated from ENET_HOST_BROADCAST to the server's + * actual IP address. */ typedef struct _ENetAddress { - enet_uint32 host; + enet_uint16 family; enet_uint16 port; + union { + struct { + enet_uint32 host; + // using uint32, not uint8 for padding to help with alignment + enet_uint32 padding[5]; + } v4; + struct { + enet_uint32 flow_info; + enet_uint32 host[4]; + enet_uint32 scope_id; + } v6; + } ip; } ENetAddress; +/** returns whether two addresses are equal */ +static inline int +ENET_ADDRESS_COMPARE (ENetAddress * a1, ENetAddress * a2) +{ + if (a1 -> family != a2 -> family || + a1 -> port != a2 -> port ) return 1 == 0; + + switch (a1 -> family) + { + case AF_INET: + return (a1->ip.v4.host == a2->ip.v4.host); + case AF_INET6: + return (a1->ip.v6.flow_info == a2->ip.v6.flow_info && + a1->ip.v6.host[0] == a2->ip.v6.host[0] && + a1->ip.v6.host[1] == a2->ip.v6.host[1] && + a1->ip.v6.host[2] == a2->ip.v6.host[2] && + a1->ip.v6.host[3] == a2->ip.v6.host[3] && + a1->ip.v6.scope_id == a2->ip.v6.scope_id); + default: + return 1 == 0; + } +} + /** * Packet flag bit constants. * * The host must be specified in network byte-order, and the port must be in * host byte-order. The constant ENET_HOST_ANY may be used to specify the * default server host. - + @sa ENetPacket */ typedef enum _ENetPacketFlag @@ -127,20 +174,20 @@ typedef void (ENET_CALLBACK * ENetPacketFreeCallback) (struct _ENetPacket *); /** * ENet packet structure. * - * An ENet data packet that may be sent to or received from a peer. The shown - * fields should only be read and never modified. The data field contains the - * allocated data for the packet. The dataLength fields specifies the length - * of the allocated data. The flags field is either 0 (specifying no flags), + * An ENet data packet that may be sent to or received from a peer. The shown + * fields should only be read and never modified. The data field contains the + * allocated data for the packet. The dataLength fields specifies the length + * of the allocated data. The flags field is either 0 (specifying no flags), * or a bitwise-or of any combination of the following flags: * * ENET_PACKET_FLAG_RELIABLE - packet must be received by the target peer * and resend attempts should be made until the packet is delivered * - * ENET_PACKET_FLAG_UNSEQUENCED - packet will not be sequenced with other packets + * ENET_PACKET_FLAG_UNSEQUENCED - packet will not be sequenced with other packets * (not supported for reliable packets) * * ENET_PACKET_FLAG_NO_ALLOCATE - packet will not allocate data, and user must supply it instead - + @sa ENetPacketFlag */ typedef struct _ENetPacket @@ -176,7 +223,7 @@ typedef struct _ENetOutgoingCommand } ENetOutgoingCommand; typedef struct _ENetIncomingCommand -{ +{ ENetListNode incomingCommandList; enet_uint16 reliableSequenceNumber; enet_uint16 unreliableSequenceNumber; @@ -198,7 +245,7 @@ typedef enum _ENetPeerState ENET_PEER_STATE_DISCONNECT_LATER = 6, ENET_PEER_STATE_DISCONNECTING = 7, ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT = 8, - ENET_PEER_STATE_ZOMBIE = 9 + ENET_PEER_STATE_ZOMBIE = 9 } ENetPeerState; #ifndef ENET_BUFFER_MAXIMUM @@ -215,7 +262,7 @@ enum ENET_PEER_DEFAULT_ROUND_TRIP_TIME = 500, ENET_PEER_DEFAULT_PACKET_THROTTLE = 32, ENET_PEER_PACKET_THROTTLE_SCALE = 32, - ENET_PEER_PACKET_THROTTLE_COUNTER = 7, + ENET_PEER_PACKET_THROTTLE_COUNTER = 7, ENET_PEER_PACKET_THROTTLE_ACCELERATION = 2, ENET_PEER_PACKET_THROTTLE_DECELERATION = 2, ENET_PEER_PACKET_THROTTLE_INTERVAL = 5000, @@ -247,12 +294,12 @@ typedef struct _ENetChannel } ENetChannel; /** - * An ENet peer which data packets may be sent or received from. + * An ENet peer which data packets may be sent or received from. * - * No fields should be modified unless otherwise specified. + * No fields should be modified unless otherwise specified. */ typedef struct _ENetPeer -{ +{ ENetListNode dispatchList; struct _ENetHost * host; enet_uint16 outgoingPeerID; @@ -310,7 +357,7 @@ typedef struct _ENetPeer int needsDispatch; enet_uint16 incomingUnsequencedGroup; enet_uint16 outgoingUnsequencedGroup; - enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32]; + enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32]; enet_uint32 eventData; } ENetPeer; @@ -333,7 +380,7 @@ typedef enet_uint32 (ENET_CALLBACK * ENetChecksumCallback) (const ENetBuffer * b /** Callback for intercepting received raw UDP packets. Should return 1 to intercept, 0 to ignore, or -1 to propagate an error. */ typedef int (ENET_CALLBACK * ENetInterceptCallback) (struct _ENetHost * host, struct _ENetEvent * event); - + /** An ENet host for communicating with peers. * * No fields should be modified unless otherwise stated. @@ -393,21 +440,21 @@ typedef struct _ENetHost typedef enum _ENetEventType { /** no event occurred within the specified time limit */ - ENET_EVENT_TYPE_NONE = 0, + ENET_EVENT_TYPE_NONE = 0, - /** a connection request initiated by enet_host_connect has completed. - * The peer field contains the peer which successfully connected. + /** a connection request initiated by enet_host_connect has completed. + * The peer field contains the peer which successfully connected. */ - ENET_EVENT_TYPE_CONNECT = 1, + ENET_EVENT_TYPE_CONNECT = 1, - /** a peer has disconnected. This event is generated on a successful - * 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. The data field contains user supplied data + /** a peer has disconnected. This event is generated on a successful + * 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. The data field contains user supplied data * describing the disconnection, or 0, if none is available. */ - ENET_EVENT_TYPE_DISCONNECT = 2, + ENET_EVENT_TYPE_DISCONNECT = 2, /** a packet has been received from a peer. The peer field specifies the * peer which sent the packet. The channelID field specifies the channel @@ -420,10 +467,10 @@ typedef enum _ENetEventType /** * An ENet event as returned by enet_host_service(). - + @sa enet_host_service */ -typedef struct _ENetEvent +typedef struct _ENetEvent { ENetEventType type; /**< type of the event */ ENetPeer * peer; /**< peer that generated a connect, disconnect or receive event */ @@ -433,17 +480,17 @@ typedef struct _ENetEvent } ENetEvent; /** @defgroup global ENet global functions - @{ + @{ */ -/** +/** Initializes ENet globally. Must be called prior to using any functions in ENet. @returns 0 on success, < 0 on failure */ ENET_API int enet_initialize (void); -/** +/** Initializes ENet globally and supplies user-overridden callbacks. Must be called prior to using any functions in ENet. Do not use enet_initialize() if you use this variant. Make sure the ENetCallbacks structure is zeroed out so that any additional callbacks added in future versions will be properly ignored. @param version the constant ENET_VERSION should be supplied so ENet knows which version of ENetCallbacks struct to use @@ -452,7 +499,7 @@ ENET_API int enet_initialize (void); */ ENET_API int enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits); -/** +/** Shuts down ENet globally. Should be called when a program that has initialized ENet exits. */ @@ -460,7 +507,7 @@ ENET_API void enet_deinitialize (void); /** Gives the linked version of the ENet library. - @returns the version number + @returns the version number */ ENET_API ENetVersion enet_linked_version (void); @@ -536,7 +583,7 @@ ENET_API ENetPacket * enet_packet_create (const void *, size_t, enet_uint32); ENET_API void enet_packet_destroy (ENetPacket *); ENET_API int enet_packet_resize (ENetPacket *, size_t); ENET_API enet_uint32 enet_crc32 (const ENetBuffer *, size_t); - + ENET_API ENetHost * enet_host_create (const ENetAddress *, size_t, size_t, enet_uint32, enet_uint32); ENET_API void enet_host_destroy (ENetHost *); ENET_API ENetPeer * enet_host_connect (ENetHost *, const ENetAddress *, size_t, enet_uint32); @@ -575,7 +622,7 @@ ENET_API void * enet_range_coder_create (void); ENET_API void enet_range_coder_destroy (void *); ENET_API size_t enet_range_coder_compress (void *, const ENetBuffer *, size_t, size_t, enet_uint8 *, size_t); ENET_API size_t enet_range_coder_decompress (void *, const enet_uint8 *, size_t, enet_uint8 *, size_t); - + extern size_t enet_protocol_command_size (enet_uint8); #ifdef __cplusplus @@ -583,4 +630,3 @@ extern size_t enet_protocol_command_size (enet_uint8); #endif #endif /* __ENET_ENET_H__ */ - diff --git a/include/enet/win32.h b/include/enet/win32.h index b7b68165..dee53870 100644 --- a/include/enet/win32.h +++ b/include/enet/win32.h @@ -16,6 +16,7 @@ #include #include +#include // previously not included on MinGW for some reason typedef SOCKET ENetSocket; diff --git a/list.c b/list.c index 1c1a8dfa..d510ac62 100644 --- a/list.c +++ b/list.c @@ -1,11 +1,11 @@ -/** +/** @file list.c @brief ENet linked list functions */ #define ENET_BUILDING_LIB 1 #include "enet/enet.h" -/** +/** @defgroup list ENet linked list utility functions @ingroup private @{ @@ -54,7 +54,7 @@ enet_list_move (ENetListIterator position, void * dataFirst, void * dataLast) first -> previous -> next = first; position -> previous = last; - + return first; } @@ -68,7 +68,7 @@ enet_list_size (ENetList * list) position != enet_list_end (list); position = enet_list_next (position)) ++ size; - + return size; } diff --git a/packet.c b/packet.c index 9a997be4..15c96284 100644 --- a/packet.c +++ b/packet.c @@ -1,4 +1,4 @@ -/** +/** @file packet.c @brief ENet packet management functions */ @@ -6,8 +6,8 @@ #define ENET_BUILDING_LIB 1 #include "enet/enet.h" -/** @defgroup Packet ENet packet functions - @{ +/** @defgroup Packet ENet packet functions + @{ */ /** Creates a packet that may be sent to a peer. @@ -67,8 +67,8 @@ enet_packet_destroy (ENetPacket * packet) enet_free (packet); } -/** Attempts to resize the data in the packet to length specified in the - dataLength parameter +/** Attempts to resize the data in the packet to length specified in the + dataLength parameter @param packet packet to resize @param dataLength new size for the packet data @returns 0 on success, < 0 on failure @@ -77,7 +77,7 @@ int enet_packet_resize (ENetPacket * packet, size_t dataLength) { enet_uint8 * newData; - + if (dataLength <= packet -> dataLength || (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE)) { packet -> dataLength = dataLength; @@ -91,7 +91,7 @@ enet_packet_resize (ENetPacket * packet, size_t dataLength) memcpy (newData, packet -> data, packet -> dataLength); enet_free (packet -> data); - + packet -> data = newData; packet -> dataLength = dataLength; @@ -101,21 +101,21 @@ enet_packet_resize (ENetPacket * packet, size_t dataLength) static int initializedCRC32 = 0; static enet_uint32 crcTable [256]; -static enet_uint32 +static enet_uint32 reflect_crc (int val, int bits) { int result = 0, bit; for (bit = 0; bit < bits; bit ++) { - if(val & 1) result |= 1 << (bits - 1 - bit); + if(val & 1) result |= 1 << (bits - 1 - bit); val >>= 1; } return result; } -static void +static void initialize_crc32 (void) { int byte; @@ -138,12 +138,12 @@ initialize_crc32 (void) initializedCRC32 = 1; } - + enet_uint32 enet_crc32 (const ENetBuffer * buffers, size_t bufferCount) { enet_uint32 crc = 0xFFFFFFFF; - + if (! initializedCRC32) initialize_crc32 (); while (bufferCount -- > 0) @@ -153,7 +153,7 @@ enet_crc32 (const ENetBuffer * buffers, size_t bufferCount) while (data < dataEnd) { - crc = (crc >> 8) ^ crcTable [(crc & 0xFF) ^ *data++]; + crc = (crc >> 8) ^ crcTable [(crc & 0xFF) ^ *data++]; } ++ buffers; diff --git a/peer.c b/peer.c index 318f2c25..d1904511 100644 --- a/peer.c +++ b/peer.c @@ -1,4 +1,4 @@ -/** +/** @file peer.c @brief ENet peer management functions */ @@ -6,7 +6,7 @@ #define ENET_BUILDING_LIB 1 #include "enet/enet.h" -/** @defgroup peer ENet peer functions +/** @defgroup peer ENet peer functions @{ */ @@ -18,23 +18,23 @@ The lowest mean round trip time from the sending of a reliable packet to the receipt of its acknowledgement is measured over an amount of time specified by the interval parameter in milliseconds. If a measured round trip time happens to - be significantly less than the mean round trip time measured over the interval, + be significantly less than the mean round trip time measured over the interval, then the throttle probability is increased to allow more traffic by an amount specified in the acceleration parameter, which is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE constant. If a measured round trip time happens to be significantly greater than the mean round trip time measured over the interval, then the throttle probability is decreased to limit traffic by an amount specified in the deceleration parameter, which is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE constant. When the throttle has - a value of ENET_PEER_PACKET_THROTTLE_SCALE, no unreliable packets are dropped by + a value of ENET_PEER_PACKET_THROTTLE_SCALE, no unreliable packets are dropped by ENet, and so 100% of all unreliable packets will be sent. When the throttle has a value of 0, all unreliable packets are dropped by ENet, and so 0% of all unreliable packets will be sent. Intermediate values for the throttle represent intermediate probabilities between 0% and 100% of unreliable packets being sent. The bandwidth - limits of the local and foreign hosts are taken into account to determine a + limits of the local and foreign hosts are taken into account to determine a sensible limit for the throttle probability above which it should not raise even in the best of conditions. - @param peer peer to configure + @param peer peer to configure @param interval interval, in milliseconds, over which to measure lowest mean RTT; the default value is ENET_PEER_PACKET_THROTTLE_INTERVAL. @param acceleration rate at which to increase the throttle probability as mean RTT declines @param deceleration rate at which to decrease the throttle probability as mean RTT increases @@ -118,7 +118,7 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet) fragmentNumber, fragmentOffset; enet_uint8 commandNumber; - enet_uint16 startSequenceNumber; + enet_uint16 startSequenceNumber; ENetList fragments; ENetOutgoingCommand * fragment; @@ -136,7 +136,7 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet) commandNumber = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingReliableSequenceNumber + 1); } - + enet_list_clear (& fragments); for (fragmentNumber = 0, @@ -154,13 +154,13 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet) while (! enet_list_empty (& fragments)) { fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments)); - + enet_free (fragment); } - + return -1; } - + fragment -> fragmentOffset = fragmentOffset; fragment -> fragmentLength = fragmentLength; fragment -> packet = packet; @@ -172,7 +172,7 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet) fragment -> command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32 (fragmentNumber); fragment -> command.sendFragment.totalLength = ENET_HOST_TO_NET_32 (packet -> dataLength); fragment -> command.sendFragment.fragmentOffset = ENET_NET_TO_HOST_32 (fragmentOffset); - + enet_list_insert (enet_list_end (& fragments), fragment); } @@ -181,7 +181,7 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet) while (! enet_list_empty (& fragments)) { fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments)); - + enet_peer_setup_outgoing_command (peer, fragment); } @@ -195,7 +195,7 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet) command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED; command.sendUnsequenced.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength); } - else + else if (packet -> flags & ENET_PACKET_FLAG_RELIABLE || channel -> outgoingUnreliableSequenceNumber >= 0xFFFF) { command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; @@ -223,7 +223,7 @@ enet_peer_receive (ENetPeer * peer, enet_uint8 * channelID) { ENetIncomingCommand * incomingCommand; ENetPacket * packet; - + if (enet_list_empty (& peer -> dispatchedCommands)) return NULL; @@ -268,8 +268,8 @@ enet_peer_reset_outgoing_commands (ENetList * queue) static void enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startCommand, ENetListIterator endCommand) { - ENetListIterator currentCommand; - + ENetListIterator currentCommand; + for (currentCommand = startCommand; currentCommand != endCommand; ) { ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; @@ -277,7 +277,7 @@ enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startComm currentCommand = enet_list_next (currentCommand); enet_list_remove (& incomingCommand -> incomingCommandList); - + if (incomingCommand -> packet != NULL) { -- incomingCommand -> packet -> referenceCount; @@ -298,7 +298,7 @@ enet_peer_reset_incoming_commands (ENetList * queue) { enet_peer_remove_incoming_commands(queue, enet_list_begin (queue), enet_list_end (queue)); } - + void enet_peer_reset_queues (ENetPeer * peer) { @@ -370,7 +370,7 @@ void enet_peer_reset (ENetPeer * peer) { enet_peer_on_disconnect (peer); - + peer -> outgoingPeerID = ENET_PROTOCOL_MAXIMUM_PEER_ID; peer -> connectID = 0; @@ -417,13 +417,13 @@ enet_peer_reset (ENetPeer * peer) peer -> eventData = 0; memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow)); - + enet_peer_reset_queues (peer); } /** Sends a ping request to a peer. @param peer destination for the ping request - @remarks ping requests factor into the mean round trip time as designated by the + @remarks ping requests factor into the mean round trip time as designated by the roundTripTime field in the ENetPeer structure. Enet automatically pings all connected peers at regular intervals, however, this function may be called to ensure more frequent ping requests. @@ -438,12 +438,12 @@ enet_peer_ping (ENetPeer * peer) command.header.command = ENET_PROTOCOL_COMMAND_PING | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; command.header.channelID = 0xFF; - + enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); } -/** Sets the interval at which pings will be sent to a peer. - +/** Sets the interval at which pings will be sent to a peer. + Pings are used both to monitor the liveness of the connection and also to dynamically adjust the throttle during periods of low traffic so that the throttle has reasonable responsiveness during traffic spikes. @@ -461,13 +461,13 @@ enet_peer_ping_interval (ENetPeer * peer, enet_uint32 pingInterval) The timeout parameter control how and when a peer will timeout from a failure to acknowledge reliable traffic. Timeout values use an exponential backoff mechanism, where if a reliable - packet is not acknowledge within some multiple of the average RTT plus a variance tolerance, + packet is not acknowledge within some multiple of the average RTT plus a variance tolerance, the timeout will be doubled until it reaches a set limit. If the timeout is thus at this - limit and reliable packets have been sent but not acknowledged within a certain minimum time + limit and reliable packets have been sent but not acknowledged within a certain minimum time period, the peer will be disconnected. Alternatively, if reliable packets have been sent but not acknowledged for a certain maximum time period, the peer will be disconnected regardless of the current timeout limit value. - + @param peer the peer to adjust @param timeoutLimit the timeout limit; defaults to ENET_PEER_TIMEOUT_LIMIT if 0 @param timeoutMinimum the timeout minimum; defaults to ENET_PEER_TIMEOUT_MINIMUM if 0 @@ -540,8 +540,8 @@ enet_peer_disconnect (ENetPeer * peer, enet_uint32 data) if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; else - command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED; - + command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED; + enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) @@ -565,10 +565,10 @@ enet_peer_disconnect (ENetPeer * peer, enet_uint32 data) */ void enet_peer_disconnect_later (ENetPeer * peer, enet_uint32 data) -{ - if ((peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) && +{ + if ((peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) && ! (enet_list_empty (& peer -> outgoingReliableCommands) && - enet_list_empty (& peer -> outgoingUnreliableCommands) && + enet_list_empty (& peer -> outgoingUnreliableCommands) && enet_list_empty (& peer -> sentReliableCommands))) { peer -> state = ENET_PEER_STATE_DISCONNECT_LATER; @@ -604,9 +604,9 @@ enet_peer_queue_acknowledgement (ENetPeer * peer, const ENetProtocol * command, acknowledgement -> sentTime = sentTime; acknowledgement -> command = * command; - + enet_list_insert (enet_list_end (& peer -> acknowledgements), acknowledgement); - + return acknowledgement; } @@ -614,7 +614,7 @@ void enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoingCommand) { ENetChannel * channel = & peer -> channels [outgoingCommand -> command.header.channelID]; - + peer -> outgoingDataTotal += enet_protocol_command_size (outgoingCommand -> command.header.command) + outgoingCommand -> fragmentLength; if (outgoingCommand -> command.header.channelID == 0xFF) @@ -645,11 +645,11 @@ enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoin { if (outgoingCommand -> fragmentOffset == 0) ++ channel -> outgoingUnreliableSequenceNumber; - + outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber; outgoingCommand -> unreliableSequenceNumber = channel -> outgoingUnreliableSequenceNumber; } - + outgoingCommand -> sendAttempts = 0; outgoingCommand -> sentTime = 0; outgoingCommand -> roundTripTimeout = 0; @@ -665,7 +665,7 @@ enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoin case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED: outgoingCommand -> command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_16 (peer -> outgoingUnsequencedGroup); break; - + default: break; } @@ -734,7 +734,7 @@ enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * if (droppedCommand != currentCommand) droppedCommand = enet_list_previous (currentCommand); } - else + else { enet_uint16 reliableWindow = incomingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE, currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; @@ -757,7 +757,7 @@ enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * } } } - + startCommand = enet_list_next (currentCommand); } @@ -788,7 +788,7 @@ enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * ch currentCommand = enet_list_next (currentCommand)) { ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; - + if (incomingCommand -> fragmentsRemaining > 0 || incomingCommand -> reliableSequenceNumber != (enet_uint16) (channel -> incomingReliableSequenceNumber + 1)) break; @@ -797,7 +797,7 @@ enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * ch if (incomingCommand -> fragmentCount > 0) channel -> incomingReliableSequenceNumber += incomingCommand -> fragmentCount - 1; - } + } if (currentCommand == enet_list_begin (& channel -> incomingReliableCommands)) return; @@ -843,14 +843,14 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1) goto freePacket; } - + switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK) { case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber) goto freePacket; - + for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands)); currentCommand != enet_list_end (& channel -> incomingReliableCommands); currentCommand = enet_list_previous (currentCommand)) @@ -880,7 +880,7 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT: unreliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendUnreliable.unreliableSequenceNumber); - if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber && + if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber && unreliableSequenceNumber <= channel -> incomingUnreliableSequenceNumber) goto freePacket; @@ -937,9 +937,9 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, incomingCommand -> fragmentsRemaining = fragmentCount; incomingCommand -> packet = packet; incomingCommand -> fragments = NULL; - + if (fragmentCount > 0) - { + { if (fragmentCount <= ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT) incomingCommand -> fragments = (enet_uint32 *) enet_malloc ((fragmentCount + 31) / 32 * sizeof (enet_uint32)); if (incomingCommand -> fragments == NULL) diff --git a/protocol.c b/protocol.c index 80cc579a..b4e7e744 100644 --- a/protocol.c +++ b/protocol.c @@ -1,4 +1,4 @@ -/** +/** @file protocol.c @brief ENet protocol functions */ @@ -76,7 +76,7 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event) event -> data = peer -> eventData; return 1; - + case ENET_PEER_STATE_ZOMBIE: host -> recalculateBandwidthLimits = 1; @@ -95,14 +95,14 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event) event -> packet = enet_peer_receive (peer, & event -> channelID); if (event -> packet == NULL) continue; - + event -> type = ENET_EVENT_TYPE_RECEIVE; event -> peer = peer; if (! enet_list_empty (& peer -> dispatchedCommands)) { peer -> needsDispatch = 1; - + enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList); } @@ -129,7 +129,7 @@ enet_protocol_notify_connect (ENetHost * host, ENetPeer * peer, ENetEvent * even event -> peer = peer; event -> data = peer -> eventData; } - else + else enet_protocol_dispatch_state (host, peer, peer -> state == ENET_PEER_STATE_CONNECTING ? ENET_PEER_STATE_CONNECTION_SUCCEEDED : ENET_PEER_STATE_CONNECTION_PENDING); } @@ -150,7 +150,7 @@ enet_protocol_notify_disconnect (ENetHost * host, ENetPeer * peer, ENetEvent * e enet_peer_reset (peer); } - else + else { peer -> eventData = 0; @@ -166,7 +166,7 @@ enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer) while (! enet_list_empty (& peer -> sentUnreliableCommands)) { outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentUnreliableCommands); - + enet_list_remove (& outgoingCommand -> outgoingCommandList); if (outgoingCommand -> packet != NULL) @@ -176,7 +176,7 @@ enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer) if (outgoingCommand -> packet -> referenceCount == 0) { outgoingCommand -> packet -> flags |= ENET_PACKET_FLAG_SENT; - + enet_packet_destroy (outgoingCommand -> packet); } } @@ -198,7 +198,7 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl currentCommand = enet_list_next (currentCommand)) { outgoingCommand = (ENetOutgoingCommand *) currentCommand; - + if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber && outgoingCommand -> command.header.channelID == channelID) break; @@ -241,7 +241,7 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl } commandNumber = (ENetProtocolCommand) (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK); - + enet_list_remove (& outgoingCommand -> outgoingCommandList); if (outgoingCommand -> packet != NULL) @@ -263,13 +263,13 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl if (enet_list_empty (& peer -> sentReliableCommands)) return commandNumber; - + outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentReliableCommands); - + peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout; return commandNumber; -} +} static ENetPeer * enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENetProtocol * command) @@ -292,8 +292,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet ++ currentPeer) { if (currentPeer -> state != ENET_PEER_STATE_DISCONNECTED && - currentPeer -> address.host == host -> receivedAddress.host && - currentPeer -> address.port == host -> receivedAddress.port && + ENET_ADDRESS_COMPARE(&(currentPeer -> address), &(host -> receivedAddress)) && currentPeer -> connectID == command -> connect.connectID) return NULL; } @@ -375,7 +374,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; else currentPeer -> windowSize = (ENET_MIN (host -> outgoingBandwidth, currentPeer -> incomingBandwidth) / - ENET_PEER_WINDOW_SIZE_SCALE) * + ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) @@ -462,11 +461,11 @@ enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const E if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || * currentData < host -> receivedData || * currentData > & host -> receivedData [host -> receivedDataLength]) - return -1; + return -1; unsequencedGroup = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.unsequencedGroup); index = unsequencedGroup % ENET_PEER_UNSEQUENCED_WINDOW_SIZE; - + if (unsequencedGroup < peer -> incomingUnsequencedGroup) unsequencedGroup += 0x10000; @@ -484,16 +483,16 @@ enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const E else if (peer -> unsequencedWindow [index / 32] & (1 << (index % 32))) return 0; - + packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnsequenced), dataLength, ENET_PACKET_FLAG_UNSEQUENCED); if (packet == NULL || enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL) return -1; - + peer -> unsequencedWindow [index / 32] |= 1 << (index % 32); - + return 0; } @@ -564,14 +563,14 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet fragmentCount = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentCount); fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset); totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength); - + if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT || fragmentNumber >= fragmentCount || totalLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || fragmentOffset >= totalLength || fragmentLength > totalLength - fragmentOffset) return -1; - + for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands)); currentCommand != enet_list_end (& channel -> incomingReliableCommands); currentCommand = enet_list_previous (currentCommand)) @@ -591,7 +590,7 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet { if (incomingCommand -> reliableSequenceNumber < startSequenceNumber) break; - + if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_FRAGMENT || totalLength != incomingCommand -> packet -> dataLength || fragmentCount != incomingCommand -> fragmentCount) @@ -601,7 +600,7 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet break; } } - + if (startCommand == NULL) { ENetProtocol hostCommand = * command; @@ -615,7 +614,7 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet if (startCommand == NULL) return -1; } - + if ((startCommand -> fragments [fragmentNumber / 32] & (1 << (fragmentNumber % 32))) == 0) { -- startCommand -> fragmentsRemaining; @@ -881,7 +880,7 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * if (peer -> roundTripTime < peer -> lowestRoundTripTime) peer -> lowestRoundTripTime = peer -> roundTripTime; - if (peer -> roundTripTimeVariance > peer -> highestRoundTripTimeVariance) + if (peer -> roundTripTimeVariance > peer -> highestRoundTripTimeVariance) peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance; if (peer -> packetThrottleEpoch == 0 || @@ -916,7 +915,7 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * case ENET_PEER_STATE_DISCONNECT_LATER: if (enet_list_empty (& peer -> outgoingReliableCommands) && - enet_list_empty (& peer -> outgoingUnreliableCommands) && + enet_list_empty (& peer -> outgoingUnreliableCommands) && enet_list_empty (& peer -> sentReliableCommands)) enet_peer_disconnect (peer, peer -> eventData); break; @@ -924,7 +923,7 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * default: break; } - + return 0; } @@ -953,7 +952,7 @@ enet_protocol_handle_verify_connect (ENetHost * host, ENetEvent * event, ENetPee } enet_protocol_remove_sent_reliable_command (peer, 1, 0xFF); - + if (channelCount < peer -> channelCount) peer -> channelCount = channelCount; @@ -965,7 +964,7 @@ enet_protocol_handle_verify_connect (ENetHost * host, ENetEvent * event, ENetPee if (mtu < ENET_PROTOCOL_MINIMUM_MTU) mtu = ENET_PROTOCOL_MINIMUM_MTU; - else + else if (mtu > ENET_PROTOCOL_MAXIMUM_MTU) mtu = ENET_PROTOCOL_MAXIMUM_MTU; @@ -1026,14 +1025,13 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) if (peer -> state == ENET_PEER_STATE_DISCONNECTED || peer -> state == ENET_PEER_STATE_ZOMBIE || - ((host -> receivedAddress.host != peer -> address.host || - host -> receivedAddress.port != peer -> address.port) && - peer -> address.host != ENET_HOST_BROADCAST) || + (!ENET_ADDRESS_COMPARE(&(peer -> address), &(host -> receivedAddress)) && + peer -> address.ip.v4.host != ENET_HOST_BROADCAST) || // BAD: IGNORES IPv6 CASE! (peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID && sessionID != peer -> incomingSessionID)) return 0; } - + if (flags & ENET_PROTOCOL_HEADER_FLAG_COMPRESSED) { size_t originalSize; @@ -1041,9 +1039,9 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) return 0; originalSize = host -> compressor.decompress (host -> compressor.context, - host -> receivedData + headerSize, - host -> receivedDataLength - headerSize, - host -> packetData [1] + headerSize, + host -> receivedData + headerSize, + host -> receivedDataLength - headerSize, + host -> packetData [1] + headerSize, sizeof (host -> packetData [1]) - headerSize); if (originalSize <= 0 || originalSize > sizeof (host -> packetData [1]) - headerSize) return 0; @@ -1067,16 +1065,29 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) if (host -> checksum (& buffer, 1) != desiredChecksum) return 0; } - + if (peer != NULL) { - peer -> address.host = host -> receivedAddress.host; - peer -> address.port = host -> receivedAddress.port; + peer -> address.port = host -> receivedAddress.port; peer -> incomingDataTotal += host -> receivedDataLength; + + switch (peer -> address.family) + { + case AF_INET: + peer -> address.ip.v4.host = host -> receivedAddress.ip.v4.host; + break; + case AF_INET6: + peer -> address.ip.v6.flow_info = host -> receivedAddress.ip.v6.flow_info; + peer -> address.ip.v6.scope_id = host -> receivedAddress.ip.v6.scope_id; + { + int i = 0; + for (; i < 4; i++) peer -> address.ip.v6.host[i] = host -> receivedAddress.ip.v6.host[i]; + } + } } - + currentData = host -> receivedData + headerSize; - + while (currentData < & host -> receivedData [host -> receivedDataLength]) { enet_uint8 commandNumber; @@ -1088,9 +1099,9 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) break; commandNumber = command -> header.command & ENET_PROTOCOL_COMMAND_MASK; - if (commandNumber >= ENET_PROTOCOL_COMMAND_COUNT) + if (commandNumber >= ENET_PROTOCOL_COMMAND_COUNT) break; - + commandSize = commandSizes [commandNumber]; if (commandSize == 0 || currentData + commandSize > & host -> receivedData [host -> receivedDataLength]) break; @@ -1099,7 +1110,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) if (peer == NULL && commandNumber != ENET_PROTOCOL_COMMAND_CONNECT) break; - + command -> header.reliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> header.reliableSequenceNumber); switch (commandNumber) @@ -1194,8 +1205,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) enet_peer_queue_acknowledgement (peer, command, sentTime); break; - default: - enet_peer_queue_acknowledgement (peer, command, sentTime); + default: + enet_peer_queue_acknowledgement (peer, command, sentTime); break; } } @@ -1207,7 +1218,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) return 0; } - + static int enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event) { @@ -1232,7 +1243,7 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event) host -> receivedData = host -> packetData [0]; host -> receivedDataLength = receivedLength; - + host -> totalReceivedData += receivedLength; host -> totalReceivedPackets ++; @@ -1245,20 +1256,20 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event) return 1; continue; - + case -1: return -1; - + default: break; } } - + switch (enet_protocol_handle_incoming_commands (host, event)) { case 1: return 1; - + case -1: return -1; @@ -1278,9 +1289,9 @@ enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer) ENetAcknowledgement * acknowledgement; ENetListIterator currentAcknowledgement; enet_uint16 reliableSequenceNumber; - + currentAcknowledgement = enet_list_begin (& peer -> acknowledgements); - + while (currentAcknowledgement != enet_list_end (& peer -> acknowledgements)) { if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || @@ -1293,7 +1304,7 @@ enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer) } acknowledgement = (ENetAcknowledgement *) currentAcknowledgement; - + currentAcknowledgement = enet_list_next (currentAcknowledgement); buffer -> data = command; @@ -1302,13 +1313,13 @@ enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer) host -> packetSize += buffer -> dataLength; reliableSequenceNumber = ENET_HOST_TO_NET_16 (acknowledgement -> command.header.reliableSequenceNumber); - + command -> header.command = ENET_PROTOCOL_COMMAND_ACKNOWLEDGE; command -> header.channelID = acknowledgement -> command.header.channelID; command -> header.reliableSequenceNumber = reliableSequenceNumber; command -> acknowledge.receivedReliableSequenceNumber = reliableSequenceNumber; command -> acknowledge.receivedSentTime = ENET_HOST_TO_NET_16 (acknowledgement -> sentTime); - + if ((acknowledgement -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT) enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); @@ -1332,7 +1343,7 @@ enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * pee ENetListIterator currentCommand; currentCommand = enet_list_begin (& peer -> outgoingUnreliableCommands); - + while (currentCommand != enet_list_end (& peer -> outgoingUnreliableCommands)) { size_t commandSize; @@ -1357,7 +1368,7 @@ enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * pee { peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER; peer -> packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE; - + if (peer -> packetThrottleCounter > peer -> packetThrottle) { enet_uint16 reliableSequenceNumber = outgoingCommand -> reliableSequenceNumber, @@ -1368,7 +1379,7 @@ enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * pee if (outgoingCommand -> packet -> referenceCount == 0) enet_packet_destroy (outgoingCommand -> packet); - + enet_list_remove (& outgoingCommand -> outgoingCommandList); enet_free (outgoingCommand); @@ -1382,24 +1393,24 @@ enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * pee currentCommand = enet_list_next (currentCommand); } - + continue; } } buffer -> data = command; buffer -> dataLength = commandSize; - + host -> packetSize += buffer -> dataLength; * command = outgoingCommand -> command; - + enet_list_remove (& outgoingCommand -> outgoingCommandList); if (outgoingCommand -> packet != NULL) { ++ buffer; - + buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset; buffer -> dataLength = outgoingCommand -> fragmentLength; @@ -1412,14 +1423,14 @@ enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * pee ++ command; ++ buffer; - } + } host -> commandCount = command - host -> commands; host -> bufferCount = buffer - host -> buffers; - if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER && + if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER && enet_list_empty (& peer -> outgoingReliableCommands) && - enet_list_empty (& peer -> outgoingUnreliableCommands) && + enet_list_empty (& peer -> outgoingUnreliableCommands) && enet_list_empty (& peer -> sentReliableCommands)) enet_peer_disconnect (peer, peer -> eventData); } @@ -1458,7 +1469,7 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even if (outgoingCommand -> packet != NULL) peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength; - + ++ peer -> packetsLost; outgoingCommand -> roundTripTimeout *= 2; @@ -1473,7 +1484,7 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout; } } - + return 0; } @@ -1490,7 +1501,7 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer) int windowExceeded = 0, windowWrap = 0, canPing = 1; currentCommand = enet_list_begin (& peer -> outgoingReliableCommands); - + while (currentCommand != enet_list_end (& peer -> outgoingReliableCommands)) { outgoingCommand = (ENetOutgoingCommand *) currentCommand; @@ -1499,27 +1510,27 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer) reliableWindow = outgoingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; if (channel != NULL) { - if (! windowWrap && - outgoingCommand -> sendAttempts < 1 && + if (! windowWrap && + outgoingCommand -> sendAttempts < 1 && ! (outgoingCommand -> reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) && (channel -> reliableWindows [(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE || - channel -> usedReliableWindows & ((((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) << reliableWindow) | + channel -> usedReliableWindows & ((((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) << reliableWindow) | (((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) >> (ENET_PEER_RELIABLE_WINDOW_SIZE - reliableWindow))))) windowWrap = 1; if (windowWrap) { currentCommand = enet_list_next (currentCommand); - + continue; } } - + if (outgoingCommand -> packet != NULL) { if (! windowExceeded) { enet_uint32 windowSize = (peer -> packetThrottle * peer -> windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE; - + if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > ENET_MAX (windowSize, peer -> mtu)) windowExceeded = 1; } @@ -1537,11 +1548,11 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer) if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || peer -> mtu - host -> packetSize < commandSize || - (outgoingCommand -> packet != NULL && + (outgoingCommand -> packet != NULL && (enet_uint16) (peer -> mtu - host -> packetSize) < (enet_uint16) (commandSize + outgoingCommand -> fragmentLength))) { host -> continueSending = 1; - + break; } @@ -1554,7 +1565,7 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer) } ++ outgoingCommand -> sendAttempts; - + if (outgoingCommand -> roundTripTimeout == 0) { outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance; @@ -1580,7 +1591,7 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer) if (outgoingCommand -> packet != NULL) { ++ buffer; - + buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset; buffer -> dataLength = outgoingCommand -> fragmentLength; @@ -1590,7 +1601,7 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer) } ++ peer -> packetsSent; - + ++ command; ++ buffer; } @@ -1609,7 +1620,7 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch ENetPeer * currentPeer; int sentLength; size_t shouldCompress = 0; - + host -> continueSending = 1; while (host -> continueSending) @@ -1646,11 +1657,11 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch enet_list_empty (& currentPeer -> sentReliableCommands) && ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= currentPeer -> pingInterval && currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing)) - { + { enet_peer_ping (currentPeer); enet_protocol_send_reliable_outgoing_commands (host, currentPeer); } - + if (! enet_list_empty (& currentPeer -> outgoingUnreliableCommands)) enet_protocol_send_unreliable_outgoing_commands (host, currentPeer); @@ -1669,11 +1680,11 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch #ifdef WIN32 printf ( #else - fprintf (stderr, + fprintf (stderr, #endif "peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingReliableCommands), enet_list_size (& currentPeer -> outgoingUnreliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0); #endif - + currentPeer -> packetLossVariance -= currentPeer -> packetLossVariance / 4; if (packetLoss >= currentPeer -> packetLoss) @@ -1756,7 +1767,7 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch host -> totalSentData += sentLength; host -> totalSentPackets ++; } - + return 0; } @@ -1837,7 +1848,7 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout) } host -> serviceTime = enet_time_get (); - + timeout += host -> serviceTime; do @@ -1929,6 +1940,5 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout) host -> serviceTime = enet_time_get (); } while (waitCondition & ENET_SOCKET_WAIT_RECEIVE); - return 0; + return 0; } - diff --git a/unix.c b/unix.c index 47ffcb9f..e770d22a 100644 --- a/unix.c +++ b/unix.c @@ -1,4 +1,4 @@ -/** +/** @file unix.c @brief ENet Unix system specific functions */ @@ -57,6 +57,16 @@ typedef int socklen_t; static enet_uint32 timeBase = 0; +static inline size_t +enet_address_get_size (const ENetAddress * address) +{ + switch (address -> family) + { + case AF_INET: return (sizeof (struct sockaddr_in)); + case AF_INET6: return (sizeof (struct sockaddr_in6)); + }; +} + int enet_initialize (void) { @@ -84,132 +94,91 @@ enet_time_set (enet_uint32 newTimeBase) struct timeval timeVal; gettimeofday (& timeVal, NULL); - + timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase; } +const static struct addrinfo hints = { + /*.ai_flags =*/ AI_PASSIVE, // For wildcard IP address + /*.ai_family =*/ AF_UNSPEC, // Allow IPv4 or IPv6 + /*.ai_socktype =*/ SOCK_DGRAM, // Datagram socket + /*.ai_protocol =*/ 0, // Any protocol + /*.ai_addrlen =*/ 0, + /*.ai_addr =*/ NULL, + /*.ai_canonname =*/ NULL, + /*.ai_next =*/ NULL, +}; + int enet_address_set_host (ENetAddress * address, const char * name) { - struct hostent * hostEntry = NULL; -#ifdef HAS_GETHOSTBYNAME_R - struct hostent hostData; - char buffer [2048]; - int errnum; - -#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum); -#else - hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum); -#endif -#else - hostEntry = gethostbyname (name); -#endif + struct addrinfo * result_box; + int error_code; - if (hostEntry == NULL || - hostEntry -> h_addrtype != AF_INET) - { -#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; - } + error_code = getaddrinfo(name, NULL, &hints, &result_box); + if (error_code != 0) return error_code; + if (result_box == NULL) return -1; - address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0]; - - return 0; + memcopy(&address, result_box -> ai_addr, result_box -> ai_addrlen); + address -> port = ENET_NET_TO_HOST_16 (address -> port); + return error_code; } int enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength) { -#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; + void * host_ptr; + switch (address -> family) { + case AF_INET: + host_ptr = & address -> ip.v4.host; + break; + case AF_INET6: + host_ptr = & address -> ip.v6.host; + break; + default: + host_ptr == NULL; // avoid wild pointer + } + return (inet_ntop (address -> family, host_ptr, name, nameLength) == NULL) ? -1 : 0; } int enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength) { - struct in_addr in; - struct hostent * hostEntry = NULL; -#ifdef HAS_GETHOSTBYADDR_R - struct hostent hostData; - char buffer [2048]; - int errnum; - - in.s_addr = address -> host; - -#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum); -#else - hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum); -#endif -#else - in.s_addr = address -> host; + int error_code = getnameinfo((struct sockaddr *) address, enet_address_get_size(address), + name, nameLength, + NULL, 0, // disregard service/socket name + NI_DGRAM); // lookup via UPD when different - hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET); -#endif - - if (hostEntry == NULL) - return enet_address_get_host_ip (address, name, nameLength); - - strncpy (name, hostEntry -> h_name, nameLength); - - return 0; + // return IP address if name lookup is unsuccessful + return (error_code == 0) ? 0 : enet_address_get_host_ip (address, name, nameLength); } int enet_socket_bind (ENetSocket socket, const ENetAddress * address) { - struct sockaddr_in sin; - - memset (& sin, 0, sizeof (struct sockaddr_in)); + const size_t length = enet_address_get_size (address); + ENetAddress * clone; - sin.sin_family = AF_INET; + memcopy (& clone, address, length); + clone -> port = ENET_HOST_TO_NET_16 (address -> port); - if (address != 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 bind (socket, - (struct sockaddr *) & sin, - sizeof (struct sockaddr_in)); + return bind (socket, (struct sockaddr *) clone, length); } int enet_socket_get_address (ENetSocket socket, ENetAddress * address) { - struct sockaddr_in sin; - socklen_t sinLength = sizeof (struct sockaddr_in); + socklen_t length = sizeof (struct sockaddr_in6); - if (getsockname (socket, (struct sockaddr *) & sin, & sinLength) == -1) + if (getsockname (socket, (struct sockaddr *) & address, & length) == -1) return -1; - address -> host = (enet_uint32) sin.sin_addr.s_addr; - address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); + address -> port = ENET_NET_TO_HOST_16 (address -> port); return 0; } -int +int enet_socket_listen (ENetSocket socket, int backlog) { return listen (socket, backlog < 0 ? SOMAXCONN : backlog); @@ -268,19 +237,17 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value) int enet_socket_connect (ENetSocket socket, const ENetAddress * address) { - struct sockaddr_in sin; int result; + size_t length = enet_address_get_size (address); + ENetAddress * clone; - memset (& sin, 0, sizeof (struct sockaddr_in)); + memcopy (& clone, address, length); + clone -> port = ENET_HOST_TO_NET_16 (address -> port); - sin.sin_family = AF_INET; - sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); - sin.sin_addr.s_addr = address -> host; + result = connect (socket, (struct sockaddr *) & clone, length); - result = connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)); if (result == -1 && errno == EINPROGRESS) return 0; - return result; } @@ -288,25 +255,22 @@ ENetSocket enet_socket_accept (ENetSocket socket, ENetAddress * address) { int result; - struct sockaddr_in sin; - socklen_t sinLength = sizeof (struct sockaddr_in); + // only call enet_address_get_size if ptr is valid + socklen_t length = sizeof (struct sockaddr_in6); + + result = accept (socket, + address != NULL ? (struct sockaddr *) & address : NULL, + address != NULL ? & length : NULL); - result = accept (socket, - address != NULL ? (struct sockaddr *) & sin : NULL, - address != NULL ? & sinLength : NULL); - if (result == -1) - return ENET_SOCKET_NULL; + return ENET_SOCKET_NULL; if (address != NULL) - { - address -> host = (enet_uint32) sin.sin_addr.s_addr; - address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); - } + address -> port = ENET_NET_TO_HOST_16 (address -> port); return result; -} - +} + int enet_socket_shutdown (ENetSocket socket, ENetSocketShutdown how) { @@ -327,28 +291,26 @@ enet_socket_send (ENetSocket socket, size_t bufferCount) { struct msghdr msgHdr; - struct sockaddr_in sin; + ENetAddress address_clone; int sentLength; memset (& msgHdr, 0, sizeof (struct msghdr)); if (address != NULL) { - memset (& sin, 0, sizeof (struct sockaddr_in)); + msgHdr.msg_name = & address_clone; + msgHdr.msg_namelen = enet_address_get_size (address); - sin.sin_family = AF_INET; - sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); - sin.sin_addr.s_addr = address -> host; + memcopy (& address_clone, address, msgHdr.msg_namelen); - msgHdr.msg_name = & sin; - msgHdr.msg_namelen = sizeof (struct sockaddr_in); + address_clone.port = ENET_HOST_TO_NET_16 (address -> port); } msgHdr.msg_iov = (struct iovec *) buffers; msgHdr.msg_iovlen = bufferCount; sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL); - + if (sentLength == -1) { if (errno == EWOULDBLOCK) @@ -367,15 +329,14 @@ enet_socket_receive (ENetSocket socket, size_t bufferCount) { struct msghdr msgHdr; - struct sockaddr_in sin; int recvLength; memset (& msgHdr, 0, sizeof (struct msghdr)); if (address != NULL) { - msgHdr.msg_name = & sin; - msgHdr.msg_namelen = sizeof (struct sockaddr_in); + msgHdr.msg_name = & address; + msgHdr.msg_namelen = sizeof (struct sockaddr_in6); } msgHdr.msg_iov = (struct iovec *) buffers; @@ -397,10 +358,7 @@ enet_socket_receive (ENetSocket socket, #endif if (address != NULL) - { - address -> host = (enet_uint32) sin.sin_addr.s_addr; - address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); - } + address -> port = ENET_NET_TO_HOST_16 (address -> port); return recvLength; } @@ -422,7 +380,7 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou #ifdef HAS_POLL struct pollfd pollSocket; int pollCount; - + pollSocket.fd = socket; pollSocket.events = 0; @@ -453,7 +411,7 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou if (pollSocket.revents & POLLOUT) * condition |= ENET_SOCKET_WAIT_SEND; - + if (pollSocket.revents & POLLIN) * condition |= ENET_SOCKET_WAIT_RECEIVE; @@ -485,7 +443,7 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou return 0; } - + return -1; } @@ -505,4 +463,3 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou } #endif - diff --git a/win32.c b/win32.c index c7c514e9..77a7108e 100644 --- a/win32.c +++ b/win32.c @@ -1,4 +1,4 @@ -/** +/** @file win32.c @brief ENet Win32 system specific functions */ @@ -10,12 +10,22 @@ static enet_uint32 timeBase = 0; +static inline size_t +enet_address_get_size (const ENetAddress * address) +{ + switch (address -> family) + { + case AF_INET: return (sizeof (struct sockaddr_in)); + case AF_INET6: return (sizeof (struct sockaddr_in6)); + }; +} + int enet_initialize (void) { WORD versionRequested = MAKEWORD (1, 1); WSADATA wsaData; - + if (WSAStartup (versionRequested, & wsaData)) return -1; @@ -23,7 +33,7 @@ enet_initialize (void) HIBYTE (wsaData.wVersion) != 1) { WSACleanup (); - + return -1; } @@ -52,90 +62,82 @@ enet_time_set (enet_uint32 newTimeBase) timeBase = (enet_uint32) timeGetTime () - newTimeBase; } +const static struct addrinfo hints = { + /*.ai_flags =*/ AI_PASSIVE, // For wildcard IP address + /*.ai_family =*/ AF_UNSPEC, // Allow IPv4 or IPv6 + /*.ai_socktype =*/ SOCK_DGRAM, // Datagram socket + /*.ai_protocol =*/ 0, // Any protocol + /*.ai_addrlen =*/ 0, + /*.ai_addr =*/ NULL, + /*.ai_canonname =*/ NULL, + /*.ai_next =*/ NULL, +}; + int enet_address_set_host (ENetAddress * address, const char * name) { - struct hostent * hostEntry; + struct addrinfo * result_box; + int error_code; - hostEntry = gethostbyname (name); - if (hostEntry == NULL || - hostEntry -> h_addrtype != AF_INET) - { - unsigned long host = inet_addr (name); - if (host == INADDR_NONE) - return -1; - address -> host = host; - return 0; - } + error_code = getaddrinfo(name, NULL, &hints, &result_box); + if (error_code != 0) return error_code; + if (result_box == NULL) return -1; - address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0]; - - return 0; + memcopy(&address, result_box -> ai_addr, result_box -> ai_addrlen); + address -> port = ENET_NET_TO_HOST_16 (address -> port); + return error_code; } int enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength) { - char * addr = inet_ntoa (* (struct in_addr *) & address -> host); - if (addr == NULL) - return -1; - strncpy (name, addr, nameLength); - return 0; + void * host_ptr; + switch (address -> family) { + case AF_INET: + host_ptr = & address -> ip.v4.host; + break; + case AF_INET6: + host_ptr = & address -> ip.v6.host; + break; + default: + host_ptr == NULL; // avoid wild pointer + } + return (inet_ntop (address -> family, host_ptr, name, nameLength) == NULL) ? -1 : 0; } int enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength) { - struct in_addr in; - struct hostent * hostEntry; - - in.s_addr = address -> host; - - hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET); - if (hostEntry == NULL) - return enet_address_get_host_ip (address, name, nameLength); - - strncpy (name, hostEntry -> h_name, nameLength); + int error_code = getnameinfo((struct sockaddr *) address, enet_address_get_size(address), + name, nameLength, + NULL, 0, // disregard service/socket name + NI_DGRAM); // lookup via UPD when different - return 0; + // return IP address if name lookup is unsuccessful + return (error_code == 0) ? 0 : enet_address_get_host_ip (address, name, nameLength); } int enet_socket_bind (ENetSocket socket, const ENetAddress * address) { - struct sockaddr_in sin; - - memset (& sin, 0, sizeof (struct sockaddr_in)); + const size_t length = enet_address_get_size (address); + ENetAddress * clone; - sin.sin_family = AF_INET; + memcopy (& clone, address, length); + clone -> port = ENET_HOST_TO_NET_16 (address -> port); - if (address != 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 bind (socket, - (struct sockaddr *) & sin, - sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0; + return bind (socket, (struct sockaddr *) clone, length); } int enet_socket_get_address (ENetSocket socket, ENetAddress * address) { - struct sockaddr_in sin; - int sinLength = sizeof (struct sockaddr_in); + int length = sizeof (struct sockaddr_in6); - if (getsockname (socket, (struct sockaddr *) & sin, & sinLength) == -1) + if (getsockname (socket, (struct sockaddr *) & address, & length) == -1) return -1; - address -> host = (enet_uint32) sin.sin_addr.s_addr; - address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); + address -> port = ENET_NET_TO_HOST_16 (address -> port); return 0; } @@ -198,16 +200,15 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value) int enet_socket_connect (ENetSocket socket, const ENetAddress * address) { - struct sockaddr_in sin; int result; + size_t length = enet_address_get_size (address); + ENetAddress * clone; - memset (& sin, 0, sizeof (struct sockaddr_in)); + memcopy (& clone, address, length); + clone -> port = ENET_HOST_TO_NET_16 (address -> port); - sin.sin_family = AF_INET; - sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); - sin.sin_addr.s_addr = address -> host; + result = connect (socket, (struct sockaddr *) & clone, length); - result = connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)); if (result == SOCKET_ERROR && WSAGetLastError () != WSAEWOULDBLOCK) return -1; @@ -218,21 +219,17 @@ ENetSocket enet_socket_accept (ENetSocket socket, ENetAddress * address) { SOCKET result; - struct sockaddr_in sin; - int sinLength = sizeof (struct sockaddr_in); - - result = accept (socket, - address != NULL ? (struct sockaddr *) & sin : NULL, - address != NULL ? & sinLength : NULL); + // only call enet_address_get_size if ptr is valid + int length = address != NULL ? enet_address_get_size (address) : 0; + result = accept (socket, + address != NULL ? (struct sockaddr *) & address : NULL, + address != NULL ? & length : NULL); if (result == INVALID_SOCKET) return ENET_SOCKET_NULL; if (address != NULL) - { - address -> host = (enet_uint32) sin.sin_addr.s_addr; - address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); - } + address -> port = ENET_NET_TO_HOST_16 (address -> port); return result; } @@ -256,25 +253,24 @@ enet_socket_send (ENetSocket socket, const ENetBuffer * buffers, size_t bufferCount) { - struct sockaddr_in sin; + ENetAddress address_clone; + int address_length = enet_address_get_size (address); DWORD sentLength; if (address != NULL) { - memset (& sin, 0, sizeof (struct sockaddr_in)); + memcopy (& address_clone, address, address_length); - sin.sin_family = AF_INET; - sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); - sin.sin_addr.s_addr = address -> host; + address_clone.port = ENET_HOST_TO_NET_16 (address -> port); } - if (WSASendTo (socket, + if (WSASendTo (socket, (LPWSABUF) buffers, (DWORD) bufferCount, & sentLength, 0, - address != NULL ? (struct sockaddr *) & sin : NULL, - address != NULL ? sizeof (struct sockaddr_in) : 0, + address != NULL ? (struct sockaddr *) & address_clone : NULL, + address != NULL ? address_length : 0, NULL, NULL) == SOCKET_ERROR) { @@ -293,18 +289,17 @@ enet_socket_receive (ENetSocket socket, ENetBuffer * buffers, size_t bufferCount) { - INT sinLength = sizeof (struct sockaddr_in); + INT length = sizeof (struct sockaddr_in6); DWORD flags = 0, recvLength; - struct sockaddr_in sin; if (WSARecvFrom (socket, (LPWSABUF) buffers, (DWORD) bufferCount, & recvLength, & flags, - address != NULL ? (struct sockaddr *) & sin : NULL, - address != NULL ? & sinLength : NULL, + address != NULL ? (struct sockaddr *) address : NULL, + address != NULL ? & length : NULL, NULL, NULL) == SOCKET_ERROR) { @@ -322,10 +317,7 @@ enet_socket_receive (ENetSocket socket, return -1; if (address != NULL) - { - address -> host = (enet_uint32) sin.sin_addr.s_addr; - address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); - } + address -> port = ENET_NET_TO_HOST_16 (address -> port); return (int) recvLength; } @@ -347,10 +339,10 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou fd_set readSet, writeSet; struct timeval timeVal; int selectCount; - + timeVal.tv_sec = timeout / 1000; timeVal.tv_usec = (timeout % 1000) * 1000; - + FD_ZERO (& readSet); FD_ZERO (& writeSet); @@ -372,12 +364,11 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou if (FD_ISSET (socket, & writeSet)) * condition |= ENET_SOCKET_WAIT_SEND; - + if (FD_ISSET (socket, & readSet)) * condition |= ENET_SOCKET_WAIT_RECEIVE; return 0; -} +} #endif -