Gnutella
  Protocollo, Organizzazione ed Estensioni


Alberto Minetti       Marco Queirolo           Davide Scola

    Dipartimento di Informatica e Scienze dell’Informazione,
               Università degli studi di Genova,
                             Italia


           Seminario Peer to Peer, 2009
Sommario

  1   Alberto
        Introduzione a Gnutella
        Protocollo Gnutella
        File Transfer
        Querying the network
        Download Mesh
  2   Marco
        Local Hostcache
        PONG Caching
        Flow Control
        Routing Table
        Duplicates Table
        Query Routing Protocol

  3   Davide
        The Webcache System
        Crawling
        Browse Host Extension
        Active Queuing Extension
        Link Compression Extension
        Vendor Messages
        Bye Message
        Metadata
Generalità sulla Gnet




   Funzionamento schematizzato
      Gnutella è un protocollo per la ricerca distribuita e la
      distribuzione digitale.
        Ogni partecipante condivide le proprie risorse locali,
        individua risorse sulla rete e le ottinene.
        Modello di ricerca decentralizzato in cui ogni client è un
        server. Ogni host è detto Servent.
        Scambio di dati diretto attraverso HTTP.
Generalità sulla Gnet




   Principi Gnutella
        Assoluta decentralizzazione.
        Tutti i nodi sono uguali, almeno in origine.
        Rete auto-gestita.
        Comunicazioni avvengono su una base client-server.
        Nelle ultime versioni arrivò ad implementare importanti
        features (hashing, multi-fonti, ...).
Storia di Gnutella


   Justin Frankel

                                        Sviluppata come piccolo programma
                                        da Justin Frankel.
                                        Insieme a Tom Pepper fondò la
                                        Nullsoft.
                                        AOL, acquistata Nullsoft, ordinò il
                                        fermo del progetto.
                                        Grazie a reverse engineering il
                                        protocollo è stato reso pubblico.


   Nota

                     Nullsoft è la stessa casa produttrice di Winamp e di
                     WASTE.
Generalità sulla Gnet




   Gnutella 0.4
      Gnutella 0.4 è una rete omogenea.
      Ogni peer esegue queste istruzioni:
         1   Connessione ad un host ottenuto dalla GWebCache.
         2   Attraverso PING si ottengono informazioni sulla rete e sui
             peer connessi.
         3   Altre connessioni per creare la rete logica Gnet.
         4   Query e QueryHit sono instradate sulla Gnet usando
             flooding (vedremo dopo in dettaglio).
Generalità sulla Gnet




   Gnutella 0.6
      Gnutella 0.6 è una rete strutturata.
        Concetto di Ultrapeer.
        Cioè un peer che eccelle per memoria, banda e tempo di
        connessione che si occupa di instradare le query dei propri
        peer foglia verso altri Ultrapeer.
        Questi ultimi a loro volta instraderanno la query verso altri
        Ultrapeer e verso i propri nodi foglia,
        Intercetteranno i QueryHit e li rispediranno all’Ultrapeer
        richiedente che a sua volta invierà le risposte al nodo foglia
        che aveva inviato la richiesta.
Principi di Elezione degli Ultrapeer




   Ultrapeer capability
        Ultrapeers sono eletti senza l’uso di un server centrale.
        Spetta a ciascun nodo determinare se vuole diventare un
        Ultrapeer o un nodo foglia.
        Requisiti fondamentali:
          1   Non Firewalled.
          2   OS adatto (*NIX, Win XP/Server/NT, Mac OS/X sono
              meglio di Win 95/98/ME, Mac Classico).
          3   Larghezza di banda.
          4   Uptime futuro (Euristica sul tempo passato nella Gnet).
          5   RAM per le tabelle di routing.
          6   CPU per inoltrare le query in arrivo.
Principi di Elezione degli Ultrapeer




   Quando diventare Ultrapeer
        Un nodo ultrapeer-capable può diventare un Ultrapeer se
        vi è la necessità di avere più Ultrapeer sulla rete.
        La necessità di Ultrapeer può essere stimata guardando il
        numero di Ultrapeers trovati sulla rete
        Tali dati possono essere comunicati quando i nuovi
        collegamenti sono stabiliti (Ultrapeer Handshake).
Prefazione




   Quando diventare Ultrapeer
       Cerchiamo di definire il protocollo Gnutella 0.6.
       La versione 0.6 anche se BETA è comunque la versione
       che viene utilizzata dalla maggioranza degli applicativi.
       Un Servent che utilizza la versione STABLE, cioè la 0.4,
       può connettersi ad una rete composta da soli Servent 0.6.
       La differenza fondamentale tra le due major version è
       appunto la presenza di Ultrapeer.
       La porta di default è 6346 in entrambe le versioni.
Estensioni del protocollo




   Estensioni
       Alcuni Servents esistenti possono estendere il protocollo o
       addirittura modificare parti di esso (ad esempio la
       compressione o la crittografia dei messaggi)
        Comunque ogni servent rimanere sempre compatibile con
        servents che seguono la specifica.
        0.4 consente estensioni all’interno di molti messaggi, che
        possono passare attraverso servent che non conoscono
        queste estensioni per raggiungere peer che le sanno
        interpretare.
Estensioni del protocollo




   Example
        Se un servent, per esempio, vuole comprimere i messaggi
        Gnutella, deve prima assicurarsi che l’host remoto della
        connessione sia in grado di decomprimere (ciò è
        controllato avviene durante l’handshake), e in caso
        contrario è obbligato lasciare i messaggi non compressi.
        I Servents possono decidere di non accettare una
        connessione con un Servent che non supporta una
        funzione, ma devono sempre fare il possibile (best effort)
        per garantire che la rete Gnutella non si divida in reti
        separate.
Bootstrap




   Bootstrap vecchie versioni
       Nelle prime fasi del protocollo Gnutella, ci sono stati diversi
       host conosciuti permanente
       Il loro scopo era quello di fornire una lista di host Gnutella
       a qualsiasi Servent Gnutella connessione a loro.
       Questi sono stati spesso chiamati hostcaches.
       Tuttavia gli hostcaches non vengono più utilizzati perchè si
       perdono alcuni dei vantaggi di un sistema distribuito.
Bootstrap



   Bootstrap nuove versioni
       Per connettersi alla rete Gnutella, un Servent ha bisogno di
       trovare e memorizzare gli indirizzi host.
       Ci sono quattro modi con cui un Servent può ottenere gli
       indirizzi di host:
        1   Chiedere a un GWebCache
        2   Memorizzare gli indirizzi host letti dagli header X-Try e dagli
            header X-Try-Ultrapeers durante un handshake (sia che la
            stretta di mano abbia avuto successo o no).
        3   Memorizzare gli indirizzi host nei messaggi pong (dopo
            almeno che un collegamento viene stabilito con la GNet).
        4   Memorizzare gli indirizzi host leggendo i messaggi
            QueryHit (dopo che un minimo di due connessioni sono
            stabilite con la GNet).
Bootstrap




   Condividere indirizzi host
      Ogni Servent dovrebbe inviare un header X-Try durante
      l’handshake.
       Questa intestazione fornisce una lista di host a cui l’altro
       Servent può tentare di connettersi
       Permette di ottenere gli indirizzi di nuovi host senza
       utilizzare il GWebCache.

   Example
   X-Try: 1.2.3.4:1234, 1.2.3.5:6346, 1.2.3.6:6347
Bootstrap




   Condividere indirizzi host
      Un Servent dovrebbe inviare un numero ragionevole di
      host, i valori sono compresi tra 10 e 20.
       Comunque chi invia X-Try dovrebbe controllare che questi
       host abbiano una buona qualità.
       Includere host remoti che sono stati visti attivi di recente
       (non più di pochi minuti).
       Gli host trovati grazie ai Pong sono buoni candidati per
       l’inserimento in intestazioni X-Try.
       Per host trovati tramite QueryHit non è detto.
Handshaking




   Condividere indirizzi host
      Un Servent crea una connessione TCP/IP ad un altro
      Servent e viene avviata una sequenza di handshaking.
       Il cliente è l’host che inizia la connessione e il server è
       l’host che è in ascolto.
Handshaking



   Condividere indirizzi host
    1   Il client stabilisce una connessione TCP con il server.
    2   Il client invia GNUTELLA CONNECT/0.6 <cr><lf>.
    3   Il client invia tutti gli header, ad eccezione di vendor-header, come
        specificato da HTTP (RFC2616).
    4   Il server risponde con GNUTELLA/0.6 200 <string> <cr><lf>.
    5   Il server invia tutte i prorpi header.
    6   Il client invia GNUTELLA/0.6 200 OK <cr><lf>, se dopo il parsing
        headers del server, desidera connettersi. In caso contrario, risponde
        con un codice di errore e chiudere la connessione.
    7   Il client invia i vendor-header se necessario.
    8   Entrambi i client e server di invio di messaggi binari, utilizzando le
        informazioni acquisite in (3) e (5).
Header HTTP



   Formato degli Header
      Ogni header è costituito da un nome di campo seguito da
      due punti e quindi il valore.
      Ogni riga termina con la sequenza <cr><lf>.
      La fine degli header è segnata da una singola linea
      <cr><lf>
      In ogni linea solitamente inizia una nuovo header
      Se inizia con uno spazio (ASCII 32) o una tabulazione
      orizzontale (ASCII 9) significa che sta continuando il
      precedente header.
      Gli spazi in più e le tabulazioni orizzontali possono essere
      compressi in uno spazio unico.
Header HTTP



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



                          equivale a:


   Example
   Primo-Campo: valore del primo campo <cr><lf>
   Secondo-Campo: valore del secondo campo <cr><lf>
Header HTTP



   Header multi linea con lo stesso nome di campo sono
   equivalenti a quelli di una linea dove tutti i valori dei campi sono
   separati da , (virgola).
   Example
   Campo: primo <cr><lf>
   Campo: secondo <cr><lf>



                               equivale a:


   Example
   Campo: primo, secondo <cr><lf>
Header HTTP




   Formato degli Header
      Vediamo un esempio di interazione tra un client e un
      server.
      I dati inviati dal client al server sono visualizzati nella parte
      sinistra.
      I dati inviati dal server al client sono visualizzati sulla
      destra.
      E’ importante notare che le intestazioni possono essere inviate in
      qualsiasi ordine.
      Alcune intestazioni non essenziali per l’esempio sono state rimosse
Esempio di Handshake


   Example
   Client                         Server
   -----------------------------------------------------------
   GNUTELLA CONNECT/0.6<cr><lf>
   User-Agent: BearShare/1.0<cr><lf>
   Pong-Caching: 0.1<cr><lf>
   GGEP: 0.5<cr><lf>
   <cr><lf>
                                  GNUTELLA/0.6 200 OK<cr><lf>
                                  User-Agent: BearShare/1.0<cr><lf>
                                  Pong-Caching: 0.1<cr><lf>
                                  GGEP: 0.5<cr><lf>
                                  Private-Data: 5ef89a<cr><lf>
                                  <cr><lf>
   GNUTELLA/0.6 200 OK<cr><lf>
   Private-Data: a04fce<cr><lf>
   <cr><lf>

   [binary messages]               [binary messages]
Handshaking




   Formato degli Header
      Il client (server) deve disconnettersi se riceve una risposta
      diversa da 200 al punto 4 (6).
      I servent deve usare intestazioni HTTP standard ove
      opportuno.
      Per esempio usare lo User-Agent piuttosto che un Vendor.
      Naturalmente esistono anche intestazioni proprie di
      Gnutella (per esempio, Query-Routing).
      Il codice di stato per il rifiuto di una connessione è 503
      seguito da Busy o un’altra stringa di descrizione.
Handshaking




   Futura Retrocompatibilità
       I servent possono ignorare i numeri di versione superiore
       al loro.
       E’ legale per un futuro client di connettersi a un server e
       inviare GNUTELLA CONNECT/0.7. Il server se non
       supporta 0.7 deve rispondere con GNUTELLA/0.6 200 OK.
       Intestazioni sconosciute al servent saranno semplicemente
       ignorate.
Handshaking




   Retrocompatibilità alla 0.4
       Alcuni vecchi servents avviano l’handshake con
       GNUTELLA CONNECT/0.4 <lf><lf>. Il server dovrebbe
       rispondere con OK GNUTELLA <lf><lf> seguito da
       messaggi binari.
       I servents possono riprovare con la stringa di connessione
       versione 0.4, se il tentativo di connessione versione 0.6 è
       stato respinto.
       Non è possibile usare nessun’header con la versione 0.4.
Handshaking




   X-Try
        Quando una connessione viene respinta, un servent deve
        fornire all’altro una lista di altri host Gnutella, in modo che il
        primo possa provare a connettersi a questi ultimi.

   Example
   X-Try: 1.2.3.4:1234,3.4.5.6:3456


   Nota
   Ogni elemento dell’header X-Try fornisce l’indirizzo IP di un Servent e il suo
   numero di porta di ascolto.
Nodi foglia e Ultrapeer



   Rete strutturata
       Originariamente tutti i nodi erano collegati gli uni agli altri in
       modo casuale.
        Ha funzionato bene per gli utenti con connessioni a banda
        larga.
        Il problema può essere alleviato con un’organizzazione
        strutturata.
        La nuova (0.6) rete gerarchica di Gnutella caratterizza i
        nodi della rete come foglie e Ultrapeers.
        I nodi della 0.4 vengono trattati come foglie poichè, non
        implementando il sistema Ultrapeer, non potranno mai
        essere Ultrapeer.
Nodi foglia e Ultrapeer




   Rete strutturata (cont.)
        Una foglia mantiene solo un piccolo numero di connessioni
        aperte, che sono quelle tra essa e alcuni Ultrapeers.
        Un Ultrapeer agisce come un proxy tra la rete Gnutella e le
        foglie ad esso collegati.
        Questo ha l’effetto di rendere la rete Gnutella scalabile
        riducendo:
          1   il numero di nodi della rete coinvolti nella gestione dei
              messaggi e nel routing
          2   quindi riduce il traffico reale tra i nodi.
Nodi foglia e Ultrapeer




   Rete strutturata (cont.)
        Un Ultrapeer inoltra una query a una foglia solo se ritiene
        che la foglia possa rispondere.
        Le foglie non inoltrano mai le query agli Ultrapeers.
        Ultrapeers sono collegati gli uni agli altri.
        Un Ultrapeer decide quali query trasmettere ai nodi foglia
        utilizzando il Query Routing Protocol, QRP.
        QRP routing non viene inviato tra Ultrapeers e foglie
        versione 0.4.
Informazioni per l’elezione




   Rete strutturata (cont.)
        Le informazioni per l’elezione degli Ultrapeer sono
        scambiate durante la sequenza di handshaking.
        Vengono usate le seguenti nuove (0.6) intestazioni:
          1   X-Ultrapeer True segnala che il nodo è un Ultrapeer, False
              segnala che il nodo vuol essere un nodo foglia.
          2   X-Ultrapeer-Needed usato per bilanciare il numero di
              Ultrapeers.
          3   X-Try-Ultrapeers come X-Try, ma contiene solo gli indirizzi
              di Ultrapeers.
          4   X-Query-Routing Segnala il supporto per QPR. Il valore è
              la versione QRP (attualmente 0.1).
Esempio di Handshake



   Example (Una foglia si connette ad un Ultrapeer)
   Leaf                        Ultrapeer
   -----------------------------------------------------------
   GNUTELLA CONNECT/0.6
   User-Agent: LimeWire/1.0
   X-Ultrapeer: False
   X-Query-Routing: 0.1
                               GNUTELLA/0.6 200 OK
                               User-Agent: LimeWire/1.0
                               X-Ultrapeer: True
                               X-Ultrapeer-Needed: False
                               X-Query-Routing: 0.1
                               X-Try: 24.37.144:6346,
                                193.205.63.22:6346
                               X-Try-Ultrapeers: 23.35.1.7:6346,
                                18.207.63.25:6347
   GNUTELLA/0.6 200 OK
    [binary messages]          [binary messages]
Esempio di Hadshake (cont.)




   Vedi esempio precedente
   Al termine dell’esempio precedente
       La foglia è coperta dal Ultrapeer.
       La foglia dovrebbe eliminare eventuali connessioni a non
       Ultrapeer.
       E inviare una tabella di routing QRP (supponendo QRP sia
       utilizzato).
Esempio di Handshake




   Example (Una foglia si connette ad un’altra foglia)
   Leaf1                            Leaf2
   -----------------------------------------------------------
   GNUTELLA CONNECT/0.6
   X-Ultrapeer: False

                                GNUTELLA/0.6 503 I am a leaf
                                X-Ultrapeer: False
                                X-Try: 24.37.144:6346
                                X-Try-Ultrapeers: 23.35.1.7:6346

                                   [Terminates connection]
Esempio di Hadshake (cont.)




   Foglia e Foglia
   Al termine dell’esempio precedente
       Se una foglia coperta riceve una richiesta di connessione,
       la connessione deve essere rifiutata con il codice di errore
       503.
       E insieme deve inviare un X-Try e un X-Try-Ultrapeer.
Esempio di Hadshake


   Foglia e Foglia
   A volte i nodi possono essere entrambi non Ultrapeer e
   incapaci di trovare un Ultrapeer. In questo caso, si comportano
   esattamente come il vecchio protocollo 0.4 non strutturato.

   Example (Una foglia si connette ad un’altra foglia)
   Leaf1                         Leaf2
   --------------------------------------------------
   GNUTELLA CONNECT/0.6
   X-Ultrapeer: False

                              GNUTELLA/0.6 200 OK
                              X-Ultrapeer: False

   GNUTELLA/0.6 200 OK

    [binary messages]           [binary messages]
Esempio di Hadshake


   Foglia e Foglia
   Quando due Ultrapeer si incontrano entrambi hanno impostato
   X-Ultrapeer: True. Se entrambi hanno nodi foglia, rimarranno
   Ultrapeers dopo l’interazione.

   Example (Connessione tra due Ultrapeer)
   UltrapeerA                     UltrapeerB
   ------------------------------------------------------
   GNUTELLA CONNECT/0.6
   X-Ultrapeer: True

                                GNUTELLA/0.6 200 OK
                                X-Ultrapeer: True

    GNUTELLA/0.6 200 OK

    [binary messages]          [binary messages]
Esempio di Hadshake




   Example (Abdicazione di un Ultrapeer)
   UltrapeerA                       UltrapeerB
   -----------------------------------------------------------
   GNUTELLA CONNECT/0.6
   X-Ultrapeer: True
                                 GNUTELLA/0.6 200 OK
                                 X-Ultrapeer: True
                                 X-Ultrapeer-Needed: False
   GNUTELLA/0.6 200 OK
    X-Ultrapeer: False
Esempio di Hadshake (cont.)



   Abdicazione di un Ultrapeer
       A volte ci saranno troppi Ultrapeer.
       Consideriamo il caso di un Ultrapeer A collegato a una
       Ultrapeer B.
       Se B non ha abbastanza foglie B può chiedere a A se può
       diventare una sua foglia.
       Se A non ha connessioni a foglie, si arresta il processo di
       nuove connessioni, termina ogni connessione 0.4, e invia
       una tabella QRP a B.
       Allora B farà da proxy ad A per tutto il traffico.
       Se A ha connessioni a foglie, ignora la richiesta.
Messaggi binari Gnutella



   Messaggi binari Gnutella
        Tutti i messaggi binari Gnutella viaggiono sulla Gnet.
        L’inoltro dei messaggi sulla rete avviene attraverso
        flooding.
        Poichè il flooding è estremamente pesante vengono usati
        alcune precauzioni:
           1   Caching (esempio pong-caching).
           2   Query Routing Table (in seguito).
           3   Dynamic Querying.

   Nota
   Il meccanismo di Dynamic Querying permette agli Ultrapeer di eseguire
   ricerche aggiuntive per file rari (poche QueryHit) e di diminuire il traffico per
   ricerche di file popolari (motle QueryHit).
Header del messaggio binario


       Message Header
    Bytes Descrizione
    0-15   GUID
    16     Payload Type
    17     TTL
    18     Hops
    19-22 Payload Length
Header del messaggio binario


       Message Header          GUID
    Bytes Descrizione          Una stringa di 16 byte (GUID)
    0-15   GUID                identifica in modo univoco il
    16     Payload Type        messaggio sulla rete.
    17     TTL
    18     Hops
    19-22 Payload Length
Header del messaggio binario


       Message Header               Payload Type
    Bytes Descrizione               Indica il tipo di messaggio.
    0-15   GUID                     0x00 Ping
    16     Payload Type             0x01 Pong
    17     TTL                      0x02 Bye
    18     Hops                     0x40 Push
    19-22 Payload Length            0x80 Query
                                    0x81 Query Hit

   Nota
   Altri tipi di messaggio Gnutella possono essere usati, ma in tal caso il
   Servent deve prima assicurarsi che l’host remoto supporta questo nuovo tipo
   di messaggio. Questo può essere fatto utilizzando le intestazioni di
   handshaking.
Header del messaggio binario


       Message Header                  Time To Live
    Bytes Descrizione                  Ogni Servent dovrà diminuire il
    0-15   GUID                        TTL, prima di passare il
    16     Payload Type                messaggio a un altro Servent.
    17     TTL                         Quando il TTL raggiunge 0, il
    18     Hops                        messaggio non sarà più
    19-22 Payload Length               trasmesso. MAI esagerare

   Nota
   L’abuso del campo TTL nei messaggi trasmessi porterà ad un ecceso di
   traffico! I servent devono verificare il TTL dei messaggi ricevuti e diminuirli se
   necessario. Messaggi con valori di TTL molto elevati (> 15) dovrebbe essere
   eliminati.
Header del messaggio binario


       Message Header                  Hops
    Bytes Descrizione                  Il numero di volte in cui il
    0-15   GUID                        messaggio è stato inoltrato. Ogni
    16     Payload Type                Servent dovrà incrementare Hops
    17     TTL                         prima di passare il messaggio ad
    18     Hops                        un altro Servent.
    19-22 Payload Length

   Nota
                            TTL(0) = TTL(i) + Hops(i)
   dove TTL(i) e il Hops(i) sono il valore del TTL e di Hops del messaggio, e
   TTL(0) è il numero massimo di salti che un messaggio può fare (possiamo
   identificarlo come profondità, di solito è impostato a 7 ma alcuni applicativi
   permettono di modificare il valore).
Header del messaggio binario


       Message Header               Payload Length
    Bytes Descrizione               La lunghezza del messaggio che
    0-15   GUID                     segue immediatamente questa
    16     Payload Type             intestazione.
    17     TTL
    18     Hops
    19-22 Payload Length

   Nota
   Questo campo è unsigned e potrebbe raggiungere il valore molto elevati. Da
   specifica non dovrebbe superare i 4 KB.
PING 0x00




   Messaggio PING
      Il messaggio PING può contenere un’estensione GGEP
      (specificato più avanti) ma nessun payload.
PONG 0x01



   Messaggio PONG
   I messaggi Pong vengono inviati solo in risposta a un
   messaggio in arrivo Ping.

   Nota
   E’ comune per un Servent inviare tutti i Pong ricevuti recentemente ad ogni
   singolo messaggio Ping. Ciò è fattibile attraverso una host-cache in modo da
   inviare informazioni memorizzate nella cache senza sovraccaricare la rete
   (vedremo questo meccanismo in dettaglio successivamente).


   Nota
   L’ID del messaggio Pong in risposta ad un Ping deve essere lo stesso ID del
   messaggio Ping.
PONG 0x001


    Messaggio PONG
   Bytes Descrizione
   0-1    Host Port
   2-5    Host IP
   6-9    Total Files
   10-13 Total KB
   14     GGEP
PONG 0x001


    Messaggio PONG      Host Port
   Bytes Descrizione    Numero di porta su cui l’host che
   0-1    Host Port     risponde può accettare
   2-5    Host IP       connessioni in ingresso.
   6-9    Total Files
   10-13 Total KB
   14     GGEP
PONG 0x001


     Messaggio PONG                Host IP
    Bytes Descrizione              Indirizzo IP dell’host che risponde.
    0-1    Host Port
    2-5    Host IP
    6-9    Total Files
    10-13 Total KB
    14     GGEP

   Nota
   Questo campo è in formato big-endian.
PONG 0x001


    Messaggio PONG      Total Files
   Bytes Descrizione    Numero di file condivisi.
   0-1    Host Port
   2-5    Host IP
   6-9    Total Files
   10-13 Total KB
   14     GGEP
PONG 0x001


    Messaggio PONG      Total KB
   Bytes Descrizione    Kilobyte condivisi.
   0-1    Host Port
   2-5    Host IP
   6-9    Total Files
   10-13 Total KB
   14     GGEP
PONG 0x001


    Messaggio PONG      GGEP
   Bytes Descrizione    Il blocco dell’estensione opzionale
   0-1    Host Port     GGEP (vedremo dopo GGEP
   2-5    Host IP       approfonditamente).
   6-9    Total Files
   10-13 Total KB
   14     GGEP
QUERY 0x80


      Messaggio QUERY
   Bytes Descrizione
   0-1    minSpeed
   2-     Search Criteria
   -      Opt. Extensions
QUERY 0x80


       Messaggio QUERY            Search Criteria
    Bytes Descrizione             Criteri di ricerca.
    0-1    minSpeed
    2-     Search Criteria
    -      Opt. Extensions

   Nota
   Questo campo è terminato da un NULL (0x00).
