Bug 2914

Summary: receiver advertise window goes to 0
Product: ns-3 Reporter: Menglei Zhang <mengleizhang.mz>
Component: tcpAssignee: natale.patriciello
Status: RESOLVED FIXED    
Severity: critical CC: ns-bugs, tomh
Priority: P3    
Version: ns-3.28   
Hardware: All   
OS: All   

Description Menglei Zhang 2018-04-24 13:21:12 UTC
In the function TcpSocketBase::AdvertisedWindowSize () line 293-295,

 2993       uint32_t max = m_rxBuffer->MaxRxSequence ().GetValue ();
 2994       uint32_t next = m_rxBuffer->NextRxSequence ().GetValue ();
 2995       w = ( max > next ) ? max - next : 0;

Once the max overflow, w bemuses 0 and stop the TCP socket from sending packets. The fix is replace these lines with

      w = (m_rxBuffer->MaxRxSequence () > m_rxBuffer->NextRxSequence ()) ?
    m_rxBuffer->MaxRxSequence () - m_rxBuffer->NextRxSequence () : 0;

Menglei
Comment 1 Tom Henderson 2018-04-24 13:34:37 UTC
(In reply to Menglei Zhang from comment #0)
> In the function TcpSocketBase::AdvertisedWindowSize () line 293-295,
> 
>  2993       uint32_t max = m_rxBuffer->MaxRxSequence ().GetValue ();
>  2994       uint32_t next = m_rxBuffer->NextRxSequence ().GetValue ();
>  2995       w = ( max > next ) ? max - next : 0;
> 
> Once the max overflow, w bemuses 0 and stop the TCP socket from sending
> packets. The fix is replace these lines with
> 
>       w = (m_rxBuffer->MaxRxSequence () > m_rxBuffer->NextRxSequence ()) ?
>     m_rxBuffer->MaxRxSequence () - m_rxBuffer->NextRxSequence () : 0;
> 

I agree with the part about performing arithmetic on the SequenceNumber type rather than converting to underlying numeric type (GetValue()) for arithmetic.  However, it seems that the above statement is still mixing types (SequenceNumber and uint32_t), so perhaps a little more work is needed.
Comment 2 natale.patriciello 2018-06-01 17:40:37 UTC
I am the source of this code.

However, the following:

w = m_rxBuffer->MaxRxSequence () - m_rxBuffer->NextRxSequence ();


produces a warning (the result is an int, and I'm trying to assign it to an unsigned int). How can I solve this using only SequenceNumber and without a cast?
Comment 3 Tom Henderson 2018-06-07 00:37:07 UTC
(In reply to natale.patriciello from comment #2)
> I am the source of this code.
> 
> However, the following:
> 
> w = m_rxBuffer->MaxRxSequence () - m_rxBuffer->NextRxSequence ();
> 
> 
> produces a warning (the result is an int, and I'm trying to assign it to an
> unsigned int). How can I solve this using only SequenceNumber and without a
> cast?

I don't think you can, but what is wrong with this solution?

-      uint32_t max = m_rxBuffer->MaxRxSequence ().GetValue ();
-      uint32_t next = m_rxBuffer->NextRxSequence ().GetValue ();
-      w = ( max > next ) ? max - next : 0;
+      NS_ASSERT_MSG (m_rxBuffer->MaxRxSequence () - m_rxBuffer->NextRxSequence () >= 0, "Unexpected sequence number values");
+      w = static_cast<uint32_t> (m_rxBuffer->MaxRxSequence () - m_rxBuffer->NextRxSequence ());
Comment 4 natale.patriciello 2018-06-08 12:49:35 UTC
Pushed the Tom version in 13642:bc07f96a4742

Thanks to everyone