<?xml version="1.0" encoding="UTF-8"?>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude"
     category="exp"
     docName="draft-x1co-ustps-03"
     ipr="trust200902"
     submissionType="independent"
     xml:lang="en"
     version="3">
  <front>
    <title abbrev="USTPS">UDP Speedy Transmission Protocol Secure (USTPS)</title>
    <seriesInfo name="Internet-Draft" value="draft-x1co-ustps-03"/>
    <author fullname="x1co" initials="X." surname="x1co">
      <organization>x1colegal</organization>
      <address>
        <email>x1colegal@outlook.com.br</email>
      </address>
    </author>
    <date year="2026" month="June" day="12"/>
    <area>General</area>
    <workgroup>Independent Submission</workgroup>
    <keyword>UDP</keyword>
    <keyword>streaming</keyword>
    <keyword>reliability</keyword>
    <keyword>security</keyword>
    <abstract>
      <t>This document describes UDP Speedy Transmission Protocol Secure (USTPS), an experimental secure transport built on UDP for low-latency streaming-oriented applications. USTPS provides packet-level authenticated encryption for DATA packets, human-readable plaintext transport control, binary UPACK DATA framing, selective retransmission, out-of-order acceptance, adaptive retransmission timeout based on RTT sampling, and application-visible stream position metadata. USTPS is intentionally unordered at the transport layer and is designed to avoid transport-level Head-of-Line blocking.</t>
    </abstract>
  </front>
  <middle>
    <section numbered="true" toc="default">
      <name>Introduction</name>
      <t>USTPS is an experimental transport that runs directly over UDP. It was designed for applications that prefer continuing delivery of later packets even when earlier packets are temporarily missing. Its current public implementation focus is media streaming, although the transport can be adapted to other applications that can tolerate or explicitly manage reordering.</t>
      <t>USTPS combines reliable recovery of missing packets, transport-level unordered behavior, and mandatory authenticated protection for application payload packets. Unlike TCP, USTPS does not force byte-stream ordering in the transport. Unlike QUIC streams, USTPS does not define per-stream in-order delivery semantics in the transport itself. Instead, it exposes both a packet sequence number and an application-facing stream position so that upper layers may reconstruct ordered output when needed.</t>
    </section>

    <section numbered="true" toc="default">
      <name>Terminology</name>
      <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" 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>
    </section>

    <section numbered="true" toc="default">
      <name>Design Goals</name>
      <t>USTPS has the following goals:</t>
      <ul spacing="normal">
        <li>Run directly over UDP.</li>
        <li>Provide authenticated protection for DATA packets.</li>
        <li>Recover missing packets with selective retransmission.</li>
        <li>Accept and process later packets even when earlier packets are missing.</li>
        <li>Expose sufficient metadata for an application to rebuild ordered output if required.</li>
        <li>Allow an existing session to survive a client path change when possible.</li>
      </ul>
      <t>USTPS is not intended to emulate TCP semantics. In particular, it does not provide transport-layer ordered byte-stream delivery and does not define congestion control.</t>
    </section>

    <section numbered="true" toc="default">
      <name>Transport Overview</name>
      <t>Each USTPS DATA packet contains a transport sequence number (<tt>seq</tt>) and a stream position (<tt>stream_pos</tt>). The sequence number is used for reliability functions such as acknowledgement, gap detection, retransmission, and RTT sampling. The stream position identifies where the payload belongs in the application's logical byte stream.</t>
      <t>Upon reception of DATA packets, a receiver SHOULD acknowledge unique packets and MAY immediately pass packet payload upward, even when a lower sequence number has not yet arrived. If an application requires ordered output, it MUST use <tt>stream_pos</tt> to reconstruct that order.</t>
      <t>Example arrival order:</t>
      <artwork><![CDATA[
      Physical arrival: 1 2 3 5 6
      Missing packet : 4
      Receiver action: accept 5 and 6, request retransmission of 4
      Later arrival  : 4
      Logical order  : 1 2 3 4 5 6
      ]]></artwork>
    </section>

    <section numbered="true" toc="default">
      <name>Packet Format</name>
      <t>The transport uses two inner wire formats.</t>
      <t>Plaintext control packets are serialized as human-readable ASCII records. Current public implementations use forms such as <tt>ACK: 10</tt>, <tt>ACK: 10 11 12</tt>, <tt>NACK: 42</tt>, <tt>HELLO: BASE64...</tt>, and <tt>CLOSE:</tt>. HELLO carries binary handshake material in Base64 when required.</t>
      <t>DATA packets use a binary frame format named UPACK, identified on the wire by the 4-octet marker <tt>UPAK</tt>.</t>
      <t>The UPACK DATA frame fields are:</t>
      <ul spacing="normal">
        <li>Magic: 4 octets</li>
        <li>Type: 1 octet</li>
        <li>Flags: 1 octet</li>
        <li>Sequence: 32 bits</li>
        <li>Stream Position: 64 bits</li>
        <li>Payload Length: 16 bits</li>
        <li>Payload: variable</li>
      </ul>
      <t>Packet types currently used by implementations include DATA, ACK, RETRANSMIT_REQUEST, HELLO, and CLOSE.</t>
      <t>Current public implementations protect DATA packets with an outer AEAD envelope identified by the magic value <tt>USS1</tt>. After decryption, DATA typically begins with <tt>UPAK</tt>, while plaintext control appears as readable ASCII control lines.</t>
    </section>

    <section numbered="true" toc="default">
      <name>Handshake and Session Model</name>
      <t>A client begins by sending a plaintext HELLO carrying its X25519 public key and requested cipher. The server does not send application DATA immediately. Instead, it replies with a plaintext challenge containing a random token, a generated Base64 session identifier, the selected cipher, and the server public key.</t>
      <t>The client MUST answer with the received token. Only after that token round-trip succeeds does the server derive the AEAD session key and begin sending DATA. After validation, the session is tracked by the generated Base64 session identifier rather than solely by the original IP address and UDP source port.</t>
      <t>Subsequent keepalive or rebind messages MAY use the session identifier to resume an existing session after a path change or source-port change.</t>
    </section>

    <section numbered="true" toc="default">
      <name>Reliability Model</name>
      <t>USTPS uses selective retransmission. A sender stores transmitted packets in a retransmission buffer until they are acknowledged or otherwise retired. A receiver detects gaps in observed sequence numbers and requests retransmission only for missing packets.</t>
      <t>USTPS intentionally avoids Go-Back-N behavior. Later packets are not discarded solely because an earlier packet is missing. Retransmission timeout (RTO) is used as a fallback if explicit retransmission requests are delayed or lost. Current implementations adapt RTO from measured RTT samples taken from non-retransmitted acknowledged packets.</t>
    </section>

    <section numbered="true" toc="default">
      <name>Head-of-Line Blocking</name>
      <t>USTPS is designed to avoid transport-level Head-of-Line blocking. A missing packet does not prevent receipt, acknowledgement, buffering, or application visibility of later packets. This differs from TCP, where the transport enforces ordered byte-stream delivery, and from individual QUIC streams, which remain in-order within each stream.</t>
      <t>If an application chooses to emit only ordered output, any waiting that occurs is an application-layer decision, not a USTPS transport requirement.</t>
    </section>

    <section numbered="true" toc="default">
      <name>Security Model</name>
      <t>USTPS uses mandatory AEAD for DATA packets. Implementations currently support ChaCha20-Poly1305, AES-256-GCM, and AES-128-GCM. Clients and servers perform an X25519-based key exchange when a client joins, and a separate session key is derived per client session.</t>
      <t>The outer secure envelope begins with the magic value <tt>USS1</tt>, meaning "UDP Speedy Secure, version 1". In current implementations, <tt>USS1</tt> identifies the encrypted/authenticated outer framing for DATA, while readable plaintext control lines identify transport control and <tt>UPAK</tt> identifies decrypted binary DATA framing.</t>
      <t>Implementations described by this document use a persistent server host key and Trust On First Use (TOFU) on the client side to detect unexpected server key changes across reconnects.</t>
    </section>

    <section numbered="true" toc="default">
      <name>Path Migration and Network Change Recovery</name>
      <t>Current public implementations support client-side path recovery. If the client detects that the active UDP path has stalled, it may recreate its UDP socket, resolve the server address again, and attempt to resume the existing session by the stored session identifier.</t>
      <t>If resume fails, the client may fall back to a fresh handshake. This behavior is intended to allow mobile or roaming devices to change networks without immediately forcing a client restart.</t>
    </section>

    <section numbered="true" toc="default">
      <name>Operational Notes</name>
      <t>USTPS has been implemented and exercised as a Beta-grade experimental protocol. Current public code and testing are primarily focused on streaming over local networks and over public Internet paths where UDP is available. Current implementations are multi-client and perform per-client session key derivation.</t>
      <t>Current public implementations also expose knobs such as simulated packet loss, output buffering delay, and cipher selection. These are implementation details and not normative wire requirements unless later specified.</t>
    </section>

    <section numbered="true" toc="default">
      <name>IANA Considerations</name>
      <t>This document has no IANA actions.</t>
    </section>

    <section numbered="true" toc="default">
      <name>Security Considerations</name>
      <t>USTPS relies on correct AEAD use, correct nonce handling, correct key derivation, and authenticated peer identity checks. Implementations MUST ensure nonce uniqueness for a given key. Implementations SHOULD authenticate server identity changes using a trust model such as TOFU or a stronger out-of-band validation method.</t>
      <t>Because USTPS is unordered, applications that require ordered interpretation MUST reconstruct order using application-visible metadata such as <tt>stream_pos</tt>. Applications that incorrectly treat physical arrival order as logical order may mis-handle retransmitted data.</t>
      <t>Implementations that support path migration or session resume MUST ensure that only holders of the valid session state can successfully resume the session.</t>
    </section>
  </middle>
  <back>
    <references>
      <name>Normative References</name>
      <reference anchor="RFC2119" target="https://www.rfc-editor.org/info/rfc2119">
        <front>
          <title>Key words for use in RFCs to Indicate Requirement Levels</title>
          <author initials="S." surname="Bradner" fullname="Scott Bradner"/>
          <date year="1997" month="March"/>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="2119"/>
      </reference>
      <reference anchor="RFC8174" target="https://www.rfc-editor.org/info/rfc8174">
        <front>
          <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
          <author initials="B." surname="Leiba" fullname="Barry Leiba"/>
          <date year="2017" month="May"/>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="8174"/>
      </reference>
    </references>
  </back>
</rfc>
