Multiple sessions from the same source port
Hi, I've a question on socket programming (I'm a bit rusty on this). I'm reading an article on NAT, which mentions a case where a client opens two sessions (to two distinct remote end-points), but from the same source ip:port. How is this possible? I thought every time a client program open a socket to a remote ip:port, the OS will automatically associate the local endpoint with a differrent port number? Regards, Verdi -- 10 GB Mailbox, 100 FreeSMS http://www.gmx.net/de/go/topmail +++ GMX - die erste Adresse f�r Mail, Message, More +++
On Tuesday 01 February 2005 03:47, Verdi March wrote:
Hi,
I've a question on socket programming (I'm a bit rusty on this).
I'm reading an article on NAT, which mentions a case where a client opens two sessions (to two distinct remote end-points), but from the same source ip:port.
How is this possible? I thought every time a client program open a socket to a remote ip:port, the OS will automatically associate the local endpoint with a differrent port number? I'm not sure of the context, but, in socket programming, the server "listens" on a known port. (for instance xinetd might listen on port 23 for telnet). When a connection is requested, the server then issues the accept(2) function, and a session is then established. The server can then reissue the listen(2). One of the parameters to listen is the number of backlogged connections. It is the accept(2) function that sets up the TCP connection on the server side. The connect(2) function sets up the request on the client side.
-- Jerry Feldman <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
Hi, Jerry Feldman wrote:
The connect(2) function sets up the request on the client side.
precisely this is where my confusion is. IIRC, at the client side, the OS will associate the session as a port (src_port). As Greg has mentioned in another post, at least one of src_ip, src_port, dst_ip, or dst_port must be unique. Does this mean the OS can assign the same src_ip:src_port to several sessions? Because I use netstat when I'm opening sessions from my box (src) to remote servers (dst), each session is assigned a different src_port. Regards, Verdi -- GMX im TV ... Die Gedanken sind frei ... Schon gesehen? Jetzt Spot online ansehen: http://www.gmx.net/de/go/tv-spot
On Tue, 1 Feb 2005 09:47:58 +0100 (MET), Verdi March <cincaipatron@gmx.net> wrote:
Hi,
I've a question on socket programming (I'm a bit rusty on this).
I'm reading an article on NAT, which mentions a case where a client opens two sessions (to two distinct remote end-points), but from the same source ip:port.
How is this possible? I thought every time a client program open a socket to a remote ip:port, the OS will automatically associate the local endpoint with a differrent port number?
Regards, Verdi
I don't know how to do it programatically, but it would not be a violation of tcp/ip. tcp/ip just requires that one of four values be unique: source host, source port dest host, dest port. If any one of those values is unique, then you have a diferent/unique socket. If they are the same, you have a conflict. I believe some of the socket hi-jacking code out there somehow takes advantage of this conflict. Greg -- Greg Freemyer
--- Greg Freemyer <greg.freemyer@gmail.com> wrote:
Hi,
I've a question on socket programming (I'm a bit rusty on this).
I'm reading an article on NAT, which mentions a case where a client opens two sessions (to two distinct remote end-points), but from the same source ip:port.
How is this possible? I thought every time a client program open a socket to a remote ip:port, the OS will automatically associate the local endpoint with a differrent
On Tue, 1 Feb 2005 09:47:58 +0100 (MET), Verdi March <cincaipatron@gmx.net> wrote: port number?
Admittedly I am no expert on this but is it possible that the remote host are joining a multicast session in which they belong to the same multicast group and even though your program connects to the router and send singlas using the same socket more then one machine picks up the signal. just a thought. George ______________________________________________________________________ Post your free ad now! http://personals.yahoo.ca
On Tuesday 01 February 2005 09:37, Greg Freemyer wrote:
On Tue, 1 Feb 2005 09:47:58 +0100 (MET), Verdi March
<cincaipatron@gmx.net> wrote:
Hi,
I've a question on socket programming (I'm a bit rusty on this).
I'm reading an article on NAT, which mentions a case where a client opens two sessions (to two distinct remote end-points), but from the same source ip:port.
How is this possible? I thought every time a client program open a socket to a remote ip:port, the OS will automatically associate the local endpoint with a differrent port number?
Regards, Verdi
I don't know how to do it programatically, but it would not be a violation of tcp/ip.
tcp/ip just requires that one of four values be unique:
source host, source port dest host, dest port.
If any one of those values is unique, then you have a diferent/unique socket.
If they are the same, you have a conflict. I believe some of the socket hi-jacking code out there somehow takes advantage of this conflict. Take a case where there are two users of a system, each establishes a telnet connection to the same host at the same time. In this case, all 4 are the same. When the server, establishes the session, a new pair of ports is set up. So, the actual TCP connection uses a unique port number. It is the initial connection that uses a common port number.
In the case of UDP, it is a bit different since a 2-way connection is not established. The server only needs to wait for data on the socket, and process them when they come in from various hosts. The difference is that TCP establishes a virtual circuit, and guarantees that all data will arrive in tact and in the correct order (even if packets are received out of order). The send(2) or recv(2) functions will return an error value (eg. -1) on error. With UDP, the only real error checking is in the single packet itself. If a packet is lost somewhere the UDP stack will not report it. -- Jerry Feldman <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
Jerry Feldman wrote:
In the case of UDP, it is a bit different since a 2-way connection is not established. The server only needs to wait for data on the socket, and process them when they come in from various hosts.
Now that you mention UDP, the article is on NAT and P2P applications and discusses techniques to go through NAT using UDP. Perhaps the sender can open a UDP port and send to different dst_ip:dst_port from the same UDP src_port? What about TCP session? The article does not mention that it is with TCP, but it implies that the scenario (same src_ip:src_port for 2 sessions to 2 different remote IP) it can be done too with TCP. Regards, Verdi -- GMX im TV ... Die Gedanken sind frei ... Schon gesehen? Jetzt Spot online ansehen: http://www.gmx.net/de/go/tv-spot
On Wednesday 02 February 2005 01:30, Verdi March wrote:
Now that you mention UDP, the article is on NAT and P2P applications and discusses techniques to go through NAT using UDP. Perhaps the sender can open a UDP port and send to different dst_ip:dst_port from the same UDP src_port? UDP is a datagram protocol. It does not matter because their is no connection between the sender and receiver. The sender sends the message. Once it leaves the buffer, the sender does not care. The receiver knows who sent the message. It's like sending a snail mail, except that if it is not delivered, it is simply trashed.
What about TCP session? The article does not mention that it is with TCP, but it implies that the scenario (same src_ip:src_port for 2 sessions to 2 different remote IP) it can be done too with TCP. As I mentioned, with TCP, there is a server who listens on a specific port/IP. The client issues a connect. When the server accepts the connection, a new port is established. The client, only sends on the known port, but it is waiting on a port assigned by the OS.
Here is the sequence: Server Client Client2 on same host. Listen on port 23 Connect on port 23 (wait on port 7899). Connect on port 23 (wait on port 7900). Accept assigned to port 8543) Connect returns 0 (success) At this point, the Server is receiving on port 8543 and sending on port 7899. The client is sending on port 8543 and receiving on port 7899. Accept assigned to port 8544) Connect returns 0 (success) At this point, the Server is receiving on port 8544 and sending on port 7900. The client is sending on port 8544 and receiving on port 7900. On the server side, when the server issues accept(2) there is a unique port for both the client and server. Let's say the client computer is an SMP and the connects are issued at the exact same time. The OS will still assign unique port numbers on the client side. -------- Multicast is a bit more complex, but does fit the above model. -- Jerry Feldman <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
As I mentioned, with TCP, there is a server who listens on a specific port/IP. The client issues a connect. When the server accepts the connection, a new port is established. The client, only sends on the known port, but it is waiting on a port assigned by the OS.
Here is the sequence: Server Client Client2 on same host. Listen on port 23 Connect on port 23 (wait on port 7899). Connect on port 23 (wait on port 7900). Accept assigned to port 8543) Connect returns 0 (success) At this point, the Server is receiving on port 8543 and sending on port 7899. The client is sending on port 8543 and receiving on port 7899.
Accept assigned to port 8544) Connect returns 0 (success) At this point, the Server is receiving on port 8544 and sending on port 7900. The client is sending on port 8544 and receiving on port 7900.
On the server side, when the server issues accept(2) there is a unique port for both the client and server. Let's say the client computer is an SMP and the connects are issued at the exact same time. The OS will still assign unique port numbers on the client side.
This is not true. The source port is assigned by the kernel, and the destination port is programatically set by the server. They do not change after a connect()/accept(). Take a look at netstat or tcpdump output. There are _applications_ that do work like this, like ftp. But, by some reason, they teach that every tcp connection works this way in the university. []s Davi de Castro Reis
This is not true. The source port is assigned by the kernel, and the destination port is programatically set by the server. They do not change after a connect()/accept(). Take a look at netstat or tcpdump output. There are _applications_ that do work like this, like ftp. But, by some reason, they teach that every tcp connection works this way in the university. That is what I said. I think you are confused. First, the client chooses the destination IP address and the destination
On Wednesday 02 February 2005 09:48, Davi de Castro Reis wrote: port. The Server chooses the the port on which it listens. So, for the client, the destination port (eg. for telnet is 23) and the source port is assigned by the kernel. On the server side, the accept system call creates a new socket, and the source and destination port are both assigned by the kernel. Since the listen socket is bound (see bind(2)) to the original port, the new socket created by the accept(2) call on the server side. It uses a new port assigned by the kernel as its receiving port, and uses the client's source port that was assigned by the client's kernel. In the case where a NAT is involved, there is a translation of the ip address and port on the NAT's LAN. -- Jerry Feldman <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
Jerry Feldman wrote:
On Wednesday 02 February 2005 09:48, Davi de Castro Reis wrote:
This is not true. The source port is assigned by the kernel, and the destination port is programatically set by the server. They do not change after a connect()/accept(). Take a look at netstat or tcpdump output. There are _applications_ that do work like this, like ftp. But, by some reason, they teach that every tcp connection works this way in the university.
That is what I said. I think you are confused.
Hum. Sorry. Maybe we are saying the same thing. But I couldn't really get it from your previous schematics. Let us check it out.
First, the client chooses the destination IP address and the destination port. The Server chooses the the port on which it listens.
Ok.
So, for the client, the destination port (eg. for telnet is 23) and the source port is assigned by the kernel. On the server side, the accept system call creates a new socket,
Yes.
and the source and destination port are both assigned by the kernel.
No. The destination (the server port) is the same of the original socket.
Since the listen socket is bound (see bind(2)) to the original port, the new socket created by the accept(2) call on the server side. It uses a new port assigned by the kernel as its receiving port,
No new port. The port is the same of the socket you called listen(2) at. and uses the client's source
port that was assigned by the client's kernel.
Yes. That is correct. In the whole process, there are only two ports involved. One given by the kernel (client), the other programatically set by the server. C code for simple server and simple client in the end of the message. []s Davi de Castro Reis //Server code #include <sys/types.h> #include <sys/socket.h> #include <assert.h> #include <stdio.h> #include <netinet/in.h> #include <netinet/tcp.h> #include <unistd.h> int main(int argc, char **argv) { int c = 0; struct sockaddr_in addr; struct sockaddr_in newaddr; socklen_t newaddr_len; struct in_addr ip; int s = socket(PF_INET, SOCK_STREAM, 0); memset(&ip, 0, sizeof(ip)); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr = ip; addr.sin_port = htons(1025); c = bind(s, (struct sockaddr *)(&addr), sizeof(addr)); assert(c != -1); c = listen(s, 1); assert(c != -1); c = accept(s, (struct sockaddr *)(&newaddr), &newaddr_len); //Check port assigned by the kernel in the client side fprintf(stderr, "Client port: %u\n", ntohs(newaddr.sin_port)); sleep(100); return 0; } //Client code #include <sys/types.h> #include <sys/socket.h> #include <assert.h> #include <stdio.h> #include <netinet/in.h> #include <netinet/tcp.h> #include <unistd.h> int main(int argc, char **argv) { int c = 0; struct sockaddr_in addr; struct in_addr ip; int s = socket(PF_INET, SOCK_STREAM, 0); memset(&ip, 0, sizeof(ip)); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr = ip; addr.sin_port = htons(1025); c = connect(s, (struct sockaddr *)&addr, sizeof(addr)); assert(c != -1); //Port programatically set by the server fprintf(stderr, "Server port: %u\n", ntohs(addr.sin_port)); sleep(100); return 0; }
On Wednesday 02 February 2005 12:52, Davi de Castro Reis wrote:
No new port. The port is the same of the socket you called listen(2) at.
and uses the client's source
port that was assigned by the client's kernel.
Yes. That is correct.
In the whole process, there are only two ports involved. One given by the kernel (client), the other programatically set by the server. C code for simple server and simple client in the end of the message.
[]s Davi de Castro Reis
//Server code
c = accept(s, (struct sockaddr *)(&newaddr), &newaddr_len);
//Check port assigned by the kernel in the client side fprintf(stderr, "Client port: %u\n", ntohs(newaddr.sin_port));
//Client code
c = connect(s, (struct sockaddr *)&addr, sizeof(addr));
fprintf(stderr, "Server port: %u\n", ntohs(addr.sin_port));
Server port: 1025 -- This is because this is from the structure you set up. Client port: 35609 -- This is the port assigned by the kernel. Take a look at the actual packets. You will see in the packet, an IP address and a port address. I don't have the time today since I have a 4 hour meeting in 5 minutes. -- Jerry Feldman <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
In my last messages I described TCP and UDP, but left out NAT. Client<--->NAT<--->Network<--->Server. In this case, the client sends a packet with a local IP, assigned port number, a remote IP and a known port number. The NAT simply substitutes the local IP with the WAN IP. It also needs to remember the client's port number, so that when the server responds, it knows where to send the packet. The server only sees the WAN IP address and the unique port number on the NAT. So, in a very simple sense, the NAT sets up a table: Client IP client port NAT port. 192.168.1.12 7499 10945 So, when the router receives an inbound packet with port #10945, it translates that to port #7499, and changes the IP to 192.168.1.12, and sends the packet to the internal LAN. Additionally, if you have a server behind a NAT (or firewall), the NAT or firewall forwards those ports when it receives an inbound packet. -- Jerry Feldman <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
Verdi March wrote:
Jerry Feldman wrote:
In the case of UDP, it is a bit different since a 2-way connection is
not
established. The server only needs to wait for data on the socket, and process them when they come in from various hosts.
Now that you mention UDP, the article is on NAT and P2P applications and discusses techniques to go through NAT using UDP. Perhaps the sender can open a UDP port and send to different dst_ip:dst_port from the same UDP src_port?
This is perfectly possible. Just look at the sendto(3) call.
What about TCP session? The article does not mention that it is with TCP, but it implies that the scenario (same src_ip:src_port for 2 sessions to 2 different remote IP) it can be done too with TCP.
As people said, as long as the one of src_ip:src_port/dst_ip:dst_port if different, it is ok. But and don't know any call at the sockets API where you can do it. Maybe it is possible with a lower level API. []s Davi de Castro Reis
After some research, I stand corrected. The port remains as the listen port. The server is able to distinguish connections from the client IP address and port number. (It's been a while since I have actually had to get into the basics of IP packets). -- Jerry Feldman <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
So, let me correct my diagram. As I mentioned, with TCP, there is a server who listens on a specific port/IP. The client issues a connect. When the server accepts the connection, a new port is established. The client, only sends on the known port, but it is waiting on a port assigned by the OS. Here is the sequence: Server Client Listen on port 23 Connect on port 23 (wait port 7899). Accept connection Connect returns 0 (success) Server may reissue listen. At this point, the Server is still receiving on port 23 and sending on port 7899. The client is sending on port 23 and receiving on port 7899. The reason the server can both listen and receive on the same port is that when the connection is accepted by the kernel, the kernel adds it to the TCP table as an established connection assocated with a client ip/port. Many times, a new process (or thread) is created at the server: // Server is in a tight loop listening on some port. In this case, the accept is embedded in the child, but it can also be in the parent before the fork(). The thread paradigm also works. while(1) { rv = listen(s, 10); if (rv == -1) { // handle error } else { child = fork(); if (child == -1) { // handle error } else if (child != 0) { // parent continue; // Continue loop } else { // child process news = accept(s, (struct sockaddr *)(&newaddr), &newaddr_len); close(s); // process receives and sends close(news); return 0; // exit child process } } } // parent -- Jerry Feldman <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
Hi, many thanks to all who have replied. So let me just summarize all these. The responds (particularly Jerry and Davi) describes that case where given a server with two open sessions (from two different clients), the dst_ip and dst_port (belong to the server) are the same. Now, if we 'reverse' the case (which was what I'm interested initially, so my original question fails to put across this intention), the case become: a client have 2 TCP sessions to two different servers. In both sessions, src_port (at client) are obtained/assigned through "connect" and both are assigned the same src_port. The respond to this, so far, is that it is possible but probably not using the BSD socket API. Regards, Verdi -- Sparen beginnt mit GMX DSL: http://www.gmx.net/de/go/dsl
On Thursday 03 February 2005 02:38, Verdi March wrote:
The responds (particularly Jerry and Davi) describes that case where given a server with two open sessions (from two different clients), the dst_ip and dst_port (belong to the server) are the same.
Now, if we 'reverse' the case (which was what I'm interested initially, so my original question fails to put across this intention), the case become: a client have 2 TCP sessions to two different servers. In both sessions, src_port (at client) are obtained/assigned through "connect" and both are assigned the same src_port. The respond to this, so far, is that it is possible but probably not using the BSD socket API. The only port that is not unique is the dst_port. The src_port is an ephemeral port assigned by the kernel. So, from the client side, there are 2 servers: 142.98.64.43.23 (where 23 is the server port on server 1) 198.98.58.29.23 (where 23 is the server port on server 2) The connect is sending there. So, in the case of a server sending to multiple hosts on the same port, the IP address is unique per host (dst_ip and dst_port). The src_ip is the client's IP address, and as mentioned, the src_prt is assigned by the kernel and is unique.
So, in both cases, you have a unique connection, even if the client for the 2 connections is the same physical process. In the case of multi-cast, the client is sending to a single multi-cast IP address. This works fine for UDP but not for TCP. -- Jerry Feldman <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
Greg Freemyer wrote:
I don't know how to do it programatically, but it would not be a violation of tcp/ip.
tcp/ip just requires that one of four values be unique:
source host, source port dest host, dest port.
If any one of those values is unique, then you have a diferent/unique socket.
Well, I'm not sure either how to programatically do this. The article I'm reading, is about NAT and P2P applications. When it discusses about "cone NAT", it describes how a machine (behind NAT) can have 2 sessions to 2 different dst_ip. The machine behind NAT uses the same src_ip:src_port for both sessions. Regards, Verdi -- Sparen beginnt mit GMX DSL: http://www.gmx.net/de/go/dsl
participants (5)
-
Davi de Castro Reis
-
George Stoianov
-
Greg Freemyer
-
Jerry Feldman
-
Verdi March