Compare commits
56 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e790647a57 | |||
| 4cde9cc3dc | |||
| 8d69c5abe4 | |||
| ad5bf95397 | |||
| ab9d471cec | |||
| c20ca391e2 | |||
| 70ce1c3e0b | |||
| cf735e639e | |||
| e8dbb360fb | |||
| 0286dcdb34 | |||
| d8976c4fcc | |||
| bdfdb8b85d | |||
| e3ada4ed75 | |||
| d9e561938f | |||
| 2cc0e7c780 | |||
| b64793fa5e | |||
| e0e7045b7e | |||
| 4de13a2c2e | |||
| 0d1fb32ee8 | |||
| 0bd265b230 | |||
| 54dac7af81 | |||
| b63fd5256a | |||
| 65dc0f74d8 | |||
| bde113ef56 | |||
| e55d226969 | |||
| 259e5dbd23 | |||
| 8d55487767 | |||
| 5de0a6f764 | |||
| 2a788029bf | |||
| 757933e7bc | |||
| eda26a26d9 | |||
| 4f3dbbaeb1 | |||
| 47d2e192aa | |||
| 8d794daa7c | |||
| 9bf55a3433 | |||
| 5c96da29c2 | |||
| d988023971 | |||
| 637cd52e96 | |||
| 512b3f26f9 | |||
| 5503534362 | |||
| 93b080b053 | |||
| cf38f85e08 | |||
| e770a52bca | |||
| 42891f6919 | |||
| eb38c3c737 | |||
| e33ca1dc47 | |||
| 7546b505c1 | |||
| 2bc07bb50d | |||
| a602abf244 | |||
| 167f41aa2b | |||
| b2ee3b7b48 | |||
| 8b24595dbd | |||
| b3e34fa1db | |||
| 4f7ef11c23 | |||
| a39d3bb49c | |||
| ae9002fe19 |
+16
-1
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
project(enet)
|
||||
|
||||
@@ -7,6 +7,7 @@ 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)
|
||||
@@ -18,6 +19,10 @@ 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()
|
||||
@@ -27,6 +32,9 @@ 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()
|
||||
@@ -54,6 +62,12 @@ 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)
|
||||
|
||||
@@ -88,6 +102,7 @@ add_library(enet STATIC
|
||||
${INCLUDE_FILES}
|
||||
${SOURCE_FILES}
|
||||
)
|
||||
target_include_directories(enet SYSTEM PUBLIC include)
|
||||
|
||||
if (MINGW)
|
||||
target_link_libraries(enet winmm ws2_32)
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
ENet 1.3.17 (November 15, 2020):
|
||||
|
||||
* fixes for sender getting too far ahead of receiver that can cause instability with reliable packets
|
||||
|
||||
ENet 1.3.16 (September 8, 2020):
|
||||
|
||||
* fix bug in unreliable fragment queuing
|
||||
* use single output queue for reliable and unreliable packets for saner ordering
|
||||
* revert experimental throttle changes that were less stable than prior algorithm
|
||||
|
||||
ENet 1.3.15 (April 20, 2020):
|
||||
|
||||
* quicker RTT initialization
|
||||
@@ -9,7 +19,7 @@ ENet 1.3.14 (January 27, 2019):
|
||||
|
||||
* bug fix for enet_peer_disconnect_later()
|
||||
* use getaddrinfo and getnameinfo where available
|
||||
* miscellenous cleanups
|
||||
* miscellaneous cleanups
|
||||
|
||||
ENet 1.3.13 (April 30, 2015):
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ PROJECT_NAME = "ENet"
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = v1.3.15
|
||||
PROJECT_NUMBER = v1.3.17
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ enetinclude_HEADERS = \
|
||||
lib_LTLIBRARIES = libenet.la
|
||||
libenet_la_SOURCES = callbacks.c compress.c host.c list.c packet.c peer.c protocol.c unix.c win32.c
|
||||
# see info '(libtool) Updating version info' before making a release
|
||||
libenet_la_LDFLAGS = $(AM_LDFLAGS) -version-info 7:3:0
|
||||
libenet_la_LDFLAGS = $(AM_LDFLAGS) -version-info 7:5:0
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
|
||||
ACLOCAL_AMFLAGS = -Im4
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
AC_INIT([libenet], [1.3.15])
|
||||
AC_INIT([libenet], [1.3.17])
|
||||
AC_CONFIG_SRCDIR([include/enet/enet.h])
|
||||
AM_INIT_AUTOMAKE([foreign])
|
||||
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ portable, and easily embeddable.
|
||||
You can retrieve the source to ENet by downloading it in either .tar.gz form
|
||||
or accessing the github distribution directly.
|
||||
|
||||
The most recent stable release (1.3.15) can be downloaded <a class="el" href="download/enet-1.3.15.tar.gz">here</a>.
|
||||
The most recent stable release (1.3.17) can be downloaded <a class="el" href="download/enet-1.3.17.tar.gz">here</a>.
|
||||
The last release that is protocol compatible with the 1.2 series or earlier (1.2.5) can be downloaded <a class="el" href="download/enet-1.2.5.tar.gz">here</a>.
|
||||
|
||||
You can find the most recent ENet source at <a class="el" href="https://github.com/lsalzman/enet">the github repository</a>.
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
/** 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
|
||||
@@ -26,7 +27,7 @@
|
||||
at any given time.
|
||||
*/
|
||||
ENetHost *
|
||||
enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
|
||||
enet_host_create (int addressFamily, const ENetAddress * address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
|
||||
{
|
||||
ENetHost * host;
|
||||
ENetPeer * currentPeer;
|
||||
@@ -48,7 +49,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
|
||||
}
|
||||
memset (host -> peers, 0, peerCount * sizeof (ENetPeer));
|
||||
|
||||
host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM);
|
||||
host -> socket = enet_socket_create (addressFamily, 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)
|
||||
@@ -61,9 +62,9 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -87,8 +88,8 @@ 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.port = 0;
|
||||
memset(& host -> receivedPeerAddress, 0, sizeof (host -> receivedPeerAddress));
|
||||
memset(& host -> receivedLocalAddress, 0, sizeof (host -> receivedLocalAddress));
|
||||
host -> receivedData = NULL;
|
||||
host -> receivedDataLength = 0;
|
||||
|
||||
@@ -124,8 +125,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
|
||||
enet_list_clear (& currentPeer -> acknowledgements);
|
||||
enet_list_clear (& currentPeer -> sentReliableCommands);
|
||||
enet_list_clear (& currentPeer -> sentUnreliableCommands);
|
||||
enet_list_clear (& currentPeer -> outgoingReliableCommands);
|
||||
enet_list_clear (& currentPeer -> outgoingUnreliableCommands);
|
||||
enet_list_clear (& currentPeer -> outgoingCommands);
|
||||
enet_list_clear (& currentPeer -> dispatchedCommands);
|
||||
|
||||
enet_peer_reset (currentPeer);
|
||||
@@ -161,6 +161,16 @@ enet_host_destroy (ENetHost * host)
|
||||
enet_free (host);
|
||||
}
|
||||
|
||||
enet_uint32
|
||||
enet_host_random (ENetHost * host)
|
||||
{
|
||||
/* Mulberry32 by Tommy Ettinger */
|
||||
enet_uint32 n = (host -> randomSeed += 0x6D2B79F5U);
|
||||
n = (n ^ (n >> 15)) * (n | 1U);
|
||||
n ^= n + (n ^ (n >> 7)) * (n | 61U);
|
||||
return n ^ (n >> 14);
|
||||
}
|
||||
|
||||
/** Initiates a connection to a foreign host.
|
||||
@param host host seeking the connection
|
||||
@param address destination for the connection
|
||||
@@ -200,7 +210,7 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC
|
||||
currentPeer -> channelCount = channelCount;
|
||||
currentPeer -> state = ENET_PEER_STATE_CONNECTING;
|
||||
currentPeer -> address = * address;
|
||||
currentPeer -> connectID = ++ host -> randomSeed;
|
||||
currentPeer -> connectID = enet_host_random (host);
|
||||
|
||||
if (host -> outgoingBandwidth == 0)
|
||||
currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
|
||||
@@ -252,30 +262,6 @@ 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
|
||||
|
||||
+27
-67
@@ -25,7 +25,7 @@ extern "C"
|
||||
|
||||
#define ENET_VERSION_MAJOR 1
|
||||
#define ENET_VERSION_MINOR 3
|
||||
#define ENET_VERSION_PATCH 15
|
||||
#define ENET_VERSION_PATCH 17
|
||||
#define ENET_VERSION_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch))
|
||||
#define ENET_VERSION_GET_MAJOR(version) (((version)>>16)&0xFF)
|
||||
#define ENET_VERSION_GET_MINOR(version) (((version)>>8)&0xFF)
|
||||
@@ -55,14 +55,14 @@ typedef enum _ENetSocketWait
|
||||
typedef enum _ENetSocketOption
|
||||
{
|
||||
ENET_SOCKOPT_NONBLOCK = 1,
|
||||
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
|
||||
ENET_SOCKOPT_RCVBUF,
|
||||
ENET_SOCKOPT_SNDBUF,
|
||||
ENET_SOCKOPT_REUSEADDR,
|
||||
ENET_SOCKOPT_RCVTIMEO,
|
||||
ENET_SOCKOPT_SNDTIMEO,
|
||||
ENET_SOCKOPT_ERROR,
|
||||
ENET_SOCKOPT_NODELAY,
|
||||
ENET_SOCKOPT_QOS,
|
||||
} ENetSocketOption;
|
||||
|
||||
typedef enum _ENetSocketShutdown
|
||||
@@ -72,24 +72,13 @@ 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
|
||||
{
|
||||
enet_uint32 host;
|
||||
enet_uint16 port;
|
||||
socklen_t addressLength;
|
||||
struct sockaddr_storage address;
|
||||
} ENetAddress;
|
||||
|
||||
/**
|
||||
@@ -212,7 +201,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 = 1400,
|
||||
ENET_HOST_DEFAULT_MTU = 900,
|
||||
ENET_HOST_DEFAULT_MAXIMUM_PACKET_SIZE = 32 * 1024 * 1024,
|
||||
ENET_HOST_DEFAULT_MAXIMUM_WAITING_DATA = 32 * 1024 * 1024,
|
||||
|
||||
@@ -270,6 +259,7 @@ 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;
|
||||
@@ -313,12 +303,10 @@ typedef struct _ENetPeer
|
||||
ENetList acknowledgements;
|
||||
ENetList sentReliableCommands;
|
||||
ENetList sentUnreliableCommands;
|
||||
ENetList outgoingReliableCommands;
|
||||
ENetList outgoingUnreliableCommands;
|
||||
ENetList outgoingCommands;
|
||||
ENetList dispatchedCommands;
|
||||
enet_uint16 flags;
|
||||
enet_uint8 roundTripTimeRemainder;
|
||||
enet_uint8 roundTripTimeVarianceRemainder;
|
||||
enet_uint16 reserved;
|
||||
enet_uint16 incomingUnsequencedGroup;
|
||||
enet_uint16 outgoingUnsequencedGroup;
|
||||
enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32];
|
||||
@@ -355,7 +343,6 @@ 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()
|
||||
@@ -387,7 +374,8 @@ 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 receivedAddress;
|
||||
ENetAddress receivedPeerAddress;
|
||||
ENetAddress receivedLocalAddress;
|
||||
enet_uint8 * receivedData;
|
||||
size_t receivedDataLength;
|
||||
enet_uint32 totalSentData; /**< total data sent, user should reset to 0 as needed to prevent overflow */
|
||||
@@ -496,14 +484,14 @@ ENET_API void enet_time_set (enet_uint32);
|
||||
/** @defgroup socket ENet socket functions
|
||||
@{
|
||||
*/
|
||||
ENET_API ENetSocket enet_socket_create (ENetSocketType);
|
||||
ENET_API ENetSocket enet_socket_create (int, 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 ENetBuffer *, size_t);
|
||||
ENET_API int enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t);
|
||||
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_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 *);
|
||||
@@ -516,17 +504,6 @@ 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
|
||||
@@ -536,26 +513,9 @@ ENET_API int enet_address_set_host_ip (ENetAddress * address, const char * hostN
|
||||
@returns the address of the given hostName in address on success
|
||||
*/
|
||||
ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName);
|
||||
|
||||
/** 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);
|
||||
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);
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -564,19 +524,19 @@ 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 ENetHost * enet_host_create (int, 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);
|
||||
ENET_API void enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32);
|
||||
extern void enet_host_bandwidth_throttle (ENetHost *);
|
||||
extern enet_uint32 enet_host_random_seed (void);
|
||||
extern enet_uint32 enet_host_random (ENetHost *);
|
||||
|
||||
ENET_API int enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *);
|
||||
ENET_API ENetPacket * enet_peer_receive (ENetPeer *, enet_uint8 * channelID);
|
||||
@@ -594,8 +554,8 @@ extern void enet_peer_setup_outgoing_command (ENetPeer *, ENetO
|
||||
extern ENetOutgoingCommand * enet_peer_queue_outgoing_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32, enet_uint16);
|
||||
extern ENetIncomingCommand * enet_peer_queue_incoming_command (ENetPeer *, const ENetProtocol *, const void *, size_t, enet_uint32, enet_uint32);
|
||||
extern ENetAcknowledgement * enet_peer_queue_acknowledgement (ENetPeer *, const ENetProtocol *, enet_uint16);
|
||||
extern void enet_peer_dispatch_incoming_unreliable_commands (ENetPeer *, ENetChannel *);
|
||||
extern void enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *);
|
||||
extern void enet_peer_dispatch_incoming_unreliable_commands (ENetPeer *, ENetChannel *, ENetIncomingCommand *);
|
||||
extern void enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *, ENetIncomingCommand *);
|
||||
extern void enet_peer_on_connect (ENetPeer *);
|
||||
extern void enet_peer_on_disconnect (ENetPeer *);
|
||||
|
||||
|
||||
@@ -10,7 +10,11 @@
|
||||
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,
|
||||
|
||||
@@ -11,11 +11,14 @@
|
||||
#pragma warning (disable: 4244) // 64bit to 32bit int
|
||||
#pragma warning (disable: 4018) // signed/unsigned mismatch
|
||||
#pragma warning (disable: 4146) // unary minus operator applied to unsigned type
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <winsock2.h>
|
||||
#include <Ws2tcpip.h>
|
||||
|
||||
typedef SOCKET ENetSocket;
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
if (rtt >= peer -> lastRoundTripTime + 2 * peer -> lastRoundTripTimeVariance)
|
||||
if (rtt > peer -> lastRoundTripTime + 2 * peer -> lastRoundTripTimeVariance)
|
||||
{
|
||||
if (peer -> packetThrottle > peer -> packetThrottleDeceleration)
|
||||
peer -> packetThrottle -= peer -> packetThrottleDeceleration;
|
||||
@@ -99,7 +99,7 @@ enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt)
|
||||
int
|
||||
enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
|
||||
{
|
||||
ENetChannel * channel = & peer -> channels [channelID];
|
||||
ENetChannel * channel;
|
||||
ENetProtocol command;
|
||||
size_t fragmentLength;
|
||||
|
||||
@@ -108,6 +108,7 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
|
||||
packet -> dataLength > peer -> host -> maximumPacketSize)
|
||||
return -1;
|
||||
|
||||
channel = & peer -> channels [channelID];
|
||||
fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment);
|
||||
if (peer -> host -> checksum != NULL)
|
||||
fragmentLength -= sizeof(enet_uint32);
|
||||
@@ -268,7 +269,7 @@ enet_peer_reset_outgoing_commands (ENetList * queue)
|
||||
}
|
||||
|
||||
static void
|
||||
enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startCommand, ENetListIterator endCommand)
|
||||
enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startCommand, ENetListIterator endCommand, ENetIncomingCommand * excludeCommand)
|
||||
{
|
||||
ENetListIterator currentCommand;
|
||||
|
||||
@@ -278,6 +279,9 @@ enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startComm
|
||||
|
||||
currentCommand = enet_list_next (currentCommand);
|
||||
|
||||
if (incomingCommand == excludeCommand)
|
||||
continue;
|
||||
|
||||
enet_list_remove (& incomingCommand -> incomingCommandList);
|
||||
|
||||
if (incomingCommand -> packet != NULL)
|
||||
@@ -298,7 +302,7 @@ enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startComm
|
||||
static void
|
||||
enet_peer_reset_incoming_commands (ENetList * queue)
|
||||
{
|
||||
enet_peer_remove_incoming_commands(queue, enet_list_begin (queue), enet_list_end (queue));
|
||||
enet_peer_remove_incoming_commands(queue, enet_list_begin (queue), enet_list_end (queue), NULL);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -318,8 +322,7 @@ enet_peer_reset_queues (ENetPeer * peer)
|
||||
|
||||
enet_peer_reset_outgoing_commands (& peer -> sentReliableCommands);
|
||||
enet_peer_reset_outgoing_commands (& peer -> sentUnreliableCommands);
|
||||
enet_peer_reset_outgoing_commands (& peer -> outgoingReliableCommands);
|
||||
enet_peer_reset_outgoing_commands (& peer -> outgoingUnreliableCommands);
|
||||
enet_peer_reset_outgoing_commands (& peer -> outgoingCommands);
|
||||
enet_peer_reset_incoming_commands (& peer -> dispatchedCommands);
|
||||
|
||||
if (peer -> channels != NULL && peer -> channelCount > 0)
|
||||
@@ -419,8 +422,6 @@ enet_peer_reset (ENetPeer * peer)
|
||||
peer -> eventData = 0;
|
||||
peer -> totalWaitingData = 0;
|
||||
peer -> flags = 0;
|
||||
peer -> roundTripTimeRemainder = 0;
|
||||
peer -> roundTripTimeVarianceRemainder = 0;
|
||||
|
||||
memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow));
|
||||
|
||||
@@ -573,8 +574,7 @@ void
|
||||
enet_peer_disconnect_later (ENetPeer * peer, enet_uint32 data)
|
||||
{
|
||||
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 -> outgoingCommands) &&
|
||||
enet_list_empty (& peer -> sentReliableCommands)))
|
||||
{
|
||||
peer -> state = ENET_PEER_STATE_DISCONNECT_LATER;
|
||||
@@ -676,10 +676,7 @@ enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoin
|
||||
break;
|
||||
}
|
||||
|
||||
if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
|
||||
enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand);
|
||||
else
|
||||
enet_list_insert (enet_list_end (& peer -> outgoingUnreliableCommands), outgoingCommand);
|
||||
enet_list_insert (enet_list_end (& peer -> outgoingCommands), outgoingCommand);
|
||||
}
|
||||
|
||||
ENetOutgoingCommand *
|
||||
@@ -702,7 +699,7 @@ enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command,
|
||||
}
|
||||
|
||||
void
|
||||
enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel)
|
||||
enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel, ENetIncomingCommand * queuedCommand)
|
||||
{
|
||||
ENetListIterator droppedCommand, startCommand, currentCommand;
|
||||
|
||||
@@ -781,11 +778,11 @@ enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel *
|
||||
droppedCommand = currentCommand;
|
||||
}
|
||||
|
||||
enet_peer_remove_incoming_commands (& channel -> incomingUnreliableCommands, enet_list_begin (& channel -> incomingUnreliableCommands), droppedCommand);
|
||||
enet_peer_remove_incoming_commands (& channel -> incomingUnreliableCommands, enet_list_begin (& channel -> incomingUnreliableCommands), droppedCommand, queuedCommand);
|
||||
}
|
||||
|
||||
void
|
||||
enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * channel)
|
||||
enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * channel, ENetIncomingCommand * queuedCommand)
|
||||
{
|
||||
ENetListIterator currentCommand;
|
||||
|
||||
@@ -820,7 +817,7 @@ enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * ch
|
||||
}
|
||||
|
||||
if (! enet_list_empty (& channel -> incomingUnreliableCommands))
|
||||
enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
|
||||
enet_peer_dispatch_incoming_unreliable_commands (peer, channel, queuedCommand);
|
||||
}
|
||||
|
||||
ENetIncomingCommand *
|
||||
@@ -978,11 +975,11 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
|
||||
{
|
||||
case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
|
||||
case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
|
||||
enet_peer_dispatch_incoming_reliable_commands (peer, channel);
|
||||
enet_peer_dispatch_incoming_reliable_commands (peer, channel, incomingCommand);
|
||||
break;
|
||||
|
||||
default:
|
||||
enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
|
||||
enet_peer_dispatch_incoming_unreliable_commands (peer, channel, incomingCommand);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
+157
-194
@@ -188,8 +188,7 @@ enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer)
|
||||
} while (! enet_list_empty (& peer -> sentUnreliableCommands));
|
||||
|
||||
if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER &&
|
||||
enet_list_empty (& peer -> outgoingReliableCommands) &&
|
||||
enet_list_empty (& peer -> outgoingUnreliableCommands) &&
|
||||
enet_list_empty (& peer -> outgoingCommands) &&
|
||||
enet_list_empty (& peer -> sentReliableCommands))
|
||||
enet_peer_disconnect (peer, peer -> eventData);
|
||||
}
|
||||
@@ -215,12 +214,15 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl
|
||||
|
||||
if (currentCommand == enet_list_end (& peer -> sentReliableCommands))
|
||||
{
|
||||
for (currentCommand = enet_list_begin (& peer -> outgoingReliableCommands);
|
||||
currentCommand != enet_list_end (& peer -> outgoingReliableCommands);
|
||||
for (currentCommand = enet_list_begin (& peer -> outgoingCommands);
|
||||
currentCommand != enet_list_end (& peer -> outgoingCommands);
|
||||
currentCommand = enet_list_next (currentCommand))
|
||||
{
|
||||
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
|
||||
|
||||
if (! (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE))
|
||||
continue;
|
||||
|
||||
if (outgoingCommand -> sendAttempts < 1) return ENET_PROTOCOL_COMMAND_NONE;
|
||||
|
||||
if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber &&
|
||||
@@ -228,7 +230,7 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl
|
||||
break;
|
||||
}
|
||||
|
||||
if (currentCommand == enet_list_end (& peer -> outgoingReliableCommands))
|
||||
if (currentCommand == enet_list_end (& peer -> outgoingCommands))
|
||||
return ENET_PROTOCOL_COMMAND_NONE;
|
||||
|
||||
wasSent = 0;
|
||||
@@ -307,10 +309,9 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
|
||||
}
|
||||
else
|
||||
if (currentPeer -> state != ENET_PEER_STATE_CONNECTING &&
|
||||
currentPeer -> address.host == host -> receivedAddress.host)
|
||||
enet_address_equal (& currentPeer -> address, & host -> receivedPeerAddress))
|
||||
{
|
||||
if (currentPeer -> address.port == host -> receivedAddress.port &&
|
||||
currentPeer -> connectID == command -> connect.connectID)
|
||||
if (currentPeer -> connectID == command -> connect.connectID)
|
||||
return NULL;
|
||||
|
||||
++ duplicatePeers;
|
||||
@@ -328,7 +329,8 @@ 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 -> receivedAddress;
|
||||
peer -> address = host -> receivedPeerAddress;
|
||||
peer -> localAddress = host -> receivedLocalAddress;
|
||||
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);
|
||||
@@ -623,7 +625,7 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
|
||||
fragmentLength);
|
||||
|
||||
if (startCommand -> fragmentsRemaining <= 0)
|
||||
enet_peer_dispatch_incoming_reliable_commands (peer, channel);
|
||||
enet_peer_dispatch_incoming_reliable_commands (peer, channel, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -741,7 +743,7 @@ enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer,
|
||||
fragmentLength);
|
||||
|
||||
if (startCommand -> fragmentsRemaining <= 0)
|
||||
enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
|
||||
enet_peer_dispatch_incoming_unreliable_commands (peer, channel, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -856,19 +858,22 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
|
||||
|
||||
if (peer -> lastReceiveTime > 0)
|
||||
{
|
||||
enet_uint32 accumRoundTripTime = (peer -> roundTripTime << 8) + peer -> roundTripTimeRemainder;
|
||||
enet_uint32 accumRoundTripTimeVariance = (peer -> roundTripTimeVariance << 8) + peer -> roundTripTimeVarianceRemainder;
|
||||
|
||||
enet_peer_throttle (peer, roundTripTime);
|
||||
|
||||
roundTripTime <<= 8;
|
||||
accumRoundTripTimeVariance = (accumRoundTripTimeVariance * 3 + ENET_DIFFERENCE (roundTripTime, accumRoundTripTime)) / 4;
|
||||
accumRoundTripTime = (accumRoundTripTime * 7 + roundTripTime) / 8;
|
||||
peer -> roundTripTimeVariance -= (peer -> roundTripTimeVariance + 3) / 4;
|
||||
|
||||
peer -> roundTripTime = accumRoundTripTime >> 8;
|
||||
peer -> roundTripTimeRemainder = accumRoundTripTime & 0xFF;
|
||||
peer -> roundTripTimeVariance = accumRoundTripTimeVariance >> 8;
|
||||
peer -> roundTripTimeVarianceRemainder = accumRoundTripTimeVariance & 0xFF;
|
||||
if (roundTripTime >= peer -> roundTripTime)
|
||||
{
|
||||
enet_uint32 diff = roundTripTime - peer -> roundTripTime;
|
||||
peer -> roundTripTimeVariance += (diff + 3) / 4;
|
||||
peer -> roundTripTime += (diff + 7) / 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
enet_uint32 diff = peer -> roundTripTime - roundTripTime;
|
||||
peer -> roundTripTimeVariance += (diff + 3) / 4;
|
||||
peer -> roundTripTime -= (diff + 7) / 8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -879,14 +884,14 @@ 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 ||
|
||||
ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> packetThrottleEpoch) >= peer -> packetThrottleInterval)
|
||||
{
|
||||
peer -> lastRoundTripTime = peer -> lowestRoundTripTime;
|
||||
peer -> lastRoundTripTimeVariance = ENET_MAX (peer -> highestRoundTripTimeVariance, 2);
|
||||
peer -> lastRoundTripTimeVariance = ENET_MAX (peer -> highestRoundTripTimeVariance, 1);
|
||||
peer -> lowestRoundTripTime = peer -> roundTripTime;
|
||||
peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance;
|
||||
peer -> packetThrottleEpoch = host -> serviceTime;
|
||||
@@ -916,8 +921,7 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
|
||||
break;
|
||||
|
||||
case ENET_PEER_STATE_DISCONNECT_LATER:
|
||||
if (enet_list_empty (& peer -> outgoingReliableCommands) &&
|
||||
enet_list_empty (& peer -> outgoingUnreliableCommands) &&
|
||||
if (enet_list_empty (& peer -> outgoingCommands) &&
|
||||
enet_list_empty (& peer -> sentReliableCommands))
|
||||
enet_peer_disconnect (peer, peer -> eventData);
|
||||
break;
|
||||
@@ -1027,9 +1031,7 @@ 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_equal(& host -> receivedAddress, & peer -> address) || */
|
||||
(peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID &&
|
||||
sessionID != peer -> incomingSessionID))
|
||||
return 0;
|
||||
@@ -1071,8 +1073,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
|
||||
|
||||
if (peer != NULL)
|
||||
{
|
||||
peer -> address.host = host -> receivedAddress.host;
|
||||
peer -> address.port = host -> receivedAddress.port;
|
||||
memcpy(& peer -> address, & host -> receivedPeerAddress, sizeof (host -> receivedPeerAddress));
|
||||
memcpy(& peer -> localAddress, & host -> receivedLocalAddress, sizeof (host -> receivedLocalAddress));
|
||||
peer -> incomingDataTotal += host -> receivedDataLength;
|
||||
}
|
||||
|
||||
@@ -1223,7 +1225,8 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
|
||||
buffer.dataLength = sizeof (host -> packetData [0]);
|
||||
|
||||
receivedLength = enet_socket_receive (host -> socket,
|
||||
& host -> receivedAddress,
|
||||
& host -> receivedPeerAddress,
|
||||
& host -> receivedLocalAddress,
|
||||
& buffer,
|
||||
1);
|
||||
|
||||
@@ -1326,108 +1329,6 @@ enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer)
|
||||
host -> bufferCount = buffer - host -> buffers;
|
||||
}
|
||||
|
||||
static void
|
||||
enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
|
||||
{
|
||||
ENetProtocol * command = & host -> commands [host -> commandCount];
|
||||
ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
|
||||
ENetOutgoingCommand * outgoingCommand;
|
||||
ENetListIterator currentCommand;
|
||||
|
||||
currentCommand = enet_list_begin (& peer -> outgoingUnreliableCommands);
|
||||
|
||||
while (currentCommand != enet_list_end (& peer -> outgoingUnreliableCommands))
|
||||
{
|
||||
size_t commandSize;
|
||||
|
||||
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
|
||||
commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK];
|
||||
|
||||
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 &&
|
||||
peer -> mtu - host -> packetSize < commandSize + outgoingCommand -> fragmentLength))
|
||||
{
|
||||
host -> continueSending = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
currentCommand = enet_list_next (currentCommand);
|
||||
|
||||
if (outgoingCommand -> packet != NULL && outgoingCommand -> fragmentOffset == 0)
|
||||
{
|
||||
peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER;
|
||||
peer -> packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE;
|
||||
|
||||
if (peer -> packetThrottleCounter > peer -> packetThrottle)
|
||||
{
|
||||
enet_uint16 reliableSequenceNumber = outgoingCommand -> reliableSequenceNumber,
|
||||
unreliableSequenceNumber = outgoingCommand -> unreliableSequenceNumber;
|
||||
for (;;)
|
||||
{
|
||||
-- outgoingCommand -> packet -> referenceCount;
|
||||
|
||||
if (outgoingCommand -> packet -> referenceCount == 0)
|
||||
enet_packet_destroy (outgoingCommand -> packet);
|
||||
|
||||
enet_list_remove (& outgoingCommand -> outgoingCommandList);
|
||||
enet_free (outgoingCommand);
|
||||
|
||||
if (currentCommand == enet_list_end (& peer -> outgoingUnreliableCommands))
|
||||
break;
|
||||
|
||||
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
|
||||
if (outgoingCommand -> reliableSequenceNumber != reliableSequenceNumber ||
|
||||
outgoingCommand -> unreliableSequenceNumber != unreliableSequenceNumber)
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
host -> packetSize += buffer -> dataLength;
|
||||
|
||||
enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand);
|
||||
}
|
||||
else
|
||||
enet_free (outgoingCommand);
|
||||
|
||||
++ command;
|
||||
++ buffer;
|
||||
}
|
||||
|
||||
host -> commandCount = command - host -> commands;
|
||||
host -> bufferCount = buffer - host -> buffers;
|
||||
|
||||
if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER &&
|
||||
enet_list_empty (& peer -> outgoingReliableCommands) &&
|
||||
enet_list_empty (& peer -> outgoingUnreliableCommands) &&
|
||||
enet_list_empty (& peer -> sentReliableCommands) &&
|
||||
enet_list_empty (& peer -> sentUnreliableCommands))
|
||||
enet_peer_disconnect (peer, peer -> eventData);
|
||||
}
|
||||
|
||||
static int
|
||||
enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * event)
|
||||
{
|
||||
@@ -1435,7 +1336,7 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even
|
||||
ENetListIterator currentCommand, insertPosition;
|
||||
|
||||
currentCommand = enet_list_begin (& peer -> sentReliableCommands);
|
||||
insertPosition = enet_list_begin (& peer -> outgoingReliableCommands);
|
||||
insertPosition = enet_list_begin (& peer -> outgoingCommands);
|
||||
|
||||
while (currentCommand != enet_list_end (& peer -> sentReliableCommands))
|
||||
{
|
||||
@@ -1466,6 +1367,8 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even
|
||||
++ peer -> packetsLost;
|
||||
|
||||
outgoingCommand -> roundTripTimeout *= 2;
|
||||
if (outgoingCommand -> roundTripTimeout > outgoingCommand -> roundTripTimeoutLimit)
|
||||
outgoingCommand -> roundTripTimeout = outgoingCommand -> roundTripTimeoutLimit;
|
||||
|
||||
enet_list_insert (insertPosition, enet_list_remove (& outgoingCommand -> outgoingCommandList));
|
||||
|
||||
@@ -1482,61 +1385,64 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even
|
||||
}
|
||||
|
||||
static int
|
||||
enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
|
||||
enet_protocol_check_outgoing_commands (ENetHost * host, ENetPeer * peer)
|
||||
{
|
||||
ENetProtocol * command = & host -> commands [host -> commandCount];
|
||||
ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
|
||||
ENetOutgoingCommand * outgoingCommand;
|
||||
ENetListIterator currentCommand;
|
||||
ENetChannel *channel;
|
||||
enet_uint16 reliableWindow;
|
||||
ENetChannel *channel = NULL;
|
||||
enet_uint16 reliableWindow = 0;
|
||||
size_t commandSize;
|
||||
int windowExceeded = 0, windowWrap = 0, canPing = 1;
|
||||
|
||||
currentCommand = enet_list_begin (& peer -> outgoingReliableCommands);
|
||||
currentCommand = enet_list_begin (& peer -> outgoingCommands);
|
||||
|
||||
while (currentCommand != enet_list_end (& peer -> outgoingReliableCommands))
|
||||
while (currentCommand != enet_list_end (& peer -> outgoingCommands))
|
||||
{
|
||||
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
|
||||
|
||||
channel = outgoingCommand -> command.header.channelID < peer -> channelCount ? & peer -> channels [outgoingCommand -> command.header.channelID] : NULL;
|
||||
reliableWindow = outgoingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
|
||||
if (channel != NULL)
|
||||
if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
|
||||
{
|
||||
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) |
|
||||
(((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) >> (ENET_PEER_RELIABLE_WINDOWS - reliableWindow)))))
|
||||
windowWrap = 1;
|
||||
if (windowWrap)
|
||||
channel = outgoingCommand -> command.header.channelID < peer -> channelCount ? & peer -> channels [outgoingCommand -> command.header.channelID] : NULL;
|
||||
reliableWindow = outgoingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
|
||||
if (channel != NULL)
|
||||
{
|
||||
currentCommand = enet_list_next (currentCommand);
|
||||
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 + 2)) - 1) << reliableWindow) |
|
||||
(((1 << (ENET_PEER_FREE_RELIABLE_WINDOWS + 2)) - 1) >> (ENET_PEER_RELIABLE_WINDOWS - reliableWindow)))))
|
||||
windowWrap = 1;
|
||||
if (windowWrap)
|
||||
{
|
||||
currentCommand = enet_list_next (currentCommand);
|
||||
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (outgoingCommand -> packet != NULL)
|
||||
{
|
||||
if (! windowExceeded)
|
||||
if (outgoingCommand -> packet != NULL)
|
||||
{
|
||||
enet_uint32 windowSize = (peer -> packetThrottle * peer -> windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE;
|
||||
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;
|
||||
}
|
||||
if (windowExceeded)
|
||||
{
|
||||
currentCommand = enet_list_next (currentCommand);
|
||||
if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > ENET_MAX (windowSize, peer -> mtu))
|
||||
windowExceeded = 1;
|
||||
}
|
||||
if (windowExceeded)
|
||||
{
|
||||
currentCommand = enet_list_next (currentCommand);
|
||||
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
canPing = 0;
|
||||
}
|
||||
|
||||
canPing = 0;
|
||||
|
||||
commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK];
|
||||
if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
|
||||
buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
|
||||
@@ -1551,33 +1457,80 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
|
||||
|
||||
currentCommand = enet_list_next (currentCommand);
|
||||
|
||||
if (channel != NULL && outgoingCommand -> sendAttempts < 1)
|
||||
if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
|
||||
{
|
||||
channel -> usedReliableWindows |= 1 << reliableWindow;
|
||||
++ channel -> reliableWindows [reliableWindow];
|
||||
}
|
||||
if (channel != NULL && outgoingCommand -> sendAttempts < 1)
|
||||
{
|
||||
channel -> usedReliableWindows |= 1 << reliableWindow;
|
||||
++ channel -> reliableWindows [reliableWindow];
|
||||
}
|
||||
|
||||
++ outgoingCommand -> sendAttempts;
|
||||
++ outgoingCommand -> sendAttempts;
|
||||
|
||||
if (outgoingCommand -> roundTripTimeout == 0)
|
||||
{
|
||||
outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance;
|
||||
outgoingCommand -> roundTripTimeoutLimit = peer -> timeoutLimit * outgoingCommand -> roundTripTimeout;
|
||||
if (outgoingCommand -> roundTripTimeout == 0)
|
||||
{
|
||||
outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * ENET_MAX (1, peer -> roundTripTimeVariance);
|
||||
outgoingCommand -> roundTripTimeoutLimit = peer -> timeoutLimit * outgoingCommand -> roundTripTimeout;
|
||||
}
|
||||
|
||||
if (enet_list_empty (& peer -> sentReliableCommands))
|
||||
peer -> nextTimeout = host -> serviceTime + outgoingCommand -> roundTripTimeout;
|
||||
|
||||
enet_list_insert (enet_list_end (& peer -> sentReliableCommands),
|
||||
enet_list_remove (& outgoingCommand -> outgoingCommandList));
|
||||
|
||||
outgoingCommand -> sentTime = host -> serviceTime;
|
||||
|
||||
host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME;
|
||||
|
||||
peer -> reliableDataInTransit += outgoingCommand -> fragmentLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (outgoingCommand -> packet != NULL && outgoingCommand -> fragmentOffset == 0)
|
||||
{
|
||||
peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER;
|
||||
peer -> packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE;
|
||||
|
||||
if (enet_list_empty (& peer -> sentReliableCommands))
|
||||
peer -> nextTimeout = host -> serviceTime + outgoingCommand -> roundTripTimeout;
|
||||
if (peer -> packetThrottleCounter > peer -> packetThrottle)
|
||||
{
|
||||
enet_uint16 reliableSequenceNumber = outgoingCommand -> reliableSequenceNumber,
|
||||
unreliableSequenceNumber = outgoingCommand -> unreliableSequenceNumber;
|
||||
for (;;)
|
||||
{
|
||||
-- outgoingCommand -> packet -> referenceCount;
|
||||
|
||||
enet_list_insert (enet_list_end (& peer -> sentReliableCommands),
|
||||
enet_list_remove (& outgoingCommand -> outgoingCommandList));
|
||||
if (outgoingCommand -> packet -> referenceCount == 0)
|
||||
enet_packet_destroy (outgoingCommand -> packet);
|
||||
|
||||
outgoingCommand -> sentTime = host -> serviceTime;
|
||||
enet_list_remove (& outgoingCommand -> outgoingCommandList);
|
||||
enet_free (outgoingCommand);
|
||||
|
||||
if (currentCommand == enet_list_end (& peer -> outgoingCommands))
|
||||
break;
|
||||
|
||||
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
|
||||
if (outgoingCommand -> reliableSequenceNumber != reliableSequenceNumber ||
|
||||
outgoingCommand -> unreliableSequenceNumber != unreliableSequenceNumber)
|
||||
break;
|
||||
|
||||
currentCommand = enet_list_next (currentCommand);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
enet_list_remove (& outgoingCommand -> outgoingCommandList);
|
||||
|
||||
if (outgoingCommand -> packet != NULL)
|
||||
enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand);
|
||||
}
|
||||
|
||||
buffer -> data = command;
|
||||
buffer -> dataLength = commandSize;
|
||||
|
||||
host -> packetSize += buffer -> dataLength;
|
||||
host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME;
|
||||
|
||||
* command = outgoingCommand -> command;
|
||||
|
||||
@@ -1589,9 +1542,10 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
|
||||
buffer -> dataLength = outgoingCommand -> fragmentLength;
|
||||
|
||||
host -> packetSize += outgoingCommand -> fragmentLength;
|
||||
|
||||
peer -> reliableDataInTransit += outgoingCommand -> fragmentLength;
|
||||
}
|
||||
else
|
||||
if (! (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE))
|
||||
enet_free (outgoingCommand);
|
||||
|
||||
++ peer -> packetsSent;
|
||||
|
||||
@@ -1602,6 +1556,12 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
|
||||
host -> commandCount = command - host -> commands;
|
||||
host -> bufferCount = buffer - host -> buffers;
|
||||
|
||||
if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER &&
|
||||
enet_list_empty (& peer -> outgoingCommands) &&
|
||||
enet_list_empty (& peer -> sentReliableCommands) &&
|
||||
enet_list_empty (& peer -> sentUnreliableCommands))
|
||||
enet_peer_disconnect (peer, peer -> eventData);
|
||||
|
||||
return canPing;
|
||||
}
|
||||
|
||||
@@ -1645,18 +1605,15 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((enet_list_empty (& currentPeer -> outgoingReliableCommands) ||
|
||||
enet_protocol_send_reliable_outgoing_commands (host, currentPeer)) &&
|
||||
if ((enet_list_empty (& currentPeer -> outgoingCommands) ||
|
||||
enet_protocol_check_outgoing_commands (host, currentPeer)) &&
|
||||
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);
|
||||
enet_protocol_check_outgoing_commands (host, currentPeer);
|
||||
}
|
||||
|
||||
if (! enet_list_empty (& currentPeer -> outgoingUnreliableCommands))
|
||||
enet_protocol_send_unreliable_outgoing_commands (host, currentPeer);
|
||||
|
||||
if (host -> commandCount == 0)
|
||||
continue;
|
||||
@@ -1670,7 +1627,7 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
|
||||
enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent;
|
||||
|
||||
#ifdef ENET_DEBUG
|
||||
printf ("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);
|
||||
printf ("peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %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 -> outgoingCommands), 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 * 3 + ENET_DIFFERENCE (packetLoss, currentPeer -> packetLoss)) / 4;
|
||||
@@ -1730,7 +1687,13 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
|
||||
|
||||
currentPeer -> lastSendTime = host -> serviceTime;
|
||||
|
||||
sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount);
|
||||
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);
|
||||
|
||||
enet_protocol_remove_sent_unreliable_commands (currentPeer);
|
||||
|
||||
@@ -1824,7 +1787,7 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
|
||||
|
||||
timeout += host -> serviceTime;
|
||||
|
||||
do
|
||||
for (;;)
|
||||
{
|
||||
if (ENET_TIME_DIFFERENCE (host -> serviceTime, host -> bandwidthThrottleEpoch) >= ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
|
||||
enet_host_bandwidth_throttle (host);
|
||||
@@ -1908,13 +1871,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)) != 0)
|
||||
if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime) / 10) != 0)
|
||||
return -1;
|
||||
}
|
||||
while (waitCondition & ENET_SOCKET_WAIT_INTERRUPT);
|
||||
|
||||
host -> serviceTime = enet_time_get ();
|
||||
} while (waitCondition & ENET_SOCKET_WAIT_RECEIVE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4,9 +4,19 @@
|
||||
*/
|
||||
#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/ioctl.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netdb.h>
|
||||
@@ -18,9 +28,9 @@
|
||||
#define ENET_BUILDING_LIB 1
|
||||
#include "enet/enet.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#ifdef HAS_POLL
|
||||
#undef HAS_POLL
|
||||
#if defined(__APPLE__)
|
||||
#ifndef HAS_POLL
|
||||
#define HAS_POLL 1
|
||||
#endif
|
||||
#ifndef HAS_FCNTL
|
||||
#define HAS_FCNTL 1
|
||||
@@ -43,20 +53,91 @@
|
||||
#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
|
||||
|
||||
#ifndef HAS_SOCKLEN_T
|
||||
#if !defined(HAS_SOCKLEN_T) && !defined(__socklen_t_defined)
|
||||
typedef int socklen_t;
|
||||
#endif
|
||||
|
||||
#ifndef SOMAXCONN
|
||||
#define SOMAXCONN 128
|
||||
#endif
|
||||
|
||||
#ifndef MSG_NOSIGNAL
|
||||
#define MSG_NOSIGNAL 0
|
||||
#endif
|
||||
@@ -77,7 +158,11 @@ enet_deinitialize (void)
|
||||
enet_uint32
|
||||
enet_host_random_seed (void)
|
||||
{
|
||||
return (enet_uint32) time (NULL);
|
||||
struct timeval timeVal;
|
||||
|
||||
gettimeofday (& timeVal, NULL);
|
||||
|
||||
return (timeVal.tv_sec * 1000) ^ (timeVal.tv_usec / 1000);
|
||||
}
|
||||
|
||||
enet_uint32
|
||||
@@ -101,186 +186,116 @@ enet_time_set (enet_uint32 newTimeBase)
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_set_host_ip (ENetAddress * address, const char * name)
|
||||
enet_address_equal (ENetAddress * address1, ENetAddress * address2)
|
||||
{
|
||||
#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;
|
||||
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));
|
||||
}
|
||||
#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_INET;
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_flags = AI_ADDRCONFIG;
|
||||
|
||||
if (getaddrinfo (name, NULL, NULL, & resultList) != 0)
|
||||
if (getaddrinfo (name, NULL, & hints, & resultList) != 0)
|
||||
return -1;
|
||||
|
||||
for (result = resultList; result != NULL; result = result -> ai_next)
|
||||
{
|
||||
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;
|
||||
}
|
||||
memcpy (& address -> address, result -> ai_addr, result -> ai_addrlen);
|
||||
address -> addressLength = result -> ai_addrlen;
|
||||
|
||||
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;
|
||||
|
||||
#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);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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 *) & sin,
|
||||
sizeof (struct sockaddr_in));
|
||||
(struct sockaddr *) & address -> address,
|
||||
address -> addressLength);
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_get_address (ENetSocket socket, ENetAddress * address)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
socklen_t sinLength = sizeof (struct sockaddr_in);
|
||||
address -> addressLength = sizeof (address -> address);
|
||||
|
||||
if (getsockname (socket, (struct sockaddr *) & sin, & sinLength) == -1)
|
||||
if (getsockname (socket, (struct sockaddr *) & address -> address, & address -> addressLength) == -1)
|
||||
return -1;
|
||||
|
||||
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -291,9 +306,39 @@ enet_socket_listen (ENetSocket socket, int backlog)
|
||||
}
|
||||
|
||||
ENetSocket
|
||||
enet_socket_create (ENetSocketType type)
|
||||
enet_socket_create (int af, ENetSocketType type)
|
||||
{
|
||||
return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
|
||||
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;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -306,12 +351,12 @@ 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:
|
||||
@@ -326,6 +371,7 @@ 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;
|
||||
@@ -343,11 +389,36 @@ 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;
|
||||
}
|
||||
@@ -375,16 +446,9 @@ 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;
|
||||
|
||||
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));
|
||||
result = connect (socket, (struct sockaddr *) & address -> address, address -> addressLength);
|
||||
if (result == -1 && errno == EINPROGRESS)
|
||||
return 0;
|
||||
|
||||
@@ -395,25 +459,20 @@ ENetSocket
|
||||
enet_socket_accept (ENetSocket socket, ENetAddress * address)
|
||||
{
|
||||
int result;
|
||||
struct sockaddr_in sin;
|
||||
socklen_t sinLength = sizeof (struct sockaddr_in);
|
||||
|
||||
if (address != NULL)
|
||||
address -> addressLength = sizeof (address -> address);
|
||||
|
||||
result = accept (socket,
|
||||
address != NULL ? (struct sockaddr *) & sin : NULL,
|
||||
address != NULL ? & sinLength : NULL);
|
||||
address != NULL ? (struct sockaddr *) & address -> address : NULL,
|
||||
address != NULL ? & address -> addressLength : NULL);
|
||||
|
||||
if (result == -1)
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_shutdown (ENetSocket socket, ENetSocketShutdown how)
|
||||
{
|
||||
@@ -429,32 +488,106 @@ enet_socket_destroy (ENetSocket socket)
|
||||
|
||||
int
|
||||
enet_socket_send (ENetSocket socket,
|
||||
const ENetAddress * address,
|
||||
const ENetAddress * peerAddress,
|
||||
const ENetAddress * localAddress,
|
||||
const ENetBuffer * buffers,
|
||||
size_t bufferCount)
|
||||
{
|
||||
struct msghdr msgHdr;
|
||||
struct sockaddr_in sin;
|
||||
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];
|
||||
|
||||
memset (& msgHdr, 0, sizeof (struct msghdr));
|
||||
|
||||
if (address != NULL)
|
||||
if (peerAddress != NULL)
|
||||
{
|
||||
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_name = (void*) & peerAddress -> address;
|
||||
msgHdr.msg_namelen = peerAddress -> addressLength;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -469,24 +602,45 @@ enet_socket_send (ENetSocket socket,
|
||||
|
||||
int
|
||||
enet_socket_receive (ENetSocket socket,
|
||||
ENetAddress * address,
|
||||
ENetAddress * peerAddress,
|
||||
ENetAddress * localAddress,
|
||||
ENetBuffer * buffers,
|
||||
size_t bufferCount)
|
||||
{
|
||||
struct msghdr msgHdr;
|
||||
struct sockaddr_in sin;
|
||||
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];
|
||||
|
||||
memset (& msgHdr, 0, sizeof (struct msghdr));
|
||||
|
||||
if (address != NULL)
|
||||
if (peerAddress != NULL)
|
||||
{
|
||||
msgHdr.msg_name = & sin;
|
||||
msgHdr.msg_namelen = sizeof (struct sockaddr_in);
|
||||
msgHdr.msg_name = & peerAddress -> address;
|
||||
msgHdr.msg_namelen = sizeof (peerAddress -> address);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@@ -503,13 +657,40 @@ enet_socket_receive (ENetSocket socket,
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
if (address != NULL)
|
||||
{
|
||||
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||
// 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 (peerAddress != NULL)
|
||||
peerAddress -> addressLength = msgHdr.msg_namelen;
|
||||
|
||||
return recvLength;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -7,21 +7,43 @@
|
||||
#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 (1, 1);
|
||||
WORD versionRequested = MAKEWORD (2, 0);
|
||||
WSADATA wsaData;
|
||||
|
||||
if (WSAStartup (versionRequested, & wsaData))
|
||||
return -1;
|
||||
|
||||
if (LOBYTE (wsaData.wVersion) != 1||
|
||||
HIBYTE (wsaData.wVersion) != 1)
|
||||
if (LOBYTE (wsaData.wVersion) != 2||
|
||||
HIBYTE (wsaData.wVersion) != 0)
|
||||
{
|
||||
WSACleanup ();
|
||||
|
||||
@@ -30,12 +52,46 @@ 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 ();
|
||||
@@ -60,121 +116,112 @@ enet_time_set (enet_uint32 newTimeBase)
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_set_host_ip (ENetAddress * address, const char * name)
|
||||
enet_address_set_port (ENetAddress * address, enet_uint16 port)
|
||||
{
|
||||
enet_uint8 vals [4] = { 0, 0, 0, 0 };
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; ++ i)
|
||||
if (address -> address.ss_family == AF_INET)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (* next != (i < 3 ? '.' : '\0'))
|
||||
return -1;
|
||||
name = next + 1;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy (& address -> host, vals, sizeof (enet_uint32));
|
||||
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_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 hostent * hostEntry;
|
||||
struct addrinfo hints, * resultList = NULL, * result = NULL;
|
||||
|
||||
hostEntry = gethostbyname (name);
|
||||
if (hostEntry == NULL ||
|
||||
hostEntry -> h_addrtype != AF_INET)
|
||||
return enet_address_set_host_ip (address, name);
|
||||
memset (& hints, 0, sizeof (hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_flags = AI_ADDRCONFIG;
|
||||
|
||||
address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
|
||||
if (getaddrinfo (name, NULL, & hints, & resultList) != 0)
|
||||
return -1;
|
||||
|
||||
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
|
||||
for (result = resultList; result != NULL; result = result -> ai_next)
|
||||
{
|
||||
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);
|
||||
memcpy (& address -> address, result -> ai_addr, result -> ai_addrlen);
|
||||
address -> addressLength = result -> ai_addrlen;
|
||||
|
||||
freeaddrinfo (resultList);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
if (resultList != NULL)
|
||||
freeaddrinfo (resultList);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
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 *) & sin,
|
||||
sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
|
||||
(struct sockaddr *) & address -> address,
|
||||
address -> addressLength);
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_get_address (ENetSocket socket, ENetAddress * address)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
int sinLength = sizeof (struct sockaddr_in);
|
||||
address -> addressLength = sizeof (address -> address);
|
||||
|
||||
if (getsockname (socket, (struct sockaddr *) & sin, & sinLength) == -1)
|
||||
if (getsockname (socket, (struct sockaddr *) & address -> address, & address -> addressLength) == -1)
|
||||
return -1;
|
||||
|
||||
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -185,9 +232,48 @@ enet_socket_listen (ENetSocket socket, int backlog)
|
||||
}
|
||||
|
||||
ENetSocket
|
||||
enet_socket_create (ENetSocketType type)
|
||||
enet_socket_create (int af, ENetSocketType type)
|
||||
{
|
||||
return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
|
||||
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;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -203,10 +289,6 @@ 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;
|
||||
@@ -231,6 +313,32 @@ 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;
|
||||
}
|
||||
@@ -257,16 +365,9 @@ 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;
|
||||
|
||||
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));
|
||||
result = connect (socket, (struct sockaddr *) & address -> address, address -> addressLength);
|
||||
if (result == SOCKET_ERROR && WSAGetLastError () != WSAEWOULDBLOCK)
|
||||
return -1;
|
||||
|
||||
@@ -276,22 +377,17 @@ enet_socket_connect (ENetSocket socket, const ENetAddress * address)
|
||||
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);
|
||||
|
||||
if (result == INVALID_SOCKET)
|
||||
return ENET_SOCKET_NULL;
|
||||
int result;
|
||||
|
||||
if (address != NULL)
|
||||
{
|
||||
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||
}
|
||||
address -> addressLength = sizeof (address -> address);
|
||||
|
||||
result = accept (socket,
|
||||
address != NULL ? (struct sockaddr *) & address -> address : NULL,
|
||||
address != NULL ? & address -> addressLength : NULL);
|
||||
|
||||
if (result == -1)
|
||||
return ENET_SOCKET_NULL;
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -311,31 +407,76 @@ enet_socket_destroy (ENetSocket socket)
|
||||
|
||||
int
|
||||
enet_socket_send (ENetSocket socket,
|
||||
const ENetAddress * address,
|
||||
const ENetAddress * peerAddress,
|
||||
const ENetAddress * localAddress,
|
||||
const ENetBuffer * buffers,
|
||||
size_t bufferCount)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
DWORD sentLength = 0;
|
||||
DWORD sentLength;
|
||||
WSAMSG msg = { 0 };
|
||||
char controlBufData[1024];
|
||||
|
||||
if (address != NULL)
|
||||
if (!qosAddedFlow && qosHandle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
memset (& sin, 0, sizeof (struct sockaddr_in));
|
||||
qosFlowId = 0; // Must be initialized to 0
|
||||
pfnQOSAddSocketToFlow(qosHandle,
|
||||
socket,
|
||||
(struct sockaddr *)&peerAddress->address,
|
||||
QOSTrafficTypeControl,
|
||||
QOS_NON_ADAPTIVE_FLOW,
|
||||
&qosFlowId);
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
|
||||
sin.sin_addr.s_addr = address -> host;
|
||||
// Even if we failed, don't try again
|
||||
qosAddedFlow = TRUE;
|
||||
}
|
||||
|
||||
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)
|
||||
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 (WSAGetLastError () == WSAEWOULDBLOCK)
|
||||
return 0;
|
||||
@@ -348,24 +489,27 @@ enet_socket_send (ENetSocket socket,
|
||||
|
||||
int
|
||||
enet_socket_receive (ENetSocket socket,
|
||||
ENetAddress * address,
|
||||
ENetAddress * peerAddress,
|
||||
ENetAddress * localAddress,
|
||||
ENetBuffer * buffers,
|
||||
size_t bufferCount)
|
||||
{
|
||||
INT sinLength = sizeof (struct sockaddr_in);
|
||||
DWORD flags = 0,
|
||||
recvLength = 0;
|
||||
struct sockaddr_in sin;
|
||||
DWORD recvLength;
|
||||
WSAMSG msg = { 0 };
|
||||
char controlBufData[1024];
|
||||
|
||||
if (WSARecvFrom (socket,
|
||||
(LPWSABUF) buffers,
|
||||
(DWORD) bufferCount,
|
||||
& recvLength,
|
||||
& flags,
|
||||
address != NULL ? (struct sockaddr *) & sin : NULL,
|
||||
address != NULL ? & sinLength : NULL,
|
||||
NULL,
|
||||
NULL) == SOCKET_ERROR)
|
||||
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)
|
||||
{
|
||||
switch (WSAGetLastError ())
|
||||
{
|
||||
@@ -377,15 +521,35 @@ enet_socket_receive (ENetSocket socket,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flags & MSG_PARTIAL)
|
||||
if (msg.dwFlags & MSG_PARTIAL)
|
||||
return -1;
|
||||
|
||||
if (address != NULL)
|
||||
{
|
||||
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
peerAddress->addressLength = msg.namelen;
|
||||
return (int) recvLength;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user