From 3a6bf88a4933abcaf479be6fee2905d16d4110d3 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Thu, 25 Sep 2008 01:43:27 +0200 Subject: [PATCH] nsc: delay creating nsc interface using ScheduleNow (). because we cannot rely on the node to have any assigned interface when the nsc stack is initialised, we need to delay creating the nsc interface. Up until now this was done by initialising the interface when the first socket is opened, which resulted in a segfault or an assertion failure when a packet arrived but no socket was ever created... --- src/internet-stack/nsc-tcp-l4-protocol.cc | 111 +++++++++++----------- src/internet-stack/nsc-tcp-l4-protocol.h | 2 +- 2 files changed, 58 insertions(+), 55 deletions(-) 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; };