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 |
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 -> needsDispatch) |
52 | { |
53 | enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList); |
54 | |
55 | peer -> needsDispatch = 1; |
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 -> 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 |
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) |
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 |
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 * |
275 | enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * , 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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 | if (peer -> incomingBandwidth == 0 || host -> outgoingBandwidth == 0) |
769 | peer -> windowSize = (ENET_MAX (peer -> incomingBandwidth, host -> outgoingBandwidth) / |
770 | ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; |
771 | else |
772 | peer -> windowSize = (ENET_MIN (peer -> incomingBandwidth, host -> outgoingBandwidth) / |
773 | ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; |
774 | |
775 | if (peer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) |
776 | peer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; |
777 | else |
778 | if (peer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) |
779 | peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; |
780 | |
781 | return 0; |
782 | } |
783 | |
784 | static int |
785 | enet_protocol_handle_throttle_configure (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) |
786 | { |
787 | if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) |
788 | return -1; |
789 | |
790 | peer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleInterval); |
791 | peer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleAcceleration); |
792 | peer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleDeceleration); |
793 | |
794 | return 0; |
795 | } |
796 | |
797 | static int |
798 | enet_protocol_handle_disconnect (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) |
799 | { |
800 | if (peer -> state == ENET_PEER_STATE_DISCONNECTED || peer -> state == ENET_PEER_STATE_ZOMBIE || peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT) |
801 | return 0; |
802 | |
803 | enet_peer_reset_queues (peer); |
804 | |
805 | if (peer -> state == ENET_PEER_STATE_CONNECTION_SUCCEEDED || peer -> state == ENET_PEER_STATE_DISCONNECTING || peer -> state == ENET_PEER_STATE_CONNECTING) |
806 | enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); |
807 | else |
808 | if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) |
809 | { |
810 | if (peer -> state == ENET_PEER_STATE_CONNECTION_PENDING) host -> recalculateBandwidthLimits = 1; |
811 | |
812 | enet_peer_reset (peer); |
813 | } |
814 | else |
815 | if (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) |
816 | enet_protocol_change_state (host, peer, ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT); |
817 | else |
818 | enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); |
819 | |
820 | if (peer -> state != ENET_PEER_STATE_DISCONNECTED) |
821 | peer -> eventData = ENET_NET_TO_HOST_32 (command -> disconnect.data); |
822 | |
823 | return 0; |
824 | } |
825 | |
826 | static int |
827 | enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command) |
828 | { |
829 | enet_uint32 roundTripTime, |
830 | receivedSentTime, |
831 | receivedReliableSequenceNumber; |
832 | ENetProtocolCommand commandNumber; |
833 | |
834 | if (peer -> state == ENET_PEER_STATE_DISCONNECTED || peer -> state == ENET_PEER_STATE_ZOMBIE) |
835 | return 0; |
836 | |
837 | receivedSentTime = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedSentTime); |
838 | receivedSentTime |= host -> serviceTime & 0xFFFF0000; |
839 | if ((receivedSentTime & 0x8000) > (host -> serviceTime & 0x8000)) |
840 | receivedSentTime -= 0x10000; |
841 | |
842 | if (ENET_TIME_LESS (host -> serviceTime, receivedSentTime)) |
843 | return 0; |
844 | |
845 | peer -> lastReceiveTime = host -> serviceTime; |
846 | peer -> earliestTimeout = 0; |
847 | |
848 | roundTripTime = ENET_TIME_DIFFERENCE (host -> serviceTime, receivedSentTime); |
849 | |
850 | enet_peer_throttle (peer, roundTripTime); |
851 | |
852 | peer -> roundTripTimeVariance -= peer -> roundTripTimeVariance / 4; |
853 | |
854 | if (roundTripTime >= peer -> roundTripTime) |
855 | { |
856 | peer -> roundTripTime += (roundTripTime - peer -> roundTripTime) / 8; |
857 | peer -> roundTripTimeVariance += (roundTripTime - peer -> roundTripTime) / 4; |
858 | } |
859 | else |
860 | { |
861 | peer -> roundTripTime -= (peer -> roundTripTime - roundTripTime) / 8; |
862 | peer -> roundTripTimeVariance += (peer -> roundTripTime - roundTripTime) / 4; |
863 | } |
864 | |
865 | if (peer -> roundTripTime < peer -> lowestRoundTripTime) |
866 | peer -> lowestRoundTripTime = peer -> roundTripTime; |
867 | |
868 | if (peer -> roundTripTimeVariance > peer -> highestRoundTripTimeVariance) |
869 | peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance; |
870 | |
871 | if (peer -> packetThrottleEpoch == 0 || |
872 | ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> packetThrottleEpoch) >= peer -> packetThrottleInterval) |
873 | { |
874 | peer -> lastRoundTripTime = peer -> lowestRoundTripTime; |
875 | peer -> lastRoundTripTimeVariance = peer -> highestRoundTripTimeVariance; |
876 | peer -> lowestRoundTripTime = peer -> roundTripTime; |
877 | peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance; |
878 | peer -> packetThrottleEpoch = host -> serviceTime; |
879 | } |
880 | |
881 | receivedReliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedReliableSequenceNumber); |
882 | |
883 | commandNumber = enet_protocol_remove_sent_reliable_command (peer, receivedReliableSequenceNumber, command -> header.channelID); |
884 | |
885 | switch (peer -> state) |
886 | { |
887 | case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT: |
888 | if (commandNumber != ENET_PROTOCOL_COMMAND_VERIFY_CONNECT) |
889 | return -1; |
890 | |
891 | enet_protocol_notify_connect (host, peer, event); |
892 | break; |
893 | |
894 | case ENET_PEER_STATE_DISCONNECTING: |
895 | if (commandNumber != ENET_PROTOCOL_COMMAND_DISCONNECT) |
896 | return -1; |
897 | |
898 | enet_protocol_notify_disconnect (host, peer, event); |
899 | break; |
900 | |
901 | case ENET_PEER_STATE_DISCONNECT_LATER: |
902 | if (enet_list_empty (& peer -> outgoingReliableCommands) && |
903 | enet_list_empty (& peer -> outgoingUnreliableCommands) && |
904 | enet_list_empty (& peer -> sentReliableCommands)) |
905 | enet_peer_disconnect (peer, peer -> eventData); |
906 | break; |
907 | |
908 | default: |
909 | break; |
910 | } |
911 | |
912 | return 0; |
913 | } |
914 | |
915 | static int |
916 | enet_protocol_handle_verify_connect (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command) |
917 | { |
918 | enet_uint32 mtu, windowSize; |
919 | size_t channelCount; |
920 | |
921 | if (peer -> state != ENET_PEER_STATE_CONNECTING) |
922 | return 0; |
923 | |
924 | channelCount = ENET_NET_TO_HOST_32 (command -> verifyConnect.channelCount); |
925 | |
926 | if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT || channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT || |
927 | ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleInterval) != peer -> packetThrottleInterval || |
928 | ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleAcceleration) != peer -> packetThrottleAcceleration || |
929 | ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleDeceleration) != peer -> packetThrottleDeceleration || |
930 | command -> verifyConnect.connectID != peer -> connectID) |
931 | { |
932 | peer -> eventData = 0; |
933 | |
934 | enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); |
935 | |
936 | return -1; |
937 | } |
938 | |
939 | enet_protocol_remove_sent_reliable_command (peer, 1, 0xFF); |
940 | |
941 | if (channelCount < peer -> channelCount) |
942 | peer -> channelCount = channelCount; |
943 | |
944 | peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> verifyConnect.outgoingPeerID); |
945 | peer -> incomingSessionID = command -> verifyConnect.incomingSessionID; |
946 | peer -> outgoingSessionID = command -> verifyConnect.outgoingSessionID; |
947 | |
948 | mtu = ENET_NET_TO_HOST_32 (command -> verifyConnect.mtu); |
949 | |
950 | if (mtu < ENET_PROTOCOL_MINIMUM_MTU) |
951 | mtu = ENET_PROTOCOL_MINIMUM_MTU; |
952 | else |
953 | if (mtu > ENET_PROTOCOL_MAXIMUM_MTU) |
954 | mtu = ENET_PROTOCOL_MAXIMUM_MTU; |
955 | |
956 | if (mtu < peer -> mtu) |
957 | peer -> mtu = mtu; |
958 | |
959 | windowSize = ENET_NET_TO_HOST_32 (command -> verifyConnect.windowSize); |
960 | |
961 | if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) |
962 | windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; |
963 | |
964 | if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) |
965 | windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; |
966 | |
967 | if (windowSize < peer -> windowSize) |
968 | peer -> windowSize = windowSize; |
969 | |
970 | peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.incomingBandwidth); |
971 | peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.outgoingBandwidth); |
972 | |
973 | enet_protocol_notify_connect (host, peer, event); |
974 | return 0; |
975 | } |
976 | |
977 | static int |
978 | enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) |
979 | { |
980 | ENetProtocolHeader * ; |
981 | ENetProtocol * command; |
982 | ENetPeer * peer; |
983 | enet_uint8 * currentData; |
984 | size_t ; |
985 | enet_uint16 peerID, flags; |
986 | enet_uint8 sessionID; |
987 | |
988 | if (host -> receivedDataLength < (size_t) & ((ENetProtocolHeader *) 0) -> sentTime) |
989 | return 0; |
990 | |
991 | header = (ENetProtocolHeader *) host -> receivedData; |
992 | |
993 | peerID = ENET_NET_TO_HOST_16 (header -> peerID); |
994 | sessionID = (peerID & ENET_PROTOCOL_HEADER_SESSION_MASK) >> ENET_PROTOCOL_HEADER_SESSION_SHIFT; |
995 | flags = peerID & ENET_PROTOCOL_HEADER_FLAG_MASK; |
996 | peerID &= ~ (ENET_PROTOCOL_HEADER_FLAG_MASK | ENET_PROTOCOL_HEADER_SESSION_MASK); |
997 | |
998 | headerSize = (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME ? sizeof (ENetProtocolHeader) : (size_t) & ((ENetProtocolHeader *) 0) -> sentTime); |
999 | if (host -> checksum != NULL) |
1000 | headerSize += sizeof (enet_uint32); |
1001 | |
1002 | if (peerID == ENET_PROTOCOL_MAXIMUM_PEER_ID) |
1003 | peer = NULL; |
1004 | else |
1005 | if (peerID >= host -> peerCount) |
1006 | return 0; |
1007 | else |
1008 | { |
1009 | peer = & host -> peers [peerID]; |
1010 | |
1011 | if (peer -> state == ENET_PEER_STATE_DISCONNECTED || |
1012 | peer -> state == ENET_PEER_STATE_ZOMBIE || |
1013 | ((host -> receivedAddress.host != peer -> address.host || |
1014 | host -> receivedAddress.port != peer -> address.port) && |
1015 | peer -> address.host != ENET_HOST_BROADCAST) || |
1016 | (peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID && |
1017 | sessionID != peer -> incomingSessionID)) |
1018 | return 0; |
1019 | } |
1020 | |
1021 | if (flags & ENET_PROTOCOL_HEADER_FLAG_COMPRESSED) |
1022 | { |
1023 | size_t originalSize; |
1024 | if (host -> compressor.context == NULL || host -> compressor.decompress == NULL) |
1025 | return 0; |
1026 | |
1027 | originalSize = host -> compressor.decompress (host -> compressor.context, |
1028 | host -> receivedData + headerSize, |
1029 | host -> receivedDataLength - headerSize, |
1030 | host -> packetData [1] + headerSize, |
1031 | sizeof (host -> packetData [1]) - headerSize); |
1032 | if (originalSize <= 0 || originalSize > sizeof (host -> packetData [1]) - headerSize) |
1033 | return 0; |
1034 | |
1035 | memcpy (host -> packetData [1], header, headerSize); |
1036 | host -> receivedData = host -> packetData [1]; |
1037 | host -> receivedDataLength = headerSize + originalSize; |
1038 | } |
1039 | |
1040 | if (host -> checksum != NULL) |
1041 | { |
1042 | enet_uint32 * checksum = (enet_uint32 *) & host -> receivedData [headerSize - sizeof (enet_uint32)], |
1043 | desiredChecksum = * checksum; |
1044 | ENetBuffer buffer; |
1045 | |
1046 | * checksum = peer != NULL ? peer -> connectID : 0; |
1047 | |
1048 | buffer.data = host -> receivedData; |
1049 | buffer.dataLength = host -> receivedDataLength; |
1050 | |
1051 | if (host -> checksum (& buffer, 1) != desiredChecksum) |
1052 | return 0; |
1053 | } |
1054 | |
1055 | if (peer != NULL) |
1056 | { |
1057 | peer -> address.host = host -> receivedAddress.host; |
1058 | peer -> address.port = host -> receivedAddress.port; |
1059 | peer -> incomingDataTotal += host -> receivedDataLength; |
1060 | } |
1061 | |
1062 | currentData = host -> receivedData + headerSize; |
1063 | |
1064 | while (currentData < & host -> receivedData [host -> receivedDataLength]) |
1065 | { |
1066 | enet_uint8 commandNumber; |
1067 | size_t commandSize; |
1068 | |
1069 | command = (ENetProtocol *) currentData; |
1070 | |
1071 | if (currentData + sizeof (ENetProtocolCommandHeader) > & host -> receivedData [host -> receivedDataLength]) |
1072 | break; |
1073 | |
1074 | commandNumber = command -> header.command & ENET_PROTOCOL_COMMAND_MASK; |
1075 | if (commandNumber >= ENET_PROTOCOL_COMMAND_COUNT) |
1076 | break; |
1077 | |
1078 | commandSize = commandSizes [commandNumber]; |
1079 | if (commandSize == 0 || currentData + commandSize > & host -> receivedData [host -> receivedDataLength]) |
1080 | break; |
1081 | |
1082 | currentData += commandSize; |
1083 | |
1084 | if (peer == NULL && commandNumber != ENET_PROTOCOL_COMMAND_CONNECT) |
1085 | break; |
1086 | |
1087 | command -> header.reliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> header.reliableSequenceNumber); |
1088 | |
1089 | switch (commandNumber) |
1090 | { |
1091 | case ENET_PROTOCOL_COMMAND_ACKNOWLEDGE: |
1092 | if (enet_protocol_handle_acknowledge (host, event, peer, command)) |
1093 | goto commandError; |
1094 | break; |
1095 | |
1096 | case ENET_PROTOCOL_COMMAND_CONNECT: |
1097 | if (peer != NULL) |
1098 | goto commandError; |
1099 | peer = enet_protocol_handle_connect (host, header, command); |
1100 | if (peer == NULL) |
1101 | goto commandError; |
1102 | break; |
1103 | |
1104 | case ENET_PROTOCOL_COMMAND_VERIFY_CONNECT: |
1105 | if (enet_protocol_handle_verify_connect (host, event, peer, command)) |
1106 | goto commandError; |
1107 | break; |
1108 | |
1109 | case ENET_PROTOCOL_COMMAND_DISCONNECT: |
1110 | if (enet_protocol_handle_disconnect (host, peer, command)) |
1111 | goto commandError; |
1112 | break; |
1113 | |
1114 | case ENET_PROTOCOL_COMMAND_PING: |
1115 | if (enet_protocol_handle_ping (host, peer, command)) |
1116 | goto commandError; |
1117 | break; |
1118 | |
1119 | case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: |
1120 | if (enet_protocol_handle_send_reliable (host, peer, command, & currentData)) |
1121 | goto commandError; |
1122 | break; |
1123 | |
1124 | case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE: |
1125 | if (enet_protocol_handle_send_unreliable (host, peer, command, & currentData)) |
1126 | goto commandError; |
1127 | break; |
1128 | |
1129 | case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED: |
1130 | if (enet_protocol_handle_send_unsequenced (host, peer, command, & currentData)) |
1131 | goto commandError; |
1132 | break; |
1133 | |
1134 | case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: |
1135 | if (enet_protocol_handle_send_fragment (host, peer, command, & currentData)) |
1136 | goto commandError; |
1137 | break; |
1138 | |
1139 | case ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT: |
1140 | if (enet_protocol_handle_bandwidth_limit (host, peer, command)) |
1141 | goto commandError; |
1142 | break; |
1143 | |
1144 | case ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE: |
1145 | if (enet_protocol_handle_throttle_configure (host, peer, command)) |
1146 | goto commandError; |
1147 | break; |
1148 | |
1149 | case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT: |
1150 | if (enet_protocol_handle_send_unreliable_fragment (host, peer, command, & currentData)) |
1151 | goto commandError; |
1152 | break; |
1153 | |
1154 | default: |
1155 | goto commandError; |
1156 | } |
1157 | |
1158 | if (peer != NULL && |
1159 | (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) != 0) |
1160 | { |
1161 | enet_uint16 sentTime; |
1162 | |
1163 | if (! (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME)) |
1164 | break; |
1165 | |
1166 | sentTime = ENET_NET_TO_HOST_16 (header -> sentTime); |
1167 | |
1168 | switch (peer -> state) |
1169 | { |
1170 | case ENET_PEER_STATE_DISCONNECTING: |
1171 | case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT: |
1172 | case ENET_PEER_STATE_DISCONNECTED: |
1173 | case ENET_PEER_STATE_ZOMBIE: |
1174 | break; |
1175 | |
1176 | case ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT: |
1177 | if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT) |
1178 | enet_peer_queue_acknowledgement (peer, command, sentTime); |
1179 | break; |
1180 | |
1181 | default: |
1182 | enet_peer_queue_acknowledgement (peer, command, sentTime); |
1183 | break; |
1184 | } |
1185 | } |
1186 | } |
1187 | |
1188 | commandError: |
1189 | if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE) |
1190 | return 1; |
1191 | |
1192 | return 0; |
1193 | } |
1194 | |
1195 | static int |
1196 | enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event) |
1197 | { |
1198 | int packets; |
1199 | |
1200 | for (packets = 0; packets < 256; ++ packets) |
1201 | { |
1202 | int receivedLength; |
1203 | ENetBuffer buffer; |
1204 | |
1205 | buffer.data = host -> packetData [0]; |
1206 | buffer.dataLength = sizeof (host -> packetData [0]); |
1207 | |
1208 | receivedLength = enet_socket_receive (host -> socket, |
1209 | & host -> receivedAddress, |
1210 | & buffer, |
1211 | 1); |
1212 | |
1213 | if (receivedLength < 0) |
1214 | return -1; |
1215 | |
1216 | if (receivedLength == 0) |
1217 | return 0; |
1218 | |
1219 | host -> receivedData = host -> packetData [0]; |
1220 | host -> receivedDataLength = receivedLength; |
1221 | |
1222 | host -> totalReceivedData += receivedLength; |
1223 | host -> totalReceivedPackets ++; |
1224 | |
1225 | if (host -> intercept != NULL) |
1226 | { |
1227 | switch (host -> intercept (host, event)) |
1228 | { |
1229 | case 1: |
1230 | if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE) |
1231 | return 1; |
1232 | |
1233 | continue; |
1234 | |
1235 | case -1: |
1236 | return -1; |
1237 | |
1238 | default: |
1239 | break; |
1240 | } |
1241 | } |
1242 | |
1243 | switch (enet_protocol_handle_incoming_commands (host, event)) |
1244 | { |
1245 | case 1: |
1246 | return 1; |
1247 | |
1248 | case -1: |
1249 | return -1; |
1250 | |
1251 | default: |
1252 | break; |
1253 | } |
1254 | } |
1255 | |
1256 | return -1; |
1257 | } |
1258 | |
1259 | static void |
1260 | enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer) |
1261 | { |
1262 | ENetProtocol * command = & host -> commands [host -> commandCount]; |
1263 | ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; |
1264 | ENetAcknowledgement * acknowledgement; |
1265 | ENetListIterator currentAcknowledgement; |
1266 | enet_uint16 reliableSequenceNumber; |
1267 | |
1268 | currentAcknowledgement = enet_list_begin (& peer -> acknowledgements); |
1269 | |
1270 | while (currentAcknowledgement != enet_list_end (& peer -> acknowledgements)) |
1271 | { |
1272 | if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || |
1273 | buffer >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || |
1274 | peer -> mtu - host -> packetSize < sizeof (ENetProtocolAcknowledge)) |
1275 | { |
1276 | host -> continueSending = 1; |
1277 | |
1278 | break; |
1279 | } |
1280 | |
1281 | acknowledgement = (ENetAcknowledgement *) currentAcknowledgement; |
1282 | |
1283 | currentAcknowledgement = enet_list_next (currentAcknowledgement); |
1284 | |
1285 | buffer -> data = command; |
1286 | buffer -> dataLength = sizeof (ENetProtocolAcknowledge); |
1287 | |
1288 | host -> packetSize += buffer -> dataLength; |
1289 | |
1290 | reliableSequenceNumber = ENET_HOST_TO_NET_16 (acknowledgement -> command.header.reliableSequenceNumber); |
1291 | |
1292 | command -> header.command = ENET_PROTOCOL_COMMAND_ACKNOWLEDGE; |
1293 | command -> header.channelID = acknowledgement -> command.header.channelID; |
1294 | command -> header.reliableSequenceNumber = reliableSequenceNumber; |
1295 | command -> acknowledge.receivedReliableSequenceNumber = reliableSequenceNumber; |
1296 | command -> acknowledge.receivedSentTime = ENET_HOST_TO_NET_16 (acknowledgement -> sentTime); |
1297 | |
1298 | if ((acknowledgement -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT) |
1299 | enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); |
1300 | |
1301 | enet_list_remove (& acknowledgement -> acknowledgementList); |
1302 | enet_free (acknowledgement); |
1303 | |
1304 | ++ command; |
1305 | ++ buffer; |
1306 | } |
1307 | |
1308 | host -> commandCount = command - host -> commands; |
1309 | host -> bufferCount = buffer - host -> buffers; |
1310 | } |
1311 | |
1312 | static void |
1313 | enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * peer) |
1314 | { |
1315 | ENetProtocol * command = & host -> commands [host -> commandCount]; |
1316 | ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; |
1317 | ENetOutgoingCommand * outgoingCommand; |
1318 | ENetListIterator currentCommand; |
1319 | |
1320 | currentCommand = enet_list_begin (& peer -> outgoingUnreliableCommands); |
1321 | |
1322 | while (currentCommand != enet_list_end (& peer -> outgoingUnreliableCommands)) |
1323 | { |
1324 | size_t commandSize; |
1325 | |
1326 | outgoingCommand = (ENetOutgoingCommand *) currentCommand; |
1327 | commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK]; |
1328 | |
1329 | if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || |
1330 | buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || |
1331 | peer -> mtu - host -> packetSize < commandSize || |
1332 | (outgoingCommand -> packet != NULL && |
1333 | peer -> mtu - host -> packetSize < commandSize + outgoingCommand -> fragmentLength)) |
1334 | { |
1335 | host -> continueSending = 1; |
1336 | |
1337 | break; |
1338 | } |
1339 | |
1340 | currentCommand = enet_list_next (currentCommand); |
1341 | |
1342 | if (outgoingCommand -> packet != NULL && outgoingCommand -> fragmentOffset == 0) |
1343 | { |
1344 | peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER; |
1345 | peer -> packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE; |
1346 | |
1347 | if (peer -> packetThrottleCounter > peer -> packetThrottle) |
1348 | { |
1349 | enet_uint16 reliableSequenceNumber = outgoingCommand -> reliableSequenceNumber, |
1350 | unreliableSequenceNumber = outgoingCommand -> unreliableSequenceNumber; |
1351 | for (;;) |
1352 | { |
1353 | -- outgoingCommand -> packet -> referenceCount; |
1354 | |
1355 | if (outgoingCommand -> packet -> referenceCount == 0) |
1356 | enet_packet_destroy (outgoingCommand -> packet); |
1357 | |
1358 | enet_list_remove (& outgoingCommand -> outgoingCommandList); |
1359 | enet_free (outgoingCommand); |
1360 | |
1361 | if (currentCommand == enet_list_end (& peer -> outgoingUnreliableCommands)) |
1362 | break; |
1363 | |
1364 | outgoingCommand = (ENetOutgoingCommand *) currentCommand; |
1365 | if (outgoingCommand -> reliableSequenceNumber != reliableSequenceNumber || |
1366 | outgoingCommand -> unreliableSequenceNumber != unreliableSequenceNumber) |
1367 | break; |
1368 | |
1369 | currentCommand = enet_list_next (currentCommand); |
1370 | } |
1371 | |
1372 | continue; |
1373 | } |
1374 | } |
1375 | |
1376 | buffer -> data = command; |
1377 | buffer -> dataLength = commandSize; |
1378 | |
1379 | host -> packetSize += buffer -> dataLength; |
1380 | |
1381 | * command = outgoingCommand -> command; |
1382 | |
1383 | enet_list_remove (& outgoingCommand -> outgoingCommandList); |
1384 | |
1385 | if (outgoingCommand -> packet != NULL) |
1386 | { |
1387 | ++ buffer; |
1388 | |
1389 | buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset; |
1390 | buffer -> dataLength = outgoingCommand -> fragmentLength; |
1391 | |
1392 | host -> packetSize += buffer -> dataLength; |
1393 | |
1394 | enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand); |
1395 | } |
1396 | else |
1397 | enet_free (outgoingCommand); |
1398 | |
1399 | ++ command; |
1400 | ++ buffer; |
1401 | } |
1402 | |
1403 | host -> commandCount = command - host -> commands; |
1404 | host -> bufferCount = buffer - host -> buffers; |
1405 | |
1406 | if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER && |
1407 | enet_list_empty (& peer -> outgoingReliableCommands) && |
1408 | enet_list_empty (& peer -> outgoingUnreliableCommands) && |
1409 | enet_list_empty (& peer -> sentReliableCommands)) |
1410 | enet_peer_disconnect (peer, peer -> eventData); |
1411 | } |
1412 | |
1413 | static int |
1414 | enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * event) |
1415 | { |
1416 | ENetOutgoingCommand * outgoingCommand; |
1417 | ENetListIterator currentCommand, insertPosition; |
1418 | |
1419 | currentCommand = enet_list_begin (& peer -> sentReliableCommands); |
1420 | insertPosition = enet_list_begin (& peer -> outgoingReliableCommands); |
1421 | |
1422 | while (currentCommand != enet_list_end (& peer -> sentReliableCommands)) |
1423 | { |
1424 | outgoingCommand = (ENetOutgoingCommand *) currentCommand; |
1425 | |
1426 | currentCommand = enet_list_next (currentCommand); |
1427 | |
1428 | if (ENET_TIME_DIFFERENCE (host -> serviceTime, outgoingCommand -> sentTime) < outgoingCommand -> roundTripTimeout) |
1429 | continue; |
1430 | |
1431 | if (peer -> earliestTimeout == 0 || |
1432 | ENET_TIME_LESS (outgoingCommand -> sentTime, peer -> earliestTimeout)) |
1433 | peer -> earliestTimeout = outgoingCommand -> sentTime; |
1434 | |
1435 | if (peer -> earliestTimeout != 0 && |
1436 | (ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMaximum || |
1437 | (outgoingCommand -> roundTripTimeout >= outgoingCommand -> roundTripTimeoutLimit && |
1438 | ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMinimum))) |
1439 | { |
1440 | enet_protocol_notify_disconnect (host, peer, event); |
1441 | |
1442 | return 1; |
1443 | } |
1444 | |
1445 | if (outgoingCommand -> packet != NULL) |
1446 | peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength; |
1447 | |
1448 | ++ peer -> packetsLost; |
1449 | |
1450 | outgoingCommand -> roundTripTimeout *= 2; |
1451 | |
1452 | enet_list_insert (insertPosition, enet_list_remove (& outgoingCommand -> outgoingCommandList)); |
1453 | |
1454 | if (currentCommand == enet_list_begin (& peer -> sentReliableCommands) && |
1455 | ! enet_list_empty (& peer -> sentReliableCommands)) |
1456 | { |
1457 | outgoingCommand = (ENetOutgoingCommand *) currentCommand; |
1458 | |
1459 | peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout; |
1460 | } |
1461 | } |
1462 | |
1463 | return 0; |
1464 | } |
1465 | |
1466 | static int |
1467 | enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer) |
1468 | { |
1469 | ENetProtocol * command = & host -> commands [host -> commandCount]; |
1470 | ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; |
1471 | ENetOutgoingCommand * outgoingCommand; |
1472 | ENetListIterator currentCommand; |
1473 | ENetChannel *channel; |
1474 | enet_uint16 reliableWindow; |
1475 | size_t commandSize; |
1476 | int windowExceeded = 0, windowWrap = 0, canPing = 1; |
1477 | |
1478 | currentCommand = enet_list_begin (& peer -> outgoingReliableCommands); |
1479 | |
1480 | while (currentCommand != enet_list_end (& peer -> outgoingReliableCommands)) |
1481 | { |
1482 | outgoingCommand = (ENetOutgoingCommand *) currentCommand; |
1483 | |
1484 | channel = outgoingCommand -> command.header.channelID < peer -> channelCount ? & peer -> channels [outgoingCommand -> command.header.channelID] : NULL; |
1485 | reliableWindow = outgoingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; |
1486 | if (channel != NULL) |
1487 | { |
1488 | if (! windowWrap && |
1489 | outgoingCommand -> sendAttempts < 1 && |
1490 | ! (outgoingCommand -> reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) && |
1491 | (channel -> reliableWindows [(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE || |
1492 | channel -> usedReliableWindows & ((((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) << reliableWindow) | |
1493 | (((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) >> (ENET_PEER_RELIABLE_WINDOWS - reliableWindow))))) |
1494 | windowWrap = 1; |
1495 | if (windowWrap) |
1496 | { |
1497 | currentCommand = enet_list_next (currentCommand); |
1498 | |
1499 | continue; |
1500 | } |
1501 | } |
1502 | |
1503 | if (outgoingCommand -> packet != NULL) |
1504 | { |
1505 | if (! windowExceeded) |
1506 | { |
1507 | enet_uint32 windowSize = (peer -> packetThrottle * peer -> windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE; |
1508 | |
1509 | if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > ENET_MAX (windowSize, peer -> mtu)) |
1510 | windowExceeded = 1; |
1511 | } |
1512 | if (windowExceeded) |
1513 | { |
1514 | currentCommand = enet_list_next (currentCommand); |
1515 | |
1516 | continue; |
1517 | } |
1518 | } |
1519 | |
1520 | canPing = 0; |
1521 | |
1522 | commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK]; |
1523 | if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || |
1524 | buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || |
1525 | peer -> mtu - host -> packetSize < commandSize || |
1526 | (outgoingCommand -> packet != NULL && |
1527 | (enet_uint16) (peer -> mtu - host -> packetSize) < (enet_uint16) (commandSize + outgoingCommand -> fragmentLength))) |
1528 | { |
1529 | host -> continueSending = 1; |
1530 | |
1531 | break; |
1532 | } |
1533 | |
1534 | currentCommand = enet_list_next (currentCommand); |
1535 | |
1536 | if (channel != NULL && outgoingCommand -> sendAttempts < 1) |
1537 | { |
1538 | channel -> usedReliableWindows |= 1 << reliableWindow; |
1539 | ++ channel -> reliableWindows [reliableWindow]; |
1540 | } |
1541 | |
1542 | ++ outgoingCommand -> sendAttempts; |
1543 | |
1544 | if (outgoingCommand -> roundTripTimeout == 0) |
1545 | { |
1546 | outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance; |
1547 | outgoingCommand -> roundTripTimeoutLimit = peer -> timeoutLimit * outgoingCommand -> roundTripTimeout; |
1548 | } |
1549 | |
1550 | if (enet_list_empty (& peer -> sentReliableCommands)) |
1551 | peer -> nextTimeout = host -> serviceTime + outgoingCommand -> roundTripTimeout; |
1552 | |
1553 | enet_list_insert (enet_list_end (& peer -> sentReliableCommands), |
1554 | enet_list_remove (& outgoingCommand -> outgoingCommandList)); |
1555 | |
1556 | outgoingCommand -> sentTime = host -> serviceTime; |
1557 | |
1558 | buffer -> data = command; |
1559 | buffer -> dataLength = commandSize; |
1560 | |
1561 | host -> packetSize += buffer -> dataLength; |
1562 | host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME; |
1563 | |
1564 | * command = outgoingCommand -> command; |
1565 | |
1566 | if (outgoingCommand -> packet != NULL) |
1567 | { |
1568 | ++ buffer; |
1569 | |
1570 | buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset; |
1571 | buffer -> dataLength = outgoingCommand -> fragmentLength; |
1572 | |
1573 | host -> packetSize += outgoingCommand -> fragmentLength; |
1574 | |
1575 | peer -> reliableDataInTransit += outgoingCommand -> fragmentLength; |
1576 | } |
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 | return canPing; |
1588 | } |
1589 | |
1590 | static int |
1591 | enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int checkForTimeouts) |
1592 | { |
1593 | enet_uint8 [sizeof (ENetProtocolHeader) + sizeof (enet_uint32)]; |
1594 | ENetProtocolHeader * = (ENetProtocolHeader *) headerData; |
1595 | ENetPeer * currentPeer; |
1596 | int sentLength; |
1597 | size_t shouldCompress = 0; |
1598 | |
1599 | host -> continueSending = 1; |
1600 | |
1601 | while (host -> continueSending) |
1602 | for (host -> continueSending = 0, |
1603 | currentPeer = host -> peers; |
1604 | currentPeer < & host -> peers [host -> peerCount]; |
1605 | ++ currentPeer) |
1606 | { |
1607 | if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED || |
1608 | currentPeer -> state == ENET_PEER_STATE_ZOMBIE) |
1609 | continue; |
1610 | |
1611 | host -> headerFlags = 0; |
1612 | host -> commandCount = 0; |
1613 | host -> bufferCount = 1; |
1614 | host -> packetSize = sizeof (ENetProtocolHeader); |
1615 | |
1616 | if (! enet_list_empty (& currentPeer -> acknowledgements)) |
1617 | enet_protocol_send_acknowledgements (host, currentPeer); |
1618 | |
1619 | if (checkForTimeouts != 0 && |
1620 | ! enet_list_empty (& currentPeer -> sentReliableCommands) && |
1621 | ENET_TIME_GREATER_EQUAL (host -> serviceTime, currentPeer -> nextTimeout) && |
1622 | enet_protocol_check_timeouts (host, currentPeer, event) == 1) |
1623 | { |
1624 | if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE) |
1625 | return 1; |
1626 | else |
1627 | continue; |
1628 | } |
1629 | |
1630 | if ((enet_list_empty (& currentPeer -> outgoingReliableCommands) || |
1631 | enet_protocol_send_reliable_outgoing_commands (host, currentPeer)) && |
1632 | enet_list_empty (& currentPeer -> sentReliableCommands) && |
1633 | ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= currentPeer -> pingInterval && |
1634 | currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing)) |
1635 | { |
1636 | enet_peer_ping (currentPeer); |
1637 | enet_protocol_send_reliable_outgoing_commands (host, currentPeer); |
1638 | } |
1639 | |
1640 | if (! enet_list_empty (& currentPeer -> outgoingUnreliableCommands)) |
1641 | enet_protocol_send_unreliable_outgoing_commands (host, currentPeer); |
1642 | |
1643 | if (host -> commandCount == 0) |
1644 | continue; |
1645 | |
1646 | if (currentPeer -> packetLossEpoch == 0) |
1647 | currentPeer -> packetLossEpoch = host -> serviceTime; |
1648 | else |
1649 | if (ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> packetLossEpoch) >= ENET_PEER_PACKET_LOSS_INTERVAL && |
1650 | currentPeer -> packetsSent > 0) |
1651 | { |
1652 | enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent; |
1653 | |
1654 | #ifdef ENET_DEBUG |
1655 | 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); |
1656 | #endif |
1657 | |
1658 | currentPeer -> packetLossVariance -= currentPeer -> packetLossVariance / 4; |
1659 | |
1660 | if (packetLoss >= currentPeer -> packetLoss) |
1661 | { |
1662 | currentPeer -> packetLoss += (packetLoss - currentPeer -> packetLoss) / 8; |
1663 | currentPeer -> packetLossVariance += (packetLoss - currentPeer -> packetLoss) / 4; |
1664 | } |
1665 | else |
1666 | { |
1667 | currentPeer -> packetLoss -= (currentPeer -> packetLoss - packetLoss) / 8; |
1668 | currentPeer -> packetLossVariance += (currentPeer -> packetLoss - packetLoss) / 4; |
1669 | } |
1670 | |
1671 | currentPeer -> packetLossEpoch = host -> serviceTime; |
1672 | currentPeer -> packetsSent = 0; |
1673 | currentPeer -> packetsLost = 0; |
1674 | } |
1675 | |
1676 | host -> buffers -> data = headerData; |
1677 | if (host -> headerFlags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME) |
1678 | { |
1679 | header -> sentTime = ENET_HOST_TO_NET_16 (host -> serviceTime & 0xFFFF); |
1680 | |
1681 | host -> buffers -> dataLength = sizeof (ENetProtocolHeader); |
1682 | } |
1683 | else |
1684 | host -> buffers -> dataLength = (size_t) & ((ENetProtocolHeader *) 0) -> sentTime; |
1685 | |
1686 | shouldCompress = 0; |
1687 | if (host -> compressor.context != NULL && host -> compressor.compress != NULL) |
1688 | { |
1689 | size_t originalSize = host -> packetSize - sizeof(ENetProtocolHeader), |
1690 | compressedSize = host -> compressor.compress (host -> compressor.context, |
1691 | & host -> buffers [1], host -> bufferCount - 1, |
1692 | originalSize, |
1693 | host -> packetData [1], |
1694 | originalSize); |
1695 | if (compressedSize > 0 && compressedSize < originalSize) |
1696 | { |
1697 | host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_COMPRESSED; |
1698 | shouldCompress = compressedSize; |
1699 | #ifdef ENET_DEBUG_COMPRESS |
1700 | printf ("peer %u: compressed %u -> %u (%u%%)\n" , currentPeer -> incomingPeerID, originalSize, compressedSize, (compressedSize * 100) / originalSize); |
1701 | #endif |
1702 | } |
1703 | } |
1704 | |
1705 | if (currentPeer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID) |
1706 | host -> headerFlags |= currentPeer -> outgoingSessionID << ENET_PROTOCOL_HEADER_SESSION_SHIFT; |
1707 | header -> peerID = ENET_HOST_TO_NET_16 (currentPeer -> outgoingPeerID | host -> headerFlags); |
1708 | if (host -> checksum != NULL) |
1709 | { |
1710 | enet_uint32 * checksum = (enet_uint32 *) & headerData [host -> buffers -> dataLength]; |
1711 | * checksum = currentPeer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID ? currentPeer -> connectID : 0; |
1712 | host -> buffers -> dataLength += sizeof (enet_uint32); |
1713 | * checksum = host -> checksum (host -> buffers, host -> bufferCount); |
1714 | } |
1715 | |
1716 | if (shouldCompress > 0) |
1717 | { |
1718 | host -> buffers [1].data = host -> packetData [1]; |
1719 | host -> buffers [1].dataLength = shouldCompress; |
1720 | host -> bufferCount = 2; |
1721 | } |
1722 | |
1723 | currentPeer -> lastSendTime = host -> serviceTime; |
1724 | |
1725 | sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount); |
1726 | |
1727 | enet_protocol_remove_sent_unreliable_commands (currentPeer); |
1728 | |
1729 | if (sentLength < 0) |
1730 | return -1; |
1731 | |
1732 | host -> totalSentData += sentLength; |
1733 | host -> totalSentPackets ++; |
1734 | } |
1735 | |
1736 | return 0; |
1737 | } |
1738 | |
1739 | /** Sends any queued packets on the host specified to its designated peers. |
1740 | |
1741 | @param host host to flush |
1742 | @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(). |
1743 | @ingroup host |
1744 | */ |
1745 | void |
1746 | enet_host_flush (ENetHost * host) |
1747 | { |
1748 | host -> serviceTime = enet_time_get (); |
1749 | |
1750 | enet_protocol_send_outgoing_commands (host, NULL, 0); |
1751 | } |
1752 | |
1753 | /** Checks for any queued events on the host and dispatches one if available. |
1754 | |
1755 | @param host host to check for events |
1756 | @param event an event structure where event details will be placed if available |
1757 | @retval > 0 if an event was dispatched |
1758 | @retval 0 if no events are available |
1759 | @retval < 0 on failure |
1760 | @ingroup host |
1761 | */ |
1762 | int |
1763 | enet_host_check_events (ENetHost * host, ENetEvent * event) |
1764 | { |
1765 | if (event == NULL) return -1; |
1766 | |
1767 | event -> type = ENET_EVENT_TYPE_NONE; |
1768 | event -> peer = NULL; |
1769 | event -> packet = NULL; |
1770 | |
1771 | return enet_protocol_dispatch_incoming_commands (host, event); |
1772 | } |
1773 | |
1774 | /** Waits for events on the host specified and shuttles packets between |
1775 | the host and its peers. |
1776 | |
1777 | @param host host to service |
1778 | @param event an event structure where event details will be placed if one occurs |
1779 | if event == NULL then no events will be delivered |
1780 | @param timeout number of milliseconds that ENet should wait for events |
1781 | @retval > 0 if an event occurred within the specified time limit |
1782 | @retval 0 if no event occurred |
1783 | @retval < 0 on failure |
1784 | @remarks enet_host_service should be called fairly regularly for adequate performance |
1785 | @ingroup host |
1786 | */ |
1787 | int |
1788 | enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout) |
1789 | { |
1790 | enet_uint32 waitCondition; |
1791 | |
1792 | if (event != NULL) |
1793 | { |
1794 | event -> type = ENET_EVENT_TYPE_NONE; |
1795 | event -> peer = NULL; |
1796 | event -> packet = NULL; |
1797 | |
1798 | switch (enet_protocol_dispatch_incoming_commands (host, event)) |
1799 | { |
1800 | case 1: |
1801 | return 1; |
1802 | |
1803 | case -1: |
1804 | #ifdef ENET_DEBUG |
1805 | perror ("Error dispatching incoming packets" ); |
1806 | #endif |
1807 | |
1808 | return -1; |
1809 | |
1810 | default: |
1811 | break; |
1812 | } |
1813 | } |
1814 | |
1815 | host -> serviceTime = enet_time_get (); |
1816 | |
1817 | timeout += host -> serviceTime; |
1818 | |
1819 | do |
1820 | { |
1821 | if (ENET_TIME_DIFFERENCE (host -> serviceTime, host -> bandwidthThrottleEpoch) >= ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL) |
1822 | enet_host_bandwidth_throttle (host); |
1823 | |
1824 | switch (enet_protocol_send_outgoing_commands (host, event, 1)) |
1825 | { |
1826 | case 1: |
1827 | return 1; |
1828 | |
1829 | case -1: |
1830 | #ifdef ENET_DEBUG |
1831 | perror ("Error sending outgoing packets" ); |
1832 | #endif |
1833 | |
1834 | return -1; |
1835 | |
1836 | default: |
1837 | break; |
1838 | } |
1839 | |
1840 | switch (enet_protocol_receive_incoming_commands (host, event)) |
1841 | { |
1842 | case 1: |
1843 | return 1; |
1844 | |
1845 | case -1: |
1846 | #ifdef ENET_DEBUG |
1847 | perror ("Error receiving incoming packets" ); |
1848 | #endif |
1849 | |
1850 | return -1; |
1851 | |
1852 | default: |
1853 | break; |
1854 | } |
1855 | |
1856 | switch (enet_protocol_send_outgoing_commands (host, event, 1)) |
1857 | { |
1858 | case 1: |
1859 | return 1; |
1860 | |
1861 | case -1: |
1862 | #ifdef ENET_DEBUG |
1863 | perror ("Error sending outgoing packets" ); |
1864 | #endif |
1865 | |
1866 | return -1; |
1867 | |
1868 | default: |
1869 | break; |
1870 | } |
1871 | |
1872 | if (event != NULL) |
1873 | { |
1874 | switch (enet_protocol_dispatch_incoming_commands (host, event)) |
1875 | { |
1876 | case 1: |
1877 | return 1; |
1878 | |
1879 | case -1: |
1880 | #ifdef ENET_DEBUG |
1881 | perror ("Error dispatching incoming packets" ); |
1882 | #endif |
1883 | |
1884 | return -1; |
1885 | |
1886 | default: |
1887 | break; |
1888 | } |
1889 | } |
1890 | |
1891 | if (ENET_TIME_GREATER_EQUAL (host -> serviceTime, timeout)) |
1892 | return 0; |
1893 | |
1894 | do |
1895 | { |
1896 | host -> serviceTime = enet_time_get (); |
1897 | |
1898 | if (ENET_TIME_GREATER_EQUAL (host -> serviceTime, timeout)) |
1899 | return 0; |
1900 | |
1901 | waitCondition = ENET_SOCKET_WAIT_RECEIVE | ENET_SOCKET_WAIT_INTERRUPT; |
1902 | |
1903 | if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0) |
1904 | return -1; |
1905 | } |
1906 | while (waitCondition & ENET_SOCKET_WAIT_INTERRUPT); |
1907 | |
1908 | host -> serviceTime = enet_time_get (); |
1909 | } while (waitCondition & ENET_SOCKET_WAIT_RECEIVE); |
1910 | |
1911 | return 0; |
1912 | } |
1913 | |
1914 | |