ns3 ringtopology

 I created a ring topology for multi-interface purpose similar the ns3 example SocketBoundTcpRoutingExample. The topolgy in SocketBoundTcpRoutingExample is the following:

/* Test program for multi-interface host, static routing

         Destination host (10.20.1.2)
                 |
                 | 10.20.1.0/24
              DSTRTR 
  10.10.1.0/24 /   \  10.10.2.0/24
              /     \
           Rtr1    Rtr2
 10.1.1.0/24 |      | 10.1.2.0/24
             |      /
              \    /
             Source
*/

 But I just add two routers in my topology:

/* Ring Network Topology
    10.1.1.0   n1--10.1.2.0--n2 10.1.3.0
  n0/                           \n5
    \10.1.4.0  n3--10.1.5.0--n4 /  10.1.6.0          
*/

 But it just did not work. The server can receive syn packet but the client seems can not get the syn+ack packet. So the three handshakes failed. Finally, I found the interface parameter in function(AddHostRouteTo (Ipv4Address (“10.1.1.1”), Ipv4Address (“10.1.2.1”), 2)) is the reason for this misbehavior. I change it to number 1, and it works. This parameter is the index for multi-interface of node. I put up my codes that works in here for record purpose.

ringtopology.cc

#include <ctype.h>
#include <iostream>
#include <fstream>
#include <string>
#include <cassert>

#include "ns3/core-module.h"
#include "ns3/applications-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/ipv4-global-routing-helper.h"

/* Ring Network Topology
    10.1.1.0   n1--10.1.2.0--n2 10.1.3.0
  n0/                           \n5
    \10.1.4.0  n3--10.1.5.0--n4 /  10.1.6.0          
*/

using namespace ns3;
using namespace std;
NS_LOG_COMPONENT_DEFINE("FirstRingTopology");

// The number of bytes to send in this simulation.
static const uint32_t totalTxBytes = 150000000;
//static const uint32_t totalTxBytes = 100;
static const uint32_t sendBufSize  = 14000; //2000000;
static const uint32_t recvBufSize  = 15000; //2000000;
static uint32_t currentTxBytes     = 0;
static const double simDuration    = 30.0;

Ptr<Node> client;
Ptr<Node> server;

static const uint32_t writeSize = 1500;
uint8_t data[writeSize];


void StartFlow (Ptr<Socket>, Ipv4Address, uint16_t);
void WriteUntilBufferFull (Ptr<Socket>, unsigned int);
void connectionSucceeded(Ptr<Socket>);
void connectionFailed(Ptr<Socket>);

void HandlePeerClose (Ptr<Socket>);
void HandlePeerError (Ptr<Socket>);
void CloseConnection (Ptr<Socket>);

int connect(Address &addr);

