Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/enet/protocol.c
9898 views
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 * header, 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 * header;
1014
ENetProtocol * command;
1015
ENetPeer * peer;
1016
enet_uint8 * currentData;
1017
size_t headerSize;
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
enet_uint32 desiredChecksum, newChecksum;
1076
ENetBuffer buffer;
1077
/* Checksum may be an unaligned pointer, use memcpy to avoid undefined behaviour. */
1078
memcpy (& desiredChecksum, checksum, sizeof (enet_uint32));
1079
1080
newChecksum = peer != NULL ? peer -> connectID : 0;
1081
memcpy (checksum, & newChecksum, sizeof (enet_uint32));
1082
1083
buffer.data = host -> receivedData;
1084
buffer.dataLength = host -> receivedDataLength;
1085
1086
if (host -> checksum (& buffer, 1) != desiredChecksum)
1087
return 0;
1088
}
1089
1090
if (peer != NULL)
1091
{
1092
enet_address_set_ip(&(peer -> address), host -> receivedAddress.host, 16);
1093
peer -> address.port = host -> receivedAddress.port;
1094
peer -> incomingDataTotal += host -> receivedDataLength;
1095
}
1096
1097
currentData = host -> receivedData + headerSize;
1098
1099
while (currentData < & host -> receivedData [host -> receivedDataLength])
1100
{
1101
enet_uint8 commandNumber;
1102
size_t commandSize;
1103
1104
command = (ENetProtocol *) currentData;
1105
1106
if (currentData + sizeof (ENetProtocolCommandHeader) > & host -> receivedData [host -> receivedDataLength])
1107
break;
1108
1109
commandNumber = command -> header.command & ENET_PROTOCOL_COMMAND_MASK;
1110
if (commandNumber >= ENET_PROTOCOL_COMMAND_COUNT)
1111
break;
1112
1113
commandSize = commandSizes [commandNumber];
1114
if (commandSize == 0 || currentData + commandSize > & host -> receivedData [host -> receivedDataLength])
1115
break;
1116
1117
currentData += commandSize;
1118
1119
if (peer == NULL && commandNumber != ENET_PROTOCOL_COMMAND_CONNECT)
1120
break;
1121
1122
command -> header.reliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> header.reliableSequenceNumber);
1123
1124
switch (commandNumber)
1125
{
1126
case ENET_PROTOCOL_COMMAND_ACKNOWLEDGE:
1127
if (enet_protocol_handle_acknowledge (host, event, peer, command))
1128
goto commandError;
1129
break;
1130
1131
case ENET_PROTOCOL_COMMAND_CONNECT:
1132
if (peer != NULL)
1133
goto commandError;
1134
peer = enet_protocol_handle_connect (host, header, command);
1135
if (peer == NULL)
1136
goto commandError;
1137
break;
1138
1139
case ENET_PROTOCOL_COMMAND_VERIFY_CONNECT:
1140
if (enet_protocol_handle_verify_connect (host, event, peer, command))
1141
goto commandError;
1142
break;
1143
1144
case ENET_PROTOCOL_COMMAND_DISCONNECT:
1145
if (enet_protocol_handle_disconnect (host, peer, command))
1146
goto commandError;
1147
break;
1148
1149
case ENET_PROTOCOL_COMMAND_PING:
1150
if (enet_protocol_handle_ping (host, peer, command))
1151
goto commandError;
1152
break;
1153
1154
case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
1155
if (enet_protocol_handle_send_reliable (host, peer, command, & currentData))
1156
goto commandError;
1157
break;
1158
1159
case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE:
1160
if (enet_protocol_handle_send_unreliable (host, peer, command, & currentData))
1161
goto commandError;
1162
break;
1163
1164
case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED:
1165
if (enet_protocol_handle_send_unsequenced (host, peer, command, & currentData))
1166
goto commandError;
1167
break;
1168
1169
case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
1170
if (enet_protocol_handle_send_fragment (host, peer, command, & currentData))
1171
goto commandError;
1172
break;
1173
1174
case ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT:
1175
if (enet_protocol_handle_bandwidth_limit (host, peer, command))
1176
goto commandError;
1177
break;
1178
1179
case ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE:
1180
if (enet_protocol_handle_throttle_configure (host, peer, command))
1181
goto commandError;
1182
break;
1183
1184
case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT:
1185
if (enet_protocol_handle_send_unreliable_fragment (host, peer, command, & currentData))
1186
goto commandError;
1187
break;
1188
1189
default:
1190
goto commandError;
1191
}
1192
1193
if (peer != NULL &&
1194
(command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) != 0)
1195
{
1196
enet_uint16 sentTime;
1197
1198
if (! (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME))
1199
break;
1200
1201
sentTime = ENET_NET_TO_HOST_16 (header -> sentTime);
1202
1203
switch (peer -> state)
1204
{
1205
case ENET_PEER_STATE_DISCONNECTING:
1206
case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT:
1207
case ENET_PEER_STATE_DISCONNECTED:
1208
case ENET_PEER_STATE_ZOMBIE:
1209
break;
1210
1211
case ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT:
1212
if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT)
1213
enet_peer_queue_acknowledgement (peer, command, sentTime);
1214
break;
1215
1216
default:
1217
enet_peer_queue_acknowledgement (peer, command, sentTime);
1218
break;
1219
}
1220
}
1221
}
1222
1223
commandError:
1224
if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE)
1225
return 1;
1226
1227
return 0;
1228
}
1229
1230
static int
1231
enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
1232
{
1233
int packets;
1234
1235
for (packets = 0; packets < 256; ++ packets)
1236
{
1237
int receivedLength;
1238
ENetBuffer buffer;
1239
1240
buffer.data = host -> packetData [0];
1241
buffer.dataLength = sizeof (host -> packetData [0]);
1242
1243
receivedLength = enet_socket_receive (host -> socket,
1244
& host -> receivedAddress,
1245
& buffer,
1246
1);
1247
1248
if (receivedLength == -2)
1249
continue;
1250
1251
if (receivedLength < 0)
1252
return -1;
1253
1254
if (receivedLength == 0)
1255
return 0;
1256
1257
host -> receivedData = host -> packetData [0];
1258
host -> receivedDataLength = receivedLength;
1259
1260
host -> totalReceivedData += receivedLength;
1261
host -> totalReceivedPackets ++;
1262
1263
if (host -> intercept != NULL)
1264
{
1265
switch (host -> intercept (host, event))
1266
{
1267
case 1:
1268
if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE)
1269
return 1;
1270
1271
continue;
1272
1273
case -1:
1274
return -1;
1275
1276
default:
1277
break;
1278
}
1279
}
1280
1281
switch (enet_protocol_handle_incoming_commands (host, event))
1282
{
1283
case 1:
1284
return 1;
1285
1286
case -1:
1287
return -1;
1288
1289
default:
1290
break;
1291
}
1292
}
1293
1294
return 0;
1295
}
1296
1297
static void
1298
enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer)
1299
{
1300
ENetProtocol * command = & host -> commands [host -> commandCount];
1301
ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
1302
ENetAcknowledgement * acknowledgement;
1303
ENetListIterator currentAcknowledgement;
1304
enet_uint16 reliableSequenceNumber;
1305
1306
currentAcknowledgement = enet_list_begin (& peer -> acknowledgements);
1307
1308
while (currentAcknowledgement != enet_list_end (& peer -> acknowledgements))
1309
{
1310
if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
1311
buffer >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
1312
peer -> mtu - host -> packetSize < sizeof (ENetProtocolAcknowledge))
1313
{
1314
peer -> flags |= ENET_PEER_FLAG_CONTINUE_SENDING;
1315
1316
break;
1317
}
1318
1319
acknowledgement = (ENetAcknowledgement *) currentAcknowledgement;
1320
1321
currentAcknowledgement = enet_list_next (currentAcknowledgement);
1322
1323
buffer -> data = command;
1324
buffer -> dataLength = sizeof (ENetProtocolAcknowledge);
1325
1326
host -> packetSize += buffer -> dataLength;
1327
1328
reliableSequenceNumber = ENET_HOST_TO_NET_16 (acknowledgement -> command.header.reliableSequenceNumber);
1329
1330
command -> header.command = ENET_PROTOCOL_COMMAND_ACKNOWLEDGE;
1331
command -> header.channelID = acknowledgement -> command.header.channelID;
1332
command -> header.reliableSequenceNumber = reliableSequenceNumber;
1333
command -> acknowledge.receivedReliableSequenceNumber = reliableSequenceNumber;
1334
command -> acknowledge.receivedSentTime = ENET_HOST_TO_NET_16 (acknowledgement -> sentTime);
1335
1336
if ((acknowledgement -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT)
1337
enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);
1338
1339
enet_list_remove (& acknowledgement -> acknowledgementList);
1340
enet_free (acknowledgement);
1341
1342
++ command;
1343
++ buffer;
1344
}
1345
1346
host -> commandCount = command - host -> commands;
1347
host -> bufferCount = buffer - host -> buffers;
1348
}
1349
1350
static int
1351
enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * event)
1352
{
1353
ENetOutgoingCommand * outgoingCommand;
1354
ENetListIterator currentCommand, insertPosition, insertSendReliablePosition;
1355
1356
currentCommand = enet_list_begin (& peer -> sentReliableCommands);
1357
insertPosition = enet_list_begin (& peer -> outgoingCommands);
1358
insertSendReliablePosition = enet_list_begin (& peer -> outgoingSendReliableCommands);
1359
1360
while (currentCommand != enet_list_end (& peer -> sentReliableCommands))
1361
{
1362
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
1363
1364
currentCommand = enet_list_next (currentCommand);
1365
1366
if (ENET_TIME_DIFFERENCE (host -> serviceTime, outgoingCommand -> sentTime) < outgoingCommand -> roundTripTimeout)
1367
continue;
1368
1369
if (peer -> earliestTimeout == 0 ||
1370
ENET_TIME_LESS (outgoingCommand -> sentTime, peer -> earliestTimeout))
1371
peer -> earliestTimeout = outgoingCommand -> sentTime;
1372
1373
if (peer -> earliestTimeout != 0 &&
1374
(ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMaximum ||
1375
((1 << (outgoingCommand -> sendAttempts - 1)) >= peer -> timeoutLimit &&
1376
ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMinimum)))
1377
{
1378
enet_protocol_notify_disconnect (host, peer, event);
1379
1380
return 1;
1381
}
1382
1383
++ peer -> packetsLost;
1384
1385
outgoingCommand -> roundTripTimeout *= 2;
1386
1387
if (outgoingCommand -> packet != NULL)
1388
{
1389
peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength;
1390
1391
enet_list_insert (insertSendReliablePosition, enet_list_remove (& outgoingCommand -> outgoingCommandList));
1392
}
1393
else
1394
enet_list_insert (insertPosition, enet_list_remove (& outgoingCommand -> outgoingCommandList));
1395
1396
if (currentCommand == enet_list_begin (& peer -> sentReliableCommands) &&
1397
! enet_list_empty (& peer -> sentReliableCommands))
1398
{
1399
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
1400
1401
peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout;
1402
}
1403
}
1404
1405
return 0;
1406
}
1407
1408
static int
1409
enet_protocol_check_outgoing_commands (ENetHost * host, ENetPeer * peer, ENetList * sentUnreliableCommands)
1410
{
1411
ENetProtocol * command = & host -> commands [host -> commandCount];
1412
ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
1413
ENetOutgoingCommand * outgoingCommand;
1414
ENetListIterator currentCommand, currentSendReliableCommand;
1415
ENetChannel *channel = NULL;
1416
enet_uint16 reliableWindow = 0;
1417
size_t commandSize;
1418
int windowWrap = 0, canPing = 1;
1419
1420
currentCommand = enet_list_begin (& peer -> outgoingCommands);
1421
currentSendReliableCommand = enet_list_begin (& peer -> outgoingSendReliableCommands);
1422
1423
for (;;)
1424
{
1425
if (currentCommand != enet_list_end (& peer -> outgoingCommands))
1426
{
1427
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
1428
1429
if (currentSendReliableCommand != enet_list_end (& peer -> outgoingSendReliableCommands) &&
1430
ENET_TIME_LESS (((ENetOutgoingCommand *) currentSendReliableCommand) -> queueTime, outgoingCommand -> queueTime))
1431
goto useSendReliableCommand;
1432
1433
currentCommand = enet_list_next (currentCommand);
1434
}
1435
else
1436
if (currentSendReliableCommand != enet_list_end (& peer -> outgoingSendReliableCommands))
1437
{
1438
useSendReliableCommand:
1439
outgoingCommand = (ENetOutgoingCommand *) currentSendReliableCommand;
1440
currentSendReliableCommand = enet_list_next (currentSendReliableCommand);
1441
}
1442
else
1443
break;
1444
1445
if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
1446
{
1447
channel = outgoingCommand -> command.header.channelID < peer -> channelCount ? & peer -> channels [outgoingCommand -> command.header.channelID] : NULL;
1448
reliableWindow = outgoingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
1449
if (channel != NULL)
1450
{
1451
if (windowWrap)
1452
continue;
1453
else
1454
if (outgoingCommand -> sendAttempts < 1 &&
1455
! (outgoingCommand -> reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) &&
1456
(channel -> reliableWindows [(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE ||
1457
channel -> usedReliableWindows & ((((1 << (ENET_PEER_FREE_RELIABLE_WINDOWS + 2)) - 1) << reliableWindow) |
1458
(((1 << (ENET_PEER_FREE_RELIABLE_WINDOWS + 2)) - 1) >> (ENET_PEER_RELIABLE_WINDOWS - reliableWindow)))))
1459
{
1460
windowWrap = 1;
1461
currentSendReliableCommand = enet_list_end (& peer -> outgoingSendReliableCommands);
1462
1463
continue;
1464
}
1465
}
1466
1467
if (outgoingCommand -> packet != NULL)
1468
{
1469
enet_uint32 windowSize = (peer -> packetThrottle * peer -> windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE;
1470
1471
if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > ENET_MAX (windowSize, peer -> mtu))
1472
{
1473
currentSendReliableCommand = enet_list_end (& peer -> outgoingSendReliableCommands);
1474
1475
continue;
1476
}
1477
}
1478
1479
canPing = 0;
1480
}
1481
1482
commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK];
1483
if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
1484
buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
1485
peer -> mtu - host -> packetSize < commandSize ||
1486
(outgoingCommand -> packet != NULL &&
1487
(enet_uint16) (peer -> mtu - host -> packetSize) < (enet_uint16) (commandSize + outgoingCommand -> fragmentLength)))
1488
{
1489
peer -> flags |= ENET_PEER_FLAG_CONTINUE_SENDING;
1490
1491
break;
1492
}
1493
1494
if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
1495
{
1496
if (channel != NULL && outgoingCommand -> sendAttempts < 1)
1497
{
1498
channel -> usedReliableWindows |= 1 << reliableWindow;
1499
++ channel -> reliableWindows [reliableWindow];
1500
}
1501
1502
++ outgoingCommand -> sendAttempts;
1503
1504
if (outgoingCommand -> roundTripTimeout == 0)
1505
outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance;
1506
1507
if (enet_list_empty (& peer -> sentReliableCommands))
1508
peer -> nextTimeout = host -> serviceTime + outgoingCommand -> roundTripTimeout;
1509
1510
enet_list_insert (enet_list_end (& peer -> sentReliableCommands),
1511
enet_list_remove (& outgoingCommand -> outgoingCommandList));
1512
1513
outgoingCommand -> sentTime = host -> serviceTime;
1514
1515
host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME;
1516
1517
peer -> reliableDataInTransit += outgoingCommand -> fragmentLength;
1518
}
1519
else
1520
{
1521
if (outgoingCommand -> packet != NULL && outgoingCommand -> fragmentOffset == 0)
1522
{
1523
peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER;
1524
peer -> packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE;
1525
1526
if (peer -> packetThrottleCounter > peer -> packetThrottle)
1527
{
1528
enet_uint16 reliableSequenceNumber = outgoingCommand -> reliableSequenceNumber,
1529
unreliableSequenceNumber = outgoingCommand -> unreliableSequenceNumber;
1530
for (;;)
1531
{
1532
-- outgoingCommand -> packet -> referenceCount;
1533
1534
if (outgoingCommand -> packet -> referenceCount == 0)
1535
enet_packet_destroy (outgoingCommand -> packet);
1536
1537
enet_list_remove (& outgoingCommand -> outgoingCommandList);
1538
enet_free (outgoingCommand);
1539
1540
if (currentCommand == enet_list_end (& peer -> outgoingCommands))
1541
break;
1542
1543
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
1544
if (outgoingCommand -> reliableSequenceNumber != reliableSequenceNumber ||
1545
outgoingCommand -> unreliableSequenceNumber != unreliableSequenceNumber)
1546
break;
1547
1548
currentCommand = enet_list_next (currentCommand);
1549
}
1550
1551
continue;
1552
}
1553
}
1554
1555
enet_list_remove (& outgoingCommand -> outgoingCommandList);
1556
1557
if (outgoingCommand -> packet != NULL)
1558
enet_list_insert (enet_list_end (sentUnreliableCommands), outgoingCommand);
1559
}
1560
1561
buffer -> data = command;
1562
buffer -> dataLength = commandSize;
1563
1564
host -> packetSize += buffer -> dataLength;
1565
1566
* command = outgoingCommand -> command;
1567
1568
if (outgoingCommand -> packet != NULL)
1569
{
1570
++ buffer;
1571
1572
buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset;
1573
buffer -> dataLength = outgoingCommand -> fragmentLength;
1574
1575
host -> packetSize += outgoingCommand -> fragmentLength;
1576
}
1577
else
1578
if (! (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE))
1579
enet_free (outgoingCommand);
1580
1581
++ peer -> packetsSent;
1582
1583
++ command;
1584
++ buffer;
1585
}
1586
1587
host -> commandCount = command - host -> commands;
1588
host -> bufferCount = buffer - host -> buffers;
1589
1590
if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER &&
1591
! enet_peer_has_outgoing_commands (peer) &&
1592
enet_list_empty (sentUnreliableCommands))
1593
enet_peer_disconnect (peer, peer -> eventData);
1594
1595
return canPing;
1596
}
1597
1598
static int
1599
enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int checkForTimeouts)
1600
{
1601
enet_uint8 headerData [sizeof (ENetProtocolHeader) + sizeof (enet_uint32)];
1602
ENetProtocolHeader * header = (ENetProtocolHeader *) headerData;
1603
int sentLength = 0;
1604
size_t shouldCompress = 0;
1605
ENetList sentUnreliableCommands;
1606
1607
enet_list_clear (& sentUnreliableCommands);
1608
1609
for (int sendPass = 0, continueSending = 0; sendPass <= continueSending; ++ sendPass)
1610
for (ENetPeer * currentPeer = host -> peers;
1611
currentPeer < & host -> peers [host -> peerCount];
1612
++ currentPeer)
1613
{
1614
if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED ||
1615
currentPeer -> state == ENET_PEER_STATE_ZOMBIE ||
1616
(sendPass > 0 && ! (currentPeer -> flags & ENET_PEER_FLAG_CONTINUE_SENDING)))
1617
continue;
1618
1619
currentPeer -> flags &= ~ ENET_PEER_FLAG_CONTINUE_SENDING;
1620
1621
host -> headerFlags = 0;
1622
host -> commandCount = 0;
1623
host -> bufferCount = 1;
1624
host -> packetSize = sizeof (ENetProtocolHeader);
1625
1626
if (! enet_list_empty (& currentPeer -> acknowledgements))
1627
enet_protocol_send_acknowledgements (host, currentPeer);
1628
1629
if (checkForTimeouts != 0 &&
1630
! enet_list_empty (& currentPeer -> sentReliableCommands) &&
1631
ENET_TIME_GREATER_EQUAL (host -> serviceTime, currentPeer -> nextTimeout) &&
1632
enet_protocol_check_timeouts (host, currentPeer, event) == 1)
1633
{
1634
if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE)
1635
return 1;
1636
else
1637
goto nextPeer;
1638
}
1639
1640
if (((enet_list_empty (& currentPeer -> outgoingCommands) &&
1641
enet_list_empty (& currentPeer -> outgoingSendReliableCommands)) ||
1642
enet_protocol_check_outgoing_commands (host, currentPeer, & sentUnreliableCommands)) &&
1643
enet_list_empty (& currentPeer -> sentReliableCommands) &&
1644
ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= currentPeer -> pingInterval &&
1645
currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing))
1646
{
1647
enet_peer_ping (currentPeer);
1648
enet_protocol_check_outgoing_commands (host, currentPeer, & sentUnreliableCommands);
1649
}
1650
1651
if (host -> commandCount == 0)
1652
goto nextPeer;
1653
1654
if (currentPeer -> packetLossEpoch == 0)
1655
currentPeer -> packetLossEpoch = host -> serviceTime;
1656
else
1657
if (ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> packetLossEpoch) >= ENET_PEER_PACKET_LOSS_INTERVAL &&
1658
currentPeer -> packetsSent > 0)
1659
{
1660
enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent;
1661
1662
#ifdef ENET_DEBUG
1663
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);
1664
#endif
1665
1666
currentPeer -> packetLossVariance = (currentPeer -> packetLossVariance * 3 + ENET_DIFFERENCE (packetLoss, currentPeer -> packetLoss)) / 4;
1667
currentPeer -> packetLoss = (currentPeer -> packetLoss * 7 + packetLoss) / 8;
1668
1669
currentPeer -> packetLossEpoch = host -> serviceTime;
1670
currentPeer -> packetsSent = 0;
1671
currentPeer -> packetsLost = 0;
1672
}
1673
1674
host -> buffers -> data = headerData;
1675
if (host -> headerFlags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME)
1676
{
1677
header -> sentTime = ENET_HOST_TO_NET_16 (host -> serviceTime & 0xFFFF);
1678
1679
host -> buffers -> dataLength = sizeof (ENetProtocolHeader);
1680
}
1681
else
1682
host -> buffers -> dataLength = (size_t) & ((ENetProtocolHeader *) 0) -> sentTime;
1683
1684
shouldCompress = 0;
1685
if (host -> compressor.context != NULL && host -> compressor.compress != NULL)
1686
{
1687
size_t originalSize = host -> packetSize - sizeof(ENetProtocolHeader),
1688
compressedSize = host -> compressor.compress (host -> compressor.context,
1689
& host -> buffers [1], host -> bufferCount - 1,
1690
originalSize,
1691
host -> packetData [1],
1692
originalSize);
1693
if (compressedSize > 0 && compressedSize < originalSize)
1694
{
1695
host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_COMPRESSED;
1696
shouldCompress = compressedSize;
1697
#ifdef ENET_DEBUG_COMPRESS
1698
printf ("peer %u: compressed %u -> %u (%u%%)\n", currentPeer -> incomingPeerID, originalSize, compressedSize, (compressedSize * 100) / originalSize);
1699
#endif
1700
}
1701
}
1702
1703
if (currentPeer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID)
1704
host -> headerFlags |= currentPeer -> outgoingSessionID << ENET_PROTOCOL_HEADER_SESSION_SHIFT;
1705
header -> peerID = ENET_HOST_TO_NET_16 (currentPeer -> outgoingPeerID | host -> headerFlags);
1706
if (host -> checksum != NULL)
1707
{
1708
enet_uint32 * checksum = (enet_uint32 *) & headerData [host -> buffers -> dataLength];
1709
enet_uint32 newChecksum = currentPeer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID ? currentPeer -> connectID : 0;
1710
/* Checksum may be unaligned, use memcpy to avoid undefined behaviour. */
1711
memcpy(checksum, & newChecksum, sizeof (enet_uint32));
1712
host -> buffers -> dataLength += sizeof (enet_uint32);
1713
newChecksum = host -> checksum (host -> buffers, host -> bufferCount);
1714
memcpy(checksum, & newChecksum, sizeof (enet_uint32));
1715
}
1716
1717
if (shouldCompress > 0)
1718
{
1719
host -> buffers [1].data = host -> packetData [1];
1720
host -> buffers [1].dataLength = shouldCompress;
1721
host -> bufferCount = 2;
1722
}
1723
1724
currentPeer -> lastSendTime = host -> serviceTime;
1725
1726
sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount);
1727
1728
enet_protocol_remove_sent_unreliable_commands (currentPeer, & sentUnreliableCommands);
1729
1730
if (sentLength < 0)
1731
return -1;
1732
1733
host -> totalSentData += sentLength;
1734
host -> totalSentPackets ++;
1735
1736
nextPeer:
1737
if (currentPeer -> flags & ENET_PEER_FLAG_CONTINUE_SENDING)
1738
continueSending = sendPass + 1;
1739
}
1740
1741
return 0;
1742
}
1743
1744
/** Sends any queued packets on the host specified to its designated peers.
1745
1746
@param host host to flush
1747
@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().
1748
@ingroup host
1749
*/
1750
void
1751
enet_host_flush (ENetHost * host)
1752
{
1753
host -> serviceTime = enet_time_get ();
1754
1755
enet_protocol_send_outgoing_commands (host, NULL, 0);
1756
}
1757
1758
/** Checks for any queued events on the host and dispatches one if available.
1759
1760
@param host host to check for events
1761
@param event an event structure where event details will be placed if available
1762
@retval > 0 if an event was dispatched
1763
@retval 0 if no events are available
1764
@retval < 0 on failure
1765
@ingroup host
1766
*/
1767
int
1768
enet_host_check_events (ENetHost * host, ENetEvent * event)
1769
{
1770
if (event == NULL) return -1;
1771
1772
event -> type = ENET_EVENT_TYPE_NONE;
1773
event -> peer = NULL;
1774
event -> packet = NULL;
1775
1776
return enet_protocol_dispatch_incoming_commands (host, event);
1777
}
1778
1779
/** Waits for events on the host specified and shuttles packets between
1780
the host and its peers.
1781
1782
@param host host to service
1783
@param event an event structure where event details will be placed if one occurs
1784
if event == NULL then no events will be delivered
1785
@param timeout number of milliseconds that ENet should wait for events
1786
@retval > 0 if an event occurred within the specified time limit
1787
@retval 0 if no event occurred
1788
@retval < 0 on failure
1789
@remarks enet_host_service should be called fairly regularly for adequate performance
1790
@ingroup host
1791
*/
1792
int
1793
enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
1794
{
1795
enet_uint32 waitCondition;
1796
1797
if (event != NULL)
1798
{
1799
event -> type = ENET_EVENT_TYPE_NONE;
1800
event -> peer = NULL;
1801
event -> packet = NULL;
1802
1803
switch (enet_protocol_dispatch_incoming_commands (host, event))
1804
{
1805
case 1:
1806
return 1;
1807
1808
case -1:
1809
#ifdef ENET_DEBUG
1810
perror ("Error dispatching incoming packets");
1811
#endif
1812
1813
return -1;
1814
1815
default:
1816
break;
1817
}
1818
}
1819
1820
host -> serviceTime = enet_time_get ();
1821
1822
timeout += host -> serviceTime;
1823
1824
do
1825
{
1826
if (ENET_TIME_DIFFERENCE (host -> serviceTime, host -> bandwidthThrottleEpoch) >= ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
1827
enet_host_bandwidth_throttle (host);
1828
1829
switch (enet_protocol_send_outgoing_commands (host, event, 1))
1830
{
1831
case 1:
1832
return 1;
1833
1834
case -1:
1835
#ifdef ENET_DEBUG
1836
perror ("Error sending outgoing packets");
1837
#endif
1838
1839
return -1;
1840
1841
default:
1842
break;
1843
}
1844
1845
switch (enet_protocol_receive_incoming_commands (host, event))
1846
{
1847
case 1:
1848
return 1;
1849
1850
case -1:
1851
#ifdef ENET_DEBUG
1852
perror ("Error receiving incoming packets");
1853
#endif
1854
1855
return -1;
1856
1857
default:
1858
break;
1859
}
1860
1861
switch (enet_protocol_send_outgoing_commands (host, event, 1))
1862
{
1863
case 1:
1864
return 1;
1865
1866
case -1:
1867
#ifdef ENET_DEBUG
1868
perror ("Error sending outgoing packets");
1869
#endif
1870
1871
return -1;
1872
1873
default:
1874
break;
1875
}
1876
1877
if (event != NULL)
1878
{
1879
switch (enet_protocol_dispatch_incoming_commands (host, event))
1880
{
1881
case 1:
1882
return 1;
1883
1884
case -1:
1885
#ifdef ENET_DEBUG
1886
perror ("Error dispatching incoming packets");
1887
#endif
1888
1889
return -1;
1890
1891
default:
1892
break;
1893
}
1894
}
1895
1896
if (ENET_TIME_GREATER_EQUAL (host -> serviceTime, timeout))
1897
return 0;
1898
1899
do
1900
{
1901
host -> serviceTime = enet_time_get ();
1902
1903
if (ENET_TIME_GREATER_EQUAL (host -> serviceTime, timeout))
1904
return 0;
1905
1906
waitCondition = ENET_SOCKET_WAIT_RECEIVE | ENET_SOCKET_WAIT_INTERRUPT;
1907
1908
if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0)
1909
return -1;
1910
}
1911
while (waitCondition & ENET_SOCKET_WAIT_INTERRUPT);
1912
1913
host -> serviceTime = enet_time_get ();
1914
} while (waitCondition & ENET_SOCKET_WAIT_RECEIVE);
1915
1916
return 0;
1917
}
1918
1919
1920