Skip to content
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
ac4ed3b
feat(msg-sim): linux stub
thedevbirb Nov 24, 2025
35d082b
chore(msg-sim): remove macos target; support only linux
thedevbirb Nov 28, 2025
89c52ec
feat(msg-sim): simulation network stub
thedevbirb Dec 1, 2025
f197870
chore(msg-sim): refactor network stub
thedevbirb Dec 1, 2025
69093db
feat(msg-sim): command utilities
thedevbirb Dec 3, 2025
863c6fe
fix(msg-sim): types, subnet
thedevbirb Dec 5, 2025
86e6a52
fix(msg-sim): avoid mask config
thedevbirb Dec 5, 2025
ee1d393
check
thedevbirb Dec 7, 2025
02b7f91
chore(msg-sim): refactor
thedevbirb Dec 7, 2025
e159181
chore(msg-sim): refactor
thedevbirb Dec 7, 2025
35579a7
feat(msg-sim): refactor with rtnetlink and new architecture
thedevbirb Dec 9, 2025
b05e0e6
feat(msg-sim): dyn task
thedevbirb Dec 10, 2025
3c1a71e
feat(msg-sim): running code in namespace works
thedevbirb Dec 15, 2025
7771d65
chore(msg-sim): add test using req/rep
thedevbirb Dec 15, 2025
7a7b9d6
feat(msg-sim): bring lo up; tc stub
thedevbirb Dec 16, 2025
75f9d00
refactor
thedevbirb Dec 17, 2025
5be66ed
stub tc
thedevbirb Dec 27, 2025
62e0141
ugly but works
thedevbirb Dec 28, 2025
c5f8213
fix(msg-sim): latency and jitter computation
thedevbirb Dec 30, 2025
e26834a
chore(msg-sim): refactor
thedevbirb Dec 30, 2025
52fe245
feat(msg-sim): generic context attempt
thedevbirb Jan 1, 2026
acb2d38
chore(msg-sim): refactor, comments
thedevbirb Jan 4, 2026
5c2c9b9
fix(msg-sim): don't build the crate on macos
thedevbirb Jan 5, 2026
3d4a4f8
fix(msg-sim): tokio fs feature, bump rtnetlink
thedevbirb Jan 5, 2026
9f73a0a
fix(msg-sim): ci, remove simulation from pubsub it
thedevbirb Jan 6, 2026
8bec9ca
stub
thedevbirb Jan 8, 2026
8aa8742
feat(msg-sim): use drr for adding classes dynamically; refactor
thedevbirb Jan 9, 2026
ab4a6ff
chore(msg-sim): document notable paths
thedevbirb Jan 9, 2026
e769af1
chore: shear deps
thedevbirb Jan 9, 2026
f8b6335
chore: bump MSRV to 1.86.0
thedevbirb Jan 9, 2026
593f2c6
chore: update ci with privileges for running msg-sim tests
thedevbirb Jan 9, 2026
7f2d13d
Merge branch 'main' of https://github.com/chainbound/msg-rs into lore…
thedevbirb Jan 9, 2026
591f8e9
chore(msg-sim): update readme
thedevbirb Jan 9, 2026
2442bf3
feat(msg-sim): Cast trait
thedevbirb Jan 9, 2026
d429e4e
fix(msg-sim): doc comments
thedevbirb Jan 9, 2026
ab0f6b4
chore(msg-sim): move scripts to separate folder; highlight limitation…
thedevbirb Jan 13, 2026
7442cf7
chore(msg-sim): example sim_multi_region
thedevbirb Jan 13, 2026
0d3a3de
chore(msg-sim): builder pattern for impairments
thedevbirb Jan 13, 2026
f6babf0
chore(msg-sim): address review
thedevbirb Jan 14, 2026
0c40910
chore: update CLAUDE.md
thedevbirb Jan 14, 2026
b9e172d
Merge branch 'main' of https://github.com/chainbound/msg-rs into lore…
thedevbirb Jan 14, 2026
fee3b9a
fix(msg-sim): ci
thedevbirb Jan 14, 2026
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
96 changes: 95 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

57 changes: 29 additions & 28 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
[workspace]
members = [
"msg",
"msg-socket",
"msg-wire",
"msg-transport",
"msg-common",
"msg-sim",
"msg",
"msg-socket",
"msg-wire",
"msg-transport",
"msg-common",
"msg-sim",
]
resolver = "2"

Expand All @@ -19,19 +19,19 @@ authors = ["Chainbound Developers <dev@chainbound.io>"]
homepage = "https://github.com/chainbound/msg-rs"
repository = "https://github.com/chainbound/msg-rs"
keywords = [
"messaging",
"distributed",
"systems",
"networking",
"quic",
"quinn",
"tokio",
"async",
"simulation",
"pnet",
"udp",
"tcp",
"socket",
"messaging",
"distributed",
"systems",
"networking",
"quic",
"quinn",
"tokio",
"async",
"simulation",
"pnet",
"udp",
"tcp",
"socket",
]

