Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of https://framagit.org/simgrid/simgrid
[simgrid.git] / src / surf / network_ns3.cpp
index 1d3e409..aaa77ed 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved.          */
+/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved.          */
 
 /* This program is free software; you can redistribute it and/or modify it
  * under the terms of the license (GNU LGPL) which comes with this package. */
@@ -51,8 +51,6 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(res_ns3, res_network, "Network model based on ns
 extern std::map<std::string, SgFlow*, std::less<>> flow_from_sock;
 extern std::map<std::string, ns3::ApplicationContainer, std::less<>> sink_from_sock;
 
-static ns3::InternetStackHelper stack;
-
 static int number_of_links    = 1;
 static int number_of_networks = 1;
 
@@ -67,6 +65,7 @@ static std::string transformIpv4Address(ns3::Ipv4Address from)
 
 NetPointNs3::NetPointNs3()
 {
+  static ns3::InternetStackHelper stack;
   stack.Install(ns3_node_);
 }
 
@@ -98,8 +97,11 @@ static void zoneCreation_cb(simgrid::s4u::NetZone const& zone)
 
 #if NS3_MINOR_VERSION < 32
   wifi.SetStandard(ns3::WIFI_PHY_STANDARD_80211n_5GHZ);
-#else
+#elif NS3_MINOR_VERSION < 36
   wifi.SetStandard(ns3::WIFI_STANDARD_80211n_5GHZ);
+#else
+  wifi.SetStandard(ns3::WIFI_STANDARD_80211n);
+  wifiPhy.Set ("ChannelSettings", ns3::StringValue ("{0, 0, BAND_5GHZ, 0}"));
 #endif
 
   std::string ssid = wifizone->get_name();
@@ -142,7 +144,7 @@ static void zoneCreation_cb(simgrid::s4u::NetZone const& zone)
   double angle    = 0;
   auto nb_stations = static_cast<double>(wifizone->get_all_hosts().size() - 1);
   double step     = 2 * M_PI / nb_stations;
-  for (auto station_host : wifizone->get_all_hosts()) {
+  for (const auto* station_host : wifizone->get_all_hosts()) {
     station_netpoint_ns3 = station_host->get_netpoint()->extension<NetPointNs3>();
     if (station_netpoint_ns3 == access_point_netpoint_ns3)
       continue;
@@ -259,16 +261,13 @@ static void routeCreation_cb(bool symmetrical, const simgrid::kernel::routing::N
     XBT_DEBUG("\tLink (%s) bw:%fbps lat:%fs", link->get_cname(), link->get_bandwidth(), link->get_latency());
 
     ns3_add_direct_route(src, dst, link->get_bandwidth(), link->get_latency(), link->get_sharing_policy());
-  } else {
-    static bool warned_about_long_routes = false;
-
-    if (not warned_about_long_routes)
-      XBT_WARN("Ignoring a route between %s and %s of length %zu: Only routes of length 1 are considered with ns-3.\n"
-               "WARNING: You can ignore this warning if your hosts can still communicate when only considering routes "
-               "of length 1.\n"
-               "WARNING: Remove long routes to avoid this harmless message; subsequent long routes will be silently "
-               "ignored.",
-               src->get_cname(), dst->get_cname(), link_list.size());
+  } else if (static bool warned_about_long_routes = false; not warned_about_long_routes) {
+    XBT_WARN("Ignoring a route between %s and %s of length %zu: Only routes of length 1 are considered with ns-3.\n"
+             "WARNING: You can ignore this warning if your hosts can still communicate when only considering routes "
+             "of length 1.\n"
+             "WARNING: Remove long routes to avoid this harmless message; subsequent long routes will be silently "
+             "ignored.",
+             src->get_cname(), dst->get_cname(), link_list.size());
     warned_about_long_routes = true;
   }
 }
@@ -276,12 +275,16 @@ static void routeCreation_cb(bool symmetrical, const simgrid::kernel::routing::N
 /*********
  * Model *
  *********/
-void surf_network_model_init_NS3()
+// We can't use SIMGRID_REGISTER_NETWORK_MODEL here because ns-3 has a dash in its name
+static void XBT_ATTRIB_CONSTRUCTOR(800) simgrid_ns3_network_model_register()
 {
-  auto net_model = std::make_shared<simgrid::kernel::resource::NetworkNS3Model>("NS3 network model");
-  auto* engine   = simgrid::kernel::EngineImpl::get_instance();
-  engine->add_model(net_model);
-  engine->get_netzone_root()->set_network_model(net_model);
+  simgrid_network_models().add(
+      "ns-3", "Network pseudo-model using the real ns-3 simulator instead of an analytic model", []() {
+        auto net_model = std::make_shared<simgrid::kernel::resource::NetworkNS3Model>("NS3 network model");
+        auto* engine   = simgrid::kernel::EngineImpl::get_instance();
+        engine->add_model(net_model);
+        engine->get_netzone_root()->set_network_model(net_model);
+      });
 }
 
 static simgrid::config::Flag<std::string>
@@ -305,8 +308,7 @@ static simgrid::config::Flag<std::string> ns3_seed(
     });
 
 namespace simgrid {
-namespace kernel {
-namespace resource {
+namespace kernel::resource {
 
 NetworkNS3Model::NetworkNS3Model(const std::string& name) : NetworkModel(name)
 {
@@ -319,8 +321,7 @@ NetworkNS3Model::NetworkNS3Model(const std::string& name) : NetworkModel(name)
   ns3::Config::SetDefault("ns3::TcpSocket::DelAckCount", ns3::UintegerValue(1));
   ns3::Config::SetDefault("ns3::TcpSocketBase::Timestamp", ns3::BooleanValue(false));
 
-  auto const& TcpProtocol = ns3_tcp_model.get();
-  if (TcpProtocol == "default") {
+  if (auto const& TcpProtocol = ns3_tcp_model.get(); TcpProtocol == "default") {
     /* nothing to do */
 
   } else if (TcpProtocol == "Reno" || TcpProtocol == "NewReno" || TcpProtocol == "Tahoe") {
@@ -367,7 +368,7 @@ StandardLinkImpl* NetworkNS3Model::create_wifi_link(const std::string& name, con
   return link;
 }
 
-Action* NetworkNS3Model::communicate(s4u::Host* src, s4u::Host* dst, double size, double rate)
+Action* NetworkNS3Model::communicate(s4u::Host* src, s4u::Host* dst, double size, double rate, bool /*streamed*/)
 {
   xbt_assert(rate == -1,
              "Communication over ns-3 links cannot specify a specific rate. Please use -1 as a value instead of %f.",
@@ -409,10 +410,7 @@ void NetworkNS3Model::update_actions_state(double now, double delta)
 {
   static std::vector<std::string> socket_to_destroy;
 
-  std::string ns3_socket;
-  for (const auto& elm : flow_from_sock) {
-    ns3_socket               = elm.first;
-    SgFlow* sgFlow           = elm.second;
+  for (const auto& [ns3_socket, sgFlow] : flow_from_sock) {
     NetworkNS3Action* action = sgFlow->action_;
     XBT_DEBUG("Processing flow %p (socket %s, action %p)", sgFlow, ns3_socket.c_str(), action);
     // Because NS3 stops as soon as a flow is finished, the other flows that ends at the same time may remains in an
@@ -448,7 +446,7 @@ void NetworkNS3Model::update_actions_state(double now, double delta)
   }
 
   while (not socket_to_destroy.empty()) {
-    ns3_socket = socket_to_destroy.back();
+    std::string ns3_socket = socket_to_destroy.back();
     socket_to_destroy.pop_back();
     SgFlow* flow = flow_from_sock.at(ns3_socket);
     if (XBT_LOG_ISENABLED(res_ns3, xbt_log_priority_debug)) {
@@ -505,8 +503,7 @@ NetworkNS3Action::NetworkNS3Action(Model* model, double totalBytes, s4u::Host* s
   // ns-3 fails when src = dst, so avoid the problem by considering that communications are infinitely fast on the
   // loopback that does not exists
   if (src == dst) {
-    static bool warned = false;
-    if (not warned) {
+    if (static bool warned = false; not warned) {
       XBT_WARN("Sending from a host %s to itself is not supported by ns-3. Every such communication finishes "
                "immediately upon startup.",
                src->get_cname());
@@ -542,8 +539,8 @@ NetworkNS3Action::NetworkNS3Action(Model* model, double totalBytes, s4u::Host* s
   XBT_DEBUG("Create socket %s for a flow of %.0f Bytes from %s to %s with Interface %s",
             transform_socket_ptr(sock).c_str(), totalBytes, src->get_cname(), dst->get_cname(), addr.c_str());
 
-  flow_from_sock.insert({transform_socket_ptr(sock), new SgFlow(static_cast<uint32_t>(totalBytes), this)});
-  sink_from_sock.insert({transform_socket_ptr(sock), apps});
+  flow_from_sock.try_emplace(transform_socket_ptr(sock), new SgFlow(static_cast<uint32_t>(totalBytes), this));
+  sink_from_sock.try_emplace(transform_socket_ptr(sock), apps);
 
   sock->Bind(ns3::InetSocketAddress(port_number));
   ns3::Simulator::ScheduleNow(&start_flow, sock, addr.c_str(), port_number);
@@ -572,8 +569,7 @@ void NetworkNS3Action::update_remains_lazy(double /*now*/)
   THROW_IMPOSSIBLE;
 }
 
-} // namespace resource
-} // namespace kernel
+} // namespace kernel::resource
 
 ns3::Ptr<ns3::Node> get_ns3node_from_sghost(const simgrid::s4u::Host* host)
 {