diff --git a/endpoint/setup.sh b/endpoint/setup.sh index 948c9eb..c1ecc6b 100644 --- a/endpoint/setup.sh +++ b/endpoint/setup.sh @@ -1,20 +1,21 @@ #!/bin/bash +set -e + echo "Setting up routes..." # By default, docker containers don't compute UDP / TCP checksums. # When packets run through ns3 however, the receiving endpoint requires valid checksums. # This command makes sure that the endpoints set the checksum on outgoing packets. ethtool -K eth0 tx off - # this relies on the IPv4 address being first in the "hostname -I" output IP=$(hostname -I | cut -f1 -d" ") GATEWAY="${IP%.*}.2" UNNEEDED_ROUTE="${IP%.*}.0" echo "Endpoint's IPv4 address is $IP" -route add -net 193.167.0.0 netmask 255.255.0.0 gw $GATEWAY +route add -net "$SUBNET_V4$SUBNET_V4_SUBNET/$SUBNET_V4_PREFIX" gw "$GATEWAY" # delete unused route -route del -net $UNNEEDED_ROUTE netmask 255.255.255.0 +route del -net "$UNNEEDED_ROUTE" netmask 255.255.255.0 # this relies on the IPv6 address being second in the "hostname -I" output IP=$(hostname -I | cut -f2 -d" ") @@ -22,9 +23,9 @@ GATEWAY="${IP%:*}:2" UNNEEDED_ROUTE="${IP%:*}:" echo "Endpoint's IPv6 address is $IP" -ip -d route add fd00:cafe:cafe::/48 via $GATEWAY +ip -d route add "$SUBNET_V6::/$SUBNET_V6_PREFIX" via "$GATEWAY" # delete unused route -ip -d route del $UNNEEDED_ROUTE/64 +ip -d route del "$UNNEEDED_ROUTE/64" # create the /logs and the /logs/qlog directory mkdir -p /logs/qlog diff --git a/sim/run.sh b/sim/run.sh index bc3a4ae..01593f0 100644 --- a/sim/run.sh +++ b/sim/run.sh @@ -7,27 +7,25 @@ set -e ifconfig eth0 promisc ifconfig eth1 promisc -# A packet arriving at eth0 destined to 10.100.0.0/16 could be routed directly to eth1, -# and a packet arriving at eth1 destined to 10.0.0.0/16 directly to eth0. +# A packet arriving at eth0 could be routed directly to eth1 and vice versa. # This would allow packets to skip the ns3 simulator altogether. -# Drop those to make sure they actually take the path through ns3. +# Drop all forwarding between these interfaces to ensure packets go through ns3. iptables -A FORWARD -i eth0 -o eth1 -j DROP iptables -A FORWARD -i eth1 -o eth0 -j DROP ip6tables -A FORWARD -i eth0 -o eth1 -j DROP ip6tables -A FORWARD -i eth1 -o eth0 -j DROP if [[ -n "$WAITFORSERVER" ]]; then - wait-for-it-quic -t 10s $WAITFORSERVER + wait-for-it-quic -t 10s "$WAITFORSERVER" fi -echo "Using scenario:" $SCENARIO +echo "Using scenario: $SCENARIO" tcpdump -i eth0 -U -w "/logs/trace_node_left.pcap" & tcpdump -i eth1 -U -w "/logs/trace_node_right.pcap" & eval ./scratch/"$SCENARIO &" -PID=`jobs -p | tr '\n' ' '` +PID=$(jobs -p | tr '\n' ' ') trap "kill -SIGINT $PID" INT trap "kill -SIGTERM $PID" TERM -trap "kill -SIGKILL $PID" KILL wait diff --git a/sim/scenarios/helper/network-config.h b/sim/scenarios/helper/network-config.h new file mode 100644 index 0000000..16e9dde --- /dev/null +++ b/sim/scenarios/helper/network-config.h @@ -0,0 +1,153 @@ +#ifndef NETWORK_CONFIG_H +#define NETWORK_CONFIG_H + +#include +#include +#include "ns3/core-module.h" +#include "ns3/ipv4-address.h" +#include "ns3/ipv6-address.h" + +namespace ns3 { + +class NetworkConfig { +public: + // Singleton instance to ensure we read environment variables only once. + static const NetworkConfig& Instance() { + static NetworkConfig instance; + return instance; + } + + const std::string& GetClientV4Addr() const { return client_v4_addr_; } + const std::string & GetServerV4Addr() const + { + return server_v4_addr_; + } + const std::string& GetClientV6Addr() const { return client_v6_addr_; } + const std::string& GetServerV6Addr() const { return server_v6_addr_; } + + Ipv4Address GetClientV4Address() const { + return Ipv4Address(client_v4_addr_.c_str()); + } + + Ipv4Address GetServerV4Address() const { + return Ipv4Address(server_v4_addr_.c_str()); + } + + const std::string & GetClientGatewayV4Addr() const + { + return client_v4_gateway_; + } + + const std::string & GetServerGatewayV4Addr() const + { + return server_v4_gateway_; + } + + const std::string & GetClientGatewayV6Addr() const + { + return client_v6_gateway_; + } + + const std::string & GetServerGatewayV6Addr() const + { + return server_v6_gateway_; + } + + const std::string & GetLeftNetName() const + { + return leftnet_name_; + } + + const std::string & GetRightNetName() const + { + return rightnet_name_; + } + + std::string GetV4PointToPointNetwork() const { + return subnet_v4_ + ".255.0"; + } + + std::string GetV4SubnetMask() const { + return "255.255.255.0"; + } + + std::string GetV6PointToPointNetwork() const { + return subnet_v6_ + ":255::"; + } + + int GetV6PrefixInt() const { + return std::stoi(v6_prefix_); + } + +private: + NetworkConfig() { + // SUBNET_V4: Base IPv4 network prefix (e.g., "10.0") + subnet_v4_ = GetEnvVar("SUBNET_V4"); + + // CLIENT_V4_ADDR: Client IPv4 address (e.g., "10.0.10.10") + client_v4_addr_ = GetEnvVar("CLIENT_V4_ADDR"); + + // SERVER_V4_ADDR: Server IPv4 address (e.g., "10.0.222.222") + server_v4_addr_ = GetEnvVar("SERVER_V4_ADDR"); + + // CLIENT_V4_GATEWAY: Client gateway IPv4 address (e.g., "10.0.10.2") + client_v4_gateway_ = GetEnvVar("CLIENT_V4_GATEWAY"); + + // SERVER_V4_GATEWAY: Server gateway IPv4 address (e.g., "10.0.222.2") + server_v4_gateway_ = GetEnvVar("SERVER_V4_GATEWAY"); + + // SUBNET_V6: Base IPv6 network prefix (e.g., "fd00:cafe:0000") + subnet_v6_ = GetEnvVar("SUBNET_V6"); + + // V6_PREFIX: IPv6 prefix length (e.g., "64") + v6_prefix_ = GetEnvVar("V6_PREFIX"); + + // CLIENT_V6_ADDR: Client IPv6 address (e.g., "fd00:cafe:0000:10::10") + client_v6_addr_ = GetEnvVar("CLIENT_V6_ADDR"); + + // SERVER_V6_ADDR: Server IPv6 address (e.g., "fd00:cafe:0000:222::222") + server_v6_addr_ = GetEnvVar("SERVER_V6_ADDR"); + + // CLIENT_V6_GATEWAY: Client gateway IPv6 address (e.g., + // "fd00:cafe:0000:10::2") + client_v6_gateway_ = GetEnvVar("CLIENT_V6_GATEWAY"); + + // SERVER_V6_GATEWAY: Server gateway IPv6 address (e.g., + // "fd00:cafe:0000:222::2") + server_v6_gateway_ = GetEnvVar("SERVER_V6_GATEWAY"); + + // LEFTNET_NAME: Left network interface name (e.g., "eth0") + leftnet_name_ = GetEnvVar("LEFTNET_NAME"); + + // RIGHTNET_NAME: Right network interface name (e.g., "eth1") + rightnet_name_ = GetEnvVar("RIGHTNET_NAME"); + + // V4_PREFIX: IPv4 prefix length - must always be "24" + std::string v4_prefix = GetEnvVar("V4_PREFIX"); + NS_ABORT_MSG_IF(v4_prefix != "24", "V4_PREFIX must be 24, but got: " << v4_prefix); + } + + static std::string GetEnvVar(const std::string& var_name) { + const char* value = std::getenv(var_name.c_str()); + NS_ABORT_MSG_IF(value == nullptr, "Environment variable " << var_name << " is not set."); + return std::string(value); + } + + std::string subnet_v4_; + std::string client_v4_addr_; + std::string server_v4_addr_; + std::string client_v4_gateway_; + std::string server_v4_gateway_; + std::string subnet_v6_; + std::string v6_prefix_; + std::string client_v6_addr_; + std::string server_v6_addr_; + std::string client_v6_gateway_; + std::string server_v6_gateway_; + std::string leftnet_name_; + std::string rightnet_name_; +}; + +} // namespace ns3 + +#endif // NETWORK_CONFIG_H diff --git a/sim/scenarios/helper/quic-network-simulator-helper.cc b/sim/scenarios/helper/quic-network-simulator-helper.cc index 81a09cd..9f26c01 100644 --- a/sim/scenarios/helper/quic-network-simulator-helper.cc +++ b/sim/scenarios/helper/quic-network-simulator-helper.cc @@ -14,6 +14,7 @@ #include "ns3/fd-net-device-module.h" #include "ns3/internet-module.h" #include "quic-network-simulator-helper.h" +#include "network-config.h" using namespace ns3; @@ -74,20 +75,34 @@ QuicNetworkSimulatorHelper::QuicNetworkSimulatorHelper() { left_node_ = nodes.Get(0); right_node_ = nodes.Get(1); - installNetDevice(left_node_, "eth0", getMacAddress("eth0"), Ipv4InterfaceAddress("193.167.0.2", "255.255.255.0"), Ipv6InterfaceAddress("fd00:cafe:cafe:0::2", 64)); - installNetDevice(right_node_, "eth1", getMacAddress("eth1"), Ipv4InterfaceAddress("193.167.100.2", "255.255.255.0"), Ipv6InterfaceAddress("fd00:cafe:cafe:100::2", 64)); + const NetworkConfig& config = NetworkConfig::Instance(); + installNetDevice(left_node_, config.GetLeftNetName().c_str(), + getMacAddress(config.GetLeftNetName().c_str()), + Ipv4InterfaceAddress(config.GetClientGatewayV4Addr().c_str(), + config.GetV4SubnetMask().c_str()), + Ipv6InterfaceAddress(config.GetClientGatewayV6Addr().c_str(), + config.GetV6PrefixInt())); + installNetDevice(right_node_, config.GetRightNetName().c_str(), + getMacAddress(config.GetRightNetName().c_str()), + Ipv4InterfaceAddress(config.GetServerGatewayV4Addr().c_str(), + config.GetV4SubnetMask().c_str()), + Ipv6InterfaceAddress(config.GetServerGatewayV6Addr().c_str(), + config.GetV6PrefixInt())); } void massageIpv6Routing(Ptr local, Ptr peer) { Ptr routing = Ipv6RoutingHelper::GetRouting(local->GetObject()->GetRoutingProtocol()); Ptr peer_ipv6 = peer->GetObject(); Ipv6Address dst; + const NetworkConfig& config = NetworkConfig::Instance(); + std::string v6_point_to_point_network = config.GetV6PointToPointNetwork(); for (uint32_t i = 0; i < peer_ipv6->GetNInterfaces(); i++) for (uint32_t j = 0; j < peer_ipv6->GetNAddresses(i); j++) - if (peer_ipv6->GetAddress(i, j).GetAddress().CombinePrefix(64) == "fd00:cafe:cafe:50::") { - dst = peer_ipv6->GetAddress(i, j).GetAddress(); - goto done; - } + if (peer_ipv6->GetAddress(i, j).GetAddress().CombinePrefix( + config.GetV6PrefixInt()) == v6_point_to_point_network.c_str()) { + dst = peer_ipv6->GetAddress(i, j).GetAddress(); + goto done; + } done: assert(dst.IsInitialized()); @@ -106,7 +121,8 @@ void QuicNetworkSimulatorHelper::Run(Time duration) { massageIpv6Routing(right_node_, left_node_); // write the routing table to file - Ptr routingStream = Create("dynamic-global-routing.routes", std::ios::out); + Ptr routingStream = + Create("/logs/simulator-routes.txt", std::ios::out); Ipv4RoutingHelper::PrintRoutingTableAllAt(Seconds(0.), routingStream); Ipv6RoutingHelper::PrintRoutingTableAllAt(Seconds(0.), routingStream); diff --git a/sim/scenarios/helper/quic-packet.cc b/sim/scenarios/helper/quic-packet.cc index a599cbb..2a8e2da 100644 --- a/sim/scenarios/helper/quic-packet.cc +++ b/sim/scenarios/helper/quic-packet.cc @@ -69,17 +69,17 @@ bool QuicPacket::IsVersionNegotiationPacket() { void QuicPacket::ReassemblePacket() { // Start with the UDP payload. - Packet new_p = Packet(udp_payload_.data(), udp_payload_.size()); + Packet * new_p = new Packet(udp_payload_.data(), udp_payload_.size()); // Add the UDP header and make sure to recalculate the checksum. udp_hdr_.ForcePayloadSize(udp_payload_.size() + udp_hdr_len_); udp_hdr_.ForceChecksum(0); udp_hdr_.InitializeChecksum(ipv4_hdr_.GetSource(), ipv4_hdr_.GetDestination(), ipv4_hdr_.GetProtocol()); - new_p.AddHeader(udp_hdr_); + new_p->AddHeader(udp_hdr_); // Add the IP header, again make sure to recalculate the checksum. ipv4_hdr_.EnableChecksum(); - new_p.AddHeader(ipv4_hdr_); + new_p->AddHeader(ipv4_hdr_); // Add the PPP header. - new_p.AddHeader(ppp_hdr_); + new_p->AddHeader(ppp_hdr_); p_->RemoveAtEnd(p_->GetSize()); - p_->AddAtEnd(Ptr(&new_p)); + p_->AddAtEnd(Ptr(new_p)); } diff --git a/sim/scenarios/helper/quic-point-to-point-helper.cc b/sim/scenarios/helper/quic-point-to-point-helper.cc index b04e063..93a9972 100644 --- a/sim/scenarios/helper/quic-point-to-point-helper.cc +++ b/sim/scenarios/helper/quic-point-to-point-helper.cc @@ -3,6 +3,7 @@ #include "ns3/ipv4-address-helper.h" #include "ns3/ipv6-address-helper.h" #include "quic-point-to-point-helper.h" +#include "network-config.h" using namespace ns3; @@ -20,12 +21,13 @@ NetDeviceContainer QuicPointToPointHelper::Install(Ptr a, Ptr b) { tch.SetRootQueueDisc("ns3::PfifoFastQueueDisc", "MaxSize", queue_size_); tch.Install(devices); + const NetworkConfig& config = NetworkConfig::Instance(); Ipv4AddressHelper ipv4; - ipv4.SetBase("193.167.50.0", "255.255.255.0"); + ipv4.SetBase(config.GetV4PointToPointNetwork().c_str(), config.GetV4SubnetMask().c_str()); ipv4.Assign(devices); Ipv6AddressHelper ipv6; - ipv6.SetBase("fd00:cafe:cafe:50::", 64); + ipv6.SetBase(config.GetV6PointToPointNetwork().c_str(), config.GetV6PrefixInt()); ipv6.Assign(devices); return devices; diff --git a/sim/scenarios/rebind/rebind-error-model.cc b/sim/scenarios/rebind/rebind-error-model.cc index 7bd578b..a5154c3 100644 --- a/sim/scenarios/rebind/rebind-error-model.cc +++ b/sim/scenarios/rebind/rebind-error-model.cc @@ -1,5 +1,6 @@ #include "rebind-error-model.h" #include "ns3/core-module.h" +#include "../helper/network-config.h" #include using namespace std; @@ -14,7 +15,9 @@ TypeId RebindErrorModel::GetTypeId(void) { } RebindErrorModel::RebindErrorModel() - : client("193.167.0.100"), server("193.167.100.100"), nat(client), + : client(ns3::NetworkConfig::Instance().GetClientV4Address()), + server(ns3::NetworkConfig::Instance().GetServerV4Address()), + nat(client), rebind_addr(false) { rng = CreateObject(); } diff --git a/sim/scenarios/tcp-cross-traffic/tcp-cross-traffic.cc b/sim/scenarios/tcp-cross-traffic/tcp-cross-traffic.cc index 662f833..712fd7c 100644 --- a/sim/scenarios/tcp-cross-traffic/tcp-cross-traffic.cc +++ b/sim/scenarios/tcp-cross-traffic/tcp-cross-traffic.cc @@ -4,6 +4,7 @@ #include "ns3/applications-module.h" #include "../helper/quic-network-simulator-helper.h" #include "../helper/quic-point-to-point-helper.h" +#include "../helper/network-config.h" using namespace ns3;