Bp-socket is a project designed to tackle a core DTN problem: providing a clean, interoperable API to facilitate application developers in sending data using the Bundle Protocol (BP).
The core objective of this project is to extend the Linux networking stack by introducing a new address family specifically for BP communication. The new address family, AF_BP, offers a protocol abstraction that aligns with the Interplanetary Networking (IPN) Scheme Naming and Addressing.
Bp-socket consists of two key components:
- Kernel Module: Provides a kernel-level abstraction for DTN communication with IPN scheme.
- User-Space Daemon: Acts as a pass-through service, facilitating communication between the kernel and the ION (Interplanetary Overlay Network) daemon, which handles the actual BP processing.
- Bp-socket
The resulting “BP Sockets” interface integrates with bundle protocol stacks in user space. Netlink IPC (Inter-Process Communication) coordinates kernel and user space interactions. The main elements of the architecture are described below.
Application
The user application creates a socket with a newly introduced address family 28, with the datagram (DGRAM) type and protocol number 0. The destination EID is provided via the sockaddr parameter of the sendto() function, and the Application Data Unit (ADU) to be conveyed via BP is provided in the message field.
Kernel Module
A kernel module processes BP Sockets calls. This module uses Netlink to deliver the bundle payload and related metadata to the BP Sockets Daemon. Netlink is a communication protocol between the Linux kernel and userspace processes designed for asynchronous message passing.
Daemon
Upon receiving a message, the BP Sockets Daemon in userspace retrieves the EID and the ADU, creates a bundle with ION, and sends it to the peer. In our case, the destination was running µD3TN on a second virtual machine (VM). This way, we demonstrated interoperability between µD3TN and ION using the BP Sockets interface. Note that the BP Sockets Daemon is modular and not locked to ION; it could easily be adapted to another Bundle Protocol implementation.
It was demonstrated by transmitting bundles from a minimal user space application through the Linux kernel and ION to µD3TN using BP Sockets. The screenshot below shows the µD3TN log (the receiving BP node) on the top, the BP Sockets App sender on the bottom left, and the BP App receiver output on the bottom right.
Choose one of the supported environments:
- RSync
- Libvirt (and QEMU)
- Vagrant
- Vagrant Libvirt
- Multipass >= 1.15
- macOS interface
en0(Wi-Fi) must support bridged mode via vmnet.framework
To set up the development environment described in the Architecture section, you must:
-
Choose your platform: either follow Linux Setup (Vagrant) or macOS Setup (Multipass).
-
Then complete the Preparing
ion-nodeandud3tn-node.
⚠️ IMPORTANT: It is highly recommended to useion-node(VM1) as your development environment. This VM already includes the necessary tools and dependencies. By working directly on VM1, you can simplify testing and avoid additional setup on your local machine. In both the Linux and macOS setups, your local project directory is automatically synced to the/bp-socketpath inside the ion-node VM.
- Create the virtual machines
Start both VMs with:
vagrant up- Enable automatic file synchronization on
ion-node
To keep your local bp-socket project synced with the /vagrant directory on ion-node, run:
vagrant rsync-autoMake sure to keep this process running in a separate terminal during development.
- Interact with the VMs
Use the following commands to connect:
vagrant ssh ion
vagrant ssh ud3tnIf you're using macOS, you can reproduce the virtual lab setup described above using Multipass and cloud-init instead of Vagrant. This approach uses QEMU with manual network configuration and provides an easy way to launch both ion-node and ud3tn-node.
- Launch
ion-node
multipass launch 24.04 \
--name ion-node \
--cpus 4 \
--memory 2G \
--disk 10G \
--timeout 1800 \
--mount $PWD:/bp-socket \
--network name=en0,mode=manual,mac="52:54:00:4b:ab:cd" \
--cloud-init configs/cloud-init/ion.cloud-config.cfgThis command:
- Assigns a static MAC address to the VM
- Mounts the project directory at
/bp-socketinside the VM - Applies the
cloud-initconfig to provision packages, IP setup, and kernel modules
- Launch
ud3tn-node
multipass launch 24.04 \
--name ud3tn-node \
--cpus 2 \
--memory 1G \
--disk 10G \
--timeout 1800 \
--network name=en0,mode=manual,mac="52:54:00:4b:ab:cf" \
--cloud-init configs/cloud-init/ud3tn.cloud-config.cfg- Interact with the VMs
Use the following commands to connect:
multipass shell ion-node
multipass shell ud3tn-node💡 Note: You can check assigned IPs using
ip ainside the VMs. Your cloud-init file should have configured static IP addresses (192.168.50.10 forion-nodeand 192.168.50.20 forud3tn-node) on interface enp0s1.
ud3tn-node
a) SSH into ud3tn-node and start the uD3TN process:
# SSH into ud3tn-node before
sudo -i
cd /opt/ud3tn/
build/posix/ud3tn \
--allow-remote-config \
--eid ipn:20.0 \
--aap2-socket ./ud3tn.aap2.socket.2 \
--cla "tcpclv3:*,4556" -L 4b) Then, in another terminal, add an outgoing contact to the ION node:
# SSH into ud3tn-node before
sudo -i
cd /opt/ud3tn/
source .venv/bin/activate
python3 tools/aap2/aap2_config.py \
--socket ./ud3tn.aap2.socket.2 \
--schedule 1 86400 100000 \
ipn:10.0 tcpclv3:192.168.50.10:4556ion-node
SSH into ion-node:
# SSH into ion-node before
sudo -i
# a) Start ION
cd /bp-socket/configs
export LD_LIBRARY_PATH="/usr/local/lib"
ionstart -I ./host.rc
# b) Build project
cd /bp-socket/
make
# c) Insert the bp.ko file and run the userspace daemon:
insmod /bp-socket/bp_socket/bp.ko
/bp-socket/daemon/bp_daemonThis section demonstrates bidirectional message exchange between ion-node and ud3tn-node by opening sockets from the custom AF_BP socket family.
ud3tn-node (receiver)
# SSH into ud3tn-node before
sudo -i
cd /opt/ud3tn/
source .venv/bin/activate
python3 tools/aap2/aap2_receive.py --agentid 2 --socket ./ud3tn.aap2.socket.2ion-node (sender)
# SSH into ion-node before
cd /bp-socket
gcc -o sender sender.c
./sender 20 2ion-node (receiver)
# SSH into ion-node before
cd /bp-socket
gcc -o receiver receiver.c
./receiver 10 2ud3tn-node (sender)
# SSH into ud3tn-node before
sudo -i
cd /opt/ud3tn/
source .venv/bin/activate
python3 tools/aap2/aap2_send.py --agentid 2 --socket ./ud3tn.aap2.socket.2 ipn:10.2 "Hello from ud3tn!" -v
