X-Git-Url: https://git.llucax.com/z.facultad/75.74/practicos.git/blobdiff_plain/918a7b42017533f6f18edc8735d6d82a5494f055..84df7fe38e7c8ff3c99cd3a05b6c42a5b8bcb213:/practicas/pipi/README?ds=inline diff --git a/practicas/pipi/README b/practicas/pipi/README index cca4337..cc25153 100644 --- a/practicas/pipi/README +++ b/practicas/pipi/README @@ -2,9 +2,9 @@ Sistemas Distribuidos I (75.74) =============================== ----------------------------- -Trabajo práctico de stack IP ----------------------------- +------------------------------------------------------------------ +TP 2: Sistema de resolución de nombres sobre IP adaptado a sockets +------------------------------------------------------------------ :Author: Leandro Lucarella (77891) @@ -14,18 +14,23 @@ Organización En el directorio `src` se encuentra el código fuente del trabajo, con su correspondiente `Makefile` para compilarlo tan solo ejecutando `make`. -Dentro de este directorio hay también dos scripts de pruebas completas: -`test.sh` (con 1 router) y `test2.sh` (con 2 routers). En el directorio `rutas_ejemplo` contiene algunos archivos con descripciones de -rutas de ejemplo para correr los programas. +rutas de ejemplo para correr los programas. En el directorio `zonas_ejemplo` se +encuentran archivos de configuración de zonas de dominios de nombre para +realizar pruebas. Uso === -El trabajo consta de un programa llamado `ip` (más algunas otras pruebas que no -tiene relevancia). Este programa corre 3 procesos, uno que recibe paquetes IP +El trabajo consta de dos programas, uno llamado `ip` y otro `dns` (más algunas +otras pruebas que no tienen relevancia). + +ip +-- + +El programa `ip` corre 3 procesos (fork(2)eados), uno que recibe paquetes IP otro que recibe entrada del usuario y envía paquetes IP y otro que redirecciona (forward) paquetes IP en caso de ser pertinente. @@ -58,7 +63,7 @@ proto Protocolo que transporta (default 0) -El programa se queda esperando la entrada del usuario, y sale cuando está se +El programa se queda esperando la entrada del usuario, y sale cuando esta se termina (Ctrl-D). El formato de entrada es:: IP DESTINO @@ -68,6 +73,46 @@ Es decir, en una línea se pone la IP de destino y en la línea siguiente el mensaje. Para enviar otro mensaje, nuevamente se pone IP de destino en una línea y el mensaje en la siguiente. +dns +--- + +El programa `dns` corre también 3 procesos (fork(2)eados), uno que recibe +peticiones de nombres, otro que recibe entrada del usuario y envía peticiones +(o mejor dicho encola peticiones para ser enviadas) y otro que realiza el envío +de las peticiones realmente. + +Uso:: + + ./dns ip [route_file [zone_file [port]]] + +ip + IP que utiliza este proceso (ídem programa `ip`) + +route_file + Archivo con las rutas (ídem programa `ip`) + +zone_file + Archivo con la descripción de las zonas. El formato es muy simple. Cada zona + está separada por un renglón en blanco y empieza con una línea con 3 campos + separados por espacios o tab: nombre de la zona, TTL y nodo padre. Luego le + sigue la lista de registros de esa zona, también con 3 campos por renglón: + nombre, tipo de registro (A para indicar una IP, NS para indicar donde buscar + registros de una zona con ese nombre) e IP (ya sea la IP definitiva si es A o + la IP del nameserver al cual recurrir si es NS). Se pueden ver ejemplos de + estos archivos en el disco entregado. + +port + Puerto en el cual escuchará la abstracción de capa física sobre TCP. + + +El programa es muy similar a `ip`, se queda esperando la entrada del usuario, +y sale cuando esta se termina (Ctrl-D). El formato de entrada es:: + + HOSTNAME_A_BUSCAR + +Es decir, se escribe en una línea el nombre del host del cual se quiera obtener +la IP y se presiona ENTER. + Diseño del trabajo ================== @@ -76,11 +121,21 @@ El trabajo fue desarrollado en C++, orientado a objetos. Se compone de las siguientes clases: Dev - Encapsula la capa física y el dispositivo de red. Utiliza una cola como medio - físico y el id representaría el cable (si 2 dispositivos tienen cola con id - distinto serían como si no compartieran el mismo cable). Por simplicidad a la - cola siempre se envía el tamaño del MTU completo pero se agrega una cabecera - con el tamaño real del frame. + Encapsula la capa física y el dispositivo de red. Es una interfaz abstracta. + +DevQue + Implementación de Dev utilizando una cola como medio físico y el id + representaría el cable (si 2 dispositivos tienen cola con id distinto serían + como si no compartieran el mismo cable). Por simplicidad a la cola siempre + se envía el tamaño del MTU completo pero se agrega una cabecera con el + tamaño real del frame. + +DevTCP + Implementación de Dev utilizando conexiones TCP. Por cada frame saliente a un + destino en particular se crea una conexión TCP (a menos que ya esté creada, en + cuyo caso se reutiliza) y se escucha por conexiones entrantes para recibir + frames (también guardándolas para reutilizarlas). A diferencia del DevQue se + envía el tamaño del frame exacto (en realidad se agrega una pequeña cabecera). IPAddr Clase auxiliar que encapsula una dirección IP. @@ -119,75 +174,178 @@ IPOut * No existe una ruta para el destino * Tamaño de paquete más grande que MTU y DF=1 +libtcp + Es el único componente del TP que no es orientado a objetos ya que se + reutilizó de trabajos anteriores. Es una pequeña abstracción sobre la API de + sockets de BSD para mayor simplicidad. -Ejemplo de corrida -================== - -Host 10.10.10.1 ---------------- - -Rutas: - -* 10.10.10.1 0.0.0.0 35 0 -* 10.10.10.3 10.10.10.5 35 1 -* 10.10.10.5 0.0.0.0 35 0 - -Envía "adios mundo cruel!!!" al host 10.10.10.3:: - - $ (echo -e '10.10.10.3\nAdios mundo cruel!!!'; sleep 1) | ./ip 10.10.10.1 0 0 ../rutas_ejemplo/route_10.10.10.1.txt - IPOut::send (10.10.10.1): Fragmento 0 => IPHeader: version=4 total_len=40 id=44919 DF=0 MF=1 offset=0 TTL=64 proto=0 checksum=214 src=10.10.10.1 dst=10.10.10.3 - data (15) = Adios mundo cru - IPOut::send (10.10.10.1): Fragmento 1 => IPHeader: version=4 total_len=25 id=44919 DF=0 MF=0 offset=15 TTL=64 proto=0 checksum=315 src=10.10.10.1 dst=10.10.10.3 - data (5) = el!!! - Enviado 'Adios mundo cruel!!!' a 10.10.10.3 - - -Router 10.10.10.5 ------------------ +ResolvProtoRequest + Clase que encapsula una petición de resolución de nombre a enviar via IP. -Rutas: +ResolvProtoResponse + Clase que encapsula una respuesta de resolución de nombre a enviar via IP. -* 10.10.10.1 0.0.0.0 35 0 -* 10.10.10.3 0.0.0.0 32 0 -* 10.10.10.5 0.0.0.0 35 0 +NameServer + Clase encargada de resolver los nombres. Escucha por peticiones y puede + resolverlas recursiva o directamente (según venga de otro NameServer o de un + Resolver la petición). Esta clase se compone de varias otras clases auxiliares + para almacenar las zonas y el cache. -Recibe el mensaje:: - $ ./ip 10.10.10.5 1 1 ../rutas_ejemplo/route_10.10.10.5.txt - IPIn::recv (10.10.10.5): IPHeader: version=4 total_len=40 id=44919 DF=0 MF=1 offset=0 TTL=64 proto=0 checksum=214 src=10.10.10.1 dst=10.10.10.3 - data (15) = Adios mundo cru - IPIn::recv (10.10.10.5): IPHeader: version=4 total_len=25 id=44919 DF=0 MF=0 offset=15 TTL=64 proto=0 checksum=315 src=10.10.10.1 dst=10.10.10.3 - data (5) = el!!! - IPOut::forward_loop (10.10.10.5): A forwardear (id 44919) - IPOut::send (10.10.10.5): Fragmento 0 => IPHeader: version=4 total_len=40 id=44919 DF=0 MF=1 offset=0 TTL=64 proto=0 checksum=214 src=10.10.10.1 dst=10.10.10.3 - data (12) = Adios mundo - IPOut::send (10.10.10.5): Fragmento 1 => IPHeader: version=4 total_len=28 id=44919 DF=0 MF=1 offset=12 TTL=64 proto=0 checksum=298 src=10.10.10.1 dst=10.10.10.3 - data (3) = cru - IPOut::forward_loop (10.10.10.5): A forwardear (id 44919) - IPOut::send (10.10.10.5): Fragmento 0 => IPHeader: version=4 total_len=25 id=44919 DF=0 MF=0 offset=15 TTL=64 proto=0 checksum=315 src=10.10.10.1 dst=10.10.10.3 - data (5) = el!!! - - -Host 10.10.10.3 ---------------- - -Rutas: - -* 10.10.10.1 10.10.10.5 32 1 -* 10.10.10.3 0.0.0.0 32 0 -* 10.10.10.5 0.0.0.0 32 0 - -Finalmente este host recibe todos los fragmentos, reensabla y pasa el - paquete completo a la capa superior:: - - $ ./ip 10.10.10.3 0 0 ../rutas_ejemplo/route_10.10.10.3.txt - IPIn::recv (10.10.10.3): IPHeader: version=4 total_len=40 id=44919 DF=0 MF=1 offset=0 TTL=64 proto=0 checksum=214 src=10.10.10.1 dst=10.10.10.3 - data (12) = Adios mundo - IPIn::recv (10.10.10.3): IPHeader: version=4 total_len=28 id=44919 DF=0 MF=1 offset=12 TTL=64 proto=0 checksum=298 src=10.10.10.1 dst=10.10.10.3 - data (3) = cru - IPIn::recv (10.10.10.3): IPHeader: version=4 total_len=25 id=44919 DF=0 MF=0 offset=15 TTL=64 proto=0 checksum=315 src=10.10.10.1 dst=10.10.10.3 - data (5) = el!!! - IPIn::recv (10.10.10.3): Paquete completo: data = 'Adios mundo cruel!!!' - Recibido 'Adios mundo cruel!!!' (len 20) de 10.10.10.1 para 10.10.10.3 (proto = 0) +Ejemplo de corrida +================== -.. vim: filetype=rst : +Archivo de configuración de zonas de 10.10.10.2:: + + homero.casa 600 10.10.10.1 + tito A 10.10.100.1 + juan A 10.10.100.2 + juan A 10.10.100.3 + pepe A 10.10.100.4 + juan A 10.10.100.5 + pepe A 10.10.100.6 + marge NS 10.10.10.3 + todos NS 10.10.10.1 + todos NS 10.10.10.3 + todos NS 10.10.10.141 + +Línea de comandos:: + + ./dns 10.10.10.2 ../rutas_ejemplo/mi_lan.txt ../zonas_ejemplo/10.10.10.2.txt + +Resolución de un nombre local con una sola IP +--------------------------------------------- + +Línea de comandos:: + + ./dns 10.10.10.2 ../rutas_ejemplo/mi_lan.txt ../zonas_ejemplo/10.10.10.2.txt + +Salida:: + + tito.homero.casa + Resolviendo tito.homero.casa... + resolv_direct -> tratando de resolver: tito.homero.casa + resolv_direct found (local/hijo): ResolvProtoResponse(ret=2, ttl=600, 10.10.100.1) + resolv_recursive -> gotcha! ResolvProtoResponse(ret=2, ttl=600, 10.10.100.1) + Resultado: ResolvProtoResponse(ret=2, ttl=600, 10.10.100.1) + +Resolución de un nombre local con múltiples IP +---------------------------------------------- + +Salida:: + + juan.homero.casa + Resolviendo juan.homero.casa... + resolv_direct -> tratando de resolver: juan.homero.casa + resolv_direct found (local/hijo): ResolvProtoResponse(ret=2, ttl=600, 10.10.100.2, 10.10.100.3, 10.10.100.5) + resolv_recursive -> gotcha! ResolvProtoResponse(ret=2, ttl=600, 10.10.100.2, 10.10.100.3, 10.10.100.5) + Resultado: ResolvProtoResponse(ret=2, ttl=600, 10.10.100.2, 10.10.100.3, 10.10.100.5) + +Resolución de un nombre local no existente +------------------------------------------ + +Salida:: + + none.homero.casa + Resolviendo none.homero.casa... + resolv_direct -> tratando de resolver: none.homero.casa + resolv_direct NOT FOUND (es local pero no existe) + Resultado: ResolvProtoResponse(ret=4, ttl=0) + +Resolución de un nombre remoto con múltiples IP y 2 niveles de indirección +-------------------------------------------------------------------------- + +Archivo de configuración de zonas de 10.10.10.1:: + + casa 600 0.0.0.0 + burns A 10.10.10.1 + homero A 10.10.10.2 + marge A 10.10.10.3 + manuk A 10.10.10.141 + juan A 100.10.100.5 + pepe A 100.10.100.6 + homero NS 10.10.10.2 + marge NS 10.10.10.3 + manuk NS 10.10.10.141 + + burns.casa 600 0.0.0.0 + tito A 100.10.100.1 + juan A 100.10.100.2 + juan A 100.10.100.3 + pepe A 100.10.100.4 + juan A 100.10.100.5 + pepe A 100.10.100.6 + + todos.homero.casa 9500 0.0.0.0 + tito A 10.1.100.1 + juan A 10.1.100.2 + juan A 10.1.100.3 + pepe A 10.1.100.4 + juan A 10.1.100.5 + pepe A 10.1.100.6 + +Archivo de configuración de zonas de 10.10.10.3:: + + marge.casa 600 10.10.10.1 + tito A 30.10.100.1 + juan A 30.10.100.2 + juan A 30.10.100.3 + pepe A 30.10.100.4 + juan A 30.10.100.5 + pepe A 30.10.100.6 + manuk NS 10.10.10.141 + todos NS 10.10.10.1 + todos NS 10.10.10.3 + todos NS 10.10.10.141 + + todos.homero.casa 9500 10.10.10.2 + tito A 10.1.100.1 + juan A 10.1.100.2 + juan A 10.1.100.3 + pepe A 10.1.100.4 + juan A 10.1.100.5 + pepe A 10.1.100.6 + + marge.homero.casa 9500 10.10.10.2 + tito A 10.3.100.1 + juan A 10.3.100.2 + juan A 10.3.100.3 + pepe A 10.3.100.4 + juan A 10.3.100.5 + pepe A 10.3.100.6 + + +La petición se realiza desde 10.10.10.2, quien debe recurir a su nodo padre +(10.10.10.1) que indica que el encargado de resolver esa zona es 10.10.10.3. + +Salida de 10.10.10.2:: + + pepe.marge.casa + Resolviendo pepe.marge.casa... + resolv_direct -> tratando de resolver: pepe.marge.casa + resolv_direct -> evaluando padre 10.10.10.1 + resolv_direct found (al padre): 10.10.10.1 + resolv_recursive -> redirect a ResolvProtoResponse(ret=3, ttl=600, 10.10.10.1) + query -> pidiendo ResolvProtoRequest(query_type=0, name=pepe.marge.casa) a 10.10.10.1 + query -> recibido ResolvProtoResponse(ret=3, ttl=600, 10.10.10.3) de 10.10.10.1 + resolv_recursive_r -> redirect a ResolvProtoResponse(ret=3, ttl=600, 10.10.10.3) + query -> pidiendo ResolvProtoRequest(query_type=0, name=pepe.marge.casa) a 10.10.10.3 + query -> recibido ResolvProtoResponse(ret=2, ttl=600, 30.10.100.4, 30.10.100.6) de 10.10.10.3 + resolv_recursive_r -> gotcha! ResolvProtoResponse(ret=2, ttl=600, 30.10.100.4, 30.10.100.6) + Resultado: ResolvProtoResponse(ret=2, ttl=600, 30.10.100.4, 30.10.100.6) + +Salida de 10.10.10.1:: + + NameServer::send_loop() -> recibido ResolvProtoRequest(query_type=0, name=pepe.marge.casa) + resolv_direct -> tratando de resolver: pepe.marge.casa + resolv_direct found (local/hijo): ResolvProtoResponse(ret=3, ttl=600, 10.10.10.3) + NameServer::send_loop() -> respondo ResolvProtoResponse(ret=3, ttl=600, 10.10.10.3) + +Salida de 10.10.10.3:: + + NameServer::send_loop() -> recibido ResolvProtoRequest(query_type=0, name=pepe.marge.casa) + resolv_direct -> tratando de resolver: pepe.marge.casa + resolv_direct found (local/hijo): ResolvProtoResponse(ret=2, ttl=600, 30.10.100.4, 30.10.100.6) + NameServer::send_loop() -> respondo ResolvProtoResponse(ret=2, ttl=600, 30.10.100.4, 30.10.100.6) + +.. vim: filetype=rst sw=2 sts=2 et :