Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions endpoint/setup.sh
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
#!/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" ")
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
12 changes: 5 additions & 7 deletions sim/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
153 changes: 153 additions & 0 deletions sim/scenarios/helper/network-config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
#ifndef NETWORK_CONFIG_H
#define NETWORK_CONFIG_H

#include <string>
#include <cstdlib>
#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
30 changes: 23 additions & 7 deletions sim/scenarios/helper/quic-network-simulator-helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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<Node> local, Ptr<Node> peer) {
Ptr<Ipv6StaticRouting> routing = Ipv6RoutingHelper::GetRouting<Ipv6StaticRouting>(local->GetObject<Ipv6>()->GetRoutingProtocol());
Ptr<Ipv6> peer_ipv6 = peer->GetObject<Ipv6>();
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());
Expand All @@ -106,7 +121,8 @@ void QuicNetworkSimulatorHelper::Run(Time duration) {
massageIpv6Routing(right_node_, left_node_);

// write the routing table to file
Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper>("dynamic-global-routing.routes", std::ios::out);
Ptr<OutputStreamWrapper> routingStream =
Create<OutputStreamWrapper>("/logs/simulator-routes.txt", std::ios::out);
Ipv4RoutingHelper::PrintRoutingTableAllAt(Seconds(0.), routingStream);
Ipv6RoutingHelper::PrintRoutingTableAllAt(Seconds(0.), routingStream);

Expand Down
10 changes: 5 additions & 5 deletions sim/scenarios/helper/quic-packet.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes a compilation warning.

// 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<Packet>(&new_p));
p_->AddAtEnd(Ptr<Packet>(new_p));
}
6 changes: 4 additions & 2 deletions sim/scenarios/helper/quic-point-to-point-helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -20,12 +21,13 @@ NetDeviceContainer QuicPointToPointHelper::Install(Ptr<Node> a, Ptr<Node> 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;
Expand Down
5 changes: 4 additions & 1 deletion sim/scenarios/rebind/rebind-error-model.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "rebind-error-model.h"
#include "ns3/core-module.h"
#include "../helper/network-config.h"
#include <cassert>

using namespace std;
Expand All @@ -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<UniformRandomVariable>();
}
Expand Down
1 change: 1 addition & 0 deletions sim/scenarios/tcp-cross-traffic/tcp-cross-traffic.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down