xiaoshua / junixsocket

Automatically exported from code.google.com/p/junixsocket
0 stars 0 forks source link

Wrong mapping of java.net.SocketOptions values into NativeUnixSocket.c #12

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Make a getSendBufferSize call on a connected AFUNIXSocket. On Linux, an
AFUNIXSocketException is thrown with message "Protocol not available".
2.
3.

What is the expected output? What do you see instead?
I would expect to get the buffer size.

What version of the product are you using? On what operating system?
1.2, RedHat Enterprise Linux 4

Please provide any additional information below.

I believe the problem is in how values are mapped in
AFUNIXSocketImpl.getOption(optID) and AFUNIXSocketImpl.setOption(optID,
value). The optID's in this context seem to be referring to SocketOption
constants values, but when I look at the C code for
Java_org_newsclub_net_unix_NativeUnixSocket_getSocketOptionInt and
Java_org_newsclub_net_unix_NativeUnixSocket_setSocketOptionInt, it is
referring to optIDs of the same name in C (e.g., SO_LINGER) which do NOT
correspond to the C values found in socket.h. For instance, on my system
SocketOptions.SO_LINGER = 128, but SO_LINGER in socket.h is 13.

Consequently most of the Java-level socket manipulation options not only
aren't implemented (not a big deal), but actually implement undefined behavior.

As a further complicating factor, the source code for
AFUNIXSocketImpl.setOption treats the SocketOptions.SO_RCVBUF and
SocketOptions.SO_SNDBUF cases as booleans; note the "expectBoolean" call. I
don't think this is right either, though it doesn't matter until the other
problem is addressed as well...

Original issue reported on code.google.com by clint.wo...@gmail.com on 7 May 2010 at 10:18

GoogleCodeExporter commented 9 years ago
How the openJDK handles this for TCP sockets:

In java.net.PlainSocketImpl there is a case statement across all known options 
to handle validation and preprocessing of the arguments (especially for Boolean 
arguments).

Within the native implementation, there is another mapping to the local 
(native) socket option values such as those found in sys/socket.h on Linux.

This makes the java implementation independent of the system values.  
Unfortunately, junixsocket should also try to be independent from the Java 
values.

The Java-side code should convert SocketOptions values to junixsocket values.  
The native-side code should convert junixsocket values to native values.

see relevant source from openjdk-6-src-b20-21_jun_2010 
(http://openjdk.java.net/projects/jdk6/)

PlainSocketImpl.java (setOption)
PlainSocketImpl.c (socketSetOption)
net_util_md.c (NET_MapSocketOption)

My suggestion for the easiest fix is to implement only the options which users 
request.  In this case, SO_SNDBUF and SO_RCVBUF.  Throw a SocketException for 
the others, until someone finds a use case (and test cast) for them.

Original comment by derrick....@gmail.com on 25 Jun 2010 at 5:17

GoogleCodeExporter commented 9 years ago
Changed in SVN trunk. Thanks for pointing this out!

Original comment by ckkohl79 on 20 Jul 2010 at 7:44

GoogleCodeExporter commented 9 years ago

Original comment by ckkohl79 on 20 Jul 2010 at 7:44

GoogleCodeExporter commented 9 years ago
Based on the diff:

The change was to map from the Java values to the native values by matching 
hard-coded numeric values (which correspond to the current Java values) and 
returning the values of SO_*.

This has the very unlikely failure case of Java changing the value of their 
socket option flags.

I appreciate the prompt fix.

Original comment by derrick....@gmail.com on 20 Jul 2010 at 8:18

GoogleCodeExporter commented 9 years ago
Thanks, Derrick.

I am pretty sure the Socket option flags will not change, as SocketOptions is 
part of the public Java API -- it would definitely break more than just 
junixsocket. Moreover, the numeric values correspond more or less to BSD's 
socket options (at least this is valid for OS X), so I guess they were never 
designed arbitrarily.

Best,
Christian

Original comment by ckkohl79 on 21 Jul 2010 at 8:30