Resumen del Capítulo 5 del Computer Networks, de Peterson: Protocolos End-To-End (Teoría de las Comunicaciones)

De Cuba-Wiki

Plantilla:Back

Introducción[editar]

Una vez que tenemos resuelto el tema de internetworking y las capas inferiores, contamos con un servicio de intercambio de paquetes entre hosts. En este capítulo vamos a aprovechar este servicio para construir un canal de comunicación entre procesos.

Antes de seguir avanzando en el tema, resulta conveniente enumerar las características deseables para un protocolo de transporte:

  • Garantía de entrega de los mensajes
  • Entrega de los mensajes en el orden en que se enviaron
  • Entrega de cada mensaje a lo sumo una vez
  • Soporte de mensajes arbitrariamente grandes
  • Soporte de sincronización entre emisor y receptor
  • Soporte de aplicación de control de flujo al emisor
  • Soporte múltiples procesos de aplicación en simultáneo en cada host.

La implementación de estas características en la capa de transporte se verá limitada o complicada por las limitaciones de la red subyacente. Algunas de las limitaciones habituales son:

  • Mensajes que se caen
  • Mensajes que llegan en desorden
  • Mensajes que llegan más de una vez
  • Mensajes limitados a un tamaño finito
  • Mensajes entregados con un delay arbitrariamente grande

A lo largo de este capítulo se analizan los tres tipos de protocolos de transporte considerados representativos. Los más simples son los que apenas ofrecen un servicio de demultiplexado asincrónico, cuyo ejemplo más típico (el que veremos en detalle) es UDP (User Datagram Protocol). Otro tipo son los que ofrecen byte-streaming confiable (TCP, Transport Control Protocol). Por último tenemos a los de tipo Request/Reply, para el que no veremos un ejemplo particular, sino algoritmos útiles para implementar un servicio de RPC (Remote Procedure Call).

UDP[editar]

El problema más importante a resolver por este protocolo es el formato de la dirección que un proceso utilizará para identificar a otro proceso destinatario de su/s mensaje/s.

La solución más sencilla sería dar a cada proceso un ID asignado por el sistema operativo. La gran desventaja de este enfoque es que sólo es practicable en el contexto de sistemas distribuídos cerrados, donde un único sistema operativo corre en todos los hosts y es el encargado de asignar los process id.

Por esto, se utiliza otra técnica. La comunicación se realiza mediante un "abstract locator", habitualmente denominado port o mailbox.

La idea fundamental de esta técnica es: el proceso de origen manda un mensaje a un puerto determinado del host destino, en lugar de mandarlo al proceso destino directamente. A su vez, el proceso destino recibe mensajes en un puerto determinado.

Encabezado UDP[editar]

+ Bits 0 - 15 16 - 31
0 Puerto origen Puerto destino
32 Longitud del Mensaje Suma de verificacion
64  
Datos
 

El header UDP tiene 4 campos de 16 bits:

  • Número de puerto de origen
  • Número de puerto de destino
  • Longitud
  • Checksum

Como para identificar a un puerto tenemos 16 bits, contamos en total con 64 mil puertos por host.

¿Cómo hace un proceso P para "aprender" el puerto del proceso Q al cual le quiere enviar un mensaje? P le envía un mensaje a un proceso servidor S. S ahora sabe el puerto de P, y le contesta a qué puerto tiene que direccionar los mensajes para Q.

Así que lo que hicimos fue patear el problema para adelante: ¿cómo hace P para conocer el puerto de S? Veamos las alternativas existentes:

  • Utilizar un well-known port para cada servidor. Por ejemplo, los DNS reciben en el puerto 53 y el servicio de mails escucha mensajes en el puerto 25. Estos mapeos son publicados periódicamente en algún RFC.
  • Utilizar un único well-known port, denominado Port Mapper, en el que corra un servicio ad-hoc para indicarle al proceso cliente a qué puerto dirigirse para establecer una comunicación con el proceso destino. Esta estrategia permite eventualmente cambiar fácilmente los ports asignados a un mismo servicio a lo largo del tiempo, y también permite a cada host realizar su propia asignación de ports a procesos.

Detalles de implementación[editar]

Típicamente, un port de UDP es una cola de mensajes. Si la cola se llena, el protocolo descarta el mensaje. Además, no existe la posibilidad de efectuar control de flujo. Cuando un proceso quiere leer un mensaje y su cola está vacía, se bloquea hasta que llega un mensaje.

Checksum[editar]

UDP asegura correctitud a través de un checksum. Para computar el checksum usa como input el header, el body, un "pseudoheader" y la longitud de UDP. El pseudoheader se forma con tres campos sacados del header de IP: protocol number, dirección IP de origen y dirección IP de destino.

El algoritmo de checksum básicamente es el mismo que el de IP.

La motivación de meter datos de IP en el checksum de UDP es poder detectar equivocaciones en la entrega de un paquete (por ejemplo, si se corrompe la dirección destino de IP de un paquete y llega al host equivocado, gracias al chequeo del pseudoheader UDP puede detectar que el mensaje no corresponde a ese host). Se puede usar la información del header IP aunque ya hayamos pasado esa capa porque normalmente UDP/TCP/IP son implementados en conjunto.

TCP[editar]

Encabezado[editar]

+ Bits 0 - 3 4 - 9 10 - 15 16 - 31
0 Puerto Origen Puerto Destino
32 Número de Secuencia
64 Número de Acuse de Recibo (ACK)
96 Longitud cabecera TCP Reservado Código Ventana
128 Suma de Verificación (Checksum) Puntero Urgente
160 Opciones + Relleno (opcional)
224  
Datos
 

Descripción[editar]

TCP es un protocolo confiable y orientado a conexión. Uno de sus puntos más importantes es que libera a la capa de aplicación de preocuparse por problemas relacionados con el reordenamiento y/o pérdida de datos, ya que garantiza que la entrega es confiable y en orden.

Otra característica es que soporta full duplex, o sea que cada conexión TCP soporte un par de flujos de bits, uno en cada sentido. Para cada uno de estos flujos se le permite al receptor aplicar control de flujo sobre el emisor.

Además, aplica control de congestión, tema que se verá en detalle en el siguiente capítulo del libro.

Vale la pena llegados a este punto hacer la distinción entre control de flujo y control de congestión:

  • Control de flujo: evitar que los emisores "overruneen" a los receptores. Es un problema end-to-end.
  • Control de congestión: evitar que demasiados datos sean inyectados en la red, provocando que los switches y/o links se sobrecarguen. Es un problema de interacción entre los hosts y las redes.