Pipe in Ping command output - linux

Ping command output:
PING google.com (216.58.197.78) 56(84) bytes of data.
......
--- google.com ping statistics ---
53 packets transmitted, 28 received, 47% packet loss, time 687ms
rtt min/avg/max/mdev = 50.360/57.587/88.878/9.458 ms, pipe 8, ipg/ewma 13.220/57.967 ms
The above output shows the statistics. Here, what is the pipe refers to ?

Its the count of maximum number of ICMP echo request packets pending responses.
See https://serverfault.com/questions/587730/what-does-pipe-number-mean-in-ping-output for information about the pipe in ping.

In the link provided by RaviTezu, check the last answer. It's not the number of packets lost. Rather, it's maximum number of outstanding requests that are not acknowledge at some point of time, but are eventually acknowledged.

Related

influence of fragmentation (DF bit) on rtt and ttl

I was doing some tests with ping on linux and I am a little bit curious about how DF bit and fragmentation works. I have been sending some packages with command -M do and some packages with -M dont and I realised that even when sending packages smaller than MTU, rtt is smaller with DF bit disabled than when DF bit is enabled. Is there really some influence of fragmentation on the rtt and why ?
The DF bit has no (real) impact on either RTT or TTL.
When sending a packet, the TTL indicates how many router hops your packet should survive. On reception, it indicates how many hops the route took (provide you know or guess the start value).
The RTT is the time a packet takes to the destination and back again. When using unfragmented ICMP echo requests (ping) the answer time might provide an estimation for the RTT - however, since ICMP usually runs with low priority the ping time might also be significantly larger than the RTT.
With larger ping packets and especially with fragmented ping packets, the bandwidth starts to kick in. Not only does the ping measure the time between sending the first fragment and receiving the last response fragment but you also need to consider the transmission time for all fragments in both directions. With thin links this adds more than negligible delay for ping.
Now, setting the DF bit just prevents you from sending fragmented echo requests.

In traceroute source code why the size is hard coded to 512 : u_char packet[512];

