Está en la página 1de 81

3.

5 Transporte orientado a conexión: TCP


3.5 Transporte orientado a conexión: TCP

Ahora que hemos cubierto los principios subyacentes de la transferencia confiable de datos, vamos

a recurra a TCP: el transporte confiable, orientado a la conexión y de la capa de transporte de

Internet protocolo. En esta sección, veremos que para proporcionar una transferencia de datos

confiable, TCP se basa en muchos de los principios subyacentes discutidos en la sección anterior,

incluyendo detección de errores, retransmisiones, acuses de recibo acumulativos, temporizadores y

campos de encabezado para números de secuencia y acuse de recibo. TCP se define en RFC 793,

RFC 1122, RFC 1323, RFC 2018 y RFC 2581.

3.5.1 La conexión TCPSe dice que TCP está orientado a la conexión porque antes de que un

proceso de aplicación pueda

comienzan a enviar datos a otro, los dos procesos primero deben "apretón de manos" con cada uno

otro, es decir, deben enviarse algunos segmentos preliminares entre sí para establecer el parámetros

de la subsiguiente transferencia de datos. Como parte del establecimiento de la conexión TCP,

ambos lados de la conexión inicializarán muchas variables de estado TCP (muchas de las cuales

serán discutido en esta sección y en la Sección 3.7) asociado con la conexión TCP.

La "conexión" TCP no es un circuito TDM o FDM de extremo a extremo como en una red de

conmutación de circuitos. Tampoco es un circuito virtual (ver Capítulo 1), ya que el estado de

conexión reside enteramente en los dos sistemas finales. Debido a que el protocolo TCP solo se

ejecuta en el sistemas finales y no en los elementos intermedios de la red (enrutadores y capa de

enlace). conmutadores), los elementos de red intermedios no mantienen el estado de conexión TCP.

VINTON CERF, ROBERT KAHN Y TCP/IP


A principios de la década de 1970, las redes de conmutación de paquetes comenzaron a proliferar,

con la ARPAnet, el precursor de Internet, es solo una de muchas redes. Cada uno de

estas redes tenían su propio protocolo. Dos investigadores, Vinton Cerf y Robert Kahn,

reconoció la importancia de interconectar estas redes e inventó un protocolo entre redes llamado

TCP/IP, que significa Control de Transmisión Protocolo/Protocolo de Internet. Aunque Cerf y Kahn

empezaron por ver el protocolo como una sola entidad, luego se dividió en sus dos partes, TCP e

IP, que operaban por separado. Cerf y Kahn publicaron un artículo sobre TCP/IP en mayo de 1974

en IEEE Transacciones sobre Tecnología de las Comunicaciones [Cerf 1974]. El protocolo TCP/IP,

que es el pan y la mantequilla de la Internet actual, fue ideado antes de las PC, estaciones de

trabajo, teléfonos inteligentes y tabletas, antes de la proliferación de Ethernet, cable, y DSL, WiFi y

otras tecnologías de red de acceso, y antes de la Web, redes sociales y transmisión de video. Cerf y

Kahn vieron la necesidad de un protocolo de red que, por un lado, proporcione un amplio soporte

para aplicaciones aún por definir y, por otro lado, permite que hosts arbitrarios y protocolos de

capa de enlace interoperen. En 2004, Cerf y Kahn recibieron el Premio Turing de la ACM,

considerado el “Premio Nobel de Informática” por “trabajo pionero en interconexión de redes,

incluido el diseño e implementación de los protocolos básicos de comunicaciones de Internet,

TCP/IP, y por un liderazgo inspirado en la creación de redes.

VINTON CERF, ROBERT KAHN Y TCP/IP

A principios de la década de 1970, las redes de conmutación de paquetes comenzaron a proliferar, con la

ARPAnet, el precursor de Internet, es solo una de muchas redes. Cada uno de

estas redes tenían su propio protocolo. Dos investigadores, Vinton Cerf y Robert Kahn,

reconoció la importancia de interconectar estas redes e inventó un protocolo entre redes llamado TCP/IP, que

significa Control de Transmisión

Protocolo/Protocolo de Internet. Aunque Cerf y Kahn empezaron por ver el protocolo como
una sola entidad, luego se dividió en sus dos partes, TCP e IP, que operaban por separado. Cerf y Kahn

publicaron un artículo sobre TCP/IP en mayo de 1974 en IEEE

Transacciones sobre Tecnología de las Comunicaciones [Cerf 1974].

El protocolo TCP/IP, que es el pan y la mantequilla de la Internet actual, fue ideado

antes de las PC, estaciones de trabajo, teléfonos inteligentes y tabletas, antes de la proliferación de Ethernet,

cable, y DSL, WiFi y otras tecnologías de red de acceso, y antes de la Web,

redes sociales y transmisión de video. Cerf y Kahn vieron la necesidad de un protocolo de red que, por un

lado, proporcione un amplio soporte para aplicaciones aún por definir

y, por otro lado, permite que hosts arbitrarios y protocolos de capa de enlace interoperen.

En 2004, Cerf y Kahn recibieron el Premio Turing de la ACM, considerado el

“Premio Nobel de Informática” por “trabajo pionero en interconexión de redes, incluido el

diseño e implementación de los protocolos básicos de comunicaciones de Internet, TCP/IP,

y por un liderazgo inspirado en la creación de redes.

De hecho, los enrutadores intermedios son completamente ajenos a las conexiones TCP; ellos

ver datagramas, no conexiones.

Una conexión TCP proporciona un servicio full-duplex: Si hay una conexión TCP

entre el Proceso A en un host y el Proceso B en otro host, entonces los datos de la capa de

aplicación pueden fluir del Proceso A al Proceso B al mismo tiempo que los datos de la capa de

aplicación fluyen del Proceso B al Proceso A. Una conexión TCP también es siempre

punto a punto, es decir, entre un solo emisor y un solo receptor. Así llamado

“multidifusión” (consulte la Sección 4.7): la transferencia de datos de un remitente a muchos

receptores en una sola operación de envío, no es posible con TCP. Con TCP, dos hosts

son compañía y tres son multitud!

Ahora echemos un vistazo a cómo se establece una conexión TCP. Supongamos que un
proceso que se ejecuta en un host quiere iniciar una conexión con otro proceso en

otro anfitrión. Recuerde que el proceso que está iniciando la conexión se llama el

proceso cliente, mientras que el otro proceso se denomina proceso servidor. El proceso de

aplicación del cliente primero informa a la capa de transporte del cliente que desea establecer un

conexión a un proceso en el servidor. Recuerde de la Sección 2.7.2, un programa cliente de Python

hace esto emitiendo el comando

clientSocket.connect((nombreServidor,PuertoServidor))

donde serverName es el nombre del servidor y serverPort identifica el

proceso en el servidor. TCP en el cliente luego procede a establecer una conexión TCP

con TCP en el servidor. Al final de esta sección discutimos con cierto detalle el procedimiento de

establecimiento de la conexión. Por ahora basta con saber que el cliente envía primero

un segmento TCP especial; el servidor responde con un segundo segmento TCP especial; y

finalmente el cliente vuelve a responder con un tercer segmento especial. Los dos primeros

segmentos no llevar carga útil, es decir, sin datos de capa de aplicación; el tercero de estos

segmentos puede llevar una carga útil. Debido a que se envían tres segmentos entre los dos hosts,

este procedimiento de establecimiento de conexión a menudo se denomina protocolo de enlace

de tres vías.

Una vez que se establece una conexión TCP, los dos procesos de aplicación pueden enviar

datos entre sí. Consideremos el envío de datos desde el proceso del cliente al

proceso del servidor. El proceso del cliente pasa un flujo de datos a través del socket (el

puerta del proceso), como se describe en la Sección 2.7. Una vez que los datos pasan

la puerta, los datos están en manos de TCP ejecutándose en el cliente. Como se muestra en la

figura

3.28, TCP dirige estos datos al búfer de envío de la conexión, que es uno de los
búfer que se reserva durante el protocolo de enlace inicial de tres vías. De vez en cuando,

TCP tomará fragmentos de datos del búfer de envío y pasará los datos a la red

capa. Curiosamente, la especificación TCP [RFC 793] es muy relajada en cuanto a especificar

cuándo TCP debe enviar datos almacenados en búfer, indicando que TCP debe "enviar

esos datos en segmentos según su propia conveniencia”. La cantidad máxima de datos que

se puede agarrar y colocar en un segmento está limitado por el tamaño máximo del segmento

(MSS). El MSS generalmente se establece determinando primero la longitud del mayor

marco de capa de enlace que puede ser enviado por el host de envío local (el llamado máximo

unidad de transmisión, MTU), y luego configurando el MSS para asegurar que un segmento TCP

(cuando está encapsulado en un datagrama IP) más la longitud del encabezado TCP/IP

(típicamente 40 bytes) caben en un solo marco de capa de enlace. Tanto los protocolos de capa de

enlace Ethernet como PPP tienen un MSS de 1500 bytes. También se han propuesto enfoques para

descubrir la ruta MTU, la trama de capa de enlace más grande que se puede enviar en todos los

enlaces desde de origen a destino [RFC 1191] y configurar el MSS en función de la ruta MTU

valor. Tenga en cuenta que el MSS es la cantidad máxima de datos de capa de aplicación en el

segmento, no el tamaño máximo del segmento TCP, incluidos los encabezados. (Esta terminología

es confusa, pero tenemos que vivir con ella, ya que está muy arraigada).

TCP empareja cada fragmento de datos del cliente con un encabezado TCP, formando así TCP
segmentos Los segmentos se transmiten a la capa de red, donde se encapsulan por separado

dentro de los datagramas IP de la capa de red. Los datagramas IP son entonces

enviado a la red. Cuando TCP recibe un segmento en el otro extremo, el segmento

los datos se colocan en el búfer de recepción de la conexión TCP, como se muestra en la Figura

3.28. Él aplicación lee el flujo de datos de este búfer. Cada lado de la conexión tiene

su propio búfer de envío y su propio búfer de recepción. (Puede ver el control de flujo en línea

subprograma en http://www.awl.com/kurose-ross, que proporciona una animación del envío

y recibir búferes). Vemos en esta discusión que una conexión TCP consta de búferes, variables y

una conexión de socket a un proceso en un host y otro conjunto de búferes, variables y una

conexión de socket a un proceso en otro host. Como se mencionó anteriormente, no se asignan

búferes ni variables a la conexión en los elementos de red. (enrutadores, conmutadores y

repetidores) entre los hosts.

3.5.2 Estructura del segmento TCP

Habiendo echado un breve vistazo a la conexión TCP, examinemos el segmento TCP

estructura. El segmento TCP consta de campos de encabezado y un campo de datos. Los datos

El campo contiene una parte de los datos de la aplicación. Como se mencionó anteriormente, el

MSS limita la
tamaño máximo del campo de datos de un segmento. Cuando TCP envía un archivo grande, como

un

imagen como parte de una página web, normalmente divide el archivo en fragmentos de tamaño

MSS

(excepto por el último fragmento, que a menudo será menor que el MSS). Sin embargo, las

aplicaciones interactivas suelen transmitir fragmentos de datos que son más pequeños que el

MSS; por

Por ejemplo, con aplicaciones de inicio de sesión remotas como Telnet, el campo de datos en el

segmento TCP suele ser de un solo byte. Debido a que el encabezado TCP suele tener 20 bytes (12

bytes

más que el encabezado UDP), los segmentos enviados por Telnet pueden tener solo 21 bytes de

longitud.

La figura 3.29 muestra la estructura del segmento TCP. Al igual que con UDP, el encabezado

incluye números de puerto de origen y destino, que se utilizan para


multiplexación/desmultiplexación de datos desde/hacia aplicaciones de capa superior. También,

como con

UDP, el encabezado incluye un campo de suma de verificación. Un encabezado de segmento TCP

también contiene

los siguientes campos:

• El campo de número de secuencia de 32 bits y el número de acuse de recibo de 32 bits

son utilizados por el remitente y el receptor de TCP para implementar datos confiables.

servicio de transferencia, como se analiza a continuación.

• El campo de la ventana de recepción de 16 bits se utiliza para el control de flujo. Veremos en

breve que

se utiliza para indicar el número de bytes que un receptor está dispuesto a aceptar.
• El campo de longitud del encabezado de 4 bits especifica la longitud del encabezado TCP en 32
bits. palabras. El encabezado TCP puede tener una longitud variable debido al campo de opciones
TCP. (Por lo general, el campo de opciones está vacío, por lo que la longitud del encabezado TCP
típico

es de 20 bytes).

• El campo de opciones de longitud variable y opcional se utiliza cuando un remitente y

El receptor negocia el tamaño máximo del segmento (MSS) o como un factor de escala de ventana

para su uso en redes de alta velocidad. También se define una opción de sellado de tiempo. Ver

RFC 854 y RFC 1323 para obtener detalles adicionales.

• El campo de bandera contiene 6 bits. El bit ACK se usa para indicar que el valor transportado en

el campo de reconocimiento es válido; es decir, el segmento contiene un

acuse de recibo de un segmento que se ha recibido con éxito. el RST,

Los bits SYN y FIN se utilizan para establecer y desconectar la conexión, como veremos al final de

esta sección. Establecer el bit PSH indica que el receptor


debe pasar los datos a la capa superior inmediatamente. Finalmente, se utiliza el bit URG

para indicar que hay datos en este segmento que la capa superior del lado emisor

entidad ha marcado como “urgente”. La ubicación del último byte de estos datos urgentes es

indicado por el campo de puntero de datos urgentes de 16 bits. TCP debe informar a la entidad de

capa superior del lado receptor cuando existan datos urgentes y pasarle un puntero al

fin de los datos urgentes. (En la práctica, el PSH, URG y el puntero de datos urgentes

no se usan Sin embargo, mencionamos estos campos para completar).

Números de secuencia y números de acuse de recibo

Dos de los campos más importantes en el encabezado del segmento TCP son el número de

secuencia

campo y el campo del número de acuse de recibo. Estos campos son una parte crítica de TCP

servicio confiable de transferencia de datos. Pero antes de analizar cómo se utilizan estos campos

para proporcionar

transferencia de datos confiable, primero expliquemos qué pone TCP exactamente en estos

campos.

TCP ve los datos como un flujo de bytes no estructurado, pero ordenado. El uso de TCP de

Los números de secuencia reflejan esta visión en el sentido de que los números de secuencia están

sobre la corriente de

bytes transmitidos y no sobre la serie de segmentos transmitidos. La secuencia

número para un segmento es, por lo tanto, el número de flujo de bytes del primer byte en el

segmento. Veamos un ejemplo. Suponga que un proceso en el Host A quiere enviar un

flujo de datos a un proceso en el Host B a través de una conexión TCP. El TCP en el Host A

numerar implícitamente cada byte en el flujo de datos. Supongamos que el flujo de datos consiste

de un archivo que consta de 500.000 bytes, que el MSS es de 1.000 bytes, y que el primero
byte del flujo de datos se numera 0. Como se muestra en la Figura 3.30, TCP construye 500

segmentos fuera del flujo de datos. Al primer segmento se le asigna el número de secuencia 0,

al segundo segmento se le asigna el número de secuencia 1,000, al tercer segmento se le asigna

número de secuencia asignado 2.000, y así sucesivamente. Cada número de secuencia se inserta

en el

campo de número de secuencia en el encabezado del segmento TCP apropiado.

Ahora consideremos los números de acuse de recibo. Estos son un poco más complicados que

números de secuencia. Recuerde que TCP es full-duplex, por lo que el Host A puede estar

recibiendo

datos del Host B mientras envía datos al Host B (como parte de la misma conexión TCP).

Cada uno de los segmentos que llegan del Host B tiene un número de secuencia para los datos

que fluye de B a A. El número de reconocimiento que el Host A pone en su segmento

es el número de secuencia del siguiente byte que el Host A espera del Host B. Está bien

para ver algunos ejemplos para entender lo que está pasando aquí. Supongamos que el anfitrión A

ha recibido todos los bytes numerados del 0 al 535 de B y suponga que se trata de

para enviar un segmento al Host B. El Host A está esperando el byte 536 y todos los subsiguientes

bytes en el flujo de datos del Host B. Entonces el Host A pone 536 en el número de

reconocimiento

campo del segmento que envía a B.


Como otro ejemplo, suponga que el Host A ha recibido un segmento del Host

B que contiene los bytes 0 a 535 y otro segmento que contiene los bytes 900 a

1,000 Por alguna razón, el Host A aún no ha recibido los bytes 536 a 899. En este

ejemplo, el host A todavía está esperando el byte 536 (y más allá) para volver a crear el de B

flujo de datos. Por lo tanto, el siguiente segmento de A a B contendrá 536 en el acuse de recibo

campo numérico. Debido a que TCP solo reconoce bytes hasta el primer byte faltante en

el flujo, se dice que TCP proporciona reconocimientos acumulativos.

Este último ejemplo también trae a colación un tema importante pero sutil. El anfitrión A recibió

el tercer segmento (bytes 900 a 1000) antes de recibir el segundo segmento

(bytes 536 a 899). Así, el tercer segmento llegó fuera de servicio. el sutil

El problema es: ¿Qué hace un host cuando recibe segmentos desordenados en una conexión TCP?

Curiosamente, los TCP RFC no imponen ninguna regla aquí y dejan el

decisión hasta las personas que programan una implementación de TCP. hay básicamente

dos opciones: (1) el receptor descarta inmediatamente los segmentos fuera de servicio

(que, como discutimos anteriormente, puede simplificar el diseño del receptor), o (2) el receptor

mantiene los bytes desordenados y espera a que los bytes que faltan llenen los espacios.

Claramente, la última opción es más eficiente en términos de ancho de banda de la red y es la

enfoque adoptado en la práctica.

En la Figura 3.30, asumimos que el número de secuencia inicial era cero. En verdad,

ambos lados de una conexión TCP eligen aleatoriamente un número de secuencia inicial. Este es

hecho para minimizar la posibilidad de que un segmento que todavía está presente en la red

de una conexión anterior ya finalizada entre dos hosts se confunde con un

segmento válido en una conexión posterior entre estos mismos dos hosts (que también utilizan los

mismos números de puerto que la conexión anterior) [Sunshine 1978].


Telnet: un estudio de caso para números de secuencia y acuse de recibo

Telnet, definido en RFC 854, es un popular protocolo de capa de aplicación utilizado para

inicio de sesión remoto. Se ejecuta sobre TCP y está diseñado para funcionar entre cualquier par

de hosts.

A diferencia de las aplicaciones de transferencia de datos masivos discutidas en el Capítulo 2,

Telnet es un

aplicación interactiva. Discutimos un ejemplo de Telnet aquí, ya que ilustra muy bien

Secuencia TCP y números de acuse de recibo. Notamos que muchos usuarios ahora

prefieren usar el protocolo SSH en lugar de Telnet, ya que los datos enviados en una conexión

Telnet (¡incluidas las contraseñas!) no están encriptados, lo que hace que Telnet sea vulnerable a

ataques de espionaje (como se discutió en la Sección 8.7).

Suponga que el Host A inicia una sesión Telnet con el Host B. Dado que el Host A inicia

la sesión, se etiqueta como el cliente y el host B se etiqueta como el servidor. Cada personaje

escrito por el usuario (en el cliente) se enviará al host remoto; el host remoto se

envíe una copia de cada carácter, que se mostrará en la pantalla del usuario de Telnet.

pantalla. Este "retroceso de eco" se utiliza para garantizar que los caracteres vistos por el usuario

de Telnet

ya han sido recibidos y procesados en el sitio remoto. Cada personaje así

atraviesa la red dos veces entre el momento en que el usuario pulsa la tecla y el momento en que

El carácter se muestra en el monitor del usuario.

Ahora suponga que el usuario escribe una sola letra, 'C', y luego toma un café. Examinemos los

segmentos TCP que se envían entre el cliente y el servidor. Como se muestra en la figura

3.31, suponemos que los números de secuencia inicial son 42 y 79 para el cliente y el servidor,
respectivamente. Recuerde que el número de secuencia de un segmento es el número de

secuencia de

el primer byte en el campo de datos. Así, el primer segmento enviado desde el cliente tendrá

número de secuencia 42; el primer segmento enviado desde el servidor tendrá un número de

secuencia

79. Recuerde que el número de acuse de recibo es el número de secuencia del siguiente byte de

datos que el host está esperando. Después de establecer la conexión TCP pero antes de cualquier

se envían los datos, el cliente está esperando el byte 79 y el servidor está esperando el byte 42.

Como se muestra en la Figura 3.31, se envían tres segmentos. El primer segmento se envía desde

el cliente al servidor, que contiene la representación ASCII de 1 byte de la letra 'C'

en su campo de datos. Este primer segmento también tiene 42 en su campo de número de

secuencia, como

recién descrito. Además, debido a que el cliente aún no ha recibido ningún dato del servidor,

este primer segmento tendrá 79 en su campo de número de acuse de recibo.

El segundo segmento se envía desde el servidor al cliente. Tiene un doble propósito. Primero

proporciona un reconocimiento de los datos que ha recibido el servidor. Por

al colocar 43 en el campo de reconocimiento, el servidor le dice al cliente que ha recibido todo con

éxito hasta el byte 42 y ahora está esperando los bytes 43

adelante. El segundo propósito de este segmento es hacer eco de la letra 'C'. Por lo tanto, el

el segundo segmento tiene la representación ASCII de 'C' en su campo de datos. Este segundo

El segmento tiene el número de secuencia 79, el número de secuencia inicial del flujo de datos de

servidor a cliente de esta conexión TCP, ya que este es el primer byte de datos que el

servidor está enviando. Tenga en cuenta que el reconocimiento de los datos de cliente a servidor

se realiza
en un segmento que transporta datos de servidor a cliente; se dice que este reconocimiento es

a cuestas en el segmento de datos de servidor a cliente.

El tercer segmento se envía desde el cliente al servidor. Su único propósito es

reconoce los datos que ha recibido del servidor. (Recuerde que el segundo segmento contenía

datos, la letra 'C', del servidor al cliente). Este segmento

tiene un campo de datos vacío (es decir, el acuse de recibo no se lleva a cuestas con

cualquier dato de cliente a servidor). El segmento tiene 80 en el campo de número de acuse de

recibo

porque el cliente ha recibido el flujo de bytes hasta el número de secuencia de bytes 79 y ahora

está esperando los bytes 80 en adelante. Usted podría pensar que es extraño que este

segmento también tiene un número de secuencia ya que el segmento no contiene datos. Pero

debido a que TCP tiene un campo de número de secuencia, el segmento debe tener algunos

secuencia de números.

3.5.3 Estimación del tiempo de ida y vuelta y tiempo de espera

TCP, como nuestro protocolo rdt en la Sección 3.4, utiliza un mecanismo de tiempo de

espera/retransmisión para
recuperarse de los segmentos perdidos. Aunque esto es conceptualmente simple, muchos sutiles

surgen problemas cuando implementamos un mecanismo de tiempo de espera/retransmisión en

un protocolo real como TCP. Quizás la pregunta más obvia es la duración del tiempo de espera.

intervalos Claramente, el tiempo de espera debe ser mayor que el tiempo de ida y vuelta de la

conexión.

(RTT), es decir, el tiempo desde que se envía un segmento hasta que se reconoce. De lo contrario,

se enviarían retransmisiones innecesarias. ¿Pero cuánto más grande? Cómo

¿Debería estimarse el RTT en primer lugar? Si se asocia un temporizador con

todos y cada uno de los segmentos no reconocidos? ¡Muchas preguntas! Nuestra discusión en

esta sección se basa en el trabajo de TCP en [Jacobson 1988] y las recomendaciones actuales de

IETF para administrar temporizadores de TCP [RFC 6298].

Estimación del tiempo de ida y vuelta

Comencemos nuestro estudio de la gestión del temporizador TCP considerando cómo calcula TCP

el tiempo de ida y vuelta entre el emisor y el receptor. Esto se logra de la siguiente manera.

El RTT de muestra, denominado SampleRTT, para un segmento es la cantidad de tiempo

entre el momento en que se envía el segmento (es decir, se pasa a IP) y el momento en que se

recibe un acuse de recibo para el segmento. En lugar de medir un SampleRTT para cada

segmento transmitido, la mayoría de las implementaciones de TCP toman solo una medida de

SampleRTT a la vez. Es decir, en cualquier momento, el SampleRTT se está estimando

solo para uno de los segmentos transmitidos pero actualmente no reconocidos, lo que lleva a una

nuevo valor de SampleRTT aproximadamente una vez cada RTT. Además, TCP nunca calcula un

SampleRTT para un segmento que se ha retransmitido; solo mide

SampleRTT para segmentos que se han transmitido una vez [Karn 1987]. (Un problema al final del

capítulo le pide que considere por qué).


Obviamente, los valores de SampleRTT fluctuarán de un segmento a otro debido

a la congestión en los enrutadores y a la carga variable en los sistemas finales. Porque

esta fluctuación, cualquier valor SampleRTT dado puede ser atípico. Para estimar

un RTT típico, por lo tanto, es natural tomar algún tipo de promedio de los valores de SampleRTT.

TCP mantiene un promedio, denominado RTT estimado, de los valores de RTT de muestra. Al

obtener un nuevo SampleRTT, las actualizaciones de TCP

RTT estimado según la siguiente fórmula:

EstimatedRTT = (1 – ) • EstimatedRTT + • SampleRTT

La fórmula anterior está escrita en forma de declaración de lenguaje de programación:

el nuevo valor de EstimatedRTT es una combinación ponderada del valor anterior

de EstimatedRTT y el nuevo valor de SampleRTT. El valor recomendado

de es = 0,125 (es decir, 1/8) [RFC 6298], en cuyo caso la fórmula anterior

se convierte en:

RTT estimado = 0,875 • RTT estimado + 0,125 • RTT de muestra

Tenga en cuenta que el RTT estimado es un promedio ponderado de los valores del RTT de la

muestra.

Como se discutió en un problema de tarea al final de este capítulo, este promedio ponderado le da

más peso a las muestras recientes que a las muestras antiguas. Esto es natural, como el

TCP proporciona una transferencia de datos confiable mediante el uso de reconocimientos

positivos y temporizadores en muchos

de la misma manera que estudiamos en la Sección 3.4. TCP reconoce los datos que han sido

recibido correctamente, y luego retransmite segmentos cuando los segmentos o sus

correspondientes
se cree que los reconocimientos se han perdido o dañado. Ciertas versiones de TCP también

tienen un

mecanismo NAK implícito: con el mecanismo de retransmisión rápida de TCP, la recepción de tres

ACK duplicados para un segmento determinado sirve como un NAK implícito para el siguiente

segmento, lo que activa la retransmisión de ese segmento antes de que se agote el tiempo de

espera. TCP utiliza secuencias de números para

permitir que el receptor identifique segmentos perdidos o duplicados. Al igual que en el caso de

nuestro confiable

protocolo de transferencia de datos, rdt3.0, TCP no puede decir con certeza si un segmento, o su

ACK, se pierde, se corrompe o se retrasa demasiado. En el remitente, la respuesta de TCP será la

misma:

retransmitir el segmento en cuestión.

TCP también utiliza canalización, lo que permite al remitente tener varios segmentos transmitidos

pero aún no reconocidos pendientes en un momento dado. Vimos anteriormente que canalizar

puede mejorar en gran medida el rendimiento de una sesión cuando la relación entre el tamaño

del segmento y el retraso de ida y vuelta es pequeña. El número específico de segmentos

pendientes no reconocidos que un

que puede tener el remitente está determinada por los mecanismos de control de congestión y

control de flujo de TCP.

El control de flujo de TCP se analiza al final de esta sección; El control de congestión TCP se analiza

en la Sección 3.7. Por el momento, simplemente debemos ser conscientes de que el remitente TCP

utiliza canalización.

las muestras más recientes reflejan mejor la congestión actual en la red. En estadística, dicho

promedio se denomina promedio móvil ponderado exponencial (EWMA).


La palabra "exponencial" aparece en EWMA porque el peso de un SampleRTT dado decae

exponencialmente rápido a medida que avanzan las actualizaciones. En los problemas de tarea, se

le pedirá que derive el término exponencial en el RTT estimado.

La Figura 3.32 muestra los valores SampleRTT y EstimatedRTT para un valor de

= 1/8 para una conexión TCP entre gaia.cs.umass.edu (en Amherst, Massachusetts) a

fantasia.eurecom.fr (en el sur de Francia). Claramente, las variaciones en

el RTT de muestra se suaviza en el cálculo del RTT estimado.

Además de tener una estimación del RTT, también es valioso tener una

medida de la variabilidad del RTT. [RFC 6298] define la variación RTT,

DevRTT, como una estimación de cuánto suele desviarse SampleRTT de

RTT estimado:

RTT dev = (1 – ) • RTT dev + •| RTT de muestra: RTT estimado |

Tenga en cuenta que DevRTT es un EWMA de la diferencia entre SampleRTT y

RTT estimado. Si los valores de SampleRTT tienen poca fluctuación, entonces DevRTT

será pequeño; por otro lado, si hay mucha fluctuación, DevRTT será

