SLikeNet 0.1.3

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ReliabilityLayer.cpp
Go to the documentation of this file.
1 /*
2 * Original work: Copyright (c) 2014, Oculus VR, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * RakNet License.txt file in the licenses directory of this source tree. An additional grant
7 * of patent rights can be found in the RakNet Patents.txt file in the same directory.
8 *
9 *
10 * Modified work: Copyright (c) 2016-2018, SLikeSoft UG (haftungsbeschränkt)
11 *
12 * This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
13 * license found in the license.txt file in the root directory of this source tree.
14 */
15
18
19
20
21 #include "slikenet/ReliabilityLayer.h"
22 #include "slikenet/GetTime.h"
23 #include "slikenet/SocketLayer.h"
24 #include "slikenet/PluginInterface2.h"
25 #include "slikenet/assert.h"
26 #include "slikenet/Rand.h"
27 #include "slikenet/MessageIdentifiers.h"
28 #ifdef USE_THREADED_SEND
29 #include "slikenet/SendToThread.h"
30 #endif
31 #include <math.h>
32 #include "slikenet/linux_adapter.h"
33 #include "slikenet/osx_adapter.h"
34
35 using namespace SLNet;
36
37 // Can't figure out which library has this function on the PS3
38 double Ceil(double d) {if (((double)((int)d))==d) return d; return (int) (d+1.0);}
39
40 // #if defined(new)
41 // #pragma push_macro("new")
42 // #undef new
43 // #define RELIABILITY_LAYER_NEW_UNDEF_ALLOCATING_QUEUE
44 // #endif
45
46
47 //#define _DEBUG_LOGGER
48
49 #if CC_TIME_TYPE_BYTES==4
50 static const CCTimeType MAX_TIME_BETWEEN_PACKETS= 350; // 350 milliseconds
51 static const CCTimeType HISTOGRAM_RESTART_CYCLE=10000; // Every 10 seconds reset the histogram
52 #else
53 static const CCTimeType MAX_TIME_BETWEEN_PACKETS= 350000; // 350 milliseconds
54 //static const CCTimeType HISTOGRAM_RESTART_CYCLE=10000000; // Every 10 seconds reset the histogram
55 #endif
56 static const int DEFAULT_HAS_RECEIVED_PACKET_QUEUE_SIZE=512;
57 static const CCTimeType STARTING_TIME_BETWEEN_PACKETS=MAX_TIME_BETWEEN_PACKETS;
58 //static const long double TIME_BETWEEN_PACKETS_INCREASE_MULTIPLIER_DEFAULT=.02;
59 //static const long double TIME_BETWEEN_PACKETS_DECREASE_MULTIPLIER_DEFAULT=1.0 / 9.0;
60
61 typedef uint32_t BitstreamLengthEncoding;
62
63 //#define PRINT_TO_FILE_RELIABLE_ORDERED_TEST
64 #ifdef PRINT_TO_FILE_RELIABLE_ORDERED_TEST
65 static unsigned int packetNumber=0;
66 static FILE *fp=0;
67 #endif
68
69 //#define FLIP_SEND_ORDER_TEST
70 //#define LOG_TRIVIAL_NOTIFICATIONS
71
72 BPSTracker::TimeAndValue2::TimeAndValue2() {}
73 BPSTracker::TimeAndValue2::~TimeAndValue2() {}
74 BPSTracker::TimeAndValue2::TimeAndValue2(SLNet::TimeUS t, uint64_t v1) : value1(v1), time(t) {}
75 //BPSTracker::TimeAndValue2::TimeAndValue2(SLNet::TimeUS t, uint64_t v1, uint64_t v2) : time(t), value1(v1), value2(v2) {}
76 BPSTracker::BPSTracker() {Reset(_FILE_AND_LINE_);}
77 BPSTracker::~BPSTracker() {}
78 //void BPSTracker::Reset(const char *file, unsigned int line) {total1=total2=lastSec1=lastSec2=0; dataQueue.Clear(file,line);}
79 void BPSTracker::Reset(const char *file, unsigned int line) {total1=lastSec1=0; dataQueue.Clear(file,line);}
80 //void BPSTracker::Push2(RakNetTimeUS time, uint64_t value1, uint64_t value2) {dataQueue.Push(TimeAndValue2(time,value1,value2),_FILE_AND_LINE_); total1+=value1; lastSec1+=value1; total2+=value2; lastSec2+=value2;}
81 //uint64_t BPSTracker::GetBPS2(RakNetTimeUS time) {ClearExpired2(time); return lastSec2;}
82 //void BPSTracker::GetBPS1And2(RakNetTimeUS time, uint64_t &out1, uint64_t &out2) {ClearExpired2(time); out1=lastSec1; out2=lastSec2;}
83 uint64_t BPSTracker::GetTotal1(void) const {return total1;}
84 //uint64_t BPSTracker::GetTotal2(void) const {return total2;}
85
86 // void BPSTracker::ClearExpired2(SLNet::TimeUS time) {
87 // SLNet::TimeUS threshold=time;
88 // if (threshold < 1000000)
89 // return;
90 // threshold-=1000000;
91 // while (dataQueue.IsEmpty()==false && dataQueue.Peek().time < threshold)
92 // {
93 // lastSec1-=dataQueue.Peek().value1;
94 // lastSec2-=dataQueue.Peek().value2;
95 // dataQueue.Pop();
96 // }
97 // }
98 void BPSTracker::ClearExpired1(SLNet::TimeUS time)
99 {
100 while (dataQueue.IsEmpty()==false &&
101 #if CC_TIME_TYPE_BYTES==8
102 dataQueue.Peek().time+1000000 < time
103 #else
104 dataQueue.Peek().time+1000 < time
105 #endif
106 )
107 {
108 lastSec1-=dataQueue.Peek().value1;
109 dataQueue.Pop();
110 }
111 }
112
113 struct DatagramHeaderFormat
114 {
115 #if INCLUDE_TIMESTAMP_WITH_DATAGRAMS==1
116 CCTimeType sourceSystemTime;
117 #endif
118 DatagramSequenceNumberType datagramNumber;
119
120 // Use floats to save bandwidth
121 // float B; // Link capacity
122 float AS; // Data arrival rate
123 bool isACK;
124 bool isNAK;
125 bool isPacketPair;
126 bool hasBAndAS;
127 bool isContinuousSend;
128 bool needsBAndAs;
129 bool isValid; // To differentiate between what I serialized, and offline data
130
131 static BitSize_t GetDataHeaderBitLength()
132 {
133 return BYTES_TO_BITS(GetDataHeaderByteLength());
134 }
135
136 static unsigned int GetDataHeaderByteLength()
137 {
138 //return 2 + 3 + sizeof(SLNet::TimeMS) + sizeof(float)*2;
139 return 2 + 3 +
140 #if INCLUDE_TIMESTAMP_WITH_DATAGRAMS==1
141 sizeof(RakNetTimeMS) +
142 #endif
143 sizeof(float)*1;
144 }
145
146 void Serialize(SLNet::BitStream *b)
147 {
148 // Not endian safe
149 // RakAssert(GetDataHeaderByteLength()==sizeof(DatagramHeaderFormat));
150 // b->WriteAlignedBytes((const unsigned char*) this, sizeof(DatagramHeaderFormat));
151 // return;
152
153 b->Write(true); // IsValid
154 if (isACK)
155 {
156 b->Write(true);
157 b->Write(hasBAndAS);
158 b->AlignWriteToByteBoundary();
159 #if INCLUDE_TIMESTAMP_WITH_DATAGRAMS==1
160 SLNet::TimeMS timeMSLow=(SLNet::TimeMS) sourceSystemTime&0xFFFFFFFF; b->Write(timeMSLow);
161 #endif
162 if (hasBAndAS)
163 {
164 // b->Write(B);
165 b->Write(AS);
166 }
167 }
168 else if (isNAK)
169 {
170 b->Write(false);
171 b->Write(true);
172 }
173 else
174 {
175 b->Write(false);
176 b->Write(false);
177 b->Write(isPacketPair);
178 b->Write(isContinuousSend);
179 b->Write(needsBAndAs);
180 b->AlignWriteToByteBoundary();
181 #if INCLUDE_TIMESTAMP_WITH_DATAGRAMS==1
182 SLNet::TimeMS timeMSLow=(SLNet::TimeMS) sourceSystemTime&0xFFFFFFFF; b->Write(timeMSLow);
183 #endif
184 b->Write(datagramNumber);
185 }
186 }
187 void Deserialize(SLNet::BitStream *b)
188 {
189 // Not endian safe
190 // b->ReadAlignedBytes((unsigned char*) this, sizeof(DatagramHeaderFormat));
191 // return;
192
193 b->Read(isValid);
194 b->Read(isACK);
195 if (isACK)
196 {
197 isNAK=false;
198 isPacketPair=false;
199 b->Read(hasBAndAS);
200 b->AlignReadToByteBoundary();
201 #if INCLUDE_TIMESTAMP_WITH_DATAGRAMS==1
202 SLNet::TimeMS timeMS; b->Read(timeMS); sourceSystemTime=(CCTimeType) timeMS;
203 #endif
204 if (hasBAndAS)
205 {
206 // b->Read(B);
207 b->Read(AS);
208 }
209 }
210 else
211 {
212 b->Read(isNAK);
213 if (isNAK)
214 {
215 isPacketPair=false;
216 }
217 else
218 {
219 b->Read(isPacketPair);
220 b->Read(isContinuousSend);
221 b->Read(needsBAndAs);
222 b->AlignReadToByteBoundary();
223 #if INCLUDE_TIMESTAMP_WITH_DATAGRAMS==1
224 SLNet::TimeMS timeMS; b->Read(timeMS); sourceSystemTime=(CCTimeType) timeMS;
225 #endif
226 b->Read(datagramNumber);
227 }
228 }
229 }
230 };
231
232 #ifdef _WIN32
233 //#define _DEBUG_LOGGER
234 #ifdef _DEBUG_LOGGER
235 #include "slikenet/WindowsIncludes.h"
236 #endif
237 #endif
238
239 //#define DEBUG_SPLIT_PACKET_PROBLEMS
240 #if defined (DEBUG_SPLIT_PACKET_PROBLEMS)
241 static int waitFlag=-1;
242 #endif
243
244 using namespace SLNet;
245
246 int SLNet::SplitPacketChannelComp( SplitPacketIdType const &key, SplitPacketChannel* const &data )
247 {
248 #if PREALLOCATE_LARGE_MESSAGES==1
249 if (key < data->returnedPacket->splitPacketId)
250 return -1;
251 if (key == data->returnedPacket->splitPacketId)
252 return 0;
253 #else
254 if (key < data->splitPacketList[0]->splitPacketId)
255 return -1;
256 if (key == data->splitPacketList[0]->splitPacketId)
257 return 0;
258 #endif
259 return 1;
260 }
261
262 // DEFINE_MULTILIST_PTR_TO_MEMBER_COMPARISONS( InternalPacket, SplitPacketIndexType, splitPacketIndex )
263 /*
264 bool operator<( const DataStructures::MLKeyRef<SplitPacketIndexType> &inputKey, const InternalPacket *cls )
265 {
266 return inputKey.Get() < cls->splitPacketIndex;
267 }
268 bool operator>( const DataStructures::MLKeyRef<SplitPacketIndexType> &inputKey, const InternalPacket *cls )
269 {
270 return inputKey.Get() > cls->splitPacketIndex;
271 }
272 bool operator==( const DataStructures::MLKeyRef<SplitPacketIndexType> &inputKey, const InternalPacket *cls )
273 {
274 return inputKey.Get() == cls->splitPacketIndex;
275 }
277 bool operator<( const DataStructures::MLKeyRef<InternalPacket *> &inputKey, const InternalPacket *cls )
278 {
279 return inputKey.Get()->splitPacketIndex < cls->splitPacketIndex;
280 }
281 bool operator>( const DataStructures::MLKeyRef<InternalPacket *> &inputKey, const InternalPacket *cls )
282 {
283 return inputKey.Get()->splitPacketIndex > cls->splitPacketIndex;
284 }
285 bool operator==( const DataStructures::MLKeyRef<InternalPacket *> &inputKey, const InternalPacket *cls )
286 {
287 return inputKey.Get()->splitPacketIndex == cls->splitPacketIndex;
288 }
289 */
290
291 int SplitPacketIndexComp( SplitPacketIndexType const &key, InternalPacket* const &data )
292 {
293 if (key < data->splitPacketIndex)
294 return -1;
295 if (key == data->splitPacketIndex)
296 return 0;
297 return 1;
298 }
299
300 //-------------------------------------------------------------------------------------------------------
301 // Constructor
302 //-------------------------------------------------------------------------------------------------------
303 // Add 21 to the default MTU so if we encrypt it can hold potentially 21 more bytes of extra data + padding.
304 ReliabilityLayer::ReliabilityLayer()
305 {
306
307 #ifdef _DEBUG
308 // Wait longer to disconnect in debug so I don't get disconnected while tracing
309 timeoutTime=30000;
310 #else
311 timeoutTime=10000;
312 #endif
313
314 #ifdef _DEBUG
315 minExtraPing=extraPingVariance=0;
316 packetloss=(double) minExtraPing;
317 #endif
318
319
320 #ifdef PRINT_TO_FILE_RELIABLE_ORDERED_TEST
321 if (fp==0 && 0)
322 {
323 fopen_s(&fp, "reliableorderedoutput.txt", "wt");
324 }
325 #endif
326
327 InitializeVariables();
328 //int i = sizeof(InternalPacket);
329 datagramHistoryMessagePool.SetPageSize(sizeof(MessageNumberNode)*128);
330 internalPacketPool.SetPageSize(sizeof(InternalPacket)*INTERNAL_PACKET_PAGE_SIZE);
331 refCountedDataPool.SetPageSize(sizeof(InternalPacketRefCountedData)*32);
332 }
333
334 //-------------------------------------------------------------------------------------------------------
335 // Destructor
336 //-------------------------------------------------------------------------------------------------------
337 ReliabilityLayer::~ReliabilityLayer()
338 {
339 FreeMemory( true ); // Free all memory immediately
340 }
341 //-------------------------------------------------------------------------------------------------------
342 // Resets the layer for reuse
343 //-------------------------------------------------------------------------------------------------------
344 void ReliabilityLayer::Reset( bool resetVariables, int MTUSize, bool _useSecurity )
345 {
346
347 FreeMemory( true ); // true because making a memory reset pending in the update cycle causes resets after reconnects. Instead, just call Reset from a single thread
348 if (resetVariables)
349 {
350 InitializeVariables();
351
352 #if LIBCAT_SECURITY==1
353 useSecurity = _useSecurity;
354
355 if (_useSecurity)
356 MTUSize -= cat::AuthenticatedEncryption::OVERHEAD_BYTES;
357 #else
358 (void) _useSecurity;
359 #endif // LIBCAT_SECURITY
360 congestionManager.Init(SLNet::GetTimeUS(), MTUSize - UDP_HEADER_SIZE);
361 }
362 }
363
364 //-------------------------------------------------------------------------------------------------------
365 // Set the time, in MS, to use before considering ourselves disconnected after not being able to deliver a reliable packet
366 //-------------------------------------------------------------------------------------------------------
367 void ReliabilityLayer::SetTimeoutTime(SLNet::TimeMS time )
368 {
369 timeoutTime=time;
370 }
371
372 //-------------------------------------------------------------------------------------------------------
373 // Returns the value passed to SetTimeoutTime. or the default if it was never called
374 //-------------------------------------------------------------------------------------------------------
375 SLNet::TimeMS ReliabilityLayer::GetTimeoutTime(void)
376 {
377 return timeoutTime;
378 }
379
380 //-------------------------------------------------------------------------------------------------------
381 // Initialize the variables
382 //-------------------------------------------------------------------------------------------------------
383 void ReliabilityLayer::InitializeVariables( void )
384 {
385 memset( orderedWriteIndex, 0, NUMBER_OF_ORDERED_STREAMS * sizeof(OrderingIndexType));
386 memset( sequencedWriteIndex, 0, NUMBER_OF_ORDERED_STREAMS * sizeof(OrderingIndexType) );
387 memset( orderedReadIndex, 0, NUMBER_OF_ORDERED_STREAMS * sizeof(OrderingIndexType) );
388 memset( highestSequencedReadIndex, 0, NUMBER_OF_ORDERED_STREAMS * sizeof(OrderingIndexType) );
389 memset( &statistics, 0, sizeof( statistics ) );
390 memset( &heapIndexOffsets, 0, sizeof( heapIndexOffsets ) );
391
392 statistics.connectionStartTime = SLNet::GetTimeUS();
393 splitPacketId = 0;
394 elapsedTimeSinceLastUpdate=0;
395 throughputCapCountdown=0;
396 sendReliableMessageNumberIndex = 0;
397 internalOrderIndex=0;
398 timeToNextUnreliableCull=0;
399 unreliableLinkedListHead=0;
400 lastUpdateTime= SLNet::GetTimeUS();
401 bandwidthExceededStatistic=false;
402 remoteSystemTime=0;
403 unreliableTimeout=0;
404 lastBpsClear=0;
405
406 // Disable packet pairs
407 countdownToNextPacketPair=15;
408
409 nextAllowedThroughputSample=0;
410 deadConnection = cheater = false;
411 timeOfLastContinualSend=0;
412
413 // timeResendQueueNonEmpty = 0;
414 timeLastDatagramArrived= SLNet::GetTimeMS();
415 // packetlossThisSample=false;
416 // backoffThisSample=0;
417 // packetlossThisSampleResendCount=0;
418 // lastPacketlossTime=0;
419 statistics.messagesInResendBuffer=0;
420 statistics.bytesInResendBuffer=0;
421
422 receivedPacketsBaseIndex=0;
423 resetReceivedPackets=true;
424 receivePacketCount=0;
425
426 // SetPing( 1000 );
427
428 timeBetweenPackets=STARTING_TIME_BETWEEN_PACKETS;
429
430 ackPingIndex=0;
431 ackPingSum=(CCTimeType)0;
432
433 nextSendTime=lastUpdateTime;
434 //nextLowestPingReset=(CCTimeType)0;
435 // continuousSend=false;
436
437 // histogramStart=(CCTimeType)0;
438 // histogramBitsSent=0;
439 unacknowledgedBytes=0;
440 resendLinkedListHead=0;
441 totalUserDataBytesAcked=0;
442
443 datagramHistoryPopCount=0;
444
445 InitHeapWeights();
446 for (int i=0; i < NUMBER_OF_PRIORITIES; i++)
447 {
448 statistics.messageInSendBuffer[i]=0;
449 statistics.bytesInSendBuffer[i]=0.0;
450 }
451
452 for (int i=0; i < RNS_PER_SECOND_METRICS_COUNT; i++)
453 {
454 bpsMetrics[i].Reset(_FILE_AND_LINE_);
455 }
456 }
457
458 //-------------------------------------------------------------------------------------------------------
459 // Frees all allocated memory
460 //-------------------------------------------------------------------------------------------------------
461 void ReliabilityLayer::FreeMemory( bool freeAllImmediately )
462 {
463 (void) freeAllImmediately;
464 FreeThreadSafeMemory();
465 }
466
467 void ReliabilityLayer::FreeThreadSafeMemory( void )
468 {
469 unsigned i,j;
470 InternalPacket *internalPacket;
471
472 ClearPacketsAndDatagrams();
473
474 for (i=0; i < splitPacketChannelList.Size(); i++)
475 {
476 for (j=0; j < splitPacketChannelList[i]->splitPacketList.Size(); j++)
477 {
478 FreeInternalPacketData(splitPacketChannelList[i]->splitPacketList[j], _FILE_AND_LINE_ );
479 ReleaseToInternalPacketPool( splitPacketChannelList[i]->splitPacketList[j] );
480 }
481 #if PREALLOCATE_LARGE_MESSAGES==1
482 if (splitPacketChannelList[i]->returnedPacket)
483 {
484 FreeInternalPacketData(splitPacketChannelList[i]->returnedPacket, __FILE__, __LINE__ );
485 ReleaseToInternalPacketPool( splitPacketChannelList[i]->returnedPacket );
486 }
487 #endif
488 SLNet::OP_DELETE(splitPacketChannelList[i], __FILE__, __LINE__);
489 }
490 splitPacketChannelList.Clear(false, _FILE_AND_LINE_);
491
492 while ( outputQueue.Size() > 0 )
493 {
494 internalPacket = outputQueue.Pop();
495 FreeInternalPacketData(internalPacket, _FILE_AND_LINE_ );
496 ReleaseToInternalPacketPool( internalPacket );
497 }
498
499 outputQueue.ClearAndForceAllocation( 32, _FILE_AND_LINE_ );
500
501 /*
502 for ( i = 0; i < orderingList.Size(); i++ )
503 {
504 if ( orderingList[ i ] )
505 {
506 DataStructures::LinkedList<InternalPacket*>* theList = orderingList[ i ];
507
508 if ( theList )
509 {
510 while ( theList->Size() )
511 {
512 internalPacket = orderingList[ i ]->Pop();
513 FreeInternalPacketData(internalPacket, _FILE_AND_LINE_ );
514 ReleaseToInternalPacketPool( internalPacket );
515 }
516
517 SLNet::OP_DELETE(theList, _FILE_AND_LINE_);
518 }
519 }
520 }
521
522 orderingList.Clear(false, _FILE_AND_LINE_);
523 */
524
525 for (i=0; i < NUMBER_OF_ORDERED_STREAMS; i++)
526 {
527 for (j=0; j < orderingHeaps[i].Size(); j++)
528 {
529 FreeInternalPacketData(orderingHeaps[i][j], _FILE_AND_LINE_ );
530 ReleaseToInternalPacketPool( orderingHeaps[i][j] );
531 }
532 orderingHeaps[i].Clear(true, _FILE_AND_LINE_);
533 }
534
535 //resendList.ForEachData(DeleteInternalPacket);
536 // resendTree.Clear(_FILE_AND_LINE_);
537 memset(resendBuffer, 0, sizeof(resendBuffer));
538 statistics.messagesInResendBuffer=0;
539 statistics.bytesInResendBuffer=0;
540
541 if (resendLinkedListHead)
542 {
543 InternalPacket *prev;
544 InternalPacket *iter = resendLinkedListHead;
545
546 for(;;)
547 {
548 if (iter->data)
549 FreeInternalPacketData(iter, _FILE_AND_LINE_ );
550 prev=iter;
551 iter=iter->resendNext;
552 if (iter==resendLinkedListHead)
553 {
554 ReleaseToInternalPacketPool(prev);
555 break;
556 }
557 ReleaseToInternalPacketPool(prev);
558 }
559 resendLinkedListHead=0;
560 }
561 unacknowledgedBytes=0;
562
563 // acknowlegements.Clear(_FILE_AND_LINE_);
564
565 for ( j=0 ; j < outgoingPacketBuffer.Size(); j++ )
566 {
567 if ( outgoingPacketBuffer[ j ]->data)
568 FreeInternalPacketData( outgoingPacketBuffer[ j ], _FILE_AND_LINE_ );
569 ReleaseToInternalPacketPool( outgoingPacketBuffer[ j ] );
570 }
571
572 outgoingPacketBuffer.Clear(true, _FILE_AND_LINE_);
573
574 #ifdef _DEBUG
575 for (i = 0; i < delayList.Size(); i++ )
576 SLNet::OP_DELETE(delayList[ i ], __FILE__, __LINE__);
577 delayList.Clear(__FILE__, __LINE__);
578 #endif
579
580 unreliableWithAckReceiptHistory.Clear(false, _FILE_AND_LINE_);
581
582 packetsToSendThisUpdate.Clear(false, _FILE_AND_LINE_);
583 packetsToSendThisUpdate.Preallocate(512, _FILE_AND_LINE_);
584 packetsToDeallocThisUpdate.Clear(false, _FILE_AND_LINE_);
585 packetsToDeallocThisUpdate.Preallocate(512, _FILE_AND_LINE_);
586 packetsToSendThisUpdateDatagramBoundaries.Clear(false, _FILE_AND_LINE_);
587 packetsToSendThisUpdateDatagramBoundaries.Preallocate(128, _FILE_AND_LINE_);
588 datagramSizesInBytes.Clear(false, _FILE_AND_LINE_);
589 datagramSizesInBytes.Preallocate(128, _FILE_AND_LINE_);
590
591 internalPacketPool.Clear(_FILE_AND_LINE_);
592
593 refCountedDataPool.Clear(_FILE_AND_LINE_);
594
595 /*
596 DataStructures::Page<DatagramSequenceNumberType, DatagramMessageIDList*, RESEND_TREE_ORDER> *cur = datagramMessageIDTree.GetListHead();
597 while (cur)
598 {
599 int treeIndex;
600 for (treeIndex=0; treeIndex < cur->size; treeIndex++)
601 ReleaseToDatagramMessageIDPool(cur->data[treeIndex]);
602 cur=cur->resendNext;
603 }
604 datagramMessageIDTree.Clear(_FILE_AND_LINE_);
605 datagramMessageIDPool.Clear(_FILE_AND_LINE_);
606 */
607
608 while (datagramHistory.Size())
609 {
610 RemoveFromDatagramHistory(datagramHistoryPopCount);
611 datagramHistory.Pop();
612 datagramHistoryPopCount++;
613 }
614 datagramHistoryMessagePool.Clear(_FILE_AND_LINE_);
615 datagramHistoryPopCount=0;
616
617 acknowlegements.Clear();
618 NAKs.Clear();
619
620 unreliableLinkedListHead=0;
621 }
622
623 //-------------------------------------------------------------------------------------------------------
624 // Packets are read directly from the socket layer and skip the reliability
625 //layer because unconnected players do not use the reliability layer
626 // This function takes packet data after a player has been confirmed as
627 //connected. The game should not use that data directly
628 // because some data is used internally, such as packet acknowledgment and
629 //split packets
630 //-------------------------------------------------------------------------------------------------------
631 bool ReliabilityLayer::HandleSocketReceiveFromConnectedPlayer(
632 const char *buffer, unsigned int length, SystemAddress &systemAddress, DataStructures::List<PluginInterface2*> &messageHandlerList, int MTUSize,
633 RakNetSocket2 *s, RakNetRandom *rnr, CCTimeType timeRead,
634 BitStream &updateBitStream)
635 {
636 #ifdef _DEBUG
637 RakAssert( !( buffer == 0 ) );
638 #endif
639
640 #if CC_TIME_TYPE_BYTES==4
641 timeRead/=1000;
642 #endif
643
644
645 bpsMetrics[(int) ACTUAL_BYTES_RECEIVED].Push1(timeRead,length);
646
647 (void) MTUSize;
648
649 if ( length <= 2 || buffer == 0 ) // Length of 1 is a connection request resend that we just ignore
650 {
651 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
652 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerNotification("length <= 2 || buffer == 0", BYTES_TO_BITS(length), systemAddress, true);
653 return true;
654 }
655
656 timeLastDatagramArrived= SLNet::GetTimeMS();
657
658 // CCTimeType time;
659 // bool indexFound;
660 // int count, size;
661 DatagramSequenceNumberType holeCount;
662 unsigned i;
663
664 #if LIBCAT_SECURITY==1
665 if (useSecurity)
666 {
667 unsigned int received = length;
668
669 if (!auth_enc.Decrypt((cat::u8*)buffer, received))
670 return false;
671
672 length = received;
673 }
674 #endif
675
676 SLNet::BitStream socketData( (unsigned char*) buffer, length, false ); // Convert the incoming data to a bitstream for easy parsing
677 // time = SLNet::GetTimeUS();
678
679 // Set to the current time if it is not zero, and we get incoming data
680 // if (timeResendQueueNonEmpty!=0)
681 // timeResendQueueNonEmpty=timeRead;
682
683 DatagramHeaderFormat dhf;
684 dhf.Deserialize(&socketData);
685 if (dhf.isValid==false)
686 {
687 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
688 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerNotification("dhf.isValid==false", BYTES_TO_BITS(length), systemAddress, true);
689
690 return true;
691 }
692 if (dhf.isACK)
693 {
694 DatagramSequenceNumberType datagramNumber;
695 // datagramNumber=dhf.datagramNumber;
696
697 #if INCLUDE_TIMESTAMP_WITH_DATAGRAMS==1
698 SLNet::TimeMS timeMSLow=(SLNet::TimeMS) timeRead&0xFFFFFFFF;
699 CCTimeType rtt = timeMSLow-dhf.sourceSystemTime;
700 #if CC_TIME_TYPE_BYTES==4
701 if (rtt > 10000)
702 #else
703 if (rtt > 10000000)
704 #endif
705 {
706 // Sanity check. This could happen due to type overflow, especially since I only send the low 4 bytes to reduce bandwidth
707 rtt=(CCTimeType) congestionManager.GetRTT();
708 }
709 // RakAssert(rtt < 500000);
710 // printf("%i ", (SLNet::TimeMS)(rtt/1000));
711 ackPing=rtt;
712 #endif
713
714 #ifdef _DEBUG
715 if (dhf.hasBAndAS==false)
716 {
717 // dhf.B=0;
718 dhf.AS=0;
719 }
720 #endif
721 // congestionManager.OnAck(timeRead, rtt, dhf.hasBAndAS, dhf.B, dhf.AS, totalUserDataBytesAcked );
722
723
724 incomingAcks.Clear();
725 if (incomingAcks.Deserialize(&socketData)==false)
726 {
727 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
728 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerNotification("incomingAcks.Deserialize failed", BYTES_TO_BITS(length), systemAddress, true);
729
730 return false;
731 }
732
733 unsigned int k = 0;
734 while (k < unreliableWithAckReceiptHistory.Size()) {
735 if (incomingAcks.IsWithinRange(unreliableWithAckReceiptHistory[k].datagramNumber)) {
736 InternalPacket *ackReceipt = AllocateFromInternalPacketPool();
737 AllocInternalPacketData(ackReceipt, 5, false, _FILE_AND_LINE_);
738 ackReceipt->dataBitLength = BYTES_TO_BITS(5);
739 ackReceipt->data[0] = (MessageID)ID_SND_RECEIPT_ACKED;
740 memcpy(ackReceipt->data + sizeof(MessageID), &unreliableWithAckReceiptHistory[k].sendReceiptSerial, sizeof(uint32_t));
741 outputQueue.Push(ackReceipt, _FILE_AND_LINE_);
742
743 // Remove, swap with last
744 unreliableWithAckReceiptHistory.RemoveAtIndex(k);
745 } else {
746 k++;
747 }
748 }
749
750 // early out, if we've got no outstanding datagramHistory entries
751 if (datagramHistory.IsEmpty()) {
752 receivePacketCount++;
753 return true;
754 }
755
756 for (i = 0; i < incomingAcks.ranges.Size(); i++) {
757 // note: minIndex is ensured to be always <= maxIndex - otherwise Deserialize() would have failed
758 RakAssert(incomingAcks.ranges[i].minIndex <= incomingAcks.ranges[i].maxIndex);
759
760 if (incomingAcks.ranges[i].maxIndex == (uint24_t)(0xFFFFFFFF)) {
761 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
762 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerNotification("incomingAcks maxIndex is max value", BYTES_TO_BITS(length), systemAddress, true);
763 return false;
764 }
765
766 for (datagramNumber = incomingAcks.ranges[i].minIndex; datagramNumber <= incomingAcks.ranges[i].maxIndex; datagramNumber++) {
767 const DatagramSequenceNumberType offsetIntoList = datagramNumber - datagramHistoryPopCount;
768 if (offsetIntoList >= datagramHistory.Size()) {
769 // reached the end of the datagramHistory list - hence, we are done
770 receivePacketCount++;
771 return true;
772 }
773
774 CCTimeType whenSent;
775 MessageNumberNode *messageNumberNode = GetMessageNumberNodeByDatagramIndex(datagramNumber, &whenSent);
776 if (messageNumberNode)
777 {
778 // printf("%p Got ack for %i\n", this, datagramNumber.val);
779 #if INCLUDE_TIMESTAMP_WITH_DATAGRAMS==1
780 congestionManager.OnAck(timeRead, rtt, dhf.hasBAndAS, 0, dhf.AS, totalUserDataBytesAcked, bandwidthExceededStatistic, datagramNumber );
781 #else
782 CCTimeType ping;
783 if (timeRead>whenSent)
784 ping=timeRead-whenSent;
785 else
786 ping=0;
787 congestionManager.OnAck(timeRead, ping, dhf.hasBAndAS, 0, dhf.AS, totalUserDataBytesAcked, bandwidthExceededStatistic, datagramNumber );
788 #endif
789 while (messageNumberNode)
790 {
791 // TESTING1
792 // printf("Remove %i on ack for datagramNumber=%i.\n", messageNumberNode->messageNumber.val, datagramNumber.val);
793
794 RemovePacketFromResendListAndDeleteOlderReliableSequenced( messageNumberNode->messageNumber, timeRead, messageHandlerList, systemAddress );
795 messageNumberNode=messageNumberNode->next;
796 }
797
798 RemoveFromDatagramHistory(datagramNumber);
799 }
800 // else if (isReliable)
801 // {
802 // // Previously used slot, rather than empty unreliable slot
803 // printf("%p Ack %i is duplicate\n", this, datagramNumber.val);
804 //
805 // congestionManager.OnDuplicateAck(timeRead, datagramNumber);
806 // }
807 }
808 }
809 }
810 else if (dhf.isNAK)
811 {
812 // early out, if we've got no outstanding datagramHistory entries
813 if (datagramHistory.IsEmpty()) {
814 receivePacketCount++;
815 return true;
816 }
817
818 DatagramSequenceNumberType messageNumber;
819 DataStructures::RangeList<DatagramSequenceNumberType> incomingNAKs;
820 if (incomingNAKs.Deserialize(&socketData)==false)
821 {
822 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
823 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerNotification("incomingNAKs.Deserialize failed", BYTES_TO_BITS(length), systemAddress, true);
824
825 return false;
826 }
827 for (i=0; i<incomingNAKs.ranges.Size();i++)
828 {
829 // note: minIndex is ensured to be always <= maxIndex - otherwise Deserialize() would have failed
830 RakAssert(incomingNAKs.ranges[i].minIndex <= incomingNAKs.ranges[i].maxIndex);
831
832 if (incomingNAKs.ranges[i].maxIndex == (uint24_t)(0xFFFFFFFF)) {
833 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
834 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerNotification("incomingNAKs maxIndex is max value", BYTES_TO_BITS(length), systemAddress, true);
835
836 return false;
837 }
838 // Sanity check
839 //RakAssert(incomingNAKs.ranges[i].maxIndex.val-incomingNAKs.ranges[i].minIndex.val<1000);
840 for (messageNumber = incomingNAKs.ranges[i].minIndex; messageNumber <= incomingNAKs.ranges[i].maxIndex; messageNumber++)
841 {
842 congestionManager.OnNAK(timeRead, messageNumber);
843
844 // REMOVEME
845 // printf("%p NAK %i\n", this, dhf.datagramNumber.val);
846
847
848 const DatagramSequenceNumberType offsetIntoList = messageNumber - datagramHistoryPopCount;
849 if (offsetIntoList >= datagramHistory.Size()) {
850 // reached the end of the datagramHistory list - hence, we are done
851 receivePacketCount++;
852 return true;
853 }
854
855 CCTimeType timeSent;
856 MessageNumberNode *messageNumberNode = GetMessageNumberNodeByDatagramIndex(messageNumber, &timeSent);
857 while (messageNumberNode)
858 {
859 // Update timers so resends occur immediately
860 InternalPacket *internalPacket = resendBuffer[messageNumberNode->messageNumber & (uint32_t) RESEND_BUFFER_ARRAY_MASK];
861 if (internalPacket)
862 {
863 if (internalPacket->nextActionTime!=0)
864 {
865 internalPacket->nextActionTime=timeRead;
866 }
867 }
868
869 messageNumberNode=messageNumberNode->next;
870 }
871 }
872 }
873 }
874 else
875 {
876 uint32_t skippedMessageCount;
877 if (!congestionManager.OnGotPacket(dhf.datagramNumber, dhf.isContinuousSend, timeRead, length, &skippedMessageCount))
878 {
879 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
880 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerNotification("congestionManager.OnGotPacket failed", BYTES_TO_BITS(length), systemAddress, true);
881
882 return true;
883 }
884 if (dhf.isPacketPair)
885 congestionManager.OnGotPacketPair(dhf.datagramNumber, length, timeRead);
886
887 DatagramHeaderFormat dhfNAK;
888 dhfNAK.isNAK=true;
889 uint32_t skippedMessageOffset;
890 for (skippedMessageOffset=skippedMessageCount; skippedMessageOffset > 0; skippedMessageOffset--)
891 {
892 NAKs.Insert(dhf.datagramNumber-skippedMessageOffset);
893 }
894 remoteSystemNeedsBAndAS=dhf.needsBAndAs;
895
896 // Ack dhf.datagramNumber
897 // Ack even unreliable messages for congestion control, just don't resend them on no ack
898 #if INCLUDE_TIMESTAMP_WITH_DATAGRAMS==1
899 SendAcknowledgementPacket( dhf.datagramNumber, dhf.sourceSystemTime);
900 #else
901 SendAcknowledgementPacket( dhf.datagramNumber, 0);
902 #endif
903
904 InternalPacket* internalPacket = CreateInternalPacketFromBitStream( &socketData, timeRead );
905 if (internalPacket==0)
906 {
907 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
908 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerNotification("CreateInternalPacketFromBitStream failed", BYTES_TO_BITS(length), systemAddress, true);
909
910 return true;
911 }
912
913 while ( internalPacket )
914 {
915 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
916 {
917 #if CC_TIME_TYPE_BYTES==4
918 messageHandlerList[messageHandlerIndex]->OnInternalPacket(internalPacket, receivePacketCount, systemAddress, timeRead, false);
919 #else
920 messageHandlerList[messageHandlerIndex]->OnInternalPacket(internalPacket, receivePacketCount, systemAddress, (SLNet::TimeMS)(timeRead/(CCTimeType)1000), false);
921 #endif
922 }
923
924 {
925
926 // resetReceivedPackets is set from a non-threadsafe function.
927 // We do the actual reset in this function so the data is not modified by multiple threads
928 if (resetReceivedPackets)
929 {
930 hasReceivedPacketQueue.ClearAndForceAllocation(DEFAULT_HAS_RECEIVED_PACKET_QUEUE_SIZE, _FILE_AND_LINE_);
931 receivedPacketsBaseIndex=0;
932 resetReceivedPackets=false;
933 }
934
935 // Check for corrupt orderingChannel
936 if (
937 internalPacket->reliability == RELIABLE_SEQUENCED ||
938 internalPacket->reliability == UNRELIABLE_SEQUENCED ||
939 internalPacket->reliability == RELIABLE_ORDERED
940 )
941 {
942 if ( internalPacket->orderingChannel >= NUMBER_OF_ORDERED_STREAMS )
943 {
944 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
945 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerNotification("internalPacket->orderingChannel >= NUMBER_OF_ORDERED_STREAMS", BYTES_TO_BITS(length), systemAddress, true);
946
947 bpsMetrics[(int) USER_MESSAGE_BYTES_RECEIVED_IGNORED].Push1(timeRead,BITS_TO_BYTES(internalPacket->dataBitLength));
948
949 FreeInternalPacketData(internalPacket, _FILE_AND_LINE_ );
950 ReleaseToInternalPacketPool( internalPacket );
951 goto CONTINUE_SOCKET_DATA_PARSE_LOOP;
952 }
953 }
954
955 // 8/12/09 was previously not checking if the message was reliable. However, on packetloss this would mean you'd eventually exceed the
956 // hole count because unreliable messages were never resent, and you'd stop getting messages
957 if (internalPacket->reliability == RELIABLE || internalPacket->reliability == RELIABLE_SEQUENCED || internalPacket->reliability == RELIABLE_ORDERED )
958 {
959 // If the following conditional is true then this either a duplicate packet
960 // or an older out of order packet
961 // The subtraction unsigned overflow is intentional
962 holeCount = (DatagramSequenceNumberType)(internalPacket->reliableMessageNumber-receivedPacketsBaseIndex);
963 const DatagramSequenceNumberType typeRange = (DatagramSequenceNumberType)(const uint32_t)-1;
964
965 // TESTING1
966 // printf("waiting on reliableMessageNumber=%i holeCount=%i datagramNumber=%i\n", receivedPacketsBaseIndex.val, holeCount.val, dhf.datagramNumber.val);
967
968 if (holeCount==(DatagramSequenceNumberType) 0)
969 {
970 // Got what we were expecting
971 if (hasReceivedPacketQueue.Size())
972 hasReceivedPacketQueue.Pop();
973 ++receivedPacketsBaseIndex;
974 }
975 else if (holeCount > typeRange/(DatagramSequenceNumberType) 2)
976 {
977 bpsMetrics[(int) USER_MESSAGE_BYTES_RECEIVED_IGNORED].Push1(timeRead,BITS_TO_BYTES(internalPacket->dataBitLength));
978
979 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
980 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerNotification("holeCount > typeRange/(DatagramSequenceNumberType) 2", BYTES_TO_BITS(length), systemAddress, false);
981
982 // Duplicate packet
983 FreeInternalPacketData(internalPacket, _FILE_AND_LINE_ );
984 ReleaseToInternalPacketPool( internalPacket );
985
986 goto CONTINUE_SOCKET_DATA_PARSE_LOOP;
987 }
988 else if ((unsigned int) holeCount<hasReceivedPacketQueue.Size())
989 {
990 // Got a higher count out of order packet that was missing in the sequence or we already got
991 if (hasReceivedPacketQueue[holeCount]!=false) // non-zero means this is a hole
992 {
993 #ifdef LOG_TRIVIAL_NOTIFICATIONS
994 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
995 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerNotification("Higher count pushed to hasReceivedPacketQueue", BYTES_TO_BITS(length), systemAddress, false);
996 #endif
997
998 // Fill in the hole
999 hasReceivedPacketQueue[holeCount]=false; // We got the packet at holeCount
1000 }
1001 else
1002 {
1003 bpsMetrics[(int) USER_MESSAGE_BYTES_RECEIVED_IGNORED].Push1(timeRead,BITS_TO_BYTES(internalPacket->dataBitLength));
1004
1005 #ifdef LOG_TRIVIAL_NOTIFICATIONS
1006 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
1007 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerNotification("Duplicate packet ignored", BYTES_TO_BITS(length), systemAddress, false);
1008 #endif
1009
1010 // Duplicate packet
1011 FreeInternalPacketData(internalPacket, _FILE_AND_LINE_ );
1012 ReleaseToInternalPacketPool( internalPacket );
1013
1014 goto CONTINUE_SOCKET_DATA_PARSE_LOOP;
1015 }
1016 }
1017 else // holeCount>=receivedPackets.Size()
1018 {
1019 if (holeCount > (DatagramSequenceNumberType) 1000000)
1020 {
1021 RakAssert("Hole count too high. See ReliabilityLayer.h" && 0);
1022
1023 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
1024 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerNotification("holeCount > 1000000", BYTES_TO_BITS(length), systemAddress, true);
1025
1026 bpsMetrics[(int) USER_MESSAGE_BYTES_RECEIVED_IGNORED].Push1(timeRead,BITS_TO_BYTES(internalPacket->dataBitLength));
1027
1028 // Would crash due to out of memory!
1029 FreeInternalPacketData(internalPacket, _FILE_AND_LINE_ );
1030 ReleaseToInternalPacketPool( internalPacket );
1031
1032 goto CONTINUE_SOCKET_DATA_PARSE_LOOP;
1033 }
1034
1035 #ifdef LOG_TRIVIAL_NOTIFICATIONS
1036 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
1037 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerNotification("Adding to hasReceivedPacketQueue later ordered message", BYTES_TO_BITS(length), systemAddress, false);
1038 #endif
1039
1040 // Fix - sending on a higher priority gives us a very very high received packets base index if we formerly had pre-split a lot of messages and
1041 // used that as the message number. Because of this, a lot of time is spent in this linear loop and the timeout time expires because not
1042 // all of the message is sent in time.
1043 // Fixed by late assigning message IDs on the sender
1044
1045 // Add 0 times to the queue until (reliableMessageNumber - baseIndex) < queue size.
1046 while ((unsigned int)(holeCount) > hasReceivedPacketQueue.Size())
1047 hasReceivedPacketQueue.Push(true, _FILE_AND_LINE_ ); // time+(CCTimeType)60 * (CCTimeType)1000 * (CCTimeType)1000); // Didn't get this packet - set the time to give up waiting
1048 hasReceivedPacketQueue.Push(false, _FILE_AND_LINE_ ); // Got the packet
1049 #ifdef _DEBUG
1050 // If this assert hits then DatagramSequenceNumberType has overflowed
1051 RakAssert(hasReceivedPacketQueue.Size() < (unsigned int)((DatagramSequenceNumberType)(const uint32_t)(-1)));
1052 #endif
1053 }
1054
1055 while ( hasReceivedPacketQueue.Size()>0 && hasReceivedPacketQueue.Peek()==false )
1056 {
1057 hasReceivedPacketQueue.Pop();
1058 ++receivedPacketsBaseIndex;
1059 }
1060 }
1061
1062 // If the allocated buffer is > DEFAULT_HAS_RECEIVED_PACKET_QUEUE_SIZE and it is 3x greater than the number of elements actually being used
1063 if (hasReceivedPacketQueue.AllocationSize() > (unsigned int) DEFAULT_HAS_RECEIVED_PACKET_QUEUE_SIZE && hasReceivedPacketQueue.AllocationSize() > hasReceivedPacketQueue.Size() * 3)
1064 hasReceivedPacketQueue.Compress(_FILE_AND_LINE_);
1065
1066
1067 /*
1068 if ( internalPacket->reliability == RELIABLE_SEQUENCED || internalPacket->reliability == UNRELIABLE_SEQUENCED )
1069 {
1070 #ifdef _DEBUG
1071 RakAssert( internalPacket->orderingChannel < NUMBER_OF_ORDERED_STREAMS );
1072 #endif
1073
1074 if ( internalPacket->orderingChannel >= NUMBER_OF_ORDERED_STREAMS )
1075 {
1076
1077 FreeInternalPacketData(internalPacket, _FILE_AND_LINE_ );
1078 ReleaseToInternalPacketPool( internalPacket );
1079
1080 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
1081 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerNotification("internalPacket->orderingChannel >= NUMBER_OF_ORDERED_STREAMS", BYTES_TO_BITS(length), systemAddress);
1082
1083 bpsMetrics[(int) USER_MESSAGE_BYTES_RECEIVED_IGNORED].Push1(timeRead,BITS_TO_BYTES(internalPacket->dataBitLength));
1084
1085 goto CONTINUE_SOCKET_DATA_PARSE_LOOP;
1086 }
1087
1088 if ( IsOlderOrderedPacket( internalPacket->orderingIndex, waitingForSequencedPacketReadIndex[ internalPacket->orderingChannel ] ) == false )
1089 {
1090 // Is this a split packet?
1091 if ( internalPacket->splitPacketCount > 0 )
1092 {
1093 // Generate the split
1094 // Verify some parameters to make sure we don't get junk data
1095
1096
1097 // Check for a rebuilt packet
1098 InsertIntoSplitPacketList( internalPacket, timeRead );
1099 bpsMetrics[(int) USER_MESSAGE_BYTES_RECEIVED_PROCESSED].Push1(timeRead,BITS_TO_BYTES(internalPacket->dataBitLength));
1100
1101 // Sequenced
1102 internalPacket = BuildPacketFromSplitPacketList( internalPacket->splitPacketId, timeRead,
1103 s, systemAddress, rnr, remotePortRakNetWasStartedOn_PS3, extraSocketOptions);
1104
1105 if ( internalPacket )
1106 {
1107 // Update our index to the newest packet
1108 waitingForSequencedPacketReadIndex[ internalPacket->orderingChannel ] = internalPacket->orderingIndex + (OrderingIndexType)1;
1109
1110 // If there is a rebuilt packet, add it to the output queue
1111 outputQueue.Push( internalPacket, _FILE_AND_LINE_ );
1112 internalPacket = 0;
1113 }
1114
1115 // else don't have all the parts yet
1116 }
1117 else
1118 {
1119 // Update our index to the newest packet
1120 waitingForSequencedPacketReadIndex[ internalPacket->orderingChannel ] = internalPacket->orderingIndex + (OrderingIndexType)1;
1121
1122 // Not a split packet. Add the packet to the output queue
1123 bpsMetrics[(int) USER_MESSAGE_BYTES_RECEIVED_PROCESSED].Push1(timeRead,BITS_TO_BYTES(internalPacket->dataBitLength));
1124 outputQueue.Push( internalPacket, _FILE_AND_LINE_ );
1125 internalPacket = 0;
1126 }
1127 }
1128 else
1129 {
1130 // Older sequenced packet. Discard it
1131 FreeInternalPacketData(internalPacket, _FILE_AND_LINE_ );
1132 ReleaseToInternalPacketPool( internalPacket );
1133
1134 bpsMetrics[(int) USER_MESSAGE_BYTES_RECEIVED_IGNORED].Push1(timeRead,BITS_TO_BYTES(internalPacket->dataBitLength));
1135
1136 }
1137
1138 goto CONTINUE_SOCKET_DATA_PARSE_LOOP;
1139 }
1140
1141 // Is this an unsequenced split packet?
1142 if ( internalPacket->splitPacketCount > 0 )
1143 {
1144 // Check for a rebuilt packet
1145 if ( internalPacket->reliability != RELIABLE_ORDERED )
1146 internalPacket->orderingChannel = 255; // Use 255 to designate not sequenced and not ordered
1147
1148 InsertIntoSplitPacketList( internalPacket, timeRead );
1149
1150 internalPacket = BuildPacketFromSplitPacketList( internalPacket->splitPacketId, timeRead,
1151 s, systemAddress, rnr, remotePortRakNetWasStartedOn_PS3, extraSocketOptions);
1152
1153 if ( internalPacket == 0 )
1154 {
1155
1156 // Don't have all the parts yet
1157 goto CONTINUE_SOCKET_DATA_PARSE_LOOP;
1158 }
1159 }
1160 */
1161
1162 /*
1163 if ( internalPacket->reliability == RELIABLE_ORDERED )
1164 {
1165 #ifdef _DEBUG
1166 RakAssert( internalPacket->orderingChannel < NUMBER_OF_ORDERED_STREAMS );
1167 #endif
1168
1169 if ( internalPacket->orderingChannel >= NUMBER_OF_ORDERED_STREAMS )
1170 {
1171 // Invalid packet
1172 FreeInternalPacketData(internalPacket, _FILE_AND_LINE_ );
1173 ReleaseToInternalPacketPool( internalPacket );
1174
1175 bpsMetrics[(int) USER_MESSAGE_BYTES_RECEIVED_IGNORED].Push1(timeRead,BITS_TO_BYTES(internalPacket->dataBitLength));
1176
1177 goto CONTINUE_SOCKET_DATA_PARSE_LOOP;
1178 }
1179
1180 bpsMetrics[(int) USER_MESSAGE_BYTES_RECEIVED_PROCESSED].Push1(timeRead,BITS_TO_BYTES(internalPacket->dataBitLength));
1181
1182 if ( waitingForOrderedPacketReadIndex[ internalPacket->orderingChannel ] == internalPacket->orderingIndex )
1183 {
1184 // Get the list to hold ordered packets for this stream
1185 DataStructures::LinkedList<InternalPacket*> *orderingListAtOrderingStream;
1186 unsigned char orderingChannelCopy = internalPacket->orderingChannel;
1187
1188 // Push the packet for the user to read
1189 outputQueue.Push( internalPacket, _FILE_AND_LINE_ );
1190 internalPacket = 0; // Don't reference this any longer since other threads access it
1191
1192 // Wait for the resendNext ordered packet in sequence
1193 waitingForOrderedPacketReadIndex[ orderingChannelCopy ] ++; // This wraps
1194
1195 orderingListAtOrderingStream = GetOrderingListAtOrderingStream( orderingChannelCopy );
1196
1197 if ( orderingListAtOrderingStream != 0)
1198 {
1199 while ( orderingListAtOrderingStream->Size() > 0 )
1200 {
1201 // Cycle through the list until nothing is found
1202 orderingListAtOrderingStream->Beginning();
1203 indexFound=false;
1204 size=orderingListAtOrderingStream->Size();
1205 count=0;
1206
1207 while (count++ < size)
1208 {
1209 if ( orderingListAtOrderingStream->Peek()->orderingIndex == waitingForOrderedPacketReadIndex[ orderingChannelCopy ] )
1210 {
1211 outputQueue.Push( orderingListAtOrderingStream->Pop(), _FILE_AND_LINE_ );
1212 waitingForOrderedPacketReadIndex[ orderingChannelCopy ]++;
1213 indexFound=true;
1214 }
1215 else
1216 (*orderingListAtOrderingStream)++;
1217 }
1218
1219 if (indexFound==false)
1220 break;
1221 }
1222 }
1223 internalPacket = 0;
1224 }
1225 else
1226 {
1227 // This is a newer ordered packet than we are waiting for. Store it for future use
1228 AddToOrderingList( internalPacket );
1229 }
1230
1231
1232 goto CONTINUE_SOCKET_DATA_PARSE_LOOP;
1233 }
1234 */
1235
1236 // Is this a split packet? If so then reassemble
1237 if ( internalPacket->splitPacketCount > 0 )
1238 {
1239 // Check for a rebuilt packet
1240 if ( internalPacket->reliability != RELIABLE_ORDERED && internalPacket->reliability!=RELIABLE_SEQUENCED && internalPacket->reliability!=UNRELIABLE_SEQUENCED)
1241 internalPacket->orderingChannel = 255; // Use 255 to designate not sequenced and not ordered
1242
1243 InsertIntoSplitPacketList( internalPacket, timeRead );
1244
1245 internalPacket = BuildPacketFromSplitPacketList( internalPacket->splitPacketId, timeRead,
1246 s, systemAddress, rnr, updateBitStream);
1247
1248 if ( internalPacket == 0 )
1249 {
1250 #ifdef LOG_TRIVIAL_NOTIFICATIONS
1251 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
1252 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerNotification("BuildPacketFromSplitPacketList did not return anything.", BYTES_TO_BITS(length), systemAddress, false);
1253 #endif
1254
1255 // Don't have all the parts yet
1256 goto CONTINUE_SOCKET_DATA_PARSE_LOOP;
1257 }
1258 }
1259
1260 #ifdef PRINT_TO_FILE_RELIABLE_ORDERED_TEST
1261 unsigned char packetId;
1262 char *type="UNDEFINED";
1263 #endif
1264 if (internalPacket->reliability == RELIABLE_SEQUENCED ||
1265 internalPacket->reliability == UNRELIABLE_SEQUENCED ||
1266 internalPacket->reliability == RELIABLE_ORDERED)
1267 {
1268 #ifdef PRINT_TO_FILE_RELIABLE_ORDERED_TEST
1269
1270 // ___________________
1271 BitStream bitStream(internalPacket->data, BITS_TO_BYTES(internalPacket->dataBitLength), false);
1272 unsigned int receivedPacketNumber;
1273 SLNet::Time receivedTime;
1274 unsigned char streamNumber;
1275 PacketReliability reliability;
1276 // ___________________
1277
1278
1279 bitStream.IgnoreBits(8); // Ignore ID_TIMESTAMP
1280 bitStream.Read(receivedTime);
1281 bitStream.Read(packetId);
1282 bitStream.Read(receivedPacketNumber);
1283 bitStream.Read(streamNumber);
1284 bitStream.Read(reliability);
1285 if (packetId==ID_USER_PACKET_ENUM+1)
1286 {
1287
1288 if (reliability==UNRELIABLE_SEQUENCED)
1289 type="UNRELIABLE_SEQUENCED";
1290 else if (reliability==RELIABLE_ORDERED)
1291 type="RELIABLE_ORDERED";
1292 else
1293 type="RELIABLE_SEQUENCED";
1294 }
1295 // ___________________
1296 #endif
1297
1298
1299 if (internalPacket->orderingIndex==orderedReadIndex[internalPacket->orderingChannel])
1300 {
1301 // Has current ordering index
1302 if (internalPacket->reliability == RELIABLE_SEQUENCED ||
1303 internalPacket->reliability == UNRELIABLE_SEQUENCED)
1304 {
1305 // Is sequenced
1306 if (IsOlderOrderedPacket(internalPacket->sequencingIndex,highestSequencedReadIndex[internalPacket->orderingChannel])==false)
1307 {
1308 // Expected or highest known value
1309
1310 #ifdef PRINT_TO_FILE_RELIABLE_ORDERED_TEST
1311 if (packetId==ID_USER_PACKET_ENUM+1 && fp)
1312 {
1313 fprintf(fp, "Returning %i, %s by fallthrough. OI=%i. SI=%i.\n", receivedPacketNumber, type, internalPacket->orderingIndex.val, internalPacket->sequencingIndex);
1314 fflush(fp);
1315 }
1316
1317 if (packetId==ID_USER_PACKET_ENUM+1)
1318 {
1319 if (receivedPacketNumber<packetNumber)
1320 {
1321 if (fp)
1322 {
1323 fprintf(fp, "Out of order packet from fallthrough! Expecting %i got %i\n", receivedPacketNumber, packetNumber);
1324 fflush(fp);
1325 }
1326 }
1327 packetNumber=receivedPacketNumber+1;
1328 }
1329 #endif
1330 // Update highest sequence
1331 // 6/26/2012 - Did not have the +1 in the next statement
1332 // Means a duplicated RELIABLE_SEQUENCED or UNRELIABLE_SEQUENCED packet would be returned to the user
1333 highestSequencedReadIndex[internalPacket->orderingChannel] = internalPacket->sequencingIndex+(OrderingIndexType)1;
1334
1335 // Fallthrough, returned to user below
1336 }
1337 else
1338 {
1339 #ifdef PRINT_TO_FILE_RELIABLE_ORDERED_TEST
1340 if (packetId==ID_USER_PACKET_ENUM+1 && fp)
1341 {
1342 fprintf(fp, "Discarding %i, %s late sequenced. OI=%i. SI=%i.\n", receivedPacketNumber, type, internalPacket->orderingIndex.val, internalPacket->sequencingIndex);
1343 fflush(fp);
1344 }
1345 #endif
1346
1347 #ifdef LOG_TRIVIAL_NOTIFICATIONS
1348 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
1349 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerNotification("Sequenced rejected: lower than highest known value", BYTES_TO_BITS(length), systemAddress, false);
1350 #endif
1351
1352 // Lower than highest known value
1353 FreeInternalPacketData(internalPacket, _FILE_AND_LINE_ );
1354 ReleaseToInternalPacketPool( internalPacket );
1355
1356 goto CONTINUE_SOCKET_DATA_PARSE_LOOP;
1357 }
1358 }
1359 else
1360 {
1361 // Push to output buffer immediately
1362 bpsMetrics[(int) USER_MESSAGE_BYTES_RECEIVED_PROCESSED].Push1(timeRead,BITS_TO_BYTES(internalPacket->dataBitLength));
1363 outputQueue.Push( internalPacket, _FILE_AND_LINE_ );
1364
1365 #ifdef PRINT_TO_FILE_RELIABLE_ORDERED_TEST
1366 if (packetId==ID_USER_PACKET_ENUM+1 && fp)
1367 {
1368 fprintf(fp, "outputting immediate %i, %s. OI=%i. SI=%i.", receivedPacketNumber, type, internalPacket->orderingIndex.val, internalPacket->sequencingIndex);
1369 if (orderingHeaps[internalPacket->orderingChannel].Size()==0)
1370 fprintf(fp, "heap empty\n");
1371 else
1372 fprintf(fp, "heap head=%i\n", orderingHeaps[internalPacket->orderingChannel].Peek()->orderingIndex.val);
1373
1374 if (receivedPacketNumber<packetNumber)
1375 {
1376 if (packetId==ID_USER_PACKET_ENUM+1 && fp)
1377 {
1378 fprintf(fp, "Out of order packet arrived! Expecting %i got %i\n", receivedPacketNumber, packetNumber);
1379 fflush(fp);
1380 }
1381 }
1382 packetNumber=receivedPacketNumber+1;
1383
1384 fflush(fp);
1385 }
1386 #endif
1387
1388 orderedReadIndex[internalPacket->orderingChannel]++;
1389 highestSequencedReadIndex[internalPacket->orderingChannel] = 0;
1390
1391 // Return off heap until order lost
1392 while (orderingHeaps[internalPacket->orderingChannel].Size()>0 &&
1393 orderingHeaps[internalPacket->orderingChannel].Peek()->orderingIndex==orderedReadIndex[internalPacket->orderingChannel])
1394 {
1395 internalPacket = orderingHeaps[internalPacket->orderingChannel].Pop(0);
1396
1397 #ifdef PRINT_TO_FILE_RELIABLE_ORDERED_TEST
1398 BitStream bitStream2(internalPacket->data, BITS_TO_BYTES(internalPacket->dataBitLength), false);
1399 bitStream2.IgnoreBits(8); // Ignore ID_TIMESTAMP
1400 bitStream2.Read(receivedTime);
1401 bitStream2.IgnoreBits(8); // Ignore ID_USER_ENUM+1
1402 bitStream2.Read(receivedPacketNumber);
1403 bitStream2.Read(streamNumber);
1404 bitStream2.Read(reliability);
1405 char *type="UNDEFINED";
1406 if (reliability==UNRELIABLE_SEQUENCED)
1407 type="UNRELIABLE_SEQUENCED";
1408 else if (reliability==RELIABLE_ORDERED)
1409 type="RELIABLE_ORDERED";
1410
1411 if (packetId==ID_USER_PACKET_ENUM+1 && fp)
1412 {
1413 fprintf(fp, "Heap pop %i, %s. OI=%i. SI=%i.\n", receivedPacketNumber, type, internalPacket->orderingIndex.val, internalPacket->sequencingIndex);
1414 fflush(fp);
1415
1416 if (receivedPacketNumber<packetNumber)
1417 {
1418 if (packetId==ID_USER_PACKET_ENUM+1 && fp)
1419 {
1420 fprintf(fp, "Out of order packet from heap! Expecting %i got %i\n", receivedPacketNumber, packetNumber);
1421 fflush(fp);
1422 }
1423 }
1424 packetNumber=receivedPacketNumber+1;
1425 }
1426 #endif
1427
1428 bpsMetrics[(int) USER_MESSAGE_BYTES_RECEIVED_PROCESSED].Push1(timeRead,BITS_TO_BYTES(internalPacket->dataBitLength));
1429 outputQueue.Push( internalPacket, _FILE_AND_LINE_ );
1430
1431 if (internalPacket->reliability == RELIABLE_ORDERED)
1432 {
1433 orderedReadIndex[internalPacket->orderingChannel]++;
1434 }
1435 else
1436 {
1437 highestSequencedReadIndex[internalPacket->orderingChannel] = internalPacket->sequencingIndex;
1438 }
1439 }
1440
1441 // Done
1442 goto CONTINUE_SOCKET_DATA_PARSE_LOOP;
1443 }
1444 }
1445 else if (IsOlderOrderedPacket(internalPacket->orderingIndex,orderedReadIndex[internalPacket->orderingChannel])==false)
1446 {
1447 // internalPacket->_orderingIndex is greater
1448 // If a message has a greater ordering index, and is sequenced or ordered, buffer it
1449 // Sequenced has a lower heap weight, ordered has max sequenced weight
1450
1451 // Keep orderedHoleCount count small
1452 if (orderingHeaps[internalPacket->orderingChannel].Size()==0)
1453 heapIndexOffsets[internalPacket->orderingChannel]=orderedReadIndex[internalPacket->orderingChannel];
1454
1455 reliabilityHeapWeightType orderedHoleCount = internalPacket->orderingIndex-heapIndexOffsets[internalPacket->orderingChannel];
1456 reliabilityHeapWeightType weight = orderedHoleCount*1048576;
1457 if (internalPacket->reliability == RELIABLE_SEQUENCED ||
1458 internalPacket->reliability == UNRELIABLE_SEQUENCED)
1459 weight+=internalPacket->sequencingIndex;
1460 else
1461 weight+=(1048576-1);
1462 orderingHeaps[internalPacket->orderingChannel].Push(weight, internalPacket, _FILE_AND_LINE_);
1463
1464 #ifdef PRINT_TO_FILE_RELIABLE_ORDERED_TEST
1465 if (packetId==ID_USER_PACKET_ENUM+1 && fp)
1466 {
1467 fprintf(fp, "Heap push %i, %s, weight=%" PRINTF_64_BIT_MODIFIER "u. OI=%i. waiting on %i. SI=%i.\n", receivedPacketNumber, type, weight, internalPacket->orderingIndex.val, orderedReadIndex[internalPacket->orderingChannel].val, internalPacket->sequencingIndex);
1468 fflush(fp);
1469 }
1470 #endif
1471
1472 #ifdef LOG_TRIVIAL_NOTIFICATIONS
1473 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
1474 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerNotification("Larger number ordered packet leaving holes", BYTES_TO_BITS(length), systemAddress, false);
1475 #endif
1476
1477 // Buffered, nothing to do
1478 goto CONTINUE_SOCKET_DATA_PARSE_LOOP;
1479 }
1480 else
1481 {
1482 // Out of order
1483 FreeInternalPacketData(internalPacket, _FILE_AND_LINE_ );
1484 ReleaseToInternalPacketPool( internalPacket );
1485
1486 #ifdef LOG_TRIVIAL_NOTIFICATIONS
1487 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
1488 messageHandlerList[messageHandlerIndex]->OnReliabilityLayerNotification("Rejected older resend", BYTES_TO_BITS(length), systemAddress, false);
1489 #endif
1490
1491 // Ignored, nothing to do
1492 goto CONTINUE_SOCKET_DATA_PARSE_LOOP;
1493 }
1494
1495 }
1496
1497 bpsMetrics[(int) USER_MESSAGE_BYTES_RECEIVED_PROCESSED].Push1(timeRead,BITS_TO_BYTES(internalPacket->dataBitLength));
1498
1499 // Nothing special about this packet. Add it to the output queue
1500 outputQueue.Push( internalPacket, _FILE_AND_LINE_ );
1501
1502 internalPacket = 0;
1503 }
1504
1505 // Used for a goto to jump to the resendNext packet immediately
1506
1507 CONTINUE_SOCKET_DATA_PARSE_LOOP:
1508 // Parse the bitstream to create an internal packet
1509 internalPacket = CreateInternalPacketFromBitStream( &socketData, timeRead );
1510 }
1511
1512 }
1513
1514
1515 receivePacketCount++;
1516
1517 return true;
1518 }
1519
1520 //-------------------------------------------------------------------------------------------------------
1521 // This gets an end-user packet already parsed out. Returns number of BITS put into the buffer
1522 //-------------------------------------------------------------------------------------------------------
1523 BitSize_t ReliabilityLayer::Receive( unsigned char **data )
1524 {
1525 InternalPacket * internalPacket;
1526
1527 if ( outputQueue.Size() > 0 )
1528 {
1529 // #ifdef _DEBUG
1530 // RakAssert(bitStream->GetNumberOfBitsUsed()==0);
1531 // #endif
1532 internalPacket = outputQueue.Pop();
1533
1534 BitSize_t bitLength;
1535 *data = internalPacket->data;
1536 bitLength = internalPacket->dataBitLength;
1537 ReleaseToInternalPacketPool( internalPacket );
1538 return bitLength;
1539 }
1540
1541 else
1542 {
1543 return 0;
1544 }
1545
1546 }
1547
1548 //-------------------------------------------------------------------------------------------------------
1549 // Puts data on the send queue
1550 // bitStream contains the data to send
1551 // priority is what priority to send the data at
1552 // reliability is what reliability to use
1553 // ordering channel is from 0 to 255 and specifies what stream to use
1554 //-------------------------------------------------------------------------------------------------------
1555 bool ReliabilityLayer::Send( char *data, BitSize_t numberOfBitsToSend, PacketPriority priority, PacketReliability reliability, unsigned char orderingChannel, bool makeDataCopy, int MTUSize, CCTimeType currentTime, uint32_t receipt )
1556 {
1557 #ifdef _DEBUG
1558 RakAssert( !( reliability >= NUMBER_OF_RELIABILITIES || reliability < 0 ) );
1559 RakAssert( !( priority > NUMBER_OF_PRIORITIES || priority < 0 ) );
1560 RakAssert( !( orderingChannel >= NUMBER_OF_ORDERED_STREAMS ) );
1561 RakAssert( numberOfBitsToSend > 0 );
1562 #endif
1563
1564 #if CC_TIME_TYPE_BYTES==4
1565 currentTime/=1000;
1566 #endif
1567
1568 (void) MTUSize;
1569
1570 // int a = BITS_TO_BYTES(numberOfBitsToSend);
1571
1572 // Fix any bad parameters
1573 if ( reliability > RELIABLE_ORDERED_WITH_ACK_RECEIPT || reliability < 0 )
1574 reliability = RELIABLE;
1575
1576 if ( priority > NUMBER_OF_PRIORITIES || priority < 0 )
1577 priority = HIGH_PRIORITY;
1578
1579 if ( orderingChannel >= NUMBER_OF_ORDERED_STREAMS )
1580 orderingChannel = 0;
1581
1582 unsigned int numberOfBytesToSend=(unsigned int) BITS_TO_BYTES(numberOfBitsToSend);
1583 if ( numberOfBitsToSend == 0 )
1584 {
1585 return false;
1586 }
1587 InternalPacket * internalPacket = AllocateFromInternalPacketPool();
1588 if (internalPacket==0)
1589 {
1590 notifyOutOfMemory(_FILE_AND_LINE_);
1591 return false; // Out of memory
1592 }
1593
1594 bpsMetrics[(int) USER_MESSAGE_BYTES_PUSHED].Push1(currentTime,numberOfBytesToSend);
1595
1596 internalPacket->creationTime = currentTime;
1597
1598 if ( makeDataCopy )
1599 {
1600 AllocInternalPacketData(internalPacket, numberOfBytesToSend, true, _FILE_AND_LINE_ );
1601 //internalPacket->data = (unsigned char*) rakMalloc_Ex( numberOfBytesToSend, _FILE_AND_LINE_ );
1602 memcpy( internalPacket->data, data, numberOfBytesToSend );
1603 }
1604 else
1605 {
1606 // Allocated the data elsewhere, delete it in here
1607 //internalPacket->data = ( unsigned char* ) data;
1608 AllocInternalPacketData(internalPacket, (unsigned char*) data );
1609 }
1610
1611 internalPacket->dataBitLength = numberOfBitsToSend;
1612 internalPacket->messageInternalOrder = internalOrderIndex++;
1613 internalPacket->priority = priority;
1614 internalPacket->reliability = reliability;
1615 internalPacket->sendReceiptSerial=receipt;
1616
1617 // Calculate if I need to split the packet
1618 // int headerLength = BITS_TO_BYTES( GetMessageHeaderLengthBits( internalPacket, true ) );
1619
1620 unsigned int maxDataSizeBytes = GetMaxDatagramSizeExcludingMessageHeaderBytes() - BITS_TO_BYTES(GetMaxMessageHeaderLengthBits());
1621
1622 bool splitPacket = numberOfBytesToSend > maxDataSizeBytes;
1623
1624 // If a split packet, we might have to upgrade the reliability
1625 if ( splitPacket )
1626 {
1627 // Split packets cannot be unreliable, in case that one part doesn't arrive and the whole cannot be reassembled.
1628 // One part could not arrive either due to packetloss or due to unreliable discard
1629 if (internalPacket->reliability==UNRELIABLE)
1630 internalPacket->reliability=RELIABLE;
1631 else if (internalPacket->reliability==UNRELIABLE_WITH_ACK_RECEIPT)
1632 internalPacket->reliability=RELIABLE_WITH_ACK_RECEIPT;
1633 else if (internalPacket->reliability==UNRELIABLE_SEQUENCED)
1634 internalPacket->reliability=RELIABLE_SEQUENCED;
1635 // else if (internalPacket->reliability==UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT)
1636 // internalPacket->reliability=RELIABLE_SEQUENCED_WITH_ACK_RECEIPT;
1637 }
1638
1639 // ++sendMessageNumberIndex;
1640
1641 if ( internalPacket->reliability == RELIABLE_SEQUENCED ||
1642 internalPacket->reliability == UNRELIABLE_SEQUENCED
1643 // ||
1644 // internalPacket->reliability == RELIABLE_SEQUENCED_WITH_ACK_RECEIPT ||
1645 // internalPacket->reliability == UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT
1646 )
1647 {
1648 // Assign the sequence stream and index
1649 internalPacket->orderingChannel = orderingChannel;
1650 internalPacket->orderingIndex = orderedWriteIndex[ orderingChannel ];
1651 internalPacket->sequencingIndex = sequencedWriteIndex[ orderingChannel ]++;
1652
1653 // This packet supersedes all other sequenced packets on the same ordering channel
1654 // Delete all packets in all send lists that are sequenced and on the same ordering channel
1655 // UPDATE:
1656 // Disabled. We don't have enough info to consistently do this. Sometimes newer data does supercede
1657 // older data such as with constantly declining health, but not in all cases.
1658 // For example, with sequenced unreliable sound packets just because you send a newer one doesn't mean you
1659 // don't need the older ones because the odds are they will still arrive in order
1660 /*
1661 for (int i=0; i < NUMBER_OF_PRIORITIES; i++)
1662 {
1663 DeleteSequencedPacketsInList(orderingChannel, sendQueue[i]);
1664 }
1665 */
1666 }
1667 else if ( internalPacket->reliability == RELIABLE_ORDERED || internalPacket->reliability == RELIABLE_ORDERED_WITH_ACK_RECEIPT )
1668 {
1669 // Assign the ordering channel and index
1670 internalPacket->orderingChannel = orderingChannel;
1671 internalPacket->orderingIndex = orderedWriteIndex[ orderingChannel ] ++;
1672 sequencedWriteIndex[ orderingChannel ]=0;
1673 }
1674
1675 if ( splitPacket ) // If it uses a secure header it will be generated here
1676 {
1677 // Must split the packet. This will also generate the SHA1 if it is required. It also adds it to the send list.
1678 //InternalPacket packetCopy;
1679 //memcpy(&packetCopy, internalPacket, sizeof(InternalPacket));
1680 //sendPacketSet[priority].CancelWriteLock(internalPacket);
1681 //SplitPacket( &packetCopy, MTUSize );
1682 SplitPacket( internalPacket );
1683 //SLNet::OP_DELETE_ARRAY(packetCopy.data, _FILE_AND_LINE_);
1684 return true;
1685 }
1686
1687 RakAssert(internalPacket->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
1688 AddToUnreliableLinkedList(internalPacket);
1689
1690 RakAssert(internalPacket->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
1691 RakAssert(internalPacket->messageNumberAssigned==false);
1692 outgoingPacketBuffer.Push( GetNextWeight(internalPacket->priority), internalPacket, _FILE_AND_LINE_ );
1693 RakAssert(outgoingPacketBuffer.Size()==0 || outgoingPacketBuffer.Peek()->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
1694 statistics.messageInSendBuffer[(int)internalPacket->priority]++;
1695 statistics.bytesInSendBuffer[(int)internalPacket->priority]+=(double) BITS_TO_BYTES(internalPacket->dataBitLength);
1696
1697 // sendPacketSet[priority].WriteUnlock();
1698 return true;
1699 }
1700 //-------------------------------------------------------------------------------------------------------
1701 // Run this once per game cycle. Handles internal lists and actually does the send
1702 //-------------------------------------------------------------------------------------------------------
1703 void ReliabilityLayer::Update( RakNetSocket2 *s, SystemAddress &systemAddress, int MTUSize, CCTimeType time,
1704 unsigned bitsPerSecondLimit,
1705 DataStructures::List<PluginInterface2*> &messageHandlerList,
1706 RakNetRandom *rnr,
1707 BitStream &updateBitStream)
1708
1709 {
1710 (void) MTUSize;
1711
1712 SLNet::TimeMS timeMs;
1713 #if CC_TIME_TYPE_BYTES==4
1714 time/=1000;
1715 timeMs=time;
1716 #else
1717 timeMs=(SLNet::TimeMS) (time/(CCTimeType)1000);
1718 #endif
1719
1720 #ifdef _DEBUG
1721 while (delayList.Size())
1722 {
1723 if (delayList.Peek()->sendTime <= timeMs)
1724 {
1725 DataAndTime *dat = delayList.Pop();
1726 // SocketLayer::SendTo( dat->s, dat->data, dat->length, systemAddress, __FILE__, __LINE__ );
1727
1728 RNS2_SendParameters bsp;
1729 bsp.data = (char*) dat->data;
1730 bsp.length = dat->length;
1731 bsp.systemAddress = systemAddress;
1732 dat->s->Send(&bsp, _FILE_AND_LINE_);
1733
1734 SLNet::OP_DELETE(dat,__FILE__,__LINE__);
1735 }
1736 else
1737 {
1738 break;
1739 }
1740 }
1741 #endif
1742
1743 // This line is necessary because the timer isn't accurate
1744 if (time <= lastUpdateTime)
1745 {
1746 // Always set the last time in case of overflow
1747 lastUpdateTime=time;
1748 return;
1749 }
1750
1751 CCTimeType timeSinceLastTick = time - lastUpdateTime;
1752 lastUpdateTime=time;
1753 #if CC_TIME_TYPE_BYTES==4
1754 if (timeSinceLastTick>100)
1755 timeSinceLastTick=100;
1756 #else
1757 if (timeSinceLastTick>100000)
1758 timeSinceLastTick=100000;
1759 #endif
1760
1761 if (unreliableTimeout>0)
1762 {
1763 if (timeSinceLastTick>=timeToNextUnreliableCull)
1764 {
1765 if (unreliableLinkedListHead)
1766 {
1767 // Cull out all unreliable messages that have exceeded the timeout
1768 InternalPacket *cur = unreliableLinkedListHead;
1769 InternalPacket *end = unreliableLinkedListHead->unreliablePrev;
1770
1771 for(;;)
1772 {
1773 if (time > cur->creationTime+(CCTimeType)unreliableTimeout)
1774 {
1775 // Flag invalid, and clear the memory. Still needs to be removed from the sendPacketSet later
1776 // This fixes a problem where a remote system disconnects, but we don't know it yet, and memory consumption increases to a huge value
1777 FreeInternalPacketData(cur, _FILE_AND_LINE_ );
1778 cur->data=0;
1779 InternalPacket *next = cur->unreliableNext;
1780 RemoveFromUnreliableLinkedList(cur);
1781
1782 if (cur==end)
1783 break;
1784
1785 cur=next;
1786 }
1787 else
1788 {
1789 // if (cur==end)
1790 // break;
1791 //
1792 // cur=cur->unreliableNext;
1793
1794 // They should be inserted in-order, so no need to iterate past the first failure
1795 break;
1796 }
1797 }
1798 }
1799
1800 timeToNextUnreliableCull=unreliableTimeout/(CCTimeType)2;
1801 }
1802 else
1803 {
1804 timeToNextUnreliableCull-=timeSinceLastTick;
1805 }
1806 }
1807
1808
1809 // Due to thread vagarities and the way I store the time to avoid slow calls to SLNet::GetTime
1810 // time may be less than lastAck
1811 #if CC_TIME_TYPE_BYTES==4
1812 if ( statistics.messagesInResendBuffer!=0 && AckTimeout(time) )
1813 #else
1814 if ( statistics.messagesInResendBuffer!=0 && AckTimeout(SLNet::TimeMS(time/(CCTimeType)1000)) )
1815 #endif
1816 {
1817 // SHOW - dead connection
1818 // We've waited a very long time for a reliable packet to get an ack and it never has
1819 deadConnection = true;
1820 return;
1821 }
1822
1823 if (congestionManager.ShouldSendACKs(time,timeSinceLastTick))
1824 {
1825 SendACKs(s, systemAddress, time, rnr, updateBitStream);
1826 }
1827
1828 if (NAKs.Size()>0)
1829 {
1830 updateBitStream.Reset();
1831 DatagramHeaderFormat dhfNAK;
1832 dhfNAK.isNAK=true;
1833 dhfNAK.isACK=false;
1834 dhfNAK.isPacketPair=false;
1835 dhfNAK.Serialize(&updateBitStream);
1836 NAKs.Serialize(&updateBitStream, GetMaxDatagramSizeExcludingMessageHeaderBits(), true);
1837 SendBitStream( s, systemAddress, &updateBitStream, rnr, time );
1838 }
1839
1840 DatagramHeaderFormat dhf;
1841 dhf.needsBAndAs=congestionManager.GetIsInSlowStart();
1842 dhf.isContinuousSend=bandwidthExceededStatistic;
1843 // bandwidthExceededStatistic=sendPacketSet[0].IsEmpty()==false ||
1844 // sendPacketSet[1].IsEmpty()==false ||
1845 // sendPacketSet[2].IsEmpty()==false ||
1846 // sendPacketSet[3].IsEmpty()==false;
1847 bandwidthExceededStatistic=outgoingPacketBuffer.Size()>0;
1848
1849 const bool hasDataToSendOrResend = IsResendQueueEmpty()==false || bandwidthExceededStatistic;
1850 RakAssert(NUMBER_OF_PRIORITIES==4);
1851 congestionManager.Update(time, hasDataToSendOrResend);
1852
1853 statistics.BPSLimitByOutgoingBandwidthLimit = BITS_TO_BYTES(bitsPerSecondLimit);
1854 statistics.BPSLimitByCongestionControl = congestionManager.GetBytesPerSecondLimitByCongestionControl();
1855
1856 unsigned int i;
1857 if (time > lastBpsClear+
1858 #if CC_TIME_TYPE_BYTES==4
1859 100
1860 #else
1861 100000
1862 #endif
1863 )
1864 {
1865 for (i=0; i < RNS_PER_SECOND_METRICS_COUNT; i++)
1866 {
1867 bpsMetrics[i].ClearExpired1(time);
1868 }
1869
1870 lastBpsClear=time;
1871 }
1872
1873 if (unreliableWithAckReceiptHistory.Size()>0)
1874 {
1875 i=0;
1876 while (i < unreliableWithAckReceiptHistory.Size())
1877 {
1878 //if (unreliableWithAckReceiptHistory[i].nextActionTime < time)
1879 if (time - unreliableWithAckReceiptHistory[i].nextActionTime < (((CCTimeType)-1)/2) )
1880 {
1881 InternalPacket *ackReceipt = AllocateFromInternalPacketPool();
1882 AllocInternalPacketData(ackReceipt, 5, false, _FILE_AND_LINE_ );
1883 ackReceipt->dataBitLength=BYTES_TO_BITS(5);
1884 ackReceipt->data[0]=(MessageID)ID_SND_RECEIPT_LOSS;
1885 memcpy(ackReceipt->data+sizeof(MessageID), &unreliableWithAckReceiptHistory[i].sendReceiptSerial, sizeof(uint32_t));
1886 outputQueue.Push(ackReceipt, _FILE_AND_LINE_ );
1887
1888 // Remove, swap with last
1889 unreliableWithAckReceiptHistory.RemoveAtIndex(i);
1890 }
1891 else
1892 i++;
1893 }
1894 }
1895
1896 if (hasDataToSendOrResend==true)
1897 {
1898 InternalPacket *internalPacket;
1899 // bool forceSend=false;
1900 bool pushedAnything;
1901 BitSize_t nextPacketBitLength;
1902 dhf.isACK=false;
1903 dhf.isNAK=false;
1904 dhf.hasBAndAS=false;
1905 ResetPacketsAndDatagrams();
1906
1907 int transmissionBandwidth = congestionManager.GetTransmissionBandwidth(time, timeSinceLastTick, unacknowledgedBytes,dhf.isContinuousSend);
1908 int retransmissionBandwidth = congestionManager.GetRetransmissionBandwidth(time, timeSinceLastTick, unacknowledgedBytes,dhf.isContinuousSend);
1909 if (retransmissionBandwidth>0 || transmissionBandwidth>0)
1910 {
1911 statistics.isLimitedByCongestionControl=false;
1912
1913 allDatagramSizesSoFar=0;
1914
1915 // Keep filling datagrams until we exceed retransmission bandwidth
1916 while ((int)BITS_TO_BYTES(allDatagramSizesSoFar)<retransmissionBandwidth)
1917 {
1918 pushedAnything=false;
1919
1920 // Fill one datagram, then break
1921 while ( IsResendQueueEmpty()==false )
1922 {
1923 internalPacket = resendLinkedListHead;
1924 RakAssert(internalPacket->messageNumberAssigned==true);
1925
1926 //if ( internalPacket->nextActionTime < time )
1927 if ( time - internalPacket->nextActionTime < (((CCTimeType)-1)/2) )
1928 {
1929 nextPacketBitLength = internalPacket->headerLength + internalPacket->dataBitLength;
1930 if ( datagramSizeSoFar + nextPacketBitLength > GetMaxDatagramSizeExcludingMessageHeaderBits() )
1931 {
1932 // Gathers all PushPackets()
1933 PushDatagram();
1934 break;
1935 }
1936
1937 PopListHead(false);
1938
1939 CC_DEBUG_PRINTF_2("Rs %i ", internalPacket->reliableMessageNumber.val);
1940
1941 bpsMetrics[(int) USER_MESSAGE_BYTES_RESENT].Push1(time,BITS_TO_BYTES(internalPacket->dataBitLength));
1942
1943 // Testing1
1944 // if (internalPacket->reliability==RELIABLE_ORDERED || internalPacket->reliability==RELIABLE_ORDERED_WITH_ACK_RECEIPT)
1945 // printf("RESEND reliableMessageNumber %i with datagram %i\n", internalPacket->reliableMessageNumber.val, congestionManager.GetNextDatagramSequenceNumber().val);
1946
1947 PushPacket(time,internalPacket,true); // Affects GetNewTransmissionBandwidth()
1948 internalPacket->timesSent++;
1949 congestionManager.OnResend(time, internalPacket->nextActionTime);
1950 internalPacket->retransmissionTime = congestionManager.GetRTOForRetransmission(internalPacket->timesSent);
1951 internalPacket->nextActionTime = internalPacket->retransmissionTime+time;
1952
1953 pushedAnything=true;
1954
1955 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
1956 {
1957 #if CC_TIME_TYPE_BYTES==4
1958 messageHandlerList[messageHandlerIndex]->OnInternalPacket(internalPacket, packetsToSendThisUpdateDatagramBoundaries.Size()+congestionManager.GetNextDatagramSequenceNumber(), systemAddress, (SLNet::TimeMS) time, true);
1959 #else
1960 messageHandlerList[messageHandlerIndex]->OnInternalPacket(internalPacket, packetsToSendThisUpdateDatagramBoundaries.Size()+congestionManager.GetNextDatagramSequenceNumber(), systemAddress, (SLNet::TimeMS)(time/(CCTimeType)1000), true);
1961 #endif
1962 }
1963
1964 // Put the packet back into the resend list at the correct spot
1965 // Don't make a copy since I'm reinserting an allocated struct
1966 InsertPacketIntoResendList( internalPacket, time, false, false );
1967
1968 // Removeme
1969 // printf("Resend:%i ", internalPacket->reliableMessageNumber);
1970 }
1971 else
1972 {
1973 // Filled one datagram.
1974 // If the 2nd and it's time to send a datagram pair, will be marked as a pair
1975 PushDatagram();
1976 break;
1977 }
1978 }
1979
1980 if (pushedAnything==false)
1981 break;
1982 }
1983 }
1984 else
1985 {
1986 statistics.isLimitedByCongestionControl=true;
1987 }
1988
1989 if ((int)BITS_TO_BYTES(allDatagramSizesSoFar)<transmissionBandwidth)
1990 {
1991 // printf("S+ ");
1992 allDatagramSizesSoFar=0;
1993
1994 // Keep filling datagrams until we exceed transmission bandwidth
1995 while (
1996 ResendBufferOverflow()==false &&
1997 ((int)BITS_TO_BYTES(allDatagramSizesSoFar)<transmissionBandwidth ||
1998 // This condition means if we want to send a datagram pair, and only have one datagram buffered, exceed bandwidth to add another
1999 (countdownToNextPacketPair==0 &&
2000 datagramsToSendThisUpdateIsPair.Size()==1))
2001 )
2002 {
2003 // Fill with packets until MTU is reached
2004 // for ( i = 0; i < NUMBER_OF_PRIORITIES; i++ )
2005 // {
2006 pushedAnything=false;
2007
2008 statistics.isLimitedByOutgoingBandwidthLimit=bitsPerSecondLimit!=0 && BITS_TO_BYTES(bitsPerSecondLimit) < bpsMetrics[USER_MESSAGE_BYTES_SENT].GetBPS1(time);
2009
2010
2011 while (outgoingPacketBuffer.Size() &&
2012 statistics.isLimitedByOutgoingBandwidthLimit==false)
2013 //while ( sendPacketSet[ i ].Size() )
2014 {
2015 internalPacket=outgoingPacketBuffer.Peek();
2016 RakAssert(internalPacket->messageNumberAssigned==false);
2017 RakAssert(outgoingPacketBuffer.Size()==0 || outgoingPacketBuffer.Peek()->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
2018
2019 // internalPacket = sendPacketSet[ i ].Peek();
2020 if (internalPacket->data==0)
2021 {
2022 //sendPacketSet[ i ].Pop();
2023 outgoingPacketBuffer.Pop(0);
2024 RakAssert(outgoingPacketBuffer.Size()==0 || outgoingPacketBuffer.Peek()->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
2025 statistics.messageInSendBuffer[(int)internalPacket->priority]--;
2026 statistics.bytesInSendBuffer[(int)internalPacket->priority]-=(double) BITS_TO_BYTES(internalPacket->dataBitLength);
2027 ReleaseToInternalPacketPool( internalPacket );
2028 continue;
2029 }
2030
2031 internalPacket->headerLength=GetMessageHeaderLengthBits(internalPacket);
2032 nextPacketBitLength = internalPacket->headerLength + internalPacket->dataBitLength;
2033 if ( datagramSizeSoFar + nextPacketBitLength > GetMaxDatagramSizeExcludingMessageHeaderBits() )
2034 {
2035 // Hit MTU. May still push packets if smaller ones exist at a lower priority
2036 RakAssert(datagramSizeSoFar!=0);
2037 RakAssert(internalPacket->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
2038 break;
2039 }
2040
2041 bool isReliable;
2042 if ( internalPacket->reliability == RELIABLE ||
2043 internalPacket->reliability == RELIABLE_SEQUENCED ||
2044 internalPacket->reliability == RELIABLE_ORDERED ||
2045 internalPacket->reliability == RELIABLE_WITH_ACK_RECEIPT ||
2046 // internalPacket->reliability == RELIABLE_SEQUENCED_WITH_ACK_RECEIPT ||
2047 internalPacket->reliability == RELIABLE_ORDERED_WITH_ACK_RECEIPT
2048 )
2049 isReliable = true;
2050 else
2051 isReliable = false;
2052
2053 //sendPacketSet[ i ].Pop();
2054 outgoingPacketBuffer.Pop(0);
2055 RakAssert(outgoingPacketBuffer.Size()==0 || outgoingPacketBuffer.Peek()->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
2056 RakAssert(internalPacket->messageNumberAssigned==false);
2057 statistics.messageInSendBuffer[(int)internalPacket->priority]--;
2058 statistics.bytesInSendBuffer[(int)internalPacket->priority]-=(double) BITS_TO_BYTES(internalPacket->dataBitLength);
2059 if (isReliable
2060 /*
2061 I thought about this and agree that UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT and RELIABLE_SEQUENCED_WITH_ACK_RECEIPT is not useful unless you also know if the message was discarded.
2062
2063 The problem is that internally, message numbers are only assigned to reliable messages, because message numbers are only used to discard duplicate message receipt and only reliable messages get sent more than once. However, without message numbers getting assigned and transmitted, there is no way to tell the sender about which messages were discarded. In fact, in looking this over I realized that UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT introduced a bug, because the remote system assumes all message numbers are used (no holes). With that send type, on packetloss, a permanent hole would have been created which eventually would cause the system to discard all further packets.
2064
2065 So I have two options. Either do not support ack receipts when sending sequenced, or write complex and major new systems. UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT would need to send the message ID number on a special channel which allows for non-delivery. And both of them would need to have a special range list to indicate which message numbers were not delivered, so when acks are sent that can be indicated as well. A further problem is that the ack itself can be lost - it is possible that the message can arrive but be discarded, yet the ack is lost. On resend, the resent message would be ignored as duplicate, and you'd never get the discard message either (unless I made a special buffer for that case too).
2066 */
2067 // ||
2068 // If needs an ack receipt, keep the internal packet around in the list
2069 // internalPacket->reliability == UNRELIABLE_WITH_ACK_RECEIPT ||
2070 // internalPacket->reliability == UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT
2071 )
2072 {
2073 internalPacket->messageNumberAssigned=true;
2074 internalPacket->reliableMessageNumber=sendReliableMessageNumberIndex;
2075 internalPacket->retransmissionTime = congestionManager.GetRTOForRetransmission(internalPacket->timesSent+1);
2076 internalPacket->nextActionTime = internalPacket->retransmissionTime+time;
2077 #if CC_TIME_TYPE_BYTES==4
2078 const CCTimeType threshhold = 10000;
2079 #else
2080 const CCTimeType threshhold = 10000000;
2081 #endif
2082 if (internalPacket->nextActionTime-time > threshhold)
2083 {
2084 // int a=5;
2085 RakAssert(time-internalPacket->nextActionTime < threshhold);
2086 }
2087 //resendTree.Insert( internalPacket->reliableMessageNumber, internalPacket);
2088 if (resendBuffer[internalPacket->reliableMessageNumber & (uint32_t) RESEND_BUFFER_ARRAY_MASK]!=0)
2089 {
2090 // bool overflow = ResendBufferOverflow();
2091 RakAssert(0);
2092 }
2093 resendBuffer[internalPacket->reliableMessageNumber & (uint32_t) RESEND_BUFFER_ARRAY_MASK] = internalPacket;
2094 statistics.messagesInResendBuffer++;
2095 statistics.bytesInResendBuffer+=BITS_TO_BYTES(internalPacket->dataBitLength);
2096
2097 // printf("pre:%i ", unacknowledgedBytes);
2098
2099 InsertPacketIntoResendList( internalPacket, time, true, isReliable);
2100
2101
2102 // printf("post:%i ", unacknowledgedBytes);
2103 sendReliableMessageNumberIndex++;
2104 }
2105 else if (internalPacket->reliability == UNRELIABLE_WITH_ACK_RECEIPT)
2106 {
2107 unreliableWithAckReceiptHistory.Push(UnreliableWithAckReceiptNode(
2108 congestionManager.GetNextDatagramSequenceNumber() + packetsToSendThisUpdateDatagramBoundaries.Size(),
2109 internalPacket->sendReceiptSerial,
2110 congestionManager.GetRTOForRetransmission(internalPacket->timesSent+1)+time
2111 ), _FILE_AND_LINE_);
2112 }
2113
2114 // If isReliable is false, the packet and its contents will be added to a list to be freed in ClearPacketsAndDatagrams
2115 // However, the internalPacket structure will remain allocated and be in the resendBuffer list if it requires a receipt
2116 bpsMetrics[(int) USER_MESSAGE_BYTES_SENT].Push1(time,BITS_TO_BYTES(internalPacket->dataBitLength));
2117
2118 // Testing1
2119 // if (internalPacket->reliability==RELIABLE_ORDERED || internalPacket->reliability==RELIABLE_ORDERED_WITH_ACK_RECEIPT)
2120 // printf("SEND reliableMessageNumber %i in datagram %i\n", internalPacket->reliableMessageNumber.val, congestionManager.GetNextDatagramSequenceNumber().val);
2121
2122 PushPacket(time,internalPacket, isReliable);
2123 internalPacket->timesSent++;
2124
2125 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
2126 {
2127 #if CC_TIME_TYPE_BYTES==4
2128 messageHandlerList[messageHandlerIndex]->OnInternalPacket(internalPacket, packetsToSendThisUpdateDatagramBoundaries.Size()+congestionManager.GetNextDatagramSequenceNumber(), systemAddress, (SLNet::TimeMS)time, true);
2129 #else
2130 messageHandlerList[messageHandlerIndex]->OnInternalPacket(internalPacket, packetsToSendThisUpdateDatagramBoundaries.Size()+congestionManager.GetNextDatagramSequenceNumber(), systemAddress, (SLNet::TimeMS)(time/(CCTimeType)1000), true);
2131 #endif
2132 }
2133 pushedAnything=true;
2134
2135 if (ResendBufferOverflow())
2136 break;
2137 }
2138 // if (ResendBufferOverflow())
2139 // break;
2140 // }z
2141
2142 // No datagrams pushed?
2143 if (datagramSizeSoFar==0)
2144 break;
2145
2146 // Filled one datagram.
2147 // If the 2nd and it's time to send a datagram pair, will be marked as a pair
2148 PushDatagram();
2149 }
2150 }
2151
2152
2153 for (unsigned int datagramIndex=0; datagramIndex < packetsToSendThisUpdateDatagramBoundaries.Size(); datagramIndex++)
2154 {
2155 if (datagramIndex>0)
2156 dhf.isContinuousSend=true;
2157 MessageNumberNode* messageNumberNode = 0;
2158 dhf.datagramNumber=congestionManager.GetAndIncrementNextDatagramSequenceNumber();
2159 dhf.isPacketPair=datagramsToSendThisUpdateIsPair[datagramIndex];
2160
2161 //printf("%p pushing datagram %i\n", this, dhf.datagramNumber.val);
2162
2163 bool isSecondOfPacketPair=dhf.isPacketPair && datagramIndex>0 && datagramsToSendThisUpdateIsPair[datagramIndex-1];
2164 unsigned int msgIndex, msgTerm;
2165 if (datagramIndex==0)
2166 {
2167 msgIndex=0;
2168 msgTerm=packetsToSendThisUpdateDatagramBoundaries[0];
2169 }
2170 else
2171 {
2172 msgIndex=packetsToSendThisUpdateDatagramBoundaries[datagramIndex-1];
2173 msgTerm=packetsToSendThisUpdateDatagramBoundaries[datagramIndex];
2174 }
2175
2176 // More accurate time to reset here
2177 #if INCLUDE_TIMESTAMP_WITH_DATAGRAMS==1
2178 dhf.sourceSystemTime= SLNet::GetTimeUS();
2179 #endif
2180 updateBitStream.Reset();
2181 dhf.Serialize(&updateBitStream);
2182 CC_DEBUG_PRINTF_2("S%i ",dhf.datagramNumber.val);
2183
2184 while (msgIndex < msgTerm)
2185 {
2186 // If reliable or needs receipt
2187 if ( packetsToSendThisUpdate[msgIndex]->reliability != UNRELIABLE &&
2188 packetsToSendThisUpdate[msgIndex]->reliability != UNRELIABLE_SEQUENCED
2189 )
2190 {
2191 if (messageNumberNode==0)
2192 {
2193 messageNumberNode = AddFirstToDatagramHistory(dhf.datagramNumber, packetsToSendThisUpdate[msgIndex]->reliableMessageNumber, time);
2194 }
2195 else
2196 {
2197 messageNumberNode = AddSubsequentToDatagramHistory(messageNumberNode, packetsToSendThisUpdate[msgIndex]->reliableMessageNumber);
2198 }
2199 }
2200
2201 RakAssert(updateBitStream.GetNumberOfBytesUsed()<=MAXIMUM_MTU_SIZE-UDP_HEADER_SIZE);
2202 WriteToBitStreamFromInternalPacket( &updateBitStream, packetsToSendThisUpdate[msgIndex], time );
2203 RakAssert(updateBitStream.GetNumberOfBytesUsed()<=MAXIMUM_MTU_SIZE-UDP_HEADER_SIZE);
2204 msgIndex++;
2205 }
2206
2207 if (isSecondOfPacketPair)
2208 {
2209 // Pad to size of first datagram
2210 RakAssert(updateBitStream.GetNumberOfBytesUsed()<=MAXIMUM_MTU_SIZE-UDP_HEADER_SIZE);
2211 updateBitStream.PadWithZeroToByteLength(datagramSizesInBytes[datagramIndex-1]);
2212 RakAssert(updateBitStream.GetNumberOfBytesUsed()<=MAXIMUM_MTU_SIZE-UDP_HEADER_SIZE);
2213 }
2214
2215 if (messageNumberNode==0)
2216 {
2217 // Unreliable, add dummy node
2218 AddFirstToDatagramHistory(dhf.datagramNumber, time);
2219 }
2220
2221 // Store what message ids were sent with this datagram
2222 // datagramMessageIDTree.Insert(dhf.datagramNumber,idList);
2223
2224 congestionManager.OnSendBytes(time,UDP_HEADER_SIZE+DatagramHeaderFormat::GetDataHeaderByteLength());
2225
2226 SendBitStream( s, systemAddress, &updateBitStream, rnr, time );
2227
2228 bandwidthExceededStatistic=outgoingPacketBuffer.Size()>0;
2229 // bandwidthExceededStatistic=sendPacketSet[0].IsEmpty()==false ||
2230 // sendPacketSet[1].IsEmpty()==false ||
2231 // sendPacketSet[2].IsEmpty()==false ||
2232 // sendPacketSet[3].IsEmpty()==false;
2233
2234
2235
2236 if (bandwidthExceededStatistic==true)
2237 timeOfLastContinualSend=time;
2238 else
2239 timeOfLastContinualSend=0;
2240 }
2241
2242 ClearPacketsAndDatagrams();
2243
2244 // Any data waiting to send after attempting to send, then bandwidth is exceeded
2245 bandwidthExceededStatistic=outgoingPacketBuffer.Size()>0;
2246 // bandwidthExceededStatistic=sendPacketSet[0].IsEmpty()==false ||
2247 // sendPacketSet[1].IsEmpty()==false ||
2248 // sendPacketSet[2].IsEmpty()==false ||
2249 // sendPacketSet[3].IsEmpty()==false;
2250 }
2251
2252
2253 // Keep on top of deleting old unreliable split packets so they don't clog the list.
2254 //DeleteOldUnreliableSplitPackets( time );
2255 }
2256
2257 //-------------------------------------------------------------------------------------------------------
2258 // Writes a bitstream to the socket
2259 //-------------------------------------------------------------------------------------------------------
2260 void ReliabilityLayer::SendBitStream( RakNetSocket2 *s, SystemAddress &systemAddress, SLNet::BitStream *bitStream, RakNetRandom *rnr, CCTimeType currentTime)
2261 {
2262 (void) systemAddress;
2263 (void) rnr;
2264
2265 unsigned int length;
2266
2267 length = (unsigned int) bitStream->GetNumberOfBytesUsed();
2268
2269
2270 #ifdef _DEBUG
2271 if (packetloss > 0.0)
2272 {
2273 if (frandomMT() < packetloss)
2274 return;
2275 }
2276
2277 if (minExtraPing > 0 || extraPingVariance > 0)
2278 {
2279 #ifdef FLIP_SEND_ORDER_TEST
2280 // Flip order of sends without delaying them for testing
2281 DataAndTime *dat = SLNet::OP_NEW<DataAndTime>(__FILE__,__LINE__);
2282 memcpy(dat->data, ( char* ) bitStream->GetData(), length );
2283 dat->s=s;
2284 dat->length=length;
2285 dat->sendTime = 0;
2286 dat->remotePortRakNetWasStartedOn_PS3=remotePortRakNetWasStartedOn_PS3;
2287 dat->extraSocketOptions=extraSocketOptions;
2288 delayList.PushAtHead(dat, 0, _FILE_AND_LINE_);
2289 #else
2290 SLNet::TimeMS delay = minExtraPing;
2291 if (extraPingVariance>0)
2292 delay += (randomMT() % extraPingVariance);
2293 if (delay > 0)
2294 {
2295 DataAndTime *dat = SLNet::OP_NEW<DataAndTime>(__FILE__,__LINE__);
2296 memcpy(dat->data, ( char* ) bitStream->GetData(), length );
2297 dat->s=s;
2298 dat->length=length;
2299 dat->sendTime = SLNet::GetTimeMS() + delay;
2300 for (unsigned int i=0; i < delayList.Size(); i++)
2301 {
2302 if (dat->sendTime < delayList[i]->sendTime)
2303 {
2304 delayList.PushAtHead(dat, i, __FILE__, __LINE__);
2305 dat=0;
2306 break;
2307 }
2308 }
2309 if (dat!=0)
2310 delayList.Push(dat,__FILE__,__LINE__);
2311 return;
2312 }
2313 #endif
2314 }
2315 #endif
2316
2317 #if LIBCAT_SECURITY==1
2318 if (useSecurity)
2319 {
2320 unsigned char *buffer = reinterpret_cast<unsigned char*>( bitStream->GetData() );
2321
2322 int buffer_size = bitStream->GetNumberOfBitsAllocated() / 8;
2323
2324 // Verify there is enough room for encrypted output and encrypt
2325 // Encrypt() will increase length
2326 bool success = auth_enc.Encrypt(buffer, buffer_size, length);
2327 RakAssert(success);
2328 }
2329 #endif
2330
2331 bpsMetrics[(int) ACTUAL_BYTES_SENT].Push1(currentTime,length);
2332
2333 RakAssert(length <= congestionManager.GetMTU());
2334
2335 #ifdef USE_THREADED_SEND
2336 SendToThread::SendToThreadBlock *block = SendToThread::AllocateBlock();
2337 memcpy(block->data, bitStream->GetData(), length);
2338 block->dataWriteOffset=length;
2339 block->extraSocketOptions=extraSocketOptions;
2340 block->remotePortRakNetWasStartedOn_PS3=remotePortRakNetWasStartedOn_PS3;
2341 block->s=s;
2342 block->systemAddress=systemAddress;
2343 SendToThread::ProcessBlock(block);
2344 #else
2345 // SocketLayer::SendTo( s, ( char* ) bitStream->GetData(), length, systemAddress, __FILE__, __LINE__ );
2346
2347 RNS2_SendParameters bsp;
2348 bsp.data = (char*) bitStream->GetData();
2349 bsp.length = length;
2350 bsp.systemAddress = systemAddress;
2351 s->Send(&bsp, _FILE_AND_LINE_);
2352 #endif
2353 }
2354
2355 //-------------------------------------------------------------------------------------------------------
2356 // Are we waiting for any data to be sent out or be processed by the player?
2357 //-------------------------------------------------------------------------------------------------------
2358 bool ReliabilityLayer::IsOutgoingDataWaiting(void)
2359 {
2360 if (outgoingPacketBuffer.Size()>0)
2361 return true;
2362
2363 // unsigned i;
2364 // for ( i = 0; i < NUMBER_OF_PRIORITIES; i++ )
2365 // {
2366 // if (sendPacketSet[ i ].Size() > 0)
2367 // return true;
2368 // }
2369
2370 return
2371 //acknowlegements.Size() > 0 ||
2372 //resendTree.IsEmpty()==false;// || outputQueue.Size() > 0 || orderingList.Size() > 0 || splitPacketChannelList.Size() > 0;
2373 statistics.messagesInResendBuffer!=0;
2374 }
2375 bool ReliabilityLayer::AreAcksWaiting(void)
2376 {
2377 return acknowlegements.Size() > 0;
2378 }
2379 //-------------------------------------------------------------------------------------------------------
2380 void ReliabilityLayer::ApplyNetworkSimulator( double _packetloss, SLNet::TimeMS _minExtraPing, SLNet::TimeMS _extraPingVariance )
2381 {
2382 #ifdef _DEBUG
2383 packetloss=_packetloss;
2384 minExtraPing=_minExtraPing;
2385 extraPingVariance=_extraPingVariance;
2386 // if (ping < (unsigned int)(minExtraPing+extraPingVariance)*2)
2387 // ping=(minExtraPing+extraPingVariance)*2;
2388 #endif
2389 }
2390 //-------------------------------------------------------------------------------------------------------
2391 void ReliabilityLayer::SetSplitMessageProgressInterval(int interval)
2392 {
2393 splitMessageProgressInterval=interval;
2394 }
2395 //-------------------------------------------------------------------------------------------------------
2396 void ReliabilityLayer::SetUnreliableTimeout(SLNet::TimeMS timeoutMS)
2397 {
2398 #if CC_TIME_TYPE_BYTES==4
2399 unreliableTimeout=timeoutMS;
2400 #else
2401 unreliableTimeout=(CCTimeType)timeoutMS*(CCTimeType)1000;
2402 #endif
2403 }
2404
2405 //-------------------------------------------------------------------------------------------------------
2406 // This will return true if we should not send at this time
2407 //-------------------------------------------------------------------------------------------------------
2408 bool ReliabilityLayer::IsSendThrottled( int MTUSize )
2409 {
2410 (void) MTUSize;
2411
2412 return false;
2413 // return resendList.Size() > windowSize;
2414
2415 // Disabling this, because it can get stuck here forever
2416 /*
2417 unsigned packetsWaiting;
2418 unsigned resendListDataSize=0;
2419 unsigned i;
2420 for (i=0; i < resendList.Size(); i++)
2421 {
2422 if (resendList[i])
2423 resendListDataSize+=resendList[i]->dataBitLength;
2424 }
2425 packetsWaiting = 1 + ((BITS_TO_BYTES(resendListDataSize)) / (MTUSize - UDP_HEADER_SIZE - 10)); // 10 to roughly estimate the raknet header
2426
2427 return packetsWaiting >= windowSize;
2428 */
2429 }
2430
2431 //-------------------------------------------------------------------------------------------------------
2432 // We lost a packet
2433 //-------------------------------------------------------------------------------------------------------
2434 void ReliabilityLayer::UpdateWindowFromPacketloss( CCTimeType time )
2435 {
2436 (void) time;
2437 }
2438
2439 //-------------------------------------------------------------------------------------------------------
2440 // Increase the window size
2441 //-------------------------------------------------------------------------------------------------------
2442 void ReliabilityLayer::UpdateWindowFromAck( CCTimeType time )
2443 {
2444 (void) time;
2445 }
2446
2447 //-------------------------------------------------------------------------------------------------------
2448 // Does what the function name says
2449 //-------------------------------------------------------------------------------------------------------
2450 unsigned ReliabilityLayer::RemovePacketFromResendListAndDeleteOlderReliableSequenced( const MessageNumberType messageNumber, CCTimeType time, DataStructures::List<PluginInterface2*> &messageHandlerList, const SystemAddress &systemAddress )
2451 {
2452 (void) time;
2453 (void) messageNumber;
2454 InternalPacket * internalPacket;
2455 //InternalPacket *temp;
2456 // PacketReliability reliability; // What type of reliability algorithm to use with this packet
2457 // unsigned char orderingChannel; // What ordering channel this packet is on, if the reliability type uses ordering channels
2458 // OrderingIndexType orderingIndex; // The ID used as identification for ordering channels
2459 // unsigned j;
2460
2461 for (unsigned int messageHandlerIndex=0; messageHandlerIndex < messageHandlerList.Size(); messageHandlerIndex++)
2462 {
2463 #if CC_TIME_TYPE_BYTES==4
2464 messageHandlerList[messageHandlerIndex]->OnAck(messageNumber, systemAddress, time);
2465 #else
2466 messageHandlerList[messageHandlerIndex]->OnAck(messageNumber, systemAddress, (SLNet::TimeMS)(time/(CCTimeType)1000));
2467 #endif
2468 }
2469
2470 // Testing1
2471 // if (resendLinkedListHead)
2472 // {
2473 // InternalPacket *internalPacket = resendLinkedListHead;
2474 // do
2475 // {
2476 // internalPacket=internalPacket->resendNext;
2477 // printf("%i ", internalPacket->reliableMessageNumber.val);
2478 // } while (internalPacket!=resendLinkedListHead);
2479 // printf("\n");
2480 // }
2481
2482 // bool deleted;
2483 // deleted=resendTree.Delete(messageNumber, internalPacket);
2484 internalPacket = resendBuffer[messageNumber & RESEND_BUFFER_ARRAY_MASK];
2485 // May ask to remove twice, for example resend twice, then second ack
2486 if (internalPacket && internalPacket->reliableMessageNumber==messageNumber)
2487 {
2488 // ValidateResendList();
2489 resendBuffer[messageNumber & RESEND_BUFFER_ARRAY_MASK]=0;
2490 CC_DEBUG_PRINTF_2("AckRcv %i ", messageNumber);
2491
2492 statistics.messagesInResendBuffer--;
2493 statistics.bytesInResendBuffer-=BITS_TO_BYTES(internalPacket->dataBitLength);
2494
2495 // orderingIndex = internalPacket->orderingIndex;
2496 totalUserDataBytesAcked+=(double) BITS_TO_BYTES(internalPacket->headerLength+internalPacket->dataBitLength);
2497
2498 // Return receipt if asked for
2499 if (internalPacket->reliability>=RELIABLE_WITH_ACK_RECEIPT &&
2500 (internalPacket->splitPacketCount==0 || internalPacket->splitPacketIndex+1==internalPacket->splitPacketCount)
2501 )
2502 {
2503 InternalPacket *ackReceipt = AllocateFromInternalPacketPool();
2504 AllocInternalPacketData(ackReceipt, 5, false, _FILE_AND_LINE_ );
2505 ackReceipt->dataBitLength=BYTES_TO_BITS(5);
2506 ackReceipt->data[0]=(MessageID)ID_SND_RECEIPT_ACKED;
2507 memcpy(ackReceipt->data+sizeof(MessageID), &internalPacket->sendReceiptSerial, sizeof(internalPacket->sendReceiptSerial));
2508 outputQueue.Push(ackReceipt, _FILE_AND_LINE_ );
2509 }
2510
2511 bool isReliable;
2512 if ( internalPacket->reliability == RELIABLE ||
2513 internalPacket->reliability == RELIABLE_SEQUENCED ||
2514 internalPacket->reliability == RELIABLE_ORDERED ||
2515 internalPacket->reliability == RELIABLE_WITH_ACK_RECEIPT ||
2516 // internalPacket->reliability == RELIABLE_SEQUENCED_WITH_ACK_RECEIPT ||
2517 internalPacket->reliability == RELIABLE_ORDERED_WITH_ACK_RECEIPT
2518 )
2519 isReliable = true;
2520 else
2521 isReliable = false;
2522
2523 RemoveFromList(internalPacket, isReliable);
2524 FreeInternalPacketData(internalPacket, _FILE_AND_LINE_ );
2525 ReleaseToInternalPacketPool( internalPacket );
2526
2527
2528 return 0;
2529 }
2530 else
2531 {
2532
2533 }
2534
2535 return (unsigned)-1;
2536 }
2537
2538 //-------------------------------------------------------------------------------------------------------
2539 // Acknowledge receipt of the packet with the specified messageNumber
2540 //-------------------------------------------------------------------------------------------------------
2541 void ReliabilityLayer::SendAcknowledgementPacket( const DatagramSequenceNumberType messageNumber, CCTimeType time )
2542 {
2543
2544 // REMOVEME
2545 // printf("%p Send ack %i\n", this, messageNumber.val);
2546
2547 nextAckTimeToSend=time;
2548 acknowlegements.Insert(messageNumber);
2549
2550 //printf("ACK_DG:%i ", messageNumber.val);
2551
2552 CC_DEBUG_PRINTF_2("AckPush %i ", messageNumber);
2553
2554 }
2555
2556 //-------------------------------------------------------------------------------------------------------
2557 // Parse an internalPacket and figure out how many header bits would be
2558 // written. Returns that number
2559 //-------------------------------------------------------------------------------------------------------
2560 BitSize_t ReliabilityLayer::GetMaxMessageHeaderLengthBits( void )
2561 {
2562 InternalPacket ip;
2563 ip.reliability=RELIABLE_SEQUENCED;
2564 ip.splitPacketCount=1;
2565 return GetMessageHeaderLengthBits(&ip);
2566 }
2567 //-------------------------------------------------------------------------------------------------------
2568 BitSize_t ReliabilityLayer::GetMessageHeaderLengthBits( const InternalPacket *const internalPacket )
2569 {
2570 BitSize_t bitLength;
2571
2572 // bitStream->AlignWriteToByteBoundary(); // Potentially unaligned
2573 // tempChar=(unsigned char)internalPacket->reliability; bitStream->WriteBits( (const unsigned char *)&tempChar, 3, true ); // 3 bits to write reliability.
2574 // bool hasSplitPacket = internalPacket->splitPacketCount>0; bitStream->Write(hasSplitPacket); // Write 1 bit to indicate if splitPacketCount>0
2575 bitLength = 8*1;
2576
2577 // bitStream->AlignWriteToByteBoundary();
2578 // RakAssert(internalPacket->dataBitLength < 65535);
2579 // unsigned short s; s = (unsigned short) internalPacket->dataBitLength; bitStream->WriteAlignedVar16((const char*)& s);
2580 bitLength += 8*2;
2581
2582 if ( internalPacket->reliability == RELIABLE ||
2583 internalPacket->reliability == RELIABLE_SEQUENCED ||
2584 internalPacket->reliability == RELIABLE_ORDERED ||
2585 internalPacket->reliability == RELIABLE_WITH_ACK_RECEIPT ||
2586 // internalPacket->reliability == RELIABLE_SEQUENCED_WITH_ACK_RECEIPT ||
2587 internalPacket->reliability == RELIABLE_ORDERED_WITH_ACK_RECEIPT
2588 )
2589 bitLength += 8*3; // bitStream->Write(internalPacket->reliableMessageNumber); // Message sequence number
2590 // bitStream->AlignWriteToByteBoundary(); // Potentially nothing else to write
2591
2592
2593
2594 if ( internalPacket->reliability == UNRELIABLE_SEQUENCED ||
2595 internalPacket->reliability == RELIABLE_SEQUENCED
2596 )
2597 {
2598 bitLength += 8*3;; // bitStream->Write(internalPacket->_sequencingIndex); // Used for UNRELIABLE_SEQUENCED, RELIABLE_SEQUENCED, RELIABLE_ORDERED.
2599 }
2600
2601 if ( internalPacket->reliability == UNRELIABLE_SEQUENCED ||
2602 internalPacket->reliability == RELIABLE_SEQUENCED ||
2603 internalPacket->reliability == RELIABLE_ORDERED ||
2604 internalPacket->reliability == RELIABLE_ORDERED_WITH_ACK_RECEIPT
2605 )
2606 {
2607 bitLength += 8*3; // bitStream->Write(internalPacket->orderingIndex); // Used for UNRELIABLE_SEQUENCED, RELIABLE_SEQUENCED, RELIABLE_ORDERED.
2608 bitLength += 8*1; // tempChar=internalPacket->orderingChannel; bitStream->WriteAlignedVar8((const char*)& tempChar); // Used for UNRELIABLE_SEQUENCED, RELIABLE_SEQUENCED, RELIABLE_ORDERED. 5 bits needed, write one byte
2609 }
2610 if (internalPacket->splitPacketCount>0)
2611 {
2612 bitLength += 8*4; // bitStream->WriteAlignedVar32((const char*)& internalPacket->splitPacketCount); RakAssert(sizeof(SplitPacketIndexType)==4); // Only needed if splitPacketCount>0. 4 bytes
2613 bitLength += 8*sizeof(SplitPacketIdType); // bitStream->WriteAlignedVar16((const char*)& internalPacket->splitPacketId); RakAssert(sizeof(SplitPacketIdType)==2); // Only needed if splitPacketCount>0.
2614 bitLength += 8*4; // bitStream->WriteAlignedVar32((const char*)& internalPacket->splitPacketIndex); // Only needed if splitPacketCount>0. 4 bytes
2615 }
2616
2617 return bitLength;
2618 }
2619
2620 //-------------------------------------------------------------------------------------------------------
2621 // Parse an internalPacket and create a bitstream to represent this data
2622 //-------------------------------------------------------------------------------------------------------
2623 BitSize_t ReliabilityLayer::WriteToBitStreamFromInternalPacket(SLNet::BitStream *bitStream, const InternalPacket *const internalPacket, CCTimeType curTime )
2624 {
2625 (void) curTime;
2626
2627 BitSize_t start = bitStream->GetNumberOfBitsUsed();
2628 unsigned char tempChar;
2629
2630 // (Incoming data may be all zeros due to padding)
2631 bitStream->AlignWriteToByteBoundary(); // Potentially unaligned
2632 if (internalPacket->reliability==UNRELIABLE_WITH_ACK_RECEIPT)
2633 tempChar=UNRELIABLE;
2634 else if (internalPacket->reliability==RELIABLE_WITH_ACK_RECEIPT)
2635 tempChar=RELIABLE;
2636 else if (internalPacket->reliability==RELIABLE_ORDERED_WITH_ACK_RECEIPT)
2637 tempChar=RELIABLE_ORDERED;
2638 else
2639 tempChar=(unsigned char)internalPacket->reliability;
2640
2641 bitStream->WriteBits( (const unsigned char *)&tempChar, 3, true ); // 3 bits to write reliability.
2642
2643 bool hasSplitPacket = internalPacket->splitPacketCount>0; bitStream->Write(hasSplitPacket); // Write 1 bit to indicate if splitPacketCount>0
2644 bitStream->AlignWriteToByteBoundary();
2645 RakAssert(internalPacket->dataBitLength < 65535);
2646 unsigned short s; s = (unsigned short) internalPacket->dataBitLength; bitStream->WriteAlignedVar16((const char*)& s);
2647 if ( internalPacket->reliability == RELIABLE ||
2648 internalPacket->reliability == RELIABLE_SEQUENCED ||
2649 internalPacket->reliability == RELIABLE_ORDERED ||
2650 internalPacket->reliability == RELIABLE_WITH_ACK_RECEIPT ||
2651 internalPacket->reliability == RELIABLE_ORDERED_WITH_ACK_RECEIPT
2652 )
2653 bitStream->Write(internalPacket->reliableMessageNumber); // Used for all reliable types
2654 bitStream->AlignWriteToByteBoundary(); // Potentially nothing else to write
2655
2656 if ( internalPacket->reliability == UNRELIABLE_SEQUENCED ||
2657 internalPacket->reliability == RELIABLE_SEQUENCED
2658 )
2659 {
2660 bitStream->Write(internalPacket->sequencingIndex); // Used for UNRELIABLE_SEQUENCED, RELIABLE_SEQUENCED, RELIABLE_ORDERED.
2661 }
2662
2663 if ( internalPacket->reliability == UNRELIABLE_SEQUENCED ||
2664 internalPacket->reliability == RELIABLE_SEQUENCED ||
2665 internalPacket->reliability == RELIABLE_ORDERED ||
2666 internalPacket->reliability == RELIABLE_ORDERED_WITH_ACK_RECEIPT
2667 )
2668 {
2669 bitStream->Write(internalPacket->orderingIndex); // Used for UNRELIABLE_SEQUENCED, RELIABLE_SEQUENCED, RELIABLE_ORDERED.
2670 tempChar=internalPacket->orderingChannel; bitStream->WriteAlignedVar8((const char*)& tempChar); // Used for UNRELIABLE_SEQUENCED, RELIABLE_SEQUENCED, RELIABLE_ORDERED. 5 bits needed, write one byte
2671 }
2672
2673 if (internalPacket->splitPacketCount>0)
2674 {
2675 // printf("Write before\n");
2676 // bitStream->PrintBits();
2677
2678 bitStream->WriteAlignedVar32((const char*)& internalPacket->splitPacketCount); RakAssert(sizeof(SplitPacketIndexType)==4); // Only needed if splitPacketCount>0. 4 bytes
2679 bitStream->WriteAlignedVar16((const char*)& internalPacket->splitPacketId); RakAssert(sizeof(SplitPacketIdType)==2); // Only needed if splitPacketCount>0.
2680 bitStream->WriteAlignedVar32((const char*)& internalPacket->splitPacketIndex); // Only needed if splitPacketCount>0. 4 bytes
2681
2682 // printf("Write after\n");
2683 // bitStream->PrintBits();
2684 }
2685
2686 // Write the actual data.
2687 bitStream->WriteAlignedBytes( ( unsigned char* ) internalPacket->data, BITS_TO_BYTES( internalPacket->dataBitLength ) );
2688
2689 return bitStream->GetNumberOfBitsUsed() - start;
2690 }
2691
2692 //-------------------------------------------------------------------------------------------------------
2693 // Parse a bitstream and create an internal packet to represent this data
2694 //-------------------------------------------------------------------------------------------------------
2695 InternalPacket* ReliabilityLayer::CreateInternalPacketFromBitStream(SLNet::BitStream *bitStream, CCTimeType time )
2696 {
2697 bool bitStreamSucceeded;
2698 InternalPacket* internalPacket;
2699 unsigned char tempChar;
2700 bool hasSplitPacket=false;
2701 bool readSuccess;
2702
2703 if ( bitStream->GetNumberOfUnreadBits() < (int) sizeof( internalPacket->reliableMessageNumber ) * 8 )
2704 return 0; // leftover bits
2705
2706 internalPacket = AllocateFromInternalPacketPool();
2707 if (internalPacket==0)
2708 {
2709 // Out of memory
2710 RakAssert(0);
2711 return 0;
2712 }
2713 internalPacket->creationTime = time;
2714
2715 // (Incoming data may be all zeros due to padding)
2716 bitStream->AlignReadToByteBoundary(); // Potentially unaligned
2717 bitStream->ReadBits( ( unsigned char* ) ( &( tempChar ) ), 3 );
2718 internalPacket->reliability = ( const PacketReliability ) tempChar;
2719 readSuccess=bitStream->Read(hasSplitPacket); // Read 1 bit to indicate if splitPacketCount>0
2720 bitStream->AlignReadToByteBoundary();
2721 unsigned short s; bitStream->ReadAlignedVar16((char*)&s); internalPacket->dataBitLength=s; // Length of message (2 bytes)
2722 if ( internalPacket->reliability == RELIABLE ||
2723 internalPacket->reliability == RELIABLE_SEQUENCED ||
2724 internalPacket->reliability == RELIABLE_ORDERED
2725 // I don't write ACK_RECEIPT to the remote system
2726 // ||
2727 // internalPacket->reliability == RELIABLE_WITH_ACK_RECEIPT ||
2728 // internalPacket->reliability == RELIABLE_SEQUENCED_WITH_ACK_RECEIPT ||
2729 // internalPacket->reliability == RELIABLE_ORDERED_WITH_ACK_RECEIPT
2730 )
2731 bitStream->Read(internalPacket->reliableMessageNumber); // Message sequence number
2732 else
2733 internalPacket->reliableMessageNumber=(MessageNumberType)(const uint32_t)-1;
2734 bitStream->AlignReadToByteBoundary(); // Potentially nothing else to Read
2735
2736 if ( internalPacket->reliability == UNRELIABLE_SEQUENCED ||
2737 internalPacket->reliability == RELIABLE_SEQUENCED
2738 )
2739 {
2740 bitStream->Read(internalPacket->sequencingIndex); // Used for UNRELIABLE_SEQUENCED, RELIABLE_SEQUENCED, RELIABLE_ORDERED.
2741 }
2742
2743 if ( internalPacket->reliability == UNRELIABLE_SEQUENCED ||
2744 internalPacket->reliability == RELIABLE_SEQUENCED ||
2745 internalPacket->reliability == RELIABLE_ORDERED ||
2746 internalPacket->reliability == RELIABLE_ORDERED_WITH_ACK_RECEIPT
2747 )
2748 {
2749 bitStream->Read(internalPacket->orderingIndex); // Used for UNRELIABLE_SEQUENCED, RELIABLE_SEQUENCED, RELIABLE_ORDERED. 4 bytes.
2750 readSuccess=bitStream->ReadAlignedVar8((char*)& internalPacket->orderingChannel); // Used for UNRELIABLE_SEQUENCED, RELIABLE_SEQUENCED, RELIABLE_ORDERED. 5 bits needed, Read one byte
2751 }
2752 else
2753 internalPacket->orderingChannel=0;
2754
2755 if (hasSplitPacket)
2756 {
2757 // printf("Read before\n");
2758 // bitStream->PrintBits();
2759
2760 bitStream->ReadAlignedVar32((char*)& internalPacket->splitPacketCount); // Only needed if splitPacketCount>0. 4 bytes
2761 bitStream->ReadAlignedVar16((char*)& internalPacket->splitPacketId); // Only needed if splitPacketCount>0.
2762 readSuccess=bitStream->ReadAlignedVar32((char*)& internalPacket->splitPacketIndex); // Only needed if splitPacketCount>0. 4 bytes
2763 RakAssert(readSuccess);
2764
2765 // printf("Read after\n");
2766 // bitStream->PrintBits();
2767 }
2768 else
2769 {
2770 internalPacket->splitPacketCount=0;
2771 }
2772
2773 if (readSuccess==false ||
2774 internalPacket->dataBitLength==0 ||
2775 internalPacket->reliability>=NUMBER_OF_RELIABILITIES ||
2776 internalPacket->orderingChannel>=32 ||
2777 (hasSplitPacket && (internalPacket->splitPacketIndex >= internalPacket->splitPacketCount)))
2778 {
2779 // If this assert hits, encoding is garbage
2780 RakAssert("Encoding is garbage" && 0);
2781 ReleaseToInternalPacketPool( internalPacket );
2782 return 0;
2783 }
2784
2785 // Allocate memory to hold our data
2786 AllocInternalPacketData(internalPacket, BITS_TO_BYTES( internalPacket->dataBitLength ), false, _FILE_AND_LINE_ );
2787 RakAssert(BITS_TO_BYTES( internalPacket->dataBitLength )<MAXIMUM_MTU_SIZE);
2788
2789 if (internalPacket->data == 0)
2790 {
2791 RakAssert("Out of memory in ReliabilityLayer::CreateInternalPacketFromBitStream" && 0);
2792 notifyOutOfMemory(_FILE_AND_LINE_);
2793 ReleaseToInternalPacketPool( internalPacket );
2794 return 0;
2795 }
2796
2797 // Set the last byte to 0 so if ReadBits does not read a multiple of 8 the last bits are 0'ed out
2798 internalPacket->data[ BITS_TO_BYTES( internalPacket->dataBitLength ) - 1 ] = 0;
2799
2800 // Read the data the packet holds
2801 bitStreamSucceeded = bitStream->ReadAlignedBytes( ( unsigned char* ) internalPacket->data, BITS_TO_BYTES( internalPacket->dataBitLength ) );
2802
2803 if ( bitStreamSucceeded == false )
2804 {
2805 // If this hits, most likely the variable buff is too small in RunUpdateCycle in RakPeer.cpp
2806 RakAssert("Couldn't read all the data" && 0);
2807
2808 FreeInternalPacketData(internalPacket, _FILE_AND_LINE_ );
2809 ReleaseToInternalPacketPool( internalPacket );
2810 return 0;
2811 }
2812
2813 return internalPacket;
2814 }
2815
2816
2817 //-------------------------------------------------------------------------------------------------------
2818 // Get the SHA1 code
2819 //-------------------------------------------------------------------------------------------------------
2820 void ReliabilityLayer::GetSHA1( unsigned char * const buffer, unsigned int
2821 nbytes, char code[ SHA1_LENGTH ] )
2822 {
2823 CSHA1 sha1;
2824
2825 sha1.Reset();
2826 sha1.Update( ( unsigned char* ) buffer, nbytes );
2827 sha1.Final();
2828 memcpy( code, sha1.GetHash(), SHA1_LENGTH );
2829 }
2830
2831 //-------------------------------------------------------------------------------------------------------
2832 // Check the SHA1 code
2833 //-------------------------------------------------------------------------------------------------------
2834 bool ReliabilityLayer::CheckSHA1( char code[ SHA1_LENGTH ], unsigned char *
2835 const buffer, unsigned int nbytes )
2836 {
2837 char code2[ SHA1_LENGTH ];
2838 GetSHA1( buffer, nbytes, code2 );
2839
2840 for ( int i = 0; i < SHA1_LENGTH; i++ )
2841 if ( code[ i ] != code2[ i ] )
2842 return false;
2843
2844 return true;
2845 }
2846
2847 /*
2848 //-------------------------------------------------------------------------------------------------------
2849 // Search the specified list for sequenced packets on the specified ordering
2850 // stream, optionally skipping those with splitPacketId, and delete them
2851 //-------------------------------------------------------------------------------------------------------
2852 void ReliabilityLayer::DeleteSequencedPacketsInList( unsigned char orderingChannel, DataStructures::List<InternalPacket*>&theList, int splitPacketId )
2853 {
2854 unsigned i = 0;
2855
2856 while ( i < theList.Size() )
2857 {
2858 if ( (
2859 theList[ i ]->reliability == RELIABLE_SEQUENCED ||
2860 theList[ i ]->reliability == UNRELIABLE_SEQUENCED
2861 // ||
2862 // theList[ i ]->reliability == RELIABLE_SEQUENCED_WITH_ACK_RECEIPT ||
2863 // theList[ i ]->reliability == UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT
2864 ) &&
2865 theList[ i ]->orderingChannel == orderingChannel && ( splitPacketId == -1 || theList[ i ]->splitPacketId != (unsigned int) splitPacketId ) )
2866 {
2867 InternalPacket * internalPacket = theList[ i ];
2868 theList.RemoveAtIndex( i );
2869 FreeInternalPacketData(internalPacket, _FILE_AND_LINE_ );
2870 ReleaseToInternalPacketPool( internalPacket );
2871 }
2872
2873 else
2874 i++;
2875 }
2876 }
2877
2878 //-------------------------------------------------------------------------------------------------------
2879 // Search the specified list for sequenced packets with a value less than orderingIndex and delete them
2880 // Note - I added functionality so you can use the Queue as a list (in this case for searching) but it is less efficient to do so than a regular list
2881 //-------------------------------------------------------------------------------------------------------
2882 void ReliabilityLayer::DeleteSequencedPacketsInList( unsigned char orderingChannel, DataStructures::Queue<InternalPacket*>&theList )
2883 {
2884 InternalPacket * internalPacket;
2885 int listSize = theList.Size();
2886 int i = 0;
2887
2888 while ( i < listSize )
2889 {
2890 if ( (
2891 theList[ i ]->reliability == RELIABLE_SEQUENCED ||
2892 theList[ i ]->reliability == UNRELIABLE_SEQUENCED
2893 // ||
2894 // theList[ i ]->reliability == RELIABLE_SEQUENCED_WITH_ACK_RECEIPT ||
2895 // theList[ i ]->reliability == UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT
2896 ) && theList[ i ]->orderingChannel == orderingChannel )
2897 {
2898 internalPacket = theList[ i ];
2899 theList.RemoveAtIndex( i );
2900 FreeInternalPacketData(internalPacket, _FILE_AND_LINE_ );
2901 ReleaseToInternalPacketPool( internalPacket );
2902 listSize--;
2903 }
2904
2905 else
2906 i++;
2907 }
2908 }
2909 */
2910
2911 //-------------------------------------------------------------------------------------------------------
2912 // Returns true if newPacketOrderingIndex is older than the waitingForPacketOrderingIndex
2913 //-------------------------------------------------------------------------------------------------------
2914 bool ReliabilityLayer::IsOlderOrderedPacket( OrderingIndexType newPacketOrderingIndex, OrderingIndexType waitingForPacketOrderingIndex )
2915 {
2916 OrderingIndexType maxRange = (OrderingIndexType) (const uint32_t)-1;
2917
2918 if ( waitingForPacketOrderingIndex > maxRange/(OrderingIndexType)2 )
2919 {
2920 if ( newPacketOrderingIndex >= waitingForPacketOrderingIndex - maxRange/(OrderingIndexType)2+(OrderingIndexType)1 && newPacketOrderingIndex < waitingForPacketOrderingIndex )
2921 {
2922 return true;
2923 }
2924 }
2925
2926 else
2927 if ( newPacketOrderingIndex >= ( OrderingIndexType ) ( waitingForPacketOrderingIndex - (( OrderingIndexType ) maxRange/(OrderingIndexType)2+(OrderingIndexType)1) ) ||
2928 newPacketOrderingIndex < waitingForPacketOrderingIndex )
2929 {
2930 return true;
2931 }
2932
2933 // Old packet
2934 return false;
2935 }
2936
2937 //-------------------------------------------------------------------------------------------------------
2938 // Split the passed packet into chunks under MTU_SIZEbytes (including headers) and save those new chunks
2939 // Optimized version
2940 //-------------------------------------------------------------------------------------------------------
2941 void ReliabilityLayer::SplitPacket( InternalPacket *internalPacket )
2942 {
2943 // Doing all sizes in bytes in this function so I don't write partial bytes with split packets
2944 internalPacket->splitPacketCount = 1; // This causes GetMessageHeaderLengthBits to account for the split packet header
2945 unsigned int headerLength = (unsigned int) BITS_TO_BYTES( GetMessageHeaderLengthBits( internalPacket ) );
2946 unsigned int dataByteLength = (unsigned int) BITS_TO_BYTES( internalPacket->dataBitLength );
2947 int maximumSendBlockBytes, byteOffset, bytesToSend;
2948 SplitPacketIndexType splitPacketIndex;
2949 int i;
2950 InternalPacket **internalPacketArray;
2951
2952 maximumSendBlockBytes = GetMaxDatagramSizeExcludingMessageHeaderBytes() - BITS_TO_BYTES(GetMaxMessageHeaderLengthBits());
2953
2954 // Calculate how many packets we need to create
2955 internalPacket->splitPacketCount = ( ( dataByteLength - 1 ) / ( maximumSendBlockBytes ) + 1 );
2956
2957 // Optimization
2958 // internalPacketArray = SLNet::OP_NEW<InternalPacket*>(internalPacket->splitPacketCount, _FILE_AND_LINE_ );
2959 bool usedAlloca=false;
2960 #if USE_ALLOCA==1
2961 if (sizeof( InternalPacket* ) * internalPacket->splitPacketCount < MAX_ALLOCA_STACK_ALLOCATION)
2962 {
2963 internalPacketArray = ( InternalPacket** ) alloca( sizeof( InternalPacket* ) * internalPacket->splitPacketCount );
2964 usedAlloca=true;
2965 }
2966 else
2967 #endif
2968 internalPacketArray = (InternalPacket**) rakMalloc_Ex( sizeof(InternalPacket*) * internalPacket->splitPacketCount, _FILE_AND_LINE_ );
2969
2970 for ( i = 0; i < ( int ) internalPacket->splitPacketCount; i++ )
2971 {
2972 internalPacketArray[ i ] = AllocateFromInternalPacketPool();
2973
2974 //internalPacketArray[ i ] = (InternalPacket*) alloca( sizeof( InternalPacket ) );
2975 // internalPacketArray[ i ] = sendPacketSet[internalPacket->priority].WriteLock();
2976 *internalPacketArray[ i ]=*internalPacket;
2977 internalPacketArray[ i ]->messageNumberAssigned=false;
2978
2979 if (i!=0)
2980 internalPacket->messageInternalOrder = internalOrderIndex++;
2981 }
2982
2983 // This identifies which packet this is in the set
2984 splitPacketIndex = 0;
2985
2986 InternalPacketRefCountedData *refCounter=0;
2987
2988 // Do a loop to send out all the packets
2989 do
2990 {
2991 byteOffset = splitPacketIndex * maximumSendBlockBytes;
2992 bytesToSend = dataByteLength - byteOffset;
2993
2994 if ( bytesToSend > maximumSendBlockBytes )
2995 bytesToSend = maximumSendBlockBytes;
2996
2997 // Copy over our chunk of data
2998
2999 AllocInternalPacketData(internalPacketArray[ splitPacketIndex ], &refCounter, internalPacket->data, internalPacket->data + byteOffset);
3000 // internalPacketArray[ splitPacketIndex ]->data = (unsigned char*) rakMalloc_Ex( bytesToSend, _FILE_AND_LINE_ );
3001 // memcpy( internalPacketArray[ splitPacketIndex ]->data, internalPacket->data + byteOffset, bytesToSend );
3002
3003 if ( bytesToSend != maximumSendBlockBytes )
3004 internalPacketArray[ splitPacketIndex ]->dataBitLength = internalPacket->dataBitLength - splitPacketIndex * ( maximumSendBlockBytes << 3 );
3005 else
3006 internalPacketArray[ splitPacketIndex ]->dataBitLength = bytesToSend << 3;
3007
3008 internalPacketArray[ splitPacketIndex ]->splitPacketIndex = splitPacketIndex;
3009 internalPacketArray[ splitPacketIndex ]->splitPacketId = splitPacketId;
3010 internalPacketArray[ splitPacketIndex ]->splitPacketCount = internalPacket->splitPacketCount;
3011 RakAssert(internalPacketArray[ splitPacketIndex ]->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
3012 } while ( ++splitPacketIndex < internalPacket->splitPacketCount );
3013
3014 splitPacketId++; // It's ok if this wraps to 0
3015
3016 // InternalPacket *workingPacket;
3017
3018 // Tell the heap we are going to push a list of elements where each element in the list follows the heap order
3019 RakAssert(outgoingPacketBuffer.Size()==0 || outgoingPacketBuffer.Peek()->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
3020 outgoingPacketBuffer.StartSeries();
3021
3022 // Copy all the new packets into the split packet list
3023 for ( i = 0; i < ( int ) internalPacket->splitPacketCount; i++ )
3024 {
3025 internalPacketArray[ i ]->headerLength=headerLength;
3026 RakAssert(internalPacketArray[ i ]->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
3027 AddToUnreliableLinkedList(internalPacketArray[ i ]);
3028 // sendPacketSet[ internalPacket->priority ].Push( internalPacketArray[ i ], _FILE_AND_LINE_ );
3029 RakAssert(internalPacketArray[ i ]->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
3030 RakAssert(internalPacketArray[ i ]->messageNumberAssigned==false);
3031 outgoingPacketBuffer.PushSeries(GetNextWeight(internalPacketArray[ i ]->priority), internalPacketArray[ i ], _FILE_AND_LINE_);
3032 RakAssert(outgoingPacketBuffer.Size()==0 || outgoingPacketBuffer.Peek()->dataBitLength<BYTES_TO_BITS(MAXIMUM_MTU_SIZE));
3033 statistics.messageInSendBuffer[(int)internalPacketArray[ i ]->priority]++;
3034 statistics.bytesInSendBuffer[(int)(int)internalPacketArray[ i ]->priority]+=(double) BITS_TO_BYTES(internalPacketArray[ i ]->dataBitLength);
3035 // workingPacket=sendPacketSet[internalPacket->priority].WriteLock();
3036 // memcpy(workingPacket, internalPacketArray[ i ], sizeof(InternalPacket));
3037 // sendPacketSet[internalPacket->priority].WriteUnlock();
3038 }
3039
3040 // Do not delete, original is referenced by all split packets to avoid numerous allocations. See AllocInternalPacketData above
3041 // FreeInternalPacketData(internalPacket, _FILE_AND_LINE_ );
3042 ReleaseToInternalPacketPool( internalPacket );
3043
3044 if (usedAlloca==false)
3045 rakFree_Ex(internalPacketArray, _FILE_AND_LINE_ );
3046 }
3047
3048 //-------------------------------------------------------------------------------------------------------
3049 // Insert a packet into the split packet list
3050 //-------------------------------------------------------------------------------------------------------
3051 void ReliabilityLayer::InsertIntoSplitPacketList( InternalPacket * internalPacket, CCTimeType time )
3052 {
3053 bool objectExists;
3054 unsigned index;
3055 // Find in splitPacketChannelList if a SplitPacketChannel with this splitPacketId was already allocated. If not, allocate and insert the channel into the list.
3056 index=splitPacketChannelList.GetIndexFromKey(internalPacket->splitPacketId, &objectExists);
3057 if (objectExists==false)
3058 {
3059 SplitPacketChannel *newChannel = SLNet::OP_NEW<SplitPacketChannel>( __FILE__, __LINE__ );
3060 #if PREALLOCATE_LARGE_MESSAGES==1
3061 index=splitPacketChannelList.Insert(internalPacket->splitPacketId, newChannel, true, __FILE__,__LINE__);
3062 newChannel->returnedPacket=CreateInternalPacketCopy( internalPacket, 0, 0, time );
3063 newChannel->gotFirstPacket=false;
3064 newChannel->splitPacketsArrived=0;
3065 AllocInternalPacketData(newChannel->returnedPacket, BITS_TO_BYTES( internalPacket->dataBitLength*internalPacket->splitPacketCount ), false, __FILE__, __LINE__ );
3066 RakAssert(newChannel->returnedPacket->data);
3067 #else
3068 newChannel->firstPacket=0;
3069 index=splitPacketChannelList.Insert(internalPacket->splitPacketId, newChannel, true, __FILE__,__LINE__);
3070 // Preallocate to the final size, to avoid runtime copies
3071 newChannel->splitPacketList.Preallocate(internalPacket->splitPacketCount, __FILE__,__LINE__);
3072
3073 #endif
3074 }
3075
3076 #if PREALLOCATE_LARGE_MESSAGES==1
3077 splitPacketChannelList[index]->lastUpdateTime=time;
3078 splitPacketChannelList[index]->splitPacketsArrived++;
3079 splitPacketChannelList[index]->returnedPacket->dataBitLength+=internalPacket->dataBitLength;
3080
3081 bool dealloc;
3082 if (internalPacket->splitPacketIndex==0)
3083 {
3084 splitPacketChannelList[index]->gotFirstPacket=true;
3085 splitPacketChannelList[index]->stride=BITS_TO_BYTES(internalPacket->dataBitLength);
3086
3087 for (unsigned int j=0; j < splitPacketChannelList[index]->splitPacketList.Size(); j++)
3088 {
3089 memcpy(splitPacketChannelList[index]->returnedPacket->data+internalPacket->splitPacketIndex*splitPacketChannelList[index]->stride, internalPacket->data, (size_t) BITS_TO_BYTES(internalPacket->dataBitLength));
3090 FreeInternalPacketData(splitPacketChannelList[index]->splitPacketList[j], __FILE__, __LINE__ );
3091 ReleaseToInternalPacketPool(splitPacketChannelList[index]->splitPacketList[j]);
3092 }
3093
3094 memcpy(splitPacketChannelList[index]->returnedPacket->data, internalPacket->data, (size_t) BITS_TO_BYTES(internalPacket->dataBitLength));
3095 splitPacketChannelList[index]->splitPacketList.Clear(true,__FILE__,__LINE__);
3096 dealloc=true;
3097 }
3098 else
3099 {
3100 if (splitPacketChannelList[index]->gotFirstPacket==true)
3101 {
3102 memcpy(splitPacketChannelList[index]->returnedPacket->data+internalPacket->splitPacketIndex*splitPacketChannelList[index]->stride, internalPacket->data, (size_t) BITS_TO_BYTES(internalPacket->dataBitLength));
3103 dealloc=true;
3104 }
3105 else
3106 {
3107 splitPacketChannelList[index]->splitPacketList.Push(internalPacket,__FILE__,__LINE__);
3108 dealloc=false;
3109 }
3110 }
3111
3112 if (splitPacketChannelList[index]->gotFirstPacket==true &&
3113 splitMessageProgressInterval &&
3114 // splitPacketChannelList[index]->firstPacket &&
3115 // splitPacketChannelList[index]->splitPacketList.Size()!=splitPacketChannelList[index]->firstPacket->splitPacketCount &&
3116 // (splitPacketChannelList[index]->splitPacketList.Size()%splitMessageProgressInterval)==0
3117 splitPacketChannelList[index]->gotFirstPacket &&
3118 splitPacketChannelList[index]->splitPacketsArrived!=splitPacketChannelList[index]->returnedPacket->splitPacketCount &&
3119 (splitPacketChannelList[index]->splitPacketsArrived%splitMessageProgressInterval)==0
3120 )
3121 {
3122 // Return ID_DOWNLOAD_PROGRESS
3123 // Write splitPacketIndex (SplitPacketIndexType)
3124 // Write splitPacketCount (SplitPacketIndexType)
3125 // Write byteLength (4)
3126 // Write data, splitPacketChannelList[index]->splitPacketList[0]->data
3127 InternalPacket *progressIndicator = AllocateFromInternalPacketPool();
3128 // unsigned int len = sizeof(MessageID) + sizeof(unsigned int)*2 + sizeof(unsigned int) + (unsigned int) BITS_TO_BYTES(splitPacketChannelList[index]->firstPacket->dataBitLength);
3129 unsigned int l = (unsigned int) splitPacketChannelList[index]->stride;
3130 const unsigned int len = sizeof(MessageID) + sizeof(unsigned int)*2 + sizeof(unsigned int) + l;
3131 AllocInternalPacketData(progressIndicator, len, false, __FILE__, __LINE__ );
3132 progressIndicator->dataBitLength=BYTES_TO_BITS(len);
3133 progressIndicator->data[0]=(MessageID)ID_DOWNLOAD_PROGRESS;
3134 unsigned int temp;
3135 // temp=splitPacketChannelList[index]->splitPacketList.Size();
3136 temp=splitPacketChannelList[index]->splitPacketsArrived;
3137 memcpy(progressIndicator->data+sizeof(MessageID), &temp, sizeof(unsigned int));
3138 temp=(unsigned int)internalPacket->splitPacketCount;
3139 memcpy(progressIndicator->data+sizeof(MessageID)+sizeof(unsigned int)*1, &temp, sizeof(unsigned int));
3140 // temp=(unsigned int) BITS_TO_BYTES(splitPacketChannelList[index]->firstPacket->dataBitLength);
3141 temp=(unsigned int) BITS_TO_BYTES(l);
3142 memcpy(progressIndicator->data+sizeof(MessageID)+sizeof(unsigned int)*2, &temp, sizeof(unsigned int));
3143 //memcpy(progressIndicator->data+sizeof(MessageID)+sizeof(unsigned int)*3, splitPacketChannelList[index]->firstPacket->data, (size_t) BITS_TO_BYTES(splitPacketChannelList[index]->firstPacket->dataBitLength));
3144 memcpy(progressIndicator->data+sizeof(MessageID)+sizeof(unsigned int)*3, splitPacketChannelList[index]->returnedPacket->data, (size_t) BITS_TO_BYTES(l));
3145 }
3146
3147 if (dealloc)
3148 {
3149 FreeInternalPacketData(internalPacket, __FILE__, __LINE__ );
3150 ReleaseToInternalPacketPool(internalPacket);
3151 }
3152 #else
3153 // Insert the packet into the SplitPacketChannel
3154 splitPacketChannelList[index]->splitPacketList.Insert(internalPacket, __FILE__, __LINE__ );
3155 splitPacketChannelList[index]->lastUpdateTime=time;
3156
3157 // If the index is 0, then this is the first packet. Record this so it can be returned to the user with download progress
3158 if (internalPacket->splitPacketIndex==0)
3159 splitPacketChannelList[index]->firstPacket=internalPacket;
3160
3161 // Return download progress if we have the first packet, the list is not complete, and there are enough packets to justify it
3162 if (splitMessageProgressInterval &&
3163 splitPacketChannelList[index]->firstPacket &&
3164 splitPacketChannelList[index]->splitPacketList.Size()!=splitPacketChannelList[index]->firstPacket->splitPacketCount &&
3165 (splitPacketChannelList[index]->splitPacketList.Size()%splitMessageProgressInterval)==0)
3166 {
3167 // Return ID_DOWNLOAD_PROGRESS
3168 // Write splitPacketIndex (SplitPacketIndexType)
3169 // Write splitPacketCount (SplitPacketIndexType)
3170 // Write byteLength (4)
3171 // Write data, splitPacketChannelList[index]->splitPacketList[0]->data
3172 InternalPacket *progressIndicator = AllocateFromInternalPacketPool();
3173 unsigned int length = sizeof(MessageID) + sizeof(unsigned int)*2 + sizeof(unsigned int) + (unsigned int) BITS_TO_BYTES(splitPacketChannelList[index]->firstPacket->dataBitLength);
3174 AllocInternalPacketData(progressIndicator, length, false, __FILE__, __LINE__ );
3175 progressIndicator->dataBitLength=BYTES_TO_BITS(length);
3176 progressIndicator->data[0]=(MessageID)ID_DOWNLOAD_PROGRESS;
3177 unsigned int temp;
3178 temp=splitPacketChannelList[index]->splitPacketList.Size();
3179 memcpy(progressIndicator->data+sizeof(MessageID), &temp, sizeof(unsigned int));
3180 temp=(unsigned int)internalPacket->splitPacketCount;
3181 memcpy(progressIndicator->data+sizeof(MessageID)+sizeof(unsigned int)*1, &temp, sizeof(unsigned int));
3182 temp=(unsigned int) BITS_TO_BYTES(splitPacketChannelList[index]->firstPacket->dataBitLength);
3183 memcpy(progressIndicator->data+sizeof(MessageID)+sizeof(unsigned int)*2, &temp, sizeof(unsigned int));
3184
3185 memcpy(progressIndicator->data+sizeof(MessageID)+sizeof(unsigned int)*3, splitPacketChannelList[index]->firstPacket->data, (size_t) BITS_TO_BYTES(splitPacketChannelList[index]->firstPacket->dataBitLength));
3186 outputQueue.Push(progressIndicator, __FILE__, __LINE__ );
3187 }
3188
3189 #endif
3190 }
3191
3192 //-------------------------------------------------------------------------------------------------------
3193 // Take all split chunks with the specified splitPacketId and try to
3194 //reconstruct a packet. If we can, allocate and return it. Otherwise return 0
3195 // Optimized version
3196 //-------------------------------------------------------------------------------------------------------
3197 InternalPacket * ReliabilityLayer::BuildPacketFromSplitPacketList( SplitPacketChannel *splitPacketChannel, CCTimeType time )
3198 {
3199 #if PREALLOCATE_LARGE_MESSAGES==1
3200 InternalPacket *returnedPacket=splitPacketChannel->returnedPacket;
3201 SLNet::OP_DELETE(splitPacketChannel, __FILE__, __LINE__);
3202 (void) time;
3203 return returnedPacket;
3204 #else
3205 unsigned int j;
3206 InternalPacket * internalPacket, *splitPacket;
3207 // int splitPacketPartLength;
3208
3209 // Reconstruct
3210 internalPacket = CreateInternalPacketCopy( splitPacketChannel->splitPacketList[0], 0, 0, time );
3211 internalPacket->dataBitLength=0;
3212 for (j=0; j < splitPacketChannel->splitPacketList.Size(); j++)
3213 internalPacket->dataBitLength+=splitPacketChannel->splitPacketList[j]->dataBitLength;
3214 // splitPacketPartLength=BITS_TO_BYTES(splitPacketChannel->firstPacket->dataBitLength);
3215
3216 internalPacket->data = (unsigned char*) rakMalloc_Ex( (size_t) BITS_TO_BYTES( internalPacket->dataBitLength ), _FILE_AND_LINE_ );
3217 internalPacket->allocationScheme=InternalPacket::NORMAL;
3218
3219 BitSize_t offset = 0;
3220 for (j=0; j < splitPacketChannel->splitPacketList.Size(); j++)
3221 {
3222 splitPacket=splitPacketChannel->splitPacketList[j];
3223 memcpy(internalPacket->data + BITS_TO_BYTES(offset), splitPacket->data, (size_t)BITS_TO_BYTES(splitPacketChannel->splitPacketList[j]->dataBitLength));
3224 offset += splitPacketChannel->splitPacketList[j]->dataBitLength;
3225 }
3226
3227 for (j=0; j < splitPacketChannel->splitPacketList.Size(); j++)
3228 {
3229 FreeInternalPacketData(splitPacketChannel->splitPacketList[j], _FILE_AND_LINE_ );
3230 ReleaseToInternalPacketPool(splitPacketChannel->splitPacketList[j]);
3231 }
3232 SLNet::OP_DELETE(splitPacketChannel, __FILE__, __LINE__);
3233
3234 return internalPacket;
3235 #endif
3236 }
3237 //-------------------------------------------------------------------------------------------------------
3238 InternalPacket * ReliabilityLayer::BuildPacketFromSplitPacketList( SplitPacketIdType inSplitPacketId, CCTimeType time,
3239 RakNetSocket2 *s, SystemAddress &systemAddress, RakNetRandom *rnr,
3240 BitStream &updateBitStream)
3241 {
3242 unsigned int i;
3243 bool objectExists;
3244 SplitPacketChannel *splitPacketChannel;
3245 InternalPacket * internalPacket;
3246
3247 // Find in splitPacketChannelList the SplitPacketChannel with this splitPacketId
3248 i=splitPacketChannelList.GetIndexFromKey(inSplitPacketId, &objectExists);
3249 splitPacketChannel=splitPacketChannelList[i];
3250
3251 #if PREALLOCATE_LARGE_MESSAGES==1
3252 if (splitPacketChannel->splitPacketsArrived==splitPacketChannel->returnedPacket->splitPacketCount)
3253 #else
3254 if (splitPacketChannel->splitPacketList.Size()==splitPacketChannel->splitPacketList[0]->splitPacketCount)
3255 #endif
3256 {
3257 // Ack immediately, because for large files this can take a long time
3258 SendACKs(s, systemAddress, time, rnr, updateBitStream);
3259 internalPacket=BuildPacketFromSplitPacketList(splitPacketChannel,time);
3260 splitPacketChannelList.RemoveAtIndex(i);
3261 return internalPacket;
3262 }
3263 else
3264 {
3265 return 0;
3266 }
3267 }
3268 /*
3269 //-------------------------------------------------------------------------------------------------------
3270 // Delete any unreliable split packets that have long since expired
3271 void ReliabilityLayer::DeleteOldUnreliableSplitPackets( CCTimeType time )
3272 {
3273 unsigned i,j;
3274 i=0;
3275 while (i < splitPacketChannelList.Size())
3276 {
3277 #if CC_TIME_TYPE_BYTES==4
3278 if (time > splitPacketChannelList[i]->lastUpdateTime + timeoutTime &&
3279 #else
3280 if (time > splitPacketChannelList[i]->lastUpdateTime + (CCTimeType)timeoutTime*(CCTimeType)1000 &&
3281 #endif
3282 (splitPacketChannelList[i]->splitPacketList[0]->reliability==UNRELIABLE || splitPacketChannelList[i]->splitPacketList[0]->reliability==UNRELIABLE_SEQUENCED))
3283 {
3284 for (j=0; j < splitPacketChannelList[i]->splitPacketList.Size(); j++)
3285 {
3286 SLNet::OP_DELETE_ARRAY(splitPacketChannelList[i]->splitPacketList[j]->data, _FILE_AND_LINE_);
3287 ReleaseToInternalPacketPool(splitPacketChannelList[i]->splitPacketList[j]);
3288 }
3289 SLNet::OP_DELETE(splitPacketChannelList[i], _FILE_AND_LINE_);
3290 splitPacketChannelList.RemoveAtIndex(i);
3291 }
3292 else
3293 i++;
3294 }
3295 }
3296 */
3297
3298 //-------------------------------------------------------------------------------------------------------
3299 // Creates a copy of the specified internal packet with data copied from the original starting at dataByteOffset for dataByteLength bytes.
3300 // Does not copy any split data parameters as that information is always generated does not have any reason to be copied
3301 //-------------------------------------------------------------------------------------------------------
3302 InternalPacket * ReliabilityLayer::CreateInternalPacketCopy( InternalPacket *original, int dataByteOffset, int dataByteLength, CCTimeType time )
3303 {
3304 InternalPacket * copy = AllocateFromInternalPacketPool();
3305 #ifdef _DEBUG
3306 // Remove accessing undefined memory error
3307 memset( copy, 255, sizeof( InternalPacket ) );
3308 #endif
3309 // Copy over our chunk of data
3310
3311 if ( dataByteLength > 0 )
3312 {
3313 AllocInternalPacketData(copy, BITS_TO_BYTES(dataByteLength ), false, _FILE_AND_LINE_ );
3314 memcpy( copy->data, original->data + dataByteOffset, dataByteLength );
3315 }
3316 else
3317 copy->data = 0;
3318
3319 copy->dataBitLength = dataByteLength << 3;
3320 copy->creationTime = time;
3321 copy->nextActionTime = 0;
3322 copy->orderingIndex = original->orderingIndex;
3323 copy->sequencingIndex = original->sequencingIndex;
3324 copy->orderingChannel = original->orderingChannel;
3325 copy->reliableMessageNumber = original->reliableMessageNumber;
3326 copy->priority = original->priority;
3327 copy->reliability = original->reliability;
3328 #if PREALLOCATE_LARGE_MESSAGES==1
3329 copy->splitPacketCount = original->splitPacketCount;
3330 copy->splitPacketId = original->splitPacketId;
3331 copy->splitPacketIndex = original->splitPacketIndex;
3332 #endif
3333
3334 return copy;
3335 }
3336
3337 //-------------------------------------------------------------------------------------------------------
3338 // Get the specified ordering list
3339 //-------------------------------------------------------------------------------------------------------
3340 /*
3341 DataStructures::LinkedList<InternalPacket*> *ReliabilityLayer::GetOrderingListAtOrderingStream( unsigned char orderingChannel )
3342 {
3343 if ( orderingChannel >= orderingList.Size() )
3344 return 0;
3345
3346 return orderingList[ orderingChannel ];
3347 }
3348
3349 //-------------------------------------------------------------------------------------------------------
3350 // Add the internal packet to the ordering list in order based on order index
3351 //-------------------------------------------------------------------------------------------------------
3352 void ReliabilityLayer::AddToOrderingList( InternalPacket * internalPacket )
3353 {
3354 }
3355 */
3356
3357 //-------------------------------------------------------------------------------------------------------
3358 // Inserts a packet into the resend list in order
3359 //-------------------------------------------------------------------------------------------------------
3360 void ReliabilityLayer::InsertPacketIntoResendList( InternalPacket *internalPacket, CCTimeType time, bool firstResend, bool modifyUnacknowledgedBytes )
3361 {
3362 (void) firstResend;
3363 (void) time;
3364 (void) internalPacket;
3365
3366 AddToListTail(internalPacket, modifyUnacknowledgedBytes);
3367 RakAssert(internalPacket->nextActionTime!=0);
3368
3369 }
3370
3371 //-------------------------------------------------------------------------------------------------------
3372 // Were you ever unable to deliver a packet despite retries?
3373 //-------------------------------------------------------------------------------------------------------
3374 bool ReliabilityLayer::IsDeadConnection( void ) const
3375 {
3376 return deadConnection;
3377 }
3378
3379 //-------------------------------------------------------------------------------------------------------
3380 // Causes IsDeadConnection to return true
3381 //-------------------------------------------------------------------------------------------------------
3382 void ReliabilityLayer::KillConnection( void )
3383 {
3384 deadConnection=true;
3385 }
3386
3387
3388 //-------------------------------------------------------------------------------------------------------
3389 // Statistics
3390 //-------------------------------------------------------------------------------------------------------
3391 RakNetStatistics * ReliabilityLayer::GetStatistics( RakNetStatistics *rns )
3392 {
3393 unsigned i;
3394 SLNet::TimeUS time = SLNet::GetTimeUS();
3395 uint64_t uint64Denominator;
3396 double doubleDenominator;
3397
3398 for (i=0; i < RNS_PER_SECOND_METRICS_COUNT; i++)
3399 {
3400 statistics.valueOverLastSecond[i]=bpsMetrics[i].GetBPS1Threadsafe(time);
3401 statistics.runningTotal[i]=bpsMetrics[i].GetTotal1();
3402 }
3403
3404 memcpy(rns, &statistics, sizeof(statistics));
3405
3406 if (rns->valueOverLastSecond[USER_MESSAGE_BYTES_SENT]+rns->valueOverLastSecond[USER_MESSAGE_BYTES_RESENT]>0)
3407 rns->packetlossLastSecond=(float)((double) rns->valueOverLastSecond[USER_MESSAGE_BYTES_RESENT]/((double) rns->valueOverLastSecond[USER_MESSAGE_BYTES_SENT]+(double) rns->valueOverLastSecond[USER_MESSAGE_BYTES_RESENT]));
3408 else
3409 rns->packetlossLastSecond=0.0f;
3410
3411 rns->packetlossTotal=0.0f;
3412 uint64Denominator=(rns->runningTotal[USER_MESSAGE_BYTES_SENT]+rns->runningTotal[USER_MESSAGE_BYTES_RESENT]);
3413 if (uint64Denominator!=0&&rns->runningTotal[USER_MESSAGE_BYTES_SENT]/uint64Denominator>0)
3414 {
3415 doubleDenominator=((double) rns->runningTotal[USER_MESSAGE_BYTES_SENT]+(double) rns->runningTotal[USER_MESSAGE_BYTES_RESENT]);
3416 if(doubleDenominator!=0)
3417 {
3418 rns->packetlossTotal=(float)((double) rns->runningTotal[USER_MESSAGE_BYTES_RESENT]/doubleDenominator);
3419 }
3420 }
3421
3422 rns->isLimitedByCongestionControl=statistics.isLimitedByCongestionControl;
3423 rns->BPSLimitByCongestionControl=statistics.BPSLimitByCongestionControl;
3424 rns->isLimitedByOutgoingBandwidthLimit=statistics.isLimitedByOutgoingBandwidthLimit;
3425 rns->BPSLimitByOutgoingBandwidthLimit=statistics.BPSLimitByOutgoingBandwidthLimit;
3426
3427 return rns;
3428 }
3429
3430 //-------------------------------------------------------------------------------------------------------
3431 // Returns the number of packets in the resend queue, not counting holes
3432 //-------------------------------------------------------------------------------------------------------
3433 unsigned int ReliabilityLayer::GetResendListDataSize(void) const
3434 {
3435 // Not accurate but thread-safe. The commented version might crash if the queue is cleared while we loop through it
3436 // return resendTree.Size();
3437 return statistics.messagesInResendBuffer;
3438 }
3439
3440 //-------------------------------------------------------------------------------------------------------
3441 bool ReliabilityLayer::AckTimeout(SLNet::Time curTime)
3442 {
3443 // I check timeLastDatagramArrived-curTime because with threading it is possible that timeLastDatagramArrived is
3444 // slightly greater than curTime, in which case this is NOT an ack timeout
3445 return (timeLastDatagramArrived-curTime)>10000 && curTime-timeLastDatagramArrived>timeoutTime;
3446 }
3447 //-------------------------------------------------------------------------------------------------------
3448 CCTimeType ReliabilityLayer::GetNextSendTime(void) const
3449 {
3450 return nextSendTime;
3451 }
3452 //-------------------------------------------------------------------------------------------------------
3453 CCTimeType ReliabilityLayer::GetTimeBetweenPackets(void) const
3454 {
3455 return timeBetweenPackets;
3456 }
3457 //-------------------------------------------------------------------------------------------------------
3458 #if INCLUDE_TIMESTAMP_WITH_DATAGRAMS==1
3459 CCTimeType ReliabilityLayer::GetAckPing(void) const
3460 {
3461 return ackPing;
3462 }
3463 #endif
3464 //-------------------------------------------------------------------------------------------------------
3465 void ReliabilityLayer::ResetPacketsAndDatagrams(void)
3466 {
3467 packetsToSendThisUpdate.Clear(true, _FILE_AND_LINE_);
3468 packetsToDeallocThisUpdate.Clear(true, _FILE_AND_LINE_);
3469 packetsToSendThisUpdateDatagramBoundaries.Clear(true, _FILE_AND_LINE_);
3470 datagramsToSendThisUpdateIsPair.Clear(true, _FILE_AND_LINE_);
3471 datagramSizesInBytes.Clear(true, _FILE_AND_LINE_);
3472 datagramSizeSoFar=0;
3473 }
3474 //-------------------------------------------------------------------------------------------------------
3475 void ReliabilityLayer::PushPacket(CCTimeType time, InternalPacket *internalPacket, bool isReliable)
3476 {
3477 BitSize_t bitsForThisPacket=BYTES_TO_BITS(BITS_TO_BYTES(internalPacket->dataBitLength)+BITS_TO_BYTES(internalPacket->headerLength));
3478 datagramSizeSoFar+=bitsForThisPacket;
3479 RakAssert(BITS_TO_BYTES(datagramSizeSoFar)<MAXIMUM_MTU_SIZE-UDP_HEADER_SIZE);
3480 allDatagramSizesSoFar+=bitsForThisPacket;
3481 packetsToSendThisUpdate.Push(internalPacket, _FILE_AND_LINE_ );
3482 packetsToDeallocThisUpdate.Push(isReliable==false, _FILE_AND_LINE_ );
3483 RakAssert(internalPacket->headerLength==GetMessageHeaderLengthBits(internalPacket));
3484
3485 // This code tells me how much time elapses between when you send, and when the message actually goes out
3486 // if (internalPacket->data[0]==0)
3487 // {
3488 // SLNet::TimeMS t;
3489 // SLNet::BitStream bs(internalPacket->data+1,sizeof(t),false);
3490 // bs.Read(t);
3491 // SLNet::TimeMS curTime=SLNet::GetTimeMS();
3492 // SLNet::TimeMS diff = curTime-t;
3493 // }
3494
3495 congestionManager.OnSendBytes(time, BITS_TO_BYTES(internalPacket->dataBitLength)+BITS_TO_BYTES(internalPacket->headerLength));
3496 }
3497 //-------------------------------------------------------------------------------------------------------
3498 void ReliabilityLayer::PushDatagram(void)
3499 {
3500 if (datagramSizeSoFar>0)
3501 {
3502 packetsToSendThisUpdateDatagramBoundaries.Push(packetsToSendThisUpdate.Size(), _FILE_AND_LINE_ );
3503 datagramsToSendThisUpdateIsPair.Push(false, _FILE_AND_LINE_ );
3504 RakAssert(BITS_TO_BYTES(datagramSizeSoFar)<MAXIMUM_MTU_SIZE-UDP_HEADER_SIZE);
3505 datagramSizesInBytes.Push(BITS_TO_BYTES(datagramSizeSoFar), _FILE_AND_LINE_ );
3506 datagramSizeSoFar=0;
3507
3508 // Disable packet pairs
3509 /*
3510 if (countdownToNextPacketPair==0)
3511 {
3512 if (TagMostRecentPushAsSecondOfPacketPair())
3513 countdownToNextPacketPair=15;
3514 }
3515 else
3516 countdownToNextPacketPair--;
3517 */
3518 }
3519 }
3520 //-------------------------------------------------------------------------------------------------------
3521 bool ReliabilityLayer::TagMostRecentPushAsSecondOfPacketPair(void)
3522 {
3523 if (datagramsToSendThisUpdateIsPair.Size()>=2)
3524 {
3525 datagramsToSendThisUpdateIsPair[datagramsToSendThisUpdateIsPair.Size()-2]=true;
3526 datagramsToSendThisUpdateIsPair[datagramsToSendThisUpdateIsPair.Size()-1]=true;
3527 return true;
3528 }
3529 return false;
3530 }
3531 //-------------------------------------------------------------------------------------------------------
3532 void ReliabilityLayer::ClearPacketsAndDatagrams(void)
3533 {
3534 unsigned int i;
3535 for (i=0; i < packetsToDeallocThisUpdate.Size(); i++)
3536 {
3537 // packetsToDeallocThisUpdate holds a boolean indicating if packetsToSendThisUpdate at this index should be freed
3538 if (packetsToDeallocThisUpdate[i])
3539 {
3540 RemoveFromUnreliableLinkedList(packetsToSendThisUpdate[i]);
3541 FreeInternalPacketData(packetsToSendThisUpdate[i], _FILE_AND_LINE_ );
3542 // if (keepInternalPacketIfNeedsAck==false || packetsToSendThisUpdate[i]->reliability<RELIABLE_WITH_ACK_RECEIPT)
3543 ReleaseToInternalPacketPool( packetsToSendThisUpdate[i] );
3544 }
3545 }
3546 packetsToDeallocThisUpdate.Clear(true, _FILE_AND_LINE_);
3547 }
3548 //-------------------------------------------------------------------------------------------------------
3549 void ReliabilityLayer::MoveToListHead(InternalPacket *internalPacket)
3550 {
3551 if ( internalPacket == resendLinkedListHead )
3552 return;
3553 if (resendLinkedListHead==0)
3554 {
3555 internalPacket->resendNext=internalPacket;
3556 internalPacket->resendPrev=internalPacket;
3557 resendLinkedListHead=internalPacket;
3558 return;
3559 }
3560 internalPacket->resendPrev->resendNext = internalPacket->resendNext;
3561 internalPacket->resendNext->resendPrev = internalPacket->resendPrev;
3562 internalPacket->resendNext=resendLinkedListHead;
3563 internalPacket->resendPrev=resendLinkedListHead->resendPrev;
3564 internalPacket->resendPrev->resendNext=internalPacket;
3565 resendLinkedListHead->resendPrev=internalPacket;
3566 resendLinkedListHead=internalPacket;
3567 RakAssert(internalPacket->headerLength+internalPacket->dataBitLength>0);
3568
3569 //ValidateResendList();
3570 }
3571 //-------------------------------------------------------------------------------------------------------
3572 void ReliabilityLayer::RemoveFromList(InternalPacket *internalPacket, bool modifyUnacknowledgedBytes)
3573 {
3574 InternalPacket *newPosition;
3575 internalPacket->resendPrev->resendNext = internalPacket->resendNext;
3576 internalPacket->resendNext->resendPrev = internalPacket->resendPrev;
3577 newPosition = internalPacket->resendNext;
3578 if ( internalPacket == resendLinkedListHead )
3579 resendLinkedListHead = newPosition;
3580 if (resendLinkedListHead==internalPacket)
3581 resendLinkedListHead=0;
3582
3583 if (modifyUnacknowledgedBytes)
3584 {
3585 RakAssert(unacknowledgedBytes>=BITS_TO_BYTES(internalPacket->headerLength+internalPacket->dataBitLength));
3586 unacknowledgedBytes-=BITS_TO_BYTES(internalPacket->headerLength+internalPacket->dataBitLength);
3587 // printf("-unacknowledgedBytes:%i ", unacknowledgedBytes);
3588
3589
3590 // ValidateResendList();
3591 }
3592 }
3593 //-------------------------------------------------------------------------------------------------------
3594 void ReliabilityLayer::AddToListTail(InternalPacket *internalPacket, bool modifyUnacknowledgedBytes)
3595 {
3596 if (modifyUnacknowledgedBytes)
3597 {
3598 unacknowledgedBytes+=BITS_TO_BYTES(internalPacket->headerLength+internalPacket->dataBitLength);
3599 // printf("+unacknowledgedBytes:%i ", unacknowledgedBytes);
3600 }
3601
3602 if (resendLinkedListHead==0)
3603 {
3604 internalPacket->resendNext=internalPacket;
3605 internalPacket->resendPrev=internalPacket;
3606 resendLinkedListHead=internalPacket;
3607 return;
3608 }
3609 internalPacket->resendNext=resendLinkedListHead;
3610 internalPacket->resendPrev=resendLinkedListHead->resendPrev;
3611 internalPacket->resendPrev->resendNext=internalPacket;
3612 resendLinkedListHead->resendPrev=internalPacket;
3613
3614 // ValidateResendList();
3615
3616 }
3617 //-------------------------------------------------------------------------------------------------------
3618 void ReliabilityLayer::PopListHead(bool modifyUnacknowledgedBytes)
3619 {
3620 RakAssert(resendLinkedListHead!=0);
3621 RemoveFromList(resendLinkedListHead, modifyUnacknowledgedBytes);
3622 }
3623 //-------------------------------------------------------------------------------------------------------
3624 bool ReliabilityLayer::IsResendQueueEmpty(void) const
3625 {
3626 return resendLinkedListHead==0;
3627 }
3628 //-------------------------------------------------------------------------------------------------------
3629 void ReliabilityLayer::SendACKs(RakNetSocket2 *s, SystemAddress &systemAddress, CCTimeType time, RakNetRandom *rnr, BitStream &updateBitStream)
3630 {
3631 BitSize_t maxDatagramPayload = GetMaxDatagramSizeExcludingMessageHeaderBits();
3632
3633 while (acknowlegements.Size()>0)
3634 {
3635 // Send acks
3636 updateBitStream.Reset();
3637 DatagramHeaderFormat dhf;
3638 dhf.isACK=true;
3639 dhf.isNAK=false;
3640 dhf.isPacketPair=false;
3641 #if INCLUDE_TIMESTAMP_WITH_DATAGRAMS==1
3642 dhf.sourceSystemTime=time;
3643 #endif
3644 double B;
3645 double AS;
3646 bool hasBAndAS;
3647 if (remoteSystemNeedsBAndAS)
3648 {
3649 congestionManager.OnSendAckGetBAndAS(time, &hasBAndAS,&B,&AS);
3650 dhf.AS=(float)AS;
3651 dhf.hasBAndAS=hasBAndAS;
3652 }
3653 else
3654 dhf.hasBAndAS=false;
3655 #if INCLUDE_TIMESTAMP_WITH_DATAGRAMS==1
3656 dhf.sourceSystemTime=nextAckTimeToSend;
3657 #endif
3658 // dhf.B=(float)B;
3659 updateBitStream.Reset();
3660 dhf.Serialize(&updateBitStream);
3661 CC_DEBUG_PRINTF_1("AckSnd ");
3662 acknowlegements.Serialize(&updateBitStream, maxDatagramPayload, true);
3663 SendBitStream( s, systemAddress, &updateBitStream, rnr, time );
3664 congestionManager.OnSendAck(time,updateBitStream.GetNumberOfBytesUsed());
3665
3666 // I think this is causing a bug where if the estimated bandwidth is very low for the recipient, only acks ever get sent
3667 // congestionManager.OnSendBytes(time,UDP_HEADER_SIZE+updateBitStream.GetNumberOfBytesUsed());
3668 }
3669 }
3670 /*
3671 //-------------------------------------------------------------------------------------------------------
3672 ReliabilityLayer::DatagramMessageIDList* ReliabilityLayer::AllocateFromDatagramMessageIDPool(void)
3673 {
3674 DatagramMessageIDList*s;
3675 s=datagramMessageIDPool.Allocate( _FILE_AND_LINE_ );
3676 // Call new operator, memoryPool doesn't do this
3677 s = new ((void*)s) DatagramMessageIDList;
3678 return s;
3679 }
3680 //-------------------------------------------------------------------------------------------------------
3681 void ReliabilityLayer::ReleaseToDatagramMessageIDPool(DatagramMessageIDList* d)
3682 {
3683 d->~DatagramMessageIDList();
3684 datagramMessageIDPool.Release(d);
3685 }
3686 */
3687 //-------------------------------------------------------------------------------------------------------
3688 InternalPacket* ReliabilityLayer::AllocateFromInternalPacketPool(void)
3689 {
3690 InternalPacket *ip = internalPacketPool.Allocate( _FILE_AND_LINE_ );
3691 ip->reliableMessageNumber = (MessageNumberType) (const uint32_t)-1;
3692 ip->messageNumberAssigned=false;
3693 ip->nextActionTime = 0;
3694 ip->splitPacketCount = 0;
3695 ip->splitPacketIndex = 0;
3696 ip->splitPacketId = 0;
3697 ip->allocationScheme=InternalPacket::NORMAL;
3698 ip->data=0;
3699 ip->timesSent=0;
3700 return ip;
3701 }
3702 //-------------------------------------------------------------------------------------------------------
3703 void ReliabilityLayer::ReleaseToInternalPacketPool(InternalPacket *ip)
3704 {
3705 internalPacketPool.Release(ip, _FILE_AND_LINE_);
3706 }
3707 //-------------------------------------------------------------------------------------------------------
3708 void ReliabilityLayer::RemoveFromUnreliableLinkedList(InternalPacket *internalPacket)
3709 {
3710 if (internalPacket->reliability==UNRELIABLE ||
3711 internalPacket->reliability==UNRELIABLE_SEQUENCED ||
3712 internalPacket->reliability==UNRELIABLE_WITH_ACK_RECEIPT
3713 // ||
3714 // internalPacket->reliability==UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT
3715 )
3716 {
3717 InternalPacket *newPosition;
3718 internalPacket->unreliablePrev->unreliableNext = internalPacket->unreliableNext;
3719 internalPacket->unreliableNext->unreliablePrev = internalPacket->unreliablePrev;
3720 newPosition = internalPacket->unreliableNext;
3721 if ( internalPacket == unreliableLinkedListHead )
3722 unreliableLinkedListHead = newPosition;
3723 if (unreliableLinkedListHead==internalPacket)
3724 unreliableLinkedListHead=0;
3725 }
3726 }
3727 //-------------------------------------------------------------------------------------------------------
3728 void ReliabilityLayer::AddToUnreliableLinkedList(InternalPacket *internalPacket)
3729 {
3730 if (internalPacket->reliability==UNRELIABLE ||
3731 internalPacket->reliability==UNRELIABLE_SEQUENCED ||
3732 internalPacket->reliability==UNRELIABLE_WITH_ACK_RECEIPT
3733 // ||
3734 // internalPacket->reliability==UNRELIABLE_SEQUENCED_WITH_ACK_RECEIPT
3735 )
3736 {
3737 if (unreliableLinkedListHead==0)
3738 {
3739 internalPacket->unreliableNext=internalPacket;
3740 internalPacket->unreliablePrev=internalPacket;
3741 unreliableLinkedListHead=internalPacket;
3742 return;
3743 }
3744 internalPacket->unreliableNext=unreliableLinkedListHead;
3745 internalPacket->unreliablePrev=unreliableLinkedListHead->unreliablePrev;
3746 internalPacket->unreliablePrev->unreliableNext=internalPacket;
3747 unreliableLinkedListHead->unreliablePrev=internalPacket;
3748 }
3749 }
3750 //-------------------------------------------------------------------------------------------------------
3751 void ReliabilityLayer::ValidateResendList(void) const
3752 {
3753 // unsigned int count1=0, count2=0;
3754 // for (unsigned int i=0; i < RESEND_BUFFER_ARRAY_LENGTH; i++)
3755 // if (resendBuffer[i])
3756 // count1++;
3757 //
3758 // if (resendLinkedListHead)
3759 // {
3760 // InternalPacket *internalPacket = resendLinkedListHead;
3761 // do
3762 // {
3763 // count2++;
3764 // internalPacket=internalPacket->resendNext;
3765 // } while (internalPacket!=resendLinkedListHead);
3766 // }
3767 // RakAssert(count1==count2);
3768 // RakAssert(count2<=RESEND_BUFFER_ARRAY_LENGTH);
3769 }
3770 //-------------------------------------------------------------------------------------------------------
3771 bool ReliabilityLayer::ResendBufferOverflow(void) const
3772 {
3773 int index1 = sendReliableMessageNumberIndex & (uint32_t) RESEND_BUFFER_ARRAY_MASK;
3774 // int index2 = (sendReliableMessageNumberIndex+(uint32_t)1) & (uint32_t) RESEND_BUFFER_ARRAY_MASK;
3775 RakAssert(index1<RESEND_BUFFER_ARRAY_LENGTH);
3776 return resendBuffer[index1]!=0; // || resendBuffer[index2]!=0;
3777
3778 }
3779 //-------------------------------------------------------------------------------------------------------
3780 ReliabilityLayer::MessageNumberNode* ReliabilityLayer::GetMessageNumberNodeByDatagramIndex(DatagramSequenceNumberType index, CCTimeType *timeSent)
3781 {
3782 if (datagramHistory.IsEmpty())
3783 return 0;
3784
3785 if (congestionManager.LessThan(index, datagramHistoryPopCount))
3786 return 0;
3787
3788 DatagramSequenceNumberType offsetIntoList = index - datagramHistoryPopCount;
3789 if (offsetIntoList >= datagramHistory.Size())
3790 return 0;
3791
3792 *timeSent=datagramHistory[offsetIntoList].timeSent;
3793 return datagramHistory[offsetIntoList].head;
3794 }
3795 //-------------------------------------------------------------------------------------------------------
3796 void ReliabilityLayer::RemoveFromDatagramHistory(DatagramSequenceNumberType index)
3797 {
3798 DatagramSequenceNumberType offsetIntoList = index - datagramHistoryPopCount;
3799 MessageNumberNode *mnm = datagramHistory[offsetIntoList].head;
3800 MessageNumberNode *next;
3801 while (mnm)
3802 {
3803 next=mnm->next;
3804 datagramHistoryMessagePool.Release(mnm, _FILE_AND_LINE_);
3805 mnm=next;
3806 }
3807 datagramHistory[offsetIntoList].head=0;
3808 }
3809 //-------------------------------------------------------------------------------------------------------
3810 void ReliabilityLayer::AddFirstToDatagramHistory(DatagramSequenceNumberType datagramNumber, CCTimeType timeSent)
3811 {
3812 (void) datagramNumber;
3813 if (datagramHistory.Size()>DATAGRAM_MESSAGE_ID_ARRAY_LENGTH)
3814 {
3815 RemoveFromDatagramHistory(datagramHistoryPopCount);
3816 datagramHistory.Pop();
3817 datagramHistoryPopCount++;
3818 }
3819
3820 datagramHistory.Push(DatagramHistoryNode(0, timeSent), _FILE_AND_LINE_);
3821 // printf("%p Pushed empty DatagramHistoryNode to datagram history at index %i\n", this, datagramHistory.Size()-1);
3822 }
3823 //-------------------------------------------------------------------------------------------------------
3824 ReliabilityLayer::MessageNumberNode* ReliabilityLayer::AddFirstToDatagramHistory(DatagramSequenceNumberType datagramNumber, DatagramSequenceNumberType messageNumber, CCTimeType timeSent)
3825 {
3826 (void) datagramNumber;
3827 // RakAssert(datagramHistoryPopCount+(unsigned int) datagramHistory.Size()==datagramNumber);
3828 if (datagramHistory.Size()>DATAGRAM_MESSAGE_ID_ARRAY_LENGTH)
3829 {
3830 RemoveFromDatagramHistory(datagramHistoryPopCount);
3831 datagramHistory.Pop();
3832 datagramHistoryPopCount++;
3833 }
3834
3835 MessageNumberNode *mnm = datagramHistoryMessagePool.Allocate(_FILE_AND_LINE_);
3836 mnm->next=0;
3837 mnm->messageNumber=messageNumber;
3838 datagramHistory.Push(DatagramHistoryNode(mnm, timeSent), _FILE_AND_LINE_);
3839 // printf("%p Pushed message %i to DatagramHistoryNode to datagram history at index %i\n", this, messageNumber.val, datagramHistory.Size()-1);
3840 return mnm;
3841 }
3842 //-------------------------------------------------------------------------------------------------------
3843 ReliabilityLayer::MessageNumberNode* ReliabilityLayer::AddSubsequentToDatagramHistory(MessageNumberNode *messageNumberNode, DatagramSequenceNumberType messageNumber)
3844 {
3845 messageNumberNode->next=datagramHistoryMessagePool.Allocate(_FILE_AND_LINE_);
3846 messageNumberNode->next->messageNumber=messageNumber;
3847 messageNumberNode->next->next=0;
3848 return messageNumberNode->next;
3849 }
3850 //-------------------------------------------------------------------------------------------------------
3851 void ReliabilityLayer::AllocInternalPacketData(InternalPacket *internalPacket, InternalPacketRefCountedData **refCounter, unsigned char *externallyAllocatedPtr, unsigned char *ourOffset)
3852 {
3853 internalPacket->allocationScheme=InternalPacket::REF_COUNTED;
3854 internalPacket->data=ourOffset;
3855 if (*refCounter==0)
3856 {
3857 *refCounter = refCountedDataPool.Allocate(_FILE_AND_LINE_);
3858 // *refCounter = SLNet::OP_NEW<InternalPacketRefCountedData>(_FILE_AND_LINE_);
3859 (*refCounter)->refCount=1;
3860 (*refCounter)->sharedDataBlock=externallyAllocatedPtr;
3861 }
3862 else
3863 (*refCounter)->refCount++;
3864 internalPacket->refCountedData=(*refCounter);
3865 }
3866 //-------------------------------------------------------------------------------------------------------
3867 void ReliabilityLayer::AllocInternalPacketData(InternalPacket *internalPacket, unsigned char *externallyAllocatedPtr)
3868 {
3869 internalPacket->allocationScheme=InternalPacket::NORMAL;
3870 internalPacket->data=externallyAllocatedPtr;
3871 }
3872 //-------------------------------------------------------------------------------------------------------
3873 void ReliabilityLayer::AllocInternalPacketData(InternalPacket *internalPacket, unsigned int numBytes, bool allowStack, const char *file, unsigned int line)
3874 {
3875 if (allowStack && numBytes <= sizeof(internalPacket->stackData))
3876 {
3877 internalPacket->allocationScheme=InternalPacket::STACK;
3878 internalPacket->data=internalPacket->stackData;
3879 }
3880 else
3881 {
3882 internalPacket->allocationScheme=InternalPacket::NORMAL;
3883 internalPacket->data=(unsigned char*) rakMalloc_Ex(numBytes,file,line);
3884 }
3885 }
3886 //-------------------------------------------------------------------------------------------------------
3887 void ReliabilityLayer::FreeInternalPacketData(InternalPacket *internalPacket, const char *file, unsigned int line)
3888 {
3889 if (internalPacket==0)
3890 return;
3891
3892 if (internalPacket->allocationScheme==InternalPacket::REF_COUNTED)
3893 {
3894 if (internalPacket->refCountedData==0)
3895 return;
3896
3897 internalPacket->refCountedData->refCount--;
3898 if (internalPacket->refCountedData->refCount==0)
3899 {
3900 rakFree_Ex(internalPacket->refCountedData->sharedDataBlock, file, line );
3901 internalPacket->refCountedData->sharedDataBlock=0;
3902 // SLNet::OP_DELETE(internalPacket->refCountedData,file, line);
3903 refCountedDataPool.Release(internalPacket->refCountedData,file, line);
3904 internalPacket->refCountedData=0;
3905 }
3906 }
3907 else if (internalPacket->allocationScheme==InternalPacket::NORMAL)
3908 {
3909 if (internalPacket->data==0)
3910 return;
3911
3912 rakFree_Ex(internalPacket->data, file, line );
3913 internalPacket->data=0;
3914 }
3915 else
3916 {
3917 // Data was on stack
3918 internalPacket->data=0;
3919 }
3920 }
3921 //-------------------------------------------------------------------------------------------------------
3922 unsigned int ReliabilityLayer::GetMaxDatagramSizeExcludingMessageHeaderBytes(void)
3923 {
3924 unsigned int val = congestionManager.GetMTU() - DatagramHeaderFormat::GetDataHeaderByteLength();
3925
3926 #if LIBCAT_SECURITY==1
3927 if (useSecurity)
3928 val -= cat::AuthenticatedEncryption::OVERHEAD_BYTES;
3929 #endif
3930
3931 return val;
3932 }
3933 //-------------------------------------------------------------------------------------------------------
3934 BitSize_t ReliabilityLayer::GetMaxDatagramSizeExcludingMessageHeaderBits(void)
3935 {
3936 return BYTES_TO_BITS(GetMaxDatagramSizeExcludingMessageHeaderBytes());
3937 }
3938 //-------------------------------------------------------------------------------------------------------
3939 void ReliabilityLayer::InitHeapWeights(void)
3940 {
3941 for (int priorityLevel=0; priorityLevel < NUMBER_OF_PRIORITIES; priorityLevel++)
3942 outgoingPacketBufferNextWeights[priorityLevel]=(1<<priorityLevel)*priorityLevel+priorityLevel;
3943 }
3944 //-------------------------------------------------------------------------------------------------------
3945 reliabilityHeapWeightType ReliabilityLayer::GetNextWeight(int priorityLevel)
3946 {
3947 uint64_t next = outgoingPacketBufferNextWeights[priorityLevel];
3948 if (outgoingPacketBuffer.Size()>0)
3949 {
3950 int peekPL = outgoingPacketBuffer.Peek()->priority;
3951 reliabilityHeapWeightType weight = outgoingPacketBuffer.PeekWeight();
3952 reliabilityHeapWeightType min = weight - (1<<peekPL)*peekPL+peekPL;
3953 if (next<min)
3954 next=min + (1<<priorityLevel)*priorityLevel+priorityLevel;
3955 outgoingPacketBufferNextWeights[priorityLevel]=next+(1<<priorityLevel)*(priorityLevel+1)+priorityLevel;
3956 }
3957 else
3958 {
3959 InitHeapWeights();
3960 }
3961 return next;
3962 }
3963
3964 //-------------------------------------------------------------------------------------------------------
3965 // #if defined(RELIABILITY_LAYER_NEW_UNDEF_ALLOCATING_QUEUE)
3966 // #pragma pop_macro("new")
3967 // #undef RELIABILITY_LAYER_NEW_UNDEF_ALLOCATING_QUEUE
3968 // #endif