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 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.
9. 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).
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 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.
29. 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.
30. 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.
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).
42. 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
43. 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.
44. 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.
45. 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).
46. 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.
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
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
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.
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.
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 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).
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 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.
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
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
120. 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
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 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.
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
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
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