Найти исходный процесс владения сокетом Linux
В Linux и других UNIX-подобных операционных системах возможно для двух (или более) процессов для совместного использования интернет-сокета. Предполагая, что между процессами не существует отношений между родителями и дочерними элементами, есть ли способ сообщить, из какого процесса изначально был создан сокет?
Уточнение: Мне нужно определить это из "внешних" процессов, используя файловую систему /proc
или аналогичную. Я не могу изменить код процессов. Я уже могу сказать, какие процессы разделяют сокеты, читая /proc/<pid>/fd
, но это не говорит мне, какой процесс изначально их создал.
Ответы
Ответ 1
Вы можете использовать netstat для этого. Вы должны посмотреть в столбцах "Local Address" и "PID/Program name".
[email protected]:~$ netstat -tulpen
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name
tcp 0 0 127.0.0.1:4005 0.0.0.0:* LISTEN 1000 68449 7559/sbcl
tcp 0 0 0.0.0.0:6000 0.0.0.0:* LISTEN 0 3938 -
tcp6 0 0 :::6000 :::* LISTEN 0 3937 -
udp 0 0 0.0.0.0:68 0.0.0.0:* 0 4528 -
Ответ 2
не помогает 'lsof -Ua'?
Ответ 3
Скорее всего, вы найдете общие сокеты, разбор /proc/net/tcp (и аналогичные "файлы" для других протоколов). Там некоторые документы в /proc/net/tcp здесь.
Вам нужно будет найти сокет (возможно, по его IP-адресам/номерам портов?) и разобрать номер inode. Когда у вас есть индекс, вы можете выполнить поиск по всем /proc/*/fd/*
, вызывая stat
для каждой ссылки и проверив член st_ino
struct stat
, пока не найдете совпадение.
Номер inode должен совпадать между двумя процессами, поэтому, когда вы прошли через все /proc/*/fd/*
, вы должны были найти их обоих.
Если то, что вы знаете, это идентификатор процесса и сокет fd первого, вам может не понадобиться проходить /proc/net/tcp, все, что вам нужно сделать, это stat /proc/<pid>/fd/<fd>
и выполнить поиск остальных /proc/*/fd/*
для соответствующего индексного дескриптора. Вам понадобится /proc/net/tcp, если вы хотите получить IP-адреса/номер порта, хотя вы можете найти, если знаете номер inode
Ответ 4
Я не знаю, как использовать sendmsg() для "отправки" сокета из одного процесса в другой.
Я знаю, что системный вызов bind() вернет EADDRINUSE, если второй процесс попытается использовать тот же порт.