1 /**
2 @file protocol.c
3 @brief ENet protocol functions
4 */
5 #include <stdio.h>
6 #include <string.h>
7 #define ENET_BUILDING_LIB 1
8 #include "enet/utility.h"
9 #include "enet/time.h"
10 #include "enet/enet.h"
11
12 static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] =
13 {
14 0,
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)
27 };
28
29 size_t
enet_protocol_command_size(enet_uint8 commandNumber)30 enet_protocol_command_size (enet_uint8 commandNumber)
31 {
32 return commandSizes [commandNumber & ENET_PROTOCOL_COMMAND_MASK];
33 }
34
35 static void
enet_protocol_change_state(ENetHost * host,ENetPeer * peer,ENetPeerState state)36 enet_protocol_change_state (ENetHost * host, ENetPeer * peer, ENetPeerState state)
37 {
38 if (state == ENET_PEER_STATE_CONNECTED || state == ENET_PEER_STATE_DISCONNECT_LATER)
39 enet_peer_on_connect (peer);
40 else
41 enet_peer_on_disconnect (peer);
42
43 peer -> state = state;
44 }
45
46 static void
enet_protocol_dispatch_state(ENetHost * host,ENetPeer * peer,ENetPeerState state)47 enet_protocol_dispatch_state (ENetHost * host, ENetPeer * peer, ENetPeerState state)
48 {
49 enet_protocol_change_state (host, peer, state);
50
51 if (! peer -> needsDispatch)
52 {
53 enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList);
54
55 peer -> needsDispatch = 1;
56 }
57 }
58
59 static int
enet_protocol_dispatch_incoming_commands(ENetHost * host,ENetEvent * event)60 enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
61 {
62 while (! enet_list_empty (& host -> dispatchQueue))
63 {
64 ENetPeer * peer = (ENetPeer *) enet_list_remove (enet_list_begin (& host -> dispatchQueue));
65
66 peer -> needsDispatch = 0;
67
68 switch (peer -> state)
69 {
70 case ENET_PEER_STATE_CONNECTION_PENDING:
71 case ENET_PEER_STATE_CONNECTION_SUCCEEDED:
72 enet_protocol_change_state (host, peer, ENET_PEER_STATE_CONNECTED);
73
74 event -> type = ENET_EVENT_TYPE_CONNECT;
75 event -> peer = peer;
76 event -> data = peer -> eventData;
77
78 return 1;
79
80 case ENET_PEER_STATE_ZOMBIE:
81 host -> recalculateBandwidthLimits = 1;
82
83 event -> type = ENET_EVENT_TYPE_DISCONNECT;
84 event -> peer = peer;
85 event -> data = peer -> eventData;
86
87 enet_peer_reset (peer);
88
89 return 1;
90
91 case ENET_PEER_STATE_CONNECTED:
92 if (enet_list_empty (& peer -> dispatchedCommands))
93 continue;
94
95 event -> packet = enet_peer_receive (peer, & event -> channelID);
96 if (event -> packet == NULL)
97 continue;
98
99 event -> type = ENET_EVENT_TYPE_RECEIVE;
100 event -> peer = peer;
101
102 if (! enet_list_empty (& peer -> dispatchedCommands))
103 {
104 peer -> needsDispatch = 1;
105
106 enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList);
107 }
108
109 return 1;
110
111 default:
112 break;
113 }
114 }
115
116 return 0;
117 }
118
119 static void
enet_protocol_notify_connect(ENetHost * host,ENetPeer * peer,ENetEvent * event)120 enet_protocol_notify_connect (ENetHost * host, ENetPeer * peer, ENetEvent * event)
121 {
122 host -> recalculateBandwidthLimits = 1;
123
124 if (event != NULL)
125 {
126 enet_protocol_change_state (host, peer, ENET_PEER_STATE_CONNECTED);
127
128 event -> type = ENET_EVENT_TYPE_CONNECT;
129 event -> peer = peer;
130 event -> data = peer -> eventData;
131 }
132 else
133 enet_protocol_dispatch_state (host, peer, peer -> state == ENET_PEER_STATE_CONNECTING ? ENET_PEER_STATE_CONNECTION_SUCCEEDED : ENET_PEER_STATE_CONNECTION_PENDING);
134 }
135
136 static void
enet_protocol_notify_disconnect(ENetHost * host,ENetPeer * peer,ENetEvent * event)137 enet_protocol_notify_disconnect (ENetHost * host, ENetPeer * peer, ENetEvent * event)
138 {
139 if (peer -> state >= ENET_PEER_STATE_CONNECTION_PENDING)
140 host -> recalculateBandwidthLimits = 1;
141
142 if (peer -> state != ENET_PEER_STATE_CONNECTING && peer -> state < ENET_PEER_STATE_CONNECTION_SUCCEEDED)
143 enet_peer_reset (peer);
144 else
145 if (event != NULL)
146 {
147 event -> type = ENET_EVENT_TYPE_DISCONNECT;
148 event -> peer = peer;
149 event -> data = 0;
150
151 enet_peer_reset (peer);
152 }
153 else
154 {
155 peer -> eventData = 0;
156
157 enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);
158 }
159 }
160
161 static void
enet_protocol_remove_sent_unreliable_commands(ENetPeer * peer)162 enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer)
163 {
164 ENetOutgoingCommand * outgoingCommand;
165
166 while (! enet_list_empty (& peer -> sentUnreliableCommands))
167 {
168 outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentUnreliableCommands);
169
170 enet_list_remove (& outgoingCommand -> outgoingCommandList);
171
172 if (outgoingCommand -> packet != NULL)
173 {
174 -- outgoingCommand -> packet -> referenceCount;
175
176 if (outgoingCommand -> packet -> referenceCount == 0)
177 {
178 outgoingCommand -> packet -> flags |= ENET_PACKET_FLAG_SENT;
179
180 enet_packet_destroy (outgoingCommand -> packet);
181 }
182 }
183
184 enet_free (outgoingCommand);
185 }
186 }
187
188 static ENetProtocolCommand
enet_protocol_remove_sent_reliable_command(ENetPeer * peer,enet_uint16 reliableSequenceNumber,enet_uint8 channelID)189 enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliableSequenceNumber, enet_uint8 channelID)
190 {
191 ENetOutgoingCommand * outgoingCommand = NULL;
192 ENetListIterator currentCommand;
193 ENetProtocolCommand commandNumber;
194 int wasSent = 1;
195
196 for (currentCommand = enet_list_begin (& peer -> sentReliableCommands);
197 currentCommand != enet_list_end (& peer -> sentReliableCommands);
198 currentCommand = enet_list_next (currentCommand))
199 {
200 outgoingCommand = (ENetOutgoingCommand *) currentCommand;
201
202 if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber &&
203 outgoingCommand -> command.header.channelID == channelID)
204 break;
205 }
206
207 if (currentCommand == enet_list_end (& peer -> sentReliableCommands))
208 {
209 for (currentCommand = enet_list_begin (& peer -> outgoingReliableCommands);
210 currentCommand != enet_list_end (& peer -> outgoingReliableCommands);
211 currentCommand = enet_list_next (currentCommand))
212 {
213 outgoingCommand = (ENetOutgoingCommand *) currentCommand;
214
215 if (outgoingCommand -> sendAttempts < 1) return ENET_PROTOCOL_COMMAND_NONE;
216
217 if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber &&
218 outgoingCommand -> command.header.channelID == channelID)
219 break;
220 }
221
222 if (currentCommand == enet_list_end (& peer -> outgoingReliableCommands))
223 return ENET_PROTOCOL_COMMAND_NONE;
224
225 wasSent = 0;
226 }
227
228 if (outgoingCommand == NULL)
229 return ENET_PROTOCOL_COMMAND_NONE;
230
231 if (channelID < peer -> channelCount)
232 {
233 ENetChannel * channel = & peer -> channels [channelID];
234 enet_uint16 reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
235 if (channel -> reliableWindows [reliableWindow] > 0)
236 {
237 -- channel -> reliableWindows [reliableWindow];
238 if (! channel -> reliableWindows [reliableWindow])
239 channel -> usedReliableWindows &= ~ (1 << reliableWindow);
240 }
241 }
242
243 commandNumber = (ENetProtocolCommand) (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK);
244
245 enet_list_remove (& outgoingCommand -> outgoingCommandList);
246
247 if (outgoingCommand -> packet != NULL)
248 {
249 if (wasSent)
250 peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength;
251
252 -- outgoingCommand -> packet -> referenceCount;
253
254 if (outgoingCommand -> packet -> referenceCount == 0)
255 {
256 outgoingCommand -> packet -> flags |= ENET_PACKET_FLAG_SENT;
257
258 enet_packet_destroy (outgoingCommand -> packet);
259 }
260 }
261
262 enet_free (outgoingCommand);
263
264 if (enet_list_empty (& peer -> sentReliableCommands))
265 return commandNumber;
266
267 outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentReliableCommands);
268
269 peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout;
270
271 return commandNumber;
272 }
273
274 static ENetPeer *
enet_protocol_handle_connect(ENetHost * host,ENetProtocolHeader * header,ENetProtocol * command)275 enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENetProtocol * command)
276 {
277 enet_uint8 incomingSessionID, outgoingSessionID;
278 enet_uint32 mtu, windowSize;
279 ENetChannel * channel;
280 size_t channelCount, duplicatePeers = 0;
281 ENetPeer * currentPeer, * peer = NULL;
282 ENetProtocol verifyCommand;
283 int i;
284
285 channelCount = ENET_NET_TO_HOST_32 (command -> connect.channelCount);
286
287 if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT ||
288 channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
289 return NULL;
290
291 for (i = 0; i < host -> peerCount; i++ )
292 {
293 currentPeer = host -> peer_list[i];
294
295 if (currentPeer -> state != ENET_PEER_STATE_DISCONNECTED &&
296 currentPeer -> address.host == host -> receivedAddress.host &&
297 currentPeer -> address.port == host -> receivedAddress.port &&
298 currentPeer -> connectID == command -> connect.connectID)
299 return NULL;
300 }
301
302 for (i = 0; i < host -> peerCount; i++ )
303 {
304 currentPeer = host -> peer_list[i];
305
306 if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED)
307 {
308 if (peer == NULL)
309 peer = currentPeer;
310 }
311 else
312 if (currentPeer -> state != ENET_PEER_STATE_CONNECTING &&
313 currentPeer -> address.host == host -> receivedAddress.host)
314 {
315 if (currentPeer -> address.port == host -> receivedAddress.port &&
316 currentPeer -> connectID == command -> connect.connectID)
317 return NULL;
318
319 ++ duplicatePeers;
320 }
321 }
322
323 if (i >= host -> peerCount)
324 {
325 if (i >= ENET_PROTOCOL_MAXIMUM_PEER_ID)
326 return NULL;
327 host -> peerCount++;
328 host -> peer_list[i] = enet_malloc (sizeof (ENetPeer));
329 memset (host -> peer_list[i], 0, sizeof (ENetPeer));
330 peer = host->peer_list[i];
331 peer -> host = host;
332 peer -> incomingPeerID = i;
333 peer -> outgoingSessionID = peer -> incomingSessionID = 0xFF;
334 peer -> data = NULL;
335
336 enet_list_clear (& peer -> acknowledgements);
337 enet_list_clear (& peer -> sentReliableCommands);
338 enet_list_clear (& peer -> sentUnreliableCommands);
339 enet_list_clear (& peer -> outgoingReliableCommands);
340 enet_list_clear (& peer -> outgoingUnreliableCommands);
341 enet_list_clear (& peer -> dispatchedCommands);
342
343 enet_peer_reset (peer);
344 }
345
346 if (peer == NULL || duplicatePeers >= host -> duplicatePeers)
347 return NULL;
348
349 if (channelCount > host -> channelLimit)
350 channelCount = host -> channelLimit;
351 peer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
352 if (peer -> channels == NULL)
353 return NULL;
354 peer -> channelCount = channelCount;
355 peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT;
356 peer -> connectID = command -> connect.connectID;
357 peer -> address = host -> receivedAddress;
358 peer -> outgoingPeerID = ENET_NET_TO_HOST_32 (command -> connect.outgoingPeerID);
359 peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth);
360 peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.outgoingBandwidth);
361 peer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleInterval);
362 peer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleAcceleration);
363 peer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleDeceleration);
364 peer -> eventData = ENET_NET_TO_HOST_32 (command -> connect.data);
365
366 incomingSessionID = command -> connect.incomingSessionID == 0xFF ? peer -> outgoingSessionID : command -> connect.incomingSessionID;
367 incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT);
368 if (incomingSessionID == peer -> outgoingSessionID)
369 incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT);
370 peer -> outgoingSessionID = incomingSessionID;
371
372 outgoingSessionID = command -> connect.outgoingSessionID == 0xFF ? peer -> incomingSessionID : command -> connect.outgoingSessionID;
373 outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT);
374 if (outgoingSessionID == peer -> incomingSessionID)
375 outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT);
376 peer -> incomingSessionID = outgoingSessionID;
377
378 for (channel = peer -> channels;
379 channel < & peer -> channels [channelCount];
380 ++ channel)
381 {
382 channel -> outgoingReliableSequenceNumber = 0;
383 channel -> outgoingUnreliableSequenceNumber = 0;
384 channel -> incomingReliableSequenceNumber = 0;
385 channel -> incomingUnreliableSequenceNumber = 0;
386
387 enet_list_clear (& channel -> incomingReliableCommands);
388 enet_list_clear (& channel -> incomingUnreliableCommands);
389
390 channel -> usedReliableWindows = 0;
391 memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows));
392 }
393
394 mtu = ENET_NET_TO_HOST_32 (command -> connect.mtu);
395
396 if (mtu < ENET_PROTOCOL_MINIMUM_MTU)
397 mtu = ENET_PROTOCOL_MINIMUM_MTU;
398 else
399 if (mtu > ENET_PROTOCOL_MAXIMUM_MTU)
400 mtu = ENET_PROTOCOL_MAXIMUM_MTU;
401
402 peer -> mtu = mtu;
403
404 if (host -> outgoingBandwidth == 0 &&
405 peer -> incomingBandwidth == 0)
406 peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
407 else
408 if (host -> outgoingBandwidth == 0 ||
409 peer -> incomingBandwidth == 0)
410 peer -> windowSize = (ENET_MAX (host -> outgoingBandwidth, peer -> incomingBandwidth) /
411 ENET_PEER_WINDOW_SIZE_SCALE) *
412 ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
413 else
414 peer -> windowSize = (ENET_MIN (host -> outgoingBandwidth, peer -> incomingBandwidth) /
415 ENET_PEER_WINDOW_SIZE_SCALE) *
416 ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
417
418 if (peer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
419 peer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
420 else
421 if (peer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
422 peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
423
424 if (host -> incomingBandwidth == 0)
425 windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
426 else
427 windowSize = (host -> incomingBandwidth / ENET_PEER_WINDOW_SIZE_SCALE) *
428 ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
429
430 if (windowSize > ENET_NET_TO_HOST_32 (command -> connect.windowSize))
431 windowSize = ENET_NET_TO_HOST_32 (command -> connect.windowSize);
432
433 if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
434 windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
435 else
436 if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
437 windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
438
439 verifyCommand.header.command = ENET_PROTOCOL_COMMAND_VERIFY_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
440 verifyCommand.header.channelID = 0xFF;
441 verifyCommand.verifyConnect.outgoingPeerID = ENET_HOST_TO_NET_32 (peer -> incomingPeerID);
442 verifyCommand.verifyConnect.incomingSessionID = incomingSessionID;
443 verifyCommand.verifyConnect.outgoingSessionID = outgoingSessionID;
444 verifyCommand.verifyConnect.mtu = ENET_HOST_TO_NET_32 (peer -> mtu);
445 verifyCommand.verifyConnect.windowSize = ENET_HOST_TO_NET_32 (windowSize);
446 verifyCommand.verifyConnect.channelCount = ENET_HOST_TO_NET_32 (channelCount);
447 verifyCommand.verifyConnect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth);
448 verifyCommand.verifyConnect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
449 verifyCommand.verifyConnect.packetThrottleInterval = ENET_HOST_TO_NET_32 (peer -> packetThrottleInterval);
450 verifyCommand.verifyConnect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (peer -> packetThrottleAcceleration);
451 verifyCommand.verifyConnect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (peer -> packetThrottleDeceleration);
452 verifyCommand.verifyConnect.connectID = peer -> connectID;
453
454 enet_peer_queue_outgoing_command (peer, & verifyCommand, NULL, 0, 0);
455
456 return peer;
457 }
458
459 static int
enet_protocol_handle_send_reliable(ENetHost * host,ENetPeer * peer,const ENetProtocol * command,enet_uint8 ** currentData)460 enet_protocol_handle_send_reliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
461 {
462 size_t dataLength;
463
464 if (command -> header.channelID >= peer -> channelCount ||
465 (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
466 return -1;
467
468 dataLength = ENET_NET_TO_HOST_16 (command -> sendReliable.dataLength);
469 * currentData += dataLength;
470 if (dataLength > host -> maximumPacketSize ||
471 * currentData < host -> receivedData ||
472 * currentData > & host -> receivedData [host -> receivedDataLength])
473 return -1;
474
475 if (enet_peer_queue_incoming_command (peer, command, (const enet_uint8 *) command + sizeof (ENetProtocolSendReliable), dataLength, ENET_PACKET_FLAG_RELIABLE, 0) == NULL)
476 return -1;
477
478 return 0;
479 }
480
481 static int
enet_protocol_handle_send_unsequenced(ENetHost * host,ENetPeer * peer,const ENetProtocol * command,enet_uint8 ** currentData)482 enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
483 {
484 enet_uint32 unsequencedGroup, index;
485 size_t dataLength;
486
487 if (command -> header.channelID >= peer -> channelCount ||
488 (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
489 return -1;
490
491 dataLength = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.dataLength);
492 * currentData += dataLength;
493 if (dataLength > host -> maximumPacketSize ||
494 * currentData < host -> receivedData ||
495 * currentData > & host -> receivedData [host -> receivedDataLength])
496 return -1;
497
498 unsequencedGroup = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.unsequencedGroup);
499 index = unsequencedGroup % ENET_PEER_UNSEQUENCED_WINDOW_SIZE;
500
501 if (unsequencedGroup < peer -> incomingUnsequencedGroup)
502 unsequencedGroup += 0x10000;
503
504 if (unsequencedGroup >= (enet_uint32) peer -> incomingUnsequencedGroup + ENET_PEER_FREE_UNSEQUENCED_WINDOWS * ENET_PEER_UNSEQUENCED_WINDOW_SIZE)
505 return 0;
506
507 unsequencedGroup &= 0xFFFF;
508
509 if (unsequencedGroup - index != peer -> incomingUnsequencedGroup)
510 {
511 peer -> incomingUnsequencedGroup = unsequencedGroup - index;
512
513 memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow));
514 }
515 else
516 if (peer -> unsequencedWindow [index / 32] & (1 << (index % 32)))
517 return 0;
518
519 if (enet_peer_queue_incoming_command (peer, command, (const enet_uint8 *) command + sizeof (ENetProtocolSendUnsequenced), dataLength, ENET_PACKET_FLAG_UNSEQUENCED, 0) == NULL)
520 return -1;
521
522 peer -> unsequencedWindow [index / 32] |= 1 << (index % 32);
523
524 return 0;
525 }
526
527 static int
enet_protocol_handle_send_unreliable(ENetHost * host,ENetPeer * peer,const ENetProtocol * command,enet_uint8 ** currentData)528 enet_protocol_handle_send_unreliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
529 {
530 size_t dataLength;
531
532 if (command -> header.channelID >= peer -> channelCount ||
533 (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
534 return -1;
535
536 dataLength = ENET_NET_TO_HOST_16 (command -> sendUnreliable.dataLength);
537 * currentData += dataLength;
538 if (dataLength > host -> maximumPacketSize ||
539 * currentData < host -> receivedData ||
540 * currentData > & host -> receivedData [host -> receivedDataLength])
541 return -1;
542
543 if (enet_peer_queue_incoming_command (peer, command, (const enet_uint8 *) command + sizeof (ENetProtocolSendUnreliable), dataLength, 0, 0) == NULL)
544 return -1;
545
546 return 0;
547 }
548
549 static int
enet_protocol_handle_send_fragment(ENetHost * host,ENetPeer * peer,const ENetProtocol * command,enet_uint8 ** currentData)550 enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
551 {
552 enet_uint32 fragmentNumber,
553 fragmentCount,
554 fragmentOffset,
555 fragmentLength,
556 startSequenceNumber,
557 totalLength;
558 ENetChannel * channel;
559 enet_uint16 startWindow, currentWindow;
560 ENetListIterator currentCommand;
561 ENetIncomingCommand * startCommand = NULL;
562
563 if (command -> header.channelID >= peer -> channelCount ||
564 (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
565 return -1;
566
567 fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength);
568 * currentData += fragmentLength;
569 if (fragmentLength > host -> maximumPacketSize ||
570 * currentData < host -> receivedData ||
571 * currentData > & host -> receivedData [host -> receivedDataLength])
572 return -1;
573
574 channel = & peer -> channels [command -> header.channelID];
575 startSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendFragment.startSequenceNumber);
576 startWindow = startSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
577 currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
578
579 if (startSequenceNumber < channel -> incomingReliableSequenceNumber)
580 startWindow += ENET_PEER_RELIABLE_WINDOWS;
581
582 if (startWindow < currentWindow || startWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1)
583 return 0;
584
585 fragmentNumber = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentNumber);
586 fragmentCount = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentCount);
587 fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset);
588 totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength);
589
590 if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT ||
591 fragmentNumber >= fragmentCount ||
592 totalLength > host -> maximumPacketSize ||
593 fragmentOffset >= totalLength ||
594 fragmentLength > totalLength - fragmentOffset)
595 return -1;
596
597 for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands));
598 currentCommand != enet_list_end (& channel -> incomingReliableCommands);
599 currentCommand = enet_list_previous (currentCommand))
600 {
601 ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand;
602
603 if (startSequenceNumber >= channel -> incomingReliableSequenceNumber)
604 {
605 if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
606 continue;
607 }
608 else
609 if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
610 break;
611
612 if (incomingCommand -> reliableSequenceNumber <= startSequenceNumber)
613 {
614 if (incomingCommand -> reliableSequenceNumber < startSequenceNumber)
615 break;
616
617 if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_FRAGMENT ||
618 totalLength != incomingCommand -> packet -> dataLength ||
619 fragmentCount != incomingCommand -> fragmentCount)
620 return -1;
621
622 startCommand = incomingCommand;
623 break;
624 }
625 }
626
627 if (startCommand == NULL)
628 {
629 ENetProtocol hostCommand = * command;
630
631 hostCommand.header.reliableSequenceNumber = startSequenceNumber;
632
633 startCommand = enet_peer_queue_incoming_command (peer, & hostCommand, NULL, totalLength, ENET_PACKET_FLAG_RELIABLE, fragmentCount);
634 if (startCommand == NULL)
635 return -1;
636 }
637
638 if ((startCommand -> fragments [fragmentNumber / 32] & (1 << (fragmentNumber % 32))) == 0)
639 {
640 -- startCommand -> fragmentsRemaining;
641
642 startCommand -> fragments [fragmentNumber / 32] |= (1 << (fragmentNumber % 32));
643
644 if (fragmentOffset + fragmentLength > startCommand -> packet -> dataLength)
645 fragmentLength = startCommand -> packet -> dataLength - fragmentOffset;
646
647 memcpy (startCommand -> packet -> data + fragmentOffset,
648 (enet_uint8 *) command + sizeof (ENetProtocolSendFragment),
649 fragmentLength);
650
651 if (startCommand -> fragmentsRemaining <= 0)
652 enet_peer_dispatch_incoming_reliable_commands (peer, channel);
653 }
654
655 return 0;
656 }
657
658 static int
enet_protocol_handle_send_unreliable_fragment(ENetHost * host,ENetPeer * peer,const ENetProtocol * command,enet_uint8 ** currentData)659 enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
660 {
661 enet_uint32 fragmentNumber,
662 fragmentCount,
663 fragmentOffset,
664 fragmentLength,
665 reliableSequenceNumber,
666 startSequenceNumber,
667 totalLength;
668 enet_uint16 reliableWindow, currentWindow;
669 ENetChannel * channel;
670 ENetListIterator currentCommand;
671 ENetIncomingCommand * startCommand = NULL;
672
673 if (command -> header.channelID >= peer -> channelCount ||
674 (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
675 return -1;
676
677 fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength);
678 * currentData += fragmentLength;
679 if (fragmentLength > host -> maximumPacketSize ||
680 * currentData < host -> receivedData ||
681 * currentData > & host -> receivedData [host -> receivedDataLength])
682 return -1;
683
684 channel = & peer -> channels [command -> header.channelID];
685 reliableSequenceNumber = command -> header.reliableSequenceNumber;
686 startSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendFragment.startSequenceNumber);
687
688 reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
689 currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
690
691 if (reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
692 reliableWindow += ENET_PEER_RELIABLE_WINDOWS;
693
694 if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1)
695 return 0;
696
697 if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber &&
698 startSequenceNumber <= channel -> incomingUnreliableSequenceNumber)
699 return 0;
700
701 fragmentNumber = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentNumber);
702 fragmentCount = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentCount);
703 fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset);
704 totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength);
705
706 if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT ||
707 fragmentNumber >= fragmentCount ||
708 totalLength > host -> maximumPacketSize ||
709 fragmentOffset >= totalLength ||
710 fragmentLength > totalLength - fragmentOffset)
711 return -1;
712
713 for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands));
714 currentCommand != enet_list_end (& channel -> incomingUnreliableCommands);
715 currentCommand = enet_list_previous (currentCommand))
716 {
717 ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand;
718
719 if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
720 {
721 if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
722 continue;
723 }
724 else
725 if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
726 break;
727
728 if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber)
729 break;
730
731 if (incomingCommand -> reliableSequenceNumber > reliableSequenceNumber)
732 continue;
733
734 if (incomingCommand -> unreliableSequenceNumber <= startSequenceNumber)
735 {
736 if (incomingCommand -> unreliableSequenceNumber < startSequenceNumber)
737 break;
738
739 if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT ||
740 totalLength != incomingCommand -> packet -> dataLength ||
741 fragmentCount != incomingCommand -> fragmentCount)
742 return -1;
743
744 startCommand = incomingCommand;
745 break;
746 }
747 }
748
749 if (startCommand == NULL)
750 {
751 startCommand = enet_peer_queue_incoming_command (peer, command, NULL, totalLength, ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT, fragmentCount);
752 if (startCommand == NULL)
753 return -1;
754 }
755
756 if ((startCommand -> fragments [fragmentNumber / 32] & (1 << (fragmentNumber % 32))) == 0)
757 {
758 -- startCommand -> fragmentsRemaining;
759
760 startCommand -> fragments [fragmentNumber / 32] |= (1 << (fragmentNumber % 32));
761
762 if (fragmentOffset + fragmentLength > startCommand -> packet -> dataLength)
763 fragmentLength = startCommand -> packet -> dataLength - fragmentOffset;
764
765 memcpy (startCommand -> packet -> data + fragmentOffset,
766 (enet_uint8 *) command + sizeof (ENetProtocolSendFragment),
767 fragmentLength);
768
769 if (startCommand -> fragmentsRemaining <= 0)
770 enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
771 }
772
773 return 0;
774 }
775
776 static int
enet_protocol_handle_ping(ENetHost * host,ENetPeer * peer,const ENetProtocol * command)777 enet_protocol_handle_ping (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
778 {
779 if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
780 return -1;
781
782 return 0;
783 }
784
785 static int
enet_protocol_handle_bandwidth_limit(ENetHost * host,ENetPeer * peer,const ENetProtocol * command)786 enet_protocol_handle_bandwidth_limit (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
787 {
788 if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
789 return -1;
790
791 if (peer -> incomingBandwidth != 0)
792 -- host -> bandwidthLimitedPeers;
793
794 peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.incomingBandwidth);
795 peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.outgoingBandwidth);
796
797 if (peer -> incomingBandwidth != 0)
798 ++ host -> bandwidthLimitedPeers;
799
800 if (peer -> incomingBandwidth == 0 && host -> outgoingBandwidth == 0)
801 peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
802 else
803 if (peer -> incomingBandwidth == 0 || host -> outgoingBandwidth == 0)
804 peer -> windowSize = (ENET_MAX (peer -> incomingBandwidth, host -> outgoingBandwidth) /
805 ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
806 else
807 peer -> windowSize = (ENET_MIN (peer -> incomingBandwidth, host -> outgoingBandwidth) /
808 ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
809
810 if (peer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
811 peer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
812 else
813 if (peer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
814 peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
815
816 return 0;
817 }
818
819 static int
enet_protocol_handle_throttle_configure(ENetHost * host,ENetPeer * peer,const ENetProtocol * command)820 enet_protocol_handle_throttle_configure (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
821 {
822 if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
823 return -1;
824
825 peer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleInterval);
826 peer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleAcceleration);
827 peer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleDeceleration);
828
829 return 0;
830 }
831
832 static int
enet_protocol_handle_disconnect(ENetHost * host,ENetPeer * peer,const ENetProtocol * command)833 enet_protocol_handle_disconnect (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
834 {
835 if (peer -> state == ENET_PEER_STATE_DISCONNECTED || peer -> state == ENET_PEER_STATE_ZOMBIE || peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT)
836 return 0;
837
838 enet_peer_reset_queues (peer);
839
840 if (peer -> state == ENET_PEER_STATE_CONNECTION_SUCCEEDED || peer -> state == ENET_PEER_STATE_DISCONNECTING || peer -> state == ENET_PEER_STATE_CONNECTING)
841 enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);
842 else
843 if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
844 {
845 if (peer -> state == ENET_PEER_STATE_CONNECTION_PENDING) host -> recalculateBandwidthLimits = 1;
846
847 enet_peer_reset (peer);
848 }
849 else
850 if (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
851 enet_protocol_change_state (host, peer, ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT);
852 else
853 enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);
854
855 if (peer -> state != ENET_PEER_STATE_DISCONNECTED)
856 peer -> eventData = ENET_NET_TO_HOST_32 (command -> disconnect.data);
857
858 return 0;
859 }
860
861 static int
enet_protocol_handle_acknowledge(ENetHost * host,ENetEvent * event,ENetPeer * peer,const ENetProtocol * command)862 enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command)
863 {
864 enet_uint32 roundTripTime,
865 receivedSentTime,
866 receivedReliableSequenceNumber;
867 ENetProtocolCommand commandNumber;
868
869 if (peer -> state == ENET_PEER_STATE_DISCONNECTED || peer -> state == ENET_PEER_STATE_ZOMBIE)
870 return 0;
871
872 receivedSentTime = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedSentTime);
873 receivedSentTime |= host -> serviceTime & 0xFFFF0000;
874 if ((receivedSentTime & 0x8000) > (host -> serviceTime & 0x8000))
875 receivedSentTime -= 0x10000;
876
877 if (ENET_TIME_LESS (host -> serviceTime, receivedSentTime))
878 return 0;
879
880 peer -> lastReceiveTime = host -> serviceTime;
881 peer -> earliestTimeout = 0;
882
883 roundTripTime = ENET_TIME_DIFFERENCE (host -> serviceTime, receivedSentTime);
884
885 enet_peer_throttle (peer, roundTripTime);
886
887 peer -> roundTripTimeVariance -= peer -> roundTripTimeVariance / 4;
888
889 if (roundTripTime >= peer -> roundTripTime)
890 {
891 peer -> roundTripTime += (roundTripTime - peer -> roundTripTime) / 8;
892 peer -> roundTripTimeVariance += (roundTripTime - peer -> roundTripTime) / 4;
893 }
894 else
895 {
896 peer -> roundTripTime -= (peer -> roundTripTime - roundTripTime) / 8;
897 peer -> roundTripTimeVariance += (peer -> roundTripTime - roundTripTime) / 4;
898 }
899
900 if (peer -> roundTripTime < peer -> lowestRoundTripTime)
901 peer -> lowestRoundTripTime = peer -> roundTripTime;
902
903 if (peer -> roundTripTimeVariance > peer -> highestRoundTripTimeVariance)
904 peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance;
905
906 if (peer -> packetThrottleEpoch == 0 ||
907 ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> packetThrottleEpoch) >= peer -> packetThrottleInterval)
908 {
909 peer -> lastRoundTripTime = peer -> lowestRoundTripTime;
910 peer -> lastRoundTripTimeVariance = peer -> highestRoundTripTimeVariance;
911 peer -> lowestRoundTripTime = peer -> roundTripTime;
912 peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance;
913 peer -> packetThrottleEpoch = host -> serviceTime;
914 }
915
916 receivedReliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedReliableSequenceNumber);
917
918 commandNumber = enet_protocol_remove_sent_reliable_command (peer, receivedReliableSequenceNumber, command -> header.channelID);
919
920 switch (peer -> state)
921 {
922 case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT:
923 if (commandNumber != ENET_PROTOCOL_COMMAND_VERIFY_CONNECT)
924 return -1;
925
926 enet_protocol_notify_connect (host, peer, event);
927 break;
928
929 case ENET_PEER_STATE_DISCONNECTING:
930 if (commandNumber != ENET_PROTOCOL_COMMAND_DISCONNECT)
931 return -1;
932
933 enet_protocol_notify_disconnect (host, peer, event);
934 break;
935
936 case ENET_PEER_STATE_DISCONNECT_LATER:
937 if (enet_list_empty (& peer -> outgoingReliableCommands) &&
938 enet_list_empty (& peer -> outgoingUnreliableCommands) &&
939 enet_list_empty (& peer -> sentReliableCommands))
940 enet_peer_disconnect (peer, peer -> eventData);
941 break;
942
943 default:
944 break;
945 }
946
947 return 0;
948 }
949
950 static int
enet_protocol_handle_verify_connect(ENetHost * host,ENetEvent * event,ENetPeer * peer,const ENetProtocol * command)951 enet_protocol_handle_verify_connect (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command)
952 {
953 enet_uint32 mtu, windowSize;
954 size_t channelCount;
955
956 if (peer -> state != ENET_PEER_STATE_CONNECTING)
957 return 0;
958
959 channelCount = ENET_NET_TO_HOST_32 (command -> verifyConnect.channelCount);
960
961 if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT || channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT ||
962 ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleInterval) != peer -> packetThrottleInterval ||
963 ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleAcceleration) != peer -> packetThrottleAcceleration ||
964 ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleDeceleration) != peer -> packetThrottleDeceleration ||
965 command -> verifyConnect.connectID != peer -> connectID)
966 {
967 peer -> eventData = 0;
968
969 enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);
970
971 return -1;
972 }
973
974 enet_protocol_remove_sent_reliable_command (peer, 1, 0xFF);
975
976 if (channelCount < peer -> channelCount)
977 peer -> channelCount = channelCount;
978
979 peer -> outgoingPeerID = ENET_NET_TO_HOST_32 (command -> verifyConnect.outgoingPeerID);
980 peer -> incomingSessionID = command -> verifyConnect.incomingSessionID;
981 peer -> outgoingSessionID = command -> verifyConnect.outgoingSessionID;
982
983 mtu = ENET_NET_TO_HOST_32 (command -> verifyConnect.mtu);
984
985 if (mtu < ENET_PROTOCOL_MINIMUM_MTU)
986 mtu = ENET_PROTOCOL_MINIMUM_MTU;
987 else
988 if (mtu > ENET_PROTOCOL_MAXIMUM_MTU)
989 mtu = ENET_PROTOCOL_MAXIMUM_MTU;
990
991 if (mtu < peer -> mtu)
992 peer -> mtu = mtu;
993
994 windowSize = ENET_NET_TO_HOST_32 (command -> verifyConnect.windowSize);
995
996 if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
997 windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
998
999 if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
1000 windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
1001
1002 if (windowSize < peer -> windowSize)
1003 peer -> windowSize = windowSize;
1004
1005 peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.incomingBandwidth);
1006 peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.outgoingBandwidth);
1007
1008 enet_protocol_notify_connect (host, peer, event);
1009 return 0;
1010 }
1011
1012 static int
enet_protocol_handle_incoming_commands(ENetHost * host,ENetEvent * event)1013 enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
1014 {
1015 ENetProtocolHeader * header;
1016 ENetProtocol * command;
1017 ENetPeer * peer;
1018 enet_uint8 * currentData;
1019 size_t headerSize;
1020 enet_uint32 peerID, flags;
1021 enet_uint8 sessionID;
1022
1023 if (host -> receivedDataLength < (size_t) & ((ENetProtocolHeader *) 0) -> sentTime)
1024 return 0;
1025
1026 header = (ENetProtocolHeader *) host -> receivedData;
1027
1028 peerID = ENET_NET_TO_HOST_32 (header -> peerID);
1029 sessionID = (peerID & ENET_PROTOCOL_HEADER_SESSION_MASK) >> ENET_PROTOCOL_HEADER_SESSION_SHIFT;
1030 flags = peerID & ENET_PROTOCOL_HEADER_FLAG_MASK;
1031 peerID &= ~ (ENET_PROTOCOL_HEADER_FLAG_MASK | ENET_PROTOCOL_HEADER_SESSION_MASK);
1032
1033 headerSize = (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME ? sizeof (ENetProtocolHeader) : (size_t) & ((ENetProtocolHeader *) 0) -> sentTime);
1034 if (host -> checksum != NULL)
1035 headerSize += sizeof (enet_uint32);
1036
1037 if (peerID == ENET_PROTOCOL_MAXIMUM_PEER_ID)
1038 peer = NULL;
1039 else
1040 if (peerID >= host -> peerCount)
1041 return 0;
1042 else
1043 {
1044 peer = host -> peer_list [peerID];
1045
1046 if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
1047 peer -> state == ENET_PEER_STATE_ZOMBIE ||
1048 ((host -> receivedAddress.host != peer -> address.host ||
1049 host -> receivedAddress.port != peer -> address.port) &&
1050 peer -> address.host != ENET_HOST_BROADCAST) ||
1051 (peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID &&
1052 sessionID != peer -> incomingSessionID))
1053 return 0;
1054 }
1055
1056 if (flags & ENET_PROTOCOL_HEADER_FLAG_COMPRESSED)
1057 {
1058 size_t originalSize;
1059 if (host -> compressor.context == NULL || host -> compressor.decompress == NULL)
1060 return 0;
1061
1062 originalSize = host -> compressor.decompress (host -> compressor.context,
1063 host -> receivedData + headerSize,
1064 host -> receivedDataLength - headerSize,
1065 host -> packetData [1] + headerSize,
1066 sizeof (host -> packetData [1]) - headerSize);
1067 if (originalSize <= 0 || originalSize > sizeof (host -> packetData [1]) - headerSize)
1068 return 0;
1069
1070 memcpy (host -> packetData [1], header, headerSize);
1071 host -> receivedData = host -> packetData [1];
1072 host -> receivedDataLength = headerSize + originalSize;
1073 }
1074
1075 if (host -> checksum != NULL)
1076 {
1077 enet_uint32 * checksum = (enet_uint32 *) & host -> receivedData [headerSize - sizeof (enet_uint32)],
1078 desiredChecksum = * checksum;
1079 ENetBuffer buffer;
1080
1081 * checksum = peer != NULL ? peer -> connectID : 0;
1082
1083 buffer.data = host -> receivedData;
1084 buffer.dataLength = host -> receivedDataLength;
1085
1086 if (host -> checksum (& buffer, 1) != desiredChecksum)
1087 return 0;
1088 }
1089
1090 if (peer != NULL)
1091 {
1092 peer -> address.host = host -> receivedAddress.host;
1093 peer -> address.port = host -> receivedAddress.port;
1094 peer -> incomingDataTotal += host -> receivedDataLength;
1095 }
1096
1097 currentData = host -> receivedData + headerSize;
1098
1099 while (currentData < & host -> receivedData [host -> receivedDataLength])
1100 {
1101 enet_uint8 commandNumber;
1102 size_t commandSize;
1103
1104 command = (ENetProtocol *) currentData;
1105
1106 if (currentData + sizeof (ENetProtocolCommandHeader) > & host -> receivedData [host -> receivedDataLength])
1107 break;
1108
1109 commandNumber = command -> header.command & ENET_PROTOCOL_COMMAND_MASK;
1110 if (commandNumber >= ENET_PROTOCOL_COMMAND_COUNT)
1111 break;
1112
1113 commandSize = commandSizes [commandNumber];
1114 if (commandSize == 0 || currentData + commandSize > & host -> receivedData [host -> receivedDataLength])
1115 break;
1116
1117 currentData += commandSize;
1118
1119 if (peer == NULL && commandNumber != ENET_PROTOCOL_COMMAND_CONNECT)
1120 break;
1121
1122 command -> header.reliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> header.reliableSequenceNumber);
1123
1124 switch (commandNumber)
1125 {
1126 case ENET_PROTOCOL_COMMAND_ACKNOWLEDGE:
1127 if (enet_protocol_handle_acknowledge (host, event, peer, command))
1128 goto commandError;
1129 break;
1130
1131 case ENET_PROTOCOL_COMMAND_CONNECT:
1132 if (peer != NULL)
1133 goto commandError;
1134 peer = enet_protocol_handle_connect (host, header, command);
1135 if (peer == NULL)
1136 goto commandError;
1137 break;
1138
1139 case ENET_PROTOCOL_COMMAND_VERIFY_CONNECT:
1140 if (enet_protocol_handle_verify_connect (host, event, peer, command))
1141 goto commandError;
1142 break;
1143
1144 case ENET_PROTOCOL_COMMAND_DISCONNECT:
1145 if (enet_protocol_handle_disconnect (host, peer, command))
1146 goto commandError;
1147 break;
1148
1149 case ENET_PROTOCOL_COMMAND_PING:
1150 if (enet_protocol_handle_ping (host, peer, command))
1151 goto commandError;
1152 break;
1153
1154 case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
1155 if (enet_protocol_handle_send_reliable (host, peer, command, & currentData))
1156 goto commandError;
1157 break;
1158
1159 case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE:
1160 if (enet_protocol_handle_send_unreliable (host, peer, command, & currentData))
1161 goto commandError;
1162 break;
1163
1164 case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED:
1165 if (enet_protocol_handle_send_unsequenced (host, peer, command, & currentData))
1166 goto commandError;
1167 break;
1168
1169 case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
1170 if (enet_protocol_handle_send_fragment (host, peer, command, & currentData))
1171 goto commandError;
1172 break;
1173
1174 case ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT:
1175 if (enet_protocol_handle_bandwidth_limit (host, peer, command))
1176 goto commandError;
1177 break;
1178
1179 case ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE:
1180 if (enet_protocol_handle_throttle_configure (host, peer, command))
1181 goto commandError;
1182 break;
1183
1184 case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT:
1185 if (enet_protocol_handle_send_unreliable_fragment (host, peer, command, & currentData))
1186 goto commandError;
1187 break;
1188
1189 default:
1190 goto commandError;
1191 }
1192
1193 if (peer != NULL &&
1194 (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) != 0)
1195 {
1196 enet_uint16 sentTime;
1197
1198 if (! (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME))
1199 break;
1200
1201 sentTime = ENET_NET_TO_HOST_16 (header -> sentTime);
1202
1203 switch (peer -> state)
1204 {
1205 case ENET_PEER_STATE_DISCONNECTING:
1206 case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT:
1207 case ENET_PEER_STATE_DISCONNECTED:
1208 case ENET_PEER_STATE_ZOMBIE:
1209 break;
1210
1211 case ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT:
1212 if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT)
1213 enet_peer_queue_acknowledgement (peer, command, sentTime);
1214 break;
1215
1216 default:
1217 enet_peer_queue_acknowledgement (peer, command, sentTime);
1218 break;
1219 }
1220 }
1221 }
1222
1223 commandError:
1224 if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE)
1225 return 1;
1226
1227 return 0;
1228 }
1229
1230 static int
enet_protocol_receive_incoming_commands(ENetHost * host,ENetEvent * event)1231 enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
1232 {
1233 int packets;
1234
1235 for (packets = 0; packets < 256; ++ packets)
1236 {
1237 int receivedLength;
1238 ENetBuffer buffer;
1239
1240 buffer.data = host -> packetData [0];
1241 buffer.dataLength = sizeof (host -> packetData [0]);
1242
1243 receivedLength = enet_socket_receive (host -> socket,
1244 & host -> receivedAddress,
1245 & buffer,
1246 1);
1247
1248 if (receivedLength < 0)
1249 return -1;
1250
1251 if (receivedLength == 0)
1252 return 0;
1253
1254 host -> receivedData = host -> packetData [0];
1255 host -> receivedDataLength = receivedLength;
1256
1257 host -> totalReceivedData += receivedLength;
1258 host -> totalReceivedPackets ++;
1259
1260 if (host -> intercept != NULL)
1261 {
1262 switch (host -> intercept (host, event))
1263 {
1264 case 1:
1265 if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE)
1266 return 1;
1267
1268 continue;
1269
1270 case -1:
1271 return -1;
1272
1273 default:
1274 break;
1275 }
1276 }
1277
1278 switch (enet_protocol_handle_incoming_commands (host, event))
1279 {
1280 case 1:
1281 return 1;
1282
1283 case -1:
1284 return -1;
1285
1286 default:
1287 break;
1288 }
1289 }
1290
1291 return -1;
1292 }
1293
1294 static void
enet_protocol_send_acknowledgements(ENetHost * host,ENetPeer * peer)1295 enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer)
1296 {
1297 ENetProtocol * command = & host -> commands [host -> commandCount];
1298 ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
1299 ENetAcknowledgement * acknowledgement;
1300 ENetListIterator currentAcknowledgement;
1301 enet_uint16 reliableSequenceNumber;
1302
1303 currentAcknowledgement = enet_list_begin (& peer -> acknowledgements);
1304
1305 while (currentAcknowledgement != enet_list_end (& peer -> acknowledgements))
1306 {
1307 if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
1308 buffer >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
1309 peer -> mtu - host -> packetSize < sizeof (ENetProtocolAcknowledge))
1310 {
1311 host -> continueSending = 1;
1312
1313 break;
1314 }
1315
1316 acknowledgement = (ENetAcknowledgement *) currentAcknowledgement;
1317
1318 currentAcknowledgement = enet_list_next (currentAcknowledgement);
1319
1320 buffer -> data = command;
1321 buffer -> dataLength = sizeof (ENetProtocolAcknowledge);
1322
1323 host -> packetSize += buffer -> dataLength;
1324
1325 reliableSequenceNumber = ENET_HOST_TO_NET_16 (acknowledgement -> command.header.reliableSequenceNumber);
1326
1327 command -> header.command = ENET_PROTOCOL_COMMAND_ACKNOWLEDGE;
1328 command -> header.channelID = acknowledgement -> command.header.channelID;
1329 command -> header.reliableSequenceNumber = reliableSequenceNumber;
1330 command -> acknowledge.receivedReliableSequenceNumber = reliableSequenceNumber;
1331 command -> acknowledge.receivedSentTime = ENET_HOST_TO_NET_16 (acknowledgement -> sentTime);
1332
1333 if ((acknowledgement -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT)
1334 enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);
1335
1336 enet_list_remove (& acknowledgement -> acknowledgementList);
1337 enet_free (acknowledgement);
1338
1339 ++ command;
1340 ++ buffer;
1341 }
1342
1343 host -> commandCount = command - host -> commands;
1344 host -> bufferCount = buffer - host -> buffers;
1345 }
1346
1347 static void
enet_protocol_send_unreliable_outgoing_commands(ENetHost * host,ENetPeer * peer)1348 enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
1349 {
1350 ENetProtocol * command = & host -> commands [host -> commandCount];
1351 ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
1352 ENetOutgoingCommand * outgoingCommand;
1353 ENetListIterator currentCommand;
1354
1355 currentCommand = enet_list_begin (& peer -> outgoingUnreliableCommands);
1356
1357 while (currentCommand != enet_list_end (& peer -> outgoingUnreliableCommands))
1358 {
1359 size_t commandSize;
1360
1361 outgoingCommand = (ENetOutgoingCommand *) currentCommand;
1362 commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK];
1363
1364 if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
1365 buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
1366 peer -> mtu - host -> packetSize < commandSize ||
1367 (outgoingCommand -> packet != NULL &&
1368 peer -> mtu - host -> packetSize < commandSize + outgoingCommand -> fragmentLength))
1369 {
1370 host -> continueSending = 1;
1371
1372 break;
1373 }
1374
1375 currentCommand = enet_list_next (currentCommand);
1376
1377 if (outgoingCommand -> packet != NULL && outgoingCommand -> fragmentOffset == 0)
1378 {
1379 peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER;
1380 peer -> packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE;
1381
1382 if (peer -> packetThrottleCounter > peer -> packetThrottle)
1383 {
1384 enet_uint16 reliableSequenceNumber = outgoingCommand -> reliableSequenceNumber,
1385 unreliableSequenceNumber = outgoingCommand -> unreliableSequenceNumber;
1386 for (;;)
1387 {
1388 -- outgoingCommand -> packet -> referenceCount;
1389
1390 if (outgoingCommand -> packet -> referenceCount == 0)
1391 enet_packet_destroy (outgoingCommand -> packet);
1392
1393 enet_list_remove (& outgoingCommand -> outgoingCommandList);
1394 enet_free (outgoingCommand);
1395
1396 if (currentCommand == enet_list_end (& peer -> outgoingUnreliableCommands))
1397 break;
1398
1399 outgoingCommand = (ENetOutgoingCommand *) currentCommand;
1400 if (outgoingCommand -> reliableSequenceNumber != reliableSequenceNumber ||
1401 outgoingCommand -> unreliableSequenceNumber != unreliableSequenceNumber)
1402 break;
1403
1404 currentCommand = enet_list_next (currentCommand);
1405 }
1406
1407 continue;
1408 }
1409 }
1410
1411 buffer -> data = command;
1412 buffer -> dataLength = commandSize;
1413
1414 host -> packetSize += buffer -> dataLength;
1415
1416 * command = outgoingCommand -> command;
1417
1418 enet_list_remove (& outgoingCommand -> outgoingCommandList);
1419
1420 if (outgoingCommand -> packet != NULL)
1421 {
1422 ++ buffer;
1423
1424 buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset;
1425 buffer -> dataLength = outgoingCommand -> fragmentLength;
1426
1427 host -> packetSize += buffer -> dataLength;
1428
1429 enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand);
1430 }
1431 else
1432 enet_free (outgoingCommand);
1433
1434 ++ command;
1435 ++ buffer;
1436 }
1437
1438 host -> commandCount = command - host -> commands;
1439 host -> bufferCount = buffer - host -> buffers;
1440
1441 if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER &&
1442 enet_list_empty (& peer -> outgoingReliableCommands) &&
1443 enet_list_empty (& peer -> outgoingUnreliableCommands) &&
1444 enet_list_empty (& peer -> sentReliableCommands))
1445 enet_peer_disconnect (peer, peer -> eventData);
1446 }
1447
1448 static int
enet_protocol_check_timeouts(ENetHost * host,ENetPeer * peer,ENetEvent * event)1449 enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * event)
1450 {
1451 ENetOutgoingCommand * outgoingCommand;
1452 ENetListIterator currentCommand, insertPosition;
1453
1454 currentCommand = enet_list_begin (& peer -> sentReliableCommands);
1455 insertPosition = enet_list_begin (& peer -> outgoingReliableCommands);
1456
1457 while (currentCommand != enet_list_end (& peer -> sentReliableCommands))
1458 {
1459 outgoingCommand = (ENetOutgoingCommand *) currentCommand;
1460
1461 currentCommand = enet_list_next (currentCommand);
1462
1463 if (ENET_TIME_DIFFERENCE (host -> serviceTime, outgoingCommand -> sentTime) < outgoingCommand -> roundTripTimeout)
1464 continue;
1465
1466 if (peer -> earliestTimeout == 0 ||
1467 ENET_TIME_LESS (outgoingCommand -> sentTime, peer -> earliestTimeout))
1468 peer -> earliestTimeout = outgoingCommand -> sentTime;
1469
1470 if (peer -> earliestTimeout != 0 &&
1471 (ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMaximum ||
1472 (outgoingCommand -> roundTripTimeout >= outgoingCommand -> roundTripTimeoutLimit &&
1473 ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMinimum)))
1474 {
1475 enet_protocol_notify_disconnect (host, peer, event);
1476
1477 return 1;
1478 }
1479
1480 if (outgoingCommand -> packet != NULL)
1481 peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength;
1482
1483 ++ peer -> packetsLost;
1484
1485 outgoingCommand -> roundTripTimeout *= 2;
1486
1487 enet_list_insert (insertPosition, enet_list_remove (& outgoingCommand -> outgoingCommandList));
1488
1489 if (currentCommand == enet_list_begin (& peer -> sentReliableCommands) &&
1490 ! enet_list_empty (& peer -> sentReliableCommands))
1491 {
1492 outgoingCommand = (ENetOutgoingCommand *) currentCommand;
1493
1494 peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout;
1495 }
1496 }
1497
1498 return 0;
1499 }
1500
1501 static int
enet_protocol_send_reliable_outgoing_commands(ENetHost * host,ENetPeer * peer)1502 enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
1503 {
1504 ENetProtocol * command = & host -> commands [host -> commandCount];
1505 ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
1506 ENetOutgoingCommand * outgoingCommand;
1507 ENetListIterator currentCommand;
1508 ENetChannel *channel;
1509 enet_uint16 reliableWindow;
1510 size_t commandSize;
1511 int windowExceeded = 0, windowWrap = 0, canPing = 1;
1512
1513 currentCommand = enet_list_begin (& peer -> outgoingReliableCommands);
1514
1515 while (currentCommand != enet_list_end (& peer -> outgoingReliableCommands))
1516 {
1517 outgoingCommand = (ENetOutgoingCommand *) currentCommand;
1518
1519 channel = outgoingCommand -> command.header.channelID < peer -> channelCount ? & peer -> channels [outgoingCommand -> command.header.channelID] : NULL;
1520 reliableWindow = outgoingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
1521 if (channel != NULL)
1522 {
1523 if (! windowWrap &&
1524 outgoingCommand -> sendAttempts < 1 &&
1525 ! (outgoingCommand -> reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) &&
1526 (channel -> reliableWindows [(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE ||
1527 channel -> usedReliableWindows & ((((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) << reliableWindow) |
1528 (((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) >> (ENET_PEER_RELIABLE_WINDOWS - reliableWindow)))))
1529 windowWrap = 1;
1530 if (windowWrap)
1531 {
1532 currentCommand = enet_list_next (currentCommand);
1533
1534 continue;
1535 }
1536 }
1537
1538 if (outgoingCommand -> packet != NULL)
1539 {
1540 if (! windowExceeded)
1541 {
1542 enet_uint32 windowSize = (peer -> packetThrottle * peer -> windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE;
1543
1544 if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > ENET_MAX (windowSize, peer -> mtu))
1545 windowExceeded = 1;
1546 }
1547 if (windowExceeded)
1548 {
1549 currentCommand = enet_list_next (currentCommand);
1550
1551 continue;
1552 }
1553 }
1554
1555 canPing = 0;
1556
1557 commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK];
1558 if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
1559 buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
1560 peer -> mtu - host -> packetSize < commandSize ||
1561 (outgoingCommand -> packet != NULL &&
1562 (enet_uint16) (peer -> mtu - host -> packetSize) < (enet_uint16) (commandSize + outgoingCommand -> fragmentLength)))
1563 {
1564 host -> continueSending = 1;
1565
1566 break;
1567 }
1568
1569 currentCommand = enet_list_next (currentCommand);
1570
1571 if (channel != NULL && outgoingCommand -> sendAttempts < 1)
1572 {
1573 channel -> usedReliableWindows |= 1 << reliableWindow;
1574 ++ channel -> reliableWindows [reliableWindow];
1575 }
1576
1577 ++ outgoingCommand -> sendAttempts;
1578
1579 if (outgoingCommand -> roundTripTimeout == 0)
1580 {
1581 outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance;
1582 outgoingCommand -> roundTripTimeoutLimit = peer -> timeoutLimit * outgoingCommand -> roundTripTimeout;
1583 }
1584
1585 if (enet_list_empty (& peer -> sentReliableCommands))
1586 peer -> nextTimeout = host -> serviceTime + outgoingCommand -> roundTripTimeout;
1587
1588 enet_list_insert (enet_list_end (& peer -> sentReliableCommands),
1589 enet_list_remove (& outgoingCommand -> outgoingCommandList));
1590
1591 outgoingCommand -> sentTime = host -> serviceTime;
1592
1593 buffer -> data = command;
1594 buffer -> dataLength = commandSize;
1595
1596 host -> packetSize += buffer -> dataLength;
1597 host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME;
1598
1599 * command = outgoingCommand -> command;
1600
1601 if (outgoingCommand -> packet != NULL)
1602 {
1603 ++ buffer;
1604
1605 buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset;
1606 buffer -> dataLength = outgoingCommand -> fragmentLength;
1607
1608 host -> packetSize += outgoingCommand -> fragmentLength;
1609
1610 peer -> reliableDataInTransit += outgoingCommand -> fragmentLength;
1611 }
1612
1613 ++ peer -> packetsSent;
1614
1615 ++ command;
1616 ++ buffer;
1617 }
1618
1619 host -> commandCount = command - host -> commands;
1620 host -> bufferCount = buffer - host -> buffers;
1621
1622 return canPing;
1623 }
1624
1625 static int
enet_protocol_send_outgoing_commands(ENetHost * host,ENetEvent * event,int checkForTimeouts)1626 enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int checkForTimeouts)
1627 {
1628 enet_uint8 headerData [sizeof (ENetProtocolHeader) + sizeof (enet_uint32)];
1629 ENetProtocolHeader * header = (ENetProtocolHeader *) headerData;
1630 ENetPeer * currentPeer;
1631 int sentLength;
1632 size_t shouldCompress = 0;
1633 int i;
1634
1635 host -> continueSending = 1;
1636
1637 while (host -> continueSending)
1638 for (host -> continueSending = 0,
1639 i = 0; i < host -> peerCount; i++ )
1640 {
1641 currentPeer = host -> peer_list[i];
1642 if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED ||
1643 currentPeer -> state == ENET_PEER_STATE_ZOMBIE)
1644 continue;
1645
1646 host -> headerFlags = 0;
1647 host -> commandCount = 0;
1648 host -> bufferCount = 1;
1649 host -> packetSize = sizeof (ENetProtocolHeader);
1650
1651 if (! enet_list_empty (& currentPeer -> acknowledgements))
1652 enet_protocol_send_acknowledgements (host, currentPeer);
1653
1654 if (checkForTimeouts != 0 &&
1655 ! enet_list_empty (& currentPeer -> sentReliableCommands) &&
1656 ENET_TIME_GREATER_EQUAL (host -> serviceTime, currentPeer -> nextTimeout) &&
1657 enet_protocol_check_timeouts (host, currentPeer, event) == 1)
1658 {
1659 if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE)
1660 return 1;
1661 else
1662 continue;
1663 }
1664
1665 if ((enet_list_empty (& currentPeer -> outgoingReliableCommands) ||
1666 enet_protocol_send_reliable_outgoing_commands (host, currentPeer)) &&
1667 enet_list_empty (& currentPeer -> sentReliableCommands) &&
1668 ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= currentPeer -> pingInterval &&
1669 currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing))
1670 {
1671 enet_peer_ping (currentPeer);
1672 enet_protocol_send_reliable_outgoing_commands (host, currentPeer);
1673 }
1674
1675 if (! enet_list_empty (& currentPeer -> outgoingUnreliableCommands))
1676 enet_protocol_send_unreliable_outgoing_commands (host, currentPeer);
1677
1678 if (host -> commandCount == 0)
1679 continue;
1680
1681 if (currentPeer -> packetLossEpoch == 0)
1682 currentPeer -> packetLossEpoch = host -> serviceTime;
1683 else
1684 if (ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> packetLossEpoch) >= ENET_PEER_PACKET_LOSS_INTERVAL &&
1685 currentPeer -> packetsSent > 0)
1686 {
1687 enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent;
1688
1689 #ifdef ENET_DEBUG
1690 printf ("peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingReliableCommands), enet_list_size (& currentPeer -> outgoingUnreliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0);
1691 #endif
1692
1693 currentPeer -> packetLossVariance -= currentPeer -> packetLossVariance / 4;
1694
1695 if (packetLoss >= currentPeer -> packetLoss)
1696 {
1697 currentPeer -> packetLoss += (packetLoss - currentPeer -> packetLoss) / 8;
1698 currentPeer -> packetLossVariance += (packetLoss - currentPeer -> packetLoss) / 4;
1699 }
1700 else
1701 {
1702 currentPeer -> packetLoss -= (currentPeer -> packetLoss - packetLoss) / 8;
1703 currentPeer -> packetLossVariance += (currentPeer -> packetLoss - packetLoss) / 4;
1704 }
1705
1706 currentPeer -> packetLossEpoch = host -> serviceTime;
1707 currentPeer -> packetsSent = 0;
1708 currentPeer -> packetsLost = 0;
1709 }
1710
1711 host -> buffers -> data = headerData;
1712 if (host -> headerFlags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME)
1713 {
1714 header -> sentTime = ENET_HOST_TO_NET_16 (host -> serviceTime & 0xFFFF);
1715
1716 host -> buffers -> dataLength = sizeof (ENetProtocolHeader);
1717 }
1718 else
1719 host -> buffers -> dataLength = (size_t) & ((ENetProtocolHeader *) 0) -> sentTime;
1720
1721 shouldCompress = 0;
1722 if (host -> compressor.context != NULL && host -> compressor.compress != NULL)
1723 {
1724 size_t originalSize = host -> packetSize - sizeof(ENetProtocolHeader),
1725 compressedSize = host -> compressor.compress (host -> compressor.context,
1726 & host -> buffers [1], host -> bufferCount - 1,
1727 originalSize,
1728 host -> packetData [1],
1729 originalSize);
1730 if (compressedSize > 0 && compressedSize < originalSize)
1731 {
1732 host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_COMPRESSED;
1733 shouldCompress = compressedSize;
1734 #ifdef ENET_DEBUG_COMPRESS
1735 printf ("peer %u: compressed %u -> %u (%u%%)\n", currentPeer -> incomingPeerID, originalSize, compressedSize, (compressedSize * 100) / originalSize);
1736 #endif
1737 }
1738 }
1739
1740 if (currentPeer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID)
1741 host -> headerFlags |= currentPeer -> outgoingSessionID << ENET_PROTOCOL_HEADER_SESSION_SHIFT;
1742 header -> peerID = ENET_HOST_TO_NET_32 (currentPeer -> outgoingPeerID | host -> headerFlags);
1743 if (host -> checksum != NULL)
1744 {
1745 enet_uint32 * checksum = (enet_uint32 *) & headerData [host -> buffers -> dataLength];
1746 * checksum = currentPeer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID ? currentPeer -> connectID : 0;
1747 host -> buffers -> dataLength += sizeof (enet_uint32);
1748 * checksum = host -> checksum (host -> buffers, host -> bufferCount);
1749 }
1750
1751 if (shouldCompress > 0)
1752 {
1753 host -> buffers [1].data = host -> packetData [1];
1754 host -> buffers [1].dataLength = shouldCompress;
1755 host -> bufferCount = 2;
1756 }
1757
1758 currentPeer -> lastSendTime = host -> serviceTime;
1759
1760 sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount);
1761
1762 enet_protocol_remove_sent_unreliable_commands (currentPeer);
1763
1764 if (sentLength < 0)
1765 return -1;
1766
1767 host -> totalSentData += sentLength;
1768 host -> totalSentPackets ++;
1769 }
1770
1771 return 0;
1772 }
1773
1774 /** Sends any queued packets on the host specified to its designated peers.
1775
1776 @param host host to flush
1777 @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().
1778 @ingroup host
1779 */
1780 void
enet_host_flush(ENetHost * host)1781 enet_host_flush (ENetHost * host)
1782 {
1783 host -> serviceTime = enet_time_get ();
1784
1785 enet_protocol_send_outgoing_commands (host, NULL, 0);
1786 }
1787
1788 /** Checks for any queued events on the host and dispatches one if available.
1789
1790 @param host host to check for events
1791 @param event an event structure where event details will be placed if available
1792 @retval > 0 if an event was dispatched
1793 @retval 0 if no events are available
1794 @retval < 0 on failure
1795 @ingroup host
1796 */
1797 int
enet_host_check_events(ENetHost * host,ENetEvent * event)1798 enet_host_check_events (ENetHost * host, ENetEvent * event)
1799 {
1800 if (event == NULL) return -1;
1801
1802 event -> type = ENET_EVENT_TYPE_NONE;
1803 event -> peer = NULL;
1804 event -> packet = NULL;
1805
1806 return enet_protocol_dispatch_incoming_commands (host, event);
1807 }
1808
1809 /** Waits for events on the host specified and shuttles packets between
1810 the host and its peers.
1811
1812 @param host host to service
1813 @param event an event structure where event details will be placed if one occurs
1814 if event == NULL then no events will be delivered
1815 @param timeout number of milliseconds that ENet should wait for events
1816 @retval > 0 if an event occurred within the specified time limit
1817 @retval 0 if no event occurred
1818 @retval < 0 on failure
1819 @remarks enet_host_service should be called fairly regularly for adequate performance
1820 @ingroup host
1821 */
1822 int
enet_host_service(ENetHost * host,ENetEvent * event,enet_uint32 timeout)1823 enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
1824 {
1825 enet_uint32 waitCondition;
1826
1827 if (event != NULL)
1828 {
1829 event -> type = ENET_EVENT_TYPE_NONE;
1830 event -> peer = NULL;
1831 event -> packet = NULL;
1832
1833 switch (enet_protocol_dispatch_incoming_commands (host, event))
1834 {
1835 case 1:
1836 return 1;
1837
1838 case -1:
1839 #ifdef ENET_DEBUG
1840 perror ("Error dispatching incoming packets");
1841 #endif
1842
1843 return -1;
1844
1845 default:
1846 break;
1847 }
1848 }
1849
1850 host -> serviceTime = enet_time_get ();
1851
1852 timeout += host -> serviceTime;
1853
1854 do
1855 {
1856 if (ENET_TIME_DIFFERENCE (host -> serviceTime, host -> bandwidthThrottleEpoch) >= ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
1857 enet_host_bandwidth_throttle (host);
1858
1859 switch (enet_protocol_send_outgoing_commands (host, event, 1))
1860 {
1861 case 1:
1862 return 1;
1863
1864 case -1:
1865 #ifdef ENET_DEBUG
1866 perror ("Error sending outgoing packets");
1867 #endif
1868
1869 return -1;
1870
1871 default:
1872 break;
1873 }
1874
1875 switch (enet_protocol_receive_incoming_commands (host, event))
1876 {
1877 case 1:
1878 return 1;
1879
1880 case -1:
1881 #ifdef ENET_DEBUG
1882 perror ("Error receiving incoming packets");
1883 #endif
1884
1885 return -1;
1886
1887 default:
1888 break;
1889 }
1890
1891 switch (enet_protocol_send_outgoing_commands (host, event, 1))
1892 {
1893 case 1:
1894 return 1;
1895
1896 case -1:
1897 #ifdef ENET_DEBUG
1898 perror ("Error sending outgoing packets");
1899 #endif
1900
1901 return -1;
1902
1903 default:
1904 break;
1905 }
1906
1907 if (event != NULL)
1908 {
1909 switch (enet_protocol_dispatch_incoming_commands (host, event))
1910 {
1911 case 1:
1912 return 1;
1913
1914 case -1:
1915 #ifdef ENET_DEBUG
1916 perror ("Error dispatching incoming packets");
1917 #endif
1918
1919 return -1;
1920
1921 default:
1922 break;
1923 }
1924 }
1925
1926 if (ENET_TIME_GREATER_EQUAL (host -> serviceTime, timeout))
1927 return 0;
1928
1929 do
1930 {
1931 host -> serviceTime = enet_time_get ();
1932
1933 if (ENET_TIME_GREATER_EQUAL (host -> serviceTime, timeout))
1934 return 0;
1935
1936 waitCondition = ENET_SOCKET_WAIT_RECEIVE | ENET_SOCKET_WAIT_INTERRUPT;
1937
1938 if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0)
1939 return -1;
1940 }
1941 while (waitCondition & ENET_SOCKET_WAIT_INTERRUPT);
1942
1943 host -> serviceTime = enet_time_get ();
1944 } while (waitCondition & ENET_SOCKET_WAIT_RECEIVE);
1945
1946 return 0;
1947 }
1948
1949 int
enet_host_get_sock_fd(ENetHost * host)1950 enet_host_get_sock_fd (ENetHost *host)
1951 {
1952 return host -> socket;
1953 }
1954