UDP packet loss rate might increase on conditions? - sockets

Does UDP packet loss percentage might increase considering packet size? For example if I send 100'000 packets, in first try byte[] size is 30, but second 300. Could packet size play role in it's drop ability or packet loss percentage is not its size dependent?

The packet loss is depending on the size of the packet. This has several reasons.
IP packets can go up to 64k approximately, but they are fragmented up to the MTU of ethernet and if one of those packets gets lost , the whole IP packet is dropped. For larger packets if the traffic is high the probability is higher that the larger packet will be dropped. The MTU is around 1500 bytes.
There is more to it than just that. Internally a protocol stack is implemented using internal buffers that are a lot smaller than the mtu, this can vary from 300 bytes and larger. But the point is that these buffers are also a limited resource. If the network device runs out of buffers, then the packet will be dropped as well.

If you don't know the MTU on the network in question according to the link below a 512-byte UDP payload is considered reasonable to allow a margin for other header information that you may not have anticipated.
What is the largest Safe UDP Packet Size on the Internet

Because you're sending larger packets, yes it could increase the chances that packets are dropped.
Now if you compare sending 100000 packets of 30 bytes or 10000 packets of 300 bytes, even though the user data is the same the total size of the packets is larger due to the headers.

Related

2 layer switch how to handle the datagram bigger than MTU?

If the datagram bigger than MTU, 2 layer switch will drop it? Dose 2 layer switch can report a ICMP? If not report ICMP, how can I determine the data size to pass the switch successfully?
If the datagram bigger than MTU, 2 layer switch will drop it?
Yes. A switch does not forward frames larger than the (configured) maximum size and drops them. For standard Ethernet, that's 1500 bytes payload plus 18 bytes L2 overhead. Note that MTU is an L3 term referring to the maximum packet size that an underlying network can transport.
Does 2 layer switch report a ICMP?
No. A layer-2 switch generally sends no ICMP messages nor is there an ICMP message to report oversized frames in L2.
A layer-3 switch used as gateway should return an ICMP Fragmentation required when the destination network's MTU does not admit the IP packet without fragmentation and its DF bit is set or IPv6 is used. For IPv4 without DF, the gateway just fragments the packet.
If not report ICMP, how can I determine the data size to pass the switch successfully?
On an unmanaged switch, see above for the maximum standard size. A few support jumbo frames, check their documentation. On some managed switches you can configure the maximum frame size globally or by VLAN. Methods and syntax vary.

how decrease UDP backlog to once packet at a time?

Most articles are about how to increase a UDP socket's receive buffer size to handle more packets, but I need a solution to decrease the UDP receive buffer to accept only 1 packet at a time and discard/drop all other packets until that packet is read.
I'm trying to do this for Linux, and did some network stack tuning, like setting the RCVBUFF and RCVBUFFFORCE socket options, but that didn't work. I cannot reduce RCVBUFF lower than 2046B (maybe 1 memory page), even when setting the udp_rmem_min to 0.
Why i can’t set UDP RCVBUF lower than 2046?

How does UDP SetWriteBuffer and SetReadBuffer the OS's buffers?

Description
I'm busy writing a high frequency UDP server with Go. I'd estimate at least 1000 packets/second both ways.
However as the size of data I'm sending over the UDP socket grew, I eventually ran into the follow error: read udp 127.0.0.1:1541->127.0.0.1:9737: wsarecv: A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself.
I eventually just grew the size of the buffers I was reading from and writing into as follows:
buffer := make([]byte, 64 * 1024 * 1024) // used to just be 1024
l, err := s.socketSim.Read(buffer)
This worked fine and I stopped getting the error... However then I can across two functions inside the net package:
s.socketSim.SetWriteBuffer(64 * 1024 * 1024)
s.socketSim.SetReadBuffer(64 * 1024 * 1024)
I learned that these two act on the operating system's transmit buffer
Question
Do I even care to set the operating system buffer size and why? How does the size on the application buffer impact the size of the operating system buffer? Should they always be the same and how big should/can they become?
First, not only do you have an MTU size for each interface on your device and whatever destination you're send/recving from, but there is also an MTU size for each device in between. For this reason, as others have mentioned, you might want to use what is generally accepted for MTU since you might not control every device in the data route. In the case of UDP, MTU really just means how big a datagram can be before fragmenting.
Second, you almost certainly want your SND/RCV buffers to be larger than the MTU. These are kernel buffers which hold on to data when you're not ready to receive them. A larger UDP RCV buffer means that the kernel will buffer more packets for you instead before dropping them into the abyss. Maybe you have some non-trivial work to do for each packet. Depending on the bitrate, you might want a larger or smaller kernel buffer.
Finally, you're using UDP. There is no guarantee that you'll receive packets in order or at all. Any router in between you and a peer could decide to drop the packet for any reason. Since you're using UDP, you should prepare for dropped and out-of-order packets. You also might need some sort of retransmission mechanism, which further complicates things.
Or you might consider using TCP if dropped packets are unacceptable, knowing that timing is indeterminate.
If you're on linux, you can see current buffer sizes in /proc/sys/net. Usually the kernel will double what you ask for.
Also, you can tune your buffer size by watching for packet drops in /proc/net/udp. If you see drops, you might want to make your rcv buffer bigger, especially if the data is bursty and the processing intensive. If you're data is coming in at a consistent rate and you're still dropping packets, then you aren't processing them fast enough.

