1. File sharing e Peer To Peer

Un file-sharing è un sistema che consente ad un utente di condividere i propri file con altri utenti.

Il file sharing è la base di tutti quei programmi che permettono di scaricare file (mp3, video, programmi, immagini) dai computer di altre persone collegate ad internet.

I sistemi di scambio files Peer to Peer coinvolgono in prima persona gli utenti che ne fanno parte. In essi e' possibile scambiarsi files con una logica in fondo simile a quanto potrebbe avvenire per una biblioteca universale, con la sola differenza che essendo il sistema basato su dati digitali, quanto acquisito ti rimane, la copia e' identica all'originale e nessuno la richiedera' indietro. In un ottica un poco piu' informatica: si immagini un hard disk enorme composto di tutti gli hard disk dei partecipanti, nel quale ognuno cerca tra le directory di tutti.

Un piccolo ma doveroso accenno è dovuto alla sicurezza, alla privacy alle resposabilità legali dovute allo scambio di materiale coperto da diritti.Alcuni programmi di filesharing introducono del codice piuttosto fastidioso, comunemente identificato col termine spyware. Porzioni di codice atte a monitorare la vostra attivita' in rete, a collezzionre dati sui vostri gusti, preferenze, ecc...Materiale molto ghiotto e ben rivendibile sul mercato delle indagini di mercato. Questo nei migliore dei casi, nel peggiore e' possibile che gli spyware frughino all'interno del sistema operativo, poiche' non vi e' motivo datosi che ormai si e' installati sulla macchina di fermarsi all'analisi del traffico di rete. Qualsiasi client per il file sharing privo di sorgenti espone potenzialmente a questo problema. In realta' qualsiasi tipo di codice non distribuito con i sorgenti lo e'. Con sorgente indichiamo il codice con cui un programma e' realizzato. Nessuno dei due paradigmi citati, napster e gnutella, comunque si preoccupa eccessivamente della sicurezza, ne' della privacy, problemi che si pongono invece due sistemi p2p interessanti: Freenet e GnuNet.

Per una prospettiva sulle problematiche di sicurezza legate al protocollo Gnutella si puo' consultare l'ottima pagina: http://www.cs.ucr.edu/~csyiazti/cs260-2.html contenente un noto articolo dal titolo "Exploiting the security weakness of the Gnutella Protocol" e una serie di link altrettanto interessanti.







    1. Storia dei Peer To Peer

Nel settembre del 1999, un programmatore di appena diciotto anni, Shawn Fanning, mise a disposizione un software gratuito per la condivisione di file musicali via Internet: Napster. La rivoluzione che ebbe inizio in quel settembre non si è più fermata: sono ormai milioni gli utenti che hanno installato Napster sui loro computer e l’archivio virtuale cui è possibile accedere conta decine di migliaia di titoli. I motivi di questo successo sono molteplici: innanzitutto la semplicità. Il client di Napster è un agile programmino di circa un mega e mezzo, che si installa automaticamente ed è subito pronto a funzionare, senza bisogno di alcuna configurazione. Per cercare un brano, è sufficiente indicarne il titolo o l’autore ed immediatamente appare una lista di tutti gli utenti che lo hanno disponibile; un clic su uno di essi, e potremo scaricare il brano direttamente da quel computer, ed ecco l’idea vincente: vedere Internet come un grande deposito di file, distribuito su migliaia di pc.

Il meccanismo su cui si basa il funzionamento di Napster è talmente semplice ed efficace da apparire geniale: il server centrale non fa altro che tenere traccia degli utenti connessi e dei file che hanno a disposizione. Nel suo archivio, non ci sono i file, ma un elenco che ricorda dove ogni file è situato. Quando un utente chiede di scaricare un file, il server lo mette in contatto diretto con il computer che effettivamente possiede il brano musicale, realizzando la cosiddetta connessione peer to peer (p2p). Questo tipo di connessione scavalca completamente la problematica del sovraffollamento dei server: il tempo per il quale si resta connessi al server centrale è brevissimo, ed è legato esclusivamente alla ricerca della posizione del brano all’interno dell’archivio. Tutta la parte più onerosa della faccenda, quella dedicata all’effettivo download del brano da un computer all’altro, è completamente delocalizzata, consentendo così un migliore sfruttamento della Rete. Recuperando l’idea base di una Rete in cui ogni nodo sia nel contempo attore e spettatore, Fanning ha restituito ad Internet la velocità e la libertà che si credevano perse con l’avvento di Internet per le masse.

