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

JRuby Addrinfo.addrinfo does not match MRI Ruby or system sort order #4594

Closed
adrienthebo opened this issue May 8, 2017 · 4 comments
Closed
Milestone

Comments

@adrienthebo
Copy link

adrienthebo commented May 8, 2017

RFC 6724 indicates that by default ipv6 addresses should be sorted before ipv4 addresses. On Linux getaddrinfo(3) documents that "The sorting function used within getaddrinfo() is defined in RFC 3484; the order can be tweaked for a particular system by editing /etc/gai.conf (available since glibc 2.5)." (RFC6724 superceded RFC3484.)

Using the system resolution on an IPv6 enabled host via getent matches this behavior, as does Ruby 2.1.5, but JRuby does not match this behavior.

Downstream ticket: https://tickets.puppetlabs.com/browse/SERVER-1801

Environment

  • Operating system: Debian 8 amd64
  • Linux orestes 4.4.0-x86_64-linode63 Project suggestions #2 SMP Tue Jan 19 12:43:53 EST 2016 x86_64 GNU/Linux
  • JRuby 1.7.16 and JRuby 9.1.6.0

In this scenario /etc/gai.conf is the default that ships with Debian 8.

Desired ordering

└> getent ahosts google.com       
2607:f8b0:4005:806::200e STREAM google.com
2607:f8b0:4005:806::200e DGRAM  
2607:f8b0:4005:806::200e RAW    
216.58.195.238  STREAM 
216.58.195.238  DGRAM  
216.58.195.238  RAW    
216.58.195.238  STREAM 
216.58.195.238  DGRAM  
216.58.195.238  RAW    
216.58.195.238  STREAM 
216.58.195.238  DGRAM  
216.58.195.238  RAW  

Test script

#!/usr/bin/env ruby
# addrinfo.rb
 
require 'socket'
 
puts "Ruby engine: #{RUBY_ENGINE}, Ruby version: #{RUBY_VERSION}"
 
addr = Addrinfo.getaddrinfo('google.com', 'ssh', Socket::AF_UNSPEC, :STREAM)
puts "All address info: #{addr.inspect}"
puts "First IP address: #{addr.first.ip_address}"

Expected Behavior

The ordering of Addrinfo.getaddrinfo should respect the ordering given by /etc/gai.conf and match the behavior of MRI ruby.

Using the system Ruby on Debian 8:

Ruby engine: ruby, Ruby version: 2.1.5
All address info: [#<Addrinfo: [2607:f8b0:4005:806::200e]:22 TCP (google.com:ssh)>, #<Addrinfo: 216.58.195.238:22 TCP (google.com:ssh)>, #<Addrinfo: 216.58.195.238:22 TCP (google.com:ssh)>, #<Addrinfo: 216.58.195.238:22 TCP (google.com:ssh)>]
First IP address: 2607:f8b0:4005:806::200e

Actual Behavior

└> rbenv shell jruby-1.7.16
└> ruby --version
jruby 1.7.16 (1.9.3p392) 2014-09-25 575b395 on OpenJDK 64-Bit Server VM 1.7.0_121-b00 +jit [linux-amd64]
└> ruby addrinfo.rb 
Ruby engine: jruby, Ruby version: 1.9.3
All address info: [#<Addrinfo: 216.58.195.238:22>, #<Addrinfo: 2607:f8b0:4005:806:0:0:0:200e:22>]
First IP address: 216.58.195.238
└> rbenv shell jruby-9.1.6.0
└> ruby --version
jruby 9.1.6.0 (2.3.1) 2016-11-09 0150a76 OpenJDK 64-Bit Server VM 24.121-b00 on 1.7.0_121-b00 +jit [linux-x86_64]
└> ruby addrinfo.rb 
Ruby engine: jruby, Ruby version: 2.3.1
All address info: [#<Addrinfo: 216.58.195.238:22>, #<Addrinfo: [2607:f8b0:4005:806::200e]:22>]
First IP address: 216.58.195.238
@headius
Copy link
Member

headius commented May 9, 2017

This appears to be Java behavior.

We simply use InetAddress.getAllByName, which by default on Java prefers IPv4 addresses (and as a result lists them first.

You can set a JVM property `java.net.preferIPv6Addresses=true" to get the behavior you're looking for.

~/projects/jruby $ jruby blah.rb
Ruby engine: jruby, Ruby version: 2.3.3
All address info: [#<Addrinfo: 172.217.4.238:22>, #<Addrinfo: [2607:f8b0:4009:801::200e]:22>]
First IP address: 172.217.4.238

~/projects/jruby $ jruby -J-Djava.net.preferIPv6Addresses=true blah.rb
Ruby engine: jruby, Ruby version: 2.3.3
All address info: [#<Addrinfo: [2607:f8b0:4009:801::200e]:22>, #<Addrinfo: 172.217.4.238:22>]
First IP address: 2607:f8b0:4009:801::200e

Here's a page detailing this and other configs and the justification (backwards compatibility) for the IPv4 preference: https://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html

@headius headius closed this as completed May 9, 2017
@headius headius added this to the Won't Fix milestone May 9, 2017
@headius
Copy link
Member

headius commented May 9, 2017

I'm closing this as Won't Fix because we're just projecting Java behavior here. If you think there's something more we should be doing, we can discuss it.

@adrienthebo
Copy link
Author

@headius thanks for taking the time to look at this issue!

@rudybroersma
Copy link

I am the author of the downstream ticket. I understand that the root cause of this issue is a setting in Java. A setting I believe has an incorrect default value, but I wont try to correct that, as it is probably not going to happen.

However, is this perhaps something we can and perhaps should fix in JRuby?

Let me start by saying I don't know if JRuby tries to be identical to regular Ruby in regard to code output, or if i should see JRuby as a separate project that is only related to regular Ruby. So I do not know if the difference in output of Ruby vs JRuby is an issue or not.

However, the setting in Java can be changed runtime:
System.setProperty("java.net.preferIPv6Addresses", "true");

Is that something JRuby would consider? By setting this value to true, it complies to the documentation which states IPv6 should come first, as described here:

https://apidock.com/ruby/v1_8_7_72/Socket/getaddrinfo/class (third bullet)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants