Deep Space Network Simulator

Simulate the Next Generation of
Space Networks

High-fidelity, event-driven simulation for LEO megaconstellations, interplanetary networks, and delay-tolerant protocols. Run 50,000+ nodes on a single CPU core, build secure-by-design protocols, and test parameters before you launch.

Published research

"DSNS: The Deep Space Network Simulator"

2025 Security for Space Systems (3S) · IEEE

Install in seconds:

git clone https://github.com/ssloxford/DSNS
cd DSNS
pip install --editable .

Open source under GPLv3 · View on GitHub

For Industry & Agencies

Mission-Ready Simulation

Validate protocols, test resilience, and align with standards before you launch.

CCSDS Reference Scenarios

Built-in implementations of the standard DTN reference scenarios for Earth Observation, Lunar Communication, and Mars Communication, enabling protocol testing under known conditions.

Earth · Moon · Mars

Realistic Orbital Mechanics

Model Walker constellations, fixed ground stations, or real satellites via TLE/SGP4 propagation, orbiting realistic planets, with planetary occlusion and elevation constraints.

Walker · TLE · SGP4

Security & Resilience Testing

Built-in attack models for global and targeted message loss, link flooding, and bandwidth exhaustion. Test rerouting and protocol robustness under stress.

Attack simulation · Message loss · Link flooding

Massive Scale, Minimal Resources

Simulate over 50,000 nodes on a single CPU core using less than 2.1 GB of RAM. Single-threaded design enables parallel parameter sweeps on one machine.

Single core · Linear scaling

Delay-Tolerant Networking

BP-style store-and-forward routing and the Licklider Transmission Protocol (LTP) with reliable per-hop segmentation and retransmission. Build protocol logic at the abstraction level you need.

BP · LTP · Store-and-forward

Standards-Aligned Testing

Ready for integration into testing pipelines. Run CCSDS reference scenarios, validate protocol behavior under realistic orbital mechanics, and test resilience before deployment.

CCSDS · Compliance · Validation

Use Case: Pre-Launch Validation

Validate protocols before hardware deployment. Simulate your entire constellation topology with realistic orbital mechanics, test protocol behavior under a range of scenarios and network conditions, and run security resilience tests – all before a single satellite leaves the ground.

Simulation Scenarios

The flexibility and modularity of DSNS makes it easy to build scenarios spanning Earth orbit, deep space, and interplanetary relay networks. Use one of the provided scenarios or build your own.

Now showing
Earth-Mars Relay

An interplanetary relay network between Earth and Mars, modeling deep-space delay-tolerant networking and planetary occlusion.

For Researchers

Built for Research

Python-native, modular, designed for rapid prototyping and open collaboration.

Modular Event-Driven Core

The simulation advances via a priority EventQueue. Actors process events via pattern matching, while DataProviders maintain state like routing tables and lookahead windows.

Swap protocols, routing strategies, or mobility models without touching the core engine. Add a new protocol in under 50 lines of Python.

Python-Native API

No domain-specific languages. Extend via standard Python classes with full type hints. The entire simulator is built in Python, so you can build new functionality by subclassing the existing Actor, DataProvider, or Constellation classes.

Jupyter-friendly outputs, Sphinx-generated docs, and seamless integration with a huge ecosystem of existing tools.

Reference Scenarios

Comes with CCSDS reference topologies and custom large-scale setups: Walker constellations, federated CubeSat networks (with live CelesTrak data), and interplanetary relay networks.

Configurable traffic generators: constant rate, uniform, Gaussian, and Pareto distributions. Export logs and aggregate metrics directly.

Seamless Research Workflow

Run dozens of independent simulations concurrently on one machine. The simplicity of the single-threaded design gives flexibility: perfect for parameter sweeps and A/B protocol testing.

Export data in CSV/JSON for downstream analysis.

Extending DSNS

DSNS can be easily extended by building custom modules on top of the core engine. Build the parts you care about, and the rest gets out of the way.

Build your own...
Event
custom_event.py
from dsns.events import Event
from typing import Any

class CustomEvent(Event):
    data: Any

    def __init__(self, time: float, data: Any):
        super().__init__(time, ["data"])
        self.data = data
custom_protocol.py
from dsns.simulation import Actor
from dsns.events import Event
from dsns.message import MessageCreatedEvent, MessageReceivedEvent

class CustomActor(Actor):
    def __init__(self, params):
        super().__init__()
        # Custom logic

    def initialize(self) -> list[Event]:
        # Generate initial events
        events = [MessageCreatedEvent(...)]
        return events

    def handle_event(self, mobility, event):
        events = []
        if isinstance(event, MessageReceivedEvent):
            # Custom message handling logic
            events.append(MessageCreatedEvent(...))
        return events
