Branch:
experimental/brainz
Date: December 10, 2025
Scope: T-1200..T-1299
Status: 📋 Planned
Phase 12 adds optional, configurable security layers to protect users in adversarial environments—dissidents, journalists, activists in repressive regimes who need to safely and anonymously share files.
All features are:
- ✅ Optional — disabled by default, enabled via WebGUI settings
- ✅ Configurable — granular control over each layer
- ✅ Documented — clear explanations in UI and docs
- ✅ Non-breaking — existing users see no changes unless they opt in
| Adversary | Capabilities |
|---|---|
| ISP/Network Observer | Deep packet inspection, traffic analysis, IP logging |
| National Firewall (GFW-style) | Protocol fingerprinting, active probing, IP blocking |
| Law Enforcement | Subpoenas, device seizure, metadata correlation |
| Sybil Attackers | Flood DHT with fake peers, correlation attacks |
| Active Attackers | MITM, timing attacks, traffic injection |
| Goal | Description |
|---|---|
| IP Protection | Hide user's real IP from peers and observers |
| Traffic Obfuscation | Make mesh traffic indistinguishable from normal HTTPS |
| Metadata Protection | Prevent "who talked to whom when" correlation |
| Censorship Resistance | Bypass national firewalls and protocol blocking |
| Plausible Deniability | Cannot prove user has specific content/conversations |
┌─────────────────────────────────────────────────────────────────────────────┐
│ APPLICATION LAYER │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ PodCore │ │ MediaCore │ │ ChatBridge │ │ Scenes │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │ │
│ ┌──────┴────────────────┴────────────────┴────────────────┴──────┐ │
│ │ PRIVACY LAYER (NEW - Phase 12) │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ Padding │ │ Timing │ │ Batching │ │ │
│ │ │ (T-1210) │ │ (T-1211) │ │ (T-1212) │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │
│ └────────────────────────────┬───────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────┴───────────────────────────────────┐ │
│ │ ANONYMITY LAYER (NEW - Phase 12) │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ Direct │ │ Tor Proxy │ │ Onion Relay │ │ │
│ │ │ (existing) │ │ (T-1220) │ │ (T-1240) │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │
│ └────────────────────────────┬───────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────┴───────────────────────────────────┐ │
│ │ TRANSPORT LAYER (ENHANCED) │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ QUIC │ │WebSocket │ │ obfs4 │ │ Meek │ │ │
│ │ │(existing)│ │ (T-1230) │ │ (T-1232) │ │ (T-1233) │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ └────────────────────────────┬───────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────┴───────────────────────────────────┐ │
│ │ NETWORK LAYER (ENHANCED) │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ Direct │ │ Bridges │ │ Domain Front │ │ │
│ │ │ (existing) │ │ (T-1250) │ │ (T-1251) │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │
│ └────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
Purpose: Prevent message size fingerprinting.
Design:
public interface IMessagePadder
{
byte[] Pad(byte[] payload);
byte[] Unpad(byte[] padded);
}
public class BucketPadder : IMessagePadder
{
// Pad all messages to fixed bucket sizes
// Buckets: 512, 1024, 2048, 4096, 8192, 16384 bytes
// Padding bytes are random, not zeros (prevent compression attacks)
}Configuration:
adversarial:
privacy:
padding:
enabled: false # Default: disabled
buckets: [512, 1024, 2048, 4096, 8192, 16384]
random_fill: true # Use random bytes, not zerosWebGUI: Settings → Privacy → Message Padding
- Toggle: Enable padding
- Info tooltip: "Pads all messages to fixed sizes to prevent size-based fingerprinting"
Purpose: Prevent timing correlation attacks.
Design:
public interface ITimingObfuscator
{
Task DelayAsync(CancellationToken ct);
Task<T> WithJitterAsync<T>(Func<Task<T>> action, CancellationToken ct);
}
public class RandomJitterObfuscator : ITimingObfuscator
{
// Add random delay (0-500ms by default) to all sends
// Configurable min/max jitter
// Optional constant-rate cover traffic when idle
}Configuration:
adversarial:
privacy:
timing:
enabled: false
min_jitter_ms: 0
max_jitter_ms: 500
cover_traffic:
enabled: false # Send dummy messages when idle
interval_ms: 30000 # Every 30 secondsWebGUI: Settings → Privacy → Timing Protection
- Toggle: Enable timing jitter
- Sliders: Min/max delay (ms)
- Toggle: Cover traffic (advanced)
Purpose: Aggregate multiple messages to prevent frequency analysis.
Design:
public interface IMessageBatcher
{
void Enqueue(byte[] message, string destination);
Task FlushAsync(CancellationToken ct);
}
public class TimedBatcher : IMessageBatcher
{
// Hold messages for configurable window (e.g., 2 seconds)
// Send all accumulated messages in one batch
// Configurable max batch size and flush interval
}Configuration:
adversarial:
privacy:
batching:
enabled: false
flush_interval_ms: 2000
max_batch_size: 10Purpose: Route all mesh traffic through Tor for IP anonymization.
Design:
public interface IAnonymityTransport
{
Task<Stream> ConnectAsync(string host, int port, CancellationToken ct);
bool IsAvailable { get; }
string TransportName { get; }
}
public class TorSocksTransport : IAnonymityTransport
{
// Connect via local Tor SOCKS5 proxy (default: 127.0.0.1:9050)
// Support stream isolation via SOCKS5 auth
// Health check: verify Tor connectivity
}Configuration:
adversarial:
anonymity:
tor:
enabled: false
socks_host: "127.0.0.1"
socks_port: 9050
stream_isolation: true # Use different circuits per peer
require_tor: false # If true, fail if Tor unavailableWebGUI: Settings → Privacy → Tor Integration
- Toggle: Route traffic through Tor
- Input: SOCKS5 address/port
- Toggle: Require Tor (block if unavailable)
- Status indicator: Tor connectivity status
User Documentation:
## Using Tor with slskdn
Tor provides strong IP anonymization by routing traffic through multiple
relays. Each relay only knows the previous and next hop, so no single
point can see both your IP and your destination.
### Setup
1. Install Tor: `apt install tor` (Linux) or download Tor Browser
2. Ensure Tor SOCKS5 proxy is running (default: 127.0.0.1:9050)
3. Enable in slskdn: Settings → Privacy → Tor Integration
### Tradeoffs
- **Latency**: +200-500ms per connection
- **Throughput**: Lower than direct connections
- **Reliability**: Tor exit nodes may be blocked by some peers
### Recommendations
- Enable "Stream Isolation" for better anonymity
- Use bridges if Tor is blocked in your countryPurpose: Alternative anonymity network optimized for peer-to-peer.
Design:
public class I2PTransport : IAnonymityTransport
{
// Connect via I2P SAM bridge
// Create destinations for mesh identity
// Better suited for persistent connections than Tor
}Configuration:
adversarial:
anonymity:
i2p:
enabled: false
sam_host: "127.0.0.1"
sam_port: 7656
tunnel_length: 3 # Hops per directionPurpose: Never make direct connections; always go through relays.
Design:
public class RelayOnlyTransport : IAnonymityTransport
{
// All connections routed through trusted relay nodes
// Relay nodes are mesh peers volunteering bandwidth
// User never reveals IP to destination peer
}Configuration:
adversarial:
anonymity:
relay_only:
enabled: false
min_relays: 2 # Minimum hops
trusted_relays: [] # Optional: prefer specific relaysPurpose: Make mesh traffic look like normal web traffic.
Design:
public interface IObfuscatedTransport
{
Task<Stream> ConnectAsync(string peerId, CancellationToken ct);
string ProtocolName { get; }
}
public class WebSocketTransport : IObfuscatedTransport
{
// Establish WSS connection to peer/relay
// Looks like normal HTTPS to observers
// Can traverse most firewalls
}Configuration:
adversarial:
transport:
websocket:
enabled: false
path: "/ws/mesh" # WebSocket path
headers: # Custom headers to blend in
User-Agent: "Mozilla/5.0 ..."Purpose: Tunnel mesh protocol over HTTP POST/GET requests.
Design:
public class HttpTunnelTransport : IObfuscatedTransport
{
// Encode mesh messages as HTTP request/response bodies
// Long-polling or chunked transfer for bidirectional
// Looks like API traffic
}Purpose: Tor's obfuscation protocol for anti-DPI.
Design:
public class Obfs4Transport : IObfuscatedTransport
{
// Uses obfs4proxy binary (Tor Project)
// Traffic looks like random noise
// Resists active probing
}Configuration:
adversarial:
transport:
obfs4:
enabled: false
binary_path: "/usr/bin/obfs4proxy"
bridges: [] # obfs4 bridge linesWebGUI: Settings → Privacy → Obfuscated Transports
- Dropdown: Transport type (Direct, WebSocket, obfs4, Meek)
- Bridge configuration for obfs4
Purpose: Route through major CDNs to avoid blocking.
Design:
public class MeekTransport : IObfuscatedTransport
{
// HTTPS to CDN (Azure, Cloudflare, etc.)
// CDN forwards to actual relay
// Blocking requires blocking entire CDN
}Configuration:
adversarial:
transport:
meek:
enabled: false
front_domain: "ajax.aspnetcdn.com" # CDN domain
relay_url: "https://meek-relay.example.com/"Purpose: Build onion-routed circuits within the mesh network.
Design:
public interface ICircuitBuilder
{
Task<ICircuit> BuildCircuitAsync(
string targetPeerId,
int hopCount = 3,
CancellationToken ct = default);
}
public interface ICircuit : IAsyncDisposable
{
string CircuitId { get; }
IReadOnlyList<string> Hops { get; }
Task<byte[]> SendAsync(byte[] data, CancellationToken ct);
IAsyncEnumerable<byte[]> ReceiveAsync(CancellationToken ct);
}
public class MeshCircuitBuilder : ICircuitBuilder
{
// Select relay nodes from mesh peers with RelayCapability
// Build circuit: encrypt message in layers (like onion)
// Each relay unwraps one layer, forwards to next
// Only exit relay sees plaintext destination
}Circuit Construction:
User → Relay1 → Relay2 → Relay3 → Target
Encryption layers (innermost to outermost):
Layer 3 (for Relay3): {target, message}
Layer 2 (for Relay2): {relay3, encrypted_layer3}
Layer 1 (for Relay1): {relay2, encrypted_layer2}
Each relay:
1. Decrypts with its private key
2. Reads next hop
3. Forwards encrypted payload
Configuration:
adversarial:
onion:
enabled: false
default_hops: 3
circuit_lifetime_minutes: 10
relay_selection:
prefer_diverse_asn: true # Different ISPs
avoid_same_country: truePurpose: Allow mesh peers to volunteer as relay nodes.
Design:
public interface IRelayService
{
bool IsRelayEnabled { get; }
Task HandleRelayRequestAsync(RelayRequest request, CancellationToken ct);
}
public class MeshRelayService : IRelayService
{
// Process forwarding requests
// Rate limiting per source
// Bandwidth accounting
// No logging of forwarded content
}Configuration:
adversarial:
relay:
enabled: false # Volunteer as relay
max_bandwidth_mbps: 10
max_circuits: 100
allow_exit: false # Be exit relay (more risk)WebGUI: Settings → Privacy → Relay Node
- Toggle: Enable relay node
- Slider: Max bandwidth
- Warning: Legal implications of relay operation
Purpose: Intelligent relay selection for security.
Design:
public interface IRelaySelector
{
Task<IReadOnlyList<string>> SelectRelaysAsync(
int count,
RelaySelectionCriteria criteria,
CancellationToken ct);
}
public class DiverseRelaySelector : IRelaySelector
{
// Prefer relays in different:
// - Autonomous Systems (ASNs)
// - Countries/jurisdictions
// - Network segments
// Avoid relays controlled by same entity
// Use reputation scores
}Purpose: Unlisted entry points for users behind firewalls.
Design:
public interface IBridgeDiscovery
{
Task<IReadOnlyList<BridgeInfo>> GetBridgesAsync(CancellationToken ct);
}
public class BridgeInfo
{
public string Address { get; init; }
public int Port { get; init; }
public string Transport { get; init; } // "direct", "obfs4", "meek"
public string Fingerprint { get; init; } // For verification
public Dictionary<string, string> TransportParams { get; init; }
}Bridge Distribution:
- Out-of-band sharing (email, QR codes, word of mouth)
- BridgeDB-style web distribution with CAPTCHA
- Steganographic embedding in images (advanced)
Configuration:
adversarial:
bridges:
enabled: false
sources:
- type: "static"
bridges:
- "obfs4 192.0.2.1:443 fingerprint=abc123 cert=xyz..."
- type: "email"
address: "[email protected]"
- type: "web"
url: "https://bridges.slskdn.org/get"WebGUI: Settings → Privacy → Bridges
- Textarea: Paste bridge lines
- Button: Request bridges via email
- Info: How to get bridges
Purpose: Disguise mesh traffic as requests to major services.
Design:
public class DomainFrontedTransport : IObfuscatedTransport
{
// TLS SNI: ajax.aspnetcdn.com (or other CDN)
// HTTP Host header: mesh-relay.example.com
// CDN routes based on Host header
// Observer sees traffic to CDN, not actual destination
}Configuration:
adversarial:
transport:
domain_fronting:
enabled: false
front_domain: "ajax.aspnetcdn.com"
host_header: "mesh.slskdn.org"Note: Domain fronting effectiveness varies as CDN providers may block it.
Purpose: Hide bridge information in innocuous content.
Design:
public interface ISteganographyCodec
{
byte[] Encode(byte[] data, byte[] carrier);
byte[] Decode(byte[] carrier);
}
public class ImageSteganography : ISteganographyCodec
{
// Hide bridge info in image LSBs
// Looks like normal image
// Can be shared on social media
}Purpose: Hidden volumes that cannot be proven to exist.
Design:
public interface IDeniableStorage
{
Task<bool> VolumeExistsAsync(string passphrase);
Task<IKeyValueStore> OpenVolumeAsync(string passphrase, CancellationToken ct);
Task CreateVolumeAsync(string passphrase, long sizeBytes, CancellationToken ct);
}
public class DeniableVolumeStorage : IDeniableStorage
{
// Multiple passphrases reveal different volumes
// Outer volume: innocent content
// Hidden volume: sensitive pods/chats
// Cryptographically impossible to prove hidden volume exists
}Configuration:
adversarial:
deniability:
storage:
enabled: false
# Configured per-volume via secure setup wizardWebGUI: Settings → Privacy → Deniable Storage
- Wizard: Create outer/hidden volumes
- Warning: Backup passphrases securely
Purpose: Maintain innocent-looking pods alongside sensitive ones.
Design:
public class DecoyPodService
{
// Auto-generate/join harmless music pods
// Maintain realistic activity patterns
// Sensitive pods only visible with correct passphrase
}Design:
┌──────────────────────────────────────────────────────────────────────────────┐
│ Settings → Privacy & Security │
├──────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────────┐│
│ │ Security Level: ○ Standard ○ Enhanced ● Maximum ││
│ │ ││
│ │ Standard: Direct connections, no padding (fastest) ││
│ │ Enhanced: Tor routing, message padding (recommended for privacy) ││
│ │ Maximum: Full onion routing, timing protection, bridges (slowest) ││
│ └─────────────────────────────────────────────────────────────────────────┘│
│ │
│ ▼ Traffic Analysis Protection │
│ ┌─────────────────────────────────────────────────────────────────────────┐│
│ │ [✓] Message Padding [ Padding to fixed sizes prevents ] ││
│ │ Bucket sizes: 512, 1024, 2048, 4096, 8192 bytes ││
│ │ [ observers from inferring content ] ││
│ │ [✓] Timing Jitter [ from message sizes. ] ││
│ │ Delay: 0-500ms ││
│ │ ││
│ │ [ ] Cover Traffic (Advanced) ││
│ │ Send dummy messages when idle ││
│ └─────────────────────────────────────────────────────────────────────────┘│
│ │
│ ▼ IP Anonymization │
│ ┌─────────────────────────────────────────────────────────────────────────┐│
│ │ Transport: [Tor SOCKS5 ▼] ││
│ │ ││
│ │ Tor Settings: ││
│ │ SOCKS Address: [127.0.0.1 ] Port: [9050 ] ││
│ │ [✓] Stream Isolation (different circuit per peer) ││
│ │ [ ] Require Tor (block if unavailable) ││
│ │ ││
│ │ Status: ● Connected (circuit established) ││
│ └─────────────────────────────────────────────────────────────────────────┘│
│ │
│ ▼ Obfuscated Transports │
│ ┌─────────────────────────────────────────────────────────────────────────┐│
│ │ Primary Transport: [WebSocket (looks like web traffic) ▼] ││
│ │ ││
│ │ [ ] obfs4 (Tor-style obfuscation) ││
│ │ Bridges: ││
│ │ ┌──────────────────────────────────────────────────────────────┐ ││
│ │ │ obfs4 192.0.2.1:443 cert=... iat-mode=0 │ ││
│ │ │ │ ││
│ │ └──────────────────────────────────────────────────────────────┘ ││
│ │ [Request Bridges via Email] [Scan QR Code] ││
│ │ ││
│ │ [ ] Domain Fronting (Advanced) ││
│ │ Front domain: [ajax.aspnetcdn.com] ││
│ └─────────────────────────────────────────────────────────────────────────┘│
│ │
│ ▼ Relay Node (Help Others) │
│ ┌─────────────────────────────────────────────────────────────────────────┐│
│ │ [ ] Enable Relay Node ││
│ │ Volunteer bandwidth to help users in censored regions ││
│ │ ││
│ │ Max bandwidth: [10 ] Mbps ││
│ │ Max circuits: [100 ] ││
│ │ ││
│ │ ⚠ Running a relay may have legal implications in your jurisdiction ││
│ └─────────────────────────────────────────────────────────────────────────┘│
│ │
│ [Save] [Reset to Default]│
└──────────────────────────────────────────────────────────────────────────────┘
Design:
┌──────────────────────────────────────────────────────────────────────────────┐
│ Dashboard → Privacy Status │
├──────────────────────────────────────────────────────────────────────────────┤
│ │
│ Current Protection Level: [████████████████░░░░] 80% (Enhanced) │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ IP Hidden │ │ Traffic │ │ Timing │ │ Censorship │ │
│ │ ✓ │ │ Padded ✓ │ │ Jittered ✓ │ │ Resistant │ │
│ │ via Tor │ │ 512-8K │ │ 0-500ms │ │ ✗ │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ Recent Activity: │
│ ┌─────────────────────────────────────────────────────────────────────────┐│
│ │ 14:23:01 Circuit established via 3 relays (de→nl→us) ││
│ │ 14:22:58 Tor connection established ││
│ │ 14:22:55 Privacy layer initialized ││
│ └─────────────────────────────────────────────────────────────────────────┘│
│ │
│ Recommendations: │
│ ┌─────────────────────────────────────────────────────────────────────────┐│
│ │ ⚠ Consider enabling obfs4 bridges if Tor is unreliable in your region ││
│ │ ⚠ Cover traffic is disabled - timing attacks may be possible ││
│ └─────────────────────────────────────────────────────────────────────────┘│
└──────────────────────────────────────────────────────────────────────────────┘
# slskdn adversarial resilience configuration
# All features are OPTIONAL and DISABLED by default
adversarial:
# Master enable switch
enabled: false
# Quick presets (overrides individual settings)
# Options: "standard", "enhanced", "maximum", "custom"
preset: "standard"
# Privacy layer (traffic analysis protection)
privacy:
padding:
enabled: false
buckets: [512, 1024, 2048, 4096, 8192, 16384]
random_fill: true
timing:
enabled: false
min_jitter_ms: 0
max_jitter_ms: 500
cover_traffic:
enabled: false
interval_ms: 30000
batching:
enabled: false
flush_interval_ms: 2000
max_batch_size: 10
# Anonymity layer (IP protection)
anonymity:
mode: "direct" # "direct", "tor", "i2p", "relay_only"
tor:
enabled: false
socks_host: "127.0.0.1"
socks_port: 9050
stream_isolation: true
require_tor: false
i2p:
enabled: false
sam_host: "127.0.0.1"
sam_port: 7656
tunnel_length: 3
relay_only:
enabled: false
min_relays: 2
trusted_relays: []
# Obfuscated transports
transport:
primary: "quic" # "quic", "websocket", "http_tunnel", "obfs4", "meek"
websocket:
enabled: false
path: "/ws/mesh"
obfs4:
enabled: false
binary_path: "/usr/bin/obfs4proxy"
bridges: []
meek:
enabled: false
front_domain: ""
relay_url: ""
domain_fronting:
enabled: false
front_domain: ""
host_header: ""
# Native onion routing
onion:
enabled: false
default_hops: 3
circuit_lifetime_minutes: 10
relay_selection:
prefer_diverse_asn: true
avoid_same_country: true
# Relay node (volunteer)
relay:
enabled: false
max_bandwidth_mbps: 10
max_circuits: 100
allow_exit: false
# Bridges (censorship circumvention)
bridges:
enabled: false
sources: []
# Deniable storage
deniability:
storage:
enabled: falsepublic class AdversarialOptions
{
public bool Enabled { get; set; } = false;
public string Preset { get; set; } = "standard";
public PrivacyOptions Privacy { get; set; } = new();
public AnonymityOptions Anonymity { get; set; } = new();
public TransportOptions Transport { get; set; } = new();
public OnionOptions Onion { get; set; } = new();
public RelayOptions Relay { get; set; } = new();
public BridgeOptions Bridges { get; set; } = new();
public DeniabilityOptions Deniability { get; set; } = new();
}
public class PrivacyOptions
{
public PaddingOptions Padding { get; set; } = new();
public TimingOptions Timing { get; set; } = new();
public BatchingOptions Batching { get; set; } = new();
}
// ... (full class definitions in implementation)Timeline: 2 weeks
Dependencies: None
| Task | Description | Priority | Effort |
|---|---|---|---|
| T-1200 | Define AdversarialOptions configuration model | P1 | S |
| T-1201 | Implement IPrivacyLayer interface | P1 | S |
| T-1202 | Add adversarial section to WebGUI settings | P1 | M |
| T-1210 | Implement BucketPadder (message padding) | P1 | M |
| T-1211 | Implement RandomJitterObfuscator (timing) | P1 | M |
| T-1212 | Implement TimedBatcher (message batching) | P2 | M |
| T-1213 | Implement CoverTrafficGenerator | P3 | M |
| T-1214 | Integrate privacy layer with overlay messaging | P1 | M |
| T-1215 | Add privacy layer unit tests | P1 | M |
| T-1216 | Add privacy layer integration tests | P2 | M |
| T-1217 | Write privacy layer user documentation | P2 | S |
Timeline: 3 weeks
Dependencies: Phase 12A
| Task | Description | Priority | Effort |
|---|---|---|---|
| T-1220 | Implement TorSocksTransport | P1 | M |
| T-1221 | Implement I2PTransport | P3 | L |
| T-1222 | Implement RelayOnlyTransport | P2 | M |
| T-1223 | Add Tor connectivity status to WebGUI | P1 | S |
| T-1224 | Implement stream isolation | P2 | M |
| T-1225 | Add anonymity transport selection logic | P1 | M |
| T-1226 | Integrate with MeshTransportService | P1 | M |
| T-1227 | Add Tor integration tests | P1 | M |
| T-1228 | Write Tor setup documentation | P1 | M |
| T-1229 | Add I2P setup documentation | P3 | S |
Timeline: 3 weeks
Dependencies: Phase 12B
| Task | Description | Priority | Effort |
|---|---|---|---|
| T-1230 | Implement WebSocketTransport | P1 | M |
| T-1231 | Implement HttpTunnelTransport | P2 | M |
| T-1232 | Implement Obfs4Transport | P2 | L |
| T-1233 | Implement MeekTransport | P3 | L |
| T-1234 | Add transport selection WebGUI | P1 | M |
| T-1235 | Implement transport fallback logic | P1 | M |
| T-1236 | Add obfuscated transport tests | P1 | M |
| T-1237 | Write obfuscation user documentation | P2 | M |
| T-1238 | Add transport performance benchmarks | P3 | M |
Timeline: 4 weeks
Dependencies: Phase 12C
| Task | Description | Priority | Effort |
|---|---|---|---|
| T-1240 | Implement MeshCircuitBuilder | P2 | XL |
| T-1241 | Implement MeshRelayService | P2 | L |
| T-1242 | Implement DiverseRelaySelector | P2 | M |
| T-1243 | Add relay node WebGUI controls | P2 | M |
| T-1244 | Implement circuit keepalive and rotation | P2 | M |
| T-1245 | Add relay bandwidth accounting | P2 | M |
| T-1246 | Add onion routing unit tests | P2 | L |
| T-1247 | Add onion routing integration tests | P2 | L |
| T-1248 | Write relay operator documentation | P2 | M |
| T-1249 | Add circuit visualization to WebGUI | P3 | M |
Timeline: 2 weeks
Dependencies: Phase 12C
| Task | Description | Priority | Effort |
|---|---|---|---|
| T-1250 | Implement BridgeDiscovery service | P1 | M |
| T-1251 | Implement DomainFrontedTransport | P2 | M |
| T-1252 | Implement ImageSteganography (bridge distribution) | P3 | L |
| T-1253 | Add bridge configuration WebGUI | P1 | M |
| T-1254 | Implement bridge health checking | P2 | S |
| T-1255 | Add bridge fallback logic | P2 | M |
| T-1256 | Write bridge setup documentation | P1 | M |
| T-1257 | Add censorship resistance tests | P2 | M |
Timeline: 3 weeks
Dependencies: Phase 12E
| Task | Description | Priority | Effort |
|---|---|---|---|
| T-1260 | Implement DeniableVolumeStorage | P3 | XL |
| T-1261 | Implement DecoyPodService | P3 | M |
| T-1262 | Add deniable storage setup wizard | P3 | L |
| T-1263 | Implement volume passphrase handling | P3 | M |
| T-1264 | Add deniability unit tests | P3 | M |
| T-1265 | Write deniability user documentation | P3 | M |
Timeline: 2 weeks
Dependencies: All previous
| Task | Description | Priority | Effort |
|---|---|---|---|
| T-1270 | Implement Privacy Settings panel | P1 | L |
| T-1271 | Implement Privacy Dashboard | P2 | M |
| T-1272 | Add security preset selector | P1 | M |
| T-1273 | Implement real-time status indicators | P2 | M |
| T-1274 | Add privacy recommendations engine | P3 | M |
| T-1275 | Integrate all layers with existing systems | P1 | L |
| T-1276 | Add end-to-end privacy tests | P1 | L |
| T-1277 | Write comprehensive user guide | P1 | L |
| T-1278 | Create threat model documentation | P2 | M |
| T-1279 | Add privacy audit logging (opt-in) | P3 | M |
Timeline: 2 weeks
Dependencies: All previous
| Task | Description | Priority | Effort |
|---|---|---|---|
| T-1290 | Create adversarial test scenarios | P1 | L |
| T-1291 | Implement traffic analysis resistance tests | P2 | M |
| T-1292 | Add censorship simulation tests | P2 | M |
| T-1293 | Performance benchmarking suite | P2 | M |
| T-1294 | Security review and audit | P1 | L |
| T-1295 | Write operator guide (relay/bridge) | P2 | M |
| T-1296 | Create video tutorials | P3 | L |
| T-1297 | Add localization for privacy UI | P3 | M |
| T-1298 | Final integration testing | P1 | L |
| T-1299 | Phase 12 release notes | P1 | S |
| Risk | Impact | Mitigation |
|---|---|---|
| Tor blocked in target region | Users can't connect | Bridges, obfs4, meek fallback |
| Performance degradation | User experience | Presets with clear tradeoffs, benchmarks |
| Legal issues for relay operators | Operator liability | Clear documentation, exit policy controls |
| Deniable storage complexity | Data loss, UX issues | Wizard-based setup, strong warnings |
| Traffic analysis still possible | Privacy leak | Multiple layers, cover traffic |
| Domain fronting blocked by CDN | Censorship circumvention fails | Multiple front domains, fallback |
- Usability: Users can enable privacy features with 3 clicks (preset selection)
- Security: Traffic from "Maximum" preset indistinguishable from HTTPS noise
- Performance: "Enhanced" preset adds <500ms latency to connections
- Reliability: All transports have >95% connection success rate
- Documentation: Complete user guides for each protection level
The signal system enables reliable, multi-channel control signaling between slskdn peers, supporting both Mesh and BitTorrent extension channels with automatic deduplication and fallback.
Key Features:
- Multi-channel delivery (Mesh primary, BT extension secondary)
- Automatic deduplication via
SignalId - Channel fallback when primary channel fails
- Optional acknowledgment pattern for critical signals
- Extensible type system for domain-specific signals
Use Cases:
- Swarm control signals (e.g.,
Swarm.RequestBtFallback) - Pod membership updates (
Pod.MembershipUpdate) - Variant opinion updates (
Pod.VariantOpinionUpdate) - Job cancellation (
Swarm.JobCancel)
┌─────────────────────────────────────────────────────────────┐
│ Application Layer │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │SwarmCore │ │ PodCore │ │MediaCore │ │Security │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │ │
│ └─────────────┴─────────────┴─────────────┘ │
│ │ │
│ ┌─────▼─────┐ │
│ │ SignalBus │ │
│ │ (T-1280) │ │
│ └─────┬─────┘ │
│ │ │
│ ┌───────────────────┴───────────────────┐ │
│ │ │ │
│ ┌────▼──────────┐ ┌───────▼──────┐ │
│ │ Mesh Channel │ │ BT Extension │ │
│ │ Handler │ │ Handler │ │
│ │ (T-1281) │ │ (T-1282) │ │
│ └───────────────┘ └──────────────┘ │
│ │ │ │
│ └───────────────────┬───────────────────┘ │
│ │ │
│ ┌──────▼──────┐ │
│ │ MeshCore │ │
│ │ BitTorrent │ │
│ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
Core Signal Type:
sealed class Signal
{
public string SignalId { get; } // ULID/UUID for deduplication
public string FromPeerId { get; } // slskdn Mesh PeerId
public string ToPeerId { get; } // Target PeerId
public DateTimeOffset SentAt { get; }
public string Type { get; } // e.g. "Swarm.RequestBtFallback"
public IReadOnlyDictionary<string, object> Body { get; }
public TimeSpan Ttl { get; }
public IReadOnlyList<SignalChannel> PreferredChannels { get; }
}
enum SignalChannel
{
Mesh, // Primary control plane
BtExtension, // Secondary via BT extension protocol
Direct // Direct peer-to-peer (future)
}Example Signal Types:
| Type | Purpose | Ack Required | Channels |
|---|---|---|---|
Swarm.RequestBtFallback |
Request BT fallback for failed transfer | Yes | Mesh, BtExtension |
Swarm.RequestBtFallbackAck |
Acknowledge BT fallback request | No | Mesh, BtExtension |
Swarm.JobCancel |
Cancel a swarm job | Yes | Mesh |
Pod.MembershipUpdate |
Update pod membership | No | Mesh |
Pod.VariantOpinionUpdate |
Update variant preference | No | Mesh |
Purpose: Central signal routing and deduplication service.
Tasks:
- Define
ISignalBusinterface withSendAsyncandSubscribeAsync - Implement
SignalBuswith LRU cache forSignalIddeduplication - Add signal type registry for validation
- Implement timeout handling for pending signals
- Add metrics/logging for signal delivery success/failure
Dependencies: None (foundational)
Estimated Effort: M (Medium)
Purpose: Deliver signals over Mesh overlay network.
Tasks:
- Implement
MeshSignalChannelHandler : ISignalChannelHandler - Wrap
SignalintoslskdnSignalMesh message envelope - Route via
MeshCoreto targetPeerId - Handle inbound
slskdnSignalmessages and forward toSignalBus - Implement
CanSendTo(PeerId)check for Mesh availability
Dependencies: T-1280 (SignalBus), MeshCore (Phase 8)
Estimated Effort: M (Medium)
Purpose: Deliver signals over BitTorrent extension protocol.
Tasks:
- Implement
BtExtensionSignalChannelHandler : ISignalChannelHandler - Serialize
Signalto CBOR/JSON - Wrap into
slskdnExtensionMessagewithKind = SignalEnvelope - Send via BT extension message ID
"slskdn" - Subscribe to inbound BT extension messages and deserialize to
Signal - Implement
CanSendTo(PeerId)check for active BT session
Dependencies: T-1280 (SignalBus), BitTorrentBackend (Phase 8)
Estimated Effort: M (Medium)
Purpose: Implement canonical BT fallback request signal.
Tasks:
- Define
Swarm.RequestBtFallbacksignal type and body schema - Implement sender in
SwarmCore(trigger on repeated transfer failures) - Implement receiver handler in
SwarmCore(validate, check security, prepare torrent) - Define and implement
Swarm.RequestBtFallbackAckacknowledgment - Add sender-side ack handling and timeout logic
- Add WebGUI toggle for BT fallback feature
Dependencies: T-1280, T-1281, T-1282, SwarmCore, SecurityCore
Estimated Effort: L (Large)
Reference: See docs/design/signal-request-bt-fallback.md for complete specification.
Purpose: Implement additional signal types for Pod and Swarm control.
Tasks:
Swarm.JobCancel- Cancel swarm job with ackPod.MembershipUpdate- Broadcast pod membership changesPod.VariantOpinionUpdate- Share variant preferencesSwarm.TransferProgress- Optional progress updates (low priority)
Dependencies: T-1280, T-1281, PodCore (Phase 10)
Estimated Effort: L (Large)
Purpose: Comprehensive test coverage for signal system.
Tasks:
- Unit tests for
SignalBusdeduplication and routing - Unit tests for channel handlers (Mesh and BT)
- Integration tests for
Swarm.RequestBtFallbackend-to-end - Test channel fallback behavior (Mesh fails, BT succeeds)
- Test ack timeout and retry logic
- Performance tests for high signal volume
Dependencies: T-1280, T-1281, T-1282, T-1283
Estimated Effort: M (Medium)
WebGUI Settings:
SignalSystem:
Enabled: true # Enable signal system
DeduplicationCacheSize: 10000 # LRU cache size for SignalIds
DefaultTtl: "00:05:00" # Default signal TTL
MeshChannel:
Enabled: true
Priority: 1 # Primary channel
BtExtensionChannel:
Enabled: true
Priority: 2 # Secondary channel
RequireActiveSession: true # Only use if BT session existsSecurity Considerations:
- Signals are not encrypted by default (rely on Mesh/BT encryption)
- For adversarial environments, enable Mesh encryption (Phase 12)
- Signal
Bodyshould not contain sensitive data (use references/IDs) SignalIdshould be cryptographically random (ULID recommended)
Document Version: 1.0
Last Updated: December 10, 2025
Author: slskdn development team