Como configurar um proxy TCP-changer persistente?

10

Eu tenho um provedor (A) que deseja nos enviar dados através de uma conexão TCP de entrada. Infelizmente, o serviço consumidor (B) não pode receber conexões TCP de entrada. Também não possui um IP estático, outro requisito.

Uma maneira de resolver isso seria um serviço que conecta a porta TCP A de entrada a outra porta TCP B, para que o consumidor possa fazer uma conexão de saída com B.

Este não é um problema único [1] [2] , e com o socat eu posso fazer algo muito próximo do que eu quero:

socat -d -d -d -u TCP4-LISTEN:PORT-A,reuseaddr TCP4-LISTEN:PORT-B,reuseaddr

No entanto, isso tem os seguintes problemas:

  • Se B desconectar, ele não poderá se reconectar. Com TCP4-LISTEN:PORT-B,reuseaddr,fork, ele pode se conectar, mas não recebe dados.
  • B não pode conectar-se antes que A estabeleça uma conexão (superável)
  • Somente uma conexão pode ser estabelecida para PORT-B(superável)

Existe uma maneira de ajustar o comando para que ele se torne "permanente" e resistente a falhas?

dtech
fonte

Respostas:

10

A questão importante é: como A reagirá à perda de conexão ou à conexão sendo recusada? Qualquer coisa que apenas presuma que uma única conexão TCP permanecerá ativa para sempre será frágil; essa é apenas a natureza da internet.

Que tal configurar o serviço socatcomo [x]inetd?

Você configuraria xinetdpara ouvir na PORT-B e iniciaria socat -u TCP4-LISTEN:PORT-A,reuseaddr STDIOassim que o lado B se conectar.

xinetdpassará o tráfego de entrada do lado B para a entrada padrão de socate capturará a saída padrão socate passará para o lado B.

Se B desconectar, o socatprocesso poderá terminar; xinetdiniciará um novo assim que B se conectar novamente. Enquanto B estiver desconectado, A estará recebendo erros de "conexão recusada".

Uma vez eu tive que fazer algo bastante semelhante em um sistema HP-UX antigo.

telcoM
fonte
A tentará se reconectar em um intervalo na perda de conexão, para que seja coberto. xinetd parece que poderia funcionar. Vou tentar informar, obrigado!
DTECH
Resolve o problema mais importante: que os serviços possam restabelecer a conexão em caso de falha. Obrigado!
DTECH
3

O mundo real está bagunçado.

No mundo real, às vezes as conexões TCP morrem, isso pode acontecer, por exemplo, se um firewall com estado ou NAT for reiniciado, se a conexão demorar muito sem tráfego, se a conexão subjacente estiver inativa por muito tempo.

Além disso, às vezes, quando as conexões morrem, elas não morrem simetricamente. Se uma conexão que carrega muitos dados morre, é provável que o remetente note que está morto muito antes do destinatário. Isso tem alguns efeitos colaterais.

  • Se a conexão for iniciada do remetente para o destinatário, uma nova conexão poderá surgir enquanto a conexão antiga aparentemente ainda estiver ativa.
  • Se a conexão for iniciada do destinatário ao remetente, pode haver um atraso substancial entre o remetente que detecta a conexão e o destinatário que detecta esse fato e desencadeia uma reconexão.

Além disso, as conexões TCP são um fluxo de bytes, NÃO um fluxo de mensagens; portanto, quando sua conexão morre, você pode receber uma mensagem parcial.

O resultado líquido disso leva-me a concluir que uma solução robusta requer uma compreensão do protocolo do aplicativo para que sua solução possa entender.

  1. Como emendar os fluxos quando uma nova conexão entra.
  2. Se as mensagens devem ou não ser armazenadas quando a fonte de dados estiver conectada pelo destinatário dos dados, não.
  3. Se um mecanismo de reconhecimento de ponta a ponta é apropriado para evitar a perda de mensagens.
  4. Se é necessário algum tipo de mecanismo "ping" no nível do aplicativo para acelerar a detecção de conexões mortas.
Peter Green
fonte
Tudo de bom, mas neste caso o protocolo de aplicação é muito simples. Mensagens parciais são facilmente detectadas e descartadas. Perder mensagens não é um grande problema se a conexão puder ser restabelecida com rapidez suficiente.
DTECH