diff --git a/src/internet-stack/nsc-tcp-l4-protocol.cc b/src/internet-stack/nsc-tcp-l4-protocol.cc index 77fdc1597..401ef1e8f 100644 --- a/src/internet-stack/nsc-tcp-l4-protocol.cc +++ b/src/internet-stack/nsc-tcp-l4-protocol.cc @@ -82,7 +82,6 @@ int external_rand() NscTcpL4Protocol::NscTcpL4Protocol () : m_endPoints (new Ipv4EndPointDemux ()), m_nscStack (0), - m_nscInterfacesSetUp(false), m_softTimer (Timer::CANCEL_ON_DESTROY) { m_dlopenHandle = NULL; @@ -134,6 +133,10 @@ NscTcpL4Protocol::SetNode (Ptr node) node->AggregateObject (nscStack); m_softTimer.Schedule (); + + // its likely no ns-3 interface exits at this point, so + // we dealy adding the nsc interface until the start of the simulation. + Simulator::ScheduleNow (&NscTcpL4Protocol::AddInterface, this); } int @@ -164,58 +167,6 @@ Ptr NscTcpL4Protocol::CreateSocket (void) { NS_LOG_FUNCTION (this); - if (!m_nscInterfacesSetUp) - { - Ptr ip = m_node->GetObject (); - - const uint32_t nInterfaces = ip->GetNInterfaces (); - // start from 1, ignore the loopback interface (HACK) - - NS_ASSERT_MSG (nInterfaces <= 2, "nsc does not support multiple interfaces per node"); - - for (uint32_t i = 1; i < nInterfaces; i++) - { - Ipv4Address addr = ip->GetAddress(i); - Ipv4Mask mask = ip->GetNetworkMask(i); - uint16_t mtu = ip->GetMtu (i); - - std::ostringstream addrOss, maskOss; - - addr.Print(addrOss); - mask.Print(maskOss); - - NS_LOG_LOGIC ("if_attach " << addrOss.str().c_str() << " " << maskOss.str().c_str() << " " << mtu); - - std::string addrStr = addrOss.str(); - std::string maskStr = maskOss.str(); - const char* addrCStr = addrStr.c_str(); - const char* maskCStr = maskStr.c_str(); - m_nscStack->if_attach(addrCStr, maskCStr, mtu); - - if (i == 1) - { - // We need to come up with a default gateway here. Can't guarantee this to be - // correct really... - - uint8_t addrBytes[4]; - addr.Serialize(addrBytes); - - // XXX: this is all a bit of a horrible hack - // - // Just increment the last octet, this gives a decent chance of this being - // 'enough'. - // - // All we need is another address on the same network as the interface. This - // will force the stack to output the packet out of the network interface. - addrBytes[3]++; - addr.Deserialize(addrBytes); - addrOss.str(""); - addr.Print(addrOss); - m_nscStack->add_default_gateway(addrOss.str().c_str()); - } - } - m_nscInterfacesSetUp = true; - } Ptr rtt = m_rttFactory.Create (); Ptr socket = CreateObject (); @@ -297,7 +248,6 @@ NscTcpL4Protocol::Receive (Ptr packet, const uint8_t *data = const_cast(packet->PeekData()); - NS_ASSERT_MSG (m_nscInterfacesSetUp, "got packet, but no listening sockets (and no interface)"); // deliver complete packet to the NSC network stack m_nscStack->if_receive_packet(0, data, packetSize); wakeup (); @@ -367,5 +317,58 @@ void NscTcpL4Protocol::gettime(unsigned int* sec, unsigned int* usec) } +void NscTcpL4Protocol::AddInterface(void) +{ + Ptr ip = m_node->GetObject (); + const uint32_t nInterfaces = ip->GetNInterfaces (); + + NS_ASSERT_MSG (nInterfaces <= 2, "nsc does not support multiple interfaces per node"); + + // start from 1, ignore the loopback interface (HACK) + // we really don't need the loop, but its here to illustrate + // how things _should_ be (once nsc can deal with multiple interfaces...) + for (uint32_t i = 1; i < nInterfaces; i++) + { + Ipv4Address addr = ip->GetAddress(i); + Ipv4Mask mask = ip->GetNetworkMask(i); + uint16_t mtu = ip->GetMtu (i); + + std::ostringstream addrOss, maskOss; + + addr.Print(addrOss); + mask.Print(maskOss); + + NS_LOG_LOGIC ("if_attach " << addrOss.str().c_str() << " " << maskOss.str().c_str() << " " << mtu); + + std::string addrStr = addrOss.str(); + std::string maskStr = maskOss.str(); + const char* addrCStr = addrStr.c_str(); + const char* maskCStr = maskStr.c_str(); + m_nscStack->if_attach(addrCStr, maskCStr, mtu); + + if (i == 1) + { + // We need to come up with a default gateway here. Can't guarantee this to be + // correct really... + + uint8_t addrBytes[4]; + addr.Serialize(addrBytes); + + // XXX: this is all a bit of a horrible hack + // + // Just increment the last octet, this gives a decent chance of this being + // 'enough'. + // + // All we need is another address on the same network as the interface. This + // will force the stack to output the packet out of the network interface. + addrBytes[3]++; + addr.Deserialize(addrBytes); + addrOss.str(""); + addr.Print(addrOss); + m_nscStack->add_default_gateway(addrOss.str().c_str()); + } + } +} + }; // namespace ns3 diff --git a/src/internet-stack/nsc-tcp-l4-protocol.h b/src/internet-stack/nsc-tcp-l4-protocol.h index 73c2d7da7..212a62755 100644 --- a/src/internet-stack/nsc-tcp-l4-protocol.h +++ b/src/internet-stack/nsc-tcp-l4-protocol.h @@ -109,12 +109,12 @@ private: Ipv4EndPointDemux *m_endPoints; ObjectFactory m_rttFactory; private: + void AddInterface (void); void SoftInterrupt (void); static ObjectFactory GetDefaultRttEstimatorFactory (void); friend class NscTcpSocketImpl; INetStack* m_nscStack; void *m_dlopenHandle; - bool m_nscInterfacesSetUp; Timer m_softTimer; };