aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2024-03-12 14:04:55 +0100
committerPau Espin Pedrol <pespin@sysmocom.de>2024-03-12 18:50:54 +0100
commitc9ad345afda0bf4a18a0292f4841020cd36973dc (patch)
treec93a957b1862e57d877f4b686bccb7d19af7ff43
parent9a7b2c950c08ffcaff433732ac26a4444e9589c9 (diff)
socket: Add remote PID and local FD to AF_UNIX sockname
This allows identifying precisely an AF_UNIX socket. Change-Id: Ic465e557ea49de8e044d1ef6d91fc3c852c88ff2
-rw-r--r--src/core/socket.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/src/core/socket.c b/src/core/socket.c
index f56dbf3a..80a9d0ec 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -26,6 +26,7 @@
* \file socket.c */
#ifdef HAVE_SYS_SOCKET_H
+#define _GNU_SOURCE /* for struct ucred on glibc >= 2.8 */
#include <osmocom/core/logging.h>
#include <osmocom/core/select.h>
@@ -2137,8 +2138,6 @@ int osmo_sock_multiaddr_get_name_buf(char *str, size_t str_len, int fd, int sk_p
*/
int osmo_sock_get_name_buf(char *str, size_t str_len, int fd)
{
- char hostbuf_l[INET6_ADDRSTRLEN], hostbuf_r[INET6_ADDRSTRLEN];
- char portbuf_l[6], portbuf_r[6];
struct osmo_strbuf sb = { .buf = str, .len = str_len };
struct osmo_sockaddr osa;
struct sockaddr_un *sun;
@@ -2161,6 +2160,10 @@ int osmo_sock_get_name_buf(char *str, size_t str_len, int fd)
switch (osa.u.sa.sa_family) {
case AF_INET:
case AF_INET6:
+ {
+ char hostbuf_l[INET6_ADDRSTRLEN], hostbuf_r[INET6_ADDRSTRLEN];
+ char portbuf_l[6], portbuf_r[6];
+
len = sizeof(osa.u.sas);
rc = getnameinfo(&osa.u.sa, len, hostbuf_l, sizeof(hostbuf_l),
portbuf_l, sizeof(portbuf_l),
@@ -2186,12 +2189,34 @@ int osmo_sock_get_name_buf(char *str, size_t str_len, int fd)
}
OSMO_STRBUF_PRINTF(sb, "r=%s:%s<->l=%s:%s", hostbuf_r, portbuf_r, hostbuf_l, portbuf_l);
return sb.chars_needed;
+ }
case AF_UNIX:
+ {
+ unsigned long long remote_pid;
+ bool have_remote_pid;
+#if defined(SO_PEERCRED)
+ struct ucred ucred;
+ len = sizeof(struct ucred);
+ if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1) {
+ have_remote_pid = false;
+ } else {
+ have_remote_pid = true;
+ remote_pid = (unsigned long long)ucred.pid;
+ }
+#else
+ #pragma message "SO_PEERCRED not available"
+ have_remote_pid = false;
+#endif
/* Make sure sun_path is NULL terminated: */
sun = (struct sockaddr_un *)&osa.u.sa;
sun->sun_path[sizeof(sun->sun_path) - 1] = '\0';
- OSMO_STRBUF_PRINTF(sb, "%s:%d", sun->sun_path, fd);
+ if (have_remote_pid)
+ OSMO_STRBUF_PRINTF(sb, "r=%llu<->", remote_pid);
+ else
+ OSMO_STRBUF_PRINTF(sb, "r=NULL<->");
+ OSMO_STRBUF_PRINTF(sb, "l=%s:%d", sun->sun_path, fd);
return sb.chars_needed;
+ }
default:
osmo_strlcpy(str, "<socket-family-no-supported>", str_len);
return -ENOTSUP;