Project Approach - rajitaaa/ECN-plus-algorithm-in-ns3 GitHub Wiki
In AddSocketTags function,present in tcp-socket-base.h,created a boolean variable hasEct whhich is false by default.
void AddSocketTags (const Ptr<Packet> &p,bool hasEct=false) const;
In tcp-socket-base.cc,created boolean variables to check if a packet has SYN, ACK and ECE bits set.
If a packet is SYN-ACK and ECN-capable: Set hasEct = true.
Call the function AddSocketTags(packet, hasEct) which is responsible for setting tags in the IP header.
If hasEct is false, it works like normal ECN and sets IP bits in data packets if both sender and receiver are ECN-capable.
If hasEct is true (SYN-ACK packet), IP bits(ECT) will be marked in the IP header before sending the SYN-ACK packet and prevent the dropping of SYN-ACK.
if (hasSyn & hasAck & hasEce)
{
m_tcb->m_ecnState = TcpSocketState::ECN_IDLE;
AddSocketTags (p,true);
}
else
{
AddSocketTags (p,false);
}
Reduce cwnd of sender and send the next packet marking the ECE bit.
CASE 1: Data has to be uploaded: cwnd of sender has to be reduced. Data is sent from the reduced cwnd.
CASE 2: Data has to be downloaded: cwnd of sender being reduced will not affect the network. The other end has to reduce its cwnd, taken care in ClassicECN.
So in both cases, we can safely reduce the cwnd of the sender.
if (tcpflags & (TcpHeader::SYN | TcpHeader::ACK)
&& m_tcb->m_nextTxSequence + SequenceNumber32 (1) == tcpHeader.GetAckNumber ())
{
if( m_ecnMode == EcnMode_t::ClassicEcn && m_tcb->m_ecnState == TcpSocketState::ECN_CE_RCVD) //If a SYN-ACK packet is marked by router
{
NS_LOG_DEBUG ("cwnd changed to 1 SMSS");
m_tcb->m_cWnd = 1 * m_tcb->m_segmentSize;
m_tcb->m_cWndInfl = m_tcb->m_cWnd;
m_tcb->m_highTxMark = ++m_tcb->m_nextTxSequence;
m_congestionControl->CongestionStateSet (m_tcb, TcpSocketState::CA_OPEN);
m_state = ESTABLISHED;
m_connected = true;
m_retxEvent.Cancel ();
m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (1));
m_txBuffer->SetHeadSequence (m_tcb->m_nextTxSequence);
SendEmptyPacket (TcpHeader::ACK | TcpHeader::ECE);
}
else {
NS_LOG_DEBUG ("SYN_SENT -> ESTABLISHED");
m_congestionControl->CongestionStateSet (m_tcb, TcpSocketState::CA_OPEN);
m_state = ESTABLISHED;
m_connected = true;
m_retxEvent.Cancel ();
m_rxBuffer->SetNextRxSequence (tcpHeader.GetSequenceNumber () + SequenceNumber32 (1));
m_tcb->m_highTxMark = ++m_tcb->m_nextTxSequence;
m_txBuffer->SetHeadSequence (m_tcb->m_nextTxSequence);
SendEmptyPacket (TcpHeader::ACK);
}
}
We tested the code using some existing topologies in ns-3 and saved the pcap file. We found out the the ECT bits in the IP header of the SYN-ACK packets were marked successfully. (set to 10)