A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
tcp-general-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015 Natale Patriciello <natale.patriciello@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7#define __STDC_LIMIT_MACROS
8#include "tcp-general-test.h"
9
10#include "ns3/internet-stack-helper.h"
11#include "ns3/ipv4-address-helper.h"
12#include "ns3/ipv4-end-point.h"
13#include "ns3/ipv6-end-point.h"
14#include "ns3/log.h"
15#include "ns3/node-container.h"
16#include "ns3/queue.h"
17#include "ns3/rtt-estimator.h"
18#include "ns3/simple-net-device-helper.h"
19#include "ns3/tcp-header.h"
20#include "ns3/tcp-l4-protocol.h"
21#include "ns3/tcp-rx-buffer.h"
22#include "ns3/tcp-socket-base.h"
23#include "ns3/tcp-tx-buffer.h"
24#include "ns3/test.h"
25
26using namespace ns3;
27
28NS_LOG_COMPONENT_DEFINE("TcpGeneralTest");
29
30TcpGeneralTest::TcpGeneralTest(const std::string& desc)
31 : TestCase(desc),
32 m_congControlTypeId(TcpNewReno::GetTypeId()),
33 m_recoveryTypeId(TcpClassicRecovery::GetTypeId()),
34 m_remoteAddr(Ipv4Address::GetAny(), 4477)
35{
36 NS_LOG_FUNCTION(this << desc);
37}
38
43
44void
46{
47 NS_LOG_FUNCTION(this << socket);
48 Ptr<Packet> packet;
49 Address from;
50
51 while ((packet = socket->RecvFrom(from)))
52 {
53 if (packet->GetSize() == 0)
54 { // EOF
55 break;
56 }
57 }
58}
59
60void
63 uint32_t pktCount,
64 Time pktInterval)
65{
66 NS_LOG_FUNCTION(this << " " << pktSize << " " << pktCount << " " << pktInterval.GetSeconds());
67 if (pktCount > 0)
68 {
69 socket->Send(Create<Packet>(pktSize));
70 Simulator::Schedule(pktInterval,
72 this,
73 socket,
74 pktSize,
75 pktCount - 1,
76 pktInterval);
77 }
78 else
79 {
80 socket->Close();
81 }
82}
83
84void
92
93void
107
108void
117
118void
120{
122
123 NS_LOG_INFO("Create nodes.");
125 nodes.Create(2);
126
127 InternetStackHelper internet;
128 internet.Install(nodes);
129
131
133
134 SimpleNetDeviceHelper helperChannel;
135 helperChannel.SetNetDevicePointToPointMode(true);
136
137 NetDeviceContainer net = helperChannel.Install(nodes, channel);
138
141
144
145 senderDev->SetMtu(m_mtu);
146 senderDev->GetQueue()->TraceConnect("Drop",
147 "SENDER",
149 senderDev->TraceConnect("PhyRxDrop", "sender", MakeCallback(&TcpGeneralTest::PhyDropCb, this));
150
151 receiverDev->SetMtu(m_mtu);
152 receiverDev->GetQueue()->TraceConnect("Drop",
153 "RECEIVER",
155 receiverDev->TraceConnect("PhyRxDrop",
156 "RECEIVER",
158
159 senderDev->SetReceiveErrorModel(senderEM);
160 receiverDev->SetReceiveErrorModel(receiverEM);
161
163 ipv4.SetBase("10.1.1.0", "255.255.255.0");
164 Ipv4InterfaceContainer i = ipv4.Assign(net);
165 Ipv4Address serverAddress = i.GetAddress(1);
166 // Ipv4Address clientAddress = i.GetAddress (0);
167
168 NS_LOG_INFO("Create sockets.");
169 // Receiver socket on n1
171
173 m_receiverSocket->SetAcceptCallback(MakeNullCallback<bool, Ptr<Socket>, const Address&>(),
180 m_receiverSocket->SetBeforeRetransmitCb(
183 m_receiverSocket->SetUpdateRttHistoryCb(
185 m_receiverSocket->TraceConnectWithoutContext("Tx",
187 m_receiverSocket->TraceConnectWithoutContext("Rx",
189
191 m_receiverSocket->Bind(local);
192
199 m_senderSocket->SetBeforeRetransmitCb(MakeCallback(&TcpGeneralTest::BeforeRetransmitCb, this));
200 m_senderSocket->SetDataSentCallback(MakeCallback(&TcpGeneralTest::DataSentCb, this));
201 m_senderSocket->SetUpdateRttHistoryCb(MakeCallback(&TcpGeneralTest::UpdateRttHistoryCb, this));
202 m_senderSocket->TraceConnectWithoutContext("CongestionWindow",
204 m_senderSocket->TraceConnectWithoutContext("CongestionWindowInflated",
206 m_senderSocket->TraceConnectWithoutContext("SlowStartThreshold",
208 m_senderSocket->TraceConnectWithoutContext("CongState",
210 m_senderSocket->TraceConnectWithoutContext("Tx",
212 m_senderSocket->TraceConnectWithoutContext("Rx",
214 m_senderSocket->TraceConnectWithoutContext("RTT",
216 m_senderSocket->TraceConnectWithoutContext(
217 "BytesInFlight",
219 m_senderSocket->TraceConnectWithoutContext("RTO",
221 m_senderSocket->TraceConnectWithoutContext("NextTxSequence",
223 m_senderSocket->TraceConnectWithoutContext(
224 "HighestSequence",
226 m_senderSocket->m_rateOps->TraceConnectWithoutContext(
227 "TcpRateUpdated",
229 m_senderSocket->m_rateOps->TraceConnectWithoutContext(
230 "TcpRateSampleUpdated",
232
233 m_remoteAddr = InetSocketAddress(serverAddress, 4477);
234
236
237 m_receiverSocket->Listen();
238 m_receiverSocket->ShutdownSend();
239
244 this,
246 m_pktSize,
249
250 NS_LOG_INFO("Run Simulation.");
252}
253
254void
260
261void
262TcpGeneralTest::HandleAccept(Ptr<Socket> socket, const Address& from [[maybe_unused]])
263{
264 socket->SetRecvCallback(MakeCallback(&TcpGeneralTest::ReceivePacket, this));
265 socket->SetCloseCallbacks(MakeCallback(&TcpGeneralTest::NormalCloseCb, this),
267}
268
271{
273
274 ch->SetAttribute("Delay", TimeValue(m_propagationDelay));
275
276 return ch;
277}
278
281{
282 return CreateSocket(node, socketType, congControl, m_recoveryTypeId);
283}
284
287 TypeId socketType,
288 TypeId congControl,
289 TypeId recoveryAlgorithm)
290{
291 ObjectFactory rttFactory;
292 ObjectFactory congestionAlgorithmFactory;
293 ObjectFactory recoveryAlgorithmFactory;
294 ObjectFactory socketFactory;
295
297 congestionAlgorithmFactory.SetTypeId(congControl);
298 recoveryAlgorithmFactory.SetTypeId(recoveryAlgorithm);
299 socketFactory.SetTypeId(socketType);
300
301 Ptr<RttEstimator> rtt = rttFactory.Create<RttEstimator>();
303 Ptr<TcpCongestionOps> algo = congestionAlgorithmFactory.Create<TcpCongestionOps>();
304 Ptr<TcpRecoveryOps> recovery = recoveryAlgorithmFactory.Create<TcpRecoveryOps>();
305
306 socket->SetNode(node);
307 socket->SetTcp(node->GetObject<TcpL4Protocol>());
308 socket->SetRtt(rtt);
309 socket->SetCongestionControlAlgorithm(algo);
310 socket->SetRecoveryAlgorithm(recovery);
311 return socket;
312}
313
316{
317 return nullptr;
318}
319
322{
323 return nullptr;
324}
325
331
337
338void
340{
341 if (context == "SENDER")
342 {
344 }
345 else if (context == "RECEIVER")
346 {
348 }
349 else
350 {
351 NS_FATAL_ERROR("Packet dropped in a queue, but queue not recognized");
352 }
353}
354
355void
356TcpGeneralTest::PhyDropCb(std::string context, Ptr<const Packet> /* p */)
357{
358 if (context == "SENDER")
359 {
361 }
362 else if (context == "RECEIVER")
363 {
365 }
366 else
367 {
368 NS_FATAL_ERROR("Packet dropped in a queue, but queue not recognized");
369 }
370}
371
372void
374{
375 if (socket->GetNode() == m_receiverSocket->GetNode())
376 {
378 }
379 else if (socket->GetNode() == m_senderSocket->GetNode())
380 {
382 }
383 else
384 {
385 NS_FATAL_ERROR("Closed socket, but not recognized");
386 }
387}
388
389void
391 const SequenceNumber32& seq,
392 uint32_t sz,
393 bool isRetransmission)
394{
395 if (tcp->GetNode() == m_receiverSocket->GetNode())
396 {
397 UpdatedRttHistory(seq, sz, isRetransmission, RECEIVER);
398 }
399 else if (tcp->GetNode() == m_senderSocket->GetNode())
400 {
401 UpdatedRttHistory(seq, sz, isRetransmission, SENDER);
402 }
403 else
404 {
405 NS_FATAL_ERROR("Closed socket, but not recognized");
406 }
407}
408
409void
411 const Ptr<const TcpSocketBase> tcp)
412{
413 if (tcp->GetNode() == m_receiverSocket->GetNode())
414 {
416 }
417 else if (tcp->GetNode() == m_senderSocket->GetNode())
418 {
420 }
421 else
422 {
423 NS_FATAL_ERROR("Closed socket, but not recognized");
424 }
425}
426
427void
429 const Ptr<const TcpSocketBase> tcp)
430{
431 if (tcp->GetNode() == m_receiverSocket->GetNode())
432 {
434 }
435 else if (tcp->GetNode() == m_senderSocket->GetNode())
436 {
438 }
439 else
440 {
441 NS_FATAL_ERROR("Closed socket, but not recognized");
442 }
443}
444
445void
447{
448 if (socket->GetNode() == m_receiverSocket->GetNode())
449 {
450 DataSent(size, RECEIVER);
451 }
452 else if (socket->GetNode() == m_senderSocket->GetNode())
453 {
454 DataSent(size, SENDER);
455 }
456 else
457 {
458 NS_FATAL_ERROR("Closed socket, but not recognized");
459 }
460}
461
462void
464{
465 if (socket->GetNode() == m_receiverSocket->GetNode())
466 {
468 }
469 else if (socket->GetNode() == m_senderSocket->GetNode())
470 {
472 }
473 else
474 {
475 NS_FATAL_ERROR("Closed socket, but not recognized");
476 }
477}
478
479void
481{
482 NS_LOG_FUNCTION(this << p << h << who);
483}
484
485void
487{
488 NS_LOG_FUNCTION(this << p << h << who);
489}
490
491void
493 const TcpHeader& h,
494 const Ptr<const TcpSocketBase> tcp)
495{
496 if (tcp->GetNode() == m_receiverSocket->GetNode())
497 {
498 RcvAck(tcp->m_tcb, h, RECEIVER);
499 }
500 else if (tcp->GetNode() == m_senderSocket->GetNode())
501 {
502 RcvAck(tcp->m_tcb, h, SENDER);
503 }
504 else
505 {
506 NS_FATAL_ERROR("Received ACK but socket not recognized");
507 }
508}
509
510void
512 const TcpHeader& h,
513 const Ptr<const TcpSocketBase> tcp)
514{
515 if (tcp->GetNode() == m_receiverSocket->GetNode())
516 {
517 Tx(p, h, RECEIVER);
518 }
519 else if (tcp->GetNode() == m_senderSocket->GetNode())
520 {
521 Tx(p, h, SENDER);
522 }
523 else
524 {
525 NS_FATAL_ERROR("Received ACK but socket not recognized");
526 }
527}
528
529void
531 const TcpHeader& h,
532 const Ptr<const TcpSocketBase> tcp)
533{
534 if (tcp->GetNode() == m_receiverSocket->GetNode())
535 {
536 Rx(p, h, RECEIVER);
537 }
538 else if (tcp->GetNode() == m_senderSocket->GetNode())
539 {
540 Rx(p, h, SENDER);
541 }
542 else
543 {
544 NS_FATAL_ERROR("Received ACK but socket not recognized");
545 }
546}
547
548void
550 const TcpHeader& h,
552{
553 if (tcp->GetNode() == m_receiverSocket->GetNode())
554 {
555 ProcessedAck(tcp->m_tcb, h, RECEIVER);
556 }
557 else if (tcp->GetNode() == m_senderSocket->GetNode())
558 {
559 ProcessedAck(tcp->m_tcb, h, SENDER);
560 }
561 else
562 {
563 NS_FATAL_ERROR("Received ACK but socket not recognized");
564 }
565}
566
567void
569{
570 NS_LOG_FUNCTION(this << tcp);
571
572 m_receiverSocket = tcp;
573}
574
577{
578 if (who == SENDER)
579 {
580 return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_retxThresh;
581 }
582 else if (who == RECEIVER)
583 {
585 }
586 else
587 {
588 NS_FATAL_ERROR("Not defined");
589 }
590}
591
594{
595 if (who == SENDER)
596 {
597 return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_dupAckCount;
598 }
599 else if (who == RECEIVER)
600 {
601 return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->m_dupAckCount;
602 }
603 else
604 {
605 NS_FATAL_ERROR("Not defined");
606 }
607}
608
611{
612 if (who == SENDER)
613 {
614 return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_delAckMaxCount;
615 }
616 else if (who == RECEIVER)
617 {
618 return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->m_delAckMaxCount;
619 }
620 else
621 {
622 NS_FATAL_ERROR("Not defined");
623 }
624}
625
626Time
628{
629 if (who == SENDER)
630 {
631 return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->GetDelAckTimeout();
632 }
633 else if (who == RECEIVER)
634 {
635 return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->GetDelAckTimeout();
636 }
637 else
638 {
639 NS_FATAL_ERROR("Not defined");
640 }
641}
642
645{
646 if (who == SENDER)
647 {
648 return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->GetSegSize();
649 }
650 else if (who == RECEIVER)
651 {
653 }
654 else
655 {
656 NS_FATAL_ERROR("Not defined");
657 }
658}
659
662{
663 return GetTcb(who)->m_highTxMark;
664}
665
668{
669 if (who == SENDER)
670 {
671 return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->GetInitialCwnd();
672 }
673 else if (who == RECEIVER)
674 {
675 return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->GetInitialCwnd();
676 }
677 else
678 {
679 NS_FATAL_ERROR("Not defined");
680 }
681}
682
685{
686 if (who == SENDER)
687 {
688 return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->GetInitialSSThresh();
689 }
690 else if (who == RECEIVER)
691 {
692 return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->GetInitialSSThresh();
693 }
694 else
695 {
696 NS_FATAL_ERROR("Not defined");
697 }
698}
699
700Time
702{
703 if (who == SENDER)
704 {
706 }
707 else if (who == RECEIVER)
708 {
710 }
711 else
712 {
713 NS_FATAL_ERROR("Not defined");
714 }
715}
716
717Time
719{
720 if (who == SENDER)
721 {
723 }
724 else if (who == RECEIVER)
725 {
727 }
728 else
729 {
730 NS_FATAL_ERROR("Not defined");
731 }
732}
733
734Time
736{
737 if (who == SENDER)
738 {
740 }
741 else if (who == RECEIVER)
742 {
744 }
745 else
746 {
747 NS_FATAL_ERROR("Not defined");
748 }
749}
750
753{
754 if (who == SENDER)
755 {
757 }
758 else if (who == RECEIVER)
759 {
761 }
762 else
763 {
764 NS_FATAL_ERROR("Not defined");
765 }
766}
767
768Time
770{
771 if (who == SENDER)
772 {
773 return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_clockGranularity;
774 }
775 else if (who == RECEIVER)
776 {
777 return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->m_clockGranularity;
778 }
779 else
780 {
781 NS_FATAL_ERROR("Not defined");
782 }
783}
784
787{
788 if (who == SENDER)
789 {
790 return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_state.Get();
791 }
792 else if (who == RECEIVER)
793 {
794 return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->m_state.Get();
795 }
796 else
797 {
798 NS_FATAL_ERROR("Not defined");
799 }
800}
801
804{
805 if (who == SENDER)
806 {
807 return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_rWnd.Get();
808 }
809 else if (who == RECEIVER)
810 {
812 }
813 else
814 {
815 NS_FATAL_ERROR("Not defined");
816 }
817}
818
821{
822 if (who == SENDER)
823 {
824 return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_persistEvent;
825 }
826 else if (who == RECEIVER)
827 {
828 return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->m_persistEvent;
829 }
830 else
831 {
832 NS_FATAL_ERROR("Not defined");
833 }
834}
835
836Time
838{
839 if (who == SENDER)
840 {
841 return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_persistTimeout;
842 }
843 else if (who == RECEIVER)
844 {
845 return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->m_persistTimeout;
846 }
847 else
848 {
849 NS_FATAL_ERROR("Not defined");
850 }
851}
852
855{
856 if (who == SENDER)
857 {
859 }
860 else if (who == RECEIVER)
861 {
863 }
864 else
865 {
866 NS_FATAL_ERROR("Not defined");
867 }
868}
869
872{
873 if (who == SENDER)
874 {
875 return DynamicCast<TcpSocketMsgBase>(m_senderSocket)->m_tcb->m_rxBuffer;
876 }
877 else if (who == RECEIVER)
878 {
879 return DynamicCast<TcpSocketMsgBase>(m_receiverSocket)->m_tcb->m_rxBuffer;
880 }
881 else
882 {
883 NS_FATAL_ERROR("Not defined");
884 }
885}
886
889{
890 if (who == SENDER)
891 {
893 }
894 else if (who == RECEIVER)
895 {
897 }
898 else
899 {
900 NS_FATAL_ERROR("Not defined");
901 }
902}
903
904void
906{
907 if (who == SENDER)
908 {
909 m_senderSocket->SetRcvBufSize(size);
910 }
911 else if (who == RECEIVER)
912 {
913 m_receiverSocket->SetRcvBufSize(size);
914 }
915 else
916 {
917 NS_FATAL_ERROR("Not defined");
918 }
919}
920
921void
923{
924 if (who == SENDER)
925 {
926 m_senderSocket->SetSegSize(segmentSize);
927 }
928 else if (who == RECEIVER)
929 {
930 m_receiverSocket->SetSegSize(segmentSize);
931 }
932 else
933 {
934 NS_FATAL_ERROR("Not defined");
935 }
936}
937
938void
940{
941 if (who == SENDER)
942 {
943 m_senderSocket->SetInitialCwnd(initialCwnd);
944 }
945 else if (who == RECEIVER)
946 {
947 m_receiverSocket->SetInitialCwnd(initialCwnd);
948 }
949 else
950 {
951 NS_FATAL_ERROR("Not defined");
952 }
953}
954
955void
957{
958 if (who == SENDER)
959 {
960 m_senderSocket->SetDelAckMaxCount(count);
961 }
962 else if (who == RECEIVER)
963 {
964 m_receiverSocket->SetDelAckMaxCount(count);
965 }
966 else
967 {
968 NS_FATAL_ERROR("Not defined");
969 }
970}
971
972void
974{
975 if (who == SENDER)
976 {
977 m_senderSocket->SetUseEcn(useEcn);
978 }
979 else if (who == RECEIVER)
980 {
981 m_receiverSocket->SetUseEcn(useEcn);
982 }
983 else
984 {
985 NS_FATAL_ERROR("Not defined");
986 }
987}
988
989void
991{
992 if (who == SENDER)
993 {
994 m_senderSocket->SetPacingStatus(pacing);
995 }
996 else if (who == RECEIVER)
997 {
998 m_receiverSocket->SetPacingStatus(pacing);
999 }
1000 else
1001 {
1002 NS_FATAL_ERROR("Not defined");
1003 }
1004}
1005
1006void
1008{
1009 if (who == SENDER)
1010 {
1011 m_senderSocket->SetPaceInitialWindow(paceWindow);
1012 }
1013 else if (who == RECEIVER)
1014 {
1015 m_receiverSocket->SetPaceInitialWindow(paceWindow);
1016 }
1017 else
1018 {
1019 NS_FATAL_ERROR("Not defined");
1020 }
1021}
1022
1023void
1025{
1026 if (who == SENDER)
1027 {
1028 m_senderSocket->SetInitialSSThresh(initialSsThresh);
1029 }
1030 else if (who == RECEIVER)
1031 {
1032 m_receiverSocket->SetInitialSSThresh(initialSsThresh);
1033 }
1034 else
1035 {
1036 NS_FATAL_ERROR("Not defined");
1037 }
1038}
1039
1041
1042TypeId
1044{
1045 static TypeId tid = TypeId("ns3::TcpSocketMsgBase")
1047 .SetGroupName("Internet")
1048 .AddConstructor<TcpSocketMsgBase>();
1049 return tid;
1050}
1051
1057
1058void
1064
1065void
1071
1072void
1078
1079void
1085
1086void
1088{
1090 m_rcvAckCb(packet, tcpHeader, this);
1091
1092 TcpSocketBase::ReceivedAck(packet, tcpHeader);
1093
1094 m_processedAckCb(packet, tcpHeader, this);
1095}
1096
1097void
1104
1105void
1107{
1108 NS_ASSERT(!cb.IsNull());
1109 m_forkCb = cb;
1110}
1111
1112void
1118
1119void
1121{
1122 TcpSocketBase::UpdateRttHistory(seq, sz, isRetransmission);
1123 if (!m_updateRttCb.IsNull())
1124 {
1125 m_updateRttCb(this, seq, sz, isRetransmission);
1126 }
1127}
1128
1129void
1131 const TcpHeader& tcpHeader,
1132 const Address& fromAddress,
1133 const Address& toAddress)
1134{
1135 TcpSocketBase::CompleteFork(p, tcpHeader, fromAddress, toAddress);
1136
1137 if (!m_forkCb.IsNull())
1138 {
1139 m_forkCb(this);
1140 }
1141}
1142
1144
1145TypeId
1147{
1148 static TypeId tid = TypeId("ns3::TcpSocketSmallAcks")
1150 .SetGroupName("Internet")
1151 .AddConstructor<TcpSocketSmallAcks>();
1152 return tid;
1153}
1154
1155/*
1156 * Send empty packet, copied/pasted from TcpSocketBase
1157 *
1158 * The rationale for copying/pasting is that we need to edit a little the
1159 * code inside. Since there isn't a well-defined division of duties,
1160 * we are forced to do this.
1161 */
1162void
1164{
1166 TcpHeader header;
1167 SequenceNumber32 s = m_tcb->m_nextTxSequence;
1168
1169 /*
1170 * Add tags for each socket option.
1171 * Note that currently the socket adds both IPv4 tag and IPv6 tag
1172 * if both options are set. Once the packet got to layer three, only
1173 * the corresponding tags will be read.
1174 */
1175 if (GetIpTos())
1176 {
1177 SocketIpTosTag ipTosTag;
1178 ipTosTag.SetTos(GetIpTos());
1179 p->AddPacketTag(ipTosTag);
1180 }
1181
1182 if (IsManualIpv6Tclass())
1183 {
1184 SocketIpv6TclassTag ipTclassTag;
1185 ipTclassTag.SetTclass(GetIpv6Tclass());
1186 p->AddPacketTag(ipTclassTag);
1187 }
1188
1189 if (IsManualIpTtl())
1190 {
1191 SocketIpTtlTag ipTtlTag;
1192 ipTtlTag.SetTtl(GetIpTtl());
1193 p->AddPacketTag(ipTtlTag);
1194 }
1195
1197 {
1198 SocketIpv6HopLimitTag ipHopLimitTag;
1199 ipHopLimitTag.SetHopLimit(GetIpv6HopLimit());
1200 p->AddPacketTag(ipHopLimitTag);
1201 }
1202
1203 if (m_endPoint == nullptr && m_endPoint6 == nullptr)
1204 {
1205 NS_LOG_WARN("Failed to send empty packet due to null endpoint");
1206 return;
1207 }
1208 if (flags & TcpHeader::FIN)
1209 {
1210 flags |= TcpHeader::ACK;
1211 }
1212 else if (m_state == FIN_WAIT_1 || m_state == LAST_ACK || m_state == CLOSING)
1213 {
1214 ++s;
1215 }
1216
1217 bool hasSyn = flags & TcpHeader::SYN;
1218 bool hasFin = flags & TcpHeader::FIN;
1219 bool isAck = flags == TcpHeader::ACK;
1220
1221 header.SetFlags(flags);
1222 header.SetSequenceNumber(s);
1223
1224 // Actual division in small acks.
1225 if (hasSyn || hasFin)
1226 {
1227 header.SetAckNumber(m_tcb->m_rxBuffer->NextRxSequence());
1228 }
1229 else
1230 {
1231 SequenceNumber32 ackSeq;
1232
1233 ackSeq = m_lastAckedSeq + m_bytesToAck;
1234
1235 if (m_bytesLeftToBeAcked == 0 && m_tcb->m_rxBuffer->NextRxSequence() > m_lastAckedSeq)
1236 {
1238 m_tcb->m_rxBuffer->NextRxSequence().GetValue() - m_lastAckedSeq.GetValue();
1240 NS_LOG_DEBUG("Setting m_bytesLeftToBeAcked to " << m_bytesLeftToBeAcked);
1241 }
1242 else if (m_bytesLeftToBeAcked > 0 && m_tcb->m_rxBuffer->NextRxSequence() > m_lastAckedSeq)
1243 {
1245 NS_LOG_DEBUG("Decrementing m_bytesLeftToBeAcked to " << m_bytesLeftToBeAcked);
1246 }
1247
1248 NS_LOG_LOGIC("Acking up to " << ackSeq << " remaining bytes: " << m_bytesLeftToBeAcked);
1249
1250 header.SetAckNumber(ackSeq);
1251 m_lastAckedSeq = ackSeq;
1252 }
1253
1254 // end of division in small acks
1255
1256 if (m_endPoint != nullptr)
1257 {
1260 }
1261 else
1262 {
1265 }
1266 AddOptions(header);
1268
1269 // RFC 6298, clause 2.4
1270 m_rto =
1271 Max(m_rtt->GetEstimate() + Max(m_clockGranularity, m_rtt->GetVariation() * 4), m_minRto);
1272
1273 if (hasSyn)
1274 {
1275 if (m_synCount == 0)
1276 { // No more connection retries, give up
1277 NS_LOG_LOGIC("Connection failed.");
1278 m_rtt->Reset(); // According to recommendation -> RFC 6298
1280 return;
1281 }
1282 else
1283 { // Exponential backoff of connection time out
1284 int backoffCount = 0x1 << (m_synRetries - m_synCount);
1285 m_rto = m_cnTimeout * backoffCount;
1286 m_synCount--;
1287 }
1288 }
1289 if (m_endPoint != nullptr)
1290 {
1291 m_tcp->SendPacket(p,
1292 header,
1296 }
1297 else
1298 {
1299 m_tcp->SendPacket(p,
1300 header,
1304 }
1305
1306 m_txTrace(p, header, this);
1307
1308 if (flags & TcpHeader::ACK)
1309 { // If sending an ACK, cancel the delay ACK as well
1311 m_delAckCount = 0;
1312 }
1313 if (m_retxEvent.IsExpired() && (hasSyn || hasFin) && !isAck)
1314 { // Retransmit SYN / SYN+ACK / FIN / FIN+ACK to guard against lost
1315 NS_LOG_LOGIC("Schedule retransmission timeout at time "
1316 << Simulator::Now().GetSeconds() << " to expire at time "
1317 << (Simulator::Now() + m_rto.Get()).GetSeconds());
1319 }
1320
1321 // send another ACK if bytes remain
1323 m_tcb->m_rxBuffer->NextRxSequence() > m_lastAckedSeq && !hasFin)
1324 {
1325 NS_LOG_DEBUG("Recursing to call SendEmptyPacket() again with m_bytesLeftToBeAcked = "
1327 SendEmptyPacket(flags);
1328 }
1329}
1330
#define Max(a, b)
a polymophic address class
Definition address.h:90
bool IsNull() const
Check for null implementation.
Definition callback.h:555
An identifier for simulation events.
Definition event-id.h:45
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition event-id.cc:44
bool IsExpired() const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition event-id.cc:58
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.
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:106
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.
friend Ptr< T > CopyObject(Ptr< T > object)
Copy an Object.
Definition object.h:581
static void EnablePrinting()
Enable printing packets metadata.
Definition packet.cc:585
Smart pointer class similar to boost::intrusive_ptr.
Base class for all RTT Estimators.
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:560
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static void ScheduleWithContext(uint32_t context, const Time &delay, FUNC f, Ts &&... args)
Schedule an event with the given context.
Definition simulator.h:577
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static void Run()
Run the simulation.
Definition simulator.cc:167
bool IsManualIpTtl() const
Checks if the socket has a specific IPv4 TTL set.
Definition socket.cc:363
virtual uint8_t GetIpTtl() const
Query the value of IP Time to Live field of this socket.
Definition socket.cc:506
uint8_t GetIpTos() const
Query the value of IP Type of Service of this socket.
Definition socket.cc:439
Ptr< NetDevice > m_boundnetdevice
the device this socket is bound to (might be null).
Definition socket.h:1070
virtual uint8_t GetIpv6HopLimit() const
Query the value of IP Hop Limit field of this socket.
Definition socket.cc:531
uint8_t GetIpv6Tclass() const
Query the value of IPv6 Traffic Class field of this socket.
Definition socket.cc:481
bool IsManualIpv6HopLimit() const
Checks if the socket has a specific IPv6 Hop Limit set.
Definition socket.cc:369
bool IsManualIpv6Tclass() const
Checks if the socket has a specific IPv6 Tclass set.
Definition socket.cc:357
indicates whether the socket has IP_TOS set.
Definition socket.h:1260
void SetTos(uint8_t tos)
Set the tag's TOS.
Definition socket.cc:787
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer.
Definition socket.h:1113
void SetTtl(uint8_t ttl)
Set the tag's TTL.
Definition socket.cc:593
This class implements a tag that carries the socket-specific HOPLIMIT of a packet to the IPv6 layer.
Definition socket.h:1161
void SetHopLimit(uint8_t hopLimit)
Set the tag's Hop Limit.
Definition socket.cc:657
indicates whether the socket has IPV6_TCLASS set.
Definition socket.h:1355
void SetTclass(uint8_t tclass)
Set the tag's Tclass.
Definition socket.cc:899
The Classic recovery implementation.
Congestion control abstract class.
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.
virtual void HighestTxSeqTrace(SequenceNumber32 oldValue, SequenceNumber32 newValue)
Highest tx seq changes.
void ErrorCloseCb(Ptr< Socket > socket)
Error Close Callback.
TypeId m_recoveryTypeId
Recovery.
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 DataSent(uint32_t size, SocketWho who)
Notifying application for sent data.
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.
virtual void CWndTrace(uint32_t oldValue, uint32_t newValue)
Tracks the congestion window changes.
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 RateUpdatedTrace(const TcpRateLinux::TcpRateConnection &rate)
Track the rate value of TcpRateLinux.
virtual void NormalClose(SocketWho who)
Socket closed normally.
uint32_t m_mtu
MTU of the environment.
virtual void RcvAck(const Ptr< const TcpSocketState > tcb, const TcpHeader &h, SocketWho who)
Received ack.
virtual void NextTxSeqTrace(SequenceNumber32 oldValue, SequenceNumber32 newValue)
Next tx seq changes.
Time GetMinRto(SocketWho who)
Get the minimum RTO attribute.
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.
virtual void SsThreshTrace(uint32_t oldValue, uint32_t newValue)
Slow start threshold changes.
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.
virtual void BeforeRTOExpired(const Ptr< const TcpSocketState > tcb, SocketWho who)
Rto has expired.
void QueueDropCb(std::string context, Ptr< const Packet > p)
Queue Drop Callback.
virtual void BytesInFlightTrace(uint32_t oldValue, uint32_t newValue)
Bytes in flight changes.
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.
uint32_t GetDupAckCount(SocketWho who)
Get the number of dupack received.
virtual void CWndInflTrace(uint32_t oldValue, uint32_t newValue)
Tracks the inflated congestion window 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 ErrorClose(SocketWho who)
Socket closed with an error.
virtual void ConfigureProperties()
Change the configuration of the socket properties.
virtual void UpdatedRttHistory(const SequenceNumber32 &seq, uint32_t sz, bool isRetransmission, SocketWho who)
Updated the Rtt history.
virtual void QueueDrop(SocketWho who)
Drop on the queue.
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.
TypeId m_congControlTypeId
Congestion control.
virtual void ReceivePacket(Ptr< Socket > socket)
Packet received.
virtual void RateSampleUpdatedTrace(const TcpRateLinux::TcpRateSample &sample)
Track the rate sample value of TcpRateLinux.
virtual void ProcessedAck(const Ptr< const TcpSocketState > tcb, const TcpHeader &h, SocketWho who)
Processed ack.
void DataSentCb(Ptr< Socket > socket, uint32_t size)
Data sent Callback.
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.
virtual void CongStateTrace(const TcpSocketState::TcpCongState_t oldValue, const TcpSocketState::TcpCongState_t newValue)
State on Ack state machine changes.
void NormalCloseCb(Ptr< Socket > socket)
Normal Close Callback.
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 AfterRTOExpired(const Ptr< const TcpSocketState > tcb, SocketWho who)
Rto has expired.
TcpSocket::TcpStates_t GetTcpState(SocketWho who)
Get the state of the TCP state machine.
virtual void PhyDrop(SocketWho who)
Link drop.
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 RtoTrace(Time oldValue, Time newValue)
RTO changes.
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.
uint32_t GetInitialCwnd(SocketWho who)
Get the initial congestion window.
TcpGeneralTest(const std::string &desc)
TcpGeneralTest constructor.
void UpdateRttHistoryCb(Ptr< const TcpSocketBase > tcp, const SequenceNumber32 &seq, uint32_t sz, bool isRetransmission)
Update RTT with new data.
virtual void RttTrace(Time oldTime, Time newTime)
Rtt changes.
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.
Header for the Transmission Control Protocol.
Definition tcp-header.h:36
void SetDestinationPort(uint16_t port)
Set the destination port.
Definition tcp-header.cc:59
void SetSequenceNumber(SequenceNumber32 sequenceNumber)
Set the sequence Number.
Definition tcp-header.cc:65
void SetFlags(uint8_t flags)
Set flags of the header.
Definition tcp-header.cc:77
void SetWindowSize(uint16_t windowSize)
Set the window size.
Definition tcp-header.cc:83
void SetSourcePort(uint16_t port)
Set the source port.
Definition tcp-header.cc:53
void SetAckNumber(SequenceNumber32 ackNumber)
Set the ACK number.
Definition tcp-header.cc:71
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.
AckManagementCb m_processedAckCb
Processed ACK callback.
void SetAfterRetransmitCb(RetrCb cb)
Set the callback invoked after the processing of a retransmit timeout.
void SetForkCb(Callback< void, Ptr< TcpSocketMsgBase > > cb)
Set the callback invoked after the forking.
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.
UseEcn_t
Parameter value related to ECN enable/disable functionality similar to sysctl for tcp_ecn.
encapsulates test code
Definition test.h:1050
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:392
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
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:55
Callback< R, Args... > MakeNullCallback()
Definition callback.h:727
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#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:250
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
TcpStates_t
Names of the 11 TCP states.
Definition tcp-socket.h:55
@ FIN_WAIT_1
Our side has shutdown, waiting to complete transmission of remaining buffered data
Definition tcp-socket.h:68
@ LAST_ACK
Our side has shutdown after remote has shutdown.
Definition tcp-socket.h:65
@ CLOSING
Both sides have shutdown but we still have data we have to finish sending
Definition tcp-socket.h:71
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1320
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:684
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580
uint32_t pktSize
packet size used for the simulation (in bytes)