Why low data throughput is observed when iperf tried with UDP packet size set below 2000?

I'm experimenting on an LTE connection for checking the maximum rate of bandwidth can be achieved in the uplink.While creating iperf sessions i observed that i'm not able to go beyond 100Kbps in the uplink when the UDP packet size is set as 1400.Apparently when i increased the packet size to 50000 i was able to achieve 2 Mbps in the same link.
Can someone guide me why this performance difference is observed ?When i tried this in a wired channel there i was able to achieve 10Mbps with UDP packet size set as 1400 itself.
What could be the reason for this?
Will trying TCP/IP instead of UDP increase the data throughput?
It probably matters where fragmentation is done - application or IP stack. Your observations show you that IP stack is more efficient.
TCP will be slower. TCP's built-in congestion control will not allow you to send packets until some of already sent have been ACK-ed. That adds round-trip time to performance considerations.
UDP has no such restrictions. It can (ab)use the network to its full potential.

Increased MTU but still can't send large UDP packets

a little info on what i'm trying to achieve here first. I'm using a Texas Instrument board EVM6678LE, and what i am trying to do is to increase the UDP transfer rate between the board and my PC.
I've increased the MTU on my PC through netsh>interface>ipv4 to 15,000. But when i ping the board from my PC i am only able to ping up to "ping 192.168.2.100 -l 10194", if i ping with 195bytes onwards i'll receive a request timeout. Is this a limitation of my PC or something?
Does anyone have any idea what could be the possible cause of this? Any advice or suggestions at all would be welcome. As the only way to increase the transfer rate i could think of it increasing the per packet size which reduces overhead. And at 10k i have a rate of around 9.1MB/s, and i'm trying to attain 25MB/s.
Thanks!
Increasing the MTU on your PC may not prevent fragmentation. I don't know exactly what is controlling this, but your network card or driver can fragment the packet even when MTU is not reached. Use a sniffer like Wireshark to see how the packets are sent.
About the timeout, it is possible that your board rejects fragmented pings (because of Ping of Death protection). There is also a possibility that its packet buffer is 10kB (10240) bytes long, and can't receive larger packets. Also, make sure that the receiving endpoint have a matching MTU.
Anyway, if you are trying to increase transfer rate, you are on the wrong track. The overhead for UDP is 8 bytes, IP 20 bytes, Ethernet 18 bytes, which make a total of 46 bytes (oh, coincidence, 46+10194 is exactly 10240). 46 bytes overhead for 1024 MTU is 95.5%. 46 bytes for 4096 is 98.9%, 46 bytes for 16384 is 99.7%. That means you gain +3.5% transfer rate from 1024 to 4096 MTU, and another +0.8% from 4096 to 16384. The gain is just ridiculous, and you should just let the MTU to the common default 1500.
Anyway, going from 9.1MB/s to 25MB/s just by changing the MTU is IMPOSSIBLE (if it was, why the PC default is not higher ?). Here I guess you are using Fast Ethernet (100BASE-T), and you are already transferring near full bandwidth. To get higher rates, you would need to have Gigabit Ethernet (1000BASE‑T). That means you need both hardware endpoints to support 1000BASE-T.