Archivar como 29 marzo 2009

Avanzando a pasos agigantados.

marzo 29, 2009

Y es que no paramos de trabajar… Si bien todavía nos queda mucho para tener algo estable y usable, esta misma semana podremos llegar a tener incluso algo funcional.

AODV que funciona a través del puerto UDP 654 genera y puede recibir tres tipos de paquetes:

  1. Route Requests (RREQ): Cuando queremos queremos comunicarnos con un ordenador C, desde nuestro ordenador A, entonces generamos un paquete de este tipo. Lo mandamos en Broadcast, es decir, mandamos un paquete esperando que lo lean la más gente posible para que nos generen una respuesta. Este paquete contiene información sobre quien lo ha generado (A) y hacia donde quiere ir (C), además de otra información de control necesaria para el protocolo: números de saltos o tiempo de vida del paquete. El paquete ira saltando por todos los nodos intermedios B1, B2, B3, etc. buscando su destino.
  2. Route Replies (RREP): Cuando un ordenador recibe un paquete RREQ cuyo destino es el mismo, o sea, el paquete anterior llega a C, entonces se genera RREP. El paquete se envia por el mismo camino que ha llegado pero, obviamente en sentido inverso. Todos los nodos intermedios aprobecharan además para actualizar su tabla de rutas porque ya saben donde estan el resto de ellos. En nuestro ejemplo, a medida que vaya pasando por los distintos nodos C, B3, B2, B1 y A añadiran en su tabla de rutas los nodos correspondientes.
  3. Route Errors (RERR): Son mensajes de error cuando alguien se ha caido de la red. Se genera este tipo de paquetes para comunicar que el nodo o nodos son inaccesibles.

Pues bien, nosotros hemos conseguido realizar peticiones de rutas e incluso respuestas de ellas. Aunque todavía está un poco verde creo que podremos mostraros un ejemplo de funcionamiento esta misma semana del funcionamiento de Meshias; desde como compilarlo, pasando por las reglas de iptables necesarias, para luego hacer un ping y conseguir generar una petición de ruta y su respuesta, consiguiendo conectar con el objetivo.

Capturando paquetes y mirando su ruta

marzo 27, 2009

¿Cómo capturamos los paquetes?

Como viene explicado en el anterior post meshias se pone en funcionamiento cada vez que tenemos que mandar un paquete. En ese momento debemos capturar el paquete para averiguar hacia donde va dirigido. Una vez averiguado hacia donde va dirigido comprobamos en la tablas de rutas del kernel si sabría enrutarlo. Este proceso es bastante sencillo de entender, no ha sido igualmente facil para programarlo.

Hemos necesitado dos librerías auxiliares para hacer este trabajo. Para capturar los paquetes hemos utilizado libnetfilter-queue, a partir de ahora nfqueue. Nfqueue es una herramienta del equipo de netfilter que nos permite hacer cosas muy curiosas. Su funcionamiento la podemos dividir en dos partes. La primera es que necesitamos reglas de iptables. Iptables es el firewall de núcleo Linux, también desarrollado por el equipo de netfilter y que nos permite, entre otras muchas cosas, crear una regla para los paquetes que cumplan las condiciones necesarias, pasarlas a cola de nfqueue. Esto significa que podemos crear reglas de iptables que irán encolando los paquetes que nosotros queramos para tratarlos manualmente.

Una vez en la cola de nfqueue podemos aceptarlos, robarlos o tirarlos para que no sigan su camino. Robarlos significa que podemos mantenerlos en espera hasta que queramos aceptarlos o tirarlos posteriormente. Nosotros lo único que hacemos es mirar a qué IP están dirigidos los paquetes, para comprobar si existe una ruta para el paquete; si existe lo aceptamos  sin más, y entonces el paquete es enrutado y  enviado por la interfaz de red correspondiente.  Si sin embargo no tenemos la ruta para la IP de destino de ese paquete y esa IP está dentro del rango de direcciones de la red mesh que está usando meshias (por ejemplo la red 192.168.1.X) lo robamos hasta averiguar la ruta. Si no la encontramos tiramos el paquete o si lo encontramos agregamos la ruta al kernel y lo aceptamos.

