Copy Link
Add to Bookmark
Report
SET 028 0x08
-[ 0x08 ]-------------------------------------------------------------------
-[ Cinco horas con Fred ]---------------------------------------------------
-[ lindir ]---------------------------------------------------------SET-28--
Cinco horas con Fred
Por Lindir
0. Contenidos
- -------------------------------------------------------------------------
1. Quien es Fred?
2. Como se habla con Fred?
3. Como accedemos a Freenet?
4. Como es Fred?
4.1. URIs y claves.
4.1.1 http://localque????
4.2. Mejoras al sistema.
4.2.1. Archivos de mapa o manifiestos.
4.2.2. Ediciones de un freesite.
4.2.3. DBRs.
4.2.4. Splitfiles.
4.2.5. FEC.
5. Las entrañas de Fred.
5.1. FNP.
5.1.1. Requerimientos a la capa de transporte.
5.1.2. Capa de sesion criptografica. (FNP/S)
5.1.2.1. Inicio de sesion. (Full Handshake)
5.1.2.1.1 Generalidades.
5.1.2.1.2. PCFB (Periodic Cipher FeedBack).
5.1.2.1.3. Establecimiento del enlace.
5.1.2.2. Reinicio de sesion (Restart Handshake).
5.1.3. Capa de presentacion/mensajes (FNP/P)
5.1.3.1. Formato general de los mensajes.
5.1.3.2. Representaciones estandar.
5.1.3.3. Campos especiales.
5.1.3.4. Mensajes Especiales.
5.1.3.5. Resumenes de Fieldset y firmas.
5.1.4. Capa de aplicacion.
5.1.4.1. Conceptos generales.
5.1.4.1.1. Identificador de mensaje (UniqueID).
5.4.1.2. Referencias a nodos (node references).
5.4.1.3 Datos.
5.4.1.4 Claves.
5.4.1.4.1. Similitud entre claves.
5.4.1.4.2. Tipos de claves y validacion de datos.
5.4.1.4.2.1. Content Hash Keys (CHK).
5.4.1.4.2.2. Signature Verifying Key (SVK).
5.4.1.4.2.3. Otras claves.
5.4.1.5. Elementos de los nodos.
5.4.1.5.1. Memoria de transacciones.
5.4.1.5.2. Tabla de enrutado.
5.4.1.5.3. Almacen de datos (Data Store).
5.4.1.5.4. Temporizador.
5.4.1.6. Preguntas (Queries).
5.4.1.6.1. Enrutando preguntas.
5.4.1.6.2. Peticiones (Requests).
5.4.1.6.2.1. Enrutado de peticiones.
5.4.1.6.2.2. Transferencia de datos.
5.4.1.6.2.3. Peticiones de insercion (InsertRequest).
5.4.1.6.2.4. Peticiones de recuperacion de datos (DataRequest).
5.4.1.6.2.5. Mensajes StoreData.
5.4.1.6.3. Anuncios (Announcement queries).
5.4.1.6.3.1. Enrutado de anuncios.
5.4.1.6.3.2. Anuncio de un nodo.
6. Amigos y parientes de Fred.
6.1. FCPTools.
6.2. FMB.
6.2.1. Canales y mensajes.
6.2.2. Archivos.
6.2.3. Informacion sobre los usuarios.
6.2.4. Ajedrez.
6.2.5. Anuncios de freesites.
6.2.6. El problema de las 00:00:00.
6.3. NIM.
6.4. El proyecto Invisible IRC.
6.5. Entropy.
6.6. JAP (Java Anonymous Proxy).
7. Lo que sabe Fred.
8. Conclusiones.
- -------------------------------------------------------------------------
1. Quien es Fred?
Fred (Freenet REference Daemon) es el nombre del programa Java que actua
como cliente/servidor para acceder a la red Freenet. La version mas moderna
de FreD en el momento de escribir estas lineas es la 0.5.2, que podeis
obtener ya precompilada de la direccion: Freenet.sourceforge.net
Fred actual como gateway personal y router dentro de la propia red.
Puesto que esta hecho en Java solo necesitais una maquina virtual Java que
sea compatible (hay problemas de incompatibilidad con algunas maquinas
virtuales) en tu sistema operativo.
Bajo linux (que es el sistema con el que he realizado las pruebas) arrancar
Fred es tan sencillo como ejectuar "sh start-freenet.sh". El propio script
start-freenet se ocupa de todo lo necesario. Para pararlo, basta con ejecutar
mas tarde "sh stop-freenet.sh". El script de inicio almacena el PID del
proceso en el archivo freenet.pid, asi que no toques ese archivo si quieres
pararlo con stop-freenet (si lo tocas, vas a tener que pararlo a mano con un
kill).
La primera vez que se ejecute Fred se iniciara la configuracion del mismo,
mediante una serie de preguntas a las que el usuario debe contestar. Entre
ellas estan los limites sobre el regimen binario que Fred debe mantener, el
tamaño de la cache en disco duro y la mas importante: si el nodo es de tipo
transitorio (transient) o no. Un nodo transient es aquel que no puede estar
continuamente conectado a la red, de modo que no es completamente funcional
a la hora de actuar como servidor/router. Los autores y desarrolladores de
Freenet ruegan a toda persona que considere que la red merece la pena y que
pueda permitirselo que mantengan nodos fijos de modo que la red sea mayor.
En mi caso, yo no tengo conectado todo el dia el PC a la red, por lo tanto
mi nodo comenzo siendo de tipo transient pero ahora es permanente. Si vas a
hacer pruebas es mejor que lo configures transient hasta que consideres si
de verdad deseas formar parte de Freenet de forma permanente.
Durante la configuracion tambien se pide una lista de nodos "semilla" (seed
nodes) que no son mas que nodos fijos en la red a los que conectarse, algo
asi como la lista de servers en el e-Donkey. El archivo que contiene esta
lista es seednodes.ref, que debe estar en el paquete bajado de sourceforge.
Toda la configuracion de Fred se almacena en el archivo freenet.conf, que
puedes editar a mano si deseas cambiar algo mas tarde. Tendras que arrancar
Fred de nuevo si quieres que la nueva configuracion entre en funcionamiento.
En Windows, dicho archivo se llama freenet.ini. Por cierto que para el que
quiera retocarlo a mano, hacer notar que las lineas que comiencen con el
caracter % tambien son comentarios (ademas de las que comienzan por #), no os
pase que creais haber cambiado algo pero no sea asi (como le paso a servidor).
2. Como se habla con Fred?
Una vez configurado y corriendo Fred, ya podemos conectarnos a Freenet. Y la
pregunta es... como se hace? Sencillo. Lo primero que debemos hacer es dejar
pasar un pequeño tiempo (un minuto bastara normalmente) para que Fred sea
capaz de encontrar nodos a los que pueda conectarse.
En la distribucion de Freenet se incluye FProxy, que no es mas que otro
programa java que actua como un proxy server y que se queda a la escucha
de conexiones en el puerto tcp 8888 del host local. Gracias a FProxy, acceder
a los contenidos de Freenet es tan sencillo como arrancar un navegador Web
cualquiera y realizar una conexion a http://localhost:8888.
En este punto aparece el interfaz Web de Fred (si no aparece, espera un poco
mas y reintenta la conexion, posiblemente aun la red no este operativa). Este
interfaz nos permite monitorizar el funcionamiento de la red: lista de
conexiones, estadisticas sobre las peticiones y las claves, etc. Tambien da
informacion sobre las opciones en linea de comandos que podemos pasar a Fred y
sobre la version del software, la maquina virtual Java... es bastante completo.
Podeis hacer que otros usuarios puedan acceder a Freenet a traves de vuestro
nodo utilizando conexiones directas al puerto FCP o mediante FProxy (con el
propio navegador). Todo ello es configurable en el fichero freenet.conf. Tened
en cuenta que si accedeis a Freenet mediante un proxy de este estilo habreis
perdido todo el anonimato, puesto que el dueño del proxy sabe que habeis
pedido y cual es la IP origen. Por ello -entre otras razones- se desaconseja
este metodo de acceso. Añado aqui una pequeña lista (no comprobada
completamente) de hosts con FProxy abierto al resto de internet:
https://freenet.homelinux.net:443
https://freenet.firenze.linux.it:1443
https://bespin.homelinux.net:443
http://freenet.leafgroup.net/
https://freenet.thing.net:443
3. Como accedemos a Freenet?
Vale, hasta ahora tenemos a Fred en nuestro ordenador y podemos monitorizar
que esta haciendo. Pero todavia no hemos accedido a ningun "freesite". Para
que podamos empezar, el propio interfaz web de Fred nos muestra unos
"bookmarks" a los que podemos conectarnos. En mi version de Fred aparecen
"The Freedom Engine", "The Freenet Help Index", "The Tower", "Content of Evil"
y "YoYo!". Todos (menos Content of Evil, alias CofE) son "freesites" que
almacenan enlaces a otros sitios dentro de Freenet. Podemos por ejemplo
acceder a "The Freedom Engine". De todas formas, estos bookmarks son
configurables por si quereis correr un nodo con FProxy abierto o simplemente
para vuestra comodidad.
Si seleccionais el enlace, posiblemente os deis cuenta de que tarda bastante
en acceder a la pagina (y bastante es *bastante*, puede que varios minutos).
Esto es asi porque no sabemos donde esta la misma, y hay que lanzar peticiones
a lo largo de la red hasta que alguien conteste. Y eso tarda. Incluso puede
ocurrir que aparezca una pagina (procedente de FProxy) que nos indique que no
se ha podido encontrar la informacion. En tal caso, se ofrece la opcion de
volver a intentarlo modificando el numero de "Hops To Live". Si os ha ocurrido
esto, cambiad el numero de Hops To Live (por ejemplo, a 25) y pulsad el boton
de reintentar la busqueda. Puesto que The Freedom Engine es un freesite muy
solicitado, deberiais poder acceder a el.
NOTA: la configuracion por defecto impide que el numero de HTL sea superior a
25, asi que aunque asigneis un valor mayor a dicho campo no conseguireis
aumentarlo en realidad. Aunque este parametro tambien es configurable, de nada
sirve aumentarlo, salvo para perder vuestro anonimato: la mayor parte de los
nodos esta con la configuracion por defecto, asi que si un nodo recibe una
peticion con HTL > 25, lo mas probable es que el nodo que la realiza sea el
consumidor de dicha informacion (es altamente improbable que haya pasado por
dos nodos con HTLmax configurado a mas de 25). Asi que no toqueis este valor
de la configuracion porque no os hareis ningun bien ni a Freenet tampoco. El
que quiera saber mas sobre este tema, que mire la "Anti-FAQ" de fish en:
SSK@kWu5Osv~VAI3-kH7z8QIVxklv-YPAgM/antifaq/7//
Bueno, ya estamos dentro de nuestro primer freesite. Ahora que? Seguro que os
habeis dado cuenta de que vuestro navegador tarda muchisimo en cargar toda la
pagina al completo. No os preocupeis mucho por las fotos y mirad los enlaces.
En TFE (The Freedom Engine) estan divididos en dos secciones principales:
sites de reciente creacion y paginas consolidadas. Podeis intentar acceder a
cualquiera de los freesites a los que TFE enlaza. (NOTA: tambien hay otras
secciones con freesites dificiles de obtener y freesites retirados, pero no
las recomiendo para principiantes.)
Ademas de una breve descripcion del contenido -para que no os lleveis
sorpresas desagradables, dado que hay libertad *total* en Freenet para
publicar lo que se desee- TFE indica si el freesite es estatico (One Shot
Freesite), con distintas ediciones (Edition Freesite) o si se actualiza de
forma continua (DBR Freesite). Si es de tipo Edition a veces lo que se indica
es cuando fue la ultima actualizacion. Las DBR y las ediciones seran
comentadas mas adelante, no te preocupes si no entiendes nada de esto ahora.
En algunos casos (pocos, segun mi experiencia) la pagina aparecera a los
pocos segundos/minutos. En otros aparecera el mensaje indicando que no se ha
podido encontrar el freesite y podremos cambiar los Hops To Live a un numero
mayor y, con un poco de suerte, finalmente obtener la informacion. En otros
(haberlos haylos) simplemente no podremos acceder a lo que queremos. Esa es
precisamente una de las principales diferencias entre Freenet y la World Wide
Web: no siempre podremos acceder a lo que queremos y la informacion puede
desaparecer de la red.
4. Como es Fred?
4.1. URIs y claves.
Otra diferencia importante con la web que de momento he obviado es el hecho de
que los archivos que obtenemos de Freenet no tienen identificadores del tipo:
http://host.domain/path/file.extension como ocurre con la web o los ftp. En
Freenet, los URIs (Uniform Resource Identifier) en Freenet son claves de tres
tipos:
- CHK (Content Hash Key)
- KSK (Keyword Signed Key)
- SSK (Signed/SVK SubSpace Key)
Estas claves no son identificadores jerarquicos como ocurre con los URIs de
la web o los numeros de telefono. Cuando Fred recibe de nosotros una peticion
lo unico que le damos es una clave, y puesto que esta clave no es jerarquica,
Fred no sabe en principio donde esta el fichero asociado a la misma. Lo unico
que puede hacer es comprobar si el fichero asociado a esa clave esta en la
cache local o, si no es asi, pasar la peticion a otros nodos de la red. En una
peticion HTTP nuestro ordenador sabe que tiene que consultar un DNS para
obtener la direccion IP del destino, y los nombres DNS estan jerarquizados,
con lo cual cada servidor DNS siempre sabe a quien debe reencaminar la
peticion en caso de no saber la respuesta. En Freenet no es asi. Se requiere
que no sea asi para no saber donde esta la informacion y garantizar el
anonimato. El algoritmo de encaminamiento es basicamente el siguiente: envia
la clave al nodo que anteriormente te haya pasado la clave mas parecida a la
que deseas. De esta forma, los nodos se "especializan" en ciertas claves que
son parecidas.
Existen otro tipo de claves (como SVK, KHK, etc.) que o bien estan obsoletas
o bien son de uso interno. Tambien se esta evaluando la posibilidad de
añadir un tipo de clave llamado TUK (Time Updatable Key o Clave Actualizable
en el Tiempo) que podria dar mayor flexibilidad para actualizar freesites
que las tecnicas actuales (DBR y ediciones, como luego veremos).
Las claves CHK tienen el mismo cometido que un checksum: evitar que un fichero
se confunda con otro. Esto es, son una firma digital de los contenidos de los
archivos de Freenet. Cada archivo que existe en Freenet tiene asociada una
clave CHK. De esta forma, si alguien intenta suplantar un archivo que hemos
subido a la red con otro distinto, los CHK de ambos seran diferentes y no
podra confundir a posibles receptores de la informacion. Cual es el problema
de dichas claves? Que cuando vemos una no sabemos que es lo que vamos a
recibir. Es decir, la clave no aporta ninguna informacion acerca del contenido
del archivo. De todas formas, Fred no necesita saber que tipo de informacion
corresponde a una clave CHK, y por ello estas claves son la base para la
informacion en Freenet. Todas las demas claves no son mas que referencias
-con nombres comprensibles para las personas- a claves CHK.
Las claves KSK son el otro extremo. Al contrario que las CHK, no son generadas
automaticamente, sino que los usuarios las crean para aportar informacion
sobre el contenido del archivo asociado. En realidad lo unico que contiene
una clave KSK es una referencia a la CHK correspondiente. Cual es el problema
con estas claves? Pues que no son unicas. Cualquiera puede crear una clave
KSK que en realidad contenga una referencia a una CHK erronea. El ejemplo mas
famoso que hay es la clave KSK@gpl.txt. En principio esta clave contenia una
referencia a una clave CHK bajo la que habia una version en ASCII del texto de
la licencia GPL de la Free Software Foundation. Hubo personas que intentaron
insertar referencias a otras claves CHK (y, por tanto, a otros archivos) y lo
consiguieron. Ahora, si intentas obtener el archivo asociado a la clave
KSK@gpl.txt puede ser que recibas el texto de la licencia GPL u otras cosas
(el resultado de esta operacion se deja a la comprobacion del lector, quiza
dicho resultado le parezca mas interesante... :-)
Por ultimo, las claves SSK son las que permiten mayor potencia. Una clave SSK
consiste en realidad en una pareja clave publica-clave privada que puede ser
generada por varios programas (el propio archivo .jar de Fred contiene una
utilidad que lo hace). Cuando queremos introducir un archivo en Freenet,
utilizamos una entrada:
SSK@<private_key>/<path>/file.ext
Y para obtener el archivo nuestros receptores deberan usar:
SSK@<public_key>/<path>/file.ext
Las claves SSK son espacios privados donde poner claves KSK. Para que los
receptores de tu informacion puedan obtenerla, les das tu clave publica. Pero
la clave privada, que es la que te permite añadir nuevos contenidos, solo la
conoces tu.
4.1.1 http://localque????
Posiblemente alguien piense que las claves en Freenet tienen el formato:
http://localhost:8888/<tipodeclave>@<clave>[/<ruta><archivo>]
Los corchetes indican partes opcionales segun el tipo de clave.
Debe quedar claro que "http://localhost:8888/" NO FORMA PARTE DE LA CLAVE.
Las peticiones se hacen asi porque el navegador habla http directamente con
FProxy (que en este caso esta en localhost, puerto 8888). Si utilizais
clientes FCP (como por ejemplo, el FIW) nunca tendreis que añadir esa parte.
El formato autentico de claves Freenet es:
[freenet:]<tipodeclave>@<clave>[/<ruta><archivo>]
Normalmente "freenet:" se obvia.
Supongamos que creamos un freesite y enlazamos a otros archivos del mismo
freesite, o a otros freesites, o utilizamos imagenes con <img> y añadimos
a los URIs "http://localhost:8888/" Que ocurrira? Pues que si alguien
quiere conectarse a traves de un FProxy abierto (incluyo una pequeña lista)
porque -puede ser- no desea/no puede mantener un nodo -transitorio o
permanente- Freenet, no funcionaran esos enlaces ni esas imagenes para el.
Por que? Porque el navegador realizara la peticion a la maquina local -que
no esta corriendo FProxy- y esta rechazara la conexion (Ay ay ay!!!).
Todos los enlaces a archivos de Freenet deben incluirse como CLAVES VALIDAS
(sin http: bla bla) para que el navegador realice la peticion al host sobre
el que corre FProxy. Cuando usamos FProxy asi, el navegador cree que *todos*
los archivos se encuentran la maquina sobre la que este corre (y de hecho,
una vez FProxy los pide es asi) de forma que al introducir las claves como
enlaces relativos se hacen las peticiones de forma correcta y transparente
al usuario, no importa si el host con FProxy es el host local o es remoto.
Ademas, el filtro de proteccion del anonimato nos avisa cada vez que
intentamos utilizar un enlace que comienza por http://, y es un verdadero
coñazo tener que cargar la pagina de aviso y pulsar el boton para cada
enlace, asi que espero potenciales creadores de freesites no me sean
chapuceros y hagan las cosas de forma correcta. :D
4.2. Mejoras al sistema.
Mediante las claves SSK ya podemos tener freesites a los que unicamente
nosotros podemos añadir nuevos archivos y que ademas den una idea de que
es lo que el usuario se esta bajando. Pero aun se puede mejorar el sistema
mucho mas. Para ello, se introducen metadatos (metadata). Los metadatos son
introducidos por Freenet junto con los archivos insertados de forma que
aportan mas informacion al cliente de lo que esta recibiendo, o incluso
pueden servir para redireccionar la peticion a otro archivo.
Si quereis podeis ver los metadatos asociados a un fichero podeis hacerlo
directamente con la distribucion de Freenet. Para ello hay que escribir:
java -cp <directorio de freenet>/freenet.jar freenet.client.cli.Main
get --noredirect <clave> <archivo>.
Por ejemplo, supongamos que queremos ver los metadatos asociados al archivo
con clave (nota: utilizo el caracter de escape \ para indicar que la orden
continua en la siguiente linea):
SSK@55pgy08Cs7yxQyOttrflL8RGZVcPAgM,W6k8nbDP~T9StSHXQg5D9g\
/freenet_set27_lindir.txt
La orden seria entonces:
java -cp freenet.jar freenet.client.cli.Main get --noredirect \
SSK@55pgy08Cs7yxQyOttrflL8RGZVcPAgM,W6k8nbDP~T9StSHXQg5D9g\
/freenet_set27_lindir.txt freenet_set27_lindir.txt
4.2.1. Archivos de mapa o manifiestos.
Los mapas (Map Files) o manifiestos (manifests) son archivos puros de
metadatos que contienen las claves CHK de otros archivos. El objetivo de los
manifiestos es acelerar la carga de un freesite reduciendo el numero de
busquedas que FProxy tiene que hacer. Me explico:
Supongamos que hemos creado un freesite, que en general sera una pagina HTML
con enlaces a otras paginas/archivos y con graficos (i.e. el fondo) etc.
dentro de un mismo espacio de claves SSK (lo mas comun). Estos enlaces a
otros archivos generalmente los añadimos como enlaces a su clave SSK (o
mediante una clave KSK menos segura, por lo tanto todo lo que sigue vale
para claves SSK o KSK).
De forma que, para cargar el contenido de una pagina y su fondo (una imagen),
FProxy tendria que buscar la clave SSK de la pagina, la cual le daria la clave
CHK asociada. Despues tendria que buscar esta clave CHK, obteniendo el texto
HTML de la pagina. Pero ese texto tendria un enlace hacia otro archivo (la
imagen de fondo) mediante otra clave SSK que FProxy tendra que obtener de la
red para conseguir la clave CHK asociada a este nuevo archivo y, mediante
esta clave CHK, obtener los datos del archivo (los datos de la imagen en este
caso). Por lo tanto en este caso han sido necesarias cuatro consultas.
Para evitar esto lo que se hace es lo siguiente: se tiene un manifiesto con
todas las claves CHK del sitio, y se se utiliza este manifiesto (que solo hay
que bajar de Freenet una vez) para realizar todas las busquedas, con lo cual
se elimina el paso de obtener las claves SSK.
En versiones antiguas de Fred se utilizaba la sintaxis MSK@SSK@<key>/<file>
para realizar la busqueda mediante el manifiesto. La sintaxis actual es mas
sencilla (recordar que tambien vale para claves KSK):
SSK@<clave>/<mapfile>//<file>.
Si FProxy recibe una peticion de este estilo, intentara obtener el manifiesto
con clave SSK@<clave>/<mapfile> y cuando lo tenga buscara en dicho archivo la
clave CHK asociada al fichero "file" e intentara obtener los datos asociados.
Algunos puristas de la programacion (particularmente jnk) consideran que
puede incluso mejorarse la tecnica si en vez de utilizar manifiestos se enlaza
directamente hacia las claves CHK (sobre todo cuando se trata de sites con
muchas imagenes) y que FProxy deberia mantener una especie de "cache" de los
manifiestos en memoria. La discusion sobre este tema -asi como un ejemplo
practico sobre el mismo- puede hallarse en:
SSK@padAbxDs9jixhld6wGLvZ0TyoFAPAgM/SSKvsCHK/2//
4.2.2. Ediciones de un freesite.
Puesto que una web estatica suele ser bastante pobre y poco interesante en la
mayoria de los casos, existe una tecnica llamada "freesites editions" que
permite distintas versiones de un mismo freesite.
Para crear ediciones, lo unico que tenemos que hacer es añadir a nuestro
archivo una referencia a una clave inexistente (aun). Es decir, si por
ejemplo nuestro sitio tiene la clave: SSK@<publica>/mi_pagina_1.html, podemos
añadir en el html un enlace a la clave: SSK@<publica>/mi_pagina_2.html, de
forma que solo cuando el nuevo archivo exista se podra acceder al mismo desde
la edicion antigua.
Hasta aqui, vale, sencillo. Pero como va el usuario a darse cuenta de que
existe una nueva version? Pues porque en realidad lo que se suele introducir
es una imagen que aun no existe, de forma que cuando obtengamos la pagina
html y veamos dicha imagen eso significara que ya hay una edicion mas moderna
de la misma. Si bajamos la pagina pero la imagen no aparece, significa que aun
no existe ninguna edicion nueva. Esto es lo que se conoce con el nombre de
"activelink". Ademas de avisarnos de la existencia de una nueva edicion, los
activelinks permiten que los manifiestos se repliquen por la red, puesto que
para obtener la clave CHK correspondiente al activelink debemos obtener
primero el manifiesto asociado. Por ello tambien contribuyen mantener vivos
los freesites. Por cierto que los activelinks tambien se utilizan en freesites
con DBR (ver DBRs mas adelante).
Las ediciones tienen dos problemas importantes: el primero, que necesitaremos
bajar las dos versiones del mismo freesite para acceder a la mas moderna. Y
el segundo, que puede ser que el freesite antiguo si este accesible pero la
imagen no, aunque exista (hay que recordar que puede ocurrir que un archivo
exista pero no consigamos obtenerlo, por ejemplo debido a que el numero de HTL
es muy bajo). Este ultimo caso es bastante improbable puesto que los
activelinks son con diferencia los contenidos mas replicados por Freenet, pero
podria darse. Aun asi, las ediciones de freesites son una tecnica muy utilizada
por sus creadores, sobre todo cuando los contenidos no se actualizan de forma
regular.
4.2.3. DBRs.
Las DBRs vienen a solucionar los problemas de modificacion de archivos de
una forma mas elegante, proporcionada por la misma Freenet de forma
transparente al usuario (receptor de la informacion).
DBR son las siglas de Date Base Redirection, redireccion de la base con la
fecha. El mecanismo se basa en traducir las claves solicitadas como
SSK@<public>/<file>// a claves de la forma:
SSK@<public>/<time>-<file>//
donde <time> es la representacion en hexadecimal del numero de segundos
transcurridos desde "La Epoca" (por ejemplo, 3c050e00). De esta forma,
la propia Freenet se ocupa de que recibamos la version mas moderna de un
freesite. De cualquier modo, siempre podemos indicar manualmente una fecha
determinada para obtener la version que queramos de esa pagina.
(Nota: La Epoca, por si alguien lo dudaba :), son las 00:00:00 del 1 de enero
de 1970)
Cual es la parte negativa de las DBR? (o acaso pensabas que esto iba a salirte
gratis?) Pues que el creador del freesite tiene que actualizar ciertos
archivos diariamente (o de forma mas o menos periodica) si desea que el
sitio este disponible. Ademas, solo puedes realizar una actualizacion por dia
del site como maximo. Esto no ocurre con las "ediciones", por ello este
metodo se usa con freesites que se actualizan muy a menudo (como TFE) y las
ediciones con los que se actualizan de tarde en tarde y con periodos
irregulares entre las distintas versiones.
4.2.4. Splitfiles.
Otro mecanismo que se utiliza para distribuir la informacion son los
"splitfiles" o archivos separados. Este consiste en dividir un archivo en
varios mas pequeños. Estos trozos se introducen todos en Freenet y tambien
se introduce un archivo con metadatos que apuntan a cada uno de los trozos.
De esta forma, ocurre al igual que con e-Donkey: podemos obtener un mismo
archivo a partir de sus trozos que pueden estar en servidores distintos.
Asimismo, podemos reanudar una descarga simplemente bajando los trozos que
aun no tenemos en la cache, reduciendo la carga de la red y el tiempo de
espera.
4.2.5. FEC.
FEC son las siglas de Forward Error Correction. Esta es una tecnica que se
utiliza en muchos sistemas (por ejemplo, en los buscapersonas) en los que
una retransmision de la informacion es muy costosa, imposible (porque en
el sistema la informacion fluye en un solo sentido, por ejemplo en los
buscas television por satelite) o incluso inservible (en sistemas en tiempo
real como en videoconferencias de nada sirve la retransmision de datos
mal recibidos).
Los sistemas FEC se basan siempre en añadir informacion redundante que permite
corregir los errores de transmision. Un ejemplo pueden ser los codigos de
correccion de errores de Hadamard, CRC polinomicos, etc.
En el caso de Freenet, los sistemas FEC que se utilizan estan estrechamente
relacionados con los splitfiles: en cada trozo de un splitfile se incluye
informacion redundante de forma que si faltan algunos trozos (no muchos) del
archivo original, este pueda reconstruirse a partir de los que si estan
disponibles. Es un caso tipico (en e-Donkey, por ejemplo) que falten solo
algunos o incluso solo un trozo de un archivo dividido. En ese caso, sin
FEC lo que si esta disponible no nos sirve para nada (en general, puede que
en algun caso no nos importe perder un trozo). Con el sistema FEC implementado
por Freenet, si tenemos suficientes porciones del archivo podremos reconstruir
el mismo al completo.
Hay que destacar que el subsistema que incluye Freenet para FEC puede ser
sustituido por otras versiones en C u otros lenguajes, no necesariamente
java, para aumentar el rendimiento del sistema al bajarse los splitfiles.
5. Las entrañas de Fred.
Hasta aqui hemos visto el aspecto "superficial" de Fred. No sabemos en
realidad nada de como se comunican unos nodos con otros, ni que protocolos
utilizan. Asi que ahora viene la parte mas interesante si te gustan las redes
de ordenadores. Si no es asi, mejor que no la leas. Puedes saltartela y
seguir utilizando Freenet tranquilamente, o elegir la pildora roja y conocer
la verdad... :-)
Toda esta informacion se encuentra desperdigada entre multiples documentos,
normalmente desfasados, por la WWW y Freenet. En la propia pagina del
proyecto se indica que el codigo fuente debe ser la unica fuente de
documentacion sobre el comportamiento de Fred, pero abordar el codigo fuente
-sobre todo si, como yo, te interesa poco el lenguaje Java- no es trivial
precisamente. Por lo tanto, me basare en dichos documentos y en informacion
obtenida de otras personas y dejo la ingenieria inversa para alguien con mas
tiempo y ganas, aunque algunas cosillas las saco directamente del codigo del
CVS.
Fred utiliza dos protocolos distintos (en realidad, dos torres de protocolo)
para su funcionamiento. FNP (Freenet Network Protocol) y FCP (Freenet Client
Protocol) son los nombres de estos protocolos. FNP es el protocolo que
utilizan los nodos para hablar entre si, y FCP es el protocolo que utilizan
los programas cliente para hablar con el nodo local.
Nota sobre FCP: La parte correspondiente al protocolo de cliente no la toco
en este articulo. Es la parte mejor documentada, y si buscais por la web de
Freenet en Sourceforge no tendreis ningun problema en hallar informacion
sobre ello.
5.1. FNP.
NOTA: La informacion aqui detallada esta basada en la descripcion del
protocolo FCP 1.4x, que se utiliza a partir de la version 0.4 de Freenet.
Puesto que el documento en cuestion se considera en desarrollo, no debe
tomarse esta informacion sino como una guia introductoria.
FNP es una torre de protocolos estratificada (al estilo OSI) que define las
tres ultimas capas del modelo OSI: sesion, presentacion y aplicacion. Las
capas inferiores no se definen, pero se requiere ciertas caracteristicas
para el correcto funcionamiento del sistema (especificamente, de la capa de
transporte). El diseño se ha llevado a cabo pensando en el protocolo TCP,
por lo que este es el protocolo de transporte por defecto, aunque nada
impide que futuras versiones utilicen otros protocolos de transporte.
Tampoco los protocolos definidos por el FNP son interdependientes, y se
supone que se puede cambiar la implementacion de una capa si su interfaz con
las otras se mantiene invariable. Para conseguir esto, los nodos deben
especificar para cada capa el protocolo mediante el cual pretenden
comunicarse antes de comenzar el intercambio de datos. Esto se hace mediante
el envio de un entero de dos octetos en forma "network-byte-order" (big
endian) al inicio de cada establecimiento de conexion en cada capa. Este
numero entero se conoce con el nombre de "indicador" (designator).
5.1.1. Requerimientos a la capa de transporte.
La capa de transporte debe ser capaz de soportar servicio en modo conexion,
transferencia de datos en forma de octetos, control de errores y la
posiblidad de mantener varias conexiones hacia otro(s) nodo(s)
simultaneamente.
No se espera de la capa de transporte que aporte un mecanismo para cortar la
conexion. En su lugar, se considera que una conexion esta cerrada despues de
recibir un mensaje que indique dicho evento a nivel de capa de sesion,
cuando se da un estado de error a la hora de negociar los protocolos de
sesion y presentacion, o cuando un campo erroneo la esta bloqueando.
5.1.2. Capa de sesion criptografica. (FNP/S)
Es la primera capa definida por el protocolo FNP. Se ocupa del
establecimiento del enlace criptografico entre dos nodos, la autenticacion
de los nodos y el envio de datos cifrados. Su indicador es 0x0001.
El mecanismo para establecer la sesion es basicamente utilizar el algoritmo
Diffie-Hellman (claves asimetricas) para comunicarse una clave secreta, y
posteriormente usar esa clave para el algoritmo de cifrado simetrico AES
(Advanced Encryption Standard). Todo el que sea un apasionado de la
criptografia sabra ya de que se habla; para los que no nos gusta tanto,
espero que la siguiente explicacion sea suficiente.
5.1.2.1. Inicio de sesion. (Full Handshake)
5.1.2.1.1 Generalidades.
Supongamos dos nodos Alice y Bob cuyos identificadores DSA son a y b
respectivamente. De ahora en adelante, el operador + indica concatenacion,
el operador ^ indica exponenciacion, ElGx(Y) significa cifrar el mensaje "Y"
mediante el algoritmo ElGamal (en realidad, se usa el algoritmo DLES, que es
equivalente a cifrar con ElGamal pero mas rapido y seguro) y la clave "x", y
el operador mod n indica resto de la division por n (tambien conocido como
modulo-n). Este numero n se corresponde con el siguiente entero primo estandar
IPSec de 1024 bits:
FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED
EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381
FFFFFFFF FFFFFFFF
Todos los numeros son enviados y calculados como MPI (Multi-Precision-Integer)
del mismo modo que se define en la especificacion de OpenPGP: cada MPI se
compone de un entero (big endian) de dos octetos que indica la longitud en
bits del numero, seguido de una cadena de octetos que contienen el numero en
forma big endian. La longitud se aplica a partir del primer bit mas
significativo distinto de cero. Por ejemplo, el numero 1 se codifica como
[0x00 0x01 0x01], no es valida la codificacion [0x00 0x02 0x01].
Las firmas se calculan mediante DSA (Digital Secure Algorithm) sobre el hash
SHA1 (Secure Hash Algorithm 1) de los datos.
Ademas del valor n utilizado, se definen tambien los valores p=n y g=2 para
el intercambio de la clave simetrica (lo que se conoce como el grupo A de
Diffie-Hellman). Distintos valores de p, g e incluso otro parametro llamado
q se definen en /crypt/Global.java para distintos "grupos" de cifrado tanto
para el algoritmo Diffie-Hellman como para el algoritmo DSA. Cada uno de
estos grupos tiene su utilidad especifica (para KSKs, SVKs, cifrado de clave
publica y firmas, etc.). Para el inicio de sesion se utiliza el anteriormente
nombrado Diffie-Hellman Group A.
5.1.2.1.2. PCFB (Periodic Cipher FeedBack).
PCFB son las siglas de Periodic Cipher FeedBack. Este es un mecanismo para
utilizar cifrado por bloques pero que permite enviar un octeto cada vez. Se
supone que ambos extremos se han puesto de arcuerdo previamente en la clave
con la que se va a cifrar (en el caso de Freenet, esto se hace con el
algoritmo Diffie-Hellman, como luego veremos).
Existen dos buffers de memoria para cada comunicacion, uno para enviar y
otro para recibir. Estos buffers toman el tamaño de un bloque de cifrado. A
partir de ahora describire lo que ocurre en uno de los flujos emisor ->
receptor par estos buffers (en el otro ocurre el mismo proceso intercambiando
emisor por receptor).
Lo primero que hace el emisor es llenar el buffer con un "vector de
iniciacion" (Initialization vector o IV) de octetos aleatorios y enviar dicho
IV al otro extremo. El otro extremo guarda el IV en su buffer de recepcion y
ambos cifran sus buffers correspondientes, reemplazando el contenido de ambos
con el resultado del cifrado. De esta forma, ambos extremos tienen en un
buffer (de emision para el emisor, de recepcion para el receptor) el IV
cifrado.
Cuando el transmisor quiere enviar su primer octeto, realiza la XOR del mismo
con el primer octeto de su buffer de transmision, envia el resultado al otro
extremo y tambien reemplaza el primer octeto del buffer de transmision con el
resultado de la XOR.
El receptor toma el octeto recibido y realiza la XOR del mismo con el primer
octeto de su buffer de recepcion, obteniendo el octeto inicial que el emisor
queria enviarle. Asimismo, reemplaza el primer octeto de su buffer de
recepcion con el octeto recibido (antes de realizar la XOR con el del buffer
de recepcion). En este momento el primer octeto del buffer de recepcion del
receptor y el primero del buffer de transmision del transmisor coinciden de
nuevo.
Para siguientes octetos se lleva a cabo el mismo proceso con los siguientes
octetos no usados de cada buffer. Una vez el buffer de transmision del
emisor (y por tanto, el de recepcion del receptor) han sido completamente
reemplazados, se vuelve a cifrar su contenido mediante AES, obteniendo un
nuevo buffer con nuevos octetos sin usar que vuelve a iniciar el ciclo.
5.1.2.1.3. Establecimiento del enlace.
Los pasos son los siguientes:
- Alice elige un entero grande "x" y calcula Ca=g^x mod n
- Alice envia a Bob un octeto (0x08) cuyos 5 bits mas significativos
indican la version del protocolo de sesion (0x01) y los tres menos
significativos son el indicador de inicio de sesion (0x00).
- Alice le envia a Bob Ca+ElGb(Ca). (recordar que b es el
identificador DSA de Bob)
- Bob comprueba que el cifrado de Ca con b es correcto y almacena Ca.
- Bob elige un entero grande "y" y calcula Cb=2^y mod n
- Bob envia a Alice 0xfb+Cb. 0xfb es el "Silent Bob byte", caracter
que no se encuentra en los protocolos que usan ASCII de 7-bit (HTTP,
FTP, etc.) y que es un numero primo.
- Para Alice, Z = Cb^x mod n. Para Bob, Z = Ca^y mod n. En ambos
casos Z = g^(xy) mod n, pero nadie que haya estado escuchando la
conversacion de Alice y Bob conoce Z salvo ellos (Diffie-Hellman).
*NOTA: A partir de este instante, toda la comunicacion siguiente se
cifra mediante el algoritmo AES (Rijndael) usando PCFB y tomando Z
como clave.
- Alice calcula su firma DSA de Ca+Cb y envia a Bob Ya+sign(Ca+Cb).
"Ya" es la clave publica DSA de Alice y el operador sign() indica
firma DSA.
- Bob comprueba que la firma es correcta.
- Bob envia a Alice sign(Ca+Cb) firmada con su clave publica Yb.
Notar que Alice conoce Yb=b.
- Alice comprueba que la firma es correcta.
A partir de este instante se considera que el enlace esta establecido y
puede comenzar el intercambio de mensajes utilizando AES con PCFB.
5.1.2.2. Reinicio de sesion (Restart Handshake).
El reinicio de sesion es un mecanismo utilizado para acelerar el
establecimiento de conexiones entre dos nodos. Para ello, los nodos deben
almacenar la clave de sesion Z en una cache durante al menos 4800 segundos
(una hora y 20 minutos). Si se quiere conectar a un nodo para el cual
tenemos una clave Z con menos de una hora de existencia almacenada, nuestro
nodo debe intentar un reinicio de sesion en lugar de establecer una nueva
sesion.
Para restablecer una sesion -es decir, para establecer una nueva conexion
con el antiguo valor Z como clave para cifrado- el proceso es:
- Alice envia a Bob un octeto (0x09) cuyos cinco bits mas
significativos indican la version del protocolo (0x01) y cuyos tres
bits menos significativos indican reinicio de sesion (0x01).
- Alice envia a Bob ElGb(hash(Z)+0x00000000) (recordar que b es el
identificador DSA de Bob). El operador hash() devuelve el hash SHA1
del operando.
- Bob comprueba que los 4 octetos menos significativos son cero, y
si es asi busca Z en su cache mediante hash(z).
A partir de este instante se considera que el enlace esta establecido y de
nuevo pueden intercambiarse mensajes mediante AES/PCFB.
5.1.3. Capa de presentacion/mensajes (FNP/P)
Los mensajes que se intercambian por los enlaces establecidos mediante FNP/S
son cadenas de caracteres UTF y tambien es posible que al final contengan un
campo de datos adjuntos en formato binario (trailing field). Los mensajes
sin los datos adjuntos pueden tener una longitud maxima de 65536 caracteres
y, aunque actualmente solo se utilizan caracteres ASCII de 7 bits, las
implementaciones deben incluir soporte para caracteres UTF fuera de ese
rango.
5.1.3.1. Formato general de los mensajes.
El formato general de un mensaje FNP/P en representacion EBNF (Extended
Bachus Naur Form) que sigue esta copiado literalmente de la especificacion
del protocolo, por lo tanto mantengo los nombres en ingles. Este formato es:
Message ::= Command NL FieldSet NL [ Trailing ]
Command ::= { UTF }
NL ::= ('0x0D' '0x0A') | '0x0A'
Fieldset ::= { Field } EndString
Field ::= FieldName '=' FieldVal NL
FieldName::= SubName { '.' SubName }
SubName ::= UTF { UTF }
FieldVal ::= { UTF }
EndString::= { UTF }
Trailing ::= Octet { Octet }
UTF ::= Octet | (Octet Octet) | (Octet Octet Octet)
Octet ::= '0x00' | '0x01' | '0x02' | ... | '0xFF'
Todas cas cadenas de caracteres UTF (Command, FieldName, FieldVal, y
EndString) tienen una longitud maxima de 4096 caracteres.
En todos los comandos (Command), subnombres (SubNames) y Terminadores
(EndStrings) se distinguen mayusculas de minusculas, y por lo tanto no es lo
mismo "Imposible" que "imposible". Las distintas implementaciones deben
asegurarse de que el receptor no recibe dos campos con el mismo nombre,
puesto que si esto ocurre el comportamiento del mismo no esta definido.
Los campos relacionados se agrupan mediante una notacion de subnombres
separados por puntos. Si un elemento llamado "im" tiene dos propiedades
llamadas "posible" y "presionante", ambos deben ser escritos como los
FieldNames im.posible e im.presionante. Los campos relacionados con los
datos, por ejemplo, que deben ser almacenados con los mismos se agrupan
bajo el subnombre Storable.
Vemos que la indicacion de nueva linea puede ser recibida al estilo Unix o
al estilo Windows, aunque este ultimo es el que se debe utilizarse cuando
se codifiquen mensajes.
Por ultimo, para permitir relleno futuros modos de cifrado por bloques
-aunque ya hemos visto que la capa FNP/S actual utiliza PCFB y no necesita
relleno- los caracteres nulos (0x00) al final de un mensaje deben ser
ignorados. Por lo tanto los comandos (Command) deben empezar con un caracter
no nulo.
5.1.3.2. Representaciones estandar.
Algunas representaciones estandar usadas en los campos son:
a)Cadenas de caracteres (Strings):
Simplemente, cadenas de caracteres UTF.
String ::= UTF { UFT }
b)Valores numericos (Numbers):
Los valores numericos son cadenas de caracteres de literales hexadecimales,
sin distincion entre mayusculas y minusculas. Si no se expresa un limite,
debe asumirse que son valores de 64 bits.
Numer ::= hex { hex }
hex ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' |
'9' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'A' | 'B' |
'C' | 'D' | 'E' | 'F'
c)Valores binarios.
Son cadenas de caracteres hexadecimales en las que cada dos caracteres
codifica un octeto.
Binary ::= byte { byte }
byte ::= hex hex
hex ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' |
'9' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'A' | 'B' |
'C' | 'D' | 'E' | 'F'
5.1.3.3. Campos especiales.
Hay algunos nombres de campos que estan reservados para las capas altas del
protocolo. Estos son:
a)El campo Connection.
Este campo esta reservado en todos los mensajes FNP para transportar
comandos relativos al estado de la conexion de la capa de transporte sobre
la cual el mensaje es enviado. En la especificacion en la que me baso solo
hay definidos dos valores, "close" (cerrar) y "sustain" (mantener).
Si se recibe un mensaje con un valor close en el campo Connection, esto
significa que se cierra la conexion, y el receptor de este mensaje debe
enviar cuanto antes otro con el valor close en campo Connection a su vez tan
pronto como pueda. Aunque es posible enviar otros mensajes una vez se haya
recibido un "close", esto debe evitarse siempre que se pueda.
El extremo que desee cerrar una conexion debe enviar un "close" y no enviar
mas mensajes por la misma. En cambio, debe permanecer a la escucha de
mensajes por esa conexion hasta que el otro extremo envie un mensaje con el
valor close en el campo Connection.
El valor sustain indica al otro extremo que debe intentar mantener la
conexion abierta tanto tiempo como pueda.
b)El campo Length.
Este campo esta reservado para indicar el numero de octetos del campo de
datos (trailing field) de todos los mensajes FNP. Si este campo no existe o
su valor es cero, no existen datos. Si su valor (n) es mayor que cero, los n
octetos que siguen a la EndString pertenecen a los datos. Los datos pueden
terminar antes de tiempo bajo alguna circunstancia (principalmente cuando un
nodo descubre que esta enviando datos corruptos). Si asi ocurriese, existe
un octeto de control (control byte) que se envia justo tras los datos que
contendra el valor apropiado (la constante CB_RESTARTED posiblemente).
5.1.3.4. Mensajes Especiales.
Los mensajes cuyo Command es "Void" se consideran mensajes vacios. Estos
mensajes no llevan informacion funcional a las capas altas del protocolo,
pero pueden servir para indicar valores en el campo Connection, y tambien
como relleno para evitar un analisis del trafico de Freenet. Los mensajes
Void pueden contener datos, pero su longitud no debe ser superior a 65536
octetos.
5.1.3.5. Resumenes de Fieldset y firmas.
Se calculan hashes (resumenes) de los grupos de campos (Fieldsets) de forma
que puedan ser autenticados. El metodo estandar para obtener el hash de un
Fieldset es todos los nombres de campo (FieldNames) en orden alfabetico y
aplicar al total el algoritmo SHA1.
Cuando se firma un Fieldset, la firma se realiza sobre el hash calculado
utilizando una clave privada, y se añade al propio Fieldset en el campo de
nombre "signature". Por supuesto, este no debe incluirse a la hora de
calcular el hash y de comprobar la firma del mensaje.
5.1.4. Capa de aplicacion.
La capa de aplicacion especifica el comportamiento esperado de las
implementaciones de Freenet. Fred se comporta siguiendo esta descripcion.
Se definen tres tipos de peticiones que pueden llevarse a cabo:
InsertRequest (peticion de insercion), DataRequest (de datos) y
Announcement (anuncio). Las peticiones de insercion (y no penseis mal)
sirven para introducir datos en Freenet. Las de datos, para recibir datos de
la red. Y los anuncios sirven para señalar la presencia de un nuevo nodo a
los existentes.
5.1.4.1. Conceptos generales.
5.1.4.1.1. Identificador de mensaje (UniqueID).
Todos los mensajes contienen un campo que sirve para identificar los
mensajes que corresponden a la misma interaccion (una instancia uno de los
tres tipos de peticiones posibles). El grupo de mensajes que comparte el
mismo UniqueID se conoce con el nombre de "cadena de mensajes" (message
chain).
El UniqueID es un numero de 64 bits codificado de forma estandar que debe
escogerse de forma aleatoria por parte del nodo que comienza la cadena de
mensajes.
5.4.1.2. Referencias a nodos (node references).
Las referencias a nodos son la forma de direccionamiento utilizada en
Freenet. Todos los nodos permanentes deben ser capaces de crear referencias
a si mismos. Las referencias contienen los siguientes elementos:
-identity: la clave publica del nodo
-identityGroup: el grupo utilizado para la clave publica. Es un campo
opcional que solo se incluye si no se utiliza el grupo por defecto.
-sesion protocols: debe ser una lista de los numeros designadores de todos
los protocolos de sesion criptografica. Al menos uno debe estar soportado.
-presentation protocols: al igual que el anterior, una lista de designadores
para los protocolos de presentacion soportados. Al menos debe haber uno.
-physical address: la direccion de red (y la parte de transporte, por
ejemplo el puerto TCP) para todos los protocolos de transporte del nodo.
Normalmente incluye direccion IP y puerto TCP.
-revision: un indicador indicando el numero de revision de la referencia.
Debe ser un valor incrementado cada vez que se cambie la referencia. Este
campo parece ser obsoleto y sustituido por otro de nombre "version".
-signature: la firma de la referencia por el propio nodo. Todas deben estar
firmadas por el nodo al que pertenecen.
-ARKencryption: la clave con la que se cifran los datos incluidos en la ARK
del nodo.
---- NOTA sobre ARK:
Las ARKs (Address Resolution Keys) no son mas que archivos que un nodo
introduce en Freenet cada vez que su direccion de red (IP en general)
cambia, bajo una clave (de tipo ARK) que contienen la nueva direccion de red
del nodo.
De esta forma, mediante un mecanismo similar al ARP de IP, se permite que
nodos con IP dinamica formen parte de Freenet. Cada vez que un nodo no pueda
contactar con alguno de su lista, intentara conseguir la clave ARK del mismo
pidiendola a otros nodos de la red. Cuando la consiga, intentara contactar
con la direccion de red que contenga el archivo recuperado. Cada nodo
inserta un archivo nuevo bajo una clave ARK que tiene una parte numerica que
se incrementa para cada archivo. De esta forma, se comienza con la ARK
revision 0 y se va incrementando cada vez que la IP cambia, insertandose las
nuevas direcciones de red bajo las claves con revision 1, 2, etc. Los otros
nodos deben mantener una referencia a la ultima revision valida de la ARK e
intentar conseguir una nueva cada vez que no puedan contactar con un nodo.
Los nodos con IP estatica no necesitan este mecanismo, ya que su direccion
no cambia.
----
Un ejemplo (real, tomado de seednodes.ref) de esto puede ser:
signature=5132f5423c0b9d5222be94c6fae97a04c0b23af9,377deb1c575f9032ea3f664...
version=Fred,0.5,1.46,598
presentations=1
identity.g=930168de21e7fb66c0375e08e964255a0f7f0ad54507a51864afdc686f36be...
identity.q=ef1f7a7a73362e526515f348075aee265e9eff45
identity.p=cb0a782c7abff4920000000000000000000000000000000000000000023d66...
identity.y=74ba7bd3a0eee38b0b0ea740eb7130785114db4df88d551d25b37893cf72cec...
ARK.encryption=9d72346e32f293def149964c10ab452398c9ae6766149e7104e5982fc1...
ARK.revision=0
sessions=1
physical.tcp=192.168.1.1:3676 /* La direccion es falsa, obviamente */
End
Puede verse que se ha modificado la especificacion, y que ahora se indican
los enteros largos g,q,p e y utilizados en los mecanismos criptograficos y
de firma, y que tambien se indica la version del nodo e incluso el numero de
construccion (build) que en este caso es el 598. Tambien se incluye la
ultima revision de la ARK, en este caso la 0 (no se ha usado ARK aun).
Hay una representacion alternativa para el caso de que la identidad de la
referencia sea conocido de antemano. Si ocurre asi, el campo "identity" sera
obviado y en su lugar se añadira el campo "identityFP" (finger print).
Cuando se necesite reconstruir esas referencias, el campo "identity" debe
ser recuperado de alguna otra fuente.
5.4.1.3 Datos.
Para cada seccion de datos existe un Fieldset asociado llamado "Storables"
(almacenables) por razones historicas. Este fieldset contiene informacion
acerca de los datos, y cada campo que lo constituye varia un poco segun el
tipo de clave al que corresponda.
Para los datos se usa un flujo progresivo de hashes, que no es mas que un
flujo de datos divididos en secciones en el cual cada seccion va precedida
de su propio hash y del hash de la siguiente parte. Para interesados en el
tema, el codigo de Fred indica que la implementacion de los flujos
progresivos de hashes se ha tomado de: "How to Sign Digital Streams" por
Gennaro, R y Rohatgi, P; Advances in Cryptology - CRYPTO '97, 1997.
Los campos de los que consta "Storables" son:
-Part-size: indica el tamaño de cada parte en el hash progresivo de los
datos.
-Initial-digest: resumen de la primera parte del flujo.
-Symmetric-cipher: tipo de cifrado utilizado, debe mantenerse para que los
clientes puedan interpretar los datos.
-Document-header: al igual que el campo anterior, ayuda a los clientes a
interpretar los datos, tampoco es usado por el protocolo.
-Public-key: clave publica para datos firmados.
-Document-name: tambien para datos firmados, debe ser un resumen del nombre
legible del documento.
-Signature: para datos firmados, la firma de todos los campos del set
"Storables", por supuesto excluyendo este campo.
En resumen, debe ser:
Initial-digest:
Part-size=<integer>
Initial-digest=<byte array>
Symmetric-cipher=<string>
Document-header=<byte array>
[Public-key=<identity set>]
[Document-name=<byte array>]
[Signature=<byte array list>]
5.4.1.4 Claves.
Ya sabemos que las claves de Freenet son los identificadores que nos
permiten acceder a los datos que estan almacenados en la red. Las claves
sirven para obtener los datos, pero tambien definen la topologia de
enrutado y (las CHK y las SSK) nos permiten validar los datos obtenidos.
Las claves son vectores de octetos de longitud arbitraria y en los mensajes
FNP se codifican como valores binarios segun hemos visto anteriormente.
5.4.1.4.1. Similitud entre claves.
Las claves deben ser susceptibles de comparacion para permitir el enrutado,
por ello hay que definir una "distancia" entre claves de forma que dada una
clave inicial y otras dos secundarias, podamos decidir cual de las dos
claves secundarias se parece mas a la inicial. Y la metrica utilizada es la
distancia lexicografica (tambien puede definirse como la distancia numerica
en la que los elementos de menor longitud se rellenan con octetos a cero).
Si dos elementos estan igual de cerca de un tercero, el que sea de longitud
mas pequeña (y por lo tanto tenga menos relleno) se considera mas cerca.
Un ejemplo de algoritmo que utiliza enteros de longitud variable y que
realiza la comparacion para comprobar cual de las claves Ka o Kb se parece
mas a la clave K es:
integer diffA = 0, diffB = 0;
for integer i
diffA = diffA * 256 + | Ka[i] - K[i] |
diffB = diffB * 256 + | Kb[i] - K[i] |
if (diffA > 1 + diffB) Kb se parece mas a K
if (diffA + 1 < diffB) Ka se parece mas a K
if (diffA > diffB) Kb se parece mas a K
if (diffA < diffB) Ka se parece mas a K
min(Ka, Kb) se parece mas a K
5.4.1.4.2. Tipos de claves y validacion de datos.
Las claves sirven para validar los datos del Fieldset "Storables", que a su
vez sirven para validar los datos, puesto que incluyen el campo
"Initial-digest" que precisamente contiene el ultimo valor del hash
progresivo de los mismos. La estructura de una clave usada para validar los
datos es:
Key ::= validator length-byte keytype
validator ::= octet { octet }
length-byte ::= octet
keytype ::= octet octet
La parte "validator" se define segun el tipo de clave. "length-byte" es el
logaritmo en base 2 del limite superior para el tamaño de los datos: los
datos podran tener una longitud maxima de 2**(length-byte)-1 octetos (NOTA:
el operador ** indica exponenciacion). "key-type" consiste en dos octetos
(numeros mayor y menor) que definen el tipo de clave.
5.4.1.4.2.1. Content Hash Keys (CHK).
Las claves CHK tienen asociado el "key-type" 0x03 0x02. Ya sabemos que las
claves CHK definen una aplicacion biyectiva entre los datos y la clave
asociada, y que son la piedra angular de Freenet.
Para los datos indexados mediante CHKs deben incluirse en el resumen todos
los campos esenciales del Fieldset "Storables", pero los campos relacionados
con firmas deben obviarse. Por lo tanto, el valor de la parte "validator"
debe ser exactamente el resumen del Fieldset "Storables".
5.4.1.4.2.2. Signature Verifying Key (SVK).
Las claves SVK fueron el inicio de las claves basadas en criptografia
asimetrica para Freenet. Hoy en dia no se utiliza este tipo de claves, sino
las claves SSK (o KSK si no necesitamos seguridad). Pero las claves SSK y
KSK son de mas actualidad que la especificacion del protocolo, por lo que su
funcionamiento no se describe en la version disponible en web (ya dije que
era muy antigua). De cualquier modo, las claves SSK y KSK no son mas que
mejoras (o simplificacion, si es KSK) a las claves SVK, por lo que les
echaremos un vistazo. De hecho, las clases ClientKSK y ClientSSK estan
heredan de la clase padre ClientSVK, por lo que el cliente las trata como si
fueran SVK, y puede deducirse que el servidor tambien las trata igual
-aunque esto es una "deduccion" mia, espero no equivocarme :)-
Las claves SVK se basan en una clave publica conocida por todos los nodos y
una clave privada que solo conoce el generador de dicha informacion. El
"keytype" de dichas claves es 0x02 0x03. Ya he explicado anteriormente el
funcionamiento de las claves SSK, y todo ello es extrapolable a claves SVK
con una sola restriccion: por cada par de claves publica-privada solo puede
insertarse un archivo. Esto es una restriccion suficiente como para que
nadie utilice las claves SVK directamente, sino las SSK que permiten
insertar tantos archivos como deseemos en un mismo subespacio de claves.
El Fieldset "Storables" debe incluir todos los campos definidos
anteriormente. La firma ("signature") debe incluir todos los campos (salvo
el propio campo "signature") y debe ser verificable con la clave publica
incluida en el campo "Public-key". Asimismo, la parte "validator" debe
incluir el resumen SHA1 de los octetos contenidos en el campo "Public-key",
seguidos de los octetos del campo "Document-name". Esto ultimo es analogo a
lo que estamos acostumbrados cuando realizamos una peticion a FProxy de una
SSK: indicamos el tipo de clave (SSK), el resumen de la "Public-key" y luego
el nombre de documento.
5.4.1.4.2.3. Otras claves.
Se definen las claves "desconocidas" (unknown) e "imaginarias" (imaginary).
Las primeras seran todas las claves para las que el "keytype" no se conozca.
Dichas claves deben poderse enrutar y transferir todos los datos asociados
a las mismas, pero los nodos no deben almacenarlas en la cache ni
proporcionarlas por ellos mismos.
Por otra parte, las claves imaginarias son un mecanismo interno para
almacenar datos en las tablas de enrutado que no sean claves en si. Para
ello el valor 0x00 0x00 de la parte "validator" queda reservado.
5.4.1.5. Elementos de los nodos.
La implementacione de un nodo requiere los siguientes elementos comunes.
5.4.1.5.1. Memoria de transacciones.
Es la memoria que contiene el estado de cada transaccion o cadena de
mensajes, identificada por su "UniqueID". Sirve tambien para sincronizar las
transacciones de forma que solo se este procesando un mensaje a la vez para
cada transaccion.
5.4.1.5.2. Tabla de enrutado.
La tabla de enrutado debe contener informacion para asociar a cada clave una
referencia de nodo, de forma que se sepa a que nodo hay que realizar la
peticion. Tambien debe permitir obtener la clave mas similar a otra dada de
entre todas las claves que tengan asociada una referencia a un nodo. Por
ultimo, debe permitir actualizar las referencias a un nodo cuando estas
cambien (por ejemplo, porque se ha recuperado un ARK actualizado).
5.4.1.5.3. Almacen de datos (Data Store).
Cada nodo debe permitir almacenar datos en una "cache", y el tamaño de la
misma debe ser configurable por el administrador del nodo. El funcionamiento
de el Store es como el de todas las caches, con colas circulares y una lista
de los LRU (Less Recently Used, menos usados recientemente) para permitir el
borrado de archivos menos pedidos cuando todo el espacio este ocupado y se
quiera almacenar nueva informacion. El metodo para descartar los datos
antiguos no esta especificado por el protocolo, y lo unico que puedo decir
al respecto es que no solo se tiene en cuenta la fecha de ultimo acceso,
sino tambien el tamaño de los datos. De esta forma se evita que un archivo
nuevo muy grande "desplace" a varios archivos mas pequeños pero mas
"populares". Como siempre, a mirar el codigo si alguien esta realmente
interesado en los algoritmos.
5.4.1.5.4. Temporizador.
Por supuesto, cada nodo contiene un temporizador que sirve para comprobar
tiempos de expiracion de peticiones, etc. Los nodos que realicen peticiones
deben calcular el tiempo tras el cual la peticion deberia haberse
completado. La formula es:
Time(n) = n*<media de Tservicio>+1.28*sqrt(n)*<Desviacion de Tservicio>
Los valores entre <> son constantes empiricas, y n es el numero de saltos.
5.4.1.6. Preguntas (Queries).
La pregunta (query) es el metodo de comunicacion entre nodos. Cada pregunta
tiene asociada un UniqueID y cada mensaje tiene el campo "HopsToLive", valor
numerico que indica el numero de nodos que resta para que el mensaje sea
desechado (de forma que no viaje sin fin por la red). Tambien incluyen un
campo "Source" que identifica el ultimo nodo que envio el mensaje.
Cuando un nodo recibe un mensaje, comprueba primero que en la memoria de
transacciones no exista una entrada con el mismo UniqueID. Si es asi, o si
el nodo esta en una situacion de sobrecarga, error, etc., contestara a la
fuente del mensaje con otro mensaje de tipo "QueryRejected" (pregunta
rechazada) sin modificar su memoria de transacciones. Si no es asi, enviara
un mensaje "Accepted" a la fuente. Hay que notar que a un mensaje "Accepted"
puede seguir otro "QueryRejected" si ocurre cualquier error posterior (por
ejemplo, la pregunta no puede rutarse).
El nodo que envia el mensaje debe activar a su vez un temporizador con el
valor Time(n=1) segun la formula expuesta anteriormente. Si no se recibe
respuesta de ningun tipo y el temporizador expira, debe tratarse esta
situacion como un "QueryRejected". En tal caso puede despreciarse la
conexion con el nodo que no contesto. Si se recibio un "Accepted", debera
esperarse un tiempo Time(n=HTL) desde la recepcion del mismo hasta recibir
una respuesta final. Si esta no llegase, se volvera a tomar como un
"QueryRejected".
Si no se recibe una respuesta para una pregunta que provenia inicialmente de
otro nodo, debe enviarse un mensaje "QueryRestarted" a dicho nodo, de forma
que este sepa que no somos nosotros los que hemos fallado. Cuando un nodo
reciba un "QueryRestarted" mientras espera una respuesta final, el nodo debe
volver a esperar la misma cantidad de tiempo.
Existe ademas un tipo de mensajes "QueryAborted", pero el que escribio la
especificacion pone (textualmente):
// TODO - there is a QueryAborted as well now IIRC, but I don't
remember the exact semantics //
Asi que si el no se acuerda, imaginate yo.... Los mensajes "QueryAborted"
sirven ('ta claro) para parar una pregunta. Por ejemplo, cuando queremos
parar una insercion de informacion en curso porque hemos detectado un error
en el hash progresivo que nos llega desde el nodo anterior. Es un mensaje
que se envia a los nodos siguientes, pero no al anterior: de esta forma el
nodo que genero el error (de forma maliciosa o no) no puede enterarse de que
la informacion no sera insertada finalmente.
Copio y pego
directamente las estructuras de los mensajes:
-Accepted:
Accepted
UniqueID=<id>
EndMessage
-QueryRejected:
QueryRejected
UniqueID=<id>
HopsToLive=<integer>
Reason=<string> /* Este campo es solo para depurado y posiblemente
desaparezca cuando se termine el protocolo. */
EndMessage
-QueryRestarted:
QueryRestarted
UniqueID=<id>
EndMessage
El formato de los mensajes QueryAborted no esta especificado, pero mirando
el codigo parece ser:
QueryAborted
UniqueID=<id>
EndMessage
5.4.1.6.1. Enrutando preguntas.
El nodo debe utilizar la tabla de enrutado para encontrar la clave mas
cercana a la que se ha pedido y la referencia asociada a la misma de entre
todas las que tenga. Si no se encuentra dicha clave y referencia (porque la
tabla de rutas este vacia), debe rechazar la pregunta.
Una vez tenga la referencia, debe intentar establecer una conexion con ese
nodo, y enviarle la pregunta. Si falla al conectarse, debe volver a buscar
la siguiente clave mas parecida, y empezar de nuevo. Cada referencia a un
nodo al que no se pueda conectar debe ser despreciada (y posiblemente,
intentar un ARK si es que el nodo utiliza ARK). El numero maximo de
reintentos de conexion es un valor constante que no depende de cuan larga
sea la tabla de rutas. Si se sobrepasa dicho numero, la pregunta sera
rechazada independientemente de que aun haya referencias a nodos que no
hayamos intentado.
5.4.1.6.2. Peticiones (Requests).
Alguien podria pensar que mejor que "pregunta" podria haber traducido query
como "peticion", pero habria entonces confusion con las verdaderas
"peticiones" (requests). La verdad es que esta nomenclatura no es muy
clarificadora que digamos, pero asi es la vida.
Las peticiones son tipos de preguntas relacionadas con los datos. Hay dos
tipos de peticiones: para obtener (DataRequest) e insertar (DataInsert)
datos. Puesto que las peticiones hay que enrutarlas, primero se describira
como hay que hacer este rutado.
5.4.1.6.2.1. Enrutado de peticiones.
Por supuesto, todo mensaje de peticion debe incluir un campo que contenga la
clave bajo la que se almacena la informacion que se desea obtener o bajo la
que se desea insertar la informacion, si es una peticion de insercion. Este
campo se llama "SearchKey". La clave se envia como un valor binario segun la
representacion estandar definida anteriormente.
Una vez la peticion se haya aceptado, el nodo realizara las acciones
pertinentes para atenderla. Estas acciones seguramente incluiran busqueda
y/o modificacion del DataStore. Si se debe seguir redireccionando la
peticion, el nodo debe comprobar primero que el campo HopsToLive es mayor
que cero. Si no es asi, el comportamiento depende del tipo de peticion que
se este atendiendo. Si es mayor que cero, simplemente debe decrementar HTL.
Si se recibe un "QueryRejected" al enrutar una peticion o bien no se recibe
respuesta, el comportamiento debe ser el mismo que cuando un envio propio
falla: intentar enrutar hacia el siguiente nodo en la lista de "claves
parecidas" a la pedida. La unica diferencia esta en el campo HopsToLive, que
en este caso debe ser el calculado anteriormente.
---- NOTA:
Hay una mejora importante a esta especificacion respecto al campo
HopsToLive (HTL). El motivo de la misma puede verse claramente si imaginamos
una situacion como la siguiente: nuestro nodo realiza una peticion con el
campo HopsToLive almacenando un valor 0. ¿Que ocurre entonces? Si el
siguiente nodo nos da la informacion que pedimos, dicho nodo es la fuente de
la misma, puesto que HTL no bajara nunca de 0. Esto choca de frente con la
necesidad de anonimato para la fuente de informacion que buscamos.
La solucion es cambiar el comportamiento: ahora existe una probabilidad de
que cada nodo decremente el campo HTL que sera p = 1 - e**(k*(HTL**2)). k se
define como el "factor HLT" (HTL_FACTOR) y actualmente toma un valor -1.5.
De esta forma se consigue que para HTL=1 en el 22% de los casos el nodo no
decremente HTL. Para HTL=2, ya solo en el 0.25% de los casos el nodo no
decrementa HTL. De esta forma, no podemos saber si realmente era el nodo
siguiente el que tenia la informacion o era otro. Sabemos que en un 78% de
los casos era el, pero es un porcentaje lo suficientemente bajo como no
estar completamente seguros (que es de lo que se trata). Para los fanaticos
de las redes, hacer notar que esto no puede causar que el mensaje nunca
muera, puesto que el siguiente nodo hara lo mismo, y la probabilidad de que
no se decremente es en este caso 22%**2 = 4.84%, 22%**3=1.06% (aprox.) en el
siguiente nodo, etc. Cualquiera que sepa un poco de estadistica puede ver
que el mensaje esta destinado a morir en pocos saltos una vez HTL ha
alcanzado el valor 1.
----
5.4.1.6.2.2. Transferencia de datos.
Los datos se transfieren en la parte final de ciertos mensajes, los cuales
contienen el Fieldset "Storables", bajo el subcampo de nombre "Storable" en
un alarde de originalidad. Cuando reciba esos mensajes, debera comprobar el
campo correspondiente a la clave e ir verificando continuamente el hash
progresivo a partir del campo "Initial-digest". Si en algun momento la
comprobacion falla, la transferencia debe terminarse. Si la conexion se cae
en algun momento durante la transferencia, debe actuarse como si hubiera
fallado la comprobacion.
Asimismo, los datos deben reenviarse de forma inmediata, sin mantener
buffers de memoria que pudieran retrasar la transferencia mas de un par de
segundos, ya que este retraso se multiplicaria por el numero de nodos por
los que la informacion debe pasar.
5.4.1.6.2.3. Peticiones de insercion (InsertRequest).
Ya se que alguno estara pensando cosas raras, pero el nombre no tienen
ningun doble sentido, y las inserciones de datos son el modo de publicar
contenidos en Freenet. :D
Este tipo de peticion inicia una insercion y, una vez aceptada, es seguido
por un mensaje "DataInsert" que sera el que contiene los datos. Los nodos
deben intentar almacenar los datos en la cache (DataStore) o, si no van a
hacerlo (porque no cabe o el tipo de clave es desconocido) preparar un
buffer circular suficiente para el reenvio "al vuelo" a otros nodos. Esto
debe ocurrir si HTL es mayor que cero y tan pronto como otro nodo haya
aceptado la correspondiente peticion de insercion. Si hay algun fallo
durante la transferencia al siguiente nodo, debe tratarse como si dicho nodo
no hubiese contestado dentro de tiempo (con el consiguiente QueryRestarted,
etc.). Si los datos que llegan fallan se debe enviar un octeto de control
con el valor CB_RESTARTED tan pronto como sea posible y despues un mensaje
de tipo "QueryAborted" al nodo al que se estan reenviando. El nodo que
envia los datos erroneos no se enterara de ello.
Una vez el mensaje "InsertRequest" llegue al nodo final HopsToLive valdra
cero. Dicho nodo contestara entonces con un mensaje "InsertReply". Todos los
nodos que hayan enrutado una peticion de insercion deben enviar hacia el
nodo anterior un mensaje "InsertReply" cuando reciban de un nodo posterior
un mensaje de dicho tipo. Hay que tener en cuenta que un nodo puede
contestar con un "InsertReply" incluso antes de haber recibido el
"DataInsert". El mensaje "InsertReply" se considera una respuesta final a la
pregunta (query) pero los nodos deben esperar aun un mensaje "StoreData"
antes de liberar la memoria de la transaccion.
Si un nodo recibe un "QueryRejected" de un nodo al que ya ha enviado un
"DataInsert" o si el mensaje "InsertReply" no llegase a tiempo, debera
reintentar la peticion mediante "InsertRequest" y utilizar los datos que
esten en su cache. Si no ha almacenado dichos datos (ha usado un buffer
circular) o si los datos han expirado, debera enviar un mensaje
"QueryRejected" hacia atras, de forma que el nodo anterior a el sea el que
se ocupe de reenviar los datos.
Un nodo que inicialmente haya aceptado un "InsertRequest" debe continuar
leyendo los datos de "DataInsert" incluso si al final acaba rechazando la
peticion (porque no consiga enrutarla, por ejemplo).
El mensaje "StoreData" sera enviado por el ultimo nodo (el que recibe
HopsToLive a cero) y debe ser reenviado hacia atras por todos los nodos que
hayan rutado la peticion. Una vez un nodo envie este mensaje, puede dar por
terminada la transaccion y liberar la memoria correspondiente a la misma.
El formato de mensajes es:
-InsertRequest:
InsertRequest
UniqueId=<integer>
SearchKey=<byte array>
HopsToLive=<integer>
Source=<Node Reference>
EndMessage
-DataInsert:
DataInsert
UniqueId=<integer>
DataLength=<integer > 0>
Storable=<Storable fieldset>
Data /* Seguido por un campo de datos de DataLength octetos. */
-InsertReply:
InsertReply
UniqueId=<integer>
EndMessage
5.4.1.6.2.4. Peticiones de recuperacion de datos (DataRequest).
Estas peticiones sirven para obtener los datos que contiene Freenet. Se
inicia una de estas peticiones con un mensaje "DataRequest", que se envia
hacia otros nodos. Cuando un nodo recibe dicho mensaje, debe buscar en su
cache la informacion correspondiente a dicha peticion. Si la encuentra,
contestara al nodo anterior con un mensaje de tipo "DataReply" en el cual se
incluiran los datos correspondientes. Si no la encuentra, debera reenviarla
a otros nodos de sus tablas de rutas. En el caso de que el mensaje alcance
un nodo final (HopsToLive=0) y tampoco dicho nodo tenga esa informacion,
este nodo final contestara con un mensaje "DataNotFound".
Bien el mensaje "DataNotFound" bien el mensaje "DataReply" se considera la
respuesta definitiva a una peticion de datos. Si el mensaje es
"DataNotFound", se podra liberar la memoria asociada a dicha transaccion una
vez se haya enviado el mensaje al nodo anterior. Cuando un nodo recibe un
"DataReply" debe reservar espacio en la cache local (o bien usar un buffer
circular) y reenviar los datos inmediatamente al nodo anterior conforme los
vaya recibiendo. Si hay un error de verificacion de los resumenes de los
datos, el nodo debe enviar el octeto de control con el valor CB_RESTARTED, y
comportarse como si el nodo posterior no hubiera contestado la peticion a
tiempo. Tras haber transferido todos los datos, el nodo que los almacenaba
inicialmente (el primero que contesta con "DataReply") debera enviar un
mensaje "StoreData" que sera reenviado hacia atras por todos los nodos que
hayan rutado dicha peticion. Cuando dicho mensaje haya sido enviado por un
nodo, ese nodo puede liberar la memoria correspondiente a la transaccion.
Los formatos de mensaje son:
-DataRequest:
DataRequest
UniqueId=<integer>
SearchKey=<byte array>
HopsToLive=<integer>
Source=<Node Reference>
EndMessage
-DataNotFound:
DataNotFound
UniqueId=<integer>
EndMessage
-DataReply:
DataReply
UniqueId=<integer>
DataLength=<integer >
Storable=<Storable fieldset>
Data /* Seguido por un campo de datos de DataLength octetos. */
5.4.1.6.2.5. Mensajes StoreData.
El mensaje de tipo StoreData es el ultimo mensaje que se envia/recibe en una
peticion de datos, ya sea de recuperacion o de insercion. El mensaje
StoreData contiene informacion acerca del enrutado y sirve para la expansion
automatica de la informacion por Freenet, el "auto-aprendizaje" de los
nodos.
Hemos visto que una vez las peticiones de datos han sido concluidas, el
ultimo nodo envia un mensaje StoreData que viaja hacia atras por toda la
cadena de nodos hasta el origen de la peticion. El mensaje "StoreData"
significa el fin de la peticion.
Cuando un nodo envia un mensaje StoreData, el campo DataSource debe contener
una referencia a el mismo con (probabilidad P) o una referencia al nodo que
tenga la clave mas parecida al valor "SearchKey" pedido (con probabilidad
1-P). Cuando un nodo reciba un mensaje "StoreData", añadira una ruta a este
valor almacenado en el campo "DataSource" a su tabla de rutas. De esta forma
se consigue descentralizar el enrutado por la red para que no se produzcan
cuellos de botella/puntos debiles susceptibles de ataque DoS (negacion de
servicio) en cuanto a enrutado.
Ademas, los mensajes "StoreData" incluyen dos campos que se proponen en la
primera version del protocolo: "HopsSinceReset" y "RequestRate". El
primero indica por cuantos nodos ha pasado el mensaje desde la ultima vez
que se cambio el campo "DataSource". Esta informacion servira para que el
nodo pueda decidir si desea almacenar los datos en su "DataStore" o no. El
segundo campo sirve como medida del trafico para conseguir un equilibrado de
la carga de la red (load balancing).
El formato del mensaje es:
StoreData
UniqueId=<integer>
DataSource=<Node reference>
HopsSinceReset=<integer>
RequestRate=<long integer>
EndMessage
5.4.1.6.3. Anuncios (Announcement queries).
Los anuncios sirven para que nuevos nodos puedan entrar a formar parte de la
red. Especialmente sirve para que estos nuevos nodos puedan adquirir algunas
referencias iniciales en su tabla de rutas, de forma que puedan satisfacer
las primeras peticiones.
5.4.1.6.3.1. Enrutado de anuncios.
Los anuncios comienzan con un mensaje de tipo "NodeAnnouncement", que se
enruta igual que cualquier pregunta, pero con usa sutil diferencia: la clave
que se utiliza para que los nodos puedan enrutar debe ser generada de forma
aleatoria y puede ser cualquiera dentro del espacio de claves. Hay tres
campos importantes en dicho mensaje: "Depth", "Anouncee" y "CommitValue". El
primero de ellos es un contador de saltos que se incrementara por cada nodo
que reenvie el mensaje. El segundo contiene la referencia al nodo que se
esta anunciando. El ultimo de ellos debe ser un valor aleatorio en forma de
vector de octetos generado en cada nodo a partir del hash SHA1 del valor
"CommitValue" recibido del nodo anterior. Este valor se utiliza a modo de
codigo de control contra errores acumulativo, como luego veremos.
Para evitar que un nodo vuelva a anunciarse, cuando se recibe un mensaje
"NodeAnnouncement", debe buscarse referencias a dicho nodo en la tabla de
rutas. Si se encuentra alguna, debe contestarse con un mensaje de tipo
"AnnouncementFailed", que viajara hacia atras por toda la cadena de nodos
anteriores. Tras enviar un mensaje "AnnouncementFailed" los nodos pueden dar
por concluida la operacion de anuncio.
Al contrario de lo que ocurre con las peticiones, es importante que los
anuncios alcancen la profundidad indicada inicialmente en el campo
HopsToLive, por lo tanto cuando un anuncio se rechace, incluso si
anteriormente habia sido aceptado, el mensaje "NodeAnnouncement" enviado en
su lugar debe contener el mismo valor en el campo HopsToLive que el primero,
no el valor tomado del mensaje "QueryRejected". Puesto que esto puede dar
lugar a un retraso, puede ser necesario indicar con un mensaje
"QueryRejected" que la operacion esta todavia pendiente. Cada implementacion
debera sopesar la situacion y actuar en consecuencia respecto a esto.
Cuando un nodo reciba el mensaje "NodeAnnouncement" (el mensaje haya
alcanzado su fin) este ultimo nodo tambien generara un valor aleatorio
similar al que se almacena en el campo "CommitValue". Este valor sera
enviado, en el mensaje de tipo "AnnouncementReply" que sirve para terminar
la peticion de anuncio, en el campo "ReturnValue". Cada uno de los nodos
que reenvia un mensaje "AnnouncementReply" -que seran cada uno de los nodos
que reenviaron "NodeAnnouncement"- debe tomar el campo "ReturnValue"
recibido, realizarle la XOR con el valor "CommitValue" que calculo en el
envio del mensaje "NodeAnnouncement" correspondiente y almacenarlo en el
campo "ReturnValue" del nuevo "AnnouncementReply". Por si no queda claro,
basicamente realizar la XOR de lo que se recibe con lo que se envio.
Formato de mensajes:
-NodeAnnouncement:
NodeAnnouncement
UniqueId=<integer>
HopsToLive=<integer>
Depth=<integer>
CommitValue=<byte array>
Source=<Node Reference>
Announcee=<Node Reference>
EndMessage
-AnnouncementFailed:
AnnouncementFailed
UniqueId=<integer>
Reason=<string>
EndMessage
-AnnouncementReply:
AnnouncementReply
UniqueId=<integer>
ReturnValue=<byte array>
EndMessage
5.4.1.6.3.2. Anuncio de un nodo.
"-Hola, soy tu menstruacion.
-Ah! La regla!..."
El metodo a seguir por un nodo cuando se quiere anunciar pasa por tener
inicialmente una tabla de rutas. Pero aqui tenemos el problema de quien fue
primero, el huevo o la gallina: como tenemos una tabla de rutas si aun no
formamos parte de la red. Y este es precisamente el unico punto en el que
Freenet no es independiente del resto de redes que van sobre IP. Para
conseguir las primeras referencias necesitamos una lista que normalmente nos
bajaremos de la web (aunque hay un mecanismo para bajarnosla directamente de
nodos que participen en Freenet si tenemos alguna referencia anterior a
ellos, por ejemplo un fichero seednodes.ref antiguo).
Una vez tenga la menos una referencia a otro nodo, debe enviar un mensaje de
tipo "NodeAnnouncement" con el campo Depth a cero, HopsToLive al numero de
nodos que se quiera alcanzar y CommitValue con el hash SHA1 de un valor
aleatorio. Una vez hecho esto, debe enrutar dicho mensaje.
Si el anuncio falla, bien porque un nodo no pueda enrutar el mensaje o
porque reciba otro de tipo "AnnouncementFailed", dicho nodo debe esperar un
tiempo antes de intentar responder. Se recomienda esperar un periodo
razonable y duplicar el periodo esperado por cada fallo sucesivo.
Cuando el nodo originario reciba el mensaje "AnnouncementReply", debera
realizar la XOR del campo "ReturnValue" con el valor aleatorio inicial para
crear una XOR que incluya todos los valores aleatorios. Esto sera llamado
"AnnouncementKey", y este valor sera firmado con su clave privada, resultado
que se enviara en un mensaje "AnnouncementExecute" en el campo
"RefSignature". El valor "AnnouncementKey" se enviara como la parte final de
dicho mensaje.
Formato de AnnouncementExecute:
AnnouncementExecute
UniqueId=<integer>
RefSignatue=<signature>
DataLength=<integer>
Data /* Seguido de una parte de datos de longitud "DataLength"
octetos con una serie de cadenas de octetos delimitadas
por caracteres de nueva linea */
Una vez un nodo ha enviado un mensaje "AnnouncementReply", debera esperar el
mensaje de tipo "AnnouncementExecute" del nodo original. El valor Depth es
conocido y debe usarse para calcular el tiempo que dicho nodo debe esperar
la respuesta.
Cuando el nodo reciba "AnnouncementExecute", debe añadir su propio valor
aleatorio (usado para el campo "CommitValue" anteriormente) al final de la
lista en la parte final del mensaje y generar el campo "AnnouncementKey"
realizando la XOR del campo "ReturnValue" que recibio con todos los valores
de la lista. Entonces debe comprobar que el valor "CommitValue" que recibio
era exactamente el hash acumulativo de los valores aleatorios de la lista y
que la firma del nodo que se anuncia valida la "AnnouncementKey". Si algo
falla debe enviar hacia atras un mensaje "AnnouncementFailed" y hacia
delante un "QueryAborted".
Si no hubo fallo, el nodo debe crear una clave de tipo "Imaginary" con el
valor "AnnouncementKey" y añadirla como una referencia al nodo que se
anuncia en su tabla de rutas. Hecho esto, debe enviar el mensaje
"AnnouncementExecute" correspondiente al siguiente nodo.
Cuando el ultimo nodo reciba el mensaje "AnnouncementExecute" debe -aparte
de realizar todas las operaciones anteriores- generar el mensaje
"AnnouncementCompleted". Tomando como valor x el minimo entre el numero de
claves no imaginarias que tenga en su tabla de rutas y Depth+HopsToLive,
debera incluir al final de dicho mensaje las x claves no imaginarias mas
parecidas a la "AnnouncementKey". Cada nodo anterior debera reenviar el
mensaje "AnnouncementCompleted" tras actualizar con claves mas parecidas
-si las tiene en su "DataStore"- dicha lista. Lo que se recomienda que se
haga la lista obtenida en el nodo que se anuncia es ordenarlas por similitud
con la "AnnouncementKey" y pedirlas tan pronto como se pueda, almacenando
los datos en el "DataStore". De esta forma se consigue que el nuevo nodo
tenga un almacen considerable de claves similares. Para descentralizar mas
la informacion puede pedirse solo una porcion de dicha lista, por ejemplo
la mitad.
Por ultimo, el formato de mensaje es:
AnnouncementComplete
UniqueId=<integer>
DataLength=<integer>
Data /* Seguido de una parte de datos de longitud "DataLength"
octetos con una serie de cadenas de octetos delimitadas
por caracteres de nueva linea */
6. Amigos y parientes de Fred.
Freenet, por si aun no lo habeis notado, es todo un microcosmos paralelo de
experimentacion y desarrollo. A partir de esta red han ido apareciendo
distintos programas y servicios que añaden funcionalidad a la misma o
facilitan la tarea de desarrollo, insercion y mantenimiento de un freesite.
En este apartado intentare "pasar por encima" de alguno de ellos.
Pero no solo de Freenet vive el paranoide :-D. Tambien existen otros proyectos
paralelos de redes anonimas como son Entropia o el IIP (Invisible IRC Project).
Tambien estos proyectos tienen su cabida en esta seccion. De hecho, es muy
comun que las personas que se conectan al IIP mantengan nodos permanentes en
Freenet y sean los creadores de los mejores freesites (como ocurre con CofE,
mids, jrand0m, thetower y el resto de la peña).
6.1. FCPTools.
Las FCPTools son utilidades de linea de comandos que nos permiten utilizar
la red Freenet de forma sencilla y potente. Basicamente son parecidas a los
"comandos r" de Unix, y permiten obtener archivos de Freenet, insertar
archivos en la red, dividir un archivo en splitfiles e insertarlos en la red,
etc. En general, estas cosas pueden hacerse con la propia distribucion .jar
de Freenet, pero estos programas son mas sencillos de usar. Pueden obtenerse,
como la mayoria del software a utilizar, de la web en sourceforge.
Asimismo, las FCPTools incluyen una biblioteca en C para acceder directamente
al puerto FCP de un host (puede ser el local o cualquiera que lo tenga
abierto al exterior), la ezFCPlib. Aunque dicen que esta mal escrita y es
bastante antigua, puede ser una ayuda para comenzar a escribir clientes para
Freenet. Incluye una documentacion bastante pobre, pero suficiente para
empezar. Programadores compulsivos en C, animo y duro con ello: Freenet
necesita buenas ideas y buenos desarrolladores.
6.2. FMB.
FMB significa Freenet Message Board. Es un sistemas de noticias al estilo
news, pero totalmente anonimo (por supuesto) y bastante particular. La verdad
es que no es muy amigable para el novato, sobre todo porque puedes obtener
una copia sin documentacion y no tiene opcion de ayuda. Es muy comun ver
mensajes de personas que no entienden el funcionamiento del sistema (todos
hemos puesto mensajes asi) pidiendo ayuda o por probar a ver que pasa.
La clave para la edicion mas moderna del freesite desde el que puedes bajar
el software a la hora de escribir estas lineas es:
SSK@rjYFfgPHfolmcStiaoxESFfBXz8PAgM/FMBwishlist/11//
6.2.1. Canales y mensajes.
El sistema de funcionamiento esta basado de nuevo en claves SSK. El programa
(o tu mismo, si lo deseas) genera un espacio de claves (una clave publica y
su privada asociada) en el que insertas tus mensajes. En el FMB este
subespacio se conoce como "canal". Cada persona que se encuentra conectada
tiene su propio canal, y si deseas ver sus mensajes lo unico que tienes que
hacer es indicar al cliente FMB que deseas comenzar a escuchar en ese canal.
No solo recibiras entonces todos los mensajes que esa persona haya escrito,
sino tambien todos los que haya obtenido de otros usuarios. Estos ultimos
mensajes se consideran "no verificados", puesto que podria ser que el usuario
del que los hemos obtenido los hubiese falsificado. Por ello aparece la opcion
"verificar", que lo que hace es buscar el mensaje original en el espacio de
claves del remitente (no del distribuidor, que es el que tenemos). Si el
mensaje existe y coincide, la opcion de verificar desaparecera. Si no se
encuentra, seguira ahi por si queremos seguir intentandolo.
Ademas de los canales personales, existe el canal de "anuncios" (Announcement
channel). Debes escuchar los mensajes de dicho canal si quieres saber que
canales estan activos en cada momento (es decir, algo asi como quien esta
conectado).
Todos los canales muestran un tiempo en color negro o rojo. Este es el tiempo
de ultima actividad de dicha persona. En negro significa que el canal esta
activo; en rojo, que no lo esta. Las pequeñas letras y numeros que hay abajo
a la izquierda en el recuadro de cada canal indican el estado, que puede ser
eXito (X), Recibiendo (R), Insertando (I), reintentos (si es un numero) o
informacion no valida (el caracter ?).
No existe el concepto de mensaje privado en el FMB. Si lo que deseas es
mensajeria privada, logicamente debes usar cifrado con clave publica/privada
como PGP. Ademas, los mensajes que recibes son -por defecto- solo los que se
han insertado durante ese dia. Si deseas recibir mensajes antiguos debes
indicar la opcion --daysBack en la linea de comandos.
6.2.2. Archivos.
Tambien existen lo que se denominan "archivos" de mensajes. Los archivos no
son mas que todos los mensajes que una persona ha recibido (los cuales el
cliente FMB guarda en el fichero XML "messages") insertados en Freenet. Si lo
que deseas es ver mensajes antiguos, puedes bajarte uno de los archivos
disponibles (son famosos los archivos de Purple, que los inserta cada sabado)
e incluso si crees que tienes una buena coleccion de mensajes (bien por
cantidad o porque algunos no han sido muy distribuidos) puedes insertar tu
propio archivo para que otras personas puedan bajarselo, siendo este un modo
mas de redundancia para evitar la "muerte" de la informacion en Freenet.
6.2.3. Informacion sobre los usuarios.
"Pleased to meet you,
hope you guessed my name..."
Aunque Freenet es totalmente anonima, desearemos saber con quien estamos
escribiendonos en cada momento, no? Y como se come eso? Pues a lo que me
refiero es a que querremos saber si la persona que escribe es la misma que
mantiene ese freesite que tanto nos gusto... o si es un cretino que solo se
dedica a insultar al resto de la gente.
Para ello, los usuarios del FMB pueden insertar informacion personal propia:
cual es la clave de su freesite, sus intereses, lo que estan haciendo/buscando,
y cosas asi. No solo eso, tambien otros usuarios pueden hacer comentarios y
"puntuar" las actitudes de los demas. La puntuacion es muy sencilla: puedes
decidir que un usuario es bueno, malo o neutral. Si alguien no te cae bien por
algun motivo, puedes puntuarlo como malo (evil) e indicar dicho motivo en tu
comentario. Tambien si te cae bien/es amigo del IIP o lo que sea puedes poner
una puntuacion de "bueno". La puntuacion neutral se utiliza mucho para hacer
saber a los usuarios recien llegados que se ha recibido su anuncio por el
canal de "anuncios", y esto se considera de cortesia hacia ellos.
6.2.4. Ajedrez.
Ademas de poder enviar mensajes, el cliente FMB tiene un "chess lounge",
un subsistema para poder jugar al ajedrez en linea con otros usuarios de
FMB, con su propio tablero y con el que puedes ver todas las partidas que
en ese momento se esten jugando.
Existen otros programas de mensajeria como Frost y seguro que varios mas,
pero FMB (junto con Frost) parece ser el mas extendido.
6.2.5. Anuncios de freesites.
En la version que utilizo en estos momentos se ha añadido la opcion de
insertar anuncios de freesites, de forma que todos sepan que hay disponible
un nuevo freesite o una nueva edicion de uno antiguo y la clave
correspondiente. Esto sirve para eliminar la dependencia de la red de indices
como TFE, The Tower (TFEE) o YoYo!.
6.2.6. El problema de las 00:00:00.
FMB utiliza un mecanismo que se basa en la fecha para insertar los datos
referentes a los usuarios activos, los mensajes, etc. Por ello cuando pase
de las 23:59 GMT a las 00:00 GMT debeis reiniciar el cliente o seguira
pidiendo los datos con la fecha en que lo arrancaste (que ahora sera ayer) y
no recibiras los nuevos.
NOTA para usuarios españoles: La tipica duda resuelta. España esta en
GMT+1, GMT+2 con el DST (Daylight Saving Time) u horario de verano en
cristiano. Asi que a la 1 con el horario de invierno y a las 2 con el de
verano (siempre hora local del ordenador, no empeceis a mirar el teletexto)
hay que reiniciar FMB.
6.3. NIM.
NIM son las siglas de Nearly Instant Messaging. En realidad NIM no es ningun
programa, sino mas bien una tecnica surgida a partir de Freenet para que los
usuarios de un freesite den sus opiniones acerca del mismo.
La tecnica es sencilla y rapida de implementar. Se basa en que el usuario
envie sus comentarios insertandolos con una clave KSK determinada, por
ejemplo KSK@comentario_web_lindir-X, donde X se sustituye por un numero.
Cada usuario que incluya un comentario debe insertarlo incrementando X en
una unidad, de forma que no se produzca lo que se denomina una "colision"
(es decir, dos archivos distintos con la misma clave). Para evitarlo, lo que
se hace usualmente es añadir enlaces a dichas claves en marcos de la pagina e
indicar al usuario que solo utilice una clave el marco no se encuentra, de
igual forma que cuando se ponen referencias a futuras ediciones de un
freesite. En otros sites simplemente tienes que ir probando hasta encontrar
uno libre, sin marcos que te ayuden.
El creador de la Web solo tendra que pedir a Freenet los archivos asociados
a dichas claves de forma secuencial hasta que ya no le sea posible conseguir
ninguno mas. En futuras ediciones del site (ediciones o versiones DBR) se
cambia el numero X al primer mensaje no utilizado que haya para que los
usuarios no tengan que probar desde el principio, claro.
6.4. El proyecto Invisible IRC.
He visto que hay bastante desconocimiento de este tema por ahi. Aunque
algunas paginas web anuncien al IIP de esta forma:
"Sobre esta red [Freenet] se ha creado tambien un servicio de chat anonimo,
IIP (Invisible IRC Project)..."
(http://diariored.com/blog/soft/archivo/000049.html)
El IIP no "corre" sobre Freenet. Es una red aparte.
El proyecto IIP (Invisible IRC Proyect) es una red similar a Freenet,
totalmente anonima (aunque no distribuida, al menos no el servidor IRC),
pero con el IRC como unico servicio. La diferencia fundamental con Freenet
es que solo existe un servidor IRC para toda la red, con lo cual si este
servidor se encuentra inoperativo, el Invisible IRC no funcionara. El metodo
para conseguir el anonimato es el mismo que Freenet usa: el obscurantismo a
traves de varios "relays".
Aunque son redes distintas, existe una aplicacion (Frazaa) que utiliza ambas
para un mismo objetivo: compartir archivos en red de forma anonima. Frazaa
actua enviando los mensajes de control a traves del IIP y utilizando Freenet
como medio comun para el almacenamiento, de forma que las claves con las que
se accede a los datos en Freenet se intercambian mediante el IIP. Es incluso
mejor que opciones como KazaA puesto que no necesitas que el usuario que
inserto la informacion este conectado una vez conoces la clave: Freenet es
la que contiene los datos, no el usuario.
Ademas del daemon IRC, que controla 0x90/nop, existe un bot en la red
conocido como Trent y creado y mantenido por mids. Este bot es el que
controla todo el proceso de registro de nicks y canales del IIP. Trent
permite que no usurpen tu nick y tambien el "anonymail", un metodo de
mensajeria totalmente anonimo a traves del IIP.
Existe gran controversia acerca del hecho de que 0x90/nop tiene todo el
control sobre el servidor e incluso se han dado casos en los que ha
realizado un /kill a algun usuario, yendo en contra de la libertad total de
expresion que es un objetivo a seguir tanto por Freenet como por el IIP. De
todos modos, estos son casos muy extraños y en general nadie recibe un
opkill en el IIP, aunque insulte a otros usuarios o inunde los canales. El
/ignore es la unica solucion en estos casos (posiblemente, ayudado por algun
script que haga "nick-following").
El proyecto IIP tiene su pagina de inicio en www.invisiblenet.net/iip/ y
desde ella podemos bajarnos el cliente/servidor de la red (el equivalente
a Fred en IIP). Al contrario que Fred, el cliente esta escrito en C y hay
versiones precompiladas para Windows y fuentes para Unix (tambien Linux, *BSD
y Mac OSX, claro).
Una vez compilado e instalado el programa (en unix se llama isproxy), lo que
tenemos es un daemon IRC escuchando en nuestra maquina y conectados a otras
maquinas que conforman la red, al igual que con FProxy. Para acceder a la red,
lo unico que necesitamos es un cliente IRC cualquiera y conectar el mismo a
localhost (o la direccion de bucle local 127.0.0.1) al puerto indicado (el
6667 por defecto). A partir de aqui, el modo de funcionamiento es el mismo
que con el IRC normal, solo que ahora seremos totalmente anonimos.
Destacar el canal #freenet del IIP, donde (claro esta) puedes charlar con
muchos de los mantenedores de freesites e incluso con Matt Toseland, alias
toad, el "monkey coder" de FProxy, uno de los actuales desarrolladores de
Freenet.
6.5. Entropy.
Entropy en realidad se escribe ENTROPY, y significa Emerging Network To Reduce
Orwellian Potency Yield. Ahi va eso.
Entropy no es mas que una red del mismo estilo que Freenet (de hecho, utiliza
el mismo protocolo para la comunicacion nodo-cliente, el FCP o Freenet
Client Protocol) que se supone 100% compatible con clientes Freenet bien
hechos. Y bien hechos quiere decir aqui que cumplen la norma del FCP al
completo y no basan su funcionamiento en caracteristicas no documentadas de
la implementacion del FCP. No he tocado de momento nada este tema, pero parece
que el cliente al menos esta hecho en C, lo cual personalmente me parece un
acierto (al contrario que hacer el cliente en Java), pero eso es cuestion de
gustos. Si alguien quiere ser mas papista que el papa o mas alternativo que
Radio3, la web oficial del proyecto Entropy en ingles es
http://entropy.stop1984.com/en/home.html.
6.6. JAP (Java Anonymous Proxy).
Como su propio nombre indica, JAP es un programa que actua como proxy en la
misma linea que FProxy, pero en este caso es para navegar por la Web.
Supongo que el sistema que utiliza para mantener el anonimato es similar al
que usa Freenet o los servidores de correo anonimo. Claro que en este caso
es solo anonimato del receptor de la informacion.
La web para obtener el software correspondiente es:
http://anon.inf.tu-dresden.de/index_en.html
7. Lo que sabe Fred.
Bueno, ya hemos hablado de toda la familia, y de Fred, pero no hemos hablado
de que contenidos hay en Freenet... Y la cosa de momento tampoco es para tirar
cohetes. (¿o si?) :)
Para el que lo este pensando: si, hay muchas paginas pornograficas, como en la
Web. Y si, hay paginas de pedofilia y otras perversiones, tambien como en la
Web. Y hay paginas de warez, de musica propietaria en mp3, de generadores de
claves de registros para programas propietarios... Hay lo tipico que puedes
encontrar en la Web si buscas a fondo. No hay nada demasiado espectacular,
nadie creo yo que se dedica a bajarse archivos mp3 de Freenet pudiendo hacerlo
con e-Donkey: la diferencia de velocidad (aqui me refiero a retardo, a
latencia, no a regimen binario) es abismal. Y si la musica es casi imposible,
imagina entonces las peliculas DivX... eso si que es ciencia ficcion. Hay
gente que lo hace, pero a ti las SGAE o la RIAA no van a meterte en el talego
por un DivX piratilla (o si?) :)
Ultimamente estan apareciendo una serie de freesites que en opinion de
muchos -me incluyo- no hacen ningun bien a Freenet. Son freesites en los que
se narra un asesinato. Al contrario que ocurria con "I Killed Jonathan
Meyer", los autores no incluyen un mensaje indicando que es todo falso, por
lo que Fillament estaba en lo cierto al avisarnos de que algo asi podria
pasarle a Freenet. En el momento de escribir estas lineas aun desconozco si
dichas historias son ciertas o no -esto ultimo es lo mas probable-, pero no
dejan de ser desagradables y me pregunto si alguna vez alguien realmente
sera capaz de hacer algo asi. Como siempre digo, estais avisados.
En Freenet puedes poner lo que te de la gana, pero no es una red pensada para
descargas masivas de informacion ilegal. Si quieres intentarlo, hazlo. Si
quieres poner/ver porno, hazlo. Es tu problema. Pero ni el creador ni los
desarrolladores la han creado para eso. La han creado para que tu hagas lo
que te de la gana con ella, y publiques sin censura lo que quieras.
Por ejemplo, hay un freesite que parodia los mensajes de la RIAA (Recording
Industry Association of America), incluyendo fotos de los campos de
concentracion nazis, de personas muriendo de hambre en etiopia o de G.W. Bush
al lado de otra de Hitler como si fueran amigos. Eso no puede hacerse en la
mayoria de paises en la Web sin buscarte problemas judiciales (no importa
que ganes o no), como ha ocurrido los casos de PutaSGAE o el Avertefue.
No existe el copyright en Freenet, e incluso puede ser que busques el texto
de la licencia GPL y lo que obtengas sea una foto de una señorita desnuda.
Existen noticias de que cierto grupo de usuarios chinos de Freenet utilizan
la red para evitar la censura en su pais. Otro ejemplo del uso de Freenet, que
no tiene por que ser "maligno" (o si?) :).
Pero sobre todo, Freenet proporciona algo muy interesante: todo el espacio
que quieras para poder publicar sin pagar NADA. Claro que, por supuesto,
solo si tu informacion es interesante para sus usuarios se mantendra en la
red...
8. Conclusiones.
Lo bueno (o malo) de Freenet es que no hay ley, es el paraiso de los
anarquistas y un lugar muy interesante donde experimentar si tienes tiempo y
ganas. Como decian en cierta revista de informatica de ocio, es "Solo para
adictos".
Desde luego si lo que buscas es entrar en ordenadores de manera sencilla,
mejor sera que te vayas olvidando: no hay nada nuevo para ello en estos
protocolos. Si lo que buscas es un estudio sobre un apartado distinto de la
seguridad en Internet (porque eres un paranoide, posiblemente) quiza sea el
momento de empezar a estudiar el tema.
Por ultimo, para todo aquel que piense que los usuarios de Freenet son todos
unos depravados pederastas o psicopatas, quiero decirle que esta muy
equivocado. No escribo este articulo para animar a nadie a delinquir -y
menos que luego lo cuente en un freesite- y repudio la pederastia, como la
mayor parte de usuarios de Freenet. Esta es solo una red que esta naciendo, y
el camino que tome depende de sus usuarios futuros, asi que es pronto para
comenzar una caza de brujas. Quiza algun dia sea realmente necesaria una red
asi, y entonces ya tendremos casi todo el camino andado.
Recordad que Freenet no es otro e-donkey: es una tabla de hashes totalmente
distribuida (jrand0m dixit). Ya podeis ir pensando que hacer con ella.
Lindir.