Cerco l'alternativa xinetd per la forking di server concorrenti in Linux

5

Recentemente ho postato qui chiedendo quali sono gli svantaggi di un processo del server associato a una porta assegnata dinamicamente. Questo approccio si è verificato perché xinetd, che ha avviato il processo del server, alloca STDIN e STDOUT come canale di comunicazione del server per il client e volevamo che il server usasse un socket bidirezionale. Le risposte (e il nostro team operativo) mi hanno convinto ad abbandonare questo approccio.

Ho bisogno di un processo daemon per monitorare una porta designata e un fork di server simultanei. Il processo del server è scritto utilizzando un'infrastruttura I / O basata su socket. Abbiamo sviluppato un processo server che può essere lanciato da xinetd. La prima cosa da fare è associare un numero di porta assegnato dinamicamente, inviare il numero di porta al client su STDOUT e quindi ascoltare sul socket per il client connect () - a quel punto è bene andare con il socket basata sull'infrastruttura I / O.

Il nostro team operativo ha bloccato l'utilizzo di porte dinamiche per motivi di sicurezza ( vedi link ). Sto cercando un modo alternativo per un client di connettersi a un server generato dinamicamente e comunicare tramite socket. La soluzione più semplice sarebbe qualcosa di identico sotto molti aspetti a xinetd , ma che, invece di allocare STDIN / STDOUT come connessione del server al client, passerebbe il socket che è stato assegnato quando il daemon accetta () ed ha effettuato la connessione, sul server. Presumibilmente, poiché il numero del socket non sarebbe prevedibile, il daemon dovrebbe anche passare il numero come argomento della riga di comando.

Ho scritto un demone del genere in Perl, ma esito a rotolare i miei perché sono certo che (x) inetd è molto meglio "indurito" di quello che avrei potuto facilmente ottenere.

Quindi questo è il problema, e quello che io penso sia la soluzione più semplice. Mi piacerebbe sentire soluzioni alternative, o anche se in effetti xinetd può essere configurato per passare un socket come ho descritto.

    
posta Chap 06.08.2013 - 19:46
fonte

2 risposte

3

Stai cercando di rendere le cose troppo complicate. Se si desidera utilizzare xinetd, scrivere l'applicazione per eseguire ogni nuova istanza parlando su stdin / stdout. Se si desidera utilizzare direttamente i socket, fare in modo che il servizio ascolti su un socket fisso e gestisca le connessioni stesse.

Non hai argomenti convincenti per spiegare perché devi complicare cose del genere, sembra solo che pensi sia l'unica soluzione. O stai lasciando fuori dettagli importanti, sei confuso su come funziona la rete o abbiamo a che fare con un Problema XY .

Dici di voler usare un "socket bidirezionale" - quando hai stdin / stdout che è un canale bidirezionale. A meno che non pianifichi di usare ioctls complessi, non c'è alcuna differenza: "passare un socket" non ti sta comprando nulla.

Dici che xinetd è "hardened" - se sei su una rete privata, protetta da firewall, è sicuro scrivere il tuo demone per ascoltare direttamente su una porta fissa. Se sei preoccupato per la sicurezza o i DOS, xinetd non ti compra molto.

Cosa c'è di sbagliato in entrambi gli approcci semplici?

    
risposta data 11.09.2013 - 20:38
fonte
1

La prima domanda è semplicemente 'perché non puoi usare lo stream IO da xinetd? A parte il fatto che dici di voler usare IO socket, non c'è una chiara spiegazione del perché devi rendere la vita più complicata per te stesso.

Se hai davvero bisogno di gestire i socket tu stesso, la soluzione è implementare il tuo server socket. Dal punto di vista del processo, è davvero semplice. Crea il tuo socket del server, ascolta per la connessione, e poi quando accetti ogni connessione hai un socket specifico per il tuo cliente per fornire il tuo servizio .

Tuttavia, qui è dove le cose diventano molto più interessanti. sarà necessario supportare più connessioni client senza una richiesta che blocchi altre richieste. La strategia più semplice si basa sul modo in cui xinetd risolve questo problema, creando un nuovo processo e il nuovo processo gestisce la connessione client ed esce quando il socket si chiude. Se stai pianificando un servizio che non sarà pesantemente caricato, questo è abbastanza buono per te.

Per gestire connessioni 1k + alla volta, l'uso di fork () e la creazione di un nuovo processo diventano molto inefficienti. Un sacco di memoria, un sacco di cambio di contesto e le prestazioni iniziano a svanire. Qui è dove devi passare a un approccio IO asincrono.

    
risposta data 11.09.2013 - 18:03
fonte

Leggi altre domande sui tag