Pregunta

Supongamos que hay un cliente que hace muchas conexiones de corta duración a un servidor.

Si el cliente cierra la conexión, habrá muchos puertos en el estado TIME_WAIT en el lado del cliente. Dado que el cliente se queda sin puertos locales, resulta imposible hacer un nuevo intento de conexión rápidamente.

Si el servidor cierra la conexión, veré muchos TIME_WAIT en el lado del servidor. Sin embargo, ¿esto hace algún daño? El cliente (u otros clientes) puede seguir haciendo intentos de conexión ya que nunca se queda sin puertos locales, y la cantidad de estado TIME_WAIT aumentará en el lado del servidor. ¿Qué pasa eventualmente? ¿Sucede algo malo? (desaceleración, caída, conexiones caídas, etc.)

Tenga en cuenta que mi pregunta no es "¿Cuál es el propósito de TIME_WAIT ? " pero " ¿Qué ocurre si hay tantos estados TIME_WAIT en el servidor? " Ya sé qué sucede cuando se cierra una conexión en TCP / IP y por qué se requiere el estado de TIME_WAIT . No estoy tratando de solucionarlo, pero solo quiero saber cuál es el problema potencial con él.

En pocas palabras, digamos netstat -nat | grep: 8080 | grep TIME_WAIT | wc -l imprime 100000 . ¿Qué pasaría? ¿Se ralentiza la pila de la red O / S? " Demasiados archivos abiertos " ¿error? ¿O simplemente no hay nada de qué preocuparse?

¿Fue útil?

Solución

Cada socket en TIME_WAIT consume algo de memoria en el kernel, por lo general algo menos que un socket ESTABLISHED , pero aún así significativo. Un número suficientemente grande podría agotar la memoria del núcleo, o al menos degradar el rendimiento porque esa memoria podría usarse para otros fines. Los sockets de TIME_WAIT no tienen descriptores de archivos abiertos (suponiendo que se hayan cerrado correctamente), por lo que no debería preocuparse por un " demasiados archivos abiertos " error.

El zócalo también vincula esa dirección IP y el puerto src / dst en particular, por lo que no se puede reutilizar durante el intervalo de TIME_WAIT . (Este es el propósito previsto del estado de TIME_WAIT ). La conexión del puerto no suele ser un problema a menos que necesite volver a conectar un con el mismo par de puertos. La mayoría de las veces un lado usará un puerto efímero, con solo un lado anclado a un puerto conocido. Sin embargo, una gran cantidad de sockets TIME_WAIT puede agotar el espacio del puerto efímero si se conecta repetida y frecuentemente entre las mismas dos direcciones IP. Tenga en cuenta que esto solo afecta a este par de direcciones IP en particular y no afectará el establecimiento de conexiones con otros hosts.

Otros consejos

Resultados hasta ahora:

Incluso si el servidor cerró el socket utilizando la llamada del sistema, su descriptor de archivo no se liberará si ingresa el estado TIME_WAIT. El descriptor de archivo se publicará más tarde cuando el estado TIME_WAIT desaparezca (es decir, después de 2 * MSL segundos). Por lo tanto, demasiados TIME_WAIT posiblemente conducirán a un error de "demasiados archivos abiertos" en el proceso del servidor.

Creo que la pila O / S TCP / IP se ha implementado con la estructura de datos adecuada (por ejemplo, la tabla hash), por lo que el número total de TIME_WAIT no debe afectar el rendimiento de la pila O / S TCP / IP. Solo el proceso (servidor) que posee los sockets en el estado TIME_WAIT sufrirá.

Cada conexión se identifica mediante una tupla (IP del servidor, puerto del servidor, IP del cliente, puerto del cliente). De manera crucial, las conexiones de TIME_WAIT (ya sea que estén en el lado del servidor o en el lado del cliente) ocupan una de estas tuplas.

Con los TIME_WAIT en el lado del cliente, es fácil ver por qué no puede hacer más conexiones, ya no tiene más puertos locales. Sin embargo, el mismo problema se aplica en el lado del servidor: una vez que tiene 64k conexiones en TIME_WAIT estado para un solo cliente , no puede aceptar más conexiones de ese cliente , porque no tiene forma de diferenciar entre la conexión anterior y la nueva; ambas conexiones se identifican con la misma tupla. En este caso, el servidor debería enviar RST s a nuevos intentos de conexión desde ese cliente.

Si tiene muchas conexiones desde muchas direcciones IP de clientes diferentes a las direcciones IP del servidor, es posible que se encuentre con limitaciones de la tabla de seguimiento de conexiones.

Verificar:

sysctl net.ipv4.netfilter.ip_conntrack_count
sysctl net.ipv4.netfilter.ip_conntrack_max

En todas las tuplas src ip / port y dest ip / port solo puede tener net.ipv4.netfilter.ip_conntrack_max en la tabla de seguimiento. Si se alcanza este límite, verá un mensaje en sus registros " nf_conntrack: tabla completa, descargando el paquete. & Quot; y el servidor no aceptará nuevas conexiones entrantes hasta que haya espacio en la tabla de seguimiento nuevamente.

Esta limitación puede afectarlo mucho antes de que se agoten los puertos efímeros.

En mi caso, ejecuté un script que programa los archivos repetidamente, mi producto realiza algunos cálculos y envía la respuesta al cliente, es decir, el cliente está realizando una llamada http repetitiva para obtener la respuesta de cada archivo. Cuando se programan aproximadamente 150 puertos de socket en mi servidor pasa al estado time_wait y se lanza una excepción en el cliente que abre una conexión http, es decir,

 Error : [Errno 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted

El resultado fue que mi aplicación se colgó. No sé si se puede haber subido el hilo en estado de espera o lo que sucedió, pero debo eliminar todos los procesos o reiniciar mi aplicación para que funcione de nuevo.

Intenté reducir el tiempo de espera a 30 segundos, ya que son 240 segundos de forma predeterminada, pero no funcionó.

Básicamente, el impacto general fue crítico, ya que hizo que mi aplicación no respondiera

parece que el servidor puede quedarse sin puertos para asignar conexiones entrantes (durante la duración de TIMED_WAITs existentes), un caso para un ataque de DOS.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top