Resumen
Consulta Streaming Library para obtener una descripción general del protocolo Streaming.
Versiones de Protocolo
El protocolo de streaming no incluye un campo de versión. Las versiones listadas a continuación son para Java I2P. Las implementaciones y el soporte criptográfico real pueden variar. No hay forma de determinar si el extremo remoto soporta alguna versión o característica en particular. La tabla a continuación es para orientación general sobre las fechas de lanzamiento de varias características.
Las características listadas a continuación son para el protocolo en sí. Varias opciones de configuración están documentadas en la Streaming Library junto con la versión de Java I2P en la que fueron implementadas.
| Router Version | Streaming Features |
|---|---|
| 0.9.58 | Bob's hash in NACKs field of SYN packet |
| 0.9.39 | OFFLINE_SIGNATURE option |
| 0.9.36 | I2CP protocol number enforced |
| 0.9.20 | FROM_INCLUDED no longer required in RESET |
| 0.9.18 | PINGs and PONGs may include a payload |
| 0.9.15 | EdDSA Ed25519 sig type |
| 0.9.12 | ECDSA P-256, P-384, and P-521 sig types |
| 0.9.11 | Variable-length signatures |
| 0.7.1 | Protocol numbers defined in I2CP |
Formato de Paquete
El formato de un solo paquete en el protocolo de streaming se muestra a continuación. El tamaño mínimo del encabezado, sin NACKs o datos de opciones, es de 22 bytes.
No hay un campo de longitud en el protocolo de streaming. El encuadre es proporcionado por las capas inferiores - I2CP e I2NP.
+----+----+----+----+----+----+----+----+
| send Stream ID | rcv Stream ID |
+----+----+----+----+----+----+----+----+
| sequence Num | ack Through |
+----+----+----+----+----+----+----+----+
| nc | nc*4 bytes of NACKs (optional)
+----+----+----+----+----+----+----+----+
| rd | flags | opt size| opt data
+----+----+----+----+----+----+----+----+
... (optional, see below) |
+----+----+----+----+----+----+----+----+
| payload ...
+----+----+----+-//
sendStreamId :: 4 byte Integer : Número aleatorio seleccionado por el destinatario del paquete antes de enviar el primer paquete de respuesta SYN y constante durante la vida de la conexión, mayor que cero. 0 en el mensaje SYN enviado por el originador de la conexión, y en mensajes posteriores, hasta que se reciba una respuesta SYN, que contiene el ID de stream del peer.
receiveStreamId :: 4 bytes Integer : Número aleatorio seleccionado por el originador del paquete antes de enviar el primer paquete SYN y constante durante toda la vida de la conexión, mayor que cero. Puede ser 0 si es desconocido, por ejemplo en un paquete RESET.
sequenceNum :: 4 bytes Integer : La secuencia para este mensaje, comenzando en 0 en el mensaje SYN, e incrementándose en 1 en cada mensaje excepto para ACKs simples y retransmisiones. Si el sequenceNum es 0 y la bandera SYN no está establecida, este es un paquete ACK simple que no debería ser confirmado con ACK.
ackThrough :: 4 byte Integer : El número de secuencia de paquete más alto que fue recibido en el receiveStreamId. Este campo se ignora en el paquete de conexión inicial (donde receiveStreamId es el id desconocido) o si está establecida la bandera NO_ACK. Todos los paquetes hasta e incluyendo este número de secuencia son confirmados (ACKed), EXCEPTO aquellos listados en los NACKs a continuación.
Recuento de NACK :: 1 byte Integer : El número de NACKs de 4 bytes en el siguiente campo, u 8 cuando se usa junto con SYNCHRONIZE para prevención de repetición desde la versión 0.9.58; ver más abajo.
NACKs :: nc * 4 bytes Integer s : Números de secuencia menores que ackThrough que aún no se han recibido. Dos NACKs de un paquete es una solicitud para una ‘retransmisión rápida’ de ese paquete. También se usa junto con SYNCHRONIZE para prevención de repetición desde la versión 0.9.58; ver más abajo.
resendDelay :: 1 byte Integer : Cuánto tiempo va a esperar el creador de este paquete antes de reenviar este paquete (si aún no ha sido confirmado con ACK). El valor son segundos desde que se creó el paquete. Actualmente se ignora al recibir.
flags :: valor de 2 bytes : Ver más abajo.
option size :: Integer de 2 bytes : El número de bytes en el siguiente campo
datos de opción :: 0 o más bytes : Según se especifica en las flags. Ver más abajo.
payload :: tamaño restante del paquete
Campos de Banderas y Datos de Opciones
El campo de flags anterior especifica algunos metadatos sobre el paquete, y a su vez puede requerir que se incluyan ciertos datos adicionales. Los flags son los siguientes. Cualquier estructura de datos especificada debe agregarse al área de opciones en el orden dado.
Orden de bits: 15….0 (15 es MSB)
| Bit | Flag | Option Order | Option Data | Function |
|---|---|---|---|---|
| 0 | SYNCHRONIZE | -- | -- | Similar to TCP SYN. Set in the initial packet and in the first response. FROM_INCLUDED and SIGNATURE_INCLUDED must also be set. |
| 1 | CLOSE | -- | -- | Similar to TCP FIN. If the response to a SYNCHRONIZE fits in a single message, the response will contain both SYNCHRONIZE and CLOSE. SIGNATURE_INCLUDED must also be set. |
| 2 | RESET | -- | -- | Abnormal close. SIGNATURE_INCLUDED must also be set. Prior to release 0.9.20, due to a bug, FROM_INCLUDED must also be set. |
| 3 | SIGNATURE_INCLUDED | 5 | variable length Signature | Currently sent only with SYNCHRONIZE, CLOSE, and RESET, where it is required, and with ECHO, where it is required for a ping. The signature uses the Destination's SigningPrivateKey to sign the entire header and payload with the space in the option data field for the signature being set to all zeroes. Prior to release 0.9.11, the signature was always 40 bytes. As of release 0.9.11, the signature may be variable-length, see below for details. |
| 4 | SIGNATURE_REQUESTED | -- | -- | Unused. Requests every packet in the other direction to have SIGNATURE_INCLUDED |
| 5 | FROM_INCLUDED | 2 | 387+ byte Destination | Currently sent only with SYNCHRONIZE, where it is required, and with ECHO, where it is required for a ping. Prior to release 0.9.20, due to a bug, must also be sent with RESET. |
| 6 | DELAY_REQUESTED | 1 | 2 byte Integer | Optional delay. How many milliseconds the sender of this packet wants the recipient to wait before sending any more data. A value greater than 60000 indicates choking. A value of 0 requests an immediate ack. |
| 7 | MAX_PACKET_SIZE_INCLUDED | 3 | 2 byte Integer | The maximum length of the payload. Send with SYNCHRONIZE. |
| 8 | PROFILE_INTERACTIVE | -- | -- | Unused or ignored; the interactive profile is unimplemented. |
| 9 | ECHO | -- | -- | Unused except by ping programs. If set, most other options are ignored. See the streaming docs. |
| 10 | NO_ACK | -- | -- | This flag simply tells the recipient to ignore the ackThrough field in the header. Currently set in the initial SYN packet, otherwise the ackThrough field is always valid. Note that this does not save any space, the ackThrough field is before the flags and is always present. |
| 11 | OFFLINE_SIGNATURE | 4 | variable length OfflineSig | Contains the offline signature section from LS2. See proposal 123 and the common structures specification. FROM_INCLUDED must also be set. Contains an OfflineSig: 1) Expires timestamp (4 bytes, seconds since epoch, rolls over in 2106) 2) Transient sig type (2 bytes) 3) Transient SigningPublicKey (length as implied by sig type) 4) Signature of expires timestamp, transient sig type, and public key, by the destination public key. Length of sig as implied by the destination public key sig type. |
| 12-15 | unused | Set to zero for compatibility with future uses. |
Antes de la versión 0.9.11, la firma en el campo de opción siempre era de 40 bytes.
A partir de la versión 0.9.11, la signature tiene longitud variable. El tipo y longitud de la Signature se infieren del tipo de clave utilizada en la opción FROM_INCLUDED y la documentación de Signature .
A partir de la versión 0.9.39, se admite la opción OFFLINE_SIGNATURE. Si esta opción está presente, se utiliza la SigningPublicKey transitoria para verificar cualquier paquete firmado, y la longitud y tipo de firma se infieren de la SigningPublicKey transitoria en la opción.
Cuando un paquete contiene tanto FROM_INCLUDED como SIGNATURE_INCLUDED (como en SYNCHRONIZE), la inferencia puede hacerse directamente.
Cuando un paquete no contiene FROM_INCLUDED, la inferencia debe hacerse a partir de un paquete SYNCHRONIZE anterior.
Cuando un paquete no contiene FROM_INCLUDED, y no hubo un paquete SYNCHRONIZE anterior (por ejemplo, un paquete CLOSE o RESET perdido), la inferencia se puede hacer desde la longitud de las opciones restantes (ya que SIGNATURE_INCLUDED es la última opción), pero el paquete probablemente será descartado de todos modos, ya que no hay FROM disponible para validar la firma. Si se definen más campos de opción en el futuro, deben ser considerados.
Prevención de Reproducción
Para evitar que Bob use un ataque de repetición almacenando un paquete SYNCHRONIZE firmado válido recibido de Alice y enviándolo posteriormente a una víctima Charlie, Alice debe incluir el hash de destino de Bob en el paquete SYNCHRONIZE de la siguiente manera:
Set NACK count field to 8
Set the NACKs field to Bob's 32-byte destination hash
Al recibir un SYNCHRONIZE, si el campo de conteo NACK es 8, Bob debe interpretar el campo NACKs como un hash de destino de 32 bytes, y debe verificar que coincida con su hash de destino. También debe verificar la firma del paquete como de costumbre, ya que esto cubre todo el paquete incluyendo los campos de conteo NACK y NACKs. Si el conteo NACK es 8 y el campo NACKs no coincide, Bob debe descartar el paquete.
Esto es requerido para las versiones 0.9.58 y superiores. Esto es compatible hacia atrás con versiones anteriores, porque los NACKs no se esperan en un paquete SYNCHRONIZE. Los destinos no saben y no pueden saber qué versión está ejecutando el otro extremo.
No es necesario realizar cambios en el paquete SYNCHRONIZE ACK enviado de Bob a Alice; no incluyas NACKs en ese paquete.
Referencias
- [Destination] Destination
- [Integer] Integer
- [OfflineSig] OfflineSignature
- [Signature] Signature
- [SigningPrivateKey] SigningPrivateKey
- [SigningPublicKey] SigningPublicKey
- [STREAMING] Biblioteca de Streaming