src/internet-stack/nsc-tcp-l4-protocol.cc
changeset 4685 ae536d9e0d6d
parent 4669 8aaa5e83939e
     1.1 --- a/src/internet-stack/nsc-tcp-l4-protocol.cc	Tue Jul 07 21:18:01 2009 +0200
     1.2 +++ b/src/internet-stack/nsc-tcp-l4-protocol.cc	Wed Jul 15 18:46:14 2009 +0200
     1.3 @@ -19,7 +19,6 @@
     1.4  
     1.5  #include "ns3/assert.h"
     1.6  #include "ns3/log.h"
     1.7 -#include "ns3/nstime.h"
     1.8  
     1.9  #include "ns3/packet.h"
    1.10  #include "ns3/node.h"
    1.11 @@ -32,7 +31,7 @@
    1.12  #include "ipv4-end-point.h"
    1.13  #include "ipv4-l3-protocol.h"
    1.14  #include "nsc-tcp-l4-protocol.h"
    1.15 -#include "nsc-sysctl.h"
    1.16 +
    1.17  #include "nsc-tcp-socket-factory-impl.h"
    1.18  
    1.19  #include "tcp-typedefs.h"
    1.20 @@ -87,36 +86,18 @@
    1.21    return tid;
    1.22  }
    1.23  
    1.24 -int external_rand()
    1.25 +NscTcpL4Protocol::NscTcpL4Protocol ()
    1.26 +  : m_endPoints (new Ipv4EndPointDemux ())
    1.27  {
    1.28 -    return 1; // TODO
    1.29 -}
    1.30 -
    1.31 -NscTcpL4Protocol::NscTcpL4Protocol ()
    1.32 -  : m_endPoints (new Ipv4EndPointDemux ()),
    1.33 -    m_nscStack (0),
    1.34 -    m_softTimer (Timer::CANCEL_ON_DESTROY)
    1.35 -{
    1.36 -  m_dlopenHandle = NULL;
    1.37    NS_LOG_LOGIC("Made a NscTcpL4Protocol "<<this);
    1.38  }
    1.39  
    1.40 -NscTcpL4Protocol::~NscTcpL4Protocol ()
    1.41 -{
    1.42 -  NS_LOG_FUNCTION (this);
    1.43 -  dlclose(m_dlopenHandle);
    1.44 -}
    1.45 -
    1.46  void
    1.47  NscTcpL4Protocol::SetNscLibrary(const std::string &soname)
    1.48  {    
    1.49    if (soname!="")
    1.50      {
    1.51        m_nscLibrary = soname;
    1.52 -      NS_ASSERT(!m_dlopenHandle);
    1.53 -      m_dlopenHandle = dlopen(soname.c_str (), RTLD_NOW);
    1.54 -      if (m_dlopenHandle == NULL)
    1.55 -        NS_FATAL_ERROR (dlerror());
    1.56      }
    1.57  }
    1.58  
    1.59 @@ -125,40 +106,14 @@
    1.60  {
    1.61    return m_nscLibrary;
    1.62  }
    1.63 -void 
    1.64 +
    1.65 +
    1.66 +void
    1.67  NscTcpL4Protocol::SetNode (Ptr<Node> node)
    1.68  {
    1.69    m_node = node;
    1.70 -
    1.71 -  if (m_nscStack)
    1.72 -    { // stack has already been loaded...
    1.73 -      return;
    1.74 -    }
    1.75 -
    1.76 -  NS_ASSERT(m_dlopenHandle);
    1.77 -
    1.78 -  FCreateStack create = (FCreateStack)dlsym(m_dlopenHandle, "nsc_create_stack");
    1.79 -  NS_ASSERT(create);
    1.80 -  m_nscStack = create(this, this, external_rand);
    1.81 -  int hzval = m_nscStack->get_hz();
    1.82 -
    1.83 -  NS_ASSERT(hzval > 0);
    1.84 -
    1.85 -  m_softTimer.SetFunction (&NscTcpL4Protocol::SoftInterrupt, this);
    1.86 -  m_softTimer.SetDelay (MilliSeconds (1000/hzval));
    1.87 -  m_nscStack->init(hzval);
    1.88 -  // This enables stack and NSC debug messages
    1.89 -  // m_nscStack->set_diagnostic(1000);
    1.90 -
    1.91 -  Ptr<Ns3NscStack> nscStack = Create<Ns3NscStack> ();
    1.92 -  nscStack->SetStack (m_nscStack);
    1.93 -  node->AggregateObject (nscStack);
    1.94 -
    1.95 -  m_softTimer.Schedule ();
    1.96 -
    1.97 -  // its likely no ns-3 interface exits at this point, so
    1.98 -  // we dealy adding the nsc interface until the start of the simulation.
    1.99 -  Simulator::ScheduleNow (&NscTcpL4Protocol::AddInterface, this);
   1.100 +  m_node->SetNscLibrary (m_nscLibrary);
   1.101 +  m_node->RegisterNscWakeupCallback (MakeCallback (&NscTcpL4Protocol::Wakeup , this));
   1.102  }
   1.103  
   1.104  void
   1.105 @@ -270,82 +225,10 @@
   1.106  NscTcpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint)
   1.107  {
   1.108    NS_LOG_FUNCTION (this << endPoint);
   1.109 -  // NSC m_endPoints->DeAllocate (endPoint);
   1.110 +  m_endPoints->DeAllocate (endPoint);
   1.111  }
   1.112  
   1.113 -Ipv4L4Protocol::RxStatus
   1.114 -NscTcpL4Protocol::Receive (Ptr<Packet> packet,
   1.115 -             Ipv4Address const &source,
   1.116 -             Ipv4Address const &destination,
   1.117 -             Ptr<Ipv4Interface> incomingInterface)
   1.118 -{
   1.119 -  NS_LOG_FUNCTION (this << packet << source << destination << incomingInterface);
   1.120 -  Ipv4Header ipHeader;
   1.121 -  uint32_t packetSize = packet->GetSize();
   1.122 -
   1.123 -  // The way things work at the moment, the IP header has been removed
   1.124 -  // by the ns-3 IPv4 processing code. However, the NSC stack expects
   1.125 -  // a complete IP packet, so we add the IP header back.
   1.126 -  // Since the original header is already gone, we create a new one
   1.127 -  // based on the information we have.
   1.128 -  ipHeader.SetSource (source);
   1.129 -  ipHeader.SetDestination (destination);
   1.130 -  ipHeader.SetProtocol (PROT_NUMBER);
   1.131 -  ipHeader.SetPayloadSize (packetSize);
   1.132 -  ipHeader.SetTtl (1);
   1.133 -  // all NSC stacks check the IP checksum
   1.134 -  ipHeader.EnableChecksum ();
   1.135 -
   1.136 -  packet->AddHeader(ipHeader);
   1.137 -  packetSize = packet->GetSize();
   1.138 -
   1.139 -  const uint8_t *data = const_cast<uint8_t *>(packet->PeekData());
   1.140 -
   1.141 -  // deliver complete packet to the NSC network stack
   1.142 -  m_nscStack->if_receive_packet(0, data, packetSize);
   1.143 -  wakeup ();
   1.144 -  return Ipv4L4Protocol::RX_OK;
   1.145 -}
   1.146 -
   1.147 -void NscTcpL4Protocol::SoftInterrupt (void)
   1.148 -{
   1.149 -  m_nscStack->timer_interrupt ();
   1.150 -  m_nscStack->increment_ticks ();
   1.151 -  m_softTimer.Schedule ();
   1.152 -}
   1.153 -
   1.154 -void NscTcpL4Protocol::send_callback(const void* data, int datalen)
   1.155 -{
   1.156 -  Ptr<Packet> p;
   1.157 -  uint32_t ipv4Saddr, ipv4Daddr;
   1.158 -
   1.159 -  NS_ASSERT(datalen > 20);
   1.160 -
   1.161 -
   1.162 -  // create packet, without IP header. The TCP header is not touched.
   1.163 -  // Not using the IP header makes integration easier, but it destroys
   1.164 -  // eg. ECN.
   1.165 -  const uint8_t *rawdata = reinterpret_cast<const uint8_t *>(data);
   1.166 -  rawdata += 20; // skip IP header. IP options aren't supported at this time.
   1.167 -  datalen -= 20;
   1.168 -  p = Create<Packet> (rawdata, datalen);
   1.169 -
   1.170 -  // we need the real source/destination ipv4 addresses for Send ().
   1.171 -  const uint32_t *ipheader = reinterpret_cast<const uint32_t *>(data);
   1.172 -  ipv4Saddr = *(ipheader+3);
   1.173 -  ipv4Daddr = *(ipheader+4);
   1.174 -
   1.175 -  Ipv4Address saddr(ntohl(ipv4Saddr));
   1.176 -  Ipv4Address daddr(ntohl(ipv4Daddr));
   1.177 -
   1.178 -  Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
   1.179 -  NS_ASSERT_MSG (ipv4, "nsc callback invoked, but node has no ipv4 object");
   1.180 -
   1.181 -  ipv4->Send (p, saddr, daddr, PROT_NUMBER, 0);
   1.182 -  m_nscStack->if_send_finish(0);
   1.183 -}
   1.184 -
   1.185 -void NscTcpL4Protocol::wakeup()
   1.186 +void NscTcpL4Protocol::Wakeup()
   1.187  {
   1.188    // TODO
   1.189    // this should schedule a timer to read from all tcp sockets now... this is
   1.190 @@ -359,70 +242,13 @@
   1.191    }
   1.192  }
   1.193  
   1.194 -void NscTcpL4Protocol::gettime(unsigned int* sec, unsigned int* usec)
   1.195 -{
   1.196 -  // Only used by the Linux network stack, e.g. during ISN generation
   1.197 -  // and in the kernel rng initialization routine. Also used in Linux
   1.198 -  // printk output.
   1.199 -  Time t = Simulator::Now ();
   1.200 -  int64_t us = t.GetMicroSeconds ();
   1.201 -  *sec = us / (1000*1000);
   1.202 -  *usec = us - *sec * (1000*1000);
   1.203 -}
   1.204 -
   1.205 -
   1.206 -void NscTcpL4Protocol::AddInterface(void)
   1.207 -{
   1.208 -  Ptr<Ipv4> ip = m_node->GetObject<Ipv4> ();
   1.209 -  const uint32_t nInterfaces = ip->GetNInterfaces ();
   1.210 -
   1.211 -  NS_ASSERT_MSG (nInterfaces <= 2, "nsc does not support multiple interfaces per node");
   1.212 -
   1.213 -  // start from 1, ignore the loopback interface (HACK)
   1.214 -  // we really don't need the loop, but its here to illustrate
   1.215 -  // how things _should_ be (once nsc can deal with multiple interfaces...)
   1.216 -  for (uint32_t i = 1; i < nInterfaces; i++)
   1.217 -    {
   1.218 -      Ipv4InterfaceAddress ifAddr = ip->GetAddress (i, 0);
   1.219 -      Ipv4Address addr = ifAddr.GetLocal ();
   1.220 -      Ipv4Mask mask = ifAddr.GetMask ();
   1.221 -      uint16_t mtu = ip->GetMtu (i);
   1.222 -
   1.223 -      std::ostringstream addrOss, maskOss;
   1.224 -
   1.225 -      addr.Print(addrOss);
   1.226 -      mask.Print(maskOss);
   1.227 -
   1.228 -      NS_LOG_LOGIC ("if_attach " << addrOss.str().c_str() << " " << maskOss.str().c_str() << " " << mtu);
   1.229 -
   1.230 -      std::string addrStr = addrOss.str();
   1.231 -      std::string maskStr = maskOss.str();
   1.232 -      const char* addrCStr = addrStr.c_str();
   1.233 -      const char* maskCStr = maskStr.c_str();
   1.234 -      m_nscStack->if_attach(addrCStr, maskCStr, mtu);
   1.235 -
   1.236 -      if (i == 1)
   1.237 -      {
   1.238 -        // We need to come up with a default gateway here. Can't guarantee this to be
   1.239 -        // correct really...
   1.240 -
   1.241 -        uint8_t addrBytes[4];
   1.242 -        addr.Serialize(addrBytes);
   1.243 -
   1.244 -        // XXX: this is all a bit of a horrible hack
   1.245 -        //
   1.246 -        // Just increment the last octet, this gives a decent chance of this being
   1.247 -        // 'enough'.
   1.248 -        //
   1.249 -        // All we need is another address on the same network as the interface. This
   1.250 -        // will force the stack to output the packet out of the network interface.
   1.251 -        addrBytes[3]++;
   1.252 -        addr.Deserialize(addrBytes);
   1.253 -        addrOss.str("");
   1.254 -        addr.Print(addrOss);
   1.255 -        m_nscStack->add_default_gateway(addrOss.str().c_str());
   1.256 -      }
   1.257 -  }
   1.258 +Ipv4L4Protocol::RxStatus
   1.259 +NscTcpL4Protocol::Receive (Ptr<Packet> p,
   1.260 +                       Ipv4Address const &source,
   1.261 +                       Ipv4Address const &destination,
   1.262 +                       Ptr<Ipv4Interface> incomingInterface)
   1.263 +{ // STUB, RX happens in node/node.cc if NSC is in use.
   1.264 +  return Ipv4L4Protocol::RX_OK;
   1.265  }
   1.266  
   1.267  }; // namespace ns3