custom_constellation.py
import numpy as np
from dsns.constellation import Constellation, Satellite, Satellites, ISLHelper, OrbitalCenter
from dsns.helpers import IDHelper

class CustomConstellation(Constellation):
    def __init__(self, name: str, id_helper: IDHelper, isl_helper: ISLHelper, orbital_center: OrbitalCenter, num_planes: int, sats_per_plane: int):
        self.name = name
        self.isl_helper = isl_helper
        self.orbital_center = orbital_center
        self.num_planes = num_planes
        self.sats_per_plane = sats_per_plane
        self.num_sats = num_planes * sats_per_plane

        # Define initial satellite positions
        self.satellites = Satellites([])
        for plane in range(num_planes):
            for sat in range(sats_per_plane):
                sat_name = f"{name}_{plane}_{sat}"
                sat_id = id_helper.assign_id(sat_name)
                self.satellites.append(Satellite(sat_name, sat_id, self.name, orbital_center=orbital_center))

        self.satellite_positions = np.zeros((self.num_sats, 3))
        self.update_positions(0.0)

    def update_positions(self, time: float):
        for plane in range(self.num_planes):
            for sat in range(self.sats_per_plane):
                sat_index = (plane * self.sats_per_plane) + sat
                pos = ...

                self.satellites[sat_index].position = pos
                self.satellite_positions[sat_index] = pos
custom_connectivity.py
from dsns.constellation import Satellites, ISLHelper
from dsns.multiconstellation import ILLHelper
from dsns.helpers import SatID

# Implement a custom Inter-Satellite Link (ISL) helper
# to define connectivity rules between nodes.
class CustomISLHelper(ISLHelper):
    def get_isls(self, satellites: Satellites, positions: np.ndarray) -> list[tuple[SatID, SatID]]:
        # Custom link logic based on distance,
        # elevation, or other constraints
        ...

# Implement a custom Inter-Layer Link (ILL) helper
# to define connectivity rules between constellations or orbital shells.
class CustomILLHelper(ILLHelper):
    def get_ills(self, satellites: Satellites, positions: np.ndarray) -> list[tuple[SatID, SatID]]:
        # Custom link logic based on distance,
        # elevation, or other constraints
        ...
custom_routing.py
from dsns.simulation import RoutingDataProvider

# Build a custom routing strategy by extending
# the base RoutingDataProvider.

class CustomRoutingProvider(RoutingDataProvider):
    def _get_next_hop(self, source: SatID, destination: SatID) -> Optional[SatID]:
        # Custom next-hop selection logic
        ...

    def get_distance(self, source: SatID, destination: SatID) -> Optional[float]:
        # Latency between a given source and destination
        ...

    def get_neighbors(self, source: SatID, max_distance: Optional[float] = None) -> list[SatID]:
        # Get the reachable neighbors for a given source, up to a maximum time difference
        ...
custom_scenario.py
import os, pickle
from dsns.presets import EarthMoonMarsMultiConstellation
from dsns.simulation import Simulation
from dsns.transmission import LinkTransmissionActor, MessageLocationTracker
from dsns.traffic_sim import MultiPointToPointTrafficActor
from dsns.message_actors import MessageRoutingActor, LookaheadRoutingDataProvider
from dsns.logging import PreprocessedLoggingActor, BandwidthLoggingActor, LTPTransmissionLoggingActor
from dsns.message import LossConfig

constellation = EarthMoonMarsMultiConstellation(moon=True, mars=False, moon_mars_link=False)
tracker = MessageLocationTracker()
routing_data_provider = LookaheadRoutingDataProvider(resolution=15.0, num_steps=600)

actors = [
    LinkTransmissionActor(default_bandwidth=100e6/8, buffer_if_link_busy=True, reroute_on_link_down=True, message_location_tracker=tracker),
    MultiPointToPointTrafficActor([("EarthToMoon", 0, 345, 1e6, 15.0)], update_interval=300, reliable_messages=False, cutoff=28800),
]

actors.append(MessageRoutingActor(routing_data_provider, store_and_forward=True, model_bandwidth=True, loss_config=LossConfig()))

logging_actor_pre = PreprocessedLoggingActor(log_other=False)
logging_actor_bw = BandwidthLoggingActor()
logging_actor_ltp = LTPTransmissionLoggingActor()

sim = Simulation(constellation, actors=actors, logging_actors=[logging_actor_pre, logging_actor_bw, logging_actor_ltp], data_providers=[routing_data_provider], timestep=15.0)
sim.initialize(0)
sim.run(43200, progress=True)

