Come posso architettare la scoperta P2P?

3

Non ho mai fatto davvero la programmazione di rete, quindi questo è tutto nuovo per me. Quello che sto tentando di fare è un client "chat" peer-to-peer. L'idea è che chiunque possa connettersi a qualcuno di cui conoscono l'IP. Tutti i messaggi di chat devono essere distribuiti a tutti.

Quello su cui mi sto bloccando è la scoperta tra pari. Quello che ho fatto finora è:

  1. L'app ha un IP di una persona conosciuta (utente fornito)
  2. Si collega all'IP noto
  3. IP noto fornisce la sua lista di peer noti; lo memorizziamo in peer list
  4. Ciclo di scoperta:
    1. Crea una copia locale di peer list
    2. Per ogni peer in local peer list
      1. Richiedi elenco peer (ad esempio, passaggio 2 + 3)
        • In caso di errore, rimuovi questo peer dall'originale peer list
        • Altrimenti, aggiungi nuovi peer all'originale peer list
    3. Accoda un altro ciclo di rilevamento in 1 minuto

L'ascolto delle connessioni nel passaggio 3 e il ciclo di rilevamento sono asincroni.

Il motivo per cui una copia viene effettuata in primo luogo è dovuta ad alcune altre decisioni di progettazione per il futuro.

Il problema è che se introduco un client con un peer non valido su peer list , ovvero non puoi collegarti ad esso, ciò che succede è che questo peer viene passato tramite il passaggio 3 quando serve il peer list noto e allora altri clienti ce l'hanno nel loro. Propagano questo peer cattivo e in seguito, durante il Discover Loop, rimuovono quel peer. Ma poi, faranno un altro ciclo di ricerca e riceveranno di nuovo quel peer da qualcun altro.

Il risultato finale è che il peer cattivo non esce mai dalla rete.

Un'opzione che posso pensare è una vaga idea di avere la "salute" di Peer che ogni cliente tiene traccia di separatamente in modo che possano ignorare i peer forniti su una lista di qualcuno. Tuttavia, penso che questo dovrebbe essere un po '"temporizzato" in modo tale che quando qualcuno si disconnette non viene escluso per sempre dalla rete.

L'altra idea che avevo era di trasmettere un messaggio broadcast a tutti i colleghi conosciuti quando si incontra un peer cattivo. Tuttavia, questa idea non mi è piaciuta perché lascia aperta la possibilità a qualcuno di fare di un altro cliente il compito di avvelenare la rete insistendo sul fatto che i pari sono cattivi. Ciò richiederebbe quindi che i peer controllino che una richiesta di rimozione sia autentica anche tentando di connettersi immediatamente al suo peer.

Sto cercando opinioni sulle due opzioni sopra.

    
posta NeomerArcana 03.10.2015 - 04:23
fonte

3 risposte

2

Sarei preoccupato per il sovraccarico nel trasmettere l'intera lista di colleghi ogni volta. Se hai N utenti e durante ciascun ciclo di individuazione ogni peer si connette al resto dei peer N e scarica un elenco di N peer, la larghezza di banda dedicata alla sincronizzazione dell'elenco dei peer aumenta come O(N^3) ! Usando alcuni trucchi per trasmettere solo i peer che differiscono tra i due, puoi ridurli a O(N^2 log N) o O(N^2) , ma è ancora piuttosto ripido.

Ho sentito qualche tempo fa un modello di sincronizzazione progettato per evitare questo problema. Non ricordo il nome quindi lo chiamerò "rumor mill synchronization."

Il tuo client mantiene tre liste di peer:

  • Conosciuto bene pari.

  • Pari modificati di recente . Ogni peer in questo elenco è associato a un flag booleano "aggiunto / rimosso" e a un orario (locale).

  • Probabilmente cambiato pari. Ogni peer ha questo elenco ha anche il flag 'added / removed', e ha anche un contatore associato.

