Compare commits
138 Commits
v1.3.8
...
v6_multihome
| Author | SHA1 | Date | |
|---|---|---|---|
| e790647a57 | |||
| 4cde9cc3dc | |||
| 8d69c5abe4 | |||
| ad5bf95397 | |||
| ab9d471cec | |||
| c20ca391e2 | |||
| 70ce1c3e0b | |||
| cf735e639e | |||
| e8dbb360fb | |||
| 0286dcdb34 | |||
| d8976c4fcc | |||
| bdfdb8b85d | |||
| e3ada4ed75 | |||
| d9e561938f | |||
| 2cc0e7c780 | |||
| b64793fa5e | |||
| e0e7045b7e | |||
| 4de13a2c2e | |||
| 0d1fb32ee8 | |||
| 0bd265b230 | |||
| 54dac7af81 | |||
| b63fd5256a | |||
| 65dc0f74d8 | |||
| bde113ef56 | |||
| e55d226969 | |||
| 259e5dbd23 | |||
| 8d55487767 | |||
| 5de0a6f764 | |||
| 2a788029bf | |||
| 757933e7bc | |||
| eda26a26d9 | |||
| 4f3dbbaeb1 | |||
| 47d2e192aa | |||
| 8d794daa7c | |||
| 9bf55a3433 | |||
| 224f31101f | |||
| 22272e29f9 | |||
| 5b93d08fa5 | |||
| c25b57b2c1 | |||
| f89e5986d0 | |||
| 5c96da29c2 | |||
| bb14921419 | |||
| 67cee4803a | |||
| 007b7d2a3f | |||
| 92bf2d8256 | |||
| 33c7d6903e | |||
| 6991632abf | |||
| d988023971 | |||
| b4c427059a | |||
| 637cd52e96 | |||
| 512b3f26f9 | |||
| 6537dc81f3 | |||
| 5503534362 | |||
| 93b080b053 | |||
| cf38f85e08 | |||
| e770a52bca | |||
| 0eaf48eeb0 | |||
| b8713bdf88 | |||
| e2ef83927d | |||
| cea2c5be9f | |||
| 295456fba9 | |||
| 219c625c74 | |||
| 335715309c | |||
| 2e1c6bceea | |||
| 42891f6919 | |||
| eb38c3c737 | |||
| 39a72ab199 | |||
| 67f964c2ad | |||
| a84c120eff | |||
| 6cc8cc8a26 | |||
| 9d9ba122d4 | |||
| 90560cd471 | |||
| 0891c520d2 | |||
| 5f5e977eef | |||
| 3ae5af4548 | |||
| e33ca1dc47 | |||
| f46fee0acc | |||
| 7546b505c1 | |||
| 2bc07bb50d | |||
| a602abf244 | |||
| 167f41aa2b | |||
| b2ee3b7b48 | |||
| 8b24595dbd | |||
| b3e34fa1db | |||
| 4f7ef11c23 | |||
| a39d3bb49c | |||
| ae9002fe19 | |||
| 4d1067179b | |||
| 00ccd3bd3f | |||
| 809a1d15b6 | |||
| 5f476546ed | |||
| f7c46f03fd | |||
| 7c27a5d5f8 | |||
| 9b06a12e71 | |||
| 8df6e58c5f | |||
| b574c946d8 | |||
| 4d2694d74e | |||
| c8fa0aeea4 | |||
| 2fb98f9b02 | |||
| 6ef4e7d277 | |||
| d85a037ec4 | |||
| 99004c45ac | |||
| 736474ca83 | |||
| 9c4d9953ac | |||
| 6f287186d8 | |||
| 379290acd5 | |||
| 127643fae4 | |||
| 98219eb50d | |||
| b14c7e99e0 | |||
| 464e883f04 | |||
| 9895a4f110 | |||
| 518144338d | |||
| 734a630bed | |||
| ea8d41f65c | |||
| 73c930881f | |||
| 5721b667f2 | |||
| c58ec4cc44 | |||
| b3de8a29c4 | |||
| 259376b214 | |||
| 01416f5850 | |||
| 272d4432f8 | |||
| 6fcfba5141 | |||
| 84a4ac70ab | |||
| 9d1d09c1e5 | |||
| d45b44f2b5 | |||
| 970ee42041 | |||
| 2ebb3560b7 | |||
| e19dc9f825 | |||
| 48571bb05f | |||
| 2c5dd69b17 | |||
| bc8019aa15 | |||
| 4d7b80152b | |||
| dc48f76192 | |||
| c0713c47e6 | |||
| 3595c0b3fb | |||
| e123218df3 | |||
| 73ef8d8a96 | |||
| 1658cf3a95 |
+109
@@ -0,0 +1,109 @@
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
project(enet)
|
||||
|
||||
# The "configure" step.
|
||||
include(CheckFunctionExists)
|
||||
include(CheckStructHasMember)
|
||||
include(CheckTypeSize)
|
||||
check_function_exists("fcntl" HAS_FCNTL)
|
||||
check_function_exists("ioctl" HAS_IOCTL)
|
||||
check_function_exists("poll" HAS_POLL)
|
||||
check_function_exists("getaddrinfo" HAS_GETADDRINFO)
|
||||
check_function_exists("getnameinfo" HAS_GETNAMEINFO)
|
||||
check_function_exists("gethostbyname_r" HAS_GETHOSTBYNAME_R)
|
||||
check_function_exists("gethostbyaddr_r" HAS_GETHOSTBYADDR_R)
|
||||
check_function_exists("inet_pton" HAS_INET_PTON)
|
||||
check_function_exists("inet_ntop" HAS_INET_NTOP)
|
||||
check_struct_has_member("struct msghdr" "msg_flags" "sys/types.h;sys/socket.h" HAS_MSGHDR_FLAGS)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES "sys/types.h" "sys/socket.h")
|
||||
check_type_size("socklen_t" HAS_SOCKLEN_T BUILTIN_TYPES_ONLY)
|
||||
unset(CMAKE_EXTRA_INCLUDE_FILES)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES "qos2.h")
|
||||
check_type_size("QOS_FLOWID" HAS_QOS_FLOWID BUILTIN_TYPES_ONLY)
|
||||
check_type_size("PQOS_FLOWID" HAS_PQOS_FLOWID BUILTIN_TYPES_ONLY)
|
||||
unset(CMAKE_EXTRA_INCLUDE_FILES)
|
||||
if(MSVC)
|
||||
add_definitions(-W3)
|
||||
else()
|
||||
add_definitions(-Wno-error)
|
||||
endif()
|
||||
|
||||
if(HAS_FCNTL)
|
||||
add_definitions(-DHAS_FCNTL=1)
|
||||
endif()
|
||||
if(HAS_IOCTL)
|
||||
add_definitions(-DHAS_IOCTL=1)
|
||||
endif()
|
||||
if(HAS_POLL)
|
||||
add_definitions(-DHAS_POLL=1)
|
||||
endif()
|
||||
if(HAS_GETNAMEINFO)
|
||||
add_definitions(-DHAS_GETNAMEINFO=1)
|
||||
endif()
|
||||
if(HAS_GETADDRINFO)
|
||||
add_definitions(-DHAS_GETADDRINFO=1)
|
||||
endif()
|
||||
if(HAS_GETHOSTBYNAME_R)
|
||||
add_definitions(-DHAS_GETHOSTBYNAME_R=1)
|
||||
endif()
|
||||
if(HAS_GETHOSTBYADDR_R)
|
||||
add_definitions(-DHAS_GETHOSTBYADDR_R=1)
|
||||
endif()
|
||||
if(HAS_INET_PTON)
|
||||
add_definitions(-DHAS_INET_PTON=1)
|
||||
endif()
|
||||
if(HAS_INET_NTOP)
|
||||
add_definitions(-DHAS_INET_NTOP=1)
|
||||
endif()
|
||||
if(HAS_MSGHDR_FLAGS)
|
||||
add_definitions(-DHAS_MSGHDR_FLAGS=1)
|
||||
endif()
|
||||
if(HAS_SOCKLEN_T)
|
||||
add_definitions(-DHAS_SOCKLEN_T=1)
|
||||
endif()
|
||||
if(HAS_QOS_FLOWID)
|
||||
add_definitions(-DHAS_QOS_FLOWID=1)
|
||||
endif()
|
||||
if(HAS_PQOS_FLOWID)
|
||||
add_definitions(-DHAS_PQOS_FLOWID=1)
|
||||
endif()
|
||||
|
||||
include_directories(${PROJECT_SOURCE_DIR}/include)
|
||||
|
||||
set(INCLUDE_FILES_PREFIX include/enet)
|
||||
set(INCLUDE_FILES
|
||||
${INCLUDE_FILES_PREFIX}/callbacks.h
|
||||
${INCLUDE_FILES_PREFIX}/enet.h
|
||||
${INCLUDE_FILES_PREFIX}/list.h
|
||||
${INCLUDE_FILES_PREFIX}/protocol.h
|
||||
${INCLUDE_FILES_PREFIX}/time.h
|
||||
${INCLUDE_FILES_PREFIX}/types.h
|
||||
${INCLUDE_FILES_PREFIX}/unix.h
|
||||
${INCLUDE_FILES_PREFIX}/utility.h
|
||||
${INCLUDE_FILES_PREFIX}/win32.h
|
||||
)
|
||||
|
||||
set(SOURCE_FILES
|
||||
callbacks.c
|
||||
compress.c
|
||||
host.c
|
||||
list.c
|
||||
packet.c
|
||||
peer.c
|
||||
protocol.c
|
||||
unix.c
|
||||
win32.c)
|
||||
|
||||
source_group(include FILES ${INCLUDE_FILES})
|
||||
source_group(source FILES ${SOURCE_FILES})
|
||||
|
||||
add_library(enet STATIC
|
||||
${INCLUDE_FILES}
|
||||
${SOURCE_FILES}
|
||||
)
|
||||
target_include_directories(enet SYSTEM PUBLIC include)
|
||||
|
||||
if (MINGW)
|
||||
target_link_libraries(enet winmm ws2_32)
|
||||
endif()
|
||||
@@ -1,3 +1,55 @@
|
||||
ENet 1.3.17 (November 15, 2020):
|
||||
|
||||
* fixes for sender getting too far ahead of receiver that can cause instability with reliable packets
|
||||
|
||||
ENet 1.3.16 (September 8, 2020):
|
||||
|
||||
* fix bug in unreliable fragment queuing
|
||||
* use single output queue for reliable and unreliable packets for saner ordering
|
||||
* revert experimental throttle changes that were less stable than prior algorithm
|
||||
|
||||
ENet 1.3.15 (April 20, 2020):
|
||||
|
||||
* quicker RTT initialization
|
||||
* use fractional precision for RTT calculations
|
||||
* fixes for packet throttle with low RTT variance
|
||||
* miscellaneous socket bug fixes
|
||||
|
||||
ENet 1.3.14 (January 27, 2019):
|
||||
|
||||
* bug fix for enet_peer_disconnect_later()
|
||||
* use getaddrinfo and getnameinfo where available
|
||||
* miscellaneous cleanups
|
||||
|
||||
ENet 1.3.13 (April 30, 2015):
|
||||
|
||||
* miscellaneous bug fixes
|
||||
* added premake and cmake support
|
||||
* miscellaneous documentation cleanups
|
||||
|
||||
ENet 1.3.12 (April 24, 2014):
|
||||
|
||||
* added maximumPacketSize and maximumWaitingData fields to ENetHost to limit the amount of
|
||||
data waiting to be delivered on a peer (beware that the default maximumPacketSize is
|
||||
32MB and should be set higher if desired as should maximumWaitingData)
|
||||
|
||||
ENet 1.3.11 (December 26, 2013):
|
||||
|
||||
* allow an ENetHost to connect to itself
|
||||
* fixed possible bug with disconnect notifications during connect attempts
|
||||
* fixed some preprocessor definition bugs
|
||||
|
||||
ENet 1.3.10 (October 23, 2013);
|
||||
|
||||
* doubled maximum reliable window size
|
||||
* fixed RCVTIMEO/SNDTIMEO socket options and also added NODELAY
|
||||
|
||||
ENet 1.3.9 (August 19, 2013):
|
||||
|
||||
* added duplicatePeers option to ENetHost which can limit the number of peers from duplicate IPs
|
||||
* added enet_socket_get_option() and ENET_SOCKOPT_ERROR
|
||||
* added enet_host_random_seed() platform stub
|
||||
|
||||
ENet 1.3.8 (June 2, 2013):
|
||||
|
||||
* added enet_linked_version() for checking the linked version
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
<doxygenlayout version="1.0">
|
||||
<!-- Generated by doxygen 1.8.6 -->
|
||||
<!-- Navigation index tabs for HTML output -->
|
||||
<navindex>
|
||||
<tab type="mainpage" visible="yes" title="Home"/>
|
||||
<tab type="user" visible="yes" title="Features" url="@ref Features" />
|
||||
<tab type="user" visible="yes" title="Downloads" url="@ref Downloads" />
|
||||
<tab type="user" visible="yes" title="Installation" url="@ref Installation" />
|
||||
<tab type="user" visible="yes" title="Tutorial" url="@ref Tutorial" />
|
||||
<tab type="user" visible="yes" title="Mailing List" url="@ref MailingList" />
|
||||
<tab type="user" visible="yes" title="IRC Channel" url="@ref IRCChannel" />
|
||||
<tab type="user" visible="yes" title="FAQ" url="@ref FAQ" />
|
||||
<tab type="user" visible="yes" title="License" url="@ref License" />
|
||||
<tab type="usergroup" visible="yes" title="Documentation" briefdescription="Documentation">
|
||||
<tab type="modules" visible="yes" title="Functions" intro=""/>
|
||||
<tab type="classlist" visible="yes" title="Data Structures" intro=""/>
|
||||
<tab type="filelist" visible="yes" title="Files" intro=""/>
|
||||
<tab type="globals" visible="yes" title="" intro=""/>
|
||||
</tab>
|
||||
</navindex>
|
||||
|
||||
<!-- Layout definition for a class page -->
|
||||
<class>
|
||||
<briefdescription visible="yes"/>
|
||||
<includes visible="$SHOW_INCLUDE_FILES"/>
|
||||
<inheritancegraph visible="$CLASS_GRAPH"/>
|
||||
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
|
||||
<memberdecl>
|
||||
<nestedclasses visible="yes" title=""/>
|
||||
<publictypes title=""/>
|
||||
<services title=""/>
|
||||
<interfaces title=""/>
|
||||
<publicslots title=""/>
|
||||
<signals title=""/>
|
||||
<publicmethods title=""/>
|
||||
<publicstaticmethods title=""/>
|
||||
<publicattributes title=""/>
|
||||
<publicstaticattributes title=""/>
|
||||
<protectedtypes title=""/>
|
||||
<protectedslots title=""/>
|
||||
<protectedmethods title=""/>
|
||||
<protectedstaticmethods title=""/>
|
||||
<protectedattributes title=""/>
|
||||
<protectedstaticattributes title=""/>
|
||||
<packagetypes title=""/>
|
||||
<packagemethods title=""/>
|
||||
<packagestaticmethods title=""/>
|
||||
<packageattributes title=""/>
|
||||
<packagestaticattributes title=""/>
|
||||
<properties title=""/>
|
||||
<events title=""/>
|
||||
<privatetypes title=""/>
|
||||
<privateslots title=""/>
|
||||
<privatemethods title=""/>
|
||||
<privatestaticmethods title=""/>
|
||||
<privateattributes title=""/>
|
||||
<privatestaticattributes title=""/>
|
||||
<friends title=""/>
|
||||
<related title="" subtitle=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
<memberdef>
|
||||
<inlineclasses title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<services title=""/>
|
||||
<interfaces title=""/>
|
||||
<constructors title=""/>
|
||||
<functions title=""/>
|
||||
<related title=""/>
|
||||
<variables title=""/>
|
||||
<properties title=""/>
|
||||
<events title=""/>
|
||||
</memberdef>
|
||||
<allmemberslink visible="yes"/>
|
||||
<usedfiles visible="$SHOW_USED_FILES"/>
|
||||
<authorsection visible="yes"/>
|
||||
</class>
|
||||
|
||||
<!-- Layout definition for a namespace page -->
|
||||
<namespace>
|
||||
<briefdescription visible="yes"/>
|
||||
<memberdecl>
|
||||
<nestednamespaces visible="yes" title=""/>
|
||||
<constantgroups visible="yes" title=""/>
|
||||
<classes visible="yes" title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
<memberdef>
|
||||
<inlineclasses title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
</memberdef>
|
||||
<authorsection visible="yes"/>
|
||||
</namespace>
|
||||
|
||||
<!-- Layout definition for a file page -->
|
||||
<file>
|
||||
<briefdescription visible="yes"/>
|
||||
<includes visible="$SHOW_INCLUDE_FILES"/>
|
||||
<includegraph visible="$INCLUDE_GRAPH"/>
|
||||
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
|
||||
<sourcelink visible="yes"/>
|
||||
<memberdecl>
|
||||
<classes visible="yes" title=""/>
|
||||
<namespaces visible="yes" title=""/>
|
||||
<constantgroups visible="yes" title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
<memberdef>
|
||||
<inlineclasses title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
</memberdef>
|
||||
<authorsection/>
|
||||
</file>
|
||||
|
||||
<!-- Layout definition for a group page -->
|
||||
<group>
|
||||
<briefdescription visible="yes"/>
|
||||
<groupgraph visible="$GROUP_GRAPHS"/>
|
||||
<memberdecl>
|
||||
<nestedgroups visible="yes" title=""/>
|
||||
<dirs visible="yes" title=""/>
|
||||
<files visible="yes" title=""/>
|
||||
<namespaces visible="yes" title=""/>
|
||||
<classes visible="yes" title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<enumvalues title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<signals title=""/>
|
||||
<publicslots title=""/>
|
||||
<protectedslots title=""/>
|
||||
<privateslots title=""/>
|
||||
<events title=""/>
|
||||
<properties title=""/>
|
||||
<friends title=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
<memberdef>
|
||||
<pagedocs/>
|
||||
<inlineclasses title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<enumvalues title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<signals title=""/>
|
||||
<publicslots title=""/>
|
||||
<protectedslots title=""/>
|
||||
<privateslots title=""/>
|
||||
<events title=""/>
|
||||
<properties title=""/>
|
||||
<friends title=""/>
|
||||
</memberdef>
|
||||
<authorsection visible="yes"/>
|
||||
</group>
|
||||
|
||||
<!-- Layout definition for a directory page -->
|
||||
<directory>
|
||||
<briefdescription visible="yes"/>
|
||||
<directorygraph visible="yes"/>
|
||||
<memberdecl>
|
||||
<dirs visible="yes"/>
|
||||
<files visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
</directory>
|
||||
</doxygenlayout>
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2002-2013 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:
|
||||
|
||||
|
||||
+2
-2
@@ -16,7 +16,7 @@ enetinclude_HEADERS = \
|
||||
lib_LTLIBRARIES = libenet.la
|
||||
libenet_la_SOURCES = callbacks.c compress.c host.c list.c packet.c peer.c protocol.c unix.c win32.c
|
||||
# see info '(libtool) Updating version info' before making a release
|
||||
libenet_la_LDFLAGS = $(AM_LDFLAGS) -version-info 5:0:3
|
||||
INCLUDES = -I$(top_srcdir)/include
|
||||
libenet_la_LDFLAGS = $(AM_LDFLAGS) -version-info 7:5:0
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
|
||||
ACLOCAL_AMFLAGS = -Im4
|
||||
|
||||
+3
-1
@@ -1,4 +1,4 @@
|
||||
AC_INIT([libenet], [1.3.8])
|
||||
AC_INIT([libenet], [1.3.17])
|
||||
AC_CONFIG_SRCDIR([include/enet/enet.h])
|
||||
AM_INIT_AUTOMAKE([foreign])
|
||||
|
||||
@@ -7,6 +7,8 @@ AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_PROG_CC
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
AC_CHECK_FUNC(getaddrinfo, [AC_DEFINE(HAS_GETADDRINFO)])
|
||||
AC_CHECK_FUNC(getnameinfo, [AC_DEFINE(HAS_GETNAMEINFO)])
|
||||
AC_CHECK_FUNC(gethostbyaddr_r, [AC_DEFINE(HAS_GETHOSTBYADDR_R)])
|
||||
AC_CHECK_FUNC(gethostbyname_r, [AC_DEFINE(HAS_GETHOSTBYNAME_R)])
|
||||
AC_CHECK_FUNC(poll, [AC_DEFINE(HAS_POLL)])
|
||||
|
||||
+2
-2
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
@page FAQ Frequently Answered Questions
|
||||
|
||||
@section Q1 Is ENet thread safe?
|
||||
@section Q1 Is ENet thread-safe?
|
||||
|
||||
ENet does not use any significant global variables, the vast majority
|
||||
of state is encapsulated in the ENetHost structure. As such, as long
|
||||
as the application guards access to this structure, then ENet should
|
||||
operate fine in a multithreaded environment.
|
||||
operate fine in a multi-threaded environment.
|
||||
|
||||
@section Q2 Isn't ENet just re-inventing TCP?! What's the point?
|
||||
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@
|
||||
|
||||
ENet evolved specifically as a UDP networking layer for the
|
||||
multiplayer first person shooter Cube. Cube necessitated low latency
|
||||
communcation with data sent out very frequently, so TCP was an
|
||||
communication with data sent out very frequently, so TCP was an
|
||||
unsuitable choice due to its high latency and stream orientation. UDP,
|
||||
however, lacks many sometimes necessary features from TCP such as
|
||||
reliability, sequencing, unrestricted packet sizes, and connection
|
||||
@@ -44,7 +44,7 @@ packet streams that simplify the transfer of various types of data.
|
||||
|
||||
ENet provides sequencing for all packets by assigning to each sent
|
||||
packet a sequence number that is incremented as packets are sent. ENet
|
||||
guarentees that no packet with a higher sequence number will be
|
||||
guarantees that no packet with a higher sequence number will be
|
||||
delivered before a packet with a lower sequence number, thus ensuring
|
||||
packets are delivered exactly in the order they are sent.
|
||||
|
||||
|
||||
+1
-2
@@ -2,8 +2,7 @@
|
||||
@page Installation Installation
|
||||
|
||||
ENet should be trivially simple to integrate with most applications.
|
||||
First, make sure you download the latest source distribution here @ref
|
||||
SourceDistro.
|
||||
First, make sure you download the latest source distribution at @ref Downloads.
|
||||
|
||||
@section Unix Unix-like Operating Systems
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
@page License License
|
||||
|
||||
Copyright (c) 2002-2013 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
|
||||
|
||||
+12
-12
@@ -1,6 +1,4 @@
|
||||
/** @mainpage enet
|
||||
<center>http://enet.bespin.org</center>
|
||||
<hr>
|
||||
/** @mainpage ENet
|
||||
|
||||
ENet's purpose is to provide a relatively thin, simple and robust
|
||||
network communication layer on top of UDP (User Datagram Protocol).
|
||||
@@ -14,7 +12,7 @@ portable, and easily embeddable.
|
||||
|
||||
@ref Features
|
||||
|
||||
@ref SourceDistro
|
||||
@ref Downloads
|
||||
|
||||
@ref Installation
|
||||
|
||||
@@ -28,32 +26,34 @@ portable, and easily embeddable.
|
||||
|
||||
@ref License
|
||||
|
||||
<a class="el" href="usergroup0.html">Documentation</a>
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
@page SourceDistro Source Distribution
|
||||
@page Downloads Downloads
|
||||
|
||||
You can retrieve the source to ENet by downloading it in either .tar.gz form
|
||||
or accessing the github distribution directly.
|
||||
|
||||
The most recent stable release (1.3.8) can be downloaded <a href="http://enet.bespin.org/download/enet-1.3.8.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 href="http://enet.bespin.org/download/enet-1.2.5.tar.gz">here</a>
|
||||
The most recent stable release (1.3.17) can be downloaded <a class="el" href="download/enet-1.3.17.tar.gz">here</a>.
|
||||
The last release that is protocol compatible with the 1.2 series or earlier (1.2.5) can be downloaded <a class="el" href="download/enet-1.2.5.tar.gz">here</a>.
|
||||
|
||||
You can find the most recent ENet source at <a 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>.
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
@page MailingList ENet Mailing List
|
||||
@page MailingList Mailing List
|
||||
|
||||
The <a href="http://lists.cubik.org/mailman/listinfo/enet-discuss">enet-discuss</a> list is for discussion of ENet, including bug reports or feature requests.
|
||||
The <a class="el" href="http://lists.cubik.org/mailman/listinfo/enet-discuss">enet-discuss</a> list is for discussion of ENet, including bug reports or feature requests.
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
@page IRCChannel ENet IRC Channel
|
||||
@page IRCChannel IRC Channel
|
||||
|
||||
Join the \#enet channel on the freenode IRC network (irc.freenode.net) for real-time discussion about the ENet library.
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
+13
-4
@@ -102,8 +102,8 @@ may be simultaneously open.
|
||||
client = enet_host_create (NULL /* create a client host */,
|
||||
1 /* only allow 1 outgoing connection */,
|
||||
2 /* allow up 2 channels to be used, 0 and 1 */,
|
||||
57600 / 8 /* 56K modem with 56 Kbps downstream bandwidth */,
|
||||
14400 / 8 /* 56K modem with 14 Kbps upstream bandwidth */);
|
||||
0 /* assume any amount of incoming bandwidth */,
|
||||
0 /* assume any amount of outgoing bandwidth */);
|
||||
|
||||
if (client == NULL)
|
||||
{
|
||||
@@ -127,6 +127,15 @@ enet_host_service() will return immediately if there are no events to
|
||||
dispatch. enet_host_service() will return 1 if an event was dispatched
|
||||
within the specified timeout.
|
||||
|
||||
Beware that most processing of the network with the ENet stack is done
|
||||
inside enet_host_service(). Both hosts that make up the sides of a connection
|
||||
must regularly call this function to ensure packets are actually sent and
|
||||
received. A common symptom of not actively calling enet_host_service()
|
||||
on both ends is that one side receives events while the other does not.
|
||||
The best way to schedule this activity to ensure adequate service is, for
|
||||
example, to call enet_host_service() with a 0 timeout (meaning non-blocking)
|
||||
at the beginning of every frame in a game loop.
|
||||
|
||||
Currently there are only four types of significant events in ENet:
|
||||
|
||||
An event of type ENET_EVENT_TYPE_NONE is returned if no event occurred
|
||||
@@ -182,7 +191,7 @@ disconnect event and must be explicitly reset.
|
||||
break;
|
||||
|
||||
case ENET_EVENT_TYPE_DISCONNECT:
|
||||
printf ("%s disconected.\n", event.peer -> data);
|
||||
printf ("%s disconnected.\n", event.peer -> data);
|
||||
|
||||
/* Reset the peer's client information. */
|
||||
|
||||
@@ -204,7 +213,7 @@ Certain flags may also be supplied to enet_packet_create() to control
|
||||
various packet features:
|
||||
|
||||
ENET_PACKET_FLAG_RELIABLE specifies that the packet must use reliable
|
||||
delivery. A reliable packet is guarenteed to be delivered, and a
|
||||
delivery. A reliable packet is guaranteed to be delivered, and a
|
||||
number of retry attempts will be made until an acknowledgement is
|
||||
received from the foreign host the packet is sent to. If a certain
|
||||
number of retry attempts is reached without any acknowledgement, ENet
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
*/
|
||||
#define ENET_BUILDING_LIB 1
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "enet/enet.h"
|
||||
|
||||
/** @defgroup host ENet host functions
|
||||
@@ -13,6 +12,7 @@
|
||||
|
||||
/** Creates a host for communicating to peers.
|
||||
|
||||
@param addressFamily the address family of the socket that should be created (ex: PF_INET/PF_INET6)
|
||||
@param address the address at which other peers may connect to this host. If NULL, then no peers may connect to the host.
|
||||
@param peerCount the maximum number of peers that should be allocated for the host.
|
||||
@param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT
|
||||
@@ -27,7 +27,7 @@
|
||||
at any given time.
|
||||
*/
|
||||
ENetHost *
|
||||
enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
|
||||
enet_host_create (int addressFamily, const ENetAddress * address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
|
||||
{
|
||||
ENetHost * host;
|
||||
ENetPeer * currentPeer;
|
||||
@@ -49,7 +49,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
|
||||
}
|
||||
memset (host -> peers, 0, peerCount * sizeof (ENetPeer));
|
||||
|
||||
host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM);
|
||||
host -> socket = enet_socket_create (addressFamily, ENET_SOCKET_TYPE_DATAGRAM);
|
||||
if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0))
|
||||
{
|
||||
if (host -> socket != ENET_SOCKET_NULL)
|
||||
@@ -62,9 +62,9 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
|
||||
}
|
||||
|
||||
enet_socket_set_option (host -> socket, ENET_SOCKOPT_NONBLOCK, 1);
|
||||
enet_socket_set_option (host -> socket, ENET_SOCKOPT_BROADCAST, 1);
|
||||
enet_socket_set_option (host -> socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
|
||||
enet_socket_set_option (host -> socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
|
||||
enet_socket_set_option (host -> socket, ENET_SOCKOPT_QOS, 1);
|
||||
|
||||
if (address != NULL && enet_socket_get_address (host -> socket, & host -> address) < 0)
|
||||
host -> address = * address;
|
||||
@@ -76,11 +76,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
|
||||
channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
|
||||
|
||||
host -> randomSeed = (enet_uint32) (size_t) host;
|
||||
#ifdef WIN32
|
||||
host -> randomSeed += (enet_uint32) timeGetTime();
|
||||
#else
|
||||
host -> randomSeed += (enet_uint32) time(NULL);
|
||||
#endif
|
||||
host -> randomSeed += enet_host_random_seed ();
|
||||
host -> randomSeed = (host -> randomSeed << 16) | (host -> randomSeed >> 16);
|
||||
host -> channelLimit = channelLimit;
|
||||
host -> incomingBandwidth = incomingBandwidth;
|
||||
@@ -92,8 +88,8 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
|
||||
host -> commandCount = 0;
|
||||
host -> bufferCount = 0;
|
||||
host -> checksum = NULL;
|
||||
host -> receivedAddress.host = ENET_HOST_ANY;
|
||||
host -> receivedAddress.port = 0;
|
||||
memset(& host -> receivedPeerAddress, 0, sizeof (host -> receivedPeerAddress));
|
||||
memset(& host -> receivedLocalAddress, 0, sizeof (host -> receivedLocalAddress));
|
||||
host -> receivedData = NULL;
|
||||
host -> receivedDataLength = 0;
|
||||
|
||||
@@ -104,6 +100,9 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
|
||||
|
||||
host -> connectedPeers = 0;
|
||||
host -> bandwidthLimitedPeers = 0;
|
||||
host -> duplicatePeers = ENET_PROTOCOL_MAXIMUM_PEER_ID;
|
||||
host -> maximumPacketSize = ENET_HOST_DEFAULT_MAXIMUM_PACKET_SIZE;
|
||||
host -> maximumWaitingData = ENET_HOST_DEFAULT_MAXIMUM_WAITING_DATA;
|
||||
|
||||
host -> compressor.context = NULL;
|
||||
host -> compressor.compress = NULL;
|
||||
@@ -126,8 +125,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
|
||||
enet_list_clear (& currentPeer -> acknowledgements);
|
||||
enet_list_clear (& currentPeer -> sentReliableCommands);
|
||||
enet_list_clear (& currentPeer -> sentUnreliableCommands);
|
||||
enet_list_clear (& currentPeer -> outgoingReliableCommands);
|
||||
enet_list_clear (& currentPeer -> outgoingUnreliableCommands);
|
||||
enet_list_clear (& currentPeer -> outgoingCommands);
|
||||
enet_list_clear (& currentPeer -> dispatchedCommands);
|
||||
|
||||
enet_peer_reset (currentPeer);
|
||||
@@ -163,6 +161,16 @@ enet_host_destroy (ENetHost * host)
|
||||
enet_free (host);
|
||||
}
|
||||
|
||||
enet_uint32
|
||||
enet_host_random (ENetHost * host)
|
||||
{
|
||||
/* Mulberry32 by Tommy Ettinger */
|
||||
enet_uint32 n = (host -> randomSeed += 0x6D2B79F5U);
|
||||
n = (n ^ (n >> 15)) * (n | 1U);
|
||||
n ^= n + (n ^ (n >> 7)) * (n | 61U);
|
||||
return n ^ (n >> 14);
|
||||
}
|
||||
|
||||
/** Initiates a connection to a foreign host.
|
||||
@param host host seeking the connection
|
||||
@param address destination for the connection
|
||||
@@ -202,7 +210,7 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC
|
||||
currentPeer -> channelCount = channelCount;
|
||||
currentPeer -> state = ENET_PEER_STATE_CONNECTING;
|
||||
currentPeer -> address = * address;
|
||||
currentPeer -> connectID = ++ host -> randomSeed;
|
||||
currentPeer -> connectID = enet_host_random (host);
|
||||
|
||||
if (host -> outgoingBandwidth == 0)
|
||||
currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
|
||||
@@ -254,30 +262,6 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC
|
||||
return currentPeer;
|
||||
}
|
||||
|
||||
/** Queues a packet to be sent to all peers associated with the host.
|
||||
@param host host on which to broadcast the packet
|
||||
@param channelID channel on which to broadcast
|
||||
@param packet packet to broadcast
|
||||
*/
|
||||
void
|
||||
enet_host_broadcast (ENetHost * host, enet_uint8 channelID, ENetPacket * packet)
|
||||
{
|
||||
ENetPeer * currentPeer;
|
||||
|
||||
for (currentPeer = host -> peers;
|
||||
currentPeer < & host -> peers [host -> peerCount];
|
||||
++ currentPeer)
|
||||
{
|
||||
if (currentPeer -> state != ENET_PEER_STATE_CONNECTED)
|
||||
continue;
|
||||
|
||||
enet_peer_send (currentPeer, channelID, packet);
|
||||
}
|
||||
|
||||
if (packet -> referenceCount == 0)
|
||||
enet_packet_destroy (packet);
|
||||
}
|
||||
|
||||
/** Sets the packet compressor the host should use to compress and decompress packets.
|
||||
@param host host to enable or disable compression for
|
||||
@param compressor callbacks for for the packet compressor; if NULL, then compression is disabled
|
||||
|
||||
+49
-61
@@ -25,7 +25,7 @@ extern "C"
|
||||
|
||||
#define ENET_VERSION_MAJOR 1
|
||||
#define ENET_VERSION_MINOR 3
|
||||
#define ENET_VERSION_PATCH 8
|
||||
#define ENET_VERSION_PATCH 17
|
||||
#define ENET_VERSION_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch))
|
||||
#define ENET_VERSION_GET_MAJOR(version) (((version)>>16)&0xFF)
|
||||
#define ENET_VERSION_GET_MINOR(version) (((version)>>8)&0xFF)
|
||||
@@ -55,12 +55,14 @@ typedef enum _ENetSocketWait
|
||||
typedef enum _ENetSocketOption
|
||||
{
|
||||
ENET_SOCKOPT_NONBLOCK = 1,
|
||||
ENET_SOCKOPT_BROADCAST = 2,
|
||||
ENET_SOCKOPT_RCVBUF = 3,
|
||||
ENET_SOCKOPT_SNDBUF = 4,
|
||||
ENET_SOCKOPT_REUSEADDR = 5,
|
||||
ENET_SOCKOPT_RCVTIMEO = 6,
|
||||
ENET_SOCKOPT_SNDTIMEO = 7
|
||||
ENET_SOCKOPT_RCVBUF,
|
||||
ENET_SOCKOPT_SNDBUF,
|
||||
ENET_SOCKOPT_REUSEADDR,
|
||||
ENET_SOCKOPT_RCVTIMEO,
|
||||
ENET_SOCKOPT_SNDTIMEO,
|
||||
ENET_SOCKOPT_ERROR,
|
||||
ENET_SOCKOPT_NODELAY,
|
||||
ENET_SOCKOPT_QOS,
|
||||
} ENetSocketOption;
|
||||
|
||||
typedef enum _ENetSocketShutdown
|
||||
@@ -70,28 +72,13 @@ typedef enum _ENetSocketShutdown
|
||||
ENET_SOCKET_SHUTDOWN_READ_WRITE = 2
|
||||
} ENetSocketShutdown;
|
||||
|
||||
enum
|
||||
{
|
||||
ENET_HOST_ANY = 0, /**< specifies the default server host */
|
||||
ENET_HOST_BROADCAST = 0xFFFFFFFF, /**< specifies a subnet-wide broadcast */
|
||||
|
||||
ENET_PORT_ANY = 0 /**< specifies that a port should be automatically chosen */
|
||||
};
|
||||
|
||||
/**
|
||||
* Portable internet address structure.
|
||||
*
|
||||
* The host must be specified in network byte-order, and the port must be in host
|
||||
* byte-order. The constant ENET_HOST_ANY may be used to specify the default
|
||||
* server host. The constant ENET_HOST_BROADCAST may be used to specify the
|
||||
* broadcast address (255.255.255.255). This makes sense for enet_host_connect,
|
||||
* but not for enet_host_create. Once a server responds to a broadcast, the
|
||||
* address is updated from ENET_HOST_BROADCAST to the server's actual IP address.
|
||||
*/
|
||||
typedef struct _ENetAddress
|
||||
{
|
||||
enet_uint32 host;
|
||||
enet_uint16 port;
|
||||
socklen_t addressLength;
|
||||
struct sockaddr_storage address;
|
||||
} ENetAddress;
|
||||
|
||||
/**
|
||||
@@ -140,7 +127,11 @@ typedef void (ENET_CALLBACK * ENetPacketFreeCallback) (struct _ENetPacket *);
|
||||
* (not supported for reliable packets)
|
||||
*
|
||||
* ENET_PACKET_FLAG_NO_ALLOCATE - packet will not allocate data, and user must supply it instead
|
||||
|
||||
*
|
||||
* ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT - packet will be fragmented using unreliable
|
||||
* (instead of reliable) sends if it exceeds the MTU
|
||||
*
|
||||
* ENET_PACKET_FLAG_SENT - whether the packet has been sent from all queues it has been entered into
|
||||
@sa ENetPacketFlag
|
||||
*/
|
||||
typedef struct _ENetPacket
|
||||
@@ -210,7 +201,9 @@ enum
|
||||
ENET_HOST_RECEIVE_BUFFER_SIZE = 256 * 1024,
|
||||
ENET_HOST_SEND_BUFFER_SIZE = 256 * 1024,
|
||||
ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL = 1000,
|
||||
ENET_HOST_DEFAULT_MTU = 1400,
|
||||
ENET_HOST_DEFAULT_MTU = 900,
|
||||
ENET_HOST_DEFAULT_MAXIMUM_PACKET_SIZE = 32 * 1024 * 1024,
|
||||
ENET_HOST_DEFAULT_MAXIMUM_WAITING_DATA = 32 * 1024 * 1024,
|
||||
|
||||
ENET_PEER_DEFAULT_ROUND_TRIP_TIME = 500,
|
||||
ENET_PEER_DEFAULT_PACKET_THROTTLE = 32,
|
||||
@@ -246,6 +239,11 @@ typedef struct _ENetChannel
|
||||
ENetList incomingUnreliableCommands;
|
||||
} ENetChannel;
|
||||
|
||||
typedef enum _ENetPeerFlag
|
||||
{
|
||||
ENET_PEER_FLAG_NEEDS_DISPATCH = (1 << 0)
|
||||
} ENetPeerFlag;
|
||||
|
||||
/**
|
||||
* An ENet peer which data packets may be sent or received from.
|
||||
*
|
||||
@@ -261,6 +259,7 @@ typedef struct _ENetPeer
|
||||
enet_uint8 outgoingSessionID;
|
||||
enet_uint8 incomingSessionID;
|
||||
ENetAddress address; /**< Internet address of the peer */
|
||||
ENetAddress localAddress;
|
||||
void * data; /**< Application private data, may be freely modified */
|
||||
ENetPeerState state;
|
||||
ENetChannel * channels;
|
||||
@@ -304,14 +303,15 @@ typedef struct _ENetPeer
|
||||
ENetList acknowledgements;
|
||||
ENetList sentReliableCommands;
|
||||
ENetList sentUnreliableCommands;
|
||||
ENetList outgoingReliableCommands;
|
||||
ENetList outgoingUnreliableCommands;
|
||||
ENetList outgoingCommands;
|
||||
ENetList dispatchedCommands;
|
||||
int needsDispatch;
|
||||
enet_uint16 flags;
|
||||
enet_uint16 reserved;
|
||||
enet_uint16 incomingUnsequencedGroup;
|
||||
enet_uint16 outgoingUnsequencedGroup;
|
||||
enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32];
|
||||
enet_uint32 eventData;
|
||||
size_t totalWaitingData;
|
||||
} ENetPeer;
|
||||
|
||||
/** An ENet packet compressor for compressing UDP packets before socket sends or receives.
|
||||
@@ -343,7 +343,6 @@ typedef int (ENET_CALLBACK * ENetInterceptCallback) (struct _ENetHost * host, st
|
||||
@sa enet_host_connect()
|
||||
@sa enet_host_service()
|
||||
@sa enet_host_flush()
|
||||
@sa enet_host_broadcast()
|
||||
@sa enet_host_compress()
|
||||
@sa enet_host_compress_with_range_coder()
|
||||
@sa enet_host_channel_limit()
|
||||
@@ -375,7 +374,8 @@ typedef struct _ENetHost
|
||||
ENetChecksumCallback checksum; /**< callback the user can set to enable packet checksums for this host */
|
||||
ENetCompressor compressor;
|
||||
enet_uint8 packetData [2][ENET_PROTOCOL_MAXIMUM_MTU];
|
||||
ENetAddress receivedAddress;
|
||||
ENetAddress receivedPeerAddress;
|
||||
ENetAddress receivedLocalAddress;
|
||||
enet_uint8 * receivedData;
|
||||
size_t receivedDataLength;
|
||||
enet_uint32 totalSentData; /**< total data sent, user should reset to 0 as needed to prevent overflow */
|
||||
@@ -385,6 +385,9 @@ typedef struct _ENetHost
|
||||
ENetInterceptCallback intercept; /**< callback the user can set to intercept received raw UDP packets */
|
||||
size_t connectedPeers;
|
||||
size_t bandwidthLimitedPeers;
|
||||
size_t duplicatePeers; /**< optional number of allowed peers from duplicate IPs, defaults to ENET_PROTOCOL_MAXIMUM_PEER_ID */
|
||||
size_t maximumPacketSize; /**< the maximum allowable packet size that may be sent or received on a peer */
|
||||
size_t maximumWaitingData; /**< the maximum aggregate amount of buffer space a peer may use waiting for packets to be delivered */
|
||||
} ENetHost;
|
||||
|
||||
/**
|
||||
@@ -401,7 +404,7 @@ typedef enum _ENetEventType
|
||||
ENET_EVENT_TYPE_CONNECT = 1,
|
||||
|
||||
/** a peer has disconnected. This event is generated on a successful
|
||||
* completion of a disconnect initiated by enet_pper_disconnect, if
|
||||
* completion of a disconnect initiated by enet_peer_disconnect, if
|
||||
* a peer has timed out, or if a connection request intialized by
|
||||
* enet_host_connect has timed out. The peer field contains the peer
|
||||
* which disconnected. The data field contains user supplied data
|
||||
@@ -447,7 +450,7 @@ ENET_API int enet_initialize (void);
|
||||
Initializes ENet globally and supplies user-overridden callbacks. Must be called prior to using any functions in ENet. Do not use enet_initialize() if you use this variant. Make sure the ENetCallbacks structure is zeroed out so that any additional callbacks added in future versions will be properly ignored.
|
||||
|
||||
@param version the constant ENET_VERSION should be supplied so ENet knows which version of ENetCallbacks struct to use
|
||||
@param inits user-overriden callbacks where any NULL callbacks will use ENet's defaults
|
||||
@param inits user-overridden callbacks where any NULL callbacks will use ENet's defaults
|
||||
@returns 0 on success, < 0 on failure
|
||||
*/
|
||||
ENET_API int enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits);
|
||||
@@ -481,16 +484,17 @@ ENET_API void enet_time_set (enet_uint32);
|
||||
/** @defgroup socket ENet socket functions
|
||||
@{
|
||||
*/
|
||||
ENET_API ENetSocket enet_socket_create (ENetSocketType);
|
||||
ENET_API ENetSocket enet_socket_create (int, ENetSocketType);
|
||||
ENET_API int enet_socket_bind (ENetSocket, const ENetAddress *);
|
||||
ENET_API int enet_socket_get_address (ENetSocket, ENetAddress *);
|
||||
ENET_API int enet_socket_listen (ENetSocket, int);
|
||||
ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *);
|
||||
ENET_API int enet_socket_connect (ENetSocket, const ENetAddress *);
|
||||
ENET_API int enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t);
|
||||
ENET_API int enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t);
|
||||
ENET_API int enet_socket_send (ENetSocket, const ENetAddress *, const ENetAddress *, const ENetBuffer *, size_t);
|
||||
ENET_API int enet_socket_receive (ENetSocket, ENetAddress *, ENetAddress *, ENetBuffer *, size_t);
|
||||
ENET_API int enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32);
|
||||
ENET_API int enet_socket_set_option (ENetSocket, ENetSocketOption, int);
|
||||
ENET_API int enet_socket_get_option (ENetSocket, ENetSocketOption, int *);
|
||||
ENET_API int enet_socket_shutdown (ENetSocket, ENetSocketShutdown);
|
||||
ENET_API void enet_socket_destroy (ENetSocket);
|
||||
ENET_API int enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSocketSet *, enet_uint32);
|
||||
@@ -509,26 +513,9 @@ ENET_API int enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSock
|
||||
@returns the address of the given hostName in address on success
|
||||
*/
|
||||
ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName);
|
||||
|
||||
/** Gives the printable form of the ip address specified in the address parameter.
|
||||
@param address address printed
|
||||
@param hostName destination for name, must not be NULL
|
||||
@param nameLength maximum length of hostName.
|
||||
@returns the null-terminated name of the host in hostName on success
|
||||
@retval 0 on success
|
||||
@retval < 0 on failure
|
||||
*/
|
||||
ENET_API int enet_address_get_host_ip (const ENetAddress * address, char * hostName, size_t nameLength);
|
||||
|
||||
/** Attempts to do a reverse lookup of the host field in the address parameter.
|
||||
@param address address used for reverse lookup
|
||||
@param hostName destination for name, must not be NULL
|
||||
@param nameLength maximum length of hostName.
|
||||
@returns the null-terminated name of the host in hostName on success
|
||||
@retval 0 on success
|
||||
@retval < 0 on failure
|
||||
*/
|
||||
ENET_API int enet_address_get_host (const ENetAddress * address, char * hostName, size_t nameLength);
|
||||
ENET_API int enet_address_set_address (ENetAddress * address, struct sockaddr * addr, socklen_t addrlen);
|
||||
ENET_API int enet_address_set_port (ENetAddress * address, enet_uint16 port);
|
||||
ENET_API int enet_address_equal (ENetAddress * address1, ENetAddress * address2);
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -537,18 +524,19 @@ ENET_API void enet_packet_destroy (ENetPacket *);
|
||||
ENET_API int enet_packet_resize (ENetPacket *, size_t);
|
||||
ENET_API enet_uint32 enet_crc32 (const ENetBuffer *, size_t);
|
||||
|
||||
ENET_API ENetHost * enet_host_create (const ENetAddress *, size_t, size_t, enet_uint32, enet_uint32);
|
||||
ENET_API ENetHost * enet_host_create (int, const ENetAddress *, size_t, size_t, enet_uint32, enet_uint32);
|
||||
ENET_API void enet_host_destroy (ENetHost *);
|
||||
ENET_API ENetPeer * enet_host_connect (ENetHost *, const ENetAddress *, size_t, enet_uint32);
|
||||
ENET_API int enet_host_check_events (ENetHost *, ENetEvent *);
|
||||
ENET_API int enet_host_service (ENetHost *, ENetEvent *, enet_uint32);
|
||||
ENET_API void enet_host_flush (ENetHost *);
|
||||
ENET_API void enet_host_broadcast (ENetHost *, enet_uint8, ENetPacket *);
|
||||
ENET_API void enet_host_compress (ENetHost *, const ENetCompressor *);
|
||||
ENET_API int enet_host_compress_with_range_coder (ENetHost * host);
|
||||
ENET_API void enet_host_channel_limit (ENetHost *, size_t);
|
||||
ENET_API void enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32);
|
||||
extern void enet_host_bandwidth_throttle (ENetHost *);
|
||||
extern enet_uint32 enet_host_random_seed (void);
|
||||
extern enet_uint32 enet_host_random (ENetHost *);
|
||||
|
||||
ENET_API int enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *);
|
||||
ENET_API ENetPacket * enet_peer_receive (ENetPeer *, enet_uint8 * channelID);
|
||||
@@ -564,10 +552,10 @@ extern int enet_peer_throttle (ENetPeer *, enet_uint32);
|
||||
extern void enet_peer_reset_queues (ENetPeer *);
|
||||
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 ENetIncomingCommand * enet_peer_queue_incoming_command (ENetPeer *, const ENetProtocol *, ENetPacket *, 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 void enet_peer_dispatch_incoming_unreliable_commands (ENetPeer *, ENetChannel *);
|
||||
extern void enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *);
|
||||
extern void enet_peer_dispatch_incoming_unreliable_commands (ENetPeer *, ENetChannel *, ENetIncomingCommand *);
|
||||
extern void enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *, ENetIncomingCommand *);
|
||||
extern void enet_peer_on_connect (ENetPeer *);
|
||||
extern void enet_peer_on_disconnect (ENetPeer *);
|
||||
|
||||
|
||||
@@ -10,14 +10,17 @@
|
||||
enum
|
||||
{
|
||||
ENET_PROTOCOL_MINIMUM_MTU = 576,
|
||||
#ifdef __WIIU__
|
||||
ENET_PROTOCOL_MAXIMUM_MTU = 1400,
|
||||
#else
|
||||
ENET_PROTOCOL_MAXIMUM_MTU = 4096,
|
||||
#endif
|
||||
ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS = 32,
|
||||
ENET_PROTOCOL_MINIMUM_WINDOW_SIZE = 4096,
|
||||
ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 32768,
|
||||
ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 65536,
|
||||
ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT = 1,
|
||||
ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT = 255,
|
||||
ENET_PROTOCOL_MAXIMUM_PEER_ID = 0xFFF,
|
||||
ENET_PROTOCOL_MAXIMUM_PACKET_SIZE = 1024 * 1024 * 1024,
|
||||
ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT = 1024 * 1024
|
||||
};
|
||||
|
||||
@@ -54,7 +57,7 @@ typedef enum _ENetProtocolFlag
|
||||
ENET_PROTOCOL_HEADER_SESSION_SHIFT = 12
|
||||
} ENetProtocolFlag;
|
||||
|
||||
#ifdef _MSC_VER_
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(push, 1)
|
||||
#define ENET_PACKED
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
@@ -191,7 +194,7 @@ typedef union _ENetProtocol
|
||||
ENetProtocolThrottleConfigure throttleConfigure;
|
||||
} ENET_PACKED ENetProtocol;
|
||||
|
||||
#ifdef _MSC_VER_
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
|
||||
+3
-5
@@ -9,6 +9,7 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -18,10 +19,7 @@
|
||||
|
||||
typedef int ENetSocket;
|
||||
|
||||
enum
|
||||
{
|
||||
ENET_SOCKET_NULL = -1
|
||||
};
|
||||
#define ENET_SOCKET_NULL -1
|
||||
|
||||
#define ENET_HOST_TO_NET_16(value) (htons (value)) /**< macro that converts host to net byte-order of a 16-bit value */
|
||||
#define ENET_HOST_TO_NET_32(value) (htonl (value)) /**< macro that converts host to net byte-order of a 32-bit value */
|
||||
@@ -43,7 +41,7 @@ typedef fd_set ENetSocketSet;
|
||||
|
||||
#define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset))
|
||||
#define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset))
|
||||
#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset))
|
||||
#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLR (socket, & (sockset))
|
||||
#define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset))
|
||||
|
||||
#endif /* __ENET_UNIX_H__ */
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#define ENET_MAX(x, y) ((x) > (y) ? (x) : (y))
|
||||
#define ENET_MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
#define ENET_DIFFERENCE(x, y) ((x) < (y) ? (y) - (x) : (x) - (y))
|
||||
|
||||
#endif /* __ENET_UTILITY_H__ */
|
||||
|
||||
|
||||
@@ -7,22 +7,22 @@
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifdef ENET_BUILDING_LIB
|
||||
#pragma warning (disable: 4996) // 'strncpy' was declared deprecated
|
||||
#pragma warning (disable: 4267) // size_t to int conversion
|
||||
#pragma warning (disable: 4244) // 64bit to 32bit int
|
||||
#pragma warning (disable: 4018) // signed/unsigned mismatch
|
||||
#pragma warning (disable: 4146) // unary minus operator applied to unsigned type
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <winsock2.h>
|
||||
#include <Ws2tcpip.h>
|
||||
|
||||
typedef SOCKET ENetSocket;
|
||||
|
||||
enum
|
||||
{
|
||||
ENET_SOCKET_NULL = INVALID_SOCKET
|
||||
};
|
||||
#define ENET_SOCKET_NULL INVALID_SOCKET
|
||||
|
||||
#define ENET_HOST_TO_NET_16(value) (htons (value))
|
||||
#define ENET_HOST_TO_NET_32(value) (htonl (value))
|
||||
@@ -52,7 +52,7 @@ typedef fd_set ENetSocketSet;
|
||||
|
||||
#define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset))
|
||||
#define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset))
|
||||
#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset))
|
||||
#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLR (socket, & (sockset))
|
||||
#define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset))
|
||||
|
||||
#endif /* __ENET_WIN32_H__ */
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
*/
|
||||
|
||||
/** Creates a packet that may be sent to a peer.
|
||||
@param dataContents initial contents of the packet's data; the packet's data will remain uninitialized if dataContents is NULL.
|
||||
@param data initial contents of the packet's data; the packet's data will remain uninitialized if data is NULL.
|
||||
@param dataLength size of the data allocated for this packet
|
||||
@param flags flags for this packet as described for the ENetPacket structure.
|
||||
@returns the packet on success, NULL on failure
|
||||
|
||||
@@ -66,7 +66,7 @@ enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt)
|
||||
peer -> packetThrottle = peer -> packetThrottleLimit;
|
||||
}
|
||||
else
|
||||
if (rtt < peer -> lastRoundTripTime)
|
||||
if (rtt <= peer -> lastRoundTripTime)
|
||||
{
|
||||
peer -> packetThrottle += peer -> packetThrottleAcceleration;
|
||||
|
||||
@@ -99,15 +99,16 @@ enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt)
|
||||
int
|
||||
enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
|
||||
{
|
||||
ENetChannel * channel = & peer -> channels [channelID];
|
||||
ENetChannel * channel;
|
||||
ENetProtocol command;
|
||||
size_t fragmentLength;
|
||||
|
||||
if (peer -> state != ENET_PEER_STATE_CONNECTED ||
|
||||
channelID >= peer -> channelCount ||
|
||||
packet -> dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE)
|
||||
packet -> dataLength > peer -> host -> maximumPacketSize)
|
||||
return -1;
|
||||
|
||||
channel = & peer -> channels [channelID];
|
||||
fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment);
|
||||
if (peer -> host -> checksum != NULL)
|
||||
fragmentLength -= sizeof(enet_uint32);
|
||||
@@ -241,6 +242,8 @@ enet_peer_receive (ENetPeer * peer, enet_uint8 * channelID)
|
||||
|
||||
enet_free (incomingCommand);
|
||||
|
||||
peer -> totalWaitingData -= packet -> dataLength;
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
@@ -266,7 +269,7 @@ enet_peer_reset_outgoing_commands (ENetList * queue)
|
||||
}
|
||||
|
||||
static void
|
||||
enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startCommand, ENetListIterator endCommand)
|
||||
enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startCommand, ENetListIterator endCommand, ENetIncomingCommand * excludeCommand)
|
||||
{
|
||||
ENetListIterator currentCommand;
|
||||
|
||||
@@ -276,6 +279,9 @@ enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startComm
|
||||
|
||||
currentCommand = enet_list_next (currentCommand);
|
||||
|
||||
if (incomingCommand == excludeCommand)
|
||||
continue;
|
||||
|
||||
enet_list_remove (& incomingCommand -> incomingCommandList);
|
||||
|
||||
if (incomingCommand -> packet != NULL)
|
||||
@@ -296,7 +302,7 @@ enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startComm
|
||||
static void
|
||||
enet_peer_reset_incoming_commands (ENetList * queue)
|
||||
{
|
||||
enet_peer_remove_incoming_commands(queue, enet_list_begin (queue), enet_list_end (queue));
|
||||
enet_peer_remove_incoming_commands(queue, enet_list_begin (queue), enet_list_end (queue), NULL);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -304,11 +310,11 @@ enet_peer_reset_queues (ENetPeer * peer)
|
||||
{
|
||||
ENetChannel * channel;
|
||||
|
||||
if (peer -> needsDispatch)
|
||||
if (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH)
|
||||
{
|
||||
enet_list_remove (& peer -> dispatchList);
|
||||
|
||||
peer -> needsDispatch = 0;
|
||||
peer -> flags &= ~ ENET_PEER_FLAG_NEEDS_DISPATCH;
|
||||
}
|
||||
|
||||
while (! enet_list_empty (& peer -> acknowledgements))
|
||||
@@ -316,8 +322,7 @@ enet_peer_reset_queues (ENetPeer * peer)
|
||||
|
||||
enet_peer_reset_outgoing_commands (& peer -> sentReliableCommands);
|
||||
enet_peer_reset_outgoing_commands (& peer -> sentUnreliableCommands);
|
||||
enet_peer_reset_outgoing_commands (& peer -> outgoingReliableCommands);
|
||||
enet_peer_reset_outgoing_commands (& peer -> outgoingUnreliableCommands);
|
||||
enet_peer_reset_outgoing_commands (& peer -> outgoingCommands);
|
||||
enet_peer_reset_incoming_commands (& peer -> dispatchedCommands);
|
||||
|
||||
if (peer -> channels != NULL && peer -> channelCount > 0)
|
||||
@@ -415,6 +420,8 @@ enet_peer_reset (ENetPeer * peer)
|
||||
peer -> incomingUnsequencedGroup = 0;
|
||||
peer -> outgoingUnsequencedGroup = 0;
|
||||
peer -> eventData = 0;
|
||||
peer -> totalWaitingData = 0;
|
||||
peer -> flags = 0;
|
||||
|
||||
memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow));
|
||||
|
||||
@@ -424,7 +431,7 @@ enet_peer_reset (ENetPeer * peer)
|
||||
/** Sends a ping request to a peer.
|
||||
@param peer destination for the ping request
|
||||
@remarks ping requests factor into the mean round trip time as designated by the
|
||||
roundTripTime field in the ENetPeer structure. Enet automatically pings all connected
|
||||
roundTripTime field in the ENetPeer structure. ENet automatically pings all connected
|
||||
peers at regular intervals, however, this function may be called to ensure more
|
||||
frequent ping requests.
|
||||
*/
|
||||
@@ -486,7 +493,7 @@ enet_peer_timeout (ENetPeer * peer, enet_uint32 timeoutLimit, enet_uint32 timeou
|
||||
@param peer peer to disconnect
|
||||
@param data data describing the disconnection
|
||||
@remarks No ENET_EVENT_DISCONNECT event will be generated. The foreign peer is not
|
||||
guarenteed to receive the disconnect notification, and is reset immediately upon
|
||||
guaranteed to receive the disconnect notification, and is reset immediately upon
|
||||
return from this function.
|
||||
*/
|
||||
void
|
||||
@@ -567,8 +574,7 @@ void
|
||||
enet_peer_disconnect_later (ENetPeer * peer, enet_uint32 data)
|
||||
{
|
||||
if ((peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) &&
|
||||
! (enet_list_empty (& peer -> outgoingReliableCommands) &&
|
||||
enet_list_empty (& peer -> outgoingUnreliableCommands) &&
|
||||
! (enet_list_empty (& peer -> outgoingCommands) &&
|
||||
enet_list_empty (& peer -> sentReliableCommands)))
|
||||
{
|
||||
peer -> state = ENET_PEER_STATE_DISCONNECT_LATER;
|
||||
@@ -670,10 +676,7 @@ enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoin
|
||||
break;
|
||||
}
|
||||
|
||||
if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
|
||||
enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand);
|
||||
else
|
||||
enet_list_insert (enet_list_end (& peer -> outgoingUnreliableCommands), outgoingCommand);
|
||||
enet_list_insert (enet_list_end (& peer -> outgoingCommands), outgoingCommand);
|
||||
}
|
||||
|
||||
ENetOutgoingCommand *
|
||||
@@ -696,7 +699,7 @@ enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command,
|
||||
}
|
||||
|
||||
void
|
||||
enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel)
|
||||
enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel, ENetIncomingCommand * queuedCommand)
|
||||
{
|
||||
ENetListIterator droppedCommand, startCommand, currentCommand;
|
||||
|
||||
@@ -721,11 +724,11 @@ enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel *
|
||||
{
|
||||
enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand));
|
||||
|
||||
if (! peer -> needsDispatch)
|
||||
if (! (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH))
|
||||
{
|
||||
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
|
||||
|
||||
peer -> needsDispatch = 1;
|
||||
peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
|
||||
}
|
||||
|
||||
droppedCommand = currentCommand;
|
||||
@@ -749,11 +752,11 @@ enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel *
|
||||
{
|
||||
enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand));
|
||||
|
||||
if (! peer -> needsDispatch)
|
||||
if (! (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH))
|
||||
{
|
||||
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
|
||||
|
||||
peer -> needsDispatch = 1;
|
||||
peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -765,21 +768,21 @@ enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel *
|
||||
{
|
||||
enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand));
|
||||
|
||||
if (! peer -> needsDispatch)
|
||||
if (! (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH))
|
||||
{
|
||||
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
|
||||
|
||||
peer -> needsDispatch = 1;
|
||||
peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
|
||||
}
|
||||
|
||||
droppedCommand = currentCommand;
|
||||
}
|
||||
|
||||
enet_peer_remove_incoming_commands (& channel -> incomingUnreliableCommands, enet_list_begin (& channel -> incomingUnreliableCommands), droppedCommand);
|
||||
enet_peer_remove_incoming_commands (& channel -> incomingUnreliableCommands, enet_list_begin (& channel -> incomingUnreliableCommands), droppedCommand, queuedCommand);
|
||||
}
|
||||
|
||||
void
|
||||
enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * channel)
|
||||
enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * channel, ENetIncomingCommand * queuedCommand)
|
||||
{
|
||||
ENetListIterator currentCommand;
|
||||
|
||||
@@ -806,19 +809,19 @@ enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * ch
|
||||
|
||||
enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingReliableCommands), enet_list_previous (currentCommand));
|
||||
|
||||
if (! peer -> needsDispatch)
|
||||
if (! (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH))
|
||||
{
|
||||
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
|
||||
|
||||
peer -> needsDispatch = 1;
|
||||
peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
|
||||
}
|
||||
|
||||
if (! enet_list_empty (& channel -> incomingUnreliableCommands))
|
||||
enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
|
||||
enet_peer_dispatch_incoming_unreliable_commands (peer, channel, queuedCommand);
|
||||
}
|
||||
|
||||
ENetIncomingCommand *
|
||||
enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 fragmentCount)
|
||||
enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, const void * data, size_t dataLength, enet_uint32 flags, enet_uint32 fragmentCount)
|
||||
{
|
||||
static ENetIncomingCommand dummyCommand;
|
||||
|
||||
@@ -827,9 +830,10 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
|
||||
enet_uint16 reliableWindow, currentWindow;
|
||||
ENetIncomingCommand * incomingCommand;
|
||||
ENetListIterator currentCommand;
|
||||
ENetPacket * packet = NULL;
|
||||
|
||||
if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
|
||||
goto freePacket;
|
||||
goto discardCommand;
|
||||
|
||||
if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED)
|
||||
{
|
||||
@@ -841,7 +845,7 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
|
||||
reliableWindow += ENET_PEER_RELIABLE_WINDOWS;
|
||||
|
||||
if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1)
|
||||
goto freePacket;
|
||||
goto discardCommand;
|
||||
}
|
||||
|
||||
switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK)
|
||||
@@ -849,7 +853,7 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
|
||||
case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
|
||||
case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
|
||||
if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber)
|
||||
goto freePacket;
|
||||
goto discardCommand;
|
||||
|
||||
for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands));
|
||||
currentCommand != enet_list_end (& channel -> incomingReliableCommands);
|
||||
@@ -871,7 +875,7 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
|
||||
if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber)
|
||||
break;
|
||||
|
||||
goto freePacket;
|
||||
goto discardCommand;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -882,7 +886,7 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
|
||||
|
||||
if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber &&
|
||||
unreliableSequenceNumber <= channel -> incomingUnreliableSequenceNumber)
|
||||
goto freePacket;
|
||||
goto discardCommand;
|
||||
|
||||
for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands));
|
||||
currentCommand != enet_list_end (& channel -> incomingUnreliableCommands);
|
||||
@@ -913,7 +917,7 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
|
||||
if (incomingCommand -> unreliableSequenceNumber < unreliableSequenceNumber)
|
||||
break;
|
||||
|
||||
goto freePacket;
|
||||
goto discardCommand;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -923,9 +927,16 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
|
||||
break;
|
||||
|
||||
default:
|
||||
goto freePacket;
|
||||
goto discardCommand;
|
||||
}
|
||||
|
||||
if (peer -> totalWaitingData >= peer -> host -> maximumWaitingData)
|
||||
goto notifyError;
|
||||
|
||||
packet = enet_packet_create (data, dataLength, flags);
|
||||
if (packet == NULL)
|
||||
goto notifyError;
|
||||
|
||||
incomingCommand = (ENetIncomingCommand *) enet_malloc (sizeof (ENetIncomingCommand));
|
||||
if (incomingCommand == NULL)
|
||||
goto notifyError;
|
||||
@@ -952,7 +963,11 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
|
||||
}
|
||||
|
||||
if (packet != NULL)
|
||||
++ packet -> referenceCount;
|
||||
{
|
||||
++ packet -> referenceCount;
|
||||
|
||||
peer -> totalWaitingData += packet -> dataLength;
|
||||
}
|
||||
|
||||
enet_list_insert (enet_list_next (currentCommand), incomingCommand);
|
||||
|
||||
@@ -960,17 +975,17 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
|
||||
{
|
||||
case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
|
||||
case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
|
||||
enet_peer_dispatch_incoming_reliable_commands (peer, channel);
|
||||
enet_peer_dispatch_incoming_reliable_commands (peer, channel, incomingCommand);
|
||||
break;
|
||||
|
||||
default:
|
||||
enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
|
||||
enet_peer_dispatch_incoming_unreliable_commands (peer, channel, incomingCommand);
|
||||
break;
|
||||
}
|
||||
|
||||
return incomingCommand;
|
||||
|
||||
freePacket:
|
||||
discardCommand:
|
||||
if (fragmentCount > 0)
|
||||
goto notifyError;
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
solution "enet"
|
||||
configurations { "Debug", "Release" }
|
||||
platforms { "x32", "x64" }
|
||||
|
||||
project "enet_static"
|
||||
kind "StaticLib"
|
||||
language "C"
|
||||
|
||||
files { "*.c" }
|
||||
|
||||
includedirs { "include/" }
|
||||
|
||||
configuration "Debug"
|
||||
targetsuffix "d"
|
||||
|
||||
defines({ "DEBUG" })
|
||||
|
||||
flags { "Symbols" }
|
||||
|
||||
configuration "Release"
|
||||
defines({ "NDEBUG" })
|
||||
|
||||
flags { "Optimize" }
|
||||
|
||||
configuration { "Debug", "x64" }
|
||||
targetsuffix "64d"
|
||||
|
||||
configuration { "Release", "x64" }
|
||||
targetsuffix "64"
|
||||
|
||||
project "enet"
|
||||
kind "SharedLib"
|
||||
language "C"
|
||||
|
||||
files { "*.c" }
|
||||
|
||||
includedirs { "include/" }
|
||||
|
||||
defines({"ENET_DLL=1" })
|
||||
|
||||
configuration "Debug"
|
||||
targetsuffix "d"
|
||||
|
||||
defines({ "DEBUG" })
|
||||
|
||||
flags { "Symbols" }
|
||||
|
||||
configuration "Release"
|
||||
defines({ "NDEBUG" })
|
||||
|
||||
flags { "Optimize" }
|
||||
|
||||
configuration { "Debug", "x64" }
|
||||
targetsuffix "64d"
|
||||
|
||||
configuration { "Release", "x64" }
|
||||
targetsuffix "64"
|
||||
|
||||
|
||||
+259
-309
@@ -48,11 +48,11 @@ enet_protocol_dispatch_state (ENetHost * host, ENetPeer * peer, ENetPeerState st
|
||||
{
|
||||
enet_protocol_change_state (host, peer, state);
|
||||
|
||||
if (! peer -> needsDispatch)
|
||||
if (! (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH))
|
||||
{
|
||||
enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList);
|
||||
|
||||
peer -> needsDispatch = 1;
|
||||
peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
|
||||
{
|
||||
ENetPeer * peer = (ENetPeer *) enet_list_remove (enet_list_begin (& host -> dispatchQueue));
|
||||
|
||||
peer -> needsDispatch = 0;
|
||||
peer -> flags &= ~ ENET_PEER_FLAG_NEEDS_DISPATCH;
|
||||
|
||||
switch (peer -> state)
|
||||
{
|
||||
@@ -101,7 +101,7 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
|
||||
|
||||
if (! enet_list_empty (& peer -> dispatchedCommands))
|
||||
{
|
||||
peer -> needsDispatch = 1;
|
||||
peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
|
||||
|
||||
enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList);
|
||||
}
|
||||
@@ -163,7 +163,10 @@ enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer)
|
||||
{
|
||||
ENetOutgoingCommand * outgoingCommand;
|
||||
|
||||
while (! enet_list_empty (& peer -> sentUnreliableCommands))
|
||||
if (enet_list_empty (& peer -> sentUnreliableCommands))
|
||||
return;
|
||||
|
||||
do
|
||||
{
|
||||
outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentUnreliableCommands);
|
||||
|
||||
@@ -182,7 +185,12 @@ enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer)
|
||||
}
|
||||
|
||||
enet_free (outgoingCommand);
|
||||
}
|
||||
} while (! enet_list_empty (& peer -> sentUnreliableCommands));
|
||||
|
||||
if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER &&
|
||||
enet_list_empty (& peer -> outgoingCommands) &&
|
||||
enet_list_empty (& peer -> sentReliableCommands))
|
||||
enet_peer_disconnect (peer, peer -> eventData);
|
||||
}
|
||||
|
||||
static ENetProtocolCommand
|
||||
@@ -206,12 +214,15 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl
|
||||
|
||||
if (currentCommand == enet_list_end (& peer -> sentReliableCommands))
|
||||
{
|
||||
for (currentCommand = enet_list_begin (& peer -> outgoingReliableCommands);
|
||||
currentCommand != enet_list_end (& peer -> outgoingReliableCommands);
|
||||
for (currentCommand = enet_list_begin (& peer -> outgoingCommands);
|
||||
currentCommand != enet_list_end (& peer -> outgoingCommands);
|
||||
currentCommand = enet_list_next (currentCommand))
|
||||
{
|
||||
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
|
||||
|
||||
if (! (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE))
|
||||
continue;
|
||||
|
||||
if (outgoingCommand -> sendAttempts < 1) return ENET_PROTOCOL_COMMAND_NONE;
|
||||
|
||||
if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber &&
|
||||
@@ -219,7 +230,7 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl
|
||||
break;
|
||||
}
|
||||
|
||||
if (currentCommand == enet_list_end (& peer -> outgoingReliableCommands))
|
||||
if (currentCommand == enet_list_end (& peer -> outgoingCommands))
|
||||
return ENET_PROTOCOL_COMMAND_NONE;
|
||||
|
||||
wasSent = 0;
|
||||
@@ -277,8 +288,8 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
|
||||
enet_uint8 incomingSessionID, outgoingSessionID;
|
||||
enet_uint32 mtu, windowSize;
|
||||
ENetChannel * channel;
|
||||
size_t channelCount;
|
||||
ENetPeer * currentPeer;
|
||||
size_t channelCount, duplicatePeers = 0;
|
||||
ENetPeer * currentPeer, * peer = NULL;
|
||||
ENetProtocol verifyCommand;
|
||||
|
||||
channelCount = ENET_NET_TO_HOST_32 (command -> connect.channelCount);
|
||||
@@ -287,59 +298,61 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
|
||||
channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
|
||||
return NULL;
|
||||
|
||||
for (currentPeer = host -> peers;
|
||||
currentPeer < & host -> peers [host -> peerCount];
|
||||
++ currentPeer)
|
||||
{
|
||||
if (currentPeer -> state != ENET_PEER_STATE_DISCONNECTED &&
|
||||
currentPeer -> address.host == host -> receivedAddress.host &&
|
||||
currentPeer -> address.port == host -> receivedAddress.port &&
|
||||
currentPeer -> connectID == command -> connect.connectID)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (currentPeer = host -> peers;
|
||||
currentPeer < & host -> peers [host -> peerCount];
|
||||
++ currentPeer)
|
||||
{
|
||||
if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED)
|
||||
break;
|
||||
{
|
||||
if (peer == NULL)
|
||||
peer = currentPeer;
|
||||
}
|
||||
else
|
||||
if (currentPeer -> state != ENET_PEER_STATE_CONNECTING &&
|
||||
enet_address_equal (& currentPeer -> address, & host -> receivedPeerAddress))
|
||||
{
|
||||
if (currentPeer -> connectID == command -> connect.connectID)
|
||||
return NULL;
|
||||
|
||||
++ duplicatePeers;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentPeer >= & host -> peers [host -> peerCount])
|
||||
if (peer == NULL || duplicatePeers >= host -> duplicatePeers)
|
||||
return NULL;
|
||||
|
||||
if (channelCount > host -> channelLimit)
|
||||
channelCount = host -> channelLimit;
|
||||
currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
|
||||
if (currentPeer -> channels == NULL)
|
||||
peer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
|
||||
if (peer -> channels == NULL)
|
||||
return NULL;
|
||||
currentPeer -> channelCount = channelCount;
|
||||
currentPeer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT;
|
||||
currentPeer -> connectID = command -> connect.connectID;
|
||||
currentPeer -> address = host -> receivedAddress;
|
||||
currentPeer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID);
|
||||
currentPeer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth);
|
||||
currentPeer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.outgoingBandwidth);
|
||||
currentPeer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleInterval);
|
||||
currentPeer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleAcceleration);
|
||||
currentPeer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleDeceleration);
|
||||
currentPeer -> eventData = ENET_NET_TO_HOST_32 (command -> connect.data);
|
||||
peer -> channelCount = channelCount;
|
||||
peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT;
|
||||
peer -> connectID = command -> connect.connectID;
|
||||
peer -> address = host -> receivedPeerAddress;
|
||||
peer -> localAddress = host -> receivedLocalAddress;
|
||||
peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID);
|
||||
peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth);
|
||||
peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.outgoingBandwidth);
|
||||
peer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleInterval);
|
||||
peer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleAcceleration);
|
||||
peer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleDeceleration);
|
||||
peer -> eventData = ENET_NET_TO_HOST_32 (command -> connect.data);
|
||||
|
||||
incomingSessionID = command -> connect.incomingSessionID == 0xFF ? currentPeer -> outgoingSessionID : command -> connect.incomingSessionID;
|
||||
incomingSessionID = command -> connect.incomingSessionID == 0xFF ? peer -> outgoingSessionID : command -> connect.incomingSessionID;
|
||||
incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT);
|
||||
if (incomingSessionID == currentPeer -> outgoingSessionID)
|
||||
if (incomingSessionID == peer -> outgoingSessionID)
|
||||
incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT);
|
||||
currentPeer -> outgoingSessionID = incomingSessionID;
|
||||
peer -> outgoingSessionID = incomingSessionID;
|
||||
|
||||
outgoingSessionID = command -> connect.outgoingSessionID == 0xFF ? currentPeer -> incomingSessionID : command -> connect.outgoingSessionID;
|
||||
outgoingSessionID = command -> connect.outgoingSessionID == 0xFF ? peer -> incomingSessionID : command -> connect.outgoingSessionID;
|
||||
outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT);
|
||||
if (outgoingSessionID == currentPeer -> incomingSessionID)
|
||||
if (outgoingSessionID == peer -> incomingSessionID)
|
||||
outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT);
|
||||
currentPeer -> incomingSessionID = outgoingSessionID;
|
||||
peer -> incomingSessionID = outgoingSessionID;
|
||||
|
||||
for (channel = currentPeer -> channels;
|
||||
channel < & currentPeer -> channels [channelCount];
|
||||
for (channel = peer -> channels;
|
||||
channel < & peer -> channels [channelCount];
|
||||
++ channel)
|
||||
{
|
||||
channel -> outgoingReliableSequenceNumber = 0;
|
||||
@@ -362,27 +375,27 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
|
||||
if (mtu > ENET_PROTOCOL_MAXIMUM_MTU)
|
||||
mtu = ENET_PROTOCOL_MAXIMUM_MTU;
|
||||
|
||||
currentPeer -> mtu = mtu;
|
||||
peer -> mtu = mtu;
|
||||
|
||||
if (host -> outgoingBandwidth == 0 &&
|
||||
currentPeer -> incomingBandwidth == 0)
|
||||
currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
|
||||
peer -> incomingBandwidth == 0)
|
||||
peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
|
||||
else
|
||||
if (host -> outgoingBandwidth == 0 ||
|
||||
currentPeer -> incomingBandwidth == 0)
|
||||
currentPeer -> windowSize = (ENET_MAX (host -> outgoingBandwidth, currentPeer -> incomingBandwidth) /
|
||||
peer -> incomingBandwidth == 0)
|
||||
peer -> windowSize = (ENET_MAX (host -> outgoingBandwidth, peer -> incomingBandwidth) /
|
||||
ENET_PEER_WINDOW_SIZE_SCALE) *
|
||||
ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
|
||||
else
|
||||
currentPeer -> windowSize = (ENET_MIN (host -> outgoingBandwidth, currentPeer -> incomingBandwidth) /
|
||||
peer -> windowSize = (ENET_MIN (host -> outgoingBandwidth, peer -> incomingBandwidth) /
|
||||
ENET_PEER_WINDOW_SIZE_SCALE) *
|
||||
ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
|
||||
|
||||
if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
|
||||
currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
|
||||
if (peer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
|
||||
peer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
|
||||
else
|
||||
if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
|
||||
currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
|
||||
if (peer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
|
||||
peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
|
||||
|
||||
if (host -> incomingBandwidth == 0)
|
||||
windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
|
||||
@@ -401,28 +414,27 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
|
||||
|
||||
verifyCommand.header.command = ENET_PROTOCOL_COMMAND_VERIFY_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
|
||||
verifyCommand.header.channelID = 0xFF;
|
||||
verifyCommand.verifyConnect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
|
||||
verifyCommand.verifyConnect.outgoingPeerID = ENET_HOST_TO_NET_16 (peer -> incomingPeerID);
|
||||
verifyCommand.verifyConnect.incomingSessionID = incomingSessionID;
|
||||
verifyCommand.verifyConnect.outgoingSessionID = outgoingSessionID;
|
||||
verifyCommand.verifyConnect.mtu = ENET_HOST_TO_NET_32 (currentPeer -> mtu);
|
||||
verifyCommand.verifyConnect.mtu = ENET_HOST_TO_NET_32 (peer -> mtu);
|
||||
verifyCommand.verifyConnect.windowSize = ENET_HOST_TO_NET_32 (windowSize);
|
||||
verifyCommand.verifyConnect.channelCount = ENET_HOST_TO_NET_32 (channelCount);
|
||||
verifyCommand.verifyConnect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth);
|
||||
verifyCommand.verifyConnect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
|
||||
verifyCommand.verifyConnect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval);
|
||||
verifyCommand.verifyConnect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration);
|
||||
verifyCommand.verifyConnect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration);
|
||||
verifyCommand.verifyConnect.connectID = currentPeer -> connectID;
|
||||
verifyCommand.verifyConnect.packetThrottleInterval = ENET_HOST_TO_NET_32 (peer -> packetThrottleInterval);
|
||||
verifyCommand.verifyConnect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (peer -> packetThrottleAcceleration);
|
||||
verifyCommand.verifyConnect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (peer -> packetThrottleDeceleration);
|
||||
verifyCommand.verifyConnect.connectID = peer -> connectID;
|
||||
|
||||
enet_peer_queue_outgoing_command (currentPeer, & verifyCommand, NULL, 0, 0);
|
||||
enet_peer_queue_outgoing_command (peer, & verifyCommand, NULL, 0, 0);
|
||||
|
||||
return currentPeer;
|
||||
return peer;
|
||||
}
|
||||
|
||||
static int
|
||||
enet_protocol_handle_send_reliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
|
||||
{
|
||||
ENetPacket * packet;
|
||||
size_t dataLength;
|
||||
|
||||
if (command -> header.channelID >= peer -> channelCount ||
|
||||
@@ -431,16 +443,12 @@ enet_protocol_handle_send_reliable (ENetHost * host, ENetPeer * peer, const ENet
|
||||
|
||||
dataLength = ENET_NET_TO_HOST_16 (command -> sendReliable.dataLength);
|
||||
* currentData += dataLength;
|
||||
if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
|
||||
if (dataLength > host -> maximumPacketSize ||
|
||||
* currentData < host -> receivedData ||
|
||||
* currentData > & host -> receivedData [host -> receivedDataLength])
|
||||
return -1;
|
||||
|
||||
packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendReliable),
|
||||
dataLength,
|
||||
ENET_PACKET_FLAG_RELIABLE);
|
||||
if (packet == NULL ||
|
||||
enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL)
|
||||
if (enet_peer_queue_incoming_command (peer, command, (const enet_uint8 *) command + sizeof (ENetProtocolSendReliable), dataLength, ENET_PACKET_FLAG_RELIABLE, 0) == NULL)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
@@ -449,7 +457,6 @@ enet_protocol_handle_send_reliable (ENetHost * host, ENetPeer * peer, const ENet
|
||||
static int
|
||||
enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
|
||||
{
|
||||
ENetPacket * packet;
|
||||
enet_uint32 unsequencedGroup, index;
|
||||
size_t dataLength;
|
||||
|
||||
@@ -459,7 +466,7 @@ enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const E
|
||||
|
||||
dataLength = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.dataLength);
|
||||
* currentData += dataLength;
|
||||
if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
|
||||
if (dataLength > host -> maximumPacketSize ||
|
||||
* currentData < host -> receivedData ||
|
||||
* currentData > & host -> receivedData [host -> receivedDataLength])
|
||||
return -1;
|
||||
@@ -485,11 +492,7 @@ enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const E
|
||||
if (peer -> unsequencedWindow [index / 32] & (1 << (index % 32)))
|
||||
return 0;
|
||||
|
||||
packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnsequenced),
|
||||
dataLength,
|
||||
ENET_PACKET_FLAG_UNSEQUENCED);
|
||||
if (packet == NULL ||
|
||||
enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL)
|
||||
if (enet_peer_queue_incoming_command (peer, command, (const enet_uint8 *) command + sizeof (ENetProtocolSendUnsequenced), dataLength, ENET_PACKET_FLAG_UNSEQUENCED, 0) == NULL)
|
||||
return -1;
|
||||
|
||||
peer -> unsequencedWindow [index / 32] |= 1 << (index % 32);
|
||||
@@ -500,7 +503,6 @@ enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const E
|
||||
static int
|
||||
enet_protocol_handle_send_unreliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
|
||||
{
|
||||
ENetPacket * packet;
|
||||
size_t dataLength;
|
||||
|
||||
if (command -> header.channelID >= peer -> channelCount ||
|
||||
@@ -509,16 +511,12 @@ enet_protocol_handle_send_unreliable (ENetHost * host, ENetPeer * peer, const EN
|
||||
|
||||
dataLength = ENET_NET_TO_HOST_16 (command -> sendUnreliable.dataLength);
|
||||
* currentData += dataLength;
|
||||
if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
|
||||
if (dataLength > host -> maximumPacketSize ||
|
||||
* currentData < host -> receivedData ||
|
||||
* currentData > & host -> receivedData [host -> receivedDataLength])
|
||||
return -1;
|
||||
|
||||
packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnreliable),
|
||||
dataLength,
|
||||
0);
|
||||
if (packet == NULL ||
|
||||
enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL)
|
||||
if (enet_peer_queue_incoming_command (peer, command, (const enet_uint8 *) command + sizeof (ENetProtocolSendUnreliable), dataLength, 0, 0) == NULL)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
@@ -544,7 +542,7 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
|
||||
|
||||
fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength);
|
||||
* currentData += fragmentLength;
|
||||
if (fragmentLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
|
||||
if (fragmentLength > host -> maximumPacketSize ||
|
||||
* currentData < host -> receivedData ||
|
||||
* currentData > & host -> receivedData [host -> receivedDataLength])
|
||||
return -1;
|
||||
@@ -567,7 +565,7 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
|
||||
|
||||
if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT ||
|
||||
fragmentNumber >= fragmentCount ||
|
||||
totalLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
|
||||
totalLength > host -> maximumPacketSize ||
|
||||
fragmentOffset >= totalLength ||
|
||||
fragmentLength > totalLength - fragmentOffset)
|
||||
return -1;
|
||||
@@ -605,13 +603,10 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
|
||||
if (startCommand == NULL)
|
||||
{
|
||||
ENetProtocol hostCommand = * command;
|
||||
ENetPacket * packet = enet_packet_create (NULL, totalLength, ENET_PACKET_FLAG_RELIABLE);
|
||||
if (packet == NULL)
|
||||
return -1;
|
||||
|
||||
hostCommand.header.reliableSequenceNumber = startSequenceNumber;
|
||||
|
||||
startCommand = enet_peer_queue_incoming_command (peer, & hostCommand, packet, fragmentCount);
|
||||
startCommand = enet_peer_queue_incoming_command (peer, & hostCommand, NULL, totalLength, ENET_PACKET_FLAG_RELIABLE, fragmentCount);
|
||||
if (startCommand == NULL)
|
||||
return -1;
|
||||
}
|
||||
@@ -630,7 +625,7 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
|
||||
fragmentLength);
|
||||
|
||||
if (startCommand -> fragmentsRemaining <= 0)
|
||||
enet_peer_dispatch_incoming_reliable_commands (peer, channel);
|
||||
enet_peer_dispatch_incoming_reliable_commands (peer, channel, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -657,7 +652,7 @@ enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer,
|
||||
|
||||
fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength);
|
||||
* currentData += fragmentLength;
|
||||
if (fragmentLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
|
||||
if (fragmentLength > host -> maximumPacketSize ||
|
||||
* currentData < host -> receivedData ||
|
||||
* currentData > & host -> receivedData [host -> receivedDataLength])
|
||||
return -1;
|
||||
@@ -686,7 +681,7 @@ enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer,
|
||||
|
||||
if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT ||
|
||||
fragmentNumber >= fragmentCount ||
|
||||
totalLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
|
||||
totalLength > host -> maximumPacketSize ||
|
||||
fragmentOffset >= totalLength ||
|
||||
fragmentLength > totalLength - fragmentOffset)
|
||||
return -1;
|
||||
@@ -729,11 +724,7 @@ enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer,
|
||||
|
||||
if (startCommand == NULL)
|
||||
{
|
||||
ENetPacket * packet = enet_packet_create (NULL, totalLength, ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT);
|
||||
if (packet == NULL)
|
||||
return -1;
|
||||
|
||||
startCommand = enet_peer_queue_incoming_command (peer, command, packet, fragmentCount);
|
||||
startCommand = enet_peer_queue_incoming_command (peer, command, NULL, totalLength, ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT, fragmentCount);
|
||||
if (startCommand == NULL)
|
||||
return -1;
|
||||
}
|
||||
@@ -752,7 +743,7 @@ enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer,
|
||||
fragmentLength);
|
||||
|
||||
if (startCommand -> fragmentsRemaining <= 0)
|
||||
enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
|
||||
enet_peer_dispatch_incoming_unreliable_commands (peer, channel, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -784,6 +775,10 @@ enet_protocol_handle_bandwidth_limit (ENetHost * host, ENetPeer * peer, const EN
|
||||
|
||||
if (peer -> incomingBandwidth == 0 && host -> outgoingBandwidth == 0)
|
||||
peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
|
||||
else
|
||||
if (peer -> incomingBandwidth == 0 || host -> outgoingBandwidth == 0)
|
||||
peer -> windowSize = (ENET_MAX (peer -> incomingBandwidth, host -> outgoingBandwidth) /
|
||||
ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
|
||||
else
|
||||
peer -> windowSize = (ENET_MIN (peer -> incomingBandwidth, host -> outgoingBandwidth) /
|
||||
ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
|
||||
@@ -818,7 +813,7 @@ enet_protocol_handle_disconnect (ENetHost * host, ENetPeer * peer, const ENetPro
|
||||
|
||||
enet_peer_reset_queues (peer);
|
||||
|
||||
if (peer -> state == ENET_PEER_STATE_CONNECTION_SUCCEEDED || peer -> state == ENET_PEER_STATE_DISCONNECTING)
|
||||
if (peer -> state == ENET_PEER_STATE_CONNECTION_SUCCEEDED || peer -> state == ENET_PEER_STATE_DISCONNECTING || peer -> state == ENET_PEER_STATE_CONNECTING)
|
||||
enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);
|
||||
else
|
||||
if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
|
||||
@@ -858,42 +853,53 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
|
||||
if (ENET_TIME_LESS (host -> serviceTime, receivedSentTime))
|
||||
return 0;
|
||||
|
||||
peer -> lastReceiveTime = host -> serviceTime;
|
||||
peer -> earliestTimeout = 0;
|
||||
|
||||
roundTripTime = ENET_TIME_DIFFERENCE (host -> serviceTime, receivedSentTime);
|
||||
roundTripTime = ENET_MAX (roundTripTime, 1);
|
||||
|
||||
enet_peer_throttle (peer, roundTripTime);
|
||||
|
||||
peer -> roundTripTimeVariance -= peer -> roundTripTimeVariance / 4;
|
||||
|
||||
if (roundTripTime >= peer -> roundTripTime)
|
||||
if (peer -> lastReceiveTime > 0)
|
||||
{
|
||||
peer -> roundTripTime += (roundTripTime - peer -> roundTripTime) / 8;
|
||||
peer -> roundTripTimeVariance += (roundTripTime - peer -> roundTripTime) / 4;
|
||||
enet_peer_throttle (peer, roundTripTime);
|
||||
|
||||
peer -> roundTripTimeVariance -= (peer -> roundTripTimeVariance + 3) / 4;
|
||||
|
||||
if (roundTripTime >= peer -> roundTripTime)
|
||||
{
|
||||
enet_uint32 diff = roundTripTime - peer -> roundTripTime;
|
||||
peer -> roundTripTimeVariance += (diff + 3) / 4;
|
||||
peer -> roundTripTime += (diff + 7) / 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
enet_uint32 diff = peer -> roundTripTime - roundTripTime;
|
||||
peer -> roundTripTimeVariance += (diff + 3) / 4;
|
||||
peer -> roundTripTime -= (diff + 7) / 8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
peer -> roundTripTime -= (peer -> roundTripTime - roundTripTime) / 8;
|
||||
peer -> roundTripTimeVariance += (peer -> roundTripTime - roundTripTime) / 4;
|
||||
peer -> roundTripTime = roundTripTime;
|
||||
peer -> roundTripTimeVariance = (roundTripTime + 1) / 2;
|
||||
}
|
||||
|
||||
if (peer -> roundTripTime < peer -> lowestRoundTripTime)
|
||||
peer -> lowestRoundTripTime = peer -> roundTripTime;
|
||||
|
||||
if (peer -> roundTripTimeVariance > peer -> highestRoundTripTimeVariance)
|
||||
if (peer -> roundTripTimeVariance > peer -> highestRoundTripTimeVariance)
|
||||
peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance;
|
||||
|
||||
if (peer -> packetThrottleEpoch == 0 ||
|
||||
ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> packetThrottleEpoch) >= peer -> packetThrottleInterval)
|
||||
{
|
||||
peer -> lastRoundTripTime = peer -> lowestRoundTripTime;
|
||||
peer -> lastRoundTripTimeVariance = peer -> highestRoundTripTimeVariance;
|
||||
peer -> lastRoundTripTimeVariance = ENET_MAX (peer -> highestRoundTripTimeVariance, 1);
|
||||
peer -> lowestRoundTripTime = peer -> roundTripTime;
|
||||
peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance;
|
||||
peer -> packetThrottleEpoch = host -> serviceTime;
|
||||
}
|
||||
|
||||
peer -> lastReceiveTime = ENET_MAX (host -> serviceTime, 1);
|
||||
peer -> earliestTimeout = 0;
|
||||
|
||||
receivedReliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedReliableSequenceNumber);
|
||||
|
||||
commandNumber = enet_protocol_remove_sent_reliable_command (peer, receivedReliableSequenceNumber, command -> header.channelID);
|
||||
@@ -915,8 +921,7 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
|
||||
break;
|
||||
|
||||
case ENET_PEER_STATE_DISCONNECT_LATER:
|
||||
if (enet_list_empty (& peer -> outgoingReliableCommands) &&
|
||||
enet_list_empty (& peer -> outgoingUnreliableCommands) &&
|
||||
if (enet_list_empty (& peer -> outgoingCommands) &&
|
||||
enet_list_empty (& peer -> sentReliableCommands))
|
||||
enet_peer_disconnect (peer, peer -> eventData);
|
||||
break;
|
||||
@@ -1026,9 +1031,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
|
||||
|
||||
if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
|
||||
peer -> state == ENET_PEER_STATE_ZOMBIE ||
|
||||
((host -> receivedAddress.host != peer -> address.host ||
|
||||
host -> receivedAddress.port != peer -> address.port) &&
|
||||
peer -> address.host != ENET_HOST_BROADCAST) ||
|
||||
/* ! enet_address_equal(& host -> receivedAddress, & peer -> address) || */
|
||||
(peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID &&
|
||||
sessionID != peer -> incomingSessionID))
|
||||
return 0;
|
||||
@@ -1070,8 +1073,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
|
||||
|
||||
if (peer != NULL)
|
||||
{
|
||||
peer -> address.host = host -> receivedAddress.host;
|
||||
peer -> address.port = host -> receivedAddress.port;
|
||||
memcpy(& peer -> address, & host -> receivedPeerAddress, sizeof (host -> receivedPeerAddress));
|
||||
memcpy(& peer -> localAddress, & host -> receivedLocalAddress, sizeof (host -> receivedLocalAddress));
|
||||
peer -> incomingDataTotal += host -> receivedDataLength;
|
||||
}
|
||||
|
||||
@@ -1211,7 +1214,9 @@ commandError:
|
||||
static int
|
||||
enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
|
||||
{
|
||||
for (;;)
|
||||
int packets;
|
||||
|
||||
for (packets = 0; packets < 256; ++ packets)
|
||||
{
|
||||
int receivedLength;
|
||||
ENetBuffer buffer;
|
||||
@@ -1220,7 +1225,8 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
|
||||
buffer.dataLength = sizeof (host -> packetData [0]);
|
||||
|
||||
receivedLength = enet_socket_receive (host -> socket,
|
||||
& host -> receivedAddress,
|
||||
& host -> receivedPeerAddress,
|
||||
& host -> receivedLocalAddress,
|
||||
& buffer,
|
||||
1);
|
||||
|
||||
@@ -1267,7 +1273,7 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1323,107 +1329,6 @@ enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer)
|
||||
host -> bufferCount = buffer - host -> buffers;
|
||||
}
|
||||
|
||||
static void
|
||||
enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
|
||||
{
|
||||
ENetProtocol * command = & host -> commands [host -> commandCount];
|
||||
ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
|
||||
ENetOutgoingCommand * outgoingCommand;
|
||||
ENetListIterator currentCommand;
|
||||
|
||||
currentCommand = enet_list_begin (& peer -> outgoingUnreliableCommands);
|
||||
|
||||
while (currentCommand != enet_list_end (& peer -> outgoingUnreliableCommands))
|
||||
{
|
||||
size_t commandSize;
|
||||
|
||||
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
|
||||
commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK];
|
||||
|
||||
if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
|
||||
buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
|
||||
peer -> mtu - host -> packetSize < commandSize ||
|
||||
(outgoingCommand -> packet != NULL &&
|
||||
peer -> mtu - host -> packetSize < commandSize + outgoingCommand -> fragmentLength))
|
||||
{
|
||||
host -> continueSending = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
currentCommand = enet_list_next (currentCommand);
|
||||
|
||||
if (outgoingCommand -> packet != NULL && outgoingCommand -> fragmentOffset == 0)
|
||||
{
|
||||
peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER;
|
||||
peer -> packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE;
|
||||
|
||||
if (peer -> packetThrottleCounter > peer -> packetThrottle)
|
||||
{
|
||||
enet_uint16 reliableSequenceNumber = outgoingCommand -> reliableSequenceNumber,
|
||||
unreliableSequenceNumber = outgoingCommand -> unreliableSequenceNumber;
|
||||
for (;;)
|
||||
{
|
||||
-- outgoingCommand -> packet -> referenceCount;
|
||||
|
||||
if (outgoingCommand -> packet -> referenceCount == 0)
|
||||
enet_packet_destroy (outgoingCommand -> packet);
|
||||
|
||||
enet_list_remove (& outgoingCommand -> outgoingCommandList);
|
||||
enet_free (outgoingCommand);
|
||||
|
||||
if (currentCommand == enet_list_end (& peer -> outgoingUnreliableCommands))
|
||||
break;
|
||||
|
||||
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
|
||||
if (outgoingCommand -> reliableSequenceNumber != reliableSequenceNumber ||
|
||||
outgoingCommand -> unreliableSequenceNumber != unreliableSequenceNumber)
|
||||
break;
|
||||
|
||||
currentCommand = enet_list_next (currentCommand);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
buffer -> data = command;
|
||||
buffer -> dataLength = commandSize;
|
||||
|
||||
host -> packetSize += buffer -> dataLength;
|
||||
|
||||
* command = outgoingCommand -> command;
|
||||
|
||||
enet_list_remove (& outgoingCommand -> outgoingCommandList);
|
||||
|
||||
if (outgoingCommand -> packet != NULL)
|
||||
{
|
||||
++ buffer;
|
||||
|
||||
buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset;
|
||||
buffer -> dataLength = outgoingCommand -> fragmentLength;
|
||||
|
||||
host -> packetSize += buffer -> dataLength;
|
||||
|
||||
enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand);
|
||||
}
|
||||
else
|
||||
enet_free (outgoingCommand);
|
||||
|
||||
++ command;
|
||||
++ buffer;
|
||||
}
|
||||
|
||||
host -> commandCount = command - host -> commands;
|
||||
host -> bufferCount = buffer - host -> buffers;
|
||||
|
||||
if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER &&
|
||||
enet_list_empty (& peer -> outgoingReliableCommands) &&
|
||||
enet_list_empty (& peer -> outgoingUnreliableCommands) &&
|
||||
enet_list_empty (& peer -> sentReliableCommands))
|
||||
enet_peer_disconnect (peer, peer -> eventData);
|
||||
}
|
||||
|
||||
static int
|
||||
enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * event)
|
||||
{
|
||||
@@ -1431,7 +1336,7 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even
|
||||
ENetListIterator currentCommand, insertPosition;
|
||||
|
||||
currentCommand = enet_list_begin (& peer -> sentReliableCommands);
|
||||
insertPosition = enet_list_begin (& peer -> outgoingReliableCommands);
|
||||
insertPosition = enet_list_begin (& peer -> outgoingCommands);
|
||||
|
||||
while (currentCommand != enet_list_end (& peer -> sentReliableCommands))
|
||||
{
|
||||
@@ -1462,6 +1367,8 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even
|
||||
++ peer -> packetsLost;
|
||||
|
||||
outgoingCommand -> roundTripTimeout *= 2;
|
||||
if (outgoingCommand -> roundTripTimeout > outgoingCommand -> roundTripTimeoutLimit)
|
||||
outgoingCommand -> roundTripTimeout = outgoingCommand -> roundTripTimeoutLimit;
|
||||
|
||||
enet_list_insert (insertPosition, enet_list_remove (& outgoingCommand -> outgoingCommandList));
|
||||
|
||||
@@ -1478,61 +1385,64 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even
|
||||
}
|
||||
|
||||
static int
|
||||
enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
|
||||
enet_protocol_check_outgoing_commands (ENetHost * host, ENetPeer * peer)
|
||||
{
|
||||
ENetProtocol * command = & host -> commands [host -> commandCount];
|
||||
ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
|
||||
ENetOutgoingCommand * outgoingCommand;
|
||||
ENetListIterator currentCommand;
|
||||
ENetChannel *channel;
|
||||
enet_uint16 reliableWindow;
|
||||
ENetChannel *channel = NULL;
|
||||
enet_uint16 reliableWindow = 0;
|
||||
size_t commandSize;
|
||||
int windowExceeded = 0, windowWrap = 0, canPing = 1;
|
||||
|
||||
currentCommand = enet_list_begin (& peer -> outgoingReliableCommands);
|
||||
currentCommand = enet_list_begin (& peer -> outgoingCommands);
|
||||
|
||||
while (currentCommand != enet_list_end (& peer -> outgoingReliableCommands))
|
||||
while (currentCommand != enet_list_end (& peer -> outgoingCommands))
|
||||
{
|
||||
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
|
||||
|
||||
channel = outgoingCommand -> command.header.channelID < peer -> channelCount ? & peer -> channels [outgoingCommand -> command.header.channelID] : NULL;
|
||||
reliableWindow = outgoingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
|
||||
if (channel != NULL)
|
||||
if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
|
||||
{
|
||||
if (! windowWrap &&
|
||||
outgoingCommand -> sendAttempts < 1 &&
|
||||
! (outgoingCommand -> reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) &&
|
||||
(channel -> reliableWindows [(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE ||
|
||||
channel -> usedReliableWindows & ((((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) << reliableWindow) |
|
||||
(((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) >> (ENET_PEER_RELIABLE_WINDOW_SIZE - reliableWindow)))))
|
||||
windowWrap = 1;
|
||||
if (windowWrap)
|
||||
channel = outgoingCommand -> command.header.channelID < peer -> channelCount ? & peer -> channels [outgoingCommand -> command.header.channelID] : NULL;
|
||||
reliableWindow = outgoingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
|
||||
if (channel != NULL)
|
||||
{
|
||||
currentCommand = enet_list_next (currentCommand);
|
||||
if (! windowWrap &&
|
||||
outgoingCommand -> sendAttempts < 1 &&
|
||||
! (outgoingCommand -> reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) &&
|
||||
(channel -> reliableWindows [(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE ||
|
||||
channel -> usedReliableWindows & ((((1 << (ENET_PEER_FREE_RELIABLE_WINDOWS + 2)) - 1) << reliableWindow) |
|
||||
(((1 << (ENET_PEER_FREE_RELIABLE_WINDOWS + 2)) - 1) >> (ENET_PEER_RELIABLE_WINDOWS - reliableWindow)))))
|
||||
windowWrap = 1;
|
||||
if (windowWrap)
|
||||
{
|
||||
currentCommand = enet_list_next (currentCommand);
|
||||
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (outgoingCommand -> packet != NULL)
|
||||
{
|
||||
if (! windowExceeded)
|
||||
if (outgoingCommand -> packet != NULL)
|
||||
{
|
||||
enet_uint32 windowSize = (peer -> packetThrottle * peer -> windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE;
|
||||
if (! windowExceeded)
|
||||
{
|
||||
enet_uint32 windowSize = (peer -> packetThrottle * peer -> windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE;
|
||||
|
||||
if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > ENET_MAX (windowSize, peer -> mtu))
|
||||
windowExceeded = 1;
|
||||
}
|
||||
if (windowExceeded)
|
||||
{
|
||||
currentCommand = enet_list_next (currentCommand);
|
||||
if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > ENET_MAX (windowSize, peer -> mtu))
|
||||
windowExceeded = 1;
|
||||
}
|
||||
if (windowExceeded)
|
||||
{
|
||||
currentCommand = enet_list_next (currentCommand);
|
||||
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
canPing = 0;
|
||||
}
|
||||
|
||||
canPing = 0;
|
||||
|
||||
commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK];
|
||||
if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
|
||||
buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
|
||||
@@ -1547,33 +1457,80 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
|
||||
|
||||
currentCommand = enet_list_next (currentCommand);
|
||||
|
||||
if (channel != NULL && outgoingCommand -> sendAttempts < 1)
|
||||
if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
|
||||
{
|
||||
channel -> usedReliableWindows |= 1 << reliableWindow;
|
||||
++ channel -> reliableWindows [reliableWindow];
|
||||
}
|
||||
if (channel != NULL && outgoingCommand -> sendAttempts < 1)
|
||||
{
|
||||
channel -> usedReliableWindows |= 1 << reliableWindow;
|
||||
++ channel -> reliableWindows [reliableWindow];
|
||||
}
|
||||
|
||||
++ outgoingCommand -> sendAttempts;
|
||||
++ outgoingCommand -> sendAttempts;
|
||||
|
||||
if (outgoingCommand -> roundTripTimeout == 0)
|
||||
{
|
||||
outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance;
|
||||
outgoingCommand -> roundTripTimeoutLimit = peer -> timeoutLimit * outgoingCommand -> roundTripTimeout;
|
||||
if (outgoingCommand -> roundTripTimeout == 0)
|
||||
{
|
||||
outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * ENET_MAX (1, peer -> roundTripTimeVariance);
|
||||
outgoingCommand -> roundTripTimeoutLimit = peer -> timeoutLimit * outgoingCommand -> roundTripTimeout;
|
||||
}
|
||||
|
||||
if (enet_list_empty (& peer -> sentReliableCommands))
|
||||
peer -> nextTimeout = host -> serviceTime + outgoingCommand -> roundTripTimeout;
|
||||
|
||||
enet_list_insert (enet_list_end (& peer -> sentReliableCommands),
|
||||
enet_list_remove (& outgoingCommand -> outgoingCommandList));
|
||||
|
||||
outgoingCommand -> sentTime = host -> serviceTime;
|
||||
|
||||
host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME;
|
||||
|
||||
peer -> reliableDataInTransit += outgoingCommand -> fragmentLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (outgoingCommand -> packet != NULL && outgoingCommand -> fragmentOffset == 0)
|
||||
{
|
||||
peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER;
|
||||
peer -> packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE;
|
||||
|
||||
if (enet_list_empty (& peer -> sentReliableCommands))
|
||||
peer -> nextTimeout = host -> serviceTime + outgoingCommand -> roundTripTimeout;
|
||||
if (peer -> packetThrottleCounter > peer -> packetThrottle)
|
||||
{
|
||||
enet_uint16 reliableSequenceNumber = outgoingCommand -> reliableSequenceNumber,
|
||||
unreliableSequenceNumber = outgoingCommand -> unreliableSequenceNumber;
|
||||
for (;;)
|
||||
{
|
||||
-- outgoingCommand -> packet -> referenceCount;
|
||||
|
||||
enet_list_insert (enet_list_end (& peer -> sentReliableCommands),
|
||||
enet_list_remove (& outgoingCommand -> outgoingCommandList));
|
||||
if (outgoingCommand -> packet -> referenceCount == 0)
|
||||
enet_packet_destroy (outgoingCommand -> packet);
|
||||
|
||||
outgoingCommand -> sentTime = host -> serviceTime;
|
||||
enet_list_remove (& outgoingCommand -> outgoingCommandList);
|
||||
enet_free (outgoingCommand);
|
||||
|
||||
if (currentCommand == enet_list_end (& peer -> outgoingCommands))
|
||||
break;
|
||||
|
||||
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
|
||||
if (outgoingCommand -> reliableSequenceNumber != reliableSequenceNumber ||
|
||||
outgoingCommand -> unreliableSequenceNumber != unreliableSequenceNumber)
|
||||
break;
|
||||
|
||||
currentCommand = enet_list_next (currentCommand);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
enet_list_remove (& outgoingCommand -> outgoingCommandList);
|
||||
|
||||
if (outgoingCommand -> packet != NULL)
|
||||
enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand);
|
||||
}
|
||||
|
||||
buffer -> data = command;
|
||||
buffer -> dataLength = commandSize;
|
||||
|
||||
host -> packetSize += buffer -> dataLength;
|
||||
host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME;
|
||||
|
||||
* command = outgoingCommand -> command;
|
||||
|
||||
@@ -1585,9 +1542,10 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
|
||||
buffer -> dataLength = outgoingCommand -> fragmentLength;
|
||||
|
||||
host -> packetSize += outgoingCommand -> fragmentLength;
|
||||
|
||||
peer -> reliableDataInTransit += outgoingCommand -> fragmentLength;
|
||||
}
|
||||
else
|
||||
if (! (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE))
|
||||
enet_free (outgoingCommand);
|
||||
|
||||
++ peer -> packetsSent;
|
||||
|
||||
@@ -1598,6 +1556,12 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
|
||||
host -> commandCount = command - host -> commands;
|
||||
host -> bufferCount = buffer - host -> buffers;
|
||||
|
||||
if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER &&
|
||||
enet_list_empty (& peer -> outgoingCommands) &&
|
||||
enet_list_empty (& peer -> sentReliableCommands) &&
|
||||
enet_list_empty (& peer -> sentUnreliableCommands))
|
||||
enet_peer_disconnect (peer, peer -> eventData);
|
||||
|
||||
return canPing;
|
||||
}
|
||||
|
||||
@@ -1641,18 +1605,15 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((enet_list_empty (& currentPeer -> outgoingReliableCommands) ||
|
||||
enet_protocol_send_reliable_outgoing_commands (host, currentPeer)) &&
|
||||
if ((enet_list_empty (& currentPeer -> outgoingCommands) ||
|
||||
enet_protocol_check_outgoing_commands (host, currentPeer)) &&
|
||||
enet_list_empty (& currentPeer -> sentReliableCommands) &&
|
||||
ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= currentPeer -> pingInterval &&
|
||||
currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing))
|
||||
{
|
||||
enet_peer_ping (currentPeer);
|
||||
enet_protocol_send_reliable_outgoing_commands (host, currentPeer);
|
||||
enet_protocol_check_outgoing_commands (host, currentPeer);
|
||||
}
|
||||
|
||||
if (! enet_list_empty (& currentPeer -> outgoingUnreliableCommands))
|
||||
enet_protocol_send_unreliable_outgoing_commands (host, currentPeer);
|
||||
|
||||
if (host -> commandCount == 0)
|
||||
continue;
|
||||
@@ -1666,26 +1627,11 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
|
||||
enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent;
|
||||
|
||||
#ifdef ENET_DEBUG
|
||||
#ifdef WIN32
|
||||
printf (
|
||||
#else
|
||||
fprintf (stderr,
|
||||
printf ("peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0);
|
||||
#endif
|
||||
"peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingReliableCommands), enet_list_size (& currentPeer -> outgoingUnreliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0);
|
||||
#endif
|
||||
|
||||
currentPeer -> packetLossVariance -= currentPeer -> packetLossVariance / 4;
|
||||
|
||||
if (packetLoss >= currentPeer -> packetLoss)
|
||||
{
|
||||
currentPeer -> packetLoss += (packetLoss - currentPeer -> packetLoss) / 8;
|
||||
currentPeer -> packetLossVariance += (packetLoss - currentPeer -> packetLoss) / 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentPeer -> packetLoss -= (currentPeer -> packetLoss - packetLoss) / 8;
|
||||
currentPeer -> packetLossVariance += (currentPeer -> packetLoss - packetLoss) / 4;
|
||||
}
|
||||
currentPeer -> packetLossVariance = (currentPeer -> packetLossVariance * 3 + ENET_DIFFERENCE (packetLoss, currentPeer -> packetLoss)) / 4;
|
||||
currentPeer -> packetLoss = (currentPeer -> packetLoss * 7 + packetLoss) / 8;
|
||||
|
||||
currentPeer -> packetLossEpoch = host -> serviceTime;
|
||||
currentPeer -> packetsSent = 0;
|
||||
@@ -1716,12 +1662,7 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
|
||||
host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_COMPRESSED;
|
||||
shouldCompress = compressedSize;
|
||||
#ifdef ENET_DEBUG_COMPRESS
|
||||
#ifdef WIN32
|
||||
printf (
|
||||
#else
|
||||
fprintf (stderr,
|
||||
#endif
|
||||
"peer %u: compressed %u -> %u (%u%%)\n", currentPeer -> incomingPeerID, originalSize, compressedSize, (compressedSize * 100) / originalSize);
|
||||
printf ("peer %u: compressed %u -> %u (%u%%)\n", currentPeer -> incomingPeerID, originalSize, compressedSize, (compressedSize * 100) / originalSize);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1746,7 +1687,13 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
|
||||
|
||||
currentPeer -> lastSendTime = host -> serviceTime;
|
||||
|
||||
sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount);
|
||||
if (currentPeer -> state == ENET_PEER_STATE_CONNECTING && currentPeer -> packetsLost == 2) {
|
||||
// Disable QoS tagging if we don't get a response to 2 connection requests in a row.
|
||||
// Some networks drop QoS tagged packets, so let's try without it.
|
||||
enet_socket_set_option (host -> socket, ENET_SOCKOPT_QOS, 0);
|
||||
}
|
||||
|
||||
sentLength = enet_socket_send (host -> socket, & currentPeer -> address, & currentPeer -> localAddress, host -> buffers, host -> bufferCount);
|
||||
|
||||
enet_protocol_remove_sent_unreliable_commands (currentPeer);
|
||||
|
||||
@@ -1840,7 +1787,7 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
|
||||
|
||||
timeout += host -> serviceTime;
|
||||
|
||||
do
|
||||
for (;;)
|
||||
{
|
||||
if (ENET_TIME_DIFFERENCE (host -> serviceTime, host -> bandwidthThrottleEpoch) >= ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
|
||||
enet_host_bandwidth_throttle (host);
|
||||
@@ -1912,6 +1859,9 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
|
||||
}
|
||||
}
|
||||
|
||||
if (ENET_TIME_GREATER_EQUAL (host -> serviceTime, timeout))
|
||||
return 0;
|
||||
|
||||
do
|
||||
{
|
||||
host -> serviceTime = enet_time_get ();
|
||||
@@ -1921,13 +1871,13 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
|
||||
|
||||
waitCondition = ENET_SOCKET_WAIT_RECEIVE | ENET_SOCKET_WAIT_INTERRUPT;
|
||||
|
||||
if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0)
|
||||
if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime) / 10) != 0)
|
||||
return -1;
|
||||
}
|
||||
while (waitCondition & ENET_SOCKET_WAIT_INTERRUPT);
|
||||
|
||||
host -> serviceTime = enet_time_get ();
|
||||
} while (waitCondition & ENET_SOCKET_WAIT_RECEIVE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2,13 +2,23 @@
|
||||
@file unix.c
|
||||
@brief ENet Unix system specific functions
|
||||
*/
|
||||
#ifndef WIN32
|
||||
#ifndef _WIN32
|
||||
|
||||
// Required for IPV6_PKTINFO with Darwin headers
|
||||
#ifndef __APPLE_USE_RFC_3542
|
||||
#define __APPLE_USE_RFC_3542 1
|
||||
#endif
|
||||
|
||||
// Required for in6_pktinfo with glibc headers
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
@@ -18,9 +28,9 @@
|
||||
#define ENET_BUILDING_LIB 1
|
||||
#include "enet/enet.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#ifdef HAS_POLL
|
||||
#undef HAS_POLL
|
||||
#if defined(__APPLE__)
|
||||
#ifndef HAS_POLL
|
||||
#define HAS_POLL 1
|
||||
#endif
|
||||
#ifndef HAS_FCNTL
|
||||
#define HAS_FCNTL 1
|
||||
@@ -37,20 +47,97 @@
|
||||
#ifndef HAS_SOCKLEN_T
|
||||
#define HAS_SOCKLEN_T 1
|
||||
#endif
|
||||
#ifndef HAS_GETADDRINFO
|
||||
#define HAS_GETADDRINFO 1
|
||||
#endif
|
||||
#ifndef HAS_GETNAMEINFO
|
||||
#define HAS_GETNAMEINFO 1
|
||||
#endif
|
||||
#elif defined(__vita__)
|
||||
#ifdef HAS_POLL
|
||||
#undef HAS_POLL
|
||||
#endif
|
||||
#ifdef HAS_FCNTL
|
||||
#undef HAS_FCNTL
|
||||
#endif
|
||||
#ifdef HAS_IOCTL
|
||||
#undef HAS_IOCTL
|
||||
#endif
|
||||
#ifndef HAS_INET_PTON
|
||||
#define HAS_INET_PTON 1
|
||||
#endif
|
||||
#ifndef HAS_INET_NTOP
|
||||
#define HAS_INET_NTOP 1
|
||||
#endif
|
||||
#ifdef HAS_MSGHDR_FLAGS
|
||||
#undef HAS_MSGHDR_FLAGS
|
||||
#endif
|
||||
#ifndef HAS_SOCKLEN_T
|
||||
#define HAS_SOCKLEN_T 1
|
||||
#endif
|
||||
#ifndef HAS_GETADDRINFO
|
||||
#define HAS_GETADDRINFO 1
|
||||
#endif
|
||||
#ifndef HAS_GETNAMEINFO
|
||||
#define HAS_GETNAMEINFO 1
|
||||
#endif
|
||||
#elif defined(__WIIU__)
|
||||
#ifndef HAS_POLL
|
||||
#define HAS_POLL 1
|
||||
#endif
|
||||
#ifndef HAS_FCNTL
|
||||
#define HAS_FCNTL 1
|
||||
#endif
|
||||
#ifndef HAS_IOCTL
|
||||
#define HAS_IOCTL 1
|
||||
#endif
|
||||
#ifndef HAS_INET_PTON
|
||||
#define HAS_INET_PTON 1
|
||||
#endif
|
||||
#ifndef HAS_INET_NTOP
|
||||
#define HAS_INET_NTOP 1
|
||||
#endif
|
||||
#ifndef HAS_SOCKLEN_T
|
||||
#define HAS_SOCKLEN_T 1
|
||||
#endif
|
||||
#ifndef HAS_GETADDRINFO
|
||||
#define HAS_GETADDRINFO 1
|
||||
#endif
|
||||
#ifndef HAS_GETNAMEINFO
|
||||
#define HAS_GETNAMEINFO 1
|
||||
#endif
|
||||
#ifndef NO_MSGAPI
|
||||
#define NO_MSGAPI 1
|
||||
#endif
|
||||
#else
|
||||
#ifndef HAS_IOCTL
|
||||
#define HAS_IOCTL 1
|
||||
#endif
|
||||
#ifndef HAS_POLL
|
||||
#define HAS_POLL 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FCNTL
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAS_POLL
|
||||
#include <sys/poll.h>
|
||||
#ifdef HAS_IOCTL
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAS_SOCKLEN_T
|
||||
#ifdef HAS_POLL
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#if !defined(HAS_SOCKLEN_T) && !defined(__socklen_t_defined)
|
||||
typedef int socklen_t;
|
||||
#endif
|
||||
|
||||
#ifndef SOMAXCONN
|
||||
#define SOMAXCONN 128
|
||||
#endif
|
||||
|
||||
#ifndef MSG_NOSIGNAL
|
||||
#define MSG_NOSIGNAL 0
|
||||
#endif
|
||||
@@ -68,6 +155,16 @@ enet_deinitialize (void)
|
||||
{
|
||||
}
|
||||
|
||||
enet_uint32
|
||||
enet_host_random_seed (void)
|
||||
{
|
||||
struct timeval timeVal;
|
||||
|
||||
gettimeofday (& timeVal, NULL);
|
||||
|
||||
return (timeVal.tv_sec * 1000) ^ (timeVal.tv_usec / 1000);
|
||||
}
|
||||
|
||||
enet_uint32
|
||||
enet_time_get (void)
|
||||
{
|
||||
@@ -88,124 +185,117 @@ enet_time_set (enet_uint32 newTimeBase)
|
||||
timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_equal (ENetAddress * address1, ENetAddress * address2)
|
||||
{
|
||||
if (address1 -> address.ss_family != address2 -> address.ss_family)
|
||||
return 0;
|
||||
|
||||
switch (address1 -> address.ss_family)
|
||||
{
|
||||
case AF_INET:
|
||||
{
|
||||
struct sockaddr_in *sin1, *sin2;
|
||||
sin1 = (struct sockaddr_in *) & address1 -> address;
|
||||
sin2 = (struct sockaddr_in *) & address2 -> address;
|
||||
return sin1 -> sin_port == sin2 -> sin_port &&
|
||||
sin1 -> sin_addr.s_addr == sin2 -> sin_addr.s_addr;
|
||||
}
|
||||
#ifdef AF_INET6
|
||||
case AF_INET6:
|
||||
{
|
||||
struct sockaddr_in6 *sin6a, *sin6b;
|
||||
sin6a = (struct sockaddr_in6 *) & address1 -> address;
|
||||
sin6b = (struct sockaddr_in6 *) & address2 -> address;
|
||||
return sin6a -> sin6_port == sin6b -> sin6_port &&
|
||||
! memcmp (& sin6a -> sin6_addr, & sin6b -> sin6_addr, sizeof (sin6a -> sin6_addr));
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_set_port (ENetAddress * address, enet_uint16 port)
|
||||
{
|
||||
if (address -> address.ss_family == AF_INET)
|
||||
{
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *) &address -> address;
|
||||
sin -> sin_port = ENET_HOST_TO_NET_16 (port);
|
||||
return 0;
|
||||
}
|
||||
#ifdef AF_INET6
|
||||
else if (address -> address.ss_family == AF_INET6)
|
||||
{
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &address -> address;
|
||||
sin6 -> sin6_port = ENET_HOST_TO_NET_16 (port);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_set_address (ENetAddress * address, struct sockaddr * addr, socklen_t addrlen)
|
||||
{
|
||||
if (addrlen > sizeof(struct sockaddr_storage))
|
||||
return -1;
|
||||
|
||||
memcpy (&address->address, addr, addrlen);
|
||||
address->addressLength = addrlen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_set_host (ENetAddress * address, const char * name)
|
||||
{
|
||||
struct hostent * hostEntry = NULL;
|
||||
#ifdef HAS_GETHOSTBYNAME_R
|
||||
struct hostent hostData;
|
||||
char buffer [2048];
|
||||
int errnum;
|
||||
struct addrinfo hints, * resultList = NULL, * result = NULL;
|
||||
|
||||
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
|
||||
#else
|
||||
hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum);
|
||||
#endif
|
||||
#else
|
||||
hostEntry = gethostbyname (name);
|
||||
#endif
|
||||
memset (& hints, 0, sizeof (hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_flags = AI_ADDRCONFIG;
|
||||
|
||||
if (hostEntry == NULL ||
|
||||
hostEntry -> h_addrtype != AF_INET)
|
||||
if (getaddrinfo (name, NULL, & hints, & resultList) != 0)
|
||||
return -1;
|
||||
|
||||
for (result = resultList; result != NULL; result = result -> ai_next)
|
||||
{
|
||||
#ifdef HAS_INET_PTON
|
||||
if (! inet_pton (AF_INET, name, & address -> host))
|
||||
#else
|
||||
if (! inet_aton (name, (struct in_addr *) & address -> host))
|
||||
#endif
|
||||
return -1;
|
||||
memcpy (& address -> address, result -> ai_addr, result -> ai_addrlen);
|
||||
address -> addressLength = result -> ai_addrlen;
|
||||
|
||||
freeaddrinfo (resultList);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
|
||||
if (resultList != NULL)
|
||||
freeaddrinfo (resultList);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
|
||||
{
|
||||
#ifdef HAS_INET_NTOP
|
||||
if (inet_ntop (AF_INET, & address -> host, name, nameLength) == NULL)
|
||||
#else
|
||||
char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
|
||||
if (addr != NULL)
|
||||
strncpy (name, addr, nameLength);
|
||||
else
|
||||
#endif
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
|
||||
{
|
||||
struct in_addr in;
|
||||
struct hostent * hostEntry = NULL;
|
||||
#ifdef HAS_GETHOSTBYADDR_R
|
||||
struct hostent hostData;
|
||||
char buffer [2048];
|
||||
int errnum;
|
||||
|
||||
in.s_addr = address -> host;
|
||||
|
||||
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
|
||||
#else
|
||||
hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum);
|
||||
#endif
|
||||
#else
|
||||
in.s_addr = address -> host;
|
||||
|
||||
hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
|
||||
#endif
|
||||
|
||||
if (hostEntry == NULL)
|
||||
return enet_address_get_host_ip (address, name, nameLength);
|
||||
|
||||
strncpy (name, hostEntry -> h_name, nameLength);
|
||||
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_bind (ENetSocket socket, const ENetAddress * address)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
|
||||
memset (& sin, 0, sizeof (struct sockaddr_in));
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
|
||||
if (address != NULL)
|
||||
{
|
||||
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
|
||||
sin.sin_addr.s_addr = address -> host;
|
||||
}
|
||||
else
|
||||
{
|
||||
sin.sin_port = 0;
|
||||
sin.sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
|
||||
return bind (socket,
|
||||
(struct sockaddr *) & sin,
|
||||
sizeof (struct sockaddr_in));
|
||||
(struct sockaddr *) & address -> address,
|
||||
address -> addressLength);
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_get_address (ENetSocket socket, ENetAddress * address)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
socklen_t sinLength = sizeof (struct sockaddr_in);
|
||||
address -> addressLength = sizeof (address -> address);
|
||||
|
||||
if (getsockname (socket, (struct sockaddr *) & sin, & sinLength) == -1)
|
||||
if (getsockname (socket, (struct sockaddr *) & address -> address, & address -> addressLength) == -1)
|
||||
return -1;
|
||||
|
||||
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -216,9 +306,39 @@ enet_socket_listen (ENetSocket socket, int backlog)
|
||||
}
|
||||
|
||||
ENetSocket
|
||||
enet_socket_create (ENetSocketType type)
|
||||
enet_socket_create (int af, ENetSocketType type)
|
||||
{
|
||||
return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
|
||||
ENetSocket sock = socket (af, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
|
||||
if (sock < 0) {
|
||||
return sock;
|
||||
}
|
||||
|
||||
#ifdef IPV6_V6ONLY
|
||||
if (af == AF_INET6) {
|
||||
int off = 0;
|
||||
|
||||
// Some OSes don't support dual-stack sockets, so ignore failures
|
||||
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&off, sizeof(off));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef IP_PKTINFO
|
||||
{
|
||||
// We turn this on for all sockets because it may be required for IPv4
|
||||
// traffic on dual-stack sockets on some OSes.
|
||||
int on = 1;
|
||||
setsockopt(sock, IPPROTO_IP, IP_PKTINFO, (char *)&on, sizeof(on));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef IPV6_RECVPKTINFO
|
||||
if (af == AF_INET6) {
|
||||
int on = 1;
|
||||
setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, (char *)&on, sizeof(on));
|
||||
}
|
||||
#endif
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -229,14 +349,14 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
|
||||
{
|
||||
case ENET_SOCKOPT_NONBLOCK:
|
||||
#ifdef HAS_FCNTL
|
||||
result = fcntl (socket, F_SETFL, O_NONBLOCK | fcntl (socket, F_GETFL));
|
||||
result = fcntl (socket, F_SETFL, (value ? O_NONBLOCK : 0) | (fcntl (socket, F_GETFL) & ~O_NONBLOCK));
|
||||
#else
|
||||
#ifdef HAS_IOCTL
|
||||
result = ioctl (socket, FIONBIO, & value);
|
||||
#else
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_NONBLOCK, (char *) & value, sizeof(int));
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
|
||||
case ENET_SOCKOPT_BROADCAST:
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
|
||||
break;
|
||||
|
||||
case ENET_SOCKOPT_REUSEADDR:
|
||||
@@ -251,12 +371,70 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
|
||||
break;
|
||||
|
||||
#ifndef __WIIU__
|
||||
case ENET_SOCKOPT_RCVTIMEO:
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_RCVTIMEO, (char *) & value, sizeof (int));
|
||||
{
|
||||
struct timeval timeVal;
|
||||
timeVal.tv_sec = value / 1000;
|
||||
timeVal.tv_usec = (value % 1000) * 1000;
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_RCVTIMEO, (char *) & timeVal, sizeof (struct timeval));
|
||||
break;
|
||||
}
|
||||
|
||||
case ENET_SOCKOPT_SNDTIMEO:
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & value, sizeof (int));
|
||||
{
|
||||
struct timeval timeVal;
|
||||
timeVal.tv_sec = value / 1000;
|
||||
timeVal.tv_usec = (value % 1000) * 1000;
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & timeVal, sizeof (struct timeval));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case ENET_SOCKOPT_NODELAY:
|
||||
result = setsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (char *) & value, sizeof (int));
|
||||
break;
|
||||
|
||||
case ENET_SOCKOPT_QOS:
|
||||
#ifdef SO_NET_SERVICE_TYPE
|
||||
// iOS/macOS
|
||||
value = value ? NET_SERVICE_TYPE_VO : NET_SERVICE_TYPE_BE;
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_NET_SERVICE_TYPE, (char *) & value, sizeof (int));
|
||||
#else
|
||||
#ifdef IP_TOS
|
||||
// UNIX - IPv4
|
||||
value = value ? 46 << 2 : 0; // DSCP: Expedited Forwarding
|
||||
result = setsockopt (socket, IPPROTO_IP, IP_TOS, (char *) & value, sizeof (int));
|
||||
#endif
|
||||
#ifdef IPV6_TCLASS
|
||||
// UNIX - IPv6
|
||||
value = value ? 46 << 2: 0; // DSCP: Expedited Forwarding
|
||||
result = setsockopt (socket, IPPROTO_IPV6, IPV6_TCLASS, (char *) & value, sizeof (int));
|
||||
#endif
|
||||
#ifdef SO_PRIORITY
|
||||
// Linux
|
||||
value = value ? 6 : 0; // Max priority without NET_CAP_ADMIN
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_PRIORITY, (char *) & value, sizeof (int));
|
||||
#endif
|
||||
#endif /* SO_NET_SERVICE_TYPE */
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result == -1 ? -1 : 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_get_option (ENetSocket socket, ENetSocketOption option, int * value)
|
||||
{
|
||||
int result = -1;
|
||||
socklen_t len;
|
||||
switch (option)
|
||||
{
|
||||
case ENET_SOCKOPT_ERROR:
|
||||
len = sizeof (int);
|
||||
result = getsockopt (socket, SOL_SOCKET, SO_ERROR, value, & len);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -268,16 +446,9 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
|
||||
int
|
||||
enet_socket_connect (ENetSocket socket, const ENetAddress * address)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
int result;
|
||||
|
||||
memset (& sin, 0, sizeof (struct sockaddr_in));
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
|
||||
sin.sin_addr.s_addr = address -> host;
|
||||
|
||||
result = connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
|
||||
result = connect (socket, (struct sockaddr *) & address -> address, address -> addressLength);
|
||||
if (result == -1 && errno == EINPROGRESS)
|
||||
return 0;
|
||||
|
||||
@@ -288,25 +459,20 @@ ENetSocket
|
||||
enet_socket_accept (ENetSocket socket, ENetAddress * address)
|
||||
{
|
||||
int result;
|
||||
struct sockaddr_in sin;
|
||||
socklen_t sinLength = sizeof (struct sockaddr_in);
|
||||
|
||||
if (address != NULL)
|
||||
address -> addressLength = sizeof (address -> address);
|
||||
|
||||
result = accept (socket,
|
||||
address != NULL ? (struct sockaddr *) & sin : NULL,
|
||||
address != NULL ? & sinLength : NULL);
|
||||
address != NULL ? (struct sockaddr *) & address -> address : NULL,
|
||||
address != NULL ? & address -> addressLength : NULL);
|
||||
|
||||
if (result == -1)
|
||||
return ENET_SOCKET_NULL;
|
||||
|
||||
if (address != NULL)
|
||||
{
|
||||
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_shutdown (ENetSocket socket, ENetSocketShutdown how)
|
||||
{
|
||||
@@ -322,32 +488,106 @@ enet_socket_destroy (ENetSocket socket)
|
||||
|
||||
int
|
||||
enet_socket_send (ENetSocket socket,
|
||||
const ENetAddress * address,
|
||||
const ENetAddress * peerAddress,
|
||||
const ENetAddress * localAddress,
|
||||
const ENetBuffer * buffers,
|
||||
size_t bufferCount)
|
||||
{
|
||||
struct msghdr msgHdr;
|
||||
struct sockaddr_in sin;
|
||||
int sentLength;
|
||||
|
||||
#ifdef NO_MSGAPI
|
||||
void* sendBuffer;
|
||||
size_t sendLength;
|
||||
|
||||
if (bufferCount > 1)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
sendLength = 0;
|
||||
for (i = 0; i < bufferCount; i++)
|
||||
{
|
||||
sendLength += buffers[i].dataLength;
|
||||
}
|
||||
|
||||
sendBuffer = malloc (sendLength);
|
||||
if (sendBuffer == NULL)
|
||||
return -1;
|
||||
|
||||
sendLength = 0;
|
||||
for (i = 0; i < bufferCount; i++)
|
||||
{
|
||||
memcpy (& ((unsigned char *)sendBuffer)[sendLength], buffers[i].data, buffers[i].dataLength);
|
||||
sendLength += buffers[i].dataLength;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sendBuffer = buffers[0].data;
|
||||
sendLength = buffers[0].dataLength;
|
||||
}
|
||||
|
||||
sentLength = sendto (socket, sendBuffer, sendLength, MSG_NOSIGNAL,
|
||||
(struct sockaddr *) & peerAddress -> address, peerAddress -> addressLength);
|
||||
|
||||
if (bufferCount > 1)
|
||||
free(sendBuffer);
|
||||
#else
|
||||
struct msghdr msgHdr;
|
||||
char controlBufData[1024];
|
||||
|
||||
memset (& msgHdr, 0, sizeof (struct msghdr));
|
||||
|
||||
if (address != NULL)
|
||||
if (peerAddress != NULL)
|
||||
{
|
||||
memset (& sin, 0, sizeof (struct sockaddr_in));
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
|
||||
sin.sin_addr.s_addr = address -> host;
|
||||
|
||||
msgHdr.msg_name = & sin;
|
||||
msgHdr.msg_namelen = sizeof (struct sockaddr_in);
|
||||
msgHdr.msg_name = (void*) & peerAddress -> address;
|
||||
msgHdr.msg_namelen = peerAddress -> addressLength;
|
||||
}
|
||||
|
||||
msgHdr.msg_iov = (struct iovec *) buffers;
|
||||
msgHdr.msg_iovlen = bufferCount;
|
||||
|
||||
// We always send traffic from the same local address as we last received
|
||||
// from this peer to ensure it correctly recognizes our responses as
|
||||
// coming from the expected host.
|
||||
if (localAddress != NULL) {
|
||||
#ifdef IP_PKTINFO
|
||||
if (localAddress->address.ss_family == AF_INET) {
|
||||
struct in_pktinfo pktInfo;
|
||||
|
||||
pktInfo.ipi_spec_dst = ((struct sockaddr_in*)&localAddress->address)->sin_addr;
|
||||
pktInfo.ipi_ifindex = 0; // Unspecified
|
||||
|
||||
msgHdr.msg_control = controlBufData;
|
||||
msgHdr.msg_controllen = CMSG_SPACE(sizeof(pktInfo));
|
||||
|
||||
struct cmsghdr *chdr = CMSG_FIRSTHDR(&msgHdr);
|
||||
chdr->cmsg_level = IPPROTO_IP;
|
||||
chdr->cmsg_type = IP_PKTINFO;
|
||||
chdr->cmsg_len = CMSG_LEN(sizeof(pktInfo));
|
||||
memcpy(CMSG_DATA(chdr), &pktInfo, sizeof(pktInfo));
|
||||
}
|
||||
#endif
|
||||
#ifdef IPV6_PKTINFO
|
||||
if (localAddress->address.ss_family == AF_INET6) {
|
||||
struct in6_pktinfo pktInfo;
|
||||
|
||||
pktInfo.ipi6_addr = ((struct sockaddr_in6*)&localAddress->address)->sin6_addr;
|
||||
pktInfo.ipi6_ifindex = 0; // Unspecified
|
||||
|
||||
msgHdr.msg_control = controlBufData;
|
||||
msgHdr.msg_controllen = CMSG_SPACE(sizeof(pktInfo));
|
||||
|
||||
struct cmsghdr *chdr = CMSG_FIRSTHDR(&msgHdr);
|
||||
chdr->cmsg_level = IPPROTO_IPV6;
|
||||
chdr->cmsg_type = IPV6_PKTINFO;
|
||||
chdr->cmsg_len = CMSG_LEN(sizeof(pktInfo));
|
||||
memcpy(CMSG_DATA(chdr), &pktInfo, sizeof(pktInfo));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL);
|
||||
#endif
|
||||
|
||||
if (sentLength == -1)
|
||||
{
|
||||
@@ -362,24 +602,45 @@ enet_socket_send (ENetSocket socket,
|
||||
|
||||
int
|
||||
enet_socket_receive (ENetSocket socket,
|
||||
ENetAddress * address,
|
||||
ENetAddress * peerAddress,
|
||||
ENetAddress * localAddress,
|
||||
ENetBuffer * buffers,
|
||||
size_t bufferCount)
|
||||
{
|
||||
struct msghdr msgHdr;
|
||||
struct sockaddr_in sin;
|
||||
int recvLength;
|
||||
|
||||
#ifdef NO_MSGAPI
|
||||
// This will ONLY work with a single buffer!
|
||||
|
||||
address -> addressLength = sizeof (address -> address);
|
||||
recvLength = recvfrom (socket, buffers[0].data, buffers[0].dataLength, MSG_NOSIGNAL,
|
||||
(struct sockaddr *) & peerAddress -> address, & peerAddress -> addressLength);
|
||||
|
||||
if (recvLength == -1)
|
||||
{
|
||||
if (errno == EWOULDBLOCK)
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return recvLength;
|
||||
#else
|
||||
struct msghdr msgHdr;
|
||||
char controlBufData[1024];
|
||||
|
||||
memset (& msgHdr, 0, sizeof (struct msghdr));
|
||||
|
||||
if (address != NULL)
|
||||
if (peerAddress != NULL)
|
||||
{
|
||||
msgHdr.msg_name = & sin;
|
||||
msgHdr.msg_namelen = sizeof (struct sockaddr_in);
|
||||
msgHdr.msg_name = & peerAddress -> address;
|
||||
msgHdr.msg_namelen = sizeof (peerAddress -> address);
|
||||
}
|
||||
|
||||
msgHdr.msg_iov = (struct iovec *) buffers;
|
||||
msgHdr.msg_iovlen = bufferCount;
|
||||
msgHdr.msg_control = controlBufData;
|
||||
msgHdr.msg_controllen = sizeof(controlBufData);
|
||||
|
||||
recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL);
|
||||
|
||||
@@ -396,13 +657,40 @@ enet_socket_receive (ENetSocket socket,
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
if (address != NULL)
|
||||
{
|
||||
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||
// Retrieve the local address that this traffic was received on
|
||||
// to ensure we respond from the correct address/interface.
|
||||
if (localAddress != NULL) {
|
||||
for (struct cmsghdr *chdr = CMSG_FIRSTHDR(&msgHdr); chdr != NULL; chdr = CMSG_NXTHDR(&msgHdr, chdr)) {
|
||||
#ifdef IP_PKTINFO
|
||||
if (chdr->cmsg_level == IPPROTO_IP && chdr->cmsg_type == IP_PKTINFO) {
|
||||
struct sockaddr_in *localAddr = (struct sockaddr_in*)&localAddress->address;
|
||||
|
||||
localAddr->sin_family = AF_INET;
|
||||
localAddr->sin_addr = ((struct in_pktinfo*)CMSG_DATA(chdr))->ipi_addr;
|
||||
|
||||
localAddress->addressLength = sizeof(*localAddr);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef IPV6_PKTINFO
|
||||
if (chdr->cmsg_level == IPPROTO_IPV6 && chdr->cmsg_type == IPV6_PKTINFO) {
|
||||
struct sockaddr_in6 *localAddr = (struct sockaddr_in6*)&localAddress->address;
|
||||
|
||||
localAddr->sin6_family = AF_INET6;
|
||||
localAddr->sin6_addr = ((struct in6_pktinfo*)CMSG_DATA(chdr))->ipi6_addr;
|
||||
|
||||
localAddress->addressLength = sizeof(*localAddr);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (peerAddress != NULL)
|
||||
peerAddress -> addressLength = msgHdr.msg_namelen;
|
||||
|
||||
return recvLength;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -4,23 +4,46 @@
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <time.h>
|
||||
#define ENET_BUILDING_LIB 1
|
||||
#include "enet/enet.h"
|
||||
#include <windows.h>
|
||||
#include <Mswsock.h>
|
||||
#ifndef HAS_QOS_FLOWID
|
||||
typedef UINT32 QOS_FLOWID;
|
||||
#endif
|
||||
#ifndef HAS_PQOS_FLOWID
|
||||
typedef UINT32 *PQOS_FLOWID;
|
||||
#endif
|
||||
#include <mmsystem.h>
|
||||
#include <qos2.h>
|
||||
#ifndef QOS_NON_ADAPTIVE_FLOW
|
||||
#define QOS_NON_ADAPTIVE_FLOW 0x00000002
|
||||
#endif
|
||||
|
||||
static enet_uint32 timeBase = 0;
|
||||
static HANDLE qosHandle = INVALID_HANDLE_VALUE;
|
||||
static QOS_FLOWID qosFlowId;
|
||||
static BOOL qosAddedFlow;
|
||||
|
||||
static HMODULE QwaveLibraryHandle;
|
||||
|
||||
BOOL (WINAPI *pfnQOSCreateHandle)(PQOS_VERSION Version, PHANDLE QOSHandle);
|
||||
BOOL (WINAPI *pfnQOSCloseHandle)(HANDLE QOSHandle);
|
||||
BOOL (WINAPI *pfnQOSAddSocketToFlow)(HANDLE QOSHandle, SOCKET Socket, PSOCKADDR DestAddr, QOS_TRAFFIC_TYPE TrafficType, DWORD Flags, PQOS_FLOWID FlowId);
|
||||
|
||||
LPFN_WSARECVMSG pfnWSARecvMsg;
|
||||
|
||||
int
|
||||
enet_initialize (void)
|
||||
{
|
||||
WORD versionRequested = MAKEWORD (1, 1);
|
||||
WORD versionRequested = MAKEWORD (2, 0);
|
||||
WSADATA wsaData;
|
||||
|
||||
if (WSAStartup (versionRequested, & wsaData))
|
||||
return -1;
|
||||
|
||||
if (LOBYTE (wsaData.wVersion) != 1||
|
||||
HIBYTE (wsaData.wVersion) != 1)
|
||||
if (LOBYTE (wsaData.wVersion) != 2||
|
||||
HIBYTE (wsaData.wVersion) != 0)
|
||||
{
|
||||
WSACleanup ();
|
||||
|
||||
@@ -29,17 +52,57 @@ enet_initialize (void)
|
||||
|
||||
timeBeginPeriod (1);
|
||||
|
||||
QwaveLibraryHandle = LoadLibraryA("qwave.dll");
|
||||
if (QwaveLibraryHandle != NULL) {
|
||||
pfnQOSCreateHandle = (void*)GetProcAddress(QwaveLibraryHandle, "QOSCreateHandle");
|
||||
pfnQOSCloseHandle = (void*)GetProcAddress(QwaveLibraryHandle, "QOSCloseHandle");
|
||||
pfnQOSAddSocketToFlow = (void*)GetProcAddress(QwaveLibraryHandle, "QOSAddSocketToFlow");
|
||||
|
||||
if (pfnQOSCreateHandle == NULL || pfnQOSCloseHandle == NULL || pfnQOSAddSocketToFlow == NULL) {
|
||||
pfnQOSCreateHandle = NULL;
|
||||
pfnQOSCloseHandle = NULL;
|
||||
pfnQOSAddSocketToFlow = NULL;
|
||||
|
||||
FreeLibrary(QwaveLibraryHandle);
|
||||
QwaveLibraryHandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
enet_deinitialize (void)
|
||||
{
|
||||
qosAddedFlow = FALSE;
|
||||
qosFlowId = 0;
|
||||
|
||||
if (qosHandle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
pfnQOSCloseHandle(qosHandle);
|
||||
qosHandle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (QwaveLibraryHandle != NULL) {
|
||||
pfnQOSCreateHandle = NULL;
|
||||
pfnQOSCloseHandle = NULL;
|
||||
pfnQOSAddSocketToFlow = NULL;
|
||||
|
||||
FreeLibrary(QwaveLibraryHandle);
|
||||
QwaveLibraryHandle = NULL;
|
||||
}
|
||||
|
||||
timeEndPeriod (1);
|
||||
|
||||
WSACleanup ();
|
||||
}
|
||||
|
||||
enet_uint32
|
||||
enet_host_random_seed (void)
|
||||
{
|
||||
return (enet_uint32) timeGetTime ();
|
||||
}
|
||||
|
||||
enet_uint32
|
||||
enet_time_get (void)
|
||||
{
|
||||
@@ -52,91 +115,113 @@ enet_time_set (enet_uint32 newTimeBase)
|
||||
timeBase = (enet_uint32) timeGetTime () - newTimeBase;
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_set_port (ENetAddress * address, enet_uint16 port)
|
||||
{
|
||||
if (address -> address.ss_family == AF_INET)
|
||||
{
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *) &address -> address;
|
||||
sin -> sin_port = ENET_HOST_TO_NET_16 (port);
|
||||
return 0;
|
||||
}
|
||||
else if (address -> address.ss_family == AF_INET6)
|
||||
{
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &address -> address;
|
||||
sin6 -> sin6_port = ENET_HOST_TO_NET_16 (port);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_set_address (ENetAddress * address, struct sockaddr * addr, socklen_t addrlen)
|
||||
{
|
||||
if (addrlen > sizeof(struct sockaddr_storage))
|
||||
return -1;
|
||||
|
||||
memcpy (&address->address, addr, addrlen);
|
||||
address->addressLength = addrlen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_equal (ENetAddress * address1, ENetAddress * address2)
|
||||
{
|
||||
if (address1 -> address.ss_family != address2 -> address.ss_family)
|
||||
return 0;
|
||||
|
||||
switch (address1 -> address.ss_family)
|
||||
{
|
||||
case AF_INET:
|
||||
{
|
||||
struct sockaddr_in *sin1, *sin2;
|
||||
sin1 = (struct sockaddr_in *) & address1 -> address;
|
||||
sin2 = (struct sockaddr_in *) & address2 -> address;
|
||||
return sin1 -> sin_port == sin2 -> sin_port &&
|
||||
sin1 -> sin_addr.S_un.S_addr == sin2 -> sin_addr.S_un.S_addr;
|
||||
}
|
||||
case AF_INET6:
|
||||
{
|
||||
struct sockaddr_in6 *sin6a, *sin6b;
|
||||
sin6a = (struct sockaddr_in6 *) & address1 -> address;
|
||||
sin6b = (struct sockaddr_in6 *) & address2 -> address;
|
||||
return sin6a -> sin6_port == sin6b -> sin6_port &&
|
||||
! memcmp (& sin6a -> sin6_addr, & sin6b -> sin6_addr, sizeof (sin6a -> sin6_addr));
|
||||
}
|
||||
default:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_set_host (ENetAddress * address, const char * name)
|
||||
{
|
||||
struct hostent * hostEntry;
|
||||
struct addrinfo hints, * resultList = NULL, * result = NULL;
|
||||
|
||||
hostEntry = gethostbyname (name);
|
||||
if (hostEntry == NULL ||
|
||||
hostEntry -> h_addrtype != AF_INET)
|
||||
memset (& hints, 0, sizeof (hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_flags = AI_ADDRCONFIG;
|
||||
|
||||
if (getaddrinfo (name, NULL, & hints, & resultList) != 0)
|
||||
return -1;
|
||||
|
||||
for (result = resultList; result != NULL; result = result -> ai_next)
|
||||
{
|
||||
unsigned long host = inet_addr (name);
|
||||
if (host == INADDR_NONE)
|
||||
return -1;
|
||||
address -> host = host;
|
||||
memcpy (& address -> address, result -> ai_addr, result -> ai_addrlen);
|
||||
address -> addressLength = result -> ai_addrlen;
|
||||
|
||||
freeaddrinfo (resultList);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
|
||||
if (resultList != NULL)
|
||||
freeaddrinfo (resultList);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
|
||||
{
|
||||
char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
|
||||
if (addr == NULL)
|
||||
return -1;
|
||||
strncpy (name, addr, nameLength);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
|
||||
{
|
||||
struct in_addr in;
|
||||
struct hostent * hostEntry;
|
||||
|
||||
in.s_addr = address -> host;
|
||||
|
||||
hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
|
||||
if (hostEntry == NULL)
|
||||
return enet_address_get_host_ip (address, name, nameLength);
|
||||
|
||||
strncpy (name, hostEntry -> h_name, nameLength);
|
||||
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_bind (ENetSocket socket, const ENetAddress * address)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
|
||||
memset (& sin, 0, sizeof (struct sockaddr_in));
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
|
||||
if (address != NULL)
|
||||
{
|
||||
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
|
||||
sin.sin_addr.s_addr = address -> host;
|
||||
}
|
||||
else
|
||||
{
|
||||
sin.sin_port = 0;
|
||||
sin.sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
|
||||
return bind (socket,
|
||||
(struct sockaddr *) & sin,
|
||||
sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
|
||||
(struct sockaddr *) & address -> address,
|
||||
address -> addressLength);
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_get_address (ENetSocket socket, ENetAddress * address)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
int sinLength = sizeof (struct sockaddr_in);
|
||||
address -> addressLength = sizeof (address -> address);
|
||||
|
||||
if (getsockname (socket, (struct sockaddr *) & sin, & sinLength) == -1)
|
||||
if (getsockname (socket, (struct sockaddr *) & address -> address, & address -> addressLength) == -1)
|
||||
return -1;
|
||||
|
||||
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -147,9 +232,48 @@ enet_socket_listen (ENetSocket socket, int backlog)
|
||||
}
|
||||
|
||||
ENetSocket
|
||||
enet_socket_create (ENetSocketType type)
|
||||
enet_socket_create (int af, ENetSocketType type)
|
||||
{
|
||||
return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
|
||||
SOCKET sock = socket (af, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
|
||||
if (sock == INVALID_SOCKET)
|
||||
return INVALID_SOCKET;
|
||||
|
||||
DWORD bytesReturned;
|
||||
GUID wsaRecvMsgGuid = WSAID_WSARECVMSG;
|
||||
if (WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &wsaRecvMsgGuid, sizeof(wsaRecvMsgGuid),
|
||||
&pfnWSARecvMsg, sizeof(pfnWSARecvMsg), &bytesReturned, NULL, NULL) == SOCKET_ERROR) {
|
||||
closesocket(sock);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
BOOL val;
|
||||
|
||||
// Enable dual-stack operation for IPv6 sockets
|
||||
if (af == AF_INET6) {
|
||||
val = FALSE;
|
||||
if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&val, sizeof(val)) == SOCKET_ERROR) {
|
||||
closesocket(sock);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
|
||||
// Enable returning local address info for IPv4 and dual-stack sockets
|
||||
val = TRUE;
|
||||
if (setsockopt(sock, IPPROTO_IP, IP_PKTINFO, (char*)&val, sizeof(val)) == SOCKET_ERROR) {
|
||||
closesocket(sock);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
// Enable returning local address info for IPv6 and dual-stack sockets
|
||||
if (af == AF_INET6) {
|
||||
val = TRUE;
|
||||
if (setsockopt(sock, IPPROTO_IPV6, IPV6_PKTINFO, (char*)&val, sizeof(val)) == SOCKET_ERROR) {
|
||||
closesocket(sock);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -165,10 +289,6 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
|
||||
break;
|
||||
}
|
||||
|
||||
case ENET_SOCKOPT_BROADCAST:
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
|
||||
break;
|
||||
|
||||
case ENET_SOCKOPT_REUSEADDR:
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
|
||||
break;
|
||||
@@ -189,6 +309,53 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & value, sizeof (int));
|
||||
break;
|
||||
|
||||
case ENET_SOCKOPT_NODELAY:
|
||||
result = setsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (char *) & value, sizeof (int));
|
||||
break;
|
||||
|
||||
case ENET_SOCKOPT_QOS:
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
QOS_VERSION qosVersion;
|
||||
|
||||
qosVersion.MajorVersion = 1;
|
||||
qosVersion.MinorVersion = 0;
|
||||
if (pfnQOSCreateHandle == NULL || !pfnQOSCreateHandle(&qosVersion, &qosHandle))
|
||||
{
|
||||
qosHandle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
else if (qosHandle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
pfnQOSCloseHandle(qosHandle);
|
||||
qosHandle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
qosAddedFlow = FALSE;
|
||||
qosFlowId = 0;
|
||||
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result == SOCKET_ERROR ? -1 : 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_get_option (ENetSocket socket, ENetSocketOption option, int * value)
|
||||
{
|
||||
int result = SOCKET_ERROR, len;
|
||||
switch (option)
|
||||
{
|
||||
case ENET_SOCKOPT_ERROR:
|
||||
len = sizeof(int);
|
||||
result = getsockopt (socket, SOL_SOCKET, SO_ERROR, (char *) value, & len);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -198,16 +365,9 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
|
||||
int
|
||||
enet_socket_connect (ENetSocket socket, const ENetAddress * address)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
int result;
|
||||
|
||||
memset (& sin, 0, sizeof (struct sockaddr_in));
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
|
||||
sin.sin_addr.s_addr = address -> host;
|
||||
|
||||
result = connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
|
||||
result = connect (socket, (struct sockaddr *) & address -> address, address -> addressLength);
|
||||
if (result == SOCKET_ERROR && WSAGetLastError () != WSAEWOULDBLOCK)
|
||||
return -1;
|
||||
|
||||
@@ -217,22 +377,17 @@ enet_socket_connect (ENetSocket socket, const ENetAddress * address)
|
||||
ENetSocket
|
||||
enet_socket_accept (ENetSocket socket, ENetAddress * address)
|
||||
{
|
||||
SOCKET result;
|
||||
struct sockaddr_in sin;
|
||||
int sinLength = sizeof (struct sockaddr_in);
|
||||
|
||||
result = accept (socket,
|
||||
address != NULL ? (struct sockaddr *) & sin : NULL,
|
||||
address != NULL ? & sinLength : NULL);
|
||||
|
||||
if (result == INVALID_SOCKET)
|
||||
return ENET_SOCKET_NULL;
|
||||
int result;
|
||||
|
||||
if (address != NULL)
|
||||
{
|
||||
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||
}
|
||||
address -> addressLength = sizeof (address -> address);
|
||||
|
||||
result = accept (socket,
|
||||
address != NULL ? (struct sockaddr *) & address -> address : NULL,
|
||||
address != NULL ? & address -> addressLength : NULL);
|
||||
|
||||
if (result == -1)
|
||||
return ENET_SOCKET_NULL;
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -252,31 +407,76 @@ enet_socket_destroy (ENetSocket socket)
|
||||
|
||||
int
|
||||
enet_socket_send (ENetSocket socket,
|
||||
const ENetAddress * address,
|
||||
const ENetAddress * peerAddress,
|
||||
const ENetAddress * localAddress,
|
||||
const ENetBuffer * buffers,
|
||||
size_t bufferCount)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
DWORD sentLength;
|
||||
WSAMSG msg = { 0 };
|
||||
char controlBufData[1024];
|
||||
|
||||
if (address != NULL)
|
||||
if (!qosAddedFlow && qosHandle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
memset (& sin, 0, sizeof (struct sockaddr_in));
|
||||
qosFlowId = 0; // Must be initialized to 0
|
||||
pfnQOSAddSocketToFlow(qosHandle,
|
||||
socket,
|
||||
(struct sockaddr *)&peerAddress->address,
|
||||
QOSTrafficTypeControl,
|
||||
QOS_NON_ADAPTIVE_FLOW,
|
||||
&qosFlowId);
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
|
||||
sin.sin_addr.s_addr = address -> host;
|
||||
// Even if we failed, don't try again
|
||||
qosAddedFlow = TRUE;
|
||||
}
|
||||
|
||||
if (WSASendTo (socket,
|
||||
(LPWSABUF) buffers,
|
||||
(DWORD) bufferCount,
|
||||
& sentLength,
|
||||
0,
|
||||
address != NULL ? (struct sockaddr *) & sin : NULL,
|
||||
address != NULL ? sizeof (struct sockaddr_in) : 0,
|
||||
NULL,
|
||||
NULL) == SOCKET_ERROR)
|
||||
msg.name = peerAddress != NULL ? (struct sockaddr *) & peerAddress -> address : NULL;
|
||||
msg.namelen = peerAddress != NULL ? peerAddress -> addressLength : 0;
|
||||
msg.lpBuffers = (LPWSABUF) buffers;
|
||||
msg.dwBufferCount = (DWORD) bufferCount;
|
||||
|
||||
// We always send traffic from the same local address as we last received
|
||||
// from this peer to ensure it correctly recognizes our responses as
|
||||
// coming from the expected host.
|
||||
if (localAddress != NULL) {
|
||||
if (localAddress->address.ss_family == AF_INET) {
|
||||
IN_PKTINFO pktInfo;
|
||||
|
||||
pktInfo.ipi_addr = ((PSOCKADDR_IN)&localAddress->address)->sin_addr;
|
||||
pktInfo.ipi_ifindex = 0; // Unspecified
|
||||
|
||||
msg.Control.buf = controlBufData;
|
||||
msg.Control.len = WSA_CMSG_SPACE(sizeof(pktInfo));
|
||||
|
||||
PWSACMSGHDR chdr = WSA_CMSG_FIRSTHDR(&msg);
|
||||
chdr->cmsg_level = IPPROTO_IP;
|
||||
chdr->cmsg_type = IP_PKTINFO;
|
||||
chdr->cmsg_len = WSA_CMSG_LEN(sizeof(pktInfo));
|
||||
memcpy(WSA_CMSG_DATA(chdr), &pktInfo, sizeof(pktInfo));
|
||||
}
|
||||
else if (localAddress->address.ss_family == AF_INET6) {
|
||||
IN6_PKTINFO pktInfo;
|
||||
|
||||
pktInfo.ipi6_addr = ((PSOCKADDR_IN6)&localAddress->address)->sin6_addr;
|
||||
pktInfo.ipi6_ifindex = 0; // Unspecified
|
||||
|
||||
msg.Control.buf = controlBufData;
|
||||
msg.Control.len = WSA_CMSG_SPACE(sizeof(pktInfo));
|
||||
|
||||
PWSACMSGHDR chdr = WSA_CMSG_FIRSTHDR(&msg);
|
||||
chdr->cmsg_level = IPPROTO_IPV6;
|
||||
chdr->cmsg_type = IPV6_PKTINFO;
|
||||
chdr->cmsg_len = WSA_CMSG_LEN(sizeof(pktInfo));
|
||||
memcpy(WSA_CMSG_DATA(chdr), &pktInfo, sizeof(pktInfo));
|
||||
}
|
||||
}
|
||||
|
||||
if (WSASendMsg (socket,
|
||||
& msg,
|
||||
0,
|
||||
& sentLength,
|
||||
NULL,
|
||||
NULL) == SOCKET_ERROR)
|
||||
{
|
||||
if (WSAGetLastError () == WSAEWOULDBLOCK)
|
||||
return 0;
|
||||
@@ -289,24 +489,27 @@ enet_socket_send (ENetSocket socket,
|
||||
|
||||
int
|
||||
enet_socket_receive (ENetSocket socket,
|
||||
ENetAddress * address,
|
||||
ENetAddress * peerAddress,
|
||||
ENetAddress * localAddress,
|
||||
ENetBuffer * buffers,
|
||||
size_t bufferCount)
|
||||
{
|
||||
INT sinLength = sizeof (struct sockaddr_in);
|
||||
DWORD flags = 0,
|
||||
recvLength;
|
||||
struct sockaddr_in sin;
|
||||
DWORD recvLength;
|
||||
WSAMSG msg = { 0 };
|
||||
char controlBufData[1024];
|
||||
|
||||
if (WSARecvFrom (socket,
|
||||
(LPWSABUF) buffers,
|
||||
(DWORD) bufferCount,
|
||||
& recvLength,
|
||||
& flags,
|
||||
address != NULL ? (struct sockaddr *) & sin : NULL,
|
||||
address != NULL ? & sinLength : NULL,
|
||||
NULL,
|
||||
NULL) == SOCKET_ERROR)
|
||||
msg.name = peerAddress != NULL ? (struct sockaddr *) & peerAddress -> address : NULL;
|
||||
msg.namelen = peerAddress != NULL ? sizeof (peerAddress -> address) : 0;
|
||||
msg.lpBuffers = (LPWSABUF) buffers;
|
||||
msg.dwBufferCount = (DWORD) bufferCount;
|
||||
msg.Control.buf = controlBufData;
|
||||
msg.Control.len = sizeof(controlBufData);
|
||||
|
||||
if (pfnWSARecvMsg (socket,
|
||||
& msg,
|
||||
& recvLength,
|
||||
NULL,
|
||||
NULL) == SOCKET_ERROR)
|
||||
{
|
||||
switch (WSAGetLastError ())
|
||||
{
|
||||
@@ -318,15 +521,35 @@ enet_socket_receive (ENetSocket socket,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flags & MSG_PARTIAL)
|
||||
if (msg.dwFlags & MSG_PARTIAL)
|
||||
return -1;
|
||||
|
||||
if (address != NULL)
|
||||
{
|
||||
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||
// Retrieve the local address that this traffic was received on
|
||||
// to ensure we respond from the correct address/interface.
|
||||
if (localAddress != NULL) {
|
||||
for (PWSACMSGHDR chdr = WSA_CMSG_FIRSTHDR(&msg); chdr != NULL; chdr = WSA_CMSG_NXTHDR(&msg, chdr)) {
|
||||
if (chdr->cmsg_level == IPPROTO_IP && chdr->cmsg_type == IP_PKTINFO) {
|
||||
PSOCKADDR_IN localAddr = (PSOCKADDR_IN)&localAddress->address;
|
||||
|
||||
localAddr->sin_family = AF_INET;
|
||||
localAddr->sin_addr = ((IN_PKTINFO*)WSA_CMSG_DATA(chdr))->ipi_addr;
|
||||
|
||||
localAddress->addressLength = sizeof(*localAddr);
|
||||
break;
|
||||
}
|
||||
else if (chdr->cmsg_level == IPPROTO_IPV6 && chdr->cmsg_type == IPV6_PKTINFO) {
|
||||
PSOCKADDR_IN6 localAddr = (PSOCKADDR_IN6)&localAddress->address;
|
||||
|
||||
localAddr->sin6_family = AF_INET6;
|
||||
localAddr->sin6_addr = ((IN6_PKTINFO*)WSA_CMSG_DATA(chdr))->ipi6_addr;
|
||||
|
||||
localAddress->addressLength = sizeof(*localAddr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
peerAddress->addressLength = msg.namelen;
|
||||
return (int) recvLength;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user