Linux drops UDP packets - linux

I have written a C++ tool for my linux machine which receives UDP (OSC) packets and sends them back immediately (thats the only thing it does). But it seems that there is some amount of dropped packets. When I send 100 packets to my linux (from another machine), mostly only 64 packets are returned. I have looked at the incoming packets with tcpdump. It tells me the following:
64 packets captured
64 packets received by filter
0 packets dropped by kernel
So where are they?

UDP, by design, does not guarantee that the packets arrive at the destination. The packets missing might no have reached your machine at all, and thus will not appear in the incoming packets.
UDP is mostly used for streams and games, as loosing a few packets does not really matter.
If you want to be sure that all the packets arrive, you should use TCP.
Let me know if this helps.

Related

Linux Raw Sockets: Block Packets?

I've written my own packet sniffer in Linux.
I open a socket with socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)) and then process the Ethernet packets - unpacking ARP packets, IP packets (and ICMP / TCP / UDP packets inside those).
This is all working fine so far.
Now I can read packets like this - and I can also inject packets by wrapping up a suitable Ethernet packet and sending it.
But what I'd like is a means to block packets - to consume them, as it were, so that they don't get further delivered into the system.
That is, if a TCP packet is being sent to port 80, then I can see the packet with my packet sniffer and it'll get delivered to the web server in the usual fashion.
But, basically, I'd like it that if I spot something wrong with the packet - not coming from the right MAC address, malformed in some way, or just breaking security policy - that I can just "consume" the packet, and it won't get further delivered onto the web server.
Because I can read packets and write packets - if I can also just block packets as well, then I'll have all I need.
Basically, I don't just want to monitor network traffic, but sometimes have control over it. E.g. "re-route" a packet by consuming the original incoming packet and then writing out a new slightly-altered packet to a different address. Or just plain block packets that shouldn't be being delivered at all.
My application is to be a general "network traffic management" program. Monitors and logs traffic. But also controls it too - blocking packets as a firewall, re-routing packets as a load balancer.
In other words, I've got a packet sniffer - but if it sniffs something that smells bad, then I'd like it to be able to stop that packet. Discard it early, so it's not further delivered anywhere.
(Being able to alter packets on the way through might be handy too - but if I can block, then there's always the possibility to just block the original packet completely, but then write out a new altered packet in its place.)
What you are looking for is libnetfilter_queue. The documentation is still incredibly bad, but the code in this example should get you started.
I used this library to develop a project that queued network packets and replayed them at a later time.
A bit of a tangent, but it was relevant when I was resolving my problem. Blocking raw packets is relatively complicated, so it might make sense to consider doing that at a different layer. In other words, does your cloud provider let you set up firewall rules to drop specific kind of traffic?
In my case it was easier to do, which is why I'm suggesting such a lateral solution.

how does linux kernel process out-of-order tcp segment?

I'm devleoping a multi rx threads ethernet driver, but this may lead to potential issuse that delivery out-of-order packets to linux network stack. this issue has been verified on PPTP connection, because GRE has sequence number and will drop out-of-order packets.
So, does TCP has an tcp reassembly queue or similar mechanism to process out-of-order segment.
TCP has a window buffer. As packets arrive they are cached until the next expected packet sequence number is received. When the next expected packet is received (and it's valid), it's passed onto the application for receiving in order.
see https://www.quora.com/How-does-TCP-handle-the-duplicate-segments-and-out-of-order-segments

use scapy to send UDP ping with a high frequency, why only receive the first few ICMP port unreachable message?

In a linux system, I use scapy to send a high frequency UDP ping. For example: each 20 milliseconds, send a UDP packet; a total of 100. But I can only get the first few ICMP port unreachable answer.
pkt = IP(dst=dst)/UDP(dport=RandShort())
ans,_ = sr(pkt*100, inter=0.02, timeout=3)
I tried to use tcpdump to capture packet and found that all UDP packets have been sent to the target machine, but only a few ICMP packet came back to the source machine. What would cause this?
If I use ICMP pingļ¼Œthis does not happen.
I guess:
may be caused by the target machine's system kernel parameter which process icmp packet
may be caused by the icmp packet routing switch strategies.
The rate of ICMP packets is hard limited by the kernel to prevent DDOS attacks. Usually to only 1 packet per second. Almost impossible to get anything faster than that in any external (internet) router. Example

Minimum requirements for custom networking stack to send UDP packets?

(edit: solved -- see below)
This is my situation:
TL-MR3020 -----ethernet----- mbed
OpenWRT C/C++ custom networking stack
192.168.2.1 192.168.2.16
TL-MR3020 is a Linux embedded router
mbed is an ARM microcontroller.
On the network I just want them to exchange messages using UDP packets on port 2225. In particular, TL-MR3020 has to periodically send packets every second to 192.168.2.16:2225, while mbed has to periodically send packets every 50ms to 192.168.2.1:2225.
Everything was good untill I removed the network stack library from mbed (lwIP, not so lightweight for me) and written a new minimal stack.
My new stacks sends 5 gratuitous ARP reply just after the ethernet link gets up, then starts sending and receiving udp packets.
Now TL-MR3020 doesn't receive any UDP packet. In particular, with ifconfig I can see packets coming, but my application can't get them.
Also, if I connect my laptop instead of the TL-MR3020, I can see the UDP packets coming, using Wireshark. There's nothing wrong, except done for my application.
I have a node.js script that has to receive the packets, but it doesn't receive nothing, but if I send UDP packets from local to local, the script receives them.
I think that my application is OK also because neither SOCAT can receive the UDP packets using socat - UDP-LISTEN:2225.
I've already checked on TL-MR3020:
arp table has the correct ip-mac assiciation
destination MAC address matches the incoming interface
destination IP address matches the incoming interface
IP checksum: wireshark says good=false, bad=false
UDP checksum: wireshark says good=false, bad=false
So, I'm asking... what are the minimum requirements for a custom networking stack to send UDP packets?
SOLVED:
You need a good checksum in the IP header.
UDP checksum, my case, can be set to zero.
tcpdump is very helpful (thanks to AndrewMcDonnell)

Where are the missing TCP packets?

I observed a surprising thing that when there are both udp-based and tcp-based applications sending packets, if the upd-based application sent the packets so fast that the bandwith are nearly filled with udp packets, then the tcp packets would be very hard to send out.
The surprising thing is that though tcp-based application is able to send a few packets out (observed by the return value of write()), the receiver of the tcp packets never receives them. Why? Is that because the tcp-packets arenot finally sent out by the network card? or the tcp packets are actually dropped by routers?
Thanks,
Steve
First, the return value of write() is not an indicator of whether packets were sent. It just indicates that the data was buffered.
Second, if you are saturating the network with UDP packets there will be a lot of packet loss, and TCP being adaptive will adapt to that by sending packets out more slowly. If the packet loss gets too high TCP can basically stop altogether. The solution is not to saturate the network with UDP packets.
This is a simplified answer. There are many articles you can read up on.
UDP is a layer built upon IP. Ditto for TCP. The network card just sends out IP packets. You can look up the various structures for these packets.
TCP is a protocol that uses IP packets but uses a mechanism to try to ensure delivery and rearranges packets in the correct order. See the article on Wikipedia.
Routers are free to drop packets. This can occur when the network is overloaded, network connections are down or the IP packet is corrupted.
So to answer your question their is no preference between UDP or IP to be transmitted from one end to the other.

Resources