Il successo di Napster ha indotto le major discografiche a additarlo come il pericolo pubblico numero uno. Stuoli di avvocati si sono impegnati a dimostrare l’illegalità del progetto Napster, mentre l'autore del software ed i suoi avvocati hanno invano tentato di dimostrare la neutralità di Napster, sostenendo che la sua unica funzione è permettere lo scambio di file mp3: che questi siano legali o copie pirata è responsabilità esclusiva dell'utente. Questa tesi non è però stata accolta dalla giustizia americana, che ha condannato alla chiusura Napster.

La prima grande rete di files sharing, Napster, e' dunque stata affossata da una causa della RIAA e del MPPA per violazione del copyright. In America infatti la violazione dei diritti intellettuali di un'opera ricade sotto la legislazione federale.

Gli unici file che è possibile scambiare tramite Napster sono quelli con estensione mp3 il cui player più famoso è sicuramente WinAmp. Non è dunque un caso che il primo a trovare e superare i limiti di Napster è stato proprio l’inventore di WinAmp: Justin Frankel.

Anch’egli giovanissimo, attraverso la Nullsoft ha sviluppato Gnutella, un programma di file sharing che non solo permette di scambiarsi file di qualsiasi tipo in modalità peer to peer, ma elimina la necessità di un server centrale, e dunque elimina anche la possibilità che quel server sia chiuso.

Scottate dall’esperienza Napster, questa volta le major non hanno aspettato la diffusione del programma per attaccarlo: grazie al fatto che Time Warner è consociata con America On Line e che AOL controlla Nullsoft, venne dato ordine di bloccare la pubblicazione di Gnutella.

Con un’azione degna dei migliori romanzi di spionaggio, poche ore prima che diventasse esecutiva la disposizione della Time Warner, alcuni tecnici della Nullsoft resero pubblici i sorgenti di Gnutella, annullando così la sentenza di morte già pronunciata dai boss della Time Warner. Ora Gnutella è un progetto open source, aperto agli sviluppatori di tutto il mondo.

I programmatori non si fecero scappare l'occasione e cominciarono a spuntare un po' ovunque client open source e non per questa tipologia di rete.

Per una lista aggiornata dei programmi attualmente disponibili:

http://www.gnutella.com/connect

Intanto qualcuno aveva inziato ad analizzare il protocollo alla base di Napster, e pubblico' un documento per illustrarne i risultati. Questo studio e' alla base della nascita del circuito OpenNap: server che utilizzano il protocollo di Napster pur non essendo affiliati con il sito in nessuna maniera.

Per maggiori informazioni: http://opennap.sf.net

Di nuovo per superare i problemi legali creati da un'organizzazione centralizzata, si tenta dunque la via della decentralizzazione: se un solo Napster puo' essere chiuso, tanti Napster hanno qualche speranza in piu' di sopravvivere.



    1. Tassonomia

Esistono due grandi scuole di pensiero per quanto riguarda il file sharing: sistemi centralizzati e sistemi decentralizzati.I sistemi centralizzati sono facilmente individuabili perchè fanno riferimento, seppur limitatamente alla fase iniziale di connessione e ricerca dei contenuti, a dei server prestabiliti su porte prestabilite.Nel seguito, concentreremo la nostra attenzione sui sistemi decentralizzati.



P2P

TCP

UDP

GNUtella

6346,6347

6346,6347

Napster

6699,8875

8876

WinMx

6699

6257

eDonkey

4661

4665

Aimster

5025


Direct Connect

411,412


Elenchiamo i protocolli dei p2p più diffusi:



protocollo

client

sorgenti

architettura





FastTrak

Kazaa

Protocollo proprietario

decentralizzato

gnutella

Gnutella, bearshare

Open source

decentralizzato

Open nap

Tutti i cloni di napster

Open source

centralizzato

WinMx

WinMx

Protocollo proprietario

decentralizzato



      1. Sistemi centralizzati

Nei sistemi centralizzati (ad esempio Napster e Audiogalaxy) un server centrale mantiene un elenco di utenti e di risorse che quest'ultimi mettono a disposizione.

