knetstat é um módulo simples do kernel Linux que adiciona quatro novos arquivos a /proc/net
: tcpstat
, tcp6stat
, udpstat
e udp6stat
. O conteúdo desses arquivos é aproximadamente equivalente à saída do netstat
com opções -t4an
, -t6an
, -u4an
e -u6an
respectivamente, ou seja, eles fornecem informações sobre soquetes TCP e UDP em formato legível por humanos. A diferença com a saída netstat
correspondente é que eles possuem uma coluna adicional que exibe (um subconjunto de) as opções de soquete. Esta foi a principal motivação para escrever o módulo do kernel knetstat: atualmente, no Linux não há nenhuma maneira de um administrador inspecionar as opções definidas em um soquete criado por algum processo (além de usar strace
ou uma ferramenta equivalente nesse processo na criação do soquete /tempo de configuração), porque essas informações não são expostas por meio do sistema de arquivos /proc
.
O knetstat reutiliza internamente a infraestrutura usada pelo kernel para gerar o conteúdo dos arquivos /proc/net/tcp
, /proc/net/tcp6
, /proc/net/udp
e /proc/net/udp6
. Isso significa que existe uma correspondência individual entre as entradas nesses arquivos e as entradas nos arquivos gerados pelo knetstat. Apenas a formatação e o conteúdo da informação são diferentes entre os dois.
Aqui está um exemplo de saída:
$ cat /proc/net/tcpstat
Recv-Q Send-Q Local Address Foreign Address Stat Diag Options
0 0 127.0.0.1:6010 0.0.0.0:* LSTN SO_REUSEADDR=1,SO_KEEPALIVE=0,TCP_NODELAY=0
0 0 0.0.0.0:22 0.0.0.0:* LSTN SO_REUSEADDR=1,SO_KEEPALIVE=0,TCP_NODELAY=0
0 0 192.168.1.18:22 192.168.1.6:49537 ESTB SO_REUSEADDR=1,SO_KEEPALIVE=1,TCP_NODELAY=1
0 0 127.0.0.1:6010 127.0.0.1:45462 ESTB SO_REUSEADDR=1,SO_KEEPALIVE=0,TCP_NODELAY=1
0 0 127.0.0.1:45462 127.0.0.1:6010 ESTB SO_REUSEADDR=0,SO_KEEPALIVE=1,TCP_NODELAY=1
A coluna "Diag" pode exibir os seguintes indicadores de diagnóstico:
Indicador | Significado |
---|---|
>| | A janela do remetente (ou seja, a janela anunciada pelo terminal remoto) é 0. Nenhum dado pode ser enviado ao peer. |
|< | A janela do receptor (ou seja, a janela anunciada pelo endpoint local) é 0. Nenhum dado pode ser recebido do peer. |
># | Existem pacotes não reconhecidos e o último ACK foi recebido há mais de um segundo. Isto pode ser uma indicação de que há problemas de rede ou que o peer travou. |
SO_REUSEADDR
, SO_REUSEPORT
, SO_KEEPALIVE
(TCP), TCP_KEEPIDLE
(TCP), TCP_KEEPCNT
(TCP), TCP_KEEPINTVL
(TCP), SO_RCVBUF
, SO_SNDBUF
, SO_RCVTIMEO
, SO_SNDTIMEO
, SO_LINGER
(TCP), TCP_NODELAY
, TCP_FASTOPEN
, TCP_DEFER_ACCEPT
, SO_BROADCAST
(UDP) TCP_KEEPIDLE, TCP_KEEPCNT e TCP_KEEPINTVL correspondem aos valores tcp_keepalive_time, tcp_keepalive_probes e tcp_keepalive_intvl descritos em tcp(7) e os respectivos sysctls. Se esses valores forem substituídos no nível do soquete (definindo-os para algo diferente de zero), eles serão impressos pelo knetstat, caso contrário, o kernel usará sysctls e o módulo irá ignorá-los enquanto imprime a saída.
O código knetstat atual foi testado com sucesso com as versões 3.13, 3.18, 4.4, 4.8, 4.9 e 4.15 do kernel. Pode funcionar com outras versões também.
Para construir o módulo, certifique-se de ter os cabeçalhos do kernel atualmente em execução, bem como as ferramentas básicas de construção, como make e GCC. Por exemplo, no Ubuntu:
# apt-get install linux-headers-$(uname -r) make gcc
Em seguida, verifique o código-fonte do knetstat e execute make
. Isso deve criar knetstat.ko
que pode ser carregado usando insmod
.
A tabela a seguir mostra a correspondência entre as opções de soquete relatadas pelos métodos knetstat e setter definidos pela classe java.net.Socket
. Essas informações podem ser usadas para inferir a configuração que um processo Java aplicou a uma instância java.net.Socket
com base na saída do knetstat. O mapeamento é simples, exceto setSoTimeout
.
Método Java | Opção de soquete relatada por knetstat |
---|---|
setKeepAlive | SO_KEEPALIVE |
setReceiveBufferSize | SO_RCVBUF |
setReuseAddress | SO_REUSEADDR |
setSendBufferSize | SO_SNDBUF |
setSoLinger | SO_LINGER |
setSoTimeout | nenhum [*] |
setTcpNoDelay | TCP_NODELAY |
[*] Em contraste com o que o Javadoc sugere, o método setSoTimeout
na verdade não define nenhuma opção de soquete no Linux. Por padrão, as instâncias java.net.Socket
são apoiadas por java.net.SocksSocketImpl
(mesmo se nenhum proxy SOCKS estiver configurado). Esta classe estende java.net.AbstractPlainSocketImpl
que armazena o tempo limite internamente para uso posterior pelos métodos de leitura em java.net.SocketInputStream
. Eles, por sua vez, passam o tempo limite para uma invocação da chamada de sistema poll
que aguarda até que os dados estejam disponíveis para leitura (ou ocorra um erro).