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