Scegli anche un intervallo di tempo in cui le modifiche devono essere considerate "nuove" e un numero richiesto di "voti" prima di eseguire il commit di una modifica ( K ). Suggerirei che il primo è fisso (basato sul test) e il secondo è configurabile dall'utente (in modo che possano impostare il livello di attendibilità della rete). Ecco la procedura:

  1. Inizi con gli indirizzi di alcuni colleghi che pensi siano buoni; questi potrebbero essere gli indirizzi dei tuoi server precaricati nell'app o una serie di peer scelti dall'utente. Chiedetene un numero, chiedendo di scaricare la loro intera lista di coetanei conosciuti . Confrontali uno con l'altro in modo che un utente malintenzionato abbia difficoltà a aggiungere indirizzi dannosi. (Questo richiede O(KN) di larghezza di banda.)

    Supponendo che ti fidi della maggior parte dei peer con cui hai appena parlato, puoi aggiungere i peer che sono nella maggior parte dei loro elenchi per il tuo elenco di coetanei conosciuti. Ora iniziamo il ciclo di scoperta.

  2. Ogni ciclo, ti connetti a un nuovo peer dalla tua lista conosciuta e chiedi la loro lista recentemente cambiata . (Se la rete è relativamente statica, questa lista dovrebbe essere inferiore a O(N) .) Se la rete è grande, puoi scegliere un peer casuale per questo passaggio, altrimenti dovresti scorrere l'elenco (ordinato a caso). L'obiettivo è parlare con il maggior numero possibile di diversi peer senza pregiudizi verso un certo sottoinsieme.

    • Se non rispondono, rimuovili dall'elenco conosciuti e aggiungili all'elenco recentemente modificato come "rimosso" (sovrascrivendo un ") aggiunta 'la voce per quel peer se esiste, non dimenticare di aggiornare anche l'ora).

    • Altrimenti, passa i peer ricevuti uno per uno.

      • Se sono nella tua lista conosciuta , non c'è niente da fare.

      • Se sono nella tua lista possibili modifiche , incrementa il contatore; altrimenti, aggiungili alla lista con il loro contatore in uno.

  3. Controlla l'elenco di possibili modifiche per vedere se qualcuno ha superato K voti; se è così, aggiungili alla tua lista di recentemente cambiati , e aggiungili o rimuovili dal tuo elenco di buoni come appropriato.

  4. Controlla l'elenco di modifiche recenti per vedere se eventuali modifiche su questo elenco sono "obsolete", cioè più vecchie della soglia di tempo. Se è così, rimuovili.

  5. Aspetta un po ', poi torna al punto 2. Dovresti anche ripetere il passaggio 1 occasionalmente con i compagni casuali della tua lista "conosciuti"; considera questo come il passaggio 2 ma scarica la loro lista di coetanei conosciuti , non coautori recentemente .

  6. Se ricevi una connessione da un peer sconosciuto, tratta questo come nel passaggio 3, aggiungendoli al tuo recentemente cambiato e noto bene peer.

Nota che questo approccio funziona solo se la rete è relativamente statica, altrimenti l'elenco delle modifiche recenti comprenderà quasi tutti i client.

I dettagli di implementazione potrebbero essere un po 'off (è stato tanto tempo fa che ho letto su questo) ma l'idea è lì; in pratica, fai squillare quanti più amici puoi e chiedi "senti nuove persone?"

    
risposta data 04.10.2015 - 03:58
fonte
1

La tua soluzione ha un problema solo se esiste un periodo in cui un file non valido può inserire un elenco IP. Se un IP non valido non può entrare in una lista, si spegnerà rapidamente.

Quindi l'unica modifica che devi fare è separare i concetti dell'elenco verificato e dell'elenco in sospeso.

  • Se un cliente richiede la tua lista, fornisci sempre la lista verificata (questo può contenere cattivi IP, ma i nuovi IP non possono entrarci).
  • Ad ogni ciclo di aggiornamento chiedi a ciascuno dei tuoi IP esistenti i loro elenchi, se non riesci a contattarli vengono rimossi dal tuo elenco. Se forniscono nuovi IP, entrano nell'elenco in sospeso, gli IP mancanti vengono ignorati.
  • Una volta che l'elenco di ips conosciuti è stato interrogato, si esegue il polling dell'elenco in sospeso, se e solo se rispondono, entrano nell'elenco verificato
risposta data 03.10.2015 - 21:40
fonte
0

Personalmente mi piace l'idea di trasmissione. Potrebbe essere possibile implementare protocolli di sicurezza per minimizzare il rischio di un attacco da arp veleno.

    
risposta data 03.10.2015 - 08:02
fonte

Leggi altre domande sui tag