<?xml version="1.0" encoding="utf-8"?>
<?xml-model href="rfc7991bis.rnc"?>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude"
     docName="draft-davis-pool-03"
     category="exp"
     ipr="trust200902"
     submissionType="IETF"
     tocInclude="true"
     sortRefs="true"
     symRefs="true"
     version="3">

  <front>
    <title abbrev="POOL">Protected Orchestrated Overlay Link (POOL): The Only Place Where Cowboys Can Water Their Horses</title>
    <seriesInfo name="Internet-Draft" value="draft-davis-pool-03"/>
    <author fullname="Drake Davis" initials="D." surname="Davis">
      <address>
        <email>adavi068@gmail.com</email>
      </address>
    </author>
    <date year="2026" month="July" day="4"/>
    <area>Transport</area>
    <keyword>overlay</keyword>
    <keyword>encryption</keyword>
    <keyword>mutual authentication</keyword>
    <keyword>stateless handshake</keyword>

    <abstract>
      <t>This document describes the Protected Orchestrated Overlay Link
      (POOL), an experimental secure transport protocol. POOL provides
      mandatory mutual authentication, always-on authenticated encryption
      with no plaintext mode, a stateless handshake resistant to resource
      exhaustion attacks, cryptographically unpredictable sequence numbers,
      self-describing 256-bit addresses, active path MTU discovery,
      per-flow telemetry, atomic configuration changes with automatic
      rollback, and an append-only hash-chained change journal. POOL
      operates either as an overlay above TCP (over IPv4 or IPv6) or
      directly over IP using experimental protocol number 253; the raw-IP
      transport is specified for IPv4 only in this document.</t>
    </abstract>

    <note removeInRFC="true">
      <name>About This Document</name>
      <t>Source for this draft and an implementation are maintained at
      <eref target="https://github.com/amosdavis/POOL"/>.</t>
    </note>
  </front>

  <middle>
    <section anchor="intro">
      <name>Introduction</name>
      <t>TCP/IP was designed for a cooperative network and acquired its
      security, observability, and operational-safety mechanisms as
      afterthoughts. The consequences are well documented: trust-by-default
      transport, spoofable sources, resource-exhausting handshakes,
      predictable sequence numbers, unauthenticated control packets,
      plaintext defaults, silent path MTU failures, and configuration
      changes with no protocol-level audit trail or rollback.</t>
      <t>POOL (Protected Orchestrated Overlay Link) is an experimental
      transport protocol that makes the opposite defaults mandatory:</t>
      <ul>
        <li>Mutual authentication on every connection; there is no
        unauthenticated mode.</li>
        <li>Authenticated encryption on every data packet; there is no
        plaintext mode.</li>
        <li>A stateless challenge-response handshake in which the server
        commits no resources until the client has proven reachability and
        expended computation.</li>
        <li>Sequence numbers that are unpredictable to off-path and on-path
        observers.</li>
        <li>Self-describing 256-bit addresses bound to node identity
        keys.</li>
        <li>Active, authenticated path MTU discovery.</li>
        <li>Telemetry (RTT, jitter, loss, throughput) embedded in the
        protocol itself.</li>
        <li>Versioned, atomically applied configuration with
        deadline-based automatic rollback.</li>
        <li>An append-only, hash-chained journal of protocol state
        transitions.</li>
      </ul>
      <t>This document specifies the POOL version 1 wire protocol and the
      normative hardening requirements labeled P01 through P13 and N02.
      It is published as an Experimental document to solicit review of the
      design and operational experience from independent
      implementations.</t>
      <section anchor="method">
        <name>Design Method: Failure Modes as Binding Tenets</name>
        <t>POOL was designed by inversion: before any mechanism was
        specified, the ways the system could fail were cataloged, and
        that catalog was adopted as a set of binding design tenets. No
        protocol mechanism is accepted if it creates a new path to a
        documented failure mode. Four failure catalogs govern this
        document:</t>
        <ol>
          <li>Failure modes of deployed Internet transport (TCP/IP),
          addressed by the core protocol design
          (<xref target="tcp-failures"/>).</li>
          <li>Protocol-level failure modes of POOL itself (P01-P13,
          N02), addressed by the normative requirements in
          <xref target="hardening"/>.</li>
          <li>Adoption failure modes — the documented reasons previous
          transport-replacement efforts stalled or died — addressed by
          the migration design in <xref target="migration"/> and
          <xref target="stalled"/>.</li>
          <li>Runtime-integrity failure modes, in which correctly
          specified code is modified after it is loaded, addressed in
          <xref target="security"/>.</li>
        </ol>
      </section>
      <section anchor="tcp-failures">
        <name>Failure Modes of Deployed Transport and POOL's Responses</name>
        <table anchor="tcp-fail-table">
          <name>TCP/IP Failure Categories and POOL Mechanisms</name>
          <thead>
            <tr><th>Failure Category</th><th>TCP/IP Problem</th><th>POOL Mechanism</th></tr>
          </thead>
          <tbody>
            <tr><td>No built-in security</td><td>Trust by default</td><td>Mandatory mutual authentication and encryption</td></tr>
            <tr><td>IP spoofing</td><td>Unverified source</td><td>Challenge-response proves reachability</td></tr>
            <tr><td>SYN flood</td><td>Stateful handshake</td><td>Stateless challenge; zero pre-allocation</td></tr>
            <tr><td>Sequence prediction</td><td>Predictable ISN</td><td>CSPRNG-derived sequence numbers</td></tr>
            <tr><td>RST injection</td><td>Unauthenticated control</td><td>Every packet HMAC-authenticated</td></tr>
            <tr><td>No encryption</td><td>Plaintext default</td><td>ChaCha20-Poly1305, always on</td></tr>
            <tr><td>Man-in-the-middle</td><td>No channel binding</td><td>Ephemeral ECDH plus per-packet HMAC</td></tr>
            <tr><td>Header manipulation</td><td>No header authentication</td><td>HMAC-SHA256 covers the entire packet</td></tr>
            <tr><td>Address exhaustion</td><td>32-bit IPv4</td><td>256-bit self-describing addresses</td></tr>
            <tr><td>Address conflicts</td><td>DHCP/static clashes</td><td>Cryptographically derived unique node IDs</td></tr>
            <tr><td>MTU silent drops</td><td>PMTUD failures</td><td>Active authenticated probing; mandatory fragmentation</td></tr>
            <tr><td>No monitoring</td><td>External tools only</td><td>Built-in per-flow telemetry</td></tr>
            <tr><td>Configuration drift</td><td>No versioning</td><td>Atomic versioned configuration with rollback</td></tr>
            <tr><td>No audit trail</td><td>External logging</td><td>Built-in hash-chained change journal</td></tr>
            <tr><td>Unsaved configuration</td><td>Volatile state</td><td>Persistent versioned configuration</td></tr>
            <tr><td>Vendor lock-in</td><td>Proprietary behavior</td><td>Single open canonical specification</td></tr>
            <tr><td>Route origin forgery</td><td>No route authentication</td><td>Addresses cryptographically bound to node identity</td></tr>
            <tr><td>Name-service dependency</td><td>Separate DNS service</td><td>Embedded peer discovery</td></tr>
            <tr><td>Cascading failure</td><td>No backpressure</td><td>OVERLOAD signal and built-in flow control</td></tr>
            <tr><td>Change-window risk</td><td>No automatic rollback</td><td>Deadline-based automatic rollback</td></tr>
          </tbody>
        </table>
      </section>
    </section>

    <section anchor="conventions">
      <name>Conventions and Terminology</name>
      <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>",
      "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>",
      "<bcp14>SHALL NOT</bcp14>", "<bcp14>SHOULD</bcp14>",
      "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>",
      "<bcp14>NOT RECOMMENDED</bcp14>", "<bcp14>MAY</bcp14>", and
      "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
      described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/>
      when, and only when, they appear in all capitals, as shown here.</t>
      <dl>
        <dt>Session:</dt>
        <dd>A mutually authenticated, encrypted association between two
        POOL nodes, identified by a 128-bit Session ID.</dd>
        <dt>Channel:</dt>
        <dd>One of 256 multiplexed logical streams within a session.</dd>
        <dt>Node identity key:</dt>
        <dd>A long-lived X25519 key pair from which a node's address Node
        ID is derived.</dd>
        <dt>Ephemeral key:</dt>
        <dd>A per-session X25519 key pair used for key agreement and
        discarded when the session ends.</dd>
      </dl>
    </section>

    <section anchor="packet">
      <name>Packet Format</name>
      <t>All POOL packets share a common 80-byte header. Multi-byte fields
      are big-endian (network byte order).</t>
      <figure anchor="header-fig">
        <name>POOL Common Header</name>
        <artwork type="ascii-art"><![CDATA[
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Version (4)  |  Type (4)     |          Flags (16)           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      Sequence Number (64)                     |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      Acknowledgment (64)                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      Session ID (128)                         |
|                                                               |
|                                                               |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      Timestamp (64)                           |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|        Payload Length (16)    |    Channel (8)  | Reserved (8)|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      HMAC (256)                               |
|                         ...                                   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      Payload (variable)                       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
]]></artwork>
      </figure>
      <dl>
        <dt>Version (4 bits):</dt>
        <dd>Protocol version. This document defines version 1.</dd>
        <dt>Type (4 bits):</dt>
        <dd>Packet type; see <xref target="pkt-types"/>.</dd>
        <dt>Flags (16 bits):</dt>
        <dd>Bit field; see <xref target="flags"/>.</dd>
        <dt>Sequence Number (64 bits):</dt>
        <dd>Cryptographic sequence number; see
        <xref target="crypto-seq"/>.</dd>
        <dt>Acknowledgment (64 bits):</dt>
        <dd>Acknowledges the peer's highest received sequence number.</dd>
        <dt>Session ID (128 bits):</dt>
        <dd>Unique session identifier generated during connection
        establishment.</dd>
        <dt>Timestamp (64 bits):</dt>
        <dd>Nanosecond-precision clock sample used for RTT and jitter
        measurement and for INIT replay protection
        (<xref target="p10"/>).</dd>
        <dt>Payload Length (16 bits):</dt>
        <dd>Length of the (encrypted) payload in bytes.</dd>
        <dt>Channel (8 bits):</dt>
        <dd>Multiplexed channel number within the session (0-255).</dd>
        <dt>Reserved (8 bits):</dt>
        <dd>MUST be zero on transmission and ignored on receipt.</dd>
        <dt>HMAC (256 bits):</dt>
        <dd>HMAC-SHA256 over the header and the plaintext payload; see
        <xref target="crypto-hmac"/>.</dd>
      </dl>

      <section anchor="pkt-types">
        <name>Packet Types</name>
        <table anchor="pkt-type-table">
          <name>POOL Packet Types</name>
          <thead>
            <tr><th>Value</th><th>Name</th><th>Description</th></tr>
          </thead>
          <tbody>
            <tr><td>0x0</td><td>INIT</td><td>Connection initiation (carries client ephemeral public key)</td></tr>
            <tr><td>0x1</td><td>CHALLENGE</td><td>Server challenge (carries puzzle and server ephemeral key)</td></tr>
            <tr><td>0x2</td><td>RESPONSE</td><td>Client puzzle solution and key-agreement completion</td></tr>
            <tr><td>0x3</td><td>DATA</td><td>Encrypted application data</td></tr>
            <tr><td>0x4</td><td>ACK</td><td>Pure acknowledgment</td></tr>
            <tr><td>0x5</td><td>HEARTBEAT</td><td>Keepalive with embedded telemetry</td></tr>
            <tr><td>0x6</td><td>REKEY</td><td>Session key rotation</td></tr>
            <tr><td>0x7</td><td>CLOSE</td><td>Graceful authenticated close</td></tr>
            <tr><td>0x8</td><td>CONFIG</td><td>Configuration change announcement</td></tr>
            <tr><td>0x9</td><td>ROLLBACK</td><td>Atomic rollback to previous configuration</td></tr>
            <tr><td>0xA</td><td>DISCOVER</td><td>Network/MTU/peer discovery</td></tr>
            <tr><td>0xB</td><td>JOURNAL</td><td>Change journal synchronization</td></tr>
            <tr><td>0xC</td><td>INTEGRITY</td><td>Peer cryptographic challenge-response (runtime behavioral verification)</td></tr>
            <tr><td>0xD-0xF</td><td>RESERVED</td><td>Reserved for future use</td></tr>
          </tbody>
        </table>
      </section>

      <section anchor="flags">
        <name>Flags</name>
        <table anchor="flags-table">
          <name>POOL Header Flags</name>
          <thead>
            <tr><th>Bit</th><th>Name</th><th>Description</th></tr>
          </thead>
          <tbody>
            <tr><td>0</td><td>ENCRYPTED</td><td>Payload is encrypted (always set after the handshake)</td></tr>
            <tr><td>1</td><td>COMPRESSED</td><td>Payload was compressed before encryption (see <xref target="p08"/>)</td></tr>
            <tr><td>2</td><td>PRIORITY</td><td>High-priority packet</td></tr>
            <tr><td>3</td><td>FRAGMENT</td><td>Packet is a fragment of a larger message</td></tr>
            <tr><td>4</td><td>LAST_FRAG</td><td>Packet is the last fragment</td></tr>
            <tr><td>5</td><td>REQUIRE_ACK</td><td>Sender requires explicit acknowledgment</td></tr>
            <tr><td>6</td><td>TELEMETRY</td><td>Heartbeat carries telemetry data</td></tr>
            <tr><td>7</td><td>ROLLBACK_READY</td><td>Node supports atomic rollback</td></tr>
            <tr><td>8</td><td>CONFIG_LOCKED</td><td>Configuration changes are frozen</td></tr>
            <tr><td>9</td><td>JOURNAL_SYNC</td><td>Journal synchronization in progress</td></tr>
            <tr><td>10-15</td><td>RESERVED</td><td>MUST be zero on transmission and ignored on receipt</td></tr>
          </tbody>
        </table>
      </section>
    </section>

    <section anchor="handshake">
      <name>Connection Establishment (Stateless Handshake)</name>
      <t>Unlike TCP's three-way handshake, which allocates server resources
      upon SYN receipt, POOL uses a stateless challenge-response in which
      the server allocates no per-connection state until the client has
      proven that it can receive replies at its claimed address and has
      solved a computational puzzle.</t>
      <figure anchor="handshake-fig">
        <name>Stateless Handshake</name>
        <artwork type="ascii-art"><![CDATA[
Client                                Server
  |                                     |
  |--- INIT (client ephemeral pubkey) ->|  Server allocates NOTHING
  |                                     |  Challenge derived from
  |                                     |  hash(client_addr, time,
  |                                     |       server_secret)
  |<-- CHALLENGE (puzzle, server key) --|  Still ZERO server state
  |                                     |
  |  Client solves puzzle               |
  |  Client derives shared secret       |
  |                                     |
  |--- RESPONSE (solution, proof) ----->|  Server verifies solution
  |                                     |  Server derives shared secret
  |                                     |  NOW session state is created
  |<-- DATA (first payload) ------------|
  |                                     |
]]></artwork>
      </figure>
      <t>The server derives the challenge from a keyed hash over the
      client's address, a timestamp, and a rotating server secret
      (<xref target="p02"/>); it can therefore regenerate and verify the
      challenge statelessly. The puzzle is a hash-preimage search whose
      difficulty is adjustable under load
      (<xref target="p10"/>).</t>
      <t>This construction resists SYN-flood-style resource exhaustion
      because unanswered INITs consume no server memory, and it resists
      source-address spoofing because a client that cannot receive the
      CHALLENGE cannot proceed.</t>
      <t>The proof-of-work puzzle input binds the full 16-byte client
      address (IPv4 addresses are represented as IPv4-mapped IPv6,
      <xref target="ipv6"/>), an 8-byte server secret, and a 4-byte
      timestamp.</t>
    </section>

    <section anchor="crypto">
      <name>Cryptography</name>
      <section anchor="crypto-kx">
        <name>Key Exchange</name>
        <t>Key agreement uses X25519 <xref target="RFC7748"/> with
        ephemeral key pairs generated per session by both sides. The
        shared secret is processed with HKDF-SHA256
        <xref target="RFC5869"/> to derive the session encryption key,
        the HMAC key, and the sequence key, using distinct info labels
        for each.</t>
      </section>
      <section anchor="crypto-aead">
        <name>Symmetric Encryption</name>
        <t>All payload encryption uses the ChaCha20-Poly1305 AEAD
        <xref target="RFC8439"/> with a 256-bit session key. The 96-bit
        nonce is constructed from session-unique material and the packet
        sequence number as specified normatively in
        <xref target="p01"/>; a nonce value is never reused under the
        same key.</t>
      </section>
      <section anchor="crypto-hmac">
        <name>Packet Authentication</name>
        <t>Every packet carries an HMAC-SHA256 <xref target="RFC2104"/>
        computed over the header and the plaintext payload using the
        session HMAC key, which is derived separately from the encryption
        key. This prevents header manipulation, reset injection, and
        sequence corruption. Verification timing requirements are given
        in <xref target="p03"/>.</t>
      </section>
      <section anchor="crypto-rekey">
        <name>Key Rotation</name>
        <t>Sessions rekey automatically after 2^28 packets or one hour,
        whichever comes first, via a new ephemeral X25519 exchange carried
        inside the encrypted session. Old key material MUST be zeroed
        immediately after rotation. Simultaneous-initiation tie-breaking
        is specified in <xref target="p06"/>.</t>
      </section>
      <section anchor="crypto-seq">
        <name>Sequence Numbers</name>
        <t>The initial sequence number is drawn from a cryptographically
        secure random number generator. Sequence numbers are unpredictable
        to external observers, which prevents the prediction and injection
        attacks that plague cleartext transports. The 64-bit space removes
        wraparound concerns in practice; rekeying is required well before
        exhaustion (<xref target="p01"/>). Anti-replay requirements are
        given in <xref target="n02"/>.</t>
      </section>
    </section>

    <section anchor="addressing">
      <name>Addressing</name>
      <t>POOL uses 256-bit self-describing addresses:</t>
      <artwork type="ascii-art"><![CDATA[
[32-bit : address type + version]
[64-bit : organization/network ID]
[64-bit : subnet/segment ID]
[64-bit : node ID (derived from the node's public key hash)]
[32-bit : checksum]
]]></artwork>
      <t>Properties:</t>
      <ul>
        <li>No exhaustion: 2^256 address space.</li>
        <li>No conflicts: the Node ID is derived from a cryptographic
        identity key and is therefore globally unique with overwhelming
        probability.</li>
        <li>Self-authenticating: an address is bound to its node's
        identity key.</li>
        <li>Hierarchical: organization and segment fields provide
        subnetting structure.</li>
        <li>The checksum catches transcription errors in manual entry;
        its collision bound and required upgrade path are discussed in
        <xref target="p09"/>.</li>
      </ul>
    </section>

    <section anchor="mtu">
      <name>MTU Discovery and Fragmentation</name>
      <ul>
        <li>DISCOVER packets probe the path MTU using binary search;
        probe rate limits and authentication requirements are given in
        <xref target="p05"/>.</li>
        <li>There are no silent drops: every fragment requires HMAC
        verification, and reassembly uses cryptographic ordering.</li>
        <li>The minimum MTU is 512 bytes.</li>
        <li>The path MTU is re-probed every 60 seconds and upon loss
        detection, and is cached per session.</li>
        <li>Fragment reassembly resource limits are normative; see
        <xref target="p04"/>.</li>
      </ul>
    </section>

    <section anchor="telemetry">
      <name>Built-in Telemetry</name>
      <t>Every HEARTBEAT packet (default interval: 5 seconds) carries a
      telemetry block:</t>
      <sourcecode type="c"><![CDATA[
struct pool_telemetry {
    uint64_t rtt_ns;         /* round-trip time, nanoseconds     */
    uint64_t jitter_ns;      /* RTT variance                     */
    uint32_t loss_rate_ppm;  /* packet loss, parts per million   */
    uint32_t throughput_bps; /* current throughput estimate      */
    uint16_t mtu_current;    /* current path MTU                 */
    uint16_t queue_depth;    /* local send queue depth           */
    uint64_t uptime_ns;      /* session uptime                   */
    uint32_t rekey_count;    /* completed key rotations          */
    uint32_t config_version; /* current configuration version    */
    uint32_t state_digest;   /* CRC32 of session state, for
                                cross-peer consistency checks    */
    uint64_t journal_head;   /* truncated journal chain head
                                commitment (see Section 10)      */
};
]]></sourcecode>
      <t>Both peers timestamp heartbeats and independently compute RTT,
      jitter, and loss, giving each side a view it can cross-check
      against the other's reported values. The state_digest and
      journal_head fields support the cross-peer integrity mechanisms
      described in <xref target="security"/>.</t>
    </section>

    <section anchor="config">
      <name>Atomic Configuration and Rollback</name>
      <t>POOL nodes maintain a versioned configuration state consisting of
      a monotonically increasing version, the previous version, SHA-256
      hashes of the serialized current and previous configurations, an
      application timestamp, and a rollback deadline.</t>
      <ol>
        <li>A CONFIG packet proposes a new configuration together with a
        rollback deadline.</li>
        <li>The peer applies the new configuration tentatively.</li>
        <li>If confirmation is not received before the deadline, the node
        automatically rolls back; semantics that prevent an attacker from
        forcing rollback by suppressing a single packet are specified in
        <xref target="p07"/>.</li>
        <li>Rollback restores the exact previous state, verified against
        the stored previous-configuration hash.</li>
        <li>Every configuration change is recorded in the change
        journal.</li>
      </ol>
    </section>

    <section anchor="journal">
      <name>Change Journal</name>
      <t>Every POOL node maintains an append-only journal of protocol
      state changes. Each entry records a timestamp, the configuration
      versions before and after, a change type, serialized change detail,
      and a SHA-256 entry hash. Entry hashes are chained: each entry's
      hash includes the previous entry's hash, so modification of any
      past entry invalidates all subsequent hashes.</t>
      <t>The chain head is a commitment to the entire journal history.
      Implementations SHOULD publish the chain head outside the node
      (for example, to remote logging infrastructure) and carry a
      truncated chain head in heartbeat telemetry so that each peer
      retains an independent replica; divergence between a node's journal
      and externally held commitments indicates tampering.</t>
      <t>Journals synchronize between peers via JOURNAL packets and
      provide a complete audit trail with before/after hashes for every
      change.</t>
    </section>

    <section anchor="errors">
      <name>Error Handling</name>
      <t>POOL never silently drops packets. Every error condition
      produces a journal entry and a telemetry counter increment, and MAY
      produce an encrypted error notification to the peer.</t>
      <table anchor="err-table">
        <name>Error Codes</name>
        <thead>
          <tr><th>Code</th><th>Category</th><th>Description</th></tr>
        </thead>
        <tbody>
          <tr><td>0x01</td><td>AUTH_FAIL</td><td>Authentication or HMAC verification failed</td></tr>
          <tr><td>0x02</td><td>DECRYPT_FAIL</td><td>Decryption failed</td></tr>
          <tr><td>0x03</td><td>SEQ_INVALID</td><td>Sequence number outside the valid window</td></tr>
          <tr><td>0x04</td><td>FRAG_TIMEOUT</td><td>Fragment reassembly timed out</td></tr>
          <tr><td>0x05</td><td>MTU_EXCEEDED</td><td>Packet exceeds the negotiated MTU</td></tr>
          <tr><td>0x06</td><td>CONFIG_REJECT</td><td>Configuration change rejected by policy</td></tr>
          <tr><td>0x07</td><td>REKEY_FAIL</td><td>Key rotation failed</td></tr>
          <tr><td>0x08</td><td>JOURNAL_FULL</td><td>Journal storage exhausted</td></tr>
          <tr><td>0x09</td><td>OVERLOAD</td><td>Node is overloaded (backpressure signal)</td></tr>
          <tr><td>0x0A</td><td>VERSION_MISMATCH</td><td>Protocol version incompatible</td></tr>
        </tbody>
      </table>
    </section>

    <section anchor="ipv6">
      <name>Transports and IP Version Support</name>
      <t>POOL runs over two transports:</t>
      <ul>
        <li>A TCP overlay (the default), which traverses existing
        networks and middleboxes unchanged; and</li>
        <li>Raw IP using experimental protocol number 253
        <xref target="RFC3692"/>, for networks that permit it.</li>
      </ul>
      <t>IP addresses are not carried in POOL packet headers; the
      underlying transport handles network addressing, so the wire
      protocol is identical over IPv4 and IPv6. Internally,
      implementations represent all addresses as 128-bit values, storing
      IPv4 addresses in IPv4-mapped IPv6 form (::ffff:a.b.c.d). A single
      dual-stack listener accepts both families. The handshake puzzle
      binds the full 16-byte client address for both families
      (<xref target="handshake"/>). The raw IP transport is currently
      specified for IPv4 only.</t>
    </section>

    <section anchor="migration">
      <name>Deployment and Incremental Migration from TCP/IP</name>
      <t>Every transport that has tried to replace TCP failed in part
      because it demanded a flag-day cutover: both endpoints had to
      change simultaneously, and neither side had an incentive to move
      first. POOL is designed so that no adopter ever has to be first,
      through three coexisting mechanisms that can be deployed
      independently and rolled back independently. TCP continues to work
      at every stage.</t>
      <section anchor="mig-bridge">
        <name>Phase 1: Edge Bridging (No Endpoint Changes)</name>
        <t>A bridge daemon terminates TCP from legacy clients at the
        network edge, establishes a POOL session to the destination, and
        forwards traffic in both directions:</t>
        <artwork type="ascii-art"><![CDATA[
TCP client -> [tcp2pool] -> POOL -> [pool2tcp] -> TCP server
]]></artwork>
        <t>Neither the client nor the server changes. The operator
        immediately gains encrypted and mutually authenticated internal
        transport, per-flow telemetry, and the audit journal on the
        bridged path. Rollback is stopping the bridge; traffic reverts
        to direct TCP.</t>
        <t>Because the bridge decrypts and re-encrypts, it handles
        plaintext and MUST be operated as a hardened, trusted node; see
        <xref target="security"/>.</t>
      </section>
      <section anchor="mig-shim">
        <name>Phase 2: Socket Interposition (No Recompilation)</name>
        <t>A dynamic-linker interposition library (for example, an
        LD_PRELOAD shared object) intercepts POSIX socket calls and
        routes TCP connections through POOL transparently. Existing
        applications run unmodified; interception can be limited to
        selected destination ports; optional fallback to TCP covers
        peers without POOL. Rollback is removing the interposition.</t>
      </section>
      <section anchor="mig-native">
        <name>Phase 3: Native POOL Applications</name>
        <t>Applications built directly against a POOL API gain access to
        all protocol features (channels, telemetry, journaling) with no
        TCP involvement. This phase is reached only after phases 1 and 2
        have established operational confidence, and phase 2's fallback
        mechanism remains available.</t>
      </section>
      <section anchor="mig-order">
        <name>Adoption Order and IP Version Coexistence</name>
        <t>The intended order is: encrypted east-west traffic via edge
        bridges first; per-service interposition next; inter-organization
        relaying and native applications last. All phases operate
        dual-stack (<xref target="ipv6"/>); the raw IP protocol 253
        transport is an optimization adopted last and only on networks
        that permit it, because middlebox tolerance is itself an adoption
        requirement (<xref target="stalled"/>).</t>
      </section>
    </section>

    <section anchor="stalled">
      <name>Adoption Failure Modes of Prior Transport Proposals</name>
      <t>The historical record of stalled and abandoned transport
      protocols is itself a failure catalog, and POOL treats it as
      binding: each documented cause of death is answered by a specific
      design decision.</t>
      <table anchor="stall-table">
        <name>Why Prior Transports Stalled, and POOL's Countermeasures</name>
        <thead>
          <tr><th>Adoption failure mode</th><th>Protocols it killed or stalled</th><th>POOL countermeasure</th></tr>
        </thead>
        <tbody>
          <tr>
            <td>Flag-day requirement: both endpoints must upgrade
            simultaneously</td>
            <td>CurveCP, MinimaLT, SST, tcpcrypt, HIP</td>
            <td>Three-phase migration with per-phase rollback
            (<xref target="migration"/>); no adopter is ever
            required to move first</td>
          </tr>
          <tr>
            <td>Middlebox ossification: NATs and firewalls drop unknown
            protocols</td>
            <td>DCCP, SCTP, CurveCP (UDP-blocked), raw-protocol
            designs</td>
            <td>Default transport is a TCP overlay that traverses
            existing middleboxes; raw protocol 253 is optional</td>
          </tr>
          <tr>
            <td>Applications must be rewritten for a new API</td>
            <td>SST, XTP, IL</td>
            <td>Bridge and socket-interposition phases require no
            application changes</td>
          </tr>
          <tr>
            <td>Opportunistic security without authentication invites
            active MITM and undermines the value proposition</td>
            <td>tcpcrypt</td>
            <td>Authentication is mandatory; there is no
            unauthenticated or plaintext mode to fall back into</td>
          </tr>
          <tr>
            <td>Complexity without a deployment story; no reference
            implementation or OS support</td>
            <td>MinimaLT, XTP, NEAT</td>
            <td>A complete open reference implementation (kernel
            module, bridge, interposition library, tooling) is
            maintained with the specification</td>
          </tr>
          <tr>
            <td>Per-flow state in the network core does not scale</td>
            <td>RSVP/IntServ</td>
            <td>All POOL state is end-to-end; the network core carries
            opaque traffic</td>
          </tr>
          <tr>
            <td>Identifier-locator split requires new infrastructure
            (rendezvous, DNS records)</td>
            <td>HIP</td>
            <td>POOL addresses are self-describing and
            self-authenticating; no new global infrastructure is
            required for basic operation</td>
          </tr>
          <tr>
            <td>A better-backed alternative absorbed the design
            space</td>
            <td>SST, Minion, DCCP (absorbed by QUIC and HTTP/2)</td>
            <td>POOL targets properties no deployed protocol provides
            (see below) rather than re-solving multiplexing or
            0-RTT</td>
          </tr>
        </tbody>
      </table>
      <t>Conversely, POOL deliberately targets capabilities that no
      widely deployed transport provides: protocol-level atomic
      configuration with automatic rollback, a transport-level audit
      journal, built-in per-flow telemetry, self-describing
      cryptographically bound addresses, MTU discovery with no silent
      drops, mandatory (non-negotiable) authentication and encryption,
      and integrated backpressure signaling.</t>
    </section>

    <section anchor="hardening">
      <name>Normative Hardening Requirements</name>
      <t>The following requirements address protocol-level failure modes
      identified during security analysis of POOL version 1. All are
      normative for compliant implementations.</t>

      <section anchor="p01">
        <name>Nonce Construction (P01)</name>
        <t>The 96-bit nonce for ChaCha20-Poly1305 MUST be constructed
        as:</t>
        <artwork type="ascii-art"><![CDATA[
nonce[0:3]  = hmac_key[0:4]    (session-unique prefix)
nonce[4:11] = big-endian(seq)  (64-bit sequence number)
]]></artwork>
        <t>Implementations MUST trigger rekeying before the sequence
        counter reaches 2^63 to prevent nonce reuse. After rekeying, the
        new HMAC key provides a fresh prefix, guaranteeing nonce
        uniqueness across key epochs.</t>
        <t>Rationale: using zero bytes for nonce[0:3] would reduce the
        effective nonce space by 32 bits, increasing collision
        probability across concurrent sessions.</t>
      </section>

      <section anchor="p02">
        <name>Challenge Secret Rotation (P02)</name>
        <t>The server MUST rotate its challenge secret at least every
        300 seconds. During rotation, the server MUST accept challenges
        generated with the previous secret for a grace period of twice
        the rotation interval, to avoid rejecting in-flight
        handshakes.</t>
        <t>Rationale: without rotation, captured challenge parameters
        could be solved offline and replayed indefinitely.</t>
      </section>

      <section anchor="p03">
        <name>HMAC Verification Timing (P03)</name>
        <t>All HMAC verification MUST use constant-time comparison.
        Variable-time memory comparison MUST NOT be used for any
        authentication tag or HMAC comparison.</t>
        <t>Rationale: variable-time comparison leaks tag bytes through
        timing side channels, enabling byte-by-byte forgery.</t>
      </section>

      <section anchor="p04">
        <name>Fragment Resource Limits (P04)</name>
        <t>Implementations MUST enforce all of the following:</t>
        <ul>
          <li>a maximum of 16 concurrent fragment reassembly slots per
          peer;</li>
          <li>a maximum 5-second timeout per incomplete fragment
          sequence;</li>
          <li>least-recently-used eviction when all fragment slots are
          occupied; and</li>
          <li>total fragment buffer memory capped at 16 times the MTU
          per peer.</li>
        </ul>
        <t>Rationale: without limits, an attacker can exhaust reassembly
        memory with many small fragment sequences that are never
        completed.</t>
      </section>

      <section anchor="p05">
        <name>MTU Probe Rate Limiting (P05)</name>
        <t>DISCOVER packets used for MTU probing MUST be rate-limited to
        at most one probe per second per peer. Probe responses MUST only
        be accepted from peers with established sessions, authenticated
        by the session HMAC.</t>
        <t>Rationale: unauthenticated probes can be amplified by
        spoofing, causing probe storms between peers.</t>
      </section>

      <section anchor="p06">
        <name>Rekey Tie-Breaking (P06)</name>
        <t>When both peers initiate REKEY simultaneously, the peer with
        the lexicographically lower Session ID MUST proceed as the rekey
        initiator; the other peer MUST abort its own attempt and process
        the received REKEY as a responder. Each rekey MUST include a
        monotonically increasing epoch number to disambiguate key
        material.</t>
      </section>

      <section anchor="p07">
        <name>Configuration Rollback Semantics (P07)</name>
        <t>If no configuration confirmation is received within the
        rollback deadline, implementations MUST treat silence as
        confirmation, not as failure. The CONFIG sender MUST retry the
        confirmation request at least three times with exponential
        backoff (1, 2, and 4 seconds) before the deadline expires.</t>
        <t>Rationale: an attacker who can suppress a single packet must
        not be able to force a rollback to a less secure
        configuration.</t>
      </section>

      <section anchor="p10">
        <name>INIT Replay Protection and Minimum Puzzle Difficulty (P10, P11)</name>
        <t>INIT packets MUST include a 64-bit nanosecond timestamp. The
        server MUST reject INIT packets whose timestamps deviate more
        than 30 seconds from the server's current time. The puzzle
        difficulty MUST be at least 16, requiring 2^16 hash operations
        on average.</t>
        <t>Rationale: without timestamps, captured INIT packets can be
        replayed indefinitely; without a difficulty floor, INIT-to-
        CHALLENGE reflection has zero computational cost for the
        sender.</t>
      </section>

      <section anchor="p13">
        <name>Version Downgrade Prevention (P13)</name>
        <t>This document specifies POOL version 1 only. Downgrade
        prevention applies once a higher protocol version exists: after a
        successful handshake with a peer at a version greater than 1, a
        POOL version 1 implementation that also supports the higher
        version MUST record that peer's maximum supported version and
        MUST reject subsequent connection attempts from that peer at a
        lower version with a CLOSE packet carrying a version-downgrade
        error. A version 1-only implementation has no higher version to
        protect and takes no downgrade-prevention action.</t>
        <t>The version 2 wire format (hybrid X25519 + ML-KEM-768 key
        agreement) is not specified in this document; the downgrade-
        prevention requirement above is stated normatively so that
        version 1 implementations that later add version 2 support are
        conformant from first deployment. Rationale: an active attacker
        could otherwise strip version negotiation and force peers into
        the X25519-only mode, which lacks post-quantum protection.</t>
      </section>

      <section anchor="p08">
        <name>Compression Oracle Mitigation (P08)</name>
        <t>When the COMPRESSED flag is set, compression occurs before
        encryption, and ciphertext length therefore leaks plaintext
        information (a CRIME/BREACH-style oracle). Applications handling
        secrets SHOULD either disable compression for sensitive channels
        or pad compressed output to fixed block sizes (for example,
        256-byte blocks).</t>
      </section>

      <section anchor="p09">
        <name>Address Checksum Collision Bound (P09)</name>
        <t>The CRC32 checksum used in POOL address derivation
        (<xref target="addressing"/>) has a birthday bound of
        approximately 2^16 addresses before a 50% collision probability.
        Deployments exceeding 10,000 nodes SHOULD upgrade to SHA-256
        truncated to its first 4 bytes for address derivation in
        protocol version 2 and later.</t>
      </section>

      <section anchor="n02">
        <name>Anti-Replay Window (N02)</name>
        <t>Implementations MUST maintain a sliding window of at least 64
        sequence numbers. Packets with sequence numbers older than the
        highest seen minus 64 MUST be silently discarded, as MUST
        duplicate sequence numbers within the window.</t>
      </section>
    </section>

    <section anchor="iana">
      <name>IANA Considerations</name>
      <t>This document has no IANA actions.</t>
      <t>POOL's raw IP transport uses IP protocol number 253, which is
      reserved for experimentation and testing by
      <xref target="RFC3692"/>; this document requests no permanent
      assignment. The TCP overlay transport uses port 9253 by local
      convention; no port assignment is requested at Experimental
      status. Should the protocol advance, a dedicated protocol number
      and a registered port would be requested, and registries for POOL
      packet types, flags, and error codes would be established.</t>
    </section>

    <section anchor="security">
      <name>Security Considerations</name>
      <t>This entire document concerns security; this section summarizes
      the threat model, residual risks, and the runtime-integrity design
      that accompanies the protocol.</t>
      <section>
        <name>Design Goals Met by Construction</name>
        <t>Source-address spoofing is countered by the reachability proof
        inherent in the challenge-response handshake
        (<xref target="handshake"/>). Resource-exhaustion attacks on the
        handshake are countered by statelessness and proof-of-work.
        Sequence prediction, reset injection, and header manipulation are
        countered by CSPRNG-seeded sequence numbers and per-packet HMAC.
        Passive interception is countered by mandatory AEAD encryption.
        On-path key compromise exposure is bounded by ephemeral keys and
        automatic rekeying.</t>
      </section>
      <section>
        <name>Residual Risks</name>
        <ul>
          <li>The compression oracle (<xref target="p08"/>) is mitigated
          by guidance, not eliminated; implementations cannot detect
          which application data is secret.</li>
          <li>The CRC32 address checksum is an error-detection code, not
          a security mechanism (<xref target="p09"/>).</li>
          <li>A migration bridge (<xref target="mig-bridge"/>)
          decrypts and re-encrypts, so plaintext exists in its memory;
          bridges MUST be operated as hardened, trusted nodes, SHOULD
          attest their own binaries at startup, and are candidates for
          replicated multi-path operation in high-assurance
          deployments.</li>
          <li>Traffic analysis (packet timing and sizes) is not
          addressed by this version of the protocol.</li>
          <li>Denial of service by a resourceful attacker willing to
          solve puzzles at scale is made expensive, not impossible.</li>
        </ul>
      </section>
      <section anchor="rt-integrity">
        <name>Runtime Integrity Failure Modes</name>
        <t>The POOL design includes a companion runtime-integrity threat
        model that assumes running code can be modified after it has
        been loaded and verified: live patching of code pages, hardware
        "overlay" interception of instruction or data flow, microcode
        or firmware modification, and memory-bus interception. Under
        this model, twenty failure modes are cataloged in four
        classes:</t>
        <dl>
          <dt>Crypto-path tampering (RT-C01 to RT-C06):</dt>
          <dd>modification of module code after load; authentication
          verification overlaid to always succeed; private-key
          exfiltration during ECDH; AEAD key or nonce exfiltration; key
          derivation replaced with attacker-known output; and compromise
          of the random number generator.</dd>
          <dt>Session and state tampering (RT-S01 to RT-S05):</dt>
          <dd>direct modification of session state in memory;
          sequence-number generation overlay; suppression of rekeying;
          bypass of puzzle verification; and state-machine transition
          override.</dd>
          <dt>Observability and audit tampering (RT-A01 to RT-A04):</dt>
          <dd>falsified status reporting; journal forgery; falsified
          self-test results; and telemetry manipulation.</dd>
          <dt>Userspace tool tampering (RT-U01 to RT-U05):</dt>
          <dd>replacement of control tools; interception of bridge
          plaintext during re-encryption; interposition-library
          tampering; validation bypass in auxiliary services; and
          manipulation of relay accounting.</dd>
        </dl>
        <t>Eight design tenets counter these: continuous (not only
        load-time) attestation; behavioral verification over binary
        verification (verify what code does, not what it is); a
        hardware root of trust where available; replicated execution
        with cross-peer consensus; cryptographic execution proofs;
        self-verifying code; append-only external audit logs; and
        assuming compromise while designing for detection and
        recovery.</t>
        <t>Protocol-visible mechanisms implementing these tenets
        include: the INTEGRITY packet type (a peer sends a random
        challenge that must be returned encrypted under the session
        key, proving the remote crypto path's behavior end to end);
        the state_digest and journal_head fields in heartbeat telemetry
        (<xref target="telemetry"/>), which let each peer hold an
        independent replica of the other's state and audit-log
        commitments; and the hash-chained journal with external
        chain-head publication (<xref target="journal"/>).
        Implementation-level mechanisms include periodic re-execution
        of known-answer self-tests with reference-digest comparison,
        code-section checksumming, continuous statistical health tests
        on all randomness, startup self-hash attestation of userspace
        tools, and a measurement chain forwarded to a hardware TPM when
        one is present. A node that fails any of these checks marks
        itself compromised, alerts through channels outside the
        potentially compromised code path, and refuses new sessions.</t>
        <t>Honest limits: a verifier co-located with the system under
        test can itself be overlaid; hardware-level interception that
        faithfully emulates correct behavior is undetectable from
        inside. Cross-peer replication and hardware roots of trust
        bound, but do not eliminate, this residual risk.</t>
        <t>Implementation status of the tenets varies. The reference
        implementation realizes Tenets T1, T2, T6, T7, and T8 in code
        (periodic self-tests, code-section checksumming, journal
        chaining with external chain-head publication, compiler
        hardening, and fail-closed integrity handling). Tenets T3
        (hardware root of trust), T4 (replicated execution with
        consensus), and T5 (cryptographic execution proofs such as
        zero-knowledge attestation) are specified normatively for future
        implementations but are only partially realized today: T3
        forwards measurements to a hardware TPM when one is present but
        cannot verify the TPM's integrity from the module; T4 exists in
        the partial form of cross-peer HMAC verification and
        state-digest replication; T5's Merkle-chained journal is
        implemented, but general cryptographic execution proofs are not.
        The full threat model, its mitigation matrix, and implementation
        status are maintained with the reference implementation.</t>
      </section>
      <section>
        <name>Cryptographic Agility</name>
        <t>POOL version 1 deliberately ships a single fixed cipher suite
        (X25519, HKDF-SHA256, ChaCha20-Poly1305, HMAC-SHA256) and no
        runtime negotiation, eliminating downgrade surface within a
        version. Algorithm migration happens only through whole protocol
        versions. A version 2 with hybrid X25519 + ML-KEM-768 key
        agreement is planned; its wire format is not specified in this
        document. Downgrade prevention between versions is specified in
        <xref target="p13"/>.</t>
      </section>
    </section>
  </middle>

  <back>
    <references>
      <name>References</name>
      <references>
        <name>Normative References</name>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2104.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5869.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7748.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8439.xml"/>
      </references>
      <references>
        <name>Informative References</name>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3692.xml"/>
      </references>
    </references>
    <section anchor="glossary" numbered="false">
      <name>Glossary</name>
      <t>This appendix collects POOL-specific terms used in the body of
      this document that are not defined in <xref target="conventions"/>.
      Core protocol terms (Session, Channel, Node identity key, Ephemeral
      key) are defined in <xref target="conventions"/>.</t>
      <dl>
        <dt>Challenge secret:</dt>
        <dd>A server-held secret rotated at least every 300 seconds
        (<xref target="p02"/>) used to construct the stateless handshake
        puzzle so that only the server that issued a challenge can verify
        its solution.</dd>
        <dt>Change journal:</dt>
        <dd>The append-only, hash-chained record of protocol state
        transitions maintained by every node (<xref target="journal"/>).
        Each entry's SHA-256 includes the prior entry's hash.</dd>
        <dt>Chain head:</dt>
        <dd>The SHA-256 hash of the most recent journal entry. It is a
        commitment to the entire journal history and is published
        externally and carried in heartbeat telemetry so peers hold
        independent replicas.</dd>
        <dt>Generosity score:</dt>
        <dd>A per-node value computed locally from observed bandwidth
        counters in the relay network, used to prioritize routing and
        enforce bandwidth reciprocity.</dd>
        <dt>INTEGRITY packet:</dt>
        <dd>A packet type by which one peer sends a random challenge that
        must be returned encrypted under the session key, proving the
        remote crypto path's behavior end to end (a Tenet T2 mechanism).</dd>
        <dt>Journal head:</dt>
        <dd>Synonym for chain head when carried in heartbeat telemetry
        (the <tt>journal_head</tt> field).</dd>
        <dt>Overlay (runtime-integrity sense):</dt>
        <dd>Hardware or firmware-level interception of instruction fetch,
        data read/write, or bus signals that substitutes different bit
        patterns at the circuit level, making a binary behave as if
        modified even when the on-disk binary is unchanged. Distinct from
        "POOL overlay" (the protocol running above TCP).</dd>
        <dt>Puzzle:</dt>
        <dd>The proof-of-work challenge in the stateless handshake
        (<xref target="handshake"/>); the client must find a nonce whose
        HMAC under the challenge secret is below a difficulty target.</dd>
        <dt>State digest:</dt>
        <dd>A CRC32 of a node's session state, carried in the
        <tt>state_digest</tt> field of heartbeat telemetry, allowing each
        peer to hold an independent replica of the other's state
        commitment.</dd>
        <dt>Text CRC:</dt>
        <dd>A CRC32 (or SHA-256) computed over the kernel module's
        <tt>.text</tt> section at init and re-verified periodically as a
        continuous runtime attestation mechanism (Tenet T1).</dd>
      </dl>
    </section>
    <section anchor="ack" numbered="false">
      <name>Acknowledgments</name>
      <t>The failure-mode-driven design method used throughout POOL —
      documenting the ways a system can fail and treating that list as
      binding design tenets — shaped every normative requirement in
      <xref target="hardening"/>.</t>
    </section>
  </back>
</rfc>
