@@ -397,57 +397,70 @@ int CSndBuffer::addBufferFromFile(fstream& ifs, int len)
397
397
return total;
398
398
}
399
399
400
- int CSndBuffer::readData (CPacket& w_packet, steady_clock::time_point& w_srctime, int kflgs)
400
+ int CSndBuffer::readData (CPacket& w_packet, steady_clock::time_point& w_srctime, int kflgs, int & w_seqnoinc )
401
401
{
402
- // No data to read
403
- if (m_pCurrBlock == m_pLastBlock)
404
- return 0 ;
402
+ int readlen = 0 ;
403
+ w_seqnoinc = 0 ;
404
+
405
+ while (m_pCurrBlock != m_pLastBlock)
406
+ {
407
+ // Make the packet REFLECT the data stored in the buffer.
408
+ w_packet.m_pcData = m_pCurrBlock->m_pcData ;
409
+ readlen = m_pCurrBlock->m_iLength ;
410
+ w_packet.setLength (readlen);
411
+ w_packet.m_iSeqNo = m_pCurrBlock->m_iSeqNo ;
412
+
413
+ // XXX This is probably done because the encryption should happen
414
+ // just once, and so this sets the encryption flags to both msgno bitset
415
+ // IN THE PACKET and IN THE BLOCK. This is probably to make the encryption
416
+ // happen at the time when scheduling a new packet to send, but the packet
417
+ // must remain in the send buffer until it's ACKed. For the case of rexmit
418
+ // the packet will be taken "as is" (that is, already encrypted).
419
+ //
420
+ // The problem is in the order of things:
421
+ // 0. When the application stores the data, some of the flags for PH_MSGNO are set.
422
+ // 1. The readData() is called to get the original data sent by the application.
423
+ // 2. The data are original and must be encrypted. They WILL BE encrypted, later.
424
+ // 3. So far we are in readData() so the encryption flags must be updated NOW because
425
+ // later we won't have access to the block's data.
426
+ // 4. After exiting from readData(), the packet is being encrypted. It's immediately
427
+ // sent, however the data must remain in the sending buffer until they are ACKed.
428
+ // 5. In case when rexmission is needed, the second overloaded version of readData
429
+ // is being called, and the buffer + PH_MSGNO value is extracted. All interesting
430
+ // flags must be present and correct at that time.
431
+ //
432
+ // The only sensible way to fix this problem is to encrypt the packet not after
433
+ // extracting from here, but when the packet is stored into CSndBuffer. The appropriate
434
+ // flags for PH_MSGNO will be applied directly there. Then here the value for setting
435
+ // PH_MSGNO will be set as is.
436
+
437
+ if (kflgs == -1 )
438
+ {
439
+ HLOGC (bslog.Debug , log << CONID () << " CSndBuffer: ERROR: encryption required and not possible. NOT SENDING." );
440
+ readlen = 0 ;
441
+ }
442
+ else
443
+ {
444
+ m_pCurrBlock->m_iMsgNoBitset |= MSGNO_ENCKEYSPEC::wrap (kflgs);
445
+ }
405
446
406
- // Make the packet REFLECT the data stored in the buffer.
407
- w_packet.m_pcData = m_pCurrBlock->m_pcData ;
408
- int readlen = m_pCurrBlock->m_iLength ;
409
- w_packet.setLength (readlen);
410
- w_packet.m_iSeqNo = m_pCurrBlock->m_iSeqNo ;
411
-
412
- // XXX This is probably done because the encryption should happen
413
- // just once, and so this sets the encryption flags to both msgno bitset
414
- // IN THE PACKET and IN THE BLOCK. This is probably to make the encryption
415
- // happen at the time when scheduling a new packet to send, but the packet
416
- // must remain in the send buffer until it's ACKed. For the case of rexmit
417
- // the packet will be taken "as is" (that is, already encrypted).
418
- //
419
- // The problem is in the order of things:
420
- // 0. When the application stores the data, some of the flags for PH_MSGNO are set.
421
- // 1. The readData() is called to get the original data sent by the application.
422
- // 2. The data are original and must be encrypted. They WILL BE encrypted, later.
423
- // 3. So far we are in readData() so the encryption flags must be updated NOW because
424
- // later we won't have access to the block's data.
425
- // 4. After exiting from readData(), the packet is being encrypted. It's immediately
426
- // sent, however the data must remain in the sending buffer until they are ACKed.
427
- // 5. In case when rexmission is needed, the second overloaded version of readData
428
- // is being called, and the buffer + PH_MSGNO value is extracted. All interesting
429
- // flags must be present and correct at that time.
430
- //
431
- // The only sensible way to fix this problem is to encrypt the packet not after
432
- // extracting from here, but when the packet is stored into CSndBuffer. The appropriate
433
- // flags for PH_MSGNO will be applied directly there. Then here the value for setting
434
- // PH_MSGNO will be set as is.
447
+ Block* p = m_pCurrBlock;
448
+ w_packet.m_iMsgNo = m_pCurrBlock->m_iMsgNoBitset ;
449
+ w_srctime = m_pCurrBlock->m_tsOriginTime ;
450
+ m_pCurrBlock = m_pCurrBlock->m_pNext ;
435
451
436
- if (kflgs == -1 )
437
- {
438
- HLOGC (bslog.Debug , log << CONID () << " CSndBuffer: ERROR: encryption required and not possible. NOT SENDING." );
439
- readlen = 0 ;
440
- }
441
- else
442
- {
443
- m_pCurrBlock->m_iMsgNoBitset |= MSGNO_ENCKEYSPEC::wrap (kflgs);
444
- }
445
-
446
- w_packet.m_iMsgNo = m_pCurrBlock->m_iMsgNoBitset ;
447
- w_srctime = m_pCurrBlock->m_tsOriginTime ;
448
- m_pCurrBlock = m_pCurrBlock->m_pNext ;
452
+ if ((p->m_iTTL >= 0 ) && (count_milliseconds (steady_clock::now () - w_srctime) > p->m_iTTL ))
453
+ {
454
+ LOGC (bslog.Warn , log << CONID () << " CSndBuffer: skipping packet %" << p->m_iSeqNo << " #" << p->getMsgSeq () << " with TTL=" << p->m_iTTL );
455
+ // Skip this packet due to TTL expiry.
456
+ readlen = 0 ;
457
+ ++w_seqnoinc;
458
+ continue ;
459
+ }
449
460
450
- HLOGC (bslog.Debug , log << CONID () << " CSndBuffer: extracting packet size=" << readlen << " to send" );
461
+ HLOGC (bslog.Debug , log << CONID () << " CSndBuffer: extracting packet size=" << readlen << " to send" );
462
+ break ;
463
+ }
451
464
452
465
return readlen;
453
466
}
0 commit comments