Unix domain sockets (UDS, AF_UNIX) in System.inheritedChannel() and elsewhere in Java

František Kučera franta-java at frantovo.cz
Sun Jul 21 10:01:25 UTC 2019


Dne 19. 07. 19 v 18:10 Alan Bateman napsal(a):
> This is something that we've prototyped several times over the years 
> but never came to a conclusion on whether to attempt to include it or not
Albeit decades after other operating systems :-) even MS Windows are now 
able to work with unix domain sockets. So current situation is IMHO 
different and UDS could be considered to be fully multiplatform 
technology comparable to TCP or UDP.
> In terms of API then introducing a SocketAddress sub-class for Unix 
> domain sockets looks right, although it should probably be created 
> with a Path or String rather than a byte array.

I would also prefer String or Path in the Java API but 
sockaddr_un.sun_path is defined in the POSIX standard as a byte array 
and it might be not only a file path but there are also "abstract" paths 
which have no representation on the filesystem – they start with \0 
null-byte and the abstract path is the whole rest of the array. So 
lossless mapping between byte arrays and strings will be difficult or 
maybe impossible (the "@" character is sometimes used in the UI instead 
of the \0 but "@" is also valid character on the filesystem path, so 
there are ambiguities).  Although Java Sting can hold the \0 bytes, 
depending on local encoding there might be edge cases where the path is 
a valid byte array (sun_path) and is addressable from the POSIX API but 
is not a valid String in given encoding. Maybe there might be subclasses 
for abstract and non-abstract addresses... but in the prototype, I 
looked for the simplest solution (but buggy, I know, it e.g. includes 
all the \0s in the toString() representation).

> No objection to exploring it again but I think it should be prototyped 
> as a JDK-specific API, probably jdk.net module.

I can implement it as a module, but I need help with some design issues:

The System.inheritedChannel() is in the Java base – there might be some 
indirect/optional dependency from the base to the module. Idea: create 
an SPI interface with methods canCreateChannel(fd) and 
createChannel(fd); the new module will implement this interface for 
AF_UNIX file descriptors; and the System.inheritedChannel() will lookup 
implementations of this interface and try to get the channel from them; 
and if no implementation will return a channel, it will fallback to the 
current implementation. Is it possible solution?

May the java.net.UnixSocketAddress and 
java.net.StandardProtocolFamily.UNIX stay where they are?

My primary goal was to fix the wrong addresses (random IP and port) 
returned from System.inheritedChannel() but then I also implemented the 
UDS client/server creation from java… These tasks might be solved 
separately – but then: is it possible to have also an SPI lookup in case 
of creating new UDS sockets? I would be happy if this will be possible:

ServerSocketChannel server = 
ServerSocketChannel.open(StandardProtocolFamily.UNIX);
UnixSocketAddress serverAddress = new 
UnixSocketAddress("/run/my-unix-socket");
server.bind(serverAddress);

i.e. the UDS implementation will be separated in a module, but from the 
application point-of-view, it will be accessible through standard API 
(same way as TCP or UDP) and an internal SPI lookup.

Franta



More information about the net-dev mailing list