Esta página fue actualizada por última vez el February 2016 y es precisa con la versión 0.9.24 del router I2P.

El Protocolo de Cliente de I2P (I2CP) presenta una fuerte compartimentalización de los asuntos entre el router I2P y cualquier cliente que quiera comunicarse a través de la red. Habilita mensajería segura y asíncrona mediante el envío y recepción de mensajes sobre un único socket TCP. Con I2CP una aplicación cliente le dice al router quiénes son ellos (sus "destinos"), qué anonimato, fiabilidad, y latencia tienen los intercambios a realizar, y a dónde enviar los mensajes. A la contra el router usa I2CP para decirle al cliente cuándo llega cualquier mensaje, y para pedirle autorización para que se usen algunos túneles.

El protocolo en si mismo está implementado en Java, para proporcionar el SDK del cliente. Este SDK (kit de desarrollo de software) se presenta en el paquete i2p.jar que implementa el lado-del-cliente de I2CP. Los clientes no deberían necesitar nunca acceder al paquete router.jar que contiene al propio router I2P y el lado-del-router de I2CP. También hay una implementación en librería C. Un cliente no-Java también tendría que implementar la librería de streaming para conexiones estilo-TCP.

Las aplicaciones pueden aprovecharse de la base I2CP además de las librerías streaming y datagram mediante el uso de los protocolos Mensajería Anónima Simple (SAM) o BOB, que no requieren clientes para tratar con cualquier clase de criptografía. Además, los clientes pueden acceder a la red por uno de los varios proxys - HTTP, CONNECT, y SOCKS 4/4a/5. A modo de alternativa, los clientes Java pueden acceder a esas librerías en ministreaming.jar y streaming.jar. Así que hay varias opciones para aplicaciones tanto Java como no-Java.

El cifrado extremo-a-extremo del lado-del-cliente (cifrando los datos sobre la conexión I2CP) fue deshabilitado en la versión 0.6 de I2P, dejando en su lugar un cifrado extremo-a-extremo ElGamal/AES que está implementado en el router. La única criptografía que las librerías del cliente todavía deben implementar es la firma de la clave publico/privada DSA (algoritmo de firma digital) para LeaseSets (grupo de túneles para un destino) y Configuraciones de sesión, y la gestión de esas claves.

En una instalación I2P estándar, el puerto 7654 es usado por clientes de Java externos para comunicarse con el router local vía I2CP. Por defecto, el router se liga a la dirección 127.0.0.1. Para ligarse a 0.0.0.0, establezca la opción de la configuración avanzada del router i2cp.tcp.bindAllInterfaces=true y reinicie. Los clientes en la misma JVM (Máquina Virtual Java), pasan los mensajes directamente al router a través de una interfaz JVM interna.

El router I2P también soporta conexiones externas sobre SSL. Aunque SSL no está habilitado por defecto, se recomienda encarecidamente para cualquier tráfico que pueda estar expuesto a la Internet abierta. La autorización usuario/contraseña (si la hay), la clave privada y la clave privada firmante para el destino, son todas transmitidas tal-cual a menos que SSL esté habilitado.

Especificación del protocolo I2CP

Ahora sobre la página de la Especificación I2CP.

Inicialización I2CP

Cuando un cliente conecta con el router, primero envía un único byte de versión de protocolo (0x2A). Entonces envía un mensaje GetDate (obtener fecha) y espera la respuesta del mensaje SetDate (configurar fecha). A continuación, envía un mensaje CreateSession (crear sesión) conteniendo la sesión de configuración. Seguidamente espera un RequestLeaseSet Message (mensaje de solicitud de LeaseSet) desde el router, indicando que los túneles de entrada han sido erigidos y responden con un CreateLeaseSetMessage (mensaje de creación de LeaseSet) conteniendo el LeaseSet firmado. El cliente puede ahora iniciar o recibir conexiones desde otros destinos I2P.

Opciones de I2CP

Opciones del lado-del-router

Las siguientes opciones se pasan tradicionalmente al router a través de un SessionConfig (configuración de la sesión) contenida en un mensaje CreateSession (crear sesión) o un Mensaje ReconfigureSession (reconfiguración de sesión).

