The UDP ASSOCIATE request is used to establish an association within
the UDP relay process to handle UDP datagrams. The DST.ADDR and
DST.PORT fields contain the address and port that the client expects
to use to send UDP datagrams on for the association. The server MAY
use this information to limit access to the association. If the
client is not in possesion of the information at the time of the UDP
ASSOCIATE, the client MUST use a port number and address of all
zeros.
From RFC 1928, I interpret the text as that the DST.ADDR and DST.PORT is only useful for limiting access to the association(I take limiting access as preventing sending UDP through the association),this makes sense to me.
By following the RFC, I already implemented client -> proxy -> remote for UDP relay.
Now the confusion I am having is how to implement remote -> proxy -> client, WHAT port to listen for remote packets and WHAT port of the client to forward the packets to? The RFC does not states this clearly.
Related
My understanding is that a socket corresponds to a network identifier, port and TCP identifier. [1]
Operating systems enable a process to be associated with a port (which IIUC is a way of making the process addressable on the network for inbound data).
So a WebSocket server will typically be associated with a port well-known for accepting and understanding HTTP for the upgrade request (like 443) and then use TCP identifiers to enable multiple network sockets to be open concurrently for a single server process and a single port.
Please can someone confirm or correct my understanding?
[1] "To provide for unique names at
each TCP, we concatenate a NETWORK identifier, and a TCP identifier
with a port name to create a SOCKET name which will be unique
throughout all networks connected together." https://www.rfc-editor.org/rfc/rfc675
When a client connects to your server on a given port, the client connection is coming from an IP address and a client-side port number. The client-side port number is automatically generated by the client and will be unique for that client. So, you end up with four items that make a connection.
Server IP address (well known to all clients)
Server port (well known to all clients)
Client IP address (unique for that client)
Client port (dynamically unique for that client and that socket)
So, it is the combination of these four items that make a unique TCP connection. If the same client makes a second connection to the same server and port, then that second connection will have a different client port number (each connection a client makes will be given a different client port number) and thus the combination of those four items above will be different for that second client connection, allowing it's traffic to be completely separate from the first connection that client made.
So, a TCP socket is a unique combination of the four items above. To see how that is used, let's look at how some traffic flows.
After a client connects to the server and a TCP socket is created to represent that connection, then the client sends a packet. The packet is sent from the client IP address and from the unique client port number that that particular socket is using. When the server receives that packet on its own port number, it can see that the packet is coming from the client IP address and from that particular client port number. It can use these items to look up in its table and see which TCP socket this traffic is associated with and trigger an event for that particular socket. This separates that client's traffic from all the other currently connected sockets (whether they are other connections from that same client or connections from other clients).
Now, the server wants to send a response to that client. The packet is sent to the client's IP address and client port number. The client TCP stack does the same thing. It receives the packet from the server IP/port and addressed to the specific client port number and can then associate that packet with the appropriate TCP socket on the client so it can trigger an event on the right socket.
All traffic can uniquely be associated with the appropriate client or server TCP socket in this way, even though many clients may connect to the same server IP and port. The uniqueness of the client IP/port allows both ends to tell which socket a given packet belongs to.
webSocket connections start out with an HTTP connection (which is a TCP socket running the HTTP protocol). That initial HTTP request contains an "upgrade" header requesting the server to upgrade the protocol from HTTP to webSocket. If the server agrees to the upgrade, then it returns a response that indicates that the protocol will be changed to the webSocket protocol. The TCP socket remains the same, but both sides agree that they will now speak the webSocket protocol instead of the HTTP protocol. So, once connected, you then have a TCP socket where both sides are speaking the webSocket protocol. This TCP connection uses the same logic described above to remain unique from other TCP connections to the same server.
In this manner, you can have a single server on a single port that works for both HTTP connections and webSocket connections. All connections to that server start out as HTTP connections, but some are converted to webSocket connections after both sides agree to change the protocol. The HTTP connections that remain HTTP connections will be typical request/response and then the socket will be closed. The HTTP connections that are "upgraded" to the webSocket protocol will remain open for the duration of the webSocket session (which can be long lived). You can have many concurrent open webSocket connections that are all distinct from one another while new HTTP connections are regularly serviced all by the same server. The TCP logic above is used to keep track of which packets to/from the same server/port belong to which connection.
FYI, you may have heard about NAT (Network Address Translation). This is commonly used to allow private networks (like a home or corporate network) to interface to a public network (like the internet). With NAT a server may see multiple clients as having the same client IP address even though they are physically different computers on a private network). With NAT, multiple computers are routed through a common IP address, but NAT still guarantees that the client IP address and client port number are still a unique combination so the above scheme still works. When using NAT an incoming packet destined for a particular client arrives at the shared IP address. The IP/port is then translated to the actual client IP address and port number on the private network and then packet is forwarded to that device. The server is generally unaware of this translation and packet forwarding. Because the NAT server still maintains the uniqueness of the client IP/client port combination, the server's logic still works just fine even though it appears that many clients are sharing a common IP address). Note, home network routes are usually configured to use NAT since all computers on the home network will "share" the one public IP address that your router has when accessing the internet.
You will not enable multiple sockets, there is no need for it. You will have multiple conections. It's a little different, but you undesrstand well. For UDP there's nothing to do, cause there is no connections.
In TCP, 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, the same machine cannot open 2 connections on the same port.
I am writing a UDP based client server and have got pretty much the code, but I am confused about how UDP server sends the response back to UDP client, this is my understanding till now:
Suppose a UDP client wants to communicate with a UDP server, so it will send a request to the UDP server (using the UDP socket opened at client's end), now this will reach the UDP module at the UDP server, where UDP module will identify the UDP service using the port number and will send that request to that UDP service/server.
Now, since UDP is a connection-less protocol so unlike TCP, UDP server will not send response over some connection, instead, UDP server will extract the source IP address and source port from the request and send the response back to client.
My confusion is that at server side, there is a socket which is bound to a UDP port and "continuously" listening for any UDP client request, but this is not true at client side, UDP client will open a socket to send the request to UDP server and then that's it, I think it cannot keep that port hanging for UDP server to respond, and if that port closes then how client will receive the response back.
I mean ofcourse, UDP server's response will reach back the UDP client because IP address is there, but once that response has reached UDP module of the client, even though there will be a port but how UDP module can send it to the client who originally sent the request because it would have closed the socket bound to that port? Or it will not?
I am looking for answer which clearly describes the UDP communication (I am not interested in contrasting it with TCP or explaining TCP since I have already fair understanding of TCP), especially how the response will reach back the UDP client.
My confusion is that at server side, there is a socket which is bound to a UDP port and "continuously" listening for any UDP client request, but this is not true at client side, UDP client will open a socket to send the request to UDP server and then that's it, I think it cannot keep that port hanging for UDP server to respond, and if that port closes then how client will receive the response back.
I agree. This is your confusion. Why do you think can't keep the socket open and do a receive on it? It can.
I mean ofcourse, UDP server's response will reach back the UDP client because IP address is there, but once that response has reached UDP module of the client, even though there will be a port but how UDP module can send it to the client who originally sent the request because it would have closed the socket bound to that port?
Why?
Or it will not?
Not.
The client:
creates a socket
sends a datagram
calls recvfrom() or friends to receive the response.
Of course if the client isn't interested in the response it can close the socket, but this is not the normal case.
I am looking for answer which clearly describes the UDP communication (I am not interested in contrasting it with TCP or explaining TCP since I have already fair understanding of TCP), especially how the response will reach back the UDP client.
So don't tag your question with the tcp tag.
Yes, UDP server can send back to client. Here is an example:
https://www.cs.rutgers.edu/~pxk/417/notes/sockets/udp.html and code demo https://www.cs.rutgers.edu/~pxk/417/notes/sockets/demo-udp-04.html
We now have a client sending a message to a server. What if the server wants to send a message back to that client? There is no connection so the server cannot just write the response back. Fortunately, the recvfrom call gave us the address of the server. It was placed in remaddr:
recvlen = recvfrom(s, buf, BUFSIZE, 0, (struct sockaddr *)&remaddr, &addrlen);
The server can use that address in sendto and send a message back to the recipient's address.
sendto(s, buf, strlen(buf), 0, (struct sockaddr *)&remaddr, addrlen)
The client uses some random but unique source port. The server sends the response back to this unique port. Server will never receive 2 request at a time from single port. Server uses this fact to map response to request. Only after receiving the response, client closes this source port/ socket. The client can send as much request as the count of ports available for its disposal at any given point of time. Since the port is closed as soon as the response is received, it becomes available again.
Reference: https://www.slashroot.in/how-does-udp-work
Usually a web server is listening to any incoming connection through port 80. So, my question is that shouldn't it be that in general concept of socket programming is that port 80 is for listen for incoming connection. But then after the server accepted the connection, it will use another port e.g port 12345 to communicate with the client. But, when I look into the wireshark, the server is always using port 80 during the communication. I am confused here.
So what if https://www.facebook.com:443, it has hundreds of thousands of connection to the it at a second. Is it possible for a single port to handle such a large amount of traffic?
A particular socket is uniquely identified by a 5-tuple (i.e. a list of 5 particular properties.) Those properties are:
Source IP Address
Destination IP Address
Source Port Number
Destination Port Number
Transport Protocol (usually TCP or UDP)
These parameters must be unique for sockets that are open at the same time. Where you're probably getting confused here is what happens on the client side vs. what happens on the server side in TCP. Regardless of the application protocol in question (HTTP, FTP, SMTP, whatever,) TCP behaves the same way.
When you open a socket on the client side, it will select a random high-number port for the new outgoing connection. This is required, otherwise you would be unable to open two separate sockets on the same computer to the same server. Since it's entirely reasonable to want to do that (and it's very common in the case of web servers, such as having stackoverflow.com open in two separate tabs) and the 5-tuple for each socket must be unique, a random high-number port is used as the source port. However, each of those sockets will connect to port 80 at stackoverflow.com's webserver.
On the server side of things, stackoverflow.com can already distinguish between those two different sockets from your client, again, because they already have different client-side port numbers. When it sees an incoming request packet from your browser, it knows which of the sockets it has open with you to respond to because of the different source port number. Similarly, when it wants to send a response packet to you, it can send it to the correct endpoint on your side by setting the destination port number to the client-side port number it got the request from.
The bottom line is that it's unnecessary for each client connection to have a separate port number on the server's side because the server can already uniquely identify each client connection by its client IP address and client-side port number. This is the way TCP (and UDP) sockets work regardless of application-layer protocol.
shouldn't it be that in general concept of socket programming is that port 80 is for listen for incoming connection. But then after the server accepted the connection, it will use another port e.g port 12345 to communicate with the client.
No.
But, when I look into the wireshark, the server is always using port 80 during the communication.
Yes.
I am confused here.
Only because your 'general concept' isn't correct. An accepted socket uses the same local port as the listening socket.
So what if https://www.facebook.com:443, it has hundreds of thousands of connection to the it at a second. Is it possible for a single port to handle such a large amount of traffic?
A port is only a number. It isn't a physical thing. It isn't handling anything. TCP is identifying connections based on the tuple {source IP, source port, target IP, target port}. There's no problem as long as the entire tuple is unique.
Ports are a virtual concept, not a hardware ressource, it's no harder to handle 10 000 connection on 1 port than 1 connection each on 10 000 port (it's probably much faster even)
Not all servers are web servers listening on port 80, nor do all servers maintain lasting connections. Web servers in particular are stateless.
Your suggestion to open a new port for further communication is exactly what happens when using the FTP protocol, but as you have seen this is not necessary.
Ports are not a physical concept, they exist in a standardised form to allow multiple servers to be reachable on the same host without specialised multiplexing software. Such software does still exist, but for entirely different reasons (see: sshttp). What you see as a response from the server on port 80, the server sees as a reply to you on a not-so-random port the OS assigned your connection.
When a server listening socket accepts a TCP request in the first time ,the function such as Socket java.net.ServerSocket.accept() will return a new communication socket whoes port number is the same as the port from java.net.ServerSocket.ServerSocket(int port).
Here are the screen shots.
Usually we can set up a proxy server by some kind of tools such as CCProxy which provides proxy services for HTTP, SOCKS, FTP packets etc.
Also, Proxifier or Proxycap is used to forward the packets of specific application on the client PC.
However, when UDP packets are forwarded to the proxy server, these packets cannot be correctly forwarded to the destination originally the application wanted them to go.
When I use a network analyzer to observe the UDP traffic flow, the UDP packets are just passed to the proxy server from my PC without going to the correct destination finally.
Besides, someone suggested that the UDP relay is not enabled in the proxy server so the UDP packets cannot be routed successfully. How can I enable the UDP relay function on the proxy server?(Assume that I can control the proxy server completely)
Any kind of proxy, whether it is for TCP or UDP, needs to be told where to forward outgoing packets to. That also allows the proxy to know who is requesting the forwarding so it can route matching inbound packets back to that same requester.
Lets assume SOCKS, for example. SOCKS v4 does not support UDP (or IPv6), but SOCKS v5 does. However, it requires the requesting app to establish a TCP connection to the SOCKS proxy and ask it to forward UDP packets on the app's behalf until that TCP connection is closed.
Tools like CCProxy, Proxycap, Proxifier, etc work (for TCP, anyway) by intercepting outgoing TCP conections and redirecting them to the proxy server, transparently handling any proxy handshaking to set up forwarding, before then allowing any application data to flow through the TCP connection. Once the TCP connection has been established, the proxifier does not need to do anything more with the connection since the app is now talking directly to the proxy.
I do not know if such tools support UDP. It would be much harder to implement, since there is no outgoing connection to redirect. Every outbound UDP packet would have to be intercepted, then the proxifier would have to check if it already has its own SOCKS v5 TCP connection associated with the packet's local/remote tuple and if not then create a new one and send the necessary UDP forwarding handshake, then encapsulate every outbound UDP packet for that tuple and send it to the proxy's outbound IP/Port, and receive every matching inbound UDP packet for that tuple from the proxy so it can be de-encapsulated and forwarded to the app's local IP/Port that sent out the original outbound UDP packet. And because UDP is connection-less, the proxifier would have to also implement a timeout mechanism on its SOCKS v5 TCP connection to the proxy so it can eventually be closed after a period of UDP traffic being idle.
That is a LOT more work for a UDP proxifier to do compared to TCP.
And that is just for SOCKS. HTTP/FTP proxies do not support UDP at all (since HTTP/FTP are TCP-based protocols). And there are other tunnel/proxy protocols as well, which may or may not have their on UDP capabilities.
So you have to check the capabilities of your proxifier tool to see if it supports UDP or not.
After many hours, I have discovered that the given udp server needs the following steps for a successful communication:
1- Send "Start Message" on a given port
2- Wait to receive from server on any port
3- Then the port dedicated to you to send further data to the server equals the port you have received on it + 1
So I am asking if this kind is a known protocol/handshaking, or it is only special to this server??
PS: All above communication were in udp sockets in C#
PS: Related to a previous question: About C# UDP Sockets
Thanks
There's no special "handshake" for UDP -- each UDP service, if it needs one, specifies its own. Usually, though, a server doesn't expect the client to be able to listen on all of its ports simultaneously. If you mean that the client expects a message from any port on the server, to the port the client sent the start message from, then that makes a lot more sense -- and is very close to how TFTP works. (The only difference i'm seeing so far, is that TFTP doesn't do the "+ 1".)
The server is, effectively, listening on a 'well known port' and then switching subsequent communications to a dedicated port per client. Requiring the client to send to the port + 1 is a little strange
Client 192.168.0.1 - port 12121 ------------------------> Server 192.168.0.2 - port 5050
Client 192.168.0.1 - port 12121 <------------------------ Server 192.168.0.2 - port 23232
Client 192.168.0.1 - port 12121 ------------------------> Server 192.168.0.2 - port 23232 + 1
<------------------------ Server 192.168.0.2 - port 23232
------------------------> Server 192.168.0.2 - port 23232 + 1
The server probably does this so that it doesn't have to demultiplex the inbound client data based on the client's address/port. Doing it this way is a little more efficient (generally) and also has some advantages, depending on the design of the server, as on the server there's a 'dedicated' socket for you which means that if they're doing overlapped I/O then the socket stays the same for the whole period of communications with you which can make it easier and more efficient to associate data with the socket (this way they can probably avoid any lookups or locking to process each datagram). Anyway, enough of that (see here, if you want to know why I do it that way).
From your point of view as a client (and I'm assuming async sockets here) you need to first Bind() your local socket (just use INADDR_ANY and 0 to allow the OS to pick the port for you) then issue a RecvFrom() on the socket (so there's no race between you sending data to the server on this socket and it sending you data back before you issue a recv). Then issue a SendTo() to the 'well known port' of the server. The server will then send you back some data and your RecvFrom() will return you the data and the address that the server sent to you from. You can then take that address, add one to the port, store that address and from then on issue SendTo()s to that new sending address whilst continuing to issue RecvFrom()s for reading the server's data; or you could do something clever with Connect() to bind the remote end of the socket to the server's 'send to address' and simply use Write() and RecvFrom() from then on.