A Discrete-Event Network Simulator
API
tcp-ecn-test.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 NITK Surathkal
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Authors: Shravya Ks <shravya.ks0@gmail.com>
18  *
19  */
20 #include "tcp-error-model.h"
21 #include "tcp-general-test.h"
22 
23 #include "ns3/ipv4-end-point.h"
24 #include "ns3/ipv4-interface-address.h"
25 #include "ns3/ipv4-route.h"
26 #include "ns3/ipv4-routing-protocol.h"
27 #include "ns3/ipv4.h"
28 #include "ns3/ipv6-end-point.h"
29 #include "ns3/ipv6-route.h"
30 #include "ns3/ipv6-routing-protocol.h"
31 #include "ns3/ipv6.h"
32 #include "ns3/log.h"
33 #include "ns3/node.h"
34 #include "ns3/tcp-l4-protocol.h"
35 #include "ns3/tcp-rx-buffer.h"
36 #include "ns3/tcp-tx-buffer.h"
37 
38 namespace ns3
39 {
40 
41 NS_LOG_COMPONENT_DEFINE("TcpEcnTestSuite");
42 
55 class TcpEcnTest : public TcpGeneralTest
56 {
57  public:
64  TcpEcnTest(uint32_t testcase, const std::string& desc);
65 
66  protected:
67  void CWndTrace(uint32_t oldValue, uint32_t newValue) override;
68  void Rx(const Ptr<const Packet> p, const TcpHeader& h, SocketWho who) override;
69  void Tx(const Ptr<const Packet> p, const TcpHeader& h, SocketWho who) override;
71  void ConfigureProperties() override;
72 
73  private:
74  uint32_t m_cwndChangeCount;
75  uint32_t m_senderSent;
76  uint32_t m_senderReceived;
77  uint32_t m_receiverReceived;
78  uint32_t m_testcase;
79 };
80 
93 {
94  public:
99  static TypeId GetTypeId();
100 
101  uint32_t m_dataPacketSent;
102  uint8_t m_testcase;
103 
105  : TcpSocketMsgBase()
106  {
107  m_dataPacketSent = 0;
108  }
109 
115  : TcpSocketMsgBase(other)
116  {
117  }
118 
123  void SetTestCase(uint8_t testCase);
124 
125  protected:
126  uint32_t SendDataPacket(SequenceNumber32 seq, uint32_t maxSize, bool withAck) override;
127  void ReTxTimeout() override;
128  Ptr<TcpSocketBase> Fork() override;
129 };
130 
131 NS_OBJECT_ENSURE_REGISTERED(TcpSocketCongestedRouter);
132 
133 TypeId
135 {
136  static TypeId tid = TypeId("ns3::TcpSocketCongestedRouter")
138  .SetGroupName("Internet")
139  .AddConstructor<TcpSocketCongestedRouter>();
140  return tid;
141 }
142 
143 void
145 {
147 }
148 
149 void
151 {
152  m_testcase = testCase;
153 }
154 
155 uint32_t
156 TcpSocketCongestedRouter::SendDataPacket(SequenceNumber32 seq, uint32_t maxSize, bool withAck)
157 {
158  NS_LOG_FUNCTION(this << seq << maxSize << withAck);
160 
161  bool isRetransmission = false;
162  if (seq != m_tcb->m_highTxMark)
163  {
164  isRetransmission = true;
165  }
166 
167  Ptr<Packet> p = m_txBuffer->CopyFromSequence(maxSize, seq)->GetPacketCopy();
168  uint32_t sz = p->GetSize(); // Size of packet
169  uint8_t flags = withAck ? TcpHeader::ACK : 0;
170  uint32_t remainingData = m_txBuffer->SizeFromSequence(seq + SequenceNumber32(sz));
171 
172  if (withAck)
173  {
175  m_delAckCount = 0;
176  }
177 
178  // Sender should reduce the Congestion Window as a response to receiver's ECN Echo notification
179  // only once per window
181  m_ecnEchoSeq.Get() > m_ecnCWRSeq.Get() && !isRetransmission)
182  {
185  m_ecnCWRSeq = seq;
186  flags |= TcpHeader::CWR;
187  NS_LOG_INFO("CWR flags set");
188  }
189  /*
190  * Add tags for each socket option.
191  * Note that currently the socket adds both IPv4 tag and IPv6 tag
192  * if both options are set. Once the packet got to layer three, only
193  * the corresponding tags will be read.
194  */
195  if (GetIpTos())
196  {
197  SocketIpTosTag ipTosTag;
198  if (m_testcase == 5 && (m_dataPacketSent == 1 || m_dataPacketSent == 3))
199  {
200  ipTosTag.SetTos(MarkEcnCe(GetIpTos()));
201  }
202  else if (m_testcase == 6 && (m_dataPacketSent == 4 || m_dataPacketSent == 5))
203  {
204  ipTosTag.SetTos(MarkEcnCe(GetIpTos()));
205  }
206  else
207  {
208  if (m_tcb->m_ecnState != TcpSocketState::ECN_DISABLED && (GetIpTos() & 0x3) == 0)
209  {
210  ipTosTag.SetTos(MarkEcnEct0(GetIpTos()));
211  }
212  else
213  {
214  ipTosTag.SetTos(GetIpTos());
215  }
216  }
217  p->AddPacketTag(ipTosTag);
218  }
219  else
220  {
221  SocketIpTosTag ipTosTag;
222  if (m_testcase == 5 && (m_dataPacketSent == 1 || m_dataPacketSent == 3))
223  {
224  ipTosTag.SetTos(MarkEcnCe(GetIpTos()));
225  }
226  else if (m_testcase == 6 && (m_dataPacketSent == 4 || m_dataPacketSent == 5))
227  {
228  ipTosTag.SetTos(MarkEcnCe(GetIpTos()));
229  }
230  else
231  {
233  {
234  ipTosTag.SetTos(MarkEcnEct0(GetIpTos()));
235  }
236  }
237  p->AddPacketTag(ipTosTag);
238  }
239 
240  if (IsManualIpv6Tclass())
241  {
242  SocketIpv6TclassTag ipTclassTag;
243  if (m_testcase == 5 && (m_dataPacketSent == 1 || m_dataPacketSent == 3))
244  {
245  ipTclassTag.SetTclass(MarkEcnCe(GetIpv6Tclass()));
246  }
247  else if (m_testcase == 6 && (m_dataPacketSent == 4 || m_dataPacketSent == 5))
248  {
249  ipTclassTag.SetTclass(MarkEcnCe(GetIpv6Tclass()));
250  }
251  else
252  {
254  {
255  ipTclassTag.SetTclass(MarkEcnEct0(GetIpv6Tclass()));
256  }
257  else
258  {
259  ipTclassTag.SetTclass(GetIpv6Tclass());
260  }
261  }
262  p->AddPacketTag(ipTclassTag);
263  }
264  else
265  {
266  SocketIpv6TclassTag ipTclassTag;
267  if (m_testcase == 5 && (m_dataPacketSent == 1 || m_dataPacketSent == 3))
268  {
269  ipTclassTag.SetTclass(MarkEcnCe(GetIpv6Tclass()));
270  }
271  else if (m_testcase == 6 && (m_dataPacketSent == 4 || m_dataPacketSent == 5))
272  {
273  ipTclassTag.SetTclass(MarkEcnCe(GetIpv6Tclass()));
274  }
275  else
276  {
278  {
279  ipTclassTag.SetTclass(MarkEcnEct0(GetIpv6Tclass()));
280  }
281  }
282  p->AddPacketTag(ipTclassTag);
283  }
284 
285  if (IsManualIpTtl())
286  {
287  SocketIpTtlTag ipTtlTag;
288  ipTtlTag.SetTtl(GetIpTtl());
289  p->AddPacketTag(ipTtlTag);
290  }
291 
292  if (IsManualIpv6HopLimit())
293  {
294  SocketIpv6HopLimitTag ipHopLimitTag;
295  ipHopLimitTag.SetHopLimit(GetIpv6HopLimit());
296  p->AddPacketTag(ipHopLimitTag);
297  }
298 
299  uint8_t priority = GetPriority();
300  if (priority)
301  {
302  SocketPriorityTag priorityTag;
303  priorityTag.SetPriority(priority);
304  p->ReplacePacketTag(priorityTag);
305  }
306 
307  if (m_closeOnEmpty && (remainingData == 0))
308  {
309  flags |= TcpHeader::FIN;
310  if (m_state == ESTABLISHED)
311  { // On active close: I am the first one to send FIN
312  NS_LOG_DEBUG("ESTABLISHED -> FIN_WAIT_1");
314  }
315  else if (m_state == CLOSE_WAIT)
316  { // On passive close: Peer sent me FIN already
317  NS_LOG_DEBUG("CLOSE_WAIT -> LAST_ACK");
318  m_state = LAST_ACK;
319  }
320  }
321  TcpHeader header;
322  header.SetFlags(flags);
323  header.SetSequenceNumber(seq);
324  header.SetAckNumber(m_tcb->m_rxBuffer->NextRxSequence());
325  if (m_endPoint)
326  {
329  }
330  else
331  {
334  }
336  AddOptions(header);
337 
338  if (m_retxEvent.IsExpired())
339  {
340  // Schedules retransmit timeout. m_rto should be already doubled.
341 
342  NS_LOG_LOGIC(this << " SendDataPacket Schedule ReTxTimeout at time "
343  << Simulator::Now().GetSeconds() << " to expire at time "
344  << (Simulator::Now() + m_rto.Get()).GetSeconds());
346  }
347 
348  m_txTrace(p, header, this);
349 
350  if (m_endPoint)
351  {
352  m_tcp->SendPacket(p,
353  header,
357  NS_LOG_DEBUG("Send segment of size "
358  << sz << " with remaining data " << remainingData << " via TcpL4Protocol to "
359  << m_endPoint->GetPeerAddress() << ". Header " << header);
360  }
361  else
362  {
363  m_tcp->SendPacket(p,
364  header,
368  NS_LOG_DEBUG("Send segment of size "
369  << sz << " with remaining data " << remainingData << " via TcpL4Protocol to "
370  << m_endPoint6->GetPeerAddress() << ". Header " << header);
371  }
372 
373  UpdateRttHistory(seq, sz, isRetransmission);
374 
375  // Notify the application of the data being sent unless this is a retransmit
376  if (seq + sz > m_tcb->m_highTxMark)
377  {
379  this,
380  (seq + sz - m_tcb->m_highTxMark.Get()));
381  }
382  // Update highTxMark
383  m_tcb->m_highTxMark = std::max(seq + sz, m_tcb->m_highTxMark.Get());
384  return sz;
385 }
386 
389 {
390  return CopyObject<TcpSocketCongestedRouter>(this);
391 }
392 
393 TcpEcnTest::TcpEcnTest(uint32_t testcase, const std::string& desc)
394  : TcpGeneralTest(desc),
395  m_cwndChangeCount(0),
396  m_senderSent(0),
397  m_senderReceived(0),
398  m_receiverReceived(0),
399  m_testcase(testcase)
400 {
401 }
402 
403 void
405 {
407  if (m_testcase == 2 || m_testcase == 4 || m_testcase == 5 || m_testcase == 6)
408  {
410  }
411  if (m_testcase == 3 || m_testcase == 4 || m_testcase == 5 || m_testcase == 6)
412  {
414  }
415 }
416 
417 void
418 TcpEcnTest::CWndTrace(uint32_t oldValue, uint32_t newValue)
419 {
420  if (m_testcase == 6)
421  {
422  if (newValue < oldValue)
423  {
426  1,
427  "Congestion window should be reduced once per every window");
428  NS_TEST_ASSERT_MSG_EQ(newValue,
429  1000,
430  "Congestion window should not drop below 2 segments");
431  }
432  }
433 }
434 
435 void
437 {
438  if (who == RECEIVER)
439  {
440  if (m_receiverReceived == 0)
441  {
443  0,
444  "SYN should be received as first message at the receiver");
445  if (m_testcase == 2 || m_testcase == 4 || m_testcase == 5 || m_testcase == 6)
446  {
448  ((h.GetFlags()) & TcpHeader::ECE) && ((h.GetFlags()) & TcpHeader::CWR),
449  0,
450  "The flags ECE + CWR should be set in the TCP header of first message received "
451  "at receiver when sender is ECN Capable");
452  }
453  else
454  {
456  ((h.GetFlags()) & TcpHeader::ECE) && ((h.GetFlags()) & TcpHeader::CWR),
457  0,
458  "The flags ECE + CWR should not be set in the TCP header of first message "
459  "received at receiver when sender is not ECN Capable");
460  }
461  }
462  else if (m_receiverReceived == 1)
463  {
465  0,
466  "ACK should be received as second message at receiver");
467  }
468  else if (m_receiverReceived == 3 && m_testcase == 5)
469  {
471  0,
472  "Sender should send CWR on receipt of ECE");
473  }
475  }
476  else if (who == SENDER)
477  {
478  if (m_senderReceived == 0)
479  {
481  ((h.GetFlags()) & TcpHeader::ACK),
482  0,
483  "SYN+ACK received as first message at sender");
484  if (m_testcase == 4 || m_testcase == 5 || m_testcase == 6)
485  {
487  (h.GetFlags() & TcpHeader::ECE),
488  0,
489  "The flag ECE should be set in the TCP header of first message received at "
490  "sender when both receiver and sender are ECN Capable");
491  }
492  else
493  {
495  ((h.GetFlags()) & TcpHeader::ECE),
496  0,
497  "The flag ECE should not be set in the TCP header of first message received at "
498  "sender when either receiver or sender are not ECN Capable");
499  }
500  }
501  if (m_testcase == 5 && m_receiverReceived > 12)
502  {
504  0,
505  "The flag ECE should not be set in TCP header of the packet sent "
506  "by the receiver after sender sends CWR flags to receiver and "
507  "receiver receives a packet without CE bit set in IP header");
508  }
510  }
511 }
512 
513 void
515 {
516  if (who == SENDER)
517  {
518  m_senderSent++;
519  if (m_senderSent == 3)
520  {
521  SocketIpTosTag ipTosTag;
522  bool found = p->PeekPacketTag(ipTosTag);
523  uint16_t ipTos = 0;
524  if (found)
525  {
526  ipTos = static_cast<uint16_t>(ipTosTag.GetTos());
527  }
528  if (m_testcase == 4 || m_testcase == 6)
529  {
530  NS_TEST_ASSERT_MSG_EQ(ipTos,
531  0x2,
532  "IP TOS should have ECT set if ECN negotiation between "
533  "endpoints is successful");
534  }
535  else if (m_testcase == 5)
536  {
537  if (m_senderSent == 3 || m_senderSent == 5)
538  {
540  ipTos,
541  0x3,
542  "IP TOS should have CE bit set for 3rd and 5th packet sent in test case 5");
543  }
544  else
545  {
546  NS_TEST_ASSERT_MSG_EQ(ipTos,
547  0x2,
548  "IP TOS should have ECT set if ECN negotiation between "
549  "endpoints is successful");
550  }
551  }
552  else
553  {
554  NS_TEST_ASSERT_MSG_NE(ipTos,
555  0x2,
556  "IP TOS should not have ECT set if ECN negotiation between "
557  "endpoints is unsuccessful");
558  }
559  }
560  }
561 }
562 
565 {
566  if (m_testcase == 5 || m_testcase == 6)
567  {
568  Ptr<TcpSocketCongestedRouter> socket = DynamicCast<TcpSocketCongestedRouter>(
570  socket->SetTestCase(m_testcase);
571  return socket;
572  }
573  else
574  {
576  }
577 }
578 
585 {
586  public:
588  : TestSuite("tcp-ecn-test", UNIT)
589  {
591  1,
592  "ECN Negotiation Test : ECN incapable sender and ECN incapable receiver"),
594  AddTestCase(
595  new TcpEcnTest(2,
596  "ECN Negotiation Test : ECN capable sender and ECN incapable receiver"),
598  AddTestCase(
599  new TcpEcnTest(3,
600  "ECN Negotiation Test : ECN incapable sender and ECN capable receiver"),
602  AddTestCase(
603  new TcpEcnTest(4, "ECN Negotiation Test : ECN capable sender and ECN capable receiver"),
605  AddTestCase(
606  new TcpEcnTest(
607  5,
608  "ECE and CWR Functionality Test: ECN capable sender and ECN capable receiver"),
610  AddTestCase(
611  new TcpEcnTest(
612  6,
613  "Congestion Window Reduction Test :ECN capable sender and ECN capable receiver"),
615  }
616 };
617 
619 
620 } // namespace ns3
#define max(a, b)
Definition: 80211b.c:42
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
bool IsExpired() const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:69
Ipv4Address GetLocalAddress() const
Get the local address.
uint16_t GetPeerPort() const
Get the peer port.
uint16_t GetLocalPort() const
Get the local port.
Ipv4Address GetPeerAddress() const
Get the peer address.
uint16_t GetLocalPort() const
Get the local port.
Ipv6Address GetPeerAddress() const
Get the peer address.
Ipv6Address GetLocalAddress() const
Get the local address.
uint16_t GetPeerPort() const
Get the peer port.
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:960
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:983
bool ReplacePacketTag(Tag &tag)
Replace the value of a packet tag.
Definition: packet.cc:975
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:605
bool IsManualIpTtl() const
Checks if the socket has a specific IPv4 TTL set.
Definition: socket.cc:374
virtual uint8_t GetIpTtl() const
Query the value of IP Time to Live field of this socket.
Definition: socket.cc:517
uint8_t GetIpTos() const
Query the value of IP Type of Service of this socket.
Definition: socket.cc:450
Ptr< NetDevice > m_boundnetdevice
the device this socket is bound to (might be null).
Definition: socket.h:1079
virtual uint8_t GetIpv6HopLimit() const
Query the value of IP Hop Limit field of this socket.
Definition: socket.cc:542
void NotifyDataSent(uint32_t size)
Notify through the callback (if set) that some data have been sent.
Definition: socket.cc:282
uint8_t GetPriority() const
Query the priority value of this socket.
Definition: socket.cc:393
uint8_t GetIpv6Tclass() const
Query the value of IPv6 Traffic Class field of this socket.
Definition: socket.cc:492
bool IsManualIpv6HopLimit() const
Checks if the socket has a specific IPv6 Hop Limit set.
Definition: socket.cc:380
bool IsManualIpv6Tclass() const
Checks if the socket has a specific IPv6 Tclass set.
Definition: socket.cc:368
indicates whether the socket has IP_TOS set.
Definition: socket.h:1269
void SetTos(uint8_t tos)
Set the tag's TOS.
Definition: socket.cc:798
uint8_t GetTos() const
Get the tag's TOS.
Definition: socket.cc:804
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer.
Definition: socket.h:1122
void SetTtl(uint8_t ttl)
Set the tag's TTL.
Definition: socket.cc:604
This class implements a tag that carries the socket-specific HOPLIMIT of a packet to the IPv6 layer.
Definition: socket.h:1170
void SetHopLimit(uint8_t hopLimit)
Set the tag's Hop Limit.
Definition: socket.cc:668
indicates whether the socket has IPV6_TCLASS set.
Definition: socket.h:1364
void SetTclass(uint8_t tclass)
Set the tag's Tclass.
Definition: socket.cc:910
indicates whether the socket has a priority set.
Definition: socket.h:1316
void SetPriority(uint8_t priority)
Set the tag's priority.
Definition: socket.cc:854
checks if ECT, CWR and ECE bits are set correctly in different scenarios
Definition: tcp-ecn-test.cc:56
void ConfigureProperties() override
Change the configuration of the socket properties.
uint32_t m_senderSent
Number of segments sent by the sender.
Definition: tcp-ecn-test.cc:75
Ptr< TcpSocketMsgBase > CreateSenderSocket(Ptr< Node > node) override
Create and install the socket to install on the sender.
void CWndTrace(uint32_t oldValue, uint32_t newValue) override
TcpEcnTest(uint32_t testcase, const std::string &desc)
Constructor.
uint32_t m_cwndChangeCount
Number of times the congestion window did change.
Definition: tcp-ecn-test.cc:74
uint32_t m_senderReceived
Number of segments received by the sender.
Definition: tcp-ecn-test.cc:76
uint32_t m_receiverReceived
Number of segments received by the receiver.
Definition: tcp-ecn-test.cc:77
void Tx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who) override
Packet transmitted down to IP layer.
uint32_t m_testcase
Test case type.
Definition: tcp-ecn-test.cc:78
void Rx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who) override
Packet received from IP layer.
TCP ECN TestSuite.
General infrastructure for TCP testing.
virtual Ptr< TcpSocketMsgBase > CreateSenderSocket(Ptr< Node > node)
Create and install the socket to install on the sender.
SocketWho
Used as parameter of methods, specifies on what node the caller is interested (e.g.
@ RECEIVER
Receiver node.
virtual Ptr< TcpSocketMsgBase > CreateSocket(Ptr< Node > node, TypeId socketType, TypeId congControl)
Create a socket.
virtual void ConfigureProperties()
Change the configuration of the socket properties.
void SetUseEcn(SocketWho who, TcpSocketState::UseEcn_t useEcn)
Forcefully set the ECN mode of use.
TypeId m_congControlTypeId
Congestion control.
Header for the Transmission Control Protocol.
Definition: tcp-header.h:47
void SetDestinationPort(uint16_t port)
Set the destination port.
Definition: tcp-header.cc:70
void SetSequenceNumber(SequenceNumber32 sequenceNumber)
Set the sequence Number.
Definition: tcp-header.cc:76
void SetFlags(uint8_t flags)
Set flags of the header.
Definition: tcp-header.cc:88
void SetWindowSize(uint16_t windowSize)
Set the window size.
Definition: tcp-header.cc:94
void SetSourcePort(uint16_t port)
Set the source port.
Definition: tcp-header.cc:64
void SetAckNumber(SequenceNumber32 ackNumber)
Set the ACK number.
Definition: tcp-header.cc:82
uint8_t GetFlags() const
Get the flags.
Definition: tcp-header.cc:148
TracedCallback< Ptr< const Packet >, const TcpHeader &, Ptr< const TcpSocketBase > > m_txTrace
Trace of transmitted packets.
Ptr< TcpL4Protocol > m_tcp
the associated TCP L4 protocol
Ptr< TcpSocketState > m_tcb
Congestion control information.
bool m_closeOnEmpty
Close socket upon tx buffer emptied.
virtual void ReTxTimeout()
An RTO event happened.
TracedValue< Time > m_rto
Retransmit timeout.
Ptr< TcpTxBuffer > m_txBuffer
Tx buffer.
EventId m_delAckEvent
Delayed ACK timeout event.
void AddOptions(TcpHeader &tcpHeader)
Add options to TcpHeader.
TracedValue< TcpStates_t > m_state
TCP state.
uint8_t MarkEcnEct0(uint8_t tos) const
Mark ECT(0) codepoint.
EventId m_retxEvent
Retransmission event.
TracedValue< SequenceNumber32 > m_ecnCWRSeq
Sequence number of the last sent CWR.
uint32_t m_delAckCount
Delayed ACK counter.
Ipv4EndPoint * m_endPoint
the IPv4 endpoint
uint8_t MarkEcnCe(uint8_t tos) const
Mark CE codepoint.
virtual uint16_t AdvertisedWindowSize(bool scale=true) const
The amount of Rx window announced to the peer.
Ipv6EndPoint * m_endPoint6
the IPv6 endpoint
TracedValue< SequenceNumber32 > m_ecnEchoSeq
Sequence number of the last received ECN Echo.
A TCP socket which sends certain data packets with CE flags set for tests 5 and 6.
Definition: tcp-ecn-test.cc:93
uint32_t m_dataPacketSent
Number of packets sent.
void ReTxTimeout() override
An RTO event happened.
uint32_t SendDataPacket(SequenceNumber32 seq, uint32_t maxSize, bool withAck) override
Extract at most maxSize bytes from the TxBuffer at sequence seq, add the TCP header,...
uint8_t m_testcase
Test case type.
static TypeId GetTypeId()
Get the type ID.
Ptr< TcpSocketBase > Fork() override
Call CopyObject<> to clone me.
TcpSocketCongestedRouter(const TcpSocketCongestedRouter &other)
Constructor.
void SetTestCase(uint8_t testCase)
Set the test case type.
Class for inserting callbacks special points of the flow of TCP sockets.
void UpdateRttHistory(const SequenceNumber32 &seq, uint32_t sz, bool isRetransmission) override
Update the RTT history, when we send TCP segments.
TracedValue< SequenceNumber32 > m_highTxMark
Highest seqno ever sent, regardless of ReTx.
@ ECN_CWR_SENT
Sender has reduced the congestion window, and sent a packet with CWR bit set in TCP header.
@ ECN_DISABLED
ECN disabled traffic.
@ ECN_ECE_RCVD
Last ACK received had ECE bit set in TCP header.
Ptr< TcpRxBuffer > m_rxBuffer
Rx buffer (reordering buffer)
static const char *const EcnStateName[TcpSocketState::ECN_CWR_SENT+1]
Literal names of ECN states for use in log messages.
TracedValue< EcnState_t > m_ecnState
Current ECN State, represented as combination of EcnState values.
@ QUICK
Fast test.
Definition: test.h:1065
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
@ UNIT
This test suite implements a Unit Test.
Definition: test.h:1265
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
T Get() const
Get the underlying value.
Definition: traced-value.h:249
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
SequenceNumber< uint32_t, int32_t > SequenceNumber32
32 bit Sequence number.
@ ESTABLISHED
Connection established
Definition: tcp-socket.h:72
@ CLOSE_WAIT
Remote side has shutdown and is waiting for us to finish writing our data and to shutdown (we have to...
Definition: tcp-socket.h:73
@ FIN_WAIT_1
Our side has shutdown, waiting to complete transmission of remaining buffered data
Definition: tcp-socket.h:79
@ LAST_ACK
Our side has shutdown after remote has shutdown.
Definition: tcp-socket.h:76
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:144
#define NS_TEST_ASSERT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report and abort if not.
Definition: test.h:564
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static TcpEcnTestSuite g_tcpECNTestSuite
static var for test initialization