diff --git a/src/internet/test/tcp-timestamp-test.cc b/src/internet/test/tcp-timestamp-test.cc index 02b65ca66..5de9c5a43 100644 --- a/src/internet/test/tcp-timestamp-test.cc +++ b/src/internet/test/tcp-timestamp-test.cc @@ -17,316 +17,177 @@ * */ -#include "ns3/test.h" -#include "ns3/socket-factory.h" -#include "ns3/tcp-socket-factory.h" -#include "ns3/simulator.h" -#include "ns3/simple-channel.h" -#include "ns3/simple-net-device.h" -#include "ns3/drop-tail-queue.h" -#include "ns3/config.h" -#include "ns3/ipv4-static-routing.h" -#include "ns3/ipv4-list-routing.h" -#include "ns3/ipv6-static-routing.h" -#include "ns3/ipv6-list-routing.h" +#include "tcp-general-test.h" #include "ns3/node.h" -#include "ns3/inet-socket-address.h" -#include "ns3/inet6-socket-address.h" -#include "ns3/uinteger.h" #include "ns3/log.h" -#include "ns3/tcp-socket-base.h" - -#include "ns3/arp-l3-protocol.h" -#include "ns3/ipv4-l3-protocol.h" -#include "ns3/ipv6-l3-protocol.h" -#include "ns3/icmpv4-l4-protocol.h" -#include "ns3/icmpv6-l4-protocol.h" -#include "ns3/udp-l4-protocol.h" -#include "ns3/tcp-l4-protocol.h" - #include "ns3/private/tcp-option-ts.h" namespace ns3 { NS_LOG_COMPONENT_DEFINE ("TimestampTestSuite"); -class TimestampTestCase : public TestCase +class TimestampTestCase : public TcpGeneralTest { public: enum Configuration { DISABLED, - ENABLED_CLIENT, - ENABLED_SERVER, + ENABLED_RECEIVER, + ENABLED_SENDER, ENABLED }; TimestampTestCase (TimestampTestCase::Configuration conf); +protected: + virtual Ptr CreateReceiverSocket (Ptr node); + virtual Ptr CreateSenderSocket (Ptr node); -private: - virtual void DoRun (void); - virtual void DoTeardown (void); - - void SetupDefaultSim (void); - //void SetupDefaultSim6 (void); - - Ptr CreateInternetNode (void); - Ptr CreateInternetNode6 (void); - Ptr AddSimpleNetDevice (Ptr node, const char* ipaddr, const char* netmask); - Ptr AddSimpleNetDevice6 (Ptr node, Ipv6Address ipaddr, Ipv6Prefix prefix); - void ServerHandleConnectionCreated (Ptr s, const Address & addr); - void ServerHandleRecv (Ptr sock); - void ServerHandleSend (Ptr sock, uint32_t sendB); - void SourceHandleSend (Ptr sock, uint32_t available); - void SourceHandleRecv (Ptr sock); + virtual void Tx (const Ptr p, const TcpHeader&h, SocketWho who); + virtual void Rx (const Ptr p, const TcpHeader&h, SocketWho who); Configuration m_configuration; - - uint32_t m_totalBytes; - uint32_t m_sourceWriteSize; - uint32_t m_sourceReadSize; - uint32_t m_serverWriteSize; - uint32_t m_serverReadSize; - uint32_t m_currentSourceTxBytes; - uint32_t m_currentSourceRxBytes; - uint32_t m_currentServerRxBytes; - uint32_t m_currentServerTxBytes; }; TimestampTestCase::TimestampTestCase (TimestampTestCase::Configuration conf) - : TestCase ("Testing the TCP Timestamp option") + : TcpGeneralTest ("Testing the TCP Timestamp option") { m_configuration = conf; - m_totalBytes = 2000; - m_sourceWriteSize = 500; - m_sourceReadSize = 500; - m_serverWriteSize = 500; - m_serverReadSize = 500; } -void -TimestampTestCase::DoRun (void) +Ptr +TimestampTestCase::CreateReceiverSocket (Ptr node) { - m_currentSourceTxBytes = 0; - m_currentSourceRxBytes = 0; - m_currentServerRxBytes = 0; - m_currentServerTxBytes = 0; - - -// if (m_useIpv6 == true) -// { -// SetupDefaultSim6 (); -// } -// else -// { - SetupDefaultSim (); -// } - - Simulator::Run (); - - NS_TEST_EXPECT_MSG_EQ (m_currentSourceTxBytes, m_totalBytes, "Source sent all bytes"); - NS_TEST_EXPECT_MSG_EQ (m_currentServerRxBytes, m_totalBytes, "Server received all bytes"); - NS_TEST_EXPECT_MSG_EQ (m_currentSourceRxBytes, m_totalBytes, "Source received all bytes"); -} - -void -TimestampTestCase::DoTeardown (void) -{ - Simulator::Destroy (); -} - -void -TimestampTestCase::ServerHandleConnectionCreated (Ptr s, const Address & addr) -{ - s->SetRecvCallback (MakeCallback (&TimestampTestCase::ServerHandleRecv, this)); - s->SetSendCallback (MakeCallback (&TimestampTestCase::ServerHandleSend, this)); -} - -void -TimestampTestCase::ServerHandleRecv (Ptr sock) -{ - while (sock->GetRxAvailable () > 0) - { - uint32_t toRead = std::min (m_serverReadSize, sock->GetRxAvailable ()); - Ptr p = sock->Recv (toRead, 0); - - if (p == 0 && sock->GetErrno () != Socket::ERROR_NOTERROR) - { - NS_FATAL_ERROR ("Server could not read stream at byte " << m_currentServerRxBytes); - } - - m_currentServerRxBytes += p->GetSize (); - - ServerHandleSend (sock, sock->GetTxAvailable ()); - } -} - -void -TimestampTestCase::ServerHandleSend (Ptr sock, uint32_t sendB) -{ - while (sock->GetTxAvailable () > 0 && m_currentServerTxBytes < m_currentServerRxBytes) - { - uint32_t left = m_currentServerRxBytes - m_currentServerTxBytes; - uint32_t toSend = std::min (left, sock->GetTxAvailable ()); - toSend = std::min (toSend, m_serverWriteSize); - - Ptr p = Create (toSend); - - int sent = sock->Send (p); - - NS_TEST_EXPECT_MSG_EQ ((sent != -1), true, "Server error during send ?"); - - m_currentServerTxBytes += sent; - } - - if (m_currentServerTxBytes == m_totalBytes) - { - sock->Close (); - } -} - -void -TimestampTestCase::SourceHandleSend (Ptr sock, uint32_t available) -{ - while (sock->GetTxAvailable () > 0 && m_currentSourceTxBytes < m_totalBytes) - { - uint32_t left = m_totalBytes - m_currentSourceTxBytes; - uint32_t toSend = std::min (left, sock->GetTxAvailable ()); - toSend = std::min (toSend, m_sourceWriteSize); - - Ptr p = Create (toSend); - - int sent = sock->Send (p); - NS_TEST_EXPECT_MSG_EQ ((sent != -1), true, "Error during send ?"); - m_currentSourceTxBytes += sent; - } -} - -void -TimestampTestCase::SourceHandleRecv (Ptr sock) -{ - while (sock->GetRxAvailable () > 0 && m_currentSourceRxBytes < m_totalBytes) - { - uint32_t toRead = std::min (m_sourceReadSize, sock->GetRxAvailable ()); - Ptr p = sock->Recv (toRead, 0); - - if (p == 0 && sock->GetErrno () != Socket::ERROR_NOTERROR) - { - NS_FATAL_ERROR ("Source could not read stream at byte " << m_currentSourceRxBytes); - } - - m_currentSourceRxBytes += p->GetSize (); - } - - if (m_currentSourceRxBytes == m_totalBytes) - { - sock->Close (); - } -} - -Ptr -TimestampTestCase::CreateInternetNode () -{ - Ptr node = CreateObject (); - //ARP - Ptr arp = CreateObject (); - node->AggregateObject (arp); - //IPV4 - Ptr ipv4 = CreateObject (); - //Routing for Ipv4 - Ptr ipv4Routing = CreateObject (); - ipv4->SetRoutingProtocol (ipv4Routing); - Ptr ipv4staticRouting = CreateObject (); - ipv4Routing->AddRoutingProtocol (ipv4staticRouting, 0); - node->AggregateObject (ipv4); - //ICMP - Ptr icmp = CreateObject (); - node->AggregateObject (icmp); - //UDP - Ptr udp = CreateObject (); - node->AggregateObject (udp); - //TCP - Ptr tcp = CreateObject (); - node->AggregateObject (tcp); - return node; -} - -Ptr -TimestampTestCase::AddSimpleNetDevice (Ptr node, const char* ipaddr, const char* netmask) -{ - Ptr dev = CreateObject (); - dev->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ())); - node->AddDevice (dev); - Ptr ipv4 = node->GetObject (); - uint32_t ndid = ipv4->AddInterface (dev); - Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (Ipv4Address (ipaddr), Ipv4Mask (netmask)); - ipv4->AddAddress (ndid, ipv4Addr); - ipv4->SetUp (ndid); - return dev; -} - -void -TimestampTestCase::SetupDefaultSim (void) -{ - const char* netmask = "255.255.255.0"; - const char* ipaddr0 = "192.168.1.1"; - const char* ipaddr1 = "192.168.1.2"; - Ptr node0 = CreateInternetNode (); - Ptr node1 = CreateInternetNode (); - Ptr dev0 = AddSimpleNetDevice (node0, ipaddr0, netmask); - Ptr dev1 = AddSimpleNetDevice (node1, ipaddr1, netmask); - - Ptr channel = CreateObject (); - dev0->SetChannel (channel); - dev1->SetChannel (channel); - - Ptr sockFactory0 = node0->GetObject (); - Ptr sockFactory1 = node1->GetObject (); - - Ptr server = DynamicCast (sockFactory0->CreateSocket ()); - Ptr source = DynamicCast (sockFactory1->CreateSocket ()); - - NS_ASSERT (server != 0); - NS_ASSERT (source != 0); + Ptr socket = TcpGeneralTest::CreateReceiverSocket (node); switch (m_configuration) { case DISABLED: - server->SetAttribute ("Timestamp", BooleanValue (false)); - source->SetAttribute ("Timestamp", BooleanValue (false)); + socket->SetAttribute ("Timestamp", BooleanValue (false)); break; - case ENABLED_CLIENT: - server->SetAttribute ("Timestamp", BooleanValue (false)); - source->SetAttribute ("Timestamp", BooleanValue (true)); + case ENABLED_RECEIVER: + socket->SetAttribute ("Timestamp", BooleanValue (true)); break; - case ENABLED_SERVER: - server->SetAttribute ("Timestamp", BooleanValue (true)); - source->SetAttribute ("Timestamp", BooleanValue (false)); + case ENABLED_SENDER: + socket->SetAttribute ("Timestamp", BooleanValue (false)); break; case ENABLED: - server->SetAttribute ("Timestamp", BooleanValue (true)); - source->SetAttribute ("Timestamp", BooleanValue (true)); + socket->SetAttribute ("Timestamp", BooleanValue (true)); break; } - uint16_t port = 50000; - InetSocketAddress serverlocaladdr (Ipv4Address::GetAny (), port); - InetSocketAddress serverremoteaddr (Ipv4Address (ipaddr0), port); - - server->Bind (serverlocaladdr); - server->Listen (); - server->SetAcceptCallback (MakeNullCallback, const Address &> (), - MakeCallback (&TimestampTestCase::ServerHandleConnectionCreated,this)); - - source->SetRecvCallback (MakeCallback (&TimestampTestCase::SourceHandleRecv, this)); - source->SetSendCallback (MakeCallback (&TimestampTestCase::SourceHandleSend, this)); - - source->Connect (serverremoteaddr); + return socket; } +Ptr +TimestampTestCase::CreateSenderSocket (Ptr node) +{ + Ptr socket = TcpGeneralTest::CreateSenderSocket (node); + + switch (m_configuration) + { + case DISABLED: + socket->SetAttribute ("Timestamp", BooleanValue (false)); + break; + + case ENABLED_RECEIVER: + socket->SetAttribute ("Timestamp", BooleanValue (false)); + break; + + case ENABLED_SENDER: + socket->SetAttribute ("Timestamp", BooleanValue (true)); + break; + + case ENABLED: + socket->SetAttribute ("Timestamp", BooleanValue (true)); + break; + } + + return socket; +} + +void +TimestampTestCase::Tx (const Ptr p, const TcpHeader &h, SocketWho who) +{ + if (m_configuration == DISABLED) + { + NS_TEST_ASSERT_MSG_EQ (h.HasOption (TcpOption::TS), false, + "timestamp disabled but option enabled"); + } + else if (m_configuration == ENABLED) + { + NS_TEST_ASSERT_MSG_EQ (h.HasOption (TcpOption::TS), true, + "timestamp enabled but option disabled"); + } + + NS_LOG_INFO (h); + if (who == SENDER) + { + if (h.GetFlags () & TcpHeader::SYN) + { + if (m_configuration == ENABLED_RECEIVER) + { + NS_TEST_ASSERT_MSG_EQ (h.HasOption (TcpOption::TS), false, + "timestamp disabled but option enabled"); + } + else if (m_configuration == ENABLED_SENDER) + { + NS_TEST_ASSERT_MSG_EQ (h.HasOption (TcpOption::TS), true, + "timestamp enabled but option disabled"); + } + } + else + { + if (m_configuration != ENABLED) + { + NS_TEST_ASSERT_MSG_EQ (h.HasOption (TcpOption::TS), false, + "timestamp disabled but option enabled"); + } + } + } + else if (who == RECEIVER) + { + if (h.GetFlags () & TcpHeader::SYN) + { + // Sender has not sent timestamp, so implementation should disable ts + if (m_configuration == ENABLED_RECEIVER) + { + NS_TEST_ASSERT_MSG_EQ (h.HasOption (TcpOption::TS), false, + "sender has not ts, but receiver sent anyway"); + } + else if (m_configuration == ENABLED_SENDER) + { + NS_TEST_ASSERT_MSG_EQ (h.HasOption (TcpOption::TS), false, + "receiver has not ts enabled but sent anyway"); + } + } + else + { + if (m_configuration != ENABLED) + { + NS_TEST_ASSERT_MSG_EQ (h.HasOption (TcpOption::TS), false, + "timestamp disabled but option enabled"); + } + } + } +} + +void +TimestampTestCase::Rx (const Ptr p, const TcpHeader &h, SocketWho who) +{ + if (who == SENDER) + { + + } + else if (who == RECEIVER) + { + + } +} + +// TimestampValueTestCase class TimestampValueTestCase : public TestCase { public: @@ -396,8 +257,8 @@ public: : TestSuite ("tcp-timestamp", UNIT) { AddTestCase (new TimestampTestCase (TimestampTestCase::DISABLED), TestCase::QUICK); - AddTestCase (new TimestampTestCase (TimestampTestCase::ENABLED_CLIENT), TestCase::QUICK); - AddTestCase (new TimestampTestCase (TimestampTestCase::ENABLED_SERVER), TestCase::QUICK); + AddTestCase (new TimestampTestCase (TimestampTestCase::ENABLED_RECEIVER), TestCase::QUICK); + AddTestCase (new TimestampTestCase (TimestampTestCase::ENABLED_SENDER), TestCase::QUICK); AddTestCase (new TimestampTestCase (TimestampTestCase::ENABLED), TestCase::QUICK); AddTestCase (new TimestampValueTestCase (0.0, 0.01, "Value Check"), TestCase::QUICK); AddTestCase (new TimestampValueTestCase (3.0, 0.5, "Value Check"), TestCase::QUICK);