Identify program that connects to a Unix Domain Socket
Yes, this is possible on Linux, but it won't be very portable. It's achieved using what is called "ancillary data" with sendmsg
/ recvmsg
.
- Use
SO_PASSCRED
withsetsockopt
- Use
SCM_CREDENTIALS
and thestruct ucred
structure
This structure is defined in Linux:
struct ucred {
pid_t pid; /* process ID of the sending process */
uid_t uid; /* user ID of the sending process */
gid_t gid; /* group ID of the sending process */
};
Note you have to fill these in your msghdr.control
, and the kernel will check if they're correct.
The main portability hindrance is that this structure differs on other Unixes - for example on FreeBSD it's:
struct cmsgcred {
pid_t cmcred_pid; /* PID of sending process */
uid_t cmcred_uid; /* real UID of sending process */
uid_t cmcred_euid; /* effective UID of sending process */
gid_t cmcred_gid; /* real GID of sending process */
short cmcred_ngroups; /* number or groups */
gid_t cmcred_groups[CMGROUP_MAX]; /* groups */
};
Identify other end of a unix domain socket connection
Update: It's been possible to to do this using actual interfaces for a while now. Starting with Linux 3.3, the UNIX_DIAG feature provides a netlink-based API for this information, and lsof 4.89 and later support it. See https://unix.stackexchange.com/a/190606/1820 for more information.
Find PID of the connected Unix Domain Socket
Based on this Golang issue implementing the same thing, you can do
sock, addr = server.accept()
other_pid = sock.getsockopt(0, 2)
where 0
corresponds to SOL_LOCAL
and 2
to LOCAL_PEERPID
.
I just tried it out – works fine on my Mac.
how do I find out what program's on the other end of a local socket?
ss -p
will tell. (Provided the socket is not owned by the kernel itself.)
Can a client determine whether the server has accept()'d a unix socket?
Looks like the answer to this is "no"; the kernel offers no way to get at this info.
(change the protocol isn't an answer, since I was debugging a pre-existing unchangeable protocol)
Calling open() on a Unix domain socket failed with error No such device or address
The /tmp/pipe1
is not a pipe file. It's a socket file. That's what the leading s
means in srwxr-xr-x
.
And Bash's redirection like >
does not support socket files. You need to use socket API to open the file.
With strace (e.g. strace bash -c 'echo > /tmp/sockfile'
) we can see:
...
openat(AT_FDCWD, "/tmp/sockfile", ...) = -1 ENXIO (No such device or address)
...
So the error code is ENXIO
whose corresponding error message is No such device or address
. Bash is just calling standard C API (like strerror) to print the error.
Exampe code for client side:
int
sock_connect(char * sockpath)
{
int sock_fd;
struct sockaddr_un srv_addr = { 0 };
sock_fd = socket(AF_LOCAL, SOCK_STREAM, 0);
if (sock_fd < 0) {
return -1;
}
srv_addr.sun_family = AF_LOCAL;
snprintf(srv_addr.sun_path, sizeof(srv_addr.sun_path), "%s", sockpath);
if (connect(sock_fd, (struct sockaddr *) & srv_addr, sizeof(srv_addr)) < 0) {
return -1;
}
return sock_fd;
}
Related Topics
Linux Desktop Shortcut and Icon from Install
What's The Purpose of Mmap Memory Protection Prot_None
In Linux, How to Create a File Descriptor for a Memory Region
Linux: How to Debug a Sigsegv? How to Trace The Error Source
Automatically Sync Two Amazon S3 Buckets, Besides S3Cmd
How to Provide Extend-On-Write Functionality for Memory Mapped Files in Linux
How to Get Yesterday and Day Before Yesterday in Linux
Gnu Time and Formatting Output
How to Monitor Cwnd and Ssthresh Values for a Tcp Connection
Bash Will Not Auto-Complete (Tab) with Files
How to Accept Multiple Tcp Connections in Perl
Why Kernel Needs Virtual Addressing
How to Exit The Wh Mode in Gdb