Skip to content

Commit

Permalink
tcp: (feature #2677) added cwnd events to congestion control
Browse files Browse the repository at this point in the history
  • Loading branch information
adeepkit01 authored and natale-p committed Nov 30, 2017
1 parent b0f77fb commit 0d64f71
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 6 deletions.
4 changes: 4 additions & 0 deletions src/internet/doc/tcp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,7 @@ Linux, and the following operations are defined:
virtual void IncreaseWindow (Ptr<TcpSocketState> tcb, uint32_t segmentsAcked);
virtual void PktsAcked (Ptr<TcpSocketState> tcb, uint32_t segmentsAcked,const Time& rtt);
virtual Ptr<TcpCongestionOps> Fork ();
virtual void CwndEvent (Ptr<TcpSocketState> tcb, const TcpSocketState::TcpCaEvent_t event);

The most interesting methods to write are GetSsThresh and IncreaseWindow.
The latter is called when TcpSocketBase decides that it is time to increase
Expand All @@ -817,6 +818,9 @@ are then asked to lower such value, and to return it.
PktsAcked is used in case the algorithm needs timing information (such as
RTT), and it is called each time an ACK is received.

CwndEvent is used in case the algorithm needs the state of socket during different
congestion window event.

TCP SACK and non-SACK
+++++++++++++++++++++
To avoid code duplication and the effort of maintaining two different versions
Expand Down
16 changes: 13 additions & 3 deletions src/internet/model/tcp-congestion-ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,15 +136,25 @@ class TcpCongestionOps : public Object
{
}

/**
* \brief Trigger events/calculations on occurance congestion window event
*
* This function mimics the function cwnd_event in Linux.
* The function is called in case of congestion window events.
*
* \param tcb internal congestion state
* \param event the event which triggered this function
*/
virtual void CwndEvent (Ptr<TcpSocketState> tcb,
const TcpSocketState::TcpCAEvent_t event)
{
}
// Present in Linux but not in ns-3 yet:
/* call when cwnd event occurs (optional) */
// void (*cwnd_event)(struct sock *sk, enum tcp_ca_event ev);
/* call when ack arrives (optional) */
// void (*in_ack_event)(struct sock *sk, u32 flags);
/* new value of cwnd after loss (optional) */
// u32 (*undo_cwnd)(struct sock *sk);
/* hook for packet ack accounting (optional) */
// void (*pkts_acked)(struct sock *sk, u32 num_acked, s32 rtt_us);

/**
* \brief Copy the congestion control algorithm across socket
Expand Down
12 changes: 9 additions & 3 deletions src/internet/model/tcp-socket-base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1877,7 +1877,7 @@ TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpd
// can increase cWnd)
segsAcked = (ackNumber - m_recover) / m_tcb->m_segmentSize;
m_congestionControl->PktsAcked (m_tcb, segsAcked, m_lastRtt);

m_congestionControl->CwndEvent (m_tcb, TcpSocketState::CA_EVENT_COMPLETE_CWR);
m_congestionControl->CongestionStateSet (m_tcb, TcpSocketState::CA_OPEN);
m_tcb->m_congState = TcpSocketState::CA_OPEN;
exitedFastRecovery = true;
Expand Down Expand Up @@ -2939,7 +2939,10 @@ TcpSocketBase::SendPendingData (bool withAck)
{
m_tcb->m_nextTxSequence = next;
}
if (m_bytesInFlight.Get () == 0)
{
m_congestionControl->CwndEvent (m_tcb, TcpSocketState::CA_EVENT_TX_START);
}
uint32_t sz = SendDataPacket (m_tcb->m_nextTxSequence, s, withAck);
m_tcb->m_nextTxSequence += sz;
Expand Down Expand Up @@ -3147,6 +3150,7 @@ TcpSocketBase::ReceivedData (Ptr<Packet> p, const TcpHeader& tcpHeader)
// Now send a new ACK packet acknowledging all received and delivered data
if (m_rxBuffer->Size () > m_rxBuffer->Available () || m_rxBuffer->NextRxSequence () > expectedSeq + p->GetSize ())
{ // A gap exists in the buffer, or we filled a gap: Always ACK
m_congestionControl->CwndEvent (m_tcb, TcpSocketState::CA_EVENT_NON_DELAYED_ACK);
SendEmptyPacket (TcpHeader::ACK);
}
else
Expand All @@ -3155,6 +3159,7 @@ TcpSocketBase::ReceivedData (Ptr<Packet> p, const TcpHeader& tcpHeader)
{
m_delAckEvent.Cancel ();
m_delAckCount = 0;
m_congestionControl->CwndEvent (m_tcb, TcpSocketState::CA_EVENT_NON_DELAYED_ACK);
SendEmptyPacket (TcpHeader::ACK);
}
else if (m_delAckEvent.IsExpired ())
Expand Down Expand Up @@ -3347,7 +3352,7 @@ TcpSocketBase::ReTxTimeout ()

// Cwnd set to 1 MSS
m_tcb->m_cWnd = m_tcb->m_segmentSize;

m_congestionControl->CwndEvent (m_tcb, TcpSocketState::CA_EVENT_LOSS);
m_congestionControl->CongestionStateSet (m_tcb, TcpSocketState::CA_LOSS);
m_tcb->m_congState = TcpSocketState::CA_LOSS;

Expand All @@ -3372,6 +3377,7 @@ void
TcpSocketBase::DelAckTimeout (void)
{
m_delAckCount = 0;
m_congestionControl->CwndEvent (m_tcb, TcpSocketState::CA_EVENT_DELAYED_ACK);
SendEmptyPacket (TcpHeader::ACK);
}

Expand Down
13 changes: 13 additions & 0 deletions src/internet/model/tcp-socket-base.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,19 @@ class TcpSocketState : public Object
CA_LAST_STATE /**< Used only in debug messages */
} TcpCongState_t;

// Note: "not triggered" events are currently not triggered by the code.
typedef enum
{
CA_EVENT_TX_START, /**< first transmit when no packets in flight */
CA_EVENT_CWND_RESTART, /**< congestion window restart. Not triggered */
CA_EVENT_COMPLETE_CWR, /**< end of congestion recovery */
CA_EVENT_LOSS, /**< loss timeout */
CA_EVENT_ECN_NO_CE, /**< ECT set, but not CE marked. Not triggered */
CA_EVENT_ECN_IS_CE, /**< received CE marked IP packet. Not triggered */
CA_EVENT_DELAYED_ACK, /**< Delayed ack is sent */
CA_EVENT_NON_DELAYED_ACK, /**< Non-delayed ack is sent */
} TcpCAEvent_t;

/**
* \ingroup tcp
* TracedValue Callback signature for TcpCongState_t
Expand Down

0 comments on commit 0d64f71

Please sign in to comment.