1 /** 2 * include/enet.h - a Single-Header auto-generated variant of enet.h library. 3 * 4 * Usage: 5 * #define ENET_IMPLEMENTATION exactly in ONE source file right BEFORE including the library, like: 6 * 7 * #define ENET_IMPLEMENTATION 8 * #include <enet.h> 9 * 10 * License: 11 * The MIT License (MIT) 12 * 13 * Copyright (c) 2002-2016 Lee Salzman 14 * Copyright (c) 2017-2018 Vladyslav Hrytsenko, Dominik Madarász 15 * 16 * Permission is hereby granted, free of charge, to any person obtaining a copy 17 * of this software and associated documentation files (the "Software"), to deal 18 * in the Software without restriction, including without limitation the rights 19 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 20 * copies of the Software, and to permit persons to whom the Software is 21 * furnished to do so, subject to the following conditions: 22 * 23 * The above copyright notice and this permission notice shall be included in all 24 * copies or substantial portions of the Software. 25 * 26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 29 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 30 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 31 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32 * SOFTWARE. 33 * 34 */ 35 #ifndef ENET_INCLUDE_H 36 #define ENET_INCLUDE_H 37 38 #include <stdlib.h> 39 #include <stdbool.h> 40 #include <stdint.h> 41 #include <time.h> 42 43 #define ENET_VERSION_MAJOR 2 44 #define ENET_VERSION_MINOR 2 45 #define ENET_VERSION_PATCH 0 46 #define ENET_VERSION_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch)) 47 #define ENET_VERSION_GET_MAJOR(version) (((version)>>16)&0xFF) 48 #define ENET_VERSION_GET_MINOR(version) (((version)>>8)&0xFF) 49 #define ENET_VERSION_GET_PATCH(version) ((version)&0xFF) 50 #define ENET_VERSION ENET_VERSION_CREATE(ENET_VERSION_MAJOR, ENET_VERSION_MINOR, ENET_VERSION_PATCH) 51 52 #define ENET_TIME_OVERFLOW 86400000 53 #define ENET_TIME_LESS(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW) 54 #define ENET_TIME_GREATER(a, b) ((b) - (a) >= ENET_TIME_OVERFLOW) 55 #define ENET_TIME_LESS_EQUAL(a, b) (! ENET_TIME_GREATER (a, b)) 56 #define ENET_TIME_GREATER_EQUAL(a, b) (! ENET_TIME_LESS (a, b)) 57 #define ENET_TIME_DIFFERENCE(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW ? (b) - (a) : (a) - (b)) 58 59 // =======================================================================// 60 // ! 61 // ! System differences 62 // ! 63 // =======================================================================// 64 65 #if defined(_WIN32) 66 #if defined(_MSC_VER) && defined(ENET_IMPLEMENTATION) 67 #pragma warning (disable: 4267) // size_t to int conversion 68 #pragma warning (disable: 4244) // 64bit to 32bit int 69 #pragma warning (disable: 4018) // signed/unsigned mismatch 70 #pragma warning (disable: 4146) // unary minus operator applied to unsigned type 71 #endif 72 73 #if _MSC_VER 74 #ifndef ENET_NO_PRAGMA_LINK 75 #pragma comment(lib, "ws2_32.lib") 76 #pragma comment(lib, "winmm.lib") 77 #endif 78 #endif 79 80 #if _MSC_VER >= 1910 81 /* It looks like there were changes as of Visual Studio 2017 and there are no 32/64 bit 82 versions of _InterlockedExchange[operation], only InterlockedExchange[operation] 83 (without leading underscore), so we have to distinguish between compiler versions */ 84 #define NOT_UNDERSCORED_INTERLOCKED_EXCHANGE 85 #endif 86 87 #ifdef __GNUC__ 88 #if (_WIN32_WINNT < 0x0501) 89 #undef _WIN32_WINNT 90 #define _WIN32_WINNT 0x0501 91 #endif 92 #endif 93 94 #include <winsock2.h> 95 #include <ws2tcpip.h> 96 #include <mmsystem.h> 97 98 #include <intrin.h> 99 100 #if defined(_WIN32) && defined(_MSC_VER) 101 #if _MSC_VER < 1900 102 typedef struct timespec { 103 long tv_sec; 104 long tv_nsec; 105 }; 106 #endif 107 #define CLOCK_MONOTONIC 0 108 #endif 109 110 typedef SOCKET ENetSocket; 111 #define ENET_SOCKET_NULL INVALID_SOCKET 112 113 #define ENET_HOST_TO_NET_16(value) (htons(value)) 114 #define ENET_HOST_TO_NET_32(value) (htonl(value)) 115 116 #define ENET_NET_TO_HOST_16(value) (ntohs(value)) 117 #define ENET_NET_TO_HOST_32(value) (ntohl(value)) 118 119 typedef struct { 120 size_t dataLength; 121 void * data; 122 } ENetBuffer; 123 124 #define ENET_CALLBACK __cdecl 125 126 #ifdef ENET_DLL 127 #ifdef ENET_IMPLEMENTATION 128 #define ENET_API __declspec( dllexport ) 129 #else 130 #define ENET_API __declspec( dllimport ) 131 #endif // ENET_IMPLEMENTATION 132 #else 133 #define ENET_API extern 134 #endif // ENET_DLL 135 136 typedef fd_set ENetSocketSet; 137 138 #define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO(&(sockset)) 139 #define ENET_SOCKETSET_ADD(sockset, socket) FD_SET(socket, &(sockset)) 140 #define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLR(socket, &(sockset)) 141 #define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET(socket, &(sockset)) 142 #else 143 #include <sys/types.h> 144 #include <sys/ioctl.h> 145 #include <sys/time.h> 146 #include <sys/socket.h> 147 #include <poll.h> 148 #include <arpa/inet.h> 149 #include <netinet/in.h> 150 #include <netinet/tcp.h> 151 #include <netdb.h> 152 #include <unistd.h> 153 #include <string.h> 154 #include <errno.h> 155 #include <fcntl.h> 156 157 #ifdef __APPLE__ 158 #include <mach/clock.h> 159 #include <mach/mach.h> 160 #include <Availability.h> 161 #endif 162 163 #ifndef MSG_NOSIGNAL 164 #define MSG_NOSIGNAL 0 165 #endif 166 167 #ifdef MSG_MAXIOVLEN 168 #define ENET_BUFFER_MAXIMUM MSG_MAXIOVLEN 169 #endif 170 171 typedef int ENetSocket; 172 173 #define ENET_SOCKET_NULL -1 174 175 #define ENET_HOST_TO_NET_16(value) (htons(value)) /**< macro that converts host to net byte-order of a 16-bit value */ 176 #define ENET_HOST_TO_NET_32(value) (htonl(value)) /**< macro that converts host to net byte-order of a 32-bit value */ 177 178 #define ENET_NET_TO_HOST_16(value) (ntohs(value)) /**< macro that converts net to host byte-order of a 16-bit value */ 179 #define ENET_NET_TO_HOST_32(value) (ntohl(value)) /**< macro that converts net to host byte-order of a 32-bit value */ 180 181 typedef struct { 182 void * data; 183 size_t dataLength; 184 } ENetBuffer; 185 186 #define ENET_CALLBACK 187 #define ENET_API extern 188 189 typedef fd_set ENetSocketSet; 190 191 #define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO(&(sockset)) 192 #define ENET_SOCKETSET_ADD(sockset, socket) FD_SET(socket, &(sockset)) 193 #define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLR(socket, &(sockset)) 194 #define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET(socket, &(sockset)) 195 #endif 196 197 #ifndef ENET_BUFFER_MAXIMUM 198 #define ENET_BUFFER_MAXIMUM (1 + 2 * ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS) 199 #endif 200 201 #define ENET_MAX(x, y) ((x) > (y) ? (x) : (y)) 202 #define ENET_MIN(x, y) ((x) < (y) ? (x) : (y)) 203 204 #define ENET_IPV6 1 205 #define ENET_HOST_ANY in6addr_any 206 #define ENET_HOST_BROADCAST 0xFFFFFFFFU 207 #define ENET_PORT_ANY 0 208 209 #ifdef __cplusplus 210 extern "C" { 211 #endif 212 213 // =======================================================================// 214 // ! 215 // ! Basic stuff 216 // ! 217 // =======================================================================// 218 219 typedef uint8_t enet_uint8; /**< unsigned 8-bit type */ 220 typedef uint16_t enet_uint16; /**< unsigned 16-bit type */ 221 typedef uint32_t enet_uint32; /**< unsigned 32-bit type */ 222 typedef uint64_t enet_uint64; /**< unsigned 64-bit type */ 223 224 typedef enet_uint32 ENetVersion; 225 226 typedef struct _ENetCallbacks { 227 void *(ENET_CALLBACK *malloc) (size_t size); 228 void (ENET_CALLBACK *free) (void *memory); 229 void (ENET_CALLBACK *no_memory) (void); 230 } ENetCallbacks; 231 232 extern void *enet_malloc(size_t); 233 extern void enet_free(void *); 234 235 // =======================================================================// 236 // ! 237 // ! List 238 // ! 239 // =======================================================================// 240 241 typedef struct _ENetListNode { 242 struct _ENetListNode *next; 243 struct _ENetListNode *previous; 244 } ENetListNode; 245 246 typedef ENetListNode *ENetListIterator; 247 248 typedef struct _ENetList { 249 ENetListNode sentinel; 250 } ENetList; 251 252 extern ENetListIterator enet_list_insert(ENetListIterator, void *); 253 extern ENetListIterator enet_list_move(ENetListIterator, void *, void *); 254 255 extern void *enet_list_remove(ENetListIterator); 256 extern void enet_list_clear(ENetList *); 257 extern size_t enet_list_size(ENetList *); 258 259 #define enet_list_begin(list) ((list)->sentinel.next) 260 #define enet_list_end(list) (&(list)->sentinel) 261 #define enet_list_empty(list) (enet_list_begin(list) == enet_list_end(list)) 262 #define enet_list_next(iterator) ((iterator)->next) 263 #define enet_list_previous(iterator) ((iterator)->previous) 264 #define enet_list_front(list) ((void *)(list)->sentinel.next) 265 #define enet_list_back(list) ((void *)(list)->sentinel.previous) 266 267 268 // =======================================================================// 269 // ! 270 // ! Protocol 271 // ! 272 // =======================================================================// 273 274 enum { 275 ENET_PROTOCOL_MINIMUM_MTU = 576, 276 ENET_PROTOCOL_MAXIMUM_MTU = 4096, 277 ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS = 32, 278 ENET_PROTOCOL_MINIMUM_WINDOW_SIZE = 4096, 279 ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 65536, 280 ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT = 1, 281 ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT = 255, 282 ENET_PROTOCOL_MAXIMUM_PEER_ID = 0xFFF, 283 ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT = 1024 * 1024 284 }; 285 286 typedef enum _ENetProtocolCommand { 287 ENET_PROTOCOL_COMMAND_NONE = 0, 288 ENET_PROTOCOL_COMMAND_ACKNOWLEDGE = 1, 289 ENET_PROTOCOL_COMMAND_CONNECT = 2, 290 ENET_PROTOCOL_COMMAND_VERIFY_CONNECT = 3, 291 ENET_PROTOCOL_COMMAND_DISCONNECT = 4, 292 ENET_PROTOCOL_COMMAND_PING = 5, 293 ENET_PROTOCOL_COMMAND_SEND_RELIABLE = 6, 294 ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE = 7, 295 ENET_PROTOCOL_COMMAND_SEND_FRAGMENT = 8, 296 ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED = 9, 297 ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT = 10, 298 ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 11, 299 ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT = 12, 300 ENET_PROTOCOL_COMMAND_COUNT = 13, 301 302 ENET_PROTOCOL_COMMAND_MASK = 0x0F, 303 304 ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE = (1 << 7), 305 ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED = (1 << 6), 306 307 ENET_PROTOCOL_COMMAND_FLAG_MASK = 0xC0 308 } ENetProtocolCommand; 309 310 typedef enum _ENetProtocolFlag { 311 ENET_PROTOCOL_HEADER_FLAG_COMPRESSED = (1 << 14), 312 ENET_PROTOCOL_HEADER_FLAG_SENT_TIME = (1 << 15), 313 ENET_PROTOCOL_HEADER_FLAG_MASK = ENET_PROTOCOL_HEADER_FLAG_COMPRESSED | ENET_PROTOCOL_HEADER_FLAG_SENT_TIME, 314 315 ENET_PROTOCOL_HEADER_SESSION_MASK = (3 << 12), 316 ENET_PROTOCOL_HEADER_SESSION_SHIFT = 12 317 } ENetProtocolFlag; 318 319 #ifdef _MSC_VER 320 #pragma pack(push, 1) 321 #define ENET_PACKED 322 #elif defined(__GNUC__) || defined(__clang__) 323 #define ENET_PACKED __attribute__ ((packed)) 324 #else 325 #define ENET_PACKED 326 #endif 327 328 typedef struct _ENetProtocolHeader { 329 enet_uint16 peerID; 330 enet_uint16 sentTime; 331 } ENET_PACKED ENetProtocolHeader; 332 333 typedef struct _ENetProtocolCommandHeader { 334 enet_uint8 command; 335 enet_uint8 channelID; 336 enet_uint16 reliableSequenceNumber; 337 } ENET_PACKED ENetProtocolCommandHeader; 338 339 typedef struct _ENetProtocolAcknowledge { 340 ENetProtocolCommandHeader header; 341 enet_uint16 receivedReliableSequenceNumber; 342 enet_uint16 receivedSentTime; 343 } ENET_PACKED ENetProtocolAcknowledge; 344 345 typedef struct _ENetProtocolConnect { 346 ENetProtocolCommandHeader header; 347 enet_uint16 outgoingPeerID; 348 enet_uint8 incomingSessionID; 349 enet_uint8 outgoingSessionID; 350 enet_uint32 mtu; 351 enet_uint32 windowSize; 352 enet_uint32 channelCount; 353 enet_uint32 incomingBandwidth; 354 enet_uint32 outgoingBandwidth; 355 enet_uint32 packetThrottleInterval; 356 enet_uint32 packetThrottleAcceleration; 357 enet_uint32 packetThrottleDeceleration; 358 enet_uint32 connectID; 359 enet_uint32 data; 360 } ENET_PACKED ENetProtocolConnect; 361 362 typedef struct _ENetProtocolVerifyConnect { 363 ENetProtocolCommandHeader header; 364 enet_uint16 outgoingPeerID; 365 enet_uint8 incomingSessionID; 366 enet_uint8 outgoingSessionID; 367 enet_uint32 mtu; 368 enet_uint32 windowSize; 369 enet_uint32 channelCount; 370 enet_uint32 incomingBandwidth; 371 enet_uint32 outgoingBandwidth; 372 enet_uint32 packetThrottleInterval; 373 enet_uint32 packetThrottleAcceleration; 374 enet_uint32 packetThrottleDeceleration; 375 enet_uint32 connectID; 376 } ENET_PACKED ENetProtocolVerifyConnect; 377 378 typedef struct _ENetProtocolBandwidthLimit { 379 ENetProtocolCommandHeader header; 380 enet_uint32 incomingBandwidth; 381 enet_uint32 outgoingBandwidth; 382 } ENET_PACKED ENetProtocolBandwidthLimit; 383 384 typedef struct _ENetProtocolThrottleConfigure { 385 ENetProtocolCommandHeader header; 386 enet_uint32 packetThrottleInterval; 387 enet_uint32 packetThrottleAcceleration; 388 enet_uint32 packetThrottleDeceleration; 389 } ENET_PACKED ENetProtocolThrottleConfigure; 390 391 typedef struct _ENetProtocolDisconnect { 392 ENetProtocolCommandHeader header; 393 enet_uint32 data; 394 } ENET_PACKED ENetProtocolDisconnect; 395 396 typedef struct _ENetProtocolPing { 397 ENetProtocolCommandHeader header; 398 } ENET_PACKED ENetProtocolPing; 399 400 typedef struct _ENetProtocolSendReliable { 401 ENetProtocolCommandHeader header; 402 enet_uint16 dataLength; 403 } ENET_PACKED ENetProtocolSendReliable; 404 405 typedef struct _ENetProtocolSendUnreliable { 406 ENetProtocolCommandHeader header; 407 enet_uint16 unreliableSequenceNumber; 408 enet_uint16 dataLength; 409 } ENET_PACKED ENetProtocolSendUnreliable; 410 411 typedef struct _ENetProtocolSendUnsequenced { 412 ENetProtocolCommandHeader header; 413 enet_uint16 unsequencedGroup; 414 enet_uint16 dataLength; 415 } ENET_PACKED ENetProtocolSendUnsequenced; 416 417 typedef struct _ENetProtocolSendFragment { 418 ENetProtocolCommandHeader header; 419 enet_uint16 startSequenceNumber; 420 enet_uint16 dataLength; 421 enet_uint32 fragmentCount; 422 enet_uint32 fragmentNumber; 423 enet_uint32 totalLength; 424 enet_uint32 fragmentOffset; 425 } ENET_PACKED ENetProtocolSendFragment; 426 427 typedef union _ENetProtocol { 428 ENetProtocolCommandHeader header; 429 ENetProtocolAcknowledge acknowledge; 430 ENetProtocolConnect connect; 431 ENetProtocolVerifyConnect verifyConnect; 432 ENetProtocolDisconnect disconnect; 433 ENetProtocolPing ping; 434 ENetProtocolSendReliable sendReliable; 435 ENetProtocolSendUnreliable sendUnreliable; 436 ENetProtocolSendUnsequenced sendUnsequenced; 437 ENetProtocolSendFragment sendFragment; 438 ENetProtocolBandwidthLimit bandwidthLimit; 439 ENetProtocolThrottleConfigure throttleConfigure; 440 } ENET_PACKED ENetProtocol; 441 442 #ifdef _MSC_VER 443 #pragma pack(pop) 444 #endif 445 446 // =======================================================================// 447 // ! 448 // ! General ENet structs/enums 449 // ! 450 // =======================================================================// 451 452 typedef enum _ENetSocketType { 453 ENET_SOCKET_TYPE_STREAM = 1, 454 ENET_SOCKET_TYPE_DATAGRAM = 2 455 } ENetSocketType; 456 457 typedef enum _ENetSocketWait { 458 ENET_SOCKET_WAIT_NONE = 0, 459 ENET_SOCKET_WAIT_SEND = (1 << 0), 460 ENET_SOCKET_WAIT_RECEIVE = (1 << 1), 461 ENET_SOCKET_WAIT_INTERRUPT = (1 << 2) 462 } ENetSocketWait; 463 464 typedef enum _ENetSocketOption { 465 ENET_SOCKOPT_NONBLOCK = 1, 466 ENET_SOCKOPT_BROADCAST = 2, 467 ENET_SOCKOPT_RCVBUF = 3, 468 ENET_SOCKOPT_SNDBUF = 4, 469 ENET_SOCKOPT_REUSEADDR = 5, 470 ENET_SOCKOPT_RCVTIMEO = 6, 471 ENET_SOCKOPT_SNDTIMEO = 7, 472 ENET_SOCKOPT_ERROR = 8, 473 ENET_SOCKOPT_NODELAY = 9, 474 ENET_SOCKOPT_IPV6_V6ONLY = 10, 475 } ENetSocketOption; 476 477 typedef enum _ENetSocketShutdown { 478 ENET_SOCKET_SHUTDOWN_READ = 0, 479 ENET_SOCKET_SHUTDOWN_WRITE = 1, 480 ENET_SOCKET_SHUTDOWN_READ_WRITE = 2 481 } ENetSocketShutdown; 482 483 /** 484 * Portable internet address structure. 485 * 486 * The host must be specified in network byte-order, and the port must be in host 487 * byte-order. The constant ENET_HOST_ANY may be used to specify the default 488 * server host. The constant ENET_HOST_BROADCAST may be used to specify the 489 * broadcast address (255.255.255.255). This makes sense for enet_host_connect, 490 * but not for enet_host_create. Once a server responds to a broadcast, the 491 * address is updated from ENET_HOST_BROADCAST to the server's actual IP address. 492 */ 493 typedef struct _ENetAddress { 494 struct in6_addr host; 495 enet_uint16 port; 496 enet_uint16 sin6_scope_id; 497 } ENetAddress; 498 499 #define in6_equal(in6_addr_a, in6_addr_b) (memcmp(&in6_addr_a, &in6_addr_b, sizeof(struct in6_addr)) == 0) 500 501 /** 502 * Packet flag bit constants. 503 * 504 * The host must be specified in network byte-order, and the port must be in 505 * host byte-order. The constant ENET_HOST_ANY may be used to specify the 506 * default server host. 507 * 508 * @sa ENetPacket 509 */ 510 typedef enum _ENetPacketFlag { 511 ENET_PACKET_FLAG_RELIABLE = (1 << 0), /** packet must be received by the target peer and resend attempts should be made until the packet is delivered */ 512 ENET_PACKET_FLAG_UNSEQUENCED = (1 << 1), /** packet will not be sequenced with other packets not supported for reliable packets */ 513 ENET_PACKET_FLAG_NO_ALLOCATE = (1 << 2), /** packet will not allocate data, and user must supply it instead */ 514 ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT = (1 << 3), /** packet will be fragmented using unreliable (instead of reliable) sends if it exceeds the MTU */ 515 ENET_PACKET_FLAG_SENT = (1 << 8), /** whether the packet has been sent from all queues it has been entered into */ 516 } ENetPacketFlag; 517 518 typedef void (ENET_CALLBACK *ENetPacketFreeCallback)(void *); 519 520 /** 521 * ENet packet structure. 522 * 523 * An ENet data packet that may be sent to or received from a peer. The shown 524 * fields should only be read and never modified. The data field contains the 525 * allocated data for the packet. The dataLength fields specifies the length 526 * of the allocated data. The flags field is either 0 (specifying no flags), 527 * or a bitwise-or of any combination of the following flags: 528 * 529 * ENET_PACKET_FLAG_RELIABLE - packet must be received by the target peer and resend attempts should be made until the packet is delivered 530 * ENET_PACKET_FLAG_UNSEQUENCED - packet will not be sequenced with other packets (not supported for reliable packets) 531 * ENET_PACKET_FLAG_NO_ALLOCATE - packet will not allocate data, and user must supply it instead 532 * ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT - packet will be fragmented using unreliable (instead of reliable) sends if it exceeds the MTU 533 * ENET_PACKET_FLAG_SENT - whether the packet has been sent from all queues it has been entered into 534 * @sa ENetPacketFlag 535 */ 536 typedef struct _ENetPacket { 537 size_t referenceCount; /**< internal use only */ 538 enet_uint32 flags; /**< bitwise-or of ENetPacketFlag constants */ 539 enet_uint8 * data; /**< allocated data for packet */ 540 size_t dataLength; /**< length of data */ 541 ENetPacketFreeCallback freeCallback; /**< function to be called when the packet is no longer in use */ 542 void * userData; /**< application private data, may be freely modified */ 543 } ENetPacket; 544 545 typedef struct _ENetAcknowledgement { 546 ENetListNode acknowledgementList; 547 enet_uint32 sentTime; 548 ENetProtocol command; 549 } ENetAcknowledgement; 550 551 typedef struct _ENetOutgoingCommand { 552 ENetListNode outgoingCommandList; 553 enet_uint16 reliableSequenceNumber; 554 enet_uint16 unreliableSequenceNumber; 555 enet_uint32 sentTime; 556 enet_uint32 roundTripTimeout; 557 enet_uint32 roundTripTimeoutLimit; 558 enet_uint32 fragmentOffset; 559 enet_uint16 fragmentLength; 560 enet_uint16 sendAttempts; 561 ENetProtocol command; 562 ENetPacket * packet; 563 } ENetOutgoingCommand; 564 565 typedef struct _ENetIncomingCommand { 566 ENetListNode incomingCommandList; 567 enet_uint16 reliableSequenceNumber; 568 enet_uint16 unreliableSequenceNumber; 569 ENetProtocol command; 570 enet_uint32 fragmentCount; 571 enet_uint32 fragmentsRemaining; 572 enet_uint32 *fragments; 573 ENetPacket * packet; 574 } ENetIncomingCommand; 575 576 typedef enum _ENetPeerState { 577 ENET_PEER_STATE_DISCONNECTED = 0, 578 ENET_PEER_STATE_CONNECTING = 1, 579 ENET_PEER_STATE_ACKNOWLEDGING_CONNECT = 2, 580 ENET_PEER_STATE_CONNECTION_PENDING = 3, 581 ENET_PEER_STATE_CONNECTION_SUCCEEDED = 4, 582 ENET_PEER_STATE_CONNECTED = 5, 583 ENET_PEER_STATE_DISCONNECT_LATER = 6, 584 ENET_PEER_STATE_DISCONNECTING = 7, 585 ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT = 8, 586 ENET_PEER_STATE_ZOMBIE = 9 587 } ENetPeerState; 588 589 enum { 590 ENET_HOST_RECEIVE_BUFFER_SIZE = 256 * 1024, 591 ENET_HOST_SEND_BUFFER_SIZE = 256 * 1024, 592 ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL = 1000, 593 ENET_HOST_DEFAULT_MTU = 1400, 594 ENET_HOST_DEFAULT_MAXIMUM_PACKET_SIZE = 32 * 1024 * 1024, 595 ENET_HOST_DEFAULT_MAXIMUM_WAITING_DATA = 32 * 1024 * 1024, 596 597 ENET_PEER_DEFAULT_ROUND_TRIP_TIME = 500, 598 ENET_PEER_DEFAULT_PACKET_THROTTLE = 32, 599 ENET_PEER_PACKET_THROTTLE_SCALE = 32, 600 ENET_PEER_PACKET_THROTTLE_COUNTER = 7, 601 ENET_PEER_PACKET_THROTTLE_ACCELERATION = 2, 602 ENET_PEER_PACKET_THROTTLE_DECELERATION = 2, 603 ENET_PEER_PACKET_THROTTLE_INTERVAL = 5000, 604 ENET_PEER_PACKET_LOSS_SCALE = (1 << 16), 605 ENET_PEER_PACKET_LOSS_INTERVAL = 10000, 606 ENET_PEER_WINDOW_SIZE_SCALE = 64 * 1024, 607 ENET_PEER_TIMEOUT_LIMIT = 32, 608 ENET_PEER_TIMEOUT_MINIMUM = 5000, 609 ENET_PEER_TIMEOUT_MAXIMUM = 30000, 610 ENET_PEER_PING_INTERVAL = 500, 611 ENET_PEER_UNSEQUENCED_WINDOWS = 64, 612 ENET_PEER_UNSEQUENCED_WINDOW_SIZE = 1024, 613 ENET_PEER_FREE_UNSEQUENCED_WINDOWS = 32, 614 ENET_PEER_RELIABLE_WINDOWS = 16, 615 ENET_PEER_RELIABLE_WINDOW_SIZE = 0x1000, 616 ENET_PEER_FREE_RELIABLE_WINDOWS = 8 617 }; 618 619 typedef struct _ENetChannel { 620 enet_uint16 outgoingReliableSequenceNumber; 621 enet_uint16 outgoingUnreliableSequenceNumber; 622 enet_uint16 usedReliableWindows; 623 enet_uint16 reliableWindows[ENET_PEER_RELIABLE_WINDOWS]; 624 enet_uint16 incomingReliableSequenceNumber; 625 enet_uint16 incomingUnreliableSequenceNumber; 626 ENetList incomingReliableCommands; 627 ENetList incomingUnreliableCommands; 628 } ENetChannel; 629 630 /** 631 * An ENet peer which data packets may be sent or received from. 632 * 633 * No fields should be modified unless otherwise specified. 634 */ 635 typedef struct _ENetPeer { 636 ENetListNode dispatchList; 637 struct _ENetHost *host; 638 enet_uint16 outgoingPeerID; 639 enet_uint16 incomingPeerID; 640 enet_uint32 connectID; 641 enet_uint8 outgoingSessionID; 642 enet_uint8 incomingSessionID; 643 ENetAddress address; /**< Internet address of the peer */ 644 void * data; /**< Application private data, may be freely modified */ 645 ENetPeerState state; 646 ENetChannel * channels; 647 size_t channelCount; /**< Number of channels allocated for communication with peer */ 648 enet_uint32 incomingBandwidth; /**< Downstream bandwidth of the client in bytes/second */ 649 enet_uint32 outgoingBandwidth; /**< Upstream bandwidth of the client in bytes/second */ 650 enet_uint32 incomingBandwidthThrottleEpoch; 651 enet_uint32 outgoingBandwidthThrottleEpoch; 652 enet_uint32 incomingDataTotal; 653 enet_uint64 totalDataReceived; 654 enet_uint32 outgoingDataTotal; 655 enet_uint64 totalDataSent; 656 enet_uint32 lastSendTime; 657 enet_uint32 lastReceiveTime; 658 enet_uint32 nextTimeout; 659 enet_uint32 earliestTimeout; 660 enet_uint32 packetLossEpoch; 661 enet_uint32 packetsSent; 662 enet_uint64 totalPacketsSent; /**< total number of packets sent during a session */ 663 enet_uint32 packetsLost; 664 enet_uint32 totalPacketsLost; /**< total number of packets lost during a session */ 665 enet_uint32 packetLoss; /**< mean packet loss of reliable packets as a ratio with respect to the constant ENET_PEER_PACKET_LOSS_SCALE */ 666 enet_uint32 packetLossVariance; 667 enet_uint32 packetThrottle; 668 enet_uint32 packetThrottleLimit; 669 enet_uint32 packetThrottleCounter; 670 enet_uint32 packetThrottleEpoch; 671 enet_uint32 packetThrottleAcceleration; 672 enet_uint32 packetThrottleDeceleration; 673 enet_uint32 packetThrottleInterval; 674 enet_uint32 pingInterval; 675 enet_uint32 timeoutLimit; 676 enet_uint32 timeoutMinimum; 677 enet_uint32 timeoutMaximum; 678 enet_uint32 lastRoundTripTime; 679 enet_uint32 lowestRoundTripTime; 680 enet_uint32 lastRoundTripTimeVariance; 681 enet_uint32 highestRoundTripTimeVariance; 682 enet_uint32 roundTripTime; /**< mean round trip time (RTT), in milliseconds, between sending a reliable packet and receiving its acknowledgement */ 683 enet_uint32 roundTripTimeVariance; 684 enet_uint32 mtu; 685 enet_uint32 windowSize; 686 enet_uint32 reliableDataInTransit; 687 enet_uint16 outgoingReliableSequenceNumber; 688 ENetList acknowledgements; 689 ENetList sentReliableCommands; 690 ENetList sentUnreliableCommands; 691 ENetList outgoingReliableCommands; 692 ENetList outgoingUnreliableCommands; 693 ENetList dispatchedCommands; 694 int needsDispatch; 695 enet_uint16 incomingUnsequencedGroup; 696 enet_uint16 outgoingUnsequencedGroup; 697 enet_uint32 unsequencedWindow[ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32]; 698 enet_uint32 eventData; 699 size_t totalWaitingData; 700 } ENetPeer; 701 702 /** An ENet packet compressor for compressing UDP packets before socket sends or receives. */ 703 typedef struct _ENetCompressor { 704 /** Context data for the compressor. Must be non-NULL. */ 705 void *context; 706 707 /** Compresses from inBuffers[0:inBufferCount-1], containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */ 708 size_t(ENET_CALLBACK * compress) (void *context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit); 709 710 /** Decompresses from inData, containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */ 711 size_t(ENET_CALLBACK * decompress) (void *context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit); 712 713 /** Destroys the context when compression is disabled or the host is destroyed. May be NULL. */ 714 void (ENET_CALLBACK * destroy)(void *context); 715 } ENetCompressor; 716 717 /** Callback that computes the checksum of the data held in buffers[0:bufferCount-1] */ 718 typedef enet_uint32 (ENET_CALLBACK * ENetChecksumCallback)(const ENetBuffer *buffers, size_t bufferCount); 719 720 /** Callback for intercepting received raw UDP packets. Should return 1 to intercept, 0 to ignore, or -1 to propagate an error. */ 721 typedef int (ENET_CALLBACK * ENetInterceptCallback)(struct _ENetHost *host, void *event); 722 723 /** An ENet host for communicating with peers. 724 * 725 * No fields should be modified unless otherwise stated. 726 * 727 * @sa enet_host_create() 728 * @sa enet_host_destroy() 729 * @sa enet_host_connect() 730 * @sa enet_host_service() 731 * @sa enet_host_flush() 732 * @sa enet_host_broadcast() 733 * @sa enet_host_compress() 734 * @sa enet_host_channel_limit() 735 * @sa enet_host_bandwidth_limit() 736 * @sa enet_host_bandwidth_throttle() 737 */ 738 typedef struct _ENetHost { 739 ENetSocket socket; 740 ENetAddress address; /**< Internet address of the host */ 741 enet_uint32 incomingBandwidth; /**< downstream bandwidth of the host */ 742 enet_uint32 outgoingBandwidth; /**< upstream bandwidth of the host */ 743 enet_uint32 bandwidthThrottleEpoch; 744 enet_uint32 mtu; 745 enet_uint32 randomSeed; 746 int recalculateBandwidthLimits; 747 ENetPeer * peers; /**< array of peers allocated for this host */ 748 size_t peerCount; /**< number of peers allocated for this host */ 749 size_t channelLimit; /**< maximum number of channels allowed for connected peers */ 750 enet_uint32 serviceTime; 751 ENetList dispatchQueue; 752 int continueSending; 753 size_t packetSize; 754 enet_uint16 headerFlags; 755 ENetProtocol commands[ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS]; 756 size_t commandCount; 757 ENetBuffer buffers[ENET_BUFFER_MAXIMUM]; 758 size_t bufferCount; 759 ENetChecksumCallback checksum; /**< callback the user can set to enable packet checksums for this host */ 760 ENetCompressor compressor; 761 enet_uint8 packetData[2][ENET_PROTOCOL_MAXIMUM_MTU]; 762 ENetAddress receivedAddress; 763 enet_uint8 * receivedData; 764 size_t receivedDataLength; 765 enet_uint32 totalSentData; /**< total data sent, user should reset to 0 as needed to prevent overflow */ 766 enet_uint32 totalSentPackets; /**< total UDP packets sent, user should reset to 0 as needed to prevent overflow */ 767 enet_uint32 totalReceivedData; /**< total data received, user should reset to 0 as needed to prevent overflow */ 768 enet_uint32 totalReceivedPackets; /**< total UDP packets received, user should reset to 0 as needed to prevent overflow */ 769 ENetInterceptCallback intercept; /**< callback the user can set to intercept received raw UDP packets */ 770 size_t connectedPeers; 771 size_t bandwidthLimitedPeers; 772 size_t duplicatePeers; /**< optional number of allowed peers from duplicate IPs, defaults to ENET_PROTOCOL_MAXIMUM_PEER_ID */ 773 size_t maximumPacketSize; /**< the maximum allowable packet size that may be sent or received on a peer */ 774 size_t maximumWaitingData; /**< the maximum aggregate amount of buffer space a peer may use waiting for packets to be delivered */ 775 } ENetHost; 776 777 /** 778 * An ENet event type, as specified in @ref ENetEvent. 779 */ 780 typedef enum _ENetEventType { 781 /** no event occurred within the specified time limit */ 782 ENET_EVENT_TYPE_NONE = 0, 783 784 /** a connection request initiated by enet_host_connect has completed. 785 * The peer field contains the peer which successfully connected. 786 */ 787 ENET_EVENT_TYPE_CONNECT = 1, 788 789 /** a peer has disconnected. This event is generated on a successful 790 * completion of a disconnect initiated by enet_peer_disconnect, if 791 * a peer has timed out. The peer field contains the peer 792 * which disconnected. The data field contains user supplied data 793 * describing the disconnection, or 0, if none is available. 794 */ 795 ENET_EVENT_TYPE_DISCONNECT = 2, 796 797 /** a packet has been received from a peer. The peer field specifies the 798 * peer which sent the packet. The channelID field specifies the channel 799 * number upon which the packet was received. The packet field contains 800 * the packet that was received; this packet must be destroyed with 801 * enet_packet_destroy after use. 802 */ 803 ENET_EVENT_TYPE_RECEIVE = 3, 804 805 /** a peer is disconnected because the host didn't receive the acknowledgment 806 * packet within certain maximum time out. The reason could be because of bad 807 * network connection or host crashed. 808 */ 809 ENET_EVENT_TYPE_DISCONNECT_TIMEOUT = 4, 810 } ENetEventType; 811 812 /** 813 * An ENet event as returned by enet_host_service(). 814 * 815 * @sa enet_host_service 816 */ 817 typedef struct _ENetEvent { 818 ENetEventType type; /**< type of the event */ 819 ENetPeer * peer; /**< peer that generated a connect, disconnect or receive event */ 820 enet_uint8 channelID; /**< channel on the peer that generated the event, if appropriate */ 821 enet_uint32 data; /**< data associated with the event, if appropriate */ 822 ENetPacket * packet; /**< packet associated with the event, if appropriate */ 823 } ENetEvent; 824 825 // =======================================================================// 826 // ! 827 // ! Public API 828 // ! 829 // =======================================================================// 830 831 /** 832 * Initializes ENet globally. Must be called prior to using any functions in ENet. 833 * @returns 0 on success, < 0 on failure 834 */ 835 ENET_API int enet_initialize(void); 836 837 /** 838 * 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. 839 * 840 * @param version the constant ENET_VERSION should be supplied so ENet knows which version of ENetCallbacks struct to use 841 * @param inits user-overridden callbacks where any NULL callbacks will use ENet's defaults 842 * @returns 0 on success, < 0 on failure 843 */ 844 ENET_API int enet_initialize_with_callbacks(ENetVersion version, const ENetCallbacks * inits); 845 846 /** 847 * Shuts down ENet globally. Should be called when a program that has initialized ENet exits. 848 */ 849 ENET_API void enet_deinitialize(void); 850 851 /** 852 * Gives the linked version of the ENet library. 853 * @returns the version number 854 */ 855 ENET_API ENetVersion enet_linked_version(void); 856 857 /** Returns the monotonic time in milliseconds. Its initial value is unspecified unless otherwise set. */ 858 ENET_API enet_uint32 enet_time_get(void); 859 860 /** ENet socket functions */ 861 ENET_API ENetSocket enet_socket_create(ENetSocketType); 862 ENET_API int enet_socket_bind(ENetSocket, ENetAddress *); 863 ENET_API int enet_socket_get_address(ENetSocket, ENetAddress *); 864 ENET_API int enet_socket_listen(ENetSocket, int); 865 ENET_API ENetSocket enet_socket_accept(ENetSocket, ENetAddress *); 866 ENET_API int enet_socket_connect(ENetSocket, ENetAddress *); 867 ENET_API int enet_socket_send(ENetSocket, ENetAddress *, ENetBuffer *, size_t); 868 ENET_API int enet_socket_receive(ENetSocket, ENetAddress *, ENetBuffer *, size_t); 869 ENET_API int enet_socket_wait(ENetSocket, enet_uint32 *, enet_uint64); 870 ENET_API int enet_socket_set_option(ENetSocket, ENetSocketOption, int); 871 ENET_API int enet_socket_get_option(ENetSocket, ENetSocketOption, int *); 872 ENET_API int enet_socket_shutdown(ENetSocket, ENetSocketShutdown); 873 ENET_API void enet_socket_destroy(ENetSocket); 874 ENET_API int enet_socketset_select(ENetSocket, ENetSocketSet *, ENetSocketSet *, enet_uint32); 875 876 /** Attempts to parse the printable form of the IP address in the parameter hostName 877 and sets the host field in the address parameter if successful. 878 @param address destination to store the parsed IP address 879 @param hostName IP address to parse 880 @retval 0 on success 881 @retval < 0 on failure 882 @returns the address of the given hostName in address on success 883 */ 884 ENET_API int enet_address_set_host_ip(ENetAddress * address, char * hostName); 885 886 /** Attempts to resolve the host named by the parameter hostName and sets 887 the host field in the address parameter if successful. 888 @param address destination to store resolved address 889 @param hostName host name to lookup 890 @retval 0 on success 891 @retval < 0 on failure 892 @returns the address of the given hostName in address on success 893 */ 894 ENET_API int enet_address_set_host(ENetAddress * address, char * hostName); 895 896 /** Gives the printable form of the IP address specified in the address parameter. 897 @param address address printed 898 @param hostName destination for name, must not be NULL 899 @param nameLength maximum length of hostName. 900 @returns the null-terminated name of the host in hostName on success 901 @retval 0 on success 902 @retval < 0 on failure 903 */ 904 ENET_API int enet_address_get_host_ip(ENetAddress * address, char * hostName, size_t nameLength); 905 906 /** Attempts to do a reverse lookup of the host field in the address parameter. 907 @param address address used for reverse lookup 908 @param hostName destination for name, must not be NULL 909 @param nameLength maximum length of hostName. 910 @returns the null-terminated name of the host in hostName on success 911 @retval 0 on success 912 @retval < 0 on failure 913 */ 914 ENET_API int enet_address_get_host(ENetAddress * address, char * hostName, size_t nameLength); 915 916 ENET_API enet_uint32 enet_host_get_peers_count(ENetHost *); 917 ENET_API enet_uint32 enet_host_get_packets_sent(ENetHost *); 918 ENET_API enet_uint32 enet_host_get_packets_received(ENetHost *); 919 ENET_API enet_uint32 enet_host_get_bytes_sent(ENetHost *); 920 ENET_API enet_uint32 enet_host_get_bytes_received(ENetHost *); 921 ENET_API enet_uint32 enet_host_get_received_data(ENetHost *, enet_uint8** data); 922 ENET_API enet_uint32 enet_host_get_mtu(ENetHost *); 923 924 ENET_API enet_uint32 enet_peer_get_id(ENetPeer *); 925 ENET_API enet_uint32 enet_peer_get_ip(ENetPeer *, char * ip, size_t ipLength); 926 ENET_API enet_uint16 enet_peer_get_port(ENetPeer *); 927 ENET_API enet_uint32 enet_peer_get_rtt(ENetPeer *); 928 ENET_API enet_uint64 enet_peer_get_packets_sent(ENetPeer *); 929 ENET_API enet_uint32 enet_peer_get_packets_lost(ENetPeer *); 930 ENET_API enet_uint64 enet_peer_get_bytes_sent(ENetPeer *); 931 ENET_API enet_uint64 enet_peer_get_bytes_received(ENetPeer *); 932 933 ENET_API ENetPeerState enet_peer_get_state(ENetPeer *); 934 935 ENET_API void * enet_peer_get_data(ENetPeer *); 936 ENET_API void enet_peer_set_data(ENetPeer *, void *); 937 938 ENET_API void * enet_packet_get_data(ENetPacket *); 939 ENET_API enet_uint32 enet_packet_get_length(ENetPacket *); 940 ENET_API void enet_packet_set_free_callback(ENetPacket *, void *); 941 942 ENET_API ENetPacket * enet_packet_create(void *, size_t, enet_uint32); 943 ENET_API ENetPacket * enet_packet_create_offset(void *, size_t, size_t, enet_uint32); 944 ENET_API void enet_packet_destroy(ENetPacket *); 945 ENET_API enet_uint32 enet_crc32(const ENetBuffer *, size_t); 946 947 ENET_API ENetHost * enet_host_create(ENetAddress *, size_t, size_t, enet_uint32, enet_uint32); 948 ENET_API void enet_host_destroy(ENetHost *); 949 ENET_API ENetPeer * enet_host_connect(ENetHost *, ENetAddress *, size_t, enet_uint32); 950 ENET_API int enet_host_check_events(ENetHost *, ENetEvent *); 951 ENET_API int enet_host_service(ENetHost *, ENetEvent *, enet_uint32); 952 ENET_API int enet_host_send_raw(ENetHost *, ENetAddress *, enet_uint8 *, size_t); 953 ENET_API int enet_host_send_raw_ex(ENetHost *host, ENetAddress* address, enet_uint8* data, size_t skipBytes, size_t bytesToSend); 954 ENET_API void enet_host_set_intercept(ENetHost *, const ENetInterceptCallback); 955 ENET_API void enet_host_flush(ENetHost *); 956 ENET_API void enet_host_broadcast(ENetHost *, enet_uint8, ENetPacket *); 957 ENET_API void enet_host_compress(ENetHost *, const ENetCompressor *); 958 ENET_API void enet_host_channel_limit(ENetHost *, size_t); 959 ENET_API void enet_host_bandwidth_limit(ENetHost *, enet_uint32, enet_uint32); 960 extern void enet_host_bandwidth_throttle(ENetHost *); 961 extern enet_uint64 enet_host_random_seed(void); 962 963 ENET_API int enet_peer_send(ENetPeer *, enet_uint8, ENetPacket *); 964 ENET_API ENetPacket * enet_peer_receive(ENetPeer *, enet_uint8 * channelID); 965 ENET_API void enet_peer_ping(ENetPeer *); 966 ENET_API void enet_peer_ping_interval(ENetPeer *, enet_uint32); 967 ENET_API void enet_peer_timeout(ENetPeer *, enet_uint32, enet_uint32, enet_uint32); 968 ENET_API void enet_peer_reset(ENetPeer *); 969 ENET_API void enet_peer_disconnect(ENetPeer *, enet_uint32); 970 ENET_API void enet_peer_disconnect_now(ENetPeer *, enet_uint32); 971 ENET_API void enet_peer_disconnect_later(ENetPeer *, enet_uint32); 972 ENET_API void enet_peer_throttle_configure(ENetPeer *, enet_uint32, enet_uint32, enet_uint32); 973 extern int enet_peer_throttle(ENetPeer *, enet_uint32); 974 extern void enet_peer_reset_queues(ENetPeer *); 975 extern void enet_peer_setup_outgoing_command(ENetPeer *, ENetOutgoingCommand *); 976 extern ENetOutgoingCommand * enet_peer_queue_outgoing_command(ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32, enet_uint16); 977 extern ENetIncomingCommand * enet_peer_queue_incoming_command(ENetPeer *, const ENetProtocol *, void *, size_t, enet_uint32, enet_uint32); 978 extern ENetAcknowledgement * enet_peer_queue_acknowledgement(ENetPeer *, const ENetProtocol *, enet_uint16); 979 extern void enet_peer_dispatch_incoming_unreliable_commands(ENetPeer *, ENetChannel *); 980 extern void enet_peer_dispatch_incoming_reliable_commands(ENetPeer *, ENetChannel *); 981 extern void enet_peer_on_connect(ENetPeer *); 982 extern void enet_peer_on_disconnect(ENetPeer *); 983 984 extern size_t enet_protocol_command_size (enet_uint8); 985 986 #if defined _WIN32 || __APPLE__ && __MAC_OS_X_VERSION_MIN_REQUIRED < 101200 987 extern int enet_gettime(int X, struct timespec *tv); 988 #else 989 # define enet_gettime clock_gettime 990 #endif 991 992 993 #ifdef __cplusplus 994 } 995 #endif 996 997 #if defined(ENET_IMPLEMENTATION) && !defined(ENET_IMPLEMENTATION_DONE) 998 #define ENET_IMPLEMENTATION_DONE 1 999 1000 #ifdef __cplusplus 1001 extern "C" { 1002 #endif 1003 1004 // =======================================================================// 1005 // ! 1006 // ! Atomics 1007 // ! 1008 // =======================================================================// 1009 1010 #if defined(_MSC_VER) 1011 1012 #define ENET_AT_CASSERT_PRED(predicate) sizeof(char[2 * !!(predicate)-1]) 1013 #define ENET_IS_SUPPORTED_ATOMIC(size) ENET_AT_CASSERT_PRED(size == 1 || size == 2 || size == 4 || size == 8) 1014 #define ENET_ATOMIC_SIZEOF(variable) (ENET_IS_SUPPORTED_ATOMIC(sizeof(*(variable))), sizeof(*(variable))) 1015 enet_at_atomic_read(char * ptr,size_t size)1016 __inline int64_t enet_at_atomic_read(char *ptr, size_t size) 1017 { 1018 switch (size) { 1019 case 1: 1020 return _InterlockedExchangeAdd8((volatile char *)ptr, 0); 1021 case 2: 1022 return _InterlockedExchangeAdd16((volatile SHORT *)ptr, 0); 1023 case 4: 1024 #ifdef NOT_UNDERSCORED_INTERLOCKED_EXCHANGE 1025 return InterlockedExchangeAdd((volatile LONG *)ptr, 0); 1026 #else 1027 return _InterlockedExchangeAdd((volatile LONG *)ptr, 0); 1028 #endif 1029 case 8: 1030 #ifdef NOT_UNDERSCORED_INTERLOCKED_EXCHANGE 1031 return InterlockedExchangeAdd64((volatile LONGLONG *)ptr, 0); 1032 #else 1033 return _InterlockedExchangeAdd64((volatile LONGLONG *)ptr, 0); 1034 #endif 1035 default: 1036 return 0xbad13bad; /* never reached */ 1037 } 1038 } 1039 enet_at_atomic_write(char * ptr,int64_t value,size_t size)1040 __inline int64_t enet_at_atomic_write(char *ptr, int64_t value, size_t size) 1041 { 1042 switch (size) { 1043 case 1: 1044 return _InterlockedExchange8((volatile char *)ptr, (char)value); 1045 case 2: 1046 return _InterlockedExchange16((volatile SHORT *)ptr, (SHORT)value); 1047 case 4: 1048 #ifdef NOT_UNDERSCORED_INTERLOCKED_EXCHANGE 1049 return InterlockedExchange((volatile LONG *)ptr, (LONG)value); 1050 #else 1051 return _InterlockedExchange((volatile LONG *)ptr, (LONG)value); 1052 #endif 1053 case 8: 1054 #ifdef NOT_UNDERSCORED_INTERLOCKED_EXCHANGE 1055 return InterlockedExchange64((volatile LONGLONG *)ptr, (LONGLONG)value); 1056 #else 1057 return _InterlockedExchange64((volatile LONGLONG *)ptr, (LONGLONG)value); 1058 #endif 1059 default: 1060 return 0xbad13bad; /* never reached */ 1061 } 1062 } 1063 enet_at_atomic_cas(char * ptr,int64_t new_val,int64_t old_val,size_t size)1064 __inline int64_t enet_at_atomic_cas(char *ptr, int64_t new_val, int64_t old_val, size_t size) 1065 { 1066 switch (size) { 1067 case 1: 1068 return _InterlockedCompareExchange8((volatile char *)ptr, (char)new_val, (char)old_val); 1069 case 2: 1070 return _InterlockedCompareExchange16((volatile SHORT *)ptr, (SHORT)new_val, 1071 (SHORT)old_val); 1072 case 4: 1073 #ifdef NOT_UNDERSCORED_INTERLOCKED_EXCHANGE 1074 return InterlockedCompareExchange((volatile LONG *)ptr, (LONG)new_val, (LONG)old_val); 1075 #else 1076 return _InterlockedCompareExchange((volatile LONG *)ptr, (LONG)new_val, (LONG)old_val); 1077 #endif 1078 case 8: 1079 #ifdef NOT_UNDERSCORED_INTERLOCKED_EXCHANGE 1080 return InterlockedCompareExchange64((volatile LONGLONG *)ptr, (LONGLONG)new_val, 1081 (LONGLONG)old_val); 1082 #else 1083 return _InterlockedCompareExchange64((volatile LONGLONG *)ptr, (LONGLONG)new_val, 1084 (LONGLONG)old_val); 1085 #endif 1086 default: 1087 return 0xbad13bad; /* never reached */ 1088 } 1089 } 1090 enet_at_atomic_inc(char * ptr,int64_t delta,size_t data_size)1091 __inline int64_t enet_at_atomic_inc(char *ptr, int64_t delta, size_t data_size) 1092 { 1093 switch (data_size) { 1094 case 1: 1095 return _InterlockedExchangeAdd8((volatile char *)ptr, (char)delta); 1096 case 2: 1097 return _InterlockedExchangeAdd16((volatile SHORT *)ptr, (SHORT)delta); 1098 case 4: 1099 #ifdef NOT_UNDERSCORED_INTERLOCKED_EXCHANGE 1100 return InterlockedExchangeAdd((volatile LONG *)ptr, (LONG)delta); 1101 #else 1102 return _InterlockedExchangeAdd((volatile LONG *)ptr, (LONG)delta); 1103 #endif 1104 case 8: 1105 #ifdef NOT_UNDERSCORED_INTERLOCKED_EXCHANGE 1106 return InterlockedExchangeAdd64((volatile LONGLONG *)ptr, (LONGLONG)delta); 1107 #else 1108 return _InterlockedExchangeAdd64((volatile LONGLONG *)ptr, (LONGLONG)delta); 1109 #endif 1110 default: 1111 return 0xbad13bad; /* never reached */ 1112 } 1113 } 1114 1115 #define ENET_ATOMIC_READ(variable) enet_at_atomic_read((char *)(variable), ENET_ATOMIC_SIZEOF(variable)) 1116 #define ENET_ATOMIC_WRITE(variable, new_val) \ 1117 enet_at_atomic_write((char *)(variable), (int64_t)(new_val), ENET_ATOMIC_SIZEOF(variable)) 1118 #define ENET_ATOMIC_CAS(variable, old_value, new_val) \ 1119 enet_at_atomic_cas((char *)(variable), (int64_t)(new_val), (int64_t)(old_value), \ 1120 ENET_ATOMIC_SIZEOF(variable)) 1121 #define ENET_ATOMIC_INC(variable) enet_at_atomic_inc((char *)(variable), 1, ENET_ATOMIC_SIZEOF(variable)) 1122 #define ENET_ATOMIC_DEC(variable) enet_at_atomic_inc((char *)(variable), -1, ENET_ATOMIC_SIZEOF(variable)) 1123 #define ENET_ATOMIC_INC_BY(variable, delta) \ 1124 enet_at_atomic_inc((char *)(variable), (delta), ENET_ATOMIC_SIZEOF(variable)) 1125 #define ENET_ATOMIC_DEC_BY(variable, delta) \ 1126 enet_at_atomic_inc((char *)(variable), -(delta), ENET_ATOMIC_SIZEOF(variable)) 1127 1128 #elif defined(__GNUC__) || defined(__clang__) 1129 1130 #if defined(__clang__) || (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) 1131 #define AT_HAVE_ATOMICS 1132 #endif 1133 1134 /* We want to use __atomic built-ins if possible because the __sync primitives are 1135 deprecated, because the __atomic build-ins allow us to use ENET_ATOMIC_WRITE on 1136 uninitialized memory without running into undefined behavior, and because the 1137 __atomic versions generate more efficient code since we don't need to rely on 1138 CAS when we don't actually want it. 1139 1140 Note that we use acquire-release memory order (like mutexes do). We could use 1141 sequentially consistent memory order but that has lower performance and is 1142 almost always unneeded. */ 1143 #ifdef AT_HAVE_ATOMICS 1144 #define ENET_ATOMIC_READ(ptr) __atomic_load_n((ptr), __ATOMIC_ACQUIRE) 1145 #define ENET_ATOMIC_WRITE(ptr, value) __atomic_store_n((ptr), (value), __ATOMIC_RELEASE) 1146 1147 #ifndef typeof 1148 #define typeof __typeof__ 1149 #endif 1150 1151 /* clang_analyzer doesn't know that CAS writes to memory so it complains about 1152 potentially lost data. Replace the code with the equivalent non-sync code. */ 1153 #ifdef __clang_analyzer__ 1154 1155 #define ENET_ATOMIC_CAS(ptr, old_value, new_value) \ 1156 ({ \ 1157 typeof(*(ptr)) ENET_ATOMIC_CAS_old_actual_ = (*(ptr)); \ 1158 if (ATOMIC_CAS_old_actual_ == (old_value)) { \ 1159 *(ptr) = new_value; \ 1160 } \ 1161 ENET_ATOMIC_CAS_old_actual_; \ 1162 }) 1163 1164 #else 1165 1166 /* Could use __auto_type instead of typeof but that shouldn't work in C++. 1167 The ({ }) syntax is a GCC extension called statement expression. It lets 1168 us return a value out of the macro. 1169 1170 TODO We should return bool here instead of the old value to avoid the ABA 1171 problem. */ 1172 #define ENET_ATOMIC_CAS(ptr, old_value, new_value) \ 1173 ({ \ 1174 typeof(*(ptr)) ENET_ATOMIC_CAS_expected_ = (old_value); \ 1175 __atomic_compare_exchange_n((ptr), &ENET_ATOMIC_CAS_expected_, (new_value), false, \ 1176 __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE); \ 1177 ENET_ATOMIC_CAS_expected_; \ 1178 }) 1179 1180 #endif /* __clang_analyzer__ */ 1181 1182 #define ENET_ATOMIC_INC(ptr) __atomic_fetch_add((ptr), 1, __ATOMIC_ACQ_REL) 1183 #define ENET_ATOMIC_DEC(ptr) __atomic_fetch_sub((ptr), 1, __ATOMIC_ACQ_REL) 1184 #define ENET_ATOMIC_INC_BY(ptr, delta) __atomic_fetch_add((ptr), (delta), __ATOMIC_ACQ_REL) 1185 #define ENET_ATOMIC_DEC_BY(ptr, delta) __atomic_fetch_sub((ptr), (delta), __ATOMIC_ACQ_REL) 1186 1187 #else 1188 1189 #define ENET_ATOMIC_READ(variable) __sync_fetch_and_add(variable, 0) 1190 #define ENET_ATOMIC_WRITE(variable, new_val) \ 1191 (void) __sync_val_compare_and_swap((variable), *(variable), (new_val)) 1192 #define ENET_ATOMIC_CAS(variable, old_value, new_val) \ 1193 __sync_val_compare_and_swap((variable), (old_value), (new_val)) 1194 #define ENET_ATOMIC_INC(variable) __sync_fetch_and_add((variable), 1) 1195 #define ENET_ATOMIC_DEC(variable) __sync_fetch_and_sub((variable), 1) 1196 #define ENET_ATOMIC_INC_BY(variable, delta) __sync_fetch_and_add((variable), (delta), 1) 1197 #define ENET_ATOMIC_DEC_BY(variable, delta) __sync_fetch_and_sub((variable), (delta), 1) 1198 1199 #endif /* AT_HAVE_ATOMICS */ 1200 1201 #undef AT_HAVE_ATOMICS 1202 1203 #endif /* defined(_MSC_VER) */ 1204 1205 1206 // =======================================================================// 1207 // ! 1208 // ! Callbacks 1209 // ! 1210 // =======================================================================// 1211 1212 static ENetCallbacks callbacks = { malloc, free, abort }; 1213 enet_initialize_with_callbacks(ENetVersion version,const ENetCallbacks * inits)1214 int enet_initialize_with_callbacks(ENetVersion version, const ENetCallbacks *inits) { 1215 if (version < ENET_VERSION_CREATE(1, 3, 0)) { 1216 return -1; 1217 } 1218 1219 if (inits->malloc != NULL || inits->free != NULL) { 1220 if (inits->malloc == NULL || inits->free == NULL) { 1221 return -1; 1222 } 1223 1224 callbacks.malloc = inits->malloc; 1225 callbacks.free = inits->free; 1226 } 1227 1228 if (inits->no_memory != NULL) { 1229 callbacks.no_memory = inits->no_memory; 1230 } 1231 1232 return enet_initialize(); 1233 } 1234 enet_linked_version(void)1235 ENetVersion enet_linked_version(void) { 1236 return ENET_VERSION; 1237 } 1238 enet_malloc(size_t size)1239 void * enet_malloc(size_t size) { 1240 void *memory = callbacks.malloc(size); 1241 1242 if (memory == NULL) { 1243 callbacks.no_memory(); 1244 } 1245 1246 return memory; 1247 } 1248 enet_free(void * memory)1249 void enet_free(void *memory) { 1250 callbacks.free(memory); 1251 } 1252 1253 // =======================================================================// 1254 // ! 1255 // ! List 1256 // ! 1257 // =======================================================================// 1258 enet_list_clear(ENetList * list)1259 void enet_list_clear(ENetList *list) { 1260 list->sentinel.next = &list->sentinel; 1261 list->sentinel.previous = &list->sentinel; 1262 } 1263 enet_list_insert(ENetListIterator position,void * data)1264 ENetListIterator enet_list_insert(ENetListIterator position, void *data) { 1265 ENetListIterator result = (ENetListIterator)data; 1266 1267 result->previous = position->previous; 1268 result->next = position; 1269 1270 result->previous->next = result; 1271 position->previous = result; 1272 1273 return result; 1274 } 1275 enet_list_remove(ENetListIterator position)1276 void *enet_list_remove(ENetListIterator position) { 1277 position->previous->next = position->next; 1278 position->next->previous = position->previous; 1279 1280 return position; 1281 } 1282 enet_list_move(ENetListIterator position,void * dataFirst,void * dataLast)1283 ENetListIterator enet_list_move(ENetListIterator position, void *dataFirst, void *dataLast) { 1284 ENetListIterator first = (ENetListIterator)dataFirst; 1285 ENetListIterator last = (ENetListIterator)dataLast; 1286 1287 first->previous->next = last->next; 1288 last->next->previous = first->previous; 1289 1290 first->previous = position->previous; 1291 last->next = position; 1292 1293 first->previous->next = first; 1294 position->previous = last; 1295 1296 return first; 1297 } 1298 enet_list_size(ENetList * list)1299 size_t enet_list_size(ENetList *list) { 1300 size_t size = 0; 1301 ENetListIterator position; 1302 1303 for (position = enet_list_begin(list); position != enet_list_end(list); position = enet_list_next(position)) { 1304 ++size; 1305 } 1306 1307 return size; 1308 } 1309 1310 // =======================================================================// 1311 // ! 1312 // ! Packet 1313 // ! 1314 // =======================================================================// 1315 1316 /** 1317 * Creates a packet that may be sent to a peer. 1318 * @param data initial contents of the packet's data; the packet's data will remain uninitialized if data is NULL. 1319 * @param dataLength size of the data allocated for this packet 1320 * @param flags flags for this packet as described for the ENetPacket structure. 1321 * @returns the packet on success, NULL on failure 1322 */ enet_packet_create(void * data,size_t dataLength,enet_uint32 flags)1323 ENetPacket *enet_packet_create(void *data, size_t dataLength, enet_uint32 flags) { 1324 ENetPacket *packet; 1325 if (flags & ENET_PACKET_FLAG_NO_ALLOCATE) { 1326 packet = (ENetPacket *)enet_malloc(sizeof (ENetPacket)); 1327 if (packet == NULL) { 1328 return NULL; 1329 } 1330 1331 packet->data = (enet_uint8 *)data; 1332 } 1333 else { 1334 packet = (ENetPacket *)enet_malloc(sizeof (ENetPacket) + dataLength); 1335 if (packet == NULL) { 1336 return NULL; 1337 } 1338 1339 packet->data = (enet_uint8 *)packet + sizeof(ENetPacket); 1340 1341 if (data != NULL) { 1342 memcpy(packet->data, data, dataLength); 1343 } 1344 } 1345 1346 packet->referenceCount = 0; 1347 packet->flags = flags; 1348 packet->dataLength = dataLength; 1349 packet->freeCallback = NULL; 1350 packet->userData = NULL; 1351 1352 return packet; 1353 } 1354 enet_packet_create_offset(void * data,size_t dataLength,size_t dataOffset,enet_uint32 flags)1355 ENetPacket *enet_packet_create_offset(void *data, size_t dataLength, size_t dataOffset, enet_uint32 flags) { 1356 ENetPacket *packet; 1357 if (flags & ENET_PACKET_FLAG_NO_ALLOCATE) { 1358 packet = (ENetPacket *)enet_malloc(sizeof (ENetPacket)); 1359 if (packet == NULL) { 1360 return NULL; 1361 } 1362 1363 packet->data = (enet_uint8 *)data; 1364 } 1365 else { 1366 packet = (ENetPacket *)enet_malloc(sizeof (ENetPacket) + dataLength + dataOffset); 1367 if (packet == NULL) { 1368 return NULL; 1369 } 1370 1371 packet->data = (enet_uint8 *)packet + sizeof(ENetPacket); 1372 1373 if (data != NULL) { 1374 memcpy(packet->data + dataOffset, data, dataLength); 1375 } 1376 } 1377 1378 packet->referenceCount = 0; 1379 packet->flags = flags; 1380 packet->dataLength = dataLength + dataOffset; 1381 packet->freeCallback = NULL; 1382 packet->userData = NULL; 1383 1384 return packet; 1385 } 1386 1387 /** 1388 * Destroys the packet and deallocates its data. 1389 * @param packet packet to be destroyed 1390 */ enet_packet_destroy(ENetPacket * packet)1391 void enet_packet_destroy(ENetPacket *packet) { 1392 if (packet == NULL) { 1393 return; 1394 } 1395 1396 if (packet->freeCallback != NULL) { 1397 (*packet->freeCallback)((void *)packet); 1398 } 1399 1400 enet_free(packet); 1401 } 1402 1403 static int initializedCRC32 = 0; 1404 static enet_uint32 crcTable[256]; 1405 reflect_crc(int val,int bits)1406 static enet_uint32 reflect_crc(int val, int bits) { 1407 int result = 0, bit; 1408 1409 for (bit = 0; bit < bits; bit++) { 1410 if (val & 1) { result |= 1 << (bits - 1 - bit); } 1411 val >>= 1; 1412 } 1413 1414 return result; 1415 } 1416 initialize_crc32(void)1417 static void initialize_crc32(void) { 1418 int byte; 1419 1420 for (byte = 0; byte < 256; ++byte) { 1421 enet_uint32 crc = reflect_crc(byte, 8) << 24; 1422 int offset; 1423 1424 for (offset = 0; offset < 8; ++offset) { 1425 if (crc & 0x80000000) { 1426 crc = (crc << 1) ^ 0x04c11db7; 1427 } else { 1428 crc <<= 1; 1429 } 1430 } 1431 1432 crcTable[byte] = reflect_crc(crc, 32); 1433 } 1434 1435 initializedCRC32 = 1; 1436 } 1437 enet_crc32(const ENetBuffer * buffers,size_t bufferCount)1438 enet_uint32 enet_crc32(const ENetBuffer *buffers, size_t bufferCount) { 1439 enet_uint32 crc = 0xFFFFFFFF; 1440 1441 if (!initializedCRC32) { initialize_crc32(); } 1442 1443 while (bufferCount-- > 0) { 1444 const enet_uint8 *data = (const enet_uint8 *)buffers->data; 1445 const enet_uint8 *dataEnd = &data[buffers->dataLength]; 1446 1447 while (data < dataEnd) { 1448 crc = (crc >> 8) ^ crcTable[(crc & 0xFF) ^ *data++]; 1449 } 1450 1451 ++buffers; 1452 } 1453 1454 return ENET_HOST_TO_NET_32(~crc); 1455 } 1456 1457 // =======================================================================// 1458 // ! 1459 // ! Protocol 1460 // ! 1461 // =======================================================================// 1462 1463 static size_t commandSizes[ENET_PROTOCOL_COMMAND_COUNT] = { 1464 0, 1465 sizeof(ENetProtocolAcknowledge), 1466 sizeof(ENetProtocolConnect), 1467 sizeof(ENetProtocolVerifyConnect), 1468 sizeof(ENetProtocolDisconnect), 1469 sizeof(ENetProtocolPing), 1470 sizeof(ENetProtocolSendReliable), 1471 sizeof(ENetProtocolSendUnreliable), 1472 sizeof(ENetProtocolSendFragment), 1473 sizeof(ENetProtocolSendUnsequenced), 1474 sizeof(ENetProtocolBandwidthLimit), 1475 sizeof(ENetProtocolThrottleConfigure), 1476 sizeof(ENetProtocolSendFragment) 1477 }; 1478 enet_protocol_command_size(enet_uint8 commandNumber)1479 size_t enet_protocol_command_size(enet_uint8 commandNumber) { 1480 return commandSizes[commandNumber & ENET_PROTOCOL_COMMAND_MASK]; 1481 } 1482 enet_protocol_change_state(ENetHost * host,ENetPeer * peer,ENetPeerState state)1483 static void enet_protocol_change_state(ENetHost *host, ENetPeer *peer, ENetPeerState state) { 1484 UNREFERENCED_PARAMETER(host); 1485 if (state == ENET_PEER_STATE_CONNECTED || state == ENET_PEER_STATE_DISCONNECT_LATER) { 1486 enet_peer_on_connect(peer); 1487 } else { 1488 enet_peer_on_disconnect(peer); 1489 } 1490 1491 peer->state = state; 1492 } 1493 enet_protocol_dispatch_state(ENetHost * host,ENetPeer * peer,ENetPeerState state)1494 static void enet_protocol_dispatch_state(ENetHost *host, ENetPeer *peer, ENetPeerState state) { 1495 enet_protocol_change_state(host, peer, state); 1496 1497 if (!peer->needsDispatch) { 1498 enet_list_insert(enet_list_end(&host->dispatchQueue), &peer->dispatchList); 1499 peer->needsDispatch = 1; 1500 } 1501 } 1502 enet_protocol_dispatch_incoming_commands(ENetHost * host,ENetEvent * event)1503 static int enet_protocol_dispatch_incoming_commands(ENetHost *host, ENetEvent *event) { 1504 while (!enet_list_empty(&host->dispatchQueue)) { 1505 ENetPeer *peer = (ENetPeer *) enet_list_remove(enet_list_begin(&host->dispatchQueue)); 1506 peer->needsDispatch = 0; 1507 1508 switch (peer->state) { 1509 case ENET_PEER_STATE_CONNECTION_PENDING: 1510 case ENET_PEER_STATE_CONNECTION_SUCCEEDED: 1511 enet_protocol_change_state(host, peer, ENET_PEER_STATE_CONNECTED); 1512 1513 event->type = ENET_EVENT_TYPE_CONNECT; 1514 event->peer = peer; 1515 event->data = peer->eventData; 1516 1517 return 1; 1518 1519 case ENET_PEER_STATE_ZOMBIE: 1520 host->recalculateBandwidthLimits = 1; 1521 1522 event->type = ENET_EVENT_TYPE_DISCONNECT; 1523 event->peer = peer; 1524 event->data = peer->eventData; 1525 1526 enet_peer_reset(peer); 1527 1528 return 1; 1529 1530 case ENET_PEER_STATE_CONNECTED: 1531 if (enet_list_empty(&peer->dispatchedCommands)) { 1532 continue; 1533 } 1534 1535 event->packet = enet_peer_receive(peer, &event->channelID); 1536 if (event->packet == NULL) { 1537 continue; 1538 } 1539 1540 event->type = ENET_EVENT_TYPE_RECEIVE; 1541 event->peer = peer; 1542 1543 if (!enet_list_empty(&peer->dispatchedCommands)) { 1544 peer->needsDispatch = 1; 1545 enet_list_insert(enet_list_end(&host->dispatchQueue), &peer->dispatchList); 1546 } 1547 1548 return 1; 1549 1550 default: 1551 break; 1552 } 1553 } 1554 1555 return 0; 1556 } /* enet_protocol_dispatch_incoming_commands */ 1557 enet_protocol_notify_connect(ENetHost * host,ENetPeer * peer,ENetEvent * event)1558 static void enet_protocol_notify_connect(ENetHost *host, ENetPeer *peer, ENetEvent *event) { 1559 host->recalculateBandwidthLimits = 1; 1560 1561 if (event != NULL) { 1562 enet_protocol_change_state(host, peer, ENET_PEER_STATE_CONNECTED); 1563 1564 peer->totalDataSent = 0; 1565 peer->totalDataReceived = 0; 1566 peer->totalPacketsSent = 0; 1567 peer->totalPacketsLost = 0; 1568 1569 event->type = ENET_EVENT_TYPE_CONNECT; 1570 event->peer = peer; 1571 event->data = peer->eventData; 1572 } else { 1573 enet_protocol_dispatch_state(host, peer, peer->state == ENET_PEER_STATE_CONNECTING ? ENET_PEER_STATE_CONNECTION_SUCCEEDED : ENET_PEER_STATE_CONNECTION_PENDING); 1574 } 1575 } 1576 enet_protocol_notify_disconnect(ENetHost * host,ENetPeer * peer,ENetEvent * event)1577 static void enet_protocol_notify_disconnect(ENetHost *host, ENetPeer *peer, ENetEvent *event) { 1578 if (peer->state >= ENET_PEER_STATE_CONNECTION_PENDING) { 1579 host->recalculateBandwidthLimits = 1; 1580 } 1581 1582 if (peer->state != ENET_PEER_STATE_CONNECTING && peer->state < ENET_PEER_STATE_CONNECTION_SUCCEEDED) { 1583 enet_peer_reset(peer); 1584 } else if (event != NULL) { 1585 event->type = ENET_EVENT_TYPE_DISCONNECT; 1586 event->peer = peer; 1587 event->data = 0; 1588 1589 enet_peer_reset(peer); 1590 } else { 1591 peer->eventData = 0; 1592 enet_protocol_dispatch_state(host, peer, ENET_PEER_STATE_ZOMBIE); 1593 } 1594 } 1595 enet_protocol_notify_disconnect_timeout(ENetHost * host,ENetPeer * peer,ENetEvent * event)1596 static void enet_protocol_notify_disconnect_timeout (ENetHost * host, ENetPeer * peer, ENetEvent * event) { 1597 if (peer->state >= ENET_PEER_STATE_CONNECTION_PENDING) { 1598 host->recalculateBandwidthLimits = 1; 1599 } 1600 1601 if (peer->state != ENET_PEER_STATE_CONNECTING && peer->state < ENET_PEER_STATE_CONNECTION_SUCCEEDED) { 1602 enet_peer_reset (peer); 1603 } 1604 else if (event != NULL) { 1605 event->type = ENET_EVENT_TYPE_DISCONNECT_TIMEOUT; 1606 event->peer = peer; 1607 event->data = 0; 1608 1609 enet_peer_reset(peer); 1610 } 1611 else { 1612 peer->eventData = 0; 1613 enet_protocol_dispatch_state(host, peer, ENET_PEER_STATE_ZOMBIE); 1614 } 1615 } 1616 enet_protocol_remove_sent_unreliable_commands(ENetPeer * peer)1617 static void enet_protocol_remove_sent_unreliable_commands(ENetPeer *peer) { 1618 ENetOutgoingCommand *outgoingCommand; 1619 1620 while (!enet_list_empty(&peer->sentUnreliableCommands)) { 1621 outgoingCommand = (ENetOutgoingCommand *) enet_list_front(&peer->sentUnreliableCommands); 1622 enet_list_remove(&outgoingCommand->outgoingCommandList); 1623 1624 if (outgoingCommand->packet != NULL) { 1625 --outgoingCommand->packet->referenceCount; 1626 1627 if (outgoingCommand->packet->referenceCount == 0) { 1628 outgoingCommand->packet->flags |= ENET_PACKET_FLAG_SENT; 1629 enet_packet_destroy(outgoingCommand->packet); 1630 } 1631 } 1632 1633 enet_free(outgoingCommand); 1634 } 1635 } 1636 enet_protocol_remove_sent_reliable_command(ENetPeer * peer,enet_uint16 reliableSequenceNumber,enet_uint8 channelID)1637 static ENetProtocolCommand enet_protocol_remove_sent_reliable_command(ENetPeer *peer, enet_uint16 reliableSequenceNumber, enet_uint8 channelID) { 1638 ENetOutgoingCommand *outgoingCommand = NULL; 1639 ENetListIterator currentCommand; 1640 ENetProtocolCommand commandNumber; 1641 int wasSent = 1; 1642 1643 for (currentCommand = enet_list_begin(&peer->sentReliableCommands); 1644 currentCommand != enet_list_end(&peer->sentReliableCommands); 1645 currentCommand = enet_list_next(currentCommand) 1646 ) { 1647 outgoingCommand = (ENetOutgoingCommand *) currentCommand; 1648 1649 if (outgoingCommand->reliableSequenceNumber == reliableSequenceNumber && outgoingCommand->command.header.channelID == channelID) { 1650 break; 1651 } 1652 } 1653 1654 if (currentCommand == enet_list_end(&peer->sentReliableCommands)) { 1655 for (currentCommand = enet_list_begin(&peer->outgoingReliableCommands); 1656 currentCommand != enet_list_end(&peer->outgoingReliableCommands); 1657 currentCommand = enet_list_next(currentCommand) 1658 ) { 1659 outgoingCommand = (ENetOutgoingCommand *) currentCommand; 1660 1661 if (outgoingCommand->sendAttempts < 1) { return ENET_PROTOCOL_COMMAND_NONE; } 1662 if (outgoingCommand->reliableSequenceNumber == reliableSequenceNumber && outgoingCommand->command.header.channelID == channelID) { 1663 break; 1664 } 1665 } 1666 1667 if (currentCommand == enet_list_end(&peer->outgoingReliableCommands)) { 1668 return ENET_PROTOCOL_COMMAND_NONE; 1669 } 1670 1671 wasSent = 0; 1672 } 1673 1674 if (outgoingCommand == NULL) { 1675 return ENET_PROTOCOL_COMMAND_NONE; 1676 } 1677 1678 if (channelID < peer->channelCount) { 1679 ENetChannel *channel = &peer->channels[channelID]; 1680 enet_uint16 reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; 1681 if (channel->reliableWindows[reliableWindow] > 0) { 1682 --channel->reliableWindows[reliableWindow]; 1683 if (!channel->reliableWindows[reliableWindow]) { 1684 channel->usedReliableWindows &= ~(1 << reliableWindow); 1685 } 1686 } 1687 } 1688 1689 commandNumber = (ENetProtocolCommand) (outgoingCommand->command.header.command & ENET_PROTOCOL_COMMAND_MASK); 1690 enet_list_remove(&outgoingCommand->outgoingCommandList); 1691 1692 if (outgoingCommand->packet != NULL) { 1693 if (wasSent) { 1694 peer->reliableDataInTransit -= outgoingCommand->fragmentLength; 1695 } 1696 1697 --outgoingCommand->packet->referenceCount; 1698 1699 if (outgoingCommand->packet->referenceCount == 0) { 1700 outgoingCommand->packet->flags |= ENET_PACKET_FLAG_SENT; 1701 enet_packet_destroy(outgoingCommand->packet); 1702 } 1703 } 1704 1705 enet_free(outgoingCommand); 1706 1707 if (enet_list_empty(&peer->sentReliableCommands)) { 1708 return commandNumber; 1709 } 1710 1711 outgoingCommand = (ENetOutgoingCommand *) enet_list_front(&peer->sentReliableCommands); 1712 peer->nextTimeout = outgoingCommand->sentTime + outgoingCommand->roundTripTimeout; 1713 1714 return commandNumber; 1715 } /* enet_protocol_remove_sent_reliable_command */ 1716 enet_protocol_handle_connect(ENetHost * host,ENetProtocolHeader * header,ENetProtocol * command)1717 static ENetPeer * enet_protocol_handle_connect(ENetHost *host, ENetProtocolHeader *header, ENetProtocol *command) { 1718 UNREFERENCED_PARAMETER(header); 1719 enet_uint8 incomingSessionID, outgoingSessionID; 1720 enet_uint32 mtu, windowSize; 1721 ENetChannel *channel; 1722 size_t channelCount, duplicatePeers = 0; 1723 ENetPeer *currentPeer, *peer = NULL; 1724 ENetProtocol verifyCommand; 1725 1726 channelCount = ENET_NET_TO_HOST_32(command->connect.channelCount); 1727 1728 if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT || channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) { 1729 return NULL; 1730 } 1731 1732 for (currentPeer = host->peers; currentPeer < &host->peers[host->peerCount]; ++currentPeer) { 1733 if (currentPeer->state == ENET_PEER_STATE_DISCONNECTED) { 1734 if (peer == NULL) { 1735 peer = currentPeer; 1736 } 1737 } else if (currentPeer->state != ENET_PEER_STATE_CONNECTING && in6_equal(currentPeer->address.host, host->receivedAddress.host)) { 1738 if (currentPeer->address.port == host->receivedAddress.port && currentPeer->connectID == command->connect.connectID) { 1739 return NULL; 1740 } 1741 1742 ++duplicatePeers; 1743 } 1744 } 1745 1746 if (peer == NULL || duplicatePeers >= host->duplicatePeers) { 1747 return NULL; 1748 } 1749 1750 if (channelCount > host->channelLimit) { 1751 channelCount = host->channelLimit; 1752 } 1753 peer->channels = (ENetChannel *) enet_malloc(channelCount * sizeof(ENetChannel)); 1754 if (peer->channels == NULL) { 1755 return NULL; 1756 } 1757 peer->channelCount = channelCount; 1758 peer->state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT; 1759 peer->connectID = command->connect.connectID; 1760 peer->address = host->receivedAddress; 1761 peer->outgoingPeerID = ENET_NET_TO_HOST_16(command->connect.outgoingPeerID); 1762 peer->incomingBandwidth = ENET_NET_TO_HOST_32(command->connect.incomingBandwidth); 1763 peer->outgoingBandwidth = ENET_NET_TO_HOST_32(command->connect.outgoingBandwidth); 1764 peer->packetThrottleInterval = ENET_NET_TO_HOST_32(command->connect.packetThrottleInterval); 1765 peer->packetThrottleAcceleration = ENET_NET_TO_HOST_32(command->connect.packetThrottleAcceleration); 1766 peer->packetThrottleDeceleration = ENET_NET_TO_HOST_32(command->connect.packetThrottleDeceleration); 1767 peer->eventData = ENET_NET_TO_HOST_32(command->connect.data); 1768 1769 incomingSessionID = command->connect.incomingSessionID == 0xFF ? peer->outgoingSessionID : command->connect.incomingSessionID; 1770 incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); 1771 if (incomingSessionID == peer->outgoingSessionID) { 1772 incomingSessionID = (incomingSessionID + 1) 1773 & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); 1774 } 1775 peer->outgoingSessionID = incomingSessionID; 1776 1777 outgoingSessionID = command->connect.outgoingSessionID == 0xFF ? peer->incomingSessionID : command->connect.outgoingSessionID; 1778 outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); 1779 if (outgoingSessionID == peer->incomingSessionID) { 1780 outgoingSessionID = (outgoingSessionID + 1) 1781 & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); 1782 } 1783 peer->incomingSessionID = outgoingSessionID; 1784 1785 for (channel = peer->channels; channel < &peer->channels[channelCount]; ++channel) { 1786 channel->outgoingReliableSequenceNumber = 0; 1787 channel->outgoingUnreliableSequenceNumber = 0; 1788 channel->incomingReliableSequenceNumber = 0; 1789 channel->incomingUnreliableSequenceNumber = 0; 1790 1791 enet_list_clear(&channel->incomingReliableCommands); 1792 enet_list_clear(&channel->incomingUnreliableCommands); 1793 1794 channel->usedReliableWindows = 0; 1795 memset(channel->reliableWindows, 0, sizeof(channel->reliableWindows)); 1796 } 1797 1798 mtu = ENET_NET_TO_HOST_32(command->connect.mtu); 1799 1800 if (mtu < ENET_PROTOCOL_MINIMUM_MTU) { 1801 mtu = ENET_PROTOCOL_MINIMUM_MTU; 1802 } else if (mtu > ENET_PROTOCOL_MAXIMUM_MTU) { 1803 mtu = ENET_PROTOCOL_MAXIMUM_MTU; 1804 } 1805 1806 peer->mtu = mtu; 1807 1808 if (host->outgoingBandwidth == 0 && peer->incomingBandwidth == 0) { 1809 peer->windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; 1810 } else if (host->outgoingBandwidth == 0 || peer->incomingBandwidth == 0) { 1811 peer->windowSize = (ENET_MAX(host->outgoingBandwidth, peer->incomingBandwidth) / ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; 1812 } else { 1813 peer->windowSize = (ENET_MIN(host->outgoingBandwidth, peer->incomingBandwidth) / ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; 1814 } 1815 1816 if (peer->windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) { 1817 peer->windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; 1818 } else if (peer->windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) { 1819 peer->windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; 1820 } 1821 1822 if (host->incomingBandwidth == 0) { 1823 windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; 1824 } else { 1825 windowSize = (host->incomingBandwidth / ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; 1826 } 1827 1828 if (windowSize > ENET_NET_TO_HOST_32(command->connect.windowSize)) { 1829 windowSize = ENET_NET_TO_HOST_32(command->connect.windowSize); 1830 } 1831 1832 if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) { 1833 windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; 1834 } else if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) { 1835 windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; 1836 } 1837 1838 verifyCommand.header.command = ENET_PROTOCOL_COMMAND_VERIFY_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; 1839 verifyCommand.header.channelID = 0xFF; 1840 verifyCommand.verifyConnect.outgoingPeerID = ENET_HOST_TO_NET_16(peer->incomingPeerID); 1841 verifyCommand.verifyConnect.incomingSessionID = incomingSessionID; 1842 verifyCommand.verifyConnect.outgoingSessionID = outgoingSessionID; 1843 verifyCommand.verifyConnect.mtu = ENET_HOST_TO_NET_32(peer->mtu); 1844 verifyCommand.verifyConnect.windowSize = ENET_HOST_TO_NET_32(windowSize); 1845 verifyCommand.verifyConnect.channelCount = ENET_HOST_TO_NET_32(channelCount); 1846 verifyCommand.verifyConnect.incomingBandwidth = ENET_HOST_TO_NET_32(host->incomingBandwidth); 1847 verifyCommand.verifyConnect.outgoingBandwidth = ENET_HOST_TO_NET_32(host->outgoingBandwidth); 1848 verifyCommand.verifyConnect.packetThrottleInterval = ENET_HOST_TO_NET_32(peer->packetThrottleInterval); 1849 verifyCommand.verifyConnect.packetThrottleAcceleration = ENET_HOST_TO_NET_32(peer->packetThrottleAcceleration); 1850 verifyCommand.verifyConnect.packetThrottleDeceleration = ENET_HOST_TO_NET_32(peer->packetThrottleDeceleration); 1851 verifyCommand.verifyConnect.connectID = peer->connectID; 1852 1853 enet_peer_queue_outgoing_command(peer, &verifyCommand, NULL, 0, 0); 1854 return peer; 1855 } /* enet_protocol_handle_connect */ 1856 enet_protocol_handle_send_reliable(ENetHost * host,ENetPeer * peer,ENetProtocol * command,enet_uint8 ** currentData)1857 static int enet_protocol_handle_send_reliable(ENetHost *host, ENetPeer *peer, ENetProtocol *command, enet_uint8 **currentData) { 1858 size_t dataLength; 1859 1860 if (command->header.channelID >= peer->channelCount || (peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER)) { 1861 return -1; 1862 } 1863 1864 dataLength = ENET_NET_TO_HOST_16(command->sendReliable.dataLength); 1865 *currentData += dataLength; 1866 1867 if (dataLength > host->maximumPacketSize || *currentData < host->receivedData || *currentData > &host->receivedData[host->receivedDataLength]) { 1868 return -1; 1869 } 1870 1871 if (enet_peer_queue_incoming_command(peer, command, (enet_uint8 *) command + sizeof(ENetProtocolSendReliable), dataLength, ENET_PACKET_FLAG_RELIABLE, 0) == NULL) { 1872 return -1; 1873 } 1874 1875 return 0; 1876 } 1877 enet_protocol_handle_send_unsequenced(ENetHost * host,ENetPeer * peer,ENetProtocol * command,enet_uint8 ** currentData)1878 static int enet_protocol_handle_send_unsequenced(ENetHost *host, ENetPeer *peer, ENetProtocol *command, enet_uint8 **currentData) { 1879 enet_uint32 unsequencedGroup, index; 1880 size_t dataLength; 1881 1882 if (command->header.channelID >= peer->channelCount || (peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER)) { 1883 return -1; 1884 } 1885 1886 dataLength = ENET_NET_TO_HOST_16(command->sendUnsequenced.dataLength); 1887 *currentData += dataLength; 1888 if (dataLength > host->maximumPacketSize || *currentData < host->receivedData || *currentData > &host->receivedData[host->receivedDataLength]) { 1889 return -1; 1890 } 1891 1892 unsequencedGroup = ENET_NET_TO_HOST_16(command->sendUnsequenced.unsequencedGroup); 1893 index = unsequencedGroup % ENET_PEER_UNSEQUENCED_WINDOW_SIZE; 1894 1895 if (unsequencedGroup < peer->incomingUnsequencedGroup) { 1896 unsequencedGroup += 0x10000; 1897 } 1898 1899 if (unsequencedGroup >= (enet_uint32) peer->incomingUnsequencedGroup + ENET_PEER_FREE_UNSEQUENCED_WINDOWS * ENET_PEER_UNSEQUENCED_WINDOW_SIZE) { 1900 return 0; 1901 } 1902 1903 unsequencedGroup &= 0xFFFF; 1904 1905 if (unsequencedGroup - index != peer->incomingUnsequencedGroup) { 1906 peer->incomingUnsequencedGroup = unsequencedGroup - index; 1907 memset(peer->unsequencedWindow, 0, sizeof(peer->unsequencedWindow)); 1908 } else if (peer->unsequencedWindow[index / 32] & (1 << (index % 32))) { 1909 return 0; 1910 } 1911 1912 if (enet_peer_queue_incoming_command(peer, command, (enet_uint8 *) command + sizeof(ENetProtocolSendUnsequenced), dataLength, ENET_PACKET_FLAG_UNSEQUENCED,0) == NULL) { 1913 return -1; 1914 } 1915 1916 peer->unsequencedWindow[index / 32] |= 1 << (index % 32); 1917 1918 return 0; 1919 } /* enet_protocol_handle_send_unsequenced */ 1920 enet_protocol_handle_send_unreliable(ENetHost * host,ENetPeer * peer,ENetProtocol * command,enet_uint8 ** currentData)1921 static int enet_protocol_handle_send_unreliable(ENetHost *host, ENetPeer *peer, ENetProtocol *command, 1922 enet_uint8 **currentData) { 1923 size_t dataLength; 1924 1925 if (command->header.channelID >= peer->channelCount || 1926 (peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER)) 1927 { 1928 return -1; 1929 } 1930 1931 dataLength = ENET_NET_TO_HOST_16(command->sendUnreliable.dataLength); 1932 *currentData += dataLength; 1933 if (dataLength > host->maximumPacketSize || *currentData < host->receivedData || *currentData > &host->receivedData[host->receivedDataLength]) { 1934 return -1; 1935 } 1936 1937 if (enet_peer_queue_incoming_command(peer, command, (enet_uint8 *) command + sizeof(ENetProtocolSendUnreliable), dataLength, 0, 0) == NULL) { 1938 return -1; 1939 } 1940 1941 return 0; 1942 } 1943 enet_protocol_handle_send_fragment(ENetHost * host,ENetPeer * peer,ENetProtocol * command,enet_uint8 ** currentData)1944 static int enet_protocol_handle_send_fragment(ENetHost *host, ENetPeer *peer, ENetProtocol *command, enet_uint8 **currentData) { 1945 enet_uint32 fragmentNumber, fragmentCount, fragmentOffset, fragmentLength, startSequenceNumber, totalLength; 1946 ENetChannel *channel; 1947 enet_uint16 startWindow, currentWindow; 1948 ENetListIterator currentCommand; 1949 ENetIncomingCommand *startCommand = NULL; 1950 1951 if (command->header.channelID >= peer->channelCount || (peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER)) { 1952 return -1; 1953 } 1954 1955 fragmentLength = ENET_NET_TO_HOST_16(command->sendFragment.dataLength); 1956 *currentData += fragmentLength; 1957 if (fragmentLength > host->maximumPacketSize || *currentData < host->receivedData || *currentData > &host->receivedData[host->receivedDataLength]) { 1958 return -1; 1959 } 1960 1961 channel = &peer->channels[command->header.channelID]; 1962 startSequenceNumber = ENET_NET_TO_HOST_16(command->sendFragment.startSequenceNumber); 1963 startWindow = startSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; 1964 currentWindow = channel->incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; 1965 1966 if (startSequenceNumber < channel->incomingReliableSequenceNumber) { 1967 startWindow += ENET_PEER_RELIABLE_WINDOWS; 1968 } 1969 1970 if (startWindow < currentWindow || startWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1) { 1971 return 0; 1972 } 1973 1974 fragmentNumber = ENET_NET_TO_HOST_32(command->sendFragment.fragmentNumber); 1975 fragmentCount = ENET_NET_TO_HOST_32(command->sendFragment.fragmentCount); 1976 fragmentOffset = ENET_NET_TO_HOST_32(command->sendFragment.fragmentOffset); 1977 totalLength = ENET_NET_TO_HOST_32(command->sendFragment.totalLength); 1978 1979 if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT || 1980 fragmentNumber >= fragmentCount || 1981 totalLength > host->maximumPacketSize || 1982 fragmentOffset >= totalLength || 1983 fragmentLength > totalLength - fragmentOffset 1984 ) { 1985 return -1; 1986 } 1987 1988 for (currentCommand = enet_list_previous(enet_list_end(&channel->incomingReliableCommands)); 1989 currentCommand != enet_list_end(&channel->incomingReliableCommands); 1990 currentCommand = enet_list_previous(currentCommand) 1991 ) { 1992 ENetIncomingCommand *incomingCommand = (ENetIncomingCommand *) currentCommand; 1993 1994 if (startSequenceNumber >= channel->incomingReliableSequenceNumber) { 1995 if (incomingCommand->reliableSequenceNumber < channel->incomingReliableSequenceNumber) { 1996 continue; 1997 } 1998 } else if (incomingCommand->reliableSequenceNumber >= channel->incomingReliableSequenceNumber) { 1999 break; 2000 } 2001 2002 if (incomingCommand->reliableSequenceNumber <= startSequenceNumber) { 2003 if (incomingCommand->reliableSequenceNumber < startSequenceNumber) { 2004 break; 2005 } 2006 2007 if ((incomingCommand->command.header.command & ENET_PROTOCOL_COMMAND_MASK) != 2008 ENET_PROTOCOL_COMMAND_SEND_FRAGMENT || 2009 totalLength != incomingCommand->packet->dataLength || 2010 fragmentCount != incomingCommand->fragmentCount 2011 ) { 2012 return -1; 2013 } 2014 2015 startCommand = incomingCommand; 2016 break; 2017 } 2018 } 2019 2020 if (startCommand == NULL) { 2021 ENetProtocol hostCommand = *command; 2022 hostCommand.header.reliableSequenceNumber = startSequenceNumber; 2023 startCommand = enet_peer_queue_incoming_command(peer, &hostCommand, NULL, totalLength, ENET_PACKET_FLAG_RELIABLE, fragmentCount); 2024 if (startCommand == NULL) { 2025 return -1; 2026 } 2027 } 2028 2029 if ((startCommand->fragments[fragmentNumber / 32] & (1 << (fragmentNumber % 32))) == 0) { 2030 --startCommand->fragmentsRemaining; 2031 startCommand->fragments[fragmentNumber / 32] |= (1 << (fragmentNumber % 32)); 2032 2033 if (fragmentOffset + fragmentLength > startCommand->packet->dataLength) { 2034 fragmentLength = startCommand->packet->dataLength - fragmentOffset; 2035 } 2036 2037 memcpy(startCommand->packet->data + fragmentOffset, (enet_uint8 *) command + sizeof(ENetProtocolSendFragment), fragmentLength); 2038 2039 if (startCommand->fragmentsRemaining <= 0) { 2040 enet_peer_dispatch_incoming_reliable_commands(peer, channel); 2041 } 2042 } 2043 2044 return 0; 2045 } /* enet_protocol_handle_send_fragment */ 2046 enet_protocol_handle_send_unreliable_fragment(ENetHost * host,ENetPeer * peer,ENetProtocol * command,enet_uint8 ** currentData)2047 static int enet_protocol_handle_send_unreliable_fragment(ENetHost *host, ENetPeer *peer, ENetProtocol *command, enet_uint8 **currentData) { 2048 enet_uint32 fragmentNumber, fragmentCount, fragmentOffset, fragmentLength, reliableSequenceNumber, startSequenceNumber, totalLength; 2049 enet_uint16 reliableWindow, currentWindow; 2050 ENetChannel *channel; 2051 ENetListIterator currentCommand; 2052 ENetIncomingCommand *startCommand = NULL; 2053 2054 if (command->header.channelID >= peer->channelCount || (peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER)) { 2055 return -1; 2056 } 2057 2058 fragmentLength = ENET_NET_TO_HOST_16(command->sendFragment.dataLength); 2059 *currentData += fragmentLength; 2060 if (fragmentLength > host->maximumPacketSize || *currentData < host->receivedData || *currentData > &host->receivedData[host->receivedDataLength]) { 2061 return -1; 2062 } 2063 2064 channel = &peer->channels[command->header.channelID]; 2065 reliableSequenceNumber = command->header.reliableSequenceNumber; 2066 startSequenceNumber = ENET_NET_TO_HOST_16(command->sendFragment.startSequenceNumber); 2067 2068 reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; 2069 currentWindow = channel->incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; 2070 2071 if (reliableSequenceNumber < channel->incomingReliableSequenceNumber) { 2072 reliableWindow += ENET_PEER_RELIABLE_WINDOWS; 2073 } 2074 2075 if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1) { 2076 return 0; 2077 } 2078 2079 if (reliableSequenceNumber == channel->incomingReliableSequenceNumber && startSequenceNumber <= channel->incomingUnreliableSequenceNumber) { 2080 return 0; 2081 } 2082 2083 fragmentNumber = ENET_NET_TO_HOST_32(command->sendFragment.fragmentNumber); 2084 fragmentCount = ENET_NET_TO_HOST_32(command->sendFragment.fragmentCount); 2085 fragmentOffset = ENET_NET_TO_HOST_32(command->sendFragment.fragmentOffset); 2086 totalLength = ENET_NET_TO_HOST_32(command->sendFragment.totalLength); 2087 2088 if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT || 2089 fragmentNumber >= fragmentCount || 2090 totalLength > host->maximumPacketSize || 2091 fragmentOffset >= totalLength || 2092 fragmentLength > totalLength - fragmentOffset 2093 ) { 2094 return -1; 2095 } 2096 2097 for (currentCommand = enet_list_previous(enet_list_end(&channel->incomingUnreliableCommands)); 2098 currentCommand != enet_list_end(&channel->incomingUnreliableCommands); 2099 currentCommand = enet_list_previous(currentCommand) 2100 ) { 2101 ENetIncomingCommand *incomingCommand = (ENetIncomingCommand *) currentCommand; 2102 2103 if (reliableSequenceNumber >= channel->incomingReliableSequenceNumber) { 2104 if (incomingCommand->reliableSequenceNumber < channel->incomingReliableSequenceNumber) { 2105 continue; 2106 } 2107 } else if (incomingCommand->reliableSequenceNumber >= channel->incomingReliableSequenceNumber) { 2108 break; 2109 } 2110 2111 if (incomingCommand->reliableSequenceNumber < reliableSequenceNumber) { 2112 break; 2113 } 2114 2115 if (incomingCommand->reliableSequenceNumber > reliableSequenceNumber) { 2116 continue; 2117 } 2118 2119 if (incomingCommand->unreliableSequenceNumber <= startSequenceNumber) { 2120 if (incomingCommand->unreliableSequenceNumber < startSequenceNumber) { 2121 break; 2122 } 2123 2124 if ((incomingCommand->command.header.command & ENET_PROTOCOL_COMMAND_MASK) != 2125 ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT || 2126 totalLength != incomingCommand->packet->dataLength || 2127 fragmentCount != incomingCommand->fragmentCount 2128 ) { 2129 return -1; 2130 } 2131 2132 startCommand = incomingCommand; 2133 break; 2134 } 2135 } 2136 2137 if (startCommand == NULL) { 2138 startCommand = enet_peer_queue_incoming_command(peer, command, NULL, totalLength, 2139 ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT, fragmentCount); 2140 if (startCommand == NULL) { 2141 return -1; 2142 } 2143 } 2144 2145 if ((startCommand->fragments[fragmentNumber / 32] & (1 << (fragmentNumber % 32))) == 0) { 2146 --startCommand->fragmentsRemaining; 2147 startCommand->fragments[fragmentNumber / 32] |= (1 << (fragmentNumber % 32)); 2148 2149 if (fragmentOffset + fragmentLength > startCommand->packet->dataLength) { 2150 fragmentLength = startCommand->packet->dataLength - fragmentOffset; 2151 } 2152 2153 memcpy(startCommand->packet->data + fragmentOffset, (enet_uint8 *) command + sizeof(ENetProtocolSendFragment), fragmentLength); 2154 2155 if (startCommand->fragmentsRemaining <= 0) { 2156 enet_peer_dispatch_incoming_unreliable_commands(peer, channel); 2157 } 2158 } 2159 2160 return 0; 2161 } /* enet_protocol_handle_send_unreliable_fragment */ 2162 enet_protocol_handle_ping(ENetHost * host,ENetPeer * peer,const ENetProtocol * command)2163 static int enet_protocol_handle_ping(ENetHost *host, ENetPeer *peer, const ENetProtocol *command) { 2164 UNREFERENCED_PARAMETER(host); 2165 UNREFERENCED_PARAMETER(command); 2166 if (peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER) { 2167 return -1; 2168 } 2169 2170 return 0; 2171 } 2172 enet_protocol_handle_bandwidth_limit(ENetHost * host,ENetPeer * peer,const ENetProtocol * command)2173 static int enet_protocol_handle_bandwidth_limit(ENetHost *host, ENetPeer *peer, const ENetProtocol *command) { 2174 if (peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER) { 2175 return -1; 2176 } 2177 2178 if (peer->incomingBandwidth != 0) { 2179 --host->bandwidthLimitedPeers; 2180 } 2181 2182 peer->incomingBandwidth = ENET_NET_TO_HOST_32(command->bandwidthLimit.incomingBandwidth); 2183 peer->outgoingBandwidth = ENET_NET_TO_HOST_32(command->bandwidthLimit.outgoingBandwidth); 2184 2185 if (peer->incomingBandwidth != 0) { 2186 ++host->bandwidthLimitedPeers; 2187 } 2188 2189 if (peer->incomingBandwidth == 0 && host->outgoingBandwidth == 0) { 2190 peer->windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; 2191 } else if (peer->incomingBandwidth == 0 || host->outgoingBandwidth == 0) { 2192 peer->windowSize = (ENET_MAX(peer->incomingBandwidth, host->outgoingBandwidth) 2193 / ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; 2194 } else { 2195 peer->windowSize = (ENET_MIN(peer->incomingBandwidth, host->outgoingBandwidth) 2196 / ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; 2197 } 2198 2199 if (peer->windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) { 2200 peer->windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; 2201 } else if (peer->windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) { 2202 peer->windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; 2203 } 2204 2205 return 0; 2206 } /* enet_protocol_handle_bandwidth_limit */ 2207 enet_protocol_handle_throttle_configure(ENetHost * host,ENetPeer * peer,ENetProtocol * command)2208 static int enet_protocol_handle_throttle_configure(ENetHost *host, ENetPeer *peer, ENetProtocol *command) { 2209 UNREFERENCED_PARAMETER(host); 2210 UNREFERENCED_PARAMETER(command); 2211 if (peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER) { 2212 return -1; 2213 } 2214 2215 peer->packetThrottleInterval = ENET_NET_TO_HOST_32(command->throttleConfigure.packetThrottleInterval); 2216 peer->packetThrottleAcceleration = ENET_NET_TO_HOST_32(command->throttleConfigure.packetThrottleAcceleration); 2217 peer->packetThrottleDeceleration = ENET_NET_TO_HOST_32(command->throttleConfigure.packetThrottleDeceleration); 2218 2219 return 0; 2220 } 2221 enet_protocol_handle_disconnect(ENetHost * host,ENetPeer * peer,const ENetProtocol * command)2222 static int enet_protocol_handle_disconnect(ENetHost *host, ENetPeer *peer, const ENetProtocol *command) { 2223 if (peer->state == ENET_PEER_STATE_DISCONNECTED || peer->state == ENET_PEER_STATE_ZOMBIE || 2224 peer->state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT 2225 ) { 2226 return 0; 2227 } 2228 2229 enet_peer_reset_queues(peer); 2230 2231 if (peer->state == ENET_PEER_STATE_CONNECTION_SUCCEEDED || peer->state == ENET_PEER_STATE_DISCONNECTING || peer->state == ENET_PEER_STATE_CONNECTING) { 2232 enet_protocol_dispatch_state(host, peer, ENET_PEER_STATE_ZOMBIE); 2233 } 2234 else if (peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER) { 2235 if (peer->state == ENET_PEER_STATE_CONNECTION_PENDING) { host->recalculateBandwidthLimits = 1; } 2236 enet_peer_reset(peer); 2237 } 2238 else if (command->header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) { 2239 enet_protocol_change_state(host, peer, ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT); 2240 } 2241 else { 2242 enet_protocol_dispatch_state(host, peer, ENET_PEER_STATE_ZOMBIE); 2243 } 2244 2245 if (peer->state != ENET_PEER_STATE_DISCONNECTED) { 2246 peer->eventData = ENET_NET_TO_HOST_32(command->disconnect.data); 2247 } 2248 2249 return 0; 2250 } 2251 enet_protocol_handle_acknowledge(ENetHost * host,ENetEvent * event,ENetPeer * peer,const ENetProtocol * command)2252 static int enet_protocol_handle_acknowledge(ENetHost *host, ENetEvent *event, ENetPeer *peer, const ENetProtocol *command) { 2253 enet_uint32 roundTripTime, receivedSentTime, receivedReliableSequenceNumber; 2254 ENetProtocolCommand commandNumber; 2255 2256 if (peer->state == ENET_PEER_STATE_DISCONNECTED || peer->state == ENET_PEER_STATE_ZOMBIE) { 2257 return 0; 2258 } 2259 2260 receivedSentTime = ENET_NET_TO_HOST_16(command->acknowledge.receivedSentTime); 2261 receivedSentTime |= host->serviceTime & 0xFFFF0000; 2262 if ((receivedSentTime & 0x8000) > (host->serviceTime & 0x8000)) { 2263 receivedSentTime -= 0x10000; 2264 } 2265 2266 if (ENET_TIME_LESS(host->serviceTime, receivedSentTime)) { 2267 return 0; 2268 } 2269 2270 peer->lastReceiveTime = host->serviceTime; 2271 peer->earliestTimeout = 0; 2272 roundTripTime = ENET_TIME_DIFFERENCE(host->serviceTime, receivedSentTime); 2273 2274 enet_peer_throttle(peer, roundTripTime); 2275 peer->roundTripTimeVariance -= peer->roundTripTimeVariance / 4; 2276 2277 if (roundTripTime >= peer->roundTripTime) { 2278 peer->roundTripTime += (roundTripTime - peer->roundTripTime) / 8; 2279 peer->roundTripTimeVariance += (roundTripTime - peer->roundTripTime) / 4; 2280 } else { 2281 peer->roundTripTime -= (peer->roundTripTime - roundTripTime) / 8; 2282 peer->roundTripTimeVariance += (peer->roundTripTime - roundTripTime) / 4; 2283 } 2284 2285 if (peer->roundTripTime < peer->lowestRoundTripTime) { 2286 peer->lowestRoundTripTime = peer->roundTripTime; 2287 } 2288 2289 if (peer->roundTripTimeVariance > peer->highestRoundTripTimeVariance) { 2290 peer->highestRoundTripTimeVariance = peer->roundTripTimeVariance; 2291 } 2292 2293 if (peer->packetThrottleEpoch == 0 || 2294 ENET_TIME_DIFFERENCE(host->serviceTime, peer->packetThrottleEpoch) >= peer->packetThrottleInterval 2295 ) { 2296 peer->lastRoundTripTime = peer->lowestRoundTripTime; 2297 peer->lastRoundTripTimeVariance = peer->highestRoundTripTimeVariance; 2298 peer->lowestRoundTripTime = peer->roundTripTime; 2299 peer->highestRoundTripTimeVariance = peer->roundTripTimeVariance; 2300 peer->packetThrottleEpoch = host->serviceTime; 2301 } 2302 2303 receivedReliableSequenceNumber = ENET_NET_TO_HOST_16(command->acknowledge.receivedReliableSequenceNumber); 2304 commandNumber = enet_protocol_remove_sent_reliable_command(peer, receivedReliableSequenceNumber, command->header.channelID); 2305 2306 switch (peer->state) { 2307 case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT: 2308 if (commandNumber != ENET_PROTOCOL_COMMAND_VERIFY_CONNECT) { 2309 return -1; 2310 } 2311 2312 enet_protocol_notify_connect(host, peer, event); 2313 break; 2314 2315 case ENET_PEER_STATE_DISCONNECTING: 2316 if (commandNumber != ENET_PROTOCOL_COMMAND_DISCONNECT) { 2317 return -1; 2318 } 2319 2320 enet_protocol_notify_disconnect(host, peer, event); 2321 break; 2322 2323 case ENET_PEER_STATE_DISCONNECT_LATER: 2324 if (enet_list_empty(&peer->outgoingReliableCommands) && 2325 enet_list_empty(&peer->outgoingUnreliableCommands) && 2326 enet_list_empty(&peer->sentReliableCommands)) 2327 { 2328 enet_peer_disconnect(peer, peer->eventData); 2329 } 2330 break; 2331 2332 default: 2333 break; 2334 } 2335 2336 return 0; 2337 } /* enet_protocol_handle_acknowledge */ 2338 enet_protocol_handle_verify_connect(ENetHost * host,ENetEvent * event,ENetPeer * peer,const ENetProtocol * command)2339 static int enet_protocol_handle_verify_connect(ENetHost *host, ENetEvent *event, ENetPeer *peer, const ENetProtocol *command) { 2340 enet_uint32 mtu, windowSize; 2341 size_t channelCount; 2342 2343 if (peer->state != ENET_PEER_STATE_CONNECTING) { 2344 return 0; 2345 } 2346 2347 channelCount = ENET_NET_TO_HOST_32(command->verifyConnect.channelCount); 2348 2349 if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT || channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT || 2350 ENET_NET_TO_HOST_32(command->verifyConnect.packetThrottleInterval) != peer->packetThrottleInterval || 2351 ENET_NET_TO_HOST_32(command->verifyConnect.packetThrottleAcceleration) != peer->packetThrottleAcceleration || 2352 ENET_NET_TO_HOST_32(command->verifyConnect.packetThrottleDeceleration) != peer->packetThrottleDeceleration || 2353 command->verifyConnect.connectID != peer->connectID 2354 ) { 2355 peer->eventData = 0; 2356 enet_protocol_dispatch_state(host, peer, ENET_PEER_STATE_ZOMBIE); 2357 return -1; 2358 } 2359 2360 enet_protocol_remove_sent_reliable_command(peer, 1, 0xFF); 2361 2362 if (channelCount < peer->channelCount) { 2363 peer->channelCount = channelCount; 2364 } 2365 2366 peer->outgoingPeerID = ENET_NET_TO_HOST_16(command->verifyConnect.outgoingPeerID); 2367 peer->incomingSessionID = command->verifyConnect.incomingSessionID; 2368 peer->outgoingSessionID = command->verifyConnect.outgoingSessionID; 2369 2370 mtu = ENET_NET_TO_HOST_32(command->verifyConnect.mtu); 2371 2372 if (mtu < ENET_PROTOCOL_MINIMUM_MTU) { 2373 mtu = ENET_PROTOCOL_MINIMUM_MTU; 2374 } else if (mtu > ENET_PROTOCOL_MAXIMUM_MTU) { 2375 mtu = ENET_PROTOCOL_MAXIMUM_MTU; 2376 } 2377 2378 if (mtu < peer->mtu) { 2379 peer->mtu = mtu; 2380 } 2381 2382 windowSize = ENET_NET_TO_HOST_32(command->verifyConnect.windowSize); 2383 if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) { 2384 windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; 2385 } 2386 2387 if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) { 2388 windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; 2389 } 2390 2391 if (windowSize < peer->windowSize) { 2392 peer->windowSize = windowSize; 2393 } 2394 2395 peer->incomingBandwidth = ENET_NET_TO_HOST_32(command->verifyConnect.incomingBandwidth); 2396 peer->outgoingBandwidth = ENET_NET_TO_HOST_32(command->verifyConnect.outgoingBandwidth); 2397 2398 enet_protocol_notify_connect(host, peer, event); 2399 return 0; 2400 } /* enet_protocol_handle_verify_connect */ 2401 enet_protocol_handle_incoming_commands(ENetHost * host,ENetEvent * event)2402 static int enet_protocol_handle_incoming_commands(ENetHost *host, ENetEvent *event) { 2403 ENetProtocolHeader *header; 2404 ENetProtocol *command; 2405 ENetPeer *peer; 2406 enet_uint8 *currentData; 2407 size_t headerSize; 2408 enet_uint16 peerID, flags; 2409 enet_uint8 sessionID; 2410 2411 if (host->receivedDataLength < (size_t) &((ENetProtocolHeader *) 0)->sentTime) { 2412 return 0; 2413 } 2414 2415 header = (ENetProtocolHeader *) host->receivedData; 2416 2417 peerID = ENET_NET_TO_HOST_16(header->peerID); 2418 sessionID = (peerID & ENET_PROTOCOL_HEADER_SESSION_MASK) >> ENET_PROTOCOL_HEADER_SESSION_SHIFT; 2419 flags = peerID & ENET_PROTOCOL_HEADER_FLAG_MASK; 2420 peerID &= ~(ENET_PROTOCOL_HEADER_FLAG_MASK | ENET_PROTOCOL_HEADER_SESSION_MASK); 2421 2422 headerSize = (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME ? sizeof(ENetProtocolHeader) : (size_t) &((ENetProtocolHeader *) 0)->sentTime); 2423 if (host->checksum != NULL) { 2424 headerSize += sizeof(enet_uint32); 2425 } 2426 2427 if (peerID == ENET_PROTOCOL_MAXIMUM_PEER_ID) { 2428 peer = NULL; 2429 } else if (peerID >= host->peerCount) { 2430 return 0; 2431 } else { 2432 peer = &host->peers[peerID]; 2433 2434 if (peer->state == ENET_PEER_STATE_DISCONNECTED || 2435 peer->state == ENET_PEER_STATE_ZOMBIE || 2436 ((!in6_equal(host->receivedAddress.host , peer->address.host) || 2437 host->receivedAddress.port != peer->address.port) && 2438 1 /* no broadcast in ipv6 !in6_equal(peer->address.host , ENET_HOST_BROADCAST)*/) || 2439 (peer->outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID && 2440 sessionID != peer->incomingSessionID) 2441 ) { 2442 return 0; 2443 } 2444 } 2445 2446 if (flags & ENET_PROTOCOL_HEADER_FLAG_COMPRESSED) { 2447 size_t originalSize; 2448 if (host->compressor.context == NULL || host->compressor.decompress == NULL) { 2449 return 0; 2450 } 2451 2452 originalSize = host->compressor.decompress(host->compressor.context, 2453 host->receivedData + headerSize, 2454 host->receivedDataLength - headerSize, 2455 host->packetData[1] + headerSize, 2456 sizeof(host->packetData[1]) - headerSize 2457 ); 2458 2459 if (originalSize <= 0 || originalSize > sizeof(host->packetData[1]) - headerSize) { 2460 return 0; 2461 } 2462 2463 memcpy(host->packetData[1], header, headerSize); 2464 host->receivedData = host->packetData[1]; 2465 host->receivedDataLength = headerSize + originalSize; 2466 } 2467 2468 if (host->checksum != NULL) { 2469 enet_uint32 *checksum = (enet_uint32 *) &host->receivedData[headerSize - sizeof(enet_uint32)]; 2470 enet_uint32 desiredChecksum = *checksum; 2471 ENetBuffer buffer; 2472 2473 *checksum = peer != NULL ? peer->connectID : 0; 2474 2475 buffer.data = host->receivedData; 2476 buffer.dataLength = host->receivedDataLength; 2477 2478 if (host->checksum(&buffer, 1) != desiredChecksum) { 2479 return 0; 2480 } 2481 } 2482 2483 if (peer != NULL) { 2484 peer->address.host = host->receivedAddress.host; 2485 peer->address.port = host->receivedAddress.port; 2486 peer->incomingDataTotal += host->receivedDataLength; 2487 peer->totalDataReceived += host->receivedDataLength; 2488 } 2489 2490 currentData = host->receivedData + headerSize; 2491 2492 while (currentData < &host->receivedData[host->receivedDataLength]) { 2493 enet_uint8 commandNumber; 2494 size_t commandSize; 2495 2496 command = (ENetProtocol *) currentData; 2497 2498 if (currentData + sizeof(ENetProtocolCommandHeader) > &host->receivedData[host->receivedDataLength]) { 2499 break; 2500 } 2501 2502 commandNumber = command->header.command & ENET_PROTOCOL_COMMAND_MASK; 2503 if (commandNumber >= ENET_PROTOCOL_COMMAND_COUNT) { 2504 break; 2505 } 2506 2507 commandSize = commandSizes[commandNumber]; 2508 if (commandSize == 0 || currentData + commandSize > &host->receivedData[host->receivedDataLength]) { 2509 break; 2510 } 2511 2512 currentData += commandSize; 2513 2514 if (peer == NULL && (commandNumber != ENET_PROTOCOL_COMMAND_CONNECT || currentData < &host->receivedData[host->receivedDataLength])) { 2515 break; 2516 } 2517 2518 command->header.reliableSequenceNumber = ENET_NET_TO_HOST_16(command->header.reliableSequenceNumber); 2519 2520 switch (commandNumber) { 2521 case ENET_PROTOCOL_COMMAND_ACKNOWLEDGE: 2522 if (enet_protocol_handle_acknowledge(host, event, peer, command)) { 2523 goto commandError; 2524 } 2525 break; 2526 2527 case ENET_PROTOCOL_COMMAND_CONNECT: 2528 if (peer != NULL) { 2529 goto commandError; 2530 } 2531 peer = enet_protocol_handle_connect(host, header, command); 2532 if (peer == NULL) { 2533 goto commandError; 2534 } 2535 break; 2536 2537 case ENET_PROTOCOL_COMMAND_VERIFY_CONNECT: 2538 if (enet_protocol_handle_verify_connect(host, event, peer, command)) { 2539 goto commandError; 2540 } 2541 break; 2542 2543 case ENET_PROTOCOL_COMMAND_DISCONNECT: 2544 if (enet_protocol_handle_disconnect(host, peer, command)) { 2545 goto commandError; 2546 } 2547 break; 2548 2549 case ENET_PROTOCOL_COMMAND_PING: 2550 if (enet_protocol_handle_ping(host, peer, command)) { 2551 goto commandError; 2552 } 2553 break; 2554 2555 case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: 2556 if (enet_protocol_handle_send_reliable(host, peer, command, ¤tData)) { 2557 goto commandError; 2558 } 2559 break; 2560 2561 case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE: 2562 if (enet_protocol_handle_send_unreliable(host, peer, command, ¤tData)) { 2563 goto commandError; 2564 } 2565 break; 2566 2567 case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED: 2568 if (enet_protocol_handle_send_unsequenced(host, peer, command, ¤tData)) { 2569 goto commandError; 2570 } 2571 break; 2572 2573 case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: 2574 if (enet_protocol_handle_send_fragment(host, peer, command, ¤tData)) { 2575 goto commandError; 2576 } 2577 break; 2578 2579 case ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT: 2580 if (enet_protocol_handle_bandwidth_limit(host, peer, command)) { 2581 goto commandError; 2582 } 2583 break; 2584 2585 case ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE: 2586 if (enet_protocol_handle_throttle_configure(host, peer, command)) { 2587 goto commandError; 2588 } 2589 break; 2590 2591 case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT: 2592 if (enet_protocol_handle_send_unreliable_fragment(host, peer, command, ¤tData)) { 2593 goto commandError; 2594 } 2595 break; 2596 2597 default: 2598 goto commandError; 2599 } 2600 2601 if (peer != NULL && (command->header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) != 0) { 2602 enet_uint16 sentTime; 2603 2604 if (!(flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME)) { 2605 break; 2606 } 2607 2608 sentTime = ENET_NET_TO_HOST_16(header->sentTime); 2609 2610 switch (peer->state) { 2611 case ENET_PEER_STATE_DISCONNECTING: 2612 case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT: 2613 case ENET_PEER_STATE_DISCONNECTED: 2614 case ENET_PEER_STATE_ZOMBIE: 2615 break; 2616 2617 case ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT: 2618 if ((command->header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT) { 2619 enet_peer_queue_acknowledgement(peer, command, sentTime); 2620 } 2621 break; 2622 2623 default: 2624 enet_peer_queue_acknowledgement(peer, command, sentTime); 2625 break; 2626 } 2627 } 2628 } 2629 2630 commandError: 2631 if (event != NULL && event->type != ENET_EVENT_TYPE_NONE) { 2632 return 1; 2633 } 2634 2635 return 0; 2636 } /* enet_protocol_handle_incoming_commands */ 2637 enet_protocol_receive_incoming_commands(ENetHost * host,ENetEvent * event)2638 static int enet_protocol_receive_incoming_commands(ENetHost *host, ENetEvent *event) { 2639 int packets; 2640 2641 for (packets = 0; packets < 256; ++packets) { 2642 int receivedLength; 2643 ENetBuffer buffer; 2644 2645 buffer.data = host->packetData[0]; 2646 // buffer.dataLength = sizeof (host->packetData[0]); 2647 buffer.dataLength = host->mtu; 2648 2649 receivedLength = enet_socket_receive(host->socket, &host->receivedAddress, &buffer, 1); 2650 2651 if (receivedLength == -2) 2652 continue; 2653 2654 if (receivedLength < 0) { 2655 return -1; 2656 } 2657 2658 if (receivedLength == 0) { 2659 return 0; 2660 } 2661 2662 host->receivedData = host->packetData[0]; 2663 host->receivedDataLength = receivedLength; 2664 2665 host->totalReceivedData += receivedLength; 2666 host->totalReceivedPackets++; 2667 2668 if (host->intercept != NULL) { 2669 switch (host->intercept(host, (void *)event)) { 2670 case 1: 2671 if (event != NULL && event->type != ENET_EVENT_TYPE_NONE) { 2672 return 1; 2673 } 2674 2675 continue; 2676 2677 case -1: 2678 return -1; 2679 2680 default: 2681 break; 2682 } 2683 } 2684 2685 switch (enet_protocol_handle_incoming_commands(host, event)) { 2686 case 1: 2687 return 1; 2688 2689 case -1: 2690 return -1; 2691 2692 default: 2693 break; 2694 } 2695 } 2696 2697 return -1; 2698 } /* enet_protocol_receive_incoming_commands */ 2699 enet_protocol_send_acknowledgements(ENetHost * host,ENetPeer * peer)2700 static void enet_protocol_send_acknowledgements(ENetHost *host, ENetPeer *peer) { 2701 ENetProtocol *command = &host->commands[host->commandCount]; 2702 ENetBuffer *buffer = &host->buffers[host->bufferCount]; 2703 ENetAcknowledgement *acknowledgement; 2704 ENetListIterator currentAcknowledgement; 2705 enet_uint16 reliableSequenceNumber; 2706 2707 currentAcknowledgement = enet_list_begin(&peer->acknowledgements); 2708 2709 while (currentAcknowledgement != enet_list_end(&peer->acknowledgements)) { 2710 if (command >= &host->commands[sizeof(host->commands) / sizeof(ENetProtocol)] || 2711 buffer >= &host->buffers[sizeof(host->buffers) / sizeof(ENetBuffer)] || 2712 peer->mtu - host->packetSize < sizeof(ENetProtocolAcknowledge) 2713 ) { 2714 host->continueSending = 1; 2715 break; 2716 } 2717 2718 acknowledgement = (ENetAcknowledgement *) currentAcknowledgement; 2719 currentAcknowledgement = enet_list_next(currentAcknowledgement); 2720 2721 buffer->data = command; 2722 buffer->dataLength = sizeof(ENetProtocolAcknowledge); 2723 host->packetSize += buffer->dataLength; 2724 2725 reliableSequenceNumber = ENET_HOST_TO_NET_16(acknowledgement->command.header.reliableSequenceNumber); 2726 2727 command->header.command = ENET_PROTOCOL_COMMAND_ACKNOWLEDGE; 2728 command->header.channelID = acknowledgement->command.header.channelID; 2729 command->header.reliableSequenceNumber = reliableSequenceNumber; 2730 command->acknowledge.receivedReliableSequenceNumber = reliableSequenceNumber; 2731 command->acknowledge.receivedSentTime = ENET_HOST_TO_NET_16(acknowledgement->sentTime); 2732 2733 if ((acknowledgement->command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT) { 2734 enet_protocol_dispatch_state(host, peer, ENET_PEER_STATE_ZOMBIE); 2735 } 2736 2737 enet_list_remove(&acknowledgement->acknowledgementList); 2738 enet_free(acknowledgement); 2739 2740 ++command; 2741 ++buffer; 2742 } 2743 2744 host->commandCount = command - host->commands; 2745 host->bufferCount = buffer - host->buffers; 2746 } /* enet_protocol_send_acknowledgements */ 2747 enet_protocol_send_unreliable_outgoing_commands(ENetHost * host,ENetPeer * peer)2748 static void enet_protocol_send_unreliable_outgoing_commands(ENetHost *host, ENetPeer *peer) { 2749 ENetProtocol *command = &host->commands[host->commandCount]; 2750 ENetBuffer *buffer = &host->buffers[host->bufferCount]; 2751 ENetOutgoingCommand *outgoingCommand; 2752 ENetListIterator currentCommand; 2753 2754 currentCommand = enet_list_begin(&peer->outgoingUnreliableCommands); 2755 while (currentCommand != enet_list_end(&peer->outgoingUnreliableCommands)) { 2756 size_t commandSize; 2757 2758 outgoingCommand = (ENetOutgoingCommand *) currentCommand; 2759 commandSize = commandSizes[outgoingCommand->command.header.command & ENET_PROTOCOL_COMMAND_MASK]; 2760 2761 if (command >= &host->commands[sizeof(host->commands) / sizeof(ENetProtocol)] || 2762 buffer + 1 >= &host->buffers[sizeof(host->buffers) / sizeof(ENetBuffer)] || 2763 peer->mtu - host->packetSize < commandSize || 2764 (outgoingCommand->packet != NULL && 2765 peer->mtu - host->packetSize < commandSize + outgoingCommand->fragmentLength) 2766 ) { 2767 host->continueSending = 1; 2768 break; 2769 } 2770 2771 currentCommand = enet_list_next(currentCommand); 2772 2773 if (outgoingCommand->packet != NULL && outgoingCommand->fragmentOffset == 0) { 2774 peer->packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER; 2775 peer->packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE; 2776 2777 if (peer->packetThrottleCounter > peer->packetThrottle) { 2778 enet_uint16 reliableSequenceNumber = outgoingCommand->reliableSequenceNumber; 2779 enet_uint16 unreliableSequenceNumber = outgoingCommand->unreliableSequenceNumber; 2780 for (;;) { 2781 --outgoingCommand->packet->referenceCount; 2782 2783 if (outgoingCommand->packet->referenceCount == 0) { 2784 enet_packet_destroy(outgoingCommand->packet); 2785 } 2786 2787 enet_list_remove(&outgoingCommand->outgoingCommandList); 2788 enet_free(outgoingCommand); 2789 2790 if (currentCommand == enet_list_end(&peer->outgoingUnreliableCommands)) { 2791 break; 2792 } 2793 2794 outgoingCommand = (ENetOutgoingCommand *) currentCommand; 2795 if (outgoingCommand->reliableSequenceNumber != reliableSequenceNumber || outgoingCommand->unreliableSequenceNumber != unreliableSequenceNumber) { 2796 break; 2797 } 2798 2799 currentCommand = enet_list_next(currentCommand); 2800 } 2801 2802 continue; 2803 } 2804 } 2805 2806 buffer->data = command; 2807 buffer->dataLength = commandSize; 2808 host->packetSize += buffer->dataLength; 2809 *command = outgoingCommand->command; 2810 enet_list_remove(&outgoingCommand->outgoingCommandList); 2811 2812 if (outgoingCommand->packet != NULL) { 2813 ++buffer; 2814 2815 buffer->data = outgoingCommand->packet->data + outgoingCommand->fragmentOffset; 2816 buffer->dataLength = outgoingCommand->fragmentLength; 2817 2818 host->packetSize += buffer->dataLength; 2819 2820 enet_list_insert(enet_list_end(&peer->sentUnreliableCommands), outgoingCommand); 2821 } else { 2822 enet_free(outgoingCommand); 2823 } 2824 2825 ++command; 2826 ++buffer; 2827 } 2828 2829 host->commandCount = command - host->commands; 2830 host->bufferCount = buffer - host->buffers; 2831 2832 if (peer->state == ENET_PEER_STATE_DISCONNECT_LATER && 2833 enet_list_empty(&peer->outgoingReliableCommands) && 2834 enet_list_empty(&peer->outgoingUnreliableCommands) && 2835 enet_list_empty(&peer->sentReliableCommands)) 2836 { 2837 enet_peer_disconnect(peer, peer->eventData); 2838 } 2839 } /* enet_protocol_send_unreliable_outgoing_commands */ 2840 enet_protocol_check_timeouts(ENetHost * host,ENetPeer * peer,ENetEvent * event)2841 static int enet_protocol_check_timeouts(ENetHost *host, ENetPeer *peer, ENetEvent *event) { 2842 ENetOutgoingCommand *outgoingCommand; 2843 ENetListIterator currentCommand, insertPosition; 2844 2845 currentCommand = enet_list_begin(&peer->sentReliableCommands); 2846 insertPosition = enet_list_begin(&peer->outgoingReliableCommands); 2847 2848 while (currentCommand != enet_list_end(&peer->sentReliableCommands)) { 2849 outgoingCommand = (ENetOutgoingCommand *) currentCommand; 2850 2851 currentCommand = enet_list_next(currentCommand); 2852 2853 if (ENET_TIME_DIFFERENCE(host->serviceTime, outgoingCommand->sentTime) < outgoingCommand->roundTripTimeout) { 2854 continue; 2855 } 2856 2857 if (peer->earliestTimeout == 0 || ENET_TIME_LESS(outgoingCommand->sentTime, peer->earliestTimeout)) { 2858 peer->earliestTimeout = outgoingCommand->sentTime; 2859 } 2860 2861 if (peer->earliestTimeout != 0 && 2862 (ENET_TIME_DIFFERENCE(host->serviceTime, peer->earliestTimeout) >= peer->timeoutMaximum || 2863 (outgoingCommand->roundTripTimeout >= outgoingCommand->roundTripTimeoutLimit && 2864 ENET_TIME_DIFFERENCE(host->serviceTime, peer->earliestTimeout) >= peer->timeoutMinimum)) 2865 ) { 2866 enet_protocol_notify_disconnect_timeout(host, peer, event); 2867 return 1; 2868 } 2869 2870 if (outgoingCommand->packet != NULL) { 2871 peer->reliableDataInTransit -= outgoingCommand->fragmentLength; 2872 } 2873 2874 ++peer->packetsLost; 2875 ++peer->totalPacketsLost; 2876 2877 /* Replaced exponential backoff time with something more linear */ 2878 /* Source: http://lists.cubik.org/pipermail/enet-discuss/2014-May/002308.html */ 2879 outgoingCommand->roundTripTimeout = peer->roundTripTime + 4 * peer->roundTripTimeVariance; 2880 outgoingCommand->roundTripTimeoutLimit = peer->timeoutLimit * outgoingCommand->roundTripTimeout; 2881 2882 enet_list_insert(insertPosition, enet_list_remove(&outgoingCommand->outgoingCommandList)); 2883 2884 if (currentCommand == enet_list_begin(&peer->sentReliableCommands) && !enet_list_empty(&peer->sentReliableCommands)) { 2885 outgoingCommand = (ENetOutgoingCommand *) currentCommand; 2886 peer->nextTimeout = outgoingCommand->sentTime + outgoingCommand->roundTripTimeout; 2887 } 2888 } 2889 2890 return 0; 2891 } /* enet_protocol_check_timeouts */ 2892 enet_protocol_send_reliable_outgoing_commands(ENetHost * host,ENetPeer * peer)2893 static int enet_protocol_send_reliable_outgoing_commands(ENetHost *host, ENetPeer *peer) { 2894 ENetProtocol *command = &host->commands[host->commandCount]; 2895 ENetBuffer *buffer = &host->buffers[host->bufferCount]; 2896 ENetOutgoingCommand *outgoingCommand; 2897 ENetListIterator currentCommand; 2898 ENetChannel *channel; 2899 enet_uint16 reliableWindow; 2900 size_t commandSize; 2901 int windowExceeded = 0, windowWrap = 0, canPing = 1; 2902 2903 currentCommand = enet_list_begin(&peer->outgoingReliableCommands); 2904 2905 while (currentCommand != enet_list_end(&peer->outgoingReliableCommands)) { 2906 outgoingCommand = (ENetOutgoingCommand *) currentCommand; 2907 2908 channel = outgoingCommand->command.header.channelID < peer->channelCount ? &peer->channels[outgoingCommand->command.header.channelID] : NULL; 2909 reliableWindow = outgoingCommand->reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; 2910 if (channel != NULL) { 2911 if (!windowWrap && 2912 outgoingCommand->sendAttempts < 1 && 2913 !(outgoingCommand->reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) && 2914 (channel->reliableWindows[(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) 2915 % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE || 2916 channel->usedReliableWindows & ((((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) << reliableWindow) 2917 | (((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) >> (ENET_PEER_RELIABLE_WINDOWS - reliableWindow)))) 2918 ) { 2919 windowWrap = 1; 2920 } 2921 2922 if (windowWrap) { 2923 currentCommand = enet_list_next(currentCommand); 2924 continue; 2925 } 2926 } 2927 2928 if (outgoingCommand->packet != NULL) { 2929 if (!windowExceeded) { 2930 enet_uint32 windowSize = (peer->packetThrottle * peer->windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE; 2931 2932 if (peer->reliableDataInTransit + outgoingCommand->fragmentLength > ENET_MAX(windowSize, peer->mtu)) { 2933 windowExceeded = 1; 2934 } 2935 } 2936 if (windowExceeded) { 2937 currentCommand = enet_list_next(currentCommand); 2938 2939 continue; 2940 } 2941 } 2942 2943 canPing = 0; 2944 2945 commandSize = commandSizes[outgoingCommand->command.header.command & ENET_PROTOCOL_COMMAND_MASK]; 2946 if (command >= &host->commands[sizeof(host->commands) / sizeof(ENetProtocol)] || 2947 buffer + 1 >= &host->buffers[sizeof(host->buffers) / sizeof(ENetBuffer)] || 2948 peer->mtu - host->packetSize < commandSize || 2949 (outgoingCommand->packet != NULL && 2950 (enet_uint16) (peer->mtu - host->packetSize) < (enet_uint16) (commandSize + outgoingCommand->fragmentLength)) 2951 ) { 2952 host->continueSending = 1; 2953 break; 2954 } 2955 2956 currentCommand = enet_list_next(currentCommand); 2957 2958 if (channel != NULL && outgoingCommand->sendAttempts < 1) { 2959 channel->usedReliableWindows |= 1 << reliableWindow; 2960 ++channel->reliableWindows[reliableWindow]; 2961 } 2962 2963 ++outgoingCommand->sendAttempts; 2964 2965 if (outgoingCommand->roundTripTimeout == 0) { 2966 outgoingCommand->roundTripTimeout = peer->roundTripTime + 4 * peer->roundTripTimeVariance; 2967 outgoingCommand->roundTripTimeoutLimit = peer->timeoutLimit * outgoingCommand->roundTripTimeout; 2968 } 2969 2970 if (enet_list_empty(&peer->sentReliableCommands)) { 2971 peer->nextTimeout = host->serviceTime + outgoingCommand->roundTripTimeout; 2972 } 2973 2974 enet_list_insert(enet_list_end(&peer->sentReliableCommands), enet_list_remove(&outgoingCommand->outgoingCommandList)); 2975 2976 outgoingCommand->sentTime = host->serviceTime; 2977 2978 buffer->data = command; 2979 buffer->dataLength = commandSize; 2980 2981 host->packetSize += buffer->dataLength; 2982 host->headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME; 2983 2984 *command = outgoingCommand->command; 2985 2986 if (outgoingCommand->packet != NULL) { 2987 ++buffer; 2988 buffer->data = outgoingCommand->packet->data + outgoingCommand->fragmentOffset; 2989 buffer->dataLength = outgoingCommand->fragmentLength; 2990 host->packetSize += outgoingCommand->fragmentLength; 2991 peer->reliableDataInTransit += outgoingCommand->fragmentLength; 2992 } 2993 2994 ++peer->packetsSent; 2995 ++peer->totalPacketsSent; 2996 2997 ++command; 2998 ++buffer; 2999 } 3000 3001 host->commandCount = command - host->commands; 3002 host->bufferCount = buffer - host->buffers; 3003 3004 return canPing; 3005 } /* enet_protocol_send_reliable_outgoing_commands */ 3006 enet_protocol_send_outgoing_commands(ENetHost * host,ENetEvent * event,int checkForTimeouts)3007 static int enet_protocol_send_outgoing_commands(ENetHost *host, ENetEvent *event, int checkForTimeouts) { 3008 enet_uint8 headerData[sizeof(ENetProtocolHeader) + sizeof(enet_uint32)]; 3009 ENetProtocolHeader *header = (ENetProtocolHeader *) headerData; 3010 ENetPeer *currentPeer; 3011 int sentLength; 3012 size_t shouldCompress = 0; 3013 host->continueSending = 1; 3014 3015 while (host->continueSending) 3016 for (host->continueSending = 0, currentPeer = host->peers; currentPeer < &host->peers[host->peerCount]; ++currentPeer) { 3017 if (currentPeer->state == ENET_PEER_STATE_DISCONNECTED || currentPeer->state == ENET_PEER_STATE_ZOMBIE) { 3018 continue; 3019 } 3020 3021 host->headerFlags = 0; 3022 host->commandCount = 0; 3023 host->bufferCount = 1; 3024 host->packetSize = sizeof(ENetProtocolHeader); 3025 3026 if (!enet_list_empty(¤tPeer->acknowledgements)) { 3027 enet_protocol_send_acknowledgements(host, currentPeer); 3028 } 3029 3030 if (checkForTimeouts != 0 && 3031 !enet_list_empty(¤tPeer->sentReliableCommands) && 3032 ENET_TIME_GREATER_EQUAL(host->serviceTime, currentPeer->nextTimeout) && 3033 enet_protocol_check_timeouts(host, currentPeer, event) == 1 3034 ) { 3035 if (event != NULL && event->type != ENET_EVENT_TYPE_NONE) { 3036 return 1; 3037 } else { 3038 continue; 3039 } 3040 } 3041 3042 if ((enet_list_empty(¤tPeer->outgoingReliableCommands) || 3043 enet_protocol_send_reliable_outgoing_commands(host, currentPeer)) && 3044 enet_list_empty(¤tPeer->sentReliableCommands) && 3045 ENET_TIME_DIFFERENCE(host->serviceTime, currentPeer->lastReceiveTime) >= currentPeer->pingInterval && 3046 currentPeer->mtu - host->packetSize >= sizeof(ENetProtocolPing) 3047 ) { 3048 enet_peer_ping(currentPeer); 3049 enet_protocol_send_reliable_outgoing_commands(host, currentPeer); 3050 } 3051 3052 if (!enet_list_empty(¤tPeer->outgoingUnreliableCommands)) { 3053 enet_protocol_send_unreliable_outgoing_commands(host, currentPeer); 3054 } 3055 3056 if (host->commandCount == 0) { 3057 continue; 3058 } 3059 3060 if (currentPeer->packetLossEpoch == 0) { 3061 currentPeer->packetLossEpoch = host->serviceTime; 3062 } else if (ENET_TIME_DIFFERENCE(host->serviceTime, currentPeer->packetLossEpoch) >= ENET_PEER_PACKET_LOSS_INTERVAL && currentPeer->packetsSent > 0) { 3063 enet_uint32 packetLoss = currentPeer->packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer->packetsSent; 3064 3065 #ifdef ENET_DEBUG 3066 printf( 3067 "peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer->incomingPeerID, 3068 currentPeer->packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, 3069 currentPeer->packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer->roundTripTime, currentPeer->roundTripTimeVariance, 3070 currentPeer->packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, 3071 enet_list_size(¤tPeer->outgoingReliableCommands), 3072 enet_list_size(¤tPeer->outgoingUnreliableCommands), 3073 currentPeer->channels != NULL ? enet_list_size( ¤tPeer->channels->incomingReliableCommands) : 0, 3074 currentPeer->channels != NULL ? enet_list_size(¤tPeer->channels->incomingUnreliableCommands) : 0 3075 ); 3076 #endif 3077 3078 currentPeer->packetLossVariance -= currentPeer->packetLossVariance / 4; 3079 3080 if (packetLoss >= currentPeer->packetLoss) { 3081 currentPeer->packetLoss += (packetLoss - currentPeer->packetLoss) / 8; 3082 currentPeer->packetLossVariance += (packetLoss - currentPeer->packetLoss) / 4; 3083 } else { 3084 currentPeer->packetLoss -= (currentPeer->packetLoss - packetLoss) / 8; 3085 currentPeer->packetLossVariance += (currentPeer->packetLoss - packetLoss) / 4; 3086 } 3087 3088 currentPeer->packetLossEpoch = host->serviceTime; 3089 currentPeer->packetsSent = 0; 3090 currentPeer->packetsLost = 0; 3091 } 3092 3093 host->buffers->data = headerData; 3094 if (host->headerFlags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME) { 3095 header->sentTime = ENET_HOST_TO_NET_16(host->serviceTime & 0xFFFF); 3096 host->buffers->dataLength = sizeof(ENetProtocolHeader); 3097 } else { 3098 host->buffers->dataLength = (size_t) &((ENetProtocolHeader *) 0)->sentTime; 3099 } 3100 3101 shouldCompress = 0; 3102 if (host->compressor.context != NULL && host->compressor.compress != NULL) { 3103 size_t originalSize = host->packetSize - sizeof(ENetProtocolHeader), 3104 compressedSize = host->compressor.compress(host->compressor.context, &host->buffers[1], host->bufferCount - 1, originalSize, host->packetData[1], originalSize); 3105 if (compressedSize > 0 && compressedSize < originalSize) { 3106 host->headerFlags |= ENET_PROTOCOL_HEADER_FLAG_COMPRESSED; 3107 shouldCompress = compressedSize; 3108 #ifdef ENET_DEBUG_COMPRESS 3109 printf("peer %u: compressed %u->%u (%u%%)\n", currentPeer->incomingPeerID, originalSize, compressedSize, (compressedSize * 100) / originalSize); 3110 #endif 3111 } 3112 } 3113 3114 if (currentPeer->outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID) { 3115 host->headerFlags |= currentPeer->outgoingSessionID << ENET_PROTOCOL_HEADER_SESSION_SHIFT; 3116 } 3117 header->peerID = ENET_HOST_TO_NET_16(currentPeer->outgoingPeerID | host->headerFlags); 3118 if (host->checksum != NULL) { 3119 enet_uint32 *checksum = (enet_uint32 *) &headerData[host->buffers->dataLength]; 3120 *checksum = currentPeer->outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID ? currentPeer->connectID : 0; 3121 host->buffers->dataLength += sizeof(enet_uint32); 3122 *checksum = host->checksum(host->buffers, host->bufferCount); 3123 } 3124 3125 if (shouldCompress > 0) { 3126 host->buffers[1].data = host->packetData[1]; 3127 host->buffers[1].dataLength = shouldCompress; 3128 host->bufferCount = 2; 3129 } 3130 3131 currentPeer->lastSendTime = host->serviceTime; 3132 sentLength = enet_socket_send(host->socket, ¤tPeer->address, host->buffers, host->bufferCount); 3133 enet_protocol_remove_sent_unreliable_commands(currentPeer); 3134 3135 if (sentLength < 0) { 3136 return -1; 3137 } 3138 3139 host->totalSentData += sentLength; 3140 currentPeer->totalDataSent += sentLength; 3141 host->totalSentPackets++; 3142 } 3143 3144 return 0; 3145 } /* enet_protocol_send_outgoing_commands */ 3146 3147 /** Sends any queued packets on the host specified to its designated peers. 3148 * 3149 * @param host host to flush 3150 * @remarks this function need only be used in circumstances where one wishes to send queued packets earlier than in a call to enet_host_service(). 3151 * @ingroup host 3152 */ enet_host_flush(ENetHost * host)3153 void enet_host_flush(ENetHost *host) { 3154 host->serviceTime = enet_time_get(); 3155 enet_protocol_send_outgoing_commands(host, NULL, 0); 3156 } 3157 3158 /** Checks for any queued events on the host and dispatches one if available. 3159 * 3160 * @param host host to check for events 3161 * @param event an event structure where event details will be placed if available 3162 * @retval > 0 if an event was dispatched 3163 * @retval 0 if no events are available 3164 * @retval < 0 on failure 3165 * @ingroup host 3166 */ enet_host_check_events(ENetHost * host,ENetEvent * event)3167 int enet_host_check_events(ENetHost *host, ENetEvent *event) { 3168 if (event == NULL) { return -1; } 3169 3170 event->type = ENET_EVENT_TYPE_NONE; 3171 event->peer = NULL; 3172 event->packet = NULL; 3173 3174 return enet_protocol_dispatch_incoming_commands(host, event); 3175 } 3176 3177 /** Waits for events on the host specified and shuttles packets between 3178 * the host and its peers. 3179 * 3180 * @param host host to service 3181 * @param event an event structure where event details will be placed if one occurs 3182 * if event == NULL then no events will be delivered 3183 * @param timeout number of milliseconds that ENet should wait for events 3184 * @retval > 0 if an event occurred within the specified time limit 3185 * @retval 0 if no event occurred 3186 * @retval < 0 on failure 3187 * @remarks enet_host_service should be called fairly regularly for adequate performance 3188 * @ingroup host 3189 */ enet_host_service(ENetHost * host,ENetEvent * event,enet_uint32 timeout)3190 int enet_host_service(ENetHost *host, ENetEvent *event, enet_uint32 timeout) { 3191 enet_uint32 waitCondition; 3192 3193 if (event != NULL) { 3194 event->type = ENET_EVENT_TYPE_NONE; 3195 event->peer = NULL; 3196 event->packet = NULL; 3197 3198 switch (enet_protocol_dispatch_incoming_commands(host, event)) { 3199 case 1: 3200 return 1; 3201 3202 case -1: 3203 #ifdef ENET_DEBUG 3204 perror("Error dispatching incoming packets"); 3205 #endif 3206 3207 return -1; 3208 3209 default: 3210 break; 3211 } 3212 } 3213 3214 host->serviceTime = enet_time_get(); 3215 timeout += host->serviceTime; 3216 3217 do { 3218 if (ENET_TIME_DIFFERENCE(host->serviceTime, host->bandwidthThrottleEpoch) >= ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL) { 3219 enet_host_bandwidth_throttle(host); 3220 } 3221 3222 switch (enet_protocol_send_outgoing_commands(host, event, 1)) { 3223 case 1: 3224 return 1; 3225 3226 case -1: 3227 #ifdef ENET_DEBUG 3228 perror("Error sending outgoing packets"); 3229 #endif 3230 3231 return -1; 3232 3233 default: 3234 break; 3235 } 3236 3237 switch (enet_protocol_receive_incoming_commands(host, event)) { 3238 case 1: 3239 return 1; 3240 3241 case -1: 3242 #ifdef ENET_DEBUG 3243 perror("Error receiving incoming packets"); 3244 #endif 3245 3246 return -1; 3247 3248 default: 3249 break; 3250 } 3251 3252 switch (enet_protocol_send_outgoing_commands(host, event, 1)) { 3253 case 1: 3254 return 1; 3255 3256 case -1: 3257 #ifdef ENET_DEBUG 3258 perror("Error sending outgoing packets"); 3259 #endif 3260 3261 return -1; 3262 3263 default: 3264 break; 3265 } 3266 3267 if (event != NULL) { 3268 switch (enet_protocol_dispatch_incoming_commands(host, event)) { 3269 case 1: 3270 return 1; 3271 3272 case -1: 3273 #ifdef ENET_DEBUG 3274 perror("Error dispatching incoming packets"); 3275 #endif 3276 3277 return -1; 3278 3279 default: 3280 break; 3281 } 3282 } 3283 3284 if (ENET_TIME_GREATER_EQUAL(host->serviceTime, timeout)) { 3285 return 0; 3286 } 3287 3288 do { 3289 host->serviceTime = enet_time_get(); 3290 3291 if (ENET_TIME_GREATER_EQUAL(host->serviceTime, timeout)) { 3292 return 0; 3293 } 3294 3295 waitCondition = ENET_SOCKET_WAIT_RECEIVE | ENET_SOCKET_WAIT_INTERRUPT; 3296 if (enet_socket_wait(host->socket, &waitCondition, ENET_TIME_DIFFERENCE(timeout, host->serviceTime)) != 0) { 3297 return -1; 3298 } 3299 } while (waitCondition & ENET_SOCKET_WAIT_INTERRUPT); 3300 3301 host->serviceTime = enet_time_get(); 3302 } while (waitCondition & ENET_SOCKET_WAIT_RECEIVE); 3303 3304 return 0; 3305 } /* enet_host_service */ 3306 3307 3308 // =======================================================================// 3309 // ! 3310 // ! Peer 3311 // ! 3312 // =======================================================================// 3313 3314 /** Configures throttle parameter for a peer. 3315 * 3316 * Unreliable packets are dropped by ENet in response to the varying conditions 3317 * of the Internet connection to the peer. The throttle represents a probability 3318 * that an unreliable packet should not be dropped and thus sent by ENet to the peer. 3319 * The lowest mean round trip time from the sending of a reliable packet to the 3320 * receipt of its acknowledgement is measured over an amount of time specified by 3321 * the interval parameter in milliseconds. If a measured round trip time happens to 3322 * be significantly less than the mean round trip time measured over the interval, 3323 * then the throttle probability is increased to allow more traffic by an amount 3324 * specified in the acceleration parameter, which is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE 3325 * constant. If a measured round trip time happens to be significantly greater than 3326 * the mean round trip time measured over the interval, then the throttle probability 3327 * is decreased to limit traffic by an amount specified in the deceleration parameter, which 3328 * is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE constant. When the throttle has 3329 * a value of ENET_PEER_PACKET_THROTTLE_SCALE, no unreliable packets are dropped by 3330 * ENet, and so 100% of all unreliable packets will be sent. When the throttle has a 3331 * value of 0, all unreliable packets are dropped by ENet, and so 0% of all unreliable 3332 * packets will be sent. Intermediate values for the throttle represent intermediate 3333 * probabilities between 0% and 100% of unreliable packets being sent. The bandwidth 3334 * limits of the local and foreign hosts are taken into account to determine a 3335 * sensible limit for the throttle probability above which it should not raise even in 3336 * the best of conditions. 3337 * 3338 * @param peer peer to configure 3339 * @param interval interval, in milliseconds, over which to measure lowest mean RTT; the default value is ENET_PEER_PACKET_THROTTLE_INTERVAL. 3340 * @param acceleration rate at which to increase the throttle probability as mean RTT declines 3341 * @param deceleration rate at which to decrease the throttle probability as mean RTT increases 3342 */ enet_peer_throttle_configure(ENetPeer * peer,enet_uint32 interval,enet_uint32 acceleration,enet_uint32 deceleration)3343 void enet_peer_throttle_configure(ENetPeer *peer, enet_uint32 interval, enet_uint32 acceleration, enet_uint32 deceleration) { 3344 ENetProtocol command; 3345 3346 peer->packetThrottleInterval = interval; 3347 peer->packetThrottleAcceleration = acceleration; 3348 peer->packetThrottleDeceleration = deceleration; 3349 3350 command.header.command = ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; 3351 command.header.channelID = 0xFF; 3352 3353 command.throttleConfigure.packetThrottleInterval = ENET_HOST_TO_NET_32(interval); 3354 command.throttleConfigure.packetThrottleAcceleration = ENET_HOST_TO_NET_32(acceleration); 3355 command.throttleConfigure.packetThrottleDeceleration = ENET_HOST_TO_NET_32(deceleration); 3356 3357 enet_peer_queue_outgoing_command(peer, &command, NULL, 0, 0); 3358 } 3359 enet_peer_throttle(ENetPeer * peer,enet_uint32 rtt)3360 int enet_peer_throttle(ENetPeer *peer, enet_uint32 rtt) { 3361 if (peer->lastRoundTripTime <= peer->lastRoundTripTimeVariance) { 3362 peer->packetThrottle = peer->packetThrottleLimit; 3363 } 3364 else if (rtt < peer->lastRoundTripTime) { 3365 peer->packetThrottle += peer->packetThrottleAcceleration; 3366 3367 if (peer->packetThrottle > peer->packetThrottleLimit) { 3368 peer->packetThrottle = peer->packetThrottleLimit; 3369 } 3370 3371 return 1; 3372 } 3373 else if (rtt > peer->lastRoundTripTime + 2 * peer->lastRoundTripTimeVariance) { 3374 if (peer->packetThrottle > peer->packetThrottleDeceleration) { 3375 peer->packetThrottle -= peer->packetThrottleDeceleration; 3376 } else { 3377 peer->packetThrottle = 0; 3378 } 3379 3380 return -1; 3381 } 3382 3383 return 0; 3384 } 3385 3386 /* Extended functionality for easier binding in other programming languages */ enet_host_get_peers_count(ENetHost * host)3387 enet_uint32 enet_host_get_peers_count(ENetHost *host) { 3388 return host->connectedPeers; 3389 } 3390 enet_host_get_packets_sent(ENetHost * host)3391 enet_uint32 enet_host_get_packets_sent(ENetHost *host) { 3392 return host->totalSentPackets; 3393 } 3394 enet_host_get_packets_received(ENetHost * host)3395 enet_uint32 enet_host_get_packets_received(ENetHost *host) { 3396 return host->totalReceivedPackets; 3397 } 3398 enet_host_get_bytes_sent(ENetHost * host)3399 enet_uint32 enet_host_get_bytes_sent(ENetHost *host) { 3400 return host->totalSentData; 3401 } 3402 enet_host_get_bytes_received(ENetHost * host)3403 enet_uint32 enet_host_get_bytes_received(ENetHost *host) { 3404 return host->totalReceivedData; 3405 } 3406 3407 /** Gets received data buffer. Returns buffer length. 3408 * @param host host to access recevie buffer 3409 * @param data ouput parameter for recevied data 3410 * @retval buffer length 3411 */ enet_host_get_received_data(ENetHost * host,enet_uint8 ** data)3412 enet_uint32 enet_host_get_received_data(ENetHost *host, /*out*/ enet_uint8** data) { 3413 *data = host->receivedData; 3414 return host->receivedDataLength; 3415 } 3416 enet_host_get_mtu(ENetHost * host)3417 enet_uint32 enet_host_get_mtu(ENetHost *host) { 3418 return host->mtu; 3419 } 3420 enet_peer_get_id(ENetPeer * peer)3421 enet_uint32 enet_peer_get_id(ENetPeer *peer) { 3422 return peer->connectID; 3423 } 3424 enet_peer_get_ip(ENetPeer * peer,char * ip,size_t ipLength)3425 enet_uint32 enet_peer_get_ip(ENetPeer *peer, char *ip, size_t ipLength) { 3426 return enet_address_get_host_ip(&peer->address, ip, ipLength); 3427 } 3428 enet_peer_get_port(ENetPeer * peer)3429 enet_uint16 enet_peer_get_port(ENetPeer *peer) { 3430 return peer->address.port; 3431 } 3432 enet_peer_get_state(ENetPeer * peer)3433 ENetPeerState enet_peer_get_state(ENetPeer *peer) { 3434 return peer->state; 3435 } 3436 enet_peer_get_rtt(ENetPeer * peer)3437 enet_uint32 enet_peer_get_rtt(ENetPeer *peer) { 3438 return peer->roundTripTime; 3439 } 3440 enet_peer_get_packets_sent(ENetPeer * peer)3441 enet_uint64 enet_peer_get_packets_sent(ENetPeer *peer) { 3442 return peer->totalPacketsSent; 3443 } 3444 enet_peer_get_packets_lost(ENetPeer * peer)3445 enet_uint32 enet_peer_get_packets_lost(ENetPeer *peer) { 3446 return peer->totalPacketsLost; 3447 } 3448 enet_peer_get_bytes_sent(ENetPeer * peer)3449 enet_uint64 enet_peer_get_bytes_sent(ENetPeer *peer) { 3450 return peer->totalDataSent; 3451 } 3452 enet_peer_get_bytes_received(ENetPeer * peer)3453 enet_uint64 enet_peer_get_bytes_received(ENetPeer *peer) { 3454 return peer->totalDataReceived; 3455 } 3456 enet_peer_get_data(ENetPeer * peer)3457 void * enet_peer_get_data(ENetPeer *peer) { 3458 return (void *) peer->data; 3459 } 3460 enet_peer_set_data(ENetPeer * peer,void * data)3461 void enet_peer_set_data(ENetPeer *peer, void *data) { 3462 peer->data = (enet_uint32 *) data; 3463 } 3464 enet_packet_get_data(ENetPacket * packet)3465 void * enet_packet_get_data(ENetPacket *packet) { 3466 return (void *) packet->data; 3467 } 3468 enet_packet_get_length(ENetPacket * packet)3469 enet_uint32 enet_packet_get_length(ENetPacket *packet) { 3470 return packet->dataLength; 3471 } 3472 enet_packet_set_free_callback(ENetPacket * packet,void * callback)3473 void enet_packet_set_free_callback(ENetPacket *packet, void *callback) { 3474 packet->freeCallback = (ENetPacketFreeCallback)callback; 3475 } 3476 3477 /** Queues a packet to be sent. 3478 * @param peer destination for the packet 3479 * @param channelID channel on which to send 3480 * @param packet packet to send 3481 * @retval 0 on success 3482 * @retval < 0 on failure 3483 */ enet_peer_send(ENetPeer * peer,enet_uint8 channelID,ENetPacket * packet)3484 int enet_peer_send(ENetPeer *peer, enet_uint8 channelID, ENetPacket *packet) { 3485 ENetChannel *channel = &peer->channels[channelID]; 3486 ENetProtocol command; 3487 size_t fragmentLength; 3488 3489 if (peer->state != ENET_PEER_STATE_CONNECTED || channelID >= peer->channelCount || packet->dataLength > peer->host->maximumPacketSize) { 3490 return -1; 3491 } 3492 3493 fragmentLength = peer->mtu - sizeof(ENetProtocolHeader) - sizeof(ENetProtocolSendFragment); 3494 if (peer->host->checksum != NULL) { 3495 fragmentLength -= sizeof(enet_uint32); 3496 } 3497 3498 if (packet->dataLength > fragmentLength) { 3499 enet_uint32 fragmentCount = (packet->dataLength + fragmentLength - 1) / fragmentLength, fragmentNumber, fragmentOffset; 3500 enet_uint8 commandNumber; 3501 enet_uint16 startSequenceNumber; 3502 ENetList fragments; 3503 ENetOutgoingCommand *fragment; 3504 3505 if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT) { 3506 return -1; 3507 } 3508 3509 if ((packet->flags & (ENET_PACKET_FLAG_RELIABLE | ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT)) == 3510 ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT && 3511 channel->outgoingUnreliableSequenceNumber < 0xFFFF) 3512 { 3513 commandNumber = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT; 3514 startSequenceNumber = ENET_HOST_TO_NET_16(channel->outgoingUnreliableSequenceNumber + 1); 3515 } else { 3516 commandNumber = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; 3517 startSequenceNumber = ENET_HOST_TO_NET_16(channel->outgoingReliableSequenceNumber + 1); 3518 } 3519 3520 enet_list_clear(&fragments); 3521 3522 for (fragmentNumber = 0, fragmentOffset = 0; fragmentOffset < packet->dataLength; ++fragmentNumber, fragmentOffset += fragmentLength) { 3523 if (packet->dataLength - fragmentOffset < fragmentLength) { 3524 fragmentLength = packet->dataLength - fragmentOffset; 3525 } 3526 3527 fragment = (ENetOutgoingCommand *) enet_malloc(sizeof(ENetOutgoingCommand)); 3528 3529 if (fragment == NULL) { 3530 while (!enet_list_empty(&fragments)) { 3531 fragment = (ENetOutgoingCommand *) enet_list_remove(enet_list_begin(&fragments)); 3532 3533 enet_free(fragment); 3534 } 3535 3536 return -1; 3537 } 3538 3539 fragment->fragmentOffset = fragmentOffset; 3540 fragment->fragmentLength = fragmentLength; 3541 fragment->packet = packet; 3542 fragment->command.header.command = commandNumber; 3543 fragment->command.header.channelID = channelID; 3544 3545 fragment->command.sendFragment.startSequenceNumber = startSequenceNumber; 3546 3547 fragment->command.sendFragment.dataLength = ENET_HOST_TO_NET_16(fragmentLength); 3548 fragment->command.sendFragment.fragmentCount = ENET_HOST_TO_NET_32(fragmentCount); 3549 fragment->command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32(fragmentNumber); 3550 fragment->command.sendFragment.totalLength = ENET_HOST_TO_NET_32(packet->dataLength); 3551 fragment->command.sendFragment.fragmentOffset = ENET_NET_TO_HOST_32(fragmentOffset); 3552 3553 enet_list_insert(enet_list_end(&fragments), fragment); 3554 } 3555 3556 packet->referenceCount += fragmentNumber; 3557 3558 while (!enet_list_empty(&fragments)) { 3559 fragment = (ENetOutgoingCommand *) enet_list_remove(enet_list_begin(&fragments)); 3560 enet_peer_setup_outgoing_command(peer, fragment); 3561 } 3562 3563 return 0; 3564 } 3565 3566 command.header.channelID = channelID; 3567 3568 if ((packet->flags & (ENET_PACKET_FLAG_RELIABLE | ENET_PACKET_FLAG_UNSEQUENCED)) == ENET_PACKET_FLAG_UNSEQUENCED) { 3569 command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED; 3570 command.sendUnsequenced.dataLength = ENET_HOST_TO_NET_16(packet->dataLength); 3571 } 3572 else if (packet->flags & ENET_PACKET_FLAG_RELIABLE || channel->outgoingUnreliableSequenceNumber >= 0xFFFF) { 3573 command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; 3574 command.sendReliable.dataLength = ENET_HOST_TO_NET_16(packet->dataLength); 3575 } 3576 else { 3577 command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE; 3578 command.sendUnreliable.dataLength = ENET_HOST_TO_NET_16(packet->dataLength); 3579 } 3580 3581 if (enet_peer_queue_outgoing_command(peer, &command, packet, 0, packet->dataLength) == NULL) { 3582 return -1; 3583 } 3584 3585 return 0; 3586 } // enet_peer_send 3587 3588 /** Attempts to dequeue any incoming queued packet. 3589 * @param peer peer to dequeue packets from 3590 * @param channelID holds the channel ID of the channel the packet was received on success 3591 * @returns a pointer to the packet, or NULL if there are no available incoming queued packets 3592 */ enet_peer_receive(ENetPeer * peer,enet_uint8 * channelID)3593 ENetPacket * enet_peer_receive(ENetPeer *peer, enet_uint8 *channelID) { 3594 ENetIncomingCommand *incomingCommand; 3595 ENetPacket *packet; 3596 3597 if (enet_list_empty(&peer->dispatchedCommands)) { 3598 return NULL; 3599 } 3600 3601 incomingCommand = (ENetIncomingCommand *) enet_list_remove(enet_list_begin(&peer->dispatchedCommands)); 3602 3603 if (channelID != NULL) { 3604 *channelID = incomingCommand->command.header.channelID; 3605 } 3606 3607 packet = incomingCommand->packet; 3608 --packet->referenceCount; 3609 3610 if (incomingCommand->fragments != NULL) { 3611 enet_free(incomingCommand->fragments); 3612 } 3613 3614 enet_free(incomingCommand); 3615 peer->totalWaitingData -= packet->dataLength; 3616 3617 return packet; 3618 } 3619 enet_peer_reset_outgoing_commands(ENetList * queue)3620 static void enet_peer_reset_outgoing_commands(ENetList *queue) { 3621 ENetOutgoingCommand *outgoingCommand; 3622 3623 while (!enet_list_empty(queue)) { 3624 outgoingCommand = (ENetOutgoingCommand *) enet_list_remove(enet_list_begin(queue)); 3625 3626 if (outgoingCommand->packet != NULL) { 3627 --outgoingCommand->packet->referenceCount; 3628 3629 if (outgoingCommand->packet->referenceCount == 0) { 3630 enet_packet_destroy(outgoingCommand->packet); 3631 } 3632 } 3633 3634 enet_free(outgoingCommand); 3635 } 3636 } 3637 enet_peer_remove_incoming_commands(ENetList * queue,ENetListIterator startCommand,ENetListIterator endCommand)3638 static void enet_peer_remove_incoming_commands(ENetList *queue, ENetListIterator startCommand, ENetListIterator endCommand) { 3639 UNREFERENCED_PARAMETER(queue); 3640 ENetListIterator currentCommand; 3641 3642 for (currentCommand = startCommand; currentCommand != endCommand;) { 3643 ENetIncomingCommand *incomingCommand = (ENetIncomingCommand *) currentCommand; 3644 3645 currentCommand = enet_list_next(currentCommand); 3646 enet_list_remove(&incomingCommand->incomingCommandList); 3647 3648 if (incomingCommand->packet != NULL) { 3649 --incomingCommand->packet->referenceCount; 3650 3651 if (incomingCommand->packet->referenceCount == 0) { 3652 enet_packet_destroy(incomingCommand->packet); 3653 } 3654 } 3655 3656 if (incomingCommand->fragments != NULL) { 3657 enet_free(incomingCommand->fragments); 3658 } 3659 3660 enet_free(incomingCommand); 3661 } 3662 } 3663 enet_peer_reset_incoming_commands(ENetList * queue)3664 static void enet_peer_reset_incoming_commands(ENetList *queue) { 3665 enet_peer_remove_incoming_commands(queue, enet_list_begin(queue), enet_list_end(queue)); 3666 } 3667 enet_peer_reset_queues(ENetPeer * peer)3668 void enet_peer_reset_queues(ENetPeer *peer) { 3669 ENetChannel *channel; 3670 3671 if (peer->needsDispatch) { 3672 enet_list_remove(&peer->dispatchList); 3673 peer->needsDispatch = 0; 3674 } 3675 3676 while (!enet_list_empty(&peer->acknowledgements)) { 3677 enet_free(enet_list_remove(enet_list_begin(&peer->acknowledgements))); 3678 } 3679 3680 enet_peer_reset_outgoing_commands(&peer->sentReliableCommands); 3681 enet_peer_reset_outgoing_commands(&peer->sentUnreliableCommands); 3682 enet_peer_reset_outgoing_commands(&peer->outgoingReliableCommands); 3683 enet_peer_reset_outgoing_commands(&peer->outgoingUnreliableCommands); 3684 enet_peer_reset_incoming_commands(&peer->dispatchedCommands); 3685 3686 if (peer->channels != NULL && peer->channelCount > 0) { 3687 for (channel = peer->channels; channel < &peer->channels[peer->channelCount]; ++channel) { 3688 enet_peer_reset_incoming_commands(&channel->incomingReliableCommands); 3689 enet_peer_reset_incoming_commands(&channel->incomingUnreliableCommands); 3690 } 3691 3692 enet_free(peer->channels); 3693 } 3694 3695 peer->channels = NULL; 3696 peer->channelCount = 0; 3697 } 3698 enet_peer_on_connect(ENetPeer * peer)3699 void enet_peer_on_connect(ENetPeer *peer) { 3700 if (peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER) { 3701 if (peer->incomingBandwidth != 0) { 3702 ++peer->host->bandwidthLimitedPeers; 3703 } 3704 3705 ++peer->host->connectedPeers; 3706 } 3707 } 3708 enet_peer_on_disconnect(ENetPeer * peer)3709 void enet_peer_on_disconnect(ENetPeer *peer) { 3710 if (peer->state == ENET_PEER_STATE_CONNECTED || peer->state == ENET_PEER_STATE_DISCONNECT_LATER) { 3711 if (peer->incomingBandwidth != 0) { 3712 --peer->host->bandwidthLimitedPeers; 3713 } 3714 3715 --peer->host->connectedPeers; 3716 } 3717 } 3718 3719 /** Forcefully disconnects a peer. 3720 * @param peer peer to forcefully disconnect 3721 * @remarks The foreign host represented by the peer is not notified of the disconnection and will timeout 3722 * on its connection to the local host. 3723 */ enet_peer_reset(ENetPeer * peer)3724 void enet_peer_reset(ENetPeer *peer) { 3725 enet_peer_on_disconnect(peer); 3726 3727 // We don't want to reset connectID here, otherwise, we can't get it in the Disconnect event 3728 // peer->connectID = 0; 3729 peer->outgoingPeerID = ENET_PROTOCOL_MAXIMUM_PEER_ID; 3730 peer->state = ENET_PEER_STATE_DISCONNECTED; 3731 peer->incomingBandwidth = 0; 3732 peer->outgoingBandwidth = 0; 3733 peer->incomingBandwidthThrottleEpoch = 0; 3734 peer->outgoingBandwidthThrottleEpoch = 0; 3735 peer->incomingDataTotal = 0; 3736 peer->totalDataReceived = 0; 3737 peer->outgoingDataTotal = 0; 3738 peer->totalDataSent = 0; 3739 peer->lastSendTime = 0; 3740 peer->lastReceiveTime = 0; 3741 peer->nextTimeout = 0; 3742 peer->earliestTimeout = 0; 3743 peer->packetLossEpoch = 0; 3744 peer->packetsSent = 0; 3745 peer->totalPacketsSent = 0; 3746 peer->packetsLost = 0; 3747 peer->totalPacketsLost = 0; 3748 peer->packetLoss = 0; 3749 peer->packetLossVariance = 0; 3750 peer->packetThrottle = ENET_PEER_DEFAULT_PACKET_THROTTLE; 3751 peer->packetThrottleLimit = ENET_PEER_PACKET_THROTTLE_SCALE; 3752 peer->packetThrottleCounter = 0; 3753 peer->packetThrottleEpoch = 0; 3754 peer->packetThrottleAcceleration = ENET_PEER_PACKET_THROTTLE_ACCELERATION; 3755 peer->packetThrottleDeceleration = ENET_PEER_PACKET_THROTTLE_DECELERATION; 3756 peer->packetThrottleInterval = ENET_PEER_PACKET_THROTTLE_INTERVAL; 3757 peer->pingInterval = ENET_PEER_PING_INTERVAL; 3758 peer->timeoutLimit = ENET_PEER_TIMEOUT_LIMIT; 3759 peer->timeoutMinimum = ENET_PEER_TIMEOUT_MINIMUM; 3760 peer->timeoutMaximum = ENET_PEER_TIMEOUT_MAXIMUM; 3761 peer->lastRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME; 3762 peer->lowestRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME; 3763 peer->lastRoundTripTimeVariance = 0; 3764 peer->highestRoundTripTimeVariance = 0; 3765 peer->roundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME; 3766 peer->roundTripTimeVariance = 0; 3767 peer->mtu = peer->host->mtu; 3768 peer->reliableDataInTransit = 0; 3769 peer->outgoingReliableSequenceNumber = 0; 3770 peer->windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; 3771 peer->incomingUnsequencedGroup = 0; 3772 peer->outgoingUnsequencedGroup = 0; 3773 peer->eventData = 0; 3774 peer->totalWaitingData = 0; 3775 3776 memset(peer->unsequencedWindow, 0, sizeof(peer->unsequencedWindow)); 3777 enet_peer_reset_queues(peer); 3778 } 3779 3780 /** Sends a ping request to a peer. 3781 * @param peer destination for the ping request 3782 * @remarks ping requests factor into the mean round trip time as designated by the 3783 * roundTripTime field in the ENetPeer structure. ENet automatically pings all connected 3784 * peers at regular intervals, however, this function may be called to ensure more 3785 * frequent ping requests. 3786 */ enet_peer_ping(ENetPeer * peer)3787 void enet_peer_ping(ENetPeer *peer) { 3788 ENetProtocol command; 3789 3790 if (peer->state != ENET_PEER_STATE_CONNECTED) { 3791 return; 3792 } 3793 3794 command.header.command = ENET_PROTOCOL_COMMAND_PING | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; 3795 command.header.channelID = 0xFF; 3796 3797 enet_peer_queue_outgoing_command(peer, &command, NULL, 0, 0); 3798 } 3799 3800 /** Sets the interval at which pings will be sent to a peer. 3801 * 3802 * Pings are used both to monitor the liveness of the connection and also to dynamically 3803 * adjust the throttle during periods of low traffic so that the throttle has reasonable 3804 * responsiveness during traffic spikes. 3805 * 3806 * @param peer the peer to adjust 3807 * @param pingInterval the interval at which to send pings; defaults to ENET_PEER_PING_INTERVAL if 0 3808 */ enet_peer_ping_interval(ENetPeer * peer,enet_uint32 pingInterval)3809 void enet_peer_ping_interval(ENetPeer *peer, enet_uint32 pingInterval) { 3810 peer->pingInterval = pingInterval ? pingInterval : (int)ENET_PEER_PING_INTERVAL; 3811 } 3812 3813 /** Sets the timeout parameters for a peer. 3814 * 3815 * The timeout parameter control how and when a peer will timeout from a failure to acknowledge 3816 * reliable traffic. Timeout values use an exponential backoff mechanism, where if a reliable 3817 * packet is not acknowledge within some multiple of the average RTT plus a variance tolerance, 3818 * the timeout will be doubled until it reaches a set limit. If the timeout is thus at this 3819 * limit and reliable packets have been sent but not acknowledged within a certain minimum time 3820 * period, the peer will be disconnected. Alternatively, if reliable packets have been sent 3821 * but not acknowledged for a certain maximum time period, the peer will be disconnected regardless 3822 * of the current timeout limit value. 3823 * 3824 * @param peer the peer to adjust 3825 * @param timeoutLimit the timeout limit; defaults to ENET_PEER_TIMEOUT_LIMIT if 0 3826 * @param timeoutMinimum the timeout minimum; defaults to ENET_PEER_TIMEOUT_MINIMUM if 0 3827 * @param timeoutMaximum the timeout maximum; defaults to ENET_PEER_TIMEOUT_MAXIMUM if 0 3828 */ 3829 enet_peer_timeout(ENetPeer * peer,enet_uint32 timeoutLimit,enet_uint32 timeoutMinimum,enet_uint32 timeoutMaximum)3830 void enet_peer_timeout(ENetPeer *peer, enet_uint32 timeoutLimit, enet_uint32 timeoutMinimum, enet_uint32 timeoutMaximum) { 3831 peer->timeoutLimit = timeoutLimit ? timeoutLimit : (int)ENET_PEER_TIMEOUT_LIMIT; 3832 peer->timeoutMinimum = timeoutMinimum ? timeoutMinimum : (int)ENET_PEER_TIMEOUT_MINIMUM; 3833 peer->timeoutMaximum = timeoutMaximum ? timeoutMaximum : (int)ENET_PEER_TIMEOUT_MAXIMUM; 3834 } 3835 3836 /** Force an immediate disconnection from a peer. 3837 * @param peer peer to disconnect 3838 * @param data data describing the disconnection 3839 * @remarks No ENET_EVENT_DISCONNECT event will be generated. The foreign peer is not 3840 * guaranteed to receive the disconnect notification, and is reset immediately upon 3841 * return from this function. 3842 */ enet_peer_disconnect_now(ENetPeer * peer,enet_uint32 data)3843 void enet_peer_disconnect_now(ENetPeer *peer, enet_uint32 data) { 3844 ENetProtocol command; 3845 3846 if (peer->state == ENET_PEER_STATE_DISCONNECTED) { 3847 return; 3848 } 3849 3850 if (peer->state != ENET_PEER_STATE_ZOMBIE && peer->state != ENET_PEER_STATE_DISCONNECTING) { 3851 enet_peer_reset_queues(peer); 3852 3853 command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED; 3854 command.header.channelID = 0xFF; 3855 command.disconnect.data = ENET_HOST_TO_NET_32(data); 3856 3857 enet_peer_queue_outgoing_command(peer, &command, NULL, 0, 0); 3858 enet_host_flush(peer->host); 3859 } 3860 3861 enet_peer_reset(peer); 3862 } 3863 3864 /** Request a disconnection from a peer. 3865 * @param peer peer to request a disconnection 3866 * @param data data describing the disconnection 3867 * @remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service() 3868 * once the disconnection is complete. 3869 */ enet_peer_disconnect(ENetPeer * peer,enet_uint32 data)3870 void enet_peer_disconnect(ENetPeer *peer, enet_uint32 data) { 3871 ENetProtocol command; 3872 3873 if (peer->state == ENET_PEER_STATE_DISCONNECTING || 3874 peer->state == ENET_PEER_STATE_DISCONNECTED || 3875 peer->state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT || 3876 peer->state == ENET_PEER_STATE_ZOMBIE 3877 ) { 3878 return; 3879 } 3880 3881 enet_peer_reset_queues(peer); 3882 3883 command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT; 3884 command.header.channelID = 0xFF; 3885 command.disconnect.data = ENET_HOST_TO_NET_32(data); 3886 3887 if (peer->state == ENET_PEER_STATE_CONNECTED || peer->state == ENET_PEER_STATE_DISCONNECT_LATER) { 3888 command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; 3889 } else { 3890 command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED; 3891 } 3892 3893 enet_peer_queue_outgoing_command(peer, &command, NULL, 0, 0); 3894 3895 if (peer->state == ENET_PEER_STATE_CONNECTED || peer->state == ENET_PEER_STATE_DISCONNECT_LATER) { 3896 enet_peer_on_disconnect(peer); 3897 3898 peer->state = ENET_PEER_STATE_DISCONNECTING; 3899 } else { 3900 enet_host_flush(peer->host); 3901 enet_peer_reset(peer); 3902 } 3903 } 3904 3905 /** Request a disconnection from a peer, but only after all queued outgoing packets are sent. 3906 * @param peer peer to request a disconnection 3907 * @param data data describing the disconnection 3908 * @remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service() 3909 * once the disconnection is complete. 3910 */ enet_peer_disconnect_later(ENetPeer * peer,enet_uint32 data)3911 void enet_peer_disconnect_later(ENetPeer *peer, enet_uint32 data) { 3912 if ((peer->state == ENET_PEER_STATE_CONNECTED || peer->state == ENET_PEER_STATE_DISCONNECT_LATER) && 3913 !(enet_list_empty(&peer->outgoingReliableCommands) && 3914 enet_list_empty(&peer->outgoingUnreliableCommands) && 3915 enet_list_empty(&peer->sentReliableCommands)) 3916 ) { 3917 peer->state = ENET_PEER_STATE_DISCONNECT_LATER; 3918 peer->eventData = data; 3919 } else { 3920 enet_peer_disconnect(peer, data); 3921 } 3922 } 3923 enet_peer_queue_acknowledgement(ENetPeer * peer,const ENetProtocol * command,enet_uint16 sentTime)3924 ENetAcknowledgement *enet_peer_queue_acknowledgement(ENetPeer *peer, const ENetProtocol *command, enet_uint16 sentTime) { 3925 ENetAcknowledgement *acknowledgement; 3926 3927 if (command->header.channelID < peer->channelCount) { 3928 ENetChannel *channel = &peer->channels[command->header.channelID]; 3929 enet_uint16 reliableWindow = command->header.reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; 3930 enet_uint16 currentWindow = channel->incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; 3931 3932 if (command->header.reliableSequenceNumber < channel->incomingReliableSequenceNumber) { 3933 reliableWindow += ENET_PEER_RELIABLE_WINDOWS; 3934 } 3935 3936 if (reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1 && reliableWindow <= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS) { 3937 return NULL; 3938 } 3939 } 3940 3941 acknowledgement = (ENetAcknowledgement *) enet_malloc(sizeof(ENetAcknowledgement)); 3942 if (acknowledgement == NULL) { 3943 return NULL; 3944 } 3945 3946 peer->outgoingDataTotal += sizeof(ENetProtocolAcknowledge); 3947 3948 acknowledgement->sentTime = sentTime; 3949 acknowledgement->command = *command; 3950 3951 enet_list_insert(enet_list_end(&peer->acknowledgements), acknowledgement); 3952 return acknowledgement; 3953 } 3954 enet_peer_setup_outgoing_command(ENetPeer * peer,ENetOutgoingCommand * outgoingCommand)3955 void enet_peer_setup_outgoing_command(ENetPeer *peer, ENetOutgoingCommand *outgoingCommand) { 3956 ENetChannel *channel = &peer->channels[outgoingCommand->command.header.channelID]; 3957 peer->outgoingDataTotal += enet_protocol_command_size(outgoingCommand->command.header.command) + outgoingCommand->fragmentLength; 3958 3959 if (outgoingCommand->command.header.channelID == 0xFF) { 3960 ++peer->outgoingReliableSequenceNumber; 3961 3962 outgoingCommand->reliableSequenceNumber = peer->outgoingReliableSequenceNumber; 3963 outgoingCommand->unreliableSequenceNumber = 0; 3964 } 3965 else if (outgoingCommand->command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) { 3966 ++channel->outgoingReliableSequenceNumber; 3967 channel->outgoingUnreliableSequenceNumber = 0; 3968 3969 outgoingCommand->reliableSequenceNumber = channel->outgoingReliableSequenceNumber; 3970 outgoingCommand->unreliableSequenceNumber = 0; 3971 } 3972 else if (outgoingCommand->command.header.command & ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED) { 3973 ++peer->outgoingUnsequencedGroup; 3974 3975 outgoingCommand->reliableSequenceNumber = 0; 3976 outgoingCommand->unreliableSequenceNumber = 0; 3977 } 3978 else { 3979 if (outgoingCommand->fragmentOffset == 0) { 3980 ++channel->outgoingUnreliableSequenceNumber; 3981 } 3982 3983 outgoingCommand->reliableSequenceNumber = channel->outgoingReliableSequenceNumber; 3984 outgoingCommand->unreliableSequenceNumber = channel->outgoingUnreliableSequenceNumber; 3985 } 3986 3987 outgoingCommand->sendAttempts = 0; 3988 outgoingCommand->sentTime = 0; 3989 outgoingCommand->roundTripTimeout = 0; 3990 outgoingCommand->roundTripTimeoutLimit = 0; 3991 outgoingCommand->command.header.reliableSequenceNumber = ENET_HOST_TO_NET_16(outgoingCommand->reliableSequenceNumber); 3992 3993 switch (outgoingCommand->command.header.command & ENET_PROTOCOL_COMMAND_MASK) { 3994 case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE: 3995 outgoingCommand->command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_16(outgoingCommand->unreliableSequenceNumber); 3996 break; 3997 3998 case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED: 3999 outgoingCommand->command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_16(peer->outgoingUnsequencedGroup); 4000 break; 4001 4002 default: 4003 break; 4004 } 4005 4006 if (outgoingCommand->command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) { 4007 enet_list_insert(enet_list_end(&peer->outgoingReliableCommands), outgoingCommand); 4008 } else { 4009 enet_list_insert(enet_list_end(&peer->outgoingUnreliableCommands), outgoingCommand); 4010 } 4011 } 4012 enet_peer_queue_outgoing_command(ENetPeer * peer,const ENetProtocol * command,ENetPacket * packet,enet_uint32 offset,enet_uint16 length)4013 ENetOutgoingCommand * enet_peer_queue_outgoing_command(ENetPeer *peer, const ENetProtocol *command, ENetPacket *packet, enet_uint32 offset, enet_uint16 length) { 4014 ENetOutgoingCommand *outgoingCommand = (ENetOutgoingCommand *) enet_malloc(sizeof(ENetOutgoingCommand)); 4015 4016 if (outgoingCommand == NULL) { 4017 return NULL; 4018 } 4019 4020 outgoingCommand->command = *command; 4021 outgoingCommand->fragmentOffset = offset; 4022 outgoingCommand->fragmentLength = length; 4023 outgoingCommand->packet = packet; 4024 if (packet != NULL) { 4025 ++packet->referenceCount; 4026 } 4027 4028 enet_peer_setup_outgoing_command(peer, outgoingCommand); 4029 return outgoingCommand; 4030 } 4031 enet_peer_dispatch_incoming_unreliable_commands(ENetPeer * peer,ENetChannel * channel)4032 void enet_peer_dispatch_incoming_unreliable_commands(ENetPeer *peer, ENetChannel *channel) { 4033 ENetListIterator droppedCommand, startCommand, currentCommand; 4034 4035 for (droppedCommand = startCommand = currentCommand = enet_list_begin(&channel->incomingUnreliableCommands); 4036 currentCommand != enet_list_end(&channel->incomingUnreliableCommands); 4037 currentCommand = enet_list_next(currentCommand) 4038 ) { 4039 ENetIncomingCommand *incomingCommand = (ENetIncomingCommand *) currentCommand; 4040 4041 if ((incomingCommand->command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED) { 4042 continue; 4043 } 4044 4045 if (incomingCommand->reliableSequenceNumber == channel->incomingReliableSequenceNumber) { 4046 if (incomingCommand->fragmentsRemaining <= 0) { 4047 channel->incomingUnreliableSequenceNumber = incomingCommand->unreliableSequenceNumber; 4048 continue; 4049 } 4050 4051 if (startCommand != currentCommand) { 4052 enet_list_move(enet_list_end(&peer->dispatchedCommands), startCommand, enet_list_previous(currentCommand)); 4053 4054 if (!peer->needsDispatch) { 4055 enet_list_insert(enet_list_end(&peer->host->dispatchQueue), &peer->dispatchList); 4056 peer->needsDispatch = 1; 4057 } 4058 4059 droppedCommand = currentCommand; 4060 } else if (droppedCommand != currentCommand) { 4061 droppedCommand = enet_list_previous(currentCommand); 4062 } 4063 } else { 4064 enet_uint16 reliableWindow = incomingCommand->reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; 4065 enet_uint16 currentWindow = channel->incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; 4066 4067 if (incomingCommand->reliableSequenceNumber < channel->incomingReliableSequenceNumber) { 4068 reliableWindow += ENET_PEER_RELIABLE_WINDOWS; 4069 } 4070 4071 if (reliableWindow >= currentWindow && reliableWindow < currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1) { 4072 break; 4073 } 4074 4075 droppedCommand = enet_list_next(currentCommand); 4076 4077 if (startCommand != currentCommand) { 4078 enet_list_move(enet_list_end(&peer->dispatchedCommands), startCommand, enet_list_previous(currentCommand)); 4079 4080 if (!peer->needsDispatch) { 4081 enet_list_insert(enet_list_end(&peer->host->dispatchQueue), &peer->dispatchList); 4082 peer->needsDispatch = 1; 4083 } 4084 } 4085 } 4086 4087 startCommand = enet_list_next(currentCommand); 4088 } 4089 4090 if (startCommand != currentCommand) { 4091 enet_list_move(enet_list_end(&peer->dispatchedCommands), startCommand, enet_list_previous(currentCommand)); 4092 4093 if (!peer->needsDispatch) { 4094 enet_list_insert(enet_list_end(&peer->host->dispatchQueue), &peer->dispatchList); 4095 peer->needsDispatch = 1; 4096 } 4097 4098 droppedCommand = currentCommand; 4099 } 4100 4101 enet_peer_remove_incoming_commands(&channel->incomingUnreliableCommands,enet_list_begin(&channel->incomingUnreliableCommands), droppedCommand); 4102 } 4103 enet_peer_dispatch_incoming_reliable_commands(ENetPeer * peer,ENetChannel * channel)4104 void enet_peer_dispatch_incoming_reliable_commands(ENetPeer *peer, ENetChannel *channel) { 4105 ENetListIterator currentCommand; 4106 4107 for (currentCommand = enet_list_begin(&channel->incomingReliableCommands); 4108 currentCommand != enet_list_end(&channel->incomingReliableCommands); 4109 currentCommand = enet_list_next(currentCommand) 4110 ) { 4111 ENetIncomingCommand *incomingCommand = (ENetIncomingCommand *) currentCommand; 4112 4113 if (incomingCommand->fragmentsRemaining > 0 || incomingCommand->reliableSequenceNumber != (enet_uint16) (channel->incomingReliableSequenceNumber + 1)) { 4114 break; 4115 } 4116 4117 channel->incomingReliableSequenceNumber = incomingCommand->reliableSequenceNumber; 4118 4119 if (incomingCommand->fragmentCount > 0) { 4120 channel->incomingReliableSequenceNumber += incomingCommand->fragmentCount - 1; 4121 } 4122 } 4123 4124 if (currentCommand == enet_list_begin(&channel->incomingReliableCommands)) { 4125 return; 4126 } 4127 4128 channel->incomingUnreliableSequenceNumber = 0; 4129 enet_list_move(enet_list_end(&peer->dispatchedCommands), enet_list_begin(&channel->incomingReliableCommands), enet_list_previous(currentCommand)); 4130 4131 if (!peer->needsDispatch) { 4132 enet_list_insert(enet_list_end(&peer->host->dispatchQueue), &peer->dispatchList); 4133 peer->needsDispatch = 1; 4134 } 4135 4136 if (!enet_list_empty(&channel->incomingUnreliableCommands)) { 4137 enet_peer_dispatch_incoming_unreliable_commands(peer, channel); 4138 } 4139 } 4140 enet_peer_queue_incoming_command(ENetPeer * peer,const ENetProtocol * command,void * data,size_t dataLength,enet_uint32 flags,enet_uint32 fragmentCount)4141 ENetIncomingCommand * enet_peer_queue_incoming_command(ENetPeer *peer, const ENetProtocol *command, void *data, size_t dataLength, enet_uint32 flags, enet_uint32 fragmentCount) { 4142 static ENetIncomingCommand dummyCommand; 4143 4144 ENetChannel *channel = &peer->channels[command->header.channelID]; 4145 enet_uint32 unreliableSequenceNumber = 0, reliableSequenceNumber = 0; 4146 enet_uint16 reliableWindow, currentWindow; 4147 ENetIncomingCommand *incomingCommand; 4148 ENetListIterator currentCommand; 4149 ENetPacket *packet = NULL; 4150 4151 if (peer->state == ENET_PEER_STATE_DISCONNECT_LATER) { 4152 goto discardCommand; 4153 } 4154 4155 if ((command->header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED) { 4156 reliableSequenceNumber = command->header.reliableSequenceNumber; 4157 reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; 4158 currentWindow = channel->incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; 4159 4160 if (reliableSequenceNumber < channel->incomingReliableSequenceNumber) { 4161 reliableWindow += ENET_PEER_RELIABLE_WINDOWS; 4162 } 4163 4164 if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1) { 4165 goto discardCommand; 4166 } 4167 } 4168 4169 switch (command->header.command & ENET_PROTOCOL_COMMAND_MASK) { 4170 case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: 4171 case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: 4172 if (reliableSequenceNumber == channel->incomingReliableSequenceNumber) { 4173 goto discardCommand; 4174 } 4175 4176 for (currentCommand = enet_list_previous(enet_list_end(&channel->incomingReliableCommands)); 4177 currentCommand != enet_list_end(&channel->incomingReliableCommands); 4178 currentCommand = enet_list_previous(currentCommand) 4179 ) { 4180 incomingCommand = (ENetIncomingCommand *) currentCommand; 4181 4182 if (reliableSequenceNumber >= channel->incomingReliableSequenceNumber) { 4183 if (incomingCommand->reliableSequenceNumber < channel->incomingReliableSequenceNumber) { 4184 continue; 4185 } 4186 } else if (incomingCommand->reliableSequenceNumber >= channel->incomingReliableSequenceNumber) { 4187 break; 4188 } 4189 4190 if (incomingCommand->reliableSequenceNumber <= reliableSequenceNumber) { 4191 if (incomingCommand->reliableSequenceNumber < reliableSequenceNumber) { 4192 break; 4193 } 4194 4195 goto discardCommand; 4196 } 4197 } 4198 break; 4199 4200 case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE: 4201 case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT: 4202 unreliableSequenceNumber = ENET_NET_TO_HOST_16(command->sendUnreliable.unreliableSequenceNumber); 4203 4204 if (reliableSequenceNumber == channel->incomingReliableSequenceNumber && unreliableSequenceNumber <= channel->incomingUnreliableSequenceNumber) { 4205 goto discardCommand; 4206 } 4207 4208 for (currentCommand = enet_list_previous(enet_list_end(&channel->incomingUnreliableCommands)); 4209 currentCommand != enet_list_end(&channel->incomingUnreliableCommands); 4210 currentCommand = enet_list_previous(currentCommand) 4211 ) { 4212 incomingCommand = (ENetIncomingCommand *) currentCommand; 4213 4214 if ((command->header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED) { 4215 continue; 4216 } 4217 4218 if (reliableSequenceNumber >= channel->incomingReliableSequenceNumber) { 4219 if (incomingCommand->reliableSequenceNumber < channel->incomingReliableSequenceNumber) { 4220 continue; 4221 } 4222 } else if (incomingCommand->reliableSequenceNumber >= channel->incomingReliableSequenceNumber) { 4223 break; 4224 } 4225 4226 if (incomingCommand->reliableSequenceNumber < reliableSequenceNumber) { 4227 break; 4228 } 4229 4230 if (incomingCommand->reliableSequenceNumber > reliableSequenceNumber) { 4231 continue; 4232 } 4233 4234 if (incomingCommand->unreliableSequenceNumber <= unreliableSequenceNumber) { 4235 if (incomingCommand->unreliableSequenceNumber < unreliableSequenceNumber) { 4236 break; 4237 } 4238 4239 goto discardCommand; 4240 } 4241 } 4242 break; 4243 4244 case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED: 4245 currentCommand = enet_list_end(&channel->incomingUnreliableCommands); 4246 break; 4247 4248 default: 4249 goto discardCommand; 4250 } 4251 4252 if (peer->totalWaitingData >= peer->host->maximumWaitingData) { 4253 goto notifyError; 4254 } 4255 4256 packet = enet_packet_create(data, dataLength, flags); 4257 if (packet == NULL) { 4258 goto notifyError; 4259 } 4260 4261 incomingCommand = (ENetIncomingCommand *) enet_malloc(sizeof(ENetIncomingCommand)); 4262 if (incomingCommand == NULL) { 4263 goto notifyError; 4264 } 4265 4266 incomingCommand->reliableSequenceNumber = command->header.reliableSequenceNumber; 4267 incomingCommand->unreliableSequenceNumber = unreliableSequenceNumber & 0xFFFF; 4268 incomingCommand->command = *command; 4269 incomingCommand->fragmentCount = fragmentCount; 4270 incomingCommand->fragmentsRemaining = fragmentCount; 4271 incomingCommand->packet = packet; 4272 incomingCommand->fragments = NULL; 4273 4274 if (fragmentCount > 0) { 4275 if (fragmentCount <= ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT) { 4276 incomingCommand->fragments = (enet_uint32 *) enet_malloc((fragmentCount + 31) / 32 * sizeof(enet_uint32)); 4277 } 4278 4279 if (incomingCommand->fragments == NULL) { 4280 enet_free(incomingCommand); 4281 4282 goto notifyError; 4283 } 4284 4285 memset(incomingCommand->fragments, 0, (fragmentCount + 31) / 32 * sizeof(enet_uint32)); 4286 } 4287 4288 if (packet != NULL) { 4289 ++packet->referenceCount; 4290 peer->totalWaitingData += packet->dataLength; 4291 } 4292 4293 enet_list_insert(enet_list_next(currentCommand), incomingCommand); 4294 4295 switch (command->header.command & ENET_PROTOCOL_COMMAND_MASK) { 4296 case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: 4297 case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: 4298 enet_peer_dispatch_incoming_reliable_commands(peer, channel); 4299 break; 4300 4301 default: 4302 enet_peer_dispatch_incoming_unreliable_commands(peer, channel); 4303 break; 4304 } 4305 4306 return incomingCommand; 4307 4308 discardCommand: 4309 if (fragmentCount > 0) { 4310 goto notifyError; 4311 } 4312 4313 if (packet != NULL && packet->referenceCount == 0) { 4314 enet_packet_destroy(packet); 4315 } 4316 4317 return &dummyCommand; 4318 4319 notifyError: 4320 if (packet != NULL && packet->referenceCount == 0) { 4321 enet_packet_destroy(packet); 4322 } 4323 4324 return NULL; 4325 } /* enet_peer_queue_incoming_command */ 4326 4327 // =======================================================================// 4328 // ! 4329 // ! Host 4330 // ! 4331 // =======================================================================// 4332 4333 /** Creates a host for communicating to peers. 4334 * 4335 * @param address the address at which other peers may connect to this host. If NULL, then no peers may connect to the host. 4336 * @param peerCount the maximum number of peers that should be allocated for the host. 4337 * @param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT 4338 * @param incomingBandwidth downstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth. 4339 * @param outgoingBandwidth upstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth. 4340 * 4341 * @returns the host on success and NULL on failure 4342 * 4343 * @remarks ENet will strategically drop packets on specific sides of a connection between hosts 4344 * to ensure the host's bandwidth is not overwhelmed. The bandwidth parameters also determine 4345 * the window size of a connection which limits the amount of reliable packets that may be in transit 4346 * at any given time. 4347 */ enet_host_create(ENetAddress * address,size_t peerCount,size_t channelLimit,enet_uint32 incomingBandwidth,enet_uint32 outgoingBandwidth)4348 ENetHost * enet_host_create(ENetAddress *address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth) { 4349 ENetHost *host; 4350 ENetPeer *currentPeer; 4351 4352 if (peerCount > ENET_PROTOCOL_MAXIMUM_PEER_ID) { 4353 return NULL; 4354 } 4355 4356 host = (ENetHost *) enet_malloc(sizeof(ENetHost)); 4357 if (host == NULL) { return NULL; } 4358 memset(host, 0, sizeof(ENetHost)); 4359 4360 host->peers = (ENetPeer *) enet_malloc(peerCount * sizeof(ENetPeer)); 4361 if (host->peers == NULL) { 4362 enet_free(host); 4363 return NULL; 4364 } 4365 4366 memset(host->peers, 0, peerCount * sizeof(ENetPeer)); 4367 4368 host->socket = enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM); 4369 if (host->socket != ENET_SOCKET_NULL) { 4370 enet_socket_set_option (host->socket, ENET_SOCKOPT_IPV6_V6ONLY, 0); 4371 } 4372 4373 if (host->socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind(host->socket, address) < 0)) { 4374 if (host->socket != ENET_SOCKET_NULL) { 4375 enet_socket_destroy(host->socket); 4376 } 4377 4378 enet_free(host->peers); 4379 enet_free(host); 4380 4381 return NULL; 4382 } 4383 4384 enet_socket_set_option(host->socket, ENET_SOCKOPT_NONBLOCK, 1); 4385 enet_socket_set_option(host->socket, ENET_SOCKOPT_BROADCAST, 1); 4386 enet_socket_set_option(host->socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE); 4387 enet_socket_set_option(host->socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE); 4388 enet_socket_set_option(host->socket, ENET_SOCKOPT_IPV6_V6ONLY, 0); 4389 4390 if (address != NULL && enet_socket_get_address(host->socket, &host->address) < 0) { 4391 host->address = *address; 4392 } 4393 4394 if (!channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) { 4395 channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT; 4396 } else if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT) { 4397 channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT; 4398 } 4399 4400 host->randomSeed = (enet_uint32) (size_t) host; 4401 host->randomSeed += enet_host_random_seed(); 4402 host->randomSeed = (host->randomSeed << 16) | (host->randomSeed >> 16); 4403 host->channelLimit = channelLimit; 4404 host->incomingBandwidth = incomingBandwidth; 4405 host->outgoingBandwidth = outgoingBandwidth; 4406 host->bandwidthThrottleEpoch = 0; 4407 host->recalculateBandwidthLimits = 0; 4408 host->mtu = ENET_HOST_DEFAULT_MTU; 4409 host->peerCount = peerCount; 4410 host->commandCount = 0; 4411 host->bufferCount = 0; 4412 host->checksum = NULL; 4413 host->receivedAddress.host = ENET_HOST_ANY; 4414 host->receivedAddress.port = 0; 4415 host->receivedData = NULL; 4416 host->receivedDataLength = 0; 4417 host->totalSentData = 0; 4418 host->totalSentPackets = 0; 4419 host->totalReceivedData = 0; 4420 host->totalReceivedPackets = 0; 4421 host->connectedPeers = 0; 4422 host->bandwidthLimitedPeers = 0; 4423 host->duplicatePeers = ENET_PROTOCOL_MAXIMUM_PEER_ID; 4424 host->maximumPacketSize = ENET_HOST_DEFAULT_MAXIMUM_PACKET_SIZE; 4425 host->maximumWaitingData = ENET_HOST_DEFAULT_MAXIMUM_WAITING_DATA; 4426 host->compressor.context = NULL; 4427 host->compressor.compress = NULL; 4428 host->compressor.decompress = NULL; 4429 host->compressor.destroy = NULL; 4430 host->intercept = NULL; 4431 4432 enet_list_clear(&host->dispatchQueue); 4433 4434 for (currentPeer = host->peers; currentPeer < &host->peers[host->peerCount]; ++currentPeer) { 4435 currentPeer->host = host; 4436 currentPeer->incomingPeerID = currentPeer - host->peers; 4437 currentPeer->outgoingSessionID = currentPeer->incomingSessionID = 0xFF; 4438 currentPeer->data = NULL; 4439 4440 enet_list_clear(¤tPeer->acknowledgements); 4441 enet_list_clear(¤tPeer->sentReliableCommands); 4442 enet_list_clear(¤tPeer->sentUnreliableCommands); 4443 enet_list_clear(¤tPeer->outgoingReliableCommands); 4444 enet_list_clear(¤tPeer->outgoingUnreliableCommands); 4445 enet_list_clear(¤tPeer->dispatchedCommands); 4446 4447 enet_peer_reset(currentPeer); 4448 } 4449 4450 return host; 4451 } /* enet_host_create */ 4452 4453 /** Destroys the host and all resources associated with it. 4454 * @param host pointer to the host to destroy 4455 */ enet_host_destroy(ENetHost * host)4456 void enet_host_destroy(ENetHost *host) { 4457 ENetPeer *currentPeer; 4458 4459 if (host == NULL) { 4460 return; 4461 } 4462 4463 enet_socket_destroy(host->socket); 4464 4465 for (currentPeer = host->peers; currentPeer < &host->peers[host->peerCount]; ++currentPeer) { 4466 enet_peer_reset(currentPeer); 4467 } 4468 4469 if (host->compressor.context != NULL && host->compressor.destroy) { 4470 (*host->compressor.destroy)(host->compressor.context); 4471 } 4472 4473 enet_free(host->peers); 4474 enet_free(host); 4475 } 4476 4477 /** Initiates a connection to a foreign host. 4478 * @param host host seeking the connection 4479 * @param address destination for the connection 4480 * @param channelCount number of channels to allocate 4481 * @param data user data supplied to the receiving host 4482 * @returns a peer representing the foreign host on success, NULL on failure 4483 * @remarks The peer returned will have not completed the connection until enet_host_service() 4484 * notifies of an ENET_EVENT_TYPE_CONNECT event for the peer. 4485 */ enet_host_connect(ENetHost * host,ENetAddress * address,size_t channelCount,enet_uint32 data)4486 ENetPeer * enet_host_connect(ENetHost *host, ENetAddress *address, size_t channelCount, enet_uint32 data) { 4487 ENetPeer *currentPeer; 4488 ENetChannel *channel; 4489 ENetProtocol command; 4490 4491 if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT) { 4492 channelCount = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT; 4493 } else if (channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) { 4494 channelCount = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT; 4495 } 4496 4497 for (currentPeer = host->peers; currentPeer < &host->peers[host->peerCount]; ++currentPeer) { 4498 if (currentPeer->state == ENET_PEER_STATE_DISCONNECTED) { 4499 break; 4500 } 4501 } 4502 4503 if (currentPeer >= &host->peers[host->peerCount]) { 4504 return NULL; 4505 } 4506 4507 currentPeer->channels = (ENetChannel *) enet_malloc(channelCount * sizeof(ENetChannel)); 4508 if (currentPeer->channels == NULL) { 4509 return NULL; 4510 } 4511 4512 currentPeer->channelCount = channelCount; 4513 currentPeer->state = ENET_PEER_STATE_CONNECTING; 4514 currentPeer->address = *address; 4515 currentPeer->connectID = ++host->randomSeed; 4516 4517 if (host->outgoingBandwidth == 0) { 4518 currentPeer->windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; 4519 } else { 4520 currentPeer->windowSize = (host->outgoingBandwidth / ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; 4521 } 4522 4523 if (currentPeer->windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) { 4524 currentPeer->windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; 4525 } else if (currentPeer->windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) { 4526 currentPeer->windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; 4527 } 4528 4529 for (channel = currentPeer->channels; channel < ¤tPeer->channels[channelCount]; ++channel) { 4530 channel->outgoingReliableSequenceNumber = 0; 4531 channel->outgoingUnreliableSequenceNumber = 0; 4532 channel->incomingReliableSequenceNumber = 0; 4533 channel->incomingUnreliableSequenceNumber = 0; 4534 4535 enet_list_clear(&channel->incomingReliableCommands); 4536 enet_list_clear(&channel->incomingUnreliableCommands); 4537 4538 channel->usedReliableWindows = 0; 4539 memset(channel->reliableWindows, 0, sizeof(channel->reliableWindows)); 4540 } 4541 4542 command.header.command = ENET_PROTOCOL_COMMAND_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; 4543 command.header.channelID = 0xFF; 4544 command.connect.outgoingPeerID = ENET_HOST_TO_NET_16(currentPeer->incomingPeerID); 4545 command.connect.incomingSessionID = currentPeer->incomingSessionID; 4546 command.connect.outgoingSessionID = currentPeer->outgoingSessionID; 4547 command.connect.mtu = ENET_HOST_TO_NET_32(currentPeer->mtu); 4548 command.connect.windowSize = ENET_HOST_TO_NET_32(currentPeer->windowSize); 4549 command.connect.channelCount = ENET_HOST_TO_NET_32(channelCount); 4550 command.connect.incomingBandwidth = ENET_HOST_TO_NET_32(host->incomingBandwidth); 4551 command.connect.outgoingBandwidth = ENET_HOST_TO_NET_32(host->outgoingBandwidth); 4552 command.connect.packetThrottleInterval = ENET_HOST_TO_NET_32(currentPeer->packetThrottleInterval); 4553 command.connect.packetThrottleAcceleration = ENET_HOST_TO_NET_32(currentPeer->packetThrottleAcceleration); 4554 command.connect.packetThrottleDeceleration = ENET_HOST_TO_NET_32(currentPeer->packetThrottleDeceleration); 4555 command.connect.connectID = currentPeer->connectID; 4556 command.connect.data = ENET_HOST_TO_NET_32(data); 4557 4558 enet_peer_queue_outgoing_command(currentPeer, &command, NULL, 0, 0); 4559 4560 return currentPeer; 4561 } /* enet_host_connect */ 4562 4563 /** Queues a packet to be sent to all peers associated with the host. 4564 * @param host host on which to broadcast the packet 4565 * @param channelID channel on which to broadcast 4566 * @param packet packet to broadcast 4567 */ enet_host_broadcast(ENetHost * host,enet_uint8 channelID,ENetPacket * packet)4568 void enet_host_broadcast(ENetHost *host, enet_uint8 channelID, ENetPacket *packet) { 4569 ENetPeer *currentPeer; 4570 4571 for (currentPeer = host->peers; currentPeer < &host->peers[host->peerCount]; ++currentPeer) { 4572 if (currentPeer->state != ENET_PEER_STATE_CONNECTED) { 4573 continue; 4574 } 4575 4576 enet_peer_send(currentPeer, channelID, packet); 4577 } 4578 4579 if (packet->referenceCount == 0) { 4580 enet_packet_destroy(packet); 4581 } 4582 } 4583 4584 /** Sends raw data to specified address. Useful when you want to send unconnected data using host's socket. 4585 * @param host host sending data 4586 * @param address destination address 4587 * @param data data pointer 4588 * @param dataLength length of data to send 4589 * @retval >=0 bytes sent 4590 * @retval <0 error 4591 * @sa enet_socket_send 4592 */ enet_host_send_raw(ENetHost * host,ENetAddress * address,enet_uint8 * data,size_t dataLength)4593 int enet_host_send_raw(ENetHost *host, ENetAddress* address, enet_uint8* data, size_t dataLength) { 4594 ENetBuffer buffer; 4595 buffer.data = data; 4596 buffer.dataLength = dataLength; 4597 return enet_socket_send(host->socket, address, &buffer, 1); 4598 } 4599 4600 /** Sends raw data to specified address with extended arguments. Allows to send only part of data, handy for other programming languages. 4601 * I.e. if you have data =- { 0, 1, 2, 3 } and call function as enet_host_send_raw_ex(data, 1, 2) then it will skip 1 byte and send 2 bytes { 1, 2 }. 4602 * @param host host sending data 4603 * @param address destination address 4604 * @param data data pointer 4605 * @param skipBytes number of bytes to skip from start of data 4606 * @param bytesToSend number of bytes to send 4607 * @retval >=0 bytes sent 4608 * @retval <0 error 4609 * @sa enet_socket_send 4610 */ enet_host_send_raw_ex(ENetHost * host,ENetAddress * address,enet_uint8 * data,size_t skipBytes,size_t bytesToSend)4611 int enet_host_send_raw_ex(ENetHost *host, ENetAddress* address, enet_uint8* data, size_t skipBytes, size_t bytesToSend) { 4612 ENetBuffer buffer; 4613 buffer.data = data + skipBytes; 4614 buffer.dataLength = bytesToSend; 4615 return enet_socket_send(host->socket, address, &buffer, 1); 4616 } 4617 4618 /** Sets intercept callback for the host. 4619 * @param host host to set a callback 4620 * @param callback intercept callback 4621 */ enet_host_set_intercept(ENetHost * host,const ENetInterceptCallback callback)4622 void enet_host_set_intercept(ENetHost *host, const ENetInterceptCallback callback) { 4623 host->intercept = callback; 4624 } 4625 4626 /** Sets the packet compressor the host should use to compress and decompress packets. 4627 * @param host host to enable or disable compression for 4628 * @param compressor callbacks for for the packet compressor; if NULL, then compression is disabled 4629 */ enet_host_compress(ENetHost * host,const ENetCompressor * compressor)4630 void enet_host_compress(ENetHost *host, const ENetCompressor *compressor) { 4631 if (host->compressor.context != NULL && host->compressor.destroy) { 4632 (*host->compressor.destroy)(host->compressor.context); 4633 } 4634 4635 if (compressor) { 4636 host->compressor = *compressor; 4637 } else { 4638 host->compressor.context = NULL; 4639 } 4640 } 4641 4642 /** Limits the maximum allowed channels of future incoming connections. 4643 * @param host host to limit 4644 * @param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT 4645 */ enet_host_channel_limit(ENetHost * host,size_t channelLimit)4646 void enet_host_channel_limit(ENetHost *host, size_t channelLimit) { 4647 if (!channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) { 4648 channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT; 4649 } else if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT) { 4650 channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT; 4651 } 4652 4653 host->channelLimit = channelLimit; 4654 } 4655 4656 /** Adjusts the bandwidth limits of a host. 4657 * @param host host to adjust 4658 * @param incomingBandwidth new incoming bandwidth 4659 * @param outgoingBandwidth new outgoing bandwidth 4660 * @remarks the incoming and outgoing bandwidth parameters are identical in function to those 4661 * specified in enet_host_create(). 4662 */ enet_host_bandwidth_limit(ENetHost * host,enet_uint32 incomingBandwidth,enet_uint32 outgoingBandwidth)4663 void enet_host_bandwidth_limit(ENetHost *host, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth) { 4664 host->incomingBandwidth = incomingBandwidth; 4665 host->outgoingBandwidth = outgoingBandwidth; 4666 host->recalculateBandwidthLimits = 1; 4667 } 4668 enet_host_bandwidth_throttle(ENetHost * host)4669 void enet_host_bandwidth_throttle(ENetHost *host) { 4670 enet_uint32 timeCurrent = enet_time_get(); 4671 enet_uint32 elapsedTime = timeCurrent - host->bandwidthThrottleEpoch; 4672 enet_uint32 peersRemaining = (enet_uint32) host->connectedPeers; 4673 enet_uint32 dataTotal = ~0; 4674 enet_uint32 bandwidth = ~0; 4675 enet_uint32 throttle = 0; 4676 enet_uint32 bandwidthLimit = 0; 4677 4678 int needsAdjustment = host->bandwidthLimitedPeers > 0 ? 1 : 0; 4679 ENetPeer *peer; 4680 ENetProtocol command; 4681 4682 if (elapsedTime < ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL) { 4683 return; 4684 } 4685 4686 if (host->outgoingBandwidth == 0 && host->incomingBandwidth == 0) { 4687 return; 4688 } 4689 4690 host->bandwidthThrottleEpoch = timeCurrent; 4691 4692 if (peersRemaining == 0) { 4693 return; 4694 } 4695 4696 if (host->outgoingBandwidth != 0) { 4697 dataTotal = 0; 4698 bandwidth = (host->outgoingBandwidth * elapsedTime) / 1000; 4699 4700 for (peer = host->peers; peer < &host->peers[host->peerCount]; ++peer) { 4701 if (peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER) { 4702 continue; 4703 } 4704 4705 dataTotal += peer->outgoingDataTotal; 4706 } 4707 } 4708 4709 while (peersRemaining > 0 && needsAdjustment != 0) { 4710 needsAdjustment = 0; 4711 4712 if (dataTotal <= bandwidth) { 4713 throttle = ENET_PEER_PACKET_THROTTLE_SCALE; 4714 } else { 4715 throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal; 4716 } 4717 4718 for (peer = host->peers; peer < &host->peers[host->peerCount]; ++peer) { 4719 enet_uint32 peerBandwidth; 4720 4721 if ((peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER) || 4722 peer->incomingBandwidth == 0 || 4723 peer->outgoingBandwidthThrottleEpoch == timeCurrent 4724 ) { 4725 continue; 4726 } 4727 4728 peerBandwidth = (peer->incomingBandwidth * elapsedTime) / 1000; 4729 if ((throttle * peer->outgoingDataTotal) / ENET_PEER_PACKET_THROTTLE_SCALE <= peerBandwidth) { 4730 continue; 4731 } 4732 4733 peer->packetThrottleLimit = (peerBandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / peer->outgoingDataTotal; 4734 4735 if (peer->packetThrottleLimit == 0) { 4736 peer->packetThrottleLimit = 1; 4737 } 4738 4739 if (peer->packetThrottle > peer->packetThrottleLimit) { 4740 peer->packetThrottle = peer->packetThrottleLimit; 4741 } 4742 4743 peer->outgoingBandwidthThrottleEpoch = timeCurrent; 4744 4745 peer->incomingDataTotal = 0; 4746 peer->outgoingDataTotal = 0; 4747 4748 needsAdjustment = 1; 4749 --peersRemaining; 4750 bandwidth -= peerBandwidth; 4751 dataTotal -= peerBandwidth; 4752 } 4753 } 4754 4755 if (peersRemaining > 0) { 4756 if (dataTotal <= bandwidth) { 4757 throttle = ENET_PEER_PACKET_THROTTLE_SCALE; 4758 } else { 4759 throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal; 4760 } 4761 4762 for (peer = host->peers; 4763 peer < &host->peers[host->peerCount]; 4764 ++peer) 4765 { 4766 if ((peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER) || peer->outgoingBandwidthThrottleEpoch == timeCurrent) { 4767 continue; 4768 } 4769 4770 peer->packetThrottleLimit = throttle; 4771 4772 if (peer->packetThrottle > peer->packetThrottleLimit) { 4773 peer->packetThrottle = peer->packetThrottleLimit; 4774 } 4775 4776 peer->incomingDataTotal = 0; 4777 peer->outgoingDataTotal = 0; 4778 } 4779 } 4780 4781 if (host->recalculateBandwidthLimits) { 4782 host->recalculateBandwidthLimits = 0; 4783 4784 peersRemaining = (enet_uint32) host->connectedPeers; 4785 bandwidth = host->incomingBandwidth; 4786 needsAdjustment = 1; 4787 4788 if (bandwidth == 0) { 4789 bandwidthLimit = 0; 4790 } else { 4791 while (peersRemaining > 0 && needsAdjustment != 0) { 4792 needsAdjustment = 0; 4793 bandwidthLimit = bandwidth / peersRemaining; 4794 4795 for (peer = host->peers; peer < &host->peers[host->peerCount]; ++peer) { 4796 if ((peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER) || 4797 peer->incomingBandwidthThrottleEpoch == timeCurrent 4798 ) { 4799 continue; 4800 } 4801 4802 if (peer->outgoingBandwidth > 0 && peer->outgoingBandwidth >= bandwidthLimit) { 4803 continue; 4804 } 4805 4806 peer->incomingBandwidthThrottleEpoch = timeCurrent; 4807 4808 needsAdjustment = 1; 4809 --peersRemaining; 4810 bandwidth -= peer->outgoingBandwidth; 4811 } 4812 } 4813 } 4814 4815 for (peer = host->peers; peer < &host->peers[host->peerCount]; ++peer) { 4816 if (peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER) { 4817 continue; 4818 } 4819 4820 command.header.command = ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; 4821 command.header.channelID = 0xFF; 4822 command.bandwidthLimit.outgoingBandwidth = ENET_HOST_TO_NET_32(host->outgoingBandwidth); 4823 4824 if (peer->incomingBandwidthThrottleEpoch == timeCurrent) { 4825 command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32(peer->outgoingBandwidth); 4826 } else { 4827 command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32(bandwidthLimit); 4828 } 4829 4830 enet_peer_queue_outgoing_command(peer, &command, NULL, 0, 0); 4831 } 4832 } 4833 } /* enet_host_bandwidth_throttle */ 4834 4835 // =======================================================================// 4836 // ! 4837 // ! Time 4838 // ! 4839 // =======================================================================// 4840 4841 #ifdef _WIN32 getFILETIMEoffset()4842 static LARGE_INTEGER getFILETIMEoffset() { 4843 SYSTEMTIME s; 4844 FILETIME f; 4845 LARGE_INTEGER t; 4846 4847 s.wYear = 1970; 4848 s.wMonth = 1; 4849 s.wDay = 1; 4850 s.wHour = 0; 4851 s.wMinute = 0; 4852 s.wSecond = 0; 4853 s.wMilliseconds = 0; 4854 SystemTimeToFileTime(&s, &f); 4855 t.QuadPart = f.dwHighDateTime; 4856 t.QuadPart <<= 32; 4857 t.QuadPart |= f.dwLowDateTime; 4858 return (t); 4859 } 4860 enet_gettime(int X,struct timespec * tv)4861 int enet_gettime(int X, struct timespec *tv) { 4862 UNREFERENCED_PARAMETER(X); 4863 LARGE_INTEGER t; 4864 FILETIME f; 4865 double microseconds; 4866 static LARGE_INTEGER offset; 4867 static double frequencyToMicroseconds; 4868 static int initialized = 0; 4869 static BOOL usePerformanceCounter = 0; 4870 4871 if (!initialized) { 4872 LARGE_INTEGER performanceFrequency; 4873 initialized = 1; 4874 usePerformanceCounter = QueryPerformanceFrequency(&performanceFrequency); 4875 if (usePerformanceCounter) { 4876 QueryPerformanceCounter(&offset); 4877 frequencyToMicroseconds = (double)performanceFrequency.QuadPart / 1000000.; 4878 } else { 4879 offset = getFILETIMEoffset(); 4880 frequencyToMicroseconds = 10.; 4881 } 4882 } 4883 if (usePerformanceCounter) { 4884 QueryPerformanceCounter(&t); 4885 } else { 4886 GetSystemTimeAsFileTime(&f); 4887 t.QuadPart = f.dwHighDateTime; 4888 t.QuadPart <<= 32; 4889 t.QuadPart |= f.dwLowDateTime; 4890 } 4891 4892 t.QuadPart -= offset.QuadPart; 4893 microseconds = (double)t.QuadPart / frequencyToMicroseconds; 4894 t.QuadPart = (LONGLONG)microseconds; 4895 tv->tv_sec = (long)(t.QuadPart / 1000000); 4896 tv->tv_nsec = t.QuadPart % 1000000 * 1000; 4897 return (0); 4898 } 4899 #elif __APPLE__ && __MAC_OS_X_VERSION_MIN_REQUIRED < 101200 4900 #define CLOCK_MONOTONIC 0 4901 enet_gettime(int X,struct timespec * ts)4902 int enet_gettime(int X, struct timespec *ts) { 4903 clock_serv_t cclock; 4904 mach_timespec_t mts; 4905 4906 host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock); 4907 clock_get_time(cclock, &mts); 4908 mach_port_deallocate(mach_task_self(), cclock); 4909 4910 ts->tv_sec = mts.tv_sec; 4911 ts->tv_nsec = mts.tv_nsec; 4912 4913 return 0; 4914 } 4915 #endif 4916 enet_time_get()4917 enet_uint32 enet_time_get() { 4918 // TODO enet uses 32 bit timestamps. We should modify it to use 4919 // 64 bit timestamps, but this is not trivial since we'd end up 4920 // changing half the structs in enet. For now, retain 32 bits, but 4921 // use an offset so we don't run out of bits. Basically, the first 4922 // call of enet_time_get() will always return 1, and follow-up calls 4923 // indicate elapsed time since the first call. 4924 // 4925 // Note that we don't want to return 0 from the first call, in case 4926 // some part of enet uses 0 as a special value (meaning time not set 4927 // for example). 4928 static uint64_t start_time_ns = 0; 4929 4930 struct timespec ts; 4931 #if defined(CLOCK_MONOTONIC_RAW) 4932 enet_gettime(CLOCK_MONOTONIC_RAW, &ts); 4933 #else 4934 enet_gettime(CLOCK_MONOTONIC, &ts); 4935 #endif 4936 4937 static const uint64_t ns_in_s = 1000 * 1000 * 1000; 4938 static const uint64_t ns_in_ms = 1000 * 1000; 4939 uint64_t current_time_ns = ts.tv_nsec + (uint64_t)ts.tv_sec * ns_in_s; 4940 4941 // Most of the time we just want to atomically read the start time. We 4942 // could just use a single CAS instruction instead of this if, but it 4943 // would be slower in the average case. 4944 // 4945 // Note that statics are auto-initialized to zero, and starting a thread 4946 // implies a memory barrier. So we know that whatever thread calls this, 4947 // it correctly sees the start_time_ns as 0 initially. 4948 uint64_t offset_ns = ENET_ATOMIC_READ(&start_time_ns); 4949 if (offset_ns == 0) { 4950 // We still need to CAS, since two different threads can get here 4951 // at the same time. 4952 // 4953 // We assume that current_time_ns is > 1ms. 4954 // 4955 // Set the value of the start_time_ns, such that the first timestamp 4956 // is at 1ms. This ensures 0 remains a special value. 4957 uint64_t want_value = current_time_ns - 1 * ns_in_ms; 4958 uint64_t old_value = ENET_ATOMIC_CAS(&start_time_ns, 0, want_value); 4959 offset_ns = old_value == 0 ? want_value : old_value; 4960 } 4961 4962 uint64_t result_in_ns = current_time_ns - offset_ns; 4963 return (enet_uint32)(result_in_ns / ns_in_ms); 4964 } 4965 4966 // =======================================================================// 4967 // ! 4968 // ! Platform Specific (Unix) 4969 // ! 4970 // =======================================================================// 4971 4972 #ifndef _WIN32 4973 enet_initialize(void)4974 int enet_initialize(void) { 4975 return 0; 4976 } 4977 enet_deinitialize(void)4978 void enet_deinitialize(void) {} 4979 enet_host_random_seed(void)4980 enet_uint64 enet_host_random_seed(void) { 4981 return (enet_uint64) time(NULL); 4982 } 4983 enet_address_set_host_ip(ENetAddress * address,char * name)4984 int enet_address_set_host_ip(ENetAddress *address, char *name) { 4985 if (!inet_pton(AF_INET6, name, &address->host)) { 4986 return -1; 4987 } 4988 4989 return 0; 4990 } 4991 enet_address_set_host(ENetAddress * address,char * name)4992 int enet_address_set_host(ENetAddress *address, char *name) { 4993 struct addrinfo hints, *resultList = NULL, *result = NULL; 4994 4995 memset(&hints, 0, sizeof(hints)); 4996 hints.ai_family = AF_UNSPEC; 4997 4998 if (getaddrinfo(name, NULL, &hints, &resultList) != 0) { 4999 return -1; 5000 } 5001 5002 for (result = resultList; result != NULL; result = result->ai_next) { 5003 if (result->ai_addr != NULL && result->ai_addrlen >= sizeof(struct sockaddr_in)) { 5004 if (result->ai_family == AF_INET) { 5005 struct sockaddr_in * sin = (struct sockaddr_in *) result->ai_addr; 5006 5007 ((uint32_t *)&address->host.s6_addr)[0] = 0; 5008 ((uint32_t *)&address->host.s6_addr)[1] = 0; 5009 ((uint32_t *)&address->host.s6_addr)[2] = htonl(0xffff); 5010 ((uint32_t *)&address->host.s6_addr)[3] = sin->sin_addr.s_addr; 5011 5012 freeaddrinfo(resultList); 5013 5014 return 0; 5015 } 5016 else if(result->ai_family == AF_INET6) { 5017 struct sockaddr_in6 * sin = (struct sockaddr_in6 *)result->ai_addr; 5018 5019 address->host = sin->sin6_addr; 5020 address->sin6_scope_id = sin->sin6_scope_id; 5021 5022 freeaddrinfo(resultList); 5023 5024 return 0; 5025 } 5026 } 5027 } 5028 5029 5030 if (resultList != NULL) { 5031 freeaddrinfo(resultList); 5032 } 5033 5034 return enet_address_set_host_ip(address, name); 5035 } /* enet_address_set_host */ 5036 enet_address_get_host_ip(ENetAddress * address,char * name,size_t nameLength)5037 int enet_address_get_host_ip(ENetAddress *address, char *name, size_t nameLength) { 5038 if (inet_ntop(AF_INET6, &address->host, name, nameLength) == NULL) { 5039 return -1; 5040 } 5041 5042 return 0; 5043 } 5044 enet_address_get_host(ENetAddress * address,char * name,size_t nameLength)5045 int enet_address_get_host(ENetAddress *address, char *name, size_t nameLength) { 5046 struct sockaddr_in6 sin; 5047 int err; 5048 5049 memset(&sin, 0, sizeof(struct sockaddr_in6)); 5050 5051 sin.sin6_family = AF_INET6; 5052 sin.sin6_port = ENET_HOST_TO_NET_16 (address->port); 5053 sin.sin6_addr = address->host; 5054 sin.sin6_scope_id = address->sin6_scope_id; 5055 5056 err = getnameinfo((struct sockaddr *) &sin, sizeof(sin), name, nameLength, NULL, 0, NI_NAMEREQD); 5057 if (!err) { 5058 if (name != NULL && nameLength > 0 && !memchr(name, '\0', nameLength)) { 5059 return -1; 5060 } 5061 return 0; 5062 } 5063 if (err != EAI_NONAME) { 5064 return -1; 5065 } 5066 5067 return enet_address_get_host_ip(address, name, nameLength); 5068 } /* enet_address_get_host */ 5069 enet_socket_bind(ENetSocket socket,ENetAddress * address)5070 int enet_socket_bind(ENetSocket socket, ENetAddress *address) { 5071 struct sockaddr_in6 sin; 5072 memset(&sin, 0, sizeof(struct sockaddr_in6)); 5073 sin.sin6_family = AF_INET6; 5074 5075 if (address != NULL) { 5076 sin.sin6_port = ENET_HOST_TO_NET_16(address->port); 5077 sin.sin6_addr = address->host; 5078 sin.sin6_scope_id = address->sin6_scope_id; 5079 } else { 5080 sin.sin6_port = 0; 5081 sin.sin6_addr = ENET_HOST_ANY; 5082 sin.sin6_scope_id = 0; 5083 } 5084 5085 return bind(socket, (struct sockaddr *)&sin, sizeof(struct sockaddr_in6)); 5086 } 5087 enet_socket_get_address(ENetSocket socket,ENetAddress * address)5088 int enet_socket_get_address(ENetSocket socket, ENetAddress *address) { 5089 struct sockaddr_in6 sin; 5090 socklen_t sinLength = sizeof(struct sockaddr_in6); 5091 5092 if (getsockname(socket, (struct sockaddr *) &sin, &sinLength) == -1) { 5093 return -1; 5094 } 5095 5096 address->host = sin.sin6_addr; 5097 address->port = ENET_NET_TO_HOST_16(sin.sin6_port); 5098 address->sin6_scope_id = sin.sin6_scope_id; 5099 5100 return 0; 5101 } 5102 enet_socket_listen(ENetSocket socket,int backlog)5103 int enet_socket_listen(ENetSocket socket, int backlog) { 5104 return listen(socket, backlog < 0 ? SOMAXCONN : backlog); 5105 } 5106 enet_socket_create(ENetSocketType type)5107 ENetSocket enet_socket_create(ENetSocketType type) { 5108 return socket(PF_INET6, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); 5109 } 5110 enet_socket_set_option(ENetSocket socket,ENetSocketOption option,int value)5111 int enet_socket_set_option(ENetSocket socket, ENetSocketOption option, int value) { 5112 int result = -1; 5113 5114 switch (option) { 5115 case ENET_SOCKOPT_NONBLOCK: 5116 result = fcntl(socket, F_SETFL, (value ? O_NONBLOCK : 0) | (fcntl(socket, F_GETFL) & ~O_NONBLOCK)); 5117 break; 5118 5119 case ENET_SOCKOPT_BROADCAST: 5120 result = setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char *)&value, sizeof(int)); 5121 break; 5122 5123 case ENET_SOCKOPT_REUSEADDR: 5124 result = setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (char *)&value, sizeof(int)); 5125 break; 5126 5127 case ENET_SOCKOPT_RCVBUF: 5128 result = setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (char *)&value, sizeof(int)); 5129 break; 5130 5131 case ENET_SOCKOPT_SNDBUF: 5132 result = setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char *)&value, sizeof(int)); 5133 break; 5134 5135 case ENET_SOCKOPT_RCVTIMEO: { 5136 struct timeval timeVal; 5137 timeVal.tv_sec = value / 1000; 5138 timeVal.tv_usec = (value % 1000) * 1000; 5139 result = setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeVal, sizeof(struct timeval)); 5140 break; 5141 } 5142 5143 case ENET_SOCKOPT_SNDTIMEO: { 5144 struct timeval timeVal; 5145 timeVal.tv_sec = value / 1000; 5146 timeVal.tv_usec = (value % 1000) * 1000; 5147 result = setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeVal, sizeof(struct timeval)); 5148 break; 5149 } 5150 5151 case ENET_SOCKOPT_NODELAY: 5152 result = setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char *)&value, sizeof(int)); 5153 break; 5154 5155 case ENET_SOCKOPT_IPV6_V6ONLY: 5156 result = setsockopt(socket, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&value, sizeof(int)); 5157 break; 5158 5159 default: 5160 break; 5161 } 5162 return result == -1 ? -1 : 0; 5163 } /* enet_socket_set_option */ 5164 enet_socket_get_option(ENetSocket socket,ENetSocketOption option,int * value)5165 int enet_socket_get_option(ENetSocket socket, ENetSocketOption option, int *value) { 5166 int result = -1; 5167 socklen_t len; 5168 5169 switch (option) { 5170 case ENET_SOCKOPT_ERROR: 5171 len = sizeof(int); 5172 result = getsockopt(socket, SOL_SOCKET, SO_ERROR, value, &len); 5173 break; 5174 5175 default: 5176 break; 5177 } 5178 return result == -1 ? -1 : 0; 5179 } 5180 enet_socket_connect(ENetSocket socket,ENetAddress * address)5181 int enet_socket_connect(ENetSocket socket, ENetAddress *address) { 5182 struct sockaddr_in6 sin; 5183 int result; 5184 5185 memset(&sin, 0, sizeof(struct sockaddr_in6)); 5186 5187 sin.sin6_family = AF_INET6; 5188 sin.sin6_port = ENET_HOST_TO_NET_16(address->port); 5189 sin.sin6_addr = address->host; 5190 sin.sin6_scope_id = address->sin6_scope_id; 5191 5192 result = connect(socket, (struct sockaddr *)&sin, sizeof(struct sockaddr_in6)); 5193 if (result == -1 && errno == EINPROGRESS) { 5194 return 0; 5195 } 5196 5197 return result; 5198 } 5199 enet_socket_accept(ENetSocket socket,ENetAddress * address)5200 ENetSocket enet_socket_accept(ENetSocket socket, ENetAddress *address) { 5201 int result; 5202 struct sockaddr_in6 sin; 5203 socklen_t sinLength = sizeof(struct sockaddr_in6); 5204 5205 result = accept(socket,address != NULL ? (struct sockaddr *) &sin : NULL, address != NULL ? &sinLength : NULL); 5206 5207 if (result == -1) { 5208 return ENET_SOCKET_NULL; 5209 } 5210 5211 if (address != NULL) { 5212 address->host = sin.sin6_addr; 5213 address->port = ENET_NET_TO_HOST_16 (sin.sin6_port); 5214 address->sin6_scope_id = sin.sin6_scope_id; 5215 } 5216 5217 return result; 5218 } 5219 enet_socket_shutdown(ENetSocket socket,ENetSocketShutdown how)5220 int enet_socket_shutdown(ENetSocket socket, ENetSocketShutdown how) { 5221 return shutdown(socket, (int) how); 5222 } 5223 enet_socket_destroy(ENetSocket socket)5224 void enet_socket_destroy(ENetSocket socket) { 5225 if (socket != -1) { 5226 close(socket); 5227 } 5228 } 5229 enet_socket_send(ENetSocket socket,ENetAddress * address,ENetBuffer * buffers,size_t bufferCount)5230 int enet_socket_send(ENetSocket socket, ENetAddress *address, ENetBuffer *buffers, size_t bufferCount) { 5231 struct msghdr msgHdr; 5232 struct sockaddr_in6 sin; 5233 int sentLength; 5234 5235 memset(&msgHdr, 0, sizeof(struct msghdr)); 5236 5237 if (address != NULL) { 5238 memset(&sin, 0, sizeof(struct sockaddr_in6)); 5239 5240 sin.sin6_family = AF_INET6; 5241 sin.sin6_port = ENET_HOST_TO_NET_16(address->port); 5242 sin.sin6_addr = address->host; 5243 sin.sin6_scope_id = address->sin6_scope_id; 5244 5245 msgHdr.msg_name = &sin; 5246 msgHdr.msg_namelen = sizeof(struct sockaddr_in6); 5247 } 5248 5249 msgHdr.msg_iov = (struct iovec *) buffers; 5250 msgHdr.msg_iovlen = bufferCount; 5251 5252 sentLength = sendmsg(socket, &msgHdr, MSG_NOSIGNAL); 5253 5254 if (sentLength == -1) { 5255 if (errno == EWOULDBLOCK) { 5256 return 0; 5257 } 5258 5259 return -1; 5260 } 5261 5262 return sentLength; 5263 } /* enet_socket_send */ 5264 enet_socket_receive(ENetSocket socket,ENetAddress * address,ENetBuffer * buffers,size_t bufferCount)5265 int enet_socket_receive(ENetSocket socket, ENetAddress *address, ENetBuffer *buffers, size_t bufferCount) { 5266 struct msghdr msgHdr; 5267 struct sockaddr_in6 sin; 5268 int recvLength; 5269 5270 memset(&msgHdr, 0, sizeof(struct msghdr)); 5271 5272 if (address != NULL) { 5273 msgHdr.msg_name = &sin; 5274 msgHdr.msg_namelen = sizeof(struct sockaddr_in6); 5275 } 5276 5277 msgHdr.msg_iov = (struct iovec *) buffers; 5278 msgHdr.msg_iovlen = bufferCount; 5279 5280 recvLength = recvmsg(socket, &msgHdr, MSG_NOSIGNAL); 5281 5282 if (recvLength == -1) { 5283 if (errno == EWOULDBLOCK) { 5284 return 0; 5285 } 5286 5287 return -1; 5288 } 5289 5290 if (msgHdr.msg_flags & MSG_TRUNC) { 5291 return -1; 5292 } 5293 5294 if (address != NULL) { 5295 address->host = sin.sin6_addr; 5296 address->port = ENET_NET_TO_HOST_16(sin.sin6_port); 5297 address->sin6_scope_id = sin.sin6_scope_id; 5298 } 5299 5300 return recvLength; 5301 } /* enet_socket_receive */ 5302 enet_socketset_select(ENetSocket maxSocket,ENetSocketSet * readSet,ENetSocketSet * writeSet,enet_uint32 timeout)5303 int enet_socketset_select(ENetSocket maxSocket, ENetSocketSet *readSet, ENetSocketSet *writeSet, enet_uint32 timeout) { 5304 struct timeval timeVal; 5305 5306 timeVal.tv_sec = timeout / 1000; 5307 timeVal.tv_usec = (timeout % 1000) * 1000; 5308 5309 return select(maxSocket + 1, readSet, writeSet, NULL, &timeVal); 5310 } 5311 enet_socket_wait(ENetSocket socket,enet_uint32 * condition,enet_uint64 timeout)5312 int enet_socket_wait(ENetSocket socket, enet_uint32 *condition, enet_uint64 timeout) { 5313 struct pollfd pollSocket; 5314 int pollCount; 5315 5316 pollSocket.fd = socket; 5317 pollSocket.events = 0; 5318 5319 if (*condition & ENET_SOCKET_WAIT_SEND) { 5320 pollSocket.events |= POLLOUT; 5321 } 5322 5323 if (*condition & ENET_SOCKET_WAIT_RECEIVE) { 5324 pollSocket.events |= POLLIN; 5325 } 5326 5327 pollCount = poll(&pollSocket, 1, timeout); 5328 5329 if (pollCount < 0) { 5330 if (errno == EINTR && *condition & ENET_SOCKET_WAIT_INTERRUPT) { 5331 *condition = ENET_SOCKET_WAIT_INTERRUPT; 5332 5333 return 0; 5334 } 5335 5336 return -1; 5337 } 5338 5339 *condition = ENET_SOCKET_WAIT_NONE; 5340 5341 if (pollCount == 0) { 5342 return 0; 5343 } 5344 5345 if (pollSocket.revents & POLLOUT) { 5346 *condition |= ENET_SOCKET_WAIT_SEND; 5347 } 5348 5349 if (pollSocket.revents & POLLIN) { 5350 *condition |= ENET_SOCKET_WAIT_RECEIVE; 5351 } 5352 5353 return 0; 5354 } /* enet_socket_wait */ 5355 5356 #endif // !_WIN32 5357 5358 5359 // =======================================================================// 5360 // ! 5361 // ! Platform Specific (Win) 5362 // ! 5363 // =======================================================================// 5364 5365 #ifdef _WIN32 5366 5367 static int is_enet_initialized = 0; 5368 enet_initialize(void)5369 int enet_initialize(void) { 5370 WORD versionRequested = MAKEWORD(1, 1); 5371 WSADATA wsaData; 5372 5373 if (WSAStartup(versionRequested, &wsaData)) { 5374 return -1; 5375 } 5376 5377 if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) { 5378 WSACleanup(); 5379 return -1; 5380 } 5381 5382 timeBeginPeriod(1); 5383 is_enet_initialized = 1; 5384 return 0; 5385 } 5386 enet_deinitialize(void)5387 void enet_deinitialize(void) { 5388 if (is_enet_initialized) { 5389 timeEndPeriod(1); 5390 WSACleanup(); 5391 is_enet_initialized = 0; 5392 } 5393 } 5394 enet_host_random_seed(void)5395 enet_uint64 enet_host_random_seed(void) { 5396 return (enet_uint64) timeGetTime(); 5397 } 5398 enet_address_set_host_ip(ENetAddress * address,char * name)5399 int enet_address_set_host_ip(ENetAddress *address, char *name) { 5400 enet_uint8 vals[4] = { 0, 0, 0, 0 }; 5401 int i; 5402 5403 for (i = 0; i < 4; ++i) { 5404 char *next = name + 1; 5405 if (*name != '0') { 5406 long val = strtol(name, (char **) &next, 10); 5407 if (val < 0 || val > 255 || next == name || next - name > 3) { 5408 return -1; 5409 } 5410 vals[i] = (enet_uint8) val; 5411 } 5412 5413 if (*next != (i < 3 ? '.' : '\0')) { 5414 return -1; 5415 } 5416 name = next + 1; 5417 } 5418 5419 memcpy(&address->host, vals, sizeof(enet_uint32)); 5420 return 0; 5421 } 5422 enet_pton(int const af,const char * const src,void * const dst)5423 int enet_pton(int const af, const char * const src, void * const dst) { 5424 struct sockaddr_storage ss; 5425 5426 int size = sizeof(ss); 5427 char src_copy[INET6_ADDRSTRLEN + 1]; 5428 5429 ZeroMemory(&ss, sizeof(ss)); 5430 5431 strncpy(src_copy, src, INET6_ADDRSTRLEN + 1); 5432 src_copy[INET6_ADDRSTRLEN] = 0; 5433 5434 if (WSAStringToAddress(src_copy, af, NULL, (struct sockaddr *)&ss, &size) == 0) { 5435 switch (af) { 5436 case AF_INET: 5437 *(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr; 5438 return 1; 5439 case AF_INET6: 5440 *(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr; 5441 return 1; 5442 } 5443 } 5444 5445 return 0; 5446 } 5447 enet_address_set_host(ENetAddress * address,char * name)5448 int enet_address_set_host(ENetAddress *address, char *name) { 5449 struct hostent *hostEntry = NULL; 5450 hostEntry = gethostbyname(name); 5451 5452 if (hostEntry == NULL || hostEntry->h_addrtype != AF_INET) { 5453 if (!enet_pton(AF_INET6, name, &address->host)) { 5454 return -1; 5455 } 5456 5457 return 0; 5458 } 5459 5460 ((enet_uint32 *)&address->host.s6_addr)[0] = 0; 5461 ((enet_uint32 *)&address->host.s6_addr)[1] = 0; 5462 ((enet_uint32 *)&address->host.s6_addr)[2] = htonl(0xffff); 5463 ((enet_uint32 *)&address->host.s6_addr)[3] = *(enet_uint32 *)hostEntry->h_addr_list[0]; 5464 5465 return 0; 5466 } 5467 enet_ntop(int const af,void const * const src,char * const dst,socklen_t const cnt)5468 char const *enet_ntop(int const af, void const *const src, char *const dst, socklen_t const cnt) { 5469 if (af == AF_INET) { 5470 struct sockaddr_in in; 5471 memset(&in, 0, sizeof(in)); 5472 in.sin_family = AF_INET; 5473 memcpy(&in.sin_addr, src, sizeof(struct in_addr)); 5474 getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST); 5475 return dst; 5476 } else if (af == AF_INET6) { 5477 struct sockaddr_in6 in; 5478 memset(&in, 0, sizeof(in)); 5479 in.sin6_family = AF_INET6; 5480 memcpy(&in.sin6_addr, src, sizeof(struct in_addr6)); 5481 getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST); 5482 return dst; 5483 } 5484 5485 return NULL; 5486 } 5487 enet_address_get_host_ip(ENetAddress * address,char * name,size_t nameLength)5488 int enet_address_get_host_ip(ENetAddress *address, char *name, size_t nameLength) { 5489 if (enet_ntop(AF_INET6, (PVOID)&address->host, name, nameLength) == NULL) { 5490 return -1; 5491 } 5492 5493 return 0; 5494 } 5495 enet_address_get_host(ENetAddress * address,char * name,size_t nameLength)5496 int enet_address_get_host(ENetAddress *address, char *name, size_t nameLength) { 5497 struct in6_addr in; 5498 struct hostent *hostEntry = NULL; 5499 5500 in = address->host; 5501 hostEntry = gethostbyaddr((char *)&in, sizeof(struct in6_addr), AF_INET6); 5502 5503 if (hostEntry == NULL) { 5504 return enet_address_get_host_ip(address, name, nameLength); 5505 } else { 5506 size_t hostLen = strlen(hostEntry->h_name); 5507 if (hostLen >= nameLength) { 5508 return -1; 5509 } 5510 memcpy(name, hostEntry->h_name, hostLen + 1); 5511 } 5512 5513 return 0; 5514 } 5515 enet_socket_bind(ENetSocket socket,ENetAddress * address)5516 int enet_socket_bind(ENetSocket socket, ENetAddress *address) { 5517 struct sockaddr_in6 sin; 5518 memset(&sin, 0, sizeof(struct sockaddr_in6)); 5519 sin.sin6_family = AF_INET6; 5520 5521 if (address != NULL) { 5522 sin.sin6_port = ENET_HOST_TO_NET_16 (address->port); 5523 sin.sin6_addr = address->host; 5524 sin.sin6_scope_id = address->sin6_scope_id; 5525 } else { 5526 sin.sin6_port = 0; 5527 sin.sin6_addr = in6addr_any; 5528 sin.sin6_scope_id = 0; 5529 } 5530 5531 return bind(socket, (struct sockaddr *) &sin, sizeof(struct sockaddr_in6)) == SOCKET_ERROR ? -1 : 0; 5532 } 5533 enet_socket_get_address(ENetSocket socket,ENetAddress * address)5534 int enet_socket_get_address(ENetSocket socket, ENetAddress *address) { 5535 struct sockaddr_in6 sin; 5536 int sinLength = sizeof(struct sockaddr_in6); 5537 5538 if (getsockname(socket, (struct sockaddr *) &sin, &sinLength) == -1) { 5539 return -1; 5540 } 5541 5542 address->host = sin.sin6_addr; 5543 address->port = ENET_NET_TO_HOST_16(sin.sin6_port); 5544 address->sin6_scope_id = sin.sin6_scope_id; 5545 5546 return 0; 5547 } 5548 enet_socket_listen(ENetSocket socket,int backlog)5549 int enet_socket_listen(ENetSocket socket, int backlog) { 5550 return listen(socket, backlog < 0 ? SOMAXCONN : backlog) == SOCKET_ERROR ? -1 : 0; 5551 } 5552 enet_socket_create(ENetSocketType type)5553 ENetSocket enet_socket_create(ENetSocketType type) { 5554 return socket(PF_INET6, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); 5555 } 5556 enet_socket_set_option(ENetSocket socket,ENetSocketOption option,int value)5557 int enet_socket_set_option(ENetSocket socket, ENetSocketOption option, int value) { 5558 int result = SOCKET_ERROR; 5559 5560 switch (option) { 5561 case ENET_SOCKOPT_NONBLOCK: { 5562 u_long nonBlocking = (u_long) value; 5563 result = ioctlsocket(socket, FIONBIO, &nonBlocking); 5564 break; 5565 } 5566 5567 case ENET_SOCKOPT_BROADCAST: 5568 result = setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char *)&value, sizeof(int)); 5569 break; 5570 5571 case ENET_SOCKOPT_REUSEADDR: 5572 result = setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (char *)&value, sizeof(int)); 5573 break; 5574 5575 case ENET_SOCKOPT_RCVBUF: 5576 result = setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (char *)&value, sizeof(int)); 5577 break; 5578 5579 case ENET_SOCKOPT_SNDBUF: 5580 result = setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char *)&value, sizeof(int)); 5581 break; 5582 5583 case ENET_SOCKOPT_RCVTIMEO: 5584 result = setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&value, sizeof(int)); 5585 break; 5586 5587 case ENET_SOCKOPT_SNDTIMEO: 5588 result = setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&value, sizeof(int)); 5589 break; 5590 5591 case ENET_SOCKOPT_NODELAY: 5592 result = setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char *)&value, sizeof(int)); 5593 break; 5594 5595 case ENET_SOCKOPT_IPV6_V6ONLY: 5596 result = setsockopt(socket, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&value, sizeof(int)); 5597 break; 5598 5599 default: 5600 break; 5601 } 5602 return result == SOCKET_ERROR ? -1 : 0; 5603 } /* enet_socket_set_option */ 5604 enet_socket_get_option(ENetSocket socket,ENetSocketOption option,int * value)5605 int enet_socket_get_option(ENetSocket socket, ENetSocketOption option, int *value) { 5606 int result = SOCKET_ERROR, len; 5607 5608 switch (option) { 5609 case ENET_SOCKOPT_ERROR: 5610 len = sizeof(int); 5611 result = getsockopt(socket, SOL_SOCKET, SO_ERROR, (char *)value, &len); 5612 break; 5613 5614 default: 5615 break; 5616 } 5617 return result == SOCKET_ERROR ? -1 : 0; 5618 } 5619 enet_socket_connect(ENetSocket socket,ENetAddress * address)5620 int enet_socket_connect(ENetSocket socket, ENetAddress *address) { 5621 struct sockaddr_in6 sin; 5622 int result; 5623 5624 memset(&sin, 0, sizeof(struct sockaddr_in6)); 5625 5626 sin.sin6_family = AF_INET6; 5627 sin.sin6_port = ENET_HOST_TO_NET_16(address->port); 5628 sin.sin6_addr = address->host; 5629 sin.sin6_scope_id = address->sin6_scope_id; 5630 5631 result = connect(socket, (struct sockaddr *) &sin, sizeof(struct sockaddr_in6)); 5632 if (result == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK) { 5633 return -1; 5634 } 5635 5636 return 0; 5637 } 5638 enet_socket_accept(ENetSocket socket,ENetAddress * address)5639 ENetSocket enet_socket_accept(ENetSocket socket, ENetAddress *address) { 5640 SOCKET result; 5641 struct sockaddr_in6 sin; 5642 int sinLength = sizeof(struct sockaddr_in6); 5643 5644 result = accept(socket, address != NULL ? (struct sockaddr *)&sin : NULL, address != NULL ? &sinLength : NULL); 5645 5646 if (result == INVALID_SOCKET) { 5647 return ENET_SOCKET_NULL; 5648 } 5649 5650 if (address != NULL) { 5651 address->host = sin.sin6_addr; 5652 address->port = ENET_NET_TO_HOST_16(sin.sin6_port); 5653 address->sin6_scope_id = sin.sin6_scope_id; 5654 } 5655 5656 return result; 5657 } 5658 enet_socket_shutdown(ENetSocket socket,ENetSocketShutdown how)5659 int enet_socket_shutdown(ENetSocket socket, ENetSocketShutdown how) { 5660 return shutdown(socket, (int) how) == SOCKET_ERROR ? -1 : 0; 5661 } 5662 enet_socket_destroy(ENetSocket socket)5663 void enet_socket_destroy(ENetSocket socket) { 5664 if (socket != INVALID_SOCKET) { 5665 closesocket(socket); 5666 } 5667 } 5668 enet_socket_send(ENetSocket socket,ENetAddress * address,ENetBuffer * buffers,size_t bufferCount)5669 int enet_socket_send(ENetSocket socket, ENetAddress *address, ENetBuffer *buffers, size_t bufferCount) { 5670 struct sockaddr_in6 sin; 5671 DWORD sentLength; 5672 5673 if (address != NULL) { 5674 memset(&sin, 0, sizeof(struct sockaddr_in6)); 5675 5676 sin.sin6_family = AF_INET6; 5677 sin.sin6_port = ENET_HOST_TO_NET_16(address->port); 5678 sin.sin6_addr = address->host; 5679 sin.sin6_scope_id = address->sin6_scope_id; 5680 } 5681 5682 if (WSASendTo(socket, 5683 (LPWSABUF) buffers, 5684 (DWORD) bufferCount, 5685 &sentLength, 5686 0, 5687 address != NULL ? (struct sockaddr *) &sin : NULL, 5688 address != NULL ? sizeof(struct sockaddr_in6) : 0, 5689 NULL, 5690 NULL) == SOCKET_ERROR 5691 ) { 5692 return (WSAGetLastError() == WSAEWOULDBLOCK) ? 0 : -1; 5693 } 5694 5695 return (int) sentLength; 5696 } 5697 enet_socket_receive(ENetSocket socket,ENetAddress * address,ENetBuffer * buffers,size_t bufferCount)5698 int enet_socket_receive(ENetSocket socket, ENetAddress *address, ENetBuffer *buffers, size_t bufferCount) { 5699 INT sinLength = sizeof(struct sockaddr_in6); 5700 DWORD flags = 0, recvLength; 5701 struct sockaddr_in6 sin; 5702 5703 if (WSARecvFrom(socket, 5704 (LPWSABUF) buffers, 5705 (DWORD) bufferCount, 5706 &recvLength, 5707 &flags, 5708 address != NULL ? (struct sockaddr *) &sin : NULL, 5709 address != NULL ? &sinLength : NULL, 5710 NULL, 5711 NULL) == SOCKET_ERROR 5712 ) { 5713 switch (WSAGetLastError()) { 5714 case WSAEWOULDBLOCK: 5715 case WSAECONNRESET: 5716 return 0; 5717 } 5718 5719 return -1; 5720 } 5721 5722 if (flags & MSG_PARTIAL) { 5723 return -1; 5724 } 5725 5726 if (address != NULL) { 5727 address->host = sin.sin6_addr; 5728 address->port = ENET_NET_TO_HOST_16(sin.sin6_port); 5729 address->sin6_scope_id = sin.sin6_scope_id; 5730 } 5731 5732 return (int) recvLength; 5733 } /* enet_socket_receive */ 5734 enet_socketset_select(ENetSocket maxSocket,ENetSocketSet * readSet,ENetSocketSet * writeSet,enet_uint32 timeout)5735 int enet_socketset_select(ENetSocket maxSocket, ENetSocketSet *readSet, ENetSocketSet *writeSet, enet_uint32 timeout) { 5736 struct timeval timeVal; 5737 5738 timeVal.tv_sec = timeout / 1000; 5739 timeVal.tv_usec = (timeout % 1000) * 1000; 5740 5741 return select(maxSocket + 1, readSet, writeSet, NULL, &timeVal); 5742 } 5743 enet_socket_wait(ENetSocket socket,enet_uint32 * condition,enet_uint64 timeout)5744 int enet_socket_wait(ENetSocket socket, enet_uint32 *condition, enet_uint64 timeout) { 5745 fd_set readSet, writeSet; 5746 struct timeval timeVal; 5747 int selectCount; 5748 5749 timeVal.tv_sec = timeout / 1000; 5750 timeVal.tv_usec = (timeout % 1000) * 1000; 5751 5752 FD_ZERO(&readSet); 5753 FD_ZERO(&writeSet); 5754 5755 if (*condition & ENET_SOCKET_WAIT_SEND) { 5756 FD_SET(socket, &writeSet); 5757 } 5758 5759 if (*condition & ENET_SOCKET_WAIT_RECEIVE) { 5760 FD_SET(socket, &readSet); 5761 } 5762 5763 selectCount = select(socket + 1, &readSet, &writeSet, NULL, &timeVal); 5764 5765 if (selectCount < 0) { 5766 return -1; 5767 } 5768 5769 *condition = ENET_SOCKET_WAIT_NONE; 5770 5771 if (selectCount == 0) { 5772 return 0; 5773 } 5774 5775 if (FD_ISSET(socket, &writeSet)) { 5776 *condition |= ENET_SOCKET_WAIT_SEND; 5777 } 5778 5779 if (FD_ISSET(socket, &readSet)) { 5780 *condition |= ENET_SOCKET_WAIT_RECEIVE; 5781 } 5782 5783 return 0; 5784 } /* enet_socket_wait */ 5785 5786 #endif // _WIN32 5787 5788 5789 #ifdef __cplusplus 5790 } 5791 #endif 5792 5793 #endif // ENET_IMPLEMENTATION 5794 #endif // ENET_INCLUDE_H 5795