La historia

Año 2012, los habitantes de Internet han desarrollado herramientas para distribuir información entre redes de pares, desde los enormemente extendidos (eDonkey y BitTorrent) a otros algo menos, de los que solo se preocupan de repartir información a los que se centran comprometer lo mínimo a los extremos (GNUnet y Freenet), de los que solo distribuyen archivos a los que conforman una capa sobre la que se pueden erigir otros protocolos (I2P).

Se han llegado a encontrar formas de coordinar toda esa nube de máquinas de forma distribuida, sin puntos centrales, con Tablas hash distribuidas. Incluso se ha conseguido llegar a una forma de identificar la forma de alcanzar la información con la llegada de los enlaces magnéticos que permitian representar un archivo en una de estas redes.

... viendo esto uno no puede dejar de sorprenderse al darse cuenta de que si, todo genial, pero para empezar uno necesita ese enlace y ¡oh! para eso hay que obtenerlo de una fuente, una página web probablemente, toda la red está distribuida menos la entrada.

Nota: bien, esto no es del todo cierto, eDonkey permite realizar búsquedas... pero todos conocemos su fiabilidad, ¿verdad?

La idea

Necesitamos una red para compartir enlaces, debe ser distribuida y a ser posible soportar una red de confianza (Web of trust) para evitar la contaminación de los enlaces sin necesidad de una moderación activa.

El prototipo/experimento

Nota: Vaya por delante que es una idea con muchos defectos pero todos sabemos como van estas cosas, lo importante es arrancar, después ya habrá tiempo de rectificar.

La parte cliente: lnet.zip (requiere pygtk)
El servidor: http://pastebin.com/3RALJEpi
La sentencia para crear la tabla:

1
2
3
4
5
6
7
CREATE TABLE `links` (
    `sent_by` varchar(256) DEFAULT NULL,
    `title` varchar(256) NOT NULL,
    `sent_on` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `url` varchar(256) NOT NULL,
    `signature` char(40) DEFAULT NULL
);

Bien, antes de seguir reconozco que separar cliente y servidor en una supuesta red P2P tiene mala pinta (ya no solo el proceso, sinó el lenguaje y que uno funcione con GUI y otro como una página de un servidor web :/. Y que estén a medio acabar solo lo deja peor (ninguno de los dos comprueba la firma de los links que recibe).

El "protocolo" es bien sencillo, funciona sobre HTTP, y definiría dos tipos de interacción, la petición de cambios y la adición de un cambio. Para hacer una petición de cambios un par se conecta a otro (supongamos que ejemplo.com/links.php) y hace una petición HTTP activando el parámetro changes y (opcionalmente) ajusta since como el momento UNIX a partir del cual se quieren los cambios, por ejemplo si es la primera vez que se hace la petición (todos los cambios, desde 0) se traduciría en ejemplo.com/ links.php?changes&since=0.

Como respuesta el servidor devolvería un conjunto de cambios, que podrían ser la adición de un enlace:

1
2
3
4
5
6
7
ADD  
title: <título>  
url: <enlace>  
sent_on: <momento de emisión>  
sent_by: <emisor, "none" si no está firmado>  
signature: <firma de "$title\n$url\n$sent_by\n$sent_on", o "none">  
.

La eliminación de un enlace (el efecto práctico sería el retiro de la firma):

1
2
3
4
5
6
7
DEL  
sent_on: <momento de emisión de la orden de eliminación>  
title: <título>  
url: <enlace>  
sent_by: <emisor de la orden>  
signature: <firma de "DEL\n$title\n$url\n$sent_by\n$sent_on">  
.

La firma de una clave por parte de otra (X firma/confía en Y):

1
2
3
4
5
SIGN  
signed_key: <clave firmada>  
signer_key: <clave que firma>  
signature: <firma de "SIGN\n$signed_key\n$signer_key">  
.

La revocación de una firma de una clave (X ya no firma/confía en Y): lo mismo que la firma (sign/unsign).

Como decía antes, también se podría enviar cambios a un nodo pero como con lo anterior solo está implementado la adición de enlaces, enviando a ejemplo.com/links.php?add por POST los parámetros

1
2
3
4
sender: <emisor o "none">  
link: <enlace>  
timestamp: <momento de emisión>  
signature: <firma como se definió en cambios `ADD`>

Esta última parte está especialemente descuidada, como mínimo habría que normalizar los nombres de los campos con los de los cambios :/.

Ventajas e inconvenientes de esta aproximación

El basar el protocolo en HTTP tiene sus ventajas, hay librerías para aburrir, de servidor o de cliente, todo el mundo lo conoce, se ríe de los firewall y no requiere un entorno especifico, cualquier servidor web podría ser un nodo.

Sin embargo otras cosas no son tan bonitas, aunque ya no sea por culpa de HTTP, este modelo lo que hace es que cada nodo tenga toda la colección de enlaces (bueno, o si se limitan a los en que confía menos), es bastante resistente, pero parece poco escalable a la larga. Por esto creo que sería interesante buscar la forma de distribuir los enlaces en una especie de DHT y después permitir a los pares hacer búsquedas sobre la red mandando una petición.

EOF

Enfin, hasta ahí he llegado, supongo que no es necesario decir que cualquier idea y/o ayuda sería muy de agradecer :)

Saludos