QUERY 0x80


       Messaggio QUERY                Optional Extensions
    Bytes Descrizione                 Il resto del messaggio di query
    0-1    minSpeed                   viene utilizzato per i blocchi delle
    2-     Search Criteria            estensioni opzionali. Le estensioni
    -      Opt. Extensions            ammesse sono GGEP, HUGE e
                                      XML (descritti in seguito).

   Nota
   Se due o più di questi tipi di estensione sono insieme, saranno separati da un
   byte 0x1C (separatore di file). Dato che i blocchi GGEP possono contenere
   un byte 0x1C, il blocco GGEP, se presente, deve essere collocato dopo i
   blocchi HUGE e blocchi XML. Il tipo di ogni blocco può essere determinato
   cercando i prefissi urn: per un grande blocco, < o ( per XML e 0xC3 per
   GGEP. Il blocco di estensione non dovrebbe essere seguito da un NULL
   (0x00), ma alcuni applicativi erroneamente lo fanno.
QUERY 0x80


       Messaggio QUERY              minSpeed
    Bytes Descrizione
                                    In Gnutella 0.4 questo campo
    0-1    minSpeed                 indicava la velocità minima in KB/s
    2-     Search Criteria          richiesta per rispondere alla query.
    -      Opt. Extensions

   minSpeed
      Questo uso è ormai obsoleto.
      Gnutella 0.6 cambia la semantica.
      Viene mantenuta una certa retrocompatibilità.
      La nuova semantica è in formato big-endian.
      Il bit più elevato (big-endian) (15◦ bit) viene usato come una flag per
      indicare nuova o vecchia semantica.
QUERY 0x80


       Messaggio QUERY             minSpeed
    Bytes Descrizione
                                   In Gnutella 0.4 questo campo
    0-1    minSpeed                indicava la velocità minima in KB/s
    2-     Search Criteria         richiesta per rispondere alla query.
    -      Opt. Extensions

   Nota
   Vediamo adesso qual’è la nuova semantica del campo che in Gnutella 0.4
   indicava la velocità.
QUERY / minSpeed/Flags


        QUERY Flags
    Bytes Descrizione
    15    EnableFlags
    14    Firewalled
    13    XML Metadata
    12    LGDQ
    11    GGEP H
    10    OOB Q
    9     Riservato
    0-8   Max QueryHits
QUERY / minSpeed/Flags


        QUERY Flags       EnableFlags
    Bytes Descrizione     Indicatore che deve essere
    15    EnableFlags     impostato a 1 per indicare che le
    14    Firewalled      bandiere sotto sono utilizzati al
    13    XML Metadata    posto di codifica per la velocità
    12    LGDQ            minima.
    11    GGEP H
    10    OOB Q
    9     Riservato
    0-8   Max QueryHits
QUERY / minSpeed/Flags


        QUERY Flags                   Firewalled
    Bytes Descrizione                 L’host che ha inviato la query non
    15    EnableFlags                 è in grado di accettare connessioni
    14    Firewalled                  in entrata.
    13    XML Metadata
    12    LGDQ
    11    GGEP H
    10    OOB Q
    9     Riservato
    0-8   Max QueryHits

   Nota
   Questa opzione può essere utilizzata dal ricevente per evitare di restituire
   QueryHit se anche lui è Firewalled.
QUERY / minSpeed/Flags


        QUERY Flags       XML Metadata
    Bytes Descrizione     Questo bit è a 1 se si desidera che
    15    EnableFlags     il ricevente invii dei metadati XML
    14    Firewalled      nella QueryHit.
    13    XML Metadata
    12    LGDQ
    11    GGEP H
    10    OOB Q
    9     Riservato
    0-8   Max QueryHits
QUERY / minSpeed/Flags


        QUERY Flags       Leaf Guidate Dynamic Query
    Bytes Descrizione
                          Quando il bit è impostato a 1,
    15    EnableFlags     questo significa che la query viene
    14    Firewalled      inviata da una foglia che vuole
    13    XML Metadata    controllare il meccanismo Dynamic
    12    LGDQ            Queryung.
    11    GGEP H
    10    OOB Q
    9     Riservato
    0-8   Max QueryHits
QUERY / minSpeed/Flags


        QUERY Flags                   Payload Length
    Bytes Descrizione
                                      GGEP H sono ammessi.
    15    EnableFlags
    14    Firewalled
    13    XML Metadata
    12    LGDQ
    11    GGEP H
    10    OOB Q
    9     Riservato
    0-8   Max QueryHits

   Nota
   Se questo bit è 1 il mittente è in grado di analizzare il GGEP H, che è un
   rimpiazzamento dell’estensione HUGE GEM (Vedremo solo HUGE).
QUERY / minSpeed/Flags


        QUERY Flags       Out of Band Query
    Bytes Descrizione
                          Questo flag viene utilizzato per
    15    EnableFlags     riconoscere una query che è stata
    14    Firewalled      inviata con l’estensione Out of
    13    XML Metadata    Band Query.
    12    LGDQ
    11    GGEP H
    10    OOB Q
    9     Riservato
    0-8   Max QueryHits
QUERY / minSpeed/Flags


        QUERY Flags                 Massime Query Hits
    Bytes Descrizione
                                    Ciò non significa che devono
    15    EnableFlags               essere eliminate delle QueryHit,
    14    Firewalled                ma significa che la Query deve
    13    XML Metadata              essere propagata in modo che il
    12    LGDQ                      numero delle risposte rispettino
    11    GGEP H                    tale limite.
    10    OOB Q
    9     Riservato
    0-8   Max QueryHits

   Nota
   0 (zero) indica nessun limite.
QUERYHIT 0x81


     Messaggio QUERYHIT
    Bytes   Descrizione
    0       Total Hits
    1-2     Host Port
    3-6     Host IP
    7-10    Speed
    11-     Result Set
    x       Extended QHD
    x       Vendor-specific
    last 16 ServentID
QUERYHIT 0x81


     Messaggio QUERYHIT      Total Hits
    Bytes   Descrizione      Il numero di riscontri nell’insieme
    0       Total Hits       dei risultati.
    1-2     Host Port
    3-6     Host IP
    7-10    Speed
    11-     Result Set
    x       Extended QHD
    x       Vendor-specific
    last 16 ServentID
QUERYHIT 0x81


     Messaggio QUERYHIT                 Host Port
    Bytes   Descrizione                 Il numero di porta su cui l’host
    0       Total Hits                  rispondente può accettare in
    1-2     Host Port                   ingresso le richieste HTTP per
    3-6     Host IP                     inviare il file.
    7-10    Speed
    11-     Result Set
    x       Extended QHD
    x       Vendor-specific
    last 16 ServentID

   Nota
   Di solito la stessa porta che è usata per il traffico della rete Gnutella.
QUERYHIT 0x81


     Messaggio QUERYHIT            Host IP
    Bytes   Descrizione            L’indirizzo IP del host rispondente.
    0       Total Hits
    1-2     Host Port
    3-6     Host IP
    7-10    Speed
    11-     Result Set
    x       Extended QHD
    x       Vendor-specific
    last 16 ServentID

   Nota
   Questo campo è in formato big-endian.
QUERYHIT 0x81


     Messaggio QUERYHIT      Speed
    Bytes   Descrizione
                             La velocità (in KB/secondo)
    0       Total Hits       dell’host rispondente.
    1-2     Host Port
    3-6     Host IP
    7-10    Speed
    11-     Result Set
    x       Extended QHD
    x       Vendor-specific
    last 16 ServentID
QUERYHIT 0x81


     Messaggio QUERYHIT              Result Set
    Bytes   Descrizione              Insieme dei risultati alla query
    0       Total Hits               corrispondente.
    1-2     Host Port
    3-6     Host IP
    7-10    Speed
    11-     Result Set
    x       Extended QHD
    x       Vendor-specific
    last 16 ServentID

   Nota
   Questo insieme contiene esattamente tanti elementi quanti sono quelli
   specificati dal primo byte della QueryHit. Vedi sotto per il formato.
QUERYHIT 0x81


     Messaggio QUERYHIT      Extended QHD
    Bytes   Descrizione      Questo blocco non è obbligatorio
    0       Total Hits       ma è molto importante, lo vediamo
    1-2     Host Port        in seguito.
    3-6     Host IP
    7-10    Speed
    11-     Result Set
    x       Extended QHD
    x       Vendor-specific
    last 16 ServentID
QUERYHIT 0x81


     Messaggio QUERYHIT      Dati Vendor-specific
    Bytes   Descrizione
                             Questi dati possono essere
    0       Total Hits       ignorati dagli applicativi che non
    1-2     Host Port        riescono a capirli.
    3-6     Host IP
    7-10    Speed
    11-     Result Set
    x       Extended QHD
    x       Vendor-specific
    last 16 ServentID
QUERYHIT 0x81


     Messaggio QUERYHIT                Servent Identifier
    Bytes   Descrizione                Una stringa di 16 byte che
    0       Total Hits                 identifica in modo univoco il
    1-2     Host Port                  Servent rispondente sulla rete.
    3-6     Host IP
    7-10    Speed                      Nota
    11-     Result Set                       Questo deve essere costante per
    x       Extended QHD                     ogni QueryHit inviata da un Servent.
    x       Vendor-specific                   Di solito è creato in funzione
    last 16 ServentID                        dell’indirizzo di rete dell’host.

   Nota
   Il Servent Identifier è utilizzato principalmente per il routing dei messaggi
   PUSH (vedi sotto).
QUERYHIT Result Set




   Result Set
      All’interno di ogni QUERYHIT abbiamo un insieme di
      elementi che corrispondono ai criteri ricercati dalle QUERY
      corrispondente.
Result Set Item


       RESULT Set Item
    Bytes Descrizione
    0-3    FileIndex
    4-7    FileDimension
    8-     FileName
    x      Extensions
Result Set Item


       RESULT Set Item     FileIndex
    Bytes Descrizione      Un numero, assegnato dall’host
    0-3    FileIndex       rispondente, che viene utilizzato
    4-7    FileDimension   per identificare in modo univoco il
    8-     FileName        file corrispondente ai criteri di
    x      Extensions      ricerca.
Result Set Item


       RESULT Set Item               FileDimension
    Bytes Descrizione                La dimensione (in byte) del file il
    0-3    FileIndex                 cui indice è FileIndex.
    4-7    FileDimension
    8-     FileName
    x      Extensions

   Nota
   Per file di grandi dimensioni la cui dimensione non può essere espressa con
   un intero senza segno a 32 bit, un blocco GGEP LF può essere utilizzato nel
   blocco estensioni.
Result Set Item


       RESULT Set Item              FileName
    Bytes Descrizione               Il nome del file il cui indice è
    0-3    FileIndex                FileIndex.
    4-7    FileDimension
    8-     FileName
    x      Extensions

   Nota
   Terminato da un byte NULL (vale a dire 0x00).
Result Set Item


       RESULT Set Item                 Extensions
    Bytes Descrizione                  Tipi di estensione ammessi sono
    0-3    FileIndex                   HUGE, GGEP e metadati
    4-7    FileDimension               plaintext. Questo campo è
    8-     FileName                    terminato da un NULL (0x00).
    x      Extensions

   Nota
   Inoltre, le estensioni di blocco stesso non deve contenere byte NULL. Se due
   o più di questi tipi di estensione coesistono, sono separati da un byte 0x1C
   (separatore di file). Dato che i blocchi GGEP possono contenere il byte 0x1C,
   il blocco GGEP, se presente, deve essere collocato dopo HUGE e dopo
   plaintext. Il tipo di ogni blocco può essere determinato cercando i prefissi urn:
   per un blocco HUGE, 0xC3 per GGEP e qualsiasi altra cosa per i metadati
   plaintext.
Result Set Item


       RESULT Set Item
    Bytes Descrizione
    0-3    FileIndex
    4-7    FileDimension
    8-     FileName
    x      Extensions

   Example
   I metadati plaintext sono destinati ad essere visualizzati direttamente
   all’utente. Un esempio di plaintext può essere quello usato nelle prime
   versioni di Gnutella per specificare la qualità di un file MP3:

                             192 kbps 44 kHz 3:23
                           120 kbps (VBR) 44kHz 3:55
Extended QueryHit Descriptor


        Extended QHD
    Bytes Descrizione
    0-3     Vendor-code
    4       OpenData size
    x       OpenData
Extended QueryHit Descriptor


        Extended QHD                    Vendor-code
    Bytes Descrizione                   Quattro caratteri case-insensitive
    0-3     Vendor-code                 che rappresentano un codice
    4       OpenData size               fornitore.
    x       OpenData

   Example
                           Ad esempio LIME di LimeWire.


   Nota
   Altri codici registrati possono essere trovati qui

     http://rfc-gnutella.sourceforge.net/developer/stable/
                       index.html#tA-1-3
Extended QueryHit Descriptor


        Extended QHD                OpenData size
    Bytes Descrizione
                                    Contiene la lunghezza (in byte) del
    0-3     Vendor-code             campo OpenData.
    4       OpenData size
    x       OpenData

   Nota
   Impostato a 2 nella maggior parte delle implementazioni attuali, e a 4 in
   quelle con il supporto di metadati XML esterno GGEP. L’area OpenData può
   essere più grande per permettere future estensioni.
Extended QueryHit Descriptor


        Extended QHD
    Bytes Descrizione
    0-3     Vendor-code
    4       OpenData size
    x       OpenData
OpenData


     OpenData primo Byte            OpenData secondo Byte
    Bit Descrizione                 Bit Descrizione
    7,6 Riservati                   7,6 Riservati
    5   setGGEP                     5   flagGGEP
    4   setUploadSpeed              4   flagUploadSpeed
    3   setHaveUploaded             3   flagHaveUploaded
    2   setBusy                     2   flagBusy
    1   Riservato                   1   Riservato
    0   flagPush                     0   setPush

   OpenData
      Il primo byte serve per abilitare le flag sel secondo.
      Solo i bit abilitati devono essere considerati.
      Logica invertita per quanto riguarda il setPush/flagPush.
OpenData (cont.)



   Campi di OpenData
   flagGGEP indica che è presente un’estensione GGEP.
   flagUploadSpeed precisa la semantinca del campo Speed
   (velocità media o massimo upload definito dell’utente).
   flagHaveUploaded indica se il Servent ha effettuato almeno un
   upload.
   flagBusy è a 1 se tutti gli slot di upload occupati.
   flagPush significa che il Servent è firewalled.

   Nota
   Se i metadati XML sono inclusi nella corrente QueryHit, i seguenti 2 byte di
   OpenData conterranno la dimensione del blocco XML che è collocato nella
   zona successiva.
PUSH 0x40


     Messaggio PUSH
    Bytes Descrizione
    0-15  ServentID
    16-19 FileIndex
    20-23 HostIp
    24-25 HostPort
    26-   Opt. GGEP
PUSH 0x40


     Messaggio PUSH                  Servent Identifier
    Bytes Descrizione                La stringa di 16 byte identifica in
    0-15  ServentID                  modo univoco il Servent sulla rete
    16-19 FileIndex                  a cui è stato chiesto di fare il push
    20-23 HostIp                     di un file. Il Servent che invia la
    24-25 HostPort                   richiesta di push deve impostare
    26-   Opt. GGEP                  questo campo con il ServentID
                                     della corrispondente QueryHit.

   Nota
   Questo è usato per instradare il messaggio Push fino al mittente del
   messaggio del QueryHit.
PUSH 0x40


     Messaggio PUSH                 FileIndex
    Bytes Descrizione               L’indice del file che identifica in
    0-15  ServentID                 modo univoco il file desiderato dal
    16-19 FileIndex                 Servent mittente. Il Servent che
    20-23 HostIp                    invia la richiesta di push deve
    24-25 HostPort                  impostare questo campo con uno
    26-   Opt. GGEP                 dei FileIndex della corrispondente
                                    QueryHit.

   Nota
   Impostato a 2 nella maggior parte delle implementazioni attuali, e a 4 in
   quelle con il supporto di metadati XML esterno GGEP. L’area OpenData può
   essere più grande per permettere future estensioni.
PUSH 0x40


     Messaggio PUSH                HostIp
    Bytes Descrizione              L’indirizzo IP del host a cui il file
    0-15  ServentID                deve essere inviato.
    16-19 FileIndex
    20-23 HostIp
    24-25 HostPort
    26-   Opt. GGEP

   Nota
   Questo campo è in formato big-endian.
PUSH 0x40


     Messaggio PUSH     HostPort
    Bytes Descrizione   il numero di porta a cui il file deve
    0-15  ServentID     essere mandato
    16-19 FileIndex
    20-23 HostIp
    24-25 HostPort
    26-   Opt. GGEP
Normal File Transfer




   Normal File Transfer
      Una volta che il servent riceve un QueryHit può iniziarre il
      download diretto del file descritto nel result set.
       I file non vengono scaricati attraverso la rete di Gnutella
       ma avviene una connessione diretta tra il richiedente e il
       possessore del file.
       Questa connessione diretta usa HTTP per trasferire i file.
       I vecchi servent utilizzano HTTP 1.0, i nuovi servent usano
       HTTP 1.1.
Richiesta File




   Example (Richiesta)
   GET /get/<FileIndex>/<FileName> HTTP/1.1<cr><lf>
   User-Agent: Bearshare<cr><lf>
   Host: 123.123.123.123:6346<cr><lf>
   Connection: Keep-Alive<cr><lf>
   Range: bytes=0-<cr><lf>
   <cr><lf>

   Nota
   <FileIndex> e <FileName> sono la coppia indice del file e il nome del file di
   una entry del result set della QueryHit.
Richiesta File (cont.)



    Example (Richiesta 2)
    GET /get/2468/Foobar.mp3 HTTP/1.1<cr><lf>
    User-Agent: Bearshare<cr><lf>
    Host: 123.123.123.123:6346<cr><lf>
    Connection: Keep-Alive<cr><lf>
    Range: bytes=0-<cr><lf>
    <cr><lf>

    Nota
    Per esempio se il result set di un QueryHit contiene questa entry:

                                   File Index: 2468
                                  File Size: 4356789
                               File Name: Foobar.mp3
Richiesta File (cont.)



    Richiesta File
        Il nome del file deve essere sempre encodato usando lo
        standard URL/URI encoding.
        La versione 0.4 di Gnutella non disponeva di supporto
        all’encoding perciò molti applicativi pur rispettando lo
        standard 0.6 fanno in modo di rispondere anche alle
        richieste 0.4.
        Se il servent non è in possesso di quel determinato file
        risponderà con un 404 Not Found.
        L’header Host, obbligatorio in HTTP, non è obbligatorio in
        Gnutella.
        L’header User-Agent identifica il tipo di applicativo.
Caratteristiche del File Transfer


    Example (Richiesta)
    GET /get/2468/Foobar.mp3 HTTP/1.1<cr><lf>
    User-Agent: Gnutella<cr><lf>
    Connection: Keep-Alive<cr><lf>
    Range: bytes=4932766-5066083<cr><lf>
      <cr><lf>

    Example (Risposta)
    HTTP/1.1 206 Partial Content<cr><lf>
    Server: Gnutella<cr><lf>
    Content-Type: audio/mpeg<cr><lf>
    Content-Length: 133318<cr><lf>
    Content-Range: bytes 4932766-5066083/5332732<cr><lf>
      <cr><lf>

    Nota
    Da notare Range e Connection (connessioni HTTP persistenti RFC 2616).
Firewalled Servent



   Firewalled
       Se il possessore del file non può accettare connessioni in
       entrata?
       Il richiedente può inviare attraverso la rete Gnutella una
       richiesta push
       Il servent che riceve la richiesta push (identificato dal
       Servent ID contenuto nel messaggio PUSH) deve tentare
       di stabilire una nuova connessione TCP/IP con il server
       che ha inviato il PUSH (identificato da IP e porta nel
       messaggio PUSH).
       Se questa connessione non può essere stabilita (entrambi
       sono dietro un firewall) allora il trasferimento del file non
       può avere luogo.
Firewalled Servent




   Firewalled
       Se la connessione tra l’host firewalled e l’host che invia la
       richiesta di PUSH viene stabilita il servent firewalled invia:

   Example
     GIV <FileIndex>:<ServentIdentifier>/<FileName><lf><lf>



   Nota
   Dove <FileIndex> e <ServentIdentifier> sono i valori dei campi FileIndex e
   ServentIdentifier della richiesta PUSH ricevuta, e <FileName> è il nome del
   file il cui FileIndex è <FileIndex>.
Firewalled Servent




   Firewalled
       Il <ServentIdentifier> è formattato come esadecimale e
       può essere letto caseinsensitive.

   Example
   GIV 36:809BC12168A1852CFF5D7A785833F600/Foo.txt<lf><lf>
   GIV 4:d51dff817f895598ff0065537c09d503/Bar.htm<lf><lf>



   Nota
   Se la connessione TCP cade dopo il trasferimento di file è iniziato il servent
   che ha avviato la connessione dovrebbe tentare di riconnettersi.
Busy Servent


   Servent Occupati
       I Servents la cui banda di upload è satura possono
       respingere una richiesta di download restituendo il codice
       503.
       Un Servents può semplicemente avere un numero fisso di
       slot.
       Solitamente si usa un sistema che ottimizza la banda in
       upload al meglio.
       Servents occupati quando ricevono un push devono
       collegarsi al richiedente e restituire il codice 503 occupato.
       Si utilizza un sistema di coda.
       Se il trasferimento viene interrotto, l’uploader mantiene una
       parte di banda riservata.
Condivisione



   I servent...
        Devono condividere i file con gli altri.
        Dovrebbero incoraggiare gli utenti a condividere i file.
        Dovrebbero evitare che comportamenti non distribuiti.
        Non Dovrebbero consentire lo scaricamento attraverso
        browser web.
        L’header HTTP User-Agent mostra quale programma
        remoto è in esecuzione.

   Nota
   Quando ci si connette ad un Servent attraverso web browser viene restituita
   una pagina html in cui è indicato come funziona Gnutella e cosa fare per
   ottenere un Servent.
Condivisione




   I servent...
        Non devono dare la precedenza ad altri utenti che
        utilizzano lo steso applicativo.
       Devono rispondere messaggi di query e accettare richieste
       di download di file utilizzando le stesse regole per tutti
       servents.
       Possono bloccare chi non seguono le regole.
       Per default condividono la directory in cui sono collocati i
       file scaricati senza attandere il riavvio dell’applicativo.
       Dovrebbero evitare di cambiare i numeri di indice dei file
       condivisi dopo il riavvio.
Condivisione




   File Incompleti
       I file incompleti non devono essere condivisi come se
       fossero completi.
       Un file parziale può essere condiviso solo se
       contrassegnato come incompleto.
       il trasferimento parziale usa Partial Sharing Protocol
       (header X-Available-Ranges).
Messaggi binari sulla Gnet




   Come evitare flooding?
       Di fondamentale importanza è il TTL (descritto
       precedentemente).
       Il valore TTL di una nuova Query creata da un Servent
       dovrebbe essere 7, non deve essere superiore a 10.
       L’Hops deve essere impostato a 0.
       Un Servent che riceve un messaggio con lo stesso
       Payload e GUID di un messaggio ricevuto in precedenza
       deve scartare il messaggio.
       Significa che il messaggio è già stato visto e che il
       messaggio è già passato attraverso quel host.
Query sulla Gnet




   Come evitare flooding?
       Le query dovrebbero essere gestite attraverso il Dynamic
       Querying.
       Un Servent dovrebbe inoltrare i messaggi Query a tutti i
       suoi servents collegati direttamente ad eccezione di quello
       che ha emesso la query.
       I Servents utilizzando il Flow Control (vedremo poi) non
       sempre inoltrano ogni query su ogni connessione.
       Alla ricezione di una Query si controlla attraverso i Search
       Criteria i propri file locali.
QueryHit sulla Gnet


   Come evitare flooding?
       Un Servent che riceve un messaggio con lo stesso
       Payload e GUID di un messaggio ricevuto in precedenza
       deve scartare il messaggio.
       Significa che il messaggio è già stato visto e che il
       messaggio è già passato attraverso quel host.
       I messaggi QueryHit devono essere inviati solo lungo lo
       stesso percorso (inverso) che portava il messaggio di
       Query.
       Questo garantisce che solo i servent inoltrano il messaggio
       di Query vedranno il messaggio QueryHit in risposta.
       Un Servent che riceve un messaggio QueryHit ma non ha
       mai ricevuto e inoltrato un messaggio di Query
       corrispondente dovrebbe rimuovere il messaggio.
Ricerche dell’utente



   Come evitare flooding?
        I messaggio di Query vengono solitamente inviati quando
        l’utente avvia una ricerca.
        Un Servent può anche creare automaticamente le query e
        inviarle (per trovare nuove locazioni della stessa risorsa).
        Non deve sovraccaricare la rete (ci vogliono dei limiti).
        Impedire che l’utente generi troppo traffico Query
        attraverso click ripetuti su un pulsante.
        Se queste query sono troppo frequenti indicano un cattivo
        comportamento del servent.
        I servent dovrebbero eliminare queste query dalla rete o
        addirittura chiudere la connessione.
Querying Criteria




   Codifica vecchi servent
      I criteri di ricerca sono testo e, storicamente, non è stato
      specificato il charset del testo.
       Pertanto servent vecchi assumono che sia solo puro
       ASCII.
       Tuttavia, molti servent sono stati sviluppati per permettere
       charset esteso.
       Ciò ha creato problemi di interoperabilità, in quanto diverse
       piattaforme usano un diverso set di caratteri nativo.
       Venne scelto di usare la codifica Western European
       (ISO8859-1) anche per i metadati nella QueryHit.
Querying Criteria




   Codifica nuovi servent
      Per i nuovi sviluppi su Gnutella UTF-8 è altamente
      raccomandato.
       Quando la decodifica UTF-8 fallisce si usa ISO8859-1.
       Se fallisce anche ISO8859-1 si usa ASCII.
Querying Criteria



   Speciali criteri di ricerca
       Formati da stringa di parole chiave.
       Un servent dovrebbe rispondere con i file che ha tutte le
       parole chiave.
       Il regolare US-ASCII space (U+0020) è il separatore di
       standard tra le parole chiave.
       Servents possono anche richiedere che tutti i termini
       corrispondenti essere presenti nello stesso numero e
       ordine nella query.
       L’abbinamento è essere case-insensitive.
       Servents possono ignorare le query i cui criteri di ricerca è
       inferiore ad una lunghezza scelta.
Querying Criteria




   Interpretare i criteri di ricerca
       Le espressioni regolari non sono supportate.
       I meta-caratteri * o . possono essere al posto di qualsiasi
       cosa.
       Estensioni GGEP possono essere utilizzate per fornire
       dettagli su come analizzare i criteri di ricerca
       Un servent non può mai essere sicuro che gli altri
       interpretino correttamente l’estensione GGEP.
Querying Criteria




   Browsing dello share
       I messaggi di query con TTL=1, Hops=0 e Search Criteria
       uguale a quattro spazi sono utilizzati per indicizzare tutti i
       file un host è la condivisione.
       I servents dovrebbero rispondere alle query browsing con
       tutti i file condivisi.
       Query multiple Hit messaggi devono essere utilizzati se
       condividono molti file.
       Non sempre i Servent rispondono con tutti i file condivisi
       (Privacy e Larghezza di banda).
Querying Criteria




   Valori dei campi di QueryHit
       Stesso GUID del messaggio Query corrispondente.
       Il valore TTL deve essere almeno quanto l’Hops della
       Query corrispondente e il valore iniziale di hops deve
       essere 0.
       Alcuni servent mandano un TTL di 7 così sono sicuri che
       se la rete dovesse cambiare forma la risposta alla query
       arriverà.
Download Mesh




   Valori dei campi di QueryHit
       Lo scopo del Download Mesh è di aiutare le persone a
       trovare più fonti per i file che stanno cercando
       Senza bisogno di richiedere nuovamente la rete.
       Queste fonti supplementari sono chiamati posizioni
       alternative, o Alt-Locs.
       Viene attuato con l’estensione HUGE.
Download Mesh



   Come funziona
      Cercare di rendere ogni Servent conoscenza di tali
      servents che condividono lo stesso file sul GNet
       Tutto questo in modo decentrato.
       La soluzione per Gnet è stata scelta come un buon
       compromesso tra efficienza e basso consumo di banda.
       E’ efficace per aiutare la ricerca di fonti per i file conosciuti.
       L’obiettivo è quello di rendere migliore il download anche
       dei file rari.
       Le informazioni vengono inviate tra gli header HTTP e
       utilizzando l’estensione HUGE nelle QueryHit.
HUGE


  Vecchie intestazioni
  La proposta HUGE utilizza due intestazioni:
       X-Gnutella-Content-URN indica l’URN associato a un file.
       X-Gnutella-Alternate-Location per indicare posizioni
       alternative per quel file.

  Example
  X-Gnutella-Alternate-Location:
  http://1.2.3.4:6546/uri-res/N2R?
  urn:sha1:OJUNVQ75FQMZ5RXR3LJUDIQSGSVC5RFE
  2002-12-27T12:35:51Z, http://1.2.3.5:6461/uri-res/N2R?
  urn:sha1:OJUNVQ75FQMZ5RXR3LJUDIQSGSVC5RFE
  2002-12-27T11:38:51Z
  X-Gnutella-Content-URN:
  urn:sha1:OJUNVQ75FQMZ5RXR3LJUDIQSGSVC5RFE
HUGE



  Nuove intestazioni
  Intestazioni così lunghe causano inefficienza.
  Il nuovo HUGE utilizza altre intestazioni:
       X-Alt header rimpiazza X-Gnutella-Alternate-Location.
       X-NAlt è stato aggiunto per indicare locazioni sbagliate
       (scadute, false o maliziose).
       E sopratutto un nuovo formato per indicare le Alt-Locs.

  Example
  X-Alt: 1.2.3.4:6347,1.2.3.5
  X-NAlt: 1.2.3.4:6346, 1.2.3.5:6341
HUGE




  X-NAlt
  X-NAlt serve quando una Alt-Loc è scaduta:
       In caso di 404.
       Se il socket non può connettersi con l’host
       Non quando dà errore 503 (Busy).
HUGE




  Funzionamento
     Il Downloader deve informare l’Uploader su locazioni
     alternative che conosce per questo file, e da cui ha
     scaricato correttamente.
       Il Downloader non deve informare l’Uploader su posizioni
       alternative da cui non ha ancora effettivamente scaricato.
       In questo modo l’Uploader viene a conoscenza delle
       Alt-Locs.
HUGE



  Example
  Funzionamento
       Il downloader dispone di 10 locazioni.
       Prova otto di essi.
       I primi cinque funzionano e gli ultimi tre non funzionano.
       Tutti i primi cinque Uploader devono essere inviati come X-Alt.
       I tre non funzionanti devono essere inviati con X-NAlt.
       Tutti gli uploader vanno informati.
       Non viene detto niente sui due non testati.

  Nota
  Se ci sono molte Alt-Locs disponibili viene inviato un massimo di 10.
HUGE




  Funzionamento
     L’Uploader può inviare solo le X-Alt (non le X-NAlt).
       L’invio avvine durante le richieste HTTP (grazie alle
       connessioni persistenti ci sono più richieste in una
       connessione).
       Oppure inviando un HEAD successivo.
HUGE




  Funzionamento
     L’Uploader non ha modo di verificare la bontà di una
     Alt-Loc.
       Solo il Downloader testa le locazioni.
       Alt-Locs possono essere ottenute grazie alle QueryHits
       quando il valore hash di HUGE è incluso.
       In questo le nuove Alt-Locs saranno aggiunte (dopo la
       verifica) alla Download Mesh di quel file.
       Esiste un’altra estensione (ALT GGEP) che fa lo stesso
       lavoro di HUGE ma che non vedremo.
Download Mesh di qualità




   Buone Regole
       Il Downloader testa gli Alt-Locs prima di inviarli.
       Il Downloader deve presentare tutte le Alt-Locs (buone e
       cattive) con gli opportuni header.
       L’Uploaders deve rimuovere le Alt-Locs presentate con
       X-NAlt (con tolleranza).
       Evitare informazioni eccessive: è inutile inviare due volte la
       stessa Alt-Loc.
Estensione HUGE




   HUGE come estensione
      HUGE è incapsulato spesso nel GGEP delle QueryHit.
        E’ possibile trovarlo anche non incapsulato in GGEP.

   Nota
   Altre informazioni su HUGE possono essere trovate qui:

              http://rfc-gnutella.sourceforge.net/src/
                      draft-gdf-huge-0_94.txt
Introduzione



   Problema

       Gnutella è una rete decentralizzata
       Quando un client vuole connettersi
       deve collegarsi con un host già
       presente nella rete.
       Ma se il client non conosce gli altri
       host...
       ...Come fa a connettersi alla rete?
       Alcuni metodi:
           Local Hostcache
           GWebCache (in seguito)
Local Hostcache




   A cosa serve?
       Permette di connettersi alla rete Gnutella in tempi brevi.
       Limitare le connessioni a GWebCache per sessione

   Cosa contiene?
      Ogni servent memorizza una lista di host prelevati da:
            X-Try e X-Try-Ultrapeer
            GWebCache
            Pong Reply
            QueryHit
Local Hostcache




   Come funziona?
      All’avvio il servent carica in RAM solo host in cache che
      hanno un legame forte con la rete.
      Questo filtro viene fatto in base ai seguenti criteri
            Uptime dell’host
            Numero di file e KB in condivisione
            Ultima volta che l’host è stato visto nella rete
            Se una connessione è stata instaurata con l’host
            L’uptime dell’ultima connessione instaurata con l’host
       Infine proverà a collegarsi con ognuno di questi host finchè
       non riuscirà ad instaurare una connessione
Introduzione PING/PONG




   Una volta connessi?
      Si cercano altri host a cui connettersi attraverso PING
      I messaggi di PING/PONG hanno infatti due funzioni:
            Ottenere informazioni su un servent nella rete
            Stimare le dimensioni della rete stessa
                i.e. Numero dei file

       I servent Gnutella devono asserire ai seguenti punti
            Quando riceve un PING, risponde con una serie di PONG
            Ogni PONG contiene informazione su chi l’ha generato
            I PONG inviati devono essere di buona qualità
            I messaggi di PING/PONG non devono saturare la banda
Schema PING/PONG




  Come funziona?

      Un client manda un PING a tutti i
      suoi vicini (in blu)
      Il servent che lo riceve
          Decrementa il TTL
               Se TTL=0, droppa il pacchetto
               Altrimenti lo propaga ai suoi vicini
          Restituisce un PONG con le sue
          informazioni. (in rosso)
          Farà da router per i PONG di
          risposta ai PING che ha propagato
          ai vicini
Schema PING/PONG




  Come funziona?

      Un client manda un PING a tutti i
      suoi vicini (in blu)
      Il servent che lo riceve
          Decrementa il TTL
               Se TTL=0, droppa il pacchetto
               Altrimenti lo propaga ai suoi vicini
          Restituisce un PONG con le sue
          informazioni. (in rosso)
          Farà da router per i PONG di
          risposta ai PING che ha propagato
          ai vicini
Schema PING/PONG




  Come funziona?

      Un client manda un PING a tutti i
      suoi vicini (in blu)
      Il servent che lo riceve
          Decrementa il TTL
               Se TTL=0, droppa il pacchetto
               Altrimenti lo propaga ai suoi vicini
          Restituisce un PONG con le sue
          informazioni. (in rosso)
          Farà da router per i PONG di
          risposta ai PING che ha propagato
          ai vicini
Schema PING/PONG




  Come funziona?

      Un client manda un PING a tutti i
      suoi vicini (in blu)
      Il servent che lo riceve
          Decrementa il TTL
               Se TTL=0, droppa il pacchetto
               Altrimenti lo propaga ai suoi vicini
          Restituisce un PONG con le sue
          informazioni. (in rosso)
          Farà da router per i PONG di
          risposta ai PING che ha propagato
          ai vicini
Schema PING/PONG




  Come funziona?

      Un client manda un PING a tutti i
      suoi vicini (in blu)
      Il servent che lo riceve
          Decrementa il TTL
               Se TTL=0, droppa il pacchetto
               Altrimenti lo propaga ai suoi vicini
          Restituisce un PONG con le sue
          informazioni. (in rosso)
          Farà da router per i PONG di
          risposta ai PING che ha propagato
          ai vicini
Schema PING/PONG




  Come funziona?

      Un client manda un PING a tutti i
      suoi vicini (in blu)
      Il servent che lo riceve
          Decrementa il TTL
               Se TTL=0, droppa il pacchetto
               Altrimenti lo propaga ai suoi vicini
          Restituisce un PONG con le sue
          informazioni. (in rosso)
          Farà da router per i PONG di
          risposta ai PING che ha propagato
          ai vicini
Schema PING/PONG




  Problema
      Nell’esempio sono stati scambiati 8 PING e 18 PONG
      Se la rete assume grandi dimensioni, il solo utilizzo di
      PING/PONG può saturare la banda.
      Il problema è dovuto principalmente al protocollo stesso
      che propaga i messaggi tramite broadcast
      Per limitare il problema si utilizza un altro approccio
          PONG Caching

      Nota: solo gli Ultrapeer hanno bisogno di implementarlo
Implementazione



   Specifiche
       Viene memorizzato un array di PONG
           Ogni indice corrisponde ad una diversa connessione
       Quando viene ricevuto un PONG, lo si inserisce nello slot
       corrispondente, eventualmente sovrascrivendo il
       messaggio precedente

       Ogni PONG contiene le seguenti informazioni
           Indirizzo IP
           Numero Porta
           Numero di file in condivisione
           Numero di KB in condivisione
           Payload GGEP (se presente)
           Numero di Hop
Implementazione



   Come funziona?

       Il servent riceve il PING P
       Cerca nella sua PONG Cache..
       ..E restituisce al client il suo ed una
       serie di altri PONG
           i.e. con differente numero di Hop

       I campi di ogni PONG S inviato
       vengono modificati come segue
           MessageID = P->MessageID
           Hops = S->Hops + 1
           TTL t.c. Hops + TTL = 7
Implementazione



   Come si aggiorna la cache?
       Si invia un PING (TTL=7, Hop=0), circa ogni 3 secondi, a
       tutti i vicini
       Può sembrare dispendioso ma...
           I nodi foglia restituiranno soltanto il loro PONG
           Gli Ultrapeer risponderanno con la loro PONG Cache
       Per i vicini che non supportano il PONG Caching si invia
       un PING circa ogni minuto.

       La informazioni di un vicino possono essere recuperate da
       subito
           Con un PING sonda (TTL=1, Hop=0) una volta connesso
           Con le informazioni scambiate durante l’handshake
Considerazioni



   In conclusione...
       Questo schema riduce sensibilmente il consumo di banda
       Supponiamo di inviare un PING ogni 3 secondi e ottenere
       10 PONG, ricordando che:
           Un PING, senza estensioni, ha dimensioni 23 byte
           Un PONG, senza estensioni, ha dimensioni 37 byte
       La banda totale utilizzata è
       (23 + (10 * 37)) / 3 = 131 B/s per connessione
       Anche con estensioni, la banda dovrebbe rimane su un
       livello accettabile
       Se così non fosse, basterebbe aumentare l’intervallo di
       tempo tra i PING
Introduzione




   Il protocollo TCP
       Il broadcasting viene fatto per tutti i tipi di messaggio
       Inoltre i servent possono sia ricevere, sia inviare
       Come abbiamo visto per i PING, può intasare l’intera rete
       Tuttavia, il broadcast non è l’unico problema di Gnutella
       GNET, infatti, si appoggia quasi interamente sul protocollo
       TCP
       Poichè TCP è affidabile, possono manifestarsi anche dei
       problemi di latenza
           i.e. pacchetti che si perdono, si rinviano...
Introduzione




   Cosa fare?
      Quando sorgono problemi di latenza, un servent Gnutella
      può:
           Droppare la connessione
           Droppare i messaggi
           Utilizzare un buffer per i messaggi, in modo da inviarli in un
           secondo momento

       Nessuna di queste azioni offre la soluzione migliore
       Rimangono, infatti, dei problemi in ognuno dei tre casi
Introduzione



   Problema
       Droppare la connessione
           Provoca il continuo disconnettersi e riconnettersi del client
           Molti messaggi vengono persi
                i.e. Il servent risponde ad un client non più connesso
       Droppare il messaggio
           Vanifica il lavoro fatto per ottenere una risposta
           Il risultato è un utilizzo inutile della banda
       Utilizzare un buffer per i messaggi
           Può aumentare ulteriormente la latenza
                I servent possono andare in buffer overflow, bloccandosi
           Il problema inoltre non è risolvibile, se non alla base
                i.e. trasmettere su più banda di quanto non sia già possibile
Introduzione




   Cosa succede?
      La rete Gnutella può ritrovarsi in stato di Meltdown
            I servent si sovraccaricano, non potendo rispondere
            Le richieste non vengono prese più in considerazione

       Alcune stime:
            I servent funzionanti possono diminuire del 90%
            La latenza può aumentare fino al minuto e mezzo


       Serve quindi un sistema per regolare il flusso di dati
Implementazione




   Cosa fare?
      Implementare una coda di output con politica FIFO
           Le dimensioni della coda devono essere almeno il 150%
           delle massime dimensioni di un messaggio
       Stabilire un valore di soglia per la coda (i.e. 25%)
       Quando la coda viene riempita oltre il limite soglia
           Si entra in modalità FC (Flow Control)
           Si resta in FC finchè non si ritorna al di sotto della soglia

       In modalità FC, le Query ricevute vengono droppate
           Evita di intasare connessioni già in difficoltà
Implementazione




   Caratteristiche
       I messaggi nella coda devono rispettare certe priorità
       Per quelli broadcast, più alto è il valore di Hop, più bassa
       sarà la priorità
            I messaggi del servent stesso sono i più importanti
       Per quelli singoli, più alto è il valore di Hop, più alta sarà la
       priorità
            Massimizza l’utilizzo e il consumo della banda

       La priorità per tipo di messaggio è definita in ordine
       decrescente come segue:
            Push, QueryHit, PONG, Query, PING
Implementazione




   Caratteristiche
       Di norma, tutti i messaggi vengono inseriti in coda
       Quando però un messaggio riempirebbe la coda oltre il
       100% delle sue dimensioni
           Ogni messaggio in coda con priorità minore viene droppato
           Se lo spazio è ora sufficiente, viene inserito in coda
           Altrimenti, se è un PING, PONG o Query, viene droppato
           Negli altri casi si restituisce un messaggio di tipo BYE
               i.e. BYE 502 (Send Queue Overflow)
SACHRIFC




  Cos’è?
     Algoritmo per il controllo di flusso usato in diversi client
     Gnutella (i.e. LimeWire, Bearshare)

      Sviluppato per i seguenti scopi:
           Evitare di droppare messaggi
           Minimizzare la latenza
           Preferire i messaggi nel seguente ordine:
                Push, QueryHit, Query, PONG, PING
           Evitare che un tipo di messaggio possa dominare il traffico
           Favorire QueryHit meno popolari da quelle più popolari
SACHRIFC



  Implementazione
     Utilizza un buffer per ogni connessione
     Ciascun buffer è suddiviso a sua volta in 5 code separate
     (una per ogni tipo di messaggio)
           Le QueryHit sono ordinate in modo crescente secondo il
           Volume GUID (risposte generate da quel GUID)
           Le altre sono ordinate in modo decrescente per il
           timestamp

     Per inserire un messaggio M di tipo T in un buffer B
     if (B(T).isFull()) B(T).removeTail();
     B(T).insertHead(M);
SACHRIFC



  Implementazione
     I messaggi nei buffer vengono scelti ed inviati con una
     politica simile al Round Robin
     foreach(Qi in B) {
         for (j = 0; j < min(|Qi|, Ni); j++) {
             M = Qi.head();
             if (M.isOld()) M.drop();
             else M.send();
         }
     }

     Ni è un valore associato ad ogni tipo di messaggio per
     indicare la quantità di messaggi da inviare ad ogni ciclo
SACHRIFC




  Example


    foreach(Qi in B) {
        for (j = 0; j < min(|Qi|, Ni); j++) {
            M = Qi.head();
            if (M.isOld()) M.drop();
            else M.send();
        }
    }
SACHRIFC




  Example


    foreach(Qi in B) {
        for (j = 0; j < min(|Qi|, Ni); j++) {
            M = Qi.head();
            if (M.isOld()) M.drop();
            else M.send();
        }
    }
SACHRIFC




  Example


    foreach(Qi in B) {
        for (j = 0; j < min(|Qi|, Ni); j++) {
            M = Qi.head();
            if (M.isOld()) M.drop();
            else M.send();
        }
    }
SACHRIFC




  Example


    foreach(Qi in B) {
        for (j = 0; j < min(|Qi|, Ni); j++) {
            M = Qi.head();
            if (M.isOld()) M.drop();
            else M.send();
        }
    }
SACHRIFC




  Example


    foreach(Qi in B) {
        for (j = 0; j < min(|Qi|, Ni); j++) {
            M = Qi.head();
            if (M.isOld()) M.drop();
            else M.send();
        }
    }
SACHRIFC




  Example


    foreach(Qi in B) {
        for (j = 0; j < min(|Qi|, Ni); j++) {
            M = Qi.head();
            if (M.isOld()) M.drop();
            else M.send();
        }
    }
SACHRIFC




  Example


    foreach(Qi in B) {
        for (j = 0; j < min(|Qi|, Ni); j++) {
            M = Qi.head();
            if (M.isOld()) M.drop();
            else M.send();
        }
    }
SACHRIFC




  Example


    foreach(Qi in B) {
        for (j = 0; j < min(|Qi|, Ni); j++) {
            M = Qi.head();
            if (M.isOld()) M.drop();
            else M.send();
        }
    }
SACHRIFC




  Example


    foreach(Qi in B) {
        for (j = 0; j < min(|Qi|, Ni); j++) {
            M = Qi.head();
            if (M.isOld()) M.drop();
            else M.send();
        }
    }
SACHRIFC




  Example


    foreach(Qi in B) {
        for (j = 0; j < min(|Qi|, Ni); j++) {
            M = Qi.head();
            if (M.isOld()) M.drop();
            else M.send();
        }
    }
SACHRIFC




  Example


    foreach(Qi in B) {
        for (j = 0; j < min(|Qi|, Ni); j++) {
            M = Qi.head();
            if (M.isOld()) M.drop();
            else M.send();
        }
    }
SACHRIFC




  Example


    foreach(Qi in B) {
        for (j = 0; j < min(|Qi|, Ni); j++) {
            M = Qi.head();
            if (M.isOld()) M.drop();
            else M.send();
        }
    }
SACHRIFC



  In generale. . .
      Il fattore N serve quindi per dare un’ulteriore priorità ai tipi
      di messaggio
      Modificando il rapporto tra i vari Ni si può aggiustare il caso
      peggiore
           I Push sono quelli a priorità più alta, ma sono i più rari
           I PING/PONG sono più comuni, ma a priorità più bassa
           Con un fattore N adeguato, si può evitare l’overflow dei
           buffer

      Inoltre le code vengono svuotate attraverso una politica di
      tipo LIFO
           I messaggi vengono inseriti e prelevati dalla testa
SACHRIFC




  Perchè LIFO?
      Consideriamo un flusso di Query che viene letto ad 1 Kb/s
      da C1
      C1 inoltrerà i messaggi alla connessione C2 che ha
      capacità 1 Kb/s
      Inizialmente nessun messaggio verrà droppato
      Successivamente C1 riceve un blocco di 10 Kb
           Con FIFO, per inviarlo a C2, C1 impiegherà 10 secondi
           Nel frattempo C1 continuerà a leggere blocchi da 1 Kb che
           metterà in coda
           La latenza tra C1 e C2 è ora 10 secondi per tutti i pacchetti
           rimanenti
SACHRIFC




  Perchè LIFO? (Cont.)
      Consideriamo lo stesso esempio utilizzando una politica
      LIFO
      Inizialmente nessun messaggio verrà droppato
      Successivamente C1 riceve un blocco di 10 Kb
           Con LIFO, C1 metterà in coda il blocco
           Nel frattempo C1 continuerà a leggere blocchi da 1 Kb
           Questi blocchi verranno subito inviati a C2 senza
           aumentare la latenza
           Il blocco in coda verrà inviato solo in seguito
               Potrebbe essere anche droppato perchè troppo vecchio
Introduzione



   Il Routing..
       I servent hanno anche il compito di instradare le risposte
       nella rete
       I messaggi da gestire sono i Push, le QueryHit e i PONG
            I PONG sono già gestiti dal PONG Caching
            Per i due messaggi rimanenti è necessario invece
            implementare una tabella di Routing

       L’idea di base è:
            Memorizzare il GUID dei messaggi di richiesta (i.e. Query)
            Aspettare la risposta (i.e. QueryHit)
            Instradare la risposta al servent che aveva inviato la
            richiesta
Introduzione



   Problema
       Per quanto tempo mantenere in memoria i GUID?
       Un servent non può memorizzare tutta la cronologia dei
       messaggi ricevuti perchè sono milioni i messaggi per cui
       viene fatto il routing ogni giorno
       Alcune soluzioni:
           Memorizzare una certa quantità di messaggi
               Non è scalabile
           Memorizzare i messaggi per un certo lasso di tempo
               Calcolare per quanto tempo memorizzarli è complesso
               Bisogna tenere conto dei limiti di TCP e del Flow Control

       Grosso modo, ogni messaggio dev’essere memorizzato
       per almeno 10 minuti
Query Routing




   Implementazione
       Utilizzare una tabella associativa, con chiave GUID e con
       valore la connessione
       Ogniqualvolta viene ricevuta una Query, si inserisce nella
       tabella l’associazione GUID => Connessione
       Se la Query è stata inviata dal servent stesso, viene usato
       un carattere speciale per indicare il valore della
       connessione (i.e. NULL)
Query Routing



   Implementazione
   Quando viene ricevuta una QueryHit ci sono 3 casi:
    1   C’è una connessione associata al GUID nella tabella
            Il messaggio viene instradato a quella connessione
    2   C’è un valore NULL associato al GUID nella tabella
            Il messaggio è una risposta alla Query del servent
    3   Non esiste il GUID nella tabella
            Il messaggio è stato erroneamente inviato al servent e
            verrà droppato
            Il GUID è scaduto, ed è stato rimosso dalla tabella prima di
            ricevere il messaggio
Push Routing




   Caratteristiche
       I Push sono i messaggi più importanti
             Permettono il download da servent firewalled
       Sono in minoranza rispetto alla QueryHit
             La tabella di Routing sarà più piccola
             Ogni entry nella tabella di Routing verrà memorizzato per
             almeno 30 minuti

       Esistono due possibili implementazioni:
         1   Standard Push Routing
         2   Broadcasting Push Routing
Standard Push Routing




   Implementazione
       Anzichè il GUID del messaggio, viene memorizzato il
       GUID del servent
           E’ incluso in entrambi gli header di QueryHit e Push
           Per evitare incomprensioni, lo chiameremo SUID

       Ogniqualvolta viene ricevuta una QueryHit, si inserisce
       nella tabella l’associazione SUID => Connessione
       Per conoscere se il Push è una richiesta del servent stesso
       si controlla che il SUID del Push corrisponda al SUID del
       servent
           Evita di memorizzare dati di QueryHit create dal servent
Standard Push Routing




   Implementazione
   Quando viene ricevuto un Push ci sono 2 casi:
    1   C’è una connessione associata al SUID nella tabella
            Il messaggio viene instradato a quella connessione
    2   Non esiste il SUID nella tabella
            Il messaggio è stato erroneamente inviato al servent e
            verrà droppato
            Il SUID è scaduto, ed è stato rimosso dalla tabella prima di
            ricevere il messaggio
Broadcasting Push Routing



   Implementazione
       Molto simile al precedente
       Ogni connessione memorizza, in una lista, i SUID delle
       QueryHit a loro corrispondenti
       Quando il servent riceve un Push, controlla la lista di
       ciascuna connessione. Ci sono 2 casi:
        1   Se esiste il SUID nella lista
                 Il messaggio viene instradato a quella connessione
        2   Se non esiste il SUID nella lista
                 Il messaggio è stato erroneamente inviato al servent e verrà
                 droppato
                 Il SUID è scaduto, ed è stato rimosso dalla lista prima di
                 ricevere il messaggio
Introduzione




   Problema
       Bisogna evitare di inviare messaggi già trasmessi nella rete
       Ogni servent GNET implementa un sistema di controllo sui
       messaggi duplicati
       Il sistema prevede la memorizzazione temporenea dei
       messaggi anzichè l’uso di una struttura dati a dimensione
       fissa
            Ogni messaggio viene memorizzato per almeno 10 minuti

       L’idea è la stessa ma l’implementazione varia in base al
       tipo di messaggio
PING Duplicati




   Caratteristiche
       Ogni servent memorizza il GUID dei PING
       Quando si riceve un PING, si controlla la PING Duplicates
       Tables
           Se il GUID è gia presente, il messaggio viene droppato
           Altrimenti, si accetta il PING e ne viene memorizzato il
           GUID

       PING duplicati sono molto rari, soprattutto se il PONG
       Caching è implementato.
PONG Duplicati




   Caratteristiche
       La PONG Duplicates Table viene mantenuta per
       retro-compatibilità
       A differenza dei PING, il solo GUID non è sufficiente
           Il GUID di tutti i PONG in risposta ad un PING è lo stesso
       Si memorizza quindi una stringa formata dalla
       concatenazione di GUID + IP + Port
       Il procedimento di controllo è lo stesso del PING

       PONG duplicati sono molto rari.
Query Duplicate




   Caratteristiche
       Come per i PING, si può memorizzare il GUID, e applicare
       lo stesso procedimento di controllo
       Il servent gestisce già il routing delle QueryHit, quindi il
       GUID delle Query è gia memorizzato
       Tuttavia, si predilige implementare una tabella a parte
       solamente per le Query

       Query duplicate sono molto frequenti
           Sono causate principalmente dai cammini ciclici della rete
QueryHit Duplicate



   Caratteristiche
       Sono il tipo di messaggio più complicato da gestire
           Due QueryHit sono equivalenti se hanno ugual MessageID
           e Payload
       Per trovare un identificatore univoco si può agire così:
           Si concatenano il MessageID, GUID del servent e l’hash del
           Payload
           Risultato: MessageID + GUID + Hash(Payload)
       QueryHit duplicate sono molto frequenti

       Nota: Non basta utilizzare MessageID + GUID poichè il
       servent può decidere di spezzare una grossa QueryHit in
       tante più piccole QueryHit
Push Duplicati




   Caratteristiche
       Come per i PING, si può memorizzare il GUID, e applicare
       lo stesso procedimento di controllo
       Il servent gestisce già il routing dei Push, ma per farlo
       memorizza il MessageID
       Quindi, a differenza delle Query, è necessario
       implementare forzatamente una tabella apposita

       Push duplicati non sono molto frequenti
           Sono solitamente ben gestiti dal loro routing
BYE Duplicati




   Caratteristiche
       I BYE sono messaggi speciali, non previsti dall’originale
       protocollo
       Quando si riceve un BYE, bisogna disconnettersi da quel
       servent
           Risulta quindi inutile un controllo dei duplicati
Introduzione




   Che cos’è?
   Il QRP è una features essenziale degli UltraPeer
       Governa il routing delle Query verso i nodi foglia che
       hanno più probabilità di restituire una QueryHit
       Questo viene fatto cercando le keywords della Query
       all’interno di una grande tabella hash, la Query Routing
       Table (QRT)
       Gli Ultrapeer ricevono le QRT dai nodi foglia
       Gli Ultrapeer possono scambiarsi le QRT tra loro
Introduzione



   Problema

       Supponiamo di essere un Ultrapeer
       Se riceviamo una Query, la
       invieremo alle nostre foglie
       Se la foglia condivide un file che
       coincide con la ricerca, produce una
       QueryHit
       Ma per le foglie che non condividono
       nulla?
           Non produrranno mai QueryHit
           Risulta inutile inviarle la Query
                Si spreca solo banda
Introduzione



   Problema

       Supponiamo di essere un Ultrapeer
       Se riceviamo una Query, la
       invieremo alle nostre foglie
       Se la foglia condivide un file che
       coincide con la ricerca, produce una
       QueryHit
       Ma per le foglie che non condividono
       nulla?
           Non produrranno mai QueryHit
           Risulta inutile inviarle la Query
                Si spreca solo banda
Introduzione



   Problema

       Supponiamo di essere un Ultrapeer
       Se riceviamo una Query, la
       invieremo alle nostre foglie
       Se la foglia condivide un file che
       coincide con la ricerca, produce una
       QueryHit
       Ma per le foglie che non condividono
       nulla?
           Non produrranno mai QueryHit
           Risulta inutile inviarle la Query
                Si spreca solo banda
Introduzione



   Problema

       Supponiamo di essere un Ultrapeer
       Se riceviamo una Query, la
       invieremo alle nostre foglie
       Se la foglia condivide un file che
       coincide con la ricerca, produce una
       QueryHit
       Ma per le foglie che non condividono
       nulla?
           Non produrranno mai QueryHit
           Risulta inutile inviarle la Query
                Si spreca solo banda
Introduzione



   Problema

       Supponiamo di essere un Ultrapeer
       Se riceviamo una Query, la
       invieremo alle nostre foglie
       Se la foglia condivide un file che
       coincide con la ricerca, produce una
       QueryHit
       Ma per le foglie che non condividono
       nulla?
           Non produrranno mai QueryHit
           Risulta inutile inviarle la Query
                Si spreca solo banda
Query Routing Table



   Che cos’è?
      Una QRT è un array solitamente di 65536 bit



           Una Keywords è associata ad un bit della tabella tramite
           un’apposita funzione hash
           Se il bit vale 1, la ricerca può dare risultato
           Se il bit vale 0, la ricerca viene bloccata
           E’ possibile che ad un bit corrispondano più Keywords
                L’obiettivo di QRP è instradare Query alle foglie solo se c’è
                anche una minima probabilità di ricevere una QueryHit
       Foglie che non condividono file hanno tutti i bit a 0
           L’Ultrapeer non gli invierà nessuna Query
Query Routing Table




   Come funziona?
      Supponiamo che la foglia condivida il file Gnutella.txt
       Codifica il nome del file in un numero con un’apposita
       funzione hash
       Cerca il bit corrispondente nella QRT e cambia il valore del
       bit da 0 a 1

       Nota: Non viene effettuato l’hash dei dati del file, ma solo
       del suo nome
            Alcuni client lo fanno anche per il percorso dei file
Introduzione




   Perchè si usa?
       Come più volte ripetuto Gnutella utilizza tecniche
       broadcast
       Ogni Ultrapeer può inoltre connettersi ad altri 32 Ultrapeer
       Se viene inviata una Query con TTL = 3
            Al 1◦ hop genererà 32 messaggi
            Al 2◦ hop genererà 322 messaggi = 1024
            Al 3◦ hop genererà 10242 messaggi = 97% della rete
       Se QRP è implementato, il 3◦ hop verrà risparmiato
            Grande risparmio di banda
            Minimizza la latenza
Implementazione




   Nelle Foglie...
    1   Dividere il nome di tutte le risorse condivise in parole
            Ogni parola dev’essere formata da lettere e/o numeri
    2   Codificare ciascuna parola e porre il corrispondente bit
        della QRT a 1
    3   Ripetere il 3◦ passaggio rimuovendo le ultime 1, 2, 3
        lettere da ciascuna parola
            Utile per rimuovere la pluralità nelle parole
    4   Comprimere eventualmente la QRT
    5   Inviare la QRT agli Ultrapeer
Implementazione



   Negli Ultrapeer...
    1   Instradare le Query alle foglie che non hanno ancora
        inviato la QRT
    2   Se la QRT è stata ricevuta, le Query verranno filtrate per
        quel nodo
            Le Keywords della Query vengono divise in parole
            Le parole vengono trasformate in lower-case e codificate in
            ASCII
            Ogni parola viene codificata con la funzione hash
            Si controlla il bit corrispondente ad ogni parola nella QRT
                 Se si verifica Query Matching, viene dichiarata una Query
                 Routing Hit
                 La Query viene propagata ai corrispettivi nodi foglia
            Altrimenti la Query viene droppata
X-Query-Routing




   Come si scambiano le QRT?
      Gli Ultrapeer che implementano il QRP inseriscono negli
      header dell’handshake X-Query-Routing: 0.1
           Le foglie che riconoscono il protocollo potranno inviare la
           loro QRT
       Le QRT possono essere scambiate anche tra gli Ultrapeer
           Negli header viene inserito X-Ultrapeer-Query-Routing: 0.1
       Il protocollo di scambio prevede due messaggi
           Reset Message
           Patch Message
Reset Message




   Descrizione
      I Reset definiscono i parametri della QRT
           Specificano le dimensioni della tabella
       Il messaggio imposterà inizialmente tutti i bit a 0
           Verranno modificati solo tramite successive Patch
Patch Message



   Descrizione
      Contiene informazioni sul come dovranno cambiare i bit
      della QRT
           Il pacchetto contiene inizialmente un array di 655356 byte
           Ogni byte corrisponde ad un bit nella QRT
       L’idea alla base è:
           Se il byte vale 0, il bit non verrà modificato
           Se il byte è negativo, il bit verrà impostato a 1
           Altrimenti, se positivo, il bit verrà impostato a 0

       L’header del pacchetto contiene due campi
           Il numero di serie del pacchetto (parte da 1)
           Il numero totale dei pacchetti
Patch Message




   64Kb sono tanti..
      Dalle specifiche si può notare che sono necessari almeno
      2 bit per descrivere ogni bit
           Molti client comprimono ciascun byte in 2-4 bit
           Le dimensioni totali passano da 64 Kb a 32-16 Kb

       Inoltre è possibile scomporre il pacchetto in più
       sottopacchetti
           Solitamente in blocchi da 4 Kb
X-Query-Routing


   Come funziona?
      Dopo aver instaurato la connessione, la foglia invia un
      Reset
        Successivamente invia le informazioni della sua QRT
        attraverso una serie di messaggi Patch
        Per continuare a sincronizzare la tabella, basterà inviare
        ulteriori messaggi Patch

   Example
    Client:   Reset Message
    Server:   OK
    Client:   Patch Message 1 of 2
    Client:   Patch Message 2 of 2
    Server:   OK

     Dopo alcuni minuti...

    Client: Patch Message 1 of 3
    ...
QRP Hashing



   Introduzione
        Ogni QueryString è formata da una o più Keywords
        separate da spazio
        Per mappare una keyword K in uno slot della tabella QRP
        di dimensione M, è necessaria una funzione hash H(K,M)
        che deve soddisfare queste proprietà:
         1   Generare hash di keywords a lunghezza arbitraria
             uniformemente OK!
         2   Facilmente implementabile su più piattaforme OK!
         3   Possibilità di convertire la keywords tra hash tables di
             diverse dimensioni ???
                  i.e. Dato H(K,M), ma non K, dev’essere possibile calcolare
                  H(K,M’) per un qualsiasi M’
                  Permette l’interoperatività tra client con diverse tabelle QRP
QRP Hashing




   Come fare?
      Convertire la keyword di lunghezza K in un numero
      naturale N a 32 bit
           Si divide la keyword in gruppi di 4 byte
           Eventualmente si aggiunge un padding
           Si esegue lo XOR concatenato
           i.e. 01011001001 = 1001 XOR 1100 XOR 0110 XOR 0001 = 0010 = N

       Mappare il numero N tra 0 e M-1
           H(N,M) = floor(M * ((N*A) - floor(N*A)))
           A è un particolare valore utilizzato per evitare collisioni per
           un’ampia gamma di dati.
QRP Hashing




   Problema
       Il risultato della funzione hash può però risultare diverso
       per via dei diversi difetti di arrotondamento su macchina
       con architetture differenti

       Tuttavia, si può restringere il campo M ad una potenza di 2
       La funzione può essere calcolata con operazioni di shift
       binario
            Si moltiplica il numero N per una costante a 32bit
                 i.e. 0x4F1BBCDC
            L’hash risultante sono i (32 - log2(M)) bit meno significativi
The Webcache System




   Introduzione
        l’obbiettivo di WebCache è quello di eliminare il problema
        del bootstrap in una rete completamente decentralizzata
       una cache è un programma residente su un qualsiasi web-
       server che memorizza gli indirizzi ip dei peer di una rete
       Gnutella e gli url di altre cache
       si noti come questo concetto di webcache risulti
       indipendente dalla rete Gnutella in sè e può essere
       applicato a qualsiasi sistema decentralizzato
The Webcache System




   Client Interface
   L’interfaccia client specifica come i client che vogliono utilizzare
   una webcache devono interagire con la controparte server; es-
   istono vari tipi di richieste, specifiche per ogni operazione che
   si vuole effettuare
Hostfile Request




   Example
           http://www.hostname.com/gwc.php?hostfile=1

   Specifica
       il client desidera ricevere una lista di peer appartenenti alla
       rete
       la cache invia una lista i cui membri sono separati da un
       <lf> nella forma ip:porta
       questa lista non deve essere molto grande, 20 nodi al
       massimo e deve contenere solo le ultime entry
Urlfile Request




   Example
             http://www.hostname.com/gwc.php?urlfile=1

   Specifica
       il client desidera ricevere una lista di url di altre cache
       la cache invia una lista in cui gli url sono separati da un <lf>
       questa lista non deve essere molto grande, 20 url al
       massimo e deve contenere solo le ultime entry
Update Request


   Example (Aggiornamento di un host)
     http://www.hostname.com/gwc.php?ip=abc.def.ghi.jkl:port

   Example (Aggiornamento di una cache)
         http://www.hostname.com/gwc.php?url=http://blah

   Specifica
       il client desidera aggiornare delle informazioni contenute
       nella cache
       l’url per l’aggiornamento di una cache deve essere il path
       completo per il programma (url-encoded se necessario)
       è possibile inviare anche i due aggiornamenti in un’unica
       query
Update Request (cont.)




   Definition (Risposte della WebCache)
                      ^(?:OK|ERROR(?::s.+)?)$

   Specifica
   si noti come il messaggio di errore sia del tutto facoltativo
Ping Request




   Example
              http://www.hostname.com/gwc.php?ping=1

   Definition (Risposte della WebCache)
                          ^PONG(?::s.+)?$

   Specifica
       classico schema di PING/PONG per verificare se una
       cache risulta essere attiva
       questo messaggio di diagnostica dovrebbe essere
       utilizzato tra cache diverse e non tra peer della rete
Stat Request



   Example
               http://www.hostname.com/gwc.php?stat=1

   Definition (Risposte della WebCache)
   numero totale richieste ricevute <crlf>
   numero richieste ricevute nell’ultima ora <crlf>
   numero richieste di tipo update ricevute nell’ultima ora <crlf>

   Specifica
       estensione che le cache possono implementare ed è utile a
       fini statistici
       per essere davvero efficace ogni client dovrebbe inviare
       informazioni aggiuntive
Stat Request (cont.)




   Example (Schema nuove query string)
              [...]?client=ABCD&version=1.2.3&hostfile=1

   Specifica
        le due variabili aggiuntive permettono di avere dati più
        accurati nelle statistiche
        la variabile client è un codice di 4 bytes che identifica il client
        (lo stesso utilizzato nelle QueryHit)
        la variabile version identifica la versione del client
Client: comportamento



   Cosa fare. . .
      i client devono mantenere una lista di peer connessi alla
      rete ed una lista di url di cache da contattare
       è compito del client mantenere una lista aggiornata di
       questi indirizzi
       un client dovrebbe inviare una richiesta di tipo Hostfile tutte
       le volte che necessita di nuovi peer a cui connettersi
       un client dovrebbe inviare una richiesta di tipo Urlfile per
       costruire la sua lista di webcache
       un client dovrebbe inviare queste richieste periodicamente,
       con il proprio indirizzo ip ed una cache funzionante scelta
       a caso tra quelle della propria lista
Client: comportamento (cont.)



   . . . e cosa non fare
          inviare il proprio indirizzo ip se non è raggiungibile dagli
          altri peer
       inviare indirizzi ip diversi dal proprio
       inviare url di cache non funzionanti

   Quando una cache è funzionante?
      per essere funzionante non basta che una cache risponda
      a dei semplici PING
       si può essere ragionevolmente sicuri che una cache sia
       funzionante se e solo se essa risponde correttamente a
       richieste di tipo PING e UPDATE
Client: comportamento (cont.)




   Richieste
       l’interazione con la cache è realizzata tramite il protocollo
       HTTP
       in particolare si utilizzano richieste di tipo GET
       ciascuna richiesta deve essere codifica come previsto da
       rfc1738 (Uniform Resource Locators)
       le richieste risultano quindi molto semplici in quanto parti
       integranti dell’url richiesto
Server: comportamento



   Specifiche
       la cache comunica con i client tramite il protocollo HTTP e
       deve quindi essere conforme a queste specifiche
       le risposte devono rispettare il Content-Type e comunque
       essere in accordo con le richieste del client
       la cache dovrebbe ritornare sono un numero ridotto di
       entry (circa 10 - 20) e solo le informazioni più recenti
       questo contribuisce a mantenere le cache di ridotte dimen-
       sioni visto che le informazioni più vecchie possono essere
       rimpiazzate con quelle nuove appena esse arrivano
       avere cache così piccole contribuisce a fornire
       informazioni sempre aggiornate
Server: comportamento (cont.)



   Risposte
       un messaggio di tipo OK implica che la procedura si è
       conclusa senza errori
       un messaggio di tipo ERROR implica che la procedura non
       si è potuta concludere per una qualche sorta di errore
       siccome i client dovrebbero rimuovere le cache che ritor-
       nano codici di errore, è consigliabile di non abusare di
       questo codice
       errori transitori, come il tentativo da parte di un client di
       eseguire l’update di un ip o url errato dovrebbero essere
       liquidati con una risposta di tipo OK seguita da un
       WARNING
Server: comportamento (cont.)




   Sicurezza
       l’attacco più ovvio che può venire in mente è quello di
       provare ad inserire host o ip invalidi all’interno della cache
       la cache, una volta ricevuto un update da un client, non
       dovrebbe accettare un’altro update dallo stesso ip per un
       intervallo di tempo stabilito
       in questo modo le entry maligne non possono essere
       inserite da un stesso ip prima di un certo lasso di tempo
       una volta inserita, una entry maligna rimarrà in cache solo
       una frazione del timeout stabilito in quanto resa obsoleta
       dagli update degli altri client
Realizzazione di un client




   gcacher
   gcacher è uno script perl che fa parte di una suite di program-
   mi scritti al fine di dimostrare alcune delle cose viste in questa
   presentazione; gcacher è rilasciato sotto GPLv2

   Installazione nelle propria home
   perl Makefile.PL PREFIX=~/.gnutella/usr
   make all test install

   export PATH=~/.gnutella/usr/bin:${PATH}
   export PERL5LIB=~/.gnutella/usr/share/perl:$PERL5LIB
Realizzazione di un client


   gcacher
   gcacher si connette ad una Web-Cache e richiede una lista di
   peer attualmente connessi alla rete Gnutella

   Example (Help)
Realizzazione di un client


   gcacher
   gcacher mentre preleva una lista di peer. . .

   Example (Una lista di peer)
Introduzione




   Che cos’è. . .
      un crawler (detto anche spider o robot), è un software che
      analizza i contenuti di una rete in un modo metodico e
      automatizzato
       catturare la topologia di una rete a fini diagnostici o statistici
       non è un compito facile
       il carico che questo crawler può imporre alla rete durante il
       suo passaggio potrebbe paralizzare la rete
Crawler Ping




   Quando gli uomini erano veramente uomini. . .
       inizialmente il crawling veniva realizzato tramite i meccanis-
       mi di PING/PONG previsti dal protocollo Gnutella
       una possibile implementazione consiste nel mandare un
       pacchetto di tipo PING con Hops = 0 e TTL = 2 ad un host
       ed aspettare tutte le risposte di tipo PONG
       questo metodo può continuare ad essere usato ma risulta
       essere troppo lento per ottenere una fotografia della rete in
       un tempo ragionevole
       al fine di limitare l’overhead è consigliabile che queste
       risposte di PONG non contengano estensioni GGEP
Crawler Headers




   . . . e non mangiatori di quiche
   Un’estensione al protocollo Gnutella prova a velocizzare il
   Crawling aggiungendo un nuovo header da inviare appena la
   connessione tra due nodi viene stabilita

   Example (Request HTTP Headers)
              Crawler: <max_Version>.<min_Version>

   Protocollo
   La versione attuale del protocollo di Crawling è la 0.1
Crawler Headers (cont.)




   Example (Reply HTTP Headers)
                       Leaves: ipleaf1 :port, [...]
                       Peers: ippeer1 :port, [...]

   Protocollo
       Leaves identifica le foglie connesse al peer interrogato se
       esso è un Ultrapeer
       Peers identifica tutti gli altri nodi connessi (ad esempio altri
       Ultrapeer )
       al termine di questa transazione la connessione viene
       chiusa immediatamente
Realizzazione di un crawler




   gcrawler
   gcrawler è uno script perl che fa parte di una suite di program-
   mi scritti al fine di dimostrare alcune delle cose viste in questa
   presentazione; gcrawler è rilasciato sotto GPLv2

   Installazione nelle propria home
   perl Makefile.PL PREFIX=~/.gnutella/usr
   make all test install

   export PATH=~/.gnutella/usr/bin:${PATH}
   export PERL5LIB=~/.gnutella/usr/share/perl:$PERL5LIB
Realizzazione di un crawler


   gcrawler
   gcrawler disegna la mappa della topologia di una parte della
   rete, differenziando gli Ultrapeer dalle foglie e visualizzando le
   connessioni tra i nodi

   Example (Help)
Introduzione




   Che cos’è. . .
   A livello di astrazione questa specifica regola il traferimento di
   pacchetti del tipo QueryHit tipici del protocollo della rete Gnutella
   attraverso il protocollo di trasporto HTTP
Browse Host Extension


   Protocollo
       una richiesta di Browse Host viene eseguita attraverso una
       richiesta GET della root
       la richiesta deve includere tutti i media type che sono ac-
       cettati come risposta attraverso l’apposito header HTTP
       Accept (rfc1945)
       i tipi possibili sono text/html e application/x-gnutella-packets
       se la richiesta può essere soddisfatta il server risponde con
       un codice 200 OK specificando il media type utilizzato nella
       risposta tramite header Content-Type
       se la richiesta non può essere soddisfatta un codice 406
       Not Acceptable viene restituito
       in ogni caso al termine della transazione la connessione
       viene terminata
Browse Host Extension


   Media Type
       application/x-gnutella-packets è lo standard previsto dal
       protocollo e consiste in uno stream di pacchetti di tipo
       QueryHit tipici del protocollo Gnutella
       text/html è utilizzato come fallback per quei client che non
       supportano il primo metodo
       text/html non dovrebbe essere utilizzato in quanto la rispos-
       ta manca di alcune informazioni come, ad esempio, la
       dimensione di ogni risorsa

   Hint
   utilizzando il protocollo HTTP questa estensione si presta molto
   bene ad essere utilizzata anche tramite PUSH nella maniera
   usuale
Browse Host Extension




   Tuning
       il traffico può anche essere compresso come previsto dalla
       Link Compression Extension
       un servent può decidere se limitare la banda dedicata a
       questa operazione
       un servent può anche decidere di mettere in coda queste
       richieste come fossero delle richieste di download (previsto
       dalla Active Queuing Extension)
Realizzazione di un browser




   gbrowser
   gbrowser è uno script perl che fa parte di una suite di program-
   mi scritti al fine di dimostrare alcune delle cose viste in questa
   presentazione; gbrowser è rilasciato sotto GPLv2

   Installazione nelle propria home
   perl Makefile.PL PREFIX=~/.gnutella/usr
   make all test install

   export PATH=~/.gnutella/usr/bin:${PATH}
   export PERL5LIB=~/.gnutella/usr/share/perl:$PERL5LIB
Realizzazione di un browser


   gbrowser
   gbrowser permette di visualizzare le risorse condivise da un
   peer attraverso la rete Gnutella

   Example (Help)
Realizzazione di un browser



   Implementazione di un pacchetto Gnutella
   Un generico pacchetto Gnutella può essere implementato, se
   si utilizza un linguaggio ad oggetti, come una classe aventi i
   campi che lo caratterizzano

   Example (Gnutella::Packet::Generic)
   my $self = {
       _accessible    => {
           debug     => $parent->debug(),
           timeout   => $parent->timeout(),
           msgid     => [],
           type      => undef,
           ttl       => 0,
           hops      => 0,
           size      => 0,
           payload   => undef,
       },
   };$
Realizzazione di un browser


   Tipi di pacchetto Gnutella
   Ciascun tipo di pacchetto è identificato in maniera univoca dal
   campo type presente nell’intestazione, ossia un intero a 8 bit
   che può assumere diversi valori

   Example (Tipi di pacchetto Gnutella)
   use constant {
       PACKET_PING    =>   0x00,
       PACKET_PONG    =>   0x01,
       PACKET_PUSH    =>   0x40,
       PACKET_QUERY   =>   0x80,
       PACKET_REPLY   =>   0x81,
   };



   Implementazione
   Per ogni tipo di pacchetto ci sarà una classe che estende il
   pacchetto generico specializzandolo nel sotto tipo desiderato
Realizzazione di un browser




   Pacchetto QueryHit
       un pacchetto di questo tipo può essere quindi implementato
       con una classe, sia Gnutella::Packet::QueryReply, figlia di
       Gnutella::Packet::Generic
       tale classe va specializzata con i campi che contraddistin-
       guono il suo payload (ad esempio ip, port, speed, results,
       guid)
       tale classe va munita di un metodo ausiliario, sia
       parsePayload, che si occupa di estrarre le informazioni dal
       payload
Realizzazione di un browser


   Example (Gnutella::Packet::QueryReply::$parsePayload)
      [...]
      for (my $i = 0;   $i < $count; $i++) {
          my @extra;
          my $index =   unpack("L", substr($data, 0, 4, ’’));
          my $size =    unpack("L", substr($data, 0, 4, ’’));
          my $name =    substr($data, 0, index($data, "x00"), ’’);

         substr($data, 0, 1, ’’);

         while(1) {
             if(substr($data, 0, 1) =~ /^(?:x00|xC3)$/) {
                 last; # no more extensions or GGEP found
             }

             my $text = substr($data, 0, index($data, "x1C"));

             $text = substr($text, 4) if $text =~ /^urn:/;

             push @extra, $text;
             substr($data, 0, index($data, "x1C") + 1, ’’);
         }

          substr($data, 0, index($data, "x00") + 1, ’’);
          push @set, [ $index, $size, $name, @extra ];
      }
      [...]
Realizzazione di un browser



   Example (Gnutella::ConnectionBinary::read)
   sub read {
       # [...]
       return undef
           unless read( $self->socket(), $header, 23) == 23;

        # parse header
        @msgid = unpack("L4",   substr($header,   0, 16));
        $type = unpack("C",     substr($header,   16, 1));
        $ttl   = unpack("C",    substr($header,   17, 1));
        $hops = unpack("C",     substr($header,   18, 1));
        $size = unpack("L",     substr($header,   19, 4));

        # read payload
        return undef
            unless $self->isReadable();

        return undef
            unless read( $self->socket(), $payload, $size ) == $size;

        return $self->$classType( $type )->new($self,
                    ’msgid’ => @msgid, ’type’ => $type, ’ttl’ => $ttl,
                    ’hops’ => $hops, ’size’ => $size, ’payload’ => $payload
                );
   }$
Realizzazione di un browser


   Che cosa ritorna?
   Il metodo ausiliario classType ritorna un tipo per il pacchetto del
   protocollo Gnutella

   Example (Gnutella::ConnectionBinary::$classType)
   my $classType = sub {
       my($self, $packetType) = @_;

        # add implemented packets
        return ’Gnutella::Packet::Generic’
            unless $packetType == PACKET_REPLY;

        return ’Gnutella::Packet::QueryReply’;
   };



   Lavori in corso
   Attualmente solo i pacchetti di tipo QueryHit sono implementati,
   gli altri vengono trattati come pacchetti generici
Realizzazione di un browser


   gbrowser
   gbrowser durante la visualizzazione delle risorse condivise da
   un peer d’oltre oceano. . .

   Example (Visualizzazione di un peer)
Realizzazione di un browser


   gbrowser
   gbrowser può fornire anche spunti interessanti. . .

   Example (Eseguire ricerche)
Realizzazione di un browser


   gbrowser
   gbrowser utilizzato insieme a gstat permette di avere anche dei
   dati a scopo statistico. . .

   Example (Un po’ di statistiche)
Introduzione




   Perchè. . .
       la gestione dei download in Gnutella è quella tipica della
       lotteria: se si è fortunati si vince, altrimenti niente
       questo approccio non premia gli utenti che aspettano per
       un file, ma peggio premia quelli che abusano della rete
       collegandosi tante volte finchè non ottengono ciò che
       desiderano
       la soluzione è quella di creare una sorta di coda di attesa
       per tutti gli utenti che vorrebbero scaricare una risorsa ma
       che al momento non è possibile servire
Handshake




   Example (HTTP Headers)
             X-Queue: <max_Version>.<min_Version>

   Protocollo
       tutti i client che supportano questa estensione inviano
       questo header quando ricevono una richiesta di download
       questo header semplicemente indica che le richieste di
       download potranno essere passibili di coda
       se un client non riceve questo header deve seguire la
       normale procedura prevista dal protocollo Gnutella
       la versione attuale del protocollo di Active Queuing è la 0.1
Handshake




   Protocollo
       se un server che ha ricevuto la richiesta di download ha uno
       slot libero allora il trasferimento inizia normalmente come
       previsto dal protocollo Gnutella (codice 200 o 206)
       altrimenti un codice 503 è ritornato ed un ulteriore header
       X-Queue è inviato
Handshake



   Example (HTTP Headers)
   X-Queue: position=2,length=5,limit=4,pollMin=45,pollMax=120

   Protocollo
       position identifica l’attuale posizione nella coda; quando
       si è giunti alla posizione #1 allora si è i primi ad ottenere il
       prossimo slot libero
       length è l’attuale lunghezza della coda
       limit è il numero di upload contemporanei consentiti
       tutti questi campi sono opzionali e servono unicamente
       per dare delle informazioni al client che può così vedere i
       propri progressi
Handshake


   Polling
       i due parametri pollMin e pollMax indicano al client quanto
       spesso deve richiedere aggiornamenti sul download
       inviare una richiesta più spesso di pollMin viene interpretato
       come flooding
       non inviare una richiesta prima di pollMax viene interpretato
       come un non più interessamento alla risorsa
       questi parametri possono cambiare tra una richiesta e l’al-
       tra e possono essere utilizzati anche al fine di bilanciare il
       carico di un peer
       pollMin e pollMax possono essere proporzionali alla
       posizione del peer nella coda; in questo modo si riduce il
       tempo tra quando uno slot è pronto e quando il download
       ha effettivamente inizio
Handshake




   Vantaggi
      utilizzando questa estensione un utente può vedere i pro-
      pri progressi fino alla posizione #1, anche con code molto
      lunghe
      se un utente non è più interessato al download di una
      risorsa può chiudere la connessione e nessuno slot verrà
      sprecato per una richiesta che non arriverà mai
      siccome le richieste sono fatte tramite HTTP un utente può
      anche richiedere una porzione della risorsa da scaricare
Handshake




   Casi Speciali
       se un utente che è già in coda richiede un altro file, esso
       deve essere spostato alla fine della coda
       un utente che ha eseguito un download parziale può
       richidere un altro chunk del file senza essere messo al-
       la fine della coda; questo incentiva il download parziale e
       concorrente da più peer
       la coda ha una lunghezza fissata; tutte le richieste che non
       possono essere messe in coda devono ricevere il codice
       standard previsto dal procollo (503)
Introduzione




   Perchè. . .
       la compressione del traffico sulla rete Gnutella è opzionale
       ed è intesa "per connessione"
       siccome la compressione dello stream è "per connes-
       sione", ogni pacchetto viene decompresso quando ricevuto
       e ricompresso per ogni connessione
       l’abilitazione alla compressione del traffico va negoziata
       secondo il famoso paradigma del 3-Way Handshake in
       quanto decomprimere è facile mentre la compressione
       richiede un minimo di risorse di cui un peer potrebbe non
       disporre
Handshake



   Example (Disponibilità a ricevere)
                 Accept-Encoding: encoding1 [, ...]

   Example (Disponibilità ad inviare)
                 Content-Encoding: encoding1 [, ...]

   HTTP Headers
      il peer disposto a comprimere il traffico deve scegliere uno
      e uno solo tra gli algoritmi supportati dalla controparte
       questo implica che la compressione può essere anche
       asimmetrica; un utente può anche accettare dati
       compressi ma spedire del plain text
Handshake: esempi




   Example (Compressione del traffico simmetrica)
   Peer1                           Peer2
   -----------------------------------------------------------
   GNUTELLA CONNECT/0.6
   Accept-Encoding: deflate

                                   GNUTELLA/0.6 200 OK
                                   Accept-Encoding: deflate
                                   Content-Encoding: deflate

   GNUTELLA/0.6 200 OK
   Content-Encoding: deflate
Handshake: esempi




   Example (Compressione del traffico asimmetrica)
   Peer1                           Peer2
   -----------------------------------------------------------
   GNUTELLA CONNECT/0.6
   Accept-Encoding: deflate

                                   GNUTELLA/0.6 200 OK
                                   Accept-Encoding: deflate

   GNUTELLA/0.6 200 OK
   Content-Encoding: deflate
Vendor Messages



   Introduzione
        il supporto ai Vendor Messages permette ai produttori di
        software di sperimentare nuovi messaggi senza snaturare
        la rete Gnutella
       a questo scopo di testing è stato introdotto un nuovo tipo
       di messaggio, 0x31; è stato inoltre definito un ulteriore
       tipo di messaggio, 0x32, riservato ai Vendor Messages
       standardizzati
       se un messaggio di un produttore inizialmente definito
       come privato viene considerato particolarmente utile dalla
       comunità questo viene promosso ad avere come type 0x32
       essendo un messaggio del protocollo Gnutella
       l’intestazione è quella standard
Vendor Messages


    Struttura del pacchetto   Vendor-ID
    so eo Campo               una sequenza di quattro caratteri
    0     3 Vendor-ID         ASCII case sensitive che deno-
    4     5 Sub-Selector      tano un produttore; stesso codice
    6     7 Version           delle QueryHit e utilizzato nelle
                              connessioni ad una WebCache
Vendor Messages


    Struttura del pacchetto    Sub-Selector
    so eo Campo                identificatore per il tipo di messag-
    0     3 Vendor-ID          gio per quello specifico produttore
    4     5 Sub-Selector       (little endian sedici bit unsigned int)
    6     7 Version

   Definition (Identificatore)
   uno specifico messaggio è univocamente identificato dalla tupla
   (Vendor-ID, Sub-Selector)
Vendor Messages


    Struttura del pacchetto   Version
    so eo Campo               little endian sedici bit unsigned int
    0     3 Vendor-ID         che denota il numero di versione;
    4     5 Sub-Selector      solitamente parte da uno
    6     7 Version
Vendor Messages




   Example (Identificazione di un pacchetto)
              <Vendor-ID>/<Sub-Seector>v<Version>

   Notazione
       ad esempio LIME/64v2 è un identificatore valido (il numero
       di versione viene spesso omesso)
       le regole su come routare uno specifico messaggio, il TTL,
       Hops, GUID ed ogni altro aspetto viene definito dal tipo di
       messaggio
Vendor Messages


   Example (HTTP Headers)
         Vendor-Message: <max_Version>.<min_Version>

   Handshake
      i peer che supportano questa estensione devono dichiararlo
      alla controparte durante handshake
       la versione attuale del protocollo è la 0.1
       con supportare qui si intende che un peer semplicemente
       legge i messaggi di tipo 0x3[12] senza terminare la con-
       nessione e non necessariamente che sia capace di capire
       il messaggio in sè
       siccome l’insieme di questi messaggi non ha una
       dimensione fissata e può essere molto grande questo non
       viene dichiarato
Vendor Messages



   Pacchetto null/0v0
      alcuni vendor message possono, ad esempio, prevedere
      una riposta
      è necessario sapere se un particolare peer supporta un
      particolare messaggio prima di inviarlo per evitare di at-
      tendere all’infinito o addirittura chiudere la connessione se
      questa non arriva entro un certo lasso di tempo
      dopo handshake è necessario dichiarare la lista dei Vendor
      Messages supportati dalla propria implementazione
      il messaggio da utilizzare viene detto null/0v0 in quanto il
      campo Vendor-ID, Sub-Selector e Version vengono settati
      a zero
Pacchetto null/0v0



                       Struttura del pacchetto
                       so eo Campo
                       8     9 Size


   Pacchetto null/0v0
      little endian sedici bit unsigned int che identifica il numero
      (e non la dimensione) di blocchi che si ripetono all’interno
      del pacchetto
       ciascun blocco ha dimensione otto byte e descrive un
       particolare Vendor Message supportato
Pacchetto null/0v0



                            Blocco ripetuto
                       so    eo Campo
                       0     3 Vendor-ID
                       4     5 Sub-Selector
                       6     7 Version


   Pacchetto null/0v0
      si noti che qui gli offset partono da zero per comodità ma il
      primo di questi blocchi nizierebbe all’offset dieci
       se più versioni dello stesso messaggio sono supportate e
       si sa che sono retro compatibili, allora solo l’ultima deve
       essere indicata
Vendor Messages




   Esempio: Hops Flow Message
                  Specifiche del pacchetto
                       Campo Specifica
                    Vendor-ID BEAR
                  Sub-Selector 4
                       Version 1
                          TTL 1
                         Hops 0
                        GUID -
                       Routed no
                      Payload si
Vendor Messages




   Esempio: Hops Flow Message
      questo messaggio è un Vendor Message realmente utilizza-
      to ed è identificato da BEAR/4v1; viene anche detto Hops
      Flow
      il payload del pacchetto è composto da un unico byte che
      esprime il numero massimo, non compreso, per il campo
      Hops quando una query viene inoltrata
      un nodo foglia può utilizzare questo messaggio per
      informare il proprio Ultrapeer di abilitare o disabilitare il
      forwarding delle query
Vendor Messages




   Esempio: Hops Flow Message
      settare un valore a 0 implica che non si vuole ricevere nes-
      suna query in quanto il valore minimo che si può inserire
      nel campo Hops è, appunto, 0
      un valore a 1, invece, dichiara che si desidera ricevere solo
      le query generate da un vicino
      in generale dovrebbe essere utilizzato un valore pari a
      max_TTL + 1
Bye Message




   Introduzione
        è un messaggio utilizzato per informare la controparte del
        fatto che si sta per chiudere la connessione
       un servent che supporta il pacchetto Bye deve annunciarne
       il supporto tramite apposito header
       la versione attuale del protocollo è la 0.1

   Example (HTTP Header)
           Bye-Message: <max_Version>.<min_Version>
Bye Message



   Introduzione
        un messaggio di tipo Bye è identificato da un nuovo opcode,
        0x02
       questo pacchetto deve sempre essere inviato con TTL = 1
       per evitare che si propaghi nella rete (Hops = 0)
       un peer che riceve un messaggio di tipo Bye deve chiudere
       la connessione immediatamente
       di conseguenza può essere inviato anche a client che non
       supportano questa estensione
       un peer che ha inviato un messaggio Bye deve attendere
       alcuni secondi prima di chiudere la connessione e non
       inviare altro; durante questo periodo deve droppare tutto
       ciò che riceve a parte messaggi di tipo QueryHit e Push
Bye Message


    Struttura del pacchetto   Code
    so eo Campo               16 bit little endian unsigned int, un
    0     1 Code              codice identificativo
    2     n Description

   Definition (Code)
   la presenza di un codice numerico garantisce che questi mes-
   saggi possano essere processati in maniera automatica; viene
   utilizzata una classificazione dei codici simile a quella del
   protocollo SMTP
Bye Message


    Struttura del pacchetto   Description
    so eo Campo               una stringa di descrizione termina-
    0     1 Code              ta da un x00 (NULL)
    2     n Description

   Definition (Description)
   il messaggio dovrebbe essere una stringa che descrive il più
   possibile l’errore che si è verificato
Bye Message


   Codici numerici
      2xx: nessun errore rilevato, la connessione viene semplice-
      mente chiusa (200) oppure su richiesta dell’amministratore
      del peer (201)
       4xx: il peer remoto ha causato un qualche errore come l’in-
       vio di pacchetti troppo grossi (400), troppi messaggi dupli-
       cati (401), query errate (402), messaggi per cui vale TTL +
       Hops > max_TTL (403), troppi messaggi sconosciuti (404),
       raggiunge un certo timeout di inattività (405), non risponde
       ad un Ping con TTL=1 (406) oppure non sta condividendo
       abbastanza risorse (407 )
       5xx: il peer ha riscontrato un errore interno come un errore
       di I/O (500), una sincronizzazione nel protocollo (501) o la
       coda d’invio è piena (502)
Bye Message




   Descrizioni
      è possibile utilizzare anche degli header HTTP per meglio
      caratterizzare ciò che è accaduto e provare ad indirizzare il
      ricevente verso altri nodi a cui connettersi
       se si vogliono inserire degli header HTTP-like bisogna
       terminare la prima descrizione con un crlf
       tutte le volte che è possibile è preferibile utilizzare anche
       gli header HTTP
Metadata



   Introduzione
        Gnutella come molti altri protocolli di condivisione di risorse
        utilizza la corrispondenza tra l’interrogazione effettuata ed il
        nome della risorsa
       questo è limitativo e restringe la richiesta a ciò che è
       contenuto nel nome della risorsa
       si pensi ad un utente che voglia cercare un libro intitolato Il
       Big Bang - L’origine dell’universo scritto da Mario Bianchi e
       pubblicato dalla Rossi Editore nel Maggio del 1998
       se qualcuno possedesse il libro potrebbe chiamare il file Il
       Big-Bang.pdf. Un utente interessato, dunque, cercherebbe
       le parole Big e Bang trovando una pletora di cose che non
       stava cercando
Metadata




   L’idea
        l’idea è quella di specificare più informazioni in un’uni-
        ca interrogazione per poter cercare più efficacemente le
        risorse
       ciascuna risorsa nella collezione di un utente, quindi, può
       essere caratterizzata da più informazioni al fine di ottenerne
       una catalogazione migliore
       è possibile codificare questi metatag in vari formati, sia
       binari sia testuali; per Gnutella si è scelto di utilizzare xml
Metadata




   Implementazione
       a ciascun tipo di risorsa viene associato uno schema che
       definisce le informazioni che possono essere associate a
       quel particolare tipo
       uno schema altro non è che un dtd a cui il metatag
       associato ad una risorsa deve essere conforme
       nell’esempio precedente del libro, al file Il Big Bang.pdf
       viene associato un metatag conforme allo schema book
Metadata



   Esempio di Rich Query
   Un utente che volesse cercare il libro del nostro esempio,
   potrebbe inviare una richiesta simile a questa

   Example (Rich Query)
   <books>
       <book schema="http://www.hostname.com/schemas/book.xsd"
            title="Il Big Bang - L’origine dell’universo"
            publisher="Rossi Editore"
            author="Mario Bianchi"
       />
   </books>



   Esempio di Rich Query
   Le informazioni non espressamente inserite dall’utente non
   compaiono nella query, risparmiando così banda
Metadata




   Example (Query Hit)
   <?xml version="1.0"?>
   <books xsi:noNamespaceSchemaLocation="http://www.hostname.com/schemas/book.xsd">
       <book identifier="/home/looser/bb.pdf"
            title="Il Big Bang - L’origine dell’universo"
            author="Mario Bianchi"
            chapters="11"
            genre="divulgazione scientifica"
            publisher="Rossi Editore"
            price="50 euro"
            comments="Un ottimo libro, ben scritto"
       />
   </books>



   Esempio di Query Hit
   Si noti il nome del file; questa risorsa non sarebbe stata trovata
   con una query tradizionale
Metadata: Estensione Query Message


    Struttura del pacchetto   Speed
     so eo Campo
                              velocità minima (inalterato)
     0     1 Speed
     2     n Query
    n+1 m Rich Query
Metadata: Estensione Query Message


    Struttura del pacchetto   Query
     so eo Campo              la stringa dell’interrogazione NULL-
     0     1 Speed            terminated (inalterato)
     2     n Query
    n+1 m Rich Query
Metadata: Estensione Query Message


    Struttura del pacchetto   Rich Query
     so eo Campo              nuova rich query, NULL terminated
     0     1 Speed            (aggiunto)
     2     n Query
    n+1 m Rich Query

   Codice numerico
      estendere il pacchetto già adibito a trasportare una query
      per la rete Gnutella risulta essere molto semplice
       questo semplice schema garantisce che i client che non
       supportano questa estensione possano tranquillamente
       ignorare le Rich Query
Metadata




   Estensione Query Hits
       un client che riceve una Rich Query e non supporta questa
       estensione esegue la normale ricerca utilizzando la query
       string e risponde con una normale QueryHit
       un client invece che supporta questa estensione risponde
       con una QueryHit inserendo il file xml di risposta nella
       sezione QHD, nella parte privata, dopo le estensioni HUGE
       e GGEP
       siccome una risposta xml può essere anche molto grande,
       si può pensare di inserire il documento xml compresso
Approfondimenti I




       http://tinyurl.com/Gnutella
       Wiki Gnutella su AulaWeb
       http://tinyurl.com/Gruppo4
       Wiki Gruppo4 su AulaWeb

Gnutella Italian Printable

  • 1.
    Gnutella Protocollo,Organizzazione ed Estensioni Alberto Minetti Marco Queirolo Davide Scola Dipartimento di Informatica e Scienze dell’Informazione, Università degli studi di Genova, Italia Seminario Peer to Peer, 2009
  • 2.
    Sommario 1 Alberto Introduzione a Gnutella Protocollo Gnutella File Transfer Querying the network Download Mesh 2 Marco Local Hostcache PONG Caching Flow Control Routing Table Duplicates Table Query Routing Protocol 3 Davide The Webcache System Crawling Browse Host Extension Active Queuing Extension Link Compression Extension Vendor Messages Bye Message Metadata
  • 3.
    Generalità sulla Gnet Funzionamento schematizzato Gnutella è un protocollo per la ricerca distribuita e la distribuzione digitale. Ogni partecipante condivide le proprie risorse locali, individua risorse sulla rete e le ottinene. Modello di ricerca decentralizzato in cui ogni client è un server. Ogni host è detto Servent. Scambio di dati diretto attraverso HTTP.
  • 4.
    Generalità sulla Gnet Principi Gnutella Assoluta decentralizzazione. Tutti i nodi sono uguali, almeno in origine. Rete auto-gestita. Comunicazioni avvengono su una base client-server. Nelle ultime versioni arrivò ad implementare importanti features (hashing, multi-fonti, ...).
  • 5.
    Storia di Gnutella Justin Frankel Sviluppata come piccolo programma da Justin Frankel. Insieme a Tom Pepper fondò la Nullsoft. AOL, acquistata Nullsoft, ordinò il fermo del progetto. Grazie a reverse engineering il protocollo è stato reso pubblico. Nota Nullsoft è la stessa casa produttrice di Winamp e di WASTE.
  • 6.
    Generalità sulla Gnet Gnutella 0.4 Gnutella 0.4 è una rete omogenea. Ogni peer esegue queste istruzioni: 1 Connessione ad un host ottenuto dalla GWebCache. 2 Attraverso PING si ottengono informazioni sulla rete e sui peer connessi. 3 Altre connessioni per creare la rete logica Gnet. 4 Query e QueryHit sono instradate sulla Gnet usando flooding (vedremo dopo in dettaglio).
  • 7.
    Generalità sulla Gnet Gnutella 0.6 Gnutella 0.6 è una rete strutturata. Concetto di Ultrapeer. Cioè un peer che eccelle per memoria, banda e tempo di connessione che si occupa di instradare le query dei propri peer foglia verso altri Ultrapeer. Questi ultimi a loro volta instraderanno la query verso altri Ultrapeer e verso i propri nodi foglia, Intercetteranno i QueryHit e li rispediranno all’Ultrapeer richiedente che a sua volta invierà le risposte al nodo foglia che aveva inviato la richiesta.
  • 8.
    Principi di Elezionedegli Ultrapeer Ultrapeer capability Ultrapeers sono eletti senza l’uso di un server centrale. Spetta a ciascun nodo determinare se vuole diventare un Ultrapeer o un nodo foglia. Requisiti fondamentali: 1 Non Firewalled. 2 OS adatto (*NIX, Win XP/Server/NT, Mac OS/X sono meglio di Win 95/98/ME, Mac Classico). 3 Larghezza di banda. 4 Uptime futuro (Euristica sul tempo passato nella Gnet). 5 RAM per le tabelle di routing. 6 CPU per inoltrare le query in arrivo.
  • 9.
    Principi di Elezionedegli Ultrapeer Quando diventare Ultrapeer Un nodo ultrapeer-capable può diventare un Ultrapeer se vi è la necessità di avere più Ultrapeer sulla rete. La necessità di Ultrapeer può essere stimata guardando il numero di Ultrapeers trovati sulla rete Tali dati possono essere comunicati quando i nuovi collegamenti sono stabiliti (Ultrapeer Handshake).
  • 10.
    Prefazione Quando diventare Ultrapeer Cerchiamo di definire il protocollo Gnutella 0.6. La versione 0.6 anche se BETA è comunque la versione che viene utilizzata dalla maggioranza degli applicativi. Un Servent che utilizza la versione STABLE, cioè la 0.4, può connettersi ad una rete composta da soli Servent 0.6. La differenza fondamentale tra le due major version è appunto la presenza di Ultrapeer. La porta di default è 6346 in entrambe le versioni.
  • 11.
    Estensioni del protocollo Estensioni Alcuni Servents esistenti possono estendere il protocollo o addirittura modificare parti di esso (ad esempio la compressione o la crittografia dei messaggi) Comunque ogni servent rimanere sempre compatibile con servents che seguono la specifica. 0.4 consente estensioni all’interno di molti messaggi, che possono passare attraverso servent che non conoscono queste estensioni per raggiungere peer che le sanno interpretare.
  • 12.
    Estensioni del protocollo Example Se un servent, per esempio, vuole comprimere i messaggi Gnutella, deve prima assicurarsi che l’host remoto della connessione sia in grado di decomprimere (ciò è controllato avviene durante l’handshake), e in caso contrario è obbligato lasciare i messaggi non compressi. I Servents possono decidere di non accettare una connessione con un Servent che non supporta una funzione, ma devono sempre fare il possibile (best effort) per garantire che la rete Gnutella non si divida in reti separate.
  • 13.
    Bootstrap Bootstrap vecchie versioni Nelle prime fasi del protocollo Gnutella, ci sono stati diversi host conosciuti permanente Il loro scopo era quello di fornire una lista di host Gnutella a qualsiasi Servent Gnutella connessione a loro. Questi sono stati spesso chiamati hostcaches. Tuttavia gli hostcaches non vengono più utilizzati perchè si perdono alcuni dei vantaggi di un sistema distribuito.
  • 14.
    Bootstrap Bootstrap nuove versioni Per connettersi alla rete Gnutella, un Servent ha bisogno di trovare e memorizzare gli indirizzi host. Ci sono quattro modi con cui un Servent può ottenere gli indirizzi di host: 1 Chiedere a un GWebCache 2 Memorizzare gli indirizzi host letti dagli header X-Try e dagli header X-Try-Ultrapeers durante un handshake (sia che la stretta di mano abbia avuto successo o no). 3 Memorizzare gli indirizzi host nei messaggi pong (dopo almeno che un collegamento viene stabilito con la GNet). 4 Memorizzare gli indirizzi host leggendo i messaggi QueryHit (dopo che un minimo di due connessioni sono stabilite con la GNet).
  • 15.
    Bootstrap Condividere indirizzi host Ogni Servent dovrebbe inviare un header X-Try durante l’handshake. Questa intestazione fornisce una lista di host a cui l’altro Servent può tentare di connettersi Permette di ottenere gli indirizzi di nuovi host senza utilizzare il GWebCache. Example X-Try: 1.2.3.4:1234, 1.2.3.5:6346, 1.2.3.6:6347
  • 16.
    Bootstrap Condividere indirizzi host Un Servent dovrebbe inviare un numero ragionevole di host, i valori sono compresi tra 10 e 20. Comunque chi invia X-Try dovrebbe controllare che questi host abbiano una buona qualità. Includere host remoti che sono stati visti attivi di recente (non più di pochi minuti). Gli host trovati grazie ai Pong sono buoni candidati per l’inserimento in intestazioni X-Try. Per host trovati tramite QueryHit non è detto.
  • 17.
    Handshaking Condividere indirizzi host Un Servent crea una connessione TCP/IP ad un altro Servent e viene avviata una sequenza di handshaking. Il cliente è l’host che inizia la connessione e il server è l’host che è in ascolto.
  • 18.
    Handshaking Condividere indirizzi host 1 Il client stabilisce una connessione TCP con il server. 2 Il client invia GNUTELLA CONNECT/0.6 <cr><lf>. 3 Il client invia tutti gli header, ad eccezione di vendor-header, come specificato da HTTP (RFC2616). 4 Il server risponde con GNUTELLA/0.6 200 <string> <cr><lf>. 5 Il server invia tutte i prorpi header. 6 Il client invia GNUTELLA/0.6 200 OK <cr><lf>, se dopo il parsing headers del server, desidera connettersi. In caso contrario, risponde con un codice di errore e chiudere la connessione. 7 Il client invia i vendor-header se necessario. 8 Entrambi i client e server di invio di messaggi binari, utilizzando le informazioni acquisite in (3) e (5).
  • 19.
    Header HTTP Formato degli Header Ogni header è costituito da un nome di campo seguito da due punti e quindi il valore. Ogni riga termina con la sequenza <cr><lf>. La fine degli header è segnata da una singola linea <cr><lf> In ogni linea solitamente inizia una nuovo header Se inizia con uno spazio (ASCII 32) o una tabulazione orizzontale (ASCII 9) significa che sta continuando il precedente header. Gli spazi in più e le tabulazioni orizzontali possono essere compressi in uno spazio unico.
  • 20.
    Header HTTP Example Primo-Campo: valore del primo campo <cr><lf> Secondo-Campo: valore <cr><lf> del <cr><lf> secondo campo <cr><lf> <cr><lf> equivale a: Example Primo-Campo: valore del primo campo <cr><lf> Secondo-Campo: valore del secondo campo <cr><lf>
  • 21.
    Header HTTP Header multi linea con lo stesso nome di campo sono equivalenti a quelli di una linea dove tutti i valori dei campi sono separati da , (virgola). Example Campo: primo <cr><lf> Campo: secondo <cr><lf> equivale a: Example Campo: primo, secondo <cr><lf>
  • 22.
    Header HTTP Formato degli Header Vediamo un esempio di interazione tra un client e un server. I dati inviati dal client al server sono visualizzati nella parte sinistra. I dati inviati dal server al client sono visualizzati sulla destra. E’ importante notare che le intestazioni possono essere inviate in qualsiasi ordine. Alcune intestazioni non essenziali per l’esempio sono state rimosse
  • 23.
    Esempio di Handshake Example Client Server ----------------------------------------------------------- GNUTELLA CONNECT/0.6<cr><lf> User-Agent: BearShare/1.0<cr><lf> Pong-Caching: 0.1<cr><lf> GGEP: 0.5<cr><lf> <cr><lf> GNUTELLA/0.6 200 OK<cr><lf> User-Agent: BearShare/1.0<cr><lf> Pong-Caching: 0.1<cr><lf> GGEP: 0.5<cr><lf> Private-Data: 5ef89a<cr><lf> <cr><lf> GNUTELLA/0.6 200 OK<cr><lf> Private-Data: a04fce<cr><lf> <cr><lf> [binary messages] [binary messages]
  • 24.
    Handshaking Formato degli Header Il client (server) deve disconnettersi se riceve una risposta diversa da 200 al punto 4 (6). I servent deve usare intestazioni HTTP standard ove opportuno. Per esempio usare lo User-Agent piuttosto che un Vendor. Naturalmente esistono anche intestazioni proprie di Gnutella (per esempio, Query-Routing). Il codice di stato per il rifiuto di una connessione è 503 seguito da Busy o un’altra stringa di descrizione.
  • 25.
    Handshaking Futura Retrocompatibilità I servent possono ignorare i numeri di versione superiore al loro. E’ legale per un futuro client di connettersi a un server e inviare GNUTELLA CONNECT/0.7. Il server se non supporta 0.7 deve rispondere con GNUTELLA/0.6 200 OK. Intestazioni sconosciute al servent saranno semplicemente ignorate.
  • 26.
    Handshaking Retrocompatibilità alla 0.4 Alcuni vecchi servents avviano l’handshake con GNUTELLA CONNECT/0.4 <lf><lf>. Il server dovrebbe rispondere con OK GNUTELLA <lf><lf> seguito da messaggi binari. I servents possono riprovare con la stringa di connessione versione 0.4, se il tentativo di connessione versione 0.6 è stato respinto. Non è possibile usare nessun’header con la versione 0.4.
  • 27.
    Handshaking X-Try Quando una connessione viene respinta, un servent deve fornire all’altro una lista di altri host Gnutella, in modo che il primo possa provare a connettersi a questi ultimi. Example X-Try: 1.2.3.4:1234,3.4.5.6:3456 Nota Ogni elemento dell’header X-Try fornisce l’indirizzo IP di un Servent e il suo numero di porta di ascolto.
  • 28.
    Nodi foglia eUltrapeer Rete strutturata Originariamente tutti i nodi erano collegati gli uni agli altri in modo casuale. Ha funzionato bene per gli utenti con connessioni a banda larga. Il problema può essere alleviato con un’organizzazione strutturata. La nuova (0.6) rete gerarchica di Gnutella caratterizza i nodi della rete come foglie e Ultrapeers. I nodi della 0.4 vengono trattati come foglie poichè, non implementando il sistema Ultrapeer, non potranno mai essere Ultrapeer.
  • 29.
    Nodi foglia eUltrapeer Rete strutturata (cont.) Una foglia mantiene solo un piccolo numero di connessioni aperte, che sono quelle tra essa e alcuni Ultrapeers. Un Ultrapeer agisce come un proxy tra la rete Gnutella e le foglie ad esso collegati. Questo ha l’effetto di rendere la rete Gnutella scalabile riducendo: 1 il numero di nodi della rete coinvolti nella gestione dei messaggi e nel routing 2 quindi riduce il traffico reale tra i nodi.
  • 30.
    Nodi foglia eUltrapeer Rete strutturata (cont.) Un Ultrapeer inoltra una query a una foglia solo se ritiene che la foglia possa rispondere. Le foglie non inoltrano mai le query agli Ultrapeers. Ultrapeers sono collegati gli uni agli altri. Un Ultrapeer decide quali query trasmettere ai nodi foglia utilizzando il Query Routing Protocol, QRP. QRP routing non viene inviato tra Ultrapeers e foglie versione 0.4.
  • 31.
    Informazioni per l’elezione Rete strutturata (cont.) Le informazioni per l’elezione degli Ultrapeer sono scambiate durante la sequenza di handshaking. Vengono usate le seguenti nuove (0.6) intestazioni: 1 X-Ultrapeer True segnala che il nodo è un Ultrapeer, False segnala che il nodo vuol essere un nodo foglia. 2 X-Ultrapeer-Needed usato per bilanciare il numero di Ultrapeers. 3 X-Try-Ultrapeers come X-Try, ma contiene solo gli indirizzi di Ultrapeers. 4 X-Query-Routing Segnala il supporto per QPR. Il valore è la versione QRP (attualmente 0.1).
  • 32.
    Esempio di Handshake Example (Una foglia si connette ad un Ultrapeer) Leaf Ultrapeer ----------------------------------------------------------- GNUTELLA CONNECT/0.6 User-Agent: LimeWire/1.0 X-Ultrapeer: False X-Query-Routing: 0.1 GNUTELLA/0.6 200 OK User-Agent: LimeWire/1.0 X-Ultrapeer: True X-Ultrapeer-Needed: False X-Query-Routing: 0.1 X-Try: 24.37.144:6346, 193.205.63.22:6346 X-Try-Ultrapeers: 23.35.1.7:6346, 18.207.63.25:6347 GNUTELLA/0.6 200 OK [binary messages] [binary messages]
  • 33.
    Esempio di Hadshake(cont.) Vedi esempio precedente Al termine dell’esempio precedente La foglia è coperta dal Ultrapeer. La foglia dovrebbe eliminare eventuali connessioni a non Ultrapeer. E inviare una tabella di routing QRP (supponendo QRP sia utilizzato).
  • 34.
    Esempio di Handshake Example (Una foglia si connette ad un’altra foglia) Leaf1 Leaf2 ----------------------------------------------------------- GNUTELLA CONNECT/0.6 X-Ultrapeer: False GNUTELLA/0.6 503 I am a leaf X-Ultrapeer: False X-Try: 24.37.144:6346 X-Try-Ultrapeers: 23.35.1.7:6346 [Terminates connection]
  • 35.
    Esempio di Hadshake(cont.) Foglia e Foglia Al termine dell’esempio precedente Se una foglia coperta riceve una richiesta di connessione, la connessione deve essere rifiutata con il codice di errore 503. E insieme deve inviare un X-Try e un X-Try-Ultrapeer.
  • 36.
    Esempio di Hadshake Foglia e Foglia A volte i nodi possono essere entrambi non Ultrapeer e incapaci di trovare un Ultrapeer. In questo caso, si comportano esattamente come il vecchio protocollo 0.4 non strutturato. Example (Una foglia si connette ad un’altra foglia) Leaf1 Leaf2 -------------------------------------------------- GNUTELLA CONNECT/0.6 X-Ultrapeer: False GNUTELLA/0.6 200 OK X-Ultrapeer: False GNUTELLA/0.6 200 OK [binary messages] [binary messages]
  • 37.
    Esempio di Hadshake Foglia e Foglia Quando due Ultrapeer si incontrano entrambi hanno impostato X-Ultrapeer: True. Se entrambi hanno nodi foglia, rimarranno Ultrapeers dopo l’interazione. Example (Connessione tra due Ultrapeer) UltrapeerA UltrapeerB ------------------------------------------------------ GNUTELLA CONNECT/0.6 X-Ultrapeer: True GNUTELLA/0.6 200 OK X-Ultrapeer: True GNUTELLA/0.6 200 OK [binary messages] [binary messages]
  • 38.
    Esempio di Hadshake Example (Abdicazione di un Ultrapeer) UltrapeerA UltrapeerB ----------------------------------------------------------- GNUTELLA CONNECT/0.6 X-Ultrapeer: True GNUTELLA/0.6 200 OK X-Ultrapeer: True X-Ultrapeer-Needed: False GNUTELLA/0.6 200 OK X-Ultrapeer: False
  • 39.
    Esempio di Hadshake(cont.) Abdicazione di un Ultrapeer A volte ci saranno troppi Ultrapeer. Consideriamo il caso di un Ultrapeer A collegato a una Ultrapeer B. Se B non ha abbastanza foglie B può chiedere a A se può diventare una sua foglia. Se A non ha connessioni a foglie, si arresta il processo di nuove connessioni, termina ogni connessione 0.4, e invia una tabella QRP a B. Allora B farà da proxy ad A per tutto il traffico. Se A ha connessioni a foglie, ignora la richiesta.
  • 40.
    Messaggi binari Gnutella Messaggi binari Gnutella Tutti i messaggi binari Gnutella viaggiono sulla Gnet. L’inoltro dei messaggi sulla rete avviene attraverso flooding. Poichè il flooding è estremamente pesante vengono usati alcune precauzioni: 1 Caching (esempio pong-caching). 2 Query Routing Table (in seguito). 3 Dynamic Querying. Nota Il meccanismo di Dynamic Querying permette agli Ultrapeer di eseguire ricerche aggiuntive per file rari (poche QueryHit) e di diminuire il traffico per ricerche di file popolari (motle QueryHit).
  • 41.
    Header del messaggiobinario Message Header Bytes Descrizione 0-15 GUID 16 Payload Type 17 TTL 18 Hops 19-22 Payload Length
  • 42.
    Header del messaggiobinario Message Header GUID Bytes Descrizione Una stringa di 16 byte (GUID) 0-15 GUID identifica in modo univoco il 16 Payload Type messaggio sulla rete. 17 TTL 18 Hops 19-22 Payload Length
  • 43.
    Header del messaggiobinario Message Header Payload Type Bytes Descrizione Indica il tipo di messaggio. 0-15 GUID 0x00 Ping 16 Payload Type 0x01 Pong 17 TTL 0x02 Bye 18 Hops 0x40 Push 19-22 Payload Length 0x80 Query 0x81 Query Hit Nota Altri tipi di messaggio Gnutella possono essere usati, ma in tal caso il Servent deve prima assicurarsi che l’host remoto supporta questo nuovo tipo di messaggio. Questo può essere fatto utilizzando le intestazioni di handshaking.
  • 44.
    Header del messaggiobinario Message Header Time To Live Bytes Descrizione Ogni Servent dovrà diminuire il 0-15 GUID TTL, prima di passare il 16 Payload Type messaggio a un altro Servent. 17 TTL Quando il TTL raggiunge 0, il 18 Hops messaggio non sarà più 19-22 Payload Length trasmesso. MAI esagerare Nota L’abuso del campo TTL nei messaggi trasmessi porterà ad un ecceso di traffico! I servent devono verificare il TTL dei messaggi ricevuti e diminuirli se necessario. Messaggi con valori di TTL molto elevati (> 15) dovrebbe essere eliminati.
  • 45.
    Header del messaggiobinario Message Header Hops Bytes Descrizione Il numero di volte in cui il 0-15 GUID messaggio è stato inoltrato. Ogni 16 Payload Type Servent dovrà incrementare Hops 17 TTL prima di passare il messaggio ad 18 Hops un altro Servent. 19-22 Payload Length Nota TTL(0) = TTL(i) + Hops(i) dove TTL(i) e il Hops(i) sono il valore del TTL e di Hops del messaggio, e TTL(0) è il numero massimo di salti che un messaggio può fare (possiamo identificarlo come profondità, di solito è impostato a 7 ma alcuni applicativi permettono di modificare il valore).
  • 46.
    Header del messaggiobinario Message Header Payload Length Bytes Descrizione La lunghezza del messaggio che 0-15 GUID segue immediatamente questa 16 Payload Type intestazione. 17 TTL 18 Hops 19-22 Payload Length Nota Questo campo è unsigned e potrebbe raggiungere il valore molto elevati. Da specifica non dovrebbe superare i 4 KB.
  • 47.
    PING 0x00 Messaggio PING Il messaggio PING può contenere un’estensione GGEP (specificato più avanti) ma nessun payload.
  • 48.
    PONG 0x01 Messaggio PONG I messaggi Pong vengono inviati solo in risposta a un messaggio in arrivo Ping. Nota E’ comune per un Servent inviare tutti i Pong ricevuti recentemente ad ogni singolo messaggio Ping. Ciò è fattibile attraverso una host-cache in modo da inviare informazioni memorizzate nella cache senza sovraccaricare la rete (vedremo questo meccanismo in dettaglio successivamente). Nota L’ID del messaggio Pong in risposta ad un Ping deve essere lo stesso ID del messaggio Ping.
  • 49.
    PONG 0x001 Messaggio PONG Bytes Descrizione 0-1 Host Port 2-5 Host IP 6-9 Total Files 10-13 Total KB 14 GGEP
  • 50.
    PONG 0x001 Messaggio PONG Host Port Bytes Descrizione Numero di porta su cui l’host che 0-1 Host Port risponde può accettare 2-5 Host IP connessioni in ingresso. 6-9 Total Files 10-13 Total KB 14 GGEP
  • 51.
    PONG 0x001 Messaggio PONG Host IP Bytes Descrizione Indirizzo IP dell’host che risponde. 0-1 Host Port 2-5 Host IP 6-9 Total Files 10-13 Total KB 14 GGEP Nota Questo campo è in formato big-endian.
  • 52.
    PONG 0x001 Messaggio PONG Total Files Bytes Descrizione Numero di file condivisi. 0-1 Host Port 2-5 Host IP 6-9 Total Files 10-13 Total KB 14 GGEP
  • 53.
    PONG 0x001 Messaggio PONG Total KB Bytes Descrizione Kilobyte condivisi. 0-1 Host Port 2-5 Host IP 6-9 Total Files 10-13 Total KB 14 GGEP
  • 54.
    PONG 0x001 Messaggio PONG GGEP Bytes Descrizione Il blocco dell’estensione opzionale 0-1 Host Port GGEP (vedremo dopo GGEP 2-5 Host IP approfonditamente). 6-9 Total Files 10-13 Total KB 14 GGEP
  • 55.
    QUERY 0x80 Messaggio QUERY Bytes Descrizione 0-1 minSpeed 2- Search Criteria - Opt. Extensions
  • 56.
    QUERY 0x80 Messaggio QUERY Search Criteria Bytes Descrizione Criteri di ricerca. 0-1 minSpeed 2- Search Criteria - Opt. Extensions Nota Questo campo è terminato da un NULL (0x00).
  • 57.
    QUERY 0x80 Messaggio QUERY Optional Extensions Bytes Descrizione Il resto del messaggio di query 0-1 minSpeed viene utilizzato per i blocchi delle 2- Search Criteria estensioni opzionali. Le estensioni - Opt. Extensions ammesse sono GGEP, HUGE e XML (descritti in seguito). Nota Se due o più di questi tipi di estensione sono insieme, saranno separati da un byte 0x1C (separatore di file). Dato che i blocchi GGEP possono contenere un byte 0x1C, il blocco GGEP, se presente, deve essere collocato dopo i blocchi HUGE e blocchi XML. Il tipo di ogni blocco può essere determinato cercando i prefissi urn: per un grande blocco, < o ( per XML e 0xC3 per GGEP. Il blocco di estensione non dovrebbe essere seguito da un NULL (0x00), ma alcuni applicativi erroneamente lo fanno.
  • 58.
    QUERY 0x80 Messaggio QUERY minSpeed Bytes Descrizione In Gnutella 0.4 questo campo 0-1 minSpeed indicava la velocità minima in KB/s 2- Search Criteria richiesta per rispondere alla query. - Opt. Extensions minSpeed Questo uso è ormai obsoleto. Gnutella 0.6 cambia la semantica. Viene mantenuta una certa retrocompatibilità. La nuova semantica è in formato big-endian. Il bit più elevato (big-endian) (15◦ bit) viene usato come una flag per indicare nuova o vecchia semantica.
  • 59.
    QUERY 0x80 Messaggio QUERY minSpeed Bytes Descrizione In Gnutella 0.4 questo campo 0-1 minSpeed indicava la velocità minima in KB/s 2- Search Criteria richiesta per rispondere alla query. - Opt. Extensions Nota Vediamo adesso qual’è la nuova semantica del campo che in Gnutella 0.4 indicava la velocità.
  • 60.
    QUERY / minSpeed/Flags QUERY Flags Bytes Descrizione 15 EnableFlags 14 Firewalled 13 XML Metadata 12 LGDQ 11 GGEP H 10 OOB Q 9 Riservato 0-8 Max QueryHits
  • 61.
    QUERY / minSpeed/Flags QUERY Flags EnableFlags Bytes Descrizione Indicatore che deve essere 15 EnableFlags impostato a 1 per indicare che le 14 Firewalled bandiere sotto sono utilizzati al 13 XML Metadata posto di codifica per la velocità 12 LGDQ minima. 11 GGEP H 10 OOB Q 9 Riservato 0-8 Max QueryHits
  • 62.
    QUERY / minSpeed/Flags QUERY Flags Firewalled Bytes Descrizione L’host che ha inviato la query non 15 EnableFlags è in grado di accettare connessioni 14 Firewalled in entrata. 13 XML Metadata 12 LGDQ 11 GGEP H 10 OOB Q 9 Riservato 0-8 Max QueryHits Nota Questa opzione può essere utilizzata dal ricevente per evitare di restituire QueryHit se anche lui è Firewalled.
  • 63.
    QUERY / minSpeed/Flags QUERY Flags XML Metadata Bytes Descrizione Questo bit è a 1 se si desidera che 15 EnableFlags il ricevente invii dei metadati XML 14 Firewalled nella QueryHit. 13 XML Metadata 12 LGDQ 11 GGEP H 10 OOB Q 9 Riservato 0-8 Max QueryHits
  • 64.
    QUERY / minSpeed/Flags QUERY Flags Leaf Guidate Dynamic Query Bytes Descrizione Quando il bit è impostato a 1, 15 EnableFlags questo significa che la query viene 14 Firewalled inviata da una foglia che vuole 13 XML Metadata controllare il meccanismo Dynamic 12 LGDQ Queryung. 11 GGEP H 10 OOB Q 9 Riservato 0-8 Max QueryHits
  • 65.
    QUERY / minSpeed/Flags QUERY Flags Payload Length Bytes Descrizione GGEP H sono ammessi. 15 EnableFlags 14 Firewalled 13 XML Metadata 12 LGDQ 11 GGEP H 10 OOB Q 9 Riservato 0-8 Max QueryHits Nota Se questo bit è 1 il mittente è in grado di analizzare il GGEP H, che è un rimpiazzamento dell’estensione HUGE GEM (Vedremo solo HUGE).
  • 66.
    QUERY / minSpeed/Flags QUERY Flags Out of Band Query Bytes Descrizione Questo flag viene utilizzato per 15 EnableFlags riconoscere una query che è stata 14 Firewalled inviata con l’estensione Out of 13 XML Metadata Band Query. 12 LGDQ 11 GGEP H 10 OOB Q 9 Riservato 0-8 Max QueryHits
  • 67.
    QUERY / minSpeed/Flags QUERY Flags Massime Query Hits Bytes Descrizione Ciò non significa che devono 15 EnableFlags essere eliminate delle QueryHit, 14 Firewalled ma significa che la Query deve 13 XML Metadata essere propagata in modo che il 12 LGDQ numero delle risposte rispettino 11 GGEP H tale limite. 10 OOB Q 9 Riservato 0-8 Max QueryHits Nota 0 (zero) indica nessun limite.
  • 68.
    QUERYHIT 0x81 Messaggio QUERYHIT Bytes Descrizione 0 Total Hits 1-2 Host Port 3-6 Host IP 7-10 Speed 11- Result Set x Extended QHD x Vendor-specific last 16 ServentID
  • 69.
    QUERYHIT 0x81 Messaggio QUERYHIT Total Hits Bytes Descrizione Il numero di riscontri nell’insieme 0 Total Hits dei risultati. 1-2 Host Port 3-6 Host IP 7-10 Speed 11- Result Set x Extended QHD x Vendor-specific last 16 ServentID
  • 70.
    QUERYHIT 0x81 Messaggio QUERYHIT Host Port Bytes Descrizione Il numero di porta su cui l’host 0 Total Hits rispondente può accettare in 1-2 Host Port ingresso le richieste HTTP per 3-6 Host IP inviare il file. 7-10 Speed 11- Result Set x Extended QHD x Vendor-specific last 16 ServentID Nota Di solito la stessa porta che è usata per il traffico della rete Gnutella.
  • 71.
    QUERYHIT 0x81 Messaggio QUERYHIT Host IP Bytes Descrizione L’indirizzo IP del host rispondente. 0 Total Hits 1-2 Host Port 3-6 Host IP 7-10 Speed 11- Result Set x Extended QHD x Vendor-specific last 16 ServentID Nota Questo campo è in formato big-endian.
  • 72.
    QUERYHIT 0x81 Messaggio QUERYHIT Speed Bytes Descrizione La velocità (in KB/secondo) 0 Total Hits dell’host rispondente. 1-2 Host Port 3-6 Host IP 7-10 Speed 11- Result Set x Extended QHD x Vendor-specific last 16 ServentID
  • 73.
    QUERYHIT 0x81 Messaggio QUERYHIT Result Set Bytes Descrizione Insieme dei risultati alla query 0 Total Hits corrispondente. 1-2 Host Port 3-6 Host IP 7-10 Speed 11- Result Set x Extended QHD x Vendor-specific last 16 ServentID Nota Questo insieme contiene esattamente tanti elementi quanti sono quelli specificati dal primo byte della QueryHit. Vedi sotto per il formato.
  • 74.
    QUERYHIT 0x81 Messaggio QUERYHIT Extended QHD Bytes Descrizione Questo blocco non è obbligatorio 0 Total Hits ma è molto importante, lo vediamo 1-2 Host Port in seguito. 3-6 Host IP 7-10 Speed 11- Result Set x Extended QHD x Vendor-specific last 16 ServentID
  • 75.
    QUERYHIT 0x81 Messaggio QUERYHIT Dati Vendor-specific Bytes Descrizione Questi dati possono essere 0 Total Hits ignorati dagli applicativi che non 1-2 Host Port riescono a capirli. 3-6 Host IP 7-10 Speed 11- Result Set x Extended QHD x Vendor-specific last 16 ServentID
  • 76.
    QUERYHIT 0x81 Messaggio QUERYHIT Servent Identifier Bytes Descrizione Una stringa di 16 byte che 0 Total Hits identifica in modo univoco il 1-2 Host Port Servent rispondente sulla rete. 3-6 Host IP 7-10 Speed Nota 11- Result Set Questo deve essere costante per x Extended QHD ogni QueryHit inviata da un Servent. x Vendor-specific Di solito è creato in funzione last 16 ServentID dell’indirizzo di rete dell’host. Nota Il Servent Identifier è utilizzato principalmente per il routing dei messaggi PUSH (vedi sotto).
  • 77.
    QUERYHIT Result Set Result Set All’interno di ogni QUERYHIT abbiamo un insieme di elementi che corrispondono ai criteri ricercati dalle QUERY corrispondente.
  • 78.
    Result Set Item RESULT Set Item Bytes Descrizione 0-3 FileIndex 4-7 FileDimension 8- FileName x Extensions
  • 79.
    Result Set Item RESULT Set Item FileIndex Bytes Descrizione Un numero, assegnato dall’host 0-3 FileIndex rispondente, che viene utilizzato 4-7 FileDimension per identificare in modo univoco il 8- FileName file corrispondente ai criteri di x Extensions ricerca.
  • 80.
    Result Set Item RESULT Set Item FileDimension Bytes Descrizione La dimensione (in byte) del file il 0-3 FileIndex cui indice è FileIndex. 4-7 FileDimension 8- FileName x Extensions Nota Per file di grandi dimensioni la cui dimensione non può essere espressa con un intero senza segno a 32 bit, un blocco GGEP LF può essere utilizzato nel blocco estensioni.
  • 81.
    Result Set Item RESULT Set Item FileName Bytes Descrizione Il nome del file il cui indice è 0-3 FileIndex FileIndex. 4-7 FileDimension 8- FileName x Extensions Nota Terminato da un byte NULL (vale a dire 0x00).
  • 82.
    Result Set Item RESULT Set Item Extensions Bytes Descrizione Tipi di estensione ammessi sono 0-3 FileIndex HUGE, GGEP e metadati 4-7 FileDimension plaintext. Questo campo è 8- FileName terminato da un NULL (0x00). x Extensions Nota Inoltre, le estensioni di blocco stesso non deve contenere byte NULL. Se due o più di questi tipi di estensione coesistono, sono separati da un byte 0x1C (separatore di file). Dato che i blocchi GGEP possono contenere il byte 0x1C, il blocco GGEP, se presente, deve essere collocato dopo HUGE e dopo plaintext. Il tipo di ogni blocco può essere determinato cercando i prefissi urn: per un blocco HUGE, 0xC3 per GGEP e qualsiasi altra cosa per i metadati plaintext.
  • 83.
    Result Set Item RESULT Set Item Bytes Descrizione 0-3 FileIndex 4-7 FileDimension 8- FileName x Extensions Example I metadati plaintext sono destinati ad essere visualizzati direttamente all’utente. Un esempio di plaintext può essere quello usato nelle prime versioni di Gnutella per specificare la qualità di un file MP3: 192 kbps 44 kHz 3:23 120 kbps (VBR) 44kHz 3:55
  • 84.
    Extended QueryHit Descriptor Extended QHD Bytes Descrizione 0-3 Vendor-code 4 OpenData size x OpenData
  • 85.
    Extended QueryHit Descriptor Extended QHD Vendor-code Bytes Descrizione Quattro caratteri case-insensitive 0-3 Vendor-code che rappresentano un codice 4 OpenData size fornitore. x OpenData Example Ad esempio LIME di LimeWire. Nota Altri codici registrati possono essere trovati qui http://rfc-gnutella.sourceforge.net/developer/stable/ index.html#tA-1-3
  • 86.
    Extended QueryHit Descriptor Extended QHD OpenData size Bytes Descrizione Contiene la lunghezza (in byte) del 0-3 Vendor-code campo OpenData. 4 OpenData size x OpenData Nota Impostato a 2 nella maggior parte delle implementazioni attuali, e a 4 in quelle con il supporto di metadati XML esterno GGEP. L’area OpenData può essere più grande per permettere future estensioni.
  • 87.
    Extended QueryHit Descriptor Extended QHD Bytes Descrizione 0-3 Vendor-code 4 OpenData size x OpenData
  • 88.
    OpenData OpenData primo Byte OpenData secondo Byte Bit Descrizione Bit Descrizione 7,6 Riservati 7,6 Riservati 5 setGGEP 5 flagGGEP 4 setUploadSpeed 4 flagUploadSpeed 3 setHaveUploaded 3 flagHaveUploaded 2 setBusy 2 flagBusy 1 Riservato 1 Riservato 0 flagPush 0 setPush OpenData Il primo byte serve per abilitare le flag sel secondo. Solo i bit abilitati devono essere considerati. Logica invertita per quanto riguarda il setPush/flagPush.
  • 89.
    OpenData (cont.) Campi di OpenData flagGGEP indica che è presente un’estensione GGEP. flagUploadSpeed precisa la semantinca del campo Speed (velocità media o massimo upload definito dell’utente). flagHaveUploaded indica se il Servent ha effettuato almeno un upload. flagBusy è a 1 se tutti gli slot di upload occupati. flagPush significa che il Servent è firewalled. Nota Se i metadati XML sono inclusi nella corrente QueryHit, i seguenti 2 byte di OpenData conterranno la dimensione del blocco XML che è collocato nella zona successiva.
  • 90.
    PUSH 0x40 Messaggio PUSH Bytes Descrizione 0-15 ServentID 16-19 FileIndex 20-23 HostIp 24-25 HostPort 26- Opt. GGEP
  • 91.
    PUSH 0x40 Messaggio PUSH Servent Identifier Bytes Descrizione La stringa di 16 byte identifica in 0-15 ServentID modo univoco il Servent sulla rete 16-19 FileIndex a cui è stato chiesto di fare il push 20-23 HostIp di un file. Il Servent che invia la 24-25 HostPort richiesta di push deve impostare 26- Opt. GGEP questo campo con il ServentID della corrispondente QueryHit. Nota Questo è usato per instradare il messaggio Push fino al mittente del messaggio del QueryHit.
  • 92.
    PUSH 0x40 Messaggio PUSH FileIndex Bytes Descrizione L’indice del file che identifica in 0-15 ServentID modo univoco il file desiderato dal 16-19 FileIndex Servent mittente. Il Servent che 20-23 HostIp invia la richiesta di push deve 24-25 HostPort impostare questo campo con uno 26- Opt. GGEP dei FileIndex della corrispondente QueryHit. Nota Impostato a 2 nella maggior parte delle implementazioni attuali, e a 4 in quelle con il supporto di metadati XML esterno GGEP. L’area OpenData può essere più grande per permettere future estensioni.
  • 93.
    PUSH 0x40 Messaggio PUSH HostIp Bytes Descrizione L’indirizzo IP del host a cui il file 0-15 ServentID deve essere inviato. 16-19 FileIndex 20-23 HostIp 24-25 HostPort 26- Opt. GGEP Nota Questo campo è in formato big-endian.
  • 94.
    PUSH 0x40 Messaggio PUSH HostPort Bytes Descrizione il numero di porta a cui il file deve 0-15 ServentID essere mandato 16-19 FileIndex 20-23 HostIp 24-25 HostPort 26- Opt. GGEP
  • 95.
    Normal File Transfer Normal File Transfer Una volta che il servent riceve un QueryHit può iniziarre il download diretto del file descritto nel result set. I file non vengono scaricati attraverso la rete di Gnutella ma avviene una connessione diretta tra il richiedente e il possessore del file. Questa connessione diretta usa HTTP per trasferire i file. I vecchi servent utilizzano HTTP 1.0, i nuovi servent usano HTTP 1.1.
  • 96.
    Richiesta File Example (Richiesta) GET /get/<FileIndex>/<FileName> HTTP/1.1<cr><lf> User-Agent: Bearshare<cr><lf> Host: 123.123.123.123:6346<cr><lf> Connection: Keep-Alive<cr><lf> Range: bytes=0-<cr><lf> <cr><lf> Nota <FileIndex> e <FileName> sono la coppia indice del file e il nome del file di una entry del result set della QueryHit.
  • 97.
    Richiesta File (cont.) Example (Richiesta 2) GET /get/2468/Foobar.mp3 HTTP/1.1<cr><lf> User-Agent: Bearshare<cr><lf> Host: 123.123.123.123:6346<cr><lf> Connection: Keep-Alive<cr><lf> Range: bytes=0-<cr><lf> <cr><lf> Nota Per esempio se il result set di un QueryHit contiene questa entry: File Index: 2468 File Size: 4356789 File Name: Foobar.mp3
  • 98.
    Richiesta File (cont.) Richiesta File Il nome del file deve essere sempre encodato usando lo standard URL/URI encoding. La versione 0.4 di Gnutella non disponeva di supporto all’encoding perciò molti applicativi pur rispettando lo standard 0.6 fanno in modo di rispondere anche alle richieste 0.4. Se il servent non è in possesso di quel determinato file risponderà con un 404 Not Found. L’header Host, obbligatorio in HTTP, non è obbligatorio in Gnutella. L’header User-Agent identifica il tipo di applicativo.
  • 99.
    Caratteristiche del FileTransfer Example (Richiesta) GET /get/2468/Foobar.mp3 HTTP/1.1<cr><lf> User-Agent: Gnutella<cr><lf> Connection: Keep-Alive<cr><lf> Range: bytes=4932766-5066083<cr><lf> <cr><lf> Example (Risposta) HTTP/1.1 206 Partial Content<cr><lf> Server: Gnutella<cr><lf> Content-Type: audio/mpeg<cr><lf> Content-Length: 133318<cr><lf> Content-Range: bytes 4932766-5066083/5332732<cr><lf> <cr><lf> Nota Da notare Range e Connection (connessioni HTTP persistenti RFC 2616).
  • 100.
    Firewalled Servent Firewalled Se il possessore del file non può accettare connessioni in entrata? Il richiedente può inviare attraverso la rete Gnutella una richiesta push Il servent che riceve la richiesta push (identificato dal Servent ID contenuto nel messaggio PUSH) deve tentare di stabilire una nuova connessione TCP/IP con il server che ha inviato il PUSH (identificato da IP e porta nel messaggio PUSH). Se questa connessione non può essere stabilita (entrambi sono dietro un firewall) allora il trasferimento del file non può avere luogo.
  • 101.
    Firewalled Servent Firewalled Se la connessione tra l’host firewalled e l’host che invia la richiesta di PUSH viene stabilita il servent firewalled invia: Example GIV <FileIndex>:<ServentIdentifier>/<FileName><lf><lf> Nota Dove <FileIndex> e <ServentIdentifier> sono i valori dei campi FileIndex e ServentIdentifier della richiesta PUSH ricevuta, e <FileName> è il nome del file il cui FileIndex è <FileIndex>.
  • 102.
    Firewalled Servent Firewalled Il <ServentIdentifier> è formattato come esadecimale e può essere letto caseinsensitive. Example GIV 36:809BC12168A1852CFF5D7A785833F600/Foo.txt<lf><lf> GIV 4:d51dff817f895598ff0065537c09d503/Bar.htm<lf><lf> Nota Se la connessione TCP cade dopo il trasferimento di file è iniziato il servent che ha avviato la connessione dovrebbe tentare di riconnettersi.
  • 103.
    Busy Servent Servent Occupati I Servents la cui banda di upload è satura possono respingere una richiesta di download restituendo il codice 503. Un Servents può semplicemente avere un numero fisso di slot. Solitamente si usa un sistema che ottimizza la banda in upload al meglio. Servents occupati quando ricevono un push devono collegarsi al richiedente e restituire il codice 503 occupato. Si utilizza un sistema di coda. Se il trasferimento viene interrotto, l’uploader mantiene una parte di banda riservata.
  • 104.
    Condivisione I servent... Devono condividere i file con gli altri. Dovrebbero incoraggiare gli utenti a condividere i file. Dovrebbero evitare che comportamenti non distribuiti. Non Dovrebbero consentire lo scaricamento attraverso browser web. L’header HTTP User-Agent mostra quale programma remoto è in esecuzione. Nota Quando ci si connette ad un Servent attraverso web browser viene restituita una pagina html in cui è indicato come funziona Gnutella e cosa fare per ottenere un Servent.
  • 105.
    Condivisione I servent... Non devono dare la precedenza ad altri utenti che utilizzano lo steso applicativo. Devono rispondere messaggi di query e accettare richieste di download di file utilizzando le stesse regole per tutti servents. Possono bloccare chi non seguono le regole. Per default condividono la directory in cui sono collocati i file scaricati senza attandere il riavvio dell’applicativo. Dovrebbero evitare di cambiare i numeri di indice dei file condivisi dopo il riavvio.
  • 106.
    Condivisione File Incompleti I file incompleti non devono essere condivisi come se fossero completi. Un file parziale può essere condiviso solo se contrassegnato come incompleto. il trasferimento parziale usa Partial Sharing Protocol (header X-Available-Ranges).
  • 107.
    Messaggi binari sullaGnet Come evitare flooding? Di fondamentale importanza è il TTL (descritto precedentemente). Il valore TTL di una nuova Query creata da un Servent dovrebbe essere 7, non deve essere superiore a 10. L’Hops deve essere impostato a 0. Un Servent che riceve un messaggio con lo stesso Payload e GUID di un messaggio ricevuto in precedenza deve scartare il messaggio. Significa che il messaggio è già stato visto e che il messaggio è già passato attraverso quel host.
  • 108.
    Query sulla Gnet Come evitare flooding? Le query dovrebbero essere gestite attraverso il Dynamic Querying. Un Servent dovrebbe inoltrare i messaggi Query a tutti i suoi servents collegati direttamente ad eccezione di quello che ha emesso la query. I Servents utilizzando il Flow Control (vedremo poi) non sempre inoltrano ogni query su ogni connessione. Alla ricezione di una Query si controlla attraverso i Search Criteria i propri file locali.
  • 109.
    QueryHit sulla Gnet Come evitare flooding? Un Servent che riceve un messaggio con lo stesso Payload e GUID di un messaggio ricevuto in precedenza deve scartare il messaggio. Significa che il messaggio è già stato visto e che il messaggio è già passato attraverso quel host. I messaggi QueryHit devono essere inviati solo lungo lo stesso percorso (inverso) che portava il messaggio di Query. Questo garantisce che solo i servent inoltrano il messaggio di Query vedranno il messaggio QueryHit in risposta. Un Servent che riceve un messaggio QueryHit ma non ha mai ricevuto e inoltrato un messaggio di Query corrispondente dovrebbe rimuovere il messaggio.
  • 110.
    Ricerche dell’utente Come evitare flooding? I messaggio di Query vengono solitamente inviati quando l’utente avvia una ricerca. Un Servent può anche creare automaticamente le query e inviarle (per trovare nuove locazioni della stessa risorsa). Non deve sovraccaricare la rete (ci vogliono dei limiti). Impedire che l’utente generi troppo traffico Query attraverso click ripetuti su un pulsante. Se queste query sono troppo frequenti indicano un cattivo comportamento del servent. I servent dovrebbero eliminare queste query dalla rete o addirittura chiudere la connessione.
  • 111.
    Querying Criteria Codifica vecchi servent I criteri di ricerca sono testo e, storicamente, non è stato specificato il charset del testo. Pertanto servent vecchi assumono che sia solo puro ASCII. Tuttavia, molti servent sono stati sviluppati per permettere charset esteso. Ciò ha creato problemi di interoperabilità, in quanto diverse piattaforme usano un diverso set di caratteri nativo. Venne scelto di usare la codifica Western European (ISO8859-1) anche per i metadati nella QueryHit.
  • 112.
    Querying Criteria Codifica nuovi servent Per i nuovi sviluppi su Gnutella UTF-8 è altamente raccomandato. Quando la decodifica UTF-8 fallisce si usa ISO8859-1. Se fallisce anche ISO8859-1 si usa ASCII.
  • 113.
    Querying Criteria Speciali criteri di ricerca Formati da stringa di parole chiave. Un servent dovrebbe rispondere con i file che ha tutte le parole chiave. Il regolare US-ASCII space (U+0020) è il separatore di standard tra le parole chiave. Servents possono anche richiedere che tutti i termini corrispondenti essere presenti nello stesso numero e ordine nella query. L’abbinamento è essere case-insensitive. Servents possono ignorare le query i cui criteri di ricerca è inferiore ad una lunghezza scelta.
  • 114.
    Querying Criteria Interpretare i criteri di ricerca Le espressioni regolari non sono supportate. I meta-caratteri * o . possono essere al posto di qualsiasi cosa. Estensioni GGEP possono essere utilizzate per fornire dettagli su come analizzare i criteri di ricerca Un servent non può mai essere sicuro che gli altri interpretino correttamente l’estensione GGEP.
  • 115.
    Querying Criteria Browsing dello share I messaggi di query con TTL=1, Hops=0 e Search Criteria uguale a quattro spazi sono utilizzati per indicizzare tutti i file un host è la condivisione. I servents dovrebbero rispondere alle query browsing con tutti i file condivisi. Query multiple Hit messaggi devono essere utilizzati se condividono molti file. Non sempre i Servent rispondono con tutti i file condivisi (Privacy e Larghezza di banda).
  • 116.
    Querying Criteria Valori dei campi di QueryHit Stesso GUID del messaggio Query corrispondente. Il valore TTL deve essere almeno quanto l’Hops della Query corrispondente e il valore iniziale di hops deve essere 0. Alcuni servent mandano un TTL di 7 così sono sicuri che se la rete dovesse cambiare forma la risposta alla query arriverà.
  • 117.
    Download Mesh Valori dei campi di QueryHit Lo scopo del Download Mesh è di aiutare le persone a trovare più fonti per i file che stanno cercando Senza bisogno di richiedere nuovamente la rete. Queste fonti supplementari sono chiamati posizioni alternative, o Alt-Locs. Viene attuato con l’estensione HUGE.
  • 118.
    Download Mesh Come funziona Cercare di rendere ogni Servent conoscenza di tali servents che condividono lo stesso file sul GNet Tutto questo in modo decentrato. La soluzione per Gnet è stata scelta come un buon compromesso tra efficienza e basso consumo di banda. E’ efficace per aiutare la ricerca di fonti per i file conosciuti. L’obiettivo è quello di rendere migliore il download anche dei file rari. Le informazioni vengono inviate tra gli header HTTP e utilizzando l’estensione HUGE nelle QueryHit.
  • 119.
    HUGE Vecchieintestazioni La proposta HUGE utilizza due intestazioni: X-Gnutella-Content-URN indica l’URN associato a un file. X-Gnutella-Alternate-Location per indicare posizioni alternative per quel file. Example X-Gnutella-Alternate-Location: http://1.2.3.4:6546/uri-res/N2R? urn:sha1:OJUNVQ75FQMZ5RXR3LJUDIQSGSVC5RFE 2002-12-27T12:35:51Z, http://1.2.3.5:6461/uri-res/N2R? urn:sha1:OJUNVQ75FQMZ5RXR3LJUDIQSGSVC5RFE 2002-12-27T11:38:51Z X-Gnutella-Content-URN: urn:sha1:OJUNVQ75FQMZ5RXR3LJUDIQSGSVC5RFE
  • 120.
    HUGE Nuoveintestazioni Intestazioni così lunghe causano inefficienza. Il nuovo HUGE utilizza altre intestazioni: X-Alt header rimpiazza X-Gnutella-Alternate-Location. X-NAlt è stato aggiunto per indicare locazioni sbagliate (scadute, false o maliziose). E sopratutto un nuovo formato per indicare le Alt-Locs. Example X-Alt: 1.2.3.4:6347,1.2.3.5 X-NAlt: 1.2.3.4:6346, 1.2.3.5:6341
  • 121.
    HUGE X-NAlt X-NAlt serve quando una Alt-Loc è scaduta: In caso di 404. Se il socket non può connettersi con l’host Non quando dà errore 503 (Busy).
  • 122.
    HUGE Funzionamento Il Downloader deve informare l’Uploader su locazioni alternative che conosce per questo file, e da cui ha scaricato correttamente. Il Downloader non deve informare l’Uploader su posizioni alternative da cui non ha ancora effettivamente scaricato. In questo modo l’Uploader viene a conoscenza delle Alt-Locs.
  • 123.
    HUGE Example Funzionamento Il downloader dispone di 10 locazioni. Prova otto di essi. I primi cinque funzionano e gli ultimi tre non funzionano. Tutti i primi cinque Uploader devono essere inviati come X-Alt. I tre non funzionanti devono essere inviati con X-NAlt. Tutti gli uploader vanno informati. Non viene detto niente sui due non testati. Nota Se ci sono molte Alt-Locs disponibili viene inviato un massimo di 10.
  • 124.
    HUGE Funzionamento L’Uploader può inviare solo le X-Alt (non le X-NAlt). L’invio avvine durante le richieste HTTP (grazie alle connessioni persistenti ci sono più richieste in una connessione). Oppure inviando un HEAD successivo.
  • 125.
    HUGE Funzionamento L’Uploader non ha modo di verificare la bontà di una Alt-Loc. Solo il Downloader testa le locazioni. Alt-Locs possono essere ottenute grazie alle QueryHits quando il valore hash di HUGE è incluso. In questo le nuove Alt-Locs saranno aggiunte (dopo la verifica) alla Download Mesh di quel file. Esiste un’altra estensione (ALT GGEP) che fa lo stesso lavoro di HUGE ma che non vedremo.
  • 126.
    Download Mesh diqualità Buone Regole Il Downloader testa gli Alt-Locs prima di inviarli. Il Downloader deve presentare tutte le Alt-Locs (buone e cattive) con gli opportuni header. L’Uploaders deve rimuovere le Alt-Locs presentate con X-NAlt (con tolleranza). Evitare informazioni eccessive: è inutile inviare due volte la stessa Alt-Loc.
  • 127.
    Estensione HUGE HUGE come estensione HUGE è incapsulato spesso nel GGEP delle QueryHit. E’ possibile trovarlo anche non incapsulato in GGEP. Nota Altre informazioni su HUGE possono essere trovate qui: http://rfc-gnutella.sourceforge.net/src/ draft-gdf-huge-0_94.txt
  • 128.
    Introduzione Problema Gnutella è una rete decentralizzata Quando un client vuole connettersi deve collegarsi con un host già presente nella rete. Ma se il client non conosce gli altri host... ...Come fa a connettersi alla rete? Alcuni metodi: Local Hostcache GWebCache (in seguito)
  • 129.
    Local Hostcache A cosa serve? Permette di connettersi alla rete Gnutella in tempi brevi. Limitare le connessioni a GWebCache per sessione Cosa contiene? Ogni servent memorizza una lista di host prelevati da: X-Try e X-Try-Ultrapeer GWebCache Pong Reply QueryHit
  • 130.
    Local Hostcache Come funziona? All’avvio il servent carica in RAM solo host in cache che hanno un legame forte con la rete. Questo filtro viene fatto in base ai seguenti criteri Uptime dell’host Numero di file e KB in condivisione Ultima volta che l’host è stato visto nella rete Se una connessione è stata instaurata con l’host L’uptime dell’ultima connessione instaurata con l’host Infine proverà a collegarsi con ognuno di questi host finchè non riuscirà ad instaurare una connessione
  • 131.
    Introduzione PING/PONG Una volta connessi? Si cercano altri host a cui connettersi attraverso PING I messaggi di PING/PONG hanno infatti due funzioni: Ottenere informazioni su un servent nella rete Stimare le dimensioni della rete stessa i.e. Numero dei file I servent Gnutella devono asserire ai seguenti punti Quando riceve un PING, risponde con una serie di PONG Ogni PONG contiene informazione su chi l’ha generato I PONG inviati devono essere di buona qualità I messaggi di PING/PONG non devono saturare la banda
  • 132.
    Schema PING/PONG Come funziona? Un client manda un PING a tutti i suoi vicini (in blu) Il servent che lo riceve Decrementa il TTL Se TTL=0, droppa il pacchetto Altrimenti lo propaga ai suoi vicini Restituisce un PONG con le sue informazioni. (in rosso) Farà da router per i PONG di risposta ai PING che ha propagato ai vicini
  • 133.
    Schema PING/PONG Come funziona? Un client manda un PING a tutti i suoi vicini (in blu) Il servent che lo riceve Decrementa il TTL Se TTL=0, droppa il pacchetto Altrimenti lo propaga ai suoi vicini Restituisce un PONG con le sue informazioni. (in rosso) Farà da router per i PONG di risposta ai PING che ha propagato ai vicini
  • 134.
    Schema PING/PONG Come funziona? Un client manda un PING a tutti i suoi vicini (in blu) Il servent che lo riceve Decrementa il TTL Se TTL=0, droppa il pacchetto Altrimenti lo propaga ai suoi vicini Restituisce un PONG con le sue informazioni. (in rosso) Farà da router per i PONG di risposta ai PING che ha propagato ai vicini
  • 135.
    Schema PING/PONG Come funziona? Un client manda un PING a tutti i suoi vicini (in blu) Il servent che lo riceve Decrementa il TTL Se TTL=0, droppa il pacchetto Altrimenti lo propaga ai suoi vicini Restituisce un PONG con le sue informazioni. (in rosso) Farà da router per i PONG di risposta ai PING che ha propagato ai vicini
  • 136.
    Schema PING/PONG Come funziona? Un client manda un PING a tutti i suoi vicini (in blu) Il servent che lo riceve Decrementa il TTL Se TTL=0, droppa il pacchetto Altrimenti lo propaga ai suoi vicini Restituisce un PONG con le sue informazioni. (in rosso) Farà da router per i PONG di risposta ai PING che ha propagato ai vicini
  • 137.
    Schema PING/PONG Come funziona? Un client manda un PING a tutti i suoi vicini (in blu) Il servent che lo riceve Decrementa il TTL Se TTL=0, droppa il pacchetto Altrimenti lo propaga ai suoi vicini Restituisce un PONG con le sue informazioni. (in rosso) Farà da router per i PONG di risposta ai PING che ha propagato ai vicini
  • 138.
    Schema PING/PONG Problema Nell’esempio sono stati scambiati 8 PING e 18 PONG Se la rete assume grandi dimensioni, il solo utilizzo di PING/PONG può saturare la banda. Il problema è dovuto principalmente al protocollo stesso che propaga i messaggi tramite broadcast Per limitare il problema si utilizza un altro approccio PONG Caching Nota: solo gli Ultrapeer hanno bisogno di implementarlo
  • 139.
    Implementazione Specifiche Viene memorizzato un array di PONG Ogni indice corrisponde ad una diversa connessione Quando viene ricevuto un PONG, lo si inserisce nello slot corrispondente, eventualmente sovrascrivendo il messaggio precedente Ogni PONG contiene le seguenti informazioni Indirizzo IP Numero Porta Numero di file in condivisione Numero di KB in condivisione Payload GGEP (se presente) Numero di Hop
  • 140.
    Implementazione Come funziona? Il servent riceve il PING P Cerca nella sua PONG Cache.. ..E restituisce al client il suo ed una serie di altri PONG i.e. con differente numero di Hop I campi di ogni PONG S inviato vengono modificati come segue MessageID = P->MessageID Hops = S->Hops + 1 TTL t.c. Hops + TTL = 7
  • 141.
    Implementazione Come si aggiorna la cache? Si invia un PING (TTL=7, Hop=0), circa ogni 3 secondi, a tutti i vicini Può sembrare dispendioso ma... I nodi foglia restituiranno soltanto il loro PONG Gli Ultrapeer risponderanno con la loro PONG Cache Per i vicini che non supportano il PONG Caching si invia un PING circa ogni minuto. La informazioni di un vicino possono essere recuperate da subito Con un PING sonda (TTL=1, Hop=0) una volta connesso Con le informazioni scambiate durante l’handshake
  • 142.
    Considerazioni In conclusione... Questo schema riduce sensibilmente il consumo di banda Supponiamo di inviare un PING ogni 3 secondi e ottenere 10 PONG, ricordando che: Un PING, senza estensioni, ha dimensioni 23 byte Un PONG, senza estensioni, ha dimensioni 37 byte La banda totale utilizzata è (23 + (10 * 37)) / 3 = 131 B/s per connessione Anche con estensioni, la banda dovrebbe rimane su un livello accettabile Se così non fosse, basterebbe aumentare l’intervallo di tempo tra i PING
  • 143.
    Introduzione Il protocollo TCP Il broadcasting viene fatto per tutti i tipi di messaggio Inoltre i servent possono sia ricevere, sia inviare Come abbiamo visto per i PING, può intasare l’intera rete Tuttavia, il broadcast non è l’unico problema di Gnutella GNET, infatti, si appoggia quasi interamente sul protocollo TCP Poichè TCP è affidabile, possono manifestarsi anche dei problemi di latenza i.e. pacchetti che si perdono, si rinviano...
  • 144.
    Introduzione Cosa fare? Quando sorgono problemi di latenza, un servent Gnutella può: Droppare la connessione Droppare i messaggi Utilizzare un buffer per i messaggi, in modo da inviarli in un secondo momento Nessuna di queste azioni offre la soluzione migliore Rimangono, infatti, dei problemi in ognuno dei tre casi
  • 145.
    Introduzione Problema Droppare la connessione Provoca il continuo disconnettersi e riconnettersi del client Molti messaggi vengono persi i.e. Il servent risponde ad un client non più connesso Droppare il messaggio Vanifica il lavoro fatto per ottenere una risposta Il risultato è un utilizzo inutile della banda Utilizzare un buffer per i messaggi Può aumentare ulteriormente la latenza I servent possono andare in buffer overflow, bloccandosi Il problema inoltre non è risolvibile, se non alla base i.e. trasmettere su più banda di quanto non sia già possibile
  • 146.
    Introduzione Cosa succede? La rete Gnutella può ritrovarsi in stato di Meltdown I servent si sovraccaricano, non potendo rispondere Le richieste non vengono prese più in considerazione Alcune stime: I servent funzionanti possono diminuire del 90% La latenza può aumentare fino al minuto e mezzo Serve quindi un sistema per regolare il flusso di dati
  • 147.
    Implementazione Cosa fare? Implementare una coda di output con politica FIFO Le dimensioni della coda devono essere almeno il 150% delle massime dimensioni di un messaggio Stabilire un valore di soglia per la coda (i.e. 25%) Quando la coda viene riempita oltre il limite soglia Si entra in modalità FC (Flow Control) Si resta in FC finchè non si ritorna al di sotto della soglia In modalità FC, le Query ricevute vengono droppate Evita di intasare connessioni già in difficoltà
  • 148.
    Implementazione Caratteristiche I messaggi nella coda devono rispettare certe priorità Per quelli broadcast, più alto è il valore di Hop, più bassa sarà la priorità I messaggi del servent stesso sono i più importanti Per quelli singoli, più alto è il valore di Hop, più alta sarà la priorità Massimizza l’utilizzo e il consumo della banda La priorità per tipo di messaggio è definita in ordine decrescente come segue: Push, QueryHit, PONG, Query, PING
  • 149.
    Implementazione Caratteristiche Di norma, tutti i messaggi vengono inseriti in coda Quando però un messaggio riempirebbe la coda oltre il 100% delle sue dimensioni Ogni messaggio in coda con priorità minore viene droppato Se lo spazio è ora sufficiente, viene inserito in coda Altrimenti, se è un PING, PONG o Query, viene droppato Negli altri casi si restituisce un messaggio di tipo BYE i.e. BYE 502 (Send Queue Overflow)
  • 150.
    SACHRIFC Cos’è? Algoritmo per il controllo di flusso usato in diversi client Gnutella (i.e. LimeWire, Bearshare) Sviluppato per i seguenti scopi: Evitare di droppare messaggi Minimizzare la latenza Preferire i messaggi nel seguente ordine: Push, QueryHit, Query, PONG, PING Evitare che un tipo di messaggio possa dominare il traffico Favorire QueryHit meno popolari da quelle più popolari
  • 151.
    SACHRIFC Implementazione Utilizza un buffer per ogni connessione Ciascun buffer è suddiviso a sua volta in 5 code separate (una per ogni tipo di messaggio) Le QueryHit sono ordinate in modo crescente secondo il Volume GUID (risposte generate da quel GUID) Le altre sono ordinate in modo decrescente per il timestamp Per inserire un messaggio M di tipo T in un buffer B if (B(T).isFull()) B(T).removeTail(); B(T).insertHead(M);
  • 152.
    SACHRIFC Implementazione I messaggi nei buffer vengono scelti ed inviati con una politica simile al Round Robin foreach(Qi in B) { for (j = 0; j < min(|Qi|, Ni); j++) { M = Qi.head(); if (M.isOld()) M.drop(); else M.send(); } } Ni è un valore associato ad ogni tipo di messaggio per indicare la quantità di messaggi da inviare ad ogni ciclo
  • 153.
    SACHRIFC Example foreach(Qi in B) { for (j = 0; j < min(|Qi|, Ni); j++) { M = Qi.head(); if (M.isOld()) M.drop(); else M.send(); } }
  • 154.
    SACHRIFC Example foreach(Qi in B) { for (j = 0; j < min(|Qi|, Ni); j++) { M = Qi.head(); if (M.isOld()) M.drop(); else M.send(); } }
  • 155.
    SACHRIFC Example foreach(Qi in B) { for (j = 0; j < min(|Qi|, Ni); j++) { M = Qi.head(); if (M.isOld()) M.drop(); else M.send(); } }
  • 156.
    SACHRIFC Example foreach(Qi in B) { for (j = 0; j < min(|Qi|, Ni); j++) { M = Qi.head(); if (M.isOld()) M.drop(); else M.send(); } }
  • 157.
    SACHRIFC Example foreach(Qi in B) { for (j = 0; j < min(|Qi|, Ni); j++) { M = Qi.head(); if (M.isOld()) M.drop(); else M.send(); } }
  • 158.
    SACHRIFC Example foreach(Qi in B) { for (j = 0; j < min(|Qi|, Ni); j++) { M = Qi.head(); if (M.isOld()) M.drop(); else M.send(); } }
  • 159.
    SACHRIFC Example foreach(Qi in B) { for (j = 0; j < min(|Qi|, Ni); j++) { M = Qi.head(); if (M.isOld()) M.drop(); else M.send(); } }
  • 160.
    SACHRIFC Example foreach(Qi in B) { for (j = 0; j < min(|Qi|, Ni); j++) { M = Qi.head(); if (M.isOld()) M.drop(); else M.send(); } }
  • 161.
    SACHRIFC Example foreach(Qi in B) { for (j = 0; j < min(|Qi|, Ni); j++) { M = Qi.head(); if (M.isOld()) M.drop(); else M.send(); } }
  • 162.
    SACHRIFC Example foreach(Qi in B) { for (j = 0; j < min(|Qi|, Ni); j++) { M = Qi.head(); if (M.isOld()) M.drop(); else M.send(); } }
  • 163.
    SACHRIFC Example foreach(Qi in B) { for (j = 0; j < min(|Qi|, Ni); j++) { M = Qi.head(); if (M.isOld()) M.drop(); else M.send(); } }
  • 164.
    SACHRIFC Example foreach(Qi in B) { for (j = 0; j < min(|Qi|, Ni); j++) { M = Qi.head(); if (M.isOld()) M.drop(); else M.send(); } }
  • 165.
    SACHRIFC Ingenerale. . . Il fattore N serve quindi per dare un’ulteriore priorità ai tipi di messaggio Modificando il rapporto tra i vari Ni si può aggiustare il caso peggiore I Push sono quelli a priorità più alta, ma sono i più rari I PING/PONG sono più comuni, ma a priorità più bassa Con un fattore N adeguato, si può evitare l’overflow dei buffer Inoltre le code vengono svuotate attraverso una politica di tipo LIFO I messaggi vengono inseriti e prelevati dalla testa
  • 166.
    SACHRIFC PerchèLIFO? Consideriamo un flusso di Query che viene letto ad 1 Kb/s da C1 C1 inoltrerà i messaggi alla connessione C2 che ha capacità 1 Kb/s Inizialmente nessun messaggio verrà droppato Successivamente C1 riceve un blocco di 10 Kb Con FIFO, per inviarlo a C2, C1 impiegherà 10 secondi Nel frattempo C1 continuerà a leggere blocchi da 1 Kb che metterà in coda La latenza tra C1 e C2 è ora 10 secondi per tutti i pacchetti rimanenti
  • 167.
    SACHRIFC PerchèLIFO? (Cont.) Consideriamo lo stesso esempio utilizzando una politica LIFO Inizialmente nessun messaggio verrà droppato Successivamente C1 riceve un blocco di 10 Kb Con LIFO, C1 metterà in coda il blocco Nel frattempo C1 continuerà a leggere blocchi da 1 Kb Questi blocchi verranno subito inviati a C2 senza aumentare la latenza Il blocco in coda verrà inviato solo in seguito Potrebbe essere anche droppato perchè troppo vecchio
  • 168.
    Introduzione Il Routing.. I servent hanno anche il compito di instradare le risposte nella rete I messaggi da gestire sono i Push, le QueryHit e i PONG I PONG sono già gestiti dal PONG Caching Per i due messaggi rimanenti è necessario invece implementare una tabella di Routing L’idea di base è: Memorizzare il GUID dei messaggi di richiesta (i.e. Query) Aspettare la risposta (i.e. QueryHit) Instradare la risposta al servent che aveva inviato la richiesta
  • 169.
    Introduzione Problema Per quanto tempo mantenere in memoria i GUID? Un servent non può memorizzare tutta la cronologia dei messaggi ricevuti perchè sono milioni i messaggi per cui viene fatto il routing ogni giorno Alcune soluzioni: Memorizzare una certa quantità di messaggi Non è scalabile Memorizzare i messaggi per un certo lasso di tempo Calcolare per quanto tempo memorizzarli è complesso Bisogna tenere conto dei limiti di TCP e del Flow Control Grosso modo, ogni messaggio dev’essere memorizzato per almeno 10 minuti
  • 170.
    Query Routing Implementazione Utilizzare una tabella associativa, con chiave GUID e con valore la connessione Ogniqualvolta viene ricevuta una Query, si inserisce nella tabella l’associazione GUID => Connessione Se la Query è stata inviata dal servent stesso, viene usato un carattere speciale per indicare il valore della connessione (i.e. NULL)
  • 171.
    Query Routing Implementazione Quando viene ricevuta una QueryHit ci sono 3 casi: 1 C’è una connessione associata al GUID nella tabella Il messaggio viene instradato a quella connessione 2 C’è un valore NULL associato al GUID nella tabella Il messaggio è una risposta alla Query del servent 3 Non esiste il GUID nella tabella Il messaggio è stato erroneamente inviato al servent e verrà droppato Il GUID è scaduto, ed è stato rimosso dalla tabella prima di ricevere il messaggio
  • 172.
    Push Routing Caratteristiche I Push sono i messaggi più importanti Permettono il download da servent firewalled Sono in minoranza rispetto alla QueryHit La tabella di Routing sarà più piccola Ogni entry nella tabella di Routing verrà memorizzato per almeno 30 minuti Esistono due possibili implementazioni: 1 Standard Push Routing 2 Broadcasting Push Routing
  • 173.
    Standard Push Routing Implementazione Anzichè il GUID del messaggio, viene memorizzato il GUID del servent E’ incluso in entrambi gli header di QueryHit e Push Per evitare incomprensioni, lo chiameremo SUID Ogniqualvolta viene ricevuta una QueryHit, si inserisce nella tabella l’associazione SUID => Connessione Per conoscere se il Push è una richiesta del servent stesso si controlla che il SUID del Push corrisponda al SUID del servent Evita di memorizzare dati di QueryHit create dal servent
  • 174.
    Standard Push Routing Implementazione Quando viene ricevuto un Push ci sono 2 casi: 1 C’è una connessione associata al SUID nella tabella Il messaggio viene instradato a quella connessione 2 Non esiste il SUID nella tabella Il messaggio è stato erroneamente inviato al servent e verrà droppato Il SUID è scaduto, ed è stato rimosso dalla tabella prima di ricevere il messaggio
  • 175.
    Broadcasting Push Routing Implementazione Molto simile al precedente Ogni connessione memorizza, in una lista, i SUID delle QueryHit a loro corrispondenti Quando il servent riceve un Push, controlla la lista di ciascuna connessione. Ci sono 2 casi: 1 Se esiste il SUID nella lista Il messaggio viene instradato a quella connessione 2 Se non esiste il SUID nella lista Il messaggio è stato erroneamente inviato al servent e verrà droppato Il SUID è scaduto, ed è stato rimosso dalla lista prima di ricevere il messaggio
  • 176.
    Introduzione Problema Bisogna evitare di inviare messaggi già trasmessi nella rete Ogni servent GNET implementa un sistema di controllo sui messaggi duplicati Il sistema prevede la memorizzazione temporenea dei messaggi anzichè l’uso di una struttura dati a dimensione fissa Ogni messaggio viene memorizzato per almeno 10 minuti L’idea è la stessa ma l’implementazione varia in base al tipo di messaggio
  • 177.
    PING Duplicati Caratteristiche Ogni servent memorizza il GUID dei PING Quando si riceve un PING, si controlla la PING Duplicates Tables Se il GUID è gia presente, il messaggio viene droppato Altrimenti, si accetta il PING e ne viene memorizzato il GUID PING duplicati sono molto rari, soprattutto se il PONG Caching è implementato.
  • 178.
    PONG Duplicati Caratteristiche La PONG Duplicates Table viene mantenuta per retro-compatibilità A differenza dei PING, il solo GUID non è sufficiente Il GUID di tutti i PONG in risposta ad un PING è lo stesso Si memorizza quindi una stringa formata dalla concatenazione di GUID + IP + Port Il procedimento di controllo è lo stesso del PING PONG duplicati sono molto rari.
  • 179.
    Query Duplicate Caratteristiche Come per i PING, si può memorizzare il GUID, e applicare lo stesso procedimento di controllo Il servent gestisce già il routing delle QueryHit, quindi il GUID delle Query è gia memorizzato Tuttavia, si predilige implementare una tabella a parte solamente per le Query Query duplicate sono molto frequenti Sono causate principalmente dai cammini ciclici della rete
  • 180.
    QueryHit Duplicate Caratteristiche Sono il tipo di messaggio più complicato da gestire Due QueryHit sono equivalenti se hanno ugual MessageID e Payload Per trovare un identificatore univoco si può agire così: Si concatenano il MessageID, GUID del servent e l’hash del Payload Risultato: MessageID + GUID + Hash(Payload) QueryHit duplicate sono molto frequenti Nota: Non basta utilizzare MessageID + GUID poichè il servent può decidere di spezzare una grossa QueryHit in tante più piccole QueryHit
  • 181.
    Push Duplicati Caratteristiche Come per i PING, si può memorizzare il GUID, e applicare lo stesso procedimento di controllo Il servent gestisce già il routing dei Push, ma per farlo memorizza il MessageID Quindi, a differenza delle Query, è necessario implementare forzatamente una tabella apposita Push duplicati non sono molto frequenti Sono solitamente ben gestiti dal loro routing
  • 182.
    BYE Duplicati Caratteristiche I BYE sono messaggi speciali, non previsti dall’originale protocollo Quando si riceve un BYE, bisogna disconnettersi da quel servent Risulta quindi inutile un controllo dei duplicati
  • 183.
    Introduzione Che cos’è? Il QRP è una features essenziale degli UltraPeer Governa il routing delle Query verso i nodi foglia che hanno più probabilità di restituire una QueryHit Questo viene fatto cercando le keywords della Query all’interno di una grande tabella hash, la Query Routing Table (QRT) Gli Ultrapeer ricevono le QRT dai nodi foglia Gli Ultrapeer possono scambiarsi le QRT tra loro
  • 184.
    Introduzione Problema Supponiamo di essere un Ultrapeer Se riceviamo una Query, la invieremo alle nostre foglie Se la foglia condivide un file che coincide con la ricerca, produce una QueryHit Ma per le foglie che non condividono nulla? Non produrranno mai QueryHit Risulta inutile inviarle la Query Si spreca solo banda
  • 185.
    Introduzione Problema Supponiamo di essere un Ultrapeer Se riceviamo una Query, la invieremo alle nostre foglie Se la foglia condivide un file che coincide con la ricerca, produce una QueryHit Ma per le foglie che non condividono nulla? Non produrranno mai QueryHit Risulta inutile inviarle la Query Si spreca solo banda
  • 186.
    Introduzione Problema Supponiamo di essere un Ultrapeer Se riceviamo una Query, la invieremo alle nostre foglie Se la foglia condivide un file che coincide con la ricerca, produce una QueryHit Ma per le foglie che non condividono nulla? Non produrranno mai QueryHit Risulta inutile inviarle la Query Si spreca solo banda
  • 187.
    Introduzione Problema Supponiamo di essere un Ultrapeer Se riceviamo una Query, la invieremo alle nostre foglie Se la foglia condivide un file che coincide con la ricerca, produce una QueryHit Ma per le foglie che non condividono nulla? Non produrranno mai QueryHit Risulta inutile inviarle la Query Si spreca solo banda
  • 188.
    Introduzione Problema Supponiamo di essere un Ultrapeer Se riceviamo una Query, la invieremo alle nostre foglie Se la foglia condivide un file che coincide con la ricerca, produce una QueryHit Ma per le foglie che non condividono nulla? Non produrranno mai QueryHit Risulta inutile inviarle la Query Si spreca solo banda
  • 189.
    Query Routing Table Che cos’è? Una QRT è un array solitamente di 65536 bit Una Keywords è associata ad un bit della tabella tramite un’apposita funzione hash Se il bit vale 1, la ricerca può dare risultato Se il bit vale 0, la ricerca viene bloccata E’ possibile che ad un bit corrispondano più Keywords L’obiettivo di QRP è instradare Query alle foglie solo se c’è anche una minima probabilità di ricevere una QueryHit Foglie che non condividono file hanno tutti i bit a 0 L’Ultrapeer non gli invierà nessuna Query
  • 190.
    Query Routing Table Come funziona? Supponiamo che la foglia condivida il file Gnutella.txt Codifica il nome del file in un numero con un’apposita funzione hash Cerca il bit corrispondente nella QRT e cambia il valore del bit da 0 a 1 Nota: Non viene effettuato l’hash dei dati del file, ma solo del suo nome Alcuni client lo fanno anche per il percorso dei file
  • 191.
    Introduzione Perchè si usa? Come più volte ripetuto Gnutella utilizza tecniche broadcast Ogni Ultrapeer può inoltre connettersi ad altri 32 Ultrapeer Se viene inviata una Query con TTL = 3 Al 1◦ hop genererà 32 messaggi Al 2◦ hop genererà 322 messaggi = 1024 Al 3◦ hop genererà 10242 messaggi = 97% della rete Se QRP è implementato, il 3◦ hop verrà risparmiato Grande risparmio di banda Minimizza la latenza
  • 192.
    Implementazione Nelle Foglie... 1 Dividere il nome di tutte le risorse condivise in parole Ogni parola dev’essere formata da lettere e/o numeri 2 Codificare ciascuna parola e porre il corrispondente bit della QRT a 1 3 Ripetere il 3◦ passaggio rimuovendo le ultime 1, 2, 3 lettere da ciascuna parola Utile per rimuovere la pluralità nelle parole 4 Comprimere eventualmente la QRT 5 Inviare la QRT agli Ultrapeer
  • 193.
    Implementazione Negli Ultrapeer... 1 Instradare le Query alle foglie che non hanno ancora inviato la QRT 2 Se la QRT è stata ricevuta, le Query verranno filtrate per quel nodo Le Keywords della Query vengono divise in parole Le parole vengono trasformate in lower-case e codificate in ASCII Ogni parola viene codificata con la funzione hash Si controlla il bit corrispondente ad ogni parola nella QRT Se si verifica Query Matching, viene dichiarata una Query Routing Hit La Query viene propagata ai corrispettivi nodi foglia Altrimenti la Query viene droppata
  • 194.
    X-Query-Routing Come si scambiano le QRT? Gli Ultrapeer che implementano il QRP inseriscono negli header dell’handshake X-Query-Routing: 0.1 Le foglie che riconoscono il protocollo potranno inviare la loro QRT Le QRT possono essere scambiate anche tra gli Ultrapeer Negli header viene inserito X-Ultrapeer-Query-Routing: 0.1 Il protocollo di scambio prevede due messaggi Reset Message Patch Message
  • 195.
    Reset Message Descrizione I Reset definiscono i parametri della QRT Specificano le dimensioni della tabella Il messaggio imposterà inizialmente tutti i bit a 0 Verranno modificati solo tramite successive Patch
  • 196.
    Patch Message Descrizione Contiene informazioni sul come dovranno cambiare i bit della QRT Il pacchetto contiene inizialmente un array di 655356 byte Ogni byte corrisponde ad un bit nella QRT L’idea alla base è: Se il byte vale 0, il bit non verrà modificato Se il byte è negativo, il bit verrà impostato a 1 Altrimenti, se positivo, il bit verrà impostato a 0 L’header del pacchetto contiene due campi Il numero di serie del pacchetto (parte da 1) Il numero totale dei pacchetti
  • 197.
    Patch Message 64Kb sono tanti.. Dalle specifiche si può notare che sono necessari almeno 2 bit per descrivere ogni bit Molti client comprimono ciascun byte in 2-4 bit Le dimensioni totali passano da 64 Kb a 32-16 Kb Inoltre è possibile scomporre il pacchetto in più sottopacchetti Solitamente in blocchi da 4 Kb
  • 198.
    X-Query-Routing Come funziona? Dopo aver instaurato la connessione, la foglia invia un Reset Successivamente invia le informazioni della sua QRT attraverso una serie di messaggi Patch Per continuare a sincronizzare la tabella, basterà inviare ulteriori messaggi Patch Example Client: Reset Message Server: OK Client: Patch Message 1 of 2 Client: Patch Message 2 of 2 Server: OK Dopo alcuni minuti... Client: Patch Message 1 of 3 ...
  • 199.
    QRP Hashing Introduzione Ogni QueryString è formata da una o più Keywords separate da spazio Per mappare una keyword K in uno slot della tabella QRP di dimensione M, è necessaria una funzione hash H(K,M) che deve soddisfare queste proprietà: 1 Generare hash di keywords a lunghezza arbitraria uniformemente OK! 2 Facilmente implementabile su più piattaforme OK! 3 Possibilità di convertire la keywords tra hash tables di diverse dimensioni ??? i.e. Dato H(K,M), ma non K, dev’essere possibile calcolare H(K,M’) per un qualsiasi M’ Permette l’interoperatività tra client con diverse tabelle QRP
  • 200.
    QRP Hashing Come fare? Convertire la keyword di lunghezza K in un numero naturale N a 32 bit Si divide la keyword in gruppi di 4 byte Eventualmente si aggiunge un padding Si esegue lo XOR concatenato i.e. 01011001001 = 1001 XOR 1100 XOR 0110 XOR 0001 = 0010 = N Mappare il numero N tra 0 e M-1 H(N,M) = floor(M * ((N*A) - floor(N*A))) A è un particolare valore utilizzato per evitare collisioni per un’ampia gamma di dati.
  • 201.
    QRP Hashing Problema Il risultato della funzione hash può però risultare diverso per via dei diversi difetti di arrotondamento su macchina con architetture differenti Tuttavia, si può restringere il campo M ad una potenza di 2 La funzione può essere calcolata con operazioni di shift binario Si moltiplica il numero N per una costante a 32bit i.e. 0x4F1BBCDC L’hash risultante sono i (32 - log2(M)) bit meno significativi
  • 202.
    The Webcache System Introduzione l’obbiettivo di WebCache è quello di eliminare il problema del bootstrap in una rete completamente decentralizzata una cache è un programma residente su un qualsiasi web- server che memorizza gli indirizzi ip dei peer di una rete Gnutella e gli url di altre cache si noti come questo concetto di webcache risulti indipendente dalla rete Gnutella in sè e può essere applicato a qualsiasi sistema decentralizzato
  • 203.
    The Webcache System Client Interface L’interfaccia client specifica come i client che vogliono utilizzare una webcache devono interagire con la controparte server; es- istono vari tipi di richieste, specifiche per ogni operazione che si vuole effettuare
  • 204.
    Hostfile Request Example http://www.hostname.com/gwc.php?hostfile=1 Specifica il client desidera ricevere una lista di peer appartenenti alla rete la cache invia una lista i cui membri sono separati da un <lf> nella forma ip:porta questa lista non deve essere molto grande, 20 nodi al massimo e deve contenere solo le ultime entry
  • 205.
    Urlfile Request Example http://www.hostname.com/gwc.php?urlfile=1 Specifica il client desidera ricevere una lista di url di altre cache la cache invia una lista in cui gli url sono separati da un <lf> questa lista non deve essere molto grande, 20 url al massimo e deve contenere solo le ultime entry
  • 206.
    Update Request Example (Aggiornamento di un host) http://www.hostname.com/gwc.php?ip=abc.def.ghi.jkl:port Example (Aggiornamento di una cache) http://www.hostname.com/gwc.php?url=http://blah Specifica il client desidera aggiornare delle informazioni contenute nella cache l’url per l’aggiornamento di una cache deve essere il path completo per il programma (url-encoded se necessario) è possibile inviare anche i due aggiornamenti in un’unica query
  • 207.
    Update Request (cont.) Definition (Risposte della WebCache) ^(?:OK|ERROR(?::s.+)?)$ Specifica si noti come il messaggio di errore sia del tutto facoltativo
  • 208.
    Ping Request Example http://www.hostname.com/gwc.php?ping=1 Definition (Risposte della WebCache) ^PONG(?::s.+)?$ Specifica classico schema di PING/PONG per verificare se una cache risulta essere attiva questo messaggio di diagnostica dovrebbe essere utilizzato tra cache diverse e non tra peer della rete
  • 209.
    Stat Request Example http://www.hostname.com/gwc.php?stat=1 Definition (Risposte della WebCache) numero totale richieste ricevute <crlf> numero richieste ricevute nell’ultima ora <crlf> numero richieste di tipo update ricevute nell’ultima ora <crlf> Specifica estensione che le cache possono implementare ed è utile a fini statistici per essere davvero efficace ogni client dovrebbe inviare informazioni aggiuntive
  • 210.
    Stat Request (cont.) Example (Schema nuove query string) [...]?client=ABCD&version=1.2.3&hostfile=1 Specifica le due variabili aggiuntive permettono di avere dati più accurati nelle statistiche la variabile client è un codice di 4 bytes che identifica il client (lo stesso utilizzato nelle QueryHit) la variabile version identifica la versione del client
  • 211.
    Client: comportamento Cosa fare. . . i client devono mantenere una lista di peer connessi alla rete ed una lista di url di cache da contattare è compito del client mantenere una lista aggiornata di questi indirizzi un client dovrebbe inviare una richiesta di tipo Hostfile tutte le volte che necessita di nuovi peer a cui connettersi un client dovrebbe inviare una richiesta di tipo Urlfile per costruire la sua lista di webcache un client dovrebbe inviare queste richieste periodicamente, con il proprio indirizzo ip ed una cache funzionante scelta a caso tra quelle della propria lista
  • 212.
    Client: comportamento (cont.) . . . e cosa non fare inviare il proprio indirizzo ip se non è raggiungibile dagli altri peer inviare indirizzi ip diversi dal proprio inviare url di cache non funzionanti Quando una cache è funzionante? per essere funzionante non basta che una cache risponda a dei semplici PING si può essere ragionevolmente sicuri che una cache sia funzionante se e solo se essa risponde correttamente a richieste di tipo PING e UPDATE
  • 213.
    Client: comportamento (cont.) Richieste l’interazione con la cache è realizzata tramite il protocollo HTTP in particolare si utilizzano richieste di tipo GET ciascuna richiesta deve essere codifica come previsto da rfc1738 (Uniform Resource Locators) le richieste risultano quindi molto semplici in quanto parti integranti dell’url richiesto
  • 214.
    Server: comportamento Specifiche la cache comunica con i client tramite il protocollo HTTP e deve quindi essere conforme a queste specifiche le risposte devono rispettare il Content-Type e comunque essere in accordo con le richieste del client la cache dovrebbe ritornare sono un numero ridotto di entry (circa 10 - 20) e solo le informazioni più recenti questo contribuisce a mantenere le cache di ridotte dimen- sioni visto che le informazioni più vecchie possono essere rimpiazzate con quelle nuove appena esse arrivano avere cache così piccole contribuisce a fornire informazioni sempre aggiornate
  • 215.
    Server: comportamento (cont.) Risposte un messaggio di tipo OK implica che la procedura si è conclusa senza errori un messaggio di tipo ERROR implica che la procedura non si è potuta concludere per una qualche sorta di errore siccome i client dovrebbero rimuovere le cache che ritor- nano codici di errore, è consigliabile di non abusare di questo codice errori transitori, come il tentativo da parte di un client di eseguire l’update di un ip o url errato dovrebbero essere liquidati con una risposta di tipo OK seguita da un WARNING
  • 216.
    Server: comportamento (cont.) Sicurezza l’attacco più ovvio che può venire in mente è quello di provare ad inserire host o ip invalidi all’interno della cache la cache, una volta ricevuto un update da un client, non dovrebbe accettare un’altro update dallo stesso ip per un intervallo di tempo stabilito in questo modo le entry maligne non possono essere inserite da un stesso ip prima di un certo lasso di tempo una volta inserita, una entry maligna rimarrà in cache solo una frazione del timeout stabilito in quanto resa obsoleta dagli update degli altri client
  • 217.
    Realizzazione di unclient gcacher gcacher è uno script perl che fa parte di una suite di program- mi scritti al fine di dimostrare alcune delle cose viste in questa presentazione; gcacher è rilasciato sotto GPLv2 Installazione nelle propria home perl Makefile.PL PREFIX=~/.gnutella/usr make all test install export PATH=~/.gnutella/usr/bin:${PATH} export PERL5LIB=~/.gnutella/usr/share/perl:$PERL5LIB
  • 218.
    Realizzazione di unclient gcacher gcacher si connette ad una Web-Cache e richiede una lista di peer attualmente connessi alla rete Gnutella Example (Help)
  • 219.
    Realizzazione di unclient gcacher gcacher mentre preleva una lista di peer. . . Example (Una lista di peer)
  • 220.
    Introduzione Che cos’è. . . un crawler (detto anche spider o robot), è un software che analizza i contenuti di una rete in un modo metodico e automatizzato catturare la topologia di una rete a fini diagnostici o statistici non è un compito facile il carico che questo crawler può imporre alla rete durante il suo passaggio potrebbe paralizzare la rete
  • 221.
    Crawler Ping Quando gli uomini erano veramente uomini. . . inizialmente il crawling veniva realizzato tramite i meccanis- mi di PING/PONG previsti dal protocollo Gnutella una possibile implementazione consiste nel mandare un pacchetto di tipo PING con Hops = 0 e TTL = 2 ad un host ed aspettare tutte le risposte di tipo PONG questo metodo può continuare ad essere usato ma risulta essere troppo lento per ottenere una fotografia della rete in un tempo ragionevole al fine di limitare l’overhead è consigliabile che queste risposte di PONG non contengano estensioni GGEP
  • 222.
    Crawler Headers . . . e non mangiatori di quiche Un’estensione al protocollo Gnutella prova a velocizzare il Crawling aggiungendo un nuovo header da inviare appena la connessione tra due nodi viene stabilita Example (Request HTTP Headers) Crawler: <max_Version>.<min_Version> Protocollo La versione attuale del protocollo di Crawling è la 0.1
  • 223.
    Crawler Headers (cont.) Example (Reply HTTP Headers) Leaves: ipleaf1 :port, [...] Peers: ippeer1 :port, [...] Protocollo Leaves identifica le foglie connesse al peer interrogato se esso è un Ultrapeer Peers identifica tutti gli altri nodi connessi (ad esempio altri Ultrapeer ) al termine di questa transazione la connessione viene chiusa immediatamente
  • 224.
    Realizzazione di uncrawler gcrawler gcrawler è uno script perl che fa parte di una suite di program- mi scritti al fine di dimostrare alcune delle cose viste in questa presentazione; gcrawler è rilasciato sotto GPLv2 Installazione nelle propria home perl Makefile.PL PREFIX=~/.gnutella/usr make all test install export PATH=~/.gnutella/usr/bin:${PATH} export PERL5LIB=~/.gnutella/usr/share/perl:$PERL5LIB
  • 225.
    Realizzazione di uncrawler gcrawler gcrawler disegna la mappa della topologia di una parte della rete, differenziando gli Ultrapeer dalle foglie e visualizzando le connessioni tra i nodi Example (Help)
  • 226.
    Introduzione Che cos’è. . . A livello di astrazione questa specifica regola il traferimento di pacchetti del tipo QueryHit tipici del protocollo della rete Gnutella attraverso il protocollo di trasporto HTTP
  • 227.
    Browse Host Extension Protocollo una richiesta di Browse Host viene eseguita attraverso una richiesta GET della root la richiesta deve includere tutti i media type che sono ac- cettati come risposta attraverso l’apposito header HTTP Accept (rfc1945) i tipi possibili sono text/html e application/x-gnutella-packets se la richiesta può essere soddisfatta il server risponde con un codice 200 OK specificando il media type utilizzato nella risposta tramite header Content-Type se la richiesta non può essere soddisfatta un codice 406 Not Acceptable viene restituito in ogni caso al termine della transazione la connessione viene terminata
  • 228.
    Browse Host Extension Media Type application/x-gnutella-packets è lo standard previsto dal protocollo e consiste in uno stream di pacchetti di tipo QueryHit tipici del protocollo Gnutella text/html è utilizzato come fallback per quei client che non supportano il primo metodo text/html non dovrebbe essere utilizzato in quanto la rispos- ta manca di alcune informazioni come, ad esempio, la dimensione di ogni risorsa Hint utilizzando il protocollo HTTP questa estensione si presta molto bene ad essere utilizzata anche tramite PUSH nella maniera usuale
  • 229.
    Browse Host Extension Tuning il traffico può anche essere compresso come previsto dalla Link Compression Extension un servent può decidere se limitare la banda dedicata a questa operazione un servent può anche decidere di mettere in coda queste richieste come fossero delle richieste di download (previsto dalla Active Queuing Extension)
  • 230.
    Realizzazione di unbrowser gbrowser gbrowser è uno script perl che fa parte di una suite di program- mi scritti al fine di dimostrare alcune delle cose viste in questa presentazione; gbrowser è rilasciato sotto GPLv2 Installazione nelle propria home perl Makefile.PL PREFIX=~/.gnutella/usr make all test install export PATH=~/.gnutella/usr/bin:${PATH} export PERL5LIB=~/.gnutella/usr/share/perl:$PERL5LIB
  • 231.
    Realizzazione di unbrowser gbrowser gbrowser permette di visualizzare le risorse condivise da un peer attraverso la rete Gnutella Example (Help)
  • 232.
    Realizzazione di unbrowser Implementazione di un pacchetto Gnutella Un generico pacchetto Gnutella può essere implementato, se si utilizza un linguaggio ad oggetti, come una classe aventi i campi che lo caratterizzano Example (Gnutella::Packet::Generic) my $self = { _accessible => { debug => $parent->debug(), timeout => $parent->timeout(), msgid => [], type => undef, ttl => 0, hops => 0, size => 0, payload => undef, }, };$
  • 233.
    Realizzazione di unbrowser Tipi di pacchetto Gnutella Ciascun tipo di pacchetto è identificato in maniera univoca dal campo type presente nell’intestazione, ossia un intero a 8 bit che può assumere diversi valori Example (Tipi di pacchetto Gnutella) use constant { PACKET_PING => 0x00, PACKET_PONG => 0x01, PACKET_PUSH => 0x40, PACKET_QUERY => 0x80, PACKET_REPLY => 0x81, }; Implementazione Per ogni tipo di pacchetto ci sarà una classe che estende il pacchetto generico specializzandolo nel sotto tipo desiderato
  • 234.
    Realizzazione di unbrowser Pacchetto QueryHit un pacchetto di questo tipo può essere quindi implementato con una classe, sia Gnutella::Packet::QueryReply, figlia di Gnutella::Packet::Generic tale classe va specializzata con i campi che contraddistin- guono il suo payload (ad esempio ip, port, speed, results, guid) tale classe va munita di un metodo ausiliario, sia parsePayload, che si occupa di estrarre le informazioni dal payload
  • 235.
    Realizzazione di unbrowser Example (Gnutella::Packet::QueryReply::$parsePayload) [...] for (my $i = 0; $i < $count; $i++) { my @extra; my $index = unpack("L", substr($data, 0, 4, ’’)); my $size = unpack("L", substr($data, 0, 4, ’’)); my $name = substr($data, 0, index($data, "x00"), ’’); substr($data, 0, 1, ’’); while(1) { if(substr($data, 0, 1) =~ /^(?:x00|xC3)$/) { last; # no more extensions or GGEP found } my $text = substr($data, 0, index($data, "x1C")); $text = substr($text, 4) if $text =~ /^urn:/; push @extra, $text; substr($data, 0, index($data, "x1C") + 1, ’’); } substr($data, 0, index($data, "x00") + 1, ’’); push @set, [ $index, $size, $name, @extra ]; } [...]
  • 236.
    Realizzazione di unbrowser Example (Gnutella::ConnectionBinary::read) sub read { # [...] return undef unless read( $self->socket(), $header, 23) == 23; # parse header @msgid = unpack("L4", substr($header, 0, 16)); $type = unpack("C", substr($header, 16, 1)); $ttl = unpack("C", substr($header, 17, 1)); $hops = unpack("C", substr($header, 18, 1)); $size = unpack("L", substr($header, 19, 4)); # read payload return undef unless $self->isReadable(); return undef unless read( $self->socket(), $payload, $size ) == $size; return $self->$classType( $type )->new($self, ’msgid’ => @msgid, ’type’ => $type, ’ttl’ => $ttl, ’hops’ => $hops, ’size’ => $size, ’payload’ => $payload ); }$
  • 237.
    Realizzazione di unbrowser Che cosa ritorna? Il metodo ausiliario classType ritorna un tipo per il pacchetto del protocollo Gnutella Example (Gnutella::ConnectionBinary::$classType) my $classType = sub { my($self, $packetType) = @_; # add implemented packets return ’Gnutella::Packet::Generic’ unless $packetType == PACKET_REPLY; return ’Gnutella::Packet::QueryReply’; }; Lavori in corso Attualmente solo i pacchetti di tipo QueryHit sono implementati, gli altri vengono trattati come pacchetti generici
  • 238.
    Realizzazione di unbrowser gbrowser gbrowser durante la visualizzazione delle risorse condivise da un peer d’oltre oceano. . . Example (Visualizzazione di un peer)
  • 239.
    Realizzazione di unbrowser gbrowser gbrowser può fornire anche spunti interessanti. . . Example (Eseguire ricerche)
  • 240.
    Realizzazione di unbrowser gbrowser gbrowser utilizzato insieme a gstat permette di avere anche dei dati a scopo statistico. . . Example (Un po’ di statistiche)
  • 241.
    Introduzione Perchè. . . la gestione dei download in Gnutella è quella tipica della lotteria: se si è fortunati si vince, altrimenti niente questo approccio non premia gli utenti che aspettano per un file, ma peggio premia quelli che abusano della rete collegandosi tante volte finchè non ottengono ciò che desiderano la soluzione è quella di creare una sorta di coda di attesa per tutti gli utenti che vorrebbero scaricare una risorsa ma che al momento non è possibile servire
  • 242.
    Handshake Example (HTTP Headers) X-Queue: <max_Version>.<min_Version> Protocollo tutti i client che supportano questa estensione inviano questo header quando ricevono una richiesta di download questo header semplicemente indica che le richieste di download potranno essere passibili di coda se un client non riceve questo header deve seguire la normale procedura prevista dal protocollo Gnutella la versione attuale del protocollo di Active Queuing è la 0.1
  • 243.
    Handshake Protocollo se un server che ha ricevuto la richiesta di download ha uno slot libero allora il trasferimento inizia normalmente come previsto dal protocollo Gnutella (codice 200 o 206) altrimenti un codice 503 è ritornato ed un ulteriore header X-Queue è inviato
  • 244.
    Handshake Example (HTTP Headers) X-Queue: position=2,length=5,limit=4,pollMin=45,pollMax=120 Protocollo position identifica l’attuale posizione nella coda; quando si è giunti alla posizione #1 allora si è i primi ad ottenere il prossimo slot libero length è l’attuale lunghezza della coda limit è il numero di upload contemporanei consentiti tutti questi campi sono opzionali e servono unicamente per dare delle informazioni al client che può così vedere i propri progressi
  • 245.
    Handshake Polling i due parametri pollMin e pollMax indicano al client quanto spesso deve richiedere aggiornamenti sul download inviare una richiesta più spesso di pollMin viene interpretato come flooding non inviare una richiesta prima di pollMax viene interpretato come un non più interessamento alla risorsa questi parametri possono cambiare tra una richiesta e l’al- tra e possono essere utilizzati anche al fine di bilanciare il carico di un peer pollMin e pollMax possono essere proporzionali alla posizione del peer nella coda; in questo modo si riduce il tempo tra quando uno slot è pronto e quando il download ha effettivamente inizio
  • 246.
    Handshake Vantaggi utilizzando questa estensione un utente può vedere i pro- pri progressi fino alla posizione #1, anche con code molto lunghe se un utente non è più interessato al download di una risorsa può chiudere la connessione e nessuno slot verrà sprecato per una richiesta che non arriverà mai siccome le richieste sono fatte tramite HTTP un utente può anche richiedere una porzione della risorsa da scaricare
  • 247.
    Handshake Casi Speciali se un utente che è già in coda richiede un altro file, esso deve essere spostato alla fine della coda un utente che ha eseguito un download parziale può richidere un altro chunk del file senza essere messo al- la fine della coda; questo incentiva il download parziale e concorrente da più peer la coda ha una lunghezza fissata; tutte le richieste che non possono essere messe in coda devono ricevere il codice standard previsto dal procollo (503)
  • 248.
    Introduzione Perchè. . . la compressione del traffico sulla rete Gnutella è opzionale ed è intesa "per connessione" siccome la compressione dello stream è "per connes- sione", ogni pacchetto viene decompresso quando ricevuto e ricompresso per ogni connessione l’abilitazione alla compressione del traffico va negoziata secondo il famoso paradigma del 3-Way Handshake in quanto decomprimere è facile mentre la compressione richiede un minimo di risorse di cui un peer potrebbe non disporre
  • 249.
    Handshake Example (Disponibilità a ricevere) Accept-Encoding: encoding1 [, ...] Example (Disponibilità ad inviare) Content-Encoding: encoding1 [, ...] HTTP Headers il peer disposto a comprimere il traffico deve scegliere uno e uno solo tra gli algoritmi supportati dalla controparte questo implica che la compressione può essere anche asimmetrica; un utente può anche accettare dati compressi ma spedire del plain text
  • 250.
    Handshake: esempi Example (Compressione del traffico simmetrica) Peer1 Peer2 ----------------------------------------------------------- GNUTELLA CONNECT/0.6 Accept-Encoding: deflate GNUTELLA/0.6 200 OK Accept-Encoding: deflate Content-Encoding: deflate GNUTELLA/0.6 200 OK Content-Encoding: deflate
  • 251.
    Handshake: esempi Example (Compressione del traffico asimmetrica) Peer1 Peer2 ----------------------------------------------------------- GNUTELLA CONNECT/0.6 Accept-Encoding: deflate GNUTELLA/0.6 200 OK Accept-Encoding: deflate GNUTELLA/0.6 200 OK Content-Encoding: deflate
  • 252.
    Vendor Messages Introduzione il supporto ai Vendor Messages permette ai produttori di software di sperimentare nuovi messaggi senza snaturare la rete Gnutella a questo scopo di testing è stato introdotto un nuovo tipo di messaggio, 0x31; è stato inoltre definito un ulteriore tipo di messaggio, 0x32, riservato ai Vendor Messages standardizzati se un messaggio di un produttore inizialmente definito come privato viene considerato particolarmente utile dalla comunità questo viene promosso ad avere come type 0x32 essendo un messaggio del protocollo Gnutella l’intestazione è quella standard
  • 253.
    Vendor Messages Struttura del pacchetto Vendor-ID so eo Campo una sequenza di quattro caratteri 0 3 Vendor-ID ASCII case sensitive che deno- 4 5 Sub-Selector tano un produttore; stesso codice 6 7 Version delle QueryHit e utilizzato nelle connessioni ad una WebCache
  • 254.
    Vendor Messages Struttura del pacchetto Sub-Selector so eo Campo identificatore per il tipo di messag- 0 3 Vendor-ID gio per quello specifico produttore 4 5 Sub-Selector (little endian sedici bit unsigned int) 6 7 Version Definition (Identificatore) uno specifico messaggio è univocamente identificato dalla tupla (Vendor-ID, Sub-Selector)
  • 255.
    Vendor Messages Struttura del pacchetto Version so eo Campo little endian sedici bit unsigned int 0 3 Vendor-ID che denota il numero di versione; 4 5 Sub-Selector solitamente parte da uno 6 7 Version
  • 256.
    Vendor Messages Example (Identificazione di un pacchetto) <Vendor-ID>/<Sub-Seector>v<Version> Notazione ad esempio LIME/64v2 è un identificatore valido (il numero di versione viene spesso omesso) le regole su come routare uno specifico messaggio, il TTL, Hops, GUID ed ogni altro aspetto viene definito dal tipo di messaggio
  • 257.
    Vendor Messages Example (HTTP Headers) Vendor-Message: <max_Version>.<min_Version> Handshake i peer che supportano questa estensione devono dichiararlo alla controparte durante handshake la versione attuale del protocollo è la 0.1 con supportare qui si intende che un peer semplicemente legge i messaggi di tipo 0x3[12] senza terminare la con- nessione e non necessariamente che sia capace di capire il messaggio in sè siccome l’insieme di questi messaggi non ha una dimensione fissata e può essere molto grande questo non viene dichiarato
  • 258.
    Vendor Messages Pacchetto null/0v0 alcuni vendor message possono, ad esempio, prevedere una riposta è necessario sapere se un particolare peer supporta un particolare messaggio prima di inviarlo per evitare di at- tendere all’infinito o addirittura chiudere la connessione se questa non arriva entro un certo lasso di tempo dopo handshake è necessario dichiarare la lista dei Vendor Messages supportati dalla propria implementazione il messaggio da utilizzare viene detto null/0v0 in quanto il campo Vendor-ID, Sub-Selector e Version vengono settati a zero
  • 259.
    Pacchetto null/0v0 Struttura del pacchetto so eo Campo 8 9 Size Pacchetto null/0v0 little endian sedici bit unsigned int che identifica il numero (e non la dimensione) di blocchi che si ripetono all’interno del pacchetto ciascun blocco ha dimensione otto byte e descrive un particolare Vendor Message supportato
  • 260.
    Pacchetto null/0v0 Blocco ripetuto so eo Campo 0 3 Vendor-ID 4 5 Sub-Selector 6 7 Version Pacchetto null/0v0 si noti che qui gli offset partono da zero per comodità ma il primo di questi blocchi nizierebbe all’offset dieci se più versioni dello stesso messaggio sono supportate e si sa che sono retro compatibili, allora solo l’ultima deve essere indicata
  • 261.
    Vendor Messages Esempio: Hops Flow Message Specifiche del pacchetto Campo Specifica Vendor-ID BEAR Sub-Selector 4 Version 1 TTL 1 Hops 0 GUID - Routed no Payload si
  • 262.
    Vendor Messages Esempio: Hops Flow Message questo messaggio è un Vendor Message realmente utilizza- to ed è identificato da BEAR/4v1; viene anche detto Hops Flow il payload del pacchetto è composto da un unico byte che esprime il numero massimo, non compreso, per il campo Hops quando una query viene inoltrata un nodo foglia può utilizzare questo messaggio per informare il proprio Ultrapeer di abilitare o disabilitare il forwarding delle query
  • 263.
    Vendor Messages Esempio: Hops Flow Message settare un valore a 0 implica che non si vuole ricevere nes- suna query in quanto il valore minimo che si può inserire nel campo Hops è, appunto, 0 un valore a 1, invece, dichiara che si desidera ricevere solo le query generate da un vicino in generale dovrebbe essere utilizzato un valore pari a max_TTL + 1
  • 264.
    Bye Message Introduzione è un messaggio utilizzato per informare la controparte del fatto che si sta per chiudere la connessione un servent che supporta il pacchetto Bye deve annunciarne il supporto tramite apposito header la versione attuale del protocollo è la 0.1 Example (HTTP Header) Bye-Message: <max_Version>.<min_Version>
  • 265.
    Bye Message Introduzione un messaggio di tipo Bye è identificato da un nuovo opcode, 0x02 questo pacchetto deve sempre essere inviato con TTL = 1 per evitare che si propaghi nella rete (Hops = 0) un peer che riceve un messaggio di tipo Bye deve chiudere la connessione immediatamente di conseguenza può essere inviato anche a client che non supportano questa estensione un peer che ha inviato un messaggio Bye deve attendere alcuni secondi prima di chiudere la connessione e non inviare altro; durante questo periodo deve droppare tutto ciò che riceve a parte messaggi di tipo QueryHit e Push
  • 266.
    Bye Message Struttura del pacchetto Code so eo Campo 16 bit little endian unsigned int, un 0 1 Code codice identificativo 2 n Description Definition (Code) la presenza di un codice numerico garantisce che questi mes- saggi possano essere processati in maniera automatica; viene utilizzata una classificazione dei codici simile a quella del protocollo SMTP
  • 267.
    Bye Message Struttura del pacchetto Description so eo Campo una stringa di descrizione termina- 0 1 Code ta da un x00 (NULL) 2 n Description Definition (Description) il messaggio dovrebbe essere una stringa che descrive il più possibile l’errore che si è verificato
  • 268.
    Bye Message Codici numerici 2xx: nessun errore rilevato, la connessione viene semplice- mente chiusa (200) oppure su richiesta dell’amministratore del peer (201) 4xx: il peer remoto ha causato un qualche errore come l’in- vio di pacchetti troppo grossi (400), troppi messaggi dupli- cati (401), query errate (402), messaggi per cui vale TTL + Hops > max_TTL (403), troppi messaggi sconosciuti (404), raggiunge un certo timeout di inattività (405), non risponde ad un Ping con TTL=1 (406) oppure non sta condividendo abbastanza risorse (407 ) 5xx: il peer ha riscontrato un errore interno come un errore di I/O (500), una sincronizzazione nel protocollo (501) o la coda d’invio è piena (502)
  • 269.
    Bye Message Descrizioni è possibile utilizzare anche degli header HTTP per meglio caratterizzare ciò che è accaduto e provare ad indirizzare il ricevente verso altri nodi a cui connettersi se si vogliono inserire degli header HTTP-like bisogna terminare la prima descrizione con un crlf tutte le volte che è possibile è preferibile utilizzare anche gli header HTTP
  • 270.
    Metadata Introduzione Gnutella come molti altri protocolli di condivisione di risorse utilizza la corrispondenza tra l’interrogazione effettuata ed il nome della risorsa questo è limitativo e restringe la richiesta a ciò che è contenuto nel nome della risorsa si pensi ad un utente che voglia cercare un libro intitolato Il Big Bang - L’origine dell’universo scritto da Mario Bianchi e pubblicato dalla Rossi Editore nel Maggio del 1998 se qualcuno possedesse il libro potrebbe chiamare il file Il Big-Bang.pdf. Un utente interessato, dunque, cercherebbe le parole Big e Bang trovando una pletora di cose che non stava cercando
  • 271.
    Metadata L’idea l’idea è quella di specificare più informazioni in un’uni- ca interrogazione per poter cercare più efficacemente le risorse ciascuna risorsa nella collezione di un utente, quindi, può essere caratterizzata da più informazioni al fine di ottenerne una catalogazione migliore è possibile codificare questi metatag in vari formati, sia binari sia testuali; per Gnutella si è scelto di utilizzare xml
  • 272.
    Metadata Implementazione a ciascun tipo di risorsa viene associato uno schema che definisce le informazioni che possono essere associate a quel particolare tipo uno schema altro non è che un dtd a cui il metatag associato ad una risorsa deve essere conforme nell’esempio precedente del libro, al file Il Big Bang.pdf viene associato un metatag conforme allo schema book
  • 273.
    Metadata Esempio di Rich Query Un utente che volesse cercare il libro del nostro esempio, potrebbe inviare una richiesta simile a questa Example (Rich Query) <books> <book schema="http://www.hostname.com/schemas/book.xsd" title="Il Big Bang - L’origine dell’universo" publisher="Rossi Editore" author="Mario Bianchi" /> </books> Esempio di Rich Query Le informazioni non espressamente inserite dall’utente non compaiono nella query, risparmiando così banda
  • 274.
    Metadata Example (Query Hit) <?xml version="1.0"?> <books xsi:noNamespaceSchemaLocation="http://www.hostname.com/schemas/book.xsd"> <book identifier="/home/looser/bb.pdf" title="Il Big Bang - L’origine dell’universo" author="Mario Bianchi" chapters="11" genre="divulgazione scientifica" publisher="Rossi Editore" price="50 euro" comments="Un ottimo libro, ben scritto" /> </books> Esempio di Query Hit Si noti il nome del file; questa risorsa non sarebbe stata trovata con una query tradizionale
  • 275.
    Metadata: Estensione QueryMessage Struttura del pacchetto Speed so eo Campo velocità minima (inalterato) 0 1 Speed 2 n Query n+1 m Rich Query
  • 276.
    Metadata: Estensione QueryMessage Struttura del pacchetto Query so eo Campo la stringa dell’interrogazione NULL- 0 1 Speed terminated (inalterato) 2 n Query n+1 m Rich Query
  • 277.
    Metadata: Estensione QueryMessage Struttura del pacchetto Rich Query so eo Campo nuova rich query, NULL terminated 0 1 Speed (aggiunto) 2 n Query n+1 m Rich Query Codice numerico estendere il pacchetto già adibito a trasportare una query per la rete Gnutella risulta essere molto semplice questo semplice schema garantisce che i client che non supportano questa estensione possano tranquillamente ignorare le Rich Query
  • 278.
    Metadata Estensione Query Hits un client che riceve una Rich Query e non supporta questa estensione esegue la normale ricerca utilizzando la query string e risponde con una normale QueryHit un client invece che supporta questa estensione risponde con una QueryHit inserendo il file xml di risposta nella sezione QHD, nella parte privata, dopo le estensioni HUGE e GGEP siccome una risposta xml può essere anche molto grande, si può pensare di inserire il documento xml compresso
  • 279.
    Approfondimenti I http://tinyurl.com/Gnutella Wiki Gnutella su AulaWeb http://tinyurl.com/Gruppo4 Wiki Gruppo4 su AulaWeb