Flow Allocation vs TLS
OAP vs TCP+TLS 1.3 and UDP+DTLS 1.3: An Architectural Comparison
- Disclaimer: This page was generated by CoPilot / Anthropic Claude Opus 4.5 based on the source code (v0.22) and the [tutorial].**
This document provides a comprehensive architectural comparison between Ouroboros flow allocation with authentication (OAP) and traditional approaches using TCP with TLS 1.3 or UDP with DTLS 1.3.
The Ouroboros architecture demonstrates that secure network communication can be achieved with dramatically simpler application code and centralized policy enforcement. Even without session resumption, OAP's 1-RTT handshake is competitive with TLS 1.3's 2.5-RTT (or 2-RTT with 0-RTT resumption), while providing stronger security guarantees (fresh keys on every connection, no replay-vulnerable early data). This comes at the cost of ecosystem maturity and (currently) cryptographic flexibility.
1. Application Code Burden
Ouroboros
Application code for a secure authenticated connection:
/* Client - entire secure connection establishment */
int fd = flow_alloc("server_name", NULL, NULL);
if (fd < 0)
return -1; /* Authentication or allocation failed */
/* Connection is now authenticated and encrypted */
flow_write(fd, data, len);
flow_read(fd, buffer, sizeof(buffer));
flow_dealloc(fd);
/* Server - entire secure connection acceptance */
int fd = flow_accept(NULL, NULL);
if (fd < 0)
return -1; /* Authentication or acceptance failed */
/* Connection is now authenticated and encrypted */
flow_read(fd, buffer, sizeof(buffer));
flow_write(fd, response, resp_len);
flow_dealloc(fd);
TCP + TLS 1.3
Equivalent functionality (simplified, error handling abbreviated):
/* Client - TCP + TLS setup */
int sock = socket(AF_INET, SOCK_STREAM, 0);
connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr));
SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
SSL_CTX_load_verify_locations(ctx, "ca-cert.pem", NULL);
SSL_CTX_use_certificate_file(ctx, "client-cert.pem", SSL_FILETYPE_PEM);
SSL_CTX_use_PrivateKey_file(ctx, "client-key.pem", SSL_FILETYPE_PEM);
SSL *ssl = SSL_new(ctx);
SSL_set_fd(ssl, sock);
SSL_connect(ssl);
/* Now authenticated and encrypted */
SSL_write(ssl, data, len);
SSL_read(ssl, buffer, sizeof(buffer));
SSL_shutdown(ssl);
SSL_free(ssl);
SSL_CTX_free(ctx);
close(sock);
/* Server - TCP + TLS setup */
int listen_sock = socket(AF_INET, SOCK_STREAM, 0);
bind(listen_sock, (struct sockaddr*)&addr, sizeof(addr));
listen(listen_sock, 5);
int client_sock = accept(listen_sock, NULL, NULL);
SSL_CTX *ctx = SSL_CTX_new(TLS_server_method());
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
SSL_CTX_load_verify_locations(ctx, "ca-cert.pem", NULL);
SSL_CTX_use_certificate_file(ctx, "server-cert.pem", SSL_FILETYPE_PEM);
SSL_CTX_use_PrivateKey_file(ctx, "server-key.pem", SSL_FILETYPE_PEM);
SSL *ssl = SSL_new(ctx);
SSL_set_fd(ssl, client_sock);
SSL_accept(ssl);
/* Now authenticated and encrypted */
SSL_read(ssl, buffer, sizeof(buffer));
SSL_write(ssl, response, resp_len);
SSL_shutdown(ssl);
SSL_free(ssl);
SSL_CTX_free(ctx);
close(client_sock);
Comparison
| Aspect | Ouroboros | TCP+TLS 1.3 / UDP+DTLS 1.3 |
|---|---|---|
| Lines of security code | 0 | 15-30+ |
| Certificate path management | System handles | Application specifies |
| Socket creation | Not needed | Required |
| Protocol selection | Automatic | Application choice |
| Verification setup | Automatic | Application responsibility |
| Cleanup complexity | Single call | Multiple cleanup calls |
2. Configuration Management
Ouroboros: Filesystem-Based Configuration
/etc/ouroboros/security/ ├── cacert/ # Trusted CA certificates │ └── myca.pem ├── untrusted/ # Revoked certificates ├── server/ # Server identities │ └── oping/ # Per-application │ ├── cert # X.509 certificate (any type) │ └── key # Private key ├── client/ # Client identities │ └── testuser/ # Per-principal │ ├── cert │ └── key └── enc.cfg # Enables encryption (presence = enabled)
Prototype Behavior:
- No credentials for an identity → authentication disabled for that identity
- Credentials present → authentication and encryption enabled
enc.cfgpresent → encrypted communication (currently PoC behavior)- Future:
enc.cfgwill support configuration options includingdisabledstanza
Certificate flexibility:
- Any X.509 certificate type works (RSA, ECDSA, EdDSA, etc.)
- Only the key exchange and symmetric crypto are currently hardcoded
- Authentication signature is based on the certificate's key type
TLS/DTLS: Application-Embedded Configuration
Each application must handle:
- Certificate file paths
- Private key file paths
- CA certificate paths
- Cipher suite selection
- Protocol version constraints
- Certificate verification callbacks
- Hostname verification
- Session caching configuration
Comparison
| Aspect | Ouroboros | TLS/DTLS |
|---|---|---|
| Configuration location | Centralized filesystem | Per-application |
| Security policy changes | Single point | Update all applications |
| Credential rotation | Replace files (hot reload) | Application restart often needed |
| Misconfiguration risk | Low (minimal options) | High (many options) |
| Default security | Secure by default | Depends on application |
| Auditability | Single location | Distributed across apps |
3. Network Efficiency
Handshake Comparison
OAP (1 RTT):
Client Server | | |-------- FLOW_REQ + OAP header ------------------> | | [ID, timestamp, certificate, ECDHE pubkey, | | optional data, signature] | | | |<------- FLOW_REPLY + OAP header ----------------- | | [ID, timestamp, certificate, ECDHE pubkey, | | optional data, signature] | | | |========= Encrypted data can flow ================ | | | Total: 1 RTT
TCP + TLS 1.3 (2.5 RTT):
Client Server | | |-------- TCP SYN ------------------------------> | \ |<------- TCP SYN-ACK -------------------------- | } TCP: 1.5 RTT |-------- TCP ACK ------------------------------> | / | | |-------- ClientHello --------------------------> | \ |<------- ServerHello, EncryptedExtensions, | | | Certificate, CertificateVerify, Finished | } TLS: 1 RTT |-------- Certificate, CertificateVerify, Finished | | | | / |========= Encrypted data can flow =============== | Total: 2.5 RTT (1.5 TCP + 1 TLS 1.3)
UDP + DTLS 1.3 (1-2 RTT):
Client Server | | |-------- ClientHello --------------------------> | \ |<------- HelloRetryRequest (optional, anti-DoS) | } 0-1 RTT (cookie) |-------- ClientHello + cookie -----------------> | / | | |<------- ServerHello, EncryptedExtensions, | \ | Certificate, CertificateVerify, Finished | } 1 RTT |-------- Certificate, CertificateVerify, Finished | / | | |========= Encrypted data can flow =============== | Total: 1-2 RTT (depending on HelloRetryRequest)
RTT Summary
| Protocol | RTT Count | Notes |
|---|---|---|
| OAP | 1 | Fixed, no optimization needed |
| TCP + TLS 1.3 | 2.5 | 1.5 (TCP) + 1 (TLS 1.3) |
| TCP + TLS 1.3 (0-RTT) | 2 | Requires previous session, replay-vulnerable early data |
| UDP + DTLS 1.3 | 1-2 | Depends on HelloRetryRequest |
Session Resumption and 0-RTT
TLS 1.3 0-RTT:
- Requires previous session ticket
- Early data (0-RTT data) is replay-vulnerable by design
- Not suitable for non-idempotent operations
- Only saves 0.5 RTT (2 RTT instead of 2.5 RTT for TCP+TLS)
- Session tickets have expiry (implementation-dependent, often 1 week)
Ouroboros:
- No session resumption mechanism currently
- Fresh key exchange on every connection
- Every connection has full forward secrecy
- No replay-vulnerable early data window
| Aspect | TLS 1.3 0-RTT | OAP + FRCT resumption |
|---|---|---|
| RTT saved | 0.5 RTT | N/A (already 1 RTT) |
| Replay protection | No (for early data) | Yes (fresh keys) |
| Forward secrecy | Reduced (for 0-RTT data) | Full |
| State management | Session tickets | Delta-t connection records |
| Expiry handling | Ticket expiration | Timer-based |
Data Piggybacking
Both OAP and TLS 1.3 allow data in the initial handshake:
| Protocol | Client first data | Server first data |
|---|---|---|
| OAP | In FLOW_REQ (authenticated) | In FLOW_REPLY (authenticated) |
| TLS 1.3 | After ClientHello complete | In first encrypted record |
| TLS 1.3 0-RTT | In 0-RTT data (replay-vulnerable) | In first encrypted record |
4. Security Properties
Authentication Model
| Property | Ouroboros | TLS 1.3 / DTLS 1.3 |
|---|---|---|
| Authentication binding | Certificate → Flow name mapping | Certificate → Hostname |
| Mutual authentication | Always (when configured) | Optional, often skipped |
| Certificate validation | Automatic, enforced | Application responsibility |
| Hostname verification | Automatic | Application must implement |
Cryptographic Properties
| Property | Ouroboros (current) | TLS 1.3 / DTLS 1.3 |
|---|---|---|
| Key exchange | ECDHE P-384 (hardcoded) | Negotiated (ECDHE, X25519, etc.) |
| Encryption | AES-256-GCM (hardcoded) | Negotiated cipher suite |
| Hash/MAC | SHA-384 (hardcoded) | Part of cipher suite |
| Forward secrecy | Always (ephemeral keys) | Always (TLS 1.3 requirement) |
| Cipher negotiation | No (simplifies attack surface) | Yes (flexibility) |
| Downgrade attacks | Impossible (no negotiation) | Possible (mitigated) |
| Certificate signing | Any type (RSA, ECDSA, EdDSA) | Any type |
Note: The hardcoded cryptography is a proof-of-concept decision. Future versions will support configuration through enc.cfg while maintaining the single-RTT negotiation.
Trust Model
Ouroboros:
┌─────────────────────────────────────────────────────────────┐
│ /etc/ouroboros/security/ │
│ ┌─────────┐ ┌────────────┐ ┌────────┐ ┌───────────────┐ │
│ │ cacert/ │ │ untrusted/ │ │server/ │ │ client/ │ │
│ │ (CAs) │ │ (revoked) │ │(server)│ │ (client) │ │
│ └─────────┘ └────────────┘ └────────┘ └───────────────┘ │
│ System Administrator Control │
└─────────────────────────────────────────────────────────────┘
│
▼
All applications use same trust store
TLS/DTLS:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ App 1 │ │ App 2 │ │ App 3 │
│ Trust Store │ │ Trust Store │ │ Trust Store │
│ + Cfg │ │ + Cfg │ │ + Cfg │
└─────────────┘ └─────────────┘ └─────────────┘
May differ May differ May differ
5. Architectural Separation
Ouroboros: Complete Separation
┌────────────────────────────────────────────────────────────────────────┐
│ APPLICATION LAYER │
│ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ Application │ │
│ │ (oping, oecho, custom application) │ │
│ │ │ │
│ │ • Uses flow_alloc() / flow_accept() only │ │
│ │ • No network addressing knowledge │ │
│ │ • No security code │ │
│ │ • No transport selection │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │
│ flow_alloc() │ flow_accept() │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ Library Layer │ │
│ │ │ │
│ │ • FRCT (reliability, retransmission, flow control) │ │
│ │ • Encryption context (receives key from IRMd) │ │
│ │ • Flow state (survives IPCP restarts) │ │
│ └──────────────────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────────────────┘
│
│ IPC via IRMd
▼
┌────────────────────────────────────────────────────────────────────────┐
│ NETWORK LAYER (IRMd) │
│ │
│ • Flow allocation/acceptance │
│ • OAP authentication and key exchange │
│ • Certificate verification │
│ • IPCP selection │
└────────────────────────────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────────────┐
│ IPCP LAYER │
│ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ local │ │ eth-llc │ │ udp │ │ unicast │ │
│ └────────────┘ └────────────┘ └────────────┘ └────────────┘ │
│ │
│ Each IPCP handles its transport technology independently │
│ • Name-to-address resolution │
│ • routing │
└────────────────────────────────────────────────────────────────────────┘
TCP+TLS: Mixed Responsibilities
┌────────────────────────────────────────────────────────────────────────┐
│ APPLICATION │
│ │
│ • Socket creation and management │
│ • Address resolution (DNS) │
│ • Connection management │
│ • TLS context setup │
│ • Certificate management │
│ • Hostname verification │
│ • Protocol selection (TCP vs UDP) │
│ • Error handling for all layers │
│ │
└────────────────────────────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────────────┐
│ TLS LIBRARY │
│ • Handshake state machine │
│ • Certificate verification │
│ • Cipher negotiation │
│ • Record encryption/decryption │
└────────────────────────────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────────────┐
│ KERNEL (TCP/UDP) │
│ • Connection management │
│ • Reliability (TCP only) │
│ • Flow control │
└────────────────────────────────────────────────────────────────────────┘
6. Transport Independence
Ouroboros
/* Same application code works over ANY transport */
int fd = flow_alloc("server_name", NULL, NULL);
/* This might flow over:
* - local (shared memory)
* - eth-llc (raw Ethernet)
* - eth-dix (Ethernet DIX)
* - udp (UDP/IP overlay)
* - unicast (recursive network)
*
* Application doesn't know and doesn't care.
* IPCP can be restarted without breaking the flow (FRCT in library).
*/
TCP+TLS / UDP+DTLS
/* Must choose transport at coding time */
/* Option 1: TCP (reliable, ordered) */
int sock = socket(AF_INET, SOCK_STREAM, 0);
SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
/* Option 2: UDP (unreliable, unordered) - different code path */
int sock = socket(AF_INET, SOCK_DGRAM, 0);
SSL_CTX *ctx = SSL_CTX_new(DTLS_client_method());
/* Plus: Handle packet loss, reordering, MTU discovery... */
/* Cannot switch transports without code changes */
/* Cannot use shared memory, raw Ethernet, etc. */
Comparison
| Aspect | Ouroboros | TCP+TLS / UDP+DTLS |
|---|---|---|
| Transport selection | Runtime (automatic) | Compile-time |
| Code changes for new transport | None | Significant |
| Shared memory optimization | Automatic (local IPCP) | Not possible |
| Raw Ethernet support | Automatic (eth-* IPCP) | Requires new code |
| Multi-path | IPCP handles | Application complexity |
7. Credential Management
Hot Reload Capability
Ouroboros:
# Update server certificate (no application restart needed)
$ cp new-cert.pem /etc/ouroboros/security/server/myapp/cert
$ cp new-key.pem /etc/ouroboros/security/server/myapp/key
# New connections immediately use new credentials
# Existing connections continue with old credentials until closed
TLS/DTLS:
/* Application must implement reload mechanism */
void reload_certificates(SSL_CTX *ctx) {
/* Thread-safety considerations */
pthread_mutex_lock(&ctx_lock);
/* Clear existing certificates */
SSL_CTX_clear_chain_certs(ctx);
/* Load new certificates */
SSL_CTX_use_certificate_file(ctx, "new-cert.pem", SSL_FILETYPE_PEM);
SSL_CTX_use_PrivateKey_file(ctx, "new-key.pem", SSL_FILETYPE_PEM);
pthread_mutex_unlock(&ctx_lock);
}
/* Need signal handler or file watcher */
void sighandler(int sig) {
reload_certificates(global_ctx);
}
Comparison
| Aspect | Ouroboros | TLS/DTLS |
|---|---|---|
| Hot reload | Built-in (filesystem watch) | Application-implemented |
| Application awareness | None needed | Full implementation required |
| Thread safety | System handles | Application responsibility |
| Rollback | Replace files | Application logic |
8. Auditability and Logging
Centralized vs Distributed
Ouroboros:
IRMd logs (single location): - Flow allocation requests - Authentication attempts (success/failure) - Certificate verification results - Key exchange completion - Flow deallocation Single audit point for: - All applications - All authentication events - All connection events
TLS/DTLS:
Per-application logging: - Application 1: own log format, location, verbosity - Application 2: different log format, location, verbosity - Application 3: might not log security events at all Audit requires: - Collecting logs from all applications - Normalizing different formats - Correlating events - Hoping all apps actually log
Comparison
| Aspect | Ouroboros | TLS/DTLS |
|---|---|---|
| Log location | Single (IRMd) | Per-application |
| Log format | Consistent | Varies |
| Coverage guarantee | All connections logged | Depends on application |
| Correlation | Built-in | Requires external tools |
| Compliance demonstration | Straightforward | Complex |
9. Error Handling
Ouroboros
/* All errors collapsed into simple return values */
int fd = flow_alloc("server", NULL, NULL);
if (fd < 0) {
/* Could be: name not found, network unreachable,
* authentication failed, peer rejected, timeout.
* Application typically just reports failure. */
perror("flow_alloc");
return -1;
}
/* Flow read/write errors */
ssize_t n = flow_read(fd, buf, sizeof(buf));
if (n < 0) {
/* Flow error - handle like any I/O error */
return -1;
}
TLS/DTLS
/* Multiple error sources, each requiring different handling */
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) { /* Socket creation failed */ }
if (connect(sock, addr, len) < 0) { /* TCP connection failed */ }
SSL *ssl = SSL_new(ctx);
if (!ssl) { /* SSL object creation failed */ }
if (SSL_set_fd(ssl, sock) != 1) { /* SSL fd assignment failed */ }
int ret = SSL_connect(ssl);
if (ret != 1) {
int err = SSL_get_error(ssl, ret);
switch (err) {
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
/* Non-blocking, need to retry */
break;
case SSL_ERROR_SYSCALL:
/* Check errno */
break;
case SSL_ERROR_SSL:
/* Protocol error, check error queue */
break;
/* ... many more cases ... */
}
}
/* Certificate verification is separate check */
X509 *cert = SSL_get_peer_certificate(ssl);
if (!cert) { /* No certificate provided */ }
long verify_result = SSL_get_verify_result(ssl);
if (verify_result != X509_V_OK) {
/* Certificate verification failed - many possible reasons */
}
/* Check certificate hostname (application responsibility) */
if (!verify_hostname(cert, expected_hostname)) {
/* Hostname mismatch */
}
Error categories to handle:
- Socket errors
- TCP connection errors
- SSL object creation errors
- SSL handshake errors (multiple types)
- Certificate verification errors
- Hostname verification errors
- SSL read/write errors (multiple types)
Comparison
| Aspect | Ouroboros | TCP+TLS / UDP+DTLS |
|---|---|---|
| Error types application handles | 2 (alloc, I/O) | 10+ |
| Certificate verification | Automatic | Application responsibility |
| Hostname verification | Automatic | Application responsibility |
| Non-blocking complexity | Standard | SSL_ERROR_WANT_* handling |
| Error recovery logic | Simple | Complex state machine |
10. Attack Surface
Cipher Downgrade and Negotiation Attacks
| Attack | Ouroboros | TLS/DTLS |
|---|---|---|
| Cipher downgrade | Impossible (no negotiation) | Possible, mitigated |
| Version rollback | N/A | Possible, mitigated |
| POODLE-style attacks | N/A | Historically vulnerable |
| Logjam (weak DH) | N/A (uses ECDHE P-384) | Required protocol fixes |
Implementation Complexity
| Component | Ouroboros | OpenSSL |
|---|---|---|
| Protocol state machine | Simple (2-message exchange) | Complex (many states) |
| Cipher implementations | One set | Many (for negotiation) |
| Legacy compatibility code | None | Extensive |
| Alert handling | Minimal | Complex |
| Extension handling | None (future: minimal) | Extensive |
Application Misconfiguration
| Risk | Ouroboros | TLS/DTLS |
|---|---|---|
| Weak cipher selection | Not possible (system policy) | Common misconfiguration |
| Disabled certificate verification | Not possible | SSL_VERIFY_NONE is easy |
| Self-signed cert acceptance | Not possible (CA validation) | Often for "testing" |
| Missing hostname check | Not possible (automatic) | Frequently forgotten |
| Expired certificate handling | Consistent policy | Per-application |
Code Requiring Security Audit
| Scope | Ouroboros | TLS/DTLS |
|---|---|---|
| Core protocol implementation | IRMd + library | TLS library |
| Per-application code | None | Each application's TLS usage |
| Configuration parsing | Minimal (file presence) | Complex (many options) |
11. Failure Modes and Resilience
IPCP Crash Recovery (Ouroboros-specific)
Because reliability (FRCT) is implemented in the library, not the IPCP:
Before IPCP crash: App ←→ Library (FRCT state) ←→ IRMd ←→ IPCP ←→ Network IPCP crashes and restarts: App ←→ Library (FRCT state preserved) ←→ IRMd ←→ [IPCP restart] ←→ Network After IPCP restart: App ←→ Library (continues) ←→ IRMd ←→ IPCP (re-enrolled) ←→ Network
The application's reliable flow can survive IPCP restarts because:
- Retransmission buffers are in application library
- Sequence numbers and acknowledgments are in application library
- Only the network path traverses the IPCP
TCP+TLS Crash Scenarios
Kernel TCP crash (rare but possible): - All TCP connections lost - All reliability state lost - Applications must reconnect and re-handshake Application crash: - All TLS sessions lost - Must renegotiate from scratch
Comparison
| Scenario | Ouroboros | TCP+TLS |
|---|---|---|
| Transport process crash | Flow survives (FRCT in library) | Connection lost |
| Kernel crash | All flows lost | All connections lost |
| Application crash | Flow lost | Connection lost |
| Network path change | Handled by IPCP | Connection may break |
12. Ecosystem Maturity
This section acknowledges practical considerations beyond architectural merit.
| Aspect | Ouroboros | TCP+TLS / UDP+DTLS |
|---|---|---|
| Production deployments | Experimental | Ubiquitous |
| Library implementations | 1 (reference) | Many (OpenSSL, BoringSSL, etc.) |
| Language bindings | C (native), Python, Rust | All major languages |
| Security audits | Limited | Extensive |
| CVE history | Minimal (new codebase) | Extensive (well-studied) |
| Documentation | Growing | Comprehensive |
| Community size | Small | Massive |
| Tool support | Custom (irm, wireshark limited) | Extensive |
| Hardware acceleration | Not yet | Widely available |
| FIPS certification | No | Available (OpenSSL, etc.) |
Note: Ecosystem maturity is a practical consideration but does not reflect on the architectural soundness of the design. Ouroboros is a research prototype demonstrating that a simpler, more secure architecture is achievable.
Summary
| Category | Ouroboros | TCP+TLS 1.3 | UDP+DTLS 1.3 |
|---|---|---|---|
| Application code | Minimal | Moderate | High |
| Configuration | Filesystem-based, system-wide | Per-application | Per-application |
| Handshake RTT | 1 | 2.5 (2 with 0-RTT) | 1-2 |
| Fresh keys every connection | Yes | Yes (No for 0-RTT early data) | Yes |
| Cipher negotiation | Not implemented | Yes | Yes |
| Downgrade resistance | Architectural | Protocol-level | Protocol-level |
| Certificate hot reload | Built-in | Application-implemented | Application-implemented |
| Policy enforcement | Centralized | Distributed | Distributed |
| Error handling | Simple | Complex | Complex |
| Transport independence | Yes | No | No |
| Audit trail | Centralized | Distributed | Distributed |
| IPCP/transport crash | Flow survives | Connection lost | Connection lost |
| Ecosystem maturity | Experimental | Production | Production |