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