static void
CwndTracer (double oldval, double newval)
{
  NS_LOG_INFO ("Moving cwnd from " << oldval << " to " << newval);
}
bool IsExistRoute (Ptr<Node> node,Ipv4Address src, Ipv4Address dst)
{
  bool found = false;
  uint32_t interface=0;
  Ptr<Node> m_node=node;
  // Look up the source address
  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();

  assert (ipv4->GetRoutingProtocol () != 0); 

  Ipv4Header l3Header;
  Socket::SocketErrno errno_;
  Ptr<Ipv4Route> route;


  interface=ipv4->GetInterfaceForAddress(src);      //Pablo UC
  Ptr<NetDevice> oif=ipv4->GetNetDevice(interface); //Pablo UC
  l3Header.SetSource (src);
  l3Header.SetDestination (dst);
  route = ipv4->GetRoutingProtocol ()->RouteOutput (Ptr<Packet> (), l3Header, oif, errno_);

  if ((route != 0) && (src == route->GetSource ()))
  {
    NS_LOG_INFO ("IsThereRoute -> Route from srcAddr "<< src << " to dstAddr " << dst << " oit "<<oif<<", exist !");
    found = true;
  }else
    NS_LOG_INFO ("IsThereRoute -> No Route from srcAddr "<< src << " to dstAddr " << dst << " oit "<<oif<<", exist !");

  return found;
}
int main (int argc, char *argv[])
{
  CommandLine cmd;
  cmd.Parse (argc, argv);
  uint32_t queueSize=100;
  uint32_t bottleQueueSize=5;
  LogComponentEnable("FirstRingTopology", LOG_LEVEL_ALL);
  LogComponentEnable("TcpSocketBase", LOG_LEVEL_ALL);
  // initialize the tx buffer.
  for(uint32_t i = 0; i < writeSize; ++i)
    {
      char m = toascii (97 + i % 26);
      data[i] = m;
    }
    // Creation of the hosts
    NodeContainer nodes;
    nodes.Create(6);
    client = nodes.Get(0);
    server = nodes.Get(5);

    InternetStackHelper spstack;
    spstack.SetTcp("ns3::TcpL4Protocol");
    spstack.Install(nodes);

    vector<Ipv4InterfaceContainer> ipv4Ints;
    //link n0-n1   0
    {
        PointToPointHelper p2plink;
        p2plink.SetQueue ("ns3::DropTailQueue", "MaxPackets",UintegerValue(queueSize));
        p2plink.SetChannelAttribute("Delay", StringValue("30ms"));
        p2plink.SetDeviceAttribute ("DataRate", StringValue("2Mbps"));
        NetDeviceContainer netDevices;
        netDevices = p2plink.Install(nodes.Get(0),nodes.Get(1));
        std::stringstream netAddr;
        netAddr << "10.1." <<"1"<< ".0";
        string str = netAddr.str();
        Ipv4AddressHelper ipv4addr;
        ipv4addr.SetBase(str.c_str(), "255.255.255.0");
        Ipv4InterfaceContainer interface = ipv4addr.Assign(netDevices);
        ipv4Ints.insert(ipv4Ints.end(), interface);
    }
    //link n1-n2  1
    {
        PointToPointHelper p2plink;
        p2plink.SetQueue ("ns3::DropTailQueue", "MaxPackets",UintegerValue(bottleQueueSize));
        p2plink.SetChannelAttribute("Delay", StringValue("50ms"));
        p2plink.SetDeviceAttribute ("DataRate", StringValue("1Mbps"));
        NetDeviceContainer netDevices;
        netDevices = p2plink.Install(nodes.Get(1),nodes.Get(2));
        std::stringstream netAddr;
        netAddr << "10.1." <<"2"<< ".0";
        string str = netAddr.str();
        Ipv4AddressHelper ipv4addr;
        ipv4addr.SetBase(str.c_str(), "255.255.255.0");
        Ipv4InterfaceContainer interface = ipv4addr.Assign(netDevices);
        ipv4Ints.insert(ipv4Ints.end(), interface);     
    }
    //link n2-n5  2
    {
        PointToPointHelper p2plink;
        p2plink.SetQueue ("ns3::DropTailQueue", "MaxPackets",UintegerValue(queueSize));
        p2plink.SetChannelAttribute("Delay", StringValue("20ms"));
        p2plink.SetDeviceAttribute ("DataRate", StringValue("2Mbps"));
        NetDeviceContainer netDevices;
        netDevices = p2plink.Install(nodes.Get(2),nodes.Get(5));
        std::stringstream netAddr;
        netAddr << "10.1." <<"3"<< ".0";
        string str = netAddr.str();
        Ipv4AddressHelper ipv4addr;
        ipv4addr.SetBase(str.c_str(), "255.255.255.0");
        Ipv4InterfaceContainer interface = ipv4addr.Assign(netDevices);
        ipv4Ints.insert(ipv4Ints.end(), interface);     
    }
        //link n0-n3  3
    {
        PointToPointHelper p2plink;
        p2plink.SetQueue ("ns3::DropTailQueue", "MaxPackets",UintegerValue(queueSize));
        p2plink.SetChannelAttribute("Delay", StringValue("50ms"));
        p2plink.SetDeviceAttribute ("DataRate", StringValue("3Mbps"));
        NetDeviceContainer netDevices;
        netDevices = p2plink.Install(nodes.Get(0),nodes.Get(3));
        std::stringstream netAddr;
        netAddr << "10.1." <<"4"<< ".0";
        string str = netAddr.str();
        Ipv4AddressHelper ipv4addr;
        ipv4addr.SetBase(str.c_str(), "255.255.255.0");
        Ipv4InterfaceContainer interface = ipv4addr.Assign(netDevices);
        ipv4Ints.insert(ipv4Ints.end(), interface);     
    }
        //link n3-n4  4
    {
        PointToPointHelper p2plink;
        p2plink.SetQueue ("ns3::DropTailQueue", "MaxPackets",UintegerValue(bottleQueueSize));
        p2plink.SetChannelAttribute("Delay", StringValue("100ms"));
        p2plink.SetDeviceAttribute ("DataRate", StringValue("1Mbps"));
        NetDeviceContainer netDevices;
        netDevices = p2plink.Install(nodes.Get(3),nodes.Get(4));
        std::stringstream netAddr;
        netAddr << "10.1." <<"5"<< ".0";
        string str = netAddr.str();
        Ipv4AddressHelper ipv4addr;
        ipv4addr.SetBase(str.c_str(), "255.255.255.0");
        Ipv4InterfaceContainer interface = ipv4addr.Assign(netDevices);
        ipv4Ints.insert(ipv4Ints.end(), interface);     
    }
        //link n4-n5  5
    {
        PointToPointHelper p2plink;
        p2plink.SetQueue ("ns3::DropTailQueue", "MaxPackets",UintegerValue(bottleQueueSize));
        p2plink.SetChannelAttribute("Delay", StringValue("50ms"));
        p2plink.SetDeviceAttribute ("DataRate", StringValue("3Mbps"));
        NetDeviceContainer netDevices;
        netDevices = p2plink.Install(nodes.Get(4),nodes.Get(5));
        std::stringstream netAddr;
        netAddr << "10.1." <<"6"<< ".0";
        string str = netAddr.str();
        Ipv4AddressHelper ipv4addr;
        ipv4addr.SetBase(str.c_str(), "255.255.255.0");
        Ipv4InterfaceContainer interface = ipv4addr.Assign(netDevices);
        ipv4Ints.insert(ipv4Ints.end(), interface);     
    }
    Ptr<Ipv4> ipv4n0 = nodes.Get(0)->GetObject<Ipv4> ();
    Ptr<Ipv4> ipv4n1 = nodes.Get(1)->GetObject<Ipv4> ();
    Ptr<Ipv4> ipv4n2 = nodes.Get(2)->GetObject<Ipv4> ();
    Ptr<Ipv4> ipv4n5 = nodes.Get(5)->GetObject<Ipv4> ();
    Ptr<Ipv4> ipv4n3 = nodes.Get(3)->GetObject<Ipv4> ();
    Ptr<Ipv4> ipv4n4 = nodes.Get(4)->GetObject<Ipv4> ();
    Ipv4StaticRoutingHelper ipv4RoutingHelper;
    Ptr<Ipv4StaticRouting> staticRoutingn0 = ipv4RoutingHelper.GetStaticRouting (ipv4n0);
    Ptr<Ipv4StaticRouting> staticRoutingn1 = ipv4RoutingHelper.GetStaticRouting (ipv4n1);
    Ptr<Ipv4StaticRouting> staticRoutingn2 = ipv4RoutingHelper.GetStaticRouting (ipv4n2);
    Ptr<Ipv4StaticRouting> staticRoutingn5 = ipv4RoutingHelper.GetStaticRouting (ipv4n5);
    Ptr<Ipv4StaticRouting> staticRoutingn3 = ipv4RoutingHelper.GetStaticRouting (ipv4n3);
    Ptr<Ipv4StaticRouting> staticRoutingn4 = ipv4RoutingHelper.GetStaticRouting (ipv4n4);
    //n1->n5
    staticRoutingn1->AddHostRouteTo (Ipv4Address ("10.1.3.2"), Ipv4Address ("10.1.2.2"), 2);
    //n0->n5
    staticRoutingn0->AddHostRouteTo (Ipv4Address ("10.1.3.2"), Ipv4Address ("10.1.1.2"),1, 5);  

    //n3->n5
    staticRoutingn3->AddHostRouteTo (Ipv4Address ("10.1.6.2"), Ipv4Address ("10.1.5.2"), 2);
    //n0->n5
    staticRoutingn0->AddHostRouteTo (Ipv4Address ("10.1.6.2"), Ipv4Address ("10.1.4.2"), 2,10);


    //n2->n0
    staticRoutingn2->AddHostRouteTo (Ipv4Address ("10.1.1.1"), Ipv4Address ("10.1.2.1"), 1);  
    //fuck this metrics,cost me nearly four hours!fuck!
    //n5->n0
    staticRoutingn5->AddHostRouteTo (Ipv4Address ("10.1.1.1"), Ipv4Address ("10.1.3.1"),1, 5);
    //n1->n0
    //staticRoutingn1->AddHostRouteTo(Ipv4Address ("10.1.1.1"), Ipv4Address ("10.1.1.1"), 1); 

    //n4->n0
    staticRoutingn4->AddHostRouteTo (Ipv4Address ("10.1.4.1"), Ipv4Address ("10.1.5.1"), 1);    
    //n5->n0
    staticRoutingn5->AddHostRouteTo (Ipv4Address ("10.1.4.1"), Ipv4Address ("10.1.6.1"), 2,10);    
NS_LOG_INFO("is exist route"<<IsExistRoute(nodes.Get(0),Ipv4Address ("10.1.1.1"),Ipv4Address ("10.1.3.2")));
NS_LOG_INFO("is exist route"<<IsExistRoute(nodes.Get(0),Ipv4Address ("10.1.4.1"),Ipv4Address ("10.1.6.2")));
NS_LOG_INFO("is exist route"<<IsExistRoute(nodes.Get(5),Ipv4Address ("10.1.3.2"),Ipv4Address ("10.1.1.1")));
NS_LOG_INFO("is exist route"<<IsExistRoute(nodes.Get(5),Ipv4Address ("10.1.6.2"),Ipv4Address ("10.1.4.1")));
NS_LOG_INFO("is exist route"<<IsExistRoute(nodes.Get(0),Ipv4Address ("10.1.1.1"),Ipv4Address ("10.1.6.2")));
Ptr<Ipv4L3Protocol> ipv4l3 = nodes.Get(0)->GetObject<Ipv4L3Protocol>();
for(int i = 0; i < ipv4l3->GetNInterfaces(); i++)
{
        Ptr<Ipv4Interface> interface = ipv4l3->GetInterface(i);
        Ipv4InterfaceAddress interfaceAddr = interface->GetAddress (0);
    Ipv4Address ipv4Addr = interfaceAddr.GetLocal();
    NS_LOG_INFO ("node0 address " << ipv4Addr);

}
    NS_LOG_INFO ("server address " << ipv4Ints[5].GetAddress (1));  
    uint32_t servPort = 5000;
    PacketSinkHelper sink ("ns3::TcpSocketFactory",
                         InetSocketAddress (Ipv4Address::GetAny (), servPort));

    ApplicationContainer apps = sink.Install (server);
    apps.Start(Seconds(0.0));
    apps.Stop(Seconds(simDuration));
    Ptr<Socket> lSocket=Socket::CreateSocket (client, TypeId::LookupByName ("ns3::TcpSocketFactory"));
    //InetSocketAddress local = InetSocketAddress (ipv4Ints[0].GetAddress (0), 4000);
NS_LOG_INFO ("client address " << ipv4Ints[0].GetAddress (1));
    lSocket->Bind ();
    Simulator::ScheduleNow (&StartFlow, lSocket, ipv4Ints[5].GetAddress (1), servPort);
    Simulator::Stop (Seconds(simDuration + 10.0));
    Simulator::Run ();
    Simulator::Destroy();
    NS_LOG_LOGIC("mpTopology:: simulation ended");
    return 0;
}
void StartFlow (Ptr<Socket> lSocket,
                Ipv4Address servAddress,
                uint16_t servPort)
{
  NS_LOG_LOGIC ("Starting flow at time " <<  Simulator::Now ().GetSeconds ());
  lSocket->SetConnectCallback  (MakeCallback (&connectionSucceeded), MakeCallback (&connectionFailed));
int connectionState = lSocket->Connect (InetSocketAddress (servAddress, servPort));
NS_LOG_INFO ("in startflow server address "<<servAddress<<" "<<servPort);
  if(connectionState == 0)
  {
      NS_LOG_INFO("connection succeed");

      lSocket->SetDataSentCallback (MakeCallback (&WriteUntilBufferFull));
      lSocket->SetCloseCallbacks   (MakeCallback (&HandlePeerClose), MakeCallback(&HandlePeerError));
  }else
  {
      NS_LOG_LOGIC("ringTopology:: connection failed");
  }  
}
void connectionSucceeded (Ptr<Socket> localSocket)
{
    NS_LOG_FUNCTION_NOARGS();
    NS_LOG_INFO("mpTopology: Connection requeste succeed");
    Simulator::ScheduleNow (&WriteUntilBufferFull, localSocket, 0);
    Simulator::Schedule (Seconds (simDuration), &CloseConnection, localSocket);
}
void connectionFailed (Ptr<Socket> lSocket)
{
    NS_LOG_FUNCTION_NOARGS();
    NS_LOG_INFO("mpTopology: Connection requeste failure");
    lSocket->Close();
}