In traceroute while revising the source code, I saw that the ICMP inbound packet size is hard coded to 512.
I don't know why the size is limited to 512 bytes. What happen if the ICMP inbound packet size is greater than 512 bytes?
In general, there are 3 ways(I am not familiar with implementation using GRE protocol) to implement traceroute, sending ICMP Echo requests, UDP packets or TCP SYN packets with gradually increasing TTL value, starting with TTL value of 1.
if it sends ICMP echo request, it expects ICMP TIME Exceed message(8 bytes + IP header(20 bytes) + first 8 bytes of original datagram's data) or the destination is reached and returns an ICMP echo reply which is 20 + 8 bytes long. Though according to rfc 792, it allows for an arbitrary data length for echo request or reply , but traceroute needn't that.
if it sends UDP pakcets, it expects ICMP TIME Exceed message or the destination is reached and return a port unreachable message which is 20 + 8 + 20 bytes long. Maybe some implementations add some data, but it wouldn't be too much.
if it sends TCP SYN packets, the inbound packets should be ICMP TIME Exceed message, TCP SYN+ACK packet or TCP RST packet, all of them are much less than 512 bytes.

what is the use of buffer size in socket?

I am learn about the ping command implementation. In that I had a one doubt. The doubt is
I know the socket buffer is for how many bytes transfer at a time in the socket.
But how the ping command manages the socket buffer size.
$ ping -S 300 -s 400 google.com
PING google.com (216.58.197.46) 400(428) bytes of data.
72 bytes from maa03s20-in-f14.1e100.net (216.58.197.46): icmp_req=1 ttl=56 (truncated)
72 bytes from maa03s20-in-f14.1e100.net (216.58.197.46): icmp_req=2 ttl=56 (truncated)
72 bytes from maa03s20-in-f14.1e100.net (216.58.197.46): icmp_req=3 ttl=56 (truncated)
^C
--- google.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 40.231/41.500/42.408/0.924 ms
In the above ping command I was given the socket buffer size as 300 and the single packet size as 400. The socket buffer size is 300 only. But the the ping transfer the 400 bytes at a time in that socket. How it is possible.
At the same time the received packet size is only 72. Why that is only 72.
Can any one please explain me.
The ping request only used/required 72 bytes of data. This is within your 300 buffer size (limit) and your 400 byte packet size. The ICMP packet likely contained 64 data bytes and 8 header bytes resulting in a 72 byte packet.
Since the ICMP packet only needed 72 bytes it isn't going to add unnecessary data to meet your 400 byte packet size.

Ping and use three octet ipv4 addresses. Why is it working?

By accident I had a typo and discovered that I can ping and ssh to IP address 10.8.290 ... right one octet is missing. Can someone explain it to me? Is this part of the protocol or some linux-black-magic (I am using Debian)?
user#ws:~$ ping -c3 10.8.290
PING 10.8.290 (10.8.1.34) 56(84) bytes of data.
64 bytes from 10.8.1.34: icmp_req=1 ttl=62 time=0.910 ms
64 bytes from 10.8.1.34: icmp_req=2 ttl=62 time=0.686 ms
64 bytes from 10.8.1.34: icmp_req=3 ttl=62 time=0.708 ms
--- 10.8.290 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1998ms
rtt min/avg/max/mdev = 0.686/0.768/0.910/0.100 ms
user#ws:~$ ssh root#10.8.290
The authenticity of host '10.8.290 (10.8.1.34)' can't be established.
ECDSA key fingerprint is 21:bd:7e:fb:1e:6d:1e:c1:e9:11:c0:a9:73:a8:cf:85.
Are you sure you want to continue connecting (yes/no)? no
Host key verification failed.
It works because you are using a value of 290 for the third byte of the ip address. A byte can store values from 0 to 255, giving 256 values. Since an IPv4 address is a 4 byte value passing 290 to the third byte leads to an integer overflow into the 4th byte -> 290 - 256 => 34
It has nothing to do with a protocol "feature". ping simply don't validate the values of the individual octets of the target command line argument and simply passes it to the lower level C function inet_aton() (aton means ascii to number). This results in pinging 10.8.1.34.
I'm not sure, but I expect other versions of ping (on Windows, BSD) behaving the same.

UDP Packet drop - INErrors Vs .RcvbufErrors

I wrote a simple UDP Server program to understand more about possible network bottlenecks.
UDP Server: Creates a UDP socket, binds it to a specified port and addr, and adds the socket file descriptor to epoll interest list. Then its epoll waits for incoming packet. On reception of incoming packet(EPOLLIN), its reads the packet and just prints the received packet length. Pretty simple, right :)
UDP Client: I used hping as shown below:
hping3 192.168.1.2 --udp -p 9996 --flood -d 100
When I send udp packets at 100 packets per second, I dont find any UDP packet loss. But when I flood udp packets (as shown in above command), I see significant packet loss.
Test1:
When 26356 packets are flooded from UDP client, my sample program receives ONLY 12127 packets and the remaining 14230 packets is getting dropped by kernel as shown in /proc/net/snmp output.
cat /proc/net/snmp | grep Udp:
Udp: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors
Udp: 12372 0 14230 218 14230 0
For Test1 packet loss percentage is ~53%.
I verified there is NOT much loss at hardware level using "ethtool -S ethX" command both on client side and server side, while at the appln level I see a loss of 53% as said above.
Hence to reduce packet loss I tried these:
- Increased the priority of my sample program using renice command.
- Increased Receive Buffer size (both at system level and process level)
Bump up the priority to -20:
renice -20 2022
2022 (process ID) old priority 0, new priority -20
Bump up the receive buf size to 16MB:
At Process Level:
int sockbufsize = 16777216;
setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF,(char *)&sockbufsize, (int)sizeof(sockbufsize))
At Kernel Level:
cat /proc/sys/net/core/rmem_default
16777216
cat /proc/sys/net/core/rmem_max
16777216
After these changes, performed Test2.
Test2:
When 1985076 packets are flooded from UDP client, my sample program receives 1848791 packets and the remaining 136286 packets is getting dropped by kernel as shown in /proc/net/snmp output.
cat /proc/net/snmp | grep Udp:
Udp: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors
Udp: 1849064 0 136286 236 0 0
For Test2 packet loss percentage is 6%.
Packet loss is reduced significantly. But I have the following questions:
Can the packet loss be further reduced?!? I know I am greedy here :) But I am just trying to find out if its possible to reduce packet loss further.
Unlike Test1, in Test2 InErrors doesnt match RcvbufErrors and RcvbufErrors is always zero. Can someone explain the reason behind it, please?!? What exactly is the difference between InErrors and RcvbufErrors. I understand RcvbufErrors but NOT InErrors.
Thanks for your help and time!!!
Tuning the Linux kernel's networking stack to reduce packet drops is a bit involved as there are a lot of tuning options from the driver all the way up through the networking stack.
I wrote a long blog post explaining all the tuning parameters from top to bottom and explaining what each of the fields in /proc/net/snmp mean so you can figure out why those errors are happening. Take a look, I think it should help you get your network drops down to 0.
If there aren't drops at hardware level then should be mostly a question of memory, you should be able to tweak the kernel configuration parameters to reach 0 drops (obviously you need a reasonable balanced hardware for the network traffic you're recv'ing).
I think you're missing netdev_max_backlog which is important for incoming packets:
Maximum number of packets, queued on the INPUT side, when the interface receives packets faster than kernel can process them.
InErrors is composed of:
corrupted packets (incorrect headers or checksum)
full RCV buffer size
So my guess is you have fixed the buffer overflow problem (RcvbufErrors is 0) and what is left are packets with incorrect checksums.

Resources