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

ServerSocket#accept_nonblock returns the server's port, not the client's #1777

Closed
iconara opened this issue Jul 1, 2014 · 1 comment
Closed
Milestone

Comments

@iconara
Copy link
Contributor

iconara commented Jul 1, 2014

Socket#accept_nonblock (ServerSocket#accept_nonblock in JRuby) returns the client socket and the client's address. However, in JRuby the address is wrong, the port is the server's and not the connecting client's.

Here's a demonstration, run with for example rvm jruby-1.7.12,ruby-2.1.1 do ruby path/to/script.rb:

require 'socket'

ServerSocketImpl = RUBY_ENGINE == 'jruby' ? ::ServerSocket : Socket

# add  `+ rand(100)` or something similar here if you want to run
# multiple times and avoid getting "address already in use" error
server_port = 8888

addrinfos = Socket.getaddrinfo('localhost', server_port, nil, Socket::SOCK_STREAM)
_, port, _, ip, address_family, socket_type = addrinfos.shift
sockaddr = Socket.sockaddr_in(port, ip)

client_socket = Socket.new(address_family, socket_type, 0)
server_socket = ServerSocketImpl.new(address_family, socket_type, 0)

if RUBY_ENGINE == 'jruby'
  server_socket.bind(sockaddr, 5)
else
  server_socket.bind(sockaddr)
  server_socket.listen(5)
end

begin
  client_socket.connect_nonblock(sockaddr)
rescue IO::EINPROGRESSWaitWritable
end

IO.select([server_socket])
client_socket, client_sockaddr = server_socket.accept_nonblock
port, host = Socket.unpack_sockaddr_in(client_sockaddr)
puts "#{RUBY_ENGINE} Client connected from #{host}:#{port}"

This is the output I get:

jruby Client connected from 127.0.0.1:8888
ruby Client connected from ::1:52090

Notice that in JRuby the port is the one the server is running on and in MRI it's the port the client connects from.

@iconara
Copy link
Contributor Author

iconara commented Jul 1, 2014

The error seems to be on this line: RubyServerSocket.java#L171, it should probably be getRemoteSocketAddress() instead of getLocalSocketAddress().

I will test and send a pull request with the fix.

headius added a commit that referenced this issue Jul 25, 2014
Fix #1777: ServerSocket#accept_nonblock to return a correct Sockaddr
@headius headius added this to the JRuby 1.7.14 milestone Jul 25, 2014
@enebo enebo modified the milestones: JRuby 1.7.14, JRuby 1.7.15 Aug 27, 2014
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