void HandlePeerClose (Ptr<Socket> localSocket)
{
    NS_LOG_FUNCTION_NOARGS();
    //NS_LOG_INFO("mpTopology: Connection closed by peer");
    NS_LOG_LOGIC("mpTopology: Connection closed by peer"<<Simulator::Now ().GetSeconds ());
    localSocket->Close();
}

void HandlePeerError (Ptr<Socket> localSocket)
{
    NS_LOG_FUNCTION_NOARGS();
    //NS_LOG_INFO("mpTopology: Connection closed by peer error");
    NS_LOG_LOGIC("mpTopology: Connection closed by peer error"<<Simulator::Now ().GetSeconds ());
    localSocket->Close();
}

void CloseConnection (Ptr<Socket> localSocket)
{
    localSocket->Close();
    NS_LOG_LOGIC("ringTopology:: currentTxBytes = " << currentTxBytes);
    NS_LOG_LOGIC("ringTopology:: totalTxBytes   = " << totalTxBytes);
    NS_LOG_LOGIC("ringTopology:: connection to remote host has been closed");
}
void WriteUntilBufferFull (Ptr<Socket> localSocket, unsigned int txSpace)
{
 while (currentTxBytes < totalTxBytes && localSocket->GetTxAvailable () > 0) 
    {
      uint32_t left = totalTxBytes - currentTxBytes;
      uint32_t dataOffset = currentTxBytes % writeSize;
      uint32_t toWrite = writeSize - dataOffset;
      toWrite = std::min (toWrite, left);
      toWrite = std::min (toWrite, localSocket->GetTxAvailable ());
      int amountSent = localSocket->Send (&data[dataOffset], toWrite, 0);
      NS_LOG_INFO("DATA SENT in WriteUntilBufferFull"<<amountSent);
      if(amountSent < 0)
        {
          // we will be called again when new tx space becomes available.
          return;
        }
      currentTxBytes += amountSent;
    }
  localSocket->Close ();
  }