Opciones del lado-del-router
Opción Desde la versión Parámetros recomendados Rango permitido Valor predeterminado Descripción
clientMessageTimeout     8*1000 - 120*1000 60*1000 El tiempo de espera (ms) para todos los mensajes enviados. No usado. Vea la especificación del protocolo para configuraciones por-mensaje.
crypto.lowTagThreshold 0.9.2   1-128 30 Número mínimo de etiquetas de sesión ElGamal/AES antes de que enviemos más. Recomendado: aproximadamente 'tagsToSend * 2/3'
crypto.tagsToSend 0.9.2   1-128 40 Número de etiquetas de sesión ElGamal/AES para enviar de golpe. Para los clientes con anchos de baja relativamente bajos para el par cliente (IRC, algunas aplicaciones UDP), esto valor puede ser más bajo.
explicitPeers       null Lista separada por comas de los Hashes Base 64 de los pares con los que construir túneles para pasar a través; sólo para depuración
i2cp.dontPublishLeaseSet   true, false   false Generalmente suele ser verdadero para los clientes y falso para los servidores
i2cp.fastReceive 0.9.4   true, false false Si es verdadero, el ruter simplemente envía el MessagePayload, en lugar de enviar MessageStatus y esperar por un ReceiveMessageBegin.
i2cp.messageReliability     BestEffort, None BestEffort Asegurarse de que está desactivado; None fue implementado en 0.8.1; la librería de straming por defecto es None como en 0.8.1, la parte cliente es None como en 0.9.4
i2cp.password 0.8.2 string     Para la autorización, si es requerida por el router. Si el cliente está ejecutandose en la misma JVM (máquina virtual Java) que el router, no se requiere esta opción. Advertencia - el nombre de usuario y la contraseña se envían en claro al router, a menos que se use SSL (i2cp.SSL=true). La autorización sólo está recomendada cuando se usa SSL.
i2cp.username 0.8.2 string    
inbound.allowZeroHop   true, false   true Si es de entrada están permitidos los túneles de cero saltos
outbound.allowZeroHop   true, false   true Si es de salida están permitidos los túneles de cero saltos
inbound.backupQuantity   número desde 0 hasta 3 Sin límite 0 Número de túneles de respaldo (`fail-over`) redundantes para túneles entrantes
outbound.backupQuantity   número desde 0 hasta 3 Sin límite 0 Número de túneles de respaldo (`fail-over`) redundantes para túneles salientes
inbound.IPRestriction   número desde 0 hasta 4 0 a 4 2 El número de bytes de la IP para comparar y determinar si los dos ruters están en el mismo túnel. 0 para deshabilitarlo
outbound.IPRestriction   número desde 0 hasta 4 0 a 4 2 El número de bytes de la IP para comparar y determinar si los dos ruters están en el mismo túnel. 0 para deshabilitarlo
inbound.length   número desde 0 hasta 3 0 a 7 3 Longitud de túneles de entrada.
outbound.length   número desde 0 hasta 3 0 a 7 3 Longitud de túneles de salida..
inbound.lengthVariance   número desde -1 hasta 2 -7 a 7 0 Cantidad aleatoria a añadir o sustraer a la longitud de los túneles entrantes. Un número positivo significa añadir una cantidad aletoria de 0 a x ambos incluidos. Un número negativo -x significa añadir una cantidad aleatoria de -x a x ambos incluidos. El router limitará la longitud total del túnel de 0 a 7 ambos incluidos. La varianza por defecto era 1 antes de la versión 0.7.6.
outbound.lengthVariance   número desde -1 hasta 2 -7 a 7 0 Cantidad aleatoria a añadir o sustraer a la longitud de los túneles salientes. Un número positivo x significa añadir una cantidad aleatoria de 0 a x ambos incluidos. Un número negativo -x significa añadir una cantidad de -x a x ambos incluidos. El router limitará la longitud total del túnel de 0 a 7 ambos incluidos. La varianza por defecto era 1 antes de la versión 0.7.6.
inbound.nickname   string     Nombre del túnel - usado por lo general en routerconsole, que usara los primeros pocos caracteres del identificador criptográfico (`hash`) Base64 del destino por defecto.
outbound.nickname   string     Nombre del túnel - ignorado por lo general a menos que inbound.nickname (apodo entrante) no esté establecido.
outbound.priority 0.9.4 número desde -25 hasta 25 -25 a 25 0 Ajustes de prioridades para los mensajes de salida. Más alto indica más prioridad.
inbound.quantity   número desde 1 hasta 3 1 a 16 2 Número de túneles entrantes. El límite fue elevado de 6 a 16 en la versión 0.9; sin embargo, números superiores a 6 son incompatibles con versiones anteriores.
outbound.quantity   número desde 1 hasta 3 Sin límite 2 Número de túneles hacia fuera
inbound.randomKey 0.9.17 Base 64 encoding of 32 random bytes     Se usa para mantener consistente el orden de los pares (peers) entre reinicios.
outbound.randomKey 0.9.17 Base 64 encoding of 32 random bytes    
inbound.*         Cualquier otra opción con el prefijo "inbound" es almacenada en las "opciones desconocidas" del grupo de configuraciones del túnel de entrada.
outbound.*         Cualquier otra opción con el prefijo "outbound" es almacenada en las "opciones desconocidas" del grupo de configuraciones del túnel de salida.
shouldBundleReplyInfo 0.9.2 true, false   true Configúrela a 'falso' para deshabilitar que se llegue a empaquetar un LeaseSet de respuesta. Para los clientes que no publican su LeaseSet (túneles a su destino I2P), esta opción debe marcarse verdadera para que las repuestas sean posibles. También se recomienda 'verdadero', para los servidores multi-hospedados (multihoming) con tiempos de conexión largos.

