Buscando a alternativa xinetd para bifurcar servidores simultâneos no Linux

5

Recentemente eu postou aqui perguntando sobre as desvantagens de ter um processo de servidor vinculado a uma porta atribuída dinamicamente. Essa abordagem surgiu porque o xinetd, que iniciou o processo do servidor, aloca STDIN e STDOUT como o canal de comunicação do servidor com o cliente, e queríamos que o servidor usasse um soquete bidirecional. As respostas (e nossa equipe de operações) me convenceram a abandonar essa abordagem.

Eu preciso de um processo do daemon para monitorar servidores e portas designados simultâneos. O processo do servidor é gravado usando uma infra-estrutura de E / S baseada em soquete. Desenvolvemos um processo de servidor que pode ser lançado pelo xinetd. A primeira coisa que faz é ligar a um número de porta dinamicamente designado, enviar o número da porta para o cliente através de STDOUT, e então escutar no socket para o cliente connect () - ponto em que é bom ir com o soquete infra-estrutura de E / S baseada em.

Nossa equipe de operações anulou o uso de portas dinâmicas por motivos de segurança ( ver link ). Eu estou procurando uma alternativa caminho para um cliente para se conectar a um servidor dinamicamente gerado e comunicar usando sockets. A solução mais simples seria algo idêntico em muitos aspectos para xinetd , mas que, em vez de alocar STDIN / STDOUT como a conexão do servidor com o cliente, passaria o soquete que foi alocado quando o daemon aceitou () a conexão, para o servidor. Presumivelmente, como o número do soquete não seria previsível, o daemon também precisaria passar o número como um argumento de linha de comando.

Eu escrevi um tal daemon em Perl, mas hesito em fazer o meu próprio porque tenho certeza que (x) o inetd é muito melhor "endurecido" do que o que eu poderia facilmente criar.

Então, esse é o problema e o que eu considero ser a solução mais simples. Eu gostaria de ouvir soluções alternativas, ou mesmo se de fato xinetd pode ser configurado para passar um socket como eu descrevi.

    
por Chap 06.08.2013 / 19:46
fonte

2 respostas

3

Você está tentando tornar as coisas muito complicadas. Se você quiser usar o xinetd, escreva seu aplicativo para executar cada nova instância falando sobre stdin / stdout. Se você quiser usar diretamente sockets, peça ao seu serviço para ouvir em um soquete fixo e lidar com as conexões em si.

Você não tem nenhum argumento convincente para explicar por que você precisa complicar coisas como essa, você parece pensar que é a única solução. Ou você está deixando de fora os principais detalhes, está confuso sobre como funciona a rede ou estamos lidando com um Problema XY .

Você diz que quer usar um "soquete bidirecional" - quando você tem stdin / stdout que'um canal bidirecional. A menos que você planeje usar ioctls complexos, não há realmente nenhuma diferença - "passar um soquete" não é comprar nada para você.

Você diz que o xinetd é "endurecido" - se você estiver em uma rede privada com firewall, é seguro gravar seu próprio daemon para ouvir diretamente em uma porta fixa. Se você está preocupado com segurança ou DOSes, o xinetd não lhe compra muito.

O que há de errado com as abordagens simples?

    
por 11.09.2013 / 20:38
fonte
1

A primeira pergunta é simplesmente 'por que você não pode usar o fluxo IO do xinetd? Além de você dizer que quer usar o socket IO, não há uma explicação clara de por que você precisa tornar a vida mais complicada para você mesmo.

Se você realmente precisa lidar com soquetes, a solução é implementar seu próprio servidor de soquete. De uma perspectiva de processo, é realmente simples. Você cria o soquete do servidor, escuta para conexão e, quando aceita cada conexão, você tem um soquete específico do cliente para fornecer seu serviço .

No entanto, aqui é onde as coisas ficam muito mais interessantes. você precisará suportar várias conexões de clientes sem que uma solicitação bloqueie outras solicitações. A estratégia mais simples é baseada em como o xinetd resolve isso, bifurcando um novo processo e o novo processo manipula essa conexão do cliente e sai quando o soquete é fechado. Se você estiver planejando um serviço que não será muito carregado, isso é bom o suficiente para você.

Para lidar com conexões de 1k + por vez, usar fork () e criar um novo processo se torna muito ineficiente. Muita memória, muita troca de contexto e desempenho começam a desaparecer. É aqui que você precisa mudar para uma abordagem de E / S assíncrona.

    
por 11.09.2013 / 18:03
fonte