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