Search code examples
socketssshoperating-systemipc

Are two sockets not allowed to use the same port?


  1. When two processes on the same host communicate using network sockets, should their sockets use different ports?

    I think yes, because a socket is identified by IP address and port number. If the sockets of the processes use the same port, then it is impossible to distinguish between their sockets, correct?

    But a host can have multiple network interfaces, so multiple IP addresses. Can the multiple network interfaces on the same host share a port, so that two sockets share the same port?

  2. For example, SSH local port forwarding is specified by the option:

    -L [bind_address:]port:host:hostport
    

    and then a process (such as Firefox) on the local host (where the SSH client is running) attaches to port.

    • Does the SSH client create a new socket with port as the socket's port?

    • Does port belong to the socket of the SSH client, or to the socket of the process (e.g. Firefox), or both (i.e. both the socket of the SSH client and the socket of Firefox process use the same port port)?

The linked thread by the comment doesn't address my questions (at least directly).


Solution

  • You have to make distinction between TCP and UDP. TCP is connection oriented and UDP is not.

    When you want to receive anything you bind the socket typically to IN_ADDRANY and to a specific port. For TCP you would do a listen and for UDP a recfrom.

    The most specific thing will be used to match. Because you can bind to a specific Ip address as well. In that case an incoming message is checked for the destination IP address and port. If anyone is listening on that ip address and that port (recfrom or listen) then that socket will be used. If noone specific is found then IN_ADDRANY is used to find a match. If you always bind to IN_ADDRANY you can not have 2 UDP sockets doing a recfrom with a socket bind to the same port, nor can you have a listening TCP socket on the same port either.

    For UDP the discussion ends here.

    For TCP things are way more complex. You start of with a listening socket on port A. At that point there is only one socket on the system that uses the port A. Now a connection is established by a client that is connecting. The the listening socket is cloned in a servicing socket that is returned in accept. That socket is not in listening state!!!. But it is still using port A. Because it is not a listening socket TCP is not going to use it to match incoming connection requests, for this it uses listening sockets only. To match incoming data it uses the notion of a connection pair. Which is your own ip address, and port, in this case A, and the source ip address and port. These 4 parameters uniquely identify the connection which is very different to the answer above that seems to claim the socket is uniquely identified by 5 parameters, it really is the TCP connection that is identified by 4 parameters. So after a connection you basically have 2 sockets on your system that are both using port A. One listening socket and one servicing socket. The more connections are established the more servicing sockets will be allocated and the more sockets will be using the same port. Of course if connections are closed, then they disappear again.

    I hope this clarifies things a bit. Conclusion is that a TCP connection is identified by 4 parameters whereas a listening TCP socket is identified by only 2. TCP connections are totally isolated from eachother and of course also from the listening sockets, this one is only used to make the connection and processes the very first TCP SYN message.

    Sorry for the lengthy answer and for the complexity. It is really simple once you understand it.

    Does the SSH client create a new socket with port as the socket's port?

    no it does not, the client connects to a well known server port but uses an ephemeral port. Unless the clients binds the socket to a well known port as well, but this is not the normal case.

    Does port belong to the socket of the SSH client, or to the socket of the process (e.g. Firefox), or both (i.e. both the socket of the SSH client and the socket of Firefox process use the same port port)?

    the ephemeral port belongs to the client, the well known ssh port belongs to the server process.

    The TCP connection between server and client is identified by the socket pair. One end of the pair is on the client machine and the other end on the server machine.

    What other questions did I not address at this point ?