4

From version 8 onwards FreeBSD supports IP_BINDANY socket option which the man page defines as:

If the IP_BINDANY option is enabled on a SOCK_STREAM, SOCK_DGRAM or a SOCK_RAW socket, one can bind(2) to any address, even one not bound to any available network interface in the system. This functionality (in conjunction with special firewall rules) can be used for implementing a transparent proxy. The PRIV_NETINET_BINDANY privilege is needed to set this option.

Is it possible to write a Java program that can use this functionality? I have checked the docs of SocketOptions and it obviously does not list this option. So is there any workaround?

with regards,

raj

Rajkumar S
  • 2,471
  • 5
  • 23
  • 28
  • I can't think of anything short of wrapping C++ via RMI. It'd be totally implementation dependant. Do you know that you really NEED bind-any, or is it just a "nice-to-have"? – corlettk May 28 '11 at 11:49
  • 1
    I'm not sure what you're asking here. Java was designed with portability in mind and `IP_BINDANY` is FreeBSD-specific. You can try passing [`24`](http://people.freebsd.org/~pjd/patches/bindany.patch) to `setOption()`, but it will fail on other platforms. – Frédéric Hamidi May 28 '11 at 11:52
  • Thanks for your replies, I will try to send 24 to setOption() and check that. This feature is a must have, so if this is too difficult in Java I might go with Perl, and yes portability is not an issue. This needs to run only in FreeBSD. – Rajkumar S May 29 '11 at 06:27

2 Answers2

1

Is it possible to write a Java program that can use this functionality?

It is not possible using a pure Java.

So is there any workaround?

There are a couple of JNA/JNI based libraries for making Posix system calls from a Java program; see this SO question/answer for details:

I don't know if these are available for Java on FreeBSD.


On further thought, it might be possible to implement this in pure (though necessarily non-portable) Java. It would entail creating subclasses of SocketImpl and/or DatagramSocketImpl and the necessary infrastructure to use them. It would be complicated.

Community
  • 1
  • 1
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Thanks for your reply. Any case this program is supposed to run only on FreeBSD so portability is not an issue. – Rajkumar S May 29 '11 at 06:25
0

I wrote a library in JNA to do the setsockopt bit reasonably portably. You can find it here.

However, to change the bind behaviour you may need to dig further into the socket code. For why, see here, specifically this bit:

So we just need to create a new java.net.Socket object, call setsockopt() and finally call bind() on the socket - easy, right? Unfortunately, it’s not quite so simple - creating a new Socket object in Java (in OpenJDK and the Oracle JVM) does not actually allocate a file descriptor. Instead, the file descriptor is allocated within Java’s bind() function itself - making it rather difficult to call setsockopt() at the appropriate point.

The author presents a reasonably complex workaround - I'm not going to copy his entire article here though.

abligh
  • 24,573
  • 4
  • 47
  • 84