BSD nc (netcat) não termina em EOF

4

Anfitrião A:

tar cf -  stuff | dd | nc  -N -l 12987

Host B:

nc a.example.com 12987 | dd | tar tf - 

No host A dd imprime seu resumo após tar ser concluído. Assim, é claro, que o tar fecha o pipe / arquivo - > %código%.

165040+0 records in 165040+0 records out 84500480 bytes transferred in 25.464802 secs (3318325 bytes/sec)

Em ambos os hosts EOF fica feliz lá sem sair. nc :

   -N      shutdown(2) the network socket after EOF on the input.  Some
           servers require this to finish their work.

Assim, no host A nc(1) deveria ter visto nc , fechado o maldito soquete e no host B EOF deveria ter visto a conexão TCP terminar e deveria ter fechado nc ( stdout of stdin / dd ).

Como posso dizer ao tar para fechar nc / terminate no host B e terminar no host A .

stdout bug?

nc (debug) não faz nada. -D não pode nem mesmo informar seu número de versão ... suspiro

Ambos os hosts são FreeBSD 10.3-RELEASE-p4 , somente IPv4.

    
por georg 10.06.2016 / 10:47

2 respostas

2

Eu também estava intrigado com o comportamento do netcat, então eu procurei o código. Aqui está a história toda:

Os servidores nc ( nc -l ) e os clientes só saem depois que a conexão mútua foi fechada. Ou seja, se cada uma das partes enviou um pacote FIN para a outra parte.

Um servidor sempre envia um pacote FIN após receber um pacote FIN do cliente. (A menos que o servidor já tenha enviado um pacote FIN .)

Um cliente envia um pacote FIN:

  • após EOF no stdin, quando executado com o argumento -N
  • após EOF no stdin, quando o servidor já enviou um pacote FIN

A opção -d sempre implica EOF no stdin.

A opção -N sempre implica em enviar FIN depois de encontrar EOF no stdin.

Formas de sair dos processos nc após a troca de dados:

  1. Resposta de Georg

    server$ echo hello | nc -l -N 2000
    client$ nc -d localhost 2000
    

    Depois de enviar hello , o servidor encontra EOF no stdin an envia FIN devido a -N .

    O cliente recebe a mensagem e, devido a -d , vê EOF no stdin e envia FIN , porque o servidor já enviou FIN .

    A conexão está fechada, tanto o cliente quanto o servidor saem.

  2. O cliente inicia o fechamento

    server$ echo hello | nc -l 2000
    client$ nc -dN localhost 2000
    

    O servidor mantém a conexão aberta após EOF no stdin.

    O cliente vê EOF no stdin e envia FIN , por causa de -N .

    O servidor envia FIN após receber o FIN do cliente.

    A conexão está fechada, tanto o cliente quanto o servidor saem.

por 31.03.2018 / 21:56
3

nc estabelece uma conexão bidirecional . Ou seja ele envia stdin do host B para o host A, bem como o desejado de A para B.

Use -d no host B para ignorar stdin . -N no host A ainda é necessário para fechar a conexão TCP no EOF.

Em resumo

Anfitrião A:

tar cf -  stuff | dd | nc  -N -l 12987

Host B:

nc -d a.example.com 12987 | dd | tar tf - 
    
por 10.06.2016 / 11:02