This document specifies an implementation of the uTP streaming protocol which uses Node Discovery Protocol v5 as a transport instead of raw UDP packets.
Motivation
The Discovery v5 protocol provides a simple and extensible UDP based protocol with robust encryption and resistance to deep packet inspection. The use of UDP however imposes a tight limit on packet sizes. Sub-protocols which wish to implement functionality that requires transmission of data that exceeds this packet size are forced to implement their own solutions for splitting these payloads across multiple UDP packets. Packet loss makes this type of solution fragile. A generic solution that can be reused across different Discovery v5 sub-protocols will improve the overall security and robustness of sub-protocols.
Specification
The uTP over Discovery v5 protocol uses the byte string utp (0x757470 in hex) as value for the protocol byte string in the TALKREQ message.
All uTP packets MUST be sent using the TALKREQ message.
This protocol MUST NOT use the TALKRESP message for sending uTP packets.
Note:
TALKREQis part of a request-response mechanism and might cause Discovery v5 implementations to invalidate peers when not receiving aTALKRESPresponse. This is an unresolved item in the specification. Thus currently aTALKRESPmessage MAY be send as response on aTALKREQmessage. However, the response MUST be ignored by the uTP protocol.
The payload passed to the request field of the TALKREQ message is the uTP packet as specified in BEP29.
BEP29
https://www.bittorrent.org/beps/bep_0029.html
The uTP protocol as specified in BEP29 defines the packet structure and logic for handling packets.
The main difference with BEP29 is that, instead of a raw UDP packet, the Discovery v5 TALKREQ message is used as transport.
Additionally, following deviations from the uTP specification or reference implementation are applied:
- The
connection_idis passed out of band (i.e. in a Portal wire protocol message), instead of randomly generated by the uTP connection intiator: This is required for integration with the Portal wire protocol. - To track incoming uTP streams, the IP address + port + Discovery v5
NodeId+connection_idis used, as opposed to IP address + port +connection_idin standard uTP. - It is allowed to send
ST_DATAwithout receivingST_DATAfirst from the initiator of the uTP connection. This is not specified in BEP29, but rather a deviation from the uTP reference implementation. It was added in the reference implementation to counter a reflective DDoS. Relevant paper: https://www.usenix.org/system/files/conference/woot15/woot15-paper-adamsky.pdf. However, when using Discovery v5 as a transport, the DDoS becomes no longer applicable because a full Discovery v5 handshake is required which will not work with a spoofed IP address. - The uTP reference implementation deviates from the uTP specification on the initialization of the
ack_nrwhen receiving theACKof aSYNpacket. The reference implementation initializes this asc.ack_nr = pkt.seq_nr - 1while the specification indicatesc.ack_nr = pkt.seq_nr. The uTP over Discovery v5 specifications follows the uTP reference implementation:c.ack_nr = pkt.seq_nr - 1.