Quando si effettua una ricerca ci si rivolge al server centrale, il quale consulta i propri archivi e quindi ci fornisce dei risultati con gli indirizzi di chi mette a disposizione una certa risorsa. Un sistema del tutto simile ad un motore di ricerca, ma in questo caso sono i client a segnalare al server cosa forniscono e non il server a visitare il web ed indicizzare. Il passaggio del file avviene direttamente tra i due utenti interessati, e non coinvolge in nessuna maniera il server, che non mantiene su di se' alcun files.Il server mantiene anche una chat-room, che non e' pero' convolta nei meccanismi di sharing.






  1. LOG -Nella prima fase, l'utente1 si connette alla rete p2p autenticandosi sul server centrale. Sempre in questa fase, l'utente trasmette al server una lista delle risorse che intende condividere.

  2. QUERY - L'utente2 esegue una ricerca di una risorsa detenuta anche da utente1

  3. RESPONSE - Il server invia all'utente2 che ne ha fatto richiesta, una lista di host che detengono la risorsa da lui richiesta insieme ad ulteriori informazioni sugli host..

  4. PUSH - L'utente2 sceglie un host da cui scaricare la risorsa e manda la richiesta direttamente.

  5. PULL - L'utente1, acconsente alla richiesta e manda la risorsa.

      1. Sistemi decentralizzati

Nei sistemi decentralizzati (ad esempio Gnutella,Kazaa,WinMx), non esiste un server centrale, ma tanti servant.

Servant indica un'entita' in grado di funzionare da server e da client. Per entrare a far parte del circuito e' necessario conoscere l'indirizzo di almeno un servant gia' attivo. Per prima cosa si comunica di essere "alive" al nostro contatto all'interno della rete, il quale a sua volta comunichera' agli altri server al quale e' connesso la nostra esistenza e lo stesso faranno quest'ultimi e via cosi'.Il processo non si perpetua all'infinito poiche' il protocollo prevede un TTL (un time to live), un numero massimo di passaggi, dopo il quale i server smettono di propagare la nostra esistenza.

Inseriti nel network e' possibile effettuare delle ricerche presso i nodi che abbiamo attraversato, e quindi scambiarsi files direttamente tra gli interessati. Nessun nodo e' vitale per l'esistenza della rete.




A) In una fase iniziale (installazione) il filesharing esegue un probe della rete su cui si trova e contatta un cache server.

  1. ALIVE - In questa fase, l' utente1 comunica agli utenti nella propria cache list, la propria esistenza.

  2. FORWARD - L' utente2, a sua volta, comunichera' agli altri server al quale e' connesso la nostra esistenza e lo stesso faranno quest'ultimi e così via. Il processo non si perpetua all'infinito poiche' il protocollo prevede un TTL (un time to live), un numero massimo di passaggi, dopo il quale i server smettono di propagare la nostra esistenza.

  3. QUERY - L'utente1 può eseguire ricerche e scambi con gli utenti 'visti' durante le fasi 1 e 2.Ogni richiesta viaggia avanti e indietro attraverso la catena di utenti.

Ciascun macchina sulla rete dei peer to peer (suppponiamo la rete Fast Track) e' connessa ad un certo numero di altri computers (peers), ciascuno di essi a propria volta connesso con altri calcolatori.Poniamo che questo processo continui in maniera indefinita.

Ora immaginiamo che un utente sia connesso con 4 calcolatori e che ciascuno di questi sia connesso con altri 4: i computer raggiungibili sarebbero dunque 4 + 4*4 = 20.

