We are using iperf2 to test UDP flow and we see a peculiar behaviour with the server implementation.
When we are using reporting interval < 2148 for the server, the server drops the connection and generates a report even though client is still sending the packets.
We took a strace and see that the recvmsg is failing with EINTR and the server is not handling this as an error and this it thinks there is reall error and close the connection.
If we set interval >=2148 then this do not happen and this is also related to the
if (setsockopt( mSettings->mSock, SOL_SOCKET, SO_RCVTIMEO, (char )&timeout, sizeof(timeout)) < 0 ) is set to the socket or not. When the TIMEOUT is set then we see this behaviour.
I am attaching the strace where it is not working.
I see that the client is handling the EINTR where as the server do not. Are there any particular reason why server is not handling the EINTR? Is it not a case that the system calls are interrupted?
23669 <... recvfrom resumed>0x563df69fb500, 1470, 0, 0x7fd23e7aace8, [128]) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
30638 <... recvmsg resumed>{msg_namelen=16}, 0) = -1 EINTR (Interrupted system call)
23669 recvfrom(4, <unfinished ...>
30638 writev(2, [{iov_base="recvmsg failed: Interrupted syst"..., iov_len=40}, {iov_base=NULL, iov_len=0}], 2) = 40
23670 <... nanosleep resumed>NULL) = 0
23670 nanosleep({tv_sec=0, tv_nsec=10000000}, NULL) = 0
23670 writev(1, [{iov_base="[ 3] 0.00-2.52 sec 360 KBytes"..., iov_len=131}, {iov_base="\n", iov_len=1}], 2) = 132
30638 write(3, "\0\t\256\232\334\205X\0\2,\312\0\0\0\0\310\0\0\0\0\0\0\0\0\5\241J\0\0\0\2"..., 1470 <unfinished ...="">
23670 nanosleep({tv_sec=0, tv_nsec=10000000}, <unfinished ...="">`</unfinished></unfinished>
Can your provide config.h? Also, the server command line?
The EINTR is a signal, likely per setitimer, and goes off when the current time exceeds the -t value. So it's not "an error to be ignored." It's indicating the server thread needs to stop.
The server is started with command line iperf -s -u -e -i 10 -p 5201.
What we see from the trace is that there is EINTR coming when -i parameter is used but I guess it is expected that the server is not expecting it to receive that signal?
can you provide the client command too? I'm seeing both reads and writes on the strace log. Is this log on the server side?
Also, what does iperf -v show for both the client and server?
Last edit: Robert McMahon 2021-07-07
It is just the server. The writes are most likely the report writing? with -i 10 it will generate report every 10 seconds or so. The client is run with
iperf -c 192.168.111.233 -u -p 5201 -t 300 -i 300 -z -e -b 100pps
We did not trace this process.
what strace options are being used? Is it just strace -fp pid?
Yes. strace with -fp was used. This looks like a side effect of the container being put to frozen state.
thanks, it does look like the UDP server needs to handle EINTR differently
Can you try the latest 2-1-3-rc (2.1.3-rc)? I think I addressed the EINTR. Make sure the date is July 8.
iperf -v
iperf version 2.1.3-rc (8 July 2021) pthreads
Bob
Will this issue be fixed in the TCP protocol as well?
We will try the latest rc and come back with results.
Just did that. I need this change to go through a code review as well as be thoroughly tested. The July 9 version of 2.1.3 has the TCP change. It would be helpful if you can use this version and inform me of any issue.
We tested the UDP one and it works well for us with the EINTR handling. Thanks a lot.
Thanks for reporting it.