TCPDatos 1444KB May 16 2016 05:13:20 PM

Anuncio
CAPÍTULO XII
Transferencia de datos TCP
En el capítulo previo se han presentado los aspectos más significativos del protocolo
TCP relacionados con el inicio y fin de una conexión. Muchos de ellos se plasman en los campos
del encabezado, pero otros comportamientos surgen de las transiciones explicadas a partir del
Diagrama de Estados.
En este capítulo se presentará el protocolo en acción, una vez que la conexión se ha
establecido. Se desarrollará en detalle la estrategia de expiración (timeout) y retransmisión y el
ajuste de los parámetros que la manejan.
Se explicará cómo afronta TCP situaciones de pérdida de segmentos, aparición de
segmentos duplicados y casos de desorden en los segmentos recibidos, debiendo asegurar, en
cualquier caso, una comunicación confiable.
El capítulo abordará la dinámica que el protocolo imprime sobre la transferencia de
datos, distinguiendo entre los casos de aplicaciones interactivas, donde la transmisión es de
pocos bytes por vez, y la transferencia de grandes volúmenes de datos.
12.1 Estrategia de expiración y retransmisión
Cada segmento enviado por TCP, lleva asociado un reloj de descuento o expiración
(timeout) que, si se agota sin que se reciba un segmento cuyo Número de ACK cubra los datos
transportados en el segmento transmitido, dispara la retransmisión. El tiempo se asocia a una
variable conocida como Expiración de Retransmisión (RTO, Retransmission Timeout). La
estrategia significa que el reloj debe ajustarse de manera de dar tiempo a bajar el segmento a
la red, que ésta lo transporte encapsulado en IP hacia destino, que el destino lo levante de la
red y verifique sus errores y, de ser correcto, que edite un segmento ACK para que viaje de
regreso hacia la fuente. Todo este tiempo se conoce como Tiempo de Viaje de Ida y Vuelta
(RTT, Round Trip Time).
En el capítulo previo, se ha mencionado que existe un tiempo de expiración asociado al
inicio de una conexión. Su naturaleza es del tipo retroceso exponencial, manejado por dos
variables: la cantidad de reintentos y el tiempo total antes de proceder a un aviso de
imposibilidad de comunicación. Estos valores podrían fijarse de antemano, en términos
generales, suficientes para cubrir cualquier tipo de conexión.
Lo interesante, durante la fase de transmisión de datos para una conexión particular, y
aún dentro de una misma conexión, es cómo fijar el valor del RTO, ya que el propio RTT puede
llegar a variar por diversos motivos, muchos de los cuales se encuentran asociados
directamente a la situación de carga de tráfico en la red.
439
La estrategia más inteligente en todos los casos sería fijar el valor del RTO en base a
una medición del RTT. Esto es lógico cuando se piensa que, si se fijara el valor del RTO en un
tiempo menor que el RTT promedio para la conexión particular, probablemente se producirían
retransmisiones innecesarias. De la misma manera, si se fija un valor superior, se podría perder
capacidad de reacción, trabajándose de manera ineficiente en el caso de una red
congestionada. Por este motivo, el valor fijado para el RTO debe seguir las propias
fluctuaciones del RTT.
Para cada conexión, el protocolo TCP toma muestras del valor del RTT, midiendo el
tiempo que transcurre entre la transmisión de un segmento de datos con un Número de
Secuencia dado y la recepción de un segmento de ACK, cuyo Número de ACK lo reconozca
como recibido correctamente. Dentro de una misma conexión, se pueden obtener muchas
muestras que pueden servir para estimar las variaciones del RTT, para el ajuste apropiado del
RTO.
La estimación debe ser lo más cercana posible a la realidad para no generar
retransmisiones disparadas prematuramente, innecesarias, o tardías, por falta de capacidad de
reacción a las variaciones.
12.1.1 Cálculo del Estimador Suavizado en el Método Clásico
Originalmente, en la RFC 793, se ofrecía un ejemplo de cálculo de un Estimador
Suavizado del RTT (SRTT, Smoothed RTT), según la siguiente relación:
= + 1 − (12.1)
En la Ec. (12.1), es la medición actual del tiempo de ida y vuelta y del lado
derecho de la igualdad es la estimación previa. Con ambos valores, pesados de manera
apropiada, se obtiene el nuevo valor de . El factor de suavizado determinará el peso
que la última medición, o el valor previo estimado, tendrán sobre la nueva estimación. Un
valor común recomendado para era 0.8ó0.9, obteniendo el 80%ó90% de la nueva
estimación, a partir de la estimación previa, y sólo el 20%ó10% a partir de la medición
actual. Una vez calculado el estimador, la RFC 793 establecía el valor de como:
= min, max , !
(12.2)
En esta expresión, se refiere a un límite superior recomendado en 1"# y
a un límite inferior recomendado en 1$%&. El parámetro ! se define como la varianza
del retardo, cuyo valor recomendado se encontraba en el rango 1.3(2. En términos prácticos,
el valor de , terminaba fijado en 1$%& o el doble del estimador. Esta medición funcionaba
correctamente en conexiones estables, sin grandes variaciones de .
440
12.1.2 Cálculo del Estimador Estándar de Jacobson
En 1988, Van Jacobson publicó un artículo en el que observaba que la estimación
clásica resultaba apropiada para cierto nivel de carga, a partir del cual la conexión respondería
al incremento con retransmisiones de paquetes que sólo habrían sido retrasados en tránsito.
En esas situaciones de congestión, los paquetes duplicados cargaban aún más la red. Por este
motivo, propuso un nuevo método de estimación, en el que calculaba el error entre la
estimación y la medición, luego el valor medio de la estimación y, por último, el valor medio de
la desviación. En su explicación, Van Jacobson comenzó reordenando la ecuación original,
definiendo 1 − = & , de tal manera que la expresión (12.1) se puede volver a escribir
como:
= + & − (12.3)
En esta ecuación, el error es la diferencia − , por lo que la nueva
predicción de la estimación queda determinada por la predicción previa y una fracción del
error. Van Jacobson consideró el error compuesto por dos componentes, un componente
aleatorio, propio de las fluctuaciones de tráfico )* , y otro debido a una mala elección del
estimador )+ . De este modo la Ec. (12.3) anterior se convierte en:
= + &)* + &)+
(12.4)
Una de las cuestiones principales es la elección del factor &. Según Jacobson, el
término aleatorio)+ mueve el valor de hacia el valor medio real, sin importar el valor
de & usado, pero un valor pequeño de & mimimiza la influencia de esta componente aleatoria.
Por este motivo, aconsejó un valor en el rango 0.1(0.2 .
El valor estimado oscilará aleatoriamente alrededor del promedio verdadero y la
desviación estándar será la del valor medido , convergiendo con una contante de tiempo
1, . Para medir la desviación estándar de , Jacobson desechó la varianza, puesto que eso
&
implicaba el cálculo de un cuadrado, − - , y luego de una raíz, complicando la
implementación. Por este motivo, en lugar de la desviación estándar, propuso calcular la
desviación media, por provenir de un cálculo más conservador y mantener una relación mayor,
pero cercana a uno, con la desviación estándar, siempre que los errores de predicción tengan
una distribución normal. Basado en estas premisas, propuso el siguiente cálculo:
).. = / − 0
0 ← 0 + &)..
2 ← 2 + ℎ|)..| − 2
= 0 + 42
(12.5)
441
En este conjunto de ecuaciones, / es el valor medido, 0 es el estimado y 2 la
desviación media. Para que el cálculo sea rápido debería ser realizado en aritmética de
números enteros, pero como & < 1 es un número no entero, impuso un escalamiento para las
expresiones previas. Jacobson propuso & = 1,8 y ℎ = 1,4, para que fuera más sencillo
escalar mediante corrimientos binarios, y porque la mayor ganancia para la desviación permite
al seguir mejor las variaciones del .
La RFC 6298 recomienda ajustar los valores iniciales para en 1$%& , cuando la
conexión recién comienza y no se han podido realizar mediciones. Este valor se eleva a 3$%&
en el caso que el primer segmento SYN no logre llegar al otro extremo o se pierda el ACK que
lo cubre. Una vez conseguida una primera medición del , se recomienda inicializar los
estimadores a (0 ← / y (2 ← /,2.
El método de Jacobson es la base sobre la que muchas implementaciones TCP calculan
el hoy en día, logrando adaptarse de manera apropiada a los vaivenes de la conexión.
12.1.3 Problema de la medición en las retransmisiones - Algoritmo de Karn
La medición del presenta un problema en el caso de dispararse una
retransmisión. Cuando se transmite un segmento, si no se recibe el ACK correspondiente,
dentro del establecido, se procede a su retransmisión. Si posteriormente llegase un ACK
para dicha retransmisión, no sería posible determinar con certeza si se corresponde a la
transmisión o a la retransmisión. Surge entonces la pregunta sobre a cuál de ambos se asocia
la medición.
Este problema, que se conoce como ambigüedad del ACK, fue estudiado por Phil Karn,
quien determinó que no era preciso asociar una medición a esta situación para luego calcular
el estimador. La RFC 6298 también estableció que no se deben tomar muestras del sobre
segmentos retransmitidos, excepto que los segmentos carguen la nueva opción de sello de
tiempo, con la que se puede remover la ambigüedad.
De todas maneras, el hecho de haber tenido que retransmitir, permite obtener
información sobre el estado de la red, ya que TCP interpreta una situación de timeout como un
indicador de congestión. No tendría sentido entonces seguir usando el mismo valor de ,
ya que probablemente disparará nuevas retransmisiones. Lo más sensato sería aumentar el
valor de para reducir la carga sobre la red.
A instancias de lo observado por Karn, TCP incorpora para estos casos un factor de
backoff para el , que se duplica con cada nueva retransmisión. Esta situación se mantiene
mientras no se pueda realizar una medición correcta, sobre un segmento no retransmitido.
Entonces, el valor del factor de backoff vuelve a 1 y el valor de se calcula a partir de los
estimadores.
442
12.1.4 Opción Sello de Tiempo para medición de RTT
La RFC 1323 define una opción TCP, conocida como Sello de Tiempo, que puede usarse
para lograr una medición más precisa del . En caso de usar esta opción, para tomar una
muestra del valor de se agrega al encabezado un número de 32#7$ , que luego es
copiado por el otro extremo en el segmento ACK. Se puede medir el registrando el
tiempo de transmisión del segmento y la llegada del ACK con el valor de Sello de Tiempo
correspondiente, y restando ambos valores entre sí. Aunque se pueden lograr mediciones más
precisas con este mecanismo, es necesario acompañarlo de reglas para diferentes situaciones
de medición, tal como se explicará en el siguiente Capítulo.
12.1.5 Algoritmo de Manejo del RTO
La RFC 6298 indica un algoritmo recomendado para el manejo del reloj de
retransmisión:
1. Cada vez que se envía un segmento con datos, aunque se trate de una retransmisión,
hay que encender el reloj que expirará luego de $%& (para el valor actual del
).
2. Cuando todos los datos pendientes se hayan reconocido, apagar el reloj.
3. Cuando se reciba un ACK para datos nuevos, re-arrancar el reloj para que expire luego
de $%&.
Cuando el reloj expire, se debe:
4. Retransmitir el segmento más viejo que no haya sido reconocido.
5. Ajustar el valor = 2 (reloj de backoff). El valor máximo de RTO debe ser,
por lo menos, de 60$%&.
6. Arrancar el reloj de retransmisión para que expire luego de $%&.
7. Si el reloj expira mientras espera la llegada de un ACK para un segmento SYN y la
implementación está usando un valor de < 3$%&, se debe re-inicializar el a
3$%& cuando comience la transferencia de datos.
Luego de una retransmisión, cuando se hayan enviado nuevos datos y recibido un ACK
para ellos, se puede obtener una nueva medición para , y un cálculo para , que
puede provocar una disminución en el valor fijado por el backoff.
12.1.6 Retransmisiones y re-empaquetado
Una cuestión a tener en cuenta es que, al momento de que se produce una expiración
del , se dispara una retransmisión, aunque no necesariamente del mismo segmento. TCP
puede re-empaquetar datos, transmitiendo un segmento de mayor tamaño por cuestiones de
eficiencia. Esta funcionalidad es posible por la forma de numerar los datos que adopta el
protocolo: por byte y no por segmento.
443
12.2 Aplicaciones interactiv
nteractivas
Una aplicación interactiva que se apoya en TCP precisa que mensajes de poco volumen
de datos se transmitan entre cliente y servidor: un carácter de teclado, un movimiento del
mouse o de un joystick. Estos pequeños mensajes provocan acciones del lado servidor.
servi
Se
trata de paquetes denominados tynigrams,
t
por diminutos o tiny, ya que son de muy pocos
bytes, razón por la que su transmisión resulta ineficiente,
ineficiente debido al gran gasto u overhead que
representa el encabezado frente a la carga de datos. Por otra parte,
rte, si se eligiera transmitir
varios de estos paquetes en uno solo, se podrían generar situaciones molestas para el usuario,
usuario
debido a que las aplicaciones interactivas son sensibles al retardo.
Se suele distinguir este tipo de transporte respecto del tráfico
tr
de grandes volúmenes
de datos. La mayoría del tráfico TCP es de este último tipo pero, a pesar de ello, el protocolo
mantiene reglas especiales para el transporte de tráfico interactivo.
Un ejemplo de viejas aplicaciones que generaban este tipo de tráfico son rlogin y
telnet. Ambas permitían el login remoto, aunque padecían de muchos inconvenientes en
cuanto a seguridad. Una aplicación más nueva, denominada SSH, por Secure Shell
Shell, trabaja de
forma similar a telnet, pero usa técnicas de cifrado,
cifrado, logrando que el tráfico sea mucho más
seguro frente a la instalación de sniffers.
Un flujo de datos típico de este tipo de aplicaciones interactivas se presenta en la Fig.
12.1.
Figura 12.1
1 – Flujo de Datos Interactivo
En este caso, cada
ada tecla presionada
presionada por el usuario genera un segmento que via
viaja por la
red hasta el servidor. Éste debe hacer eco de lo que el cliente escribe,
escribe, para que el usuario lo
pueda apreciar en su pantalla.. Con esta forma de operación,, la transmisión de un único
carácter, pueden
en generar hasta cuatro segmentos:
segmen
el de datos y su correspondiente ACK, y el
de eco y su propio ACK. En la Fig. 12.1
1
se puede observar que, luego de la llegada del primer
dato al lado servidor, se retrasa
retras el segmento de ACK que lo reconoce,, probablemente en
espera de poder cargar el eco, para hacer la transmisión más eficiente.
444
Figura 1
12.2 – Flujo de Datos Interactivo
Normalmente, el lado servidor es lo suficientemente rápido como para combinar
ambos segmentos, tal como se observa en la Fig. 12.2. Esta técnica de combinación de ACK con
datos se conoce con el nombre de piggybacking, que significa montado a caballito
caballito. Del lado
cliente, sin embargo, no se puede juntar el ACK con el siguiente dato, pues esto depende de la
rapidez con que ell usuario maneje el teclado.
La técnica de ACK retardado es una técnica muy usada por el protocolo TCP. Lo cierto
es que no se puede retrasar el envío del segmento ACK sin que se ponga en juego cierta
probabilidad de retransmisión. Por este motivo, la RFC
RFC 1122 establecía un máximo de
500"$%& al tiempo de retraso,, pero muchas implementaciones lo ajustan en 200"$%&
"$%&.
Hemos mencionado ya que TCP utiliza una técnica conocida como ACK acumulativo
acumulativo,
con la cual no es preciso generar un ACK por cada segmento recibido. Siguiendo este criterio,
el protocolo puede demorar la generación de un ACK,, a la espera de poder combinarlo con el
envío de datos. La Fig. 12.2
.2 presenta el caso en que la implementación posee un límite de
200"$%&, resaltando
ndo el hecho de que las transmisiones de segmentos ACK se disparan a
partir de un reloj interno del mismo período.
12.2.1 Algoritmo de Nagle
Para poder manejar de manera eficiente situaciones de paquetes pequeños inyectados
en la red, TCP incluye el Algoritmo
oritmo de Nagle,
Nagle que se basa en la existencia de ACK retardados y
se encuentra descripto en la RFC 896.
896
El algoritmo establece que, ccuando
uando una conexión tiene datos en el buffer de
transmisión a la espera de ACK,, no puede transmitir nuevos datos bajados por el usuario en
forma de segmentos pequeños,, hasta que los datos no reciban el correspondiente ACK. De
este modo, no sólo se busca juntar
junta cierta cantidad de datos en un segmento,, transmitiéndolo
cuando se reciba el ACK,, sino además se
s agrega características de auto-sincronismo
sincronismo a la propia
445
conexión, ya que cuanto más rápido se reciban segmentos ACK, más pronto se transmitirán los
datos.
Un detalle importante es que la aplicación del algoritmo es diferente según el entorno.
Por ejemplo, si la conexión se ha establecido entre dos máquinas en una misma red
LAN, cuyo retardo ida y vuelta es mucho más pequeño que 1"$%&, se precisaría que el
usuario fuera capaz de manejar el teclado a una velocidad superior a 1000:(.(:7%.%$/$%&
para poder observar el algoritmo trabajando. En este entorno, el Algortimo de Nagle no se
dispara, puesto que el segmento de ACK siempre llega antes que el siguiente carácter en el
buffer. En un entorno WAN, sin embargo, se modifican bastante los tiempos, pudiendo
llegarse a retardos en el orden de los segundos. En este caso, un usuario generando caracteres
a razón de 1:(.á:7%./$%&, aumenta la probabilidad de que el Algoritmo de Nagle se dispare,
colectando datos antes de que llegue un ACK. De esta manera, se reducirá el número de
paquetes pequeños en la red aunque la conexión se verá afectada, probablemente aumentado
la duración total de la misma, debido a la característica de auto-sincronismo impuesta.
Generalmente, el Algoritmo de Nagle se encuentra habilitado por default, pero hay
ocasiones, en entornos altamente interactivos, donde los efectos de performance que genera
pueden ser indeseables con respecto a la latencia. Por este motivo, se lo puede deshabilitar
sobre una base por conexión, a través de una opción de socket().
12.3 Tratamiento de datos - Bandera PSH
Mientras que las aplicaciones manejan la velocidad y el momento con que envían
datos a TCP, no pueden controlar ni la velocidad ni el tiempo con que TCP los envía a la red. En
el caso de transmisiones de grandes archivos esto no sería un problema mientras TCP
acumulara los datos en buffer y los fuera transmitiendo a medida que la conexión lo
permitiese.
En el caso de una aplicación interactiva, no se desea que TCP acumule los datos, sino
que los transmita lo más rápidamente posible, para que no se perciban demoras en el proceso
interactivo. Para manejar esas situaciones se incluyó la bandera de PUSH en el encabezado
TCP. Cuando se invoca esta funcionalidad, TCP creará un segmento o varios que contengan los
datos en espera y los transmitirá con la bandera de PUSH en alto. Los límites de los mensajes
dependen de las aplicaciones.
En la práctica se suele encender esta bandera cuando se vacía el buffer de transmisión,
toda vez que se transmite un segmento.
12.4 Tratamiento de datos - Bandera URG
El protocolo TCP permite que las aplicaciones marquen datos que precisan
tratamiento urgente. Cuando se envían datos de este tenor para ser transmitidos, levantan la
bandera URG del encabezado, indicando que el campo Puntero URG es válido.
446
El mecanismo urgente de TCP permite marcar un punto en el flujo de bytes como el
final de la información que precisa tratamiento urgente. Siempre que dicho número sea mayor
que el extremo izquierdo de la ventana de recepción (RCV.NXT), el protocolo receptor debe
avisar a la aplicación para que ésta entre en modo urgente. Cuando el borde izquierdo de la
ventana de recepción haya alcanzado el número de byte que marca el puntero urgente, TCP
debe avisar a la aplicación que puede volver al modo normal de operación. Esto significa que
ciertos datos que fueron recibidos como normales, podrían convertirse en datos urgentes si se
recibe una indicación URG en un segmento posterior, antes que dichos datos hayan sido
subidos a la aplicación.
El último byte de datos urgentes se encuentra sumando el campo Número de
Secuencia con el valor del campo Puntero Urgente, cargados en el segmento con la bandera
URG levantada.
Este mecanismo presentó varias ambigüedades desde el momento de su definición. No
se trata de un mecanismo de entrega de datos fuera de banda, pero muchas
implementaciones procesan los datos urgentes de ese modo, no entregándolos como parte del
flujo de datos normal, como lo especifica la RFC original, sino separando el último byte de
datos urgente . También, durante muchos años existió una ambigüedad referida a si el puntero
urgente apuntaba al primero o al último byte de datos urgentes, hasta que la RFC 1011 aclaró
que se trata del último byte.
Como consecuencia de estas cuestiones, la RFC 6093 aconsejó que las nuevas
aplicaciones no usaran el mecanismo urgente de TCP, aunque estableció que todas las
implementaciones TCP lo deben seguir incorporándolo para que pueda ser utilizado por
aquellas aplicaciones ya existentes que lo invocan.
12.6 Flujo de grandes volúmenes de datos
En contraposición con el tráfico de aplicaciones interactivas, el 90% de las
transmisiones TCP se refiere a intercambio de grandes volúmenes de datos. A continuación, se
presentan varios ejemplos de transferencias de datos entre un cliente y un servidor web. En
algunos casos, se ha omitido el inicio de la conexión y se ha numerado los segmentos con un
número de secuencia relativo, a partir del número “0”, reservado para el primer byte de datos
de cada extremo. Los números entre corchetes “? @” representan la carga de datos de cada
segmento. Resaltado junto al instante de transmisión de cada segmento aparece un número
indicador del orden del mismo en el flujo de datos TCP.
12.6.1 Intercambio de segmentos – Situación de timeout
En la Fig. 12.3, se presenta parte de una transferencia de datos entre un cliente y un
servidor web. La intención de este ejemplo es ver al protocolo en acción en una transferencia
de segmentos con gran cantidad de datos y situaciones de timeout. Se aconseja al lector seguir
el flujo de Números de Secuencia y Números de ACK para entender mejor cómo trabaja TCP.
447
448
Figura 12.3
.3 – Flujo de grandes volúmenes de datos
El segmento 1 es un pedido GET del cliente HTTP, que carga 1010A7%$
A7%$ de datos y
anuncia un tamaño de ventana de 251A7%$. Es dable aclarar que ste valor de ventana,
debería escalarse, puesto que ambos extremos negociaron en el inicio la utilización de la
opción Escalamiento de Ventana
Ventana, que acá se omite. Por lo tanto, lo mismo debería
interpretarse a partir de los valores de ventana anunciados por el servidor.
449
En el segmento2, el servidor reconoce todos los datos provenientes del cliente,
mediante un ACK retardado, o sea un segmento sin datos, únicamente transmitido para
reconocimiento de los datos recibidos. Es preciso hacer notar que, un segmento ACK sin
datos, lleva el número de secuencia que el otro extremo está esperando recibir, que también
será el número de secuencia del siguiente segmento de datos que el cliente transmita.
El servidor comienza a transmitir datos en los segmentos 3 y 4. Primero transmite
590A7%$ y luego 222A7%$, que son reconocidos en conjunto con un ACK retardado
proveniente del cliente, cuyo número de secuencia es 1010. El número de ACK es la suma
590 + 222 = 812.
En el segmento 6, el cliente realiza un nuevo pedido, de 1018A7%$ de datos. Su
número de secuencia es 1010, porque esa fue la cantidad de datos transmitida en el primer
segmento, cuyo número de secuencia se fijó en “0”, para numeración relativa. El servidor
reconoce la llegada correcta de estos nuevos datos con el ACK retardado del segmento 7. Los
segmentos 8 y 9 son la respuesta al requerimiento, transmitida en dos paquetes de523 y
223A7%$ de datos, respectivamente. Obsérvese en ambos extremos las leves variaciones de
la ventana anunciada, sin olvidar que está escalada.
En el segmento 10 se puede observar un caso de piggybacking: el cliente reconoce
todos los bytes recibidos y aprovecha la transmisión del segmento de ACK para enviar
1018A7%$ de datos. Con el segmento 11, el servidor sólo reconoce una parte de los datos
recibidos. En los segmentos 12 y 13, el servidor envía en total 384A7%$ de datos, pero no
reconoce nuevos datos recibidos. La llegada correcta de estos datos al lado cliente se reconoce
en el segmento 14, otro ACK retardado. Evidentemente, este segmento ACK se pierde y el
extremo servidor se ve obligado a retransmitir estos datos en el segmento 15. Esto es evidente
en el Número de Secuencia del segmento 15.
Vale la pena destacar que la situación de timeout es una indicación fuerte de
congestión para TCP. Por otra parte, el segmento 15 es una muestra de lo que en TCP se
conoce como re-empaquetado o repacketization: en lugar retransmitir los datos en dos
segmentos, como se habían transmitido originalmente, el protocolo realiza la retransmisión
juntando ambos segmentos en uno.
El cliente reconoce la retransmisión en el segmento 16 y, posteriormente, en el
segmento 17, transmite más datos. Luego, el lado servidor transmite un segmento con
384A7%$ de nuevos datos, tal como lo indica su Número de Secuencia. Los segmentos 19 y
20 representan una repacketization de estos datos para su retransmisión. El segmento 21,
proveniente del cliente, reconoce los datos previos y el segmento 22 carga 631A7%$ de un
pedido del cliente, que se reconocen en el segmento 23.
Los segmentos 24 y 25 son dos nuevas transmisiones del servidor. El segmento 26 es
un ACK retardado del lado cliente. En el segmento 27, el cliente envía datos, que el servidor
reconoce en el segmento 28. Nuevamente el servidor transmite dos segmentos, que el cliente
reconoce con un ACK retardado.
450
En el segmento 32,, el cliente transmite 757A7%$ de datos, que el servidor reconoce
en el segmento 33.. La situación es similar para los segmentos 34 y 35.. Los segmentos 36 y 37
provenientes del servidor, son reconocidos de manera acumulativa con el segmento 38 del
cliente. En el segmento 39,, el cliente vuelve a enviar datos y el servidor los reconoce con el
ACK retrasado del segmento 40..
Si repitiéramos
mos la misma conexión, enviando al servidor los mismos requerimientos, el
flujo no tendría por qué ser igual que el presentado, ya que la forma en que se transfieren los
datos depende de la situación particular,
particular de ambos extremos y de la red, en un momento
dado.
12.6.2
.6.2 Intercambio de segmentos – Recepción de ACK duplicados
En la Fig. 12.4 see presenta otro intercambio de datos entre otro cliente y el mismo
servidor, donde se puede observar una situación de congestión,
congestión, menos grave que el timeout,
que se percibe por la recepción de ACK duplicados.
Figura 12.4 – Situación de congestión. ACK duplicados.
En el segmento 1,, el servidor transmite 53A7%$, luego 505 y 47A7%$
A7%$, en los
segmentos 2 y 3 respectivamente.
respectivamente En estos segmentos se observa el mismo número de ACK.
Mediante el número de secuencia de estos segmentos, se puede inferir que el servidor ha
451
transmitido 56836 − 1A7%$, ya que el número de secuencia inicial ISN también cuenta,
aunque en el segmento SYN no se envían datos. También, por el Número de ACK, se interpreta
que el servidor ha recibido segmentos correctos y en orden hasta el byte 10987.
En el segmento 4, el cliente reconoce todas las transmisiones previas, pero su número
de secuencia es 2730 números mayor que lo que el servidor le ha reconocido. Esto se
confirma en el segmento 5, cuando el servidor transmite 41A7%$, pero insiste con el mismo
número de ACK que en los segmentos previos. En el segmento 6, el cliente tiene datos para
transmitir y aprovecha para reconocer los datos del segmento previo transmitido por el
servidor.
La llegada del segmento 6 de 41A7%$ de datos del cliente, dispara del lado servidor
un ACK sin datos, que repite el Número de ACK 10988. En su forma tradicional, cuando el
protocolo TCP recibe datos correctamente pero fuera de orden, lo único que puede hacer es
repetir el número de ACK correspondiente al último segmento recibido en orden y sin errores.
Es lo que se denomina generación de ACK duplicados. No es una situación tan grave como un
timeout, pero es un indicador de que un segmento pudo haberse perdido, aunque hay otros
que siguen llegando correctamente pero fuera de orden.
El aviso parece no ser suficiente para disparar una retransmisión, ya que el lado cliente
sigue enviando nuevos datos, en los segmentos 8 y 9, primero 1460A7%$ y luego 24A7%$.
La llegada de estos datos al servidor dispara dos nuevos ACK duplicados, se trata de los
segmentos 9 y 10. Al recibirlos, el TCP del lado cliente considera necesaria la retransmisión
del segmento con el número de secuencia esperado por el servidor, en el que carga
1460A7%$ de datos. Evidentemente, esta transmisión llena el hueco que existía en el buffer
de recepción del protocolo TCP del lado servidor, pues este avanza el borde izquierdo de la
ventana hasta el Número de ACK 15243 en el segmento 13.
12.6.3 Control de Flujo - Manejo de las ventanas de transmisión y recepción
En la Fig. 12.5 se presenta otro intercambio cliente-servidor con el propósito de seguir
la variación de las ventanas deslizantes de transmisión y recepción en entorno de flujo de
grandes volúmenes de datos.
En este ejemplo, el intercambio TCP comienza con el inicio de la conexión. El cliente
envía un segmento SYN, con el valor de la opción MSS que indica que se encuentra en una
LAN, un anuncio de factor de escalamiento de ventana de 8 y el aviso de que puede hacer
reconocimiento de datos por bloque, SACK. El extremo TCP servidor puede manejar las
mismas opciones, aunque el factor de escalamiento que usará es 6, según lo anuncia en el
segmento 2. Como ambos entienden la opción de escalamiento de ventana, a partir de este
momento cada segmento del lado cliente anunciará en el campo Ventana (win) un valor que
deberá ser multiplicado por 2C = 256 para hallar el verdadero tamaño de la ventana. Del lado
servidor, cada anuncio de ventana deberá ser multiplicado por 64 del lado cliente, para hallar
el verdadero valor de la ventana de recepción del servidor. Se ha elegido presentar los campos
452
de win de los segmentos subsiguientes con el valor ya escalado, pero en realidad,, por ejemplo
en el segmento 4,, el valor escrito en el campo win es 256, y en el segmento 5 es 10
108.
En el segmento 4,, el cliente envía al servidor 513A7%$ de datos con Número de
Secuencia 1.. La transmisión de este segmento se traduce en una ventana de transmisión
(recuadro de línea punteado) con 513A7%$ almacenados a la espera de un ACK.. La ventana
de recepción escalada anunciada por el cliente en este segmento es 65536A7%$.
La transmisión del segmento 5 obedece al hecho de que el servidor ha recibido los
datos correctamente, quedando la ventana de recepción (recuadro de línea
línea llena) con el
puntero de la izquierda apuntando al número 514,, el siguiente byte que espera recibir. El
anuncio de la ventana escalada del servidor es 6912A7%$.
Figura 12.5 – Control de Flujo por Ventanas Deslizantes.
Luego el servidor transmite el segmento 6, con 352A7%$ de datos. Esto no modifica
el valor de la ventana anunciada al otro extremo, pero sí modifica la situación de su propia
ventana de transmisión, en este caso con 352A7%$ de datos a la espera
ra de un ACK. La llegada
453
de este segmento, coloca el estado de la ventana de recepción del cliente como se ha
supuesto en la figura. El segmento 7 es otra transmisión del servidor, de 15A7%$, que
modifica el estado de la ventana de transmisión tal como se presenta en el recuadro punteado.
Del lado cliente, si los datos llegan correctamente, se almacenan en la ventana de recepción, a
la espera de ser entregados a la aplicación. La transmisión del ACK en el segmento 8, confirma
la llegada correcta y vuelve a dejar libre el buffer de recepción del lado cliente. La recepción de
este segmento permite al protocolo TCP del lado servidor, retirar los datos pendientes de su
ventana de transmisión.
A partir de este segmento la situación del par de ventanas de cada lado se mantiene
estática porque ya no se intercambian más datos.
En este ejemplo, se ha incluido el cierre de la conexión, para resaltar que tanto el
segmento SYN, como el segmento FIN, utilizan un número de secuencia, a pesar de no
transportar datos.
12.7 Aviso de ventana nula - Síndrome de la ventana tonta
El anuncio de la ventana es lo que permite realizar el control de flujo por parte del
receptor. Dado que TCP almacena los segmentos en el buffer de recepción, para subir a las
aplicaciones aquellos que llegaron correctamente y en orden, si las aplicaciones no están
ocupadas, inmediatamente leerán los datos del buffer, manteniéndose el anuncio de la
ventana en un valor casi estático, constante. Otras veces, cuando las aplicaciones tienen
tareas que cumplir, no pueden vaciar inmediatamente el buffer de recepción. En estos casos,
se observarán anuncios de ventana más pequeños, pudiéndose llegar a una situación de
aviso de ventana nulo. Un aviso de este tipo detendrá el flujo de datos transmitidos desde el
otro extremo. La forma de reanudar la comunicación es enviando un segmento de
actualización del estado de la ventana, una vez que se haya liberado espacio en el buffer de
recepción.
En general, luego de un aviso D# = 0, la actualización del tamaño de la ventana o
window update, se realiza por medio de un segmento sin datos, o sea un segmento ACK, cuya
transmisión no es confiable. El peligro de que dicho segmento se pierda podría conducir a
una situación de punto muerto o deadlock, donde cada extremo espera que el otro realice
alguna acción: el transmisor espera la actualización y el receptor espera que le envíen datos.
Para evitar estas situaciones, TCP incluye un reloj persistente, conocido como timer
persist, que dispara la transmisión de segmentos de sondeo de ventana, también conocidos
como window probes, para obligar al extremo que anunció la ventana nula a realizar una
actualización. La RFC 1122 aconseja disparar el mecanismo luego del primer RTO transcurrido
desde el aviso D# = 0 y, a partir de allí, manejarlo con un mecanismo de backoff
exponencial. No se define un límite máximo de segmentos de sondeo transmitidos,
simplemente el mecanismo deja de funcionar al recibir una respuesta D# ≠ 0.
454
Los segmentos de sondeo se cargan con un byte de datos, para que su transmisión
sea confiable, obligando al receptor a generar un aviso de ventana por medio de un
segmento ACK. El dato se aceptará o no del lado receptor, dependiendo del estado del buffer
de recepción. Por ejemplo, si el último ACK recibido con aviso de ventana D# = 0 transporta
un Número de ACK 9034 , entonces el segmento de sondeo llevará un Número de Secuencia
9034, que es el que espera recibir el otro extremo. Puede cargar un byte de datos por que el
protocolo permite que la numeración sobrepase el borde de la ventana cerrada. La respuesta
del otro extremo, si la ventana continuara siendo nula, es un segmento ACK de número
9034, es decir que no se reconoce el byte de datos. Por este motivo el segmento window
probe se sigue retransmitiendo.
El aviso de ventana nula puede causar problemas si no se imponen ciertas
condiciones. Si el receptor, ni bien sale de la condición de ventana cerrada, empieza a
anunciar tamaños de ventana pequeños, y el transmisor aprovecha estos anuncios para
transmitir datos inmediatamente, vuelve a llenar la ventana, provocando nuevos avisos de
D# = 0. Esta situación se conoce como Síndrome de la Ventana Tonta (SWS, Silly Window
Syndrome). Para evitarlo, basta con cumplir una serie de reglas, presentadas en la RFC 1122:
•
Regla 1: Los receptores no deben anunciar tamaños de ventana pequeños, aunque
sean mayores que los advertidos previamente, hasta que la ventana pueda alcanzar el
un valor que se fija en el mínimo entre el tamaño de un segmento completo, o sea el
valor MSS, o la mitad del espacio del buffer de recepción. Esta regla se aplica cuando
las aplicaciones liberan espacio del buffer de recepción, disparando actualizaciones, o
en respuesta a window probes.
•
Regla 2: Para evitar el síndrome de la ventana tonta, los transmisores no deben enviar
segmentos, al menos que se cumplan alguna de las siguientes condiciones:
1. Se puede enviar un segmento de tamaño MSS. Esta condición se incluye para
evitar la ineficiencia debida al overhead, presente al transmitir segmentos
pequeños.
2. Se puede enviar al menos la mitad del tamaño de ventana máximo anunciado por
el receptor durante la conexión. Esta condición es para manejar la situación de
aquellos dispositivos que anuncian tamaños de ventana de pocos bytes, tal vez
menores que MSS.
3. Se puede transmitir todo lo que queda pendiente mientras no se está esperando
ACK por ningún dato o el algoritmo de Nagle está deshabilitado para esta
conexión. Esta última condición es aplicable al caso en que la aplicación del lado
transmisor realice pequeñas escrituras.
12.8 Conexiones ociosas - Mecanismo Keepalive
Se ha explicado hasta aquí la forma en que se establece una conexión, con su
correspondiente reserva de recursos, algunas cuestiones relativas al intercambio de datos y los
455
aspectos relevantes del cierre de una conexión, ya sea que suceda de forma ordenada o
desordenada, liberando los recursos pre-asignados.
En este apartado se abordará la situación de aquellas conexiones que, una vez
establecidas, permanecen ociosas, sin transmitir ni recibir datos. Esta situación podría deberse
a una serie de razones no tan inusuales.
Un cliente podría establecer una conexión TCP con una aplicación servidora, y luego el
propio usuario retirarse de la máquina y dejar la conexión establecida sin intercambio de datos
por un tiempo indeterminado. También, podría suceder que cayeran routers intermedios
entre ambos extremos de la comunicación, condenando las conexiones a la inactividad,
aunque se encuentren establecidas. Dependiendo de las circunstancias, podría ser útil que los
extremos permanezcan conectados aunque tengan muy pocos datos para intercambiar. En
otros casos, sería mejor terminar la conexión, para no desperdiciar recursos.
Muchas implementaciones TCP proveen un método, denominado mantener vivo o
keepalive, para probar si el otro extremo de la conexión se encuentra presente. El método
lleva un reloj asociado, que se conoce con el mismo nombre, y que permite marcar tiempos
que disparan el envío segmentos de sondeo al otro extremo, para comprobar si se encuentra
presente.
El problema con este esquema es que se pueden confundir situaciones de ociosidad
legítimas con fallas transitorias de la red, terminando conexiones por motivos ajenos a las
mismas. La controversia se extiende cuando se menciona que las aplicaciones deberían
hacerse cargo de esta funcionalidad, aunque la contrapartida afirma que, si hubiese muchas
aplicaciones que lo precisasen, lo más lógico sería que TCP la proveyera.
Como la funcionalidad es opcional, existen algunos parámetros de configuración que
se ajustan para controlar la ausencia de actividad de una conexión por algún período de
tiempo, para disparar el mecanismo de sondeo. Un parámetro ajusta el período de repetición
de los segmentos de sondeo, cuando no se recibe respuesta del otro extremo. También es
posible configurar un número máximo de estos segmentos. Cuando se alcanza el límite sin
respuestas, se considera el otro extremo inalcanzable y se finaliza la conexión.
A diferencia de los segmentos de sondeo del reloj persistente, el número de secuencia
de un sondeo keepalive es un número menos que el mayor número de ACK recibido desde el
otro extremo. Al igual que los segmentos de sondeo del reloj persistente, estos segmentos
pueden cargar un byte de datos. El dato en sí no es relevante para la conexión, ni queda sujeto
al mecanismo tradicional de retransmisión, pero, de encontrarse presente y activo, el otro
extremo contestará con un ACK.
En cualquier caso, existen cuatro escenarios posibles:
456
1. El dispositivo en el otro extremo se encuentra activo y alcanzable. El protocolo TCP
responderá con un ACK, reiniciando el reloj de keepalive en el extremo TCP que
realiza el sondeo.
2. El dispositivo en el otro extremo ha caído y se encuentra en proceso de rearranque. No se recibirá respuesta por parte del protocolo TCP del otro extremo,
por lo que se continuará con el sondeo keepalive, según los parámetros de
expiración y número máximo de segmentos de prueba especificados. Si se alcanza
este número y aún no se recibe respuesta, se da por terminada la conexión. La
aplicación que realiza el sondeo puede recibir entonces un mensaje de “error por
expiración”. Vale la pena aclarar que, cuando un dispositivo cae, no puede realizar
el cierre, ni siquiera emitiendo un segmento RST.
3. El dispositivo en el otro extremo ha caído y re-arrancado. La respuesta al sondeo
es un segmento con la bandera RST levantada, ya que no se reconoce la conexión
que había estado establecida. Esta respuesta termina la conexión y se comunica a
la aplicación a través de un mensaje que suele ser del tipo “conexión reiniciada por
el par”.
4. El dispositivo en el otro extremo se encuentra activo pero es inalcanzable por
problemas en la red. La situación no se podrá distinguir del caso 2, aunque podría
llegar a recibirse un mensaje de error ICMP.
La confusión entre el segundo y el cuarto escenario es lo que genera tanta controversia
con respecto al uso de esta herramienta.
En sistemas tipo Linux, los valores default del reloj de keepalive suelen ser de 2ℎ$,
ajustándose en 75$%& el intervalo de sondeo y 9 segmentos como valor máximo de pruebas
de sondeo. En Windows, en cambio, el intervalo se suele fijar en 1$%& y el valor máximo en 10
segmentos.
El mecanismo de keepalive no se encuentra definido en la especificación de TCP pero,
como algunos Sistemas Operativos lo incorporan, la RFC 1122 aclara que utilizarlo puede llevar
a cerrar una conexión perfectamente establecida por falla en la Internet. También se critica en
dicha RFC el consumo de ancho de banda de los mensajes en una conexión naturalmente
ociosa y el costo en aquellos casos donde el cargo es por paquete transmitido.
Bibliografía
1. RFC
793
“Transmission
Control
Protocol
ˮ,
September
http://tools.ietf.org/html/rfc793
2. RFC 896 “Congestion Control in IP/TCP Internetworks”, January
http://tools.ietf.org/html/rfc896
1981.
1984.
457
3. RFC 1122 “Requirements for Internet Hosts -- Communication Layersˮ, October 1989.
http://tools.ietf.org/html/rfc1122
4. RFC
1323
“TCP
Extensions
for
High
Performanceˮ,
May
1992.
https://www.ietf.org/rfc/rfc1323.txt
5. RFC 6093 “On the Implementation of the TCP Urgent Mechanismˮ, January 2011.
http://tools.ietf.org/html/rfc6093
6. RFC 6247 “Moving the Undeployed TCP Extensions RFC 1072, RFC 1106, RFC 1110, RFC
1145, RFC 1146, RFC 1379, RFC 1644, and RFC 1693 to Historic Status ˮ, May 2011.
http://tools.ietf.org/html/rfc6247
7. RFC
6298
“Computing
TCP´s
Retransmission
Timerˮ,
June
2011.
http://tools.ietf.org/html/rfc6298
8. Jacobson, Van, “Congestion Avoidance and Controlˮ, CM SIGCOMM Computer
Communication Review. ACM, 1988. p. 314-329.
9. Karn, P. , C. Partridge, "Improving Round-Trip Time Estimates in Reliable Transport
Protocols", SIGCOMM 87. http://ccr.sigcomm.org/archive/1995/jan95/ccr-9501partridge87.pdf
10. Kozierok, Charles M., “The TCP/IP Guideˮ. http://www.tcpipguide.com/free/t_toc.htm
11. Comer, Douglas, “Internetworking with TCP/IP: Principles, Protocols and Architecture
v. 1ˮ. Pearson EducaƟon, 1995.
12. Stevens, W. Richard, “TCP/IP Illustrated, Vol. 1: The Protocols (Addison-Wesley
Professional Computing Series) ˮ. Addison-Wesley, 1993.
Problemas
1. ¿Cómo se establece el para una conexión TC? ¿Qué importancia tiene el Algoritmo de
Karn?
2. Explique el concepto de re-empaquetado en TCP.
3. ¿Cuál es la característica del flujo de datos interactivos? ¿Para qué se utiliza el Algoritmo de
Nagle?
4. ¿Cuál es el sentido del timer persist? ¿Qué relación existe entre el timer persist y el
síndrome de la ventana tonta?
5. Mencione ventajas y desventajas asociadas con la implementación de un timer keepalive.
6. Sobre la siguiente captura de un segmento TCP, sabiendo que el cliente únicamente ha
transferido 393 bytes al Servidor desde que comenzara la conexión, contestar:
a) Nº de Secuencia del SYN inicial de Cliente a Servidor y Nº de Secuencia del SYN del
Servidor al Cliente.
c) Nº de Secuencia y Nº de ACK del segmento con los 393 bytes de Cliente a Servidor.
d) Sabiendo que en el SYN inicial de Cliente a Servidor el campo de opciones era: <
Maximum segment size: 1460 bytes, NOP, Window scale: 1, NOP, NOP, SACK permitted >,
determine el verdadero valor de la ventana anunciada en el segmento capturado.
458
Transmission Control Protocol,
Source port: http (80)
Destination port: 1543 (1543)
Sequence number: 2976738361
Acknowledgement number: 1544685068
Header length: 20 bytes
Flags: 0x0010 (ACK)
0... .... = Congestion Window Reduced (CWR): Not set
.0.. .... = ECN-Echo: Not set
..0. .... = Urgent: Not set
...1 .... = Acknowledgment: Set
.... 0... = Push: Not set
.... .0.. = Reset: Not set
.... ..0. = Syn: Not set
.... ...0 = Fin: Not set
Window size: 6432
Checksum: 0xfc01 (correct).
459
Descargar