Re: [CentOS] UDP de-fragmentation problem

2016-04-11 Thread Marcelo Ricardo Leitner

Em 11-04-2016 09:10, Marcelo Ricardo Leitner escreveu:

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);
}


http://code.qt.io/cgit/qt/qt.git/tree/src/network/socket/qnativesocketengine.cpp
FWIW


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

   Marcelo



___
CentOS mailing list
CentOS@centos.org
https://lists.centos.org/mailman/listinfo/centos


Re: [CentOS] UDP de-fragmentation problem

2016-04-11 Thread Marcelo Ricardo Leitner

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

___
CentOS mailing list
CentOS@centos.org
https://lists.centos.org/mailman/listinfo/centos


Re: [CentOS] UDP de-fragmentation problem

2016-04-10 Thread Volker
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


___
CentOS mailing list
CentOS@centos.org
https://lists.centos.org/mailman/listinfo/centos


Re: [CentOS] UDP de-fragmentation problem

2016-04-09 Thread Marcelo Ricardo Leitner

Em 07-04-2016 12:19, Volker escreveu:
...

select(8, [3 7], [], [], NULL)  = 1 (in [7])
recvfrom(7, 0x7ffdf3072e1b, 1, 2, 0x7ffdf3072e20, 0x7ffdf3072e1c) = -1

  ^--- I think that's why


