Skip to content

Commit

Permalink
Initial version
Browse files Browse the repository at this point in the history
  • Loading branch information
snkas committed Sep 11, 2020
0 parents commit 94d7c01
Show file tree
Hide file tree
Showing 216 changed files with 44,991 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.idea
*.pyc
gen_data
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "ns3-sat-sim/simulator/contrib/basic-sim"]
path = ns3-sat-sim/simulator/contrib/basic-sim
url = https://github.com/snkas/basic-sim
4 changes: 4 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ns3-sat-sim/ is licensed under the GNU GPL version 2 license.
satgenpy/ is licensed under the MIT license.
satviz/ is license under the MIT license.
paper/ is licensed under the MIT license.
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Hypatia

Hypatia is a low earth orbit (LEO) satellite network simulation framework.

It consists of four main components:

* `satgenpy` : Python framework to generate LEO satellite networks and generate
routing over time over a period of time. It additionally includes several
analysis tools to study individual cases.
(license: MIT)

* `ns3-sat-sim` : ns-3 based framework which takes as input the state generated
by `satgenpy` to perform packet-level simulations over LEO satellite networks.
It makes use of the `satellite` ns-3 module by Pedro Silva to calculate
satellite locations over time.
(license: GNU GPL version 2)

* `satviz` : Cesium visualization pipeline to generate interactive satellite network
visualizations. It makes use of the online Cesium API by generating CesiumJS code.
The API calls require its user to obtain a Cesium access token (via [https://cesium.com/]()).
More information can be found in `satviz/README.md`.
(license: MIT)

* `paper` : Experimental and plotting code to reproduce the experiments and
figures which are presented in the paper.
(license: MIT)

This is the code repository introduced and used in "Exploring the “Internet from space” with Hypatia"
by Simon Kassing*, Debopam Bhattacherjee*, André Baptista Águas, Jens Eirik Saethre and Ankit Singla
(*equal contribution), which is published in the Internet Measurement Conference (IMC) 2020.

BibTeX citation:
```
To be announced.
```

## Getting started

The reproduction of the paper is essentially the tutorial for Hypatia.
Please navigate to `paper/README.md`.
6 changes: 6 additions & 0 deletions ns3-sat-sim/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.idea
ns-3.30.1
*.pyc
CMakeLists.txt
cmake-build-debug
copy_simulator*
339 changes: 339 additions & 0 deletions ns3-sat-sim/LICENSE

Large diffs are not rendered by default.

38 changes: 38 additions & 0 deletions ns3-sat-sim/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Low earth orbit satellite network simulation using ns-3

Hypatia makes use of ns-3 to simulate the satellite networks at packet-level
granularity. It builds upon two ns-3 modules:

* `satellite` : Satellite movement calculation using SGP-4. This module is used
by Hypatia to calculate the channel delay for each packet which traverses
either a GSl or ISL. It was written by Pedro Silva at INESC-TEC. It can
be found at:

https://gitlab.inesctec.pt/pmms/ns3-satellite

A copy of it is included in this repository with minor modifications.
It is located at: simulator/src/satellite

* `basic-sim` : Simulation framework to make e.g., running end-to-end
TCP flows more easier. It can be found at:

https://github.com/snkas/basic-sim

It is added as git submodule at: simulator/contrib/basic-sim


## Getting started

1. Install dependencies (inherited from `basic-sim` ns-3 module):
```
sudo apt-get update
sudo apt-get -y install mpic++ libopenmpi-dev lcov gnuplot
pip install numpy statsmodels
pip install git+https://github.com/snkas/exputilpy.git
git submodule update --init --recursive
```

2. Build optimized:
```
bash build.sh --optimized
```
44 changes: 44 additions & 0 deletions ns3-sat-sim/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
NS3_VERSION="ns-3.31"

# Usage help
if [ "$1" == "--help" ]; then
echo "Usage: bash build.sh [--help, --debug_all, --debug_minimal, --optimized, --optimized_with_tests]"
exit 0
fi

# Extract copy of ns-3
echo "Unzipping clean ns-3 (no overwrites)"
unzip ${NS3_VERSION}.zip || exit 1
cp -r ${NS3_VERSION}/* simulator/ || exit 1
rm -r ${NS3_VERSION} || exit 1
cd simulator || exit 1

# Update the basic-sim module
echo "Updating git submodules"
git submodule update || exit 1

# Configure the build
if [ "$1" == "--debug_all" ]; then
./waf configure --build-profile=debug --enable-mpi --enable-examples --enable-tests --enable-gcov --out=build/debug_all || exit 1

elif [ "$1" == "--debug_minimal" ]; then
./waf configure --build-profile=debug --enable-mpi --out=build/debug_minimal || exit 1

elif [ "$1" == "--optimized" ]; then
./waf configure --build-profile=optimized --enable-mpi --out=build/optimized || exit 1

elif [ "$1" == "--optimized_with_tests" ]; then
./waf configure --build-profile=optimized --enable-mpi --enable-tests --out=build/optimized_with_tests || exit 1

elif [ "$1" == "" ]; then
# Default is debug_all
./waf configure --build-profile=debug --enable-mpi --enable-examples --enable-tests --enable-gcov --out=build/debug_all || exit 1

else
echo "Invalid build option: $1"
echo "Usage: bash build.sh [--debug_all, --debug_minimal, --optimized, --optimized_with_tests]"
exit 1
fi

# Perform the build
./waf -j4 || exit 1
Binary file added ns3-sat-sim/ns-3.31.zip
Binary file not shown.
6 changes: 6 additions & 0 deletions ns3-sat-sim/rebuild.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

# Create the basic-sim module
cd simulator || exit 1

# Rebuild whichever build is configured right now
./waf -j4 || exit 1
5 changes: 5 additions & 0 deletions ns3-sat-sim/simulator/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/*
!contrib
!.gitignore
!scratch
!src
3 changes: 3 additions & 0 deletions ns3-sat-sim/simulator/contrib/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/*
!satellite-network
!basic-sim
1 change: 1 addition & 0 deletions ns3-sat-sim/simulator/contrib/basic-sim
Submodule basic-sim added at 96b470
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Satellite network module
----------------------------
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-

def build(bld):
pass
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/*
* Copyright (c) 2020 ETH Zurich
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Simon 2020
*/

#include "arbiter-single-forward-helper.h"

namespace ns3 {

ArbiterSingleForwardHelper::ArbiterSingleForwardHelper (Ptr<BasicSimulation> basicSimulation, Ptr<TopologySatelliteNetwork> topology) {
std::cout << "SETUP SINGLE FORWARDING ROUTING" << std::endl;
m_basicSimulation = basicSimulation;
m_topology = topology;

// Read in initial forwarding state
std::cout << " > Create initial single forwarding state" << std::endl;
std::vector<std::vector<std::tuple<int32_t, int32_t, int32_t>>> initial_forwarding_state = InitialEmptyForwardingState();
basicSimulation->RegisterTimestamp("Create initial single forwarding state");

// Set the routing arbiters
std::cout << " > Setting the routing arbiter on each node" << std::endl;
NodeContainer nodes = m_topology->GetNodes();
for (int i = 0; i < m_topology->GetNumNodes(); i++) {
Ptr<ArbiterSingleForward> arbiter = CreateObject<ArbiterSingleForward>(nodes.Get(i), nodes, m_topology, initial_forwarding_state[i]);
m_arbiters.push_back(arbiter);
nodes.Get(i)->GetObject<Ipv4>()->GetRoutingProtocol()->GetObject<Ipv4ArbiterRouting>()->SetArbiter(arbiter);
}
basicSimulation->RegisterTimestamp("Setup routing arbiter on each node");

// Load first forwarding state
m_dynamicStateUpdateIntervalNs = parse_positive_int64(m_basicSimulation->GetConfigParamOrFail("dynamic_state_update_interval_ns"));
std::cout << " > Forward state update interval: " << m_dynamicStateUpdateIntervalNs << "ns" << std::endl;
std::cout << " > Perform first forwarding state load for t=0" << std::endl;
UpdateForwardingState(0);
basicSimulation->RegisterTimestamp("Create initial single forwarding state");

std::cout << std::endl;
}

std::vector<std::vector<std::tuple<int32_t, int32_t, int32_t>>>
ArbiterSingleForwardHelper::InitialEmptyForwardingState() {
std::vector<std::vector<std::tuple<int32_t, int32_t, int32_t>>> initial_forwarding_state;
for (int i = 0; i < m_topology->GetNumNodes(); i++) {
std::vector <std::tuple<int32_t, int32_t, int32_t>> next_hop_list;
for (int j = 0; j < m_topology->GetNumNodes(); j++) {
next_hop_list.push_back(std::make_tuple(-2, -2, -2)); // -2 indicates an invalid entry
}
initial_forwarding_state.push_back(next_hop_list);
}
return initial_forwarding_state;
}

void ArbiterSingleForwardHelper::UpdateForwardingState(int64_t t) {

// Filename
std::ostringstream res;
res << m_basicSimulation->GetRunDir() << "/";
res << m_basicSimulation->GetConfigParamOrFail("satellite_network_routes_dir") << "/fstate_" << t << ".txt";
std::string filename = res.str();

// Check that the file exists
if (!file_exists(filename)) {
throw std::runtime_error(format_string("File %s does not exist.", filename.c_str()));
}

// Open file
std::string line;
std::ifstream fstate_file(filename);
if (fstate_file) {

// Go over each line
size_t line_counter = 0;
while (getline(fstate_file, line)) {

// Split on ,
std::vector<std::string> comma_split = split_string(line, ",", 5);

// Retrieve node identifiers
int64_t current_node_id = parse_positive_int64(comma_split[0]);
int64_t target_node_id = parse_positive_int64(comma_split[1]);
int64_t next_hop_node_id = parse_int64(comma_split[2]);
int64_t my_if_id = parse_int64(comma_split[3]);
int64_t next_if_id = parse_int64(comma_split[4]);
// TODO: more node identifier checks
if (next_hop_node_id < -1) {
throw std::runtime_error("Invalid next hop id.");
} else if (my_if_id < -1) {
throw std::runtime_error("Invalid my interface id.");
} else if (next_if_id < -1) {
throw std::runtime_error("Invalid next interface id.");
}

// Add to forwarding state
m_arbiters[current_node_id]->SetSingleForwardState(
target_node_id,
next_hop_node_id,
1 + my_if_id, // Skip the loop-back interface
1 + next_if_id // Skip the loop-back interface
);

// Next line
line_counter++;

}

// Close file
fstate_file.close();

} else {
throw std::runtime_error(format_string("File %s could not be read.", filename.c_str()));
}

// Given that this code will only be used with satellite networks, this is okay-ish,
// but it does create a very tight coupling between the two -- technically this class
// can be used for other purposes as well
if (!parse_boolean(m_basicSimulation->GetConfigParamOrDefault("satellite_network_force_static", "false"))) {
// Plan the next update
int64_t next_update_ns = t + m_dynamicStateUpdateIntervalNs;
if (next_update_ns < m_basicSimulation->GetSimulationEndTimeNs()) {
Simulator::Schedule(NanoSeconds(m_dynamicStateUpdateIntervalNs), &ArbiterSingleForwardHelper::UpdateForwardingState, this, next_update_ns);
}
}

}

} // namespace ns3
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2020 ETH Zurich
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Simon 2020
*/

#ifndef ARBITER_SINGLE_FORWARD_HELPER
#define ARBITER_SINGLE_FORWARD_HELPER

#include "ns3/ipv4-routing-helper.h"
#include "ns3/basic-simulation.h"
#include "ns3/topology-satellite-network.h"
#include "ns3/ipv4-arbiter-routing.h"
#include "ns3/arbiter-single-forward.h"

namespace ns3 {

class ArbiterSingleForwardHelper
{
public:
ArbiterSingleForwardHelper(Ptr<BasicSimulation> basicSimulation, Ptr<TopologySatelliteNetwork> topology);
private:
std::vector<std::vector<std::tuple<int32_t, int32_t, int32_t>>> InitialEmptyForwardingState();
void UpdateForwardingState(int64_t t);

// Parameters
Ptr<BasicSimulation> m_basicSimulation;
Ptr<TopologySatelliteNetwork> m_topology;
int64_t m_dynamicStateUpdateIntervalNs;
std::vector<Ptr<ArbiterSingleForward>> m_arbiters;

};

} // namespace ns3

#endif /* ARBITER_SINGLE_FORWARD_HELPER */
Loading

0 comments on commit 94d7c01

Please sign in to comment.