Poniéndolo en "false", falso, puede ahorrar bastante ancho de banda de salida, especialmente si el cliente está configurado para usar un gran número de túneles de entrada (Leases). Si las respuestas son aún necesarias, esto puede cambiar la carga a el cliente más lejano final y en el floodfill. Hay varios casos donde "false" podría ser apropiado:

  • Dirección unidireccional, no se necesita respuesta
  • El LeaseSet está publicado y un latencia de respuesta mayor es aceptable
  • El LeaseSet está publicado, el cliente es un "servidor", todas las conexiones son de entrada, por lo que la destinación lejana que se está conectanda ya tiene el leaseset, obviamente. Las conexiones o son cortas, o son aceptables para la latencia o conexiones de larga duración para incrementar temporalmente mientras que la otra descarga de nuevo el LeaseSet después de expirar. Los servidores HTTP puede encajar en estos requerimientos.

Nota: Una gran cantidad de configuraciones, el tamaño o variaciones en las configuraciones pueden causar bastantes problemas en el rendimiento o fiabilidad.

Nota: Desde la versión 0.7.7, los nombre y valores de las opciones deben usar codificación UTF-8. Esto es útil principalmente para los nicknames ('apodos'). Con anterioridad a esta versión, la opciones con caracteres multi-byte estaban corruptas. Como estas opicones están codificadas en un mapeado, los nombres de todas las opciones y valores están limitados a un máximo de 255 bytes (no caracteres).

Opciones de la parte cliente

Las siguientes opciones son interpretadas por la parte cliente, y serán interpretadas si pasan a la I2PSession a través de la llamada I2PClient.createSession(). La librería de streaming también debería pasar estas opciones a través de I2CP. Otras implementaciones pueden tener otros valores por defecto.