[workspace.dependencies]
Expand All @@ -44,11 +44,11 @@ msg-sim = { path = "./msg-sim" }
# async
async-trait = "0.1"
tokio = { version = "1", features = [
"rt",
"rt-multi-thread",
"net",
"io-util",
"macros",
"rt",
"rt-multi-thread",
"net",
"io-util",
"macros",
] }
tokio-util = { version = "0.7", features = ["codec"] }
tokio-stream = { version = "0.1", features = ["sync"] }
Expand All @@ -64,12 +64,13 @@ rustc-hash = "2"
rand = "0.9"
libc = "0.2"
derive_more = { version = "2.1.1", features = [
"from",
"into",
"deref",
"deref_mut",
"from",
"into",
"deref",
"deref_mut",
] }
arc-swap = "1.8.0"
nix = { version = "0.30.1" }

# networking
quinn = "0.11.9"
Expand Down
14 changes: 14 additions & 0 deletions msg-sim/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,18 @@ repository.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
msg-socket.workspace = true
msg-transport.workspace = true

pnet.workspace = true
nix.workspace = true
thiserror.workspace = true
tracing.workspace = true
derive_more.workspace = true
tokio.workspace = true
futures.workspace = true
rtnetlink = { version = "0.19.0" }


[dev-dependencies]
tracing-subscriber = "0.3"
64 changes: 7 additions & 57 deletions msg-sim/README.md
Original file line number Diff line number Diff line change
@@ -1,65 +1,15 @@
# `msg-sim`

## Overview
This crate provides functionality to simulate real-world network conditions
locally to and from a specific endpoint for testing and benchmarking purposes.
It only works on MacOS and Linux.
todo: update README.md

## Implementation
#### How to run tests

### MacOS
On MacOS, we use a combination of the `pfctl` and `dnctl` tools.
[`pfctl`](https://man.freebsd.org/cgi/man.cgi?query=pfctl&apropos=0&sektion=8&manpath=FreeBSD+14.0-RELEASE+and+Ports&arch=default&format=html) is a tool to manage the packet filter device. [`dnctl`](https://man.freebsd.org/cgi/man.cgi?query=dnctl&sektion=8&format=html) can manage
the [dummynet](http://info.iet.unipi.it/~luigi/papers/20100304-ccr.pdf) traffic shaper.
Given that the tests require root privileges to modify the networking stack,
you can run them with the following command:

The general flow is as follows:

* Create a dummynet pipe with `dnctl` and configure it with `bw`, `delay`, `plr`

Example:
```bash
sudo dnctl pipe 1 config bw 10Kbit/s delay 50 plr 0.1
```

* Create a loopback alias with `ifconfig` to simulate a different endpoint and
set the MTU to the usual value (1500)

Example:
```bash
sudo ifconfig lo0 alias 127.0.0.3 up
sudo ifconfig lo0 mtu 1500
```

* Use `pfctl` to create a rule to match traffic and send it through the pipe

Example:
```bash
# Create an anchor (a named container for rules, close to a namespace)
(cat /etc/pf.conf && echo "dummynet-anchor \"msg-sim\"" && \
echo "anchor \"msg-sim\"") | sudo pfctl -f -

# Create a rule to match traffic from any to the alias and send it through the pipe
echo 'dummynet in from any to 127.0.0.3 pipe 1' | sudo pfctl -a msg-sim -f -

# Enable the packet filter
sudo pfctl -E
```

* Remove the rules and the pipe
```bash
# Apply the default configuration
sudo pfctl -f /etc/pf.conf
# Disable the packet filter
sudo pfctl -d
# Remove the alias & reset the MTU
sudo ifconfig lo0 -alias 127.0.0.3
sudo ifconfig lo0 mtu 16384
# Remove the dummynet pipes
sudo dnctl pipe delete 1
sudo HOME=$HOME $(which cargo) test # add your arguments here
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not super liking this - isn't there a better way? Maybe asking capabilities from the kernel? Or elevate priviledges inside the binary

Copy link
Contributor Author

@thedevbirb thedevbirb Jan 9, 2026

Choose a reason for hiding this comment

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

I hear that. This has been a forever pain point since I started using namespaces. Using plain sudo is just bad and I know. But you need the capabilities to fiddle with the networking stack, like CAP_NET_ADMIN (and something more). So an approach I tried briefly is to first compile the test binaries (--no-run flag), identify them, grant privileges with sudo, and then run them.

Still not incredible DX, so I'm postponing the problem for now until I think of something better.

```

### Questions
- Do we need to create 2 pipes to simulate a bidirectional link? MAN page seems to say so.

### Linux
On Linux, we use dummy interfaces and `tc` with `netem` to simulate and shape traffic.
We need to provide the `$HOME` environment variable to `sudo` to ensure that
it can find the Rust toolchain, and then we also need to provide the path of `cargo`.
Loading
Loading