2011-02-09 13 views
21

La máquina es RHEL 5.3 (kernel 2.6.18).¿Cómo puede tener una conexión TCP de regreso al mismo puerto?

Algunas veces me aviso netstat que mi aplicación tiene conexión, la conexión TCP establecida cuando Dirección local y Dirección de Asuntos Exteriores son los mismos.

Here mismo problema informado por otra persona también.

Los síntomas son los mismos que se describen en el enlace: el cliente se conecta al puerto X del servidor que se ejecuta localmente. Después de algún tiempo, netstat muestra que el cliente tiene conexión de 127.0.0.1:X a 127.0.0.1:X

¿Cómo es posible?

Edición 01

abierta simultánea está causando el problema (muchas gracias a Hasturkun). Puede verlo en classical TCP state diagram en la transición del estado SYN_SENT a SYNC_RECEIVED

+0

Los síntomas son los mismos que se describen en el enlace: el cliente se conecta al puerto X del servidor que se ejecuta localmente. Después de un tiempo, netstat muestra que el cliente tiene una conexión de 127.0.0.1:X a 127.0.0.1:X – dimba

Respuesta

17

Esto puede deberse a la conexión simultánea de TCP (mencionado on this post to LKML, ver también here).

Es posible que un programa bucle intente conectarse a un puerto dentro del rango de puerto local dinámico (que se puede ver en /proc/sys/net/ipv4/ip_local_port_range), para tener éxito mientras el servidor no está escuchando en ese puerto.

En un número suficientemente grande de intentos, el socket que se utiliza para conectar puede estar vinculado al mismo puerto al que se conecta, que se realiza correctamente debido a la conexión simultánea mencionada anteriormente. Ahora tiene mágicamente un cliente conectado a sí mismo

+0

+1 parece que esto puede ser la causa de mi problema – dimba

+0

De hecho, mi cliente intenta constantemente conectarse al servidor si el servidor no funciona. ¿Entonces la pregunta ahora cómo puedo prevenir tal situación? ¿Significa que el servidor debe usar puertos que no estén en/proc/sys/net/ipv4/ip_local_port_range range? – dimba

+0

@dimba: sí, hacer que el servidor escuche un puerto más bajo que el extremo inferior de ese rango evitará este problema por completo – Hasturkun

12

Una conexión TCP está identificada de forma exclusiva por esta tupla (local address, local port #, foreign address, foreign port #). No es necesario que local address y foreign address, o que los números de puerto sean diferentes (aunque eso sería extremadamente extraño). Pero hay como máximo 1 conexión TCP que tiene los mismos valores para una tupla determinada.

Cuando una computadora se conecta a sí misma, su dirección local y su dirección en el extranjero son casi siempre las mismas. Después de todo, el lado 'local' y el lado 'extranjero' son en realidad la misma computadora. De hecho, cuando esto sucede, su computadora debe mostrar dos conexiones que tienen las mismas direcciones "locales" y "extranjeras", pero números de puerto invertidos. Por ejemplo:

$ ssh localhost 

resultará en dos conexiones que ser algo como esto:

$ netstat -nA inet | fgrep :22 
Active Internet connections (w/o servers) 
Proto Recv-Q Send-Q Local Address  Foreign Address  State  
tcp  0  0 127.0.0.1:56039  127.0.0.1:22   ESTABLISHED 
tcp  0  0 127.0.0.1:22   127.0.0.1:56039  ESTABLISHED 

Como se puede ver, la dirección local y direcciones en el extranjero son los mismos, pero los números de puerto se invierten. La única tupla para esta conexión TCP es (127.0.0.1, 56039, 127.0.0.1, 22). No habrá otra conexión TCP que tenga estos mismos cuatro campos.

El hecho de que vea dos es porque su computadora está en ambos extremos de la conexión. Cada extremo tiene su propia visión de cuál es 'extranjero' y cuál es 'local'.

Incluso puede conectarse a usted mismo en el mismo puerto, y aunque esto no es una ocurrencia común, no está prohibido por la especificación. Aquí está un ejemplo de programa en Python que hacer esto:

import socket 
import time 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.bind(('127.0.0.1', 56443)) 
s.connect(('127.0.0.1', 56443)) 
time.sleep(30) 

Este código funciona porque de una manera en la que es posible abrir una conexión TCP es tener al otro lado de la conexión intente abrir uno con usted de forma simultánea . Esto se conoce como simultaneous SYN exchange, y la respuesta vinculada a StackOverflow describe de qué se trata.

También tengo un documento en using simultaneous SYN exchange to get through NAT, aunque en ese caso la fuente y el extranjero serían completamente diferentes.

+0

Entendido. ¿Pero cómo el cliente eventualmente abre el mismo puerto de servidor (ver enlace en la publicación)? El servidor de resultados no puede abrir su puerto de servidor como ya está en uso. – dimba

+0

AFAIK, no conecto intencionalmente desde el mismo puerto al mismo puerto – dimba

+0

@dimba - Ahora tengo un código que muestra cómo hacerlo realidad. Por qué alguien haría tal cosa es otra pregunta. Pero ciertamente es posible. – Omnifarious

Cuestiones relacionadas