In questo caso, il messaggio ha viaggiato soltanto per due hops (due passaggi da un macchina ad un'altra).

Nelle ricerche viene definito un parametro noto come TTL (time to live), in questo caso il TTL e' pari a 2.

Se settassimo il TTL a 3, mantenendo lo scenario invariato raggiungeremmo 4 + 4*4 + 4*4*4 = 84 calcolatori.

Quindi il numero di computer con i quali possiamo comunicare cresce in maniera esponenziale al TTL. Dunque la struttura della rete si disegna mano a mano che la esploriamo, e non soffre della mancanza di nodi centrali. Queste sono semplificazioni, per una prospettiva piu' precisa si vedano:

http://opennap.sf.net/napster.txt

http://www9.limewire.com/developer/gnutella_protocol_0.4.pdf

oppure

http://www.infoanarchy.org/wiki/wiki.pl?Gnutella/Protocol

E per essere sempre aggiornati sugli sviluppi:

http://rfc-gnutella.sf.net

Il sito contiene tutte le proposte per la revisione del protocollo, verso la versione 0.6.



      1. Connessione ad un network peer To peer

La domanda più importante che ci si pone in questo contesto è:

Come riesce un p2p a capire su quale porta inziare la connessione con un altro p2p ?

Nei p2p centralizzati la richiesta viene fatta ad un server centrale appunto su una porta ben conosciuta.Nei p2p de-centralizzati, una tecnica frequentemente utilizzata consiste nel conservare una lista di poche centinaia di hosts sul disco. La probabilita' che almeno uno di essi sia in funzione e' molto alta, anche quando la lista e' vecchia di alcune settimane.

Ad esempio, per potersi connettere alla rete Gnutella, un servant deve trovare un hostiniziale a cui dirigere la sua prima connessione. Successivamente, altri hosts verranno forniti usando i messaggi Pong e gli headers X-Try.

Ci sono diversi hosts Gnutella permanenti che forniscono una lista di hosts Gnutella a tutti i servant che si connettono a loro. Questi sono spesso chiamati hostscaches. Una lista di hostscaches pubblici e' disponibile presso:

http://groups.yahoo.com/group/the_gdf/database?method=reportRows&tbl=5

(richiede la GDF membership)

Per ridurre la vulnerabilita', ogni servant Gnutella con una base di utenza abbastanza larga e che usi gli hostscaches DOVREBBE avere il suo hostscache pubblico.Ci sono diversi programmi hostscache open source disponibili. Si veda per esempio:

http://groups.yahoo.com/group/the_gdf/message/1375

Dal momento che gli hostscache possono essere sovraccarichi, o essere down, ogni servant NON DEVE dipendere da questi.


      1. Fase di ricerca delle risorse

E' importante esaminare come network p2p permettano la ricerca di risorse condivise.

Bisogna distinguere il comportamento dei due più diffusi fileSharing

Gnutella network

Durante la fase denominata ALIVE, il p2p comunica (PING) la propria presenza (ip address e porta) agli altri p2p direttamente raggiungibili.Questi, dopo aver risposto (PONG), ritrasmettono quel PING ai loro p2p vicini.Il p2p iniziale si è così costruito una lista di host attivi con cui dialogare.Al momento della ricerca, il p2p contatta direttamente tutti i p2p presenti nella propria lista.

FastTrack network (kazaa)

Lo sviluppo del protocollo FastTrack ebbe come obiettivo proprio quello di ottimizzare la fase di ricerca al fine di minimizzare la quantità di traffico generato in fase di ricerca.

Per ridurre le latenze di scambio di informazioni, certi peer (KaZaa clients) vengono elevati a Super node (temporaneamente o no). La selezione è determinata in base alla banda e alla disponibilità di computer che usano il medesimo software. Dunque un client Kazaa può essere elevato a Super node nella comunicazione p2p e funzionerà come punto di informazione per altri client Kazaa che si trovano nelle vicinanze.

Questo Super node aiuta le ricerche così che gli altri p2p che ospitanouna certa risorsa, posso essere trovati più facilmente.Successivamente il file cercato può essere scaricato direttamente dell' host che lo detiene.

Alla prima installazione di Kazaa, viene installata anche una lista di Super node.

Se nessuno di quei Super node può essere contattato, Kazaa tenta di scaricare una nuova lista di Super node da un server web.


    1. Analisi


      1. Metodologia

L' analisi dei protocolli è stata eseguita utilizzando un sistema di sniffing basato su una macchina virtuale. Per permettermi di studiare i più comuni filesharing commerciali che girano su piattaforme Microsoft, ho utilizzato il sistema operativo Linux con gli strumenti TCPDUMP e ETHEREAL.


Su Linux ho fatto girare una macchina virtuale (VMware) dentro la quale girava il sistema operativo Microsoft windows 2000. Il sistema operativo usato è Linux [naturalmete (-;] RedHat 7.3 su cui gira VMware 3.0 build 1455. VMware crea una macchina virtuale che ospita il sistema operativo Microsoft windows 2000 professional. Vmware usa una interfaccia di rete virtuale (vmnet8 nel mio caso) alla quale ho assegnato, da lato di windows l' indirizzo IP 192.168.0.128. Windows comunica con il resto del mondo attraverso il NAT creato da Linux. In questa maniera è semplicissimo sniffare tutto il traffico semplicemnete ascoltando sull'interfaccia virtuale vmnet8. A posteriori mi rendo conto della notevole comodità di una tale configurazione

Linux->VMware->Windows. In laboratorio, su una sola macchina fisica, è possibile simulare e studiare il comportamento di una intera LAN.



      1. Il protocollo di Gnutella - file sharing decentralizzato

Gnutella e' un sistema open suorce, peer-to-peer decentralizzato. Permette ai partecipanti di condividere risorse presenti sul proprio sistema e di accedere alle risorse condivise da altri. Le risorse potrebbero essere di ogni genere: link ad altre risorse, chiavi crittografiche, files di ogni tipo, ecc...

Ciascun partecipante esegue un programma che implementi le specifiche di Gnutella e ricerchi altri nodi nella rete. Questo insieme di nodi genera il traffico della rete Gnutella, che e' essenzialmente composto da queries, risposte e messaggi di controllo per trovare altri nodi.

Gli utenti si scambiano di nodo in nodo la lista delle risorse disponibili sulla propria macchina, effettuano delle ricerche all'interno di queste liste, sperando di trovare un nodo in grado di soddisfare la ricerca.

Lo scambio di risorse viene in seguito negoziato tra i nodi interessati attraverso il protocollo HTTP. La rete Gnutella e' utilizzata esclusivamente per localizzare la posizione di una certa risorsa.

Un pacchetto in Gnutella inizia la sua vita da un singolo servant e viene trasmesso, secondo un meccanismo tipico delle reti broadcast, a tutti gli altri servants direttamente raggiungibili. Quest'ultimi instraderanno a loro volta il pacchetto a tutti i servants direttamente raggiungibili da loro stessi e cosi' via sino a che il TTL (il time to live) del pacchetto non scadra'.

Se ogni servants ha 8 host direttamente connessi, un pacchetto con un TTL pari a 7 puo' raggiungre 8^7 servants, 2097152 hosts.

Un pacchetto di replay (risposta) ad un messaggio broadcast di un certo servant viene trasmesso a ritroso per la rete sino a che non giunga al servant sorgente del pacchetto.

Per tener traccia della provenienza di un pacchetto, ciascuno di essi viene fatto precedere da Message ID di 16 byte. Tale ID e' costituito da un numero casuale, con il quale ogni servant firma i propri messaggi.

Ciascun servant mantiene un hash table con la corrispondenza tra un ID ed il rispettivo IP, per qualche migliaio di pacchetti, che lo hanno attraversato. Per far giungere una risposta ad un certo hosts dunque ciascun servant controlla la propria hash table alla ricerca di una corrispondenza tra l'ID del pacchetto da instradare e l'IP. Questo processo continua sino a che il pacchetto non giunge a destinazione.

Il risultato e' una rete priva di gerarchia, ciascun servant e' uguale a tutti gli altri. Per partecipare alla rete, si deve necessariamente contribuirvi.

Ciascun server conosce soltanto l'indirizzo dei nodi direttamente connessi. Tutti gli altri servers sono invisibili, sino a quando non si rivelano rispondendo ad un PING e ad una QUERY. Esiste dunque una sorta di pseudo anonimato. Sfortunatamente, combinare una rete priva di gerarchia e l'impossibilita' di creare una lista di tutti i server connessi, genera una rete non semplice da descrivere.

Non e' un albero (poiche' non vi e' gerarchia) ed e' ciclica. Questa ciclicita' implica la presenza di molto traffico inutile, ridondante. Allo stato attuale del protocollo non si puo' fare molto per ottimizzare il traffico.

The Gnutella Development Forum (the GDF) e' un buon posto dove trovare della documentazione su Gnutella. Gli archivi sono una buona fonte di informazioni per comprendere il protocollo e la sua implementazione. Tutti possono diventare membre del Gnutella Development Forum.

Il forum si trova presso http://groups.yahoo.com/group/the_gdf

Esistono molti altri forum comunque nei quali viene discusso losviluppo di Gnutella.



        1. Terminologia



Un programma che partecipa alla rete Gnutella e'detto servant. I termini "peer", "node" e "host" hanno significati simili, ma si riferiscono ad membro della rete piuttosto che ad un programma. Client puo' essere sinonimo di servent, anche se in una rete Gnutella soltanto in alcuni casi e' possibile attribuire un ruolo di client o di server ad un certo nodo. In generale un nodo svolge entrambe le funzioni.

I messaggi sono entita' per trasmettere informazioni sulla rete. "Packet" viene talvolta utilizzato con il medesimo significato. Altri documenti ancora utilizzano il termine "descriptor".

Globally Unique IDentifier. E' un valore casuale di 16 byte, che identifica i servants ed i messaggi.Non e' da considerarsi una signature, ma un modo per identificare in maniera univoca i partecipanti alla rete.



        1. Il protocollo



Questo documento contiene le specifiche del protocollo 0.6 di Gnutella.

Ciascun Servants puo' estendere o cambiarne delle parti (ad esempio comprimendo o cifrando i messaggi), ma tutti i servants devono comunque conservare la compatibilita' con queste specifiche.

Se un servant, per esempio, intende comprimere i messaggi Gnutella, deve prima di tutto essere certo che l'altra parte possa decomprimere il flusso di dati, o altrimenti trasportare i messaggi non compressi.

Ciascun servants puo' rifiutare una connessione con un altro che non possiede una qualche feature, ma deve comunque garantire che la rete gnutella non venga divisa in tante reti separate.

Il protocollo Gnutella definisce il sistema con il quale i servants comunicano sulla rete. Consiste di un insieme di messaggi utilizzato per scambiarsi dati tra i servants ed un insieme di regole per lo scambio di messaggi tra i servant.

I possibili messaggi sono

Utilizzato per scoprire gli hosts sulla rete. Un servant che riceve un messaggio di Ping, risponde con uno o piu' Pong.

La risposta ad un Ping. Prevede l'invio dell' indirizzo del servant, la porta sulla quale e' in ascolto, e le informazioni circa la quantita' di dati disponibile sulla rete.

Il meccanismo principale per la ricerca all'interno della rete. Un servant riceve una Query alla quale risponde con una Query Hit se possiede in locale la risorsa.

La risposta ad una Query. Questo messaggio fornisce le informazioni necessarie per l'acquisizione della risorsa.

Un meccanismo per permettere ad un servant dietro ad un firewall di condividere files all'interno della rete.

Un messaggio facoltativo per chiudere la connessione con la rete.

Inizio della connessione

Un servant Gnutella si connette alla rete stabilendo una connessione con un altro partecipante alla rete.

Quando la prima connessione e' stata instaurata gli indirizzi di altri hosts vengono forniti direttamente dalla rete. La porta di default e' la 6346, ma un servant puo' utilizzare qualsiasi porta inutilizzata.

La porta utilizzata viene segnalata attraverso il comando pong.

Le tecniche utilizzate per decidere come decidere a quale altro nodo gnutella connettersi e quando accettare richieste di connessione sono state discusse precedentemente.

Quando si ottiene l'indirizzo di un altro servant, viene stabilita una connessione TCP/IP ed inizia la fase di handshake del protocollo. L'host che apre la sessione e' detto client, il server e' l'altra parte, che riceve.

"<cr>" indica il carattere ASCII 13(carriage return), e "<lf>" il 10 (new line).

  1. Il client realizza una connessione TCP con il server.

GNUTELLA CONNECT/0.6<cr><lf>

Il client spedisce degli headers contenenti le capability che implementa -- ad eccezzione degli headers vendor-specific -- ciascuno di essi terminato da "<cr><lf>", con un "<cr><lf>" alla fine.

  1. Il server risponde con "GNUTELLA/0.6 200 <string><cr><lf>".

<string> dovrebbe essere "OK", ma i servants dovrebbero effettuare il controllo sul codice "200".

  1. Il server manda tutti i propri headers, con il medesimo formato visto al punto 1.

  2. I clients spediscono un "GNUTELLA/0.6 200 OK<cr><lf>", come al punto 2, se dopo aver controllato ciascun headers, desiderano ancora connettersi. Altrimenti spediscono un codice d'errore e chiudono la connessione.

  3. I clients spediscono ogni i vendor-specific headers, con il medesimo formato.

  4. Sia i client che i server spediscono una serie di messaggi binari, utilizzando le informazioni ottenute ai punti 1 ed 5.

Tutti gli headers dovrebbero essere registrati nell'apposito database GDF all'indirizzo http://groups.yahoo.com/group/the_gdf/database?method=reportRows&tbl=9 (Requires GDF membership)

Gli headers segnuono lo standard definito nel RFC822 e nel RFC2616. Ciascun header e' composto di un campo nome, seguito un ':', e quindi un valore. Ciascuna linea termina con <cr><lf>, e la fine dell'headers e' contrassegnata una linea composta solo di <cr><lf>. Ciasuna linea contiene di solito un header, a meno che non inizi con con uno spazio o una tabulazione (rispettivamente codice 32 e 9 della codifica ASCII), nel qual caso rappresentano la continuazione di un precedente header.

Per esempio:

Primo-Campo: valore del primo campo<cr><lf>

Secondo-Campo: valore<cr><lf>

del<cr><lf>

secondo campo<cr><lf>

<cr><lf>



L'header precedente si compone di due campi, "Primo-Campo" e "Second-Campo" i cui valori sono rispettivamente "valore del primo campo" e "valore del secondo campo".Un campo composto di piu' valori puo' essere introdotto con due diverse, ma equivalenti, strutture.

Campo: primo valore<cr><lf>

Campo: secondo valore<cr><lf>

oppure

Campo: primo valore,secondo valore<cr><lf>

Call Flow

Qui di seguito vi e' un esempio di interazione tra un client ed un server.

Client

Server

GNUTELLA CONNECT/0.6<cr><lf>

User-Agent: BearShare<cr><lf>

Query-Routing: 0.2<cr><lf>

Pong-Caching: 0.1

<cr><lf>













GNUTELLA/0.6 200 OK<cr><lf>

Private-Data: a04fce<cr><lf>

<cr><lf>

[binary messages] [binary messages]











GNUTELLA/0.6 200 OK<cr><lf>

User-Agent: BearShare<cr><lf>

Query-Routing: 0.1<cr><lf>

Private-Data: 5ef89a<cr><lf>

Pong-Caching: 0.1

<cr><lf>



HEADER

Bytes 0 - 15: Message ID: Un message ID viene generato dal client ed identifica sulla rete Gnutella la sorgente di un messaggio. Di solito sono 16 bytes di dati casuali.

Byte 16: Function ID: Quali tipo di funzione svolge il pacchetto, le diverse tipologie sono illustrate poco piu' avanti.

Byte 17: TTL Remaining: il numero di hops prima di morire.

Byte 18: Hops taken: quanti hops ha gia' attraversato. Il TTL di una messaggio di risposta deve contenere questo valore, per essere sicuri che possa raggiungere il destinatario.

Bytes 19 - 22: Data Length: la dimensione della parte dati del pacchetto. Vi e' in corso una discussione per definire se soltanto 2 byte rappresentino le dimensioni e gli altri siano utilizzati per altre informazioni, l'autore del testo, sostiene che siano tutti destinati alla lunghezza dei dati.



Le operazioni possibili: * 0: Ping * 1: Ping Reply (Pong) * 64: Push Request * 128: Query * 129: Query Reply (Hits)

LA PARTE DATI:

Un ping non ha corpo, quindi il campo Data Lenght dell'header e' uguale a 0.

Routing: instradare il pacchetto attraverso ogni connessione aperta, ad eccezzione di quella da cui e' giunto.

Bytes 0 - 1: Host port: La porta TCP sulla quale il server e' in ascolto.

Bytes 2 - 5: Host IP: IP del server in ascolto, in network byte order.

Bytes 6 - 9: File Count: un intero che indica il numero di files condivisi dal host.

Bytes 10 - 14: File size: un intero che indica la dimensione totale dei files condivisi espressa in KB.

Routing: instradare il pacchetto solo attraverso la connessione dalla quale e' giunto il ping corrispondente.

Bytes 0 - 1: Minimum Speed: la velocita' minima che un servant dovrebbe avere per rispondere alla richiesta.

Bytes 2 +: Search String: una stringa terminata da NULL contenente la ricerca.

Routing: Instradare il pacchetto attraverso ogni connessione disponibile, eccetto quella da cui proviene.

Byte 0: Number of Items: In numero di risultati della ricerca.

Bytes 1 - 2: Host Port: la porta TCP del servant dell'host.

Bytes 3 - 6: Host IP: Ip dell'host, in network byte order.

Bytes 7 - 8: Host Speed: velocita' dell'host.

Bytes 9 - 10: Teoricamente a disposizione, non utilizzati o utilizzati per fornire informazioni ulteriori sulla velocita' della connessione.

Bytes 11 +: Lista dei risultati. Ogni campo della lista e' strutturato in questa maniera:

Bytes 0 - 3: File Index: A ciascun file presente nelle dir di upload viene assegnato un numero progressivo detto file index che lo identifica.

Bytes 4 - 7: File Size: le dimensioni del file (in bytes).

Bytes 8 +: File Name: Il nome del file, senza informazioni sul path all'interno del sistema. Deve essere terminato da 2 caretteri NULL.

Last 16 Bytes: Footer: Il clientID128 dell'host. Di solito e' una qualche funzione ricavata dall'IP e dalla porta.

Routing: Instradare il pacchetto soltanto attraverso l'interfaccia da cui e' giunto.

Bytes 0 - 15: ClientID128: il ClientID128 del server dal quale vorremmo ricevere il file. Dovrebbe contenere lo stesso valore fornito dal servant nella query hit in risposta ad una nostra query.

Bytes 16 - 19: File Index: il File Index dell'oggetto richiesto.

Bytes 20 - 23: Requester IP: IP del host. Network byte order.

Bytes 24 - 25: Requester Port: TCP port del servant.

Downloading

Il download avviene attraverso l'HTTP. Una GET viene spedita, con l'URI costruito in base alle informazioni contenute nel Query Replay. l'URI inizia con /get/ seguito dal File Index, quindi il nome.

Ad esempio:

GET /get/1234/risora_condivisa.tar.gz HTTP/1.0\r\n Connection: Keep-Alive\r\n Range: bytes=0-\r\n \r\n

Il server risponde con un normale header HTTP, e quindi il file.

HTTP 200 OK\r\n Server: Gnutella\r\n Content-type:application/binary\r\n Content-length: 948\r\n \r\n

Uploading:

L'upload avviene in risposta ad una Push Request. L'uploader stabilisce una connesione TCP con il richiedente e manda il comando GIV, seguito dal File Index e dal proprio ClientID128 e quindi il filename. Ad esempio:

GIV 1234/abcdefghijklmnop/ risora_condivisa.tar.gz\r\n\r\n


      1. Il protocollo di Kazaa - file sharing decentralizzato


Per studiare il protocollo ho utilizzato Kazaa Media Desktop V2.1 (Built: Thursday, February 06, 2003 14:15:14).Al momento non esiste una versione di kazaa per Linux.Per analizzare il traffico ho creato una macchina virtuale dentro il mio Linux box..

Il sistema operativo usato è Linux [naturalmete (-;] RedHat 7.3 su cui gira VMware 3.0 build 1455.Ho subito notato, come del resto si trova in tutta la documentazione di kazaa, che la porta in ascolto predefinita è la 1214. Ho dunque bloccato tale porta con:

iptables -A INPUT -p tcp --destination-port 1214 -j DROP

Una volta caricato VMware attivo il mio Sniffer (ho utilizzat Ethereal Version 0.9.7) e avvio Kazza Media Desktop su Windows 2000.Il Kazaa esegue subito delle chiamate al DNS e risolve 2 domini:

desktop.kazaa.com alias rr1.kazaa.com

www.altnetp2p.com (217.116.227.249) che è un alias di media.altnet.com

A questi si collega sulla porta 80 e scarica quello che poi presenta come pubblicità iniziale e banner in footer. Ho bloccato i traffico da/per questi indirizzi, il client kazaa continua a connettersi ma il desktop pubblicitario iniziale non è più visualizzato.

Immediatamente dopo, Kazaa si connette in http su www.cms1.net con la seguente riga:

http://209.73.225.7/scripts/cms/CmsInit.ASP?ID=200101&D2=%3F% <http://209.73.225.7/scripts/cms/CmsInit.ASP?ID=200101&D2=%3F%>

3F%3F%3F%3F%3F%3F%3F%3F%3F%40%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F&AW=291&LV=3210&CU=22068156

In risposta riceve:

DATA_OK W_STR [C=101][V=] W_STR [C=103][V=] W_STR [C=100][V=]

W_STR [C=102][V=] W_STR [C=104][V=] W_INT [C=33][V=22068156]

W_INT [C=34][V=1036021229]

Non risulta alcuna traccia di questi dati, ne sulla documentazione di kazaa ne su quella di fast track. Anche bloccando il traffico verso quest'ultimo domino, il cliente kazaa si connette...

La parte più importante viene di seguito. Per snellire la presentazione, ho escluso tutto il traffico sulle porte 80 perchè è dovuto per la quasi totalità a pagine pubblicitarie, e sulla porta 53 perchè le risoluzione del DNS non inficiano il concetto del protocollo. La mia stringa di tcpdump è la seguente

tcpdump -n -i vmnet8 ! port 80 && ! port 53

21:38:07.808426 arp who-has 192.168.0.2 tell 192.168.0.128

21:38:07.808609 arp reply 192.168.0.2 is-at 0:50:56:de:52:23

21:38:08.236503 192.168.0.128.3773 > 128.211.232.227.3498: udp 12

21:38:08.238046 192.168.0.128.3773 > 35.11.141.122.3876: udp 12

21:38:08.239208 192.168.0.128.3773 > 66.76.22.146.1665: udp 12

21:38:08.239931 192.168.0.128.3773 > 24.47.7.139.2603: udp 12

21:38:08.240596 192.168.0.128.3773 > 128.211.224.151.3398: udp 12

Se blocco il traffico sulla mia porta di origine, la 3773, il kazaa fa il bind di una nuova porta. Il mio client fa 5 richieste UDP a 5 server diversi su 5 porte diverse. Bloccando questi indirizzi e rilanciando il kazaa, il programma fa altre 5 richieste UDP a 5 server diversi dai precedenti.Dalle righe seguenti:

21:38:08.377185 24.47.7.139.2603 > 192.168.0.128.3773: udp 17

21:38:08.399219 128.211.224.151.3398 > 192.168.0.128.3773: udp 17

si evince che i client stanno rispondendo ognuno segnalando la propria porta disponibile alllo sharing.

Dopo di che comincia la transazione e scambio di risorse.

Il dump completo di tale transazione è riportato nell' APPENDICE A.

Continuando a bloccare server e porte, mi accorgo che solo 3 su 80 usano la famosa porta 1214.Una lista degli indirizzi/porte rilevate bloccate è riportata in APPENDICE B.




14