Transport Reference¶
Technical specifications for Kunuleco transport layers.
Transport Priority¶
There is no single priority list. The node uses one order to make first contact and
another to send over connections that already exist. Checked against the source on
2026-09-30. Paths are under src/kunuleco/.
First contact (join)¶
Each arm counts only when the peer's signed hello verifies and the host answers the join.
A connection with no verified hello, or a host that stays silent, moves the walk to the
next arm. transport disable <t> skips an arm, and transport force <t> skips every other
arm and the race.
join form |
Order | Source |
|---|---|---|
join <name#TAG> [presence] |
1. an existing LAN (mDNS) session · 2. Veilid · 3. Tor · 4. IPFS · 5. a race of every endpoint in the peer's record at once, first to connect wins (skipped when an earlier arm reached the host and the host stayed silent) | verbs/invite_system.py:1541, :1608, :1659, :1711, :1751 |
join <short-code> |
1. an existing LAN session · 2. Veilid · 3. Tor · 4. IPFS. No race | verbs/invite_system.py:1873, :1888, :1936, :1987 |
join <kunul1… seed> |
a race of the LAN addresses in the seed | verbs/unified_verbs.py:13495 |
The race starts every endpoint in the same pass (transport/connection_racer.py:129). The
endpoint priorities (private LAN address 1, Veilid 2, Tor 3, IPFS 4, public address 5) set
the order the attempts start in, not a wait between them, so the first endpoint to connect
wins whatever its priority.
Sending over an existing connection¶
No send path opens a new connection.
| What is sent | Order | Source |
|---|---|---|
tell / whisper, and the outbox flush |
1. the LAN (mDNS) session · 2. any other live CapTP session to that peer · 3. Tor · 4. Veilid · 5. the invite system's lookup, which checks LAN, Tor, Veilid, then IPFS. If the peer has no connected session, the message is queued in the outbox first | verbs/unified_verbs.py:3936, :3949, :3963, :3975, :3988; verbs/invite_system.py:1170; queueing at verbs/unified_verbs.py:229 |
| Speech in a presence, to remote members | 1. the LAN session · 2. the member's stored connection · 3. Tor · 4. Veilid. Tor leads Veilid because a Veilid route can accept a message and lose it | captp/message_router.py:2180, :2191, :2204, :2217; the reason at :2124 |
Other presence traffic (send_to_peer) |
1. any live CapTP session · 2. Tor · 3. Veilid | captp/message_router.py:2531, :2567, :2578 |
P2PCapTPBridge.send_via_best_transport (transport/veilid/bridge.py:4637, TCP, then
Veilid, then IPFS) is attached to the bridge but nothing calls it.
mDNS Transport¶
Service Definition¶
| Property | Value |
|---|---|
| Service Type | _kunuleco._tcp.local. |
| Port | 4243 (the CapTP port, set by KUNULECO_CAPTP_PORT) |
| Protocol | TCP |
Service TXT Records¶
All four keys are unsigned hints. The signed CapTP hello decides who the peer is.
| Key | Value |
|---|---|
identity |
Name#Discriminator |
version |
0.5.0 |
captp_port |
The CapTP port to dial (4243 by default) |
verify_key |
Hex-encoded Ed25519 verify key (omitted when the identity has none) |
Simultaneous Dials¶
Two peers that discover each other may both dial at once. The CapTP layer merges the two connections into one session.
Reconnection¶
- At most 8 LAN dials in flight
- Backoff after a failed dial: 10 s, doubling to 300 s
Veilid Transport¶
API Connection¶
| Property | Value |
|---|---|
| Host | localhost |
| Port | 15959 on an installed node, 5959 without a config file (see Configuration) |
| Protocol | JSON over HTTP |
Route Configuration¶
| Setting | Value |
|---|---|
| Refresh interval | 120 seconds (transport/veilid/__init__.py:27) |
| Stability | Reliable |
| Sequencing | EnsureOrdered |
| Hop count | Default |
Route Blob Format¶
Opaque binary blob (base64-encoded for transmission).
Message Operations¶
| Operation | Latency |
|---|---|
app_message (fire-and-forget) |
5-10ms |
app_call (round-trip) |
~183ms through CGNAT |
| Route import | 4-10ms |
Status Response¶
Tor Transport¶
Configuration¶
| Property | Value |
|---|---|
| SOCKS Port | 19050 (isolated) or 9050 (system) |
| Control Port | 19051 (isolated) or 9051 (system) |
| CapTP Port | 4243 |
Onion Service¶
| Property | Value |
|---|---|
| Version | 3 (v3 onion addresses) |
| Port | 80 (mapped to local 4243) |
| Persistence | Persistent (key stored) |
Key Storage¶
Authentication¶
Methods (in order of preference):
- Cookie authentication
- Password (via
TOR_CONTROL_PASSWORD) - No authentication (if enabled in torrc)
Status Response¶
IPFS Transport¶
API Connection¶
| Property | Value |
|---|---|
| Host | localhost |
| Port | 15001 (isolated) or 5001 (system) |
| Protocol | HTTP |
Required Configuration¶
P2P Protocol¶
| Property | Value |
|---|---|
| Protocol | /x/kunuleco/1.0.0 |
| Legacy | /x/kunuleco (cleaned on startup) |
Discovery PubSub¶
| Property | Value |
|---|---|
| Topic | kunuleco:discovery |
| Message Format | JSON |
Discovery Message¶
{
"type": "presence",
"peer_id": "QmYourPeerID...",
"identity": "Name#1234",
"timestamp": 1706640000
}
Connection Strategies¶
- Direct IP — If peer IP is known
- DHT Routing — Use IPFS DHT to find addresses
- Circuit Relay — NAT traversal via relay nodes
Port Summary¶
Default Configuration¶
| Service | Standard | Kunuleco Isolated |
|---|---|---|
| IPFS API | 5001 | 15001 |
| IPFS Swarm | 4001 | 14001 |
| IPFS Gateway | 8080 | 18080 |
| Veilid API | 5959 | 5959 |
| Tor SOCKS | 9050 | 19050 |
| Tor Control | 9051 | 19051 |
| Kunuleco CapTP | 4243 | 4243 |
Wire Protocol¶
All transports ultimately carry CapTP messages.
Framing¶
Messages are length-prefixed:
┌──────────────┬────────────────────────────┐
│ 4-byte len │ JSON payload │
│ (big-endian) │ │
└──────────────┴────────────────────────────┘
Health Check Endpoints¶
mDNS¶
No endpoint — health determined by service registration.
Veilid¶
IPFS¶
Tor¶
Control port connection with AUTHENTICATE command.