El control de congestión evita que la red se sature cuando varios flujos compiten por el mismo enlace. TCP ajusta su ventana de congestión en función de las pérdidas y del tiempo que tardan los ACK en regresar.
Desde RFC 5681 el algoritmo base combinó slow start, congestion avoidance, fast retransmit y fast recovery. Versiones modernas como CUBIC o BBR parten de esos principios pero aplican métodos estadísticos más sofisticados para adaptarse a enlaces de alta velocidad.
Una red congestionada no puede atender todas las solicitudes que recibe. Los buffers de routers se llenan, aumentan las colas y finalmente se descartan paquetes. TCP interpreta la pérdida o los grandes retrasos como señales para disminuir el ritmo de envío antes de que la red colapse.
Slow start inicia cada conexión con una ventana de congestión (cwnd) pequeña, tradicionalmente de uno o dos MSS. Tras cada ACK, la ventana se duplica aproximadamente, lo que produce un crecimiento exponencial.
Este comportamiento dura hasta que la cwnd alcanza el umbral de slow start (ssthresh) o hasta que ocurre una pérdida. El propósito es descubrir rápidamente el ancho de banda disponible sin saturar la red de inmediato.
Cuando cwnd supera ssthresh, el crecimiento pasa a ser lineal. Por cada RTT exitoso la ventana aumenta en aproximadamente un MSS. Este modo busca estabilidad: evita oscilaciones bruscas y mantiene el flujo cerca del punto óptimo de utilización.
Si se detecta pérdida por timeout, TCP considera que hubo congestión severa, por lo que reduce ssthresh a la mitad de la ventana actual y reinicia slow start desde un valor más pequeño.
Tres ACK duplicados son una señal temprana de pérdida. Fast retransmit reenvía el segmento faltante sin esperar al temporizador. Luego fast recovery baja ssthresh y reduce cwnd, pero evita regresar al crecimiento exponencial si la red parece estable.
Este ciclo permite recuperarse rápidamente de pérdidas aisladas sin reducir drásticamente el rendimiento.
El caudal efectivo es proporcional a cwnd/RTT. Si la ventana se reduce o el RTT aumenta, el throughput cae. Los emisores modernos estiman el RTT con filtros exponenciales para reaccionar a variaciones sin dejarse llevar por picos espurios.
Combinar control de congestión con control de flujo asegura que la cantidad de datos aceptados por el receptor sea coherente con la capacidad de la red que los transporta.
El patrón clásico de cwnd es un diente de sierra: crece linealmente, se reduce a la mitad ante pérdida y vuelve a crecer. Analizar la pendiente de ese diente permite estimar si la conexión está limitada por el ancho de banda disponible o por la configuración del host.
Herramientas como Wireshark permiten graficar cwnd en Statistics > TCP Stream Graphs > Time Sequence Graph (Stevens).
El siguiente script modela slow start y congestion avoidance, incluyendo eventos de pérdida por timeout y por ACK duplicados:
def simular_cwnd(rangos, mss=1, ssthresh=16):
cwnd = mss
for evento in rangos:
if evento == "ack":
if cwnd < ssthresh:
cwnd *= 2 # slow start
else:
cwnd += mss # congestion avoidance
elif evento == "triple_ack":
ssthresh = max(mss, cwnd // 2)
cwnd = ssthresh + 3 * mss
elif evento == "timeout":
ssthresh = max(mss, cwnd // 2)
cwnd = mss
yield cwnd, ssthresh, evento
secuencia = ["ack"] * 6 + ["triple_ack"] + ["ack"] * 4 + ["timeout"] + ["ack"] * 4
for valor, umbral, evento in simular_cwnd(secuencia):
print(f"Evento={evento:11s} -> cwnd={valor:02d}, ssthresh={umbral:02d}")
Ajustando la lista de eventos se puede observar cómo cada tipo de pérdida modifica la ventana, lo que ayuda a interpretar capturas reales.
Windows ofrece contadores de rendimiento y cmdlets que exponen métricas relacionadas con la congestión.
Get-NetTCPConnection -State Established |
Select-Object -First 5 -Property LocalPort, RemotePort, CongestionControlAlgorithm
Get-Counter -Counter "\TCPv4\Connection Failures" -SampleInterval 1 -MaxSamples 5
El primer comando revela qué algoritmo está usando Windows (por ejemplo, CUBIC). El segundo permite detectar fallas relacionadas con congestión prolongada cuando los valores crecen de manera sostenida.
Un modelo simplificado establece que el throughput de TCP es proporcional a MSS / (RTT * sqrt(p)), donde p es la probabilidad de pérdida.
Esto explica por qué enlaces de alta latencia con pérdidas leves pueden experimentar caídas dramáticas en el ancho de banda utilizable.
Para mitigar este efecto se emplean colas con Active Queue Management (AQM) como RED o CoDel, que intentan señalar congestion antes de que los buffers se llenen.
Comprender el control de congestión permite explicar variaciones de rendimiento que no se deben a la aplicación sino a la red subyacente.