Coder Social home page Coder Social logo

Comments (11)

headius avatar headius commented on July 22, 2024

It seems like we may be using a bad value for one of the parameters to setsockopt within this code:

if (0 != Native.setsockopt(fd, SocketLevel.SOL_SOCKET, optname, optvalue)) {
throw new IOException(Native.getLastErrorString());
}

The UnixSocketOption value for SO_RCVTIMEO used for the setSoTimeout is mapped to a value from jnr-constants at this line of code:

wMap.put(UnixSocketOptions.SO_RCVTIMEO, jnr.constants.platform.SocketOption.SO_RCVTIMEO);

So at this point I would suspect that the value defined there is not correct for your flavor of Solaris.

I will need some help investigating this! The values in jnr-constants (linked above) are generated from the actual C constants on a given platform. If you look here you can see the values we are currently using for all Solaris flavors. Can you look into the C socket headers on your system and see if these values match?

If they don't we may finally be forced to split these constants by hardware platform as well as by OS.

The only workaround at this point would be for you to reflectively dig out the file descriptor and call setsockopt yourself with the proper values, either by binding setsockopt on your own (using jnr-ffi, the native binding library behind jnr-unixsocket) or by using reflection to dig into the function already bound by jnr-unixsocket here.

Alternatively, if you are able to give me shell access to a matching environment, I can do the investigation myself.

from jnr-unixsocket.

wolfchimneyrock avatar wolfchimneyrock commented on July 22, 2024

the constants are the same on my sys/socket.h as in your jnr-constants package:

 #define SO_RCVTIMEO 0x1006      /* receive timeout */

from jnr-unixsocket.

wolfchimneyrock avatar wolfchimneyrock commented on July 22, 2024

the workaround I have done that works is to switch to non-blocking on the client channel, it is a little more complicated to use but it allows the timeout to be used in the select() call.

Unfortunately we can't give out shell access. Though I would be happy to do an attempt at setsockopt() using reflection

from jnr-unixsocket.

wolfchimneyrock avatar wolfchimneyrock commented on July 22, 2024

When I run the following:

        UnixSocketChannel channel = UnixSocketChannel.create();

        try {
            Class<?> nativeClass = Class.forName("jnr.unixsocket.Native");
            Method setsockopt = nativeClass.getDeclaredMethod("setsockopt", int.class, SocketLevel.class, SocketOption.class, int.class);
            setsockopt.setAccessible(true);
            Integer result = (Integer)setsockopt.invoke(null, channel.getFD(), SocketLevel.SOL_SOCKET, SocketOption.SO_RCVTIMEO, 10);
            System.out.println("setsockopt result = " + result);
        } catch (Exception e) {
            e.printStackTrace();
        }

on linux/amd64: setsockopt result = 0
on AIX/power9: setsockopt result = 0
on Solaris 11.3/sparc: setsockopt result = -1

Can you walk me through how I could make custom values of the SocketLevel and SocketOption ?

from jnr-unixsocket.

headius avatar headius commented on July 22, 2024

Perhaps the mismatch is in SocketLevel?

https://github.com/jnr/jnr-constants/blob/master/src/main/java/jnr/constants/platform/solaris/SocketLevel.java

It seems that the setsockopt function is being called, but we are getting this error. Another thing you could investigate would be to add code to your println to check the errno value. I suspect it will be EINVAL, though.

System.out.println("errno: " + LastError.getLastError(Runtime.getSystemRuntime()));

(untested code but you can see the equivalent here:

return strerror(LastError.getLastError(Runtime.getSystemRuntime()));

from jnr-unixsocket.

wolfchimneyrock avatar wolfchimneyrock commented on July 22, 2024

errno = 99 => ENOPROTOOPT

from jnr-unixsocket.

wolfchimneyrock avatar wolfchimneyrock commented on July 22, 2024

If I do the same thing but set SO_RCVBUF it works fine

from jnr-unixsocket.

wolfchimneyrock avatar wolfchimneyrock commented on July 22, 2024

I notice the man page for setsockopt on Solaris 11.3 doesn't mention SO_RCVTIMEO:
https://docs.oracle.com/cd/E86824_01/html/E54774/setsockopt-3socket.html#scrolltoc

whereas the man page for setsockopt on Solaris 11.4 does mention it:
https://docs.oracle.com/cd/E88353_01/html/E37843/setsockopt-3c.html#scrolltoc

from jnr-unixsocket.

headius avatar headius commented on July 22, 2024

So then it is possible this socket option is simply not supported? Maybe there is a different option that has a similar effect?

from jnr-unixsocket.

wolfchimneyrock avatar wolfchimneyrock commented on July 22, 2024

yeah I think thats the case - can't set a timeout for blocking socket read. Like I said earlier, the work around is to make the channel non-blocking and use a Selector.

from jnr-unixsocket.

headius avatar headius commented on July 22, 2024

Okay, that is a non-trivial workaround but I'm glad you have something to go forward with. If you are able to determine that there is some other way we can adjust this timeout on earlier versions of solaris, please open a new issue. I will close this issue since there's not much we can do at the moment.

from jnr-unixsocket.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.