And this interfaces index configuration works too:

//       -(if1)-n1-(if2)-----(if1)-n2-(if2)-
//(if1)/                                     \(if1)
//  n0                                          n5
//if(2) \                                    /(if2)
//        -(if1)-n3-(if2)-----(if1)-n4-(if2)-
    //n1->n5
    staticRoutingn1->AddHostRouteTo (Ipv4Address ("10.1.3.2"), Ipv4Address ("10.1.2.2"), 2);
    //n0->n5
    staticRoutingn0->AddHostRouteTo (Ipv4Address ("10.1.3.2"), Ipv4Address ("10.1.1.2"),1); 
    //n3->n5
    staticRoutingn3->AddHostRouteTo (Ipv4Address ("10.1.6.2"), Ipv4Address ("10.1.5.2"), 2);
    //n0->n5
    staticRoutingn0->AddHostRouteTo (Ipv4Address ("10.1.6.2"), Ipv4Address ("10.1.4.2"), 2);
    //n2->n0
    staticRoutingn2->AddHostRouteTo (Ipv4Address ("10.1.1.1"), Ipv4Address ("10.1.2.1"), 1);
    //n5->n0
    staticRoutingn5->AddHostRouteTo (Ipv4Address ("10.1.1.1"), Ipv4Address ("10.1.3.1"),1);
    //n1->n0
    //staticRoutingn1->AddHostRouteTo(Ipv4Address ("10.1.1.1"), Ipv4Address ("10.1.1.1"), 1); 
    //n4->n0
    staticRoutingn4->AddHostRouteTo (Ipv4Address ("10.1.4.1"), Ipv4Address ("10.1.5.1"), 1);    
    //n5->n0
    staticRoutingn5->AddHostRouteTo (Ipv4Address ("10.1.4.1"), Ipv4Address ("10.1.6.1"), 2,10); 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325425473&siteId=291194637