Messages in this thread | | | Subject | [FIX] Re: connect() occasionally succeeds improperly to localhost port 1024-4999 | Date | Mon, 30 Aug 1999 00:06:55 -0700 | From | Craig Milo Rogers <> |
| |
>Sometimes a connect() to localhost will succeed even if >there is no process listening on the port. This happens when the >ephemeral local port selected by the kernel during the connect() >happens to be the same port you are trying to connect to. In effect, >you end up connecting to yourself.
The first generation of Internet programs (telnet, FTP, etc.) connect from a transient port to a well-known port, and won't see the problem you described. Programs that utilize fixed, unofficially-well-known server ports in the transient local port space are in for trouble when their clients and servers run on the same machine. Single-system peer-to-peer communication, with both parties using transient local ports, has unavoidable exposure to this problem.
Single-port self-connection is allowed by the TCP RFCs, as I recall, although it might be a discouraged practice by now. (Linux on hairy palmtops?... nah, I'd never suggest such a joke.) Rather than redesigning TCP, you could make your scanner program bind() itself to a port before connecting (a 1 line solution to your application, no kernel change needed). If you want to be extra safe, allocate your fixed port outside the transient local port range on your system (see /proc/sys/net/ipv4/ip_local_port_range).
As you suggest, the Linux socket/TCP code can be modified to avoid accidental self-connections. This can be done without interfering with intentional self-connection. The pertinent points are:
1) When connecting a socket that does not have a locally bound name (source TCP port),
2) and when the destination IP address is equivalent to the (implied) source IP address,
3) then avoid allocating a source port that's the same as the destination port.
An even simpler algorithm is the following:
1) When connecting a socket that does not have a locally bound name (source TCP port),
2) don't allocate a source TCP port that's the same as the socket's destination TCP port, regardless of destination address.
This involves a trivial change to ipv4/tcp_ipv4/tcp_v4_get_port() in linux-2.2.12 and linux-2.3.15. In the rover loop, before the "break;", add:
if (sk->dport == rover) goto next;
ipv6 probably needs a similar change, etc.; I haven't checked.
[TWIMC: when I connected to www.us.kernel.org tonight, the HTTP menus were two weeks out of date. Something's stuck. The FTP archive was OK, though.]
Craig Milo Rogers
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |