How does webserver handle multiple connections on the same port [duplicate] - node.js

This question already has answers here:
TCP: can two different sockets share a port?
(7 answers)
Closed 6 years ago.
TCP connection is defined by [client IP address:outgoing port - server IP address:incoming port]. Web server listens on one port but handles multiple tcp connections on the same port - how is that achieved? Is one connection somehow transferred to other incoming port to be able to listen to new connection?

Even if the server IP and server port are the same, the client IP or client port are different. So there is no problem, from the TCP point of view.
If you want more details, in the server code there is a socket destined to accept connections, that will be the listening socket and it will be bound to the server port (and optionally to the IP). When a client connects to this port the listening socket accepts it and a new connected socket is returned.
Even if all the server sockets use the same port, only one of them is actually listening, so there is no problem.

Related

Node.js sending data to already started socket connection

I have a Server socket and a device which uses TCP long-connection mode.
They can connect and exchange data together. The node.js server is something like this:
net.createServer(function (socket) {
console.log('ip:port' + socket.remoteAddress +':'+ socket.remotePort);
socket.on('data', console.log);
}).listen(‘0.0.0.0’, 8888);
The device connects just right and I'm able to receive data from it.
I can send commands to it by using the same process, by just doing socket.write('dothisplease') and this works too.
Now I have another worker process which should be sending commands at regular intervals. I can get ip and port from console.log when the device connects, it looks like: xx.xxx.xx.xxx:63024
I tried using this combination ip:port to create new connection:
var client = new net.Socket();
client.connect(device_port, device_ip, function () {
client.write('dothisplease');
});
... but the result was ECONNREFUSED
Is it right to use the same port to create a second connection to the device?
Why does it work from the same process, but does not work from another?
Eventually, can I pass the socket to another node Worker process. How?
Thanks a lot!
Your server is listening on port 8888. That's the port that all clients need to connect to. The client will also have to know what the server's IP address is in order to connect to it. A client uses a target IP address and target port to specify the destination for a TCP connection.
socket.remotePort is not the port that anyone can connect on. That is the outgoing port that the first client used to connect to your server port. The outgoing port is a client bookkeeping thing that helps the client keep track of which network traffic belongs to which socket and is usually randomly assigned by the client.
You read more about what remotePort is here.
For reference, a TCP connection consists of two endpoints and each endpoint has an IP address and a port. The server will need to have a known IP address and a known port that all clients will use in order to connect to it. The client will already have its own IP address. Then, during the process of making a TCP connection to a server, the client will dynamically allocate an unused port number for the communication for this socket. That port number is used by the client to keep track of which network traffic belongs to which socket. This is not a port number that anyone can connect to.
Is it right to use the same port to create a second connection to the device?
No. You can't create a connection to a client. You can only create a connection to a listening server. And, you couldn't use the client's port that belongs to that other socket either.

How does OS route TCP packets of an established connection

I'm confused about how TCP packets are routed on the OS level after TCP connection has been established.
Suppose a sever is listening passively on a TCP port for incoming traffic. The server receives a connection request, accepts it, and created a socket for source_ip:port and destination_ip:port, e.g. (x.x.x.x:9999, 127.0.0.1:8080).
How are subsequent packets sent from x.x.x.x:9999 to 127.0.0.1:8080 routed on the server? Does the OS route them to the process binding port 8080, which in turn routes them to file descriptor with source x.x.x.x:9999? If yes, does this mean that each application much implement logic to route packets of established connections to the appropriate file descriptor?
Or does the OS route them directly to the open socket? If yes, how does the OS know which socket to route to since incoming request use well known port number (8080 in this case)?

What is the difference between net.createServer() and net.createConnection()?

