3
@brief ENet protocol functions
7
#define ENET_BUILDING_LIB 1
8
#include "enet/utility.h"
10
#include "enet/enet.h"
12
static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] =
15
sizeof (ENetProtocolAcknowledge),
16
sizeof (ENetProtocolConnect),
17
sizeof (ENetProtocolVerifyConnect),
18
sizeof (ENetProtocolDisconnect),
19
sizeof (ENetProtocolPing),
20
sizeof (ENetProtocolSendReliable),
21
sizeof (ENetProtocolSendUnreliable),
22
sizeof (ENetProtocolSendFragment),
23
sizeof (ENetProtocolSendUnsequenced),
24
sizeof (ENetProtocolBandwidthLimit),
25
sizeof (ENetProtocolThrottleConfigure),
26
sizeof (ENetProtocolSendFragment)
30
enet_protocol_command_size (enet_uint8 commandNumber)
32
return commandSizes [commandNumber & ENET_PROTOCOL_COMMAND_MASK];
36
enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
38
while (! enet_list_empty (& host -> dispatchQueue))
40
ENetPeer * peer = (ENetPeer *) enet_list_remove (enet_list_begin (& host -> dispatchQueue));
42
peer -> needsDispatch = 0;
44
switch (peer -> state)
46
case ENET_PEER_STATE_CONNECTION_PENDING:
47
case ENET_PEER_STATE_CONNECTION_SUCCEEDED:
48
peer -> state = ENET_PEER_STATE_CONNECTED;
50
event -> type = ENET_EVENT_TYPE_CONNECT;
52
event -> data = peer -> eventData;
56
case ENET_PEER_STATE_ZOMBIE:
57
host -> recalculateBandwidthLimits = 1;
59
event -> type = ENET_EVENT_TYPE_DISCONNECT;
61
event -> data = peer -> eventData;
63
enet_peer_reset (peer);
67
case ENET_PEER_STATE_CONNECTED:
68
if (enet_list_empty (& peer -> dispatchedCommands))
71
event -> packet = enet_peer_receive (peer, & event -> channelID);
72
if (event -> packet == NULL)
75
event -> type = ENET_EVENT_TYPE_RECEIVE;
78
if (! enet_list_empty (& peer -> dispatchedCommands))
80
peer -> needsDispatch = 1;
82
enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList);
93
enet_protocol_dispatch_state (ENetHost * host, ENetPeer * peer, ENetPeerState state)
95
peer -> state = state;
97
if (! peer -> needsDispatch)
99
enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList);
101
peer -> needsDispatch = 1;
106
enet_protocol_notify_connect (ENetHost * host, ENetPeer * peer, ENetEvent * event)
108
host -> recalculateBandwidthLimits = 1;
112
peer -> state = ENET_PEER_STATE_CONNECTED;
114
event -> type = ENET_EVENT_TYPE_CONNECT;
115
event -> peer = peer;
116
event -> data = peer -> eventData;
119
enet_protocol_dispatch_state (host, peer, peer -> state == ENET_PEER_STATE_CONNECTING ? ENET_PEER_STATE_CONNECTION_SUCCEEDED : ENET_PEER_STATE_CONNECTION_PENDING);
123
enet_protocol_notify_disconnect (ENetHost * host, ENetPeer * peer, ENetEvent * event)
125
if (peer -> state >= ENET_PEER_STATE_CONNECTION_PENDING)
126
host -> recalculateBandwidthLimits = 1;
128
if (peer -> state != ENET_PEER_STATE_CONNECTING && peer -> state < ENET_PEER_STATE_CONNECTION_SUCCEEDED)
129
enet_peer_reset (peer);
133
event -> type = ENET_EVENT_TYPE_DISCONNECT;
134
event -> peer = peer;
137
enet_peer_reset (peer);
141
peer -> eventData = 0;
143
enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);
148
enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer)
150
ENetOutgoingCommand * outgoingCommand;
152
while (! enet_list_empty (& peer -> sentUnreliableCommands))
154
outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentUnreliableCommands);
156
enet_list_remove (& outgoingCommand -> outgoingCommandList);
158
if (outgoingCommand -> packet != NULL)
160
-- outgoingCommand -> packet -> referenceCount;
162
if (outgoingCommand -> packet -> referenceCount == 0)
163
enet_packet_destroy (outgoingCommand -> packet);
166
enet_free (outgoingCommand);
170
static ENetProtocolCommand
171
enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliableSequenceNumber, enet_uint8 channelID)
173
ENetOutgoingCommand * outgoingCommand = NULL;
174
ENetListIterator currentCommand;
175
ENetProtocolCommand commandNumber;
178
for (currentCommand = enet_list_begin (& peer -> sentReliableCommands);
179
currentCommand != enet_list_end (& peer -> sentReliableCommands);
180
currentCommand = enet_list_next (currentCommand))
182
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
184
if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber &&
185
outgoingCommand -> command.header.channelID == channelID)
189
if (currentCommand == enet_list_end (& peer -> sentReliableCommands))
191
for (currentCommand = enet_list_begin (& peer -> outgoingReliableCommands);
192
currentCommand != enet_list_end (& peer -> outgoingReliableCommands);
193
currentCommand = enet_list_next (currentCommand))
195
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
197
if (outgoingCommand -> sendAttempts < 1) return ENET_PROTOCOL_COMMAND_NONE;
199
if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber &&
200
outgoingCommand -> command.header.channelID == channelID)
204
if (currentCommand == enet_list_end (& peer -> outgoingReliableCommands))
205
return ENET_PROTOCOL_COMMAND_NONE;
210
if (channelID < peer -> channelCount)
212
ENetChannel * channel = & peer -> channels [channelID];
213
enet_uint16 reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
214
if (channel -> reliableWindows [reliableWindow] > 0)
216
-- channel -> reliableWindows [reliableWindow];
217
if (! channel -> reliableWindows [reliableWindow])
218
channel -> usedReliableWindows &= ~ (1 << reliableWindow);
222
commandNumber = (ENetProtocolCommand) (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK);
224
enet_list_remove (& outgoingCommand -> outgoingCommandList);
226
if (outgoingCommand -> packet != NULL)
229
peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength;
231
-- outgoingCommand -> packet -> referenceCount;
233
if (outgoingCommand -> packet -> referenceCount == 0)
234
enet_packet_destroy (outgoingCommand -> packet);
237
enet_free (outgoingCommand);
239
if (enet_list_empty (& peer -> sentReliableCommands))
240
return commandNumber;
242
outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentReliableCommands);
244
peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout;
246
return commandNumber;
250
enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENetProtocol * command)
252
enet_uint8 incomingSessionID, outgoingSessionID;
253
enet_uint32 mtu, windowSize;
254
ENetChannel * channel;
256
ENetPeer * currentPeer;
257
ENetProtocol verifyCommand;
259
channelCount = ENET_NET_TO_HOST_32 (command -> connect.channelCount);
261
if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT ||
262
channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
265
for (currentPeer = host -> peers;
266
currentPeer < & host -> peers [host -> peerCount];
269
if (currentPeer -> state != ENET_PEER_STATE_DISCONNECTED &&
270
currentPeer -> address.host == host -> receivedAddress.host &&
271
currentPeer -> address.port == host -> receivedAddress.port &&
272
currentPeer -> connectID == command -> connect.connectID)
276
for (currentPeer = host -> peers;
277
currentPeer < & host -> peers [host -> peerCount];
280
if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED)
284
if (currentPeer >= & host -> peers [host -> peerCount])
287
if (channelCount > host -> channelLimit)
288
channelCount = host -> channelLimit;
289
currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
290
if (currentPeer -> channels == NULL)
292
currentPeer -> channelCount = channelCount;
293
currentPeer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT;
294
currentPeer -> connectID = command -> connect.connectID;
295
currentPeer -> address = host -> receivedAddress;
296
currentPeer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID);
297
currentPeer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth);
298
currentPeer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.outgoingBandwidth);
299
currentPeer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleInterval);
300
currentPeer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleAcceleration);
301
currentPeer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleDeceleration);
302
currentPeer -> eventData = ENET_NET_TO_HOST_32 (command -> connect.data);
304
incomingSessionID = command -> connect.incomingSessionID == 0xFF ? currentPeer -> outgoingSessionID : command -> connect.incomingSessionID;
305
incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT);
306
if (incomingSessionID == currentPeer -> outgoingSessionID)
307
incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT);
308
currentPeer -> outgoingSessionID = incomingSessionID;
310
outgoingSessionID = command -> connect.outgoingSessionID == 0xFF ? currentPeer -> incomingSessionID : command -> connect.outgoingSessionID;
311
outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT);
312
if (outgoingSessionID == currentPeer -> incomingSessionID)
313
outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT);
314
currentPeer -> incomingSessionID = outgoingSessionID;
316
for (channel = currentPeer -> channels;
317
channel < & currentPeer -> channels [channelCount];
320
channel -> outgoingReliableSequenceNumber = 0;
321
channel -> outgoingUnreliableSequenceNumber = 0;
322
channel -> incomingReliableSequenceNumber = 0;
323
channel -> incomingUnreliableSequenceNumber = 0;
325
enet_list_clear (& channel -> incomingReliableCommands);
326
enet_list_clear (& channel -> incomingUnreliableCommands);
328
channel -> usedReliableWindows = 0;
329
memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows));
332
mtu = ENET_NET_TO_HOST_32 (command -> connect.mtu);
334
if (mtu < ENET_PROTOCOL_MINIMUM_MTU)
335
mtu = ENET_PROTOCOL_MINIMUM_MTU;
337
if (mtu > ENET_PROTOCOL_MAXIMUM_MTU)
338
mtu = ENET_PROTOCOL_MAXIMUM_MTU;
340
currentPeer -> mtu = mtu;
342
if (host -> outgoingBandwidth == 0 &&
343
currentPeer -> incomingBandwidth == 0)
344
currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
346
if (host -> outgoingBandwidth == 0 ||
347
currentPeer -> incomingBandwidth == 0)
348
currentPeer -> windowSize = (ENET_MAX (host -> outgoingBandwidth, currentPeer -> incomingBandwidth) /
349
ENET_PEER_WINDOW_SIZE_SCALE) *
350
ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
352
currentPeer -> windowSize = (ENET_MIN (host -> outgoingBandwidth, currentPeer -> incomingBandwidth) /
353
ENET_PEER_WINDOW_SIZE_SCALE) *
354
ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
356
if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
357
currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
359
if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
360
currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
362
if (host -> incomingBandwidth == 0)
363
windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
365
windowSize = (host -> incomingBandwidth / ENET_PEER_WINDOW_SIZE_SCALE) *
366
ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
368
if (windowSize > ENET_NET_TO_HOST_32 (command -> connect.windowSize))
369
windowSize = ENET_NET_TO_HOST_32 (command -> connect.windowSize);
371
if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
372
windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
374
if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
375
windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
377
verifyCommand.header.command = ENET_PROTOCOL_COMMAND_VERIFY_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
378
verifyCommand.header.channelID = 0xFF;
379
verifyCommand.verifyConnect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
380
verifyCommand.verifyConnect.incomingSessionID = incomingSessionID;
381
verifyCommand.verifyConnect.outgoingSessionID = outgoingSessionID;
382
verifyCommand.verifyConnect.mtu = ENET_HOST_TO_NET_16 (currentPeer -> mtu);
383
verifyCommand.verifyConnect.windowSize = ENET_HOST_TO_NET_32 (windowSize);
384
verifyCommand.verifyConnect.channelCount = ENET_HOST_TO_NET_32 (channelCount);
385
verifyCommand.verifyConnect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth);
386
verifyCommand.verifyConnect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
387
verifyCommand.verifyConnect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval);
388
verifyCommand.verifyConnect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration);
389
verifyCommand.verifyConnect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration);
390
verifyCommand.verifyConnect.connectID = currentPeer -> connectID;
392
enet_peer_queue_outgoing_command (currentPeer, & verifyCommand, NULL, 0, 0);
398
enet_protocol_handle_send_reliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
403
if (command -> header.channelID >= peer -> channelCount ||
404
(peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
407
dataLength = ENET_NET_TO_HOST_16 (command -> sendReliable.dataLength);
408
* currentData += dataLength;
409
if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
410
* currentData < host -> receivedData ||
411
* currentData > & host -> receivedData [host -> receivedDataLength])
414
packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendReliable),
416
ENET_PACKET_FLAG_RELIABLE);
417
if (packet == NULL ||
418
enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL)
425
enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
428
enet_uint32 unsequencedGroup, index;
431
if (command -> header.channelID >= peer -> channelCount ||
432
(peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
435
dataLength = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.dataLength);
436
* currentData += dataLength;
437
if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
438
* currentData < host -> receivedData ||
439
* currentData > & host -> receivedData [host -> receivedDataLength])
442
unsequencedGroup = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.unsequencedGroup);
443
index = unsequencedGroup % ENET_PEER_UNSEQUENCED_WINDOW_SIZE;
445
if (unsequencedGroup < peer -> incomingUnsequencedGroup)
446
unsequencedGroup += 0x10000;
448
if (unsequencedGroup >= (enet_uint32) peer -> incomingUnsequencedGroup + ENET_PEER_FREE_UNSEQUENCED_WINDOWS * ENET_PEER_UNSEQUENCED_WINDOW_SIZE)
451
unsequencedGroup &= 0xFFFF;
453
if (unsequencedGroup - index != peer -> incomingUnsequencedGroup)
455
peer -> incomingUnsequencedGroup = unsequencedGroup - index;
457
memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow));
460
if (peer -> unsequencedWindow [index / 32] & (1 << (index % 32)))
463
packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnsequenced),
465
ENET_PACKET_FLAG_UNSEQUENCED);
466
if (packet == NULL ||
467
enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL)
470
peer -> unsequencedWindow [index / 32] |= 1 << (index % 32);
476
enet_protocol_handle_send_unreliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
481
if (command -> header.channelID >= peer -> channelCount ||
482
(peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
485
dataLength = ENET_NET_TO_HOST_16 (command -> sendUnreliable.dataLength);
486
* currentData += dataLength;
487
if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
488
* currentData < host -> receivedData ||
489
* currentData > & host -> receivedData [host -> receivedDataLength])
492
packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnreliable),
495
if (packet == NULL ||
496
enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL)
503
enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
505
enet_uint32 fragmentNumber,
511
ENetChannel * channel;
512
enet_uint16 startWindow, currentWindow;
513
ENetListIterator currentCommand;
514
ENetIncomingCommand * startCommand = NULL;
516
if (command -> header.channelID >= peer -> channelCount ||
517
(peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
520
fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength);
521
* currentData += fragmentLength;
522
if (fragmentLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
523
* currentData < host -> receivedData ||
524
* currentData > & host -> receivedData [host -> receivedDataLength])
527
channel = & peer -> channels [command -> header.channelID];
528
startSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendFragment.startSequenceNumber);
529
startWindow = startSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
530
currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
532
if (startSequenceNumber < channel -> incomingReliableSequenceNumber)
533
startWindow += ENET_PEER_RELIABLE_WINDOWS;
535
if (startWindow < currentWindow || startWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1)
538
fragmentNumber = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentNumber);
539
fragmentCount = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentCount);
540
fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset);
541
totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength);
543
if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT ||
544
fragmentNumber >= fragmentCount ||
545
totalLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
546
fragmentOffset >= totalLength ||
547
fragmentLength > totalLength - fragmentOffset)
550
for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands));
551
currentCommand != enet_list_end (& channel -> incomingReliableCommands);
552
currentCommand = enet_list_previous (currentCommand))
554
ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand;
556
if (startSequenceNumber >= channel -> incomingReliableSequenceNumber)
558
if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
562
if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
565
if (incomingCommand -> reliableSequenceNumber <= startSequenceNumber)
567
if (incomingCommand -> reliableSequenceNumber < startSequenceNumber)
570
if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_FRAGMENT ||
571
totalLength != incomingCommand -> packet -> dataLength ||
572
fragmentCount != incomingCommand -> fragmentCount)
575
startCommand = incomingCommand;
580
if (startCommand == NULL)
582
ENetProtocol hostCommand = * command;
583
ENetPacket * packet = enet_packet_create (NULL, totalLength, ENET_PACKET_FLAG_RELIABLE);
587
hostCommand.header.reliableSequenceNumber = startSequenceNumber;
589
startCommand = enet_peer_queue_incoming_command (peer, & hostCommand, packet, fragmentCount);
590
if (startCommand == NULL)
594
if ((startCommand -> fragments [fragmentNumber / 32] & (1 << (fragmentNumber % 32))) == 0)
596
-- startCommand -> fragmentsRemaining;
598
startCommand -> fragments [fragmentNumber / 32] |= (1 << (fragmentNumber % 32));
600
if (fragmentOffset + fragmentLength > startCommand -> packet -> dataLength)
601
fragmentLength = startCommand -> packet -> dataLength - fragmentOffset;
603
memcpy (startCommand -> packet -> data + fragmentOffset,
604
(enet_uint8 *) command + sizeof (ENetProtocolSendFragment),
607
if (startCommand -> fragmentsRemaining <= 0)
608
enet_peer_dispatch_incoming_reliable_commands (peer, channel);
615
enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
617
enet_uint32 fragmentNumber,
621
reliableSequenceNumber,
624
enet_uint16 reliableWindow, currentWindow;
625
ENetChannel * channel;
626
ENetListIterator currentCommand;
627
ENetIncomingCommand * startCommand = NULL;
629
if (command -> header.channelID >= peer -> channelCount ||
630
(peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
633
fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength);
634
* currentData += fragmentLength;
635
if (fragmentLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
636
* currentData < host -> receivedData ||
637
* currentData > & host -> receivedData [host -> receivedDataLength])
640
channel = & peer -> channels [command -> header.channelID];
641
reliableSequenceNumber = command -> header.reliableSequenceNumber;
642
startSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendFragment.startSequenceNumber);
644
reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
645
currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
647
if (reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
648
reliableWindow += ENET_PEER_RELIABLE_WINDOWS;
650
if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1)
653
if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber &&
654
startSequenceNumber <= channel -> incomingUnreliableSequenceNumber)
657
fragmentNumber = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentNumber);
658
fragmentCount = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentCount);
659
fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset);
660
totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength);
662
if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT ||
663
fragmentNumber >= fragmentCount ||
664
totalLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
665
fragmentOffset >= totalLength ||
666
fragmentLength > totalLength - fragmentOffset)
669
for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands));
670
currentCommand != enet_list_end (& channel -> incomingUnreliableCommands);
671
currentCommand = enet_list_previous (currentCommand))
673
ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand;
675
if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
677
if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
681
if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
684
if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber)
687
if (incomingCommand -> reliableSequenceNumber > reliableSequenceNumber)
690
if (incomingCommand -> unreliableSequenceNumber <= startSequenceNumber)
692
if (incomingCommand -> unreliableSequenceNumber < startSequenceNumber)
695
if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT ||
696
totalLength != incomingCommand -> packet -> dataLength ||
697
fragmentCount != incomingCommand -> fragmentCount)
700
startCommand = incomingCommand;
705
if (startCommand == NULL)
707
ENetPacket * packet = enet_packet_create (NULL, totalLength, ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT);
711
startCommand = enet_peer_queue_incoming_command (peer, command, packet, fragmentCount);
712
if (startCommand == NULL)
716
if ((startCommand -> fragments [fragmentNumber / 32] & (1 << (fragmentNumber % 32))) == 0)
718
-- startCommand -> fragmentsRemaining;
720
startCommand -> fragments [fragmentNumber / 32] |= (1 << (fragmentNumber % 32));
722
if (fragmentOffset + fragmentLength > startCommand -> packet -> dataLength)
723
fragmentLength = startCommand -> packet -> dataLength - fragmentOffset;
725
memcpy (startCommand -> packet -> data + fragmentOffset,
726
(enet_uint8 *) command + sizeof (ENetProtocolSendFragment),
729
if (startCommand -> fragmentsRemaining <= 0)
730
enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
737
enet_protocol_handle_ping (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
743
enet_protocol_handle_bandwidth_limit (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
745
peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.incomingBandwidth);
746
peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.outgoingBandwidth);
748
if (peer -> incomingBandwidth == 0 && host -> outgoingBandwidth == 0)
749
peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
751
peer -> windowSize = (ENET_MIN (peer -> incomingBandwidth, host -> outgoingBandwidth) /
752
ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
754
if (peer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
755
peer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
757
if (peer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
758
peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
764
enet_protocol_handle_throttle_configure (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
766
peer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleInterval);
767
peer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleAcceleration);
768
peer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleDeceleration);
774
enet_protocol_handle_disconnect (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
776
if (peer -> state == ENET_PEER_STATE_ZOMBIE || peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT)
779
enet_peer_reset_queues (peer);
781
if (peer -> state == ENET_PEER_STATE_CONNECTION_SUCCEEDED || peer -> state == ENET_PEER_STATE_DISCONNECTING)
782
enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);
784
if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
786
if (peer -> state == ENET_PEER_STATE_CONNECTION_PENDING) host -> recalculateBandwidthLimits = 1;
788
enet_peer_reset (peer);
791
if (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
792
peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT;
794
enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);
796
if (peer -> state != ENET_PEER_STATE_DISCONNECTED)
797
peer -> eventData = ENET_NET_TO_HOST_32 (command -> disconnect.data);
803
enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command)
805
enet_uint32 roundTripTime,
807
receivedReliableSequenceNumber;
808
ENetProtocolCommand commandNumber;
810
receivedSentTime = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedSentTime);
811
receivedSentTime |= host -> serviceTime & 0xFFFF0000;
812
if ((receivedSentTime & 0x8000) > (host -> serviceTime & 0x8000))
813
receivedSentTime -= 0x10000;
815
if (ENET_TIME_LESS (host -> serviceTime, receivedSentTime))
818
peer -> lastReceiveTime = host -> serviceTime;
819
peer -> earliestTimeout = 0;
821
roundTripTime = ENET_TIME_DIFFERENCE (host -> serviceTime, receivedSentTime);
823
enet_peer_throttle (peer, roundTripTime);
825
peer -> roundTripTimeVariance -= peer -> roundTripTimeVariance / 4;
827
if (roundTripTime >= peer -> roundTripTime)
829
peer -> roundTripTime += (roundTripTime - peer -> roundTripTime) / 8;
830
peer -> roundTripTimeVariance += (roundTripTime - peer -> roundTripTime) / 4;
834
peer -> roundTripTime -= (peer -> roundTripTime - roundTripTime) / 8;
835
peer -> roundTripTimeVariance += (peer -> roundTripTime - roundTripTime) / 4;
838
if (peer -> roundTripTime < peer -> lowestRoundTripTime)
839
peer -> lowestRoundTripTime = peer -> roundTripTime;
841
if (peer -> roundTripTimeVariance > peer -> highestRoundTripTimeVariance)
842
peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance;
844
if (peer -> packetThrottleEpoch == 0 ||
845
ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> packetThrottleEpoch) >= peer -> packetThrottleInterval)
847
peer -> lastRoundTripTime = peer -> lowestRoundTripTime;
848
peer -> lastRoundTripTimeVariance = peer -> highestRoundTripTimeVariance;
849
peer -> lowestRoundTripTime = peer -> roundTripTime;
850
peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance;
851
peer -> packetThrottleEpoch = host -> serviceTime;
854
receivedReliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedReliableSequenceNumber);
856
commandNumber = enet_protocol_remove_sent_reliable_command (peer, receivedReliableSequenceNumber, command -> header.channelID);
858
switch (peer -> state)
860
case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT:
861
if (commandNumber != ENET_PROTOCOL_COMMAND_VERIFY_CONNECT)
864
enet_protocol_notify_connect (host, peer, event);
867
case ENET_PEER_STATE_DISCONNECTING:
868
if (commandNumber != ENET_PROTOCOL_COMMAND_DISCONNECT)
871
enet_protocol_notify_disconnect (host, peer, event);
874
case ENET_PEER_STATE_DISCONNECT_LATER:
875
if (enet_list_empty (& peer -> outgoingReliableCommands) &&
876
enet_list_empty (& peer -> outgoingUnreliableCommands) &&
877
enet_list_empty (& peer -> sentReliableCommands))
878
enet_peer_disconnect (peer, peer -> eventData);
886
enet_protocol_handle_verify_connect (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command)
888
enet_uint32 mtu, windowSize;
891
if (peer -> state != ENET_PEER_STATE_CONNECTING)
894
channelCount = ENET_NET_TO_HOST_32 (command -> verifyConnect.channelCount);
896
if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT || channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT ||
897
ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleInterval) != peer -> packetThrottleInterval ||
898
ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleAcceleration) != peer -> packetThrottleAcceleration ||
899
ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleDeceleration) != peer -> packetThrottleDeceleration ||
900
command -> verifyConnect.connectID != peer -> connectID)
902
peer -> eventData = 0;
904
enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);
909
enet_protocol_remove_sent_reliable_command (peer, 1, 0xFF);
911
if (channelCount < peer -> channelCount)
912
peer -> channelCount = channelCount;
914
peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> verifyConnect.outgoingPeerID);
915
peer -> incomingSessionID = command -> verifyConnect.incomingSessionID;
916
peer -> outgoingSessionID = command -> verifyConnect.outgoingSessionID;
918
mtu = ENET_NET_TO_HOST_32 (command -> verifyConnect.mtu);
920
if (mtu < ENET_PROTOCOL_MINIMUM_MTU)
921
mtu = ENET_PROTOCOL_MINIMUM_MTU;
923
if (mtu > ENET_PROTOCOL_MAXIMUM_MTU)
924
mtu = ENET_PROTOCOL_MAXIMUM_MTU;
926
if (mtu < peer -> mtu)
929
windowSize = ENET_NET_TO_HOST_32 (command -> verifyConnect.windowSize);
931
if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
932
windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
934
if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
935
windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
937
if (windowSize < peer -> windowSize)
938
peer -> windowSize = windowSize;
940
peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.incomingBandwidth);
941
peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.outgoingBandwidth);
943
enet_protocol_notify_connect (host, peer, event);
948
enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
950
ENetProtocolHeader * header;
951
ENetProtocol * command;
953
enet_uint8 * currentData;
955
enet_uint16 peerID, flags;
956
enet_uint8 sessionID;
958
if (host -> receivedDataLength < (size_t) & ((ENetProtocolHeader *) 0) -> sentTime)
961
header = (ENetProtocolHeader *) host -> receivedData;
963
peerID = ENET_NET_TO_HOST_16 (header -> peerID);
964
sessionID = (peerID & ENET_PROTOCOL_HEADER_SESSION_MASK) >> ENET_PROTOCOL_HEADER_SESSION_SHIFT;
965
flags = peerID & ENET_PROTOCOL_HEADER_FLAG_MASK;
966
peerID &= ~ (ENET_PROTOCOL_HEADER_FLAG_MASK | ENET_PROTOCOL_HEADER_SESSION_MASK);
968
headerSize = (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME ? sizeof (ENetProtocolHeader) : (size_t) & ((ENetProtocolHeader *) 0) -> sentTime);
969
if (host -> checksum != NULL)
970
headerSize += sizeof (enet_uint32);
972
if (peerID == ENET_PROTOCOL_MAXIMUM_PEER_ID)
975
if (peerID >= host -> peerCount)
979
peer = & host -> peers [peerID];
981
if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
982
peer -> state == ENET_PEER_STATE_ZOMBIE ||
983
((host -> receivedAddress.host != peer -> address.host ||
984
host -> receivedAddress.port != peer -> address.port) &&
985
peer -> address.host != ENET_HOST_BROADCAST) ||
986
(peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID &&
987
sessionID != peer -> incomingSessionID))
991
if (flags & ENET_PROTOCOL_HEADER_FLAG_COMPRESSED)
994
if (host -> compressor.context == NULL || host -> compressor.decompress == NULL)
997
originalSize = host -> compressor.decompress (host -> compressor.context,
998
host -> receivedData + headerSize,
999
host -> receivedDataLength - headerSize,
1000
host -> packetData [1] + headerSize,
1001
sizeof (host -> packetData [1]) - headerSize);
1002
if (originalSize <= 0 || originalSize > sizeof (host -> packetData [1]) - headerSize)
1005
memcpy (host -> packetData [1], header, headerSize);
1006
host -> receivedData = host -> packetData [1];
1007
host -> receivedDataLength = headerSize + originalSize;
1010
if (host -> checksum != NULL)
1012
enet_uint32 * checksum = (enet_uint32 *) & host -> receivedData [headerSize - sizeof (enet_uint32)],
1013
desiredChecksum = * checksum;
1016
* checksum = peer != NULL ? peer -> connectID : 0;
1018
buffer.data = host -> receivedData;
1019
buffer.dataLength = host -> receivedDataLength;
1021
if (host -> checksum (& buffer, 1) != desiredChecksum)
1027
peer -> address.host = host -> receivedAddress.host;
1028
peer -> address.port = host -> receivedAddress.port;
1029
peer -> incomingDataTotal += host -> receivedDataLength;
1032
currentData = host -> receivedData + headerSize;
1034
while (currentData < & host -> receivedData [host -> receivedDataLength])
1036
enet_uint8 commandNumber;
1039
command = (ENetProtocol *) currentData;
1041
if (currentData + sizeof (ENetProtocolCommandHeader) > & host -> receivedData [host -> receivedDataLength])
1044
commandNumber = command -> header.command & ENET_PROTOCOL_COMMAND_MASK;
1045
if (commandNumber >= ENET_PROTOCOL_COMMAND_COUNT)
1048
commandSize = commandSizes [commandNumber];
1049
if (commandSize == 0 || currentData + commandSize > & host -> receivedData [host -> receivedDataLength])
1052
currentData += commandSize;
1054
if (peer == NULL && commandNumber != ENET_PROTOCOL_COMMAND_CONNECT)
1057
command -> header.reliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> header.reliableSequenceNumber);
1059
switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK)
1061
case ENET_PROTOCOL_COMMAND_ACKNOWLEDGE:
1062
if (enet_protocol_handle_acknowledge (host, event, peer, command))
1066
case ENET_PROTOCOL_COMMAND_CONNECT:
1067
peer = enet_protocol_handle_connect (host, header, command);
1072
case ENET_PROTOCOL_COMMAND_VERIFY_CONNECT:
1073
if (enet_protocol_handle_verify_connect (host, event, peer, command))
1077
case ENET_PROTOCOL_COMMAND_DISCONNECT:
1078
if (enet_protocol_handle_disconnect (host, peer, command))
1082
case ENET_PROTOCOL_COMMAND_PING:
1083
if (enet_protocol_handle_ping (host, peer, command))
1087
case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
1088
if (enet_protocol_handle_send_reliable (host, peer, command, & currentData))
1092
case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE:
1093
if (enet_protocol_handle_send_unreliable (host, peer, command, & currentData))
1097
case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED:
1098
if (enet_protocol_handle_send_unsequenced (host, peer, command, & currentData))
1102
case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
1103
if (enet_protocol_handle_send_fragment (host, peer, command, & currentData))
1107
case ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT:
1108
if (enet_protocol_handle_bandwidth_limit (host, peer, command))
1112
case ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE:
1113
if (enet_protocol_handle_throttle_configure (host, peer, command))
1117
case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT:
1118
if (enet_protocol_handle_send_unreliable_fragment (host, peer, command, & currentData))
1127
(command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) != 0)
1129
enet_uint16 sentTime;
1131
if (! (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME))
1134
sentTime = ENET_NET_TO_HOST_16 (header -> sentTime);
1136
switch (peer -> state)
1138
case ENET_PEER_STATE_DISCONNECTING:
1139
case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT:
1142
case ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT:
1143
if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT)
1144
enet_peer_queue_acknowledgement (peer, command, sentTime);
1148
enet_peer_queue_acknowledgement (peer, command, sentTime);
1155
if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE)
1162
enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
1169
buffer.data = host -> packetData [0];
1170
buffer.dataLength = sizeof (host -> packetData [0]);
1172
receivedLength = enet_socket_receive (host -> socket,
1173
& host -> receivedAddress,
1177
if (receivedLength < 0)
1180
if (receivedLength == 0)
1183
host -> receivedData = host -> packetData [0];
1184
host -> receivedDataLength = receivedLength;
1186
host -> totalReceivedData += receivedLength;
1187
host -> totalReceivedPackets ++;
1189
switch (enet_protocol_handle_incoming_commands (host, event))
1206
enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer)
1208
ENetProtocol * command = & host -> commands [host -> commandCount];
1209
ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
1210
ENetAcknowledgement * acknowledgement;
1211
ENetListIterator currentAcknowledgement;
1213
currentAcknowledgement = enet_list_begin (& peer -> acknowledgements);
1215
while (currentAcknowledgement != enet_list_end (& peer -> acknowledgements))
1217
if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
1218
buffer >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
1219
peer -> mtu - host -> packetSize < sizeof (ENetProtocolAcknowledge))
1221
host -> continueSending = 1;
1226
acknowledgement = (ENetAcknowledgement *) currentAcknowledgement;
1228
currentAcknowledgement = enet_list_next (currentAcknowledgement);
1230
buffer -> data = command;
1231
buffer -> dataLength = sizeof (ENetProtocolAcknowledge);
1233
host -> packetSize += buffer -> dataLength;
1235
command -> header.command = ENET_PROTOCOL_COMMAND_ACKNOWLEDGE;
1236
command -> header.channelID = acknowledgement -> command.header.channelID;
1237
command -> acknowledge.receivedReliableSequenceNumber = ENET_HOST_TO_NET_16 (acknowledgement -> command.header.reliableSequenceNumber);
1238
command -> acknowledge.receivedSentTime = ENET_HOST_TO_NET_16 (acknowledgement -> sentTime);
1240
if ((acknowledgement -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT)
1241
enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);
1243
enet_list_remove (& acknowledgement -> acknowledgementList);
1244
enet_free (acknowledgement);
1250
host -> commandCount = command - host -> commands;
1251
host -> bufferCount = buffer - host -> buffers;
1255
enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
1257
ENetProtocol * command = & host -> commands [host -> commandCount];
1258
ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
1259
ENetOutgoingCommand * outgoingCommand;
1260
ENetListIterator currentCommand;
1262
currentCommand = enet_list_begin (& peer -> outgoingUnreliableCommands);
1264
while (currentCommand != enet_list_end (& peer -> outgoingUnreliableCommands))
1268
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
1269
commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK];
1271
if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
1272
buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
1273
peer -> mtu - host -> packetSize < commandSize ||
1274
(outgoingCommand -> packet != NULL &&
1275
peer -> mtu - host -> packetSize < commandSize + outgoingCommand -> fragmentLength))
1277
host -> continueSending = 1;
1282
currentCommand = enet_list_next (currentCommand);
1284
if (outgoingCommand -> packet != NULL && outgoingCommand -> fragmentOffset == 0)
1286
peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER;
1287
peer -> packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE;
1289
if (peer -> packetThrottleCounter > peer -> packetThrottle)
1291
enet_uint16 reliableSequenceNumber = outgoingCommand -> reliableSequenceNumber,
1292
unreliableSequenceNumber = outgoingCommand -> unreliableSequenceNumber;
1295
-- outgoingCommand -> packet -> referenceCount;
1297
if (outgoingCommand -> packet -> referenceCount == 0)
1298
enet_packet_destroy (outgoingCommand -> packet);
1300
enet_list_remove (& outgoingCommand -> outgoingCommandList);
1301
enet_free (outgoingCommand);
1303
if (currentCommand == enet_list_end (& peer -> outgoingUnreliableCommands))
1306
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
1307
if (outgoingCommand -> reliableSequenceNumber != reliableSequenceNumber ||
1308
outgoingCommand -> unreliableSequenceNumber != unreliableSequenceNumber)
1311
currentCommand = enet_list_next (currentCommand);
1318
buffer -> data = command;
1319
buffer -> dataLength = commandSize;
1321
host -> packetSize += buffer -> dataLength;
1323
* command = outgoingCommand -> command;
1325
enet_list_remove (& outgoingCommand -> outgoingCommandList);
1327
if (outgoingCommand -> packet != NULL)
1331
buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset;
1332
buffer -> dataLength = outgoingCommand -> fragmentLength;
1334
host -> packetSize += buffer -> dataLength;
1336
enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand);
1339
enet_free (outgoingCommand);
1345
host -> commandCount = command - host -> commands;
1346
host -> bufferCount = buffer - host -> buffers;
1348
if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER &&
1349
enet_list_empty (& peer -> outgoingReliableCommands) &&
1350
enet_list_empty (& peer -> outgoingUnreliableCommands) &&
1351
enet_list_empty (& peer -> sentReliableCommands))
1352
enet_peer_disconnect (peer, peer -> eventData);
1356
enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * event)
1358
ENetOutgoingCommand * outgoingCommand;
1359
ENetListIterator currentCommand, insertPosition;
1361
currentCommand = enet_list_begin (& peer -> sentReliableCommands);
1362
insertPosition = enet_list_begin (& peer -> outgoingReliableCommands);
1364
while (currentCommand != enet_list_end (& peer -> sentReliableCommands))
1366
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
1368
currentCommand = enet_list_next (currentCommand);
1370
if (ENET_TIME_DIFFERENCE (host -> serviceTime, outgoingCommand -> sentTime) < outgoingCommand -> roundTripTimeout)
1373
if (peer -> earliestTimeout == 0 ||
1374
ENET_TIME_LESS (outgoingCommand -> sentTime, peer -> earliestTimeout))
1375
peer -> earliestTimeout = outgoingCommand -> sentTime;
1377
if (peer -> earliestTimeout != 0 &&
1378
(ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= ENET_PEER_TIMEOUT_MAXIMUM ||
1379
(outgoingCommand -> roundTripTimeout >= outgoingCommand -> roundTripTimeoutLimit &&
1380
ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= ENET_PEER_TIMEOUT_MINIMUM)))
1382
enet_protocol_notify_disconnect (host, peer, event);
1387
if (outgoingCommand -> packet != NULL)
1388
peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength;
1390
++ peer -> packetsLost;
1392
outgoingCommand -> roundTripTimeout *= 2;
1394
enet_list_insert (insertPosition, enet_list_remove (& outgoingCommand -> outgoingCommandList));
1396
if (currentCommand == enet_list_begin (& peer -> sentReliableCommands) &&
1397
! enet_list_empty (& peer -> sentReliableCommands))
1399
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
1401
peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout;
1409
enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
1411
ENetProtocol * command = & host -> commands [host -> commandCount];
1412
ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
1413
ENetOutgoingCommand * outgoingCommand;
1414
ENetListIterator currentCommand;
1415
ENetChannel *channel;
1416
enet_uint16 reliableWindow;
1418
int windowExceeded = 0, windowWrap = 0, canPing = 1;
1420
currentCommand = enet_list_begin (& peer -> outgoingReliableCommands);
1422
while (currentCommand != enet_list_end (& peer -> outgoingReliableCommands))
1424
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
1426
channel = outgoingCommand -> command.header.channelID < peer -> channelCount ? & peer -> channels [outgoingCommand -> command.header.channelID] : NULL;
1427
reliableWindow = outgoingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
1428
if (channel != NULL)
1431
outgoingCommand -> sendAttempts < 1 &&
1432
! (outgoingCommand -> reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) &&
1433
(channel -> reliableWindows [(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE ||
1434
channel -> usedReliableWindows & ((((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) << reliableWindow) |
1435
(((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) >> (ENET_PEER_RELIABLE_WINDOW_SIZE - reliableWindow)))))
1439
currentCommand = enet_list_next (currentCommand);
1445
if (outgoingCommand -> packet != NULL)
1447
if (! windowExceeded)
1449
enet_uint32 windowSize = (peer -> packetThrottle * peer -> windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE;
1451
if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > ENET_MAX (windowSize, peer -> mtu))
1456
currentCommand = enet_list_next (currentCommand);
1464
commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK];
1465
if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
1466
buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
1467
peer -> mtu - host -> packetSize < commandSize ||
1468
(outgoingCommand -> packet != NULL &&
1469
(enet_uint16) (peer -> mtu - host -> packetSize) < (enet_uint16) (commandSize + outgoingCommand -> fragmentLength)))
1471
host -> continueSending = 1;
1476
currentCommand = enet_list_next (currentCommand);
1478
if (channel != NULL && outgoingCommand -> sendAttempts < 1)
1480
channel -> usedReliableWindows |= 1 << reliableWindow;
1481
++ channel -> reliableWindows [reliableWindow];
1484
++ outgoingCommand -> sendAttempts;
1486
if (outgoingCommand -> roundTripTimeout == 0)
1488
outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance;
1489
outgoingCommand -> roundTripTimeoutLimit = ENET_PEER_TIMEOUT_LIMIT * outgoingCommand -> roundTripTimeout;
1492
if (enet_list_empty (& peer -> sentReliableCommands))
1493
peer -> nextTimeout = host -> serviceTime + outgoingCommand -> roundTripTimeout;
1495
enet_list_insert (enet_list_end (& peer -> sentReliableCommands),
1496
enet_list_remove (& outgoingCommand -> outgoingCommandList));
1498
outgoingCommand -> sentTime = host -> serviceTime;
1500
buffer -> data = command;
1501
buffer -> dataLength = commandSize;
1503
host -> packetSize += buffer -> dataLength;
1504
host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME;
1506
* command = outgoingCommand -> command;
1508
if (outgoingCommand -> packet != NULL)
1512
buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset;
1513
buffer -> dataLength = outgoingCommand -> fragmentLength;
1515
host -> packetSize += outgoingCommand -> fragmentLength;
1517
peer -> reliableDataInTransit += outgoingCommand -> fragmentLength;
1520
++ peer -> packetsSent;
1526
host -> commandCount = command - host -> commands;
1527
host -> bufferCount = buffer - host -> buffers;
1533
enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int checkForTimeouts)
1535
enet_uint8 headerData [sizeof (ENetProtocolHeader) + sizeof (enet_uint32)];
1536
ENetProtocolHeader * header = (ENetProtocolHeader *) headerData;
1537
ENetPeer * currentPeer;
1539
size_t shouldCompress = 0;
1541
host -> continueSending = 1;
1543
while (host -> continueSending)
1544
for (host -> continueSending = 0,
1545
currentPeer = host -> peers;
1546
currentPeer < & host -> peers [host -> peerCount];
1549
if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED ||
1550
currentPeer -> state == ENET_PEER_STATE_ZOMBIE)
1553
host -> headerFlags = 0;
1554
host -> commandCount = 0;
1555
host -> bufferCount = 1;
1556
host -> packetSize = sizeof (ENetProtocolHeader);
1558
if (! enet_list_empty (& currentPeer -> acknowledgements))
1559
enet_protocol_send_acknowledgements (host, currentPeer);
1561
if (checkForTimeouts != 0 &&
1562
! enet_list_empty (& currentPeer -> sentReliableCommands) &&
1563
ENET_TIME_GREATER_EQUAL (host -> serviceTime, currentPeer -> nextTimeout) &&
1564
enet_protocol_check_timeouts (host, currentPeer, event) == 1)
1566
if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE)
1572
if ((enet_list_empty (& currentPeer -> outgoingReliableCommands) ||
1573
enet_protocol_send_reliable_outgoing_commands (host, currentPeer)) &&
1574
enet_list_empty (& currentPeer -> sentReliableCommands) &&
1575
ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= ENET_PEER_PING_INTERVAL &&
1576
currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing))
1578
enet_peer_ping (currentPeer);
1579
enet_protocol_send_reliable_outgoing_commands (host, currentPeer);
1582
if (! enet_list_empty (& currentPeer -> outgoingUnreliableCommands))
1583
enet_protocol_send_unreliable_outgoing_commands (host, currentPeer);
1585
if (host -> commandCount == 0)
1588
if (currentPeer -> packetLossEpoch == 0)
1589
currentPeer -> packetLossEpoch = host -> serviceTime;
1591
if (ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> packetLossEpoch) >= ENET_PEER_PACKET_LOSS_INTERVAL &&
1592
currentPeer -> packetsSent > 0)
1594
enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent;
1602
"peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingReliableCommands), enet_list_size (& currentPeer -> outgoingUnreliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0);
1605
currentPeer -> packetLossVariance -= currentPeer -> packetLossVariance / 4;
1607
if (packetLoss >= currentPeer -> packetLoss)
1609
currentPeer -> packetLoss += (packetLoss - currentPeer -> packetLoss) / 8;
1610
currentPeer -> packetLossVariance += (packetLoss - currentPeer -> packetLoss) / 4;
1614
currentPeer -> packetLoss -= (currentPeer -> packetLoss - packetLoss) / 8;
1615
currentPeer -> packetLossVariance += (currentPeer -> packetLoss - packetLoss) / 4;
1618
currentPeer -> packetLossEpoch = host -> serviceTime;
1619
currentPeer -> packetsSent = 0;
1620
currentPeer -> packetsLost = 0;
1623
host -> buffers -> data = headerData;
1624
if (host -> headerFlags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME)
1626
header -> sentTime = ENET_HOST_TO_NET_16 (host -> serviceTime & 0xFFFF);
1628
host -> buffers -> dataLength = sizeof (ENetProtocolHeader);
1631
host -> buffers -> dataLength = (size_t) & ((ENetProtocolHeader *) 0) -> sentTime;
1634
if (host -> compressor.context != NULL && host -> compressor.compress != NULL)
1636
size_t originalSize = host -> packetSize - sizeof(ENetProtocolHeader),
1637
compressedSize = host -> compressor.compress (host -> compressor.context,
1638
& host -> buffers [1], host -> bufferCount - 1,
1640
host -> packetData [1],
1642
if (compressedSize > 0 && compressedSize < originalSize)
1644
host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_COMPRESSED;
1645
shouldCompress = compressedSize;
1646
#ifdef ENET_DEBUG_COMPRESS
1652
"peer %u: compressed %u -> %u (%u%%)\n", currentPeer -> incomingPeerID, originalSize, compressedSize, (compressedSize * 100) / originalSize);
1657
if (currentPeer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID)
1658
host -> headerFlags |= currentPeer -> outgoingSessionID << ENET_PROTOCOL_HEADER_SESSION_SHIFT;
1659
header -> peerID = ENET_HOST_TO_NET_16 (currentPeer -> outgoingPeerID | host -> headerFlags);
1660
if (host -> checksum != NULL)
1662
enet_uint32 * checksum = (enet_uint32 *) & headerData [host -> buffers -> dataLength];
1663
* checksum = currentPeer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID ? currentPeer -> connectID : 0;
1664
host -> buffers -> dataLength += sizeof (enet_uint32);
1665
* checksum = host -> checksum (host -> buffers, host -> bufferCount);
1668
if (shouldCompress > 0)
1670
host -> buffers [1].data = host -> packetData [1];
1671
host -> buffers [1].dataLength = shouldCompress;
1672
host -> bufferCount = 2;
1675
currentPeer -> lastSendTime = host -> serviceTime;
1677
sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount);
1679
enet_protocol_remove_sent_unreliable_commands (currentPeer);
1684
host -> totalSentData += sentLength;
1685
host -> totalSentPackets ++;
1691
/** Sends any queued packets on the host specified to its designated peers.
1693
@param host host to flush
1694
@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().
1698
enet_host_flush (ENetHost * host)
1700
host -> serviceTime = enet_time_get ();
1702
enet_protocol_send_outgoing_commands (host, NULL, 0);
1705
/** Checks for any queued events on the host and dispatches one if available.
1707
@param host host to check for events
1708
@param event an event structure where event details will be placed if available
1709
@retval > 0 if an event was dispatched
1710
@retval 0 if no events are available
1711
@retval < 0 on failure
1715
enet_host_check_events (ENetHost * host, ENetEvent * event)
1717
if (event == NULL) return -1;
1719
event -> type = ENET_EVENT_TYPE_NONE;
1720
event -> peer = NULL;
1721
event -> packet = NULL;
1723
return enet_protocol_dispatch_incoming_commands (host, event);
1726
/** Waits for events on the host specified and shuttles packets between
1727
the host and its peers.
1729
@param host host to service
1730
@param event an event structure where event details will be placed if one occurs
1731
if event == NULL then no events will be delivered
1732
@param timeout number of milliseconds that ENet should wait for events
1733
@retval > 0 if an event occurred within the specified time limit
1734
@retval 0 if no event occurred
1735
@retval < 0 on failure
1736
@remarks enet_host_service should be called fairly regularly for adequate performance
1740
enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
1742
enet_uint32 waitCondition;
1746
event -> type = ENET_EVENT_TYPE_NONE;
1747
event -> peer = NULL;
1748
event -> packet = NULL;
1750
switch (enet_protocol_dispatch_incoming_commands (host, event))
1756
perror ("Error dispatching incoming packets");
1765
host -> serviceTime = enet_time_get ();
1767
timeout += host -> serviceTime;
1771
if (ENET_TIME_DIFFERENCE (host -> serviceTime, host -> bandwidthThrottleEpoch) >= ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
1772
enet_host_bandwidth_throttle (host);
1774
switch (enet_protocol_send_outgoing_commands (host, event, 1))
1780
perror ("Error sending outgoing packets");
1788
switch (enet_protocol_receive_incoming_commands (host, event))
1794
perror ("Error receiving incoming packets");
1802
switch (enet_protocol_send_outgoing_commands (host, event, 1))
1808
perror ("Error sending outgoing packets");
1818
switch (enet_protocol_dispatch_incoming_commands (host, event))
1824
perror ("Error dispatching incoming packets");
1833
host -> serviceTime = enet_time_get ();
1835
if (ENET_TIME_GREATER_EQUAL (host -> serviceTime, timeout))
1838
waitCondition = ENET_SOCKET_WAIT_RECEIVE;
1840
if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0)
1843
host -> serviceTime = enet_time_get ();
1844
} while (waitCondition == ENET_SOCKET_WAIT_RECEIVE);