largo. El valor recomendado de β es 0,25.


Configuración y administración del intervalo de tiempo de espera de retransmisión

Dados los valores de EstimatedRTT y DevRTT, ¿qué valor se debe usar para

¿Intervalo de tiempo de espera de TCP? Claramente, el intervalo debe ser mayor o igual que

Se enviarían RTT estimados o retransmisiones innecesarias. Pero el tiempo de espera

el intervalo no debe ser mucho mayor que el RTT estimado; de lo contrario, cuando se pierde un

segmento, TCP no retransmitiría rápidamente el segmento, lo que provocaría grandes retrasos en

la transferencia de datos. Por lo tanto, es deseable establecer el tiempo de espera igual a la RTT

estimada más

algún margen. El margen debe ser grande cuando hay mucha fluctuación en el

Valores de SampleRTT; debe ser pequeño cuando hay poca fluctuación. El valor de

DevRTT debería entrar en juego aquí. Todas estas consideraciones se tienen en cuenta

cuenta en el método de TCP para determinar el intervalo de tiempo de espera de retransmisión:

Intervalo de tiempo de espera = RTT estimado + 4 • RTT de desarrollo


Se recomienda un valor inicial de TimeoutInterval de 1 segundo [RFC 6298].

Además, cuando se produce un tiempo de espera, el valor de TimeoutInterval se duplica para

evitar

un tiempo de espera prematuro que se produce para un segmento posterior que pronto será

reconocido. Sin embargo, tan pronto como se recibe un segmento y se actualiza el RTT estimado,

el TimeoutInterval se vuelve a calcular utilizando la fórmula anterior.

3.5.4 Transferencia de datos fiable

Recuerde que el servicio de capa de red de Internet (servicio IP) no es confiable. IP hace

no garantiza la entrega de datagramas, no garantiza la entrega correcta de datagramas y no

garantiza la integridad de los datos en los datagramas. Con IP

servicio, los datagramas pueden desbordar los búfer del enrutador y nunca llegar a su destino,

los datagramas pueden llegar desordenados y los bits del datagrama pueden corromperse

(invertido de 0 a 1 y viceversa). Debido a que los segmentos de la capa de transporte se

transportan

a través de la red por datagramas IP, los segmentos de la capa de transporte pueden sufrir estos

problemas también.

TCP crea un servicio de transferencia de datos confiable además del servicio de mejor esfuerzo no

confiable de IP. El servicio confiable de transferencia de datos de TCP garantiza que el flujo de

datos que un

El proceso lee de su búfer de recepción TCP no está dañado, sin espacios, sin

duplicación, y en secuencia; es decir, el flujo de bytes es exactamente el mismo flujo de bytes

que fue enviado por el sistema final en el otro lado de la conexión. Cómo TCP proporciona una

transferencia de datos confiable implica muchos de los principios que estudiamos en

Sección 3.4.
En nuestro desarrollo anterior de técnicas confiables de transferencia de datos, era

conceptualmente más fácil asumir que un temporizador individual está asociado con cada

transmisión.

pero segmento aún no reconocido. Si bien esto es genial en teoría, la gestión del temporizador

puede requerir una sobrecarga considerable. Por lo tanto, la gestión del temporizador TCP

recomendada

Los procedimientos [RFC 6298] utilizan solo un único temporizador de retransmisión, incluso si hay

varios segmentos transmitidos pero aún no reconocidos. El protocolo TCP descrito

en esta sección sigue esta recomendación de temporizador único.

Discutiremos cómo TCP proporciona una transferencia de datos confiable en dos pasos

incrementales.

pasos. Primero presentamos una descripción altamente simplificada de un remitente TCP que usa

solo

tiempos de espera para recuperarse de segmentos perdidos; luego presentamos una descripción

más completa que utiliza acuses de recibo duplicados además de tiempos de espera. En la

discusión subsiguiente, suponemos que los datos se envían en una sola dirección, del Host A al

Host B, y que Host A está enviando un archivo grande.

La figura 3.33 presenta una descripción muy simplificada de un remitente TCP. Vemos

que hay tres eventos principales relacionados con la transmisión y retransmisión de datos en

el remitente TCP: datos recibidos de la aplicación anterior; tiempo de espera del temporizador; y

ACK

recibo. Al ocurrir el primer evento importante, TCP recibe datos del

aplicación, encapsula los datos en un segmento y pasa el segmento a IP. Nota

que cada segmento incluye un número de secuencia que es el número de flujo de bytes de
el primer byte de datos en el segmento, como se describe en la Sección 3.5.2. También tenga en

cuenta que si el

el temporizador ya no se está ejecutando para algún otro segmento, TCP inicia el temporizador

cuando el

el segmento se pasa a IP. (Es útil pensar en el temporizador como asociado con

el segmento no reconocido más antiguo.) El intervalo de expiración para este temporizador es el

TimeoutInterval, que se calcula a partir de la estimación de RTT y DevRTT,

como se describe en la Sección 3.5.3.

/* Asumir que el remitente no está limitado por el flujo de TCP o el control de congestión, que los

datos de arriba son menos

que MSS en tamaño, y que la transferencia de datos es en una sola dirección. */

NextSeqNum=NúmeroSeqInicial SendBase=NúmeroSeqInicial bucle (para siempre) { cambiar

(evento)

evento: datos recibidos de la aplicación anterior crear segmento TCP con número de secuencia

NextSeqNum si (el temporizador no se está ejecutando actualmente) temporizador de inicio pasar

segmento a IP NextSeqNum=NextSeqNum+longitud(datos) romper; evento: tiempo de espera del

temporizador retransmitir el segmento aún no reconocido con número de secuencia más pequeño

temporizador de inicio romper; evento: ACK recibido, con valor de campo ACK de y if (y >

EnviarBase) { EnviarBase=y si (actualmente hay segmentos aún no reconocidos) temporizador de

inicio} romper; } /* fin del bucle para siempre */

El segundo evento importante es el tiempo de espera. TCP responde al evento de tiempo de

espera por

retransmitiendo el segmento que provocó el tiempo de espera. Luego, TCP reinicia el

temporizador.
El tercer evento importante que debe manejar el remitente TCP es la llegada de un

segmento de reconocimiento (ACK) del receptor (más específicamente, un segmento que contiene

un valor de campo ACK válido). Al ocurrir este evento, TCP compara el

ACK valor y con su variable SendBase. La variable de estado TCP SendBase es la

número de secuencia del byte no reconocido más antiguo. (Así, SendBase–1 es el

número de secuencia del último byte que se sabe que se recibió correctamente y en

orden en el receptor.) Como se indicó anteriormente, TCP utiliza acuses de recibo acumulativos,

por lo que

que y acusa recibo de todos los bytes antes del número de byte y. Si y > EnviarBase,

entonces el ACK reconoce uno o más segmentos previamente no reconocidos.

Así, el remitente actualiza su variable SendBase; también reinicia el temporizador si actualmente

hay segmentos aún no reconocidos.

Algunos escenarios interesantes

Acabamos de describir una versión muy simplificada de cómo TCP proporciona

transferencia de datos. Pero incluso esta versión altamente simplificada tiene muchas sutilezas.

Conseguir un

buena sensación de cómo funciona este protocolo, ahora repasemos algunos sencillos

escenarios. La Figura 3.34 muestra el primer escenario, en el que el Host A envía un segmento al

Host B. Suponga que este segmento tiene el número de secuencia 92 y contiene 8

bytes de datos. Después de enviar este segmento, el host A espera un segmento de B con

acuse de recibo número 100. Aunque el segmento de A se recibe en B, el

el acuse de recibo de B a A se pierde. En este caso, se produce el evento de tiempo de espera y

Host A retransmite el mismo segmento. Por supuesto, cuando el Host B recibe el

retransmisión, observa a partir del número de secuencia que el segmento contiene


datos que ya han sido recibidos. Por lo tanto, TCP en el Host B descartará los bytes en

el segmento retransmitido

En un segundo escenario, que se muestra en la Figura 3.35, el Host A envía dos segmentos de

regreso a

espalda. El primer segmento tiene el número de secuencia 92 y 8 bytes de datos, y el segundo

El segmento tiene el número de secuencia 100 y 20 bytes de datos. Suponga que ambos

segmentos

llegan intactos a B, y B envía dos reconocimientos separados para cada uno de estos segmentos. El

primero de estos reconocimientos tiene el número de reconocimiento 100; la

el segundo tiene el número de reconocimiento 120. Suponga ahora que ninguno de los

reconocimientos llega al Host A antes del tiempo de espera. Cuando se produce el evento de

tiempo de espera, Host


A vuelve a enviar el primer segmento con el número de secuencia 92 y reinicia el temporizador.

mientras

como el ACK para el segundo segmento llega antes del nuevo tiempo de espera, el segundo

segmento no se retransmitirá.

En un tercer y último escenario, suponga que el Host A envía los dos segmentos, exactamente

como

en el segundo ejemplo. El acuse de recibo del primer segmento se pierde en el

red, pero justo antes del evento de tiempo de espera, el Host A recibe un reconocimiento con

acuse de recibo número 120. Por lo tanto, el Host A sabe que el Host B ha recibido

todo hasta el byte 119; entonces Host A no reenvía ninguno de los dos

segmentos Este escenario se ilustra en la Figura 3.36.


Duplicación del intervalo de tiempo de espera

Ahora discutimos algunas modificaciones que emplean la mayoría de las implementaciones de

TCP. Él

primero se refiere a la duración del intervalo de tiempo de espera después de la expiración de un

temporizador. En esta modificación, cada vez que ocurre el evento de tiempo de espera, TCP

retransmite el segmento aún no reconocido con el número de secuencia más pequeño, como se

describió anteriormente. Pero

cada vez que TCP retransmite, establece el siguiente intervalo de tiempo de espera en el doble del

anterior valor, en lugar de derivarlo de los últimos RTT estimado y DevRTT (como descrito en la

Sección 3.5.3). Por ejemplo, supongamos que TimeoutInterval está asociado con el segmento más

antiguo aún no reconocido es de 0,75 segundos cuando el temporizador expira por primera vez.

TCP retransmitirá este segmento y establecerá el nuevo tiempo de caducidad en 1,5 segundos. Si
el temporizador vuelve a expirar 1,5 segundos después, TCP volverá a transmitir este segmento,
ahora estableciendo el tiempo de caducidad en 3,0 seg. Así, los intervalos crecen
exponencialmente después de cada retransmisión. Sin embargo, cada vez que el temporizador se
inicia después de cualquiera de los dos otros eventos (es decir, datos recibidos de la aplicación
anterior y ACK recibido), el TimeoutInterval se deriva de los valores más recientes de
EstimatedRTT

y DevRTT.

Esta modificación proporciona una forma limitada de control de la congestión. (En la Sección 3.7

se estudiarán formas más completas de control de congestión de TCP).

lo más probable es que la caducidad del temporizador se deba a la congestión de la red, es decir,

también

muchos paquetes que llegan a una (o más) colas de enrutador en la ruta entre la fuente

y el destino, lo que hace que los paquetes se descarten y/o que se produzcan largas demoras en la

cola. En tiempos

de congestión, si las fuentes continúan retransmitiendo paquetes persistentemente, la congestión

puede empeorar. En cambio, TCP actúa de manera más cortés, con cada remitente

retransmitiendo

después de intervalos cada vez más largos. Veremos que una idea similar es utilizada por Ethernet

cuando estudiamos CSMA/CD en el Capítulo 5.

Retransmisión rápida

Uno de los problemas con las retransmisiones activadas por tiempo de espera es que el tiempo de

espera

período puede ser relativamente largo. Cuando se pierde un segmento, este largo período de

tiempo de espera

obliga al remitente a retrasar el reenvío del paquete perdido, lo que aumenta el retraso de

extremo a extremo. Afortunadamente, el remitente a menudo puede detectar la pérdida de

paquetes mucho antes de que ocurra el evento de tiempo de espera al observar los llamados ACK

duplicados. Un ACK duplicado es un ACK


que reconozca un segmento para el cual el remitente ya ha recibido un anterior

Reconocimiento. Para comprender la respuesta del remitente a un ACK duplicado, debemos

mire por qué el receptor envía un ACK duplicado en primer lugar. La Tabla 3.2 resume la política

de generación de ACK del receptor TCP [RFC 5681]. Cuando un receptor TCP

recibe un segmento con un número de secuencia mayor que el siguiente, esperado,

número de secuencia en orden, detecta una brecha en el flujo de datos, es decir, un segmento

faltante. Esta brecha podría ser el resultado de segmentos perdidos o reordenados dentro de la

red.

Dado que TCP no utiliza reconocimientos negativos, el receptor no puede enviar un

reconocimiento negativo explícito al remitente. En cambio, simplemente vuelve a reconocer (es

decir, genera un ACK duplicado para) el último byte de datos en orden que tiene.

recibió. (Tenga en cuenta que la Tabla 3.2 permite el caso de que el receptor no descarte

segmentos desordenados).

Debido a que un remitente a menudo envía una gran cantidad de segmentos consecutivos, si se

pierde un segmento, es probable que haya muchos ACK duplicados consecutivos. Si el remitente

TCP
recibe tres ACK duplicados para los mismos datos, esto se toma como una indicación de que el

el segmento que sigue al segmento que ha sido ACKed tres veces se ha perdido. (En el

problemas de tarea, consideramos la pregunta de por qué el remitente espera tres ACK

duplicados, en lugar de solo un ACK duplicado). En el caso de que tres

Se reciben ACK, el remitente TCP realiza una retransmisión rápida [RFC 5681], retransmitiendo el

segmento faltante antes de que expire el temporizador de ese segmento. Esto se muestra en

Figura 3.37, donde el segundo segmento se pierde y luego se retransmite antes de su

temporizador

caduca Para TCP con retransmisión rápida, el siguiente fragmento de código reemplaza el ACK

evento recibido en la Figura 3.33:

evento: ACK recibido, con valor de campo ACK de y

