]> git.llucax.com Git - z.facultad/75.74/practicos.git/blob - practicas/pipi-2da-entrega/README
Tag de 2da entrega.
[z.facultad/75.74/practicos.git] / practicas / pipi-2da-entrega / README
1 ===============================
2 Sistemas Distribuidos I (75.74)
3 ===============================
4
5 ------------------------------------------------------------------
6 TP 2: Sistema de resolución de nombres sobre IP adaptado a sockets
7 ------------------------------------------------------------------
8
9 :Author: Leandro Lucarella (77891)
10
11
12 Organización
13 ============
14
15 En el directorio `src` se encuentra el código fuente del trabajo, con su
16 correspondiente `Makefile` para compilarlo tan solo ejecutando `make`.
17
18 En el directorio `rutas_ejemplo` contiene algunos archivos con descripciones de
19 rutas de ejemplo para correr los programas. En el directorio `zonas_ejemplo` se
20 encuentran archivos de configuración de zonas de dominios de nombre para
21 realizar pruebas.
22
23
24 Uso
25 ===
26
27 El trabajo consta de dos programas, uno llamado `ip` y otro `dns` (más algunas
28 otras pruebas que no tienen relevancia).
29
30 ip
31 --
32
33 El programa `ip` corre 3 procesos (fork(2)eados), uno que recibe paquetes IP
34 otro que recibe entrada del usuario y envía paquetes IP y otro que redirecciona
35 (forward) paquetes IP en caso de ser pertinente.
36
37 Uso::
38
39   ./ip ip [router [forward [route_file [queue_id [proto]]]]]
40
41 ip
42   IP que utiliza este proceso
43
44 router
45   0 si es router, 1 si no lo es (default 0)
46
47 forward
48   0 si puede hacer forwarding, 1 si no (default 0)
49
50 route_file
51   Archivo con las rutas. El formato del archivo es una ruta por línea, cada
52   línea se compone de red (por ahora sólo soporta IPs puntuales), gateway (si es
53   cero es que están en la misma red), MTU y métrica (todavía no se usa),
54   separados por uno o más espacios o tabs (default `route.txt`)
55
56 queue_id
57   Identificador de la cola a usar como medio físico, también establece el
58   identificador de la cola a usar para comunicarse con el otro proceso
59   (`test_ipout`) para hacer forwarding, que será queue_id + 1 (default
60   `DEV_DEFAULT_KEY` obtenido de `dev.h`)
61
62 proto
63   Protocolo que transporta (default 0)
64
65
66 El programa se queda esperando la entrada del usuario, y sale cuando esta se
67 termina (Ctrl-D). El formato de entrada es::
68
69   IP DESTINO
70   MENSAJE
71
72 Es decir, en una línea se pone la IP de destino y en la línea siguiente el
73 mensaje. Para enviar otro mensaje, nuevamente se pone IP de destino en una línea
74 y el mensaje en la siguiente.
75
76 dns
77 ---
78
79 El programa `dns` corre también 3 procesos (fork(2)eados), uno que recibe
80 peticiones de nombres, otro que recibe entrada del usuario y envía peticiones
81 (o mejor dicho encola peticiones para ser enviadas) y otro que realiza el envío
82 de las peticiones realmente.
83
84 Uso::
85
86   ./dns ip [route_file [zone_file [port]]]
87
88 ip
89   IP que utiliza este proceso (ídem programa `ip`)
90
91 route_file
92   Archivo con las rutas (ídem programa `ip`)
93
94 zone_file
95   Archivo con la descripción de las zonas. El formato es muy simple. Cada zona
96   está separada por un renglón en blanco y empieza con una línea con 3 campos
97   separados por espacios o tab: nombre de la zona, TTL y nodo padre. Luego le
98   sigue la lista de registros de esa zona, también con 3 campos por renglón:
99   nombre, tipo de registro (A para indicar una IP, NS para indicar donde buscar
100   registros de una zona con ese nombre) e IP (ya sea la IP definitiva si es A o
101   la IP del nameserver al cual recurrir si es NS). Se pueden ver ejemplos de
102   estos archivos en el disco entregado.
103
104 port
105   Puerto en el cual escuchará la abstracción de capa física sobre TCP.
106
107
108 El programa es muy similar a `ip`, se queda esperando la entrada del usuario,
109 y sale cuando esta se termina (Ctrl-D). El formato de entrada es::
110
111   HOSTNAME_A_BUSCAR
112
113 Es decir, se escribe en una línea el nombre del host del cual se quiera obtener
114 la IP y se presiona ENTER.
115
116
117 Diseño del trabajo
118 ==================
119
120 El trabajo fue desarrollado en C++, orientado a objetos. Se compone de las
121 siguientes clases:
122
123 Dev
124   Encapsula la capa física y el dispositivo de red. Es una interfaz abstracta.
125
126 DevQue
127   Implementación de Dev utilizando una cola como medio físico y el id
128   representaría el cable (si 2 dispositivos tienen cola con id distinto serían
129   como si no compartieran el mismo cable). Por simplicidad a la cola siempre
130   se envía el tamaño del MTU completo pero se agrega una cabecera con el
131   tamaño real del frame.
132
133 DevTCP
134   Implementación de Dev utilizando conexiones TCP. Por cada frame saliente a un
135   destino en particular se crea una conexión TCP (a menos que ya esté creada, en
136   cuyo caso se reutiliza) y se escucha por conexiones entrantes para recibir
137   frames (también guardándolas para reutilizarlas). A diferencia del DevQue se
138   envía el tamaño del frame exacto (en realidad se agrega una pequeña cabecera).
139
140 IPAddr
141   Clase auxiliar que encapsula una dirección IP.
142
143 IPHeader
144   Encapsula una cabecera IP. El cálculo de checksum se simplificó (haciendo una
145   suma byte a byte de toda la cabecera) porque cumple con el objetivo didactico
146   de todas maneras.
147
148 RouteTable
149   Encapsula una tabla de ruteo. Por falta de tiempo y simplicidad por ahora sólo
150   soporta rutas a un sólo host (no a una red) pero es muy fácilmente extensible
151   y transparente para el resto de las clases que la usan. Las rutas se componen
152   de red (en realidad por ahora host), geteway, MTU, metrica y dispositivo de
153   red por el cual salir (Dev).
154   
155 IPIn
156   Es la clase encargada de recibir paquetes IP. Hace chequeos varios y descarta
157   paquetes según los siguientes criterios:
158
159   * Cabecera incompleta o no es IP
160   * Versión IP incorrecta
161   * Mal checksum
162   * TTL=0
163   * No es para nosotros y no hacemos forward
164   * Es para nosotros pero somos un router
165
166   Si hace forwarding le pasa a IPOut el paquete por una cola y reensabla de ser
167   necesario.
168
169 IPOut
170   Es la clase encargada de enviar paquetes IP. Tiene una RouteTable para hacer
171   el ruteo y verifica si hay paquetes a forwardear antes de enviar lo que le
172   piden. También fragmenta y puede "descartar" paquetes según estos criterios:
173
174   * No existe una ruta para el destino
175   * Tamaño de paquete más grande que MTU y DF=1
176
177 libtcp
178   Es el único componente del TP que no es orientado a objetos ya que se
179   reutilizó de trabajos anteriores. Es una pequeña abstracción sobre la API de
180   sockets de BSD para mayor simplicidad.
181
182 ResolvProtoRequest
183   Clase que encapsula una petición de resolución de nombre a enviar via IP.
184
185 ResolvProtoResponse
186   Clase que encapsula una respuesta de resolución de nombre a enviar via IP.
187
188 NameServer
189   Clase encargada de resolver los nombres. Escucha por peticiones y puede
190   resolverlas recursiva o directamente (según venga de otro NameServer o de un
191   Resolver la petición). Esta clase se compone de varias otras clases auxiliares
192   para almacenar las zonas y el cache.
193
194
195 Ejemplo de corrida
196 ==================
197
198 Archivo de configuración de zonas de 10.10.10.2::
199
200   homero.casa   600     10.10.10.1
201   tito  A       10.10.100.1
202   juan  A       10.10.100.2
203   juan  A       10.10.100.3
204   pepe  A       10.10.100.4
205   juan  A       10.10.100.5
206   pepe  A       10.10.100.6
207   marge NS      10.10.10.3
208   todos NS      10.10.10.1
209   todos NS      10.10.10.3
210   todos NS      10.10.10.141
211
212 Línea de comandos::
213
214   ./dns 10.10.10.2 ../rutas_ejemplo/mi_lan.txt ../zonas_ejemplo/10.10.10.2.txt
215
216 Resolución de un nombre local con una sola IP
217 ---------------------------------------------
218
219 Línea de comandos::
220
221   ./dns 10.10.10.2 ../rutas_ejemplo/mi_lan.txt ../zonas_ejemplo/10.10.10.2.txt
222
223 Salida::
224
225   tito.homero.casa
226   Resolviendo tito.homero.casa...
227   resolv_direct -> tratando de resolver: tito.homero.casa
228   resolv_direct found (local/hijo): ResolvProtoResponse(ret=2, ttl=600, 10.10.100.1)
229   resolv_recursive -> gotcha! ResolvProtoResponse(ret=2, ttl=600, 10.10.100.1)
230   Resultado: ResolvProtoResponse(ret=2, ttl=600, 10.10.100.1)
231
232 Resolución de un nombre local con múltiples IP
233 ----------------------------------------------
234
235 Salida::
236
237   juan.homero.casa
238   Resolviendo juan.homero.casa...
239   resolv_direct -> tratando de resolver: juan.homero.casa
240   resolv_direct found (local/hijo): ResolvProtoResponse(ret=2, ttl=600, 10.10.100.2, 10.10.100.3, 10.10.100.5)
241   resolv_recursive -> gotcha! ResolvProtoResponse(ret=2, ttl=600, 10.10.100.2, 10.10.100.3, 10.10.100.5)
242   Resultado: ResolvProtoResponse(ret=2, ttl=600, 10.10.100.2, 10.10.100.3, 10.10.100.5)
243
244 Resolución de un nombre local no existente
245 ------------------------------------------
246
247 Salida::
248
249   none.homero.casa
250   Resolviendo none.homero.casa...
251   resolv_direct -> tratando de resolver: none.homero.casa
252   resolv_direct NOT FOUND (es local pero no existe)
253   Resultado: ResolvProtoResponse(ret=4, ttl=0)
254
255 Resolución de un nombre remoto con múltiples IP y 2 niveles de indirección
256 --------------------------------------------------------------------------
257
258 Archivo de configuración de zonas de 10.10.10.1::
259
260   casa  600 0.0.0.0
261   burns A 10.10.10.1
262   homero  A 10.10.10.2
263   marge A 10.10.10.3
264   manuk A 10.10.10.141
265   juan  A 100.10.100.5
266   pepe  A 100.10.100.6
267   homero  NS  10.10.10.2
268   marge NS  10.10.10.3
269   manuk NS  10.10.10.141
270
271   burns.casa  600 0.0.0.0
272   tito  A 100.10.100.1
273   juan  A 100.10.100.2
274   juan  A 100.10.100.3
275   pepe  A 100.10.100.4
276   juan  A 100.10.100.5
277   pepe  A 100.10.100.6
278
279   todos.homero.casa 9500  0.0.0.0
280   tito  A 10.1.100.1
281   juan  A 10.1.100.2
282   juan  A 10.1.100.3
283   pepe  A 10.1.100.4
284   juan  A 10.1.100.5
285   pepe  A 10.1.100.6
286
287 Archivo de configuración de zonas de 10.10.10.3::
288
289   marge.casa  600 10.10.10.1
290   tito  A 30.10.100.1
291   juan  A 30.10.100.2
292   juan  A 30.10.100.3
293   pepe  A 30.10.100.4
294   juan  A 30.10.100.5
295   pepe  A 30.10.100.6
296   manuk NS  10.10.10.141
297   todos NS  10.10.10.1
298   todos NS  10.10.10.3
299   todos NS  10.10.10.141
300
301   todos.homero.casa 9500  10.10.10.2
302   tito  A 10.1.100.1
303   juan  A 10.1.100.2
304   juan  A 10.1.100.3
305   pepe  A 10.1.100.4
306   juan  A 10.1.100.5
307   pepe  A 10.1.100.6
308
309   marge.homero.casa 9500  10.10.10.2
310   tito  A 10.3.100.1
311   juan  A 10.3.100.2
312   juan  A 10.3.100.3
313   pepe  A 10.3.100.4
314   juan  A 10.3.100.5
315   pepe  A 10.3.100.6
316
317
318 La petición se realiza desde 10.10.10.2, quien debe recurir a su nodo padre
319 (10.10.10.1) que indica que el encargado de resolver esa zona es 10.10.10.3.
320
321 Salida de 10.10.10.2::
322
323   pepe.marge.casa
324   Resolviendo pepe.marge.casa...
325   resolv_direct -> tratando de resolver: pepe.marge.casa
326   resolv_direct -> evaluando padre 10.10.10.1
327   resolv_direct found (al padre): 10.10.10.1
328   resolv_recursive -> redirect a ResolvProtoResponse(ret=3, ttl=600, 10.10.10.1)
329   query -> pidiendo ResolvProtoRequest(query_type=0, name=pepe.marge.casa) a 10.10.10.1
330   query -> recibido ResolvProtoResponse(ret=3, ttl=600, 10.10.10.3) de 10.10.10.1
331   resolv_recursive_r -> redirect a ResolvProtoResponse(ret=3, ttl=600, 10.10.10.3)
332   query -> pidiendo ResolvProtoRequest(query_type=0, name=pepe.marge.casa) a 10.10.10.3
333   query -> recibido ResolvProtoResponse(ret=2, ttl=600, 30.10.100.4, 30.10.100.6) de 10.10.10.3
334   resolv_recursive_r -> gotcha! ResolvProtoResponse(ret=2, ttl=600, 30.10.100.4, 30.10.100.6)
335   Resultado: ResolvProtoResponse(ret=2, ttl=600, 30.10.100.4, 30.10.100.6)
336
337 Salida de 10.10.10.1::
338
339   NameServer::send_loop() -> recibido ResolvProtoRequest(query_type=0, name=pepe.marge.casa)
340   resolv_direct -> tratando de resolver: pepe.marge.casa
341   resolv_direct found (local/hijo): ResolvProtoResponse(ret=3, ttl=600, 10.10.10.3)
342   NameServer::send_loop() -> respondo ResolvProtoResponse(ret=3, ttl=600, 10.10.10.3)
343
344 Salida de 10.10.10.3::
345
346   NameServer::send_loop() -> recibido ResolvProtoRequest(query_type=0, name=pepe.marge.casa)
347   resolv_direct -> tratando de resolver: pepe.marge.casa
348   resolv_direct found (local/hijo): ResolvProtoResponse(ret=2, ttl=600, 30.10.100.4, 30.10.100.6)
349   NameServer::send_loop() -> respondo ResolvProtoResponse(ret=2, ttl=600, 30.10.100.4, 30.10.100.6)
350
351 .. vim: filetype=rst sw=2 sts=2 et :