Socket Connessione a un numero elevato di IP

0

Ho un file di testo di ~ 600 blocchi IP di notazione CIDR che, quando espanso, ammonta a ~ 17.5 M indirizzi IP. Devo collegarmi connettere a ciascuno. Se si collega, lo aggiungo a un elenco "live", se restituisce un errore / rifiuto, a un elenco "morto". Quindi la presa è chiusa. Non ho bisogno di leggerlo, non ho bisogno di scriverlo. Ovviamente, questo è un problema di scala, se assumiamo generosamente che la connessione richiede solo un secondo per restituire il successo o il fallimento, ci vorrebbero mesi per il completamento, ma probabilmente diversi anni. Devo ridurlo a < 24 ore.

In questo momento sto usando Python per espandere / contare ciascuno degli indirizzi IP, perché è banale farlo. Sto scrivendo un semplice programma C multi-thread per risolvere il problema precedente. Ci sono alcuni modi in cui ho pensato di affrontare questo:

  1. Uso puramente C: non ho trovato un modo per espandere un blocco CIDR in C, (gestire le stringhe in generale è un dolore). Probabilmente potrei cucinare qualcosa, ma se qualcosa esiste già mi piacerebbe sentirne parlare. Sarò in grado di generare abbastanza thread? Anche se depongo un thread per ogni blocco, quei 600 thread! Mi sento come se avessi bisogno di ridurre lo spazio di stack assegnato ai thread per fare questo forse? Anche così, devo essere in grado di gestire un numero elevato di stringhe perché i blocchi devono essere espansi. Indipendentemente da ciò, ho esaminato la lista a mano, e uno dei blocchi ha una notazione CIDR / 10, che ammonta a > IP 4M da solo. Ciò richiederebbe ancora troppo tempo.

  2. Generazione di processi C da Python: questo banalizza il problema delle stringhe e ogni singolo IP può essere inviato a un'istanza di una funzione C chiamata da Python, che quindi terminerebbe. La domanda che ho è: quando Python chiama una funzione C esterna, continua a funzionare con il processo C in parallelo? O aspetta che la funzione C si completi? So che Python non consente il multi-threading (o meglio, lo fa, ma è un po 'uno scherzo dal momento che solo una riga viene interpretata alla volta), quindi questo è il modo corretto di "esportare" multi-threading?

  3. Viceversa: come sopra, ma con C che chiama il codice Python, questo "di più" è corretto? In altre parole, C può avviare più processi Python e continuare a farlo da solo?

  4. Qualcosa di completamente diverso.

Qualsiasi domanda, suggerimento o dubbio sono ben accetti. Si prega di indicare qualsiasi cosa potrei essere mancante o ipotesi errate che ho fatto.

Grazie per il tuo aiuto.

    
posta EruditeEremite 11.11.2014 - 09:31
fonte

3 risposte

2

Farai fatica a rendere questo lavoro così come speri. Le cifre precise variano a seconda del sistema operativo, ma se provi ad aprire più di qualche centinaio di socket alla volta su base continuativa, inizierai a esaurire le risorse di sistema abbastanza rapidamente. Sui computer desktop Windows il limite è ancora inferiore (Windows Desktop impedisce attività come questa come parte del piano intenzionale di ridurre l'efficacia degli attacchi e dei worm ddos).

Suggerirei:

  • usa un processo a thread singolo e i / o non bloccante (ad es. seleziona in c, non so se python lo supporta)

  • distribuisci la tua attività su un piccolo cluster in modo tale da avere solo 100 socket in ogni macchina. Un servizio cloud (ad es. Amazon ec2) potrebbe essere la soluzione migliore.

Vedi anche link che ha suggerimenti sull'ottimizzazione di un sistema linux per aumentare il numero di tentativi di connessione parallela che puoi effettuare.

    
risposta data 11.11.2014 - 12:19
fonte
0

Devi dividerlo in due passaggi: Innanzitutto, usa python per analizzare il file di testo e generare un elenco di indirizzi IP facili da utilizzare in C.

In secondo luogo, esaminiamo il problema esatto. Vuoi "connetterti" ma non hai intenzione di leggere o scrivere. Non sono sicuro di quale sia lo scopo di questo. Non potresti usare il ping per realizzare la stessa cosa? Se si desidera ancora aprire un socket, è necessario implementare l'handshake TCP / IP a tre vie (SYN, SYN-ACK, ACK) in un singolo thread. Avrai a che fare direttamente con il livello IP sottostante, essenzialmente simulando ciò che TCP fa per te. Se ti ricordi che ogni 'connessione' è in realtà solo una coppia di indirizzi, combinazioni di porte e hai 64k di porte a tua disposizione, allora la tua velocità è limitata solo dalla latenza dell'handshake. (Comincia a sembrare una buona domanda per i compiti ...) Se puoi licenziare i pacchetti SYN ad una velocità di diverse centinaia di secondi e ogni transazione ha una latenza di andata e ritorno di 200 ms ... Puoi calcolare quanto tempo impiegherà il tuo elenco di milioni di indirizzi .

Ecco alcuni riferimenti utili. Vuoi imparare a usare socket grezzi. Attuerai tu stesso la stretta di mano del taco.

link

link

link

Buona fortuna

    
risposta data 12.11.2014 - 07:49
fonte
0

Concentrati sul problema, non sulla soluzione. Riprendendo questo problema in termini astratti, hai uno scenario che urla per più processi che comunicano tramite le code. Un processo (il "lettore di input") esegue il ciclo di lettura degli elementi dall'elenco di input (blocchi CIDR) e li aggiunge a una coda enumerata. Un secondo set di processi (gli "enumeratori") eseguirà il looping afferrando l'elemento da enumerare più in alto, espanderli e aggiungere i risultati (singoli indirizzi IP), uno alla volta, a una coda da controllare. Un terzo gruppo di processi (i "controllori") eseguirà il looping afferrando l'elemento più in alto da verificare, eseguirà il controllo e aggiungerà i risultati a una coda da segnalare. L'ultimo processo (il "reporter") eseguirà il looping afferrando l'elemento più in alto dalla coda da segnalare e scrivendolo sui risultati finali.

    
risposta data 13.11.2014 - 12:08
fonte

Leggi altre domande sui tag