[CentOS] UDP de-fragmentation problem

Mon Apr 11 12:10:17 UTC 2016
Marcelo Ricardo Leitner <marcelo.leitner at gmail.com>

Em 10-04-2016 14:25, Volker escreveu:
> On 09.04.2016 21:40, Marcelo Ricardo Leitner wrote:
>> Hi,
>>
>> Em 07-04-2016 12:19, Volker escreveu:
>>> Hi all.
>>>
>>> I have a strange problem at hand regarding UDP fragmentation on Centos7:
>>> Applications are unable to receive UDP packets which have undergone
>>> fragmentation UNLESS the netfilter modules are loaded.
>>>
>>> The problem arose on a application which would run fine on OpenSuse but
>>> does not work on Centos7. The application processes UDP data and on
>>> Centos only small packets are received and processed, packets below the
>>> fragmentation size limit of about 1500 bytes. UDP packets which have
>>> undergone fragmentation are not received by the application.
>>>
>>> The application in question uses Qt, which opens the UDP socket in
>>> non-blocking mode - apparently that's an issue because reading from the
>>> socket in blocking mode does not cause the problem.
>>>
>>> By chance I hit on the fact that once the netfilter kernel-modules
>>> (nf_nat, iptable_nat, nf_nat ...) are loaded the problem disappears and
>>> UDP packets of all sizes are correctly delivered and processed.
>>>
>>> NOTES:
>>> - I'm not using netfilter. My iptables are empty, firewalld is not
>>> running.
>>>
>>> - Other networking applications -at least tcp- are working fine:
>>> webbrowsing, ssh, nfs etc even DNS
>>>
>>> - Does not happen on Opensuse regardless if netfilter modules are loaded
>>> or not.
>>>
>>> - Does not happen on Opensuse on the same machine. Does happen on
>>> different machines on Centos7. So it's not HW dependend
>>>
>>> - There is AFAIK nothing special about my Centos7 installation. Out of
>>> the box install, simple network config, latest updates applied.
>>
>> Which kernel are you using?
>> And as you have trimmed it down to a reproducer, can you share it please?
>
> 3.10.0-327.10.1.el7.x86_64
>
> I have put the files on github
> https://github.com/volkerp/qtudptest

Okay, you can't do that change I mentioned easily because the call is 
made by Qt instead.
When testing with this app, on nstat I'm getting after 2 attempts:
UdpInErrors                     2                  0.0
UdpInCsumErrors                 2                  0.0

I tried removing the probe for more data, the while condition, but it 
still peeked the socket. I think it's because of this Qt code:

qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxSize, 
QHostAddress *address,
                                       quint16 *port)
{
     Q_D(QNativeSocketEngine);
     Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::readDatagram(), -1);
     Q_CHECK_TYPE(QNativeSocketEngine::readDatagram(), 
QAbstractSocket::UdpSocket, false);                              <----

     return d->nativeReceiveDatagram(data, maxSize, address, port);
}

So I'm afraid there is no way around this issue with Qt.

   Marcelo