if (y > EnviarBase) {

EnviarBase=y

si (actualmente hay alguno que aún no

segmentos reconocidos)

temporizador de inicio

else { /* un ACK duplicado para ya ACKed

segmento */

incrementar el número de ACK duplicados

recibido por ti

si (número de AACK duplicados recibidos

para y==3)

/* Retransmisión rápida de TCP */


reenviar segmento con número de secuencia y

romper;

Anteriormente notamos que surgen muchos problemas sutiles cuando se implementa un

mecanismo de tiempo de espera/retransmisión en un protocolo real como TCP. Los

procedimientos anteriores,

que han evolucionado como resultado de más de 20 años de experiencia con temporizadores TCP,

¡Debería convencerte de que este es realmente el caso!

¿Go-Back-N o repetición selectiva?

Cerremos nuestro estudio del mecanismo de recuperación de errores de TCP considerando la

siguiente pregunta: ¿TCP es un protocolo GBN o SR? Recuerde que los acuses de recibo de TCP son

acumulativos y correctamente recibidos pero los segmentos fuera de servicio no se

ACKed por el receptor. En consecuencia, como se muestra en la Figura 3.33 (ver también la Figura

3.19),
el remitente TCP solo necesita mantener el número de secuencia más pequeño de un mensaje

transmitido pero

byte no reconocido (SendBase) y el número de secuencia del siguiente byte a ser

enviado (NextSeqNum). En este sentido, TCP se parece mucho a un protocolo de estilo GBN. Pero

hay algunas diferencias notables entre TCP y Go-Back-N. Muchas implementaciones de TCP

almacenarán en el búfer correctamente los segmentos recibidos pero desordenados [Stevens

1994].

Considere también lo que sucede cuando el remitente envía una secuencia de segmentos 1,

2, . . . ,

N, y todos los segmentos llegan en orden sin error al receptor. Supongamos además

que el acuse de recibo para el paquete n < N se pierde, pero los restantes N – 1 acuses de recibo

llegan al remitente antes de sus respectivos tiempos de espera. En este ejemplo, GBN

retransmitiría no solo el paquete n, sino también todos los paquetes posteriores n + 1, n + 2,

. . . , N. TCP, por otro lado, retransmitiría como máximo un segmento, a saber, el segmento n.

Además, TCP ni siquiera retransmitiría el segmento n si el acuse de recibo

para el segmento n + 1 llegó antes del tiempo de espera para el segmento n.

Una modificación propuesta a TCP, el llamado reconocimiento selectivo

[RFC 2018], permite que un receptor TCP reconozca segmentos fuera de orden de forma selectiva

en lugar de solo reconocer acumulativamente el último segmento en orden recibido

correctamente. Cuando se combina con la retransmisión selectiva, omitiendo el

retransmisión de segmentos que ya han sido reconocidos selectivamente por el

receptor: TCP se parece mucho a nuestro protocolo SR genérico. Por lo tanto, la recuperación de

errores de TCP

El mecanismo probablemente se clasifique mejor como un híbrido de los protocolos GBN y SR.
3.5.5 Control de flujo

Recuerde que los hosts en cada lado de una conexión TCP reservan un búfer de recepción para

la conexión. Cuando la conexión TCP recibe bytes correctos y en

secuencia, coloca los datos en el búfer de recepción. El proceso de solicitud asociado

leerá los datos de este búfer, pero no necesariamente en el instante en que llegan los datos.

De hecho, la aplicación receptora puede estar ocupada con alguna otra tarea y no

incluso intente leer los datos hasta mucho después de que hayan llegado. Si la aplicación es

relativamente lenta para leer los datos, el remitente puede desbordar fácilmente la conexión.

búfer de recepción enviando demasiados datos demasiado rápido.

TCP proporciona un servicio de control de flujo a sus aplicaciones para eliminar la posibilidad

del remitente desbordando el búfer del receptor. El control de flujo es, por lo tanto, un ajuste de

velocidad

servicio: hacer coincidir la tasa a la que el remitente envía con la tasa a la que el

la aplicación receptora está leyendo. Como se señaló anteriormente, un remitente TCP también se

puede limitar

debido a la congestión dentro de la red IP; esta forma de control del remitente se conoce como

control de congestión, un tema que exploraremos en detalle en las Secciones 3.6 y 3.7. Incluso

aunque las acciones tomadas por el control de flujo y congestión son similares (el

estrangulamiento de

el remitente), obviamente se toman por razones muy diferentes. Desafortunadamente, muchos

los autores usan los términos indistintamente, y el lector inteligente haría bien en distinguirlos.

Analicemos ahora cómo TCP proporciona su servicio de control de flujo. En

Para ver el bosque por los árboles, suponemos a lo largo de esta sección que el TCP

la implementación es tal que el receptor TCP descarta los segmentos fuera de servicio.
TCP proporciona control de flujo al hacer que el remitente mantenga una variable llamada

recibir ventana. Informalmente, la ventana de recepción se utiliza para dar al remitente una idea

de

cuánto espacio de búfer libre está disponible en el receptor. Debido a que TCP es full-duplex, el

El remitente en cada lado de la conexión mantiene una ventana de recepción distinta.

Investiguemos la ventana de recepción en el contexto de una transferencia de archivos. Suponga

que el host A está enviando

un archivo grande al Host B a través de una conexión TCP. El host B asigna un búfer de recepción a

este

conexión; denote su tamaño por RcvBuffer. De vez en cuando, el proceso de solicitud

en Host B lee del búfer. Defina las siguientes variables:

• LastByteRead: el número del último byte en el flujo de datos leído del

buffer por el proceso de aplicación en B

• LastByteRcvd: el número del último byte en el flujo de datos que ha llegado

de la red y se ha colocado en el búfer de recepción en B

Debido a que TCP no puede desbordar el búfer asignado, debemos tener

LastByteRcvd – LastByteRead RcvBuffer


La ventana de recepción, denominada rwnd, se establece en la cantidad de espacio libre en el

búfer:

rwnd = RcvBuffer – [ÚltimoByteRcvd – ÚltimoByteLeído]

Debido a que la habitación libre cambia con el tiempo, rwnd es dinámico. La variable rwnd es

ilustrado en la Figura 3.38.

¿Cómo usa la conexión la variable rwnd para proporcionar el control de flujo?

¿Servicio? El host B le dice al host A cuánto espacio libre tiene en el búfer de conexión

colocando su valor actual de rwnd en el campo de la ventana de recepción de cada segmento que

envía a A. Inicialmente, el host B establece rwnd = RcvBuffer. Tenga en cuenta que para lograr

esto,

El host B debe realizar un seguimiento de varias variables específicas de la conexión.

El host A, a su vez, realiza un seguimiento de dos variables, LastByteSent y LastByteAcked, que

tienen significados obvios. Tenga en cuenta que la diferencia entre estos

dos variables, LastByteSent – LastByteAcked, es la cantidad de datos no reconocidos que A ha

enviado a la conexión. Manteniendo la cantidad de

datos no reconocidos menores que el valor de rwnd, el Host A está seguro de que no es

desbordando el búfer de recepción en el Host B. Por lo tanto, el Host A se asegura durante todo el

la vida de la conexión que

LastByteSent – LastByteAcked rwnd

Hay un problema técnico menor con este esquema. Para ver esto, supongamos

El búfer de recepción del host B se llena, de modo que rwnd = 0. Después de anunciar rwnd = 0

al Host A, suponga también que B no tiene nada que enviar a A. Ahora considere lo que sucede. A

medida que el proceso de aplicación en B vacía el búfer, TCP no envía nuevos segmentos con

nuevos valores rwnd al Host A; de hecho, TCP envía un segmento al Host A


solo si tiene datos para enviar o si tiene un acuse de recibo para enviar. Por lo tanto, el anfitrión A

nunca se le informa que se ha abierto algo de espacio en el búfer de recepción del Host B: Host

¡A está bloqueado y no puede transmitir más datos! Para resolver este problema, la especificación

TCP requiere que el Host A continúe enviando segmentos con un byte de datos cuando B

la ventana de recepción es cero. Estos segmentos serán reconocidos por el receptor.

Eventualmente, el búfer comenzará a vaciarse y los reconocimientos contendrán un

valor de rwnd distinto de cero.

El sitio en línea en http://www.awl.com/kurose-ross para este libro proporciona una

applet interactivo de Java que ilustra el funcionamiento de la ventana de recepción de TCP.

Habiendo descrito el servicio de control de flujo de TCP, mencionamos brevemente aquí que UDP

no proporciona control de flujo. Para comprender el problema, considere enviar una serie de

Segmentos UDP de un proceso en el Host A a un proceso en el Host B. Para un UDP típico

implementación, UDP agregará los segmentos en un búfer de tamaño finito que "precede"

el zócalo correspondiente (es decir, la puerta al proceso). El proceso lee todo un

segmento a la vez desde el búfer. Si el proceso no lee los segmentos rápido

suficiente del búfer, el búfer se desbordará y los segmentos se perderán.

3.5.6 Gestión de conexiones TCP

En esta subsección, veremos más de cerca cómo se establece y cómo se establece una conexión

TCP.

derribado. Aunque este tema puede no parecer particularmente emocionante, es importante

porque el establecimiento de la conexión TCP puede aumentar significativamente los retrasos

percibidos
(por ejemplo, al navegar por la Web). Además, muchos de los ataques de red más comunes,

incluido el increíblemente popular ataque de inundación SYN, aprovechan las vulnerabilidades en

la administración de conexiones TCP. Primero echemos un vistazo a cómo un TCP

se establece la conexión. Supongamos que un proceso que se ejecuta en un host (cliente) desea

iniciar una conexión con otro proceso en otro host (servidor). El proceso de aplicación del cliente

primero informa al cliente TCP que desea establecer una conexión con

un proceso en el servidor. El TCP en el cliente luego procede a establecer una conexión TCP con el

TCP en el servidor de la siguiente manera:

• Paso 1. El TCP del lado del cliente primero envía un segmento TCP especial al lado del servidor

TCP. Este segmento especial no contiene datos de capa de aplicación. Pero uno de la bandera

bits en el encabezado del segmento (ver Figura 3.29), el bit SYN, se establece en 1. Para esto

Por este motivo, este segmento especial se denomina segmento SYN. además, el

cliente elige aleatoriamente un número de secuencia inicial (client_isn) y pone

este número en el campo de número de secuencia del segmento TCP SYN inicial. Este

El segmento se encapsula dentro de un datagrama IP y se envía al servidor. Ahi hay

considerable interés en aleatorizar adecuadamente la elección de los

client_isn para evitar ciertos ataques de seguridad [CERT 2001–09].

• Paso 2. Una vez que el datagrama IP que contiene el segmento TCP SYN llega al

host del servidor (¡suponiendo que llegue!), el servidor extrae el segmento TCP SYN

del datagrama, asigna los búferes TCP y las variables a la conexión, y

envía un segmento de conexión otorgada al cliente TCP. (Veremos en el Capítulo 8 que

la asignación de estos buffers y variables antes de completar el tercer paso del

El protocolo de enlace de tres vías hace que TCP sea vulnerable a un ataque de denegación de

servicio conocido
como inundación SYN). Este segmento de conexión otorgada tampoco contiene datos de la capa

de aplicación. Sin embargo, contiene tres piezas importantes de información en el

encabezado del segmento. Primero, el bit SYN se establece en 1. Segundo, el campo de

reconocimiento

del encabezado del segmento TCP se establece en client_isn+1. Finalmente, el servidor

elige su propio número de secuencia inicial (server_isn) y pone este valor en

el campo de número de secuencia del encabezado del segmento TCP. Esta conexión otorgada

segmento está diciendo, en efecto, "Recibí su paquete SYN para iniciar una conexión

con su número de secuencia inicial, client_isn. Acepto establecer esta conexión. Mi propio número

de secuencia inicial es server_isn”. El segmento de conexión otorgada se denomina segmento

SYNACK.

• Paso 3. Al recibir el segmento SYNACK, el cliente también asigna búferes

y variables a la conexión. El host del cliente luego envía al servidor otro

segmento; este último segmento reconoce el segmento de conexión otorgada del servidor (el

cliente lo hace poniendo el valor server_isn+1 en el campo de reconocimiento del encabezado del

segmento TCP). El bit SYN se establece en cero, ya que el

se establece la conexión. Esta tercera etapa del apretón de manos de tres vías puede llevar

datos de cliente a servidor en la carga útil del segmento

Una vez que se han completado estos tres pasos, los hosts cliente y servidor pueden enviar

segmentos que contienen datos entre sí. En cada uno de estos segmentos futuros, el bit SYN

se pondrá a cero. Tenga en cuenta que para establecer la conexión, se envían tres paquetes

entre los dos hosts, como se ilustra en la Figura 3.39. Por esta razón, este procedimiento de

establecimiento de conexión a menudo se denomina protocolo de enlace de tres vías. Varios

los aspectos del protocolo de enlace de tres vías TCP se exploran en los problemas de tarea
(¿Por qué se necesitan números de secuencia iniciales? ¿Por qué es un apretón de manos de tres

vías, como

opuesto a un apretón de manos bidireccional, ¿necesario?). Es interesante notar que un escalador

y un asegurador (que está estacionado debajo del escalador y cuyo trabajo es manejar

la cuerda de seguridad del escalador) utilice un protocolo de comunicación de apretón de manos

de tres vías que es

idénticos a los TCP para garantizar que ambos lados estén listos antes de que el escalador

comience a ascender.

Todo lo bueno debe llegar a su fin, y lo mismo ocurre con una conexión TCP. Cualquiera de los dos

procesos que participan en una conexión TCP puede finalizar la conexión. Cuando finaliza una

conexión, los "recursos" (es decir, los búferes y las variables)

en los hosts están desasignados. Como ejemplo, supongamos que el cliente decide cerrar el

conexión, como se muestra en la Figura 3.40. El proceso de solicitud del cliente emite un cierre
dominio. Esto hace que el cliente TCP envíe un segmento TCP especial al servidor

proceso. Este segmento especial tiene un bit indicador en el encabezado del segmento, el bit FIN

(ver Figura 3.29), establecido en 1. Cuando el servidor recibe este segmento, envía al cliente

un segmento de reconocimiento a cambio. El servidor luego envía su propio apagado

segmento, que tiene el bit FIN establecido en 1. Finalmente, el cliente reconoce el

segmento de cierre del servidor. En este punto, todos los recursos en los dos hosts ahora están

desasignado

Durante la vida de una conexión TCP, el protocolo TCP que se ejecuta en cada host

hace transiciones a través de varios estados de TCP. La Figura 3.41 ilustra un típico

secuencia de estados TCP que son visitados por el cliente TCP. El cliente TCP comienza en

el estado CERRADO. La aplicación en el lado del cliente inicia una nueva conexión TCP (al crear un

objeto Socket en nuestros ejemplos de Java como en los ejemplos de Python

del capítulo 2). Esto hace que TCP en el cliente envíe un segmento SYN a TCP en el

servidor. Luego de haber enviado el segmento SYN, el cliente TCP ingresa al SYN_SENT

Expresar. Mientras está en el estado SYN_SENT, el cliente TCP espera un segmento del

servidor TCP que incluye un reconocimiento para el segmento anterior del cliente y

tiene el bit SYN establecido en 1. Habiendo recibido dicho segmento, el cliente TCP ingresa al

Estado ESTABLECIDO. Mientras está en el estado ESTABLECIDO, el cliente TCP puede enviar

y recibir segmentos TCP que contienen datos de carga útil (es decir, generados por la aplicación).
Suponga que la aplicación cliente decide que quiere cerrar la conexión.

(Tenga en cuenta que el servidor también podría optar por cerrar la conexión). Esto hace que el

Cliente TCP para enviar un segmento TCP con el bit FIN establecido en 1 y para ingresar el

Estado FIN_WAIT_1. Mientras está en el estado FIN_WAIT_1, el cliente TCP espera un TCP

segmento del servidor con un reconocimiento. Cuando recibe este segmento,

el cliente TCP entra en el estado FIN_WAIT_2. Mientras está en el estado FIN_WAIT_2, el

el cliente espera otro segmento del servidor con el bit FIN establecido en 1; después

Al recibir este segmento, el cliente TCP reconoce el segmento del servidor y

entra en el estado TIME_WAIT. El estado TIME_WAIT permite que el cliente TCP reenvíe el

acuse de recibo final en caso de que se pierda el ACK. El tiempo pasado en TIME_WAIT

El estado depende de la implementación, pero los valores típicos son 30 segundos, 1 minuto y

2 minutos. Después de la espera, la conexión se cierra formalmente y todos los recursos en el


lado del cliente (incluidos los números de puerto) se liberan.

La Figura 3.42 ilustra la serie de estados visitados típicamente por el lado del servidor

TCP, asumiendo que el cliente comienza a interrumpir la conexión. Las transiciones se explican por

sí mismas. En estos dos diagramas de transición de estado, solo hemos mostrado cómo un TCP

normalmente se establece y se cierra la conexión. No hemos descrito lo que


EL ATAQUE SYN FLOOD

Hemos visto en nuestra discusión sobre el protocolo de enlace de tres vías de TCP que un servidor

asigna

e inicializa las variables de conexión y los búferes en respuesta a un SYN recibido. Él

El servidor luego envía un SYNACK en respuesta y espera un segmento ACK del

cliente. Si el cliente no envía un ACK para completar el tercer paso de este 3-way

apretón de manos, eventualmente (a menudo después de un minuto o más) el servidor terminará

la conexión semiabierta y recuperará los recursos asignados.

Este protocolo de gestión de conexiones TCP prepara el escenario para una denegación clásica de

Ataque de servicio (DoS) conocido como ataque de inundación SYN. En este ataque, el(los)

atacante(s)

enviar una gran cantidad de segmentos TCP SYN, sin completar el tercer protocolo de enlace

paso. Con esta avalancha de segmentos SYN, los recursos de conexión del servidor se vuelven

agotados ya que se asignan (¡pero nunca se usan!) para conexiones semiabiertas; a los clientes

legítimos se les niega el servicio. Tales ataques de inundación SYN estuvieron entre los primeros

ataques DoS documentados [CERT SYN 1996]. Afortunadamente, una defensa efectiva conocida

ya que las cookies SYN [RFC 4987] ahora se implementan en la mayoría de los principales sistemas

operativos.

Las cookies SYN funcionan de la siguiente manera:

Cuando el servidor recibe un segmento SYN, no sabe si el segmento proviene de un usuario

legítimo o es parte de un ataque de inundación SYN. Entonces, en lugar de crear

una conexión TCP medio abierta para este SYN, el servidor crea un TCP inicial
número de secuencia que es una función complicada (función hash) de direcciones IP de origen y

destino y números de puerto del segmento SYN, así como un secreto

número que solo conoce el servidor. Este número de secuencia inicial cuidadosamente elaborado

es

la llamada “cookie”. Luego, el servidor envía al cliente un paquete SYNACK con este

número de secuencia inicial especial. Es importante destacar que el servidor no recuerda el

cookie o cualquier otra información de estado correspondiente al SYN.

o Un cliente legítimo devolverá un segmento ACK. Cuando el servidor recibe esto

ACK, debe verificar que el ACK corresponde a algún SYN enviado anteriormente. pero como es

¿Se hace esto si el servidor no mantiene memoria sobre los segmentos SYN? como puedas

lo habrás adivinado, se hace con la galleta. Recuerde que para un ACK legítimo, el

El valor en el campo de reconocimiento es igual al número de secuencia inicial en el

SYNACK (el valor de la cookie en este caso) más uno (ver Figura 3.39). El servidor puede

luego ejecute la misma función hash usando la dirección IP de origen y destino y

números de puerto en el SYNACK (que son los mismos que en el SYN original) y el

número secreto. Si el resultado de la función más uno es el mismo que el valor de reconocimiento

(cookie) en el SYNACK del cliente, el servidor concluye que el ACK corresponde a un segmento SYN

anterior y, por lo tanto, es válido. A continuación, el servidor crea un

conexión completamente abierta junto con un enchufe.

o Por otro lado, si el cliente no devuelve un segmento ACK, entonces el original

SYN no ha causado ningún daño en el servidor, ya que el servidor aún no ha asignado ningún

recursos en respuesta al SYN falso original.


sucede en ciertos escenarios patológicos, por ejemplo, cuando ambos lados de una conexión

quieren iniciar o cerrar al mismo tiempo. Si está interesado en aprender sobre este y otros temas

avanzados relacionados con TCP, le animamos a ver

Libro completo de Stevens [Stevens 1994].

Nuestra discusión anterior ha asumido que tanto el cliente como el servidor están preparados

para comunicarse, es decir, que el servidor está escuchando en el puerto al que el cliente envía

su segmento SYN. Consideremos lo que sucede cuando un host recibe un segmento TCP

cuyos números de puerto o dirección IP de origen no coincidan con ninguno de los

enchufes en el anfitrión. Por ejemplo, suponga que un host recibe un paquete TCP SYN con

puerto de destino 80, pero el host no acepta conexiones en el puerto 80 (es decir, es

no está ejecutando un servidor web en el puerto 80). Luego, el host enviará un segmento de

reinicio especial a la fuente. Este segmento TCP tiene el bit indicador RST (consulte la Sección

3.5.2) establecido en

1. Por lo tanto, cuando un host envía un segmento de reinicio, le está diciendo a la fuente "No

tengo un

socket para ese segmento. Por favor, no reenvíe el segmento”. Cuando un host recibe un

Paquete UDP cuyo número de puerto de destino no coincide con un UDP en curso

socket, el host envía un datagrama ICMP especial, como se explica en el Capítulo 4.

Ahora que tenemos una buena comprensión de la gestión de conexiones TCP, vamos a

vuelva a visitar la herramienta de escaneo de puertos nmap y examine más de cerca cómo

funciona. Para explorar

un puerto TCP específico, digamos el puerto 6789, en un host de destino, nmap enviará un

segmento TCP SYN con el puerto de destino 6789 a ese host. Hay tres resultados posibles:

• El host de origen recibe un segmento TCP SYNACK del host de destino. Desde esto
significa que una aplicación se está ejecutando con el puerto TCP 6789 en la publicación de

destino, nmap

devuelve "abierto".

• El host de origen recibe un segmento TCP RST del host de destino. Esto significa que

el segmento SYN alcanzó el host de destino, pero el host de destino no está ejecutando una

aplicación con el puerto TCP 6789. Pero el atacante al menos sabe que los segmentos destinados

al host en el puerto 6789 no están bloqueados por ningún firewall en la ruta entre

hosts de origen y de destino. (Los cortafuegos se analizan en el Capítulo 8).

• La fuente no recibe nada. Esto probablemente significa que el segmento SYN fue bloqueado

por un cortafuegos intermedio y nunca llegó al host de destino.

Nmap es una herramienta poderosa, que puede "encajonar la unión" no solo para puertos TCP

abiertos,

pero también para puertos UDP abiertos, para firewalls y sus configuraciones, e incluso para las

versiones de aplicaciones y sistemas operativos. La mayor parte de esto se hace mediante la

manipulación de TCP

segmentos de gestión de conexión [Skoudis 2006]. Puede descargar nmap desde

www.nmap.org.

Esto completa nuestra introducción al control de errores y control de flujo en TCP. En

En la Sección 3.7, volveremos a TCP y analizaremos el control de congestión de TCP con cierta

profundidad.

Sin embargo, antes de hacerlo, primero damos un paso atrás y examinamos los problemas de

control de la congestión.

en un contexto más amplio.

3.6 Principios del control de la congestión


En las secciones anteriores, examinamos tanto los principios generales como los específicos.

Mecanismos TCP utilizados para proporcionar un servicio de transferencia de datos confiable

frente a

paquete perdido. Mencionamos anteriormente que, en la práctica, tal pérdida típicamente resulta

de

el desbordamiento de los búfer del enrutador a medida que la red se congestiona. Paquete

la retransmisión trata así un síntoma de congestión de la red (la pérdida de un

segmento de la capa de transporte), pero no trata la causa de la congestión de la red, demasiado

muchas fuentes que intentan enviar datos a una velocidad demasiado alta. Para tratar la causa de

la congestión de la red, se necesitan mecanismos para estrangular a los remitentes frente a la red.

congestión.

En esta sección, consideramos el problema del control de la congestión en un contexto general,

buscando entender por qué la congestión es algo malo, cómo la congestión de la red

se manifiesta en el rendimiento recibido por las aplicaciones de capa superior, y varios

enfoques que se pueden tomar para evitar o reaccionar ante la congestión de la red. esto mas

El estudio general del control de la congestión es apropiado ya que, al igual que con la

transferencia confiable de datos, ocupa un lugar destacado en nuestra lista de los "diez

principales" de problemas fundamentalmente importantes en las redes. Concluimos esta sección

con una discusión sobre el control de la congestión en el

servicio de tasa de bits disponible (ABR) en modo de transferencia asíncrona (ATM)

redes La siguiente sección contiene un estudio detallado del algoritmo de control de congestión de

TCP.

3.6.1 Las Causas y los Costos de la Congestión

Comencemos nuestro estudio general del control de la congestión examinando tres cada vez más
escenarios complejos en los que se produce la congestión. En cada caso, veremos por qué ocurre

la congestión en primer lugar y al costo de la congestión (en términos de recursos

no completamente utilizados y bajo rendimiento recibido por los sistemas finales). No lo haremos

(todavía)

centrarse en cómo reaccionar o evitar la congestión, sino más bien centrarse en el problema más

simple

de comprender lo que sucede a medida que los hosts aumentan su velocidad de transmisión y la

red se congestiona.

Escenario 1: dos remitentes, un enrutador con búferes infinitos

Comenzamos considerando quizás el escenario de congestión más simple posible: Dos

hosts (A y B) cada uno tiene una conexión que comparte un solo salto entre la fuente y

destino, como se muestra en la Figura 3.43.

Supongamos que la aplicación en el Host A está enviando datos a la conexión

(por ejemplo, pasar datos al protocolo de nivel de transporte a través de un socket) a una tasa

promedio de bytes/seg. Estos datos son originales en el sentido de que cada unidad de datos

se envía al socket una sola vez. El protocolo de nivel de transporte subyacente es un


uno sencillo Los datos se encapsulan y envían; no se realiza recuperación de errores (por ejemplo,

retransmisión), control de flujo o control de congestión. Ignorando el adicional

sobrecarga debido a la adición de información de encabezado de capa inferior y de transporte, la

tasa en

qué host A ofrece tráfico al enrutador en este primer escenario es, por lo tanto,

en bytes/seg.

Host B opera de manera similar, y asumimos por simplicidad que también es

enviando a una velocidad de bytes/seg. Los paquetes de los hosts A y B pasan a través de un

enrutador y a través de un enlace saliente compartido de capacidad R. El enrutador tiene búferes

que

permitirle almacenar paquetes entrantes cuando la tasa de llegada de paquetes exceda la

capacidad del enlace saliente. En este primer escenario, asumimos que el enrutador tiene un

infinito

cantidad de espacio de búfer.

La Figura 3.44 traza el desempeño de la conexión del Host A bajo este primer

guión. El gráfico de la izquierda traza el rendimiento por conexión (número de bytes por

segundo en el receptor) en función de la tasa de conexión-envío. para un envio

tasa entre 0 y R / 2, el rendimiento en el receptor es igual al envío del remitente

Tasa: todo lo que envía el remitente se recibe en el receptor con un retraso finito.

Sin embargo, cuando la tasa de envío es superior a R/2, el rendimiento es solo R/2. esta parte

superior

El límite de rendimiento es una consecuencia de compartir la capacidad del enlace entre dos

conexiones El enlace simplemente no puede entregar paquetes a un receptor en estado estable.

tasa que exceda R/2. No importa cuán altas establezcan los hosts A y B sus tasas de envío,
cada uno de ellos nunca verá un rendimiento superior a R/2.

Lograr un rendimiento por conexión de R/2 en realidad podría parecer una

bueno, porque el enlace se utiliza completamente para entregar paquetes a sus destinos. El

gráfico de la derecha en la Figura 3.44, sin embargo, muestra la consecuencia de

operando cerca de la capacidad del enlace. A medida que la tasa de envío se acerca a R/2 (desde la

izquierda), la

el retraso promedio se vuelve más y más grande. Cuando la tasa de envío supera R/2, el

número promedio de paquetes en cola en el enrutador es ilimitado, y el retraso promedio

entre origen y destino se vuelve infinito (asumiendo que las conexiones

operar a estas tasas de envío por un período infinito de tiempo y hay un número infinito

cantidad de almacenamiento intermedio disponible). Por lo tanto, mientras opera a un

rendimiento agregado de

cerca de R puede ser ideal desde el punto de vista del rendimiento, está lejos de ser ideal desde un

retraso

punto de vista. Incluso en este escenario (extremadamente) idealizado, ya hemos encontrado uno
costo de una red congestionada: se experimentan grandes retrasos en las colas a medida que la

tasa de llegada de paquetes se acerca a la capacidad del enlace.

Escenario 2: dos remitentes y un enrutador con búferes finitos

Modifiquemos ahora ligeramente el escenario 1 de las siguientes dos maneras (ver Figura 3.45).

En primer lugar, se supone que la cantidad de almacenamiento en búfer del enrutador es finita.

Una consecuencia de esto

La suposición del mundo real es que los paquetes se descartarán cuando lleguen a un búfer ya

lleno. Segundo, asumimos que cada conexión es confiable. Si un paquete que contiene un

segmento de nivel de transporte se descarta en el enrutador, el remitente eventualmente

retransmitirlo. Debido a que los paquetes se pueden retransmitir, ahora debemos tener más

cuidado

con nuestro uso del término tasa de envío. Específicamente, denotemos nuevamente la tasa en

por el que la aplicación envía los datos originales al socket en bytes/seg. La tasa en

que la capa de transporte envía segmentos (que contienen datos originales y datos retransmitidos)

a la red se indicará en bytes/seg. a veces se hace referencia a

como la carga ofrecida a la red.

El desempeño realizado bajo el escenario 2 ahora dependerá en gran medida de

cómo se realiza la retransmisión. Primero, considere el caso poco realista de que el Host A es

capaz de alguna manera (¡mágicamente!) Determinar si un búfer está libre o no en el enrutador

y, por lo tanto, envía un paquete solo cuando hay un búfer libre. En este caso, no se produciría

ninguna pérdida.
in sería igual a in, y el rendimiento de la conexión sería igual a

pulg. Este caso se muestra en la figura 3.46(a). Desde el punto de vista del rendimiento, el

rendimiento es ideal: todo lo que se envía se recibe. Tenga en cuenta que el host promedio que

envía

tasa no puede exceder R/2 en este escenario, ya que se supone que la pérdida de paquetes nunca

que se produzca.

Considere a continuación el caso un poco más realista de que el remitente retransmite solo

cuando se sabe con certeza que un paquete se ha perdido. (De nuevo, esta suposición es un poco

estirar. Sin embargo, es posible que el host de envío establezca su tiempo de espera demasiado

suficiente para estar virtualmente seguro de que un paquete que no ha sido reconocido ha

perdido.) En este caso, el rendimiento podría parecerse al que se muestra en

Figura 3.46(b). Para apreciar lo que está sucediendo aquí, considere el caso de que el

carga ofrecida, en (la tasa de transmisión de datos original más retransmisiones), es igual
R/2. De acuerdo con la Figura 3.46(b), a este valor de la carga ofrecida, la tasa a la cual

los datos se entregan a la aplicación receptora es R/3. Así, de las unidades 0.5R de

datos transmitidos, 0.333R bytes/seg (en promedio) son datos originales y 0.166R bytes/

seg (en promedio) son datos retransmitidos. Vemos aquí otro costo de una red congestionada: el

remitente debe realizar retransmisiones para compensar la caída

paquetes (perdidos) debido a un desbordamiento del búfer.

Finalmente, consideremos el caso de que el remitente puede expirar prematuramente y

retransmitir un paquete que se ha retrasado en la cola pero que aún no se ha perdido. En este

caso,

tanto el paquete de datos original como la retransmisión pueden llegar al receptor. De

Por supuesto, el receptor solo necesita una copia de este paquete y descartará la retransmisión.

En este caso, el trabajo realizado por el enrutador al reenviar los datos retransmitidos

se desperdició una copia del paquete original, ya que el receptor ya habrá recibido

la copia original de este paquete. El enrutador habría utilizado mejor la capacidad de transmisión

del enlace para enviar un paquete diferente. Aquí entonces hay otro costo más de

una red congestionada: retransmisiones innecesarias por parte del remitente frente a grandes
los retrasos pueden hacer que un enrutador use su ancho de banda de enlace para reenviar copias

innecesarias de un

paquete. La figura 3.46 (c) muestra el rendimiento frente a la carga ofrecida cuando cada paquete

se supone que el enrutador lo reenvía (en promedio) dos veces. Dado que cada paquete es

reenviado dos veces, el rendimiento tendrá un valor asintótico de R/4 como el ofrecido

la carga se aproxima a R/2.

Escenario 3: cuatro remitentes, enrutadores con búfer finitos y

Rutas multisalto

En nuestro escenario de congestión final, cuatro hosts transmiten paquetes, cada uno sobre rutas

de dos saltos superpuestas, como se muestra en la Figura 3.47. Nuevamente asumimos que cada

host

utiliza un mecanismo de tiempo de espera/retransmisión para implementar una transferencia de

datos confiable

servicio, que todos los hosts tengan el mismo valor de in, y que todos los enlaces del enrutador

tengan

capacidad R bytes/seg.

Consideremos la conexión del Host A al Host C, pasando por enrutadores

R1 y R2. La conexión A–C comparte el enrutador R1 con la conexión D–B y

comparte el enrutador R2 con la conexión B–D. Para valores extremadamente pequeños de in,

buffer

los desbordamientos son raros (como en los escenarios de congestión 1 y 2) y el rendimiento

equivale aproximadamente a la carga ofrecida. Para valores ligeramente mayores de in, el

correspondiente

el rendimiento también es mayor, ya que se transmiten más datos originales al


red y entregado al destino, y los desbordamientos siguen siendo raros. Así, para pequeños

valores de

in, un aumento en da como resultado un aumento en out.

Habiendo considerado el caso de tráfico extremadamente bajo, examinemos a continuación el

caso de que

in (y por lo tanto in) es extremadamente grande. Considere el enrutador R2. El AC

tráfico que llega al enrutador R2 (que llega a R2 después de ser reenviado desde R1)

puede tener una tasa de llegada a R2 que es como máximo R, la capacidad del enlace desde R1

a R2, independientemente del valor de in. Si es extremadamente grande para todas las conexiones

(incluida la conexión B-D), entonces la tasa de llegada del tráfico B-D en R2 puede ser

mucho mayor que la del tráfico A-C. Debido a que el tráfico A–C y B–D debe
competir en el enrutador R2 por la cantidad limitada de espacio de búfer, la cantidad de A–C

El tráfico que pasa con éxito a través de R2 (es decir, no se pierde debido al desbordamiento del

búfer) se vuelve cada vez más pequeño a medida que la carga ofrecida de B–D se hace más grande

más grande En el límite, cuando la carga ofrecida se acerca al infinito, un búfer vacío en R2

se llena inmediatamente con un paquete B-D, y el rendimiento de la conexión A-C

en R2 va a cero. Esto, a su vez, implica que el rendimiento de extremo a extremo de A-C va

a cero en el límite de tráfico pesado. Estas consideraciones dan lugar a la propuesta

el equilibrio entre carga y rendimiento que se muestra en la Figura 3.48.

La razón de la eventual disminución en el rendimiento con el aumento ofrecido

La carga es evidente cuando se considera la cantidad de trabajo desperdiciado realizado por la red.

En el escenario de alto tráfico descrito anteriormente, cada vez que se descarta un paquete

en un enrutador de segundo salto, el trabajo realizado por el enrutador de primer salto al reenviar

un

El paquete al enrutador de segundo salto termina siendo "desperdiciado". La red sería

han estado igualmente bien (más exactamente, igualmente mal) si el primer enrutador

simplemente había descartado ese paquete y permanecido inactivo. Más concretamente, la

capacidad de transmisión utilizada en el primer enrutador para reenviar el paquete al segundo

enrutador

podría haber sido mucho más rentable para transmitir un paquete diferente. (Para

ejemplo, al seleccionar un paquete para la transmisión, podría ser mejor para un enrutador

para dar prioridad a los paquetes que ya han atravesado cierto número de upstream

enrutadores.) Así que aquí vemos otro costo más de descartar un paquete debido a la congestión:

cuando un paquete se descarta a lo largo de una ruta, la capacidad de transmisión que se


utilizado en cada uno de los enlaces ascendentes para reenviar ese paquete al punto en el que

se deja caer termina habiéndose desperdiciado.

3.6.2 Enfoques para el control de la congestión

En la Sección 3.7, examinaremos el enfoque específico de TCP para el control de la congestión en

gran medida.

detalle. Aquí, identificamos los dos enfoques amplios para el control de la congestión que son

tomados en la práctica y discutir arquitecturas de red específicas y control de congestión

protocolos que incorporan estos enfoques.

En el nivel más amplio, podemos distinguir entre enfoques de control de congestión

por si la capa de red proporciona alguna ayuda explícita a la capa de transporte

para fines de control de la congestión:

• Control de congestión de extremo a extremo. En un enfoque de extremo a extremo para el

control de la congestión,

la capa de red no proporciona soporte explícito a la capa de transporte para propósitos de control

de congestión. Incluso se debe inferir la presencia de congestión en la red


por los sistemas finales basados únicamente en el comportamiento observado de la red (por

ejemplo, paquetes

pérdida y retraso). Veremos en la Sección 3.7 que TCP necesariamente debe adoptar este enfoque

de extremo a extremo hacia el control de la congestión, ya que la capa IP no proporciona

retroalimentación.

hasta los sistemas finales con respecto a la congestión de la red. Pérdida de segmento TCP (como

se indica

por un tiempo de espera o un acuse de recibo triple duplicado) se toma como una indicación de

congestión de la red y TCP reduce el tamaño de su ventana en consecuencia. también veremos

una propuesta más reciente para el control de congestión de TCP que utiliza el aumento de ida y

vuelta

valores de retardo como indicadores de mayor congestión en la red.

Control de congestión asistido por red. Con control de congestión asistido por red,

Los componentes de la capa de red (es decir, los enrutadores) brindan retroalimentación explícita

al

remitente sobre el estado de congestión en la red. Esta retroalimentación puede ser tan

simple como un solo bit que indica congestión en un enlace. Este enfoque fue tomado en

los primeros IBM SNA [Schwartz 1982] y DEC DECnet [Jain 1989; Ramakrishnan 1990], se propuso

recientemente para redes TCP/IP [Floyd TCP

1994; RFC 3168], y también se utiliza en el control de congestión de tasa de bits disponible (ABR)

de ATM, como se explica a continuación. También es posible una retroalimentación de red más

sofisticada. Por ejemplo, una forma de control de congestión ATM ABR que estudiaremos

en breve permite que un enrutador informe al remitente explícitamente de la velocidad de

transmisión que
(el enrutador) puede admitir en un enlace saliente. El protocolo XCP [Katabi 2002] proporciona

retroalimentación calculada por el enrutador a cada fuente, transportada en el encabezado del

paquete,

con respecto a cómo esa fuente debe aumentar o disminuir su tasa de transmisión.

Para el control de congestión asistido por red, la información de congestión generalmente se

alimenta

de la red al remitente en una de dos formas, como se muestra en la Figura 3.49.

Se pueden enviar comentarios directos desde un enrutador de red al remitente. Esta forma de

notificación generalmente toma la forma de un paquete de estrangulamiento (esencialmente dice:

"¡Estoy congestionado!"). La segunda forma de notificación ocurre cuando un enrutador

marca/actualiza un campo

en un paquete que fluye del remitente al receptor para indicar congestión. Al recibir un

paquete marcado, el receptor luego notifica al remitente de la indicación de congestión.

Tenga en cuenta que esta última forma de notificación requiere al menos un tiempo completo de

ida y vuelta.

3.6.3 Ejemplo de control de congestión asistido por red:

Control de congestión ATM ABR

Concluimos esta sección con un breve estudio de caso del algoritmo de control de congestión

en ATM ABR, un protocolo que adopta un enfoque asistido por red para la congestión

control. Hacemos hincapié en que nuestro objetivo aquí no es describir aspectos de la arquitectura

ATM
en gran detalle, sino más bien para ilustrar un protocolo que toma un marcado diferente

enfoque hacia el control de la congestión del protocolo TCP de Internet. En efecto,

solo presentamos a continuación aquellos pocos aspectos de la arquitectura ATM que se necesitan

para

entender el control de congestión ABR.

Básicamente, ATM adopta un enfoque orientado al circuito virtual (VC) hacia

conmutación de paquetes. Recuerde de nuestra discusión en el Capítulo 1, esto significa que cada

el cambio en la ruta de origen a destino mantendrá el estado sobre el VC de origen a destino. Este

estado por VC permite que un conmutador rastree el comportamiento de los remitentes

individuales (p. ej., rastree su tasa de transmisión promedio) y tome

acciones de control de congestión específicas de la fuente (como señalar explícitamente a la

remitente para reducir su tasa cuando el conmutador se congestiona). Este estado por VC

en los conmutadores de red hace que ATM sea ideal para realizar el control de congestión asistido

por red.
ABR ha sido diseñado como un servicio de transferencia de datos elástico de una manera que

recuerda a TCP. Cuando la red está sobrecargada, el servicio ABR debería poder tomar

ventaja del ancho de banda disponible de repuesto; cuando la red está congestionada, ABR

El servicio debe reducir su velocidad de transmisión a una velocidad de transmisión mínima

predeterminada. En [Jain 1996] se proporciona un tutorial detallado sobre el control de

congestión ATM ABR y la gestión del tráfico.

La Figura 3.50 muestra el marco para el control de congestión ATM ABR. En nuestro

discusión adoptamos la terminología ATM (por ejemplo, usando el término interruptor en lugar de

en lugar de enrutador, y el término celda en lugar de paquete). Con servicio ATM ABR, datos

Las células se transmiten desde un origen a un destino a través de una serie de conmutadores

intermedios. Intercaladas con las celdas de datos hay celdas de gestión de recursos

(células RM); estas celdas RM se pueden usar para transmitir información relacionada con la

congestión

entre los hosts y switches. Cuando una celda RM llega a un destino,

ser dado la vuelta y enviado de vuelta al remitente (posiblemente después de que el destino haya

modificó el contenido de la celda RM). También es posible que un interruptor genere


una celda RM y enviar esta celda RM directamente a una fuente. Por lo tanto, las células RM

pueden ser

se utiliza para proporcionar retroalimentación directa de la red y retroalimentación de la red a

través del

receptor, como se muestra en la Figura 3.50.

El control de congestión ATM ABR es un enfoque basado en la tasa. Es decir, el remitente.

calcula explícitamente una tasa máxima a la que puede enviar y se regula en consecuencia. ABR

proporciona tres mecanismos para señalar información relacionada con la congestión

de los interruptores al receptor:

• Bit EFCI. Cada celda de datos contiene una indicación de congestión directa explícita

(EFCI) bits. Un conmutador de red congestionado puede establecer el bit EFCI en una celda de

datos para

1 para señalar la congestión al host de destino. El destino debe comprobar la

Bit EFCI en todas las celdas de datos recibidas. Cuando una celda RM llega al destino,

si la celda de datos recibida más recientemente tenía el bit EFCI establecido en 1, entonces el

destino establece el bit de indicación de congestión (el bit CI) de la celda RM en 1 y

envía la celda RM de vuelta al remitente. Usando el EFCI en celdas de datos y el CI

bit en celdas RM, un remitente puede ser notificado sobre la congestión en una red

cambiar.

• Bits CI y NI. Como se indicó anteriormente, las celdas RM de emisor a receptor se intercalan

con celdas de datos. La tasa de intercalación de celdas RM es un parámetro ajustable, con

el valor predeterminado es una celda RM cada 32 celdas de datos. Estas células RM tienen un

bit de indicación de congestión (CI) y un bit de no aumento (NI) que puede establecerse mediante

un
conmutador de red congestionada. Específicamente, un interruptor puede configurar el bit NI en

un paso

celda RM a 1 bajo congestión leve y puede establecer el bit CI a 1 bajo severa

condiciones de congestión. Cuando un host de destino recibe una celda RM,

enviar la celda RM de regreso al remitente con sus bits CI y NI intactos (excepto que

El destino puede establecer CI en 1 como resultado del mecanismo EFCI

descrito arriba).

• Configuración de la sala de emergencias. Cada celda RM también contiene un campo de tasa

explícita (ER) de 2 bytes. Un interruptor congestionado puede reducir el valor contenido en el

campo ER en un RM que pasa

celúla. De esta manera, el campo ER se establecerá en la tasa mínima soportable de

todos los interruptores en la ruta de origen a destino.

Una fuente ATM ABR ajusta la velocidad a la que puede enviar celdas en función de

los valores de CI, NI y ER en una celda RM devuelta. Las reglas para hacer esta tarifa

ajuste son bastante complicados y un poco tediosos. Se remite al lector interesado

a [Jain 1996] para más detalles.

3.7 Control de congestión TCP

En esta sección volvemos a nuestro estudio de TCP. Como aprendimos en la Sección 3.5, TCP

brinda un servicio de transporte confiable entre dos procesos que se ejecutan en diferentes hosts.

Otro componente clave de TCP es su mecanismo de control de congestión. Como se indica

En la sección anterior, TCP debe usar control de congestión de extremo a extremo en lugar de

control de congestión asistido por red, ya que la capa IP no proporciona retroalimentación

explícita a

los sistemas finales con respecto a la congestión de la red.


El enfoque adoptado por TCP es hacer que cada remitente limite la velocidad a la que

envía tráfico a su conexión en función de la congestión de la red percibida. si un

El remitente TCP percibe que hay poca congestión en la ruta entre él y

el destino, entonces el remitente TCP aumenta su tasa de envío; si el remitente percibe

que hay congestión a lo largo de la ruta, entonces el remitente reduce su tasa de envío. Pero esto

enfoque plantea tres preguntas. En primer lugar, ¿cómo limita un remitente TCP la velocidad a la

que

envía tráfico a su conexión? En segundo lugar, ¿cómo percibe un remitente TCP que

hay congestión en el camino entre él y el destino? Y tercero, ¿qué

algoritmo debe utilizar el remitente para cambiar su tasa de envío como una función de percibido

congestión de extremo a extremo?

Primero examinemos cómo un remitente TCP limita la velocidad a la que envía tráfico

en su conexión. En la Sección 3.5 vimos que cada lado de una conexión TCP consiste

de un búfer de recepción, un búfer de envío y varias variables (LastByteRead, rwnd,

y así). El mecanismo de control de congestión de TCP que opera en el remitente mantiene

seguimiento de una variable adicional, la ventana de congestión. La ventana de congestión,

denotado cwnd, impone una restricción sobre la velocidad a la que un remitente TCP puede enviar

tráfico

en la red. Específicamente, la cantidad de datos no reconocidos en un remitente puede

no exceder el mínimo de cwnd y rwnd, es decir:

LastByteSent – LastByteAcked min{cwnd, rwnd}

Para centrarnos en el control de congestión (en oposición al control de flujo), supongamos de

ahora en adelante que el búfer de recepción de TCP es tan grande que la restricción de la ventana

de recepción puede ignorarse; por lo tanto, la cantidad de datos no reconocidos en el remitente es


limitada únicamente por cwnd. También supondremos que el remitente siempre tiene datos para

enviar, es decir, que se envíen todos los segmentos de la ventana de congestión.

La restricción anterior limita la cantidad de datos no reconocidos en el remitente

y, por lo tanto, limita indirectamente la velocidad de envío del remitente. Para ver esto, considere

una conexión para la cual la pérdida y los retrasos en la transmisión de paquetes son

insignificantes. Entonces, aproximadamente, en

el comienzo de cada RTT, la restricción permite al remitente enviar cwnd bytes de

datos en la conexión; al final del RTT, el remitente recibe acuses de recibo de los datos. Por lo

tanto, la tasa de envío del remitente es aproximadamente cwnd/RTT bytes/seg. Por

ajustando el valor de cwnd, el remitente puede, por lo tanto, ajustar la tasa a la que

envía datos a su conexión.

Consideremos a continuación cómo un remitente TCP percibe que hay congestión en

el camino entre sí mismo y el destino. Definamos un "evento de pérdida" en un TCP

remitente como la ocurrencia de un tiempo de espera o la recepción de tres duplicados

ACK del receptor. (Recuerde nuestra discusión en la Sección 3.5.4 del tiempo de espera

evento en la Figura 3.33 y la modificación posterior para incluir retransmisión rápida

al recibir tres ACK duplicados.) Cuando hay una congestión excesiva, entonces

uno (o más) búferes del enrutador a lo largo de la ruta se desbordan, lo que hace que se descarte

un datagrama (que contiene un segmento TCP). El datagrama descartado, a su vez, da como

resultado

un evento de pérdida en el remitente, ya sea un tiempo de espera o la recepción de tres

duplicados

ACK, que el remitente interpreta como una indicación de congestión en el

ruta de emisor a receptor.


Habiendo considerado cómo se detecta la congestión, ahora consideremos más

caso optimista cuando la red está libre de congestión, es decir, cuando un evento de pérdida

no ocurre En este caso, reconocimientos por no reconocido previamente

Los segmentos se recibirán en el remitente TCP. Como veremos, TCP tomará la

llegada de estos reconocimientos como una indicación de que todo está bien, que los segmentos

que se transmiten a la red se entregan con éxito al

destino, y utilizará reconocimientos para aumentar su ventana de congestión

tamaño (y por lo tanto su velocidad de transmisión). Tenga en cuenta que si los acuses de recibo

llegan a un

tasa relativamente lenta (por ejemplo, si la ruta de extremo a extremo tiene un retraso alto o

contiene un

enlace de bajo ancho de banda), entonces la ventana de congestión se incrementará en un

relativamente

ritmo lento. Por otro lado, si los acuses de recibo llegan a una tasa alta, entonces el

la ventana de congestión aumentará más rápidamente. Porque TCP usa

reconocimientos para activar (o registrar) su aumento en el tamaño de la ventana de congestión,

Se dice que TCP es auto-reloj.

Dado el mecanismo de ajuste del valor de cwnd para controlar la tasa de envío,

la pregunta crítica sigue siendo: ¿Cómo debe un remitente TCP determinar la velocidad a la que

debe enviar? Si los remitentes TCP envían colectivamente demasiado rápido, pueden congestionar

la red, lo que lleva al tipo de colapso de congestión que vimos en la Figura 3.48. En efecto,

la versión de TCP que estudiaremos en breve se desarrolló en respuesta a

Colapso de congestión de Internet [Jacobson 1988] bajo versiones anteriores de TCP. Sin embargo,

si los remitentes de TCP son demasiado cautelosos y envían demasiado lento, podrían subutilizar
el ancho de banda en la red; es decir, los remitentes TCP podrían enviar a una velocidad mayor

sin congestionar la red. Entonces, ¿cómo determinan los remitentes TCP sus tasas de envío de

modo que no congestionen la red pero al mismo tiempo hagan uso de

todo el ancho de banda disponible? ¿Los remitentes de TCP están explícitamente coordinados o

existe una

enfoque distribuido en el que los remitentes TCP pueden establecer sus tasas de envío basándose

únicamente

en la información local? TCP responde a estas preguntas utilizando la siguiente guía

principios:

Un segmento perdido implica congestión y, por lo tanto, la tasa del remitente TCP debe ser

disminuye cuando se pierde un segmento. Recuerde de nuestra discusión en la Sección 3.5.4,

que un evento de tiempo de espera o la recepción de cuatro acuses de recibo para un segmento

dado (un ACK original y luego tres ACK duplicados) se interpreta como un

indicación implícita de "evento de pérdida" del segmento que sigue al cuádruple ACK

segmento, desencadenando una retransmisión del segmento perdido. Desde el punto de vista del

control de la congestión, la pregunta es cómo el remitente TCP debería disminuir el tamaño de su

ventana de congestión y, por lo tanto, su tasa de envío, en respuesta a esta inferencia.

evento de pérdida.

• Un segmento reconocido indica que la red está entregando el mensaje del remitente.

segmentos al receptor, y por lo tanto, la tarifa del remitente se puede aumentar cuando un

ACK llega para un segmento previamente no reconocido. La llegada de reconocimientos se toma

como una indicación implícita de que todo está bien: los segmentos se están

entregado con éxito del remitente al receptor y, por lo tanto, la red no está congestionada. Por lo

tanto, se puede aumentar el tamaño de la ventana de congestión.


• Sondeo de ancho de banda. Dados ACK que indican un origen a destino libre de congestión

eventos de ruta y pérdida que indican una ruta congestionada, la estrategia de TCP para ajustar su

tasa de transmisión es aumentar su tasa en respuesta a los ACK que llegan hasta una pérdida

ocurre un evento, momento en el que la velocidad de transmisión disminuye. El remitente TCP

por lo tanto, aumenta su tasa de transmisión para sondear la tasa a la que la congestión

comienza el inicio, retrocede de ese ritmo y luego comienza a sondear nuevamente para ver si

la tasa de inicio de congestión ha cambiado. El comportamiento del remitente TCP es quizás

análogo al niño que solicita (y obtiene) más y más golosinas hasta que finalmente

finalmente se le dice "¡No!", retrocede un poco, pero luego comienza a hacer solicitudes

de nuevo poco después. Tenga en cuenta que no hay señalización explícita de congestión.

estado por la red—ACKs y eventos de pérdida sirven como señales implícitas—y que

cada remitente TCP actúa sobre la información local de forma asíncrona desde otro TCP

remitentes

Dada esta descripción general del control de congestión de TCP, ahora estamos en condiciones de

considerar

los detalles del célebre algoritmo de control de congestión de TCP, que se

descrito en [Jacobson 1988] y está estandarizado en [RFC 5681]. El algoritmo tiene

tres componentes principales: (1) inicio lento, (2) evitación de congestión y (3) recuperación

rápida. El inicio lento y la evitación de la congestión son componentes obligatorios de TCP, que se

diferencian en cómo aumentan el tamaño de cwnd en respuesta a los ACK recibidos. Ya veremos

en breve, ese inicio lento aumenta el tamaño de cwnd más rápidamente (¡a pesar de su nombre!)

que evitar la congestión. Se recomienda, pero no se requiere, una recuperación rápida para

Remitentes TCP.

Comienzo lento
Cuando comienza una conexión TCP, el valor de cwnd normalmente se inicializa a un

pequeño valor de 1 MSS [RFC 3390], lo que da como resultado una tasa de envío inicial de

aproximadamente

SMS/RTT. Por ejemplo, si MSS = 500 bytes y RTT = 200 mseg, el resultado

la velocidad de envío inicial es de solo unos 20 kbps. Dado que el ancho de banda disponible para

el

El remitente TCP puede ser mucho más grande que MSS/RTT, al remitente TCP le gustaría

encuentre la cantidad de ancho de banda disponible rápidamente. Así, en el estado de arranque

lento, el

El valor de cwnd comienza en 1 MSS y aumenta en 1 MSS cada vez que se transmite

el segmento es reconocido primero. En el ejemplo de la Figura 3.51, TCP envía el primer

segmento en la red y espera un reconocimiento. Cuando llega este reconocimiento, el remitente

TCP aumenta la ventana de congestión en un MSS

y envía dos segmentos de tamaño máximo. Estos segmentos luego son reconocidos, con el

remitente aumentando la ventana de congestión en 1 MSS para cada uno de

los segmentos reconocidos, dando una ventana de congestión de 4 MSS, y así sucesivamente.

Este proceso da como resultado una duplicación de la tasa de envío cada RTT. Así, el TCP

La tasa de envío comienza lenta pero crece exponencialmente durante la fase de inicio lento.

Pero, ¿cuándo debería terminar este crecimiento exponencial? El inicio lento proporciona varios

respuestas a esta pregunta. Primero, si hay un evento de pérdida (es decir, congestión) indicado

por un tiempo de espera, el remitente TCP establece el valor de cwnd a 1 y comienza la lenta

iniciar el proceso de nuevo. También establece el valor de una segunda variable de estado,

ssthresh
(abreviatura de “umbral de inicio lento”) a cwnd/2: la mitad del valor de la ventana de congestión

cuando se detectó la congestión. La segunda forma en que

el inicio lento puede terminar está directamente relacionado con el valor de ssthresh. Desde

ssthresh

es la mitad del valor de cwnd cuando se detectó la congestión por última vez, podría ser un poco

imprudente seguir duplicando cwnd cuando alcanza o supera el valor de

ssthresh. Por lo tanto, cuando el valor de cwnd es igual a ssthresh, finaliza el inicio lento.

y TCP pasa al modo de prevención de congestión. Como veremos, TCP aumenta

DIVISIÓN DE TCP: OPTIMIZACIÓN DEL RENDIMIENTO DE LOS SERVICIOS EN LA NUBE

Para servicios en la nube, como búsqueda, correo electrónico y redes sociales, es deseable

proporcionar un

alto nivel de capacidad de respuesta, idealmente dando a los usuarios la ilusión de que los

servicios están funcionando

dentro de sus propios sistemas finales (incluidos sus teléfonos inteligentes). Esto puede ser un

gran desafío,

ya que los usuarios a menudo se encuentran lejos de los centros de datos que son responsables de

servir

el contenido dinámico asociado a los servicios en la nube. De hecho, si el sistema final está lejos

desde un centro de datos, entonces el RTT será grande, lo que podría conducir a un tiempo de

respuesta deficiente

rendimiento debido al inicio lento de TCP.

Como caso de estudio, considere la demora en recibir una respuesta para una consulta de

búsqueda.

Por lo general, el servidor requiere tres ventanas TCP durante el inicio lento para entregar el
respuesta [Pathak 2010]. Por lo tanto, el tiempo desde que un sistema final inicia una conexión

TCP hasta que recibe el último paquete de la respuesta es de aproximadamente 4 RTT.

(un RTT para configurar la conexión TCP más tres RTT para las tres ventanas de datos)

más el tiempo de procesamiento en el centro de datos. Estos retrasos de RTT pueden conducir a

un notable

retraso en la devolución de resultados de búsqueda para una fracción significativa de consultas.

Además, hay

puede haber una pérdida significativa de paquetes en las redes de acceso, lo que lleva a

retransmisiones TCP y

retrasos aún mayores.

Una forma de mitigar este problema y mejorar el rendimiento percibido por el usuario es (1)

implementar servidores front-end más cerca de los usuarios, y (2) utilizar la división de TCP

rompiendo el

Conexión TCP en el servidor front-end. Con la división de TCP, el cliente establece una conexión

TCP con el front-end cercano y el front-end mantiene una conexión TCP persistente con

el centro de datos con una ventana de congestión TCP muy grande [Tariq 2008, Pathak 2010,

Chen 2011]. Con este enfoque, el tiempo de respuesta se convierte aproximadamente en 4 RTTFE

RTTBE

tiempo de procesamiento, donde RTTFE es el tiempo de ida y vuelta entre el cliente y el servidor

front-end, y

RTT

BE es el tiempo de ida y vuelta entre el servidor front-end y el centro de datos (servidor back-end).

Si el servidor front-end está cerca del cliente, entonces este tiempo de respuesta se vuelve

aproximadamente
RTT más tiempo de procesamiento, ya que RTTFE es insignificantemente pequeño y RTTBE es

aproximadamente RTT. En

En resumen, la división de TCP puede reducir el retraso de la red aproximadamente de 4 RTT a

RTT, mejorando significativamente el rendimiento percibido por el usuario, especialmente para los

usuarios que están lejos del

centro de datos más cercano. La división de TCP también ayuda a reducir los retrasos en la

retransmisión de TCP causados por

pérdidas en las redes de acceso. Hoy, Google y Akamai hacen un uso extensivo de su CDN

servidores en redes de acceso (consulte la Sección 7.2) para realizar la división de TCP para los

servicios en la nube

apoyan [Chen 2011].

cwnd con más cautela cuando esté en el modo de prevención de congestión. La última forma de

entrar

el inicio lento puede terminar si se detectan tres ACK duplicados, en cuyo caso

TCP realiza una retransmisión rápida (consulte la Sección 3.5.4) y entra en la recuperación rápida

estado, como se analiza a continuación. El comportamiento de TCP en inicio lento se resume en el

FSM
descripción del control de congestión de TCP en la Figura 3.52. El algoritmo de inicio lento

rastrea sus raíces hasta [Jacobson 1988]; un enfoque similar al inicio lento también se propuso de

forma independiente en [Jain 1986].

Prevención de la congestión

Al entrar en el estado de evitación de congestión, el valor de cwnd es aproximadamente la mitad

su valor cuando se encontró congestión por última vez; la congestión podría estar alrededor

¡la esquina! Por lo tanto, en lugar de duplicar el valor de cwnd cada RTT, TCP adopta un

enfoque más conservador y aumenta el valor de cwnd en un solo MSS

cada RTT [RFC 5681]. Esto puede ser realizado de varias maneras. Una común

El enfoque es que el remitente TCP aumente cwnd en bytes MSS (MSS/cwnd) cada vez que llega

un nuevo reconocimiento. Por ejemplo, si MSS tiene 1460 bytes y cwnd


es de 14.600 bytes, luego se envían 10 segmentos dentro de un RTT. Cada ACK que llega

(suponiendo un ACK por segmento) aumenta el tamaño de la ventana de congestión en 1/10

MSS, por lo que el valor de la ventana de congestión habrá aumentado en un MSS

después de los ACK cuando se han recibido los 10 segmentos.

Pero, ¿cuándo debería aumentar linealmente la evitación de la congestión (de 1 MSS por RTT)?

¿fin? El algoritmo para evitar la congestión de TCP se comporta de la misma manera cuando se

agota el tiempo de espera.

ocurre. Como en el caso de inicio lento: el valor de cwnd se establece en 1 MSS, y el

el valor de ssthresh se actualiza a la mitad del valor de cwnd cuando el evento de pérdida
ocurrió. Recuerde, sin embargo, que un evento de pérdida también puede desencadenarse por un

evento ACK duplicado triple. En este caso, la red continúa entregando segmentos de

remitente al receptor (según lo indicado por la recepción de ACK duplicados). Entonces, el

comportamiento de TCP ante este tipo de evento de pérdida debería ser menos drástico que con

una pérdida indicada por tiempo de espera:

TCP reduce a la mitad el valor de cwnd (agregando 3 MSS como buena medida para tener en

cuenta

los ACK duplicados triples recibidos) y registra el valor de ssthresh para que sea la mitad

el valor de cwnd cuando se recibieron los ACK duplicados triples. La rápida recuperación

luego se ingresa el estado.

Rápida recuperación

En la recuperación rápida, el valor de cwnd aumenta en 1 MSS por cada ACK duplicado

recibido para el segmento faltante que hizo que TCP entrara en el estado de recuperación rápida.

Eventualmente, cuando llega un ACK para el segmento faltante, TCP ingresa al

estado de evitación de congestión después de desinflar cwnd. Si ocurre un evento de tiempo de

espera, rápido

la recuperación pasa al estado de inicio lento después de realizar las mismas acciones que en

arranque lento y evitación de congestión: el valor de cwnd se establece en 1 MSS, y el

el valor de ssthresh se establece en la mitad del valor de cwnd cuando ocurrió el evento de

pérdida.

La recuperación rápida es un componente recomendado, pero no obligatorio, de TCP [RFC

5681]. Es interesante que una versión anterior de TCP, conocida como TCP Tahoe, redujo

incondicionalmente su ventana de congestión a 1 MSS y entró en la fase de inicio lento después de


ya sea un evento de pérdida indicado por tiempo de espera o triple-duplicado-ACK-indicado. el

mas nuevo

versión de TCP, TCP Reno, incorpora recuperación rápida.

La Figura 3.53 ilustra la evolución de la ventana de congestión de TCP tanto para Reno

y Tahoe. En esta figura, el umbral es inicialmente igual a 8 MSS. Para los primeros ocho

rondas de transmisión, Tahoe y Reno toman acciones idénticas. La ventana de congestión

sube exponencialmente rápido durante el comienzo lento y alcanza el umbral en la cuarta ronda

de transmision Luego, la ventana de congestión sube linealmente hasta que ocurre un evento de

triple ACK duplicado, justo después de la ronda 8 de transmisión. Tenga en cuenta que la ventana

de congestión

es 12 • MSS cuando ocurre este evento de pérdida. A continuación, el valor de ssthresh se

establece en

0,5 • cwnd = 6 • MSS. En TCP Reno, la ventana de congestión se establece en cwnd =

6 • MSS y luego crece linealmente. En TCP Tahoe, la ventana de congestión se establece en

1 MSS y crece exponencialmente hasta que alcanza el valor de ssthresh, en el cual

punto crece linealmente.


La figura 3.52 presenta la descripción FSM completa de los algoritmos de control de congestión de

TCP: inicio lento, evitación de congestión y recuperación rápida. La figura

también indica dónde se puede transmitir la transmisión de nuevos segmentos o segmentos

retransmitidos.

ocurrir. Aunque es importante distinguir entre el control/retransmisión de errores de TCP y el

control de congestión de TCP, también es importante apreciar cómo estos dos

Los aspectos de TCP están inextricablemente vinculados.

Control de congestión de TCP: Retrospectiva

Habiendo profundizado en los detalles del inicio lento, la evitación de la congestión y la

recuperación rápida, vale la pena dar un paso atrás y ver el bosque desde los árboles. Ignorando el

período inicial de inicio lento cuando comienza una conexión y suponiendo que las pérdidas se

indican mediante ACK duplicados triples en lugar de tiempos de espera, el control de congestión

de TCP consiste en un aumento lineal (aditivo) en cwnd de 1 MSS por RTT y luego una reducción a

la mitad

(disminución multiplicativa) de cwnd en un evento triple duplicado-ACK. Por esta razón,

El control de congestión de TCP a menudo se conoce como una forma de control de congestión de

aumento aditivo, disminución multiplicativa (AIMD). El control de congestión AIMD da lugar

al comportamiento de "diente de sierra" que se muestra en la Figura 3.54, que también ilustra

muy bien nuestro

intuición anterior de TCP "probando" el ancho de banda: TCP aumenta linealmente el tamaño de

su ventana de congestión (y, por lo tanto, su velocidad de transmisión) hasta un triple ACK

duplicado

evento ocurre. Luego disminuye el tamaño de su ventana de congestión por un factor de dos, pero

luego nuevamente comienza a aumentarlo linealmente, sondeando para ver si hay más disponible
banda ancha.

Como se señaló anteriormente, muchas implementaciones de TCP utilizan el algoritmo Reno

[Padhye

2001]. Se han propuesto muchas variaciones del algoritmo de Reno [RFC 3782; RFC

2018]. El algoritmo TCP Vegas [Brakmo 1995; Ahn 1995] intenta evitar la congestión manteniendo

un buen rendimiento. La idea básica de Vegas es (1) detectar la congestión en los enrutadores

entre el origen y el destino antes de que ocurra la pérdida de paquetes, y (2)

baje la tasa linealmente cuando se detecte esta pérdida de paquete inminente. Pérdida inminente

de paquetes

se predice observando el RTT. Cuanto más largo sea el RTT de los paquetes, mayor será la

Congestión en los enrutadores. Linux admite una serie de algoritmos de control de congestión

(incluyendo TCP Reno y TCP Vegas) y permite que un administrador del sistema configure

qué versión de TCP se utilizará. La versión predeterminada de TCP en Linux versión 2.6.18

se configuró en CUBIC [Ha 2008], una versión de TCP desarrollada para aplicaciones de gran ancho

de banda. Para una encuesta reciente de los muchos sabores de TCP, consulte [Afanasyev 2010].
El algoritmo AIMD de TCP se desarrolló sobre la base de una gran cantidad de conocimientos de

ingeniería y experimentación con el control de la congestión en las redes operativas. Diez años

después del desarrollo de TCP, los análisis teóricos mostraron que TCP

algoritmo de control de congestión sirve como una optimización asíncrona distribuida

algoritmo que da como resultado varios aspectos importantes del rendimiento del usuario y de la

red

siendo optimizado simultáneamente [Kelly 1998]. Una rica teoría del control de la congestión

desde entonces se ha desarrollado [Srikant 2004].

Descripción macroscópica del rendimiento de TCP

Dado el comportamiento de dientes de sierra de TCP, es natural considerar cuál es el promedio

podría ser el rendimiento (es decir, la tasa promedio) de una conexión TCP de larga duración. En

esto

análisis ignoraremos las fases de inicio lento que ocurren después de los eventos de tiempo de

espera. (Estos

Las fases suelen ser muy cortas, ya que el emisor crece exponencialmente fuera de la fase.

rápido.) Durante un intervalo de ida y vuelta en particular, la velocidad a la que TCP envía datos es

un

función de la ventana de congestión y el RTT actual. Cuando el tamaño de la ventana es w

bytes y el tiempo de ida y vuelta actual es RTT segundos, entonces la velocidad de transmisión de

TCP es

aproximadamente con RTT. Luego, TCP busca ancho de banda adicional aumentando w en 1 MSS

cada RTT hasta que ocurra un evento de pérdida. Denotar por W el valor de w cuando ocurre un

evento de pérdida

ocurre. Suponiendo que RTT y W son aproximadamente constantes durante la duración de


la conexión, la velocidad de transmisión de TCP oscila entre W/(2 · RTT) y W/RTT.

Estos supuestos conducen a un modelo macroscópico altamente simplificado para la

Comportamiento en estado estacionario de TCP. La red descarta un paquete de la conexión

cuando

la tasa aumenta a W/RTT; Luego, la tasa se reduce a la mitad y luego aumenta en

MSS/RTT cada RTT hasta que llegue nuevamente a W/RTT. Este proceso se repite a lo largo

y otra vez Debido a que el rendimiento de TCP (es decir, la tasa) aumenta linealmente entre

los dos valores extremos, tenemos

Usando este modelo altamente idealizado para la dinámica de estado estacionario de TCP,

podemos

también obtenga una expresión interesante que relacione la tasa de pérdida de una conexión con

su ancho de banda disponible [Mahdavi 1997]. Esta derivación se describe en los problemas de

tarea. Un modelo más sofisticado que se ha encontrado empíricamente para estar de acuerdo con

los datos medidos son [Padhye 2000].

TCP sobre rutas de gran ancho de banda

Es importante darse cuenta de que el control de congestión de TCP ha evolucionado a lo largo de

los años y

de hecho continúa evolucionando. Para obtener un resumen de las variantes actuales de TCP y la

discusión

de la evolución de TCP, consulte [Floyd 2001, RFC 5681, Afanasyev 2010]. que estuvo bueno

para Internet, cuando la mayor parte de las conexiones TCP llevaban tráfico SMTP, FTP y Telnet, no

es necesariamente bueno para la Internet actual dominada por HTTP o para un


Internet del futuro con servicios que aún no se han soñado.

La necesidad de una evolución continua de TCP se puede ilustrar considerando la

Conexiones TCP de alta velocidad que se necesitan para aplicaciones de computación en red y en

la nube. Por ejemplo, considere una conexión TCP con segmentos de 1500 bytes y 100

ms RTT, y supongamos que queremos enviar datos a través de esta conexión a 10 Gbps.

Siguiendo [RFC 3649], notamos que usando la fórmula de rendimiento de TCP anterior, en

Para lograr un rendimiento de 10 Gbps, el tamaño promedio de la ventana de congestión sería

necesita ser 83,333 segmentos. Son muchos segmentos, lo que nos lleva a estar bastante

preocupados de que uno de estos 83,333 segmentos en vuelo se pierda. Qué pasaría

en el caso de una pérdida? O, dicho de otro modo, ¿qué fracción de los segmentos transmitidos

podría perderse que permitiría que el algoritmo de control de congestión de TCP especificado en

la Figura 3.52 aún alcanzara la velocidad deseada de 10 Gbps? En las preguntas de tarea para este

capítulo, lo guían a través de la derivación de una fórmula que relaciona el rendimiento de un

Conexión TCP en función de la tasa de pérdida (L), el tiempo de ida y vuelta (RTT) y la

tamaño máximo de segmento (MSS)

Usando esta fórmula, podemos ver que para lograr un rendimiento de 10 Gbps,

el algoritmo de control de congestión de TCP actual solo puede tolerar una probabilidad de

pérdida de segmento de 2 · 10–10 (o equivalente, un evento de pérdida por cada 5,000,000,000

segmentos):

una tasa muy baja. Esta observación ha llevado a un número de investigadores a investigar nuevas

versiones de TCP diseñadas específicamente para entornos de alta velocidad;

ver [Jin 2004; RFC 3649; Kelly 2003; Ha 2008] para las discusiones de estos esfuerzos.
3.7.1 Equidad

Considere las conexiones K TCP, cada una con una ruta de extremo a extremo diferente, pero

todas pasan

a través de un enlace de cuello de botella con tasa de transmisión R bps. (Por enlace de cuello de

botella, queremos decir

También podría gustarte