How to Find the Client Process Connected to a UNIX Domain Socket in Linux


2 views

When debugging inter-process communication via UNIX domain sockets, one common challenge is tracing both ends of a socket connection. The example shows a dbus-daemon (PID 23284) with multiple connections, where we specifically want to identify the client process using file descriptor 36.

We begin by examining the file descriptor:

ls -l /proc/23284/fd/36
lrwx------ 1 depesz depesz 64 2011-03-28 15:32 /proc/23284/fd/36 -> socket:[1013410]

The socket inode number (1013410) is our key identifier for tracing the connection.

For modern Linux systems, these methods provide the most reliable results:

Method 1: Using ss (Socket Statistics)

ss -xp | grep 1013410

This will show both ends of the connection with process information. The -x flag limits to UNIX sockets, while -p shows process information.

Method 2: lsof with Inode Filter

lsof -U | grep 1013410

Or more precisely:

lsof -Ua +E -i | grep 1013410

Method 3: Direct /proc Inspection

For systems where root access is available:

grep -l 1013410 /proc/*/fd/* 2>/dev/null

Here's a complete debugging session example:

# Find socket inode
ls -l /proc/23284/fd/36

# Get connection details
ss -xp | grep 1013410

# Sample output:
# unix  3   [ ]   STREAM  CONNECTED  1013410  23284/dbus-daemon  @/tmp/dbus-3XDU4PYEzD
# unix  3   [ ]   STREAM  CONNECTED  1013410  12345/client-process

For frequent debugging, consider this bash function:

find_socket_peer() {
    local pid=$1
    local fd=$2
    local inode=$(readlink /proc/$pid/fd/$fd | grep -oP 'socket:$$\K\d+$$')
    if [[ -z "$inode" ]]; then
        echo "Not a socket"
        return 1
    fi
    echo "Socket inode: $inode"
    echo "Connected processes:"
    ss -xp | grep "$inode"
}

For DBUS connections specifically, you can also use:

dbus-monitor --address unix:path=/tmp/dbus-3XDU4PYEzD

This won't show the process information but can help understand the communication.

Once you identify the potential client process, verify by checking its open files:

ls -l /proc/<client_pid>/fd/ | grep socket

Look for the same inode number (1013410 in our example) to confirm the connection.


When working with UNIX domain sockets in Linux, you might encounter situations where you need to identify both ends of a socket connection, particularly when debugging inter-process communication. The example shows a dbus-daemon process with multiple socket connections, and we need to find which client process is connected via file descriptor #36.

First, let's understand how to examine socket connections from both system-wide and process-specific perspectives:

# System-wide view of UNIX sockets
ss -xap | grep dbus-daemon

# Process-specific file descriptors
ls -l /proc/23284/fd/

To find the other end of a specific socket connection (inode 1013410 in our example), we can use these approaches:

# Method 1: Using lsof
lsof -U | grep 1013410

# Method 2: Parsing /proc/net/unix
grep "1013410" /proc/net/unix

# Method 3: Using ss with advanced filtering
ss -xap -e src inode=1013410

Here's a more robust approach that handles permission issues and provides complete information:

#!/bin/bash

# Get socket inode from process FD
INODE=$(readlink /proc/23284/fd/36 | sed 's/socket:$\(.*$\]/\1/')

# Find the peer connection
find_peer() {
    # Check all processes
    for pid in /proc/[0-9]*; do
        pid=${pid#/proc/}
        # Skip if not a valid PID
        [ "$pid" -eq "$pid" ] 2>/dev/null || continue
        
        # Check all file descriptors
        for fd in /proc/$pid/fd/*; do
            if [ -L "$fd" ]; then
                link_target=$(readlink "$fd")
                if [[ "$link_target" == *"$INODE"* ]]; then
                    echo "Found peer process:"
                    ps -p $pid -o pid,cmd
                    return 0
                fi
            fi
        done
    done
    echo "No peer process found"
    return 1
}

find_peer

For systems with many connections, we can optimize the search:

# Using inotifywait to monitor socket creation
inotifywait -m /tmp -e create |
while read path action file; do
    if [[ "$file" == dbus-* ]]; then
        echo "New DBus socket created: $file"
        ss -xap src "/tmp/$file"
    fi
done

When standard tools don't show the peer connection:

  • Run commands as root to see all processes
  • Check if the connection is already closed
  • Use strace to monitor socket activity
strace -p 23284 -e trace=network -s 1000