Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Socket.isIPv6Preferred() may return an incorrect value #10909

Closed
trustin opened this issue Jan 4, 2021 · 5 comments
Closed

Socket.isIPv6Preferred() may return an incorrect value #10909

trustin opened this issue Jan 4, 2021 · 5 comments

Comments

@trustin
Copy link
Member

trustin commented Jan 4, 2021

Expected behavior

io.netty.channel.unix.Socket.isIPv6Preferred() returns true on a Linux system with IPv6 support, even if a user attempted to initialize io_uring support.

Actual behavior

false is returned even on a Linux system with IPv6 support when both Epoll and IOUring are loaded.

It seems like the secondly loaded library 'reverts' the initialization performed by the firstly loaded library when it's loaded. Native class of the both libraries attempt to call Socket.initialize(), but the second call will not have any effect because of an initialization check.

We could solve this problem either by:

  • resolving the JNI methods of Socket dynamically like we do for epoll and io_uring; or
  • (perhaps not a good idea) allowing the force re-initialization of Socket

Steps to reproduce

On Linux kernel without io_uring support (5.4.85 in my case),

  1. Attempt to load Epoll, which succeeds.
  2. Check if Socket.isIPv6Preferred() returns true, which should.
  3. Attempt to load IOUring, which fails due to a 'failed to allocate a ring buffer' error.
    • Note that the loading of native library has succeeded.
  4. Socket.isIPv6Preferred() suddenly starts to return false.

Minimal yet complete reproducer code (or URL to code)

Epoll.unavailabilityCause();
assertTrue(Socket.isIPv6Preferred());
IOUring.unavailabilityCause();
assertTrue(Socket.isIPv6Preferred()); // FAIL

Netty version

4.1.54

JVM version (e.g. java -version)

openjdk version "14.0.2" 2020-07-14
OpenJDK Runtime Environment AdoptOpenJDK (build 14.0.2+12)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 14.0.2+12, mixed mode, sharing)

OS version (e.g. uname -a)

Linux ... 5.4.85-1-MANJARO #1 SMP PREEMPT Mon Dec 21 21:38:53 UTC 2020 x86_64 GNU/Linux
@trustin trustin added the defect label Jan 4, 2021
@trustin
Copy link
Member Author

trustin commented Jan 4, 2021

Possible workarounds for this issue at the moment are:

  • Do not load both epoll and io_uring transport; or
  • Call Socket.initialize(NetUtil.isIPv4StackPreferred()) reflectively with the setAccessible(true) trick.

I'm currently using the second workaround because Armeria currently tries to detect all available native transports upfront.

trustin added a commit to trustin/armeria that referenced this issue Jan 4, 2021
…ive library

Motivation:

Since 4edffc8, we check whether epoll
and io_uring native transports are available or not upfront. However,
there's a known issue in Netty where `Socket.isIPv6Preferred()` can
return a wrong value when more than one native transport are loaded:

- netty/netty#10909

Modifications:

- Force-reinitialize `Socket` by calling its private method after a new
  native library is loaded, so that `Socket.isIPv6Preferred()` always
  returns a correct value.

Result:

- We don't get the 'Address family not supported by protocol' or
  'Connection refused' error anymore.
- Works around netty/netty#10909 until it's
  fixed.
@normanmaurer
Copy link
Member

@trustin
Copy link
Member Author

trustin commented Jan 4, 2021

Oh, that's awesome 😄

@trustin trustin added this to the 4.1.57.Final milestone Jan 5, 2021
@trustin trustin closed this as completed Jan 5, 2021
@trustin
Copy link
Member Author

trustin commented Mar 30, 2021

I found I can actually reproduce this problem with 4.1.58 and 0.0.3 🤔

@normanmaurer
Copy link
Member

Please open a new issue and a reproducer :)

trustin added a commit to trustin/armeria that referenced this issue Mar 30, 2021
Since 4edffc8, we check whether epoll
and io_uring native transports are available or not upfront. However,
there's a known issue in Netty where `Socket.isIPv6Preferred()` can
return a wrong value when more than one native transport are loaded:

- netty/netty#10909

Modifications:

- Force-reinitialize `Socket` by calling its private method after a new
  native library is loaded, so that `Socket.isIPv6Preferred()` always
  returns a correct value.

Result:

- We don't get the 'Address family not supported by protocol' or
  'Connection refused' error anymore.
- Works around netty/netty#10909 until it's
  fixed.
trustin added a commit to trustin/armeria that referenced this issue Mar 30, 2021
…ive library

Motivation:

Since 4edffc8, we check whether epoll
and io_uring native transports are available or not upfront. However,
there's a known issue in Netty where `Socket.isIPv6Preferred()` can
return a wrong value when more than one native transport are loaded:

- netty/netty#10909

Modifications:

- Force-reinitialize `Socket` by calling its private method after a new
  native library is loaded, so that `Socket.isIPv6Preferred()` always
  returns a correct value.

Result:

- We don't get the 'Address family not supported by protocol' or
  'Connection refused' error anymore.
- Works around netty/netty#10909 until it's
  fixed.
trustin added a commit to line/armeria that referenced this issue Mar 31, 2021
…e library (#3425)

Motivation:

Since 4edffc8, we check whether epoll
and io_uring native transports are available or not upfront. However,
there's a known issue in Netty where `Socket.isIPv6Preferred()` can
return a wrong value when more than one native transport are loaded:

- netty/netty#10909

Modifications:

- Force-reinitialize `Socket` by calling its private method after a new
  native library is loaded, so that `Socket.isIPv6Preferred()` always
  returns a correct value.

Result:

- We don't get the 'Address family not supported by protocol' or
  'Connection refused' error anymore.
- Works around netty/netty#10909 until it's
  fixed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants