From 7ecbc1b14472e8aaf2d0764bd4d37859c10592a2 Mon Sep 17 00:00:00 2001 From: bcamus Date: Thu, 19 Sep 2019 11:51:22 +0200 Subject: [PATCH] Unblock the number of communications that can be done with NS-3 by + looping on the ports used to communicate, + and closing the sockets on the receiver sides (nb. the senders sockets were already closed). This point also improves the NS-3 bindings performance. --- src/surf/network_ns3.cpp | 10 +++++++++- src/surf/ns3/ns3_simulator.cpp | 26 +++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/surf/network_ns3.cpp b/src/surf/network_ns3.cpp index 0dc2149118..31580eaa48 100644 --- a/src/surf/network_ns3.cpp +++ b/src/surf/network_ns3.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include "network_ns3.hpp" #include "ns3/ns3_simulator.hpp" @@ -39,6 +40,7 @@ std::vector IPV4addr; *****************/ extern std::map flow_from_sock; +extern std::map sink_from_sock; static ns3::InternetStackHelper stack; static ns3::NodeContainer nodes; @@ -274,6 +276,7 @@ void NetworkNS3Model::update_actions_state(double now, double delta) } delete flow; flow_from_sock.erase(ns3_socket); + sink_from_sock.erase(ns3_socket); } } @@ -330,17 +333,22 @@ NetworkNS3Action::NetworkNS3Action(Model* model, double totalBytes, s4u::Host* s XBT_DEBUG("ns3: Create flow of %.0f Bytes from %u to %u with Interface %s", totalBytes, node1, node2, addr.c_str()); ns3::PacketSinkHelper sink("ns3::TcpSocketFactory", ns3::InetSocketAddress(ns3::Ipv4Address::GetAny(), port_number)); - sink.Install(dst_node); + ns3::ApplicationContainer apps = sink.Install(dst_node); ns3::Ptr sock = ns3::Socket::CreateSocket(src_node, ns3::TcpSocketFactory::GetTypeId()); flow_from_sock.insert({transform_socket_ptr(sock), new SgFlow(totalBytes, this)}); + sink_from_sock.insert({transform_socket_ptr(sock), apps}); sock->Bind(ns3::InetSocketAddress(port_number)); ns3::Simulator::ScheduleNow(&start_flow, sock, addr.c_str(), port_number); port_number++; + if(port_number > 65000){ + port_number = 1025; + XBT_WARN("Too many connections! Port number is saturated. Trying to use the oldest ports."); + } xbt_assert(port_number <= 65000, "Too many connections! Port number is saturated."); s4u::Link::on_communicate(*this, src, dst); diff --git a/src/surf/ns3/ns3_simulator.cpp b/src/surf/ns3/ns3_simulator.cpp index 019ef94cb4..63a0e8bb9e 100644 --- a/src/surf/ns3/ns3_simulator.cpp +++ b/src/surf/ns3/ns3_simulator.cpp @@ -9,10 +9,15 @@ #include #include +#include +#include +#include +#include #include std::map flow_from_sock; // ns3::sock -> SgFlow +std::map sink_from_sock; // ns3::sock -> ns3::PacketSink static void receive_callback(ns3::Ptr socket); static void datasent_cb(ns3::Ptr socket, uint32_t dataSent); @@ -32,6 +37,12 @@ static SgFlow* getFlowFromSocket(ns3::Ptr socket) return (it == flow_from_sock.end()) ? nullptr : it->second; } +static ns3::ApplicationContainer* getSinkFromSocket(ns3::Ptr socket) +{ + auto it = sink_from_sock.find(transform_socket_ptr(socket)); + return (it == sink_from_sock.end()) ? nullptr : &(it->second); +} + static void receive_callback(ns3::Ptr socket) { SgFlow* flow = getFlowFromSocket(socket); @@ -49,6 +60,7 @@ static void receive_callback(ns3::Ptr socket) static void send_cb(ns3::Ptr sock, uint32_t txSpace) { SgFlow* flow = getFlowFromSocket(sock); + ns3::ApplicationContainer* sink = getSinkFromSocket(sock); XBT_DEBUG("Asked to write on F[%p, total: %u, remain: %u]", flow, flow->total_bytes_, flow->remaining_); if (flow->remaining_ == 0) // all data was already buffered (and socket was already closed) @@ -74,8 +86,18 @@ static void send_cb(ns3::Ptr sock, uint32_t txSpace) flow->remaining_); } - if (flow->buffered_bytes_ >= flow->total_bytes_) + if (flow->buffered_bytes_ >= flow->total_bytes_){ + XBT_DEBUG("Closing Sockets of flow %p", flow); + // Closing the sockets of the receiving application + ns3::Ptr app = ns3::DynamicCast(sink->Get(0)); + ns3::Ptr listening_sock = app->GetListeningSocket(); + listening_sock->Close(); + listening_sock->SetRecvCallback(ns3::MakeNullCallback>()); + for(ns3::Ptr accepted_sock : app->GetAcceptedSockets()) + accepted_sock->Close(); + // Closing the socket of the sender sock->Close(); + } } static void datasent_cb(ns3::Ptr socket, uint32_t dataSent) @@ -127,8 +149,6 @@ void start_flow(ns3::Ptr sock, const char* to, uint16_t port_number // tell the tcp implementation to call send_cb again // if we blocked and new tx buffer space becomes available sock->SetSendCallback(MakeCallback(&send_cb)); - // Notice when the send is over - sock->SetRecvCallback(MakeCallback(&receive_callback)); // Notice when we actually sent some data (mostly for the TRACING module) sock->SetDataSentCallback(MakeCallback(&datasent_cb)); -- 2.20.1