JRuby

TCPSocket.new(dest_adrr, dest_port, src_addr, src_port) missing from JRuby

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Minor Minor
  • Resolution: Fixed
  • Affects Version/s: JRuby 1.0.0
  • Fix Version/s: JRuby 1.2
  • Component/s: Core Classes/Modules
  • Labels:
    None
  • Number of attachments :
    0

Description

TCPSocket.new(dest_addr, dest_port) works just fine. However, if a user wishes to specify the source address and port for the TCPSocket, there is no way to do this.

In MRI, you could use Socket.new() to create the TCPSocket, but this doesn't work in JRuby.

Thanks!

Activity

Hide
Thomas E Enebo added a comment -

I fixed this on trunk (commit 4267) but had a weird time matching MRI/socket library behavior for localhost so I am luke warm about committing this to 1.0 branch until someone has verified/used this new TCPSocket.new code. Can the original reporter try their code against trunk to see if things are peachy?

Leaving open to indicate it is candidate for 1.0 branch.

Show
Thomas E Enebo added a comment - I fixed this on trunk (commit 4267) but had a weird time matching MRI/socket library behavior for localhost so I am luke warm about committing this to 1.0 branch until someone has verified/used this new TCPSocket.new code. Can the original reporter try their code against trunk to see if things are peachy? Leaving open to indicate it is candidate for 1.0 branch.
Hide
Alex D added a comment -

Thanks for the update. I've tried the trunk, and and can now call TCPSocket.new() with four parameters. However, the behaviour is really weird. I've been running Wireshark to figure out what is actually happening, and I just can't understand it. It looks like two TCP sockets are opened - one on the port I want, and one on a random port. It looks like the action is happening on both sockets, but, because the random one is opened first, that one completes first. Very strange...

Show
Alex D added a comment - Thanks for the update. I've tried the trunk, and and can now call TCPSocket.new() with four parameters. However, the behaviour is really weird. I've been running Wireshark to figure out what is actually happening, and I just can't understand it. It looks like two TCP sockets are opened - one on the port I want, and one on a random port. It looks like the action is happening on both sockets, but, because the random one is opened first, that one completes first. Very strange...
Hide
Thomas E Enebo added a comment -

Out of curiousity do you see these two connection with the two parameter version as well? I am wondering if the SocketChannel class we use on the socket is responsible for the second connection. If so, then the two parameter connection should do the same thing.

Show
Thomas E Enebo added a comment - Out of curiousity do you see these two connection with the two parameter version as well? I am wondering if the SocketChannel class we use on the socket is responsible for the second connection. If so, then the two parameter connection should do the same thing.
Hide
Alex D added a comment -

I think that the four parameter version worked fine when the src_port was specified as 0. It was only when I used an explicit port number that things went wrong.

Thanks!

Show
Alex D added a comment - I think that the four parameter version worked fine when the src_port was specified as 0. It was only when I used an explicit port number that things went wrong. Thanks!
Hide
Charles Oliver Nutter added a comment -

Sounds like this is a safe backport to 1.0. Tom, can you take it?

Show
Charles Oliver Nutter added a comment - Sounds like this is a safe backport to 1.0. Tom, can you take it?
Hide
Thomas E Enebo added a comment -

This has problems which still need addressing on trunk much less moving to branch. We at least accept four params now, but something is not quite right. We appear to make multiple port connections.

Show
Thomas E Enebo added a comment - This has problems which still need addressing on trunk much less moving to branch. We at least accept four params now, but something is not quite right. We appear to make multiple port connections.
Hide
Charles Oliver Nutter added a comment -

Bumping off 1.0.2...Tom, if you think it can get into 1.0.2 go ahead.

Show
Charles Oliver Nutter added a comment - Bumping off 1.0.2...Tom, if you think it can get into 1.0.2 go ahead.
Hide
Joshua Graham added a comment -

Well according to the RubyTCPSocket source that I'm looking at (trunk rev 4998) of JRuby 1.1, it is doing nothing wrong as far as Java NIO is concerned. The problems with an ephemeral local port being ("accidentally") opened and then the specified local port being opened for connected socket aren't happening on Windows XP and JDK 1.6.

When attempting the following command line args: -C -e "require 'socket'; TCPSocket.new('mail.grahamis.com', 25, 'localhost', 1)" which should refuse connection, I get the following TCP activity on Windows

<pre>
C:\>netstat -p TCP -n
TCP 192.168.2.100:1086 74.50.13.92:143 ESTABLISHED
TCP 192.168.2.100:1087 74.50.13.92:143 ESTABLISHED

