A Discrete-Event Network Simulator
API
tcp-general-test.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Natale Patriciello <natale.patriciello@gmail.com>
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  */
18 #define __STDC_LIMIT_MACROS
19 #include "tcp-general-test.h"
20 
21 #include "ns3/internet-stack-helper.h"
22 #include "ns3/ipv4-address-helper.h"
23 #include "ns3/ipv4-end-point.h"
24 #include "ns3/ipv6-end-point.h"
25 #include "ns3/log.h"
26 #include "ns3/node-container.h"
27 #include "ns3/queue.h"
28 #include "ns3/rtt-estimator.h"
29 #include "ns3/simple-net-device-helper.h"
30 #include "ns3/tcp-header.h"
31 #include "ns3/tcp-l4-protocol.h"
32 #include "ns3/tcp-rx-buffer.h"
33 #include "ns3/tcp-socket-base.h"
34 #include "ns3/tcp-tx-buffer.h"
35 #include "ns3/test.h"
36 
37 using namespace ns3;
38 
39 NS_LOG_COMPONENT_DEFINE("TcpGeneralTest");
40 
41 TcpGeneralTest::TcpGeneralTest(const std::string& desc)
42  : TestCase(desc),
43  m_congControlTypeId(TcpNewReno::GetTypeId()),
44  m_recoveryTypeId(TcpClassicRecovery::GetTypeId()),
45  m_remoteAddr(Ipv4Address::GetAny(), 4477)
46 {
47  NS_LOG_FUNCTION(this << desc);
48 }
49 
51 {
53 }
54 
55 void
57 {
58  NS_LOG_FUNCTION(this << socket);
59  Ptr<Packet> packet;
60  Address from;
61 
62  while ((packet = socket->RecvFrom(from)))
63  {
64  if (packet->GetSize() == 0)
65  { // EOF
66  break;
67  }
68  }
69 }
70 
71 void
73  uint32_t pktSize,
74  uint32_t pktCount,
75  Time pktInterval)
76 {
77  NS_LOG_FUNCTION(this << " " << pktSize << " " << pktCount << " " << pktInterval.GetSeconds());
78  if (pktCount > 0)
79  {
80  socket->Send(Create<Packet>(pktSize));
81  Simulator::Schedule(pktInterval,
83  this,
84  socket,
85  pktSize,
86  pktCount - 1,
87  pktInterval);
88  }
89  else
90  {
91  socket->Close();
92  }
93 }
94 
95 void
97 {
98  FinalChecks();
99 
101  NS_LOG_INFO("Done.");
102 }
103 
104 void
106 {
107  NS_LOG_FUNCTION(this);
108 
113  SetAppPktSize(500);
114  SetAppPktCount(10);
116  SetMTU(1500);
117 }
118 
119 void
121 {
122  NS_LOG_FUNCTION(this);
125  SetSegmentSize(SENDER, 500);
126  SetSegmentSize(RECEIVER, 500);
127 }
128 
129 void
131 {
133 
134  NS_LOG_INFO("Create nodes.");
136  nodes.Create(2);
137 
139  internet.Install(nodes);
140 
142 
144 
145  SimpleNetDeviceHelper helperChannel;
146  helperChannel.SetNetDevicePointToPointMode(true);
147 
148  NetDeviceContainer net = helperChannel.Install(nodes, channel);
149 
152 
153  Ptr<SimpleNetDevice> senderDev = DynamicCast<SimpleNetDevice>(net.Get(0));
154  Ptr<SimpleNetDevice> receiverDev = DynamicCast<SimpleNetDevice>(net.Get(1));
155 
156  senderDev->SetMtu(m_mtu);
157  senderDev->GetQueue()->TraceConnect("Drop",
158  "SENDER",
160  senderDev->TraceConnect("PhyRxDrop", "sender", MakeCallback(&TcpGeneralTest::PhyDropCb, this));
161 
162  receiverDev->SetMtu(m_mtu);
163  receiverDev->GetQueue()->TraceConnect("Drop",
164  "RECEIVER",
166  receiverDev->TraceConnect("PhyRxDrop",
167  "RECEIVER",
169 
170  senderDev->SetReceiveErrorModel(senderEM);
171  receiverDev->SetReceiveErrorModel(receiverEM);
172 
174  ipv4.SetBase("10.1.1.0", "255.255.255.0");
175  Ipv4InterfaceContainer i = ipv4.Assign(net);
176  Ipv4Address serverAddress = i.GetAddress(1);
177  // Ipv4Address clientAddress = i.GetAddress (0);
178 
179  NS_LOG_INFO("Create sockets.");
180  // Receiver socket on n1
182 
184  m_receiverSocket->SetAcceptCallback(MakeNullCallback<bool, Ptr<Socket>, const Address&>(),
190  m_receiverSocket->SetAfterRetransmitCb(MakeCallback(&TcpGeneralTest::AfterRetransmitCb, this));
191  m_receiverSocket->SetBeforeRetransmitCb(
194  m_receiverSocket->SetUpdateRttHistoryCb(
196  m_receiverSocket->TraceConnectWithoutContext("Tx",
198  m_receiverSocket->TraceConnectWithoutContext("Rx",
200 
202  m_receiverSocket->Bind(local);
203 
205  m_senderSocket->SetCloseCallbacks(MakeCallback(&TcpGeneralTest::NormalCloseCb, this),
208  m_senderSocket->SetProcessedAckCb(MakeCallback(&TcpGeneralTest::ProcessedAckCb, this));
209  m_senderSocket->SetAfterRetransmitCb(MakeCallback(&TcpGeneralTest::AfterRetransmitCb, this));
210  m_senderSocket->SetBeforeRetransmitCb(MakeCallback(&TcpGeneralTest::BeforeRetransmitCb, this));
211  m_senderSocket->SetDataSentCallback(MakeCallback(&TcpGeneralTest::DataSentCb, this));
212  m_senderSocket->SetUpdateRttHistoryCb(MakeCallback(&TcpGeneralTest::UpdateRttHistoryCb, this));
213  m_senderSocket->TraceConnectWithoutContext("CongestionWindow",
215  m_senderSocket->TraceConnectWithoutContext("CongestionWindowInflated",
217  m_senderSocket->TraceConnectWithoutContext("SlowStartThreshold",
219  m_senderSocket->TraceConnectWithoutContext("CongState",
221  m_senderSocket->TraceConnectWithoutContext("Tx",
223  m_senderSocket->TraceConnectWithoutContext("Rx",
225  m_senderSocket->TraceConnectWithoutContext("RTT",
227  m_senderSocket->TraceConnectWithoutContext(
228  "BytesInFlight",
230  m_senderSocket->TraceConnectWithoutContext("RTO",
232  m_senderSocket->TraceConnectWithoutContext("NextTxSequence",
234  m_senderSocket->TraceConnectWithoutContext(
235  "HighestSequence",
237  m_senderSocket->m_rateOps->TraceConnectWithoutContext(
238  "TcpRateUpdated",
240  m_senderSocket->m_rateOps->TraceConnectWithoutContext(
241  "TcpRateSampleUpdated",
243 
244  m_remoteAddr = InetSocketAddress(serverAddress, 4477);
245 
247 
248  m_receiverSocket->Listen();
249  m_receiverSocket->ShutdownSend();
250 
253  m_startTime,
255  this,
257  m_pktSize,
258  m_pktCount,
260 
261  NS_LOG_INFO("Run Simulation.");
262  Simulator::Run();
263 }
264 
265 void
267 {
268  NS_LOG_INFO(this);
269  m_senderSocket->Connect(m_remoteAddr);
270 }
271 
272 void
273 TcpGeneralTest::HandleAccept(Ptr<Socket> socket, const Address& from [[maybe_unused]])
274 {
278 }
279 
282 {
283  Ptr<SimpleChannel> ch = CreateObject<SimpleChannel>();
284 
285  ch->SetAttribute("Delay", TimeValue(m_propagationDelay));
286 
287  return ch;
288 }
289 
291 TcpGeneralTest::CreateSocket(Ptr<Node> node, TypeId socketType, TypeId congControl)
292 {
293  return CreateSocket(node, socketType, congControl, m_recoveryTypeId);
294 }
295 
298  TypeId socketType,
299  TypeId congControl,
300  TypeId recoveryAlgorithm)
301 {
302  ObjectFactory rttFactory;
303  ObjectFactory congestionAlgorithmFactory;
304  ObjectFactory recoveryAlgorithmFactory;
305  ObjectFactory socketFactory;
306 
308  congestionAlgorithmFactory.SetTypeId(congControl);
309  recoveryAlgorithmFactory.SetTypeId(recoveryAlgorithm);
310  socketFactory.SetTypeId(socketType);
311 
312  Ptr<RttEstimator> rtt = rttFactory.Create<RttEstimator>();
313  Ptr<TcpSocketMsgBase> socket = DynamicCast<TcpSocketMsgBase>(socketFactory.Create());
314  Ptr<TcpCongestionOps> algo = congestionAlgorithmFactory.Create<TcpCongestionOps>();
315  Ptr<TcpRecoveryOps> recovery = recoveryAlgorithmFactory.Create<TcpRecoveryOps>();
316 
317  socket->SetNode(node);
318  socket->SetTcp(node->GetObject<TcpL4Protocol>());
319  socket->SetRtt(rtt);
320  socket->SetCongestionControlAlgorithm(algo);
321  socket->SetRecoveryAlgorithm(recovery);
322  return socket;
323 }
324 
327 {
328  return nullptr;
329 }
330 
333 {
334  return nullptr;
335 }
336 
339 {
341 }
342 
345 {
347 }
348 
349 void
351 {
352  if (context == "SENDER")
353  {
354  QueueDrop(SENDER);
355  }
356  else if (context == "RECEIVER")
357  {
359  }
360  else
361  {
362  NS_FATAL_ERROR("Packet dropped in a queue, but queue not recognized");
363  }
364 }
365 
366 void
367 TcpGeneralTest::PhyDropCb(std::string context, Ptr<const Packet> /* p */)
368 {
369  if (context == "SENDER")
370  {
371  PhyDrop(SENDER);
372  }
373  else if (context == "RECEIVER")
374  {
375  PhyDrop(RECEIVER);
376  }
377  else
378  {
379  NS_FATAL_ERROR("Packet dropped in a queue, but queue not recognized");
380  }
381 }
382 
383 void
385 {
386  if (socket->GetNode() == m_receiverSocket->GetNode())
387  {
389  }
390  else if (socket->GetNode() == m_senderSocket->GetNode())
391  {
393  }
394  else
395  {
396  NS_FATAL_ERROR("Closed socket, but not recognized");
397  }
398 }
399 
400 void
402  const SequenceNumber32& seq,
403  uint32_t sz,
404  bool isRetransmission)
405 {
406  if (tcp->GetNode() == m_receiverSocket->GetNode())
407  {
408  UpdatedRttHistory(seq, sz, isRetransmission, RECEIVER);
409  }
410  else if (tcp->GetNode() == m_senderSocket->GetNode())
411  {
412  UpdatedRttHistory(seq, sz, isRetransmission, SENDER);
413  }
414  else
415  {
416  NS_FATAL_ERROR("Closed socket, but not recognized");
417  }
418 }
419 
420 void
422  const Ptr<const TcpSocketBase> tcp)
423 {
424  if (tcp->GetNode() == m_receiverSocket->GetNode())
425  {
427  }
428  else if (tcp->GetNode() == m_senderSocket->GetNode())
429  {
430  AfterRTOExpired(tcb, SENDER);
431  }
432  else
433  {
434  NS_FATAL_ERROR("Closed socket, but not recognized");
435  }
436 }
437 
438 void
440  const Ptr<const TcpSocketBase> tcp)
441 {
442  if (tcp->GetNode() == m_receiverSocket->GetNode())
443  {
445  }
446  else if (tcp->GetNode() == m_senderSocket->GetNode())
447  {
448  BeforeRTOExpired(tcb, SENDER);
449  }
450  else
451  {
452  NS_FATAL_ERROR("Closed socket, but not recognized");
453  }
454 }
455 
456 void
458 {
459  if (socket->GetNode() == m_receiverSocket->GetNode())
460  {
461  DataSent(size, RECEIVER);
462  }
463  else if (socket->GetNode() == m_senderSocket->GetNode())
464  {
465  DataSent(size, SENDER);
466  }
467  else
468  {
469  NS_FATAL_ERROR("Closed socket, but not recognized");
470  }
471 }
472 
473 void
475 {
476  if (socket->GetNode() == m_receiverSocket->GetNode())
477  {
479  }
480  else if (socket->GetNode() == m_senderSocket->GetNode())
481  {
483  }
484  else
485  {
486  NS_FATAL_ERROR("Closed socket, but not recognized");
487  }
488 }
489 
490 void
492 {
493  NS_LOG_FUNCTION(this << p << h << who);
494 }
495 
496 void
498 {
499  NS_LOG_FUNCTION(this << p << h << who);
500 }
501 
502 void
504  const TcpHeader& h,
505  const Ptr<const TcpSocketBase> tcp)
506 {
507  if (tcp->GetNode() == m_receiverSocket->GetNode())
508  {
509  RcvAck(tcp->m_tcb, h, RECEIVER);
510  }
511  else if (tcp->GetNode() == m_senderSocket->GetNode())
512  {
513  RcvAck(tcp->m_tcb, h, SENDER);
514  }
515  else
516  {
517  NS_FATAL_ERROR("Received ACK but socket not recognized");
518  }
519 }
520 
521 void
523  const TcpHeader& h,
524  const Ptr<const TcpSocketBase> tcp)
525 {
526  if (tcp->GetNode() == m_receiverSocket->GetNode())
527  {
528  Tx(p, h, RECEIVER);
529  }
530  else if (tcp->GetNode() == m_senderSocket->GetNode())
531  {
532  Tx(p, h, SENDER);
533  }
534  else
535  {
536  NS_FATAL_ERROR("Received ACK but socket not recognized");
537  }
538 }
539 
540 void
542  const TcpHeader& h,
543  const Ptr<const TcpSocketBase> tcp)
544 {
545  if (tcp->GetNode() == m_receiverSocket->GetNode())
546  {
547  Rx(p, h, RECEIVER);
548  }
549  else if (tcp->GetNode() == m_senderSocket->GetNode())
550  {
551  Rx(p, h, SENDER);
552  }
553  else
554  {
555  NS_FATAL_ERROR("Received ACK but socket not recognized");
556  }
557 }
558 
559 void
561  const TcpHeader& h,
563 {
564  if (tcp->GetNode() == m_receiverSocket->GetNode())
565  {
566  ProcessedAck(tcp->m_tcb, h, RECEIVER);
567  }
568  else if (tcp->GetNode() == m_senderSocket->GetNode())
569  {
570  ProcessedAck(tcp->m_tcb, h, SENDER);
571  }
572  else
573  {
574  NS_FATAL_ERROR("Received ACK but socket not recognized");
575  }
576 }
577 
578 void
580 {
581  NS_LOG_FUNCTION(this << tcp);
582 
583  m_receiverSocket = tcp;
584 }
585 
586 uint32_t
588 {
589  if (who == SENDER)
590  {
591  return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_retxThresh;
592  }
593  else if (who == RECEIVER)
594  {
595  return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->m_retxThresh;
596  }
597  else
598  {
599  NS_FATAL_ERROR("Not defined");
600  }
601 }
602 
603 uint32_t
605 {
606  if (who == SENDER)
607  {
608  return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_dupAckCount;
609  }
610  else if (who == RECEIVER)
611  {
612  return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->m_dupAckCount;
613  }
614  else
615  {
616  NS_FATAL_ERROR("Not defined");
617  }
618 }
619 
620 uint32_t
622 {
623  if (who == SENDER)
624  {
625  return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_delAckMaxCount;
626  }
627  else if (who == RECEIVER)
628  {
629  return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->m_delAckMaxCount;
630  }
631  else
632  {
633  NS_FATAL_ERROR("Not defined");
634  }
635 }
636 
637 Time
639 {
640  if (who == SENDER)
641  {
642  return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->GetDelAckTimeout();
643  }
644  else if (who == RECEIVER)
645  {
646  return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->GetDelAckTimeout();
647  }
648  else
649  {
650  NS_FATAL_ERROR("Not defined");
651  }
652 }
653 
654 uint32_t
656 {
657  if (who == SENDER)
658  {
659  return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->GetSegSize();
660  }
661  else if (who == RECEIVER)
662  {
663  return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->GetSegSize();
664  }
665  else
666  {
667  NS_FATAL_ERROR("Not defined");
668  }
669 }
670 
673 {
674  return GetTcb(who)->m_highTxMark;
675 }
676 
677 uint32_t
679 {
680  if (who == SENDER)
681  {
682  return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->GetInitialCwnd();
683  }
684  else if (who == RECEIVER)
685  {
686  return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->GetInitialCwnd();
687  }
688  else
689  {
690  NS_FATAL_ERROR("Not defined");
691  }
692 }
693 
694 uint32_t
696 {
697  if (who == SENDER)
698  {
699  return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->GetInitialSSThresh();
700  }
701  else if (who == RECEIVER)
702  {
703  return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->GetInitialSSThresh();
704  }
705  else
706  {
707  NS_FATAL_ERROR("Not defined");
708  }
709 }
710 
711 Time
713 {
714  if (who == SENDER)
715  {
716  return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_rto.Get();
717  }
718  else if (who == RECEIVER)
719  {
720  return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->m_rto.Get();
721  }
722  else
723  {
724  NS_FATAL_ERROR("Not defined");
725  }
726 }
727 
728 Time
730 {
731  if (who == SENDER)
732  {
733  return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_minRto;
734  }
735  else if (who == RECEIVER)
736  {
737  return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->m_minRto;
738  }
739  else
740  {
741  NS_FATAL_ERROR("Not defined");
742  }
743 }
744 
745 Time
747 {
748  if (who == SENDER)
749  {
750  return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_cnTimeout;
751  }
752  else if (who == RECEIVER)
753  {
754  return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->m_cnTimeout;
755  }
756  else
757  {
758  NS_FATAL_ERROR("Not defined");
759  }
760 }
761 
764 {
765  if (who == SENDER)
766  {
767  return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_rtt;
768  }
769  else if (who == RECEIVER)
770  {
771  return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->m_rtt;
772  }
773  else
774  {
775  NS_FATAL_ERROR("Not defined");
776  }
777 }
778 
779 Time
781 {
782  if (who == SENDER)
783  {
784  return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_clockGranularity;
785  }
786  else if (who == RECEIVER)
787  {
788  return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->m_clockGranularity;
789  }
790  else
791  {
792  NS_FATAL_ERROR("Not defined");
793  }
794 }
795 
798 {
799  if (who == SENDER)
800  {
801  return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_state.Get();
802  }
803  else if (who == RECEIVER)
804  {
805  return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->m_state.Get();
806  }
807  else
808  {
809  NS_FATAL_ERROR("Not defined");
810  }
811 }
812 
813 uint32_t
815 {
816  if (who == SENDER)
817  {
818  return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_rWnd.Get();
819  }
820  else if (who == RECEIVER)
821  {
822  return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->m_rWnd.Get();
823  }
824  else
825  {
826  NS_FATAL_ERROR("Not defined");
827  }
828 }
829 
830 EventId
832 {
833  if (who == SENDER)
834  {
835  return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_persistEvent;
836  }
837  else if (who == RECEIVER)
838  {
839  return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->m_persistEvent;
840  }
841  else
842  {
843  NS_FATAL_ERROR("Not defined");
844  }
845 }
846 
847 Time
849 {
850  if (who == SENDER)
851  {
852  return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_persistTimeout;
853  }
854  else if (who == RECEIVER)
855  {
856  return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->m_persistTimeout;
857  }
858  else
859  {
860  NS_FATAL_ERROR("Not defined");
861  }
862 }
863 
866 {
867  if (who == SENDER)
868  {
869  return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_tcb;
870  }
871  else if (who == RECEIVER)
872  {
873  return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->m_tcb;
874  }
875  else
876  {
877  NS_FATAL_ERROR("Not defined");
878  }
879 }
880 
883 {
884  if (who == SENDER)
885  {
886  return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_tcb->m_rxBuffer;
887  }
888  else if (who == RECEIVER)
889  {
890  return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->m_tcb->m_rxBuffer;
891  }
892  else
893  {
894  NS_FATAL_ERROR("Not defined");
895  }
896 }
897 
900 {
901  if (who == SENDER)
902  {
903  return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_txBuffer;
904  }
905  else if (who == RECEIVER)
906  {
907  return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->m_txBuffer;
908  }
909  else
910  {
911  NS_FATAL_ERROR("Not defined");
912  }
913 }
914 
915 void
917 {
918  if (who == SENDER)
919  {
920  m_senderSocket->SetRcvBufSize(size);
921  }
922  else if (who == RECEIVER)
923  {
924  m_receiverSocket->SetRcvBufSize(size);
925  }
926  else
927  {
928  NS_FATAL_ERROR("Not defined");
929  }
930 }
931 
932 void
934 {
935  if (who == SENDER)
936  {
937  m_senderSocket->SetSegSize(segmentSize);
938  }
939  else if (who == RECEIVER)
940  {
941  m_receiverSocket->SetSegSize(segmentSize);
942  }
943  else
944  {
945  NS_FATAL_ERROR("Not defined");
946  }
947 }
948 
949 void
950 TcpGeneralTest::SetInitialCwnd(SocketWho who, uint32_t initialCwnd)
951 {
952  if (who == SENDER)
953  {
954  m_senderSocket->SetInitialCwnd(initialCwnd);
955  }
956  else if (who == RECEIVER)
957  {
958  m_receiverSocket->SetInitialCwnd(initialCwnd);
959  }
960  else
961  {
962  NS_FATAL_ERROR("Not defined");
963  }
964 }
965 
966 void
968 {
969  if (who == SENDER)
970  {
971  m_senderSocket->SetDelAckMaxCount(count);
972  }
973  else if (who == RECEIVER)
974  {
975  m_receiverSocket->SetDelAckMaxCount(count);
976  }
977  else
978  {
979  NS_FATAL_ERROR("Not defined");
980  }
981 }
982 
983 void
985 {
986  if (who == SENDER)
987  {
988  m_senderSocket->SetUseEcn(useEcn);
989  }
990  else if (who == RECEIVER)
991  {
992  m_receiverSocket->SetUseEcn(useEcn);
993  }
994  else
995  {
996  NS_FATAL_ERROR("Not defined");
997  }
998 }
999 
1000 void
1002 {
1003  if (who == SENDER)
1004  {
1005  m_senderSocket->SetPacingStatus(pacing);
1006  }
1007  else if (who == RECEIVER)
1008  {
1009  m_receiverSocket->SetPacingStatus(pacing);
1010  }
1011  else
1012  {
1013  NS_FATAL_ERROR("Not defined");
1014  }
1015 }
1016 
1017 void
1019 {
1020  if (who == SENDER)
1021  {
1022  m_senderSocket->SetPaceInitialWindow(paceWindow);
1023  }
1024  else if (who == RECEIVER)
1025  {
1026  m_receiverSocket->SetPaceInitialWindow(paceWindow);
1027  }
1028  else
1029  {
1030  NS_FATAL_ERROR("Not defined");
1031  }
1032 }
1033 
1034 void
1035 TcpGeneralTest::SetInitialSsThresh(SocketWho who, uint32_t initialSsThresh)
1036 {
1037  if (who == SENDER)
1038  {
1039  m_senderSocket->SetInitialSSThresh(initialSsThresh);
1040  }
1041  else if (who == RECEIVER)
1042  {
1043  m_receiverSocket->SetInitialSSThresh(initialSsThresh);
1044  }
1045  else
1046  {
1047  NS_FATAL_ERROR("Not defined");
1048  }
1049 }
1050 
1052 
1053 TypeId
1055 {
1056  static TypeId tid = TypeId("ns3::TcpSocketMsgBase")
1058  .SetGroupName("Internet")
1059  .AddConstructor<TcpSocketMsgBase>();
1060  return tid;
1061 }
1062 
1065 {
1066  return CopyObject<TcpSocketMsgBase>(this);
1067 }
1068 
1069 void
1071 {
1072  NS_ASSERT(!cb.IsNull());
1073  m_rcvAckCb = cb;
1074 }
1075 
1076 void
1078 {
1079  NS_ASSERT(!cb.IsNull());
1080  m_processedAckCb = cb;
1081 }
1082 
1083 void
1085 {
1086  NS_ASSERT(!cb.IsNull());
1087  m_afterRetrCallback = cb;
1088 }
1089 
1090 void
1092 {
1093  NS_ASSERT(!cb.IsNull());
1094  m_beforeRetrCallback = cb;
1095 }
1096 
1097 void
1099 {
1101  m_rcvAckCb(packet, tcpHeader, this);
1102 
1103  TcpSocketBase::ReceivedAck(packet, tcpHeader);
1104 
1105  m_processedAckCb(packet, tcpHeader, this);
1106 }
1107 
1108 void
1110 {
1111  m_beforeRetrCallback(m_tcb, this);
1113  m_afterRetrCallback(m_tcb, this);
1114 }
1115 
1116 void
1118 {
1119  NS_ASSERT(!cb.IsNull());
1120  m_forkCb = cb;
1121 }
1122 
1123 void
1125 {
1126  NS_ASSERT(!cb.IsNull());
1127  m_updateRttCb = cb;
1128 }
1129 
1130 void
1131 TcpSocketMsgBase::UpdateRttHistory(const SequenceNumber32& seq, uint32_t sz, bool isRetransmission)
1132 {
1133  TcpSocketBase::UpdateRttHistory(seq, sz, isRetransmission);
1134  if (!m_updateRttCb.IsNull())
1135  {
1136  m_updateRttCb(this, seq, sz, isRetransmission);
1137  }
1138 }
1139 
1140 void
1142  const TcpHeader& tcpHeader,
1143  const Address& fromAddress,
1144  const Address& toAddress)
1145 {
1146  TcpSocketBase::CompleteFork(p, tcpHeader, fromAddress, toAddress);
1147 
1148  if (!m_forkCb.IsNull())
1149  {
1150  m_forkCb(this);
1151  }
1152 }
1153 
1155 
1156 TypeId
1158 {
1159  static TypeId tid = TypeId("ns3::TcpSocketSmallAcks")
1161  .SetGroupName("Internet")
1162  .AddConstructor<TcpSocketSmallAcks>();
1163  return tid;
1164 }
1165 
1166 /*
1167  * Send empty packet, copied/pasted from TcpSocketBase
1168  *
1169  * The rationale for copying/pasting is that we need to edit a little the
1170  * code inside. Since there isn't a well-defined division of duties,
1171  * we are forced to do this.
1172  */
1173 void
1175 {
1176  Ptr<Packet> p = Create<Packet>();
1177  TcpHeader header;
1179 
1180  /*
1181  * Add tags for each socket option.
1182  * Note that currently the socket adds both IPv4 tag and IPv6 tag
1183  * if both options are set. Once the packet got to layer three, only
1184  * the corresponding tags will be read.
1185  */
1186  if (GetIpTos())
1187  {
1188  SocketIpTosTag ipTosTag;
1189  ipTosTag.SetTos(GetIpTos());
1190  p->AddPacketTag(ipTosTag);
1191  }
1192 
1193  if (IsManualIpv6Tclass())
1194  {
1195  SocketIpv6TclassTag ipTclassTag;
1196  ipTclassTag.SetTclass(GetIpv6Tclass());
1197  p->AddPacketTag(ipTclassTag);
1198  }
1199 
1200  if (IsManualIpTtl())
1201  {
1202  SocketIpTtlTag ipTtlTag;
1203  ipTtlTag.SetTtl(GetIpTtl());
1204  p->AddPacketTag(ipTtlTag);
1205  }
1206 
1207  if (IsManualIpv6HopLimit())
1208  {
1209  SocketIpv6HopLimitTag ipHopLimitTag;
1210  ipHopLimitTag.SetHopLimit(GetIpv6HopLimit());
1211  p->AddPacketTag(ipHopLimitTag);
1212  }
1213 
1214  if (m_endPoint == nullptr && m_endPoint6 == nullptr)
1215  {
1216  NS_LOG_WARN("Failed to send empty packet due to null endpoint");
1217  return;
1218  }
1219  if (flags & TcpHeader::FIN)
1220  {
1221  flags |= TcpHeader::ACK;
1222  }
1223  else if (m_state == FIN_WAIT_1 || m_state == LAST_ACK || m_state == CLOSING)
1224  {
1225  ++s;
1226  }
1227 
1228  bool hasSyn = flags & TcpHeader::SYN;
1229  bool hasFin = flags & TcpHeader::FIN;
1230  bool isAck = flags == TcpHeader::ACK;
1231 
1232  header.SetFlags(flags);
1233  header.SetSequenceNumber(s);
1234 
1235  // Actual division in small acks.
1236  if (hasSyn || hasFin)
1237  {
1238  header.SetAckNumber(m_tcb->m_rxBuffer->NextRxSequence());
1239  }
1240  else
1241  {
1242  SequenceNumber32 ackSeq;
1243 
1244  ackSeq = m_lastAckedSeq + m_bytesToAck;
1245 
1246  if (m_bytesLeftToBeAcked == 0 && m_tcb->m_rxBuffer->NextRxSequence() > m_lastAckedSeq)
1247  {
1249  m_tcb->m_rxBuffer->NextRxSequence().GetValue() - m_lastAckedSeq.GetValue();
1251  NS_LOG_DEBUG("Setting m_bytesLeftToBeAcked to " << m_bytesLeftToBeAcked);
1252  }
1253  else if (m_bytesLeftToBeAcked > 0 && m_tcb->m_rxBuffer->NextRxSequence() > m_lastAckedSeq)
1254  {
1256  NS_LOG_DEBUG("Decrementing m_bytesLeftToBeAcked to " << m_bytesLeftToBeAcked);
1257  }
1258 
1259  NS_LOG_LOGIC("Acking up to " << ackSeq << " remaining bytes: " << m_bytesLeftToBeAcked);
1260 
1261  header.SetAckNumber(ackSeq);
1262  m_lastAckedSeq = ackSeq;
1263  }
1264 
1265  // end of division in small acks
1266 
1267  if (m_endPoint != nullptr)
1268  {
1271  }
1272  else
1273  {
1276  }
1277  AddOptions(header);
1279 
1280  // RFC 6298, clause 2.4
1281  m_rto =
1282  Max(m_rtt->GetEstimate() + Max(m_clockGranularity, m_rtt->GetVariation() * 4), m_minRto);
1283 
1284  if (hasSyn)
1285  {
1286  if (m_synCount == 0)
1287  { // No more connection retries, give up
1288  NS_LOG_LOGIC("Connection failed.");
1289  m_rtt->Reset(); // According to recommendation -> RFC 6298
1290  CloseAndNotify();
1291  return;
1292  }
1293  else
1294  { // Exponential backoff of connection time out
1295  int backoffCount = 0x1 << (m_synRetries - m_synCount);
1296  m_rto = m_cnTimeout * backoffCount;
1297  m_synCount--;
1298  }
1299  }
1300  if (m_endPoint != nullptr)
1301  {
1302  m_tcp->SendPacket(p,
1303  header,
1307  }
1308  else
1309  {
1310  m_tcp->SendPacket(p,
1311  header,
1315  }
1316 
1317  m_txTrace(p, header, this);
1318 
1319  if (flags & TcpHeader::ACK)
1320  { // If sending an ACK, cancel the delay ACK as well
1322  m_delAckCount = 0;
1323  }
1324  if (m_retxEvent.IsExpired() && (hasSyn || hasFin) && !isAck)
1325  { // Retransmit SYN / SYN+ACK / FIN / FIN+ACK to guard against lost
1326  NS_LOG_LOGIC("Schedule retransmission timeout at time "
1327  << Simulator::Now().GetSeconds() << " to expire at time "
1328  << (Simulator::Now() + m_rto.Get()).GetSeconds());
1330  }
1331 
1332  // send another ACK if bytes remain
1334  m_tcb->m_rxBuffer->NextRxSequence() > m_lastAckedSeq && !hasFin)
1335  {
1336  NS_LOG_DEBUG("Recursing to call SendEmptyPacket() again with m_bytesLeftToBeAcked = "
1338  SendEmptyPacket(flags);
1339  }
1340 }
1341 
1344 {
1345  return CopyObject<TcpSocketSmallAcks>(this);
1346 }
a polymophic address class
Definition: address.h:101
bool IsNull() const
Check for null implementation.
Definition: callback.h:569
An identifier for simulation events.
Definition: event-id.h:55
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
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
static Ipv4Address GetAny()
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.
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
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.
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
uint32_t GetId() const
Definition: node.cc:117
Instantiate subclasses of ns3::Object.
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
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
static void EnablePrinting()
Enable printing packets metadata.
Definition: packet.cc:596
Base class for all RTT Estimators.
Definition: rtt-estimator.h:43
static TypeId GetTypeId()
Get the type ID.
NUMERIC_TYPE GetValue() const
Extracts the numeric value of the sequence number.
build a set of SimpleNetDevice objects
void SetNetDevicePointToPointMode(bool pointToPointMode)
SimpleNetDevice is Broadcast capable and ARP needing.
NetDeviceContainer Install(Ptr< Node > node) const
This method creates an ns3::SimpleChannel with the attributes configured by SimpleNetDeviceHelper::Se...
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void ScheduleWithContext(uint32_t context, const Time &delay, FUNC f, Ts &&... args)
Schedule an event with the given context.
Definition: simulator.h:588
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
static void Run()
Run the simulation.
Definition: simulator.cc:178
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
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
void SetCloseCallbacks(Callback< void, Ptr< Socket >> normalClose, Callback< void, Ptr< Socket >> errorClose)
Detect socket recv() events such as graceful shutdown or error.
Definition: socket.cc:96
uint8_t GetIpTos() const
Query the value of IP Type of Service of this socket.
Definition: socket.cc:450
void SetRecvCallback(Callback< void, Ptr< Socket >> receivedData)
Notify application when new data is available to be read.
Definition: socket.cc:128
Ptr< NetDevice > m_boundnetdevice
the device this socket is bound to (might be null).
Definition: socket.h:1079
virtual Ptr< Node > GetNode() const =0
Return the node this socket is associated with.
virtual uint8_t GetIpv6HopLimit() const
Query the value of IP Hop Limit field of this socket.
Definition: socket.cc:542
virtual int Close()=0
Close a socket.
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)=0
Read a single packet from the socket and retrieve the sender address.
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
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
The Classic recovery implementation.
Congestion control abstract class.
virtual void PhyDrop(SocketWho who[[maybe_unused]])
Link drop.
Ptr< RttEstimator > GetRttEstimator(SocketWho who)
Get the Rtt estimator of the socket.
virtual Ptr< TcpSocketMsgBase > CreateSenderSocket(Ptr< Node > node)
Create and install the socket to install on the sender.
void ErrorCloseCb(Ptr< Socket > socket)
Error Close Callback.
virtual void BeforeRTOExpired(const Ptr< const TcpSocketState > tcb[[maybe_unused]], SocketWho who[[maybe_unused]])
Rto has expired.
TypeId m_recoveryTypeId
Recovery.
virtual void RttTrace(Time oldTime[[maybe_unused]], Time newTime[[maybe_unused]])
Rtt changes.
uint32_t GetDelAckCount(SocketWho who)
Get the number of delayed ack (if present)
void SetPropagationDelay(Time propDelay)
Propagation delay of the bottleneck link.
virtual void ErrorClose(SocketWho who[[maybe_unused]])
Socket closed with an error.
virtual Ptr< ErrorModel > CreateReceiverErrorModel()
Create and return the error model to install in the receiver node.
void SetAppPktCount(uint32_t pktCount)
Set app packet count.
void SetDelAckMaxCount(SocketWho who, uint32_t count)
Forcefully set the delayed acknowledgement count.
SocketWho
Used as parameter of methods, specifies on what node the caller is interested (e.g.
@ RECEIVER
Receiver node.
void BeforeRetransmitCb(const Ptr< const TcpSocketState > tcb, const Ptr< const TcpSocketBase > tcp)
Invoked before a retransmit event.
Ptr< TcpTxBuffer > GetTxBuffer(SocketWho who)
Get the Tx buffer from selected socket.
void TxPacketCb(const Ptr< const Packet > p, const TcpHeader &h, const Ptr< const TcpSocketBase > tcp)
Tx packet Callback.
void SetAppPktSize(uint32_t pktSize)
Set app packet size.
void SetCongestionControl(TypeId congControl)
Congestion control of the sender socket.
virtual void NormalClose(SocketWho who[[maybe_unused]])
Socket closed normally.
uint32_t m_mtu
MTU of the environment.
Time GetMinRto(SocketWho who)
Get the minimum RTO attribute.
virtual void RateUpdatedTrace(const TcpRateLinux::TcpRateConnection &rate[[maybe_unused]])
Track the rate value of TcpRateLinux.
Ptr< TcpSocketState > GetTcb(SocketWho who)
Get the TCB from selected socket.
void SetRcvBufSize(SocketWho who, uint32_t size)
Forcefully set a defined size for rx buffer.
Time m_interPacketInterval
Time between sending application packet down to tcp socket.
uint32_t m_pktSize
Size of the application packet.
EventId GetPersistentEvent(SocketWho who)
Get the persistent event of the selected socket.
uint32_t m_pktCount
Count of the application packet.
void HandleAccept(Ptr< Socket > socket, const Address &from)
Handle an accept connection.
void QueueDropCb(std::string context, Ptr< const Packet > p)
Queue Drop Callback.
void ForkCb(Ptr< TcpSocketMsgBase > tcp)
Fork Callback.
uint32_t GetReTxThreshold(SocketWho who)
Get the retransmission threshold.
void SetInitialCwnd(SocketWho who, uint32_t initialCwnd)
Forcefully set the initial cwnd.
void RxPacketCb(const Ptr< const Packet > p, const TcpHeader &h, const Ptr< const TcpSocketBase > tcp)
Rx packet Callback.
virtual Ptr< TcpSocketMsgBase > CreateReceiverSocket(Ptr< Node > node)
Create and install the socket to install on the receiver.
virtual void AfterRTOExpired(const Ptr< const TcpSocketState > tcb[[maybe_unused]], SocketWho who[[maybe_unused]])
Rto has expired.
uint32_t GetDupAckCount(SocketWho who)
Get the number of dupack received.
virtual void SsThreshTrace(uint32_t oldValue[[maybe_unused]], uint32_t newValue[[maybe_unused]])
Slow start threshold changes.
void SetPaceInitialWindow(SocketWho who, bool paceWindow)
Enable or disable pacing of the initial window.
uint32_t GetInitialSsThresh(SocketWho who)
Get the initial slow start threshold.
virtual Ptr< TcpSocketMsgBase > CreateSocket(Ptr< Node > node, TypeId socketType, TypeId congControl)
Create a socket.
virtual void ConfigureProperties()
Change the configuration of the socket properties.
virtual Ptr< SimpleChannel > CreateChannel()
Create and return the channel installed between the two socket.
void DoRun() override
Execute the tcp test.
Time GetDelAckTimeout(SocketWho who)
Get the timeout of delayed ack (if present)
void SetMTU(uint32_t mtu)
MTU of the bottleneck link.
Time GetClockGranularity(SocketWho who)
Get the clock granularity attribute.
void SetUseEcn(SocketWho who, TcpSocketState::UseEcn_t useEcn)
Forcefully set the ECN mode of use.
Time m_startTime
Data transmission time.
Ptr< TcpSocketMsgBase > m_senderSocket
Pointer to sender socket.
void DoConnect()
Scheduled at 0.0, SENDER starts the connection to RECEIVER.
Time GetRto(SocketWho who)
Get the retransmission time.
Ptr< TcpRxBuffer > GetRxBuffer(SocketWho who)
Get the Rx buffer from selected socket.
Time GetConnTimeout(SocketWho who)
Get the retransmission time for the SYN segments.
void AfterRetransmitCb(const Ptr< const TcpSocketState > tcb, const Ptr< const TcpSocketBase > tcp)
Invoked after a retransmit event.
void SetAppPktInterval(Time pktInterval)
Interval between app-generated packet.
uint32_t GetRWnd(SocketWho who)
Get the rWnd of the selected socket.
void PhyDropCb(std::string context, Ptr< const Packet > p)
Drop at Phy layer Callback.
uint32_t GetSegSize(SocketWho who)
Get the segment size of the node specified.
virtual void BytesInFlightTrace(uint32_t oldValue[[maybe_unused]], uint32_t newValue[[maybe_unused]])
Bytes in flight changes.
TypeId m_congControlTypeId
Congestion control.
virtual void ReceivePacket(Ptr< Socket > socket)
Packet received.
void DataSentCb(Ptr< Socket > socket, uint32_t size)
Data sent Callback.
virtual void UpdatedRttHistory(const SequenceNumber32 &seq[[maybe_unused]], uint32_t sz[[maybe_unused]], bool isRetransmission[[maybe_unused]], SocketWho who[[maybe_unused]])
Updated the Rtt history.
virtual void RtoTrace(Time oldValue[[maybe_unused]], Time newValue[[maybe_unused]])
RTO changes.
virtual void Rx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who)
Packet received from IP layer.
void SendPacket(Ptr< Socket > socket, uint32_t pktSize, uint32_t pktCount, Time pktInterval)
Send packets to other endpoint.
void NormalCloseCb(Ptr< Socket > socket)
Normal Close Callback.
virtual void RateSampleUpdatedTrace(const TcpRateLinux::TcpRateSample &sample[[maybe_unused]])
Track the rate sample value of TcpRateLinux.
Time m_propagationDelay
Propagation delay of the channel.
void RcvAckCb(Ptr< const Packet > p, const TcpHeader &h, Ptr< const TcpSocketBase > tcp)
Receive ACK Callback.
virtual void RcvAck(const Ptr< const TcpSocketState > tcb[[maybe_unused]], const TcpHeader &h[[maybe_unused]], SocketWho who[[maybe_unused]])
Received ack.
TcpSocket::TcpStates_t GetTcpState(SocketWho who)
Get the state of the TCP state machine.
virtual void NextTxSeqTrace(SequenceNumber32 oldValue[[maybe_unused]], SequenceNumber32 newValue[[maybe_unused]])
Next tx seq changes.
void SetInitialSsThresh(SocketWho who, uint32_t initialSsThresh)
Forcefully set the initial ssthresh.
SequenceNumber32 GetHighestTxMark(SocketWho who)
Get the highest tx mark of the node specified.
virtual void FinalChecks()
Performs the (eventual) final checks through test asserts.
Time GetPersistentTimeout(SocketWho who)
Get the persistent timeout of the selected socket.
void SetRecoveryAlgorithm(TypeId recovery)
recovery algorithm of the sender socket
virtual void DataSent(uint32_t size[[maybe_unused]], SocketWho who[[maybe_unused]])
Notifying application for sent data.
virtual void Tx(const Ptr< const Packet > p, const TcpHeader &h, SocketWho who)
Packet transmitted down to IP layer.
void SetPacingStatus(SocketWho who, bool pacing)
Enable or disable pacing in the TCP socket.
Ptr< TcpSocketMsgBase > m_receiverSocket
Pointer to receiver socket.
virtual void ConfigureEnvironment()
Change the configuration of the environment.
virtual Ptr< ErrorModel > CreateSenderErrorModel()
Create and return the error model to install in the sender node.
virtual void CWndInflTrace(uint32_t oldValue[[maybe_unused]], uint32_t newValue[[maybe_unused]])
Tracks the inflated congestion window changes.
uint32_t GetInitialCwnd(SocketWho who)
Get the initial congestion window.
TcpGeneralTest(const std::string &desc)
TcpGeneralTest constructor.
virtual void ProcessedAck(const Ptr< const TcpSocketState > tcb[[maybe_unused]], const TcpHeader &h[[maybe_unused]], SocketWho who[[maybe_unused]])
Processed ack.
virtual void CongStateTrace(const TcpSocketState::TcpCongState_t oldValue[[maybe_unused]], const TcpSocketState::TcpCongState_t newValue[[maybe_unused]])
State on Ack state machine changes.
void UpdateRttHistoryCb(Ptr< const TcpSocketBase > tcp, const SequenceNumber32 &seq, uint32_t sz, bool isRetransmission)
Update RTT with new data.
virtual void CWndTrace(uint32_t oldValue[[maybe_unused]], uint32_t newValue[[maybe_unused]])
Tracks the congestion window changes.
virtual void QueueDrop(SocketWho who[[maybe_unused]])
Drop on the queue.
void ProcessedAckCb(Ptr< const Packet > p, const TcpHeader &h, Ptr< const TcpSocketBase > tcp)
ACK processed Callback.
void DoTeardown() override
Teardown the TCP test.
void SetTransmitStart(Time startTime)
Set the initial time at which the application sends the first data packet.
InetSocketAddress m_remoteAddr
Remote peer address.
void SetSegmentSize(SocketWho who, uint32_t segmentSize)
Forcefully set the segment size.
virtual void HighestTxSeqTrace(SequenceNumber32 oldValue[[maybe_unused]], SequenceNumber32 newValue[[maybe_unused]])
Highest tx seq changes.
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
TCP socket creation and multiplexing/demultiplexing.
The NewReno implementation.
recovery abstract class
A base class for implementation of a stream socket using TCP.
Time m_minRto
minimum value of the Retransmit timeout
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.
void CloseAndNotify()
Peacefully close the socket by notifying the upper layer and deallocate end point.
virtual void ReTxTimeout()
An RTO event happened.
TracedValue< Time > m_rto
Retransmit timeout.
EventId m_delAckEvent
Delayed ACK timeout event.
void AddOptions(TcpHeader &tcpHeader)
Add options to TcpHeader.
TracedValue< TcpStates_t > m_state
TCP state.
Ptr< RttEstimator > m_rtt
Round trip time estimator.
EventId m_retxEvent
Retransmission event.
virtual void ReceivedAck(Ptr< Packet > packet, const TcpHeader &tcpHeader)
Received an ACK packet.
uint32_t m_delAckCount
Delayed ACK counter.
Ipv4EndPoint * m_endPoint
the IPv4 endpoint
Time m_cnTimeout
Timeout for connection retry.
Time m_clockGranularity
Clock Granularity used in RTO calcs.
virtual uint16_t AdvertisedWindowSize(bool scale=true) const
The amount of Rx window announced to the peer.
Ipv6EndPoint * m_endPoint6
the IPv6 endpoint
virtual void CompleteFork(Ptr< Packet > p, const TcpHeader &tcpHeader, const Address &fromAddress, const Address &toAddress)
Complete a connection by forking the socket.
uint32_t m_synRetries
Number of connection attempts.
uint32_t m_synCount
Count of remaining connection retries.
virtual void UpdateRttHistory(const SequenceNumber32 &seq, uint32_t sz, bool isRetransmission)
Update the RTT history, when we send TCP segments.
Class for inserting callbacks special points of the flow of TCP sockets.
UpdateRttCallback m_updateRttCb
Update RTT callback.
void SetForkCb(Callback< void, Ptr< TcpSocketMsgBase >> cb)
Set the callback invoked after the forking.
AckManagementCb m_processedAckCb
Processed ACK callback.
void SetAfterRetransmitCb(RetrCb cb)
Set the callback invoked after the processing of a retransmit timeout.
void UpdateRttHistory(const SequenceNumber32 &seq, uint32_t sz, bool isRetransmission) override
Update the RTT history, when we send TCP segments.
void SetRcvAckCb(AckManagementCb cb)
Set the callback invoked when an ACK is received (at the beginning of the processing)
AckManagementCb m_rcvAckCb
Receive ACK callback.
void SetProcessedAckCb(AckManagementCb cb)
Set the callback invoked when an ACK is received and processed (at the end of the processing)
void SetBeforeRetransmitCb(RetrCb cb)
Set the callback invoked before the processing of a retransmit timeout.
void CompleteFork(Ptr< Packet > p, const TcpHeader &tcpHeader, const Address &fromAddress, const Address &toAddress) override
Complete a connection by forking the socket.
Ptr< TcpSocketBase > Fork() override
Call CopyObject<> to clone me.
static TypeId GetTypeId()
Get the type ID.
RetrCb m_beforeRetrCallback
Before retransmission callback.
Callback< void, Ptr< TcpSocketMsgBase > > m_forkCb
Fork callback.
void ReceivedAck(Ptr< Packet > packet, const TcpHeader &tcpHeader) override
Received an ACK packet.
RetrCb m_afterRetrCallback
After retransmission callback.
void ReTxTimeout() override
An RTO event happened.
void SetUpdateRttHistoryCb(UpdateRttCallback cb)
Set the callback invoked when we update rtt history.
A TCP socket which sends ACKs smaller than the segment received.
static TypeId GetTypeId()
Get the type ID.
SequenceNumber32 m_lastAckedSeq
Last sequence number ACKed.
uint32_t m_bytesToAck
Number of bytes to be ACKed.
void SendEmptyPacket(uint8_t flags) override
Send a empty packet that carries a flag, e.g., ACK.
uint32_t m_bytesLeftToBeAcked
Number of bytes to be ACKed left.
Ptr< TcpSocketBase > Fork() override
Call CopyObject<> to clone me.
TracedValue< SequenceNumber32 > m_highTxMark
Highest seqno ever sent, regardless of ReTx.
UseEcn_t
Parameter value related to ECN enable/disable functionality similar to sysctl for tcp_ecn.
Ptr< TcpRxBuffer > m_rxBuffer
Rx buffer (reordering buffer)
TracedValue< SequenceNumber32 > m_nextTxSequence
Next seqnum to be sent (SND.NXT), ReTx pushes it back.
encapsulates test code
Definition: test.h:1060
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
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
uint32_t segmentSize
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
Callback< R, Args... > MakeNullCallback()
Definition: callback.h:747
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
int64x64_t Max(const int64x64_t &a, const int64x64_t &b)
Maximum.
Definition: int64x64.h:243
#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_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
#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
TcpStates_t
Names of the 11 TCP states.
Definition: tcp-socket.h:66
@ 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
@ CLOSING
Both sides have shutdown but we still have data we have to finish sending
Definition: tcp-socket.h:82
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
NodeContainer nodes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
channel
Definition: third.py:88
uint32_t pktSize
packet size used for the simulation (in bytes)