Seminario di Protocolli di Rete
Transcript
Seminario di Protocolli di Rete Gnutella Università Ca’Foscari di Venezia Dipartimento di Informatica Corso di Protocolli di Reti AA 2008-2009 Docente: Francesco Dalla Libera SEMINARIO DI PROTOCOLLI DI RETE GNUTELLA Bonaventura Nicola 812106 [email protected] [email protected] Zuin Matteo 805463 [email protected] Pag. 1 di 14 Seminario di Protocolli di Rete Gnutella INDICE DEGLI ARGOMENTI 1. 2. 3. 4. 5. Gnutella Definizione Protocollo Messaggi Struttura dei Messaggi Payload Descriptor a. Ping b. Pong c. Query d. QueryHit e. Push 6. Funzionamento a. Bootstrap b. Ricerca e reperimento risorsa 7. Vantaggi e svantaggi della rete Gnutella Pag. 2 di 14 Seminario di Protocolli di Rete Gnutella 1. Gnutella Gnutella è un protocollo di livello application per la ricerca distribuita basato sulla connessione TCP. Sebbene il protocollo Gnutella supporta un tradizionale paradigma client/server, la differenza da questo sistema è il suo modello decentralizzato P2P (peer-to-peer). E’ il primo esempio nella storia di P2P puro: nessun server centrale e broadcast forzato. In questo modello ogni peer (o nodo equivalente) “conosce” alcuni vicini, facendo sì che le richieste vengano propagate all'interno della rete sfruttando la relazione di vicinanza. Per ovviare al problema che le richieste continuino a girare in tondo, viene normalmente indicato il numero massimo di hop che una richiesta può fare sui peer contigui a partire dal nodo che l'ha generata. Se si definisce orizzonte di un peer il gruppo di client Gnutella con cui è in grado di comunicare in un dato momento, a causa della natura decentralizzata della rete Gnutella, l’orizzonte non comprende l'intera rete attiva Gnutella. Un'estensione del protocollo Gnutella 0.4, Gnutella 0.6, ha introdotto una differenziazione nei nodi, fra "peer" e "ultrapeer" o supernodi, utile per distribuire i carichi e ridurre le richieste di file e i continui invii di tavole Hash. Nascita Il protocollo è stato sviluppato inizialmente come un piccolo programma da Justin Frankel e Tom Pepper della Nullsoft, una compagnia famosa per il suo player multimediale WinAMP. Il programma Gnutella fu distribuito un giorno solo, il 14 marzo 2000 e fu scaricato da migliaia di persone grazie all'annuncio apparso su slashdot.org - news for nerds. Il codice definitivo molto probabilmente sarebbe stato rilasciato in seguito sotto licenza GNU GPL. Il giorno dopo AOL, che aveva da poco acquisito la Nullsoft, ordinò alla Nullsoft di cessare la distribuzione e lo sviluppo del software per motivi legali. Tuttavia i dettagli sul protocollo di Gnutella furono resi pubblici usando tecniche di reverse engineering e presto furono sviluppati cloni free/opensource e nuovi client per accedere alla rete. Al momento il protocollo Gnutella è sviluppato da un gruppo di programmatori chiamato “Gnutella Developers Forum” (GDF). Sono molte le estensioni del protocollo in corso di elaborazione da parte dei vendor di software e dagli sviluppatori di Gnutella del GDF. Nonostante il nome contenga la parola GNU, esso non è parte dell’omonimo progetto, per questo motivo la FSF, custode del progetto GNU, ne ha chiesto il cambiamento del nome. La seconda parte del nome deriva dalla Nutella, molto apprezzata dagli sviluppatori di questa rete. Pag. 3 di 14 Seminario di Protocolli di Rete Gnutella 2. Definizione Protocollo Il protocollo Gnutella definisce il modo in cui i peer comunicano sulla rete. Per immaginare come Gnutella funzionava originariamente, è necessario immaginare una grande cerchia di utenti (chiamati nodi), predisposti con il software client Gnutella. Al primo avvio, il software client deve attuare un’operazione di bootstrap e trovare almeno un altro nodo nella rete connesso a Gnutella. Una volta connesso, il client richiede un elenco di working adresses. Il client Gnutella tenta di connettersi ai nodi “vicini”, sia quelli a cui a passato il proprio indirizzo, sia a quelli di cui ha ricevuto l’indirizzo, fino a raggiungere una certa quota. Il client si limiterà a collegarsi con questi nodi: metterà localmente in cache gli indirizzi che non ha ancora provato e scarterà gli indirizzi non validi. In questo modello, ogni client è un server, e viceversa e perciò vengono chiamati "servents". Essi forniscono le interfacce lato client attraverso le quali gli utenti possono effettuare query e visualizzare i risultati della ricerca, mentre al tempo stesso anche accettare richieste da parte di altri servents, controllare i riscontri con i loro data set locali, e rispondere con risultati applicabili. Grazie alla sua natura distribuita, una rete di servents che implementa il protocollo di Gnutella è altamente robusta, quindi tollerante ai guasti, in quanto il funzionamento della rete non viene interrotto se un sottoinsieme di servents va offline. Pag. 4 di 14 Seminario di Protocolli di Rete Gnutella 3. Messaggi I servent Gnutella comunicano all’interno della rete per mezzo di messaggi che si dividono in 3 tipologie: Multicast: devono essere propagati attraverso l'infrastruttura di rete, ovvero vengono letti e interpretati da tutti i servent. Tali messaggi servono sia per effettuare delle ricerche, sia per segnalare la propria presenza nella rete cercando di ottenere nel contempo una stima della sua estensione. Ogni nodo, come già detto, è connesso ad un certo numero di altri nodi e, in presenza di questo genere di messaggi, ha compito di propagarli verso tutti i nodi (ad eccezione del nodo da cui è arrivato il messaggio). Unicast: utilizzati nella rete Gnutella per mettere in comunicazione due nodi. Tipicamente questi messaggi sono risposte a messaggi multicast (QueryHit, Pong). Diretto: sono messaggi diretti tra nodi che avvengono senza l'utilizzo dell'infrastruttura Gnutella e servono a mettere in comunicazione diretta due nodi che tipicamente devono scambiarsi dei file. Questi messaggi servono essenzialmente per gestire e per trasferire risorse. Pag. 5 di 14 Seminario di Protocolli di Rete Gnutella 4. Struttura dei messaggi La comunicazione avviene per mezzo di descriptors (messaggi). I messaggi multicast generati da un nodo vengono inoltrati lungo tutte le connessioni attive: i nodi che li ricevono li rispediscono verso tutte le loro connessioni (ad esclusione di quella da cui il messaggio è giunto). Ogni messaggio è dotato di un contatore di Hop, ovvero di passaggi tra nodo e nodo e di un campo (TTL) che definisce dopo quanti Hop il messaggio deve essere eliminato. Il campo TTL, infatti, viene decrementato ad ogni passaggio ed al raggiungimento del valore zero impone al nodo che riceve il messaggio la cancellazione del messaggio stesso. Ogni messaggio scambiato in rete deve essere preceduto da un Description Header. Sotto ogni campo di dimensione predefinita, viene riportata la misura della sua lunghezza espressa in bytes. Insieme ad ogni tipo (meglio tipo di nome?!?) di messaggio c’è la codifica esadecimale nel suo Payload Descriptor. I messaggi Multicast e Unicast, quelli che in sostanza usano l’infrastruttura della rete, hanno tutti quanti il medesimo Description Header, che si antepone al messaggio specifico. Il Description Header è composto come segue: Nome Campo Byte Offset DescriptorID 0 - 15 Payload Descriptor 15 TTL Hops 17 18 Payload Length 19 - 22 DescriptorID (16 bytes) Il DescriptorID è l’identificatore di messaggio e viene generato casualmente. Ogni nodo tiene traccia di tutti i DescriptorID che incontra, in modo da riconoscere messaggi di un determinato tipo già inoltrati e per restituire le risposte verso l’origine che ha generato la domanda. Esiste infatti la non remota possibilità che alcuni messaggi, muovendosi attraverso un grafo ciclico non diretto, arrivino allo stesso nodo per due archi differenti. Quindi è compito del nodo stesso riconoscerli e lasciar passare solo il primo. Payload Descriptor (1 byte) Questo campo serve a descrivere il tipo di messaggio che segue. Attualmente sono utilizzati i seguenti valori: 0x00 = Ping 0x01 = Pong 0x40 = Push 0x80 = Query 0x81 = QueryHit Pag. 6 di 14 Seminario di Protocolli di Rete Gnutella TTL (1 byte) Time To Live. Ogni messaggio ha una vita prefissata e determinata dal numero di Hop effettuati: alla creazione di ogni pacchetto viene fissato questo campo ad un valore tipicamente intorno a 7 o 8. Ogni servent decrementa questo valore prima di inoltrare il messaggio e non lo inoltra affatto quando il valore raggiunge 0. Dal momento che il TTL è l’unico meccanismo esistente per eliminare pacchetti dalla rete, risulta estremamente importante, per le implementazioni, evitare che questi valori vengano abusati. Infatti valori troppo grandi tendono ad appesantire l’intera rete e diverse implementazioni, per disincentivare gli abusi, eliminano messaggi il cui valore del campo TTL supera un certo valore. Hops (1 byte) Ad ogni passaggio da nodo in nodo, questo valore viene incrementato. Si noti che per ogni messaggio la somma dei valori TTL e Hops è uguale al valore che aveva assunto il campo TTL alla creazione del messaggio stesso. Questa condizione può essere definita in modo formale come segue: TTL (0) = TTL(i)+ Hops(i) dove TTL(i) e Hops(i) sono rispettivamente i valori dei campi TTL e Hops all’i-esimo Hop, con i >0. Payload Length (4 bytes) In questi quattro byte viene rappresentata la lunghezza del messaggio nel pacchetto. La dimensione massima di ogni messaggio, nella maggior parte delle implementazioni prese in considerazione viene fissato a 4 Kb. Il campo Payload Length è l'unico modo affidabile che dispone un servent per trovare l'inizio del prossimo descrittore nel flusso di input. Il protocollo Gnutella non prevede qualsiasi altro metodo di sincronizzazione. Pertanto, i servents dovrebbero convalidare rigorosamente il campo Payload Length per ogni Descriptor ricevuto (almeno per i descrittori con lunghezza fissa). Se un servent va fuori sincronizzazione con il suo input stream, deve far cadere la connessione associata al flusso fino a che l'upstream servent sta generando, o facendo forwarding, di descrittori non validi. Pag. 7 di 14 Seminario di Protocolli di Rete Gnutella 5. Payload Descriptor Il protocollo è costituito da una serie di descrittori utilizzati per la comunicazione di dati tra servents e una serie di regole che disciplinano lo scambio inter-servent di descrittori. a. Ping: usato per attivare la ricerca di host nella rete. Un servent quando riceve un Ping risponde con uno o più Pong. I messaggi Ping non hanno associato alcun carico e hanno lunghezza 0. Un ping è quindi rappresentato soltanto da un Descriptor Header il cui campo Payload Descriptor e il cui campo Payload Length siano entrambi fissati al valore 0. Un servent usa i Ping per conoscere lo stato della rete: un servent che riceve un pacchetto di questo tipo è tenuto a rispondere con un pacchetto Pong, che ne contiene l’indirizzo e l’ammontare delle risorse condivise da quel particolare nodo. Non c’è alcuna specifica ufficiale che descriva le modalità e i tempi d’utilizzo di questo tipo di messaggi, ma ogni nodo dovrebbe tendere a minimizzarli all’indispensabile. Diversi studi hanno verificato che la maggior parte dei pacchetti che transitano su una rete sono di questo tipo. Si stanno attualmente studiando diverse soluzioni per arginare il problema della percentuale eccessiva dei pacchetti Ping. b. Pong: la risposta ad un Ping. Include l’indirizzo del servent Gnutella connesso e informazioni riguardanti l’ammontare di dati che sono disponibili nella rete. Il Pong è un messaggio di risposta al Ping ed è caratterizzato dai seguenti campi: Nome Campo Port IP Address Byte Offset 0-1 2-5 Number of file shared 6-9 Number of kylobytes shared 10 - 13 Port (2 bytes): questo valore rappresenta la porta alla quale il servent risponde alle domande di connessione in entrata. IP Address (4 bytes) Number of file shared (4 bytes): numero dei file condivisi dall’host identificato dall’IP e dalla porta specificati. Number of kylobytes shared (4 bytes): dimensione totale dei file condivisi espressi in Kb. c. Query: il meccanismo primario per ricerche nella rete distribuita. Un servent che riceve un descriptor Query risponde con un descriptor QueryHit se ha riscontro locale della risorsa cercata. I messaggi Query servono ad effettuare delle ricerche nella rete. Sono messaggi Multicast ed ogni nodo che li riceve è tenuto a confrontare i criteri di ricerca con il proprio insieme di risorse condivise per verificare la presenza di file che risponderebbero alle esigenze descritte. Questi messaggi sono caratterizzati dai seguenti campi: Nome Campo Byte Offset Minimum Speed 0–1 Search criteria 2-… Pag. 8 di 14 Seminario di Protocolli di Rete Gnutella Minimum Speed (2 bytes): la velocità minima, espressa in Kb/s, indica il limite inferiore di velocità richiesta ai servent che rispondono. Un servent che riceve un Query descriptor con un campo Minimum Speed di n Kb/s dovrebbe rispondere con un QueryHit solo se è in grado di comunicare con una velocità maggiore di n Kb/s. Search criteria (null terminated search string): questo campo, di tipo stringa, delimitato dal carattere 0x00, è composto dall’insieme delle parole che devono essere presenti nel file di risposta. La lunghezza massima di questo campo è determinata dal campo Payload Length nel descriptor header. d. QueryHit: la risposta ad una query. Il descrittore provvede a fornire le informazioni per acquisire la risorsa voluta. In risposta ai messaggi Query ci sono dei messaggi unicast QueryHit che contengono tutte le specifiche necessarie per riuscire ad effettuare la transazione da parte di un client. Nome Campo Byte Offset Number of Hits 0 Port IP Address Speed Result Set 1-2 3-6 7 - 10 11 - … Number of Hits (1 byte): Numero di record nel campo Result Set. Port (2 bytes): Porta del servent che risponde. IP Address (4 bytes): Indirizzo IP del server in risposta. Speed (4 bytes): Velocità espressa in Kb/s. Result Set (...): Questo campo contiene un certo numero di record (fissato dal campo Number of Hits). Ogni record è definito dalla seguente struttura: Nome Campo Byte Offset o o o Servent Identifier n – n+16 File Index 0–3 File Size 4–7 File Name 8-… File Index (4 bytes): Valore assegnato dall’host in risposta che viene usato per identificare univocamente una risorsa all’interno del database delle risorse condivise. File Size (4 bytes): Dimensione espressa in Kb. File Name (double null terminated string): Il nome del file che risponde alle richieste formulate nel campo Search Criteria del messaggio Query relativo e che corrisponde all’indice specificato nel campo File Index. Questo campo è terminato con due caratteri 0x0000 Servent Identifier (16 bytes): Ogni servent sulla rete deve essere identificato da una sequenza di 16 bytes, solitamente il risultato di una funzione partendo dall’indirizzo IP. Molte tra le più importanti implementazioni utilizzano invece un numero casuale, fisso per ogni sessione ma non persistente, chiamato GUID. Pag. 9 di 14 Seminario di Protocolli di Rete Gnutella I messaggi QueryHit vengono generati soltanto in risposta a Query e contengono soltanto proposte strettamente inerenti al criterio di ricerca ricevuto. Il DescriptorID nel Descriptor Header deve contenere lo stesso valore del rispettivo campo del messaggio Query, in modo da permettere al messaggio di ritornare a destinazione tramite il protocollo di routing. e. Push: un meccanismo che permette anche ad un servent che si trova dietro ad un firewall di condividere dei file. Ovvero un servent può inviare un Push descriptor se riceve un descrittore QueryHit da un servent che non accetta connessioni in entrata. Ottenuto un messaggio di QueryHit il nodo può stabilire una connessione diretta per effettuare la transazione effettuando un collegamento TCP all’indirizzo e alla porta specificata. Qualora un servent non possa ricevere delle connessioni dirette può comunque condividere delle risorse utilizzando un meccanismo che permette di spedire il file. Qualora si voglia scaricare delle risorse da un servent non in grado di ricevere connessioni dirette, si possono spedire dei messaggi di Push per ovviare alla necessità di ottenere determinati file, identificati dagli indici associati. I messaggi Push sono così composti: Nome Campo Byte Offset Servent Identifier 0 - 15 File Index 16 - 19 IP Address 20 - 23 Port 24 - 25 Servent Identifier (16 bytes): Questo campo specifica a quale servent è indirizzato il messaggio. File Index (4 bytes): Questo indice è il codice utilizzato dal server per identificare una risorsa e compare nel file record del messaggio QueryHit relativo. IP Address (4 bytes): L’indirizzo del client a cui il server dovrà spedire (Push) il file richiesto, codificato in big-endian (dal byte più significativo a quello meno significativo). Port (2 bytes): Porta di accesso al servizio alla quale il file con indice File Index deve essere pushed. Un servent che riceve un messaggio Push si preoccupa di spedire la risorsa soltanto nel caso in cui il Servent Identifier corrisponda al proprio, negli altri casi si limita ad inoltrarlo come un comune messaggio Multicast. Il campo Descriptor ID nel Descriptor Header di un Push non dovrebbe contenere lo stesso valore associato al QueryHit, ma dovrebbe contenere un nuovo valore generato dall’algoritmo di generazione di Descriptor ID del servent. Pag. 10 di 14 Seminario di Protocolli di Rete Gnutella 6. Funzionamento Gli sviluppatori di Gnutella hanno adottato una serie di iniziative molto promettenti per ridurre il numero di messaggi che scorre nella GNet, rendendo i metodi più diretti nonché trasportando ulteriori informazioni. Hanno applicato ciò creando una gerarchia di due livelli per i nodi della rete Gnutella, dove i nodi più veloci (quelli che hanno una migliore capacità di collegamento in rete e una maggiore potenza computazionale) si occuperanno di gran parte del carico rispetto ai nodi più lenti. Un servent ad elevata capacità, che funziona da proxy per i "nodi foglia" proteggendoli dalla maggior parte del traffico di messaggi, viene chiamato ultrapeer. Un nodo foglia, o nodo terminale, è un nodo il cui traffico è protetto da un ultrapeer. Gli ultrapeers in genere hanno un numero <10 di connessioni con altri ultrapeer e un numero compreso tra 1 e 100 di connessioni terminali. Affinché un client possa connettersi alla rete Gnutella ha bisogno dei seguenti servizi: LocalHostCache: che memorizza i servents della GNet; o durante la negoziazione con un ultrapeer (che abbia successo o meno), o dalla ricezione di un messaggio Pong (dopo che almeno una connessione è stata stabilita con la Gnutella Network), o leggendolo da un messaggio QueryHit (dopo un minimo di 2 connessioni stabilite con la GNet). GWebCache: che è un sistema distribuito per aiutare i servents a connettersi alla rete Gnutella, risolvendo così il problema dell'accesso alla rete (bootstrapping). I servent interrogano centinaia di server GWebCache per trovare gli indirizzi di altri servent. I server GWebCache in genere sono server web che eseguono un modulo software speciale. È possibile descrivere il protocollo Gnutella in operazioni fondamentali: a. BootStrap: Avvio del client e caricamento della LocalHostCache. Tentativo di connessione alla GNet usando la LocalHostCache (invio Ping settaggio campi). In caso di insuccesso o di LocalHostCache vuota interroga vari GWebCache finché uno non risponde. Una volta connesso (ricevuto Pong) il servent non interroga più nessun GWebCache durante la successiva sessione. b. Routing: La natura P2P della rete Gnutella richiede che i servents instradino il traffico (query, risposte a query, richieste di push, ecc…) in modo appropriato. Un servent Gnutella dovrebbe seguire le seguenti regole: I Pong Descriptors devono essere inviati unicamente lungo lo stesso percorso da dove proveniva il Ping Descriptor corrispondente. Questo assicura che unicamente i servents che hanno istradato il Ping vedano il Pong in risposta. I QueryHit Descriptors devono essere inviati unicamente lungo lo stesso percorso da dove proveniva il Query Descriptor corrispondente. Questo assicura che unicamente i servents che hanno istradato il Query vedano il QueryHit in risposta. Pag. 11 di 14 Seminario di Protocolli di Rete Gnutella I Push Descriptors devono essere inviati unicamente lungo lo stesso percorso da dove proveniva il QueryHit Descriptor corrispondente. Questo assicura che unicamente i servents che hanno istradato il QueryHit vedano il Push in risposta. Un servent deve inoltrare Ping e Query Descriptors in entrata a tutti i servents connessi a lui direttamente, ad eccezione di quello che gli ha spediti. Un servent deve decrementare il campo TTL del descriptor header, e incrementare il campo Hops, prima di inoltrare il descriptor. Un servent che riceve un descriptor con lo stesso Payload Descriptor e DescriptorID di uno ricevuto precedentemente deve scartarlo e non inoltrarlo. c. Ricerca e reperimento risorsa: Effettua la ricerca della risorsa attraverso una richiesta ai servent da lui conosciuti (settaggio TTL e Hop della Query). I servent che ricevono una richiesta di risorsa effettuano un match con file locali condivisi in GNet, se il match è positivo rispondono alla richiesta con un QueryHit (settaggio numero porta). Una volta che il servent riceve il QueryHit può iniziare lo scaricamento del file tramite una connessione diretta tramite http (Push). Cioè i files sono scaricati al di fuori della rete, mai tramite questa. In ogni caso re-inviano la richiesta agli ulteriori servent a loro connessi usando sistemi di flow control o degli ultrapeers (decremento TTL e incremento Hops) Pag. 12 di 14 Seminario di Protocolli di Rete Gnutella Per esempio, se il Result Set corrispondente ad un QueryHit contiene il record: File Index File Size File Name 2488 4895623 Carpediem.txt\x00\x00 Allora una richiesta di download per quel file sarà inizializzata nella seguente maniera: GET /get/2488/ Carpediem.txt / HTTP/1.0\r\n Connection: Keep-Alive\r\n Range: bytes=0-\r\n User-Agent: Gnutella \r\n Mentre il server risponderà: HTTP 200 OK\r\n Server: Gnutella\r\n Content-type: application/binary\r\n Content-length: 4895623\r\n \r\n Pag. 13 di 14 Seminario di Protocolli di Rete Gnutella 7. Vantaggi e svantaggi della rete Gnutella I principali aspetti positivi della struttura della rete Gnutella sono i seguenti: la rete non si appoggia su nessun server centrale, pertanto non ci sono possibilità che si creino colli di bottiglia e non si ha dipendenza dalla presenza di un solo server per l’accesso alla rete. non è penalmente perseguibile sia per l’assenza di un server centrale, sia per il fatto che i file Gnutella hanno l’aspetto di un qualunque altro file che viene scambiato nel Web. è compatibile con qualunque tipo di file. consente agli utenti dietro a un firewall di connettersi in rete. è totalmente freeware. D’altra parte possiamo osservare i seguenti svantaggi: per la connessione alla rete si necessita della presenza di un altro utente (almeno) precedentemente connesso. ogni utente ha un “orizzonte limitato”: il TTL fa sì che i messaggi non raggiungano mai quei nodi della rete che si trovano al passo successivo, oltre il quale scade il TTL. non è scalabile: inviare ad esempio una richiesta con TTL pari a 10 supponendo che i vicini abbiano collegamenti ciascuno con altri sei nodi, porta ad avere fino a un milione di messaggi scambiati nel caso peggiore. Si ha una grossa difficoltà ad autenticare la fonte da cui provengono i dati ottenuti. Pag. 14 di 14
Documenti analoghi
Gnutella
Criteri per la determinazione dei nodi SuperPeer Capable
non deve trovarsi a monte di un firewall
sufficiente banda di ingresso/uscita
quantità di RAM disponibile. Un SuperPeer deve memorizza...
Linguaggi ed Applicazioni mulømediali
La chiave viene solitamente generata applicando una funzione (detta funzione di
hash) al dato stesso che deve essere inserito/cercato nella DHT.
Sono spesso utilizzate le funzioni della famiglia SH...
Sistemi non strutturati - the Netgroup at Politecnico di Torino
• Questa query serve a stimare la popolarità della risorsa
• Se si ottengono 150 risposte positive in tutto l’algoritmo finisce
Un sistema di sicurezza per ambienti peer-to-peer
Il progetto di tesi si è sviluppato in più fasi e i contributi si articolano come segue:
Descrizione del contesto e del problema: Sono state analizzate tutte le più importanti tecnologie
peer to pe...