Compare commits
65 Commits
master
...
v6_multihome
| 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 | |||
| 224f31101f | |||
| 22272e29f9 | |||
| 5b93d08fa5 | |||
| c25b57b2c1 | |||
| f89e5986d0 | |||
| bb14921419 | |||
| 67cee4803a | |||
| 007b7d2a3f | |||
| 92bf2d8256 | |||
| 33c7d6903e | |||
| 6991632abf | |||
| b4c427059a | |||
| 6537dc81f3 | |||
| 0eaf48eeb0 | |||
| b8713bdf88 | |||
| e2ef83927d | |||
| cea2c5be9f | |||
| 295456fba9 | |||
| 219c625c74 | |||
| 335715309c | |||
| 2e1c6bceea | |||
| 39a72ab199 | |||
| 67f964c2ad | |||
| a84c120eff | |||
| 6cc8cc8a26 | |||
| 9d9ba122d4 | |||
| 90560cd471 | |||
| 0891c520d2 | |||
| 5f5e977eef | |||
| 3ae5af4548 | |||
| f46fee0acc |
+54
-14
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
project(enet)
|
||||
|
||||
@@ -19,7 +19,16 @@ 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()
|
||||
add_definitions(-Wno-error)
|
||||
endif()
|
||||
|
||||
if(HAS_FCNTL)
|
||||
add_definitions(-DHAS_FCNTL=1)
|
||||
endif()
|
||||
@@ -53,17 +62,48 @@ 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)
|
||||
|
||||
|
||||
set(INCLUDE_FILES_PREFIX include/enet)
|
||||
set(INCLUDE_FILES
|
||||
${INCLUDE_FILES_PREFIX}/callbacks.h
|
||||
${INCLUDE_FILES_PREFIX}/enet.h
|
||||
${INCLUDE_FILES_PREFIX}/list.h
|
||||
${INCLUDE_FILES_PREFIX}/protocol.h
|
||||
${INCLUDE_FILES_PREFIX}/time.h
|
||||
${INCLUDE_FILES_PREFIX}/types.h
|
||||
${INCLUDE_FILES_PREFIX}/unix.h
|
||||
${INCLUDE_FILES_PREFIX}/utility.h
|
||||
${INCLUDE_FILES_PREFIX}/win32.h
|
||||
)
|
||||
|
||||
set(SOURCE_FILES
|
||||
callbacks.c
|
||||
compress.c
|
||||
host.c
|
||||
list.c
|
||||
packet.c
|
||||
peer.c
|
||||
protocol.c
|
||||
unix.c
|
||||
win32.c)
|
||||
|
||||
source_group(include FILES ${INCLUDE_FILES})
|
||||
source_group(source FILES ${SOURCE_FILES})
|
||||
|
||||
add_library(enet STATIC
|
||||
callbacks.c
|
||||
compress.c
|
||||
host.c
|
||||
list.c
|
||||
packet.c
|
||||
peer.c
|
||||
protocol.c
|
||||
unix.c
|
||||
win32.c
|
||||
)
|
||||
${INCLUDE_FILES}
|
||||
${SOURCE_FILES}
|
||||
)
|
||||
target_include_directories(enet SYSTEM PUBLIC include)
|
||||
|
||||
if (MINGW)
|
||||
target_link_libraries(enet winmm ws2_32)
|
||||
endif()
|
||||
|
||||
@@ -1,4 +1,25 @@
|
||||
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
|
||||
* use fractional precision for RTT calculations
|
||||
* fixes for packet throttle with low RTT variance
|
||||
* miscellaneous socket bug fixes
|
||||
|
||||
ENet 1.3.14 (January 27, 2019):
|
||||
|
||||
* bug fix for enet_peer_disconnect_later()
|
||||
* use getaddrinfo and getnameinfo where available
|
||||
* 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.13
|
||||
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,4 +1,4 @@
|
||||
Copyright (c) 2002-2016 Lee Salzman
|
||||
Copyright (c) 2002-2020 Lee Salzman
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
+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:1: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.13])
|
||||
AC_INIT([libenet], [1.3.17])
|
||||
AC_CONFIG_SRCDIR([include/enet/enet.h])
|
||||
AM_INIT_AUTOMAKE([foreign])
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
@page License License
|
||||
|
||||
Copyright (c) 2002-2016 Lee Salzman
|
||||
Copyright (c) 2002-2020 Lee Salzman
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
+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.13) can be downloaded <a class="el" href="download/enet-1.3.13.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>.
|
||||
|
||||
+2
-2
@@ -102,8 +102,8 @@ may be simultaneously open.
|
||||
client = enet_host_create (NULL /* create a client host */,
|
||||
1 /* only allow 1 outgoing connection */,
|
||||
2 /* allow up 2 channels to be used, 0 and 1 */,
|
||||
57600 / 8 /* 56K modem with 56 Kbps downstream bandwidth */,
|
||||
14400 / 8 /* 56K modem with 14 Kbps upstream bandwidth */);
|
||||
0 /* assume any amount of incoming bandwidth */,
|
||||
0 /* assume any amount of outgoing bandwidth */);
|
||||
|
||||
if (client == NULL)
|
||||
{
|
||||
|
||||
@@ -88,7 +88,8 @@ enet_host_create (int addressFamily, const ENetAddress * address, size_t peerCou
|
||||
host -> commandCount = 0;
|
||||
host -> bufferCount = 0;
|
||||
host -> checksum = NULL;
|
||||
memset(& host -> receivedAddress, 0, sizeof (host -> receivedAddress));
|
||||
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 (int addressFamily, const ENetAddress * address, size_t peerCou
|
||||
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;
|
||||
|
||||
+17
-9
@@ -25,7 +25,7 @@ extern "C"
|
||||
|
||||
#define ENET_VERSION_MAJOR 1
|
||||
#define ENET_VERSION_MINOR 3
|
||||
#define ENET_VERSION_PATCH 13
|
||||
#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)
|
||||
@@ -239,6 +239,11 @@ typedef struct _ENetChannel
|
||||
ENetList incomingUnreliableCommands;
|
||||
} ENetChannel;
|
||||
|
||||
typedef enum _ENetPeerFlag
|
||||
{
|
||||
ENET_PEER_FLAG_NEEDS_DISPATCH = (1 << 0)
|
||||
} ENetPeerFlag;
|
||||
|
||||
/**
|
||||
* An ENet peer which data packets may be sent or received from.
|
||||
*
|
||||
@@ -254,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;
|
||||
@@ -297,10 +303,10 @@ typedef struct _ENetPeer
|
||||
ENetList acknowledgements;
|
||||
ENetList sentReliableCommands;
|
||||
ENetList sentUnreliableCommands;
|
||||
ENetList outgoingReliableCommands;
|
||||
ENetList outgoingUnreliableCommands;
|
||||
ENetList outgoingCommands;
|
||||
ENetList dispatchedCommands;
|
||||
int needsDispatch;
|
||||
enet_uint16 flags;
|
||||
enet_uint16 reserved;
|
||||
enet_uint16 incomingUnsequencedGroup;
|
||||
enet_uint16 outgoingUnsequencedGroup;
|
||||
enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32];
|
||||
@@ -368,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 */
|
||||
@@ -483,8 +490,8 @@ 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 *);
|
||||
@@ -529,6 +536,7 @@ 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);
|
||||
@@ -546,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,
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#define ENET_MAX(x, y) ((x) > (y) ? (x) : (y))
|
||||
#define ENET_MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
#define ENET_DIFFERENCE(x, y) ((x) < (y) ? (y) - (x) : (x) - (y))
|
||||
|
||||
#endif /* __ENET_UTILITY_H__ */
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#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
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt)
|
||||
peer -> packetThrottle = peer -> packetThrottleLimit;
|
||||
}
|
||||
else
|
||||
if (rtt < peer -> lastRoundTripTime)
|
||||
if (rtt <= peer -> lastRoundTripTime)
|
||||
{
|
||||
peer -> packetThrottle += peer -> packetThrottleAcceleration;
|
||||
|
||||
@@ -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
|
||||
@@ -306,11 +310,11 @@ enet_peer_reset_queues (ENetPeer * peer)
|
||||
{
|
||||
ENetChannel * channel;
|
||||
|
||||
if (peer -> needsDispatch)
|
||||
if (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH)
|
||||
{
|
||||
enet_list_remove (& peer -> dispatchList);
|
||||
|
||||
peer -> needsDispatch = 0;
|
||||
peer -> flags &= ~ ENET_PEER_FLAG_NEEDS_DISPATCH;
|
||||
}
|
||||
|
||||
while (! enet_list_empty (& peer -> acknowledgements))
|
||||
@@ -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)
|
||||
@@ -418,6 +421,7 @@ enet_peer_reset (ENetPeer * peer)
|
||||
peer -> outgoingUnsequencedGroup = 0;
|
||||
peer -> eventData = 0;
|
||||
peer -> totalWaitingData = 0;
|
||||
peer -> flags = 0;
|
||||
|
||||
memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow));
|
||||
|
||||
@@ -570,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;
|
||||
@@ -673,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 *
|
||||
@@ -699,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;
|
||||
|
||||
@@ -724,11 +724,11 @@ enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel *
|
||||
{
|
||||
enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand));
|
||||
|
||||
if (! peer -> needsDispatch)
|
||||
if (! (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH))
|
||||
{
|
||||
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
|
||||
|
||||
peer -> needsDispatch = 1;
|
||||
peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
|
||||
}
|
||||
|
||||
droppedCommand = currentCommand;
|
||||
@@ -752,11 +752,11 @@ enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel *
|
||||
{
|
||||
enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand));
|
||||
|
||||
if (! peer -> needsDispatch)
|
||||
if (! (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH))
|
||||
{
|
||||
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
|
||||
|
||||
peer -> needsDispatch = 1;
|
||||
peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -768,21 +768,21 @@ enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel *
|
||||
{
|
||||
enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand));
|
||||
|
||||
if (! peer -> needsDispatch)
|
||||
if (! (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH))
|
||||
{
|
||||
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
|
||||
|
||||
peer -> needsDispatch = 1;
|
||||
peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -809,15 +809,15 @@ enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * ch
|
||||
|
||||
enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingReliableCommands), enet_list_previous (currentCommand));
|
||||
|
||||
if (! peer -> needsDispatch)
|
||||
if (! (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH))
|
||||
{
|
||||
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
|
||||
|
||||
peer -> needsDispatch = 1;
|
||||
peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
|
||||
}
|
||||
|
||||
if (! enet_list_empty (& channel -> incomingUnreliableCommands))
|
||||
enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
|
||||
enet_peer_dispatch_incoming_unreliable_commands (peer, channel, queuedCommand);
|
||||
}
|
||||
|
||||
ENetIncomingCommand *
|
||||
@@ -975,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;
|
||||
}
|
||||
|
||||
|
||||
+172
-203
@@ -48,11 +48,11 @@ enet_protocol_dispatch_state (ENetHost * host, ENetPeer * peer, ENetPeerState st
|
||||
{
|
||||
enet_protocol_change_state (host, peer, state);
|
||||
|
||||
if (! peer -> needsDispatch)
|
||||
if (! (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH))
|
||||
{
|
||||
enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList);
|
||||
|
||||
peer -> needsDispatch = 1;
|
||||
peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
|
||||
{
|
||||
ENetPeer * peer = (ENetPeer *) enet_list_remove (enet_list_begin (& host -> dispatchQueue));
|
||||
|
||||
peer -> needsDispatch = 0;
|
||||
peer -> flags &= ~ ENET_PEER_FLAG_NEEDS_DISPATCH;
|
||||
|
||||
switch (peer -> state)
|
||||
{
|
||||
@@ -101,7 +101,7 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
|
||||
|
||||
if (! enet_list_empty (& peer -> dispatchedCommands))
|
||||
{
|
||||
peer -> needsDispatch = 1;
|
||||
peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
|
||||
|
||||
enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList);
|
||||
}
|
||||
@@ -163,7 +163,10 @@ enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer)
|
||||
{
|
||||
ENetOutgoingCommand * outgoingCommand;
|
||||
|
||||
while (! enet_list_empty (& peer -> sentUnreliableCommands))
|
||||
if (enet_list_empty (& peer -> sentUnreliableCommands))
|
||||
return;
|
||||
|
||||
do
|
||||
{
|
||||
outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentUnreliableCommands);
|
||||
|
||||
@@ -182,7 +185,12 @@ enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer)
|
||||
}
|
||||
|
||||
enet_free (outgoingCommand);
|
||||
}
|
||||
} while (! enet_list_empty (& peer -> sentUnreliableCommands));
|
||||
|
||||
if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER &&
|
||||
enet_list_empty (& peer -> outgoingCommands) &&
|
||||
enet_list_empty (& peer -> sentReliableCommands))
|
||||
enet_peer_disconnect (peer, peer -> eventData);
|
||||
}
|
||||
|
||||
static ENetProtocolCommand
|
||||
@@ -206,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 &&
|
||||
@@ -219,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;
|
||||
@@ -298,7 +309,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
|
||||
}
|
||||
else
|
||||
if (currentPeer -> state != ENET_PEER_STATE_CONNECTING &&
|
||||
enet_address_equal (& currentPeer -> address, & host -> receivedAddress))
|
||||
enet_address_equal (& currentPeer -> address, & host -> receivedPeerAddress))
|
||||
{
|
||||
if (currentPeer -> connectID == command -> connect.connectID)
|
||||
return NULL;
|
||||
@@ -318,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);
|
||||
@@ -613,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;
|
||||
@@ -731,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;
|
||||
@@ -841,42 +853,53 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
|
||||
if (ENET_TIME_LESS (host -> serviceTime, receivedSentTime))
|
||||
return 0;
|
||||
|
||||
peer -> lastReceiveTime = host -> serviceTime;
|
||||
peer -> earliestTimeout = 0;
|
||||
|
||||
roundTripTime = ENET_TIME_DIFFERENCE (host -> serviceTime, receivedSentTime);
|
||||
roundTripTime = ENET_MAX (roundTripTime, 1);
|
||||
|
||||
enet_peer_throttle (peer, roundTripTime);
|
||||
|
||||
peer -> roundTripTimeVariance -= peer -> roundTripTimeVariance / 4;
|
||||
|
||||
if (roundTripTime >= peer -> roundTripTime)
|
||||
if (peer -> lastReceiveTime > 0)
|
||||
{
|
||||
peer -> roundTripTime += (roundTripTime - peer -> roundTripTime) / 8;
|
||||
peer -> roundTripTimeVariance += (roundTripTime - peer -> roundTripTime) / 4;
|
||||
enet_peer_throttle (peer, roundTripTime);
|
||||
|
||||
peer -> roundTripTimeVariance -= (peer -> roundTripTimeVariance + 3) / 4;
|
||||
|
||||
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
|
||||
{
|
||||
peer -> roundTripTime -= (peer -> roundTripTime - roundTripTime) / 8;
|
||||
peer -> roundTripTimeVariance += (peer -> roundTripTime - roundTripTime) / 4;
|
||||
peer -> roundTripTime = roundTripTime;
|
||||
peer -> roundTripTimeVariance = (roundTripTime + 1) / 2;
|
||||
}
|
||||
|
||||
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 = peer -> highestRoundTripTimeVariance;
|
||||
peer -> lastRoundTripTimeVariance = ENET_MAX (peer -> highestRoundTripTimeVariance, 1);
|
||||
peer -> lowestRoundTripTime = peer -> roundTripTime;
|
||||
peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance;
|
||||
peer -> packetThrottleEpoch = host -> serviceTime;
|
||||
}
|
||||
|
||||
peer -> lastReceiveTime = ENET_MAX (host -> serviceTime, 1);
|
||||
peer -> earliestTimeout = 0;
|
||||
|
||||
receivedReliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedReliableSequenceNumber);
|
||||
|
||||
commandNumber = enet_protocol_remove_sent_reliable_command (peer, receivedReliableSequenceNumber, command -> header.channelID);
|
||||
@@ -898,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;
|
||||
@@ -1051,7 +1073,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
|
||||
|
||||
if (peer != NULL)
|
||||
{
|
||||
memcpy(& peer -> address, & host -> receivedAddress, sizeof (host -> receivedAddress));
|
||||
memcpy(& peer -> address, & host -> receivedPeerAddress, sizeof (host -> receivedPeerAddress));
|
||||
memcpy(& peer -> localAddress, & host -> receivedLocalAddress, sizeof (host -> receivedLocalAddress));
|
||||
peer -> incomingDataTotal += host -> receivedDataLength;
|
||||
}
|
||||
|
||||
@@ -1202,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);
|
||||
|
||||
@@ -1249,7 +1273,7 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1305,107 +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_peer_disconnect (peer, peer -> eventData);
|
||||
}
|
||||
|
||||
static int
|
||||
enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * event)
|
||||
{
|
||||
@@ -1413,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))
|
||||
{
|
||||
@@ -1444,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));
|
||||
|
||||
@@ -1460,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)] ||
|
||||
@@ -1529,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;
|
||||
|
||||
@@ -1567,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;
|
||||
|
||||
@@ -1580,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;
|
||||
}
|
||||
|
||||
@@ -1623,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;
|
||||
@@ -1648,21 +1627,11 @@ 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 / 4;
|
||||
|
||||
if (packetLoss >= currentPeer -> packetLoss)
|
||||
{
|
||||
currentPeer -> packetLoss += (packetLoss - currentPeer -> packetLoss) / 8;
|
||||
currentPeer -> packetLossVariance += (packetLoss - currentPeer -> packetLoss) / 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentPeer -> packetLoss -= (currentPeer -> packetLoss - packetLoss) / 8;
|
||||
currentPeer -> packetLossVariance += (currentPeer -> packetLoss - packetLoss) / 4;
|
||||
}
|
||||
currentPeer -> packetLossVariance = (currentPeer -> packetLossVariance * 3 + ENET_DIFFERENCE (packetLoss, currentPeer -> packetLoss)) / 4;
|
||||
currentPeer -> packetLoss = (currentPeer -> packetLoss * 7 + packetLoss) / 8;
|
||||
|
||||
currentPeer -> packetLossEpoch = host -> serviceTime;
|
||||
currentPeer -> packetsSent = 0;
|
||||
@@ -1724,7 +1693,7 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
|
||||
enet_socket_set_option (host -> socket, ENET_SOCKOPT_QOS, 0);
|
||||
}
|
||||
|
||||
sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount);
|
||||
sentLength = enet_socket_send (host -> socket, & currentPeer -> address, & currentPeer -> localAddress, host -> buffers, host -> bufferCount);
|
||||
|
||||
enet_protocol_remove_sent_unreliable_commands (currentPeer);
|
||||
|
||||
|
||||
@@ -4,11 +4,20 @@
|
||||
*/
|
||||
#ifndef _WIN32
|
||||
|
||||
// Required for IPV6_PKTINFO with Darwin headers
|
||||
#ifndef __APPLE_USE_RFC_3542
|
||||
#define __APPLE_USE_RFC_3542 1
|
||||
#endif
|
||||
|
||||
// Required for in6_pktinfo with glibc headers
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
@@ -20,8 +29,8 @@
|
||||
#include "enet/enet.h"
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#ifdef HAS_POLL
|
||||
#undef HAS_POLL
|
||||
#ifndef HAS_POLL
|
||||
#define HAS_POLL 1
|
||||
#endif
|
||||
#ifndef HAS_FCNTL
|
||||
#define HAS_FCNTL 1
|
||||
@@ -72,10 +81,41 @@
|
||||
#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
|
||||
@@ -87,10 +127,10 @@
|
||||
#endif
|
||||
|
||||
#ifdef HAS_POLL
|
||||
#include <sys/poll.h>
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAS_SOCKLEN_T
|
||||
#if !defined(HAS_SOCKLEN_T) && !defined(__socklen_t_defined)
|
||||
typedef int socklen_t;
|
||||
#endif
|
||||
|
||||
@@ -161,6 +201,7 @@ enet_address_equal (ENetAddress * address1, ENetAddress * address2)
|
||||
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;
|
||||
@@ -169,6 +210,7 @@ enet_address_equal (ENetAddress * address1, ENetAddress * address2)
|
||||
return sin6a -> sin6_port == sin6b -> sin6_port &&
|
||||
! memcmp (& sin6a -> sin6_addr, & sin6b -> sin6_addr, sizeof (sin6a -> sin6_addr));
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
{
|
||||
return 0;
|
||||
@@ -185,12 +227,14 @@ enet_address_set_port (ENetAddress * address, enet_uint16 port)
|
||||
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;
|
||||
@@ -264,7 +308,37 @@ enet_socket_listen (ENetSocket socket, int backlog)
|
||||
ENetSocket
|
||||
enet_socket_create (int af, ENetSocketType type)
|
||||
{
|
||||
return socket (af, 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
|
||||
@@ -297,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;
|
||||
@@ -314,6 +389,7 @@ 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));
|
||||
@@ -412,7 +488,8 @@ 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)
|
||||
{
|
||||
@@ -450,24 +527,65 @@ enet_socket_send (ENetSocket socket,
|
||||
}
|
||||
|
||||
sentLength = sendto (socket, sendBuffer, sendLength, MSG_NOSIGNAL,
|
||||
(struct sockaddr *) & address -> address, address -> addressLength);
|
||||
(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)
|
||||
{
|
||||
msgHdr.msg_name = (void*) & address -> address;
|
||||
msgHdr.msg_namelen = address -> addressLength;
|
||||
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
|
||||
|
||||
@@ -484,7 +602,8 @@ enet_socket_send (ENetSocket socket,
|
||||
|
||||
int
|
||||
enet_socket_receive (ENetSocket socket,
|
||||
ENetAddress * address,
|
||||
ENetAddress * peerAddress,
|
||||
ENetAddress * localAddress,
|
||||
ENetBuffer * buffers,
|
||||
size_t bufferCount)
|
||||
{
|
||||
@@ -495,7 +614,7 @@ enet_socket_receive (ENetSocket socket,
|
||||
|
||||
address -> addressLength = sizeof (address -> address);
|
||||
recvLength = recvfrom (socket, buffers[0].data, buffers[0].dataLength, MSG_NOSIGNAL,
|
||||
(struct sockaddr *) & address -> address, & address -> addressLength);
|
||||
(struct sockaddr *) & peerAddress -> address, & peerAddress -> addressLength);
|
||||
|
||||
if (recvLength == -1)
|
||||
{
|
||||
@@ -508,17 +627,20 @@ enet_socket_receive (ENetSocket socket,
|
||||
return recvLength;
|
||||
#else
|
||||
struct msghdr msgHdr;
|
||||
char controlBufData[1024];
|
||||
|
||||
memset (& msgHdr, 0, sizeof (struct msghdr));
|
||||
|
||||
if (address != NULL)
|
||||
if (peerAddress != NULL)
|
||||
{
|
||||
msgHdr.msg_name = & address -> address;
|
||||
msgHdr.msg_namelen = sizeof (address -> address);
|
||||
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);
|
||||
|
||||
@@ -529,15 +651,44 @@ enet_socket_receive (ENetSocket socket,
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (address != NULL)
|
||||
address -> addressLength = msgHdr.msg_namelen;
|
||||
|
||||
#ifdef HAS_MSGHDR_FLAGS
|
||||
if (msgHdr.msg_flags & MSG_TRUNC)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
// Retrieve the local address that this traffic was received on
|
||||
// to ensure we respond from the correct address/interface.
|
||||
if (localAddress != NULL) {
|
||||
for (struct cmsghdr *chdr = CMSG_FIRSTHDR(&msgHdr); chdr != NULL; chdr = CMSG_NXTHDR(&msgHdr, chdr)) {
|
||||
#ifdef IP_PKTINFO
|
||||
if (chdr->cmsg_level == IPPROTO_IP && chdr->cmsg_type == IP_PKTINFO) {
|
||||
struct sockaddr_in *localAddr = (struct sockaddr_in*)&localAddress->address;
|
||||
|
||||
localAddr->sin_family = AF_INET;
|
||||
localAddr->sin_addr = ((struct in_pktinfo*)CMSG_DATA(chdr))->ipi_addr;
|
||||
|
||||
localAddress->addressLength = sizeof(*localAddr);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef IPV6_PKTINFO
|
||||
if (chdr->cmsg_level == IPPROTO_IPV6 && chdr->cmsg_type == IPV6_PKTINFO) {
|
||||
struct sockaddr_in6 *localAddr = (struct sockaddr_in6*)&localAddress->address;
|
||||
|
||||
localAddr->sin6_family = AF_INET6;
|
||||
localAddr->sin6_addr = ((struct in6_pktinfo*)CMSG_DATA(chdr))->ipi6_addr;
|
||||
|
||||
localAddress->addressLength = sizeof(*localAddr);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (peerAddress != NULL)
|
||||
peerAddress -> addressLength = msgHdr.msg_namelen;
|
||||
|
||||
return recvLength;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -7,14 +7,32 @@
|
||||
#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)
|
||||
{
|
||||
@@ -34,6 +52,22 @@ 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;
|
||||
}
|
||||
|
||||
@@ -45,10 +79,19 @@ enet_deinitialize (void)
|
||||
|
||||
if (qosHandle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
QOSCloseHandle(qosHandle);
|
||||
pfnQOSCloseHandle(qosHandle);
|
||||
qosHandle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (QwaveLibraryHandle != NULL) {
|
||||
pfnQOSCreateHandle = NULL;
|
||||
pfnQOSCloseHandle = NULL;
|
||||
pfnQOSAddSocketToFlow = NULL;
|
||||
|
||||
FreeLibrary(QwaveLibraryHandle);
|
||||
QwaveLibraryHandle = NULL;
|
||||
}
|
||||
|
||||
timeEndPeriod (1);
|
||||
|
||||
WSACleanup ();
|
||||
@@ -191,7 +234,46 @@ enet_socket_listen (ENetSocket socket, int backlog)
|
||||
ENetSocket
|
||||
enet_socket_create (int af, ENetSocketType type)
|
||||
{
|
||||
return socket (af, 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
|
||||
@@ -239,14 +321,14 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
|
||||
|
||||
qosVersion.MajorVersion = 1;
|
||||
qosVersion.MinorVersion = 0;
|
||||
if (!QOSCreateHandle(&qosVersion, &qosHandle))
|
||||
if (pfnQOSCreateHandle == NULL || !pfnQOSCreateHandle(&qosVersion, &qosHandle))
|
||||
{
|
||||
qosHandle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
else if (qosHandle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
QOSCloseHandle(qosHandle);
|
||||
pfnQOSCloseHandle(qosHandle);
|
||||
qosHandle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
@@ -325,35 +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)
|
||||
{
|
||||
DWORD sentLength;
|
||||
WSAMSG msg = { 0 };
|
||||
char controlBufData[1024];
|
||||
|
||||
if (!qosAddedFlow && qosHandle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
qosFlowId = 0; // Must be initialized to 0
|
||||
QOSAddSocketToFlow(qosHandle,
|
||||
socket,
|
||||
(struct sockaddr *)&address->address,
|
||||
QOSTrafficTypeControl,
|
||||
QOS_NON_ADAPTIVE_FLOW,
|
||||
&qosFlowId);
|
||||
pfnQOSAddSocketToFlow(qosHandle,
|
||||
socket,
|
||||
(struct sockaddr *)&peerAddress->address,
|
||||
QOSTrafficTypeControl,
|
||||
QOS_NON_ADAPTIVE_FLOW,
|
||||
&qosFlowId);
|
||||
|
||||
// Even if we failed, don't try again
|
||||
qosAddedFlow = TRUE;
|
||||
}
|
||||
|
||||
if (WSASendTo (socket,
|
||||
(LPWSABUF) buffers,
|
||||
(DWORD) bufferCount,
|
||||
& sentLength,
|
||||
0,
|
||||
address != NULL ? (struct sockaddr *) & address -> address : NULL,
|
||||
address != NULL ? address -> addressLength : 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;
|
||||
@@ -366,25 +489,27 @@ enet_socket_send (ENetSocket socket,
|
||||
|
||||
int
|
||||
enet_socket_receive (ENetSocket socket,
|
||||
ENetAddress * address,
|
||||
ENetAddress * peerAddress,
|
||||
ENetAddress * localAddress,
|
||||
ENetBuffer * buffers,
|
||||
size_t bufferCount)
|
||||
{
|
||||
DWORD flags = 0,
|
||||
recvLength;
|
||||
|
||||
if (address != NULL)
|
||||
address -> addressLength = sizeof (address -> address);
|
||||
DWORD recvLength;
|
||||
WSAMSG msg = { 0 };
|
||||
char controlBufData[1024];
|
||||
|
||||
if (WSARecvFrom (socket,
|
||||
(LPWSABUF) buffers,
|
||||
(DWORD) bufferCount,
|
||||
& recvLength,
|
||||
& flags,
|
||||
address != NULL ? (struct sockaddr *) & address -> address : NULL,
|
||||
address != NULL ? & address -> addressLength : 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 ())
|
||||
{
|
||||
@@ -396,9 +521,35 @@ enet_socket_receive (ENetSocket socket,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flags & MSG_PARTIAL)
|
||||
if (msg.dwFlags & MSG_PARTIAL)
|
||||
return -1;
|
||||
|
||||
// Retrieve the local address that this traffic was received on
|
||||
// to ensure we respond from the correct address/interface.
|
||||
if (localAddress != NULL) {
|
||||
for (PWSACMSGHDR chdr = WSA_CMSG_FIRSTHDR(&msg); chdr != NULL; chdr = WSA_CMSG_NXTHDR(&msg, chdr)) {
|
||||
if (chdr->cmsg_level == IPPROTO_IP && chdr->cmsg_type == IP_PKTINFO) {
|
||||
PSOCKADDR_IN localAddr = (PSOCKADDR_IN)&localAddress->address;
|
||||
|
||||
localAddr->sin_family = AF_INET;
|
||||
localAddr->sin_addr = ((IN_PKTINFO*)WSA_CMSG_DATA(chdr))->ipi_addr;
|
||||
|
||||
localAddress->addressLength = sizeof(*localAddr);
|
||||
break;
|
||||
}
|
||||
else if (chdr->cmsg_level == IPPROTO_IPV6 && chdr->cmsg_type == IPV6_PKTINFO) {
|
||||
PSOCKADDR_IN6 localAddr = (PSOCKADDR_IN6)&localAddress->address;
|
||||
|
||||
localAddr->sin6_family = AF_INET6;
|
||||
localAddr->sin6_addr = ((IN6_PKTINFO*)WSA_CMSG_DATA(chdr))->ipi6_addr;
|
||||
|
||||
localAddress->addressLength = sizeof(*localAddr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
peerAddress->addressLength = msg.namelen;
|
||||
return (int) recvLength;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user