I am trying to create a simplistic TCP client and server. Conceptually, I know that a TCP socket is the same on both the client and server side (at least, this is how it is in python). However, the steps after creating a socket are different. Ie, for clients, the socket establishes a TCP connection to the server. On the server side, the socket is bound to a specific port, and waits for connections, and when it gets a req, it creates a new connected socket. (correct me if I got anything wrong, I'm new to networking).
My question is if there's any difference between the net.Socket and net.Server classes. Did node.js separate the two, and net.Server is explicitly meant for servers? Is it still possible to use net.Socket to make the TCP server socket?
What is the difference between net.createServer() and net.createConnection()?
net.createConnection() initiates an outbound TCP connection to some other host or server.
net.createServer() sets up a server that will accept incoming TCP connections from other hosts or processes.
These are opposite ends of enabling a connection.
My question is if there's any difference between the net.Socket and net.Server classes.
Yes, there's a huge difference between them as neither is a substitute for the other. A server listens for inbound connections.
A client then creates a TCP socket and attempts to connect to a server that is listening for inbound connections on the port and IP address that the server is listening on. During the connection process, the server follows the TCP handshake process to enable the creation of a TCP socket that connects the client and server. That TCP socket is then bidirectional so either end can then send data to the other.
Nodejs uses the net.Socket class as the nodejs object to represent a TCP socket so when you initiate a connection from a client, you get a net.Socket object that represents your TCP connection to some other server. When you are a server and someone connects to you, you get a net.Socket object that represents your TCP connection to the client that connected to you. Those two objects are different ends of a TCP connection and both ends do not have to be nodejs endpoints - they can be any language or tool that can make a standard TCP connection.
Did node.js separate the two, and net.Server is explicitly meant for servers? Is it still possible to use net.Socket to make the TCP server socket?
Yes, net.Server is exclusively for servers to set up a listener for inbound connections on a specific port on your host.
net.socket by itself cannot listen to incoming connections (you use an instance on net.Server for that. It is either used to initiate a TCP connection to some server or it is created as part of of some client connecting to your server.

Understanding Client Server Connections [duplicate]

This question already has answers here:
Does the port change when a server accepts a TCP connection?
(3 answers)
Closed 4 years ago.
I understand the basics of how ports work. However, what I don't get is how multiple clients can simultaneously connect to say port 80. I know each client has a unique (for their machine) port. Does the server reply back from an available port to the client, and simply state the reply came from 80? How does this work?
First off, a "port" is just a number. All a "connection to a port" really represents is a packet which has that number specified in its "destination port" header field.
Now, there are two answers to your question, one for stateful protocols and one for stateless protocols.
For a stateless protocol (ie UDP), there is no problem because "connections" don't exist - multiple people can send packets to the same port, and their packets will arrive in whatever sequence. Nobody is ever in the "connected" state.
For a stateful protocol (like TCP), a connection is identified by a 4-tuple consisting of source and destination ports and source and destination IP addresses. So, if two different machines connect to the same port on a third machine, there are two distinct connections because the source IPs differ. If the same machine (or two behind NAT or otherwise sharing the same IP address) connects twice to a single remote end, the connections are differentiated by source port (which is generally a random high-numbered port).
Simply, if I connect to the same web server twice from my client, the two connections will have different source ports from my perspective and destination ports from the web server's. So there is no ambiguity, even though both connections have the same source and destination IP addresses.
Ports are a way to multiplex IP addresses so that different applications can listen on the same IP address/protocol pair. Unless an application defines its own higher-level protocol, there is no way to multiplex a port. If two connections using the same protocol simultaneously have identical source and destination IPs and identical source and destination ports, they must be the same connection.
Important:
I'm sorry to say that the response from "Borealid" is imprecise and somewhat incorrect - firstly there is no relation to statefulness or statelessness to answer this question, and most importantly the definition of the tuple for a socket is incorrect.
First remember below two rules:
Primary key of a socket: A socket is identified by {SRC-IP, SRC-PORT, DEST-IP, DEST-PORT, PROTOCOL} not by {SRC-IP, SRC-PORT, DEST-IP, DEST-PORT} - Protocol is an important part of a socket's definition.
OS Process & Socket mapping: A process can be associated with (can open/can listen to) multiple sockets which might be obvious to many readers.
Example 1: Two clients connecting to same server port means: socket1 {SRC-A, 100, DEST-X,80, TCP} and socket2{SRC-B, 100, DEST-X,80, TCP}. This means host A connects to server X's port 80 and another host B also connects to the same server X to the same port 80. Now, how the server handles these two sockets depends on if the server is single-threaded or multiple-threaded (I'll explain this later). What is important is that one server can listen to multiple sockets simultaneously.
To answer the original question of the post:
Irrespective of stateful or stateless protocols, two clients can connect to the same server port because for each client we can assign a different socket (as the client IP will definitely differ). The same client can also have two sockets connecting to the same server port - since such sockets differ by SRC-PORT. With all fairness, "Borealid" essentially mentioned the same correct answer but the reference to state-less/full was kind of unnecessary/confusing.
To answer the second part of the question on how a server knows which socket to answer. First understand that for a single server process that is listening to the same port, there could be more than one socket (maybe from the same client or from different clients). Now as long as a server knows which request is associated with which socket, it can always respond to the appropriate client using the same socket. Thus a server never needs to open another port in its own node than the original one on which the client initially tried to connect. If any server allocates different server ports after a socket is bound, then in my opinion the server is wasting its resource and it must be needing the client to connect again to the new port assigned.
A bit more for completeness:
Example 2: It's a very interesting question: "can two different processes on a server listen to the same port". If you do not consider protocol as one of the parameters defining sockets then the answer is no. This is so because we can say that in such a case, a single client trying to connect to a server port will not have any mechanism to mention which of the two listening processes the client intends to connect to. This is the same theme asserted by rule (2). However, this is the WRONG answer because 'protocol' is also a part of the socket definition. Thus two processes in the same node can listen to the same port only if they are using different protocols. For example, two unrelated clients (say one is using TCP and another is using UDP) can connect and communicate to the same server node and to the same port but they must be served by two different server processes.
Server Types - single & multiple:
When a server processes listening to a port that means multiple sockets can simultaneously connect and communicate with the same server process. If a server uses only a single child process to serve all the sockets then the server is called single-process/threaded and if the server uses many sub-processes to serve each socket by one sub-process then the server is called a multi-process/threaded server. Note that irrespective of the server's type a server can/should always use the same initial socket to respond back (no need to allocate another server port).
Suggested Books and the rest of the two volumes if you can.
A Note on Parent/Child Process (in response to query/comment of 'Ioan Alexandru Cucu')
Wherever I mentioned any concept in relation to two processes say A and B, consider that they are not related by the parent-child relationship. OS's (especially UNIX) by design allows a child process to inherit all File-descriptors (FD) from parents. Thus all the sockets (in UNIX like OS are also part of FD) that process A listening to can be listened to by many more processes A1, A2, .. as long as they are related by parent-child relation to A. But an independent process B (i.e. having no parent-child relation to A) cannot listen to the same socket. In addition, also note that this rule of disallowing two independent processes to listen to the same socket lies on an OS (or its network libraries), and by far it's obeyed by most OS's. However, one can create own OS which can very well violate this restriction.
TCP / HTTP Listening On Ports: How Can Many Users Share the Same Port
So, what happens when a server listen for incoming connections on a TCP port? For example, let's say you have a web-server on port 80. Let's assume that your computer has the public IP address of 24.14.181.229 and the person that tries to connect to you has IP address 10.1.2.3. This person can connect to you by opening a TCP socket to 24.14.181.229:80. Simple enough.
Intuitively (and wrongly), most people assume that it looks something like this:
Local Computer | Remote Computer
--------------------------------
<local_ip>:80 | <foreign_ip>:80
^^ not actually what happens, but this is the conceptual model a lot of people have in mind.
This is intuitive, because from the standpoint of the client, he has an IP address, and connects to a server at IP:PORT. Since the client connects to port 80, then his port must be 80 too? This is a sensible thing to think, but actually not what happens. If that were to be correct, we could only serve one user per foreign IP address. Once a remote computer connects, then he would hog the port 80 to port 80 connection, and no one else could connect.
Three things must be understood:
1.) On a server, a process is listening on a port. Once it gets a connection, it hands it off to another thread. The communication never hogs the listening port.
2.) Connections are uniquely identified by the OS by the following 5-tuple: (local-IP, local-port, remote-IP, remote-port, protocol). If any element in the tuple is different, then this is a completely independent connection.
3.) When a client connects to a server, it picks a random, unused high-order source port. This way, a single client can have up to ~64k connections to the server for the same destination port.
So, this is really what gets created when a client connects to a server:
Local Computer | Remote Computer | Role
-----------------------------------------------------------
0.0.0.0:80 | <none> | LISTENING
127.0.0.1:80 | 10.1.2.3:<random_port> | ESTABLISHED
Looking at What Actually Happens
First, let's use netstat to see what is happening on this computer. We will use port 500 instead of 80 (because a whole bunch of stuff is happening on port 80 as it is a common port, but functionally it does not make a difference).
netstat -atnp | grep -i ":500 "
As expected, the output is blank. Now let's start a web server:
sudo python3 -m http.server 500
Now, here is the output of running netstat again:
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:500 0.0.0.0:* LISTEN -
So now there is one process that is actively listening (State: LISTEN) on port 500. The local address is 0.0.0.0, which is code for "listening for all". An easy mistake to make is to listen on address 127.0.0.1, which will only accept connections from the current computer. So this is not a connection, this just means that a process requested to bind() to port IP, and that process is responsible for handling all connections to that port. This hints to the limitation that there can only be one process per computer listening on a port (there are ways to get around that using multiplexing, but this is a much more complicated topic). If a web-server is listening on port 80, it cannot share that port with other web-servers.
So now, let's connect a user to our machine:
quicknet -m tcp -t localhost:500 -p Test payload.
This is a simple script (https://github.com/grokit/dcore/tree/master/apps/quicknet) that opens a TCP socket, sends the payload ("Test payload." in this case), waits a few seconds and disconnects. Doing netstat again while this is happening displays the following:
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:500 0.0.0.0:* LISTEN -
tcp 0 0 192.168.1.10:500 192.168.1.13:54240 ESTABLISHED -
If you connect with another client and do netstat again, you will see the following:
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:500 0.0.0.0:* LISTEN -
tcp 0 0 192.168.1.10:500 192.168.1.13:26813 ESTABLISHED -
... that is, the client used another random port for the connection. So there is never confusion between the IP addresses.
Normally, for every connecting client the server forks a child process that communicates with the client (TCP). The parent server hands off to the child process an established socket that communicates back to the client.
When you send the data to a socket from your child server, the TCP stack in the OS creates a packet going back to the client and sets the "from port" to 80.
Multiple clients can connect to the same port (say 80) on the server because on the server side, after creating a socket and binding (setting local IP and port) listen is called on the socket which tells the OS to accept incoming connections.
When a client tries to connect to server on port 80, the accept call is invoked on the server socket. This creates a new socket for the client trying to connect and similarly new sockets will be created for subsequent clients using same port 80.
Words in italics are system calls.
Ref
http://www.scs.stanford.edu/07wi-cs244b/refs/net2.pdf

TCP/IP basics: Destination port relevance

Ok this is kind of embarassing but I just have a rather "noob" question.
In a client server TCP communications, where my system is a client accessing a remote server at say Port XX, isnt the client opening a random port YY in its system to talk to remote port XX?
So when we code we do specify the destination port XX right?
For the client, the port YY itself is chosen when the socket is created, isnt it?
Is there anyway I could monitor/restrict/control any client talking to a particular server?(like say clients talking to servers at specific serving ports??)
Is there any IPTABLE rule or some firewall rule restricting the client?
Can this be done at all??
Are destination ports saved in the socket structures? If so where??
Thanks!
First, server side creates a listening socket, with the chain of socket(2), bind(2), and listen(2) calls, then waits for incoming client connection requests with the accept(2) call. Once a client connects (socket(2) and then connect(2) on the client side) and the TCP/IP stacks of the client and the server machines complete the three way handshake, the accept(2) returns new socket descriptor - that's the server's end of the connected socket. Both bind(2) on the server side, and connect(2) on the client side take server's address and port.
Now, the full TCP connection is described by four numbers - server address, server port, client address, and client port. The first two must obviously be known to the client prior to the connection attempt (otherwise, where do we go?). The client address and port, while could be specified explicitly with the bind(2), are usually assigned dynamically - the address is the IP address of the outgoing network interface, as determined by the routing table, and the port selected out of range of ephemeral ports.
The netstat(8) command shows you established connections. Adding -a flag lets you see listening sockets, -n flag disables DNS and service resolution, so you just see numeric addresses and ports.
Linux iptables(8) allows you to restrict where clients are allowed to connect to. You can restrict based on source and destination ports, addresses, and more.
You can get socket local binding with getsockname(2) call, remote binding is given by getpeername(2).
Hope this makes it a bit more clear.
Yes you can create a firewall rule to prevent outbound TCP connections to port XX. For example, some organizations prevent outbound TCP port 25, to prevent spam being sent from network PCs to remote SMTP servers.

Resources