Bash tcp redirecionamento final da transmissão

3

Eu fiz um serviço de rede simples com xinetd que lê uma string do socket tcp e produz sua view codificada. Binário original (qrencode) apenas lendo stdin.

Funciona bem quando eu uso com netcat as echo string | nc <ip> <port>

Mas ele não responde quando tento usá-lo via redirecionamento bash tcp.

exec 7<>/dev/tcp/<ip>/<port>
echo string >&7
cat <&7

Espera para sempre. Eu tentei ecoar \ 004, cat / dev / null para este fd e sem sorte. Como posso fazer isso funcionar?

    
por doublebind 19.06.2017 / 20:41

2 respostas

4

Esse inetd service ou o seu provavelmente está aguardando o EOF antes de sair (e fechar a conexão).

Para fazer isso, você precisaria que o cliente desligasse o lado de envio do soquete enquanto ainda mantinha o lado de recepção aberto. Isso é o que o nc faz quando detecta EOF no seu stdin.

A interface virtual /dev/tcp/host/port de bash (copiada do ksh) não permite isso. Mesmo a alternativa zsh mais flexível de ztcp não tem a capacidade de desligar as conexões assimetricamente.

Você poderia confiar em um tempo limite, mas isso não seria confiável. Portanto, é melhor confiar em utilitários dedicados como nc ou socat (possivelmente com um coproc para ter uma interface semelhante) ou usar uma linguagem de programação com uma API de rede adequada (com uma interface para shutdown() ). / p>

O caractere 0x04 ( ^D ) significa apenas EOF para dispositivos de terminal quando a disciplina de linha está no modo icanon (implementa um editor de linha bruto). Então, para que isso funcione, você teria que inserir um pseudo-terminal entre o soquete criado por xinetd e seu serviço. Por exemplo, iniciando com:

socat - exec:'your-service',pty,raw,icanon,echo=0,discard=,lnext=,werase=,kill=,start=,stop=,rprnt=,erase=,fdout=3

em vez de

your-service

Então você precisa enviar:

printf 'text\n' >&7

Ou:

printf 'text' >&7

para o seu serviço ver o final da entrada.

Por causa desse editor de linhas, your-service só verá dados quando você envia novos caracteres ou ^D (desativamos todos os outros caracteres de edição, como werase , erase , kill acima e ^C , ^Z ... handling também está desativado como parte de raw ).

Assim, você também pode inserir um pré-processador de entrada que saia desse caractere 0x4 como:

awk -v RS='' -v ORS= '{print; exit}' | your-service

(observe que awk não pode ser mawk , pois mawk insiste em não processar sua entrada, desde que não seja recebido um buffer completo ou eof).

    
por 20.06.2017 / 15:03
0

Parece que, se o seu serviço não estiver fechando a sessão TCP estabelecida, não há outra maneira de interromper a conexão do lado do cliente. Por exemplo, usando o comando timeout:

timeout 1 cat <&7

Além disso, os outros comandos ( echoing exec 7<>/dev/tcp/<ip>/<port>4, cat /dev/null ) que você está tentando provavelmente falharão porque você os executa de outro shell. Observe que o descritor de arquivo 7 está anexado ao shell no qual você executou o primeiro %code% e, portanto, só é possível interagir com ele a partir do primeiro shell.

Referência

    
por 20.06.2017 / 14:41