Manejando rutas

Hemos dicho que usamos principalmente dos librerías. Pues si la primera era nfqueue, la segunda es libnl. Esta ruta es una interfaz que nos permite comunicarnos con el kernel mediante sockets netlink, pero que nos oculta su funcionamiento interno y nos ofrece una interfaz más cómoda de usar. Como bien explican en la wikipedia, los sockets netlink son usados por muchas aplicaciones de red para comunicarse con el kernel, por ejemplo iproute los usa.

Nosotros para agregar o quitar rutas si se cae un enlace lo hacemos a través del libnl. Una vez conocida la ruta para una dirección ip, la añadimos a la tabla de rutas con libnl. Pero ahí no acaba nuestro trabajo: tenemos que mantener la ruta actualizada. Las redes mesh tienen un carácter más o menos dinámico, y los nodos pueden conectarse, desconectarse,y moverse de lugar con el tiempo. Por ello si no recibimos actividad por cierta ruta tras cierto intervalo de tiempo, asumimos que algún nodo de la ruta ya no está ahí, y tenemos que borrar la ruta de la tabla de rutas. El borrar de la tabla de ruta también lo hacemos con libnl.

Hay otro tipo de ocasiones en las que también necesitamos borrar rutas. Como ya contamos en la entrada anterior del blog, una ruta puede tener varios nodos intermedios por los que va saltando el paquete hasta llegar a su destino. En el párrafo anterior hemos contemplado que si una ruta deja de estar activa cierto tiempo debemos asumir que algún enlace de la cadena se ha roto y por tanto tenemos que invalidr la ruta. Bien, pues gracias a que libnl nos permite conocer el estado de los nodos que están cerca nuestra mediante la tabla de vecinos,podemos saber si un vecino ya no está ahí. Si un vecino deja de serlo, libnl nos avisará, y nosotros entonces comprobaremos si teníamos alguna que pasaba por ese vecino. En caso de que sea así, tendremos que borrar la ruta. Esto actualmente no lo tenemos implementado y en AODV es opcional (está contemplado como detalle de implementación), pero planeamos hacerlo.

Documentando el proyecto

marzo 25, 2009

Feliz año! La última entrada decía que el trabajo se demuestra andando, pero lo cierto es que si bien nosotros hemos andado mucho en meshias, ha sido en la sombra porque no hemos publicado nada en el blog. Sólo un post! Está claro que a estas alturas ya lo único que podemos hacer es.. documentar mediante el weblog. Y eso intentaré hacer.

¿Qué es Meshias?

Meshias por ahora pretende ser una implementación del RFC experimental 3561, que se refiere al protocolo AODV. AODV es un protocolo de red que permite implementar una red mesh, que es básicamente una red wifi descentralizada que no necesita de puntos de acceso, y cuyo radio de cobertura de la red no es el del punto de acceso/los puntos de acceso de la red como en una red wifi normal (porque como he dicho, no existen puntos de acceso), sino que el radio de cobertura de la red es la unión del radio de todos los nodos de la red.

¿Cómo funciona AODV?

Hablaré muchas veces de AODV y de Meshias indistintamente, pero que quede claro que AODV es el protocolo, Meshias una implementación de éste. Bien. AODV trabaja sobre una red wifi en modo Ad-Hoc. AODV es un protocolo de enrutado, y entra en acción cuando se va a enviar un paquete a una dirección IP hacia la cual no tenemos una ruta conocida. Si tenemos 3 equipos A-B-C y cada equipo solo tiene enlace con los que tiene a su lado, en una red Ad-Hoc normal A nunca podría enviar paquetes a C porque no tiene enlace con él. Con AODV, todos los nodos de la red pasan a ser enrutadores en caso necesario. Así, si A quiere enviar un paquete a C, B haría de paso intermedio, recibiría los paquetes de A y los enviaría a C.

