~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/enet/protocol.c

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

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