Как сделать как netstat -p, но быстрее?

И «netstat -p», и «lsof -n -i -P», по-видимому, читают ссылки на все процессы fd, такие как stat /proc/*/fd/*.

Как сделать это эффективнее?

Моя программа хочет знать, какой процесс к ней подключается. Обход всех процессов снова и снова кажется слишком неэффективным.

Способы, предлагающие iptables или патчи ядра, также приветствуются.


person Vi.    schedule 30.10.2010    source источник
comment
Аналогичный вопрос: stackoverflow.com/questions/838317/ Но там нет полезных ответов.   -  person Vi.    schedule 30.10.2010


Ответы (1)


Взгляните на этот ответ, где упоминаются различные методы и программы, выполняющие сопоставление сокета с процессом. Вы также можете попробовать несколько дополнительных методов для повышения производительности:

  1. Кэширование файловых дескрипторов в /proc и информации в /proc/net. Это делается программами, упомянутыми в связанном ответе, но это возможно только в том случае, если ваш процесс длится более нескольких секунд.
  2. You might try getpeername(), but this relies you knowing of the possible endpoints and what processes they map to. Your questions suggests that you are connecting sockets locally, you might try using Unix sockets which allow you to receive the credentials of a peer when exchanging messages by passing SO_PASSCRED to setsockopt(). Take a look at these examples (they're pretty nasty but the best I could find).
  3. Взгляните на fs/proc/base.c в ядре Linux. Это основная часть информации, полученной в результате ссылки на чтение файлового дескриптора в /proc/PID/fd/FD. Значительная часть накладных расходов — это передача запросов вверх и вниз по уровню VFS, многочисленные блокировки, происходящие во всех структурах данных ядра, которые предоставляют предоставленную информацию, а также преобразование и удаление строк в ядре и на вашем конце соответственно. Вы можете адаптировать часть кода в этом файле, чтобы генерировать эту информацию без многих промежуточных уровней, в частности, сведя к минимуму блокировку до одного раза на процесс или просто один раз за сканирование всего набора данных, который вам нужен.

Моя личная рекомендация состоит в том, чтобы просто выполнить перебор, в идеале пройтись по процессам в /proc в обратном числовом порядке, так как более свежие и интересные процессы будут иметь более высокие PID и возвращаться, как только вы найдете нужные результаты. . Выполнение этого один раз для каждого входящего соединения является относительно дешевым, это действительно зависит от того, насколько критична производительность вашего приложения. Вы определенно сочтете целесообразным обойти вызов netstat и напрямую проанализировать новое соединение из /proc/net/PROTO, а затем найти сокет в /proc/PID/fd. Если весь ваш трафик является локальным, просто переключитесь на сокеты Unix и получите учетные данные напрямую. Написание нового системного вызова или модуля proc, который выгружает огромные объемы данных, касающихся файловых дескрипторов, которые я бы оставил напоследок.

person Matt Joiner    schedule 30.10.2010
comment
2 это не выход. Сокеты Unix тоже. Программа перехватывает соединение, перенаправленное с помощью -j REDIRECT, и показывает пользователю, для какой программы предназначено соединение (и применяет политики в зависимости от имени процесса). если Firefox, то высокий приоритет; если qbittorrent то низкий приоритет. - person Vi.; 30.10.2010
comment
Делать это один раз для входящего соединения относительно дешево, даже если это так, внешний вид strace в консоли будет не таким приятным, как раньше. Большинство системных вызовов будут напрасными (лишь несколько - с прибылью). - person Vi.; 30.10.2010
comment
@Vi: Слушай, и действительность — это слишком разные вещи. Вы можете заметить, что вызов любой программы на C выглядит очень плохо в strace. Поскольку вы на самом деле еще не реализовали это, вы заметите, насколько медленным выглядит netstat. Вы обнаружите, что это не имеет ничего общего с накладными расходами на поиск fd в /proc, и все, что связано с обратным поиском имени хоста (передайте -n, чтобы обойти это). Вы должны профилировать свое возможное приложение, прежде чем винить в этом эту часть своей программы. - person Matt Joiner; 30.10.2010
comment
Что это значит. Если весь ваш трафик идет через локальный хост, просто переключитесь на сокеты Unix и получите учетные данные напрямую. ? - person Lavanya; 13.01.2012
comment
@Lavanya: ОП хочет получить подробную информацию о процессе однорангового сокета. Сокеты Unix позволяют вам получить это из сокета без необходимости копаться в /proc. - person Matt Joiner; 13.01.2012