C:\>netstat -p TCP -n
TCP 127.0.0.1:1 74.50.13.92:25 SYN_SENT
TCP 192.168.2.100:1086 74.50.13.92:143 ESTABLISHED
TCP 192.168.2.100:1087 74.50.13.92:143 ESTABLISHED

-e:1:in `new': Connection refused (Errno::ECONNREFUSED)

C:\>netstat -p TCP -n
TCP 192.168.2.100:1086 74.50.13.92:143 ESTABLISHED
TCP 192.168.2.100:1087 74.50.13.92:143 ESTABLISHED
</pre>

No junk local ports got opened as far as netstat was concerned. I would have expected to see something like this if there was a zombie ephemeral port opened:

TCP 127.0.0.1:2021 0.0.0.0:0 UNKNOWN

Alex should have another test?

Show
Joshua Graham added a comment - Well according to the RubyTCPSocket source that I'm looking at (trunk rev 4998) of JRuby 1.1, it is doing nothing wrong as far as Java NIO is concerned. The problems with an ephemeral local port being ("accidentally") opened and then the specified local port being opened for connected socket aren't happening on Windows XP and JDK 1.6. When attempting the following command line args: -C -e "require 'socket'; TCPSocket.new('mail.grahamis.com', 25, 'localhost', 1)" which should refuse connection, I get the following TCP activity on Windows <pre> C:\>netstat -p TCP -n TCP 192.168.2.100:1086 74.50.13.92:143 ESTABLISHED TCP 192.168.2.100:1087 74.50.13.92:143 ESTABLISHED C:\>netstat -p TCP -n TCP 127.0.0.1:1 74.50.13.92:25 SYN_SENT TCP 192.168.2.100:1086 74.50.13.92:143 ESTABLISHED TCP 192.168.2.100:1087 74.50.13.92:143 ESTABLISHED -e:1:in `new': Connection refused (Errno::ECONNREFUSED) C:\>netstat -p TCP -n TCP 192.168.2.100:1086 74.50.13.92:143 ESTABLISHED TCP 192.168.2.100:1087 74.50.13.92:143 ESTABLISHED </pre> No junk local ports got opened as far as netstat was concerned. I would have expected to see something like this if there was a zombie ephemeral port opened: TCP 127.0.0.1:2021 0.0.0.0:0 UNKNOWN Alex should have another test?
Hide
Charles Oliver Nutter added a comment -

This doesn't seem quite right on trunk either, so I think it's still broken. Bumping off dead 1.0 branch.

Show
Charles Oliver Nutter added a comment - This doesn't seem quite right on trunk either, so I think it's still broken. Bumping off dead 1.0 branch.
Hide
Charles Oliver Nutter added a comment -

Punting...it's been around forever and nobody seems to want to/know how to tackle it.

Show
Charles Oliver Nutter added a comment - Punting...it's been around forever and nobody seems to want to/know how to tackle it.
Hide
Charles Oliver Nutter added a comment -

I made a small change for this that I think should resolve remaining issues

Before, a SocketChannel was opened, the related socket had "bind" and "connect" called on it, and then SocketChannel.finishConnect was called. I suspect this last call may have caused the channel to try to re-open a new connection and possible abandon the old one (which would then go into TIME_WAIT and eventually disconnect. Unfortunately I was unable to reproduce the double-socket thing...I think it's too transient to notice with netstat -a.

My modification simply constructs a Socket object, calls bind and connect, and then gets the underlying channel. This will hopefully eliminate the double-socket you noticed. Please confirm.

I also am not sure the best way to test this, so if you can please submit a simple test case that does not depend on an outside server, it would be most appreciated.

Committed in r9162.

Show
Charles Oliver Nutter added a comment - I made a small change for this that I think should resolve remaining issues Before, a SocketChannel was opened, the related socket had "bind" and "connect" called on it, and then SocketChannel.finishConnect was called. I suspect this last call may have caused the channel to try to re-open a new connection and possible abandon the old one (which would then go into TIME_WAIT and eventually disconnect. Unfortunately I was unable to reproduce the double-socket thing...I think it's too transient to notice with netstat -a. My modification simply constructs a Socket object, calls bind and connect, and then gets the underlying channel. This will hopefully eliminate the double-socket you noticed. Please confirm. I also am not sure the best way to test this, so if you can please submit a simple test case that does not depend on an outside server, it would be most appreciated. Committed in r9162.

People

Vote (0)
Watch (1)

Dates

  • Created:
    Updated:
    Resolved: