1 Commits

Author SHA1 Message Date
Cameron Gutman 3fcb07f723 fix RTO limit being exceeded 2021-05-14 18:48:47 -05:00
8 changed files with 457 additions and 765 deletions
-15
View File
@@ -7,7 +7,6 @@ include(CheckFunctionExists)
include(CheckStructHasMember)
include(CheckTypeSize)
check_function_exists("fcntl" HAS_FCNTL)
check_function_exists("ioctl" HAS_IOCTL)
check_function_exists("poll" HAS_POLL)
check_function_exists("getaddrinfo" HAS_GETADDRINFO)
check_function_exists("getnameinfo" HAS_GETNAMEINFO)
@@ -19,10 +18,6 @@ check_struct_has_member("struct msghdr" "msg_flags" "sys/types.h;sys/socket.h" H
set(CMAKE_EXTRA_INCLUDE_FILES "sys/types.h" "sys/socket.h")
check_type_size("socklen_t" HAS_SOCKLEN_T BUILTIN_TYPES_ONLY)
unset(CMAKE_EXTRA_INCLUDE_FILES)
set(CMAKE_EXTRA_INCLUDE_FILES "qos2.h")
check_type_size("QOS_FLOWID" HAS_QOS_FLOWID BUILTIN_TYPES_ONLY)
check_type_size("PQOS_FLOWID" HAS_PQOS_FLOWID BUILTIN_TYPES_ONLY)
unset(CMAKE_EXTRA_INCLUDE_FILES)
if(MSVC)
add_definitions(-W3)
else()
@@ -32,9 +27,6 @@ endif()
if(HAS_FCNTL)
add_definitions(-DHAS_FCNTL=1)
endif()
if(HAS_IOCTL)
add_definitions(-DHAS_IOCTL=1)
endif()
if(HAS_POLL)
add_definitions(-DHAS_POLL=1)
endif()
@@ -62,12 +54,6 @@ endif()
if(HAS_SOCKLEN_T)
add_definitions(-DHAS_SOCKLEN_T=1)
endif()
if(HAS_QOS_FLOWID)
add_definitions(-DHAS_QOS_FLOWID=1)
endif()
if(HAS_PQOS_FLOWID)
add_definitions(-DHAS_PQOS_FLOWID=1)
endif()
include_directories(${PROJECT_SOURCE_DIR}/include)
@@ -102,7 +88,6 @@ add_library(enet STATIC
${INCLUDE_FILES}
${SOURCE_FILES}
)
target_include_directories(enet SYSTEM PUBLIC include)
if (MINGW)
target_link_libraries(enet winmm ws2_32)
+29 -6
View File
@@ -12,7 +12,6 @@
/** Creates a host for communicating to peers.
@param addressFamily the address family of the socket that should be created (ex: PF_INET/PF_INET6)
@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.
@param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT
@@ -27,7 +26,7 @@
at any given time.
*/
ENetHost *
enet_host_create (int addressFamily, const ENetAddress * address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
{
ENetHost * host;
ENetPeer * currentPeer;
@@ -49,7 +48,7 @@ enet_host_create (int addressFamily, const ENetAddress * address, size_t peerCou
}
memset (host -> peers, 0, peerCount * sizeof (ENetPeer));
host -> socket = enet_socket_create (addressFamily, ENET_SOCKET_TYPE_DATAGRAM);
host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM);
if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0))
{
if (host -> socket != ENET_SOCKET_NULL)
@@ -62,9 +61,9 @@ enet_host_create (int addressFamily, const ENetAddress * address, size_t peerCou
}
enet_socket_set_option (host -> socket, ENET_SOCKOPT_NONBLOCK, 1);
enet_socket_set_option (host -> socket, ENET_SOCKOPT_BROADCAST, 1);
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);
enet_socket_set_option (host -> socket, ENET_SOCKOPT_QOS, 1);
if (address != NULL && enet_socket_get_address (host -> socket, & host -> address) < 0)
host -> address = * address;
@@ -88,8 +87,8 @@ enet_host_create (int addressFamily, const ENetAddress * address, size_t peerCou
host -> commandCount = 0;
host -> bufferCount = 0;
host -> checksum = NULL;
memset(& host -> receivedPeerAddress, 0, sizeof (host -> receivedPeerAddress));
memset(& host -> receivedLocalAddress, 0, sizeof (host -> receivedLocalAddress));
host -> receivedAddress.host = ENET_HOST_ANY;
host -> receivedAddress.port = 0;
host -> receivedData = NULL;
host -> receivedDataLength = 0;
@@ -262,6 +261,30 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC
return currentPeer;
}
/** Queues a packet to be sent to all peers associated with the host.
@param host host on which to broadcast the packet
@param channelID channel on which to broadcast
@param packet packet to broadcast
*/
void
enet_host_broadcast (ENetHost * host, enet_uint8 channelID, ENetPacket * packet)
{
ENetPeer * currentPeer;
for (currentPeer = host -> peers;
currentPeer < & host -> peers [host -> peerCount];
++ currentPeer)
{
if (currentPeer -> state != ENET_PEER_STATE_CONNECTED)
continue;
enet_peer_send (currentPeer, channelID, packet);
}
if (packet -> referenceCount == 0)
enet_packet_destroy (packet);
}
/** Sets the packet compressor the host should use to compress and decompress packets.
@param host host to enable or disable compression for
@param compressor callbacks for for the packet compressor; if NULL, then compression is disabled
+60 -21
View File
@@ -55,14 +55,14 @@ typedef enum _ENetSocketWait
typedef enum _ENetSocketOption
{
ENET_SOCKOPT_NONBLOCK = 1,
ENET_SOCKOPT_RCVBUF,
ENET_SOCKOPT_SNDBUF,
ENET_SOCKOPT_REUSEADDR,
ENET_SOCKOPT_RCVTIMEO,
ENET_SOCKOPT_SNDTIMEO,
ENET_SOCKOPT_ERROR,
ENET_SOCKOPT_NODELAY,
ENET_SOCKOPT_QOS,
ENET_SOCKOPT_BROADCAST = 2,
ENET_SOCKOPT_RCVBUF = 3,
ENET_SOCKOPT_SNDBUF = 4,
ENET_SOCKOPT_REUSEADDR = 5,
ENET_SOCKOPT_RCVTIMEO = 6,
ENET_SOCKOPT_SNDTIMEO = 7,
ENET_SOCKOPT_ERROR = 8,
ENET_SOCKOPT_NODELAY = 9
} ENetSocketOption;
typedef enum _ENetSocketShutdown
@@ -72,13 +72,24 @@ typedef enum _ENetSocketShutdown
ENET_SOCKET_SHUTDOWN_READ_WRITE = 2
} ENetSocketShutdown;
#define ENET_HOST_ANY 0
#define ENET_HOST_BROADCAST 0xFFFFFFFFU
#define ENET_PORT_ANY 0
/**
* Portable internet address structure.
*
* 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.
*/
typedef struct _ENetAddress
{
socklen_t addressLength;
struct sockaddr_storage address;
enet_uint32 host;
enet_uint16 port;
} ENetAddress;
/**
@@ -201,7 +212,7 @@ enum
ENET_HOST_RECEIVE_BUFFER_SIZE = 256 * 1024,
ENET_HOST_SEND_BUFFER_SIZE = 256 * 1024,
ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL = 1000,
ENET_HOST_DEFAULT_MTU = 900,
ENET_HOST_DEFAULT_MTU = 1400,
ENET_HOST_DEFAULT_MAXIMUM_PACKET_SIZE = 32 * 1024 * 1024,
ENET_HOST_DEFAULT_MAXIMUM_WAITING_DATA = 32 * 1024 * 1024,
@@ -259,7 +270,6 @@ typedef struct _ENetPeer
enet_uint8 outgoingSessionID;
enet_uint8 incomingSessionID;
ENetAddress address; /**< Internet address of the peer */
ENetAddress localAddress;
void * data; /**< Application private data, may be freely modified */
ENetPeerState state;
ENetChannel * channels;
@@ -343,6 +353,7 @@ typedef int (ENET_CALLBACK * ENetInterceptCallback) (struct _ENetHost * host, st
@sa enet_host_connect()
@sa enet_host_service()
@sa enet_host_flush()
@sa enet_host_broadcast()
@sa enet_host_compress()
@sa enet_host_compress_with_range_coder()
@sa enet_host_channel_limit()
@@ -374,8 +385,7 @@ typedef struct _ENetHost
ENetChecksumCallback checksum; /**< callback the user can set to enable packet checksums for this host */
ENetCompressor compressor;
enet_uint8 packetData [2][ENET_PROTOCOL_MAXIMUM_MTU];
ENetAddress receivedPeerAddress;
ENetAddress receivedLocalAddress;
ENetAddress receivedAddress;
enet_uint8 * receivedData;
size_t receivedDataLength;
enet_uint32 totalSentData; /**< total data sent, user should reset to 0 as needed to prevent overflow */
@@ -484,14 +494,14 @@ ENET_API void enet_time_set (enet_uint32);
/** @defgroup socket ENet socket functions
@{
*/
ENET_API ENetSocket enet_socket_create (int, ENetSocketType);
ENET_API ENetSocket enet_socket_create (ENetSocketType);
ENET_API int enet_socket_bind (ENetSocket, const ENetAddress *);
ENET_API int enet_socket_get_address (ENetSocket, ENetAddress *);
ENET_API int enet_socket_listen (ENetSocket, int);
ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *);
ENET_API int enet_socket_connect (ENetSocket, const ENetAddress *);
ENET_API int enet_socket_send (ENetSocket, const ENetAddress *, const ENetAddress *, const ENetBuffer *, size_t);
ENET_API int enet_socket_receive (ENetSocket, ENetAddress *, ENetAddress *, ENetBuffer *, size_t);
ENET_API int enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t);
ENET_API int enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t);
ENET_API int enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32);
ENET_API int enet_socket_set_option (ENetSocket, ENetSocketOption, int);
ENET_API int enet_socket_get_option (ENetSocket, ENetSocketOption, int *);
@@ -504,6 +514,17 @@ ENET_API int enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSock
/** @defgroup Address ENet address functions
@{
*/
/** Attempts to parse the printable form of the IP address in the parameter hostName
and sets the host field in the address parameter if successful.
@param address destination to store the parsed IP address
@param hostName IP address to parse
@retval 0 on success
@retval < 0 on failure
@returns the address of the given hostName in address on success
*/
ENET_API int enet_address_set_host_ip (ENetAddress * address, const char * hostName);
/** Attempts to resolve the host named by the parameter hostName and sets
the host field in the address parameter if successful.
@param address destination to store resolved address
@@ -513,9 +534,26 @@ ENET_API int enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSock
@returns the address of the given hostName in address on success
*/
ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName);
ENET_API int enet_address_set_address (ENetAddress * address, struct sockaddr * addr, socklen_t addrlen);
ENET_API int enet_address_set_port (ENetAddress * address, enet_uint16 port);
ENET_API int enet_address_equal (ENetAddress * address1, ENetAddress * address2);
/** Gives the printable form of the IP address specified in the address parameter.
@param address address printed
@param hostName destination for name, must not be NULL
@param nameLength maximum length of hostName.
@returns the null-terminated name of the host in hostName on success
@retval 0 on success
@retval < 0 on failure
*/
ENET_API int enet_address_get_host_ip (const ENetAddress * address, char * hostName, size_t nameLength);
/** Attempts to do a reverse lookup of the host field in the address parameter.
@param address address used for reverse lookup
@param hostName destination for name, must not be NULL
@param nameLength maximum length of hostName.
@returns the null-terminated name of the host in hostName on success
@retval 0 on success
@retval < 0 on failure
*/
ENET_API int enet_address_get_host (const ENetAddress * address, char * hostName, size_t nameLength);
/** @} */
@@ -524,12 +562,13 @@ 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 (int, const ENetAddress *, size_t, size_t, enet_uint32, enet_uint32);
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);
ENET_API int enet_host_check_events (ENetHost *, ENetEvent *);
ENET_API int enet_host_service (ENetHost *, ENetEvent *, enet_uint32);
ENET_API void enet_host_flush (ENetHost *);
ENET_API void enet_host_broadcast (ENetHost *, enet_uint8, ENetPacket *);
ENET_API void enet_host_compress (ENetHost *, const ENetCompressor *);
ENET_API int enet_host_compress_with_range_coder (ENetHost * host);
ENET_API void enet_host_channel_limit (ENetHost *, size_t);
-4
View File
@@ -10,11 +10,7 @@
enum
{
ENET_PROTOCOL_MINIMUM_MTU = 576,
#ifdef __WIIU__
ENET_PROTOCOL_MAXIMUM_MTU = 1400,
#else
ENET_PROTOCOL_MAXIMUM_MTU = 4096,
#endif
ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS = 32,
ENET_PROTOCOL_MINIMUM_WINDOW_SIZE = 4096,
ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 65536,
-1
View File
@@ -18,7 +18,6 @@
#include <stdlib.h>
#include <winsock2.h>
#include <Ws2tcpip.h>
typedef SOCKET ENetSocket;
+20 -25
View File
@@ -309,9 +309,10 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
}
else
if (currentPeer -> state != ENET_PEER_STATE_CONNECTING &&
enet_address_equal (& currentPeer -> address, & host -> receivedPeerAddress))
currentPeer -> address.host == host -> receivedAddress.host)
{
if (currentPeer -> connectID == command -> connect.connectID)
if (currentPeer -> address.port == host -> receivedAddress.port &&
currentPeer -> connectID == command -> connect.connectID)
return NULL;
++ duplicatePeers;
@@ -329,8 +330,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
peer -> channelCount = channelCount;
peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT;
peer -> connectID = command -> connect.connectID;
peer -> address = host -> receivedPeerAddress;
peer -> localAddress = host -> receivedLocalAddress;
peer -> address = host -> receivedAddress;
peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID);
peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth);
peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.outgoingBandwidth);
@@ -860,19 +860,19 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
{
enet_peer_throttle (peer, roundTripTime);
peer -> roundTripTimeVariance -= (peer -> roundTripTimeVariance + 3) / 4;
peer -> roundTripTimeVariance -= peer -> roundTripTimeVariance / 4;
if (roundTripTime >= peer -> roundTripTime)
{
enet_uint32 diff = roundTripTime - peer -> roundTripTime;
peer -> roundTripTimeVariance += (diff + 3) / 4;
peer -> roundTripTime += (diff + 7) / 8;
peer -> roundTripTimeVariance += diff / 4;
peer -> roundTripTime += diff / 8;
}
else
{
enet_uint32 diff = peer -> roundTripTime - roundTripTime;
peer -> roundTripTimeVariance += (diff + 3) / 4;
peer -> roundTripTime -= (diff + 7) / 8;
peer -> roundTripTimeVariance += diff / 4;
peer -> roundTripTime -= diff / 8;
}
}
else
@@ -1031,7 +1031,9 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
peer -> state == ENET_PEER_STATE_ZOMBIE ||
/* ! enet_address_equal(& host -> receivedAddress, & peer -> address) || */
((host -> receivedAddress.host != peer -> address.host ||
host -> receivedAddress.port != peer -> address.port) &&
peer -> address.host != ENET_HOST_BROADCAST) ||
(peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID &&
sessionID != peer -> incomingSessionID))
return 0;
@@ -1073,8 +1075,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
if (peer != NULL)
{
memcpy(& peer -> address, & host -> receivedPeerAddress, sizeof (host -> receivedPeerAddress));
memcpy(& peer -> localAddress, & host -> receivedLocalAddress, sizeof (host -> receivedLocalAddress));
peer -> address.host = host -> receivedAddress.host;
peer -> address.port = host -> receivedAddress.port;
peer -> incomingDataTotal += host -> receivedDataLength;
}
@@ -1225,8 +1227,7 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
buffer.dataLength = sizeof (host -> packetData [0]);
receivedLength = enet_socket_receive (host -> socket,
& host -> receivedPeerAddress,
& host -> receivedLocalAddress,
& host -> receivedAddress,
& buffer,
1);
@@ -1469,7 +1470,7 @@ enet_protocol_check_outgoing_commands (ENetHost * host, ENetPeer * peer)
if (outgoingCommand -> roundTripTimeout == 0)
{
outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * ENET_MAX (1, peer -> roundTripTimeVariance);
outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance;
outgoingCommand -> roundTripTimeoutLimit = peer -> timeoutLimit * outgoingCommand -> roundTripTimeout;
}
@@ -1687,13 +1688,7 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
currentPeer -> lastSendTime = host -> serviceTime;
if (currentPeer -> state == ENET_PEER_STATE_CONNECTING && currentPeer -> packetsLost == 2) {
// Disable QoS tagging if we don't get a response to 2 connection requests in a row.
// Some networks drop QoS tagged packets, so let's try without it.
enet_socket_set_option (host -> socket, ENET_SOCKOPT_QOS, 0);
}
sentLength = enet_socket_send (host -> socket, & currentPeer -> address, & currentPeer -> localAddress, host -> buffers, host -> bufferCount);
sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount);
enet_protocol_remove_sent_unreliable_commands (currentPeer);
@@ -1787,7 +1782,7 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
timeout += host -> serviceTime;
for (;;)
do
{
if (ENET_TIME_DIFFERENCE (host -> serviceTime, host -> bandwidthThrottleEpoch) >= ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
enet_host_bandwidth_throttle (host);
@@ -1871,13 +1866,13 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
waitCondition = ENET_SOCKET_WAIT_RECEIVE | ENET_SOCKET_WAIT_INTERRUPT;
if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime) / 10) != 0)
if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0)
return -1;
}
while (waitCondition & ENET_SOCKET_WAIT_INTERRUPT);
host -> serviceTime = enet_time_get ();
}
} while (waitCondition & ENET_SOCKET_WAIT_RECEIVE);
return 0;
}
+196 -377
View File
@@ -4,19 +4,9 @@
*/
#ifndef _WIN32
// Required for IPV6_PKTINFO with Darwin headers
#ifndef __APPLE_USE_RFC_3542
#define __APPLE_USE_RFC_3542 1
#endif
// Required for in6_pktinfo with glibc headers
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <netinet/tcp.h>
#include <netdb.h>
@@ -28,9 +18,9 @@
#define ENET_BUILDING_LIB 1
#include "enet/enet.h"
#if defined(__APPLE__)
#ifndef HAS_POLL
#define HAS_POLL 1
#ifdef __APPLE__
#ifdef HAS_POLL
#undef HAS_POLL
#endif
#ifndef HAS_FCNTL
#define HAS_FCNTL 1
@@ -53,79 +43,12 @@
#ifndef HAS_GETNAMEINFO
#define HAS_GETNAMEINFO 1
#endif
#elif defined(__vita__)
#ifdef HAS_POLL
#undef HAS_POLL
#endif
#ifdef HAS_FCNTL
#undef HAS_FCNTL
#endif
#ifdef HAS_IOCTL
#undef HAS_IOCTL
#endif
#ifndef HAS_INET_PTON
#define HAS_INET_PTON 1
#endif
#ifndef HAS_INET_NTOP
#define HAS_INET_NTOP 1
#endif
#ifdef HAS_MSGHDR_FLAGS
#undef HAS_MSGHDR_FLAGS
#endif
#ifndef HAS_SOCKLEN_T
#define HAS_SOCKLEN_T 1
#endif
#ifndef HAS_GETADDRINFO
#define HAS_GETADDRINFO 1
#endif
#ifndef HAS_GETNAMEINFO
#define HAS_GETNAMEINFO 1
#endif
#elif defined(__WIIU__)
#ifndef HAS_POLL
#define HAS_POLL 1
#endif
#ifndef HAS_FCNTL
#define HAS_FCNTL 1
#endif
#ifndef HAS_IOCTL
#define HAS_IOCTL 1
#endif
#ifndef HAS_INET_PTON
#define HAS_INET_PTON 1
#endif
#ifndef HAS_INET_NTOP
#define HAS_INET_NTOP 1
#endif
#ifndef HAS_SOCKLEN_T
#define HAS_SOCKLEN_T 1
#endif
#ifndef HAS_GETADDRINFO
#define HAS_GETADDRINFO 1
#endif
#ifndef HAS_GETNAMEINFO
#define HAS_GETNAMEINFO 1
#endif
#ifndef NO_MSGAPI
#define NO_MSGAPI 1
#endif
#else
#ifndef HAS_IOCTL
#define HAS_IOCTL 1
#endif
#ifndef HAS_POLL
#define HAS_POLL 1
#endif
#endif
#ifdef HAS_FCNTL
#include <fcntl.h>
#endif
#ifdef HAS_IOCTL
#include <sys/ioctl.h>
#endif
#ifdef HAS_POLL
#include <poll.h>
#endif
@@ -134,10 +57,6 @@
typedef int socklen_t;
#endif
#ifndef SOMAXCONN
#define SOMAXCONN 128
#endif
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
#endif
@@ -158,11 +77,7 @@ enet_deinitialize (void)
enet_uint32
enet_host_random_seed (void)
{
struct timeval timeVal;
gettimeofday (& timeVal, NULL);
return (timeVal.tv_sec * 1000) ^ (timeVal.tv_usec / 1000);
return (enet_uint32) time (NULL);
}
enet_uint32
@@ -186,116 +101,186 @@ enet_time_set (enet_uint32 newTimeBase)
}
int
enet_address_equal (ENetAddress * address1, ENetAddress * address2)
enet_address_set_host_ip (ENetAddress * address, const char * name)
{
if (address1 -> address.ss_family != address2 -> address.ss_family)
return 0;
switch (address1 -> address.ss_family)
{
case AF_INET:
{
struct sockaddr_in *sin1, *sin2;
sin1 = (struct sockaddr_in *) & address1 -> address;
sin2 = (struct sockaddr_in *) & address2 -> address;
return sin1 -> sin_port == sin2 -> sin_port &&
sin1 -> sin_addr.s_addr == sin2 -> sin_addr.s_addr;
}
#ifdef AF_INET6
case AF_INET6:
{
struct sockaddr_in6 *sin6a, *sin6b;
sin6a = (struct sockaddr_in6 *) & address1 -> address;
sin6b = (struct sockaddr_in6 *) & address2 -> address;
return sin6a -> sin6_port == sin6b -> sin6_port &&
! memcmp (& sin6a -> sin6_addr, & sin6b -> sin6_addr, sizeof (sin6a -> sin6_addr));
}
#ifdef HAS_INET_PTON
if (! inet_pton (AF_INET, name, & address -> host))
#else
if (! inet_aton (name, (struct in_addr *) & address -> host))
#endif
default:
{
return 0;
}
}
}
int
enet_address_set_port (ENetAddress * address, enet_uint16 port)
{
if (address -> address.ss_family == AF_INET)
{
struct sockaddr_in *sin = (struct sockaddr_in *) &address -> address;
sin -> sin_port = ENET_HOST_TO_NET_16 (port);
return 0;
}
#ifdef AF_INET6
else if (address -> address.ss_family == AF_INET6)
{
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &address -> address;
sin6 -> sin6_port = ENET_HOST_TO_NET_16 (port);
return 0;
}
#endif
else
{
return -1;
}
}
int
enet_address_set_address (ENetAddress * address, struct sockaddr * addr, socklen_t addrlen)
{
if (addrlen > sizeof(struct sockaddr_storage))
return -1;
memcpy (&address->address, addr, addrlen);
address->addressLength = addrlen;
return 0;
}
int
enet_address_set_host (ENetAddress * address, const char * name)
{
#ifdef HAS_GETADDRINFO
struct addrinfo hints, * resultList = NULL, * result = NULL;
memset (& hints, 0, sizeof (hints));
hints.ai_family = AF_UNSPEC;
hints.ai_flags = AI_ADDRCONFIG;
hints.ai_family = AF_INET;
if (getaddrinfo (name, NULL, & hints, & resultList) != 0)
if (getaddrinfo (name, NULL, NULL, & resultList) != 0)
return -1;
for (result = resultList; result != NULL; result = result -> ai_next)
{
memcpy (& address -> address, result -> ai_addr, result -> ai_addrlen);
address -> addressLength = result -> ai_addrlen;
freeaddrinfo (resultList);
return 0;
if (result -> ai_family == AF_INET && result -> ai_addr != NULL && result -> ai_addrlen >= sizeof (struct sockaddr_in))
{
struct sockaddr_in * sin = (struct sockaddr_in *) result -> ai_addr;
address -> host = sin -> sin_addr.s_addr;
freeaddrinfo (resultList);
return 0;
}
}
if (resultList != NULL)
freeaddrinfo (resultList);
#else
struct hostent * hostEntry = NULL;
#ifdef HAS_GETHOSTBYNAME_R
struct hostent hostData;
char buffer [2048];
int errnum;
return -1;
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
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
if (hostEntry != NULL && hostEntry -> h_addrtype == AF_INET)
{
address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
return 0;
}
#endif
return enet_address_set_host_ip (address, name);
}
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)
{
size_t addrLen = strlen(addr);
if (addrLen >= nameLength)
return -1;
memcpy (name, addr, addrLen + 1);
}
else
#endif
return -1;
return 0;
}
int
enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
{
#ifdef HAS_GETNAMEINFO
struct sockaddr_in sin;
int err;
memset (& sin, 0, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
err = getnameinfo ((struct sockaddr *) & sin, sizeof (sin), name, nameLength, NULL, 0, NI_NAMEREQD);
if (! err)
{
if (name != NULL && nameLength > 0 && ! memchr (name, '\0', nameLength))
return -1;
return 0;
}
if (err != EAI_NONAME)
return -1;
#else
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__) || defined(__DragonFly__)
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;
hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
#endif
if (hostEntry != NULL)
{
size_t hostLen = strlen (hostEntry -> h_name);
if (hostLen >= nameLength)
return -1;
memcpy (name, hostEntry -> h_name, hostLen + 1);
return 0;
}
#endif
return 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));
sin.sin_family = AF_INET;
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 *) & address -> address,
address -> addressLength);
(struct sockaddr *) & sin,
sizeof (struct sockaddr_in));
}
int
enet_socket_get_address (ENetSocket socket, ENetAddress * address)
{
address -> addressLength = sizeof (address -> address);
struct sockaddr_in sin;
socklen_t sinLength = sizeof (struct sockaddr_in);
if (getsockname (socket, (struct sockaddr *) & address -> address, & address -> addressLength) == -1)
if (getsockname (socket, (struct sockaddr *) & sin, & sinLength) == -1)
return -1;
address -> host = (enet_uint32) sin.sin_addr.s_addr;
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
return 0;
}
@@ -306,39 +291,9 @@ enet_socket_listen (ENetSocket socket, int backlog)
}
ENetSocket
enet_socket_create (int af, ENetSocketType type)
enet_socket_create (ENetSocketType type)
{
ENetSocket sock = socket (af, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
if (sock < 0) {
return sock;
}
#ifdef IPV6_V6ONLY
if (af == AF_INET6) {
int off = 0;
// Some OSes don't support dual-stack sockets, so ignore failures
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&off, sizeof(off));
}
#endif
#ifdef IP_PKTINFO
{
// We turn this on for all sockets because it may be required for IPv4
// traffic on dual-stack sockets on some OSes.
int on = 1;
setsockopt(sock, IPPROTO_IP, IP_PKTINFO, (char *)&on, sizeof(on));
}
#endif
#ifdef IPV6_RECVPKTINFO
if (af == AF_INET6) {
int on = 1;
setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, (char *)&on, sizeof(on));
}
#endif
return sock;
return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
}
int
@@ -351,14 +306,14 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
#ifdef HAS_FCNTL
result = fcntl (socket, F_SETFL, (value ? O_NONBLOCK : 0) | (fcntl (socket, F_GETFL) & ~O_NONBLOCK));
#else
#ifdef HAS_IOCTL
result = ioctl (socket, FIONBIO, & value);
#else
result = setsockopt (socket, SOL_SOCKET, SO_NONBLOCK, (char *) & value, sizeof(int));
#endif
#endif
break;
case ENET_SOCKOPT_BROADCAST:
result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_REUSEADDR:
result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
break;
@@ -371,7 +326,6 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
break;
#ifndef __WIIU__
case ENET_SOCKOPT_RCVTIMEO:
{
struct timeval timeVal;
@@ -389,36 +343,11 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
result = setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & timeVal, sizeof (struct timeval));
break;
}
#endif
case ENET_SOCKOPT_NODELAY:
result = setsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_QOS:
#ifdef SO_NET_SERVICE_TYPE
// iOS/macOS
value = value ? NET_SERVICE_TYPE_VO : NET_SERVICE_TYPE_BE;
result = setsockopt (socket, SOL_SOCKET, SO_NET_SERVICE_TYPE, (char *) & value, sizeof (int));
#else
#ifdef IP_TOS
// UNIX - IPv4
value = value ? 46 << 2 : 0; // DSCP: Expedited Forwarding
result = setsockopt (socket, IPPROTO_IP, IP_TOS, (char *) & value, sizeof (int));
#endif
#ifdef IPV6_TCLASS
// UNIX - IPv6
value = value ? 46 << 2: 0; // DSCP: Expedited Forwarding
result = setsockopt (socket, IPPROTO_IPV6, IPV6_TCLASS, (char *) & value, sizeof (int));
#endif
#ifdef SO_PRIORITY
// Linux
value = value ? 6 : 0; // Max priority without NET_CAP_ADMIN
result = setsockopt (socket, SOL_SOCKET, SO_PRIORITY, (char *) & value, sizeof (int));
#endif
#endif /* SO_NET_SERVICE_TYPE */
break;
default:
break;
}
@@ -446,9 +375,16 @@ enet_socket_get_option (ENetSocket socket, ENetSocketOption option, int * value)
int
enet_socket_connect (ENetSocket socket, const ENetAddress * address)
{
struct sockaddr_in sin;
int result;
result = connect (socket, (struct sockaddr *) & address -> address, address -> addressLength);
memset (& sin, 0, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
result = connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
if (result == -1 && errno == EINPROGRESS)
return 0;
@@ -459,20 +395,25 @@ ENetSocket
enet_socket_accept (ENetSocket socket, ENetAddress * address)
{
int result;
if (address != NULL)
address -> addressLength = sizeof (address -> address);
struct sockaddr_in sin;
socklen_t sinLength = sizeof (struct sockaddr_in);
result = accept (socket,
address != NULL ? (struct sockaddr *) & address -> address : NULL,
address != NULL ? & address -> addressLength : NULL);
address != NULL ? (struct sockaddr *) & sin : NULL,
address != NULL ? & sinLength : NULL);
if (result == -1)
return ENET_SOCKET_NULL;
return result;
}
if (address != NULL)
{
address -> host = (enet_uint32) sin.sin_addr.s_addr;
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
}
return result;
}
int
enet_socket_shutdown (ENetSocket socket, ENetSocketShutdown how)
{
@@ -488,106 +429,32 @@ enet_socket_destroy (ENetSocket socket)
int
enet_socket_send (ENetSocket socket,
const ENetAddress * peerAddress,
const ENetAddress * localAddress,
const ENetAddress * address,
const ENetBuffer * buffers,
size_t bufferCount)
{
int sentLength;
#ifdef NO_MSGAPI
void* sendBuffer;
size_t sendLength;
if (bufferCount > 1)
{
size_t i;
sendLength = 0;
for (i = 0; i < bufferCount; i++)
{
sendLength += buffers[i].dataLength;
}
sendBuffer = malloc (sendLength);
if (sendBuffer == NULL)
return -1;
sendLength = 0;
for (i = 0; i < bufferCount; i++)
{
memcpy (& ((unsigned char *)sendBuffer)[sendLength], buffers[i].data, buffers[i].dataLength);
sendLength += buffers[i].dataLength;
}
}
else
{
sendBuffer = buffers[0].data;
sendLength = buffers[0].dataLength;
}
sentLength = sendto (socket, sendBuffer, sendLength, MSG_NOSIGNAL,
(struct sockaddr *) & peerAddress -> address, peerAddress -> addressLength);
if (bufferCount > 1)
free(sendBuffer);
#else
struct msghdr msgHdr;
char controlBufData[1024];
struct sockaddr_in sin;
int sentLength;
memset (& msgHdr, 0, sizeof (struct msghdr));
if (peerAddress != NULL)
if (address != NULL)
{
msgHdr.msg_name = (void*) & peerAddress -> address;
msgHdr.msg_namelen = peerAddress -> addressLength;
memset (& sin, 0, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
msgHdr.msg_name = & sin;
msgHdr.msg_namelen = sizeof (struct sockaddr_in);
}
msgHdr.msg_iov = (struct iovec *) buffers;
msgHdr.msg_iovlen = bufferCount;
// We always send traffic from the same local address as we last received
// from this peer to ensure it correctly recognizes our responses as
// coming from the expected host.
if (localAddress != NULL) {
#ifdef IP_PKTINFO
if (localAddress->address.ss_family == AF_INET) {
struct in_pktinfo pktInfo;
pktInfo.ipi_spec_dst = ((struct sockaddr_in*)&localAddress->address)->sin_addr;
pktInfo.ipi_ifindex = 0; // Unspecified
msgHdr.msg_control = controlBufData;
msgHdr.msg_controllen = CMSG_SPACE(sizeof(pktInfo));
struct cmsghdr *chdr = CMSG_FIRSTHDR(&msgHdr);
chdr->cmsg_level = IPPROTO_IP;
chdr->cmsg_type = IP_PKTINFO;
chdr->cmsg_len = CMSG_LEN(sizeof(pktInfo));
memcpy(CMSG_DATA(chdr), &pktInfo, sizeof(pktInfo));
}
#endif
#ifdef IPV6_PKTINFO
if (localAddress->address.ss_family == AF_INET6) {
struct in6_pktinfo pktInfo;
pktInfo.ipi6_addr = ((struct sockaddr_in6*)&localAddress->address)->sin6_addr;
pktInfo.ipi6_ifindex = 0; // Unspecified
msgHdr.msg_control = controlBufData;
msgHdr.msg_controllen = CMSG_SPACE(sizeof(pktInfo));
struct cmsghdr *chdr = CMSG_FIRSTHDR(&msgHdr);
chdr->cmsg_level = IPPROTO_IPV6;
chdr->cmsg_type = IPV6_PKTINFO;
chdr->cmsg_len = CMSG_LEN(sizeof(pktInfo));
memcpy(CMSG_DATA(chdr), &pktInfo, sizeof(pktInfo));
}
#endif
}
sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL);
#endif
if (sentLength == -1)
{
@@ -602,45 +469,24 @@ enet_socket_send (ENetSocket socket,
int
enet_socket_receive (ENetSocket socket,
ENetAddress * peerAddress,
ENetAddress * localAddress,
ENetAddress * address,
ENetBuffer * buffers,
size_t bufferCount)
{
int recvLength;
#ifdef NO_MSGAPI
// This will ONLY work with a single buffer!
address -> addressLength = sizeof (address -> address);
recvLength = recvfrom (socket, buffers[0].data, buffers[0].dataLength, MSG_NOSIGNAL,
(struct sockaddr *) & peerAddress -> address, & peerAddress -> addressLength);
if (recvLength == -1)
{
if (errno == EWOULDBLOCK)
return 0;
return -1;
}
return recvLength;
#else
struct msghdr msgHdr;
char controlBufData[1024];
struct sockaddr_in sin;
int recvLength;
memset (& msgHdr, 0, sizeof (struct msghdr));
if (peerAddress != NULL)
if (address != NULL)
{
msgHdr.msg_name = & peerAddress -> address;
msgHdr.msg_namelen = sizeof (peerAddress -> address);
msgHdr.msg_name = & sin;
msgHdr.msg_namelen = sizeof (struct sockaddr_in);
}
msgHdr.msg_iov = (struct iovec *) buffers;
msgHdr.msg_iovlen = bufferCount;
msgHdr.msg_control = controlBufData;
msgHdr.msg_controllen = sizeof(controlBufData);
recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL);
@@ -657,40 +503,13 @@ enet_socket_receive (ENetSocket socket,
return -1;
#endif
// Retrieve the local address that this traffic was received on
// to ensure we respond from the correct address/interface.
if (localAddress != NULL) {
for (struct cmsghdr *chdr = CMSG_FIRSTHDR(&msgHdr); chdr != NULL; chdr = CMSG_NXTHDR(&msgHdr, chdr)) {
#ifdef IP_PKTINFO
if (chdr->cmsg_level == IPPROTO_IP && chdr->cmsg_type == IP_PKTINFO) {
struct sockaddr_in *localAddr = (struct sockaddr_in*)&localAddress->address;
localAddr->sin_family = AF_INET;
localAddr->sin_addr = ((struct in_pktinfo*)CMSG_DATA(chdr))->ipi_addr;
localAddress->addressLength = sizeof(*localAddr);
break;
}
#endif
#ifdef IPV6_PKTINFO
if (chdr->cmsg_level == IPPROTO_IPV6 && chdr->cmsg_type == IPV6_PKTINFO) {
struct sockaddr_in6 *localAddr = (struct sockaddr_in6*)&localAddress->address;
localAddr->sin6_family = AF_INET6;
localAddr->sin6_addr = ((struct in6_pktinfo*)CMSG_DATA(chdr))->ipi6_addr;
localAddress->addressLength = sizeof(*localAddr);
break;
}
#endif
}
if (address != NULL)
{
address -> host = (enet_uint32) sin.sin_addr.s_addr;
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
}
if (peerAddress != NULL)
peerAddress -> addressLength = msgHdr.msg_namelen;
return recvLength;
#endif
}
int
+152 -316
View File
@@ -7,43 +7,21 @@
#define ENET_BUILDING_LIB 1
#include "enet/enet.h"
#include <windows.h>
#include <Mswsock.h>
#ifndef HAS_QOS_FLOWID
typedef UINT32 QOS_FLOWID;
#endif
#ifndef HAS_PQOS_FLOWID
typedef UINT32 *PQOS_FLOWID;
#endif
#include <mmsystem.h>
#include <qos2.h>
#ifndef QOS_NON_ADAPTIVE_FLOW
#define QOS_NON_ADAPTIVE_FLOW 0x00000002
#endif
static enet_uint32 timeBase = 0;
static HANDLE qosHandle = INVALID_HANDLE_VALUE;
static QOS_FLOWID qosFlowId;
static BOOL qosAddedFlow;
static HMODULE QwaveLibraryHandle;
BOOL (WINAPI *pfnQOSCreateHandle)(PQOS_VERSION Version, PHANDLE QOSHandle);
BOOL (WINAPI *pfnQOSCloseHandle)(HANDLE QOSHandle);
BOOL (WINAPI *pfnQOSAddSocketToFlow)(HANDLE QOSHandle, SOCKET Socket, PSOCKADDR DestAddr, QOS_TRAFFIC_TYPE TrafficType, DWORD Flags, PQOS_FLOWID FlowId);
LPFN_WSARECVMSG pfnWSARecvMsg;
int
enet_initialize (void)
{
WORD versionRequested = MAKEWORD (2, 0);
WORD versionRequested = MAKEWORD (1, 1);
WSADATA wsaData;
if (WSAStartup (versionRequested, & wsaData))
return -1;
if (LOBYTE (wsaData.wVersion) != 2||
HIBYTE (wsaData.wVersion) != 0)
if (LOBYTE (wsaData.wVersion) != 1||
HIBYTE (wsaData.wVersion) != 1)
{
WSACleanup ();
@@ -52,46 +30,12 @@ enet_initialize (void)
timeBeginPeriod (1);
QwaveLibraryHandle = LoadLibraryA("qwave.dll");
if (QwaveLibraryHandle != NULL) {
pfnQOSCreateHandle = (void*)GetProcAddress(QwaveLibraryHandle, "QOSCreateHandle");
pfnQOSCloseHandle = (void*)GetProcAddress(QwaveLibraryHandle, "QOSCloseHandle");
pfnQOSAddSocketToFlow = (void*)GetProcAddress(QwaveLibraryHandle, "QOSAddSocketToFlow");
if (pfnQOSCreateHandle == NULL || pfnQOSCloseHandle == NULL || pfnQOSAddSocketToFlow == NULL) {
pfnQOSCreateHandle = NULL;
pfnQOSCloseHandle = NULL;
pfnQOSAddSocketToFlow = NULL;
FreeLibrary(QwaveLibraryHandle);
QwaveLibraryHandle = NULL;
}
}
return 0;
}
void
enet_deinitialize (void)
{
qosAddedFlow = FALSE;
qosFlowId = 0;
if (qosHandle != INVALID_HANDLE_VALUE)
{
pfnQOSCloseHandle(qosHandle);
qosHandle = INVALID_HANDLE_VALUE;
}
if (QwaveLibraryHandle != NULL) {
pfnQOSCreateHandle = NULL;
pfnQOSCloseHandle = NULL;
pfnQOSAddSocketToFlow = NULL;
FreeLibrary(QwaveLibraryHandle);
QwaveLibraryHandle = NULL;
}
timeEndPeriod (1);
WSACleanup ();
@@ -116,112 +60,121 @@ enet_time_set (enet_uint32 newTimeBase)
}
int
enet_address_set_port (ENetAddress * address, enet_uint16 port)
enet_address_set_host_ip (ENetAddress * address, const char * name)
{
if (address -> address.ss_family == AF_INET)
{
struct sockaddr_in *sin = (struct sockaddr_in *) &address -> address;
sin -> sin_port = ENET_HOST_TO_NET_16 (port);
return 0;
}
else if (address -> address.ss_family == AF_INET6)
{
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &address -> address;
sin6 -> sin6_port = ENET_HOST_TO_NET_16 (port);
return 0;
}
else
{
return -1;
}
}
enet_uint8 vals [4] = { 0, 0, 0, 0 };
int i;
int
enet_address_set_address (ENetAddress * address, struct sockaddr * addr, socklen_t addrlen)
{
if (addrlen > sizeof(struct sockaddr_storage))
return -1;
for (i = 0; i < 4; ++ i)
{
const char * next = name + 1;
if (* name != '0')
{
long val = strtol (name, (char **) & next, 10);
if (val < 0 || val > 255 || next == name || next - name > 3)
return -1;
vals [i] = (enet_uint8) val;
}
memcpy (&address->address, addr, addrlen);
address->addressLength = addrlen;
if (* next != (i < 3 ? '.' : '\0'))
return -1;
name = next + 1;
}
memcpy (& address -> host, vals, sizeof (enet_uint32));
return 0;
}
int
enet_address_equal (ENetAddress * address1, ENetAddress * address2)
{
if (address1 -> address.ss_family != address2 -> address.ss_family)
return 0;
switch (address1 -> address.ss_family)
{
case AF_INET:
{
struct sockaddr_in *sin1, *sin2;
sin1 = (struct sockaddr_in *) & address1 -> address;
sin2 = (struct sockaddr_in *) & address2 -> address;
return sin1 -> sin_port == sin2 -> sin_port &&
sin1 -> sin_addr.S_un.S_addr == sin2 -> sin_addr.S_un.S_addr;
}
case AF_INET6:
{
struct sockaddr_in6 *sin6a, *sin6b;
sin6a = (struct sockaddr_in6 *) & address1 -> address;
sin6b = (struct sockaddr_in6 *) & address2 -> address;
return sin6a -> sin6_port == sin6b -> sin6_port &&
! memcmp (& sin6a -> sin6_addr, & sin6b -> sin6_addr, sizeof (sin6a -> sin6_addr));
}
default:
{
return 0;
}
}
}
int
enet_address_set_host (ENetAddress * address, const char * name)
{
struct addrinfo hints, * resultList = NULL, * result = NULL;
struct hostent * hostEntry;
memset (& hints, 0, sizeof (hints));
hints.ai_family = AF_UNSPEC;
hints.ai_flags = AI_ADDRCONFIG;
hostEntry = gethostbyname (name);
if (hostEntry == NULL ||
hostEntry -> h_addrtype != AF_INET)
return enet_address_set_host_ip (address, name);
if (getaddrinfo (name, NULL, & hints, & resultList) != 0)
return -1;
address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
for (result = resultList; result != NULL; result = result -> ai_next)
return 0;
}
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;
else
{
memcpy (& address -> address, result -> ai_addr, result -> ai_addrlen);
address -> addressLength = result -> ai_addrlen;
freeaddrinfo (resultList);
return 0;
size_t addrLen = strlen(addr);
if (addrLen >= nameLength)
return -1;
memcpy (name, addr, addrLen + 1);
}
return 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);
else
{
size_t hostLen = strlen (hostEntry -> h_name);
if (hostLen >= nameLength)
return -1;
memcpy (name, hostEntry -> h_name, hostLen + 1);
}
if (resultList != NULL)
freeaddrinfo (resultList);
return -1;
return 0;
}
int
enet_socket_bind (ENetSocket socket, const ENetAddress * address)
{
struct sockaddr_in sin;
memset (& sin, 0, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
if (address != NULL)
{
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
}
else
{
sin.sin_port = 0;
sin.sin_addr.s_addr = INADDR_ANY;
}
return bind (socket,
(struct sockaddr *) & address -> address,
address -> addressLength);
(struct sockaddr *) & sin,
sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
}
int
enet_socket_get_address (ENetSocket socket, ENetAddress * address)
{
address -> addressLength = sizeof (address -> address);
struct sockaddr_in sin;
int sinLength = sizeof (struct sockaddr_in);
if (getsockname (socket, (struct sockaddr *) & address -> address, & address -> addressLength) == -1)
if (getsockname (socket, (struct sockaddr *) & sin, & sinLength) == -1)
return -1;
address -> host = (enet_uint32) sin.sin_addr.s_addr;
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
return 0;
}
@@ -232,48 +185,9 @@ enet_socket_listen (ENetSocket socket, int backlog)
}
ENetSocket
enet_socket_create (int af, ENetSocketType type)
enet_socket_create (ENetSocketType type)
{
SOCKET sock = socket (af, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
return INVALID_SOCKET;
DWORD bytesReturned;
GUID wsaRecvMsgGuid = WSAID_WSARECVMSG;
if (WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &wsaRecvMsgGuid, sizeof(wsaRecvMsgGuid),
&pfnWSARecvMsg, sizeof(pfnWSARecvMsg), &bytesReturned, NULL, NULL) == SOCKET_ERROR) {
closesocket(sock);
return INVALID_SOCKET;
}
BOOL val;
// Enable dual-stack operation for IPv6 sockets
if (af == AF_INET6) {
val = FALSE;
if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&val, sizeof(val)) == SOCKET_ERROR) {
closesocket(sock);
return INVALID_SOCKET;
}
}
// Enable returning local address info for IPv4 and dual-stack sockets
val = TRUE;
if (setsockopt(sock, IPPROTO_IP, IP_PKTINFO, (char*)&val, sizeof(val)) == SOCKET_ERROR) {
closesocket(sock);
return INVALID_SOCKET;
}
// Enable returning local address info for IPv6 and dual-stack sockets
if (af == AF_INET6) {
val = TRUE;
if (setsockopt(sock, IPPROTO_IPV6, IPV6_PKTINFO, (char*)&val, sizeof(val)) == SOCKET_ERROR) {
closesocket(sock);
return INVALID_SOCKET;
}
}
return sock;
return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
}
int
@@ -289,6 +203,10 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
break;
}
case ENET_SOCKOPT_BROADCAST:
result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_REUSEADDR:
result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
break;
@@ -313,32 +231,6 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
result = setsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_QOS:
{
if (value)
{
QOS_VERSION qosVersion;
qosVersion.MajorVersion = 1;
qosVersion.MinorVersion = 0;
if (pfnQOSCreateHandle == NULL || !pfnQOSCreateHandle(&qosVersion, &qosHandle))
{
qosHandle = INVALID_HANDLE_VALUE;
}
}
else if (qosHandle != INVALID_HANDLE_VALUE)
{
pfnQOSCloseHandle(qosHandle);
qosHandle = INVALID_HANDLE_VALUE;
}
qosAddedFlow = FALSE;
qosFlowId = 0;
result = 0;
break;
}
default:
break;
}
@@ -365,9 +257,16 @@ enet_socket_get_option (ENetSocket socket, ENetSocketOption option, int * value)
int
enet_socket_connect (ENetSocket socket, const ENetAddress * address)
{
struct sockaddr_in sin;
int result;
result = connect (socket, (struct sockaddr *) & address -> address, address -> addressLength);
memset (& sin, 0, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
result = connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
if (result == SOCKET_ERROR && WSAGetLastError () != WSAEWOULDBLOCK)
return -1;
@@ -377,18 +276,23 @@ enet_socket_connect (ENetSocket socket, const ENetAddress * address)
ENetSocket
enet_socket_accept (ENetSocket socket, ENetAddress * address)
{
int result;
if (address != NULL)
address -> addressLength = sizeof (address -> address);
SOCKET result;
struct sockaddr_in sin;
int sinLength = sizeof (struct sockaddr_in);
result = accept (socket,
address != NULL ? (struct sockaddr *) & address -> address : NULL,
address != NULL ? & address -> addressLength : NULL);
if (result == -1)
address != NULL ? (struct sockaddr *) & sin : NULL,
address != NULL ? & sinLength : 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);
}
return result;
}
@@ -407,76 +311,31 @@ enet_socket_destroy (ENetSocket socket)
int
enet_socket_send (ENetSocket socket,
const ENetAddress * peerAddress,
const ENetAddress * localAddress,
const ENetAddress * address,
const ENetBuffer * buffers,
size_t bufferCount)
{
DWORD sentLength;
WSAMSG msg = { 0 };
char controlBufData[1024];
struct sockaddr_in sin;
DWORD sentLength = 0;
if (!qosAddedFlow && qosHandle != INVALID_HANDLE_VALUE)
if (address != NULL)
{
qosFlowId = 0; // Must be initialized to 0
pfnQOSAddSocketToFlow(qosHandle,
socket,
(struct sockaddr *)&peerAddress->address,
QOSTrafficTypeControl,
QOS_NON_ADAPTIVE_FLOW,
&qosFlowId);
memset (& sin, 0, sizeof (struct sockaddr_in));
// Even if we failed, don't try again
qosAddedFlow = TRUE;
sin.sin_family = AF_INET;
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
}
msg.name = peerAddress != NULL ? (struct sockaddr *) & peerAddress -> address : NULL;
msg.namelen = peerAddress != NULL ? peerAddress -> addressLength : 0;
msg.lpBuffers = (LPWSABUF) buffers;
msg.dwBufferCount = (DWORD) bufferCount;
// We always send traffic from the same local address as we last received
// from this peer to ensure it correctly recognizes our responses as
// coming from the expected host.
if (localAddress != NULL) {
if (localAddress->address.ss_family == AF_INET) {
IN_PKTINFO pktInfo;
pktInfo.ipi_addr = ((PSOCKADDR_IN)&localAddress->address)->sin_addr;
pktInfo.ipi_ifindex = 0; // Unspecified
msg.Control.buf = controlBufData;
msg.Control.len = WSA_CMSG_SPACE(sizeof(pktInfo));
PWSACMSGHDR chdr = WSA_CMSG_FIRSTHDR(&msg);
chdr->cmsg_level = IPPROTO_IP;
chdr->cmsg_type = IP_PKTINFO;
chdr->cmsg_len = WSA_CMSG_LEN(sizeof(pktInfo));
memcpy(WSA_CMSG_DATA(chdr), &pktInfo, sizeof(pktInfo));
}
else if (localAddress->address.ss_family == AF_INET6) {
IN6_PKTINFO pktInfo;
pktInfo.ipi6_addr = ((PSOCKADDR_IN6)&localAddress->address)->sin6_addr;
pktInfo.ipi6_ifindex = 0; // Unspecified
msg.Control.buf = controlBufData;
msg.Control.len = WSA_CMSG_SPACE(sizeof(pktInfo));
PWSACMSGHDR chdr = WSA_CMSG_FIRSTHDR(&msg);
chdr->cmsg_level = IPPROTO_IPV6;
chdr->cmsg_type = IPV6_PKTINFO;
chdr->cmsg_len = WSA_CMSG_LEN(sizeof(pktInfo));
memcpy(WSA_CMSG_DATA(chdr), &pktInfo, sizeof(pktInfo));
}
}
if (WSASendMsg (socket,
& msg,
0,
& sentLength,
NULL,
NULL) == SOCKET_ERROR)
if (WSASendTo (socket,
(LPWSABUF) buffers,
(DWORD) bufferCount,
& sentLength,
0,
address != NULL ? (struct sockaddr *) & sin : NULL,
address != NULL ? sizeof (struct sockaddr_in) : 0,
NULL,
NULL) == SOCKET_ERROR)
{
if (WSAGetLastError () == WSAEWOULDBLOCK)
return 0;
@@ -489,27 +348,24 @@ enet_socket_send (ENetSocket socket,
int
enet_socket_receive (ENetSocket socket,
ENetAddress * peerAddress,
ENetAddress * localAddress,
ENetAddress * address,
ENetBuffer * buffers,
size_t bufferCount)
{
DWORD recvLength;
WSAMSG msg = { 0 };
char controlBufData[1024];
INT sinLength = sizeof (struct sockaddr_in);
DWORD flags = 0,
recvLength = 0;
struct sockaddr_in sin;
msg.name = peerAddress != NULL ? (struct sockaddr *) & peerAddress -> address : NULL;
msg.namelen = peerAddress != NULL ? sizeof (peerAddress -> address) : 0;
msg.lpBuffers = (LPWSABUF) buffers;
msg.dwBufferCount = (DWORD) bufferCount;
msg.Control.buf = controlBufData;
msg.Control.len = sizeof(controlBufData);
if (pfnWSARecvMsg (socket,
& msg,
& recvLength,
NULL,
NULL) == SOCKET_ERROR)
if (WSARecvFrom (socket,
(LPWSABUF) buffers,
(DWORD) bufferCount,
& recvLength,
& flags,
address != NULL ? (struct sockaddr *) & sin : NULL,
address != NULL ? & sinLength : NULL,
NULL,
NULL) == SOCKET_ERROR)
{
switch (WSAGetLastError ())
{
@@ -521,35 +377,15 @@ enet_socket_receive (ENetSocket socket,
return -1;
}
if (msg.dwFlags & MSG_PARTIAL)
if (flags & MSG_PARTIAL)
return -1;
// Retrieve the local address that this traffic was received on
// to ensure we respond from the correct address/interface.
if (localAddress != NULL) {
for (PWSACMSGHDR chdr = WSA_CMSG_FIRSTHDR(&msg); chdr != NULL; chdr = WSA_CMSG_NXTHDR(&msg, chdr)) {
if (chdr->cmsg_level == IPPROTO_IP && chdr->cmsg_type == IP_PKTINFO) {
PSOCKADDR_IN localAddr = (PSOCKADDR_IN)&localAddress->address;
localAddr->sin_family = AF_INET;
localAddr->sin_addr = ((IN_PKTINFO*)WSA_CMSG_DATA(chdr))->ipi_addr;
localAddress->addressLength = sizeof(*localAddr);
break;
}
else if (chdr->cmsg_level == IPPROTO_IPV6 && chdr->cmsg_type == IPV6_PKTINFO) {
PSOCKADDR_IN6 localAddr = (PSOCKADDR_IN6)&localAddress->address;
localAddr->sin6_family = AF_INET6;
localAddr->sin6_addr = ((IN6_PKTINFO*)WSA_CMSG_DATA(chdr))->ipi6_addr;
localAddress->addressLength = sizeof(*localAddr);
break;
}
}
if (address != NULL)
{
address -> host = (enet_uint32) sin.sin_addr.s_addr;
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
}
peerAddress->addressLength = msg.namelen;
return (int) recvLength;
}