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