PF_PACKET socket and 'Port unreachable' ICMP messages - linux-kernel

My application needs to receive UDP packets from multiple destination ports (this is a bonafide application and not a sniffer). Therefore, I have chosen to use a PF_PACKET socket and to do port filtering at the application level.
Here's how I create the socket:
int g_rawSocket = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
I am correctly receiving UDP packets. However, the kernel on which the application runs is sending ICMP packets of type 'Destination unreachable' and code 'Port unreachable' to the remote device that is sending packets to my app. I guess that this is because I have not bound a port number to the socket. However, I wonder if it is appropriate to use bind with a PF_PACKET socket, especially as I need to bind multiple ports to it, which I guess is not possible.
Any comments please?

No, it can't be bound to a specific port, since it's working on a lower level than the Transport (UDP/TCP) layer. However, you could open and listen to all sockets, using regular UDP (AF_INET/SOCK_DGRAM) sockets and select for example and as far as I know you can bind and listen to as many sockets as you want, as long as you don't exceed the limits of open file descriptors for your process.

I have also done the same thing in my application.
in my case i have created sockets as many i need & bind them with the particular port. but i m not listening to any socket. so i created one raw socket
int sock_raw = socket(AF_INET , SOCK_RAW , IPPROTO_UDP);
& then received all the traffic without any ICMP.
So i think u have to bind all the ports to avoid ICMP either you have to some kernel hacking as stoping or removing the code for ICMP in the linux-kernel code & build it again

Related

what does tcp:*:port mean in zeromq?

I see this sort of address used in a bunch of examples. What does it mean exactly? Does it mean it will connect to any/all machines on the subnet that have something listening to that port? Or something else entirely? I see such usage in the docs and in books without explanation. Sort of annoying.
It is explained in the manual.
ZeroMQ supports multiple transports. tcp means you are using the TCP transport.
The address (or endpoint) for the TCP transport has the following format:
tcp://interface:port
When you bind to a local address, interface is either the IP address of a specific interface (network) or *, which means to listen on all interfaces (networks). port is the TCP port or * for a random port.
When you connect to a remote endpoint, interface is the hostname or IP address of the remote machine. port is the TCP port of the remote endpoint.
To add to rveerd's answer, what's often missed is that you can multiply bind a socket. So, tcp://*:5555 specifies port 5555 on any interface and you can bind the socket accordindly. But by calling zmq_bind() again you can bind the same socket to, say, ipc:///tmp/feeds/0, which means it will also accept connections on the /tmp/feeds/0 IPC pipe.
This is a pretty spectacularly useful feature in my view, because you can trvially have other actors local and remote to the machine though a single zmq socket.

Multiple clients - one server - one port? [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

How to close Winsock UDP socket hard?

I need to close UDP socket which has unsent data immediately.
There is SO_LINGER parameter for TCP sockets but I didn't find out anything for UDP.
It's on Windows.
Thanks in advance.
Update 0:
I give background of this question. I have application 1st thread opens/binds/closes socket, 2nd thread sends datagrams to it.
In some cases after closing the socket (errorcode = 0) bind function returns errorcode 10048 "Address already in use". I found out after close() execution port is still used (via netstat command). Maybe I ask incorrect question and the reason of such behavior is something else?
For all application purposes once your send() returns, the packet is "sent". There's no send-buffer like in TCP, and you have no control over the NIC packet queue. Normal close() is all you need.
Edit 0:
#EJP, here's a quote from UNP for you (Section 2.11 "UDP Output"):
This time, we show the socket send buffer as a dashed box bacause it
doesn't really exist. A UDP socket has a send buffer size (which we
can change with the SO_SNDBUF socket option, Section 7.5), but this
is simply an upper limit on the maximum-sized UDP datagram that can
be written to the socket. If an application writes a datagram larget
than the socket send buffer size, EMSGSIZE is returned. Since UDP is
unreliable, it does not need tp keep a copy of the application's data
and does not need an actual send buffer. (The application data is
normally copied into a kernel buffer of some form as it passes down
the protocol stack, but this copy is discarded by the datalink layer
after the data is transmitted.)
This is what I meant in my answer - you have no control over the send buffer - , so "for all application purposes" it does not exist.
I was having this problem with a windows UDP socket as well. After hours of trying everything I finally found my problem was that I was calling socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) on the main thread to create the socket, calling bind(...) and recvfrom() on a worker thread, then after closing the worker thread I called closesocket(...) on the main thread. None of the functions returned an error but tor some reason, doing this leaves the UDP address/port combination in use (so a future call to bind() triggers error 10048 WSAEADDRINUSE and netstat -abot -p UDP also shows the port still in use until the whole application is closed). The solution was to move socket(...) and closesocket(...) calls into the worker thread.
Other than weird issues like the case above, there is normally no way that a UDP server socket can be left open after calling closesocket() on it. Microsoft explains that there is no connection maintained with a UDP socket and no need to call shutdown() or any other function. Usually the reason a TCP socket is left open after calling closesocket() is that it wasn't disconnected gracefully and it's waiting for about 4 minutes in TCP_WAIT state for possible additional data to come in before it actually closes. In the case above, netstat showed the UDP socket never closed until the application was closed even if I waited 30+ minutes.
If you're using a wrapper around winsock like the .NET framework, I've also read some features like setting up async callbacks can leave a UDP socket bound open if you don't clean up the callbacks correctly, but I don't think there are any such features in the win32 winsock API that can cause that.
Just close it. There's nothing in UDP that says that pending data will be sent, unlike TCP.

