1 ===============================
2 Sistemas Distribuidos I (75.74)
3 ===============================
5 ------------------------------------------------------------------
6 TP 2: Sistema de resolución de nombres sobre IP adaptado a sockets
7 ------------------------------------------------------------------
9 :Author: Leandro Lucarella (77891)
16 En el directorio `src` se encuentra el código fuente del trabajo, con su
17 correspondiente `Makefile` para compilarlo tan solo ejecutando `make`.
19 En el directorio `rutas_ejemplo` contiene algunos archivos con descripciones de
20 rutas de ejemplo para correr los programas. En el directorio `zonas_ejemplo` se
21 encuentran archivos de configuración de zonas de dominios de nombre para
28 El trabajo consta de dos programas, uno llamado `ip` y otro `dns` (más algunas
29 otras pruebas que no tienen relevancia).
34 El programa `ip` corre 3 procesos (fork(2)eados), uno que recibe paquetes IP
35 otro que recibe entrada del usuario y envía paquetes IP y otro que redirecciona
36 (forward) paquetes IP en caso de ser pertinente.
40 ./ip ip [router [forward [route_file [queue_id [proto]]]]]
43 IP que utiliza este proceso
46 0 si es router, 1 si no lo es (default 0)
49 0 si puede hacer forwarding, 1 si no (default 0)
52 Archivo con las rutas. El formato del archivo es una ruta por línea, cada
53 línea se compone de red (por ahora sólo soporta IPs puntuales), gateway (si es
54 cero es que están en la misma red), MTU y métrica (todavía no se usa),
55 separados por uno o más espacios o tabs (default `route.txt`)
58 Identificador de la cola a usar como medio físico, también establece el
59 identificador de la cola a usar para comunicarse con el otro proceso
60 (`test_ipout`) para hacer forwarding, que será queue_id + 1 (default
61 `DEV_DEFAULT_KEY` obtenido de `dev.h`)
64 Protocolo que transporta (default 0)
67 El programa se queda esperando la entrada del usuario, y sale cuando esta se
68 termina (Ctrl-D). El formato de entrada es::
73 Es decir, en una línea se pone la IP de destino y en la línea siguiente el
74 mensaje. Para enviar otro mensaje, nuevamente se pone IP de destino en una línea
75 y el mensaje en la siguiente.
80 El programa `dns` corre también 3 procesos (fork(2)eados), uno que recibe
81 peticiones de nombres, otro que recibe entrada del usuario y envía peticiones
82 (o mejor dicho encola peticiones para ser enviadas) y otro que realiza el envío
83 de las peticiones realmente.
87 ./dns ip [route_file [zone_file [port]]]
90 IP que utiliza este proceso (ídem programa `ip`)
93 Archivo con las rutas (ídem programa `ip`)
96 Archivo con la descripción de las zonas. El formato es muy simple. Cada zona
97 está separada por un renglón en blanco y empieza con una línea con 3 campos
98 separados por espacios o tab: nombre de la zona, TTL y nodo padre. Luego le
99 sigue la lista de registros de esa zona, también con 3 campos por renglón:
100 nombre, tipo de registro (A para indicar una IP, NS para indicar donde buscar
101 registros de una zona con ese nombre) e IP (ya sea la IP definitiva si es A o
102 la IP del nameserver al cual recurrir si es NS). Se pueden ver ejemplos de
103 estos archivos en el disco entregado.
106 Puerto en el cual escuchará la abstracción de capa física sobre TCP.
109 El programa es muy similar a `ip`, se queda esperando la entrada del usuario,
110 y sale cuando esta se termina (Ctrl-D). El formato de entrada es::
114 Es decir, se escribe en una línea el nombre del host del cual se quiera obtener
115 la IP y se presiona ENTER.
121 El trabajo fue desarrollado en C++, orientado a objetos. Se compone de las
125 Encapsula la capa física y el dispositivo de red. Es una interfaz abstracta.
128 Implementación de Dev utilizando una cola como medio físico y el id
129 representaría el cable (si 2 dispositivos tienen cola con id distinto serían
130 como si no compartieran el mismo cable). Por simplicidad a la cola siempre
131 se envía el tamaño del MTU completo pero se agrega una cabecera con el
132 tamaño real del frame.
135 Implementación de Dev utilizando conexiones TCP. Por cada frame saliente a un
136 destino en particular se crea una conexión TCP (a menos que ya esté creada, en
137 cuyo caso se reutiliza) y se escucha por conexiones entrantes para recibir
138 frames (también guardándolas para reutilizarlas). A diferencia del DevQue se
139 envía el tamaño del frame exacto (en realidad se agrega una pequeña cabecera).
142 Clase auxiliar que encapsula una dirección IP.
145 Encapsula una cabecera IP. El cálculo de checksum se simplificó (haciendo una
146 suma byte a byte de toda la cabecera) porque cumple con el objetivo didactico
150 Encapsula una tabla de ruteo. Por falta de tiempo y simplicidad por ahora sólo
151 soporta rutas a un sólo host (no a una red) pero es muy fácilmente extensible
152 y transparente para el resto de las clases que la usan. Las rutas se componen
153 de red (en realidad por ahora host), geteway, MTU, metrica y dispositivo de
154 red por el cual salir (Dev).
157 Es la clase encargada de recibir paquetes IP. Hace chequeos varios y descarta
158 paquetes según los siguientes criterios:
160 * Cabecera incompleta o no es IP
161 * Versión IP incorrecta
164 * No es para nosotros y no hacemos forward
165 * Es para nosotros pero somos un router
167 Si hace forwarding le pasa a IPOut el paquete por una cola y reensabla de ser
171 Es la clase encargada de enviar paquetes IP. Tiene una RouteTable para hacer
172 el ruteo y verifica si hay paquetes a forwardear antes de enviar lo que le
173 piden. También fragmenta y puede "descartar" paquetes según estos criterios:
175 * No existe una ruta para el destino
176 * Tamaño de paquete más grande que MTU y DF=1
179 Es el único componente del TP que no es orientado a objetos ya que se
180 reutilizó de trabajos anteriores. Es una pequeña abstracción sobre la API de
181 sockets de BSD para mayor simplicidad.
184 Clase que encapsula una petición de resolución de nombre a enviar via IP.
187 Clase que encapsula una respuesta de resolución de nombre a enviar via IP.
190 Clase encargada de resolver los nombres. Escucha por peticiones y puede
191 resolverlas recursiva o directamente (según venga de otro NameServer o de un
192 Resolver la petición). Esta clase se compone de varias otras clases auxiliares
193 para almacenar las zonas y el cache.
199 Archivo de configuración de zonas de 10.10.10.2::
201 homero.casa 600 10.10.10.1
211 todos NS 10.10.10.141
215 ./dns 10.10.10.2 ../rutas_ejemplo/mi_lan.txt ../zonas_ejemplo/10.10.10.2.txt
217 Resolución de un nombre local con una sola IP
218 ---------------------------------------------
222 ./dns 10.10.10.2 ../rutas_ejemplo/mi_lan.txt ../zonas_ejemplo/10.10.10.2.txt
227 Resolviendo tito.homero.casa...
228 resolv_direct -> tratando de resolver: tito.homero.casa
229 resolv_direct found (local/hijo): ResolvProtoResponse(ret=2, ttl=600, 10.10.100.1)
230 resolv_recursive -> gotcha! ResolvProtoResponse(ret=2, ttl=600, 10.10.100.1)
231 Resultado: ResolvProtoResponse(ret=2, ttl=600, 10.10.100.1)
233 Resolución de un nombre local con múltiples IP
234 ----------------------------------------------
239 Resolviendo juan.homero.casa...
240 resolv_direct -> tratando de resolver: juan.homero.casa
241 resolv_direct found (local/hijo): ResolvProtoResponse(ret=2, ttl=600, 10.10.100.2, 10.10.100.3, 10.10.100.5)
242 resolv_recursive -> gotcha! ResolvProtoResponse(ret=2, ttl=600, 10.10.100.2, 10.10.100.3, 10.10.100.5)
243 Resultado: ResolvProtoResponse(ret=2, ttl=600, 10.10.100.2, 10.10.100.3, 10.10.100.5)
245 Resolución de un nombre local no existente
246 ------------------------------------------
251 Resolviendo none.homero.casa...
252 resolv_direct -> tratando de resolver: none.homero.casa
253 resolv_direct NOT FOUND (es local pero no existe)
254 Resultado: ResolvProtoResponse(ret=4, ttl=0)
256 Resolución de un nombre remoto con múltiples IP y 2 niveles de indirección
257 --------------------------------------------------------------------------
259 Archivo de configuración de zonas de 10.10.10.1::
270 manuk NS 10.10.10.141
272 burns.casa 600 0.0.0.0
280 todos.homero.casa 9500 0.0.0.0
288 Archivo de configuración de zonas de 10.10.10.3::
290 marge.casa 600 10.10.10.1
297 manuk NS 10.10.10.141
300 todos NS 10.10.10.141
302 todos.homero.casa 9500 10.10.10.2
310 marge.homero.casa 9500 10.10.10.2
319 La petición se realiza desde 10.10.10.2, quien debe recurir a su nodo padre
320 (10.10.10.1) que indica que el encargado de resolver esa zona es 10.10.10.3.
322 Salida de 10.10.10.2::
325 Resolviendo pepe.marge.casa...
326 resolv_direct -> tratando de resolver: pepe.marge.casa
327 resolv_direct -> evaluando padre 10.10.10.1
328 resolv_direct found (al padre): 10.10.10.1
329 resolv_recursive -> redirect a ResolvProtoResponse(ret=3, ttl=600, 10.10.10.1)
330 query -> pidiendo ResolvProtoRequest(query_type=0, name=pepe.marge.casa) a 10.10.10.1
331 query -> recibido ResolvProtoResponse(ret=3, ttl=600, 10.10.10.3) de 10.10.10.1
332 resolv_recursive_r -> redirect a ResolvProtoResponse(ret=3, ttl=600, 10.10.10.3)
333 query -> pidiendo ResolvProtoRequest(query_type=0, name=pepe.marge.casa) a 10.10.10.3
334 query -> recibido ResolvProtoResponse(ret=2, ttl=600, 30.10.100.4, 30.10.100.6) de 10.10.10.3
335 resolv_recursive_r -> gotcha! ResolvProtoResponse(ret=2, ttl=600, 30.10.100.4, 30.10.100.6)
336 Resultado: ResolvProtoResponse(ret=2, ttl=600, 30.10.100.4, 30.10.100.6)
338 Salida de 10.10.10.1::
340 NameServer::send_loop() -> recibido ResolvProtoRequest(query_type=0, name=pepe.marge.casa)
341 resolv_direct -> tratando de resolver: pepe.marge.casa
342 resolv_direct found (local/hijo): ResolvProtoResponse(ret=3, ttl=600, 10.10.10.3)
343 NameServer::send_loop() -> respondo ResolvProtoResponse(ret=3, ttl=600, 10.10.10.3)
345 Salida de 10.10.10.3::
347 NameServer::send_loop() -> recibido ResolvProtoRequest(query_type=0, name=pepe.marge.casa)
348 resolv_direct -> tratando de resolver: pepe.marge.casa
349 resolv_direct found (local/hijo): ResolvProtoResponse(ret=2, ttl=600, 30.10.100.4, 30.10.100.6)
350 NameServer::send_loop() -> respondo ResolvProtoResponse(ret=2, ttl=600, 30.10.100.4, 30.10.100.6)
352 .. vim: filetype=rst sw=2 sts=2 et :