El problema radica en encontrar el camino de A a C, porque puede haber cualquier número de nodos intermedios entre los dos equipos: A-B1-B2-B3…BN-C. AODV se encarga de calcular la ruta de A a C cuando se detecta un paquete dirigido a un equipo (C) cuya ruta es desconocida. Una vez Meshias encuentra la ruta, añade a la tabla de rutas del kernel (puedes consultarla con el comando route -n) y ya está, todo funciona sólo sin necesidad de Meshias, Linux lo hace todo sólito. Meshias deja que se envíe el paquete que había capturado dirigido a C, y el kernel lo enruta y todo funciona de forma transparente.

Meshias volverá a capturar sucesivos paquetes dirigidos a C (y en general captura paquetes dirigidos a cualquier equipo de la red mesh), pero comprobará que ya existe una ruta a C en la tabla de rutas del kernel, y “aceptará” etos paquetes, los dejará pasar de largo para que el kernel de Linux se encargue de enrutarlos.

Encontrando la ruta

Bien, y ahora viene la gran pregunta ¿cómo demonios encuentro la ruta del arroz? Ahí está el quit de la cuestión. La idea es enviar una petición de ruta por broadcast para que todos los equipos que estén dentro de mi rango de cobertura la reciban y la procesen. De esa manera, si desde A queremos encontrar la ruta a C, B recibiría una petición broadcast de A preguntando “¿donde está C?”. B en un principio no sabría donde está C, así que haría exactamente lo mismo. Pero antes se apunta que tiene enlace directo con la ip de A en su tabla de rutas, aprovechando que le ha llegado tráfico de A.

Despues de eso, B  renviaría la petición broadcast que le llega de A. C recibiría una petición de ruta por broadcast enviada por B en nombre de A diciendo “¿donde está C?”, y como Ć lo sabe (es él!), se apunta que tiene una ruta hacia A, que es exactamente la ruta inversa que ha seguido la petición broadcast. Luego de eso, C envia una respuesta a la petición de ruta: una respuesta de ruta.  Se la envía directamente con destino A. Al enviar ese paquete, como ya tenemos la ruta hacia A, el paquete se envía. B lo procesa, y se guarda la ruta hacia C igual que hacemos cada vez que recibimos un paquete AODV. Finalmente esa misma respuesta de ruta llega a A, y se apunta la ruta hacia C en la tabla de rutas. Por fin, despues de eso, Meshias acepta el paquete inicial que iba dirigido a C, y el kernel lo enruta adecuadamente. B recibe ese mismo paquete, y como también conoce una ruta hacia C, hace de router reenviando el paquete, que finalmente llega a C.

Este es, a muy groso modo por supuesto el funcionamiento de AODV.

State of the art

Actualmente tenemos creada  la infraestructura y enviamos y procesamos peticiones de rutas, falta poder procesar respuesta de rutas para que AODV funcione mínimamente. El desarrollo de meshias estuvo parado unos meses por navidades y Enero pero luego, pese a no haber estado publicando en el blog, hemos estado programando, que es lo que realmente nos gusta. El código no lo hemos subido aun sin embargo a la forja de RedIRIS, porque hemos tenido problemas con ella (mi usuario no funciona!). Mientras tanto hemos estado usando Launchpad con bazaar que funcionan muy bien. Podéis descargaros el código de meshias con el siguiente comando:

bzr branch lp:meshias

Para compilarlo, las instrucciones están (en inglés, como todo el código de Meshias) en el fichero COMPILE. Comprobaréis que compila. Se puede ejecutar, pero lo cierto es que actualmente no hemos creado ningún fichero con instrucciones de cómo usar meshias porque aun no es usable. Pronto (esta semana o la siguiente!) lo será, y subiremos instrucciones para poder probarlo en casa. Be tunned!


Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.