Skip to content

Commit

Permalink
native: Probe availability of abstract socket namespace on Linux
Browse files Browse the repository at this point in the history
When using a Linux emulation layer like NetBSD or FreeBSD, the abstract
socket namespace may not be available.

Try to bind on an abstract socket upon initialization. If that fails,
don't add the "CAPABILITY_ABSTRACT_NAMESPACE" capability.
  • Loading branch information
kohlschuetter committed Feb 14, 2024
1 parent a30644e commit 3a88285
Showing 1 changed file with 35 additions and 1 deletion.
36 changes: 35 additions & 1 deletion junixsocket-native/src/main/c/capabilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
#include "config.h"
#include "capabilities.h"

#if defined(__linux__)
#include <sys/socket.h>
#include <sys/un.h>
#endif

#include "filedescriptors.h"
#include "init.h"
#include "reflection.h"
Expand Down Expand Up @@ -48,6 +53,30 @@ void init_capabilities(JNIEnv *env CK_UNUSED) {
void destroy_capabilities(JNIEnv *env CK_UNUSED) {
}

#if defined(__linux__)
static bool checkHasAbstractNamespace(void) {
bool hasAbstractNamespace = true;

struct sockaddr_un addr = {
.sun_family = AF_UNIX,
.sun_path = "\0junixsocket-capability-abstract\0"
};

int sockFd = socket(AF_UNIX, SOCK_STREAM, 0);
if(sockFd != -1) {
if(bind(sockFd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) == -1) {
// typically, ENOENT is returned on NetBSD/FreeBSD
if(errno != EADDRINUSE) {
hasAbstractNamespace = false;
}
}
close(sockFd);
}

return hasAbstractNamespace;
}
#endif

/*
* Class: org_newsclub_net_unix_NativeUnixSocket
* Method: capabilities
Expand Down Expand Up @@ -83,7 +112,12 @@ defined(SO_PEERCRED) || defined(SO_PEERID) || defined(__NetBSD__) || defined(__s
// despite earlier claims [1], it's not supported in Windows 10 (yet) [2]
// [1] https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/
// [2] https://github.com/microsoft/WSL/issues/4240
capabilities |= CAPABILITY_ABSTRACT_NAMESPACE;

// Some Linux emulation layers (like NetBSD, FreeBSD) don't support
// the abstract socket namespace
if(checkHasAbstractNamespace()) {
capabilities |= CAPABILITY_ABSTRACT_NAMESPACE;
}
#endif

#if !defined(_WIN32)
Expand Down

0 comments on commit 3a88285

Please sign in to comment.