UDP listening socket stops listening after network configuration changes

I have a UDP socket listening in a port for broadcast transmissions and it is working fine.
However, when I hibernate and resume the OS (Windows 7), the socket just stops receving data (and I can see that there is data arriving using Wireshark).
This also happens if I change any network settings like, change my IP address, disable and enable the network adapter.
The OS seems to disable all network adapters when hibernating and to re-enable them when it is resumed.
select just returns 0 (timeout) which is no different than when I'm not receiving any data. I could not find any references to this behavior anywhere.
If I close the socket and recreate it, it starts to work again.
My TCP listening sockets still working fine after resuming the OS.
Any ideas on how detect and correct this situation?
EDIT: It still receiving directly addresses data just fine, it just does not receive brodcast transmissions anymore.
EDIT2: Just discovered that if I write to the socket (send a dummy packet to anywhere) it starts to work again...
I think your code does not explicitly binds the socket to "0.0.0.0" address. So when you do sentto it binds the interface IP which is available at that time. When this IP is changed or interface is disabled, this socket will be reset by the TCP/IP stack. In your TCP socket, you should have bound to "0.0.0.0" address so it will always listen for connection independent of any IP/interface changes. You can make your udp socket also bound to "0.0.0.0" before sending any data on it. This will make it work even after hibernation or IP changes.

Receiving datagrams using Udp connection

In order to receive datagrams through an UDP connection I have created an object of type UDPClient.
receivedNotificationSock = new UdpClient();
However once done and on using the receive method:
receivedHostNameBuffer=receivedNotificationSock.Receive(ref receivedNotificationIP);
I am getting an exception saying that I must call the bind method.
But there is no bind method in the UDPClient class.
Could You guys please provide me with the code if possible as to what should be done to overcome this exception.
You need I think to know some more about sockets.
All sockets possess a port number. First, you create a socket - which is almost useless on its own. It just floats there. But then you bind it - you assign it a port number. Now it's useful - now you can send and receive data on it.
Remember, all UDP communications are defined by the quad data set of the IP and port of the source and the IP and port of the destination. A freshly created socket doesn't have an IP address or port; binding gives it an IP address and port.
Unfortunately, I'm not a C# programmer, so I can't properly answer your question. But at least you know why it's important.
Pass the port number into the constructor of your UDP client.
receivedNotificationSock = new UdpClient(21000);
You may need to change firewall settings to allow the bind, though a popup window normally opens when you first run this on your dev machine.
For Socket proramming you need to know the sequence of syscalls you need to do on client side and on the server side.
If you are writting a client :
you open a socket with a socket call.
you then connect to the server port with a connect call
once connect is successful
then you send the request to the server using either a send or sendto or a write
which results in reception of data that you can read using a receive or read
On Server Side
you create a socket
bind it to a port
start listening on the socket for incoming connections from various clients using a listen.
There is a non blocking way of listening for connections as well with a select syscall.
Once the you establish a connection you can essentially read the request and start processing it.
Here's an example in C# that may be useful to you.
http://www.developerfusion.com/article/3918/socket-programming-in-c-part-1/

Resources