os.makedirs("results", exist_ok=True)
with open("results/pre.pickle", "wb") as f: pickle.dump((pre.direct_messages, pre.broadcast_messages, pre.other_events), f)
with open("results/bw.pickle", "wb") as f: pickle.dump(bw.aggregate(1.0, default_bandwidth=100e6/8), f)
with open("results/ltp.pickle", "wb") as f: pickle.dump(ltp.aggregate(1.0), f)

Architecture

A modular, event-driven design with sub-millisecond precision and support for varying levels of abstraction, from high-level protocol logic down to bit-level fidelity.

DSNS Architecture Diagram Event-driven simulation architecture showing MultiConstellation, EventQueue, Actor, DataProvider, and Processing components with their interactions. Simulation MultiConstellation Constellation ISLHelper ILLHelper EventQueue Event t1 Data Event t2 Data Event t3 Data Event t4 Data Event Actor DataProvider update(t1) handle_event list[Event]

Event-Driven Engine

Manages simulation time via a priority EventQueue. Every state change is a timestamped Event: the loop pops the next event, sends it to all actors, and enqueues any new events they generate. An optional minimum timestep batches mobility and connectivity updates. This architecture means the simulation can fast-forward through idle periods and long interplanetary gaps while preserving sub-millisecond precision when needed.

Actors

The Actor base class implements all logic via pattern-matching on events. Actors never call each other directly; they communicate solely through the event queue. This decoupling makes it trivial to swap or add protocols (e.g. MessageRoutingActor, LinkTransmissionActor, LTPActor) without any modifications to the core engine.

DataProviders

These maintain global, queryable state outside the event stream, such as routing tables and connectivity graphs. For example, the RoutingDataProvider computes next-hop routes for message delivery systems. The LookaheadRoutingDataProvider enables store-and-forward delivery by analyzing future network states over a configurable window.

Mobility & Connectivity

The MultiConstellation aggregates multiple Constellations (Walker, TLE, etc.), each with its own OrbitalCenter (Earth, Mars, etc.). ISLHelpers define links within constellations; ILLHelpers define links between constellations based on elevation, distance, and planetary occlusion. Once defined, these can be plugged into each other – the simulator handles the rest.

Message Delivery & Routing

The MessageRoutingActor provides message delivery by forwarding messages at each hop, querying a RoutingDataProvider. The LinkTransmissionActor models physical-layer constraints: bandwidth limits, queueing, and speed-of-light propagation delays. The simulator supports both best-effort (IP-style) and store-and-forward (DTN-style) delivery, swappable via a single flag.

Protocol Extensibility

The LTPActor demonstrates adding the Licklider Transmission Protocol as a full protocol layer: segmenting messages into red/green blocks, checkpointing, and retransmission with configurable timeouts. Attack simulation is supported out of the box via LossConfig (global or per-link message loss) and TrafficFloodActor (bandwidth exhaustion). Any protocol can be added by subclassing Actor or DataProvider.

Performance & Benchmarks

DSNS is resource-efficient, feature-rich, and scalable to thousands of nodes.

Scalability: Nodes vs Execution Time

Execution time (seconds) to run a 6,000-second simulation, for networks of varying sizes.

Scalability: Memory Usage

RAM usage scales linearly with network size.

Comparison with Existing Tools

Tool Orbital
Simulation
Interplanetary Dynamic
Links
Dynamic
Timesteps
Extensible Scalable Abstracted
Stack
DSNS
ONE Simulator
NOS3
SpaceSecLab/NSE2
Hypatia
Celestial
StarryNet
xeoverse
Stardust
SatScope

● = Full support    ◐ = Partial support    ○ = No support

Faster than Real-Time

Simulation speed is affected only by the number of events, enabling it to significantly outpace real time (even at 50,000+ nodes), and slow down to sub-millisecond precision when needed.

Single-Core Scalability

No multithreading overhead enables trivial horizontal scaling: run large numbers of simulations at once to cover all parameter combinations.

Abstracted Stack

No virtualization overhead: only simulate the layers you need to test. Supports highly abstracted protocols alongside bit-level implementations if required.

Cite DSNS

If you use DSNS in your research, please cite the following paper.

BibTeX
@inproceedings{smailesDSNS2025,
  author       = {Smailes, Joshua and Futera, Filip and K{\"o}hler, Sebastian and Birnbach, Simon and Strohmeier, Martin and Martinovic, Ivan},
  title        = {{DSNS}: {The Deep Space Network Simulator}},
  booktitle    = {2025 Security for Space Systems (3S)},
  year         = {2025},
  organization = {IEEE}
}