Как да направя като 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. Ако целият ви трафик е localhost, просто превключете към Unix сокети и вземете идентификационните данни директно. Писане на нов syscall или proc модул, който изхвърля огромни количества данни относно файлови дескриптори, които бих запазил за последно.

person Matt Joiner    schedule 30.10.2010
comment
2 не е начин. Unix сокети също. Програмата улавя връзката, пренасочена от -j REDIRECT, и показва на потребителя за коя програма е връзката (и прилага политики в зависимост от името на процеса) Напр. ако firefox тогава high prio; ако 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
Какво означава това Ако целият ви трафик е localhost, просто превключете към Unix сокети и вземете идентификационните данни директно. ? - person Lavanya; 13.01.2012
comment
@Lavanya: OP иска да получи подробности за равноправния процес на сокет. Unix сокетите ви позволяват да извлечете това от сокета, без да се налага да ровите в /proc. - person Matt Joiner; 13.01.2012