Opciones de la parte cliente
Opción Desde la versión Parámetros recomendados Rango permitido Valor predeterminado Descripción
i2cp.closeIdleTime 0.7.1 1800000 mínimo 300000   (ms) tiempo inactivo requerido (por defecto 30 minutos)
i2cp.closeOnIdle 0.7.1 true, false   false Cerrar las sesiones I2P cuando esté inactivo
i2cp.encryptLeaseSet 0.7.1 true, false   false Cifrar el lease
i2cp.fastReceive 0.9.4   true, false true Si es verdadero, el ruter simplemente envía el MessagePayload, en lugar de enviar MessageStatus y esperar por un ReceiveMessageBegin.
i2cp.gzip 0.6.5 true, false   true Gzip los datos de salida
i2cp.leaseSetKey 0.7.1       Para leasesets cifrados. SessionKey (clave de sesión) Base 64 (44 caracteres)
i2cp.leaseSetPrivateKey 0.9.18       Clave privada base 64 para cifrado. Precedida opcionalmente por el tipo de clave y ':'. Sólo está soportado "ELGAMAL_2048:", que es el predeterminado. I2CP generará la clave pública desde la clave privada. Se utiliza para claves persistentes de leasesets entre reinicios.
i2cp.leaseSetSigningPrivateKey 0.9.18       Clave privada Base 64 para firmas. Precedido opcionalmente por el tipo de clave y ':'. DSA_SHA1 es la predeterminada. El tipo de clave tiene que coincidir con el tipo de firma en el destino I2P. I2CP generará la clave pública desde la clave privada. Se utiliza para claves persistentes de leasets entre reinicios.
i2cp.messageReliability     BestEffort, None None Asegurarse de que está desactivado; None fue implementado en 0.8.1; None es el valor por defecto en 0.9.4
i2cp.reduceIdleTime 0.7.1 1200000 mínimo 300000   (ms) el tienpo inactivo requerido (por defecto 20 minutos, mínimo 5 minutos)
i2cp.reduceOnIdle 0.7.1 true, false   false Reducir la cantidad de túneles cuando está inactivo
i2cp.reduceQuantity 0.7.1 1 1 a 5 1 Cantidad de túneles cuando se reduce el número (se aplica tanto a los de entrada como a los de salida)
i2cp.SSL 0.8.3 true, false   false Conectar con el ruter usando SSL. Si el cliente se está ejecutando en la misma JVM que el ruter esta opción es ignorada, y el cliente conecta con el ruter internamente.
i2cp.tcp.host       127.0.0.1 Hostname del ruter. Si el cliente se ejecuta en la misma JVM como un ruter, esta opción es ignorada, y el cliente se conecta al ruter internamente.
i2cp.tcp.port     1-65535 7654 Puerto I2CP del ruter. Si el cliente se ejecuta en la misma JVM como un ruter, esta opción es ignorada, y el cliente se conecta al ruter internamente.

Nota: todos los argumentos, incluyendo los números, son cadenas de caracteres. Los valores True/false son cadenas de caracteres y son sensibles a las mayúsculas o minúsculas. Cualquier otro que no sea "true" en minúsculas será interpretado como falso. Todas los nombres de opciones son sensibles a las mayúsculas/minúsculas.

Formato de los datos del payload I2CP y de Multiplexing

El mensaje de fin a fin manejado por I2CP (por ejemplo los dato enviados por el cliente en el SendMessageMessage y recibido por el cliente en un MessagePayloadMessage) están comprimidos con gzip con una cabecera de inicio de 10 bytes con 0x1F 0x8B 0x08 como se especifica en el RFC 1952. A partir de la versión 0.7.1, I2P usa partes ignoradas de la cabecera gzip para incluir el protocolo, el puerto desde, y la información del puerto hacia, con lo que se soporta streamings y datagramas en la misma destinación, y permite peticiones/respuestas usando datagramas para trabajar fiable en presencia de múltiples canales.

La función gzip puede apagarse completamente, aunque si se pone la opción i2cp.gzip=false, se cambia el valor de esfuerzo de gzip a 0, lo que puede ahorrar un poco de CPU.

Bytes Contenido
0-2 Cabecera gzip 0x1F 0x8B 0x08
3 Opciones de gzip
4-5 Puerto de origen I2P (mtime de Gzip)
6-7 Puerto de destino de I2p (mtime de Gzip)
8 Zflags de Gzip
9 Protocolo I2P (6= Streaming, 17 = Datagram, 18 = Raw Datagrams) (OS de Gzip)

Note: I2P protocol numbers 224-254 are reserved for experimental protocols. I2P protocol number 255 is reserved for future expansion.

La integridad de los datos es verificada con el estándar gzip CRC-32 como es especificado por el RFC 1952.

Trabajo futuro

C library implementation