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.