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