101 Commits

Author SHA1 Message Date
Cameron Gutman 299ab267c9 Enable ECN/L4S on UNIX
Since this is enabled as a QoS option, it will benefit from the opportunistic
disablement code when ECN-intolerant networks are encountered.
2024-02-03 14:32:25 -06:00
Cameron Gutman 9bf55a3433 Disable QoS tagging if 2 connect packets in a row are dropped 2020-06-12 21:16:46 -07:00
Cameron Gutman 5c96da29c2 Enable QoS prioritization on Windows 2020-04-09 17:42:12 -07:00
Cameron Gutman d988023971 Use EF instead of CS7 for DSCP
Some security guidelines recommend dropping CS7 tagged packets at the edge,
since CS7 is reserved for network control. EF seems to be the standard for
telephony applications and is fairly well preserved across the Internet per
https://www.sciencedirect.com/science/article/pii/S0166531619300203
2020-04-03 16:58:18 -07:00
Cameron Gutman 637cd52e96 Enable QoS prioritization on Linux 2020-03-29 15:44:14 -07:00
Cameron Gutman 512b3f26f9 Enable QOS prioritization on macOS 2020-03-29 15:21:26 -07:00
Cameron Gutman 5503534362 Fix Linux build 2019-10-12 19:41:41 -07:00
Sunguk Lee 93b080b053 vita: No more need vita specific codesets (#4)
* vita: No more need to define sockaddr_storage

* vita: Remove everything and combine unix codeset

* unix: Remove HACK for the specialized code of the vita nonblock IO
2019-10-12 15:10:59 -07:00
Cameron Gutman cf38f85e08 Be more lenient with the expected peer address for multi-homed hosts 2019-09-14 14:05:05 -07:00
Cameron Gutman e770a52bca Merge pull request #3 from d3m3vilurr/fix-vita-error-code
vita: No more use self defined net error code
2019-02-17 09:49:11 -08:00
Sunguk Lee 42891f6919 vita: No more use self defined net error code 2018-07-28 21:50:59 +09:00
Antonio Aloisio eb38c3c737 Fixed build with latest VitaSDK (#2) 2018-07-25 21:27:12 -07:00
Sunguk Lee e33ca1dc47 Add vita environment (#1)
* vita: Initial port

* vita: add debug logging and reduce max number of IOV (caused errors)

* vita: now using newlib's socket apis

* vita: Refactoring for cgutman/enet

* Fix review things

https://github.com/cgutman/enet/pull/1#pullrequestreview-2436331
2016-10-02 00:56:59 -07:00
Cameron Gutman 7546b505c1 Lower ENet's MTU to 900 because some ISPs will drop the RTSP DESCRIBE response packets with the default MTU 2016-05-21 18:01:31 -05:00
Cameron Gutman 2bc07bb50d Add enet_address_set_address() function to allow ENetAddress to be populated from sockaddr directly 2016-04-02 14:04:31 -04:00
Cameron Gutman a602abf244 Switch to gettimeofday() for seeding on UNIX 2016-03-31 11:22:06 -04:00
Cameron Gutman 167f41aa2b Fix build with NO_MSGAPI undefined 2016-03-27 22:47:50 -04:00
Cameron Gutman b2ee3b7b48 Add support for building with PNaCl's newlibc 2016-03-11 00:27:48 -08:00
Cameron Gutman 8b24595dbd Require an address family to be specified when creating a host 2016-03-07 14:26:13 -08:00
Cameron Gutman b3e34fa1db Fix some IPv6 compatibility issues 2016-03-06 23:22:59 -08:00
Cameron Gutman 4f7ef11c23 Fix some compilation warnings 2016-03-06 15:33:32 -08:00
Cameron Gutman a39d3bb49c Wake up every once in a while to see if any retransmissions or pings need to be sent 2016-03-06 14:56:08 -08:00
Cameron Gutman ae9002fe19 Protocol agnostic socket address to fix IPv6 and remove broadcast support 2016-03-06 14:47:01 -08:00
lsalzman@gmail.com 4d1067179b update copyright years 2016-02-19 20:07:08 -05:00
lsalzman@gmail.com 00ccd3bd3f return -1 instead of 0 if getnameinfo returns an error 2016-02-19 19:54:40 -05:00
Lee Salzman 809a1d15b6 update packet flag documentation 2015-12-30 18:13:58 -05:00
Lee Salzman 5f476546ed use getaddrinfo and getnameinfo where available 2015-05-11 05:41:27 -04:00
lsalzman@gmail.com f7c46f03fd enet 1.3.13 release prep 2015-04-30 06:32:01 -07:00
lsalzman@gmail.com 7c27a5d5f8 fix window wrap check when sending reliable outgoing commands 2015-03-12 16:25:26 -07:00
lsalzman@gmail.com 9b06a12e71 handle case in bandwidth limit protocol where either incoming or outgoing limits are disabled, but not both 2015-03-09 11:54:01 -07:00
lsalzman 8df6e58c5f gethostbyname_r/gethostbyaddr_r fix for dragonfly bsd 2015-02-14 07:48:49 -08:00
Lee Salzman b574c946d8 update copyright year 2015-01-13 19:59:27 +02:00
Lee Salzman 4d2694d74e fix ENET_SOCKOPT_NONBLOCK when value is 0 2014-12-31 00:24:29 +02:00
Lee Salzman c8fa0aeea4 add cmake support 2014-12-02 17:46:04 +02:00
lsalzman 2fb98f9b02 added note about calling enet_host_service on both ends of a connection 2014-11-17 10:26:39 +02:00
Lee Salzman 6ef4e7d277 limit number of packets that can be received per iteration of protocol loop 2014-09-29 15:49:34 +03:00
Lee Salzman d85a037ec4 add premake file 2014-09-07 12:14:10 +03:00
Lee Salzman 99004c45ac include mmsystem.h for timeGetTime 2014-05-28 21:16:14 +03:00
Lee Salzman 736474ca83 small doc fixes 2014-05-11 08:00:37 +03:00
Lee Salzman 9c4d9953ac bold some links 2014-05-11 07:55:27 +03:00
Lee Salzman 6f287186d8 more doxygen cleanups 2014-05-11 07:26:52 +03:00
Lee Salzman 379290acd5 add doxygen layout 2014-05-11 06:36:21 +03:00
Lee Salzman 127643fae4 doxygen output cleanups 2014-05-11 06:28:48 +03:00
Lee Salzman 98219eb50d doxygen output cleanups 2014-05-11 05:08:55 +03:00
Lee Salzman b14c7e99e0 Merge pull request #33 from stephanecharette/master
upgrade doxygen configuration file
2014-05-11 04:47:24 +03:00
Stephane Charette 464e883f04 upgrade doxygen configuration file 2014-05-07 02:16:54 -07:00
lsalzman 9895a4f110 enet 1.3.12 release prep 2014-04-24 10:47:26 +03:00
Lee Salzman 518144338d fix maximumWaitingData handling to allow acknowledgements when the packet already exists 2014-04-14 21:21:21 +03:00
Lee Salzman 734a630bed update license date 2014-04-14 19:23:00 +03:00
Lee Salzman ea8d41f65c added maximumPacketSize and maximumWaitingData fields for limiting peer buffer space 2014-04-14 19:11:44 +03:00
Lee Salzman 73c930881f avoid some strncpy usage 2014-03-08 18:46:39 +02:00
lsalzman 5721b667f2 avoid an enet_time_get call when timeout expires 2014-02-21 11:20:20 +02:00
Lee Salzman c58ec4cc44 note about null-termination in enet_address_get_host 2014-02-20 19:55:51 +02:00
Lee Salzman b3de8a29c4 another doc fix 2013-12-28 17:21:14 +02:00
Lee Salzman 259376b214 doc fix 2013-12-28 16:43:12 +02:00
Lee Salzman 01416f5850 typo fix 2013-12-28 16:31:45 +02:00
Lee Salzman 272d4432f8 typo fixes 2013-12-28 16:30:15 +02:00
Lee Salzman 6fcfba5141 enet 1.3.11 release prep 2013-12-26 15:49:43 +02:00
lsalzman 84a4ac70ab handle disconnects in connecting state 2013-11-27 16:33:09 +02:00
Lee Salzman 9d1d09c1e5 _MSC_VER fix 2013-11-26 19:40:06 +02:00
Lee Salzman d45b44f2b5 allow loopback connections 2013-11-17 20:19:17 +02:00
Lee Salzman 970ee42041 FD_CLR typo fix 2013-11-07 23:40:15 +02:00
lsalzman 2ebb3560b7 enet 1.3.10 release prep 2013-10-23 14:13:44 +03:00
Lee Salzman e19dc9f825 double maximum reliable window size 2013-10-20 13:29:44 +03:00
Lee Salzman 48571bb05f make VS quiet down about -unsigned 2013-10-09 00:25:36 +03:00
lsalzman 2c5dd69b17 fix RCVTIMEO and SNDTIMEO options on unix and also add NODELAY 2013-09-27 09:42:37 +03:00
Lee Salzman bc8019aa15 fix some warnings 2013-08-19 07:07:19 +03:00
Lee Salzman 4d7b80152b small fix for duplicate peers 2013-08-18 17:20:17 +03:00
Lee Salzman dc48f76192 enet 1.3.9 release prep 2013-08-16 01:19:06 +03:00
Lee Salzman c0713c47e6 more ENET_SOCKOPT_ERROR fixes 2013-08-16 01:18:21 +03:00
Lee Salzman 3595c0b3fb ENET_SOCKOPT_ERROR fix 2013-08-16 00:35:28 +03:00
Lee Salzman e123218df3 added enet_socket_get_option() and ENET_SOCKOPT_ERROR 2013-08-16 00:14:02 +03:00
lsalzman 73ef8d8a96 enet_host_random_seed fix 2013-08-14 18:26:29 +03:00
lsalzman 1658cf3a95 stub out enet_host_random_seed() 2013-08-09 09:41:57 +03:00
lsalzman 4697a58d53 fix file permissions 2013-07-08 14:59:05 +03:00
Lee Salzman 742e6b9552 1.3.8 release prep 2013-06-02 13:23:50 +03:00
Lee Salzman 51f303d5e2 another typo fix 2013-05-12 18:29:22 +03:00
Lee Salzman 2d2440053d typo fix 2013-05-12 11:04:00 +03:00
Lee Salzman 5f05025ee1 note about enet_host_bandwidth_throttle optimizations 2013-05-11 21:58:27 +03:00
Lee Salzman 69b98608e5 track the number of connected peers to make throttling a bit cheaper 2013-05-11 21:53:55 +03:00
Lee Salzman 2bb83d9813 check for MS C compiler before using pragmas 2013-05-11 18:56:20 +03:00
Lee Salzman 7dc0189ffb handle EINTR in enet_socket_wait 2013-05-10 17:49:44 +03:00
Lee Salzman 5d76b92c54 explicitly include sys/socket.h 2013-05-09 15:19:44 +03:00
Lee Salzman bd4e5035bc move MSG_MAXIOVLEN check out of configure.ac 2013-05-09 15:04:01 +03:00
lsalzman 71d6d63ed8 remove some more looping in enet_host_bandwidth_throttle 2013-05-08 11:02:13 +03:00
lsalzman 30d859f9a4 avoid some looping in enet_host_bandwidth_throttle 2013-05-08 10:46:17 +03:00
lsalzman 27d41dd2ae add enet_linked_version() for querying linked version 2013-05-07 10:11:22 +03:00
Lee Salzman ff4e2cab30 check for _WIN32 instead of WIN32 2013-04-07 07:11:12 +03:00
lsalzman 03c0de167c add clang check 2013-04-03 10:30:41 +03:00
Lee Salzman 714f40319a set unused reliable sequence number field for acks to sane value 2013-03-23 17:22:32 +02:00
Lee Salzman bf8187f265 changelog note about enet_socket_get_address 2013-03-20 00:49:49 +02:00
Lee Salzman bc81ba716f Merge branch 'master' of github.com:lsalzman/enet 2013-03-20 00:44:14 +02:00
Lee Salzman 726ff6bc6d query the socket name if an explicit address binding is requested on host creation 2013-03-20 00:43:34 +02:00
lsalzman db685c3d4f only use perror if ENET_DEBUG defined 2013-03-19 11:26:54 +02:00
lsalzman eb7126c662 ENet 1.3.7 release prep 2013-03-06 17:10:59 +02:00
lsalzman 4ce4aac149 added ENET_PACKET_FLAG_SENT to indicate that a packet has been sent 2013-02-27 16:29:22 +02:00
Lee Salzman 8ff344897a added userData field to ENetPacket 2013-01-19 16:39:34 +02:00
Lee Salzman 5ff8ccb74f updating changelog 2013-01-07 21:18:35 +02:00
Lee Salzman 9185dc80bc state handling cleanups 2013-01-07 20:46:31 +02:00
Lee Salzman 2e708e5908 Merge branch 'master' of github.com:lsalzman/enet 2012-12-14 05:10:44 +02:00
Lee Salzman 65f71f82b8 use timeGetTime() for random seed instead of time() on windows 2012-12-14 05:10:13 +02:00
26 changed files with 3241 additions and 1229 deletions
+69
View File
@@ -0,0 +1,69 @@
cmake_minimum_required(VERSION 2.6)
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)
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()
include_directories(${PROJECT_SOURCE_DIR}/include)
add_library(enet STATIC
callbacks.c
compress.c
host.c
list.c
packet.c
peer.c
protocol.c
unix.c
win32.c
)
+46
View File
@@ -1,3 +1,49 @@
* use getaddrinfo and getnameinfo where available
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
* added enet_socket_get_address() for querying the local address of a socket
* silenced some debugging prints unless ENET_DEBUG is defined during compilation
* handle EINTR in enet_socket_wait() so that enet_host_service() doesn't propagate errors from signals
* optimized enet_host_bandwidth_throttle() to be less expensive for large numbers of peers
ENet 1.3.7 (March 6, 2013):
* added ENET_PACKET_FLAG_SENT to indicate that a packet is being freed because it has been sent
* added userData field to ENetPacket
* changed how random seed is generated on Windows to avoid import warnings
* fixed case where disconnects could be generated with no preceding connect event
ENet 1.3.6 (December 11, 2012):
* added support for intercept callback in ENetHost that can be used to process raw packets before ENet
Executable → Regular
+1952 -642
View File
File diff suppressed because it is too large Load Diff
+191
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 2002-2012 Lee Salzman
Copyright (c) 2002-2016 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
View File
@@ -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 3:0:1
INCLUDES = -I$(top_srcdir)/include
libenet_la_LDFLAGS = $(AM_LDFLAGS) -version-info 7:1:0
AM_CPPFLAGS = -I$(top_srcdir)/include
ACLOCAL_AMFLAGS = -Im4
+6
View File
@@ -27,6 +27,12 @@ enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits
return enet_initialize ();
}
ENetVersion
enet_linked_version (void)
{
return ENET_VERSION;
}
void *
enet_malloc (size_t size)
+3 -4
View File
@@ -1,4 +1,4 @@
AC_INIT([libenet], [1.3.6])
AC_INIT([libenet], [1.3.13])
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)])
@@ -21,9 +23,6 @@ AC_CHECK_TYPE(socklen_t, [AC_DEFINE(HAS_SOCKLEN_T)], ,
#include <sys/socket.h>
)
AC_EGREP_HEADER(MSG_MAXIOVLEN, /usr/include/sys/socket.h, AC_DEFINE(ENET_BUFFER_MAXIMUM, [MSG_MAXIOVLEN]))
AC_EGREP_HEADER(MSG_MAXIOVLEN, socket.h, AC_DEFINE(ENET_BUFFER_MAXIMUM, [MSG_MAXIOVLEN]))
AC_CONFIG_FILES([Makefile
libenet.pc])
AC_OUTPUT
Executable → Regular
+2 -2
View File
@@ -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?
Executable → Regular
+2 -2
View File
@@ -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.
Executable → Regular
+1 -2
View File
@@ -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
Executable → Regular
+1 -1
View File
@@ -1,7 +1,7 @@
/**
@page License License
Copyright (c) 2002-2012 Lee Salzman
Copyright (c) 2002-2016 Lee Salzman
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
Executable → Regular
+12 -12
View File
@@ -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.6) can be downloaded <a href="http://enet.bespin.org/download/enet-1.3.6.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.13) can be downloaded <a class="el" href="download/enet-1.3.13.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.
*/
Executable → Regular
+11 -2
View File
@@ -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
Executable → Regular
View File
+59 -78
View File
@@ -3,9 +3,7 @@
@brief ENet host management functions
*/
#define ENET_BUILDING_LIB 1
#define __MINGW_USE_VC2005_COMPAT 1
#include <string.h>
#include <time.h>
#include "enet/enet.h"
/** @defgroup host ENet host functions
@@ -14,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
@@ -28,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;
@@ -50,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)
@@ -63,11 +62,11 @@ 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)
if (address != NULL && enet_socket_get_address (host -> socket, & host -> address) < 0)
host -> address = * address;
if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
@@ -76,7 +75,8 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
host -> randomSeed = (enet_uint32) time(NULL) + (enet_uint32) (size_t) host;
host -> randomSeed = (enet_uint32) (size_t) host;
host -> randomSeed += enet_host_random_seed ();
host -> randomSeed = (host -> randomSeed << 16) | (host -> randomSeed >> 16);
host -> channelLimit = channelLimit;
host -> incomingBandwidth = incomingBandwidth;
@@ -88,8 +88,7 @@ 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 -> receivedAddress, 0, sizeof (host -> receivedAddress));
host -> receivedData = NULL;
host -> receivedDataLength = 0;
@@ -98,6 +97,12 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
host -> totalReceivedData = 0;
host -> totalReceivedPackets = 0;
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;
host -> compressor.decompress = NULL;
@@ -247,30 +252,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
@@ -324,46 +305,44 @@ enet_host_bandwidth_throttle (ENetHost * host)
{
enet_uint32 timeCurrent = enet_time_get (),
elapsedTime = timeCurrent - host -> bandwidthThrottleEpoch,
peersTotal = 0,
dataTotal = 0,
peersRemaining,
bandwidth,
peersRemaining = (enet_uint32) host -> connectedPeers,
dataTotal = ~0,
bandwidth = ~0,
throttle = 0,
bandwidthLimit = 0;
int needsAdjustment;
int needsAdjustment = host -> bandwidthLimitedPeers > 0 ? 1 : 0;
ENetPeer * peer;
ENetProtocol command;
if (elapsedTime < ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
return;
for (peer = host -> peers;
peer < & host -> peers [host -> peerCount];
++ peer)
{
if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
continue;
host -> bandwidthThrottleEpoch = timeCurrent;
++ peersTotal;
dataTotal += peer -> outgoingDataTotal;
}
if (peersTotal == 0)
if (peersRemaining == 0)
return;
peersRemaining = peersTotal;
needsAdjustment = 1;
if (host -> outgoingBandwidth != 0)
{
dataTotal = 0;
bandwidth = (host -> outgoingBandwidth * elapsedTime) / 1000;
if (host -> outgoingBandwidth == 0)
bandwidth = ~0;
else
bandwidth = (host -> outgoingBandwidth * elapsedTime) / 1000;
for (peer = host -> peers;
peer < & host -> peers [host -> peerCount];
++ peer)
{
if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
continue;
dataTotal += peer -> outgoingDataTotal;
}
}
while (peersRemaining > 0 && needsAdjustment != 0)
{
needsAdjustment = 0;
if (dataTotal < bandwidth)
if (dataTotal <= bandwidth)
throttle = ENET_PEER_PACKET_THROTTLE_SCALE;
else
throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal;
@@ -394,7 +373,9 @@ enet_host_bandwidth_throttle (ENetHost * host)
peer -> outgoingBandwidthThrottleEpoch = timeCurrent;
peer -> incomingDataTotal = 0;
peer -> outgoingDataTotal = 0;
needsAdjustment = 1;
-- peersRemaining;
bandwidth -= peerBandwidth;
@@ -403,25 +384,35 @@ enet_host_bandwidth_throttle (ENetHost * host)
}
if (peersRemaining > 0)
for (peer = host -> peers;
peer < & host -> peers [host -> peerCount];
++ peer)
{
if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
continue;
if (dataTotal <= bandwidth)
throttle = ENET_PEER_PACKET_THROTTLE_SCALE;
else
throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal;
peer -> packetThrottleLimit = throttle;
for (peer = host -> peers;
peer < & host -> peers [host -> peerCount];
++ peer)
{
if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
continue;
if (peer -> packetThrottle > peer -> packetThrottleLimit)
peer -> packetThrottle = peer -> packetThrottleLimit;
peer -> packetThrottleLimit = throttle;
if (peer -> packetThrottle > peer -> packetThrottleLimit)
peer -> packetThrottle = peer -> packetThrottleLimit;
peer -> incomingDataTotal = 0;
peer -> outgoingDataTotal = 0;
}
}
if (host -> recalculateBandwidthLimits)
{
host -> recalculateBandwidthLimits = 0;
peersRemaining = peersTotal;
peersRemaining = (enet_uint32) host -> connectedPeers;
bandwidth = host -> incomingBandwidth;
needsAdjustment = 1;
@@ -472,16 +463,6 @@ enet_host_bandwidth_throttle (ENetHost * host)
enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
}
}
host -> bandwidthThrottleEpoch = timeCurrent;
for (peer = host -> peers;
peer < & host -> peers [host -> peerCount];
++ peer)
{
peer -> incomingDataTotal = 0;
peer -> outgoingDataTotal = 0;
}
}
/** @} */
+57 -58
View File
@@ -12,7 +12,7 @@ extern "C"
#include <stdlib.h>
#ifdef WIN32
#ifdef _WIN32
#include "enet/win32.h"
#else
#include "enet/unix.h"
@@ -25,8 +25,11 @@ extern "C"
#define ENET_VERSION_MAJOR 1
#define ENET_VERSION_MINOR 3
#define ENET_VERSION_PATCH 6
#define ENET_VERSION_PATCH 13
#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)
#define ENET_VERSION_GET_PATCH(version) ((version)&0xFF)
#define ENET_VERSION ENET_VERSION_CREATE(ENET_VERSION_MAJOR, ENET_VERSION_MINOR, ENET_VERSION_PATCH)
typedef enet_uint32 ENetVersion;
@@ -43,20 +46,23 @@ typedef enum _ENetSocketType
typedef enum _ENetSocketWait
{
ENET_SOCKET_WAIT_NONE = 0,
ENET_SOCKET_WAIT_SEND = (1 << 0),
ENET_SOCKET_WAIT_RECEIVE = (1 << 1)
ENET_SOCKET_WAIT_NONE = 0,
ENET_SOCKET_WAIT_SEND = (1 << 0),
ENET_SOCKET_WAIT_RECEIVE = (1 << 1),
ENET_SOCKET_WAIT_INTERRUPT = (1 << 2)
} 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
@@ -66,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;
/**
@@ -112,7 +103,10 @@ typedef enum _ENetPacketFlag
ENET_PACKET_FLAG_NO_ALLOCATE = (1 << 2),
/** packet will be fragmented using unreliable (instead of reliable) sends
* if it exceeds the MTU */
ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT = (1 << 3)
ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT = (1 << 3),
/** whether the packet has been sent from all queues it has been entered into */
ENET_PACKET_FLAG_SENT = (1<<8)
} ENetPacketFlag;
typedef void (ENET_CALLBACK * ENetPacketFreeCallback) (struct _ENetPacket *);
@@ -133,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
@@ -143,6 +141,7 @@ typedef struct _ENetPacket
enet_uint8 * data; /**< allocated data for packet */
size_t dataLength; /**< length of data */
ENetPacketFreeCallback freeCallback; /**< function to be called when the packet is no longer in use */
void * userData; /**< application private data, may be freely modified */
} ENetPacket;
typedef struct _ENetAcknowledgement
@@ -202,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,
@@ -304,6 +305,7 @@ typedef struct _ENetPeer
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.
@@ -335,7 +337,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,6 +376,11 @@ typedef struct _ENetHost
enet_uint32 totalReceivedData; /**< total data received, user should reset to 0 as needed to prevent overflow */
enet_uint32 totalReceivedPackets; /**< total UDP packets received, user should reset to 0 as needed to prevent overflow */
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;
/**
@@ -391,7 +397,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
@@ -437,7 +443,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);
@@ -448,6 +454,12 @@ ENET_API int enet_initialize_with_callbacks (ENetVersion version, const ENetCall
*/
ENET_API void enet_deinitialize (void);
/**
Gives the linked version of the ENet library.
@returns the version number
*/
ENET_API ENetVersion enet_linked_version (void);
/** @} */
/** @defgroup private ENet private implementation functions */
@@ -465,8 +477,9 @@ 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 *);
@@ -474,6 +487,7 @@ ENET_API int enet_socket_send (ENetSocket, const ENetAddress *, const ENe
ENET_API int enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t);
ENET_API int enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32);
ENET_API int enet_socket_set_option (ENetSocket, ENetSocketOption, int);
ENET_API int enet_socket_get_option (ENetSocket, ENetSocketOption, int *);
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);
@@ -492,26 +506,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);
/** @} */
@@ -520,18 +517,18 @@ 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);
ENET_API int enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *);
ENET_API ENetPacket * enet_peer_receive (ENetPeer *, enet_uint8 * channelID);
@@ -547,10 +544,12 @@ 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_on_connect (ENetPeer *);
extern void enet_peer_on_disconnect (ENetPeer *);
ENET_API void * enet_range_coder_create (void);
ENET_API void enet_range_coder_destroy (void *);
+4 -5
View File
@@ -13,11 +13,10 @@ enum
ENET_PROTOCOL_MAXIMUM_MTU = 4096,
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,10 +53,10 @@ 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__)
#elif defined(__GNUC__) || defined(__clang__)
#define ENET_PACKED __attribute__ ((packed))
#else
#define ENET_PACKED
@@ -191,7 +190,7 @@ typedef union _ENetProtocol
ENetProtocolThrottleConfigure throttleConfigure;
} ENET_PACKED ENetProtocol;
#ifdef _MSC_VER_
#ifdef _MSC_VER
#pragma pack(pop)
#endif
+7 -5
View File
@@ -8,15 +8,17 @@
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#ifdef MSG_MAXIOVLEN
#define ENET_BUFFER_MAXIMUM MSG_MAXIOVLEN
#endif
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 */
@@ -38,7 +40,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__ */
+8 -8
View File
@@ -5,22 +5,22 @@
#ifndef __ENET_WIN32_H__
#define __ENET_WIN32_H__
#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
#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))
@@ -36,8 +36,8 @@ typedef struct
#define ENET_CALLBACK __cdecl
#if defined ENET_DLL
#if defined ENET_BUILDING_LIB
#ifdef ENET_DLL
#ifdef ENET_BUILDING_LIB
#define ENET_API __declspec( dllexport )
#else
#define ENET_API __declspec( dllimport )
@@ -50,7 +50,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__ */
+3 -2
View File
@@ -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
@@ -45,6 +45,7 @@ enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags)
packet -> flags = flags;
packet -> dataLength = dataLength;
packet -> freeCallback = NULL;
packet -> userData = NULL;
return packet;
}
@@ -115,7 +116,7 @@ reflect_crc (int val, int bits)
}
static void
initialize_crc32 ()
initialize_crc32 (void)
{
int byte;
+60 -15
View File
@@ -105,7 +105,7 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
if (peer -> state != ENET_PEER_STATE_CONNECTED ||
channelID >= peer -> channelCount ||
packet -> dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE)
packet -> dataLength > peer -> host -> maximumPacketSize)
return -1;
fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment);
@@ -241,6 +241,8 @@ enet_peer_receive (ENetPeer * peer, enet_uint8 * channelID)
enet_free (incomingCommand);
peer -> totalWaitingData -= packet -> dataLength;
return packet;
}
@@ -337,6 +339,30 @@ enet_peer_reset_queues (ENetPeer * peer)
peer -> channelCount = 0;
}
void
enet_peer_on_connect (ENetPeer * peer)
{
if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
{
if (peer -> incomingBandwidth != 0)
++ peer -> host -> bandwidthLimitedPeers;
++ peer -> host -> connectedPeers;
}
}
void
enet_peer_on_disconnect (ENetPeer * peer)
{
if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
{
if (peer -> incomingBandwidth != 0)
-- peer -> host -> bandwidthLimitedPeers;
-- peer -> host -> connectedPeers;
}
}
/** Forcefully disconnects a peer.
@param peer peer to forcefully disconnect
@remarks The foreign host represented by the peer is not notified of the disconnection and will timeout
@@ -345,6 +371,8 @@ enet_peer_reset_queues (ENetPeer * peer)
void
enet_peer_reset (ENetPeer * peer)
{
enet_peer_on_disconnect (peer);
peer -> outgoingPeerID = ENET_PROTOCOL_MAXIMUM_PEER_ID;
peer -> connectID = 0;
@@ -389,6 +417,7 @@ enet_peer_reset (ENetPeer * peer)
peer -> incomingUnsequencedGroup = 0;
peer -> outgoingUnsequencedGroup = 0;
peer -> eventData = 0;
peer -> totalWaitingData = 0;
memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow));
@@ -398,7 +427,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.
*/
@@ -460,7 +489,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
@@ -519,7 +548,11 @@ enet_peer_disconnect (ENetPeer * peer, enet_uint32 data)
enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
peer -> state = ENET_PEER_STATE_DISCONNECTING;
{
enet_peer_on_disconnect (peer);
peer -> state = ENET_PEER_STATE_DISCONNECTING;
}
else
{
enet_host_flush (peer -> host);
@@ -584,7 +617,7 @@ void
enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoingCommand)
{
ENetChannel * channel = & peer -> channels [outgoingCommand -> command.header.channelID];
peer -> outgoingDataTotal += enet_protocol_command_size (outgoingCommand -> command.header.command) + outgoingCommand -> fragmentLength;
if (outgoingCommand -> command.header.channelID == 0xFF)
@@ -788,7 +821,7 @@ enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * ch
}
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;
@@ -797,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)
{
@@ -811,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)
@@ -819,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);
@@ -841,7 +875,7 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber)
break;
goto freePacket;
goto discardCommand;
}
}
break;
@@ -852,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);
@@ -883,7 +917,7 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
if (incomingCommand -> unreliableSequenceNumber < unreliableSequenceNumber)
break;
goto freePacket;
goto discardCommand;
}
}
break;
@@ -893,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;
@@ -922,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);
@@ -940,7 +985,7 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
return incomingCommand;
freePacket:
discardCommand:
if (fragmentCount > 0)
goto notifyError;
+59
View File
@@ -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"
+179 -139
View File
@@ -32,6 +32,30 @@ enet_protocol_command_size (enet_uint8 commandNumber)
return commandSizes [commandNumber & ENET_PROTOCOL_COMMAND_MASK];
}
static void
enet_protocol_change_state (ENetHost * host, ENetPeer * peer, ENetPeerState state)
{
if (state == ENET_PEER_STATE_CONNECTED || state == ENET_PEER_STATE_DISCONNECT_LATER)
enet_peer_on_connect (peer);
else
enet_peer_on_disconnect (peer);
peer -> state = state;
}
static void
enet_protocol_dispatch_state (ENetHost * host, ENetPeer * peer, ENetPeerState state)
{
enet_protocol_change_state (host, peer, state);
if (! peer -> needsDispatch)
{
enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList);
peer -> needsDispatch = 1;
}
}
static int
enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
{
@@ -45,7 +69,7 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
{
case ENET_PEER_STATE_CONNECTION_PENDING:
case ENET_PEER_STATE_CONNECTION_SUCCEEDED:
peer -> state = ENET_PEER_STATE_CONNECTED;
enet_protocol_change_state (host, peer, ENET_PEER_STATE_CONNECTED);
event -> type = ENET_EVENT_TYPE_CONNECT;
event -> peer = peer;
@@ -92,19 +116,6 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
return 0;
}
static void
enet_protocol_dispatch_state (ENetHost * host, ENetPeer * peer, ENetPeerState state)
{
peer -> state = state;
if (! peer -> needsDispatch)
{
enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList);
peer -> needsDispatch = 1;
}
}
static void
enet_protocol_notify_connect (ENetHost * host, ENetPeer * peer, ENetEvent * event)
{
@@ -112,7 +123,7 @@ enet_protocol_notify_connect (ENetHost * host, ENetPeer * peer, ENetEvent * even
if (event != NULL)
{
peer -> state = ENET_PEER_STATE_CONNECTED;
enet_protocol_change_state (host, peer, ENET_PEER_STATE_CONNECTED);
event -> type = ENET_EVENT_TYPE_CONNECT;
event -> peer = peer;
@@ -163,7 +174,11 @@ enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer)
-- outgoingCommand -> packet -> referenceCount;
if (outgoingCommand -> packet -> referenceCount == 0)
enet_packet_destroy (outgoingCommand -> packet);
{
outgoingCommand -> packet -> flags |= ENET_PACKET_FLAG_SENT;
enet_packet_destroy (outgoingCommand -> packet);
}
}
enet_free (outgoingCommand);
@@ -237,7 +252,11 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl
-- outgoingCommand -> packet -> referenceCount;
if (outgoingCommand -> packet -> referenceCount == 0)
enet_packet_destroy (outgoingCommand -> packet);
{
outgoingCommand -> packet -> flags |= ENET_PACKET_FLAG_SENT;
enet_packet_destroy (outgoingCommand -> packet);
}
}
enet_free (outgoingCommand);
@@ -258,8 +277,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);
@@ -268,59 +287,60 @@ 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 -> receivedAddress))
{
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 -> receivedAddress;
peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID);
peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth);
peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.outgoingBandwidth);
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;
@@ -343,27 +363,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;
@@ -382,28 +402,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 ||
@@ -412,16 +431,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;
@@ -430,7 +445,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;
@@ -440,7 +454,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;
@@ -466,11 +480,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);
@@ -481,7 +491,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 ||
@@ -490,16 +499,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;
@@ -525,7 +530,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;
@@ -548,7 +553,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;
@@ -586,13 +591,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;
}
@@ -638,7 +640,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;
@@ -667,7 +669,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;
@@ -710,11 +712,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;
}
@@ -742,17 +740,33 @@ enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer,
static int
enet_protocol_handle_ping (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
{
if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
return -1;
return 0;
}
static int
enet_protocol_handle_bandwidth_limit (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
{
if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
return -1;
if (peer -> incomingBandwidth != 0)
-- host -> bandwidthLimitedPeers;
peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.incomingBandwidth);
peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.outgoingBandwidth);
if (peer -> incomingBandwidth != 0)
++ host -> bandwidthLimitedPeers;
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;
@@ -769,6 +783,9 @@ enet_protocol_handle_bandwidth_limit (ENetHost * host, ENetPeer * peer, const EN
static int
enet_protocol_handle_throttle_configure (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
{
if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
return -1;
peer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleInterval);
peer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleAcceleration);
peer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleDeceleration);
@@ -779,12 +796,12 @@ enet_protocol_handle_throttle_configure (ENetHost * host, ENetPeer * peer, const
static int
enet_protocol_handle_disconnect (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
{
if (peer -> state == ENET_PEER_STATE_ZOMBIE || peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT)
if (peer -> state == ENET_PEER_STATE_DISCONNECTED || peer -> state == ENET_PEER_STATE_ZOMBIE || peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT)
return 0;
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)
@@ -795,7 +812,7 @@ enet_protocol_handle_disconnect (ENetHost * host, ENetPeer * peer, const ENetPro
}
else
if (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT;
enet_protocol_change_state (host, peer, ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT);
else
enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);
@@ -813,6 +830,9 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
receivedReliableSequenceNumber;
ENetProtocolCommand commandNumber;
if (peer -> state == ENET_PEER_STATE_DISCONNECTED || peer -> state == ENET_PEER_STATE_ZOMBIE)
return 0;
receivedSentTime = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedSentTime);
receivedSentTime |= host -> serviceTime & 0xFFFF0000;
if ((receivedSentTime & 0x8000) > (host -> serviceTime & 0x8000))
@@ -989,9 +1009,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;
@@ -1033,8 +1051,7 @@ 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 -> receivedAddress, sizeof (host -> receivedAddress));
peer -> incomingDataTotal += host -> receivedDataLength;
}
@@ -1065,7 +1082,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
command -> header.reliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> header.reliableSequenceNumber);
switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK)
switch (commandNumber)
{
case ENET_PROTOCOL_COMMAND_ACKNOWLEDGE:
if (enet_protocol_handle_acknowledge (host, event, peer, command))
@@ -1073,6 +1090,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
break;
case ENET_PROTOCOL_COMMAND_CONNECT:
if (peer != NULL)
goto commandError;
peer = enet_protocol_handle_connect (host, header, command);
if (peer == NULL)
goto commandError;
@@ -1146,6 +1165,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
{
case ENET_PEER_STATE_DISCONNECTING:
case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT:
case ENET_PEER_STATE_DISCONNECTED:
case ENET_PEER_STATE_ZOMBIE:
break;
case ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT:
@@ -1170,7 +1191,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;
@@ -1236,7 +1259,8 @@ enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer)
ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
ENetAcknowledgement * acknowledgement;
ENetListIterator currentAcknowledgement;
enet_uint16 reliableSequenceNumber;
currentAcknowledgement = enet_list_begin (& peer -> acknowledgements);
while (currentAcknowledgement != enet_list_end (& peer -> acknowledgements))
@@ -1258,10 +1282,13 @@ enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer)
buffer -> dataLength = sizeof (ENetProtocolAcknowledge);
host -> packetSize += buffer -> dataLength;
reliableSequenceNumber = ENET_HOST_TO_NET_16 (acknowledgement -> command.header.reliableSequenceNumber);
command -> header.command = ENET_PROTOCOL_COMMAND_ACKNOWLEDGE;
command -> header.channelID = acknowledgement -> command.header.channelID;
command -> acknowledge.receivedReliableSequenceNumber = ENET_HOST_TO_NET_16 (acknowledgement -> command.header.reliableSequenceNumber);
command -> header.reliableSequenceNumber = reliableSequenceNumber;
command -> acknowledge.receivedReliableSequenceNumber = reliableSequenceNumber;
command -> acknowledge.receivedSentTime = ENET_HOST_TO_NET_16 (acknowledgement -> sentTime);
if ((acknowledgement -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT)
@@ -1459,7 +1486,7 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
! (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)))))
(((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) >> (ENET_PEER_RELIABLE_WINDOWS - reliableWindow)))))
windowWrap = 1;
if (windowWrap)
{
@@ -1621,12 +1648,7 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent;
#ifdef ENET_DEBUG
#ifdef WIN32
printf (
#else
fprintf (stderr,
#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);
printf ("peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingReliableCommands), enet_list_size (& currentPeer -> outgoingUnreliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0);
#endif
currentPeer -> packetLossVariance -= currentPeer -> packetLossVariance / 4;
@@ -1671,12 +1693,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
}
}
@@ -1701,6 +1718,12 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
currentPeer -> lastSendTime = host -> serviceTime;
if (currentPeer -> state == ENET_PEER_STATE_CONNECTING && currentPeer -> packetsLost == 2) {
// Disable QoS tagging if we don't get a response to 2 connection requests in a row.
// Some networks drop QoS tagged packets, so let's try without it.
enet_socket_set_option (host -> socket, ENET_SOCKOPT_QOS, 0);
}
sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount);
enet_protocol_remove_sent_unreliable_commands (currentPeer);
@@ -1780,7 +1803,9 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
return 1;
case -1:
#ifdef ENET_DEBUG
perror ("Error dispatching incoming packets");
#endif
return -1;
@@ -1793,7 +1818,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);
@@ -1804,7 +1829,9 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
return 1;
case -1:
#ifdef ENET_DEBUG
perror ("Error sending outgoing packets");
#endif
return -1;
@@ -1818,7 +1845,9 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
return 1;
case -1:
#ifdef ENET_DEBUG
perror ("Error receiving incoming packets");
#endif
return -1;
@@ -1832,7 +1861,9 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
return 1;
case -1:
#ifdef ENET_DEBUG
perror ("Error sending outgoing packets");
#endif
return -1;
@@ -1848,7 +1879,9 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
return 1;
case -1:
#ifdef ENET_DEBUG
perror ("Error dispatching incoming packets");
#endif
return -1;
@@ -1857,18 +1890,25 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
}
}
host -> serviceTime = enet_time_get ();
if (ENET_TIME_GREATER_EQUAL (host -> serviceTime, timeout))
return 0;
waitCondition = ENET_SOCKET_WAIT_RECEIVE;
do
{
host -> serviceTime = enet_time_get ();
if (ENET_TIME_GREATER_EQUAL (host -> serviceTime, timeout))
return 0;
waitCondition = ENET_SOCKET_WAIT_RECEIVE | ENET_SOCKET_WAIT_INTERRUPT;
if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime) / 10) != 0)
return -1;
}
while (waitCondition & ENET_SOCKET_WAIT_INTERRUPT);
if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0)
return -1;
host -> serviceTime = enet_time_get ();
} while (waitCondition == ENET_SOCKET_WAIT_RECEIVE);
}
return 0;
}
+312 -142
View File
@@ -2,13 +2,14 @@
@file unix.c
@brief ENet Unix system specific functions
*/
#ifndef WIN32
#ifndef _WIN32
#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,7 +19,7 @@
#define ENET_BUILDING_LIB 1
#include "enet/enet.h"
#ifdef __APPLE__
#if defined(__APPLE__)
#ifdef HAS_POLL
#undef HAS_POLL
#endif
@@ -37,12 +38,54 @@
#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
#else
#ifndef HAS_IOCTL
#define HAS_IOCTL 1
#endif
#endif
#ifdef HAS_FCNTL
#include <fcntl.h>
#endif
#ifdef HAS_IOCTL
#include <sys/ioctl.h>
#endif
#ifdef HAS_POLL
#include <sys/poll.h>
#endif
@@ -51,6 +94,10 @@
typedef int socklen_t;
#endif
#ifndef SOMAXCONN
#define SOMAXCONN 128
#endif
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
#endif
@@ -68,6 +115,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,110 +145,114 @@ 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;
}
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_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_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)
{
address -> addressLength = sizeof (address -> address);
if (getsockname (socket, (struct sockaddr *) & address -> address, & address -> addressLength) == -1)
return -1;
return 0;
}
int
@@ -201,9 +262,9 @@ 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);
return socket (af, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
}
int
@@ -214,14 +275,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:
@@ -237,11 +298,67 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
break;
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;
}
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 | 0x01) : 0; // DSCP: Expedited Forwarding + ECT(1) (L4S)
result = setsockopt (socket, IPPROTO_IP, IP_TOS, (char *) & value, sizeof (int));
#endif
#ifdef IPV6_TCLASS
// UNIX - IPv6
value = value ? (46 << 2 | 0x01): 0; // DSCP: Expedited Forwarding + ECT(1) (L4S)
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:
@@ -253,16 +370,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;
@@ -273,25 +383,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)
{
@@ -311,28 +416,60 @@ enet_socket_send (ENetSocket socket,
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 *) & address -> address, address -> addressLength);
if (bufferCount > 1)
free(sendBuffer);
#else
struct msghdr msgHdr;
memset (& msgHdr, 0, sizeof (struct msghdr));
if (address != 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*) & address -> address;
msgHdr.msg_namelen = address -> addressLength;
}
msgHdr.msg_iov = (struct iovec *) buffers;
msgHdr.msg_iovlen = bufferCount;
sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL);
#endif
if (sentLength == -1)
{
@@ -351,16 +488,33 @@ enet_socket_receive (ENetSocket socket,
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 *) & address -> address, & address -> addressLength);
if (recvLength == -1)
{
if (errno == EWOULDBLOCK)
return 0;
return -1;
}
return recvLength;
#else
struct msghdr msgHdr;
memset (& msgHdr, 0, sizeof (struct msghdr));
if (address != NULL)
{
msgHdr.msg_name = & sin;
msgHdr.msg_namelen = sizeof (struct sockaddr_in);
msgHdr.msg_name = & address -> address;
msgHdr.msg_namelen = sizeof (address -> address);
}
msgHdr.msg_iov = (struct iovec *) buffers;
@@ -375,19 +529,17 @@ enet_socket_receive (ENetSocket socket,
return -1;
}
if (address != NULL)
address -> addressLength = msgHdr.msg_namelen;
#ifdef HAS_MSGHDR_FLAGS
if (msgHdr.msg_flags & MSG_TRUNC)
return -1;
#endif
if (address != NULL)
{
address -> host = (enet_uint32) sin.sin_addr.s_addr;
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
}
return recvLength;
#endif
}
int
@@ -420,7 +572,16 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou
pollCount = poll (& pollSocket, 1, timeout);
if (pollCount < 0)
return -1;
{
if (errno == EINTR && * condition & ENET_SOCKET_WAIT_INTERRUPT)
{
* condition = ENET_SOCKET_WAIT_INTERRUPT;
return 0;
}
return -1;
}
* condition = ENET_SOCKET_WAIT_NONE;
@@ -454,7 +615,16 @@ enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeou
selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
if (selectCount < 0)
return -1;
{
if (errno == EINTR && * condition & ENET_SOCKET_WAIT_INTERRUPT)
{
* condition = ENET_SOCKET_WAIT_INTERRUPT;
return 0;
}
return -1;
}
* condition = ENET_SOCKET_WAIT_NONE;
+194 -107
View File
@@ -2,25 +2,30 @@
@file win32.c
@brief ENet Win32 system specific functions
*/
#ifdef WIN32
#ifdef _WIN32
#include <time.h>
#define ENET_BUILDING_LIB 1
#include "enet/enet.h"
#include <windows.h>
#include <mmsystem.h>
#include <qos2.h>
static enet_uint32 timeBase = 0;
static HANDLE qosHandle = INVALID_HANDLE_VALUE;
static QOS_FLOWID qosFlowId;
static BOOL qosAddedFlow;
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 ();
@@ -35,11 +40,26 @@ enet_initialize (void)
void
enet_deinitialize (void)
{
qosAddedFlow = FALSE;
qosFlowId = 0;
if (qosHandle != INVALID_HANDLE_VALUE)
{
QOSCloseHandle(qosHandle);
qosHandle = INVALID_HANDLE_VALUE;
}
timeEndPeriod (1);
WSACleanup ();
}
enet_uint32
enet_host_random_seed (void)
{
return (enet_uint32) timeGetTime ();
}
enet_uint32
enet_time_get (void)
{
@@ -52,77 +72,114 @@ 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)
{
address -> addressLength = sizeof (address -> address);
if (getsockname (socket, (struct sockaddr *) & address -> address, & address -> addressLength) == -1)
return -1;
return 0;
}
int
@@ -132,9 +189,9 @@ 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);
return socket (af, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
}
int
@@ -150,10 +207,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;
@@ -174,6 +227,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 (!QOSCreateHandle(&qosVersion, &qosHandle))
{
qosHandle = INVALID_HANDLE_VALUE;
}
}
else if (qosHandle != INVALID_HANDLE_VALUE)
{
QOSCloseHandle(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;
}
@@ -183,16 +283,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;
@@ -202,22 +295,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;
}
@@ -241,16 +329,20 @@ enet_socket_send (ENetSocket socket,
const ENetBuffer * buffers,
size_t bufferCount)
{
struct sockaddr_in sin;
DWORD sentLength;
if (address != NULL)
if (!qosAddedFlow && qosHandle != INVALID_HANDLE_VALUE)
{
memset (& sin, 0, sizeof (struct sockaddr_in));
qosFlowId = 0; // Must be initialized to 0
QOSAddSocketToFlow(qosHandle,
socket,
(struct sockaddr *)&address->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,
@@ -258,8 +350,8 @@ enet_socket_send (ENetSocket socket,
(DWORD) bufferCount,
& sentLength,
0,
address != NULL ? (struct sockaddr *) & sin : NULL,
address != NULL ? sizeof (struct sockaddr_in) : 0,
address != NULL ? (struct sockaddr *) & address -> address : NULL,
address != NULL ? address -> addressLength : 0,
NULL,
NULL) == SOCKET_ERROR)
{
@@ -278,18 +370,19 @@ enet_socket_receive (ENetSocket socket,
ENetBuffer * buffers,
size_t bufferCount)
{
INT sinLength = sizeof (struct sockaddr_in);
DWORD flags = 0,
recvLength;
struct sockaddr_in sin;
if (address != NULL)
address -> addressLength = sizeof (address -> address);
if (WSARecvFrom (socket,
(LPWSABUF) buffers,
(DWORD) bufferCount,
& recvLength,
& flags,
address != NULL ? (struct sockaddr *) & sin : NULL,
address != NULL ? & sinLength : NULL,
address != NULL ? (struct sockaddr *) & address -> address : NULL,
address != NULL ? & address -> addressLength : NULL,
NULL,
NULL) == SOCKET_ERROR)
{
@@ -306,12 +399,6 @@ enet_socket_receive (ENetSocket socket,
if (flags & 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);
}
return (int) recvLength;
}