renet 0.1.0-universal-darwin

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,816 @@
1
+ /**
2
+ @file peer.c
3
+ @brief ENet peer management functions
4
+ */
5
+ #include <string.h>
6
+ #define ENET_BUILDING_LIB 1
7
+ #include "enet/enet.h"
8
+
9
+ /** @defgroup peer ENet peer functions
10
+ @{
11
+ */
12
+
13
+ /** Configures throttle parameter for a peer.
14
+
15
+ Unreliable packets are dropped by ENet in response to the varying conditions
16
+ of the Internet connection to the peer. The throttle represents a probability
17
+ that an unreliable packet should not be dropped and thus sent by ENet to the peer.
18
+ The lowest mean round trip time from the sending of a reliable packet to the
19
+ receipt of its acknowledgement is measured over an amount of time specified by
20
+ the interval parameter in milliseconds. If a measured round trip time happens to
21
+ be significantly less than the mean round trip time measured over the interval,
22
+ then the throttle probability is increased to allow more traffic by an amount
23
+ specified in the acceleration parameter, which is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE
24
+ constant. If a measured round trip time happens to be significantly greater than
25
+ the mean round trip time measured over the interval, then the throttle probability
26
+ is decreased to limit traffic by an amount specified in the deceleration parameter, which
27
+ is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE constant. When the throttle has
28
+ a value of ENET_PEER_PACKET_THROTTLE_SCALE, on unreliable packets are dropped by
29
+ ENet, and so 100% of all unreliable packets will be sent. When the throttle has a
30
+ value of 0, all unreliable packets are dropped by ENet, and so 0% of all unreliable
31
+ packets will be sent. Intermediate values for the throttle represent intermediate
32
+ probabilities between 0% and 100% of unreliable packets being sent. The bandwidth
33
+ limits of the local and foreign hosts are taken into account to determine a
34
+ sensible limit for the throttle probability above which it should not raise even in
35
+ the best of conditions.
36
+
37
+ @param peer peer to configure
38
+ @param interval interval, in milliseconds, over which to measure lowest mean RTT; the default value is ENET_PEER_PACKET_THROTTLE_INTERVAL.
39
+ @param acceleration rate at which to increase the throttle probability as mean RTT declines
40
+ @param deceleration rate at which to decrease the throttle probability as mean RTT increases
41
+ */
42
+ void
43
+ enet_peer_throttle_configure (ENetPeer * peer, enet_uint32 interval, enet_uint32 acceleration, enet_uint32 deceleration)
44
+ {
45
+ ENetProtocol command;
46
+
47
+ peer -> packetThrottleInterval = interval;
48
+ peer -> packetThrottleAcceleration = acceleration;
49
+ peer -> packetThrottleDeceleration = deceleration;
50
+
51
+ command.header.command = ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
52
+ command.header.channelID = 0xFF;
53
+
54
+ command.throttleConfigure.packetThrottleInterval = ENET_HOST_TO_NET_32 (interval);
55
+ command.throttleConfigure.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (acceleration);
56
+ command.throttleConfigure.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (deceleration);
57
+
58
+ enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
59
+ }
60
+
61
+ int
62
+ enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt)
63
+ {
64
+ if (peer -> lastRoundTripTime <= peer -> lastRoundTripTimeVariance)
65
+ {
66
+ peer -> packetThrottle = peer -> packetThrottleLimit;
67
+ }
68
+ else
69
+ if (rtt < peer -> lastRoundTripTime)
70
+ {
71
+ peer -> packetThrottle += peer -> packetThrottleAcceleration;
72
+
73
+ if (peer -> packetThrottle > peer -> packetThrottleLimit)
74
+ peer -> packetThrottle = peer -> packetThrottleLimit;
75
+
76
+ return 1;
77
+ }
78
+ else
79
+ if (rtt > peer -> lastRoundTripTime + 2 * peer -> lastRoundTripTimeVariance)
80
+ {
81
+ if (peer -> packetThrottle > peer -> packetThrottleDeceleration)
82
+ peer -> packetThrottle -= peer -> packetThrottleDeceleration;
83
+ else
84
+ peer -> packetThrottle = 0;
85
+
86
+ return -1;
87
+ }
88
+
89
+ return 0;
90
+ }
91
+
92
+ /** Queues a packet to be sent.
93
+ @param peer destination for the packet
94
+ @param channelID channel on which to send
95
+ @param packet packet to send
96
+ @retval 0 on success
97
+ @retval < 0 on failure
98
+ */
99
+ int
100
+ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
101
+ {
102
+ ENetChannel * channel = & peer -> channels [channelID];
103
+ ENetProtocol command;
104
+ size_t fragmentLength;
105
+
106
+ if (peer -> state != ENET_PEER_STATE_CONNECTED ||
107
+ channelID >= peer -> channelCount)
108
+ return -1;
109
+
110
+ fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment);
111
+
112
+ if (packet -> dataLength > fragmentLength)
113
+ {
114
+ enet_uint16 startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingReliableSequenceNumber + 1);
115
+ enet_uint32 fragmentCount = ENET_HOST_TO_NET_32 ((packet -> dataLength + fragmentLength - 1) / fragmentLength),
116
+ fragmentNumber,
117
+ fragmentOffset;
118
+ ENetList fragments;
119
+ ENetOutgoingCommand * fragment;
120
+
121
+ enet_list_clear (& fragments);
122
+
123
+ for (fragmentNumber = 0,
124
+ fragmentOffset = 0;
125
+ fragmentOffset < packet -> dataLength;
126
+ ++ fragmentNumber,
127
+ fragmentOffset += fragmentLength)
128
+ {
129
+ if (packet -> dataLength - fragmentOffset < fragmentLength)
130
+ fragmentLength = packet -> dataLength - fragmentOffset;
131
+
132
+ fragment = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand));
133
+ if (fragment == NULL)
134
+ {
135
+ while (! enet_list_empty (& fragments))
136
+ {
137
+ fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments));
138
+
139
+ enet_free (fragment);
140
+ }
141
+
142
+ return -1;
143
+ }
144
+
145
+ fragment -> fragmentOffset = fragmentOffset;
146
+ fragment -> fragmentLength = fragmentLength;
147
+ fragment -> packet = packet;
148
+ fragment -> command.header.command = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
149
+ fragment -> command.header.channelID = channelID;
150
+ fragment -> command.sendFragment.startSequenceNumber = startSequenceNumber;
151
+ fragment -> command.sendFragment.dataLength = ENET_HOST_TO_NET_16 (fragmentLength);
152
+ fragment -> command.sendFragment.fragmentCount = fragmentCount;
153
+ fragment -> command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32 (fragmentNumber);
154
+ fragment -> command.sendFragment.totalLength = ENET_HOST_TO_NET_32 (packet -> dataLength);
155
+ fragment -> command.sendFragment.fragmentOffset = ENET_NET_TO_HOST_32 (fragmentOffset);
156
+
157
+ enet_list_insert (enet_list_end (& fragments), fragment);
158
+ }
159
+
160
+ packet -> referenceCount += fragmentNumber;
161
+
162
+ while (! enet_list_empty (& fragments))
163
+ {
164
+ fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments));
165
+
166
+ enet_peer_setup_outgoing_command (peer, fragment);
167
+ }
168
+
169
+ return 0;
170
+ }
171
+
172
+ command.header.channelID = channelID;
173
+
174
+ if (packet -> flags & ENET_PACKET_FLAG_RELIABLE)
175
+ {
176
+ command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
177
+ command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
178
+ }
179
+ else
180
+ if (packet -> flags & ENET_PACKET_FLAG_UNSEQUENCED)
181
+ {
182
+ command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
183
+ command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_16 (peer -> outgoingUnsequencedGroup + 1);
184
+ command.sendUnsequenced.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
185
+ }
186
+ else
187
+ if (channel -> outgoingUnreliableSequenceNumber >= 0xFFFF)
188
+ {
189
+ command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
190
+ command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
191
+ }
192
+ else
193
+ {
194
+ command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE;
195
+ command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingUnreliableSequenceNumber + 1);
196
+ command.sendUnreliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
197
+ }
198
+
199
+ if (enet_peer_queue_outgoing_command (peer, & command, packet, 0, packet -> dataLength) == NULL)
200
+ return -1;
201
+
202
+ return 0;
203
+ }
204
+
205
+ /** Attempts to dequeue any incoming queued packet.
206
+ @param peer peer to dequeue packets from
207
+ @param channelID holds the channel ID of the channel the packet was received on success
208
+ @returns a pointer to the packet, or NULL if there are no available incoming queued packets
209
+ */
210
+ ENetPacket *
211
+ enet_peer_receive (ENetPeer * peer, enet_uint8 * channelID)
212
+ {
213
+ ENetIncomingCommand * incomingCommand;
214
+ ENetPacket * packet;
215
+
216
+ if (enet_list_empty (& peer -> dispatchedCommands))
217
+ return NULL;
218
+
219
+ incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (& peer -> dispatchedCommands));
220
+
221
+ if (channelID != NULL)
222
+ * channelID = incomingCommand -> command.header.channelID;
223
+
224
+ packet = incomingCommand -> packet;
225
+
226
+ -- packet -> referenceCount;
227
+
228
+ if (incomingCommand -> fragments != NULL)
229
+ enet_free (incomingCommand -> fragments);
230
+
231
+ enet_free (incomingCommand);
232
+
233
+ return packet;
234
+ }
235
+
236
+ static void
237
+ enet_peer_reset_outgoing_commands (ENetList * queue)
238
+ {
239
+ ENetOutgoingCommand * outgoingCommand;
240
+
241
+ while (! enet_list_empty (queue))
242
+ {
243
+ outgoingCommand = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (queue));
244
+
245
+ if (outgoingCommand -> packet != NULL)
246
+ {
247
+ -- outgoingCommand -> packet -> referenceCount;
248
+
249
+ if (outgoingCommand -> packet -> referenceCount == 0)
250
+ enet_packet_destroy (outgoingCommand -> packet);
251
+ }
252
+
253
+ enet_free (outgoingCommand);
254
+ }
255
+ }
256
+
257
+ static void
258
+ enet_peer_reset_incoming_commands (ENetList * queue)
259
+ {
260
+ ENetIncomingCommand * incomingCommand;
261
+
262
+ while (! enet_list_empty (queue))
263
+ {
264
+ incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (queue));
265
+
266
+ if (incomingCommand -> packet != NULL)
267
+ {
268
+ -- incomingCommand -> packet -> referenceCount;
269
+
270
+ if (incomingCommand -> packet -> referenceCount == 0)
271
+ enet_packet_destroy (incomingCommand -> packet);
272
+ }
273
+
274
+ if (incomingCommand -> fragments != NULL)
275
+ enet_free (incomingCommand -> fragments);
276
+
277
+ enet_free (incomingCommand);
278
+ }
279
+ }
280
+
281
+ void
282
+ enet_peer_reset_queues (ENetPeer * peer)
283
+ {
284
+ ENetChannel * channel;
285
+
286
+ if (peer -> needsDispatch)
287
+ {
288
+ enet_list_remove (& peer -> dispatchList);
289
+
290
+ peer -> needsDispatch = 0;
291
+ }
292
+
293
+ while (! enet_list_empty (& peer -> acknowledgements))
294
+ enet_free (enet_list_remove (enet_list_begin (& peer -> acknowledgements)));
295
+
296
+ enet_peer_reset_outgoing_commands (& peer -> sentReliableCommands);
297
+ enet_peer_reset_outgoing_commands (& peer -> sentUnreliableCommands);
298
+ enet_peer_reset_outgoing_commands (& peer -> outgoingReliableCommands);
299
+ enet_peer_reset_outgoing_commands (& peer -> outgoingUnreliableCommands);
300
+ enet_peer_reset_incoming_commands (& peer -> dispatchedCommands);
301
+
302
+ if (peer -> channels != NULL && peer -> channelCount > 0)
303
+ {
304
+ for (channel = peer -> channels;
305
+ channel < & peer -> channels [peer -> channelCount];
306
+ ++ channel)
307
+ {
308
+ enet_peer_reset_incoming_commands (& channel -> incomingReliableCommands);
309
+ enet_peer_reset_incoming_commands (& channel -> incomingUnreliableCommands);
310
+ }
311
+
312
+ enet_free (peer -> channels);
313
+ }
314
+
315
+ peer -> channels = NULL;
316
+ peer -> channelCount = 0;
317
+ }
318
+
319
+ /** Forcefully disconnects a peer.
320
+ @param peer peer to forcefully disconnect
321
+ @remarks The foreign host represented by the peer is not notified of the disconnection and will timeout
322
+ on its connection to the local host.
323
+ */
324
+ void
325
+ enet_peer_reset (ENetPeer * peer)
326
+ {
327
+ peer -> outgoingPeerID = ENET_PROTOCOL_MAXIMUM_PEER_ID;
328
+ peer -> connectID = 0;
329
+
330
+ peer -> state = ENET_PEER_STATE_DISCONNECTED;
331
+
332
+ peer -> incomingBandwidth = 0;
333
+ peer -> outgoingBandwidth = 0;
334
+ peer -> incomingBandwidthThrottleEpoch = 0;
335
+ peer -> outgoingBandwidthThrottleEpoch = 0;
336
+ peer -> incomingDataTotal = 0;
337
+ peer -> outgoingDataTotal = 0;
338
+ peer -> lastSendTime = 0;
339
+ peer -> lastReceiveTime = 0;
340
+ peer -> nextTimeout = 0;
341
+ peer -> earliestTimeout = 0;
342
+ peer -> packetLossEpoch = 0;
343
+ peer -> packetsSent = 0;
344
+ peer -> packetsLost = 0;
345
+ peer -> packetLoss = 0;
346
+ peer -> packetLossVariance = 0;
347
+ peer -> packetThrottle = ENET_PEER_DEFAULT_PACKET_THROTTLE;
348
+ peer -> packetThrottleLimit = ENET_PEER_PACKET_THROTTLE_SCALE;
349
+ peer -> packetThrottleCounter = 0;
350
+ peer -> packetThrottleEpoch = 0;
351
+ peer -> packetThrottleAcceleration = ENET_PEER_PACKET_THROTTLE_ACCELERATION;
352
+ peer -> packetThrottleDeceleration = ENET_PEER_PACKET_THROTTLE_DECELERATION;
353
+ peer -> packetThrottleInterval = ENET_PEER_PACKET_THROTTLE_INTERVAL;
354
+ peer -> lastRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME;
355
+ peer -> lowestRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME;
356
+ peer -> lastRoundTripTimeVariance = 0;
357
+ peer -> highestRoundTripTimeVariance = 0;
358
+ peer -> roundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME;
359
+ peer -> roundTripTimeVariance = 0;
360
+ peer -> mtu = peer -> host -> mtu;
361
+ peer -> reliableDataInTransit = 0;
362
+ peer -> outgoingReliableSequenceNumber = 0;
363
+ peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
364
+ peer -> incomingUnsequencedGroup = 0;
365
+ peer -> outgoingUnsequencedGroup = 0;
366
+ peer -> eventData = 0;
367
+
368
+ memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow));
369
+
370
+ enet_peer_reset_queues (peer);
371
+ }
372
+
373
+ /** Sends a ping request to a peer.
374
+ @param peer destination for the ping request
375
+ @remarks ping requests factor into the mean round trip time as designated by the
376
+ roundTripTime field in the ENetPeer structure. Enet automatically pings all connected
377
+ peers at regular intervals, however, this function may be called to ensure more
378
+ frequent ping requests.
379
+ */
380
+ void
381
+ enet_peer_ping (ENetPeer * peer)
382
+ {
383
+ ENetProtocol command;
384
+
385
+ if (peer -> state != ENET_PEER_STATE_CONNECTED)
386
+ return;
387
+
388
+ command.header.command = ENET_PROTOCOL_COMMAND_PING | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
389
+ command.header.channelID = 0xFF;
390
+
391
+ enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
392
+ }
393
+
394
+ /** Force an immediate disconnection from a peer.
395
+ @param peer peer to disconnect
396
+ @param data data describing the disconnection
397
+ @remarks No ENET_EVENT_DISCONNECT event will be generated. The foreign peer is not
398
+ guarenteed to receive the disconnect notification, and is reset immediately upon
399
+ return from this function.
400
+ */
401
+ void
402
+ enet_peer_disconnect_now (ENetPeer * peer, enet_uint32 data)
403
+ {
404
+ ENetProtocol command;
405
+
406
+ if (peer -> state == ENET_PEER_STATE_DISCONNECTED)
407
+ return;
408
+
409
+ if (peer -> state != ENET_PEER_STATE_ZOMBIE &&
410
+ peer -> state != ENET_PEER_STATE_DISCONNECTING)
411
+ {
412
+ enet_peer_reset_queues (peer);
413
+
414
+ command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
415
+ command.header.channelID = 0xFF;
416
+ command.disconnect.data = ENET_HOST_TO_NET_32 (data);
417
+
418
+ enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
419
+
420
+ enet_host_flush (peer -> host);
421
+ }
422
+
423
+ enet_peer_reset (peer);
424
+ }
425
+
426
+ /** Request a disconnection from a peer.
427
+ @param peer peer to request a disconnection
428
+ @param data data describing the disconnection
429
+ @remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service()
430
+ once the disconnection is complete.
431
+ */
432
+ void
433
+ enet_peer_disconnect (ENetPeer * peer, enet_uint32 data)
434
+ {
435
+ ENetProtocol command;
436
+
437
+ if (peer -> state == ENET_PEER_STATE_DISCONNECTING ||
438
+ peer -> state == ENET_PEER_STATE_DISCONNECTED ||
439
+ peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT ||
440
+ peer -> state == ENET_PEER_STATE_ZOMBIE)
441
+ return;
442
+
443
+ enet_peer_reset_queues (peer);
444
+
445
+ command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT;
446
+ command.header.channelID = 0xFF;
447
+ command.disconnect.data = ENET_HOST_TO_NET_32 (data);
448
+
449
+ if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
450
+ command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
451
+ else
452
+ command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
453
+
454
+ enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
455
+
456
+ if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
457
+ peer -> state = ENET_PEER_STATE_DISCONNECTING;
458
+ else
459
+ {
460
+ enet_host_flush (peer -> host);
461
+ enet_peer_reset (peer);
462
+ }
463
+ }
464
+
465
+ /** Request a disconnection from a peer, but only after all queued outgoing packets are sent.
466
+ @param peer peer to request a disconnection
467
+ @param data data describing the disconnection
468
+ @remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service()
469
+ once the disconnection is complete.
470
+ */
471
+ void
472
+ enet_peer_disconnect_later (ENetPeer * peer, enet_uint32 data)
473
+ {
474
+ if ((peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) &&
475
+ ! (enet_list_empty (& peer -> outgoingReliableCommands) &&
476
+ enet_list_empty (& peer -> outgoingUnreliableCommands) &&
477
+ enet_list_empty (& peer -> sentReliableCommands)))
478
+ {
479
+ peer -> state = ENET_PEER_STATE_DISCONNECT_LATER;
480
+ peer -> eventData = data;
481
+ }
482
+ else
483
+ enet_peer_disconnect (peer, data);
484
+ }
485
+
486
+ ENetAcknowledgement *
487
+ enet_peer_queue_acknowledgement (ENetPeer * peer, const ENetProtocol * command, enet_uint16 sentTime)
488
+ {
489
+ ENetAcknowledgement * acknowledgement;
490
+
491
+ if (command -> header.channelID < peer -> channelCount)
492
+ {
493
+ ENetChannel * channel = & peer -> channels [command -> header.channelID];
494
+ enet_uint16 reliableWindow = command -> header.reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE,
495
+ currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
496
+
497
+ if (command -> header.reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
498
+ reliableWindow += ENET_PEER_RELIABLE_WINDOWS;
499
+
500
+ if (reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1 && reliableWindow <= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS)
501
+ return NULL;
502
+ }
503
+
504
+ acknowledgement = (ENetAcknowledgement *) enet_malloc (sizeof (ENetAcknowledgement));
505
+ if (acknowledgement == NULL)
506
+ return NULL;
507
+
508
+ peer -> outgoingDataTotal += sizeof (ENetProtocolAcknowledge);
509
+
510
+ acknowledgement -> sentTime = sentTime;
511
+ acknowledgement -> command = * command;
512
+
513
+ enet_list_insert (enet_list_end (& peer -> acknowledgements), acknowledgement);
514
+
515
+ return acknowledgement;
516
+ }
517
+
518
+ void
519
+ enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoingCommand)
520
+ {
521
+ ENetChannel * channel = & peer -> channels [outgoingCommand -> command.header.channelID];
522
+
523
+ peer -> outgoingDataTotal += enet_protocol_command_size (outgoingCommand -> command.header.command) + outgoingCommand -> fragmentLength;
524
+
525
+ if (outgoingCommand -> command.header.channelID == 0xFF)
526
+ {
527
+ ++ peer -> outgoingReliableSequenceNumber;
528
+
529
+ outgoingCommand -> reliableSequenceNumber = peer -> outgoingReliableSequenceNumber;
530
+ outgoingCommand -> unreliableSequenceNumber = 0;
531
+ }
532
+ else
533
+ if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
534
+ {
535
+ ++ channel -> outgoingReliableSequenceNumber;
536
+ channel -> outgoingUnreliableSequenceNumber = 0;
537
+
538
+ outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber;
539
+ outgoingCommand -> unreliableSequenceNumber = 0;
540
+ }
541
+ else
542
+ if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED)
543
+ {
544
+ ++ peer -> outgoingUnsequencedGroup;
545
+
546
+ outgoingCommand -> reliableSequenceNumber = 0;
547
+ outgoingCommand -> unreliableSequenceNumber = 0;
548
+ }
549
+ else
550
+ {
551
+ ++ channel -> outgoingUnreliableSequenceNumber;
552
+
553
+ outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber;
554
+ outgoingCommand -> unreliableSequenceNumber = channel -> outgoingUnreliableSequenceNumber;
555
+ }
556
+
557
+ outgoingCommand -> sendAttempts = 0;
558
+ outgoingCommand -> sentTime = 0;
559
+ outgoingCommand -> roundTripTimeout = 0;
560
+ outgoingCommand -> roundTripTimeoutLimit = 0;
561
+ outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_16 (outgoingCommand -> reliableSequenceNumber);
562
+
563
+ if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
564
+ enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand);
565
+ else
566
+ enet_list_insert (enet_list_end (& peer -> outgoingUnreliableCommands), outgoingCommand);
567
+ }
568
+
569
+ ENetOutgoingCommand *
570
+ enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 offset, enet_uint16 length)
571
+ {
572
+ ENetOutgoingCommand * outgoingCommand = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand));
573
+ if (outgoingCommand == NULL)
574
+ return NULL;
575
+
576
+ outgoingCommand -> command = * command;
577
+ outgoingCommand -> fragmentOffset = offset;
578
+ outgoingCommand -> fragmentLength = length;
579
+ outgoingCommand -> packet = packet;
580
+ if (packet != NULL)
581
+ ++ packet -> referenceCount;
582
+
583
+ enet_peer_setup_outgoing_command (peer, outgoingCommand);
584
+
585
+ return outgoingCommand;
586
+ }
587
+
588
+ void
589
+ enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel)
590
+ {
591
+ ENetListIterator currentCommand;
592
+
593
+ for (currentCommand = enet_list_begin (& channel -> incomingUnreliableCommands);
594
+ currentCommand != enet_list_end (& channel -> incomingUnreliableCommands);
595
+ currentCommand = enet_list_next (currentCommand))
596
+ {
597
+ ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand;
598
+
599
+ if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE &&
600
+ incomingCommand -> reliableSequenceNumber != channel -> incomingReliableSequenceNumber)
601
+ break;
602
+ }
603
+
604
+ if (currentCommand == enet_list_begin (& channel -> incomingUnreliableCommands))
605
+ return;
606
+
607
+ enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingUnreliableCommands), enet_list_previous (currentCommand));
608
+
609
+ if (! peer -> needsDispatch)
610
+ {
611
+ enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
612
+
613
+ peer -> needsDispatch = 1;
614
+ }
615
+ }
616
+
617
+ void
618
+ enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * channel)
619
+ {
620
+ ENetListIterator currentCommand;
621
+
622
+ for (currentCommand = enet_list_begin (& channel -> incomingReliableCommands);
623
+ currentCommand != enet_list_end (& channel -> incomingReliableCommands);
624
+ currentCommand = enet_list_next (currentCommand))
625
+ {
626
+ ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand;
627
+
628
+ if (incomingCommand -> fragmentsRemaining > 0 ||
629
+ incomingCommand -> reliableSequenceNumber != (enet_uint16) (channel -> incomingReliableSequenceNumber + 1))
630
+ break;
631
+
632
+ channel -> incomingReliableSequenceNumber = incomingCommand -> reliableSequenceNumber;
633
+
634
+ if (incomingCommand -> fragmentCount > 0)
635
+ channel -> incomingReliableSequenceNumber += incomingCommand -> fragmentCount - 1;
636
+ }
637
+
638
+ if (currentCommand == enet_list_begin (& channel -> incomingReliableCommands))
639
+ return;
640
+
641
+ enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingReliableCommands), enet_list_previous (currentCommand));
642
+
643
+ if (! peer -> needsDispatch)
644
+ {
645
+ enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
646
+
647
+ peer -> needsDispatch = 1;
648
+ }
649
+
650
+ enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
651
+ }
652
+
653
+ ENetIncomingCommand *
654
+ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 fragmentCount)
655
+ {
656
+ static ENetIncomingCommand dummyCommand;
657
+
658
+ ENetChannel * channel = & peer -> channels [command -> header.channelID];
659
+ enet_uint32 unreliableSequenceNumber = 0, reliableSequenceNumber;
660
+ enet_uint16 reliableWindow, currentWindow;
661
+ ENetIncomingCommand * incomingCommand;
662
+ ENetListIterator currentCommand;
663
+
664
+ if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
665
+ goto freePacket;
666
+
667
+ if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED)
668
+ {
669
+ reliableSequenceNumber = command -> header.reliableSequenceNumber;
670
+ reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
671
+ currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
672
+
673
+ if (reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
674
+ reliableWindow += ENET_PEER_RELIABLE_WINDOWS;
675
+
676
+ if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1)
677
+ goto freePacket;
678
+ }
679
+
680
+ switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK)
681
+ {
682
+ case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
683
+ case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
684
+ if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber)
685
+ goto freePacket;
686
+
687
+ for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands));
688
+ currentCommand != enet_list_end (& channel -> incomingReliableCommands);
689
+ currentCommand = enet_list_previous (currentCommand))
690
+ {
691
+ incomingCommand = (ENetIncomingCommand *) currentCommand;
692
+
693
+ if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
694
+ {
695
+ if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
696
+ continue;
697
+ }
698
+ else
699
+ if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
700
+ break;
701
+
702
+ if (incomingCommand -> reliableSequenceNumber <= reliableSequenceNumber)
703
+ {
704
+ if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber)
705
+ break;
706
+
707
+ goto freePacket;
708
+ }
709
+ }
710
+ break;
711
+
712
+ case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE:
713
+ unreliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendUnreliable.unreliableSequenceNumber);
714
+
715
+ for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands));
716
+ currentCommand != enet_list_end (& channel -> incomingUnreliableCommands);
717
+ currentCommand = enet_list_previous (currentCommand))
718
+ {
719
+ incomingCommand = (ENetIncomingCommand *) currentCommand;
720
+
721
+ if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE)
722
+ continue;
723
+
724
+ if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
725
+ {
726
+ if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
727
+ continue;
728
+ }
729
+ else
730
+ if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
731
+ break;
732
+
733
+ if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber)
734
+ break;
735
+
736
+ if (incomingCommand -> reliableSequenceNumber > reliableSequenceNumber)
737
+ continue;
738
+
739
+ if (incomingCommand -> unreliableSequenceNumber <= unreliableSequenceNumber)
740
+ {
741
+ if (incomingCommand -> unreliableSequenceNumber < unreliableSequenceNumber)
742
+ break;
743
+
744
+ goto freePacket;
745
+ }
746
+ }
747
+ break;
748
+
749
+ case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED:
750
+ currentCommand = enet_list_end (& channel -> incomingUnreliableCommands);
751
+ break;
752
+
753
+ default:
754
+ goto freePacket;
755
+ }
756
+
757
+ incomingCommand = (ENetIncomingCommand *) enet_malloc (sizeof (ENetIncomingCommand));
758
+ if (incomingCommand == NULL)
759
+ goto notifyError;
760
+
761
+ incomingCommand -> reliableSequenceNumber = command -> header.reliableSequenceNumber;
762
+ incomingCommand -> unreliableSequenceNumber = unreliableSequenceNumber & 0xFFFF;
763
+ incomingCommand -> command = * command;
764
+ incomingCommand -> fragmentCount = fragmentCount;
765
+ incomingCommand -> fragmentsRemaining = fragmentCount;
766
+ incomingCommand -> packet = packet;
767
+ incomingCommand -> fragments = NULL;
768
+
769
+ if (fragmentCount > 0)
770
+ {
771
+ incomingCommand -> fragments = (enet_uint32 *) enet_malloc ((fragmentCount + 31) / 32 * sizeof (enet_uint32));
772
+ if (incomingCommand -> fragments == NULL)
773
+ {
774
+ enet_free (incomingCommand);
775
+
776
+ goto notifyError;
777
+ }
778
+ memset (incomingCommand -> fragments, 0, (fragmentCount + 31) / 32 * sizeof (enet_uint32));
779
+ }
780
+
781
+ if (packet != NULL)
782
+ ++ packet -> referenceCount;
783
+
784
+ enet_list_insert (enet_list_next (currentCommand), incomingCommand);
785
+
786
+ switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK)
787
+ {
788
+ case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
789
+ case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
790
+ enet_peer_dispatch_incoming_reliable_commands (peer, channel);
791
+ break;
792
+
793
+ default:
794
+ enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
795
+ break;
796
+ }
797
+
798
+ return incomingCommand;
799
+
800
+ freePacket:
801
+ if (fragmentCount > 0)
802
+ goto notifyError;
803
+
804
+ if (packet != NULL && packet -> referenceCount == 0)
805
+ enet_packet_destroy (packet);
806
+
807
+ return & dummyCommand;
808
+
809
+ notifyError:
810
+ if (packet != NULL && packet -> referenceCount == 0)
811
+ enet_packet_destroy (packet);
812
+
813
+ return NULL;
814
+ }
815
+
816
+ /** @} */