Compare commits
126 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0eb84dcca8 | |||
| c7353c0593 | |||
| 78cc9b4b03 | |||
| dea6fb5414 | |||
| 115a10baa1 | |||
| 44c85e1627 | |||
| badcd6c01d | |||
| b757dc7c28 | |||
| bbf71856bb | |||
| 76125b56b3 | |||
| 9e1cfe280a | |||
| 0032f5e750 | |||
| d3a323fc8b | |||
| 04e2759067 | |||
| a754295f42 | |||
| a92d6960a6 | |||
| a339bf51c8 | |||
| 061ce30163 | |||
| c76572875a | |||
| f6e67b1138 | |||
| acf813c4aa | |||
| c6bb0e5011 | |||
| 43218d4de2 | |||
| 89a7ebd63d | |||
| c07aa74c60 | |||
| bbfe93c248 | |||
| 880e41f3ab | |||
| 50ab7907d8 | |||
| 68ffba7d45 | |||
| bbed828aae | |||
| bdda0eecc5 | |||
| 2a85cd6445 | |||
| 4979b629c2 | |||
| 33c726ab73 | |||
| 441a6e9c5b | |||
| 7914bc74a9 | |||
| fc123218d3 | |||
| ea4607a90d | |||
| 8ae0e85298 | |||
| 07a40ef0f9 | |||
| eb89a34d66 | |||
| 4faa11a243 | |||
| 47e42dbf42 | |||
| 153e10f953 | |||
| e790647a57 | |||
| be7cefa39c | |||
| 9dde91d003 | |||
| ca18dfb8f8 | |||
| d7e5470cf7 | |||
| bb788ea48b | |||
| 4e69c700d6 | |||
| 311360dbdd | |||
| b06d154579 | |||
| 6800acd9c7 | |||
| 4f8e9bdc4c | |||
| 3340d1cf85 | |||
| bd0115c907 | |||
| 987cd0650f | |||
| 92ef50a080 | |||
| 498b9e3571 | |||
| 4cde9cc3dc | |||
| 74cea7abf5 | |||
| 8d69c5abe4 | |||
| ad5bf95397 | |||
| ab9d471cec | |||
| c20ca391e2 | |||
| 9fda19e54b | |||
| 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 |
@@ -0,0 +1,21 @@
|
|||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
name: CMake
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
cmake-build:
|
||||||
|
name: CMake ${{ matrix.os }} ${{ matrix.build_type }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: ["ubuntu-latest", "windows-latest", "macos-latest"]
|
||||||
|
build_type: ["Debug", "Release"]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Configure CMake
|
||||||
|
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: cmake --build ${{github.workspace}}/build --config ${{ matrix.build_type }}
|
||||||
+63
-11
@@ -1,7 +1,9 @@
|
|||||||
cmake_minimum_required(VERSION 2.6)
|
cmake_minimum_required(VERSION 2.8.12...3.20)
|
||||||
|
|
||||||
project(enet)
|
project(enet)
|
||||||
|
|
||||||
|
option(ENET_NO_INSTALL "Disable installation of headers and libraries" OFF)
|
||||||
|
|
||||||
# The "configure" step.
|
# The "configure" step.
|
||||||
include(CheckFunctionExists)
|
include(CheckFunctionExists)
|
||||||
include(CheckStructHasMember)
|
include(CheckStructHasMember)
|
||||||
@@ -19,6 +21,15 @@ 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")
|
set(CMAKE_EXTRA_INCLUDE_FILES "sys/types.h" "sys/socket.h")
|
||||||
check_type_size("socklen_t" HAS_SOCKLEN_T BUILTIN_TYPES_ONLY)
|
check_type_size("socklen_t" HAS_SOCKLEN_T BUILTIN_TYPES_ONLY)
|
||||||
unset(CMAKE_EXTRA_INCLUDE_FILES)
|
unset(CMAKE_EXTRA_INCLUDE_FILES)
|
||||||
|
set(CMAKE_EXTRA_INCLUDE_FILES "winsock2.h;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)
|
if(HAS_FCNTL)
|
||||||
add_definitions(-DHAS_FCNTL=1)
|
add_definitions(-DHAS_FCNTL=1)
|
||||||
@@ -53,17 +64,58 @@ endif()
|
|||||||
if(HAS_SOCKLEN_T)
|
if(HAS_SOCKLEN_T)
|
||||||
add_definitions(-DHAS_SOCKLEN_T=1)
|
add_definitions(-DHAS_SOCKLEN_T=1)
|
||||||
endif()
|
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)
|
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
|
add_library(enet STATIC
|
||||||
callbacks.c
|
${INCLUDE_FILES}
|
||||||
compress.c
|
${SOURCE_FILES}
|
||||||
host.c
|
)
|
||||||
list.c
|
target_include_directories(enet SYSTEM PUBLIC include)
|
||||||
packet.c
|
|
||||||
peer.c
|
if (MINGW)
|
||||||
protocol.c
|
target_link_libraries(enet winmm ws2_32)
|
||||||
unix.c
|
endif()
|
||||||
win32.c
|
|
||||||
)
|
if(NOT ENET_NO_INSTALL)
|
||||||
|
install(TARGETS enet
|
||||||
|
RUNTIME DESTINATION bin
|
||||||
|
ARCHIVE DESTINATION lib/static
|
||||||
|
LIBRARY DESTINATION lib)
|
||||||
|
|
||||||
|
install(DIRECTORY include/
|
||||||
|
DESTINATION include)
|
||||||
|
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
|
* use getaddrinfo and getnameinfo where available
|
||||||
|
* miscellaneous cleanups
|
||||||
|
|
||||||
ENet 1.3.13 (April 30, 2015):
|
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
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# 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
|
# 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
|
# 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:
|
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
|
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
|
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
|
# 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
|
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||||
|
|
||||||
ACLOCAL_AMFLAGS = -Im4
|
ACLOCAL_AMFLAGS = -Im4
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Please visit the ENet homepage at http://enet.bespin.org for installation
|
Please visit the ENet homepage at http://sauerbraten.org/enet/ for installation
|
||||||
and usage instructions.
|
and usage instructions.
|
||||||
|
|
||||||
If you obtained this package from github, the quick description on how to build
|
If you obtained this package from github, the quick description on how to build
|
||||||
|
|||||||
+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])
|
AC_CONFIG_SRCDIR([include/enet/enet.h])
|
||||||
AM_INIT_AUTOMAKE([foreign])
|
AM_INIT_AUTOMAKE([foreign])
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
@page License License
|
@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
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
||||||
|
|||||||
+2
-2
@@ -36,7 +36,7 @@ portable, and easily embeddable.
|
|||||||
You can retrieve the source to ENet by downloading it in either .tar.gz form
|
You can retrieve the source to ENet by downloading it in either .tar.gz form
|
||||||
or accessing the github distribution directly.
|
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>.
|
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>.
|
You can find the most recent ENet source at <a class="el" href="https://github.com/lsalzman/enet">the github repository</a>.
|
||||||
@@ -53,7 +53,7 @@ The <a class="el" href="http://lists.cubik.org/mailman/listinfo/enet-discuss">en
|
|||||||
/**
|
/**
|
||||||
@page IRCChannel IRC Channel
|
@page IRCChannel IRC Channel
|
||||||
|
|
||||||
Join the \#enet channel on the <a class="el" href="http://freenode.net">freenode IRC network (irc.freenode.net)</a> for real-time discussion about the ENet library.
|
Join the \#enet channel on the <a class="el" href="https://libera.chat">Libera Chat IRC network (irc.libera.chat)</a> for real-time discussion about the ENet library.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -102,8 +102,8 @@ may be simultaneously open.
|
|||||||
client = enet_host_create (NULL /* create a client host */,
|
client = enet_host_create (NULL /* create a client host */,
|
||||||
1 /* only allow 1 outgoing connection */,
|
1 /* only allow 1 outgoing connection */,
|
||||||
2 /* allow up 2 channels to be used, 0 and 1 */,
|
2 /* allow up 2 channels to be used, 0 and 1 */,
|
||||||
57600 / 8 /* 56K modem with 56 Kbps downstream bandwidth */,
|
0 /* assume any amount of incoming bandwidth */,
|
||||||
14400 / 8 /* 56K modem with 14 Kbps upstream bandwidth */);
|
0 /* assume any amount of outgoing bandwidth */);
|
||||||
|
|
||||||
if (client == NULL)
|
if (client == NULL)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -61,10 +61,11 @@ enet_host_create (int addressFamily, const ENetAddress * address, size_t peerCou
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
host -> wildcardBind = address && enet_address_wildcard (address);
|
||||||
|
|
||||||
enet_socket_set_option (host -> socket, ENET_SOCKOPT_NONBLOCK, 1);
|
enet_socket_set_option (host -> socket, ENET_SOCKOPT_NONBLOCK, 1);
|
||||||
enet_socket_set_option (host -> socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
|
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_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)
|
if (address != NULL && enet_socket_get_address (host -> socket, & host -> address) < 0)
|
||||||
host -> address = * address;
|
host -> address = * address;
|
||||||
@@ -88,7 +89,8 @@ enet_host_create (int addressFamily, const ENetAddress * address, size_t peerCou
|
|||||||
host -> commandCount = 0;
|
host -> commandCount = 0;
|
||||||
host -> bufferCount = 0;
|
host -> bufferCount = 0;
|
||||||
host -> checksum = NULL;
|
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 -> receivedData = NULL;
|
||||||
host -> receivedDataLength = 0;
|
host -> receivedDataLength = 0;
|
||||||
|
|
||||||
@@ -96,6 +98,7 @@ enet_host_create (int addressFamily, const ENetAddress * address, size_t peerCou
|
|||||||
host -> totalSentPackets = 0;
|
host -> totalSentPackets = 0;
|
||||||
host -> totalReceivedData = 0;
|
host -> totalReceivedData = 0;
|
||||||
host -> totalReceivedPackets = 0;
|
host -> totalReceivedPackets = 0;
|
||||||
|
host -> totalQueued = 0;
|
||||||
|
|
||||||
host -> connectedPeers = 0;
|
host -> connectedPeers = 0;
|
||||||
host -> bandwidthLimitedPeers = 0;
|
host -> bandwidthLimitedPeers = 0;
|
||||||
@@ -123,9 +126,8 @@ enet_host_create (int addressFamily, const ENetAddress * address, size_t peerCou
|
|||||||
|
|
||||||
enet_list_clear (& currentPeer -> acknowledgements);
|
enet_list_clear (& currentPeer -> acknowledgements);
|
||||||
enet_list_clear (& currentPeer -> sentReliableCommands);
|
enet_list_clear (& currentPeer -> sentReliableCommands);
|
||||||
enet_list_clear (& currentPeer -> sentUnreliableCommands);
|
enet_list_clear (& currentPeer -> outgoingCommands);
|
||||||
enet_list_clear (& currentPeer -> outgoingReliableCommands);
|
enet_list_clear (& currentPeer -> outgoingSendReliableCommands);
|
||||||
enet_list_clear (& currentPeer -> outgoingUnreliableCommands);
|
|
||||||
enet_list_clear (& currentPeer -> dispatchedCommands);
|
enet_list_clear (& currentPeer -> dispatchedCommands);
|
||||||
|
|
||||||
enet_peer_reset (currentPeer);
|
enet_peer_reset (currentPeer);
|
||||||
@@ -161,6 +163,16 @@ enet_host_destroy (ENetHost * host)
|
|||||||
enet_free (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.
|
/** Initiates a connection to a foreign host.
|
||||||
@param host host seeking the connection
|
@param host host seeking the connection
|
||||||
@param address destination for the connection
|
@param address destination for the connection
|
||||||
@@ -200,7 +212,8 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC
|
|||||||
currentPeer -> channelCount = channelCount;
|
currentPeer -> channelCount = channelCount;
|
||||||
currentPeer -> state = ENET_PEER_STATE_CONNECTING;
|
currentPeer -> state = ENET_PEER_STATE_CONNECTING;
|
||||||
currentPeer -> address = * address;
|
currentPeer -> address = * address;
|
||||||
currentPeer -> connectID = ++ host -> randomSeed;
|
currentPeer -> connectID = enet_host_random (host);
|
||||||
|
currentPeer -> mtu = host -> mtu;
|
||||||
|
|
||||||
if (host -> outgoingBandwidth == 0)
|
if (host -> outgoingBandwidth == 0)
|
||||||
currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
|
currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
|
||||||
|
|||||||
+44
-21
@@ -12,7 +12,7 @@ extern "C"
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) && !defined(NXDK)
|
||||||
#include "enet/win32.h"
|
#include "enet/win32.h"
|
||||||
#else
|
#else
|
||||||
#include "enet/unix.h"
|
#include "enet/unix.h"
|
||||||
@@ -25,7 +25,7 @@ extern "C"
|
|||||||
|
|
||||||
#define ENET_VERSION_MAJOR 1
|
#define ENET_VERSION_MAJOR 1
|
||||||
#define ENET_VERSION_MINOR 3
|
#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_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch))
|
||||||
#define ENET_VERSION_GET_MAJOR(version) (((version)>>16)&0xFF)
|
#define ENET_VERSION_GET_MAJOR(version) (((version)>>16)&0xFF)
|
||||||
#define ENET_VERSION_GET_MINOR(version) (((version)>>8)&0xFF)
|
#define ENET_VERSION_GET_MINOR(version) (((version)>>8)&0xFF)
|
||||||
@@ -55,14 +55,16 @@ typedef enum _ENetSocketWait
|
|||||||
typedef enum _ENetSocketOption
|
typedef enum _ENetSocketOption
|
||||||
{
|
{
|
||||||
ENET_SOCKOPT_NONBLOCK = 1,
|
ENET_SOCKOPT_NONBLOCK = 1,
|
||||||
ENET_SOCKOPT_RCVBUF,
|
ENET_SOCKOPT_BROADCAST = 2,
|
||||||
ENET_SOCKOPT_SNDBUF,
|
ENET_SOCKOPT_RCVBUF = 3,
|
||||||
ENET_SOCKOPT_REUSEADDR,
|
ENET_SOCKOPT_SNDBUF = 4,
|
||||||
ENET_SOCKOPT_RCVTIMEO,
|
ENET_SOCKOPT_REUSEADDR = 5,
|
||||||
ENET_SOCKOPT_SNDTIMEO,
|
ENET_SOCKOPT_RCVTIMEO = 6,
|
||||||
ENET_SOCKOPT_ERROR,
|
ENET_SOCKOPT_SNDTIMEO = 7,
|
||||||
ENET_SOCKOPT_NODELAY,
|
ENET_SOCKOPT_ERROR = 8,
|
||||||
ENET_SOCKOPT_QOS,
|
ENET_SOCKOPT_NODELAY = 9,
|
||||||
|
ENET_SOCKOPT_TTL = 10,
|
||||||
|
ENET_SOCKOPT_QOS = 11,
|
||||||
} ENetSocketOption;
|
} ENetSocketOption;
|
||||||
|
|
||||||
typedef enum _ENetSocketShutdown
|
typedef enum _ENetSocketShutdown
|
||||||
@@ -158,7 +160,7 @@ typedef struct _ENetOutgoingCommand
|
|||||||
enet_uint16 unreliableSequenceNumber;
|
enet_uint16 unreliableSequenceNumber;
|
||||||
enet_uint32 sentTime;
|
enet_uint32 sentTime;
|
||||||
enet_uint32 roundTripTimeout;
|
enet_uint32 roundTripTimeout;
|
||||||
enet_uint32 roundTripTimeoutLimit;
|
enet_uint32 queueTime;
|
||||||
enet_uint32 fragmentOffset;
|
enet_uint32 fragmentOffset;
|
||||||
enet_uint16 fragmentLength;
|
enet_uint16 fragmentLength;
|
||||||
enet_uint16 sendAttempts;
|
enet_uint16 sendAttempts;
|
||||||
@@ -198,8 +200,17 @@ typedef enum _ENetPeerState
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
#if defined(__WIIU__)
|
||||||
|
ENET_HOST_RECEIVE_BUFFER_SIZE = 256 * 1024,
|
||||||
|
// Send buffer size is limited since it cannot use userbuffers
|
||||||
|
ENET_HOST_SEND_BUFFER_SIZE = 0x10000 - 1,
|
||||||
|
#elif defined(__3DS__)
|
||||||
|
ENET_HOST_RECEIVE_BUFFER_SIZE = 0x20000,
|
||||||
|
ENET_HOST_SEND_BUFFER_SIZE = 0x20000,
|
||||||
|
#else
|
||||||
ENET_HOST_RECEIVE_BUFFER_SIZE = 256 * 1024,
|
ENET_HOST_RECEIVE_BUFFER_SIZE = 256 * 1024,
|
||||||
ENET_HOST_SEND_BUFFER_SIZE = 256 * 1024,
|
ENET_HOST_SEND_BUFFER_SIZE = 256 * 1024,
|
||||||
|
#endif
|
||||||
ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL = 1000,
|
ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL = 1000,
|
||||||
ENET_HOST_DEFAULT_MTU = 900,
|
ENET_HOST_DEFAULT_MTU = 900,
|
||||||
ENET_HOST_DEFAULT_MAXIMUM_PACKET_SIZE = 32 * 1024 * 1024,
|
ENET_HOST_DEFAULT_MAXIMUM_PACKET_SIZE = 32 * 1024 * 1024,
|
||||||
@@ -239,6 +250,12 @@ typedef struct _ENetChannel
|
|||||||
ENetList incomingUnreliableCommands;
|
ENetList incomingUnreliableCommands;
|
||||||
} ENetChannel;
|
} ENetChannel;
|
||||||
|
|
||||||
|
typedef enum _ENetPeerFlag
|
||||||
|
{
|
||||||
|
ENET_PEER_FLAG_NEEDS_DISPATCH = (1 << 0),
|
||||||
|
ENET_PEER_FLAG_CONTINUE_SENDING = (1 << 1)
|
||||||
|
} ENetPeerFlag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An ENet peer which data packets may be sent or received from.
|
* An ENet peer which data packets may be sent or received from.
|
||||||
*
|
*
|
||||||
@@ -254,6 +271,7 @@ typedef struct _ENetPeer
|
|||||||
enet_uint8 outgoingSessionID;
|
enet_uint8 outgoingSessionID;
|
||||||
enet_uint8 incomingSessionID;
|
enet_uint8 incomingSessionID;
|
||||||
ENetAddress address; /**< Internet address of the peer */
|
ENetAddress address; /**< Internet address of the peer */
|
||||||
|
ENetAddress localAddress;
|
||||||
void * data; /**< Application private data, may be freely modified */
|
void * data; /**< Application private data, may be freely modified */
|
||||||
ENetPeerState state;
|
ENetPeerState state;
|
||||||
ENetChannel * channels;
|
ENetChannel * channels;
|
||||||
@@ -296,11 +314,11 @@ typedef struct _ENetPeer
|
|||||||
enet_uint16 outgoingReliableSequenceNumber;
|
enet_uint16 outgoingReliableSequenceNumber;
|
||||||
ENetList acknowledgements;
|
ENetList acknowledgements;
|
||||||
ENetList sentReliableCommands;
|
ENetList sentReliableCommands;
|
||||||
ENetList sentUnreliableCommands;
|
ENetList outgoingSendReliableCommands;
|
||||||
ENetList outgoingReliableCommands;
|
ENetList outgoingCommands;
|
||||||
ENetList outgoingUnreliableCommands;
|
|
||||||
ENetList dispatchedCommands;
|
ENetList dispatchedCommands;
|
||||||
int needsDispatch;
|
enet_uint16 flags;
|
||||||
|
enet_uint16 reserved;
|
||||||
enet_uint16 incomingUnsequencedGroup;
|
enet_uint16 incomingUnsequencedGroup;
|
||||||
enet_uint16 outgoingUnsequencedGroup;
|
enet_uint16 outgoingUnsequencedGroup;
|
||||||
enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32];
|
enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32];
|
||||||
@@ -346,6 +364,7 @@ typedef int (ENET_CALLBACK * ENetInterceptCallback) (struct _ENetHost * host, st
|
|||||||
typedef struct _ENetHost
|
typedef struct _ENetHost
|
||||||
{
|
{
|
||||||
ENetSocket socket;
|
ENetSocket socket;
|
||||||
|
int wildcardBind;
|
||||||
ENetAddress address; /**< Internet address of the host */
|
ENetAddress address; /**< Internet address of the host */
|
||||||
enet_uint32 incomingBandwidth; /**< downstream bandwidth of the host */
|
enet_uint32 incomingBandwidth; /**< downstream bandwidth of the host */
|
||||||
enet_uint32 outgoingBandwidth; /**< upstream bandwidth of the host */
|
enet_uint32 outgoingBandwidth; /**< upstream bandwidth of the host */
|
||||||
@@ -358,7 +377,7 @@ typedef struct _ENetHost
|
|||||||
size_t channelLimit; /**< maximum number of channels allowed for connected peers */
|
size_t channelLimit; /**< maximum number of channels allowed for connected peers */
|
||||||
enet_uint32 serviceTime;
|
enet_uint32 serviceTime;
|
||||||
ENetList dispatchQueue;
|
ENetList dispatchQueue;
|
||||||
int continueSending;
|
enet_uint32 totalQueued;
|
||||||
size_t packetSize;
|
size_t packetSize;
|
||||||
enet_uint16 headerFlags;
|
enet_uint16 headerFlags;
|
||||||
ENetProtocol commands [ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS];
|
ENetProtocol commands [ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS];
|
||||||
@@ -368,7 +387,8 @@ typedef struct _ENetHost
|
|||||||
ENetChecksumCallback checksum; /**< callback the user can set to enable packet checksums for this host */
|
ENetChecksumCallback checksum; /**< callback the user can set to enable packet checksums for this host */
|
||||||
ENetCompressor compressor;
|
ENetCompressor compressor;
|
||||||
enet_uint8 packetData [2][ENET_PROTOCOL_MAXIMUM_MTU];
|
enet_uint8 packetData [2][ENET_PROTOCOL_MAXIMUM_MTU];
|
||||||
ENetAddress receivedAddress;
|
ENetAddress receivedPeerAddress;
|
||||||
|
ENetAddress receivedLocalAddress;
|
||||||
enet_uint8 * receivedData;
|
enet_uint8 * receivedData;
|
||||||
size_t receivedDataLength;
|
size_t receivedDataLength;
|
||||||
enet_uint32 totalSentData; /**< total data sent, user should reset to 0 as needed to prevent overflow */
|
enet_uint32 totalSentData; /**< total data sent, user should reset to 0 as needed to prevent overflow */
|
||||||
@@ -483,8 +503,8 @@ ENET_API int enet_socket_get_address (ENetSocket, ENetAddress *);
|
|||||||
ENET_API int enet_socket_listen (ENetSocket, int);
|
ENET_API int enet_socket_listen (ENetSocket, int);
|
||||||
ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *);
|
ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *);
|
||||||
ENET_API int enet_socket_connect (ENetSocket, const 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_send (ENetSocket, const ENetAddress *, const ENetAddress *, const ENetBuffer *, size_t);
|
||||||
ENET_API int enet_socket_receive (ENetSocket, ENetAddress *, 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_wait (ENetSocket, enet_uint32 *, enet_uint32);
|
||||||
ENET_API int enet_socket_set_option (ENetSocket, ENetSocketOption, int);
|
ENET_API int enet_socket_set_option (ENetSocket, ENetSocketOption, int);
|
||||||
ENET_API int enet_socket_get_option (ENetSocket, ENetSocketOption, int *);
|
ENET_API int enet_socket_get_option (ENetSocket, ENetSocketOption, int *);
|
||||||
@@ -508,6 +528,7 @@ ENET_API int enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSock
|
|||||||
ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName);
|
ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName);
|
||||||
ENET_API int enet_address_set_address (ENetAddress * address, struct sockaddr * addr, socklen_t addrlen);
|
ENET_API int enet_address_set_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_set_port (ENetAddress * address, enet_uint16 port);
|
||||||
|
ENET_API int enet_address_wildcard (const ENetAddress * address);
|
||||||
ENET_API int enet_address_equal (ENetAddress * address1, ENetAddress * address2);
|
ENET_API int enet_address_equal (ENetAddress * address1, ENetAddress * address2);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
@@ -529,6 +550,7 @@ ENET_API void enet_host_channel_limit (ENetHost *, size_t);
|
|||||||
ENET_API void enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32);
|
ENET_API void enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32);
|
||||||
extern void enet_host_bandwidth_throttle (ENetHost *);
|
extern void enet_host_bandwidth_throttle (ENetHost *);
|
||||||
extern enet_uint32 enet_host_random_seed (void);
|
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 int enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *);
|
||||||
ENET_API ENetPacket * enet_peer_receive (ENetPeer *, enet_uint8 * channelID);
|
ENET_API ENetPacket * enet_peer_receive (ENetPeer *, enet_uint8 * channelID);
|
||||||
@@ -542,12 +564,13 @@ ENET_API void enet_peer_disconnect_later (ENetPeer *, enet_uint32
|
|||||||
ENET_API void enet_peer_throttle_configure (ENetPeer *, enet_uint32, enet_uint32, enet_uint32);
|
ENET_API void enet_peer_throttle_configure (ENetPeer *, enet_uint32, enet_uint32, enet_uint32);
|
||||||
extern int enet_peer_throttle (ENetPeer *, enet_uint32);
|
extern int enet_peer_throttle (ENetPeer *, enet_uint32);
|
||||||
extern void enet_peer_reset_queues (ENetPeer *);
|
extern void enet_peer_reset_queues (ENetPeer *);
|
||||||
|
extern int enet_peer_has_outgoing_commands (ENetPeer *);
|
||||||
extern void enet_peer_setup_outgoing_command (ENetPeer *, ENetOutgoingCommand *);
|
extern void enet_peer_setup_outgoing_command (ENetPeer *, ENetOutgoingCommand *);
|
||||||
extern ENetOutgoingCommand * enet_peer_queue_outgoing_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32, enet_uint16);
|
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 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 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_unreliable_commands (ENetPeer *, ENetChannel *, ENetIncomingCommand *);
|
||||||
extern void enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *);
|
extern void enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *, ENetIncomingCommand *);
|
||||||
extern void enet_peer_on_connect (ENetPeer *);
|
extern void enet_peer_on_connect (ENetPeer *);
|
||||||
extern void enet_peer_on_disconnect (ENetPeer *);
|
extern void enet_peer_on_disconnect (ENetPeer *);
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,11 @@
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
ENET_PROTOCOL_MINIMUM_MTU = 576,
|
ENET_PROTOCOL_MINIMUM_MTU = 576,
|
||||||
|
#if defined(__WIIU__) || defined(__3DS__)
|
||||||
|
ENET_PROTOCOL_MAXIMUM_MTU = 1400,
|
||||||
|
#else
|
||||||
ENET_PROTOCOL_MAXIMUM_MTU = 4096,
|
ENET_PROTOCOL_MAXIMUM_MTU = 4096,
|
||||||
|
#endif
|
||||||
ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS = 32,
|
ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS = 32,
|
||||||
ENET_PROTOCOL_MINIMUM_WINDOW_SIZE = 4096,
|
ENET_PROTOCOL_MINIMUM_WINDOW_SIZE = 4096,
|
||||||
ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 65536,
|
ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 65536,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#define ENET_MAX(x, y) ((x) > (y) ? (x) : (y))
|
#define ENET_MAX(x, y) ((x) > (y) ? (x) : (y))
|
||||||
#define ENET_MIN(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__ */
|
#endif /* __ENET_UTILITY_H__ */
|
||||||
|
|
||||||
|
|||||||
@@ -11,12 +11,14 @@
|
|||||||
#pragma warning (disable: 4244) // 64bit to 32bit int
|
#pragma warning (disable: 4244) // 64bit to 32bit int
|
||||||
#pragma warning (disable: 4018) // signed/unsigned mismatch
|
#pragma warning (disable: 4018) // signed/unsigned mismatch
|
||||||
#pragma warning (disable: 4146) // unary minus operator applied to unsigned type
|
#pragma warning (disable: 4146) // unary minus operator applied to unsigned type
|
||||||
|
#define _CRT_SECURE_NO_DEPRECATE
|
||||||
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <Ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
|
|
||||||
typedef SOCKET ENetSocket;
|
typedef SOCKET ENetSocket;
|
||||||
|
|
||||||
|
|||||||
@@ -98,54 +98,47 @@ enet_packet_resize (ENetPacket * packet, size_t dataLength)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int initializedCRC32 = 0;
|
static const enet_uint32 crcTable [256] =
|
||||||
static enet_uint32 crcTable [256];
|
|
||||||
|
|
||||||
static enet_uint32
|
|
||||||
reflect_crc (int val, int bits)
|
|
||||||
{
|
{
|
||||||
int result = 0, bit;
|
0, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
|
||||||
|
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
|
||||||
for (bit = 0; bit < bits; bit ++)
|
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
|
||||||
{
|
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
|
||||||
if(val & 1) result |= 1 << (bits - 1 - bit);
|
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
|
||||||
val >>= 1;
|
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
|
||||||
}
|
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
|
||||||
|
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
|
||||||
return result;
|
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
|
||||||
}
|
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
|
||||||
|
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
|
||||||
static void
|
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
|
||||||
initialize_crc32 (void)
|
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
|
||||||
{
|
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
|
||||||
int byte;
|
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
|
||||||
|
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
|
||||||
for (byte = 0; byte < 256; ++ byte)
|
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
|
||||||
{
|
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
|
||||||
enet_uint32 crc = reflect_crc (byte, 8) << 24;
|
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
|
||||||
int offset;
|
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
|
||||||
|
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
|
||||||
for(offset = 0; offset < 8; ++ offset)
|
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
|
||||||
{
|
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
|
||||||
if (crc & 0x80000000)
|
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
|
||||||
crc = (crc << 1) ^ 0x04c11db7;
|
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x5005713,
|
||||||
else
|
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0xBDBDF21,
|
||||||
crc <<= 1;
|
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
|
||||||
}
|
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
|
||||||
|
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
|
||||||
crcTable [byte] = reflect_crc (crc, 32);
|
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
|
||||||
}
|
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
|
||||||
|
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
|
||||||
initializedCRC32 = 1;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
enet_uint32
|
enet_uint32
|
||||||
enet_crc32 (const ENetBuffer * buffers, size_t bufferCount)
|
enet_crc32 (const ENetBuffer * buffers, size_t bufferCount)
|
||||||
{
|
{
|
||||||
enet_uint32 crc = 0xFFFFFFFF;
|
enet_uint32 crc = 0xFFFFFFFF;
|
||||||
|
|
||||||
if (! initializedCRC32) initialize_crc32 ();
|
|
||||||
|
|
||||||
while (bufferCount -- > 0)
|
while (bufferCount -- > 0)
|
||||||
{
|
{
|
||||||
const enet_uint8 * data = (const enet_uint8 *) buffers -> data,
|
const enet_uint8 * data = (const enet_uint8 *) buffers -> data,
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt)
|
|||||||
peer -> packetThrottle = peer -> packetThrottleLimit;
|
peer -> packetThrottle = peer -> packetThrottleLimit;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (rtt < peer -> lastRoundTripTime)
|
if (rtt <= peer -> lastRoundTripTime)
|
||||||
{
|
{
|
||||||
peer -> packetThrottle += peer -> packetThrottleAcceleration;
|
peer -> packetThrottle += peer -> packetThrottleAcceleration;
|
||||||
|
|
||||||
@@ -90,6 +90,13 @@ enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Queues a packet to be sent.
|
/** Queues a packet to be sent.
|
||||||
|
|
||||||
|
On success, ENet will assume ownership of the packet, and so enet_packet_destroy
|
||||||
|
should not be called on it thereafter. On failure, the caller still must destroy
|
||||||
|
the packet on its own as ENet has not queued the packet. The caller can also
|
||||||
|
check the packet's referenceCount field after sending to check if ENet queued
|
||||||
|
the packet and thus incremented the referenceCount.
|
||||||
|
|
||||||
@param peer destination for the packet
|
@param peer destination for the packet
|
||||||
@param channelID channel on which to send
|
@param channelID channel on which to send
|
||||||
@param packet packet to send
|
@param packet packet to send
|
||||||
@@ -99,7 +106,7 @@ enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt)
|
|||||||
int
|
int
|
||||||
enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
|
enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
|
||||||
{
|
{
|
||||||
ENetChannel * channel = & peer -> channels [channelID];
|
ENetChannel * channel;
|
||||||
ENetProtocol command;
|
ENetProtocol command;
|
||||||
size_t fragmentLength;
|
size_t fragmentLength;
|
||||||
|
|
||||||
@@ -108,6 +115,7 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
|
|||||||
packet -> dataLength > peer -> host -> maximumPacketSize)
|
packet -> dataLength > peer -> host -> maximumPacketSize)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
channel = & peer -> channels [channelID];
|
||||||
fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment);
|
fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment);
|
||||||
if (peer -> host -> checksum != NULL)
|
if (peer -> host -> checksum != NULL)
|
||||||
fragmentLength -= sizeof(enet_uint32);
|
fragmentLength -= sizeof(enet_uint32);
|
||||||
@@ -268,7 +276,7 @@ enet_peer_reset_outgoing_commands (ENetList * queue)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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;
|
ENetListIterator currentCommand;
|
||||||
|
|
||||||
@@ -278,6 +286,9 @@ enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startComm
|
|||||||
|
|
||||||
currentCommand = enet_list_next (currentCommand);
|
currentCommand = enet_list_next (currentCommand);
|
||||||
|
|
||||||
|
if (incomingCommand == excludeCommand)
|
||||||
|
continue;
|
||||||
|
|
||||||
enet_list_remove (& incomingCommand -> incomingCommandList);
|
enet_list_remove (& incomingCommand -> incomingCommandList);
|
||||||
|
|
||||||
if (incomingCommand -> packet != NULL)
|
if (incomingCommand -> packet != NULL)
|
||||||
@@ -298,7 +309,7 @@ enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startComm
|
|||||||
static void
|
static void
|
||||||
enet_peer_reset_incoming_commands (ENetList * queue)
|
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
|
void
|
||||||
@@ -306,20 +317,19 @@ enet_peer_reset_queues (ENetPeer * peer)
|
|||||||
{
|
{
|
||||||
ENetChannel * channel;
|
ENetChannel * channel;
|
||||||
|
|
||||||
if (peer -> needsDispatch)
|
if (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH)
|
||||||
{
|
{
|
||||||
enet_list_remove (& peer -> dispatchList);
|
enet_list_remove (& peer -> dispatchList);
|
||||||
|
|
||||||
peer -> needsDispatch = 0;
|
peer -> flags &= ~ ENET_PEER_FLAG_NEEDS_DISPATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (! enet_list_empty (& peer -> acknowledgements))
|
while (! enet_list_empty (& peer -> acknowledgements))
|
||||||
enet_free (enet_list_remove (enet_list_begin (& peer -> acknowledgements)));
|
enet_free (enet_list_remove (enet_list_begin (& peer -> acknowledgements)));
|
||||||
|
|
||||||
enet_peer_reset_outgoing_commands (& peer -> sentReliableCommands);
|
enet_peer_reset_outgoing_commands (& peer -> sentReliableCommands);
|
||||||
enet_peer_reset_outgoing_commands (& peer -> sentUnreliableCommands);
|
enet_peer_reset_outgoing_commands (& peer -> outgoingCommands);
|
||||||
enet_peer_reset_outgoing_commands (& peer -> outgoingReliableCommands);
|
enet_peer_reset_outgoing_commands (& peer -> outgoingSendReliableCommands);
|
||||||
enet_peer_reset_outgoing_commands (& peer -> outgoingUnreliableCommands);
|
|
||||||
enet_peer_reset_incoming_commands (& peer -> dispatchedCommands);
|
enet_peer_reset_incoming_commands (& peer -> dispatchedCommands);
|
||||||
|
|
||||||
if (peer -> channels != NULL && peer -> channelCount > 0)
|
if (peer -> channels != NULL && peer -> channelCount > 0)
|
||||||
@@ -418,6 +428,7 @@ enet_peer_reset (ENetPeer * peer)
|
|||||||
peer -> outgoingUnsequencedGroup = 0;
|
peer -> outgoingUnsequencedGroup = 0;
|
||||||
peer -> eventData = 0;
|
peer -> eventData = 0;
|
||||||
peer -> totalWaitingData = 0;
|
peer -> totalWaitingData = 0;
|
||||||
|
peer -> flags = 0;
|
||||||
|
|
||||||
memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow));
|
memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow));
|
||||||
|
|
||||||
@@ -560,6 +571,17 @@ enet_peer_disconnect (ENetPeer * peer, enet_uint32 data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_peer_has_outgoing_commands (ENetPeer * peer)
|
||||||
|
{
|
||||||
|
if (enet_list_empty (& peer -> outgoingCommands) &&
|
||||||
|
enet_list_empty (& peer -> outgoingSendReliableCommands) &&
|
||||||
|
enet_list_empty (& peer -> sentReliableCommands))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/** Request a disconnection from a peer, but only after all queued outgoing packets are sent.
|
/** Request a disconnection from a peer, but only after all queued outgoing packets are sent.
|
||||||
@param peer peer to request a disconnection
|
@param peer peer to request a disconnection
|
||||||
@param data data describing the disconnection
|
@param data data describing the disconnection
|
||||||
@@ -570,9 +592,7 @@ void
|
|||||||
enet_peer_disconnect_later (ENetPeer * peer, enet_uint32 data)
|
enet_peer_disconnect_later (ENetPeer * peer, enet_uint32 data)
|
||||||
{
|
{
|
||||||
if ((peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) &&
|
if ((peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) &&
|
||||||
! (enet_list_empty (& peer -> outgoingReliableCommands) &&
|
enet_peer_has_outgoing_commands (peer))
|
||||||
enet_list_empty (& peer -> outgoingUnreliableCommands) &&
|
|
||||||
enet_list_empty (& peer -> sentReliableCommands)))
|
|
||||||
{
|
{
|
||||||
peer -> state = ENET_PEER_STATE_DISCONNECT_LATER;
|
peer -> state = ENET_PEER_STATE_DISCONNECT_LATER;
|
||||||
peer -> eventData = data;
|
peer -> eventData = data;
|
||||||
@@ -616,8 +636,6 @@ enet_peer_queue_acknowledgement (ENetPeer * peer, const ENetProtocol * command,
|
|||||||
void
|
void
|
||||||
enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoingCommand)
|
enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoingCommand)
|
||||||
{
|
{
|
||||||
ENetChannel * channel = & peer -> channels [outgoingCommand -> command.header.channelID];
|
|
||||||
|
|
||||||
peer -> outgoingDataTotal += enet_protocol_command_size (outgoingCommand -> command.header.command) + outgoingCommand -> fragmentLength;
|
peer -> outgoingDataTotal += enet_protocol_command_size (outgoingCommand -> command.header.command) + outgoingCommand -> fragmentLength;
|
||||||
|
|
||||||
if (outgoingCommand -> command.header.channelID == 0xFF)
|
if (outgoingCommand -> command.header.channelID == 0xFF)
|
||||||
@@ -628,36 +646,40 @@ enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoin
|
|||||||
outgoingCommand -> unreliableSequenceNumber = 0;
|
outgoingCommand -> unreliableSequenceNumber = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
|
|
||||||
{
|
{
|
||||||
++ channel -> outgoingReliableSequenceNumber;
|
ENetChannel * channel = & peer -> channels [outgoingCommand -> command.header.channelID];
|
||||||
channel -> outgoingUnreliableSequenceNumber = 0;
|
|
||||||
|
|
||||||
outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber;
|
if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
|
||||||
outgoingCommand -> unreliableSequenceNumber = 0;
|
{
|
||||||
}
|
++ channel -> outgoingReliableSequenceNumber;
|
||||||
else
|
channel -> outgoingUnreliableSequenceNumber = 0;
|
||||||
if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED)
|
|
||||||
{
|
|
||||||
++ peer -> outgoingUnsequencedGroup;
|
|
||||||
|
|
||||||
outgoingCommand -> reliableSequenceNumber = 0;
|
outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber;
|
||||||
outgoingCommand -> unreliableSequenceNumber = 0;
|
outgoingCommand -> unreliableSequenceNumber = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED)
|
||||||
if (outgoingCommand -> fragmentOffset == 0)
|
{
|
||||||
++ channel -> outgoingUnreliableSequenceNumber;
|
++ peer -> outgoingUnsequencedGroup;
|
||||||
|
|
||||||
outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber;
|
outgoingCommand -> reliableSequenceNumber = 0;
|
||||||
outgoingCommand -> unreliableSequenceNumber = channel -> outgoingUnreliableSequenceNumber;
|
outgoingCommand -> unreliableSequenceNumber = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (outgoingCommand -> fragmentOffset == 0)
|
||||||
|
++ channel -> outgoingUnreliableSequenceNumber;
|
||||||
|
|
||||||
|
outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber;
|
||||||
|
outgoingCommand -> unreliableSequenceNumber = channel -> outgoingUnreliableSequenceNumber;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outgoingCommand -> sendAttempts = 0;
|
outgoingCommand -> sendAttempts = 0;
|
||||||
outgoingCommand -> sentTime = 0;
|
outgoingCommand -> sentTime = 0;
|
||||||
outgoingCommand -> roundTripTimeout = 0;
|
outgoingCommand -> roundTripTimeout = 0;
|
||||||
outgoingCommand -> roundTripTimeoutLimit = 0;
|
|
||||||
outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_16 (outgoingCommand -> reliableSequenceNumber);
|
outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_16 (outgoingCommand -> reliableSequenceNumber);
|
||||||
|
outgoingCommand -> queueTime = ++ peer -> host -> totalQueued;
|
||||||
|
|
||||||
switch (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK)
|
switch (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK)
|
||||||
{
|
{
|
||||||
@@ -673,10 +695,11 @@ enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoin
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
|
if ((outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) != 0 &&
|
||||||
enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand);
|
outgoingCommand -> packet != NULL)
|
||||||
|
enet_list_insert (enet_list_end (& peer -> outgoingSendReliableCommands), outgoingCommand);
|
||||||
else
|
else
|
||||||
enet_list_insert (enet_list_end (& peer -> outgoingUnreliableCommands), outgoingCommand);
|
enet_list_insert (enet_list_end (& peer -> outgoingCommands), outgoingCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
ENetOutgoingCommand *
|
ENetOutgoingCommand *
|
||||||
@@ -699,7 +722,7 @@ enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
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;
|
ENetListIterator droppedCommand, startCommand, currentCommand;
|
||||||
|
|
||||||
@@ -724,11 +747,11 @@ enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel *
|
|||||||
{
|
{
|
||||||
enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand));
|
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);
|
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
|
||||||
|
|
||||||
peer -> needsDispatch = 1;
|
peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
droppedCommand = currentCommand;
|
droppedCommand = currentCommand;
|
||||||
@@ -752,11 +775,11 @@ enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel *
|
|||||||
{
|
{
|
||||||
enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand));
|
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);
|
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
|
||||||
|
|
||||||
peer -> needsDispatch = 1;
|
peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -768,21 +791,21 @@ enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel *
|
|||||||
{
|
{
|
||||||
enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand));
|
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);
|
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
|
||||||
|
|
||||||
peer -> needsDispatch = 1;
|
peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
droppedCommand = currentCommand;
|
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
|
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;
|
ENetListIterator currentCommand;
|
||||||
|
|
||||||
@@ -809,15 +832,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));
|
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);
|
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))
|
if (! enet_list_empty (& channel -> incomingUnreliableCommands))
|
||||||
enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
|
enet_peer_dispatch_incoming_unreliable_commands (peer, channel, queuedCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
ENetIncomingCommand *
|
ENetIncomingCommand *
|
||||||
@@ -975,11 +998,11 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
|
|||||||
{
|
{
|
||||||
case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
|
case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
|
||||||
case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
|
case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
|
||||||
enet_peer_dispatch_incoming_reliable_commands (peer, channel);
|
enet_peer_dispatch_incoming_reliable_commands (peer, channel, incomingCommand);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
|
enet_peer_dispatch_incoming_unreliable_commands (peer, channel, incomingCommand);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+297
-249
@@ -9,7 +9,7 @@
|
|||||||
#include "enet/time.h"
|
#include "enet/time.h"
|
||||||
#include "enet/enet.h"
|
#include "enet/enet.h"
|
||||||
|
|
||||||
static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] =
|
static const size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] =
|
||||||
{
|
{
|
||||||
0,
|
0,
|
||||||
sizeof (ENetProtocolAcknowledge),
|
sizeof (ENetProtocolAcknowledge),
|
||||||
@@ -48,11 +48,11 @@ enet_protocol_dispatch_state (ENetHost * host, ENetPeer * peer, ENetPeerState st
|
|||||||
{
|
{
|
||||||
enet_protocol_change_state (host, peer, state);
|
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);
|
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));
|
ENetPeer * peer = (ENetPeer *) enet_list_remove (enet_list_begin (& host -> dispatchQueue));
|
||||||
|
|
||||||
peer -> needsDispatch = 0;
|
peer -> flags &= ~ ENET_PEER_FLAG_NEEDS_DISPATCH;
|
||||||
|
|
||||||
switch (peer -> state)
|
switch (peer -> state)
|
||||||
{
|
{
|
||||||
@@ -101,7 +101,7 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
|
|||||||
|
|
||||||
if (! enet_list_empty (& peer -> dispatchedCommands))
|
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);
|
enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList);
|
||||||
}
|
}
|
||||||
@@ -159,13 +159,16 @@ enet_protocol_notify_disconnect (ENetHost * host, ENetPeer * peer, ENetEvent * e
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer)
|
enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer, ENetList * sentUnreliableCommands)
|
||||||
{
|
{
|
||||||
ENetOutgoingCommand * outgoingCommand;
|
ENetOutgoingCommand * outgoingCommand;
|
||||||
|
|
||||||
while (! enet_list_empty (& peer -> sentUnreliableCommands))
|
if (enet_list_empty (sentUnreliableCommands))
|
||||||
|
return;
|
||||||
|
|
||||||
|
do
|
||||||
{
|
{
|
||||||
outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentUnreliableCommands);
|
outgoingCommand = (ENetOutgoingCommand *) enet_list_front (sentUnreliableCommands);
|
||||||
|
|
||||||
enet_list_remove (& outgoingCommand -> outgoingCommandList);
|
enet_list_remove (& outgoingCommand -> outgoingCommandList);
|
||||||
|
|
||||||
@@ -182,7 +185,36 @@ enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
enet_free (outgoingCommand);
|
enet_free (outgoingCommand);
|
||||||
|
} while (! enet_list_empty (sentUnreliableCommands));
|
||||||
|
|
||||||
|
if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER &&
|
||||||
|
! enet_peer_has_outgoing_commands (peer))
|
||||||
|
enet_peer_disconnect (peer, peer -> eventData);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ENetOutgoingCommand *
|
||||||
|
enet_protocol_find_sent_reliable_command (ENetList * list, enet_uint16 reliableSequenceNumber, enet_uint8 channelID)
|
||||||
|
{
|
||||||
|
ENetListIterator currentCommand;
|
||||||
|
|
||||||
|
for (currentCommand = enet_list_begin (list);
|
||||||
|
currentCommand != enet_list_end (list);
|
||||||
|
currentCommand = enet_list_next (currentCommand))
|
||||||
|
{
|
||||||
|
ENetOutgoingCommand * outgoingCommand = (ENetOutgoingCommand *) currentCommand;
|
||||||
|
|
||||||
|
if (! (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (outgoingCommand -> sendAttempts < 1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber &&
|
||||||
|
outgoingCommand -> command.header.channelID == channelID)
|
||||||
|
return outgoingCommand;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ENetProtocolCommand
|
static ENetProtocolCommand
|
||||||
@@ -206,21 +238,9 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl
|
|||||||
|
|
||||||
if (currentCommand == enet_list_end (& peer -> sentReliableCommands))
|
if (currentCommand == enet_list_end (& peer -> sentReliableCommands))
|
||||||
{
|
{
|
||||||
for (currentCommand = enet_list_begin (& peer -> outgoingReliableCommands);
|
outgoingCommand = enet_protocol_find_sent_reliable_command (& peer -> outgoingCommands, reliableSequenceNumber, channelID);
|
||||||
currentCommand != enet_list_end (& peer -> outgoingReliableCommands);
|
if (outgoingCommand == NULL)
|
||||||
currentCommand = enet_list_next (currentCommand))
|
outgoingCommand = enet_protocol_find_sent_reliable_command (& peer -> outgoingSendReliableCommands, reliableSequenceNumber, channelID);
|
||||||
{
|
|
||||||
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
|
|
||||||
|
|
||||||
if (outgoingCommand -> sendAttempts < 1) return ENET_PROTOCOL_COMMAND_NONE;
|
|
||||||
|
|
||||||
if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber &&
|
|
||||||
outgoingCommand -> command.header.channelID == channelID)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentCommand == enet_list_end (& peer -> outgoingReliableCommands))
|
|
||||||
return ENET_PROTOCOL_COMMAND_NONE;
|
|
||||||
|
|
||||||
wasSent = 0;
|
wasSent = 0;
|
||||||
}
|
}
|
||||||
@@ -298,7 +318,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (currentPeer -> state != ENET_PEER_STATE_CONNECTING &&
|
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)
|
if (currentPeer -> connectID == command -> connect.connectID)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -318,7 +338,9 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
|
|||||||
peer -> channelCount = channelCount;
|
peer -> channelCount = channelCount;
|
||||||
peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT;
|
peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT;
|
||||||
peer -> connectID = command -> connect.connectID;
|
peer -> connectID = command -> connect.connectID;
|
||||||
peer -> address = host -> receivedAddress;
|
peer -> address = host -> receivedPeerAddress;
|
||||||
|
peer -> localAddress = host -> receivedLocalAddress;
|
||||||
|
peer -> mtu = host -> mtu;
|
||||||
peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID);
|
peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID);
|
||||||
peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth);
|
peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth);
|
||||||
peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.outgoingBandwidth);
|
peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.outgoingBandwidth);
|
||||||
@@ -363,7 +385,8 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
|
|||||||
if (mtu > ENET_PROTOCOL_MAXIMUM_MTU)
|
if (mtu > ENET_PROTOCOL_MAXIMUM_MTU)
|
||||||
mtu = ENET_PROTOCOL_MAXIMUM_MTU;
|
mtu = ENET_PROTOCOL_MAXIMUM_MTU;
|
||||||
|
|
||||||
peer -> mtu = mtu;
|
if (mtu < peer -> mtu)
|
||||||
|
peer -> mtu = mtu;
|
||||||
|
|
||||||
if (host -> outgoingBandwidth == 0 &&
|
if (host -> outgoingBandwidth == 0 &&
|
||||||
peer -> incomingBandwidth == 0)
|
peer -> incomingBandwidth == 0)
|
||||||
@@ -530,7 +553,8 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
|
|||||||
|
|
||||||
fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength);
|
fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength);
|
||||||
* currentData += fragmentLength;
|
* currentData += fragmentLength;
|
||||||
if (fragmentLength > host -> maximumPacketSize ||
|
if (fragmentLength <= 0 ||
|
||||||
|
fragmentLength > host -> maximumPacketSize ||
|
||||||
* currentData < host -> receivedData ||
|
* currentData < host -> receivedData ||
|
||||||
* currentData > & host -> receivedData [host -> receivedDataLength])
|
* currentData > & host -> receivedData [host -> receivedDataLength])
|
||||||
return -1;
|
return -1;
|
||||||
@@ -554,6 +578,7 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
|
|||||||
if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT ||
|
if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT ||
|
||||||
fragmentNumber >= fragmentCount ||
|
fragmentNumber >= fragmentCount ||
|
||||||
totalLength > host -> maximumPacketSize ||
|
totalLength > host -> maximumPacketSize ||
|
||||||
|
totalLength < fragmentCount ||
|
||||||
fragmentOffset >= totalLength ||
|
fragmentOffset >= totalLength ||
|
||||||
fragmentLength > totalLength - fragmentOffset)
|
fragmentLength > totalLength - fragmentOffset)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -613,7 +638,7 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
|
|||||||
fragmentLength);
|
fragmentLength);
|
||||||
|
|
||||||
if (startCommand -> fragmentsRemaining <= 0)
|
if (startCommand -> fragmentsRemaining <= 0)
|
||||||
enet_peer_dispatch_incoming_reliable_commands (peer, channel);
|
enet_peer_dispatch_incoming_reliable_commands (peer, channel, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -731,7 +756,7 @@ enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer,
|
|||||||
fragmentLength);
|
fragmentLength);
|
||||||
|
|
||||||
if (startCommand -> fragmentsRemaining <= 0)
|
if (startCommand -> fragmentsRemaining <= 0)
|
||||||
enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
|
enet_peer_dispatch_incoming_unreliable_commands (peer, channel, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -841,24 +866,32 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
|
|||||||
if (ENET_TIME_LESS (host -> serviceTime, receivedSentTime))
|
if (ENET_TIME_LESS (host -> serviceTime, receivedSentTime))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
peer -> lastReceiveTime = host -> serviceTime;
|
|
||||||
peer -> earliestTimeout = 0;
|
|
||||||
|
|
||||||
roundTripTime = ENET_TIME_DIFFERENCE (host -> serviceTime, receivedSentTime);
|
roundTripTime = ENET_TIME_DIFFERENCE (host -> serviceTime, receivedSentTime);
|
||||||
|
roundTripTime = ENET_MAX (roundTripTime, 1);
|
||||||
|
|
||||||
enet_peer_throttle (peer, roundTripTime);
|
if (peer -> lastReceiveTime > 0)
|
||||||
|
|
||||||
peer -> roundTripTimeVariance -= peer -> roundTripTimeVariance / 4;
|
|
||||||
|
|
||||||
if (roundTripTime >= peer -> roundTripTime)
|
|
||||||
{
|
{
|
||||||
peer -> roundTripTime += (roundTripTime - peer -> roundTripTime) / 8;
|
enet_peer_throttle (peer, roundTripTime);
|
||||||
peer -> roundTripTimeVariance += (roundTripTime - peer -> roundTripTime) / 4;
|
|
||||||
|
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
|
else
|
||||||
{
|
{
|
||||||
peer -> roundTripTime -= (peer -> roundTripTime - roundTripTime) / 8;
|
peer -> roundTripTime = roundTripTime;
|
||||||
peer -> roundTripTimeVariance += (peer -> roundTripTime - roundTripTime) / 4;
|
peer -> roundTripTimeVariance = (roundTripTime + 1) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peer -> roundTripTime < peer -> lowestRoundTripTime)
|
if (peer -> roundTripTime < peer -> lowestRoundTripTime)
|
||||||
@@ -871,12 +904,15 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
|
|||||||
ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> packetThrottleEpoch) >= peer -> packetThrottleInterval)
|
ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> packetThrottleEpoch) >= peer -> packetThrottleInterval)
|
||||||
{
|
{
|
||||||
peer -> lastRoundTripTime = peer -> lowestRoundTripTime;
|
peer -> lastRoundTripTime = peer -> lowestRoundTripTime;
|
||||||
peer -> lastRoundTripTimeVariance = peer -> highestRoundTripTimeVariance;
|
peer -> lastRoundTripTimeVariance = ENET_MAX (peer -> highestRoundTripTimeVariance, 1);
|
||||||
peer -> lowestRoundTripTime = peer -> roundTripTime;
|
peer -> lowestRoundTripTime = peer -> roundTripTime;
|
||||||
peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance;
|
peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance;
|
||||||
peer -> packetThrottleEpoch = host -> serviceTime;
|
peer -> packetThrottleEpoch = host -> serviceTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
peer -> lastReceiveTime = ENET_MAX (host -> serviceTime, 1);
|
||||||
|
peer -> earliestTimeout = 0;
|
||||||
|
|
||||||
receivedReliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedReliableSequenceNumber);
|
receivedReliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedReliableSequenceNumber);
|
||||||
|
|
||||||
commandNumber = enet_protocol_remove_sent_reliable_command (peer, receivedReliableSequenceNumber, command -> header.channelID);
|
commandNumber = enet_protocol_remove_sent_reliable_command (peer, receivedReliableSequenceNumber, command -> header.channelID);
|
||||||
@@ -898,9 +934,7 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ENET_PEER_STATE_DISCONNECT_LATER:
|
case ENET_PEER_STATE_DISCONNECT_LATER:
|
||||||
if (enet_list_empty (& peer -> outgoingReliableCommands) &&
|
if (! enet_peer_has_outgoing_commands (peer))
|
||||||
enet_list_empty (& peer -> outgoingUnreliableCommands) &&
|
|
||||||
enet_list_empty (& peer -> sentReliableCommands))
|
|
||||||
enet_peer_disconnect (peer, peer -> eventData);
|
enet_peer_disconnect (peer, peer -> eventData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1051,7 +1085,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
|
|||||||
|
|
||||||
if (peer != NULL)
|
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;
|
peer -> incomingDataTotal += host -> receivedDataLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1202,10 +1237,14 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
|
|||||||
buffer.dataLength = sizeof (host -> packetData [0]);
|
buffer.dataLength = sizeof (host -> packetData [0]);
|
||||||
|
|
||||||
receivedLength = enet_socket_receive (host -> socket,
|
receivedLength = enet_socket_receive (host -> socket,
|
||||||
& host -> receivedAddress,
|
& host -> receivedPeerAddress,
|
||||||
|
& host -> receivedLocalAddress,
|
||||||
& buffer,
|
& buffer,
|
||||||
1);
|
1);
|
||||||
|
|
||||||
|
if (receivedLength == -2)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (receivedLength < 0)
|
if (receivedLength < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -1249,7 +1288,7 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1269,7 +1308,7 @@ enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer)
|
|||||||
buffer >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
|
buffer >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
|
||||||
peer -> mtu - host -> packetSize < sizeof (ENetProtocolAcknowledge))
|
peer -> mtu - host -> packetSize < sizeof (ENetProtocolAcknowledge))
|
||||||
{
|
{
|
||||||
host -> continueSending = 1;
|
peer -> flags |= ENET_PEER_FLAG_CONTINUE_SENDING;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1305,115 +1344,16 @@ enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer)
|
|||||||
host -> bufferCount = buffer - host -> buffers;
|
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
|
static int
|
||||||
enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * event)
|
enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * event)
|
||||||
{
|
{
|
||||||
ENetOutgoingCommand * outgoingCommand;
|
ENetOutgoingCommand * outgoingCommand;
|
||||||
ENetListIterator currentCommand, insertPosition;
|
ENetListIterator currentCommand, insertPosition, insertSendReliablePosition;
|
||||||
|
enet_uint32 roundTripTimeout;
|
||||||
|
|
||||||
currentCommand = enet_list_begin (& peer -> sentReliableCommands);
|
currentCommand = enet_list_begin (& peer -> sentReliableCommands);
|
||||||
insertPosition = enet_list_begin (& peer -> outgoingReliableCommands);
|
insertPosition = enet_list_begin (& peer -> outgoingCommands);
|
||||||
|
insertSendReliablePosition = enet_list_begin (& peer -> outgoingSendReliableCommands);
|
||||||
|
|
||||||
while (currentCommand != enet_list_end (& peer -> sentReliableCommands))
|
while (currentCommand != enet_list_end (& peer -> sentReliableCommands))
|
||||||
{
|
{
|
||||||
@@ -1430,7 +1370,7 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even
|
|||||||
|
|
||||||
if (peer -> earliestTimeout != 0 &&
|
if (peer -> earliestTimeout != 0 &&
|
||||||
(ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMaximum ||
|
(ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMaximum ||
|
||||||
(outgoingCommand -> roundTripTimeout >= outgoingCommand -> roundTripTimeoutLimit &&
|
((1U << (outgoingCommand -> sendAttempts - 1)) >= peer -> timeoutLimit &&
|
||||||
ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMinimum)))
|
ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMinimum)))
|
||||||
{
|
{
|
||||||
enet_protocol_notify_disconnect (host, peer, event);
|
enet_protocol_notify_disconnect (host, peer, event);
|
||||||
@@ -1438,14 +1378,23 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outgoingCommand -> packet != NULL)
|
|
||||||
peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength;
|
|
||||||
|
|
||||||
++ peer -> packetsLost;
|
++ peer -> packetsLost;
|
||||||
|
|
||||||
outgoingCommand -> roundTripTimeout *= 2;
|
roundTripTimeout = peer -> roundTripTime + ENET_MIN (peer -> roundTripTime, 4 * ENET_MAX (1, peer -> roundTripTimeVariance));
|
||||||
|
roundTripTimeout = ENET_MIN (roundTripTimeout, peer->timeoutMaximum / 5);
|
||||||
|
if (outgoingCommand -> sendAttempts < peer -> timeoutLimit)
|
||||||
|
outgoingCommand -> roundTripTimeout = roundTripTimeout * ENET_MAX (1, outgoingCommand -> sendAttempts);
|
||||||
|
else
|
||||||
|
outgoingCommand -> roundTripTimeout = roundTripTimeout * peer -> timeoutLimit;
|
||||||
|
|
||||||
enet_list_insert (insertPosition, enet_list_remove (& outgoingCommand -> outgoingCommandList));
|
if (outgoingCommand -> packet != NULL)
|
||||||
|
{
|
||||||
|
peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength;
|
||||||
|
|
||||||
|
enet_list_insert (insertSendReliablePosition, enet_list_remove (& outgoingCommand -> outgoingCommandList));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
enet_list_insert (insertPosition, enet_list_remove (& outgoingCommand -> outgoingCommandList));
|
||||||
|
|
||||||
if (currentCommand == enet_list_begin (& peer -> sentReliableCommands) &&
|
if (currentCommand == enet_list_begin (& peer -> sentReliableCommands) &&
|
||||||
! enet_list_empty (& peer -> sentReliableCommands))
|
! enet_list_empty (& peer -> sentReliableCommands))
|
||||||
@@ -1460,61 +1409,79 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
|
enet_protocol_check_outgoing_commands (ENetHost * host, ENetPeer * peer, ENetList * sentUnreliableCommands)
|
||||||
{
|
{
|
||||||
ENetProtocol * command = & host -> commands [host -> commandCount];
|
ENetProtocol * command = & host -> commands [host -> commandCount];
|
||||||
ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
|
ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
|
||||||
ENetOutgoingCommand * outgoingCommand;
|
ENetOutgoingCommand * outgoingCommand;
|
||||||
ENetListIterator currentCommand;
|
ENetListIterator currentCommand, currentSendReliableCommand;
|
||||||
ENetChannel *channel;
|
ENetChannel *channel = NULL;
|
||||||
enet_uint16 reliableWindow;
|
enet_uint16 reliableWindow = 0;
|
||||||
size_t commandSize;
|
size_t commandSize;
|
||||||
int windowExceeded = 0, windowWrap = 0, canPing = 1;
|
int windowWrap = 0, canPing = 1;
|
||||||
|
|
||||||
currentCommand = enet_list_begin (& peer -> outgoingReliableCommands);
|
currentCommand = enet_list_begin (& peer -> outgoingCommands);
|
||||||
|
currentSendReliableCommand = enet_list_begin (& peer -> outgoingSendReliableCommands);
|
||||||
|
|
||||||
while (currentCommand != enet_list_end (& peer -> outgoingReliableCommands))
|
for (;;)
|
||||||
{
|
{
|
||||||
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
|
if (currentCommand != enet_list_end (& peer -> outgoingCommands))
|
||||||
|
|
||||||
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 (! windowWrap &&
|
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
|
||||||
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)
|
|
||||||
{
|
|
||||||
currentCommand = enet_list_next (currentCommand);
|
|
||||||
|
|
||||||
continue;
|
if (currentSendReliableCommand != enet_list_end (& peer -> outgoingSendReliableCommands) &&
|
||||||
}
|
ENET_TIME_LESS (((ENetOutgoingCommand *) currentSendReliableCommand) -> queueTime, outgoingCommand -> queueTime))
|
||||||
|
goto useSendReliableCommand;
|
||||||
|
|
||||||
|
currentCommand = enet_list_next (currentCommand);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (outgoingCommand -> packet != NULL)
|
if (currentSendReliableCommand != enet_list_end (& peer -> outgoingSendReliableCommands))
|
||||||
{
|
{
|
||||||
if (! windowExceeded)
|
useSendReliableCommand:
|
||||||
|
outgoingCommand = (ENetOutgoingCommand *) currentSendReliableCommand;
|
||||||
|
currentSendReliableCommand = enet_list_next (currentSendReliableCommand);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
|
||||||
|
{
|
||||||
|
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 (windowWrap)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
if (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;
|
||||||
|
currentSendReliableCommand = enet_list_end (& peer -> outgoingSendReliableCommands);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outgoingCommand -> packet != NULL)
|
||||||
{
|
{
|
||||||
enet_uint32 windowSize = (peer -> packetThrottle * peer -> windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE;
|
enet_uint32 windowSize = (peer -> packetThrottle * peer -> windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE;
|
||||||
|
|
||||||
if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > ENET_MAX (windowSize, peer -> mtu))
|
if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > ENET_MAX (windowSize, peer -> mtu))
|
||||||
windowExceeded = 1;
|
{
|
||||||
}
|
currentSendReliableCommand = enet_list_end (& peer -> outgoingSendReliableCommands);
|
||||||
if (windowExceeded)
|
|
||||||
{
|
|
||||||
currentCommand = enet_list_next (currentCommand);
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
canPing = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
canPing = 0;
|
|
||||||
|
|
||||||
commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK];
|
commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK];
|
||||||
if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
|
if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
|
||||||
buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
|
buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
|
||||||
@@ -1522,40 +1489,84 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
|
|||||||
(outgoingCommand -> packet != NULL &&
|
(outgoingCommand -> packet != NULL &&
|
||||||
(enet_uint16) (peer -> mtu - host -> packetSize) < (enet_uint16) (commandSize + outgoingCommand -> fragmentLength)))
|
(enet_uint16) (peer -> mtu - host -> packetSize) < (enet_uint16) (commandSize + outgoingCommand -> fragmentLength)))
|
||||||
{
|
{
|
||||||
host -> continueSending = 1;
|
peer -> flags |= ENET_PEER_FLAG_CONTINUE_SENDING;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentCommand = enet_list_next (currentCommand);
|
if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
|
||||||
|
|
||||||
if (channel != NULL && outgoingCommand -> sendAttempts < 1)
|
|
||||||
{
|
{
|
||||||
channel -> usedReliableWindows |= 1 << reliableWindow;
|
if (channel != NULL && outgoingCommand -> sendAttempts < 1)
|
||||||
++ channel -> reliableWindows [reliableWindow];
|
{
|
||||||
|
channel -> usedReliableWindows |= 1 << reliableWindow;
|
||||||
|
++ channel -> reliableWindows [reliableWindow];
|
||||||
|
}
|
||||||
|
|
||||||
|
++ outgoingCommand -> sendAttempts;
|
||||||
|
|
||||||
|
if (outgoingCommand -> roundTripTimeout == 0) {
|
||||||
|
outgoingCommand -> roundTripTimeout = peer -> roundTripTime + ENET_MIN (peer -> roundTripTime, 4 * ENET_MAX (1, peer -> roundTripTimeVariance));
|
||||||
|
outgoingCommand -> roundTripTimeout = ENET_MIN (outgoingCommand -> roundTripTimeout, peer->timeoutMaximum / 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
++ outgoingCommand -> sendAttempts;
|
|
||||||
|
|
||||||
if (outgoingCommand -> roundTripTimeout == 0)
|
|
||||||
{
|
{
|
||||||
outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance;
|
if (outgoingCommand -> packet != NULL && outgoingCommand -> fragmentOffset == 0)
|
||||||
outgoingCommand -> roundTripTimeoutLimit = peer -> timeoutLimit * outgoingCommand -> roundTripTimeout;
|
{
|
||||||
|
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 -> 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 (sentUnreliableCommands), outgoingCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
buffer -> data = command;
|
buffer -> data = command;
|
||||||
buffer -> dataLength = commandSize;
|
buffer -> dataLength = commandSize;
|
||||||
|
|
||||||
host -> packetSize += buffer -> dataLength;
|
host -> packetSize += buffer -> dataLength;
|
||||||
host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME;
|
|
||||||
|
|
||||||
* command = outgoingCommand -> command;
|
* command = outgoingCommand -> command;
|
||||||
|
|
||||||
@@ -1567,9 +1578,10 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
|
|||||||
buffer -> dataLength = outgoingCommand -> fragmentLength;
|
buffer -> dataLength = outgoingCommand -> fragmentLength;
|
||||||
|
|
||||||
host -> packetSize += 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;
|
++ peer -> packetsSent;
|
||||||
|
|
||||||
@@ -1580,6 +1592,11 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
|
|||||||
host -> commandCount = command - host -> commands;
|
host -> commandCount = command - host -> commands;
|
||||||
host -> bufferCount = buffer - host -> buffers;
|
host -> bufferCount = buffer - host -> buffers;
|
||||||
|
|
||||||
|
if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER &&
|
||||||
|
! enet_peer_has_outgoing_commands (peer) &&
|
||||||
|
enet_list_empty (sentUnreliableCommands))
|
||||||
|
enet_peer_disconnect (peer, peer -> eventData);
|
||||||
|
|
||||||
return canPing;
|
return canPing;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1588,22 +1605,24 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
|
|||||||
{
|
{
|
||||||
enet_uint8 headerData [sizeof (ENetProtocolHeader) + sizeof (enet_uint32)];
|
enet_uint8 headerData [sizeof (ENetProtocolHeader) + sizeof (enet_uint32)];
|
||||||
ENetProtocolHeader * header = (ENetProtocolHeader *) headerData;
|
ENetProtocolHeader * header = (ENetProtocolHeader *) headerData;
|
||||||
ENetPeer * currentPeer;
|
int sentLength = 0;
|
||||||
int sentLength;
|
|
||||||
size_t shouldCompress = 0;
|
size_t shouldCompress = 0;
|
||||||
|
ENetList sentUnreliableCommands;
|
||||||
|
|
||||||
host -> continueSending = 1;
|
enet_list_clear (& sentUnreliableCommands);
|
||||||
|
|
||||||
while (host -> continueSending)
|
for (int sendPass = 0, continueSending = 0; sendPass <= continueSending; ++ sendPass)
|
||||||
for (host -> continueSending = 0,
|
for (ENetPeer * currentPeer = host -> peers;
|
||||||
currentPeer = host -> peers;
|
|
||||||
currentPeer < & host -> peers [host -> peerCount];
|
currentPeer < & host -> peers [host -> peerCount];
|
||||||
++ currentPeer)
|
++ currentPeer)
|
||||||
{
|
{
|
||||||
if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED ||
|
if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED ||
|
||||||
currentPeer -> state == ENET_PEER_STATE_ZOMBIE)
|
currentPeer -> state == ENET_PEER_STATE_ZOMBIE ||
|
||||||
|
(sendPass > 0 && ! (currentPeer -> flags & ENET_PEER_FLAG_CONTINUE_SENDING)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
currentPeer -> flags &= ~ ENET_PEER_FLAG_CONTINUE_SENDING;
|
||||||
|
|
||||||
host -> headerFlags = 0;
|
host -> headerFlags = 0;
|
||||||
host -> commandCount = 0;
|
host -> commandCount = 0;
|
||||||
host -> bufferCount = 1;
|
host -> bufferCount = 1;
|
||||||
@@ -1620,24 +1639,22 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
|
|||||||
if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE)
|
if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE)
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
continue;
|
goto nextPeer;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((enet_list_empty (& currentPeer -> outgoingReliableCommands) ||
|
if (((enet_list_empty (& currentPeer -> outgoingCommands) &&
|
||||||
enet_protocol_send_reliable_outgoing_commands (host, currentPeer)) &&
|
enet_list_empty (& currentPeer -> outgoingSendReliableCommands)) ||
|
||||||
|
enet_protocol_check_outgoing_commands (host, currentPeer, & sentUnreliableCommands)) &&
|
||||||
enet_list_empty (& currentPeer -> sentReliableCommands) &&
|
enet_list_empty (& currentPeer -> sentReliableCommands) &&
|
||||||
ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= currentPeer -> pingInterval &&
|
ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= currentPeer -> pingInterval &&
|
||||||
currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing))
|
currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing))
|
||||||
{
|
{
|
||||||
enet_peer_ping (currentPeer);
|
enet_peer_ping (currentPeer);
|
||||||
enet_protocol_send_reliable_outgoing_commands (host, currentPeer);
|
enet_protocol_check_outgoing_commands (host, currentPeer, & sentUnreliableCommands);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! enet_list_empty (& currentPeer -> outgoingUnreliableCommands))
|
|
||||||
enet_protocol_send_unreliable_outgoing_commands (host, currentPeer);
|
|
||||||
|
|
||||||
if (host -> commandCount == 0)
|
if (host -> commandCount == 0)
|
||||||
continue;
|
goto nextPeer;
|
||||||
|
|
||||||
if (currentPeer -> packetLossEpoch == 0)
|
if (currentPeer -> packetLossEpoch == 0)
|
||||||
currentPeer -> packetLossEpoch = host -> serviceTime;
|
currentPeer -> packetLossEpoch = host -> serviceTime;
|
||||||
@@ -1648,21 +1665,11 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
|
|||||||
enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent;
|
enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent;
|
||||||
|
|
||||||
#ifdef ENET_DEBUG
|
#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) + enet_list_size (& currentPeer -> outgoingSendReliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
currentPeer -> packetLossVariance -= currentPeer -> packetLossVariance / 4;
|
currentPeer -> packetLossVariance = (currentPeer -> packetLossVariance * 3 + ENET_DIFFERENCE (packetLoss, currentPeer -> packetLoss)) / 4;
|
||||||
|
currentPeer -> packetLoss = (currentPeer -> packetLoss * 7 + packetLoss) / 8;
|
||||||
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 -> packetLossEpoch = host -> serviceTime;
|
currentPeer -> packetLossEpoch = host -> serviceTime;
|
||||||
currentPeer -> packetsSent = 0;
|
currentPeer -> packetsSent = 0;
|
||||||
@@ -1718,26 +1725,61 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
|
|||||||
|
|
||||||
currentPeer -> lastSendTime = host -> serviceTime;
|
currentPeer -> lastSendTime = host -> serviceTime;
|
||||||
|
|
||||||
if (currentPeer -> state == ENET_PEER_STATE_CONNECTING && currentPeer -> packetsLost == 2) {
|
if ((currentPeer -> state == ENET_PEER_STATE_CONNECTING || currentPeer -> state == ENET_PEER_STATE_ACKNOWLEDGING_CONNECT) && currentPeer -> packetsLost == 3) {
|
||||||
// Disable QoS tagging if we don't get a response to 2 connection requests in a row.
|
// Disable QoS tagging if we don't get a response to 3 connection requests/acks in a row.
|
||||||
// Some networks drop QoS tagged packets, so let's try without it.
|
// Some networks drop QoS tagged packets, so let's try without it.
|
||||||
enet_socket_set_option (host -> socket, ENET_SOCKOPT_QOS, 0);
|
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,
|
||||||
|
host -> wildcardBind ? (& currentPeer -> localAddress) : NULL,
|
||||||
|
host -> buffers, host -> bufferCount);
|
||||||
|
|
||||||
enet_protocol_remove_sent_unreliable_commands (currentPeer);
|
enet_protocol_remove_sent_unreliable_commands (currentPeer, & sentUnreliableCommands);
|
||||||
|
|
||||||
if (sentLength < 0)
|
if (sentLength < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
host -> totalSentData += sentLength;
|
host -> totalSentData += sentLength;
|
||||||
host -> totalSentPackets ++;
|
host -> totalSentPackets ++;
|
||||||
|
|
||||||
|
nextPeer:
|
||||||
|
if (currentPeer -> flags & ENET_PEER_FLAG_CONTINUE_SENDING)
|
||||||
|
continueSending = sendPass + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enet_uint32
|
||||||
|
enet_protocol_compute_wait_timeout(ENetHost * host, enet_uint32 timeout)
|
||||||
|
{
|
||||||
|
for (ENetPeer * currentPeer = host -> peers;
|
||||||
|
currentPeer < & host -> peers [host -> peerCount];
|
||||||
|
++ currentPeer)
|
||||||
|
{
|
||||||
|
if (! ENET_TIME_LESS (currentPeer -> nextTimeout, host -> serviceTime)) {
|
||||||
|
timeout = ENET_MIN (timeout, ENET_TIME_DIFFERENCE (currentPeer -> nextTimeout, host -> serviceTime) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentPeer -> lastReceiveTime && currentPeer -> lastSendTime) {
|
||||||
|
enet_uint32 timeSinceLastRecv = ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime);
|
||||||
|
enet_uint32 timeSinceLastSend = ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastSendTime);
|
||||||
|
enet_uint32 timeSinceLastComm = ENET_MIN(timeSinceLastSend, timeSinceLastRecv);
|
||||||
|
if (timeSinceLastComm >= currentPeer -> pingInterval) {
|
||||||
|
// Ping is due now for this peer
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
timeout = ENET_MIN (timeout, currentPeer -> pingInterval - timeSinceLastComm);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
timeout = ENET_MIN (timeout, currentPeer -> pingInterval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return timeout;
|
||||||
|
}
|
||||||
|
|
||||||
/** Sends any queued packets on the host specified to its designated peers.
|
/** Sends any queued packets on the host specified to its designated peers.
|
||||||
|
|
||||||
@param host host to flush
|
@param host host to flush
|
||||||
@@ -1895,14 +1937,20 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
enet_uint32 waitTime;
|
||||||
|
|
||||||
host -> serviceTime = enet_time_get ();
|
host -> serviceTime = enet_time_get ();
|
||||||
|
|
||||||
if (ENET_TIME_GREATER_EQUAL (host -> serviceTime, timeout))
|
if (ENET_TIME_GREATER_EQUAL (host -> serviceTime, timeout))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
waitTime = enet_protocol_compute_wait_timeout(host, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime));
|
||||||
|
if (waitTime == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
waitCondition = ENET_SOCKET_WAIT_RECEIVE | ENET_SOCKET_WAIT_INTERRUPT;
|
waitCondition = ENET_SOCKET_WAIT_RECEIVE | ENET_SOCKET_WAIT_INTERRUPT;
|
||||||
|
|
||||||
if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime) / 10) != 0)
|
if (enet_socket_wait (host -> socket, & waitCondition, waitTime) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
while (waitCondition & ENET_SOCKET_WAIT_INTERRUPT);
|
while (waitCondition & ENET_SOCKET_WAIT_INTERRUPT);
|
||||||
|
|||||||
@@ -2,13 +2,22 @@
|
|||||||
@file unix.c
|
@file unix.c
|
||||||
@brief ENet Unix system specific functions
|
@brief ENet Unix system specific functions
|
||||||
*/
|
*/
|
||||||
#ifndef _WIN32
|
#if !defined(_WIN32) || defined(NXDK)
|
||||||
|
|
||||||
|
// 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/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -20,8 +29,11 @@
|
|||||||
#include "enet/enet.h"
|
#include "enet/enet.h"
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
#ifdef HAS_POLL
|
#if !defined(IPV6_RECVPKTINFO) || !defined(IPV6_PKTINFO)
|
||||||
#undef HAS_POLL
|
#warning Missing IPv6 socket option definitions. Is __APPLE_USE_RFC_3542 defined?
|
||||||
|
#endif
|
||||||
|
#ifndef HAS_POLL
|
||||||
|
#define HAS_POLL 1
|
||||||
#endif
|
#endif
|
||||||
#ifndef HAS_FCNTL
|
#ifndef HAS_FCNTL
|
||||||
#define HAS_FCNTL 1
|
#define HAS_FCNTL 1
|
||||||
@@ -45,14 +57,9 @@
|
|||||||
#define HAS_GETNAMEINFO 1
|
#define HAS_GETNAMEINFO 1
|
||||||
#endif
|
#endif
|
||||||
#elif defined(__vita__)
|
#elif defined(__vita__)
|
||||||
#ifdef HAS_POLL
|
// PS Vita: No support for ancillary data or advanced message control
|
||||||
#undef HAS_POLL
|
#ifndef NO_MSGAPI
|
||||||
#endif
|
#define NO_MSGAPI 1
|
||||||
#ifdef HAS_FCNTL
|
|
||||||
#undef HAS_FCNTL
|
|
||||||
#endif
|
|
||||||
#ifdef HAS_IOCTL
|
|
||||||
#undef HAS_IOCTL
|
|
||||||
#endif
|
#endif
|
||||||
#ifndef HAS_INET_PTON
|
#ifndef HAS_INET_PTON
|
||||||
#define HAS_INET_PTON 1
|
#define HAS_INET_PTON 1
|
||||||
@@ -60,9 +67,6 @@
|
|||||||
#ifndef HAS_INET_NTOP
|
#ifndef HAS_INET_NTOP
|
||||||
#define HAS_INET_NTOP 1
|
#define HAS_INET_NTOP 1
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAS_MSGHDR_FLAGS
|
|
||||||
#undef HAS_MSGHDR_FLAGS
|
|
||||||
#endif
|
|
||||||
#ifndef HAS_SOCKLEN_T
|
#ifndef HAS_SOCKLEN_T
|
||||||
#define HAS_SOCKLEN_T 1
|
#define HAS_SOCKLEN_T 1
|
||||||
#endif
|
#endif
|
||||||
@@ -72,10 +76,104 @@
|
|||||||
#ifndef HAS_GETNAMEINFO
|
#ifndef HAS_GETNAMEINFO
|
||||||
#define HAS_GETNAMEINFO 1
|
#define HAS_GETNAMEINFO 1
|
||||||
#endif
|
#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
|
||||||
|
#elif defined(NXDK)
|
||||||
|
#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
|
||||||
|
#elif defined(__3DS__)
|
||||||
|
#ifdef AF_INET6
|
||||||
|
#undef AF_INET6
|
||||||
|
#endif
|
||||||
|
#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
|
||||||
|
#elif defined(__HAIKU__)
|
||||||
|
#ifndef HAS_POLL
|
||||||
|
#define HAS_POLL 1
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#ifndef HAS_IOCTL
|
#ifndef HAS_IOCTL
|
||||||
#define HAS_IOCTL 1
|
#define HAS_IOCTL 1
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef HAS_POLL
|
||||||
|
#define HAS_POLL 1
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAS_FCNTL
|
#ifdef HAS_FCNTL
|
||||||
@@ -87,10 +185,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAS_POLL
|
#ifdef HAS_POLL
|
||||||
#include <sys/poll.h>
|
#include <poll.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAS_SOCKLEN_T
|
#if !defined(HAS_SOCKLEN_T) && !defined(__socklen_t_defined) && !defined(__HAIKU__)
|
||||||
typedef int socklen_t;
|
typedef int socklen_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -145,6 +243,27 @@ enet_time_set (enet_uint32 newTimeBase)
|
|||||||
timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
|
timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
void
|
||||||
|
enet_address_make_v4mapped (ENetAddress * address)
|
||||||
|
{
|
||||||
|
ENetAddress oldAddress = *address;
|
||||||
|
struct sockaddr_in *sin = ((struct sockaddr_in *)&oldAddress.address);
|
||||||
|
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&address->address;
|
||||||
|
|
||||||
|
memset(sin6, 0, sizeof(*sin6));
|
||||||
|
sin6->sin6_family = AF_INET6;
|
||||||
|
sin6->sin6_len = sizeof(*sin6);
|
||||||
|
sin6->sin6_port = sin->sin_port;
|
||||||
|
|
||||||
|
sin6->sin6_addr.s6_addr[10] = 0xFF;
|
||||||
|
sin6->sin6_addr.s6_addr[11] = 0xFF;
|
||||||
|
memcpy(&sin6->sin6_addr.s6_addr[12], &sin->sin_addr, 4);
|
||||||
|
|
||||||
|
address->addressLength = sizeof(*sin6);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
enet_address_equal (ENetAddress * address1, ENetAddress * address2)
|
enet_address_equal (ENetAddress * address1, ENetAddress * address2)
|
||||||
{
|
{
|
||||||
@@ -161,6 +280,7 @@ enet_address_equal (ENetAddress * address1, ENetAddress * address2)
|
|||||||
return sin1 -> sin_port == sin2 -> sin_port &&
|
return sin1 -> sin_port == sin2 -> sin_port &&
|
||||||
sin1 -> sin_addr.s_addr == sin2 -> sin_addr.s_addr;
|
sin1 -> sin_addr.s_addr == sin2 -> sin_addr.s_addr;
|
||||||
}
|
}
|
||||||
|
#ifdef AF_INET6
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
{
|
{
|
||||||
struct sockaddr_in6 *sin6a, *sin6b;
|
struct sockaddr_in6 *sin6a, *sin6b;
|
||||||
@@ -169,6 +289,31 @@ enet_address_equal (ENetAddress * address1, ENetAddress * address2)
|
|||||||
return sin6a -> sin6_port == sin6b -> sin6_port &&
|
return sin6a -> sin6_port == sin6b -> sin6_port &&
|
||||||
! memcmp (& sin6a -> sin6_addr, & sin6b -> sin6_addr, sizeof (sin6a -> sin6_addr));
|
! memcmp (& sin6a -> sin6_addr, & sin6b -> sin6_addr, sizeof (sin6a -> sin6_addr));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_address_wildcard (const ENetAddress * address)
|
||||||
|
{
|
||||||
|
switch (address -> address.ss_family)
|
||||||
|
{
|
||||||
|
case AF_INET:
|
||||||
|
{
|
||||||
|
struct sockaddr_in *sin = (struct sockaddr_in *) & address -> address;
|
||||||
|
return sin -> sin_addr.s_addr == INADDR_ANY;
|
||||||
|
}
|
||||||
|
#ifdef AF_INET6
|
||||||
|
case AF_INET6:
|
||||||
|
{
|
||||||
|
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) & address -> address;
|
||||||
|
return ! memcmp (& sin6 -> sin6_addr, & in6addr_any, sizeof (in6addr_any));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@@ -185,12 +330,14 @@ enet_address_set_port (ENetAddress * address, enet_uint16 port)
|
|||||||
sin -> sin_port = ENET_HOST_TO_NET_16 (port);
|
sin -> sin_port = ENET_HOST_TO_NET_16 (port);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#ifdef AF_INET6
|
||||||
else if (address -> address.ss_family == AF_INET6)
|
else if (address -> address.ss_family == AF_INET6)
|
||||||
{
|
{
|
||||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &address -> address;
|
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &address -> address;
|
||||||
sin6 -> sin6_port = ENET_HOST_TO_NET_16 (port);
|
sin6 -> sin6_port = ENET_HOST_TO_NET_16 (port);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
@@ -264,7 +411,51 @@ enet_socket_listen (ENetSocket socket, int backlog)
|
|||||||
ENetSocket
|
ENetSocket
|
||||||
enet_socket_create (int af, ENetSocketType type)
|
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));
|
||||||
|
}
|
||||||
|
#elif defined(IP_RECVDSTADDR)
|
||||||
|
// FreeBSD uses IP_RECVDSTADDR instead of IP_PKTINFO when struct in_pktinfo is not available
|
||||||
|
{
|
||||||
|
int on = 1;
|
||||||
|
setsockopt(sock, IPPROTO_IP, IP_RECVDSTADDR, (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
|
||||||
|
|
||||||
|
#ifdef __WIIU__
|
||||||
|
{
|
||||||
|
// Enable usage of userbuffers on Wii U
|
||||||
|
int on = 1;
|
||||||
|
setsockopt(sock, SOL_SOCKET, SO_RUSRBUF, (char *)&on, sizeof(on));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -275,7 +466,7 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
|
|||||||
{
|
{
|
||||||
case ENET_SOCKOPT_NONBLOCK:
|
case ENET_SOCKOPT_NONBLOCK:
|
||||||
#ifdef HAS_FCNTL
|
#ifdef HAS_FCNTL
|
||||||
result = fcntl (socket, F_SETFL, (value ? O_NONBLOCK : 0) | (fcntl (socket, F_GETFL) & ~O_NONBLOCK));
|
result = fcntl (socket, F_SETFL, (value ? O_NONBLOCK : 0) | (fcntl (socket, F_GETFL, 0) & ~O_NONBLOCK));
|
||||||
#else
|
#else
|
||||||
#ifdef HAS_IOCTL
|
#ifdef HAS_IOCTL
|
||||||
result = ioctl (socket, FIONBIO, & value);
|
result = ioctl (socket, FIONBIO, & value);
|
||||||
@@ -297,6 +488,7 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
|
|||||||
result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
|
result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#if !defined(__WIIU__) && !defined(__3DS__)
|
||||||
case ENET_SOCKOPT_RCVTIMEO:
|
case ENET_SOCKOPT_RCVTIMEO:
|
||||||
{
|
{
|
||||||
struct timeval timeVal;
|
struct timeval timeVal;
|
||||||
@@ -314,6 +506,7 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
|
|||||||
result = setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & timeVal, sizeof (struct timeval));
|
result = setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & timeVal, sizeof (struct timeval));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
case ENET_SOCKOPT_NODELAY:
|
case ENET_SOCKOPT_NODELAY:
|
||||||
result = setsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (char *) & value, sizeof (int));
|
result = setsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (char *) & value, sizeof (int));
|
||||||
@@ -324,7 +517,7 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
|
|||||||
// iOS/macOS
|
// iOS/macOS
|
||||||
value = value ? NET_SERVICE_TYPE_VO : NET_SERVICE_TYPE_BE;
|
value = value ? NET_SERVICE_TYPE_VO : NET_SERVICE_TYPE_BE;
|
||||||
result = setsockopt (socket, SOL_SOCKET, SO_NET_SERVICE_TYPE, (char *) & value, sizeof (int));
|
result = setsockopt (socket, SOL_SOCKET, SO_NET_SERVICE_TYPE, (char *) & value, sizeof (int));
|
||||||
#else
|
#endif
|
||||||
#ifdef IP_TOS
|
#ifdef IP_TOS
|
||||||
// UNIX - IPv4
|
// UNIX - IPv4
|
||||||
value = value ? (46 << 2 | 0x01) : 0; // DSCP: Expedited Forwarding + ECT(1) (L4S)
|
value = value ? (46 << 2 | 0x01) : 0; // DSCP: Expedited Forwarding + ECT(1) (L4S)
|
||||||
@@ -340,7 +533,10 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
|
|||||||
value = value ? 6 : 0; // Max priority without NET_CAP_ADMIN
|
value = value ? 6 : 0; // Max priority without NET_CAP_ADMIN
|
||||||
result = setsockopt (socket, SOL_SOCKET, SO_PRIORITY, (char *) & value, sizeof (int));
|
result = setsockopt (socket, SOL_SOCKET, SO_PRIORITY, (char *) & value, sizeof (int));
|
||||||
#endif
|
#endif
|
||||||
#endif /* SO_NET_SERVICE_TYPE */
|
break;
|
||||||
|
|
||||||
|
case ENET_SOCKOPT_TTL:
|
||||||
|
result = setsockopt (socket, IPPROTO_IP, IP_TTL, (char *) & value, sizeof (int));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -361,6 +557,11 @@ enet_socket_get_option (ENetSocket socket, ENetSocketOption option, int * value)
|
|||||||
result = getsockopt (socket, SOL_SOCKET, SO_ERROR, value, & len);
|
result = getsockopt (socket, SOL_SOCKET, SO_ERROR, value, & len);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ENET_SOCKOPT_TTL:
|
||||||
|
len = sizeof (int);
|
||||||
|
result = getsockopt (socket, IPPROTO_IP, IP_TTL, (char *) value, & len);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -412,7 +613,8 @@ enet_socket_destroy (ENetSocket socket)
|
|||||||
|
|
||||||
int
|
int
|
||||||
enet_socket_send (ENetSocket socket,
|
enet_socket_send (ENetSocket socket,
|
||||||
const ENetAddress * address,
|
const ENetAddress * peerAddress,
|
||||||
|
const ENetAddress * localAddress,
|
||||||
const ENetBuffer * buffers,
|
const ENetBuffer * buffers,
|
||||||
size_t bufferCount)
|
size_t bufferCount)
|
||||||
{
|
{
|
||||||
@@ -450,33 +652,106 @@ enet_socket_send (ENetSocket socket,
|
|||||||
}
|
}
|
||||||
|
|
||||||
sentLength = sendto (socket, sendBuffer, sendLength, MSG_NOSIGNAL,
|
sentLength = sendto (socket, sendBuffer, sendLength, MSG_NOSIGNAL,
|
||||||
(struct sockaddr *) & address -> address, address -> addressLength);
|
(struct sockaddr *) & peerAddress -> address, peerAddress -> addressLength);
|
||||||
|
|
||||||
if (bufferCount > 1)
|
if (bufferCount > 1)
|
||||||
free(sendBuffer);
|
free(sendBuffer);
|
||||||
#else
|
#else
|
||||||
struct msghdr msgHdr;
|
struct msghdr msgHdr;
|
||||||
|
char controlBufData[1024];
|
||||||
|
|
||||||
memset (& msgHdr, 0, sizeof (struct msghdr));
|
memset (& msgHdr, 0, sizeof (struct msghdr));
|
||||||
|
|
||||||
if (address != NULL)
|
if (peerAddress != NULL)
|
||||||
{
|
{
|
||||||
msgHdr.msg_name = (void*) & address -> address;
|
msgHdr.msg_name = (void*) & peerAddress -> address;
|
||||||
msgHdr.msg_namelen = address -> addressLength;
|
msgHdr.msg_namelen = peerAddress -> addressLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
msgHdr.msg_iov = (struct iovec *) buffers;
|
msgHdr.msg_iov = (struct iovec *) buffers;
|
||||||
msgHdr.msg_iovlen = bufferCount;
|
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));
|
||||||
|
}
|
||||||
|
#elif defined(IP_SENDSRCADDR)
|
||||||
|
// FreeBSD uses IP_SENDSRCADDR with struct in_addr instead of IP_PKTINFO
|
||||||
|
if (localAddress->address.ss_family == AF_INET) {
|
||||||
|
struct in_addr srcAddr = ((struct sockaddr_in*)&localAddress->address)->sin_addr;
|
||||||
|
|
||||||
|
msgHdr.msg_control = controlBufData;
|
||||||
|
msgHdr.msg_controllen = CMSG_SPACE(sizeof(srcAddr));
|
||||||
|
|
||||||
|
struct cmsghdr *chdr = CMSG_FIRSTHDR(&msgHdr);
|
||||||
|
chdr->cmsg_level = IPPROTO_IP;
|
||||||
|
chdr->cmsg_type = IP_SENDSRCADDR;
|
||||||
|
chdr->cmsg_len = CMSG_LEN(sizeof(srcAddr));
|
||||||
|
memcpy(CMSG_DATA(chdr), &srcAddr, sizeof(srcAddr));
|
||||||
|
}
|
||||||
|
#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);
|
sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (sentLength == -1)
|
if (sentLength == -1)
|
||||||
{
|
{
|
||||||
if (errno == EWOULDBLOCK)
|
switch (errno)
|
||||||
return 0;
|
{
|
||||||
|
case EWOULDBLOCK:
|
||||||
|
return 0;
|
||||||
|
|
||||||
return -1;
|
// These errors are treated as possible transient
|
||||||
|
// conditions that could be caused by a network
|
||||||
|
// interruption. We'll ignore them and allow the
|
||||||
|
// socket timeout to kill us if the connection
|
||||||
|
// is permanently interrupted.
|
||||||
|
case EADDRNOTAVAIL:
|
||||||
|
case ENETDOWN:
|
||||||
|
case ENETUNREACH:
|
||||||
|
#if !defined(EHOSTDOWN) || (EHOSTDOWN != EHOSTUNREACH)
|
||||||
|
case EHOSTDOWN:
|
||||||
|
#endif
|
||||||
|
case EHOSTUNREACH:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sentLength;
|
return sentLength;
|
||||||
@@ -484,7 +759,8 @@ enet_socket_send (ENetSocket socket,
|
|||||||
|
|
||||||
int
|
int
|
||||||
enet_socket_receive (ENetSocket socket,
|
enet_socket_receive (ENetSocket socket,
|
||||||
ENetAddress * address,
|
ENetAddress * peerAddress,
|
||||||
|
ENetAddress * localAddress,
|
||||||
ENetBuffer * buffers,
|
ENetBuffer * buffers,
|
||||||
size_t bufferCount)
|
size_t bufferCount)
|
||||||
{
|
{
|
||||||
@@ -493,9 +769,9 @@ enet_socket_receive (ENetSocket socket,
|
|||||||
#ifdef NO_MSGAPI
|
#ifdef NO_MSGAPI
|
||||||
// This will ONLY work with a single buffer!
|
// This will ONLY work with a single buffer!
|
||||||
|
|
||||||
address -> addressLength = sizeof (address -> address);
|
peerAddress -> addressLength = sizeof (peerAddress -> address);
|
||||||
recvLength = recvfrom (socket, buffers[0].data, buffers[0].dataLength, MSG_NOSIGNAL,
|
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)
|
if (recvLength == -1)
|
||||||
{
|
{
|
||||||
@@ -508,17 +784,20 @@ enet_socket_receive (ENetSocket socket,
|
|||||||
return recvLength;
|
return recvLength;
|
||||||
#else
|
#else
|
||||||
struct msghdr msgHdr;
|
struct msghdr msgHdr;
|
||||||
|
char controlBufData[1024];
|
||||||
|
|
||||||
memset (& msgHdr, 0, sizeof (struct msghdr));
|
memset (& msgHdr, 0, sizeof (struct msghdr));
|
||||||
|
|
||||||
if (address != NULL)
|
if (peerAddress != NULL)
|
||||||
{
|
{
|
||||||
msgHdr.msg_name = & address -> address;
|
msgHdr.msg_name = & peerAddress -> address;
|
||||||
msgHdr.msg_namelen = sizeof (address -> address);
|
msgHdr.msg_namelen = sizeof (peerAddress -> address);
|
||||||
}
|
}
|
||||||
|
|
||||||
msgHdr.msg_iov = (struct iovec *) buffers;
|
msgHdr.msg_iov = (struct iovec *) buffers;
|
||||||
msgHdr.msg_iovlen = bufferCount;
|
msgHdr.msg_iovlen = bufferCount;
|
||||||
|
msgHdr.msg_control = controlBufData;
|
||||||
|
msgHdr.msg_controllen = sizeof(controlBufData);
|
||||||
|
|
||||||
recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL);
|
recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL);
|
||||||
|
|
||||||
@@ -530,14 +809,65 @@ enet_socket_receive (ENetSocket socket,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (address != NULL)
|
|
||||||
address -> addressLength = msgHdr.msg_namelen;
|
|
||||||
|
|
||||||
#ifdef HAS_MSGHDR_FLAGS
|
#ifdef HAS_MSGHDR_FLAGS
|
||||||
if (msgHdr.msg_flags & MSG_TRUNC)
|
if (msgHdr.msg_flags & MSG_TRUNC)
|
||||||
return -1;
|
return -2;
|
||||||
#endif
|
#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;
|
||||||
|
}
|
||||||
|
#elif defined(IP_RECVDSTADDR)
|
||||||
|
// FreeBSD uses IP_RECVDSTADDR with struct in_addr instead of IP_PKTINFO
|
||||||
|
if (chdr->cmsg_level == IPPROTO_IP && chdr->cmsg_type == IP_RECVDSTADDR) {
|
||||||
|
struct sockaddr_in *localAddr = (struct sockaddr_in*)&localAddress->address;
|
||||||
|
|
||||||
|
localAddr->sin_family = AF_INET;
|
||||||
|
localAddr->sin_addr = *((struct in_addr*)CMSG_DATA(chdr));
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
// HACK: Apple platforms return AF_INET addresses in msg_name from recvmsg() on dual-stack sockets
|
||||||
|
// instead of AF_INET6 addresses then rejects those same addresses when they are passed to sendmsg().
|
||||||
|
// Strangely, this only happens when the socket is bound, and IPV6_PKTINFO properly returns v4-mapped
|
||||||
|
// addresses in the same call. This is probably a kernel bug, so we fix it up here.
|
||||||
|
if (peerAddress -> address.ss_family == AF_INET && localAddress -> address.ss_family == AF_INET6) {
|
||||||
|
enet_address_make_v4mapped(peerAddress);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
return recvLength;
|
return recvLength;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -569,7 +899,18 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou
|
|||||||
if (* condition & ENET_SOCKET_WAIT_RECEIVE)
|
if (* condition & ENET_SOCKET_WAIT_RECEIVE)
|
||||||
pollSocket.events |= POLLIN;
|
pollSocket.events |= POLLIN;
|
||||||
|
|
||||||
|
#if defined(__3DS__)
|
||||||
|
uint64_t poll_start = osGetTime();
|
||||||
|
for (uint64_t i = poll_start; (i - poll_start) < timeout; i = osGetTime()) {
|
||||||
|
pollCount = poll(& pollSocket, 1, 0); // need to do this on 3ds since poll will block even if socket is ready before
|
||||||
|
if (pollCount) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
svcSleepThread(1000);
|
||||||
|
}
|
||||||
|
#else
|
||||||
pollCount = poll (& pollSocket, 1, timeout);
|
pollCount = poll (& pollSocket, 1, timeout);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (pollCount < 0)
|
if (pollCount < 0)
|
||||||
{
|
{
|
||||||
@@ -642,4 +983,3 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -2,19 +2,50 @@
|
|||||||
@file win32.c
|
@file win32.c
|
||||||
@brief ENet Win32 system specific functions
|
@brief ENet Win32 system specific functions
|
||||||
*/
|
*/
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) && !defined(NXDK)
|
||||||
|
|
||||||
#define ENET_BUILDING_LIB 1
|
#define ENET_BUILDING_LIB 1
|
||||||
#include "enet/enet.h"
|
#include "enet/enet.h"
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <mmsystem.h>
|
#include <mswsock.h>
|
||||||
|
#ifndef HAS_QOS_FLOWID
|
||||||
|
typedef UINT32 QOS_FLOWID;
|
||||||
|
#endif
|
||||||
|
#ifndef HAS_PQOS_FLOWID
|
||||||
|
typedef UINT32 *PQOS_FLOWID;
|
||||||
|
#endif
|
||||||
#include <qos2.h>
|
#include <qos2.h>
|
||||||
|
#ifndef QOS_NON_ADAPTIVE_FLOW
|
||||||
|
#define QOS_NON_ADAPTIVE_FLOW 0x00000002
|
||||||
|
#endif
|
||||||
|
|
||||||
static enet_uint32 timeBase = 0;
|
static enet_uint32 timeBase = 0;
|
||||||
|
|
||||||
|
#if !(defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP)
|
||||||
|
# define HAS_QWAVE
|
||||||
|
# include <versionhelpers.h>
|
||||||
|
#else
|
||||||
|
# define IsWindows10OrGreater() TRUE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAS_QWAVE
|
||||||
|
|
||||||
static HANDLE qosHandle = INVALID_HANDLE_VALUE;
|
static HANDLE qosHandle = INVALID_HANDLE_VALUE;
|
||||||
static QOS_FLOWID qosFlowId;
|
static QOS_FLOWID qosFlowId;
|
||||||
static BOOL qosAddedFlow;
|
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);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static BOOL enableEcn;
|
||||||
|
static LPFN_WSARECVMSG pfnWSARecvMsg;
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
enet_initialize (void)
|
enet_initialize (void)
|
||||||
{
|
{
|
||||||
@@ -32,44 +63,68 @@ enet_initialize (void)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
timeBeginPeriod (1);
|
#ifdef HAS_QWAVE
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
enet_deinitialize (void)
|
enet_deinitialize (void)
|
||||||
{
|
{
|
||||||
|
#ifdef HAS_QWAVE
|
||||||
qosAddedFlow = FALSE;
|
qosAddedFlow = FALSE;
|
||||||
qosFlowId = 0;
|
qosFlowId = 0;
|
||||||
|
enableEcn = FALSE;
|
||||||
|
|
||||||
if (qosHandle != INVALID_HANDLE_VALUE)
|
if (qosHandle != INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
QOSCloseHandle(qosHandle);
|
pfnQOSCloseHandle(qosHandle);
|
||||||
qosHandle = INVALID_HANDLE_VALUE;
|
qosHandle = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
timeEndPeriod (1);
|
if (QwaveLibraryHandle != NULL) {
|
||||||
|
pfnQOSCreateHandle = NULL;
|
||||||
|
pfnQOSCloseHandle = NULL;
|
||||||
|
pfnQOSAddSocketToFlow = NULL;
|
||||||
|
|
||||||
|
FreeLibrary(QwaveLibraryHandle);
|
||||||
|
QwaveLibraryHandle = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
WSACleanup ();
|
WSACleanup ();
|
||||||
}
|
}
|
||||||
|
|
||||||
enet_uint32
|
enet_uint32
|
||||||
enet_host_random_seed (void)
|
enet_host_random_seed (void)
|
||||||
{
|
{
|
||||||
return (enet_uint32) timeGetTime ();
|
return (enet_uint32) GetTickCount ();
|
||||||
}
|
}
|
||||||
|
|
||||||
enet_uint32
|
enet_uint32
|
||||||
enet_time_get (void)
|
enet_time_get (void)
|
||||||
{
|
{
|
||||||
return (enet_uint32) timeGetTime () - timeBase;
|
return (enet_uint32) GetTickCount () - timeBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
enet_time_set (enet_uint32 newTimeBase)
|
enet_time_set (enet_uint32 newTimeBase)
|
||||||
{
|
{
|
||||||
timeBase = (enet_uint32) timeGetTime () - newTimeBase;
|
timeBase = (enet_uint32) GetTickCount () - newTimeBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -135,6 +190,28 @@ enet_address_equal (ENetAddress * address1, ENetAddress * address2)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_address_wildcard (const ENetAddress * address)
|
||||||
|
{
|
||||||
|
switch (address -> address.ss_family)
|
||||||
|
{
|
||||||
|
case AF_INET:
|
||||||
|
{
|
||||||
|
struct sockaddr_in *sin = (struct sockaddr_in *) & address -> address;
|
||||||
|
return sin -> sin_addr.S_un.S_addr == INADDR_ANY;
|
||||||
|
}
|
||||||
|
case AF_INET6:
|
||||||
|
{
|
||||||
|
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) & address -> address;
|
||||||
|
return ! memcmp (& sin6 -> sin6_addr, & in6addr_any, sizeof (in6addr_any));
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
enet_address_set_host (ENetAddress * address, const char * name)
|
enet_address_set_host (ENetAddress * address, const char * name)
|
||||||
{
|
{
|
||||||
@@ -191,7 +268,46 @@ enet_socket_listen (ENetSocket socket, int backlog)
|
|||||||
ENetSocket
|
ENetSocket
|
||||||
enet_socket_create (int af, ENetSocketType type)
|
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
|
int
|
||||||
@@ -233,30 +349,38 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
|
|||||||
|
|
||||||
case ENET_SOCKOPT_QOS:
|
case ENET_SOCKOPT_QOS:
|
||||||
{
|
{
|
||||||
|
// Enable ECN marking on Windows 10 if QOS is enabled
|
||||||
|
enableEcn = value != 0 && IsWindows10OrGreater();
|
||||||
|
|
||||||
|
#ifdef HAS_QWAVE
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
QOS_VERSION qosVersion;
|
QOS_VERSION qosVersion;
|
||||||
|
|
||||||
qosVersion.MajorVersion = 1;
|
qosVersion.MajorVersion = 1;
|
||||||
qosVersion.MinorVersion = 0;
|
qosVersion.MinorVersion = 0;
|
||||||
if (!QOSCreateHandle(&qosVersion, &qosHandle))
|
if (pfnQOSCreateHandle == NULL || !pfnQOSCreateHandle(&qosVersion, &qosHandle))
|
||||||
{
|
{
|
||||||
qosHandle = INVALID_HANDLE_VALUE;
|
qosHandle = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (qosHandle != INVALID_HANDLE_VALUE)
|
else if (qosHandle != INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
QOSCloseHandle(qosHandle);
|
pfnQOSCloseHandle(qosHandle);
|
||||||
qosHandle = INVALID_HANDLE_VALUE;
|
qosHandle = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
qosAddedFlow = FALSE;
|
qosAddedFlow = FALSE;
|
||||||
qosFlowId = 0;
|
qosFlowId = 0;
|
||||||
|
#endif
|
||||||
result = 0;
|
result = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ENET_SOCKOPT_TTL:
|
||||||
|
result = setsockopt (socket, IPPROTO_IP, IP_TTL, (char *) & value, sizeof (int));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -274,6 +398,11 @@ enet_socket_get_option (ENetSocket socket, ENetSocketOption option, int * value)
|
|||||||
result = getsockopt (socket, SOL_SOCKET, SO_ERROR, (char *) value, & len);
|
result = getsockopt (socket, SOL_SOCKET, SO_ERROR, (char *) value, & len);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ENET_SOCKOPT_TTL:
|
||||||
|
len = sizeof(int);
|
||||||
|
result = getsockopt (socket, IPPROTO_IP, IP_TTL, (char *) value, & len);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -325,40 +454,159 @@ enet_socket_destroy (ENetSocket socket)
|
|||||||
|
|
||||||
int
|
int
|
||||||
enet_socket_send (ENetSocket socket,
|
enet_socket_send (ENetSocket socket,
|
||||||
const ENetAddress * address,
|
const ENetAddress * peerAddress,
|
||||||
|
const ENetAddress * localAddress,
|
||||||
const ENetBuffer * buffers,
|
const ENetBuffer * buffers,
|
||||||
size_t bufferCount)
|
size_t bufferCount)
|
||||||
{
|
{
|
||||||
DWORD sentLength;
|
DWORD sentLength;
|
||||||
|
WSAMSG msg = { 0 };
|
||||||
|
char controlBufData[1024];
|
||||||
|
PWSACMSGHDR chdr = NULL;
|
||||||
|
|
||||||
|
#ifdef HAS_QWAVE
|
||||||
if (!qosAddedFlow && qosHandle != INVALID_HANDLE_VALUE)
|
if (!qosAddedFlow && qosHandle != INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
|
BOOL isV4MappedV6Addr =
|
||||||
|
peerAddress->address.ss_family == AF_INET6 &&
|
||||||
|
IN6_IS_ADDR_V4MAPPED(&((PSOCKADDR_IN6)&peerAddress->address)->sin6_addr);
|
||||||
|
|
||||||
|
// qWAVE doesn't properly support IPv4-mapped IPv6 addresses, nor does it
|
||||||
|
// correctly support IPv4 addresses on a dual-stack socket (despite MSDN's
|
||||||
|
// claims to the contrary). To get proper QoS tagging when hosting in dual
|
||||||
|
// stack mode, we will temporarily connect() the socket to allow qWAVE to
|
||||||
|
// successfully initialize a flow, then disconnect it again so WSASendMsg()
|
||||||
|
// works later on.
|
||||||
|
if (isV4MappedV6Addr) {
|
||||||
|
connect(socket, (PSOCKADDR)&peerAddress->address, peerAddress->addressLength);
|
||||||
|
}
|
||||||
|
|
||||||
qosFlowId = 0; // Must be initialized to 0
|
qosFlowId = 0; // Must be initialized to 0
|
||||||
QOSAddSocketToFlow(qosHandle,
|
pfnQOSAddSocketToFlow(qosHandle,
|
||||||
socket,
|
socket,
|
||||||
(struct sockaddr *)&address->address,
|
isV4MappedV6Addr ? NULL : (struct sockaddr *)&peerAddress->address,
|
||||||
QOSTrafficTypeControl,
|
QOSTrafficTypeControl,
|
||||||
QOS_NON_ADAPTIVE_FLOW,
|
QOS_NON_ADAPTIVE_FLOW,
|
||||||
&qosFlowId);
|
&qosFlowId);
|
||||||
|
|
||||||
|
if (isV4MappedV6Addr) {
|
||||||
|
SOCKADDR_IN6 empty = { 0 };
|
||||||
|
empty.sin6_family = AF_INET6;
|
||||||
|
connect(socket, (PSOCKADDR)&empty, sizeof(empty));
|
||||||
|
}
|
||||||
|
|
||||||
// Even if we failed, don't try again
|
// Even if we failed, don't try again
|
||||||
qosAddedFlow = TRUE;
|
qosAddedFlow = TRUE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (WSASendTo (socket,
|
msg.name = (struct sockaddr *) & peerAddress -> address;
|
||||||
(LPWSABUF) buffers,
|
msg.namelen = peerAddress -> addressLength;
|
||||||
(DWORD) bufferCount,
|
msg.lpBuffers = (LPWSABUF) buffers;
|
||||||
& sentLength,
|
msg.dwBufferCount = (DWORD) bufferCount;
|
||||||
0,
|
|
||||||
address != NULL ? (struct sockaddr *) & address -> address : NULL,
|
// We always send traffic from the same local address as we last received
|
||||||
address != NULL ? address -> addressLength : 0,
|
// from this peer to ensure it correctly recognizes our responses as
|
||||||
NULL,
|
// coming from the expected host.
|
||||||
NULL) == SOCKET_ERROR)
|
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));
|
||||||
|
if (chdr == NULL) {
|
||||||
|
chdr = WSA_CMSG_FIRSTHDR(&msg);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
chdr = WSA_CMSG_NXTHDR(&msg, chdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
if (chdr == NULL) {
|
||||||
|
chdr = WSA_CMSG_FIRSTHDR(&msg);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
chdr = WSA_CMSG_NXTHDR(&msg, chdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a bit of a hack because it's not really per-socket or
|
||||||
|
// per-destination, but it is fine for our current usage of ENet
|
||||||
|
// in Moonlight and Sunshine where only a single socket is used.
|
||||||
|
if (enableEcn) {
|
||||||
|
BOOL isV4MappedV6Addr =
|
||||||
|
peerAddress->address.ss_family == AF_INET6 &&
|
||||||
|
IN6_IS_ADDR_V4MAPPED(&((PSOCKADDR_IN6)&peerAddress->address)->sin6_addr);
|
||||||
|
|
||||||
|
msg.Control.buf = controlBufData;
|
||||||
|
msg.Control.len += WSA_CMSG_SPACE(sizeof(INT));
|
||||||
|
if (chdr == NULL) {
|
||||||
|
chdr = WSA_CMSG_FIRSTHDR(&msg);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
chdr = WSA_CMSG_NXTHDR(&msg, chdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (peerAddress->address.ss_family == AF_INET || isV4MappedV6Addr) {
|
||||||
|
chdr->cmsg_level = IPPROTO_IP;
|
||||||
|
chdr->cmsg_type = IP_ECN;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
chdr->cmsg_level = IPPROTO_IPV6;
|
||||||
|
chdr->cmsg_type = IPV6_ECN;
|
||||||
|
}
|
||||||
|
chdr->cmsg_len = WSA_CMSG_LEN(sizeof(INT));
|
||||||
|
*(PINT)WSA_CMSG_DATA(chdr) = 0x01; // ECT(1) (L4S)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WSASendMsg (socket,
|
||||||
|
& msg,
|
||||||
|
0,
|
||||||
|
& sentLength,
|
||||||
|
NULL,
|
||||||
|
NULL) == SOCKET_ERROR)
|
||||||
{
|
{
|
||||||
if (WSAGetLastError () == WSAEWOULDBLOCK)
|
switch (WSAGetLastError ())
|
||||||
return 0;
|
{
|
||||||
|
case WSAEWOULDBLOCK:
|
||||||
|
return 0;
|
||||||
|
|
||||||
return -1;
|
// These errors are treated as possible transient
|
||||||
|
// conditions that could be caused by a network
|
||||||
|
// interruption. We'll ignore them and allow the
|
||||||
|
// socket timeout to kill us if the connection
|
||||||
|
// is permanently interrupted.
|
||||||
|
case WSAEADDRNOTAVAIL:
|
||||||
|
case WSAENETDOWN:
|
||||||
|
case WSAENETUNREACH:
|
||||||
|
case WSAEHOSTDOWN:
|
||||||
|
case WSAEHOSTUNREACH:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int) sentLength;
|
return (int) sentLength;
|
||||||
@@ -366,39 +614,69 @@ enet_socket_send (ENetSocket socket,
|
|||||||
|
|
||||||
int
|
int
|
||||||
enet_socket_receive (ENetSocket socket,
|
enet_socket_receive (ENetSocket socket,
|
||||||
ENetAddress * address,
|
ENetAddress * peerAddress,
|
||||||
|
ENetAddress * localAddress,
|
||||||
ENetBuffer * buffers,
|
ENetBuffer * buffers,
|
||||||
size_t bufferCount)
|
size_t bufferCount)
|
||||||
{
|
{
|
||||||
DWORD flags = 0,
|
DWORD recvLength;
|
||||||
recvLength;
|
WSAMSG msg = { 0 };
|
||||||
|
char controlBufData[1024];
|
||||||
|
|
||||||
if (address != NULL)
|
msg.name = peerAddress != NULL ? (struct sockaddr *) & peerAddress -> address : NULL;
|
||||||
address -> addressLength = sizeof (address -> address);
|
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 (WSARecvFrom (socket,
|
if (pfnWSARecvMsg (socket,
|
||||||
(LPWSABUF) buffers,
|
& msg,
|
||||||
(DWORD) bufferCount,
|
& recvLength,
|
||||||
& recvLength,
|
NULL,
|
||||||
& flags,
|
NULL) == SOCKET_ERROR)
|
||||||
address != NULL ? (struct sockaddr *) & address -> address : NULL,
|
|
||||||
address != NULL ? & address -> addressLength : NULL,
|
|
||||||
NULL,
|
|
||||||
NULL) == SOCKET_ERROR)
|
|
||||||
{
|
{
|
||||||
switch (WSAGetLastError ())
|
switch (WSAGetLastError ())
|
||||||
{
|
{
|
||||||
case WSAEWOULDBLOCK:
|
case WSAEWOULDBLOCK:
|
||||||
case WSAECONNRESET:
|
case WSAECONNRESET:
|
||||||
return 0;
|
return 0;
|
||||||
|
case WSAEMSGSIZE:
|
||||||
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & MSG_PARTIAL)
|
if (msg.dwFlags & MSG_PARTIAL)
|
||||||
return -1;
|
return -2;
|
||||||
|
|
||||||
|
// 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;
|
return (int) recvLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user