diff --git a/src/net/SocketDescriptor.cxx b/src/net/SocketDescriptor.cxx index 4752b7e1..6ffb5de5 100644 --- a/src/net/SocketDescriptor.cxx +++ b/src/net/SocketDescriptor.cxx @@ -8,6 +8,10 @@ #include "IPv6Address.hxx" #include "UniqueSocketDescriptor.hxx" +#ifdef __linux__ +#include "io/UniqueFileDescriptor.hxx" +#endif + #ifdef _WIN32 #include #else @@ -235,6 +239,24 @@ SocketDescriptor::GetPeerCredentials() const noexcept #endif +#ifdef __linux__ + +#ifndef SO_PEERPIDFD +#define SO_PEERPIDFD 77 +#endif + +UniqueFileDescriptor +SocketDescriptor::GetPeerPidfd() const noexcept +{ + int pidfd; + if (GetOption(SOL_SOCKET, SO_PEERPIDFD, &pidfd, sizeof(pidfd)) < sizeof(pidfd)) + return {}; + + return UniqueFileDescriptor{pidfd}; +} + +#endif // __linux__ + #ifdef _WIN32 bool diff --git a/src/net/SocketDescriptor.hxx b/src/net/SocketDescriptor.hxx index 1b2f0c01..1f0621c6 100644 --- a/src/net/SocketDescriptor.hxx +++ b/src/net/SocketDescriptor.hxx @@ -25,6 +25,7 @@ class StaticSocketAddress; class IPv4Address; class IPv6Address; class UniqueSocketDescriptor; +class UniqueFileDescriptor; /** * An OO wrapper for a Berkeley or WinSock socket descriptor. @@ -229,6 +230,16 @@ public: struct ucred GetPeerCredentials() const noexcept; #endif +#ifdef __linux__ + /** + * Get a pidfd for the peer process. Returns an undefined + * instance on error (with errno set). + * + * Requires Linux 6.5. + */ + UniqueFileDescriptor GetPeerPidfd() const noexcept; +#endif // __linux__ + bool SetOption(int level, int name, const void *value, std::size_t size) const noexcept;