JDK-8313873 : java/nio/channels/DatagramChannel/SendReceiveMaxSize.java fails on AIX due to small default RCVBUF size and different IPv6 Header interpretation
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.nio
  • Affected Version: 21,22
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: aix
  • CPU: ppc
  • Submitted: 2023-08-07
  • Updated: 2024-05-29
  • Resolved: 2023-08-31
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 17 JDK 21 JDK 22
17.0.13-oracleFixed 21.0.2Fixed 22 b14Fixed
Related Reports
Duplicate :  
Description
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 like IPv4 and still uses 65535 as maximum IPv6 Packet size. Then the resulting size for the UDP-Payload is 40 Bytes less; e.g.  65535 - 40 - 8 = 65487


If we use the maximum value for linux (65527) then the sendto() API of AIX claims that this is too large and breaks in error.

So to fix this we can use 65527 for all other platforms and 65487 only for AIX. This has to be adopted in java/nio/channels/DatagramChannel/SendReceiveMaxSize.java itself.

Comments
[jdk17u-fix-request] Approval Request from Martin Should get backported for parity with 17.0.13-oracle. Applies cleanly except Copyright year update. Tier1-4 have passed.
28-05-2024

A pull request was submitted for review. URL: https://git.openjdk.org/jdk17u-dev/pull/2496 Date: 2024-05-27 15:36:49 +0000
27-05-2024

[jdk21u-fix-request] Approval Request from JoKern65 Backport of test fix for AIX. No risk, clean backport.
13-09-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk21u/pull/155 Date: 2023-09-12 14:03:06 +0000
12-09-2023

Changeset: 486fa08d Author: Thomas Obermeier <thomas.obermeier@sap.com> Committer: Thomas Stuefe <stuefe@openjdk.org> Date: 2023-08-31 09:51:13 +0000 URL: https://git.openjdk.org/jdk/commit/486fa08d4b22243443d39efa34c78d7e9eb44775
31-08-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/15209 Date: 2023-08-09 14:35:26 +0000
09-08-2023

Thanks, [~jkern], for the analysis. Regarding the RCVBUF, would it be an option to always check its size and enlarge it if necessary to a value beyond the maximum packet size when creating a socket on AIX? Then this could work transparently without a user's need to configure anything. Any hints, [~alanb]? As for the IPv6 maximum packet size, I guess the different size for AIX should be implemented as you described.
07-08-2023