EAGAIN (Resource temporarily unavailable)
select(8, [3 7], [], [], NULL
[...]


RHEL7 still doesn't have this patch:
https://patchwork.ozlabs.org/patch/561746/

As test/workaround while that patch isn't out, please make that buffer 
as big as your payload, even if you're going to use only one byte. It 
will copy more but it's MSG_PEEK, it's not discarding/removing anything 
from the queue anyway. It will probably work then.


  Marcelo

___
CentOS mailing list
CentOS@centos.org
https://lists.centos.org/mailman/listinfo/centos


Re: [CentOS] UDP de-fragmentation problem

2016-04-09 Thread Marcelo Ricardo Leitner

Em 08-04-2016 14:38, Gordon Messmer escreveu:

On 04/07/2016 08:19 AM, Volker wrote:

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 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.


I'm not sure you need to look much further than that.  Using select()
and non-blocking sockets together doesn't make a whole lot of sense. The


Yes it does. You can mix both. Why not? For example, select will return 
only "data ready" but will not tell you how much is in there. With 
non-blocking he can keep reading until the data is drained and without 
calling select() on it on every single iteration. If the traffic is 
bursty, this may save some syscalls.



man page for select() says that descriptors listed in readfds will be
watched "precisely, to see if a read will not block."

So, if the socket returned by select() can be read without blocking, you
don't need to put the socket in non-blocking mode.

It's hard to say more since your strace output was cut.  I'd expect you
to get another return from select() when the rest of the data arrives,
and for recvfrom() to work at that point.  I can't tell if that's


No because that implies that the application has to do the 
defragmentation, which is impossible as it doesn't have the necessary 
information for that. Kernel must hold the fragments until it's 
reconstructed, and only then deliver it to the application.



happening or not.  If it's not, then you probably have hit a bug.  The
documented behavior for message-based sockets is to read the entire
message in one operation, and to discard data on recvfrom() if it's too
big for the buffer.  Maybe you're creating a condition where the system
is discarding data if it can't be read in one operation.

Regardless, in the select()/recvfrom() pattern you described, the socket
should be in blocking mode.

___
CentOS mailing list
CentOS@centos.org
https://lists.centos.org/mailman/listinfo/centos


___
CentOS mailing list
CentOS@centos.org
https://lists.centos.org/mailman/listinfo/centos


Re: [CentOS] UDP de-fragmentation problem

2016-04-09 Thread Marcelo Ricardo Leitner

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?

  Marcelo
___
CentOS mailing list
CentOS@centos.org
https://lists.centos.org/mailman/listinfo/centos


Re: [CentOS] UDP de-fragmentation problem

2016-04-08 Thread Gordon Messmer

On 04/07/2016 08:19 AM, Volker wrote:

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 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.


I'm not sure you need to look much further than that.  Using select() 
and non-blocking sockets together doesn't make a whole lot of sense.  
The man page for select() says that descriptors listed in readfds will 
be watched "precisely, to see if a read will not block."


So, if the socket returned by select() can be read without blocking, you 
don't need to put the socket in non-blocking mode.


It's hard to say more since your strace output was cut.  I'd expect you 
to get another return from select() when the rest of the data arrives, 
and for recvfrom() to work at that point.  I can't tell if that's 
happening or not.  If it's not, then you probably have hit a bug.  The 
documented behavior for message-based sockets is to read the entire 
message in one operation, and to discard data on recvfrom() if it's too 
big for the buffer.  Maybe you're creating a condition where the system 
is discarding data if it can't be read in one operation.


Regardless, in the select()/recvfrom() pattern you described, the socket 
should be in blocking mode.


___
CentOS mailing list
CentOS@centos.org
https://lists.centos.org/mailman/listinfo/centos


[CentOS] UDP de-fragmentation problem

2016-04-07 Thread Volker
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.

- Rebuilding the application on Centos7 with centos supplied gcc, libs
etc does not make the problem go away.

- I have broken the application down to a small Qt test program which
opens a UDP socket, binds and waits on it

This is an strace output of the problem, where a 1 byte UDP packet
is send to the application, triggers the select(), then the
recvfrom(7...) fails with eagain
[...]
socket(PF_INET, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_IP) = 7
fcntl(7, F_GETFL)   = 0x2 (flags O_RDWR)
fcntl(7, F_SETFL, O_RDWR|O_NONBLOCK)= 0
setsockopt(7, SOL_SOCKET, SO_BROADCAST, [1], 4) = 0
bind(7, {sa_family=AF_INET, sin_port=htons(10001),
sin_addr=inet_addr("0.0.0.0")}, 16) = 0
getsockname(7, {sa_family=AF_INET, sin_port=htons(10001),
sin_addr=inet_addr("0.0.0.0")}, [16]) = 0
getpeername(7, 0x7ffdf3073470, [16])= -1 ENOTCONN (Transport
endpoint is not connected)
getsockopt(7, SOL_SOCKET, SO_TYPE, [2], [4]) = 0
select(8, [3 7], [], [], NULL)  = 1 (in [7])
recvfrom(7, 0x7ffdf3072e1b, 1, 2, 0x7ffdf3072e20, 0x7ffdf3072e1c) = -1
EAGAIN (Resource temporarily unavailable)
select(8, [3 7], [], [], NULL
[...]

And after the netfilter modules are loaded:
[...]
socket(PF_INET, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_IP) = 7
fcntl(7, F_GETFL)   = 0x2 (flags O_RDWR)
fcntl(7, F_SETFL, O_RDWR|O_NONBLOCK)= 0
setsockopt(7, SOL_SOCKET, SO_BROADCAST, [1], 4) = 0
bind(7, {sa_family=AF_INET, sin_port=htons(10001),
sin_addr=inet_addr("0.0.0.0")}, 16) = 0
getsockname(7, {sa_family=AF_INET, sin_port=htons(10001),
sin_addr=inet_addr("0.0.0.0")}, [16]) = 0
getpeername(7, 0x7ffc5939e8c0, [16])= -1 ENOTCONN (Transport
endpoint is not connected)
getsockopt(7, SOL_SOCKET, SO_TYPE, [2], [4]) = 0
select(8, [3 7], [], [], NULL)  = 1 (in [7])
recvfrom(7, "x", 1, MSG_PEEK, {sa_family=AF_INET, sin_port=htons(60921),
sin_addr=inet_addr("10.77.32.30")}, [16]) = 1
recvfrom(7, "x", 1, MSG_PEEK, {sa_family=AF_INET, sin_port=htons(60921),
sin_addr=inet_addr("10.77.32.30")}, [16]) = 1
recvfrom(7, ""..., 65536, 0,
{sa_family=AF_INET, sin_port=htons(60921),
sin_addr=inet_addr("10.77.32.30")}, [16]) = 1
recvfrom(7, 0x7ffc5939e0bb, 1, 2, 0x7ffc5939e0c0, 0x7ffc5939e0bc) = -1
EAGAIN (Resource temporarily unavailable)
select(8, [3 7], [], [], NULL
[...]


Any help? bug?

Regards
.Volker

___
CentOS mailing list
CentOS@centos.org
https://lists.centos.org/mailman/listinfo/centos