RFR: JDK-8313873: java/nio/channels/DatagramChannel/SendReceiveMaxSize.java fails on AIX due to small default RCVBUF size and different IPv6 Header interpretation [v6]

Daniel Fuchs dfuchs at openjdk.org
Thu Aug 24 10:48:27 UTC 2023


On Tue, 22 Aug 2023 16:29:47 GMT, Thomas Obermeier <duke at openjdk.org> wrote:

>> Description from JBS Bug:
>> When trying to receive (recvfrom()) the greatest possible UDP Datagram package of size 65507 Bytes, the recvfrom() API got stuck due to a smaller default udp_recvspace of 42080 Bytes. This can be checked by the command 
>> 
>> no -a | grep space
>> 
>>             tcp_recvspace = 16384
>> 
>>             tcp_sendspace = 16384
>> 
>>             udp_recvspace = 42080
>> 
>>             udp_sendspace = 9216
>> 
>> There are at least two ways to fix this. Either in the test program itself, by dynamically enlarging the receiver buffer of the socket used in recvfrom() explicitly, or by raising the OS default to a higher limit (The linux default seems to be about 200KB). Setting the AIX default can be done with the command e.g. (value should be at least greater than 65535)
>> 
>> no -r -o udp_recvspace=132768
>> 
>> I would prefer raising the default, and document it for the customer, so he knows he cannot use larger datagram packets than 42080 without raising the default size of the udp_recvspace when he does not want his program ending in a hang state.
>> 
>> 
>> 
>> The second bug comes from a different interpretation of the IPv6 header field Payload Length. Here is the background:
>> 
>> An IP Packet consists of the IP Header and the IP Payload (e.g. a Datagram). in IPv4 the IP-Header contains the 16-Bit Field Total Length
>> 
>> Total Length:  This 16-bit field defines the entire packet size in bytes, including header and data.
>> 
>> [Internet Protocol version 4 - Wikipedia|https://en.wikipedia.org/wiki/Internet_Protocol_version_4#Total_Length]
>> 
>> This means the total IP-Packet could have only 65535 Bytes. From this value you have to subtract 20 Bytes for the IP-Header and additional 8 Bytes for the UDP-Header to receive maximum of 65507 UDP Datagram Payload Bytes. Here AIX and Linux both have the same opinion.
>> 
>> In IPv6 the IP-Header contains the field Payload Length
>> 
>> Payload Length (16 bits) The size of the payload in octets, including any extension headers. The length is set to zero when a Hop-by-Hop extension header carries a Jumbo Payload option.
>> 
>> [IPv6 packet - Wikipedia|https://en.wikipedia.org/wiki/IPv6_packet]
>> 
>> This means not the total length of IP Packet is restricted to 65535 Bytes, but the size of the Payload. The IP-Packet could have a size of 65535+40 (IPv6-Header has 40 Bytes). Linux is going this way and therefore allows a UDP Payload of  65535 -8 (UDP-Header has 8 Bytes) = 65527.
>> 
>> IBM seems to interpret this field ...
>
> Thomas Obermeier has updated the pull request incrementally with one additional commit since the last revision:
> 
>   8313873: Update SendReceiveMaxSize.java - trailing blanks

The DatagramSocket test doesn't use the loopback - it uses a single address:

        HOST_ADDR = InetAddress.getLocalHost();

I guess that it's possible depending on the test machine configuration that this will always be an IPv4 address even in the case where `-Djava.net.preferIPv6Addresses=true`.

Maybe the DatagramSocket test could be changed to additionally use the loopback like the DatagramChannel test, in which case I assume it would need to use the new `IPSupport` method too.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/15209#issuecomment-1691445181


More information about the nio-dev mailing list