Sei sulla pagina 1di 66

PROGETTAZIONE E REALIZZAZIONE IN JAVA DI

UNA RETE PEER TO PEER ANONIMA E


MULTIFUNZIONALE
RELATORE: Ch.mo Prof. Enoch Peserico Stecchini Negri De Salvi
LAUREANDO: Paolo Bertasi

Corso di laurea in Ingegneria Informatica

A.A. 2004-2005
UNIVERSITÀ DEGLI STUDI DI PADOVA
Dipartimento di Ingegneria dell’Informazione
Corso di Laurea in Ingegneria Informatica

TESI DI LAUREA

PROGETTAZIONE E
REALIZZAZIONE IN JAVA DI UNA
RETE PEER TO PEER ANONIMA E
MULTIFUNZIONALE

RELATORE: Prof. Enoch Peserico Stecchini Negri De Salvi

LAUREANDO: Paolo Bertasi

A.A. 2004-2005
Ai miei genitori
chi mi hanno sempre sostenuto
incoraggiato e aiutato.
Indice

Sommario 1

Introduzione 3

1 Le caratteristiche peculiari 7
1.1 Architettura a plug-in . . . . . . . . . . . . . . . . . . . . . . . . 8
1.2 Serverless . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.3 Anonimato . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.4 I crediti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

2 Le componenti 15
2.1 Core . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.1.1 Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.1.2 Connettività . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.2 Kademlia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.3 Altri plug-in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.3.1 Web server (http) . . . . . . . . . . . . . . . . . . . . . . 28
2.3.2 E-mail (smtp, pop3) . . . . . . . . . . . . . . . . . . . . . 29
2.3.3 Host resolution (dns) . . . . . . . . . . . . . . . . . . . . . 30
2.3.4 File sharing (aMule) . . . . . . . . . . . . . . . . . . . . . 30

3 Management 33

Conclusioni 37

A Documentazione del progetto 39


A.1 Kademlia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
A.1.1 ADT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
A.1.2 Communication . . . . . . . . . . . . . . . . . . . . . . . . 42
A.1.3 Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

v
INDICE

A.1.4 Datagrams . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
A.2 Core . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
A.2.1 The core . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
A.2.2 Resource manager . . . . . . . . . . . . . . . . . . . . . . . 49
A.2.3 Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

Bibliografia 53

Elenco delle figure 55

Elenco delle tabelle 57

vi
Sommario

Con l’avvento delle connessioni a banda larga e la moltiplicazione dei PC


posseduti dai singoli privati è, di fatto, nato un nuovo possibile uso di internet.
Già da qualche anno, infatti, per sfruttare le potenzialità delle macchine connesse
alla rete, sono sorti diversi progetti per il calcolo distribuito1 . Parallelamente,
è esploso il fenomeno del file sharing grazie a client estremamente semplici e
funzionali come eMule2 . Entrambe queste tecnologie hanno un denominatore
comune: sfruttano l’architettura peer-to-peer per offrire servizi che le singole
macchine, da sole, non potrebbero mai offrire. Da qui l’idea di realizzare una
rete multi-funzionale, in grado, grazie al contributo di tutti gli utenti, di fornire
tutti i servizi già oggi disponibili su internet e di essere aggiornata con nuove
funzionalità, qualora ce ne fosse l’esigenza.
Una caratteristica, che avrà un forte peso nella realizzazione di questa infra-
struttura, sarà l’attenzione all’anonimato. In un momento in cui, sempre più
spesso, casi di censura balzano agli onori della cronaca3 , una rete come questa
permetterà la libera circolazione di idee e informazioni.

1
Citiamo qui solo Boinc http://boinc.berkeley.edu/.
2
http://www.emule-project.net/
3
Uno su tutti: Cina, anche Google accetta la censura
http://www.corriere.it/Primo Piano/Scienze e Tecnologie/2006/01 Gennaio/25/
google.shtml
Introduzione

In questo elaborato si illustrerà la progettazione di PariPari, una nuova rete


peer-to-peer.

Generalmente per peer-to-peer (o P2P) si intende una rete di compu-


ter o qualsiasi rete che non possiede client o server fissi, ma un numero
di nodi equivalenti (peer, appunto) che fungono sia da client che da
server verso altri nodi della rete4 .

Gli esempi più famosi di reti di questo tipo sono quelle dedicate allo scambio
di file: in principio si trattava di file musicali (MP3), poi si è arrivati allo scambio
di qualsiasi genere di file. Queste reti, nonostante la loro natura distribuita, basa-
vano il loro funzionamento su dei server. Questi servivano a mettere in contatto
tra loro i vari nodi della rete, senza però prendere mai parte al trasferimento dei
file. Tuttavia, è chiaro che in caso di irraggiungibilità di questi server, la rete non
poteva sussistere proprio perché i vari nodi non avrebbero potuto comunicare tra
loro. Esempi di questo tipo di rete sono la rete eDonkey2000 (d’ora in poi ED2K),
ancor oggi usata da celebri programmi come mlDonkey, eMule, aMule e la rete
Bittorrent5 col suo famoso client Azureus.
Per rendere la rete più resistente al black out di qualunque dei computer ad
essa collegati sono stati sviluppati protocolli di gestione completamente decen-
tralizzati6 . Questi protocolli cercano di affidare a ogni nodo che concorre alla
formazione della rete l’indicizzazione di alcuni file, in modo che ogni file faccia
riferimento ad un nodo attivo, e sia quindi rintracciabile. Alcuni protocolli di
questo tipo sono Chord7 , Pastry8 , ma soprattutto Kademlia. Quest’ultimo, che
4
[4]
5
Cfr. [5]
6
Protocolli DHT: Distributed Hash Table.
cfr. http://en.wikipedia.org/wiki/Distributed hash table
7
Cfr. [6]
8
Cfr. [7]

3
INTRODUZIONE

sembra essere il più promettente, viene già sfruttato nelle recenti versioni di quasi
tutti i client per la rete ED2K.
Un altro aspetto poco desiderabile delle reti P2P è il fatto che, anche in
una rete completamente serverless, è piuttosto semplice riuscire a scoprire quali
nodi (quali indirizzi IP) condividono quali file. La privacy degli utenti della
rete non è, quindi, per nulla garantita. Questo problema è stato affrontato e
risolto da recenti reti, come Ants e Mute, che si avvalgono di tecniche come
il routing probabilistico9 . Queste reti sono però, tuttora, reti di nicchia, vista
l’esigua dimensione che raggiungono, proprio perché la garanzia dell’anonimato
dell’utente tende a rendere la ricerca meno efficiente e, quindi, spesso, più lenta.
Tuttavia il fattore che maggiormente contribuisce a contenere la dimensione di
queste reti, è il cosiddetto effetto rete 10 .
Accanto a queste reti, che hanno come scopo il trasferimento file, vivono
altri progetti con obiettivi diversi. Citiamo qui Freenet11 , che fornisce servizi di
webhosting anonimo e Skype12 che gestisce un sistema di VOIP su una rete P2P.
Uno dei problemi principali che hanno affrontato queste reti è stato come
invogliare l’utente a condividere i propri file. Per risolvere questo problema le
reti si sono spesso basate su un sistema di gestione di crediti virtuali. Il sistema
che sembra funzionare meglio13 è quello adottato dalla rete ED2K. Proviamo a
spiegare come funziona con un semplice esempio. Se Alice scarica un file da Bob,
Alice è in debito verso Bob e, quindi, Bob potrà saldare il credito scaricando i
file di Alice prima degli altri eventuali concorrenti. Questo sistema ha però una
grossa pecca: Bob, infatti, sarà in credito solo con Alice e con nessun altro nodo
della rete, nonostante la partecipazione alla rete e la condivisione dei file rendano
un servizio (per quanto ipotetico) a tutti i nodi.
PariPari è una rete serverless basata su una variante di kademlia, garantisce
l’anonimato dei suoi nodi, fornisce un sistema di crediti più intelligente di reti
come ED2K, e, soprattutto, è multifunzionale. È probabilmente la multifunziona-
lità l’aspetto più innovativo di questo progetto (e probabilemte la sfida più grande
che ci siamo posti). Lo scopo è, infatti, quello di distribuire sulla rete tutti i più
comuni servizi disponibili su internet, mantendendoli però raggiungibili e fruibili
anche da computer esterni a PariPari. Per raggiungere questo obiettivo è stato
scelto un approccio a plug-in. Attorno a un nucleo centrale (detto core) viene
9
Cfr. [8]
10
Cfr. http://en.wikipedia.org/wiki/Network effect
11
http://freenetproject.org/
12
http://www.skype.com/
13
Valutandolo in base al numero di utenti

4
gradualmente costruita una galassia di plug-in che saranno in grado di interagi-
re tra loro e con internet per fornire i più disparati servizi. Questa architettura
permette di poter aggiungere alla rete nuovi servizi, qualora ce ne sia la necessità.
PariPari si propone, quindi, di creare una macchina virtuale capace di prov-
vedere a tutti i bisogni dell’utente di internet mantendosi dipendente solo dalla
comunità dei nodi da cui è formata.

Figura 1: La rete e gli host esterni.

Nelle prossime pagine illustreremo approfonditamente i tratti innovativi di


questa rete. Inoltre, tratteremo la progettazione della rete e la realizzazione
di alcune sue parti. Nel primo capitolo passeremo in rassegna le peculiarità di
PariPari. Nel secondo, invece, sposteremo l’attenzione sulla progettazione della
rete e sulla realizzazione delle parti a me assegnate. Si menzionerano altresı̀ gli
altri plug-in e il loro stato d’avanzamento. Il terzo capitolo verrà dedicato alle
problematiche dovute alla gestione del progetto. Infine, in appendice, si potrà
trovare la documentazione, in inglese, delle parti del progetto da me realizzate.

5
INTRODUZIONE

6
Capitolo 1

Le caratteristiche peculiari

PariPari, come detto nell’introduzione, si contraddistingue per quattro aspetti


principali:

• la sua natura serverless,

• l’architettura dedita all’espandibilità e alla multifunzionalità,

• il sistema di gestione dei crediti,

• la garanzia di anonimato per l’utente.

Questi punti saranno, in seguito, approfonditi adeguatamente; ora invece sottoli-


neiamo altre due caratteristiche del client e della rete.
Si è deciso di scrivere il client in Java, per permettere la massima penetrazione
della rete. Java, come è noto, rende possibile la portabilità del programma su
tutte le principali piattaforme senza la necessità di ri-compilare il codice sorgente.
Java, inoltre, grazie alla tecnologia Java Web Start, rende trasparente all’utente
l’uso della rete. Infatti, grazie all’integrazione col browser, sarà possibile scaricare,
installare, e tenere aggiornato il software in modo pressochè automatico.
L’uso di Java, tuttavia, comporta una certa perdita di performance. Le ope-
razioni più costose dal punto di vista computazionale risultano essere quelle di
crittografia. Queste, scritte in Java, risultano quattro volte più lente che se fosse-
ro scritte in C++. Questa riduzione nelle prestazioni non influisce molto sui tempi
di risposta del programma, dato che la maggior parte delle cifrazioni avviene su
stream di byte dalle dimensioni molto contenute.
Possiamo affermare quindi, che a fronte di un leggero calo nelle prestazioni,
c’è, per l’utente finale, e per lo sviluppatore, un significativo incremento nella
facilità d’uso e di gestione del client.

7
1. LE CARATTERISTICHE PECULIARI

Un altro punto di forza della rete è la fruibilità dei servizi anche dall’esterno.
Infatti, i client che partecipano alla rete possono utilizzare le risorse condivise da-
gli altri nodi; elemento di novità è che la rete potrà essere sfruttata da computer
non facenti parte di PariPari. Ad esempio, se all’interno della rete, Alice si pro-
pone come webserver e Bob le fornisce una sua pagina, la pagina sarà consultabile
da qualsiasi computer connesso a internet con un normale browser.
Vista la natura aperta al pubblico e agli sviluppatori della rete si è deciso che
il progetto sarà open source e rilasciato sotto licenza GPL1 .

1.1 Architettura a plug-in


La rete, come detto, è concepita per permetterle di fornire praticamente qualsiasi
serivizio. Ogni nodo, infatti, concorrerà alla creazione di un’entità in grado,
al momento, di agire come un server web o un server per la posta elettronica,
di trasferire file, e, in un futuro prossimo, di condividere i cicli macchina, di
permettere il VOIP e di offrire le funzionalità di un DBMS distribuito. Per
raggiungere questo obiettivo, ogni client della rete è costituito da un nocciolo
centrale, detto core, che si occupa di fare da collante tra i vari plug-in e di gestire
le comunicazioni tra questi. I plug-in, realizzati secondo una specifica interfaccia,
gestiscono le varie funzionalità della rete e sfruttano le risorse della macchina su
cui gira il client, interagendo con gli altri plug-in tramite il core. Sempre con la
struttura di semplici plug-in, si possono individuare alcune classi che svolgono un
ruolo basilare per il client: i gestori di risorse. Questi, scritti esattamente come
dei normali plug-in, sovraintendono all’utilizzazione delle risorse del computer
locale da parte dei plug-in. Questo approccio garantisce la modularità, non solo
per quanto riguarda i servizi offerti alla rete, ma anche per quanto riguarda la
gestione interna dei plug-in. Con un esempio si chiarirà meglio questa scelta.
Il plug-in, che funge da server ftp sul nodo PariPari di Alice, viene contat-
tato da un normale utente del web, Bob. Bob fa upload di un file e il server ftp
lo salva. L’ftp però non ha accesso diretto al disco di Alice, ma inoltra la sua
richiesta di salvataggio del file al gestore dello spazio su disco, il quale si occupa
di salvare realmente il file. Questo layer interposto tra il disco e il server permette
di aggiungere nuove potenzialità in maniera estremamente semplice, non modifi-
cando cioè in alcun modo i plug-in già disponibili e cambiando solamente qualche
riga nei gestori di risorse. Si immagini, infatti, di voler aggiungere la possibilità
di salvare il file non sul disco fisso locale, ma di distribuendolo tra diversi nodi
1
Cfr. http://www.gnu.org/copyleft/gpl.html

8
1.2 SERVERLESS

della rete (ad esempio per assicurarne la sopravvivenza in caso di disastro); il


gestore semplicemente passerà il file a un ulteriore plug-in che si occupa di questo
processo e questo plug-in, interagendo con altri plug-in e altri moduli, disperderà
il file sulla rete. Ovviamente, su richiesta, il file potrà venir recuperato e passato
nuovamente al gestore e da questo al server ftp.
Concludiamo dicendo che, nonostante questo sistema garantisca una cosı̀ am-
pia elasticità, scrivere i plug-in risulta ancora molto semplice. Questi, infatti, non
hanno alcuna interazione diretta tra loro, ma vengono sempre mediati dal core
e comunque usano le risorse del sistema e gli altri plug-in come se quest ultimi
fossero delle semplici black box. Colui che scrive un plug-in, in ultima analisi, si
deve preoccupare solo di capire con quali eventuali altri moduli interagire e cosa
questi prendono in input e forniscono come output.

Figura 1.1: La struttura del client.

1.2 Serverless
PariPari deve il suo successo alla possibilità di funzionare senza richiedere ai
suoi utenti di permanere collegati ad essa perennemente. D’altra parte, non è
consigliabile mantenere una struttura centralizzata della rete, tramite dei nodi
principali, proprio perché l’indisponibilità di quest ultimi disgregherebbe la rete
intera.

9
1. LE CARATTERISTICHE PECULIARI

Per fronteggiare queste richieste, ci siamo orientati verso un protocollo recente,


ma già usato e collaudato: Kademlia.
Kademlia, ideato da Petar Maymounkov e David Mazi‘eres, è essenzialmente
un sistema per indicizzare host e risorse e permettere la ricerca di entrambi, in
modo completamente decentralizzato. Senza aver la presunzione di affrontare il
problema in modo esaustivo, possiamo dire che questo sistema associa ad ogni
risorsa e ad ogni nodo un hash univoco nello stesso spazio matematico. Con
una metrica basata sull’operazione di XOR, è possibile calcolare le distanze tra i
nodi e le risorse ed assegnare ad ogni nodo attivo la responsabilità delle risorse
a lui più vicine. Un nodo che cerca sulla rete qualcosa (di cui conosce l’hash)
interroga tutti i nodi che già conosce che sono più vicini alla risorsa. Questi
rispondono o con la risorsa stessa o fornendo al cercatore una lista di ulteriori
nodi ancora più vicini. La rete diventa cosı̀ completamente serverless e quindi
molto resistente all’inevitabile indisponibilità di alcuni suoi nodi. Questo risultato
permette, altresı̀, alla rete di essere difficilmente sabotabile dato che i suoi nodi
sono tutti uguali e perciò non presenta nessun punto debole.2

1.3 Anonimato
In una rete P2P, e quindi anche in PariPari, le transizioni di risorse (file, cicli
macchina,...) avvengono sempre tra due nodi della rete. Il nostro sistema di ano-
nimato permette di effetture questo contatto senza che sia possibile rintracciare
l’indirizzo IP del mittente nè quello del ricevente. Senza addentraci in una de-
scrizione troppo approfondita che sarà esposta in [3], diamo una descrizione dei
tratti salienti del funzionamento di questo sistema.
Premettiamo che ogni volta che si parlerà di crittografia si intenderà un pro-
cesso misto tra crittografia simmetrica e asimmetrica. Attualmente, infatti, i
dati sottoposti a cifratura, vengono prima passati all’algoritmo a chiave segreta
AES e poi, solo la chiave viene passata all’algoritmo RSA con chiave pubblica
privata a 2048 bit3 . La crittografia sui byte viene affidata ad un algoritmo molto
veloce, mentre a quello molto più lento viene lasciata la crittografia solo della
chiave simmetrica (della dimensione di pochi byte). In questo modo si possono
sfruttare i benefici derivanti dall’uso di algoritmo a chiave asimmetrica pagando
solo marginalmente la sua effettiva lentezza.
2
Sarebbe più corretto dire che tutti i nodi sono punti con la stessa debolezza.
3
La limitazione 2048 bit è imposta dalle JCE della Sun per restrizioni sull’esportazione di
tecnologia crittografica fuori dagli USA.

10
1.4 I CREDITI

dimensione array in KB ms per RSA ms per AES


3 27721 141
11 107865 145
269 2498566 285
1799 16612472 1306

Tabella 1.1: Crittografia: RSA vs AES.

Il sistema permette all’utente della rete di creare tra sè e il suo interlocutore
una catena di nodi, e altrettanto può fare l’interlocutore stesso. Il mittente, e
simmetricamente il ricevente, prima di iniziare la trasmissione, sceglie una catena
di nodi intermedi, ognuno dei quali ignora l’esistenza e quindi l’identità degli altri
nodi formanti la catena. Vengono quindi passate le richieste tra i due interlocu-
tori attraverso questi tunnel con un meccanismo di onion routing che permette
la segretezza dei dati trasportati dai nodi e la sicurezza della comunicazione. I
dati, infatti, sono cifrati con le chiavi pubbliche in modo che solo il nodo che in
quel momento deve ricevere, ed eventualemente rispedire, il pacchetto di comu-
nicazione può leggerne il contenuto. È evidente che, quanto più le catene sono
lunghe, tanto è maggiore la sicurezza offerta all’utente, d’altra parte, aumentando
il numero di salti e di passaggi crittografici aumenta anche la latenza nei trasferi-
menti e nelle ricerche. Inoltre, l’uso dell’onion routing, aumenta il carico di banda
complessivo per la rete in modo proporzionale al numero di salti.
Riportiamo solamente qui un risultato discusso in[3]:

È sufficiente che un nodo della catena non tenti di imbrogliare il


nodo che l’ha reclutato per la costruzione del tunnel per garantirne
l’anonimato.

Si mette quindi a disposizione di ogni nodo una tecnologia che mira a garantire
la privacy dell’utilizzatore. Inoltre, l’utente può scegliere se usare o meno questo
sistema, indipendentemente dalla scelta effettuata dal suo interlocutore.

1.4 I crediti
La gestione dei crediti in una rete P2P potrebbe sembrare un argomento di se-
codaria importanza, visto che non ne migliora le prestazioni, nè ne aumenta le
caratteristiche. Tuttavia è uno dei punti cruciali di queste reti perché regola

11
1. LE CARATTERISTICHE PECULIARI

Alice Bob

Figura 1.2: Formazione di tunnel per la comunicazione anonima.

i rapporti di collaborazione dei nodi e garantisce quindi l’esistenza della rete.


Proviamo ad analizzare alcune dinamiche che si possono presentare.
Il caso più semplice, quello in cui non servirebbe nemmeno l’emissione di
crediti, si verifica quando due utenti barattano tra loro due loro risorse simul-
taneamente. Questo scenario risulta essere però estremamente raro; è difficile,
infatti, che i due interlocutori necessitino, nello stesso momento, della risorsa of-
ferta dall’altro. È molto più frequente, invece, il caso in cui questo avvenga in
tempi differenti. Ecco una descrizone esemplificata di quanto appena descritto.
Alice cerca un file musicale che possiede Bob, ma Bob nel momento in cui cede
il file ad Alice, non ha bisogno di niente da Alice. Tuttavia, visti gli interessi
comuni dei due, è facile prevedere che, presto o tardi, Alice sarà nella condizione
di ricambiare il favore di Bob. Basterebbe che Alice si ricordasse di avere un de-
bito verso Bob per soddisfare la sua richiesta tempestivamente. Questo sistema,
attualmente usato dalla rete ED2K, premia le “amicizie” tra i nodi della rete, ma
trascura un fatto molto rilevante. Un nodo che mette a disposizione della rete
grandi risorse, e aumenta di molto la potenzialità della rete stessa, potrà, quin-
di, in prima approssimazione, esigere risorse solo dai nodi con cui ha già avuto
transizioni; per tutti gli altri nodi della rete, invece, avrà le stesse credenziali di
un nodo appena connesso. Se poi questi nodi dovessero sparire, il nodo fornitore
si ritroverebbe esattamente come un nodo appena entrato, avendo, in qualche
modo, sprecato le risorse che aveva condiviso coi nodi fuggiaschi. Inoltre, per

12
1.4 I CREDITI

garantire l’accrescimento della rete, si dovrebbe favorire i client che condividono


le risorse.
Per superare questo problema si potrebbe pensare all’adozione di una “mone-
ta” unica comune per tutta la rete, non solo per ogni coppia di nodi interlocutori.
Questo approccio però risulta estremamente complesso e insicuro. In primo luogo,
ci sarebbe il rischio che la moneta potesse soffrire di forti movimenti inflazioni-
stici, tali da precludere l’accesso alla rete da parte di nuovi nodi. In secondo
luogo, sarebbe necessaria la presenza di un’ autorità che regolamenti l’emissione
di questa moneta, ma questo entrerebbe in conflitto con la natura completamente
decentrata della rete.
Il sistema che noi proponiamo si basa su due pilastri fondamentali: il criterio
del buon emporista e il sacrificio.
Partendo dalla situazione precedentemente menzionata, assumiamo che Bob,
Alice, Charlie siano tre utenti della rete. Alice e Bob spesso concludono affari tra
loro cosı̀ come Alice e Charlie, mentre Bob e Charlie supponiamo non abbiano
mai avuto nessun contatto diretto. Immaginiamo ora che Charlie sia interessato
ad acquisire una risorsa di Bob. Putroppo, Charlie non è in credito con Bob e non
ha modo per aggiudicarsi tale risorsa. Alice, però, è fortemente indebitata con
Charlie. Charlie procederà quindi ad acquisire la risorsa grazie alla mediazione
di Alice, che risulta essere in debito con Charlie e in credito con Bob.
Il nocciolo della questione è questo: come Alice media questa transizione?
Alice si trova ad avere crediti verso diversi altri utenti che le vengono richiesti con
frequenze e quantità sempre diversi. Il suo scopo sarà quello di riuscire a compiere
queste mediazioni, guadagnando comqunue sulla transazione, non rimanendo mai
sprovvista di quei crediti che potrebbero servirle in futuro. Dovrebbe, sulla base
delle transazioni cui ha preso parte, grazie a dei filtri di Kalman o dei filtri
bayesiani, minimizzare la probabilità di non poter concludere gli affari che le
potranno interessare nel futuro. Quello appena illustrato è, appunto, il criterio
del buon emporista che deve cercare sempre di guadagnare non rimanendo mai
senza scorta di nessun prodotto che possa interessare ai clienti.
Per rendere agevole ad un nuovo nodo entrare nella rete senza aver nessuna
risorsa da condividere, senza rischiare che questi si approfitti della situazione, si
ricorre al sacrificio. Qualora, infatti, si permettesse ad un nodo appena entrato
di acquisire risorse senza cederne di sue, concedendogli di emettere dei suoi cre-
diti, si renderebbe estremamente facile la creazione di masse di nodi-sanguisuga.
Converrebbe, infatti, ai nodi non interessati allo sviluppo della rete, sferrare un

13
1. LE CARATTERISTICHE PECULIARI

attacco Sibilla4 verso la rete nel seguente modo:

1. il nodo si crea un’identità e si connette alla rete;

2. il nodo trova la risorsa che sta cercando, la acquisisce rilasciando al fornitore


i suoi crediti;

3. il nodo si sconnette e non torna mai più con quella identità in rete;

4. il nodo ri-esegue le fasi da 1 a 3 cambiando identità un numero indefinito


di volte.

Questo comportamento, assolutamente da evitare, penalizza i nodi onesti della


rete dilapidando le loro risorse in favore dei nodi-sanguisuga. Ma, se per il nodo
non fosse cosı̀ semplice cambiare identità o non gli fosse possibile emettere crediti,
il problema sarebbe risolto.
La nostra soluzione propone che un nuovo nodo che entra in rete non posso
indebitarsi, senza prima aver sprecato una certa quantità delle sue risorse. Un
utente novello che volesse acuisire una risorsa della rete, non avendo nulla con cui
scambiarla, e neppure altri crediti per procedere a una mediazione, sprecherebbe,
per esempio, la sua banda, come pegno della sua buona volontà, per comprare la
risorsa desiderata. È immediato realizzare che la quantità sprecata deve essere
non eccessivamente grande per non precludere l’accesso alla rete, nè troppo piccola
per fornire un efficace deterrente ai possibili nodi-sanguisuga. Questo spreco di
risorse, chiamato appunto sacrificio, permette, in fin dei conti, ad ogni nodo senza
risorse richieste di partecipare alla rete, proteggendola da utenti malintenzionati.
Questa visione “a volo d’uccello” su un ambito cosı̀ critico della nostra rete,
verrà comunque ripreso, approfondito e maggiormente argomentato nella tesi di
un collega.

4
Cfr. John R. Doceur, The Sybil Attack

14
Capitolo 2

Le componenti

Come precedentamente illustrato, per garantire una spinta modularità al client,


abbiamo optato per un’architettura a plug-in. A livello di struttura possiamo,
quindi, individuare il core, che permette il caricamento dei plug-in e le loro
comunicazioni, e i plug-in stessi. Esaminiamo in dettaglio quanto finora esposto.

2.1 Core
Il core assolve a due funzioni principali: caricare le classi già compilate che
contengono i plug-in e permettere ai plug-in di comunicare tra loro.
Per concedere la più ampia libertà possibile agli sviluppatori dei plug-in abbia-
mo cercato di limitare al massimo le richieste dell’interfaccia. Al momento, non
è addirittura possibile specificare un interface dato che l’unica richiesta strin-
gente è un vincolo sul costruttore. Al costruttore del plug-in, infatti, è necessario
passare come argomento il monitor del core. Se poi, come sembra evidente, il
plug-in necessita di comunicare con altri plug-in, lo sviluppatore portà spedire al
e ricevere dal monitor i messaggi di cui ha bisogno.
Il caricamento dinamico delle classi già compilate è stato affrontato ponendo
delle blande restrizioni sui nomi che le classi possono assumere e usando i package
di Java java.lang.ClassLoader e java.lang.reflect. Il nome che assume la
classe, e quindi anche il costruttore, è assunto come identificativo univoco del
plug-in per tutto il tempo in cui rimane attivo. Viene, quindi, passata la lista dei
nomi delle classi, che deve caricare, al core. Quest’ultimo carica le classi e invoca
i costruttori passando loro come argomento il monitor.
Il core, al momento della creazione degli oggetti plug-in, associa ad ognuno
una coda prioritaria. Ogni coda è assegnata ad un plug-in e contraddistinta dal
nome del plug-in stesso. Il plug-in, a questo punto, per comunicare con un suo

15
2. LE COMPONENTI

Figura 2.1: La Struttura del nucleo.

16
2.1 CORE

pari, semplicemente inserisce la sua richiesta nella coda del destinatario. L’even-
tuale risposta gli verrà recapitata direttamente nella propria coda. Il ricevente
deve continuare a fare polling della propria coda in attesa di messaggi diretti a
lui. Questo ciclo infinito tenderebbe a sprecare le risorse del sistema; proprio per
questo abbiamo scelto di usare la PriorityBlockingQueue. Questa struttura
dati già presente nelle JDK dalla versione 1.5, porge due caratteristiche molto in-
teressanti. In primo luogo incorpora nella coda già un monitor. Questo permette
al thread, che controlla la coda in attesa di nuovi messaggi, di andare in uno stato
di wait in caso di coda vuota e di non sprecare risorse. In secondo luogo poi, la
coda gestisce un sistema di priorità definibile sulla base di un comparatore che
abbiamo noi stessi specificato. In questo modo, in caso di congestione del core, si
può sperare che i messaggi con priorità più alta arrivino comunque a destinazione,
consentendo al core stesso di mantenere le sue normali funzionalità.
Da alcune prove che abbiamo eseguito, questo sistema sembra comportarsi
secondo le attese. Tuttavia possono sorgere problemi nel caso i plug-in produca-
no messaggi a una velocità molto maggiore della velocità con cui li consumano.
In tale evenienza, infatti, le code si riempiono e tendono a saturare la memoria
della JVM. Questo comporta il lancio di un’eccezione e l’arresto di tutto il core.
Per fronteggiare il problema, si è provveduto a limitare il numero di messaggi che
possono essere contemporaneamente in una coda, scartando gli ulteriori even-
tuali messaggi in arrivo. Questo escamotage, che sembra funzionare secondo le
previsioni, è tuttavia ampiamente migliorabile. Sarebbe auspicabile, infatti, un
controllo sulla priorità del pacchetto prima di decidere se scartarlo, o meno o
anche un approccio di tipo RED[2].
Questa struttura con un grosso monitor dotato di code è stato scelto per ov-
viare ad alcune limitazioni di Java. Se i plug-in avessero comunicato direttamente
tra loro senza passare da un monitor, ci sarebbe stato sicuramente un incremento
delle prestazioni (ci sarebbe stato, infatti, un passaggio in meno). In C/C++ si
sarebbero probabilmente potuti usare i puntatori per affrontare il problema. In
Java ci siamo invece affidati all’uso di un monitor opportunamente modificato:
una soluzione che permette anche di controllare i flussi di messaggi tra i plug-in.
Vediamo ora cosa sono esattamente questi messaggi. I messaggi trasmessi
tra i vari plug-in sono dei pacchetti caratterizzati quasi come dei datagrammi di
networking. Ognuno di questi pacchetti è formato da diversi campi che servono
ad indicare la provenienza e la destinazione del pacchetto, la priorità e il pay-
lod. Questi pacchetti, che abbiamo chiamato cocoon, corrispondono, se vogliamo
continuare il nostro parallelo col mondo delle reti, a datagrammi ip. Il payload

17
2. LE COMPONENTI

poi si differenzia a seconda della funzione che ha il messaggio e a seconda del


plug-in da cui proviene o a cui è destinato. Se, ad esempio, si tratterà di un
cocoon destinato a Connectivity, incapsulerà un oggetto flux che a sua volta
incapsulerà un oggetto triplaDati. flux corrisponderebbe quindi al protocollo
tcp e triplaDati ad un datagramma http.

Figura 2.2: L’incapsulamento dei messaggi.

Nel pacchetto core sono anche inseriti i manager per le risorse. Questi moduli
hanno il compito di assegnare e, in caso di conflitto, arbitrare le risorse. Queste
operazioni però, non dipendono esclusivamente dal resource manager competen-
te. L’assegnazione, infatti, si basa su un meccanismo che coinvolge il plug-in
richiedente e il modulo per la gestione dei crediti. Il plug-in che vuole usufruire,
ad esempio, di una certa quantità di spazio su disco, deve, infatti, richiederne
l’uso al gestore locale ma deve anche “pagare” al modulo per la gestione dei cre-
diti. La transazione tende a complicarsi nel caso in cui è un altro nodo della rete
a interrogare il client locale per usarne lo spazio. Infatti, il nodo remoto, deve
prendere contatto col plug-in locale per controllare la disponibilità del servizio,
e, poi, deve interagire col modulo di gestione crediti per accordarsi sul prezzo.
In locale, il plug-in accetta di fornire il servizio al nodo remoto previa verifica
di pagamento presso il modulo gestione crediti. Successivamente si fa carico di
chiedere l’allocazione della risorsa presso il gestore della risorsa competente. Il
gestore dovrà quindi, oltre ad accettare le richieste dei plug-in, controllare pre-

18
2.1 CORE

ventivamente la possibilità di assegnare risorse. Tornando all’esempio dello spazio


su disco, prima di prendere in carico i dati da salvare, il gestore deve assicurarsi
di avere abbastanza byte liberi da utilizzare.
Lo scenario si arricchisce pensando a quante e quali diverse possibili risorse
possono venire trattare dalla rete. Forniamo qui un elenco di risorse previste (e
di loro caratteristiche).

• Spazio su disco;

• cicli macchina;

• connettività:

– velocità;
– latenza;
– assenza di jitter.

Da queste risorse, che possono essere sfruttare dai vari plug-in, è possibile ricavare
diversi servizi. Si pensi, ad esempio, come un servizio di web hosting faccia uso
contemporaneamente di spazio su disco e connettività. In questo modo, all’utente,
è rischiesto di gestire servizi finiti, mentre la scomposizione di questi in risorse è
lasciata ai plug-in e ai gestori delle risorse.
Passiamo ora a illustrare i gestori delle risorse attualmente inclusi nel core.

2.1.1 Storage
Come già detto precedentemente, i gestori, hanno la medesima struttura dei plug-
in, si differenziano da essi solo per la loro funzione. I gestori, infatti, sono il
tramite tra il core, e i suoi plug-in, e le risorse della macchina su cui gira il client.
Essi, infatti, amministrano spazio su disco, banda e, nel futuro, cicli macchina.
dataStorage è il gestore che sovraintende lo spazio su disco. Attualmente pre-
senta una struttura piuttosto semplice, perché gestisce solamente qualche opera-
zione su file in locale. Questo gestore gestisce file interi tramite un handler di
Java. In questo modo il passaggio di un file da una parte all’altra del client non
comporta nessun accesso al disco, eliminando uno dei possibili colli di bottiglia del
client. Oltre file interi dataStorage lavora anche su pezzi di file, chiamati chunk.
dataStorage può ricevere da un plug-in dei chunk, senza che questi seguano ne-
cessariamente un ordine, e riassemblare il file, mantendo opzionalmente un certo
controllo nella ricostruzione. Questo gestore, infatti, può controllare che i chunk

19
2. LE COMPONENTI

non diano origine a deleteri fenomeni di overlapping. D’altra parte dataStorage


può inviare chunk su richiesta.
Il vero punto di forza di questo gestore è però da cercarsi non nelle sue attuali
capacità, ma nei suoi sviluppi futuri. Infatti inserire dataStorage tra il disco loca-
le e il plug-in equivale alla creazione di un nuovo layer intermedio. Questo layer
permette ai plug-in di non dovere cambiare i loro meccanismi interni di storing,
qualora cambiasse la natura del salvataggio. Quando sarà pronta l’infrastruttura
per il salvataggio di dati su diversi nodi della rete, il plug-in che vorrà sfruttare
questa nuova feature dovrà semplicemente cambiare il valore di un parametro nel
messaggio inviato a dataStorage. D’altra parte, grazie alla progettazione modu-
lare del gestore stesso, l’aggiornamento con la nuova caratteristica comporterà la
riscrittura di solo un paio di righe di codice.

Erasure coding

Questo, che è uno degli aspetti più innovativi di tutto il progetto, verrà qui solo
accennato senza alcuna pretesa di completezza. Sarà, infatti, esposto nella tesi di
Federico Sogaro. Scopo dell’erasure coding è modificare un file aggiungendo un
piccolo overhead in modo tale che in caso di irrecuperabilità di alcune sue parti il
file sia comunque ricostruibile. Uno schema di funzionamento possibile, anche se
descritto in maniera volutamente molto semplificata su un ipotetico file da 100
MB, segue.

1. Il file viene opportunamente modificato aggiungendo un 10% di overhead


arrivando ad occupare 110 MB;

2. il file viene scomposto il 110 pacchetti da 1 MB l’uno;

3. del file vengono recuperati 100 pacchetti qualsiasi;

4. tramite opportune manipolazione si ricostruisce il file iniziale.

Questo sistema permette, con relativamente poco overhead, e con un’efficien-


za molto maggiore della semplice ridondanza, il backup di grossi file sulla rete.
Esistono, inoltre, alcune sue versioni modificate, chiamate digital foutain la cui
vocazione è la trasmissione e non lo storage. Le digital foutain, infatti, applicano
il protocollo precedentemente descritto per scomporre il file e poi procedono a
spedire i pacchetti su protocolli veloci, ma inaffidabili, sulla rete, senza aspettare
mai nessuna conferma intermedia. I riceventi quindi recuperano una certa per-
centuale di pacchetti; quando ne hanno ricevuti abbastanza per poter ricostruire

20
2.1 CORE

il file, mandano un segnale di stop al mittente. Quando il mittente riceve tutti i


segnali di stop smette di erogare pacchetti. Il risultato probabilmente più signifi-
cativo è che la trasmissione tramite digital foutain su udp è più efficiente che la
trasmissione semplice su tcp.

Test eseguiti con le digital foutain hanno dimostrato di poter otte-


nere velocità di trasmissione dati fino a 10 volte maggiore rispetto
alle trasmissioni su tcp (condizioni con latenze elevate, come tra-
smissioni tra continenti diversi e perdita dei pacchetti dell’1%) Gli
erasure coding devono tuttavia usare erasure channel , cioè canali di
trasmissione dove i dati quando arrivano a destinazioni sono sicura-
mente corretti. Sono quindi necessari codici di individuazioni degli
errori per correggere ma principalmente scartare i pacchetti errati1
(udp checksum).

Purtroppo molte di queste tecnologie studiate negli U.S.A. risultano essere


già brevettate e quindi incompatibili con la licenza GPL da noi scelta. Tuttavia,
almeno per ora, possiamo usare queste tecnologie in ambito europeo grazie al
voto contrario alla brevettabilità del software del Parlamento Europeo2 .

2.1.2 Connettività
Questo secondo gestore presiede alla trasmissione e alla ricezione di byte. Il
package permette l’invio e la ricezione dati su protocollo udp e tcp. Scendere a
livello del protocollo ip non è purtroppo stato possibile dato che java non prevede
nativamente questa possibilità. A onor del vero usando alcune librerie come le
jpcap sarebbe stato possibile manipolare i pacchetti ip. Questo risultato sarebbe
arrivato però ad un costo troppo alto. Infatti le jpcap sono solo un wrapper
attorno alle celeberrime pcap (scritte in C). Usarle si sarebbe tradotto in:

• installare ulteriori librerie presso l’utente;

• permettere l’esecuzione del client solo con privilegi di root.

È chiaro che sono due condizioni che avrebbero troppo pesato sull’utente finale.
I plug-in che desiderano ricevere pacchetti dall’esterno, al loro avvio, preno-
tano una porta. Il gestore inoltrerà loro tutto quello che arriverà su quella porta
corredato con informazioni ausiliarie come la porta e l’indirizzo ip di partenza.
1
Cfr. http://sgharea.dyndns.org/mediawiki/index.php/Distributed Storage
2
Cfr. http://punto-informatico.it/p.asp?i=53935

21
2. LE COMPONENTI

Nel caso di comunicazioni su tcp, il plug-in che riceve il datagramma può spedire
la risposta sullo stesso socket su cui è arrivato il datagramma stesso.Il problema
non si pone per comunicazioni udp o singole tcp.
Connectivity verrà presto migliorato aggiungendo la possibilità di limitare la
banda da usare. Inoltre, nel momento in cui il modulo di anonimato risulterà
pronto, l’infrastruttura è disegnata per accoglierlo senza cambiare praticamente
nulla nel codice. Ai plug-in, quindi, basterà cambiare un campo nei messaggi
inviati a questo gestore per avvalersi di queste due nuove funzionalità.

2.2 Kademlia
Kademlia, come già annunciato, è il protocollo di ricerca su cui si basa PariPari
per essere completamente serverless. Inizialmente, abbiamo cercato di imple-
mentare quanto descritto nel paper di Petar Maymounkov e David Mazi‘eres [1]
quanto più fedelemente possibile.

Con lettera maiuscola vengono indicati i nodi;


Esempio: A, B, C.
Con lettera maiuscola corsiva vengono indicate le risorse;
Esempio: A, B, C.
X,Y indicano il nodo generico;
X , Y indicano l’hash generico;
IPC indica le informazioni utili a contattare C.
IDX = ID del nodo X.
hashB = hash della risorsa B.
Tabella 2.1: Pseudocodice: convenzioni

Ripassiamo ora i principi cardine del funzionamento di Kademlia. Kademlia


basa il suo funzionamento sulla metrica XOR. Ogni nodo è contrassegnato da un
codice identificativo univoco (d’ora in poi semplicemente ID). Ogni risorsa gestita
dalla rete è pure contraddistinta da un codice (d’ora in poi semplicmente hash)
appartenente allo stesso spazio di ID. Ogni nodo che entra nella rete assume,
quindi, un ID e calcola l’hash di tutte le sue risorse da condividere. Kademlia
calcola le distanze, interpretando come un intero lo XOR bit a bit dei due ID (o
dei due hash).
d(A, B) = IDA ⊕ IDB ;

22
2.2 KADEMLIA

Successivamente il nodo contatta i nodi i cui ID sono molto vicini all’hash delle
sue risorse e comunica loro le coordinate per essere raggiunto. In questo modo
ogni hash viene assegnato al nodo che più gli è vicino e la ricerca di una risorsa si
riduce alla ricerca di un nodo della rete. Il nodo che vuole cercare un altro nodo
nella rete conoscendone l’ID contatta i nodi che già conosce richiedendo infor-
mazioni sull’oggetto della sua ricerca. I nodi interrogati rispondono fornendogli
l’elenco dei nodi più vicini di cui loro hanno notizia. Successivamente, il nodo
cercatore, iterativamente, interrogherà dalla lista dei nodi ricevuti i più vicini a
quello cercato finchè questo ciclo non lo condurrà a contattare il nodo che voleva
trovare (vedi 2.2).

A cerca Z.

1. A per tutti i nodi che conosce calcola le distanze da Z:


d(Z, Xi ) = IDZ ⊕ IDXi ;
2. A ordina le distanze:
sort d(Z, Xi )
3. A sceglie le distanze minori
4. A interroga i nodi corrispondenti.
asks Xi
5. ogni nodo interrogato esegue le operazioni 1, 2 e 3.
6. ogni nodo interrogato invia ad A i suoi risultati:
Xi sends to A IPYi
7. A interroga i nuovi nodi più vicini di cui ha ricevuto le informazioni:
A asks Yi
8. A ripete questa procedura fino al rinvenimento di IPZ

Tabella 2.2: Pseudocodice: la ricerca in Kademlia

Volendo si può visualizzare questo schema di lavoro come una discesa lungo un
albero binario in cui le foglie corrispondono ai nodi della rete. Ad ogni salto della
ricerca si procede verso il basso escludendo mezzo sotto-albero fino ad arrivare
alla foglia cercata.
Per realizzare questo sistema abbiamo proceduto per fasi. Abbiamo prima
individuato la struttura interna che avrebbe dovuto avere il plug-in per poter sal-
vare, come descritto in [1], le informazioni riguardo i nodi con cui sarebbe entrato

23
2. LE COMPONENTI

0 1

00 01 10 11

000 001 010 011 100 101 110 111

Figura 2.3: Albero di Kademlia: ad ogni salto durante la discesa si elimina mezzo
sotto-albero.

in contatto. Successivamente si è focalizzata l’attenzione sulle comunicazioni che


sarebbero intercorse tra i vari nodi della rete. Sono stati individuati quattro RPC
principali:

• Ping;

• Find Value;

• Find Node;

• Store.

Abbiamo, quindi, provveduto a definire i datagrammi per contenre questi RPC e


le relative risposte. Si è proceduto a questo lavoro, tenendo sempre in mente la
scalabilità della struttura. La parametrizzazione pressochè completa del codice
permette, infatti, di poter cambiare al volo la lunghezza di hash e ID e, addirit-
tura, la possbilità di cambiare la metrica di misura delle distanze. Inoltre è ora
estremamente semplice poter aggiungere nuove funzionalità a Kademlia proprio
perché non tutti i bit dei datagrammi spediti (e ricevuti) sono completamente
usati. Abbiamo preferito sacrificare un po’ di velocità di trasmissione pur di
mantnere facilmente aggiornabile il protocollo.
Terminata l’architettura di base abbiamo, individuato due possibili miglio-
ramenti. Col modus operandi sopra descritto, ogni volta che il nodo cercatore

24
2.2 KADEMLIA

interroga un suo pari, prima di riprendere la ricerca deve aspettare la risposta.


Petar Maymounkov e David Mazi‘eres suggeriscono comunque di non aspettare
l’arrivo di tutte le risposte ma di iniziare subito a sondare i nuovi nodi per rispar-
miare tempo. Tuttavia, è nostra intenzione, usare Kademlia anche per fornire
serivizi in cui è indispensabile una latenza molto bassa. Per ottenere prestazioni
ancora migliori abbiamo, allora, pensato di introdurre una nuova funzionalità. Il
primo nodo, infatti, che chiameremo origine, oltre a comportarsi come descritto
in [1], sceglie, tra i nodi che deve contattare, un prediletto. Questo prediletto
inoltrerà direttamente la richiesta di ricerca a uno dei nodi che sta per trasmet-
tere come risposta all’origine. Questo avviene iterativamente ad ogni salto della
ricerca: il prediletto di prima generazione sceglie un prediletto tra i suoi nodi,
mentre trasmette la propria risposta direttamente all’origine. In questo modo,
nel caso la catena di prediletti non si interrompa, si arriva quasi a dimezzare il
tempo di ricerca (vedi 2.3).
Supponiamo, infatti, che tra l’origine e il nodo cercato ci siano 7 salti da
fare. Col metodo standard sarebbero necessari 12 comunicazioni per permettere
all’origine di conoscere l’indirizzo del nodo cercato.

comunicazioni = (distanza − 1) · 2

Invece, col nuovo sistema, in caso di successo, bastano 6 comunicazioni.

comunicazioni = distanza − 1

Assumendo che tutte le comunicazioni abbiano uguale durata, si avrebbe un


risparmio del 50% in termini di tempo. In caso di insuccesso, d’altra parte, le pre-
stazioni non verrebbero assolutamente variate dato che la ricerca continuerebbe
in parallelo seguendo il metodo standard.
Come scegliere il prediletto? La risposta più immediata potrebbe essere sce-
gliere un nodo a caso, ma questo non porterebbe a nessun risultato prevedibile.
Dato che questo miglioramento è stato concepito per accelerare la ricerca, abbia-
mo scelto di eleggere come prediletto il nodo il cui ID è più vicino all’ID del nodo
cercato. Un altro approccio potrebbe invece cercare di privilegiare il buon esito
della ricerca piuttosto che puramente la velocità. Petar Maymounkov e David
Mazi‘eres, studiando la rete Gnutella3 , hanno scoperto che statisticamente i nodi
che rimangono on-line a lungo hanno molte probabilità di rimanere attivi ancora
molto tempo. Sulla scorta di questo risultato si potrebbe scegliere come eletto il
nodo che è attivo da più tempo.
3
Cfr. [9]

25
2. LE COMPONENTI

A cerca Z col sistema del prediletto.

1. A per tutti i nodi che conosce calcola le distanze da Z:


d(Z, Xi ) = IDZ ⊕ IDXi ;
2. A ordina le distanze:
sort d(Z, Xi )
3. A sceglie le distanze minori
4. A sceglie tra i nodi con distanza minore il suo prediletto:D.
5. A interroga i nodi con distanze minori e chiede a D di scegliere un
prediletto.
A asks Xi
A asks as favorite D.
6. ogni nodo interrogato esegue le operazioni 1, 2 e 3.
7. D sceglie un suo prediletto,F ,tra i nodi selezionati e lo interroga
direttamente:
D asks as favorite F.
8. ogni nodo interrogato invia ad A i suoi risultati:
Xi sends to A IPYi
9. A interroga i nuovi nodi più vicini di cui ha ricevuto le informazioni:
A asks Yi
10. A ripete questa procedura fino al rinvenimento di IPZ

Tabella 2.3: Pseudocodice: la ricerca in Kademlia col sistema del prediletto.

26
2.2 KADEMLIA

Figura 2.4: Il sistema del prediletto.

27
2. LE COMPONENTI

Quest’ultima scelta però non assicura ancora che la ricerca tramite prediletto
termini con successo. Sarebbe più efficace che ogni nodo eleggesse un nume-
ro costante di prediletti; quest’approccio tuttavia comporterebbe l’esplosione del
problema inondando la rete di prediletti e, quindi, di comunicazioni. Sarebbe
preferibile riuscire ad utilizzare più di una catena di prediletti. Questo garan-
tirebbe una certa parsimonia nelle comunicazioni e una probabilità maggiore di
arrivare velocemente al nodo cercato. Ancora migliore sarebbe la possibilità di
far interagire le diverse catene di prediletti in modo che il loro numero sia sempre
costante. Nel caso una di queste arrivasse in un vicolo cieco potrebbe rigenerarsi
a partire da un nodo diverso fornito da un’altra catena. Questi, appena elencati,
sono i possibili miglioramenti che verranno nel prossimo futuro studiati e, quindi,
applicati al progetto.

2.3 Altri plug-in


Al momento sono in lavorazione diversi altri plug-in:

• web server (http);

• e-mail (smtp, pop3);

• host resolution (dns);

• file sharing (aMule).

Ci sono poi una serie di altri plug-in cui si procederà alla realizzazione quanto
prima:

• database distribuito (DBMS);

• newsgroup (nntp);

• chat (irc);

2.3.1 Web server (http)


Questo modulo permette la pubblicazione di pagine web su internet. Si rifà
all’RFC 2616 e quindi implementa il protocollo http 1.1. La sua peculiarità
è quella di sfruttare pesantemente l’infrastruttura del core e quindi attingere ai
file che deve ospitare tanto dal disco locale, quanto dal disco di altri client. Di
basilare importanza sarà l’utilizzazione di politiche dedite alla minimizzazione dei

28
2.3 ALTRI PLUG-IN

tempi di latenza. Alcune di queste strategie potrebbero essere la predizione delle


pagine da caricare e il caching locale di quest ultime.

2.3.2 E-mail (smtp, pop3)


Lo sviluppo di questo modulo segue RFC 1939, RFC 2821 e RFC 2822. Dei due
server, quello concettulamente più complesso da realizzare in modo distribuito è
il server pop3. Il problema è, infatti, quello di disperdere le e-mail per la rete
in modo che siano sempre disponibili qualora il destinatario volesse recuperarle,
senza dover dipendere dallo stato di un unico nodo. È ovvio, però, che le copie
delle e-mail dovranno comunque essere sincronizzate tra di loro. Per semplificare
leggermente questo problema, si è optato per salvare le e-mail col sistema maildir
(una mail, un file). Quando sarà completato il modulo DBMS, il sistema di
gestione delle e-mail verrà re-implementato avvalendosi di questo nuovo modulo.
Un altro grosso problema affligge, invece, il server smtp. Tutti i maggiori
server di posta mondiali, infatti, non accettano il relaying di posta da client con
indirizzo ip dinamico. Chiaramente, la stragrande maggioranza dei nodi della
rete, nonostante probabili tempi di uptime elevati, avranno ip dinamico. Una
soluzione per ora solo abbozzata sarebbe il dirottamento della posta fuori da
PariPari solo attraverso host con indirizzo statico.

ip dinamico

ip dinamico

ip dinamico

ip statico

stmp.gmail.com

Figura 2.5: Dirottamento di tutta la posta su host con ip statico.

In questo modo il modulo riuscirebbe a trasformare, anche per l’utente esterno,


PariPari in un server e-mail completo e affidabile.

29
2. LE COMPONENTI

2.3.3 Host resolution (dns)


Questo modulo, che implementa RFC 1034 e RFC 1035, rappresenta il punto
di ingresso per l’internauta alla nostra rete. In primo luogo, per semplicità, il
server dns attualmente non è distribuito, ma semplicemente copiato. Ci saran-
no, infatti, in PariPari diversi server tutti con lo stesso contenuto. Qualora un
utente esterno alla rete facesse richiesta di un servizio interno alla rete stessa,
interrogherebbe uno di questi server, il quale fornirebbe all’utente l’indirizzo cor-
retto della macchina che assolve a quel servizio. La sincronizzazione dei server
sia tra loro che con le macchine che svolgono servizi all’interno della rete sarà
una delle difficoltà da affrontare nella scrittura del modulo. È allettante inoltre
la possibilità di dotare di capacità di load balancing questi server dns.

Figura 2.6: Uso di server DNS da host esterni la rete.

2.3.4 File sharing (aMule)


Questo plug-in, secondo i punti di vista, è il più o il meno importante del progetto.
Semplicemente dovrebbe aggiungere al client di PariPari la possibilità di entrare
nella rete ED2K fornendo i servizi di client come eMule. Non dovrebbe riservare
grosse soprprese nè rivelarsi un ambito di ricerca, in quanto sarebbe una specie
clone di aMule con l’unica peculiarità di doversi integrare col core.
Il motivo dell’inclusione di questo modulo nel progetto è prettamente di natura
commerciale. La sua funzione, infatti, è quella di invogliare l’ignaro navigatore
a provare il software se non altro usandolo come portale di accesso per la più

30
2.3 ALTRI PLUG-IN

grande rete di filesharing attualmente in uso. L’utente avrebbe in seconda battuta


la possibilità di provare le innovative peculiarità del client. Quest’attenzione al
lancio del prodotto è dovuta al fatto che una rete P2P è tanto più interessante
per l’utente quanto più contenuti può offrire e i contenuti sono legati a doppio
filo al numero degli utenti4 .

4
Tipico caso di effetto rete. Cfr. http://en.wikipedia.org/wiki/Network effect

31
2. LE COMPONENTI

32
Capitolo 3

Management

Per affrontare un progetto cosı̀ vasto e diversificato, abbiamo proceduto alla crea-
zione di un gruppo di ricerca. L’importanza di questa organizzazione risulta ancor
più evidente pensando che i lavori proseguiranno per almeno un altro paio d’anni.
La presenza di un gruppo ben organizzato mette il progetto al riparo da evenienze
come la morte prematura dello stesso per abbandono dei partecipanti.
La struttura modulare del progetto ha, in qualche modo, suggerito un ap-
proccio divide and conquer. Ad ogni laureando, infatti, sono state assegnate la
progettazione e la realizzazione di uno o più plug-in (secondo la complessità del
plug-in e il tipo di laurea da conseguire.), sempre sotto la supervisione e il con-
trollo di quello che potremmo chiamare il coordinatore. Scopo del coordinatore
è proprio quello di assegnare i lavori (in accordo col prof. Peserico) e controllare
come questi vengano progettati e implementati. Ha anche la funzione di esperto
on-line per quegli studenti che non hanno ancora maturato una certa esperienza
di progettazione e programmazione in Java. Il coordinatore è anche il punto di
comunicazione tra gli studenti e il professore. Questo compito, oltre a permettere
di raccogliere le domande per riformularle in modo più efficiente e conciso per
l’interazione col relatore, genera una specie di effetto caching. Spesso, infatti, i
problemi sollevati sono uguali o simili tra loro, e perciò possono essere risolti in
modo più veloce. L’ultima funzione del coordinatore, ma forse la più significativa,
è proprio quella di rappresentare il trait d’union tra gli stessi coordinatori. Per
non disperdere il know-how è oltremodo importante che il coordinatore provveda
a trasferire le proprie conoscenze non scritte e documentate al suo successore.
Per progetti cosı̀ estesi, è molto utile per gli sviluppatori presenti e futu-
ri, la possibilità di comprendere la struttura e il funzionamento di quanto già
scritto. Per adempiere a questa necessità, ad ogni sviluppatore è richiesto di
commentare pesantemente il codice prodotto, e di scrivere qualche pagina di do-

33
3. MANAGEMENT

Figura 3.1: Organizzazione delle risorse umane.

34
3.0

cumentazione. Abbiamo scelto di adottare come lingua del progetto l’inglese per
evidenti motivi di internazionalizzazione. L’idea, poi, di fare ospitare il progetto
su sourceforge.net avvalora ancora di più questa scelta.
Nonostante la natura modulare, che permette il lavoro quasi indipendente
dei membri del gruppo, abbiamo trovato grossissimi problemi di comunicazione.
Tutti i moduli, infatti, devono cooperare tra loro ed è essenziale per i vari svi-
luppatori scambiarsi idee, consigli e richieste. Purtroppo, non è sempre stato
semplice gestire in modo organico le comunicazioni e le richieste dei vari studenti.

35
3. MANAGEMENT

36
Conclusioni

Abbiamo già notato, in questi pochi mesi di vita, come non sia per nulla semplice
gestire un progetto cosı̀ ambizioso. Oltre i problemi di ordine tecnico e logistico
che, in qualche modo, sono stati risolti, continuano a presentarsi problemi di or-
dine logico. Abbiamo tentato di mantenere la struttura del core il più semplice e
funzionale possibile1 proprio per permettergli di crescere e fornire tutte le funzio-
nalità che gli saranno richieste in futuro. Purtroppo, nonostante questo sforzo di
progettazione, è già accaduto di dover riscrivere completamente un modulo2 per
aggiungergli nuove caratteristiche indispensabili ad altri plug-in. È prevedibile
che, nonostante tutto, da oggi al giorno del lancio al pubblico del client, moltis-
simi altri saranno i problemi e le conseguenti correzioni in itinere. La speranza è
quella di avere impostato il progetto in modo che questi aggiustamenti in corso
d’opera siano i più semplici e più efficienti possibili, garantendo il migliore dei
substrati possibili per i plug-in presenti e futuri.

1
Principio KISS http://en.wikipedia.org/wiki/KISS principle
2
È stato completamente riscritto il modulo di connettività: Connectivity

37
CONCLUSIONI

38
Appendice A

Documentazione del progetto

A.1 Kademlia
This document describes our Kademlia implementation. This client is intended
to run over a connectivity layer allowing high scalability and high modularization.
Byte arrays moving between the Kademlia layer and connectivity layer are mana-
ged by a simple monitor. Kademlia, as described in [1], uses four logic RPC and
several ADT that store information about the net around a node. A description
of the implementation of the four RPC follows. We explain choices and policies
and finally most important pieces of code.
The main class of the package is KadAdt that provides all the primary low
level methods to operate on the basic structure of Kademlia. Besides this object
other threads maintain data consistency and the node running1 .
We analyze the whole package keeping in mind how it works, giving a tran-
sversal view of the involved classes.

A.1.1 ADT
In a Kademlia client there are three different main data structures.

1. the table of buckets;

2. the table of random bytes;

3. the table of store:

• the table of internal store;


• the table of external store.
1
Accepting new incoming connection.

39
Documentazione del progetto

Table of buckets

This table is built directly in the constructor of the class KadAdt. It is implemen-
ted by an array of Object. Each of these Object is an instance of different sizes2
dopArray.
dopArray is built coupling two simple arrays:

1. Long[];

2. tripla[].

The first one stores a long value3 that represents the timestamp obtained
running the java method System.currentTimeMillis. A -1 value in this field denotes
an empty tripla. So the erasing procedure4 consists simply in putting a -1 in
the long cell.
The second array holds instances of the class tripla.

The class tripla is a collection of three different Object. It is conceived to


represent a node on the net. In fact it is structured in the following way:

InetAddress ip represents the ip address of the node;

int port represents the port address on which the node is listening;

String Hash represents the ID of the node.

Table of random bytes

This table is built using brand new own made class called triplArray. This class
is composed by three different simple arrays:

1. Long[];

2. Byte[];

3. Object[].

The first one stores a long value5 that represents the timestamp obtained
running the java method System.currentTimeMillis. A -1 value in this field denotes
2
The size of the dopArray is defined according to the kademlia policies.
3
A long encapsulated in a Long.
4
And the initialization.
5
A long encapsulated in a Long.

40
Appendice

an empty tripla. So the erasing procedure6 consists simply in putting a -1 in


the long cell.
The second array holds the type of the sent request just to increase the
security allowing a further check on the answer.
The last array keeps the arrays of random bytes.
Besides this class there is another thread object that runs continuously to de-
lete the too old entries. This class is KadRnd and uses the methods in triplArray
to find the obsolete entries and to delete them.

Table of store

There are two different tables: the table that stores the node’s own links and the
table to store the link from other clients. They have the same structure and they
are implemented by the class store. This class is composed by three different
simple arrays:

1. Long[];

2. Vector[];

3. String[].

The first one stores a long value7 that represents the timestamp obtained
running the java method System.currentTimeMillis. A -1 value in this field denotes
an empty tripla. So the erasing procedure8 consists simply in putting a -1 in
the long cell.
The third field holds the hash of the resource whose link had to be saved.
Finally in the second field the client keeps a collection of instances of tripla,
that refers to the third field.
Besides this two tables, there is another thread called kadStore that keeps
the two tables refreshed. Continuously, at pre-defined time intervals, it deletes
the obsolete entries in the table that hosts external information and republishes
in the net the old entries in the other table.
6
And the initialization.
7
A long encapsulated in a Long.
8
And the initialization.

41
Documentazione del progetto

A.1.2 Communication
Since now we call communication the RPC and its reply. We’ve defined a
datagram for each communication; all of them have one header in common9 .

Byte Use Note


0 KaD version the version of the datagram
1,2 size the size of the whole datagram (max 64KB)
3 type the nature of the datagram
4,5,6,7 random byte

Here some more words about the third and the fourth field.
The type field describes the type of the datagram that follow. For each RPC
is assigned a byte value as you can see in this list.

1 ping;

2 ping reply;

4 ping check;

5 ping reply check;

6 ping sink check;

7 fing node;

8 fing node reply;

9 fing value;

10 fing value reply;

11 fing value reply ok;

13 store.

The random byte field is filled by four bytes randomly generated by the
client who send the request. The recipient replies embedding these four bytes
in the answer, this way the sender can understand the match for the answer to
the question. Moreover this practice increases the security level against malicious
datagram sent to a client.
9
Other parts of the datagram are in common but at the moment they aren’t in the header
in order to keep a more logic structure of the datagram.

42
Appendice

Ping

The PING RPC probes a node to see if it is on line.

This statement expresses the basic role of this RPC. Whenever a node receives
a ping, it answers and adds the sender to his table of buckets; the same
behavior must be honored for any other RPC received. Whenever a client receives
a ping it replies to the source with a ping reply (with ping reply) and then calls
the method insNodo. So the source receives the ping reply and processes it with
ping sink and erases from the table of random byte the random bytes of the
first request.
insNodo provides the functionalities to insert the node passed as argument
in the table of buckets. It calculates the distance with XOR metric10 and
selects the right bucket for insertion. If the bucket has at least one free cell the
node is straitforward inserted; otherwise the so called kadInsert thread is run.
kadInsert searches the right bucket11 for the oldest inserted node and then
tries to ping check12 it. If the old node replies, kadInsert refreshes the node in
the bucket; otherwise it replaces it with the new one.

Store

STORE instructs a node to store a (key; value) pair for later retrieval

As described by this statement this RPC purpose is to spread the information


in the network to find the host of a resource. In fact every node and every resource
is labeled by an hash in the same space. A node that wants to share a resource
publishes the hash to the right node. The recipient node holds in the external
store the tripla of the sender beside the hash and the timestamp. Meanwhile,
the sender holds in its internal store the tripla of the recipient, the hash of
the resource and the timestamp. The methods involved in these operations are
directStore and store sink.
Kademlia stores a resource hash in the ID closest node13 . This task is accom-
plished by the thread kadStorer. kadStorer calling other class and methods,
later examined, finds the right collection of nodes14 and instruct them sending a
store RPC as described above.
10
Provided by metric
11
Given as an argument
12
The series of ping check, ping reply check and ping sink check acts exactly as the normal
ping suite except fot the type, so they use the same method but different parameters.
13
One or more node in case resource hash 6= node ID.
14
Or just one.

43
Documentazione del progetto

Find Node

FIND NODE takes a 160-bit ID as an argument. The recipient of


a the RPC returns IP address; UDP port; Node ID triples for the k
nodes it knows about closest to the target ID. These triples can come
from a single k-bucket, or they may come from multiple k-buckets if
the closest k-bucket is not full. In any case, the RPC recipient must
return k items (unless there are fewer than k nodes in all its k-buckets
combined, in which case it returns every node it knows about).

The class that performs any kind of research on Kademlia is kadSearcher.


The kadSearcher thread undertakes several actions. First it searches the local
Table of buckets for the searched node ID. In case of unsuccesfull resear-
ch it puts α tripla in a Vector called cercatore. Finally it runs the th-
read inquirer. Furtermore it checks for any found condition launched by other
processes15 .
inquirer processeses all the tripla in cercatore as it follows.

1. It sends a fing node request to α unprocessed tripla received from the


same node and marks em as processed.

2. It waits any possible reply from the asked clients.

3. If the research id unsuccesfull it asks all the unprocessedtripla.

Find Value

FIND VALUE behaves like FIND NODE returning IP address; UDP


port; Node ID triples with one exception. If the RPC recipient has
received a STORE RPC for the key, it just returns the stored value.

As mentioned in A.1.2 the class that performs this kind of search is still
kadSearcher. The behaviour to find a value is very very similar to that to find
a node. Now we consider only the differences.
The recipient of a fing value checks its table of store to find recurrences of
the searched hash. If found it replies with fing reply sending the correct tripla16 .
15
fing sink in class kadAdt.
16
Otherwise it follows the behaviour of find node

44
Appendice

Find - favorite mode

This is a variation on Find Node and Find Value introduced to half the round trip
time. The searching node, while it proceeds with the default searching behaviour,
chooses a favorite among the nodes it is going to contact. This favorite node, other
than answering the searcher, chooses a favorite, called child, among the nodes it
is going to send to the requesting node. The favorite node asks its child directly
for the searched ID or hash and to choose another child to continue the chain of
favorites.

A.1.3 Classes
Here is a list of classes with a brief description.

kadAdt the main class;

kadSearcher a thread that searches;

kadStorer a thread that searches and then stores;

kadStore a thread that keeps in order the table of store;

inquirer a thread used by kadSearcher to search;

dopArray ADT to implement a bucket17 ;

triplArray ADT to implement table of random bytes;

cop ADT used in kadAdt18 ;

copHashComparator a comparator on hash in object cop used to sort triplas;

tripla ADT that represents a node on th net;

triplaDati ADT to exchange data with connectivity layer;

kadInsert a thread to insert a node in case of full bucket;

store ADT to implement a table of store;

metric static class with methods that calculate XOR distances;

kadCLI Command Line Interface;


17
An element of table of buckets
18
In cercatore

45
Documentazione del progetto

kadCommand the object to communicate with kad;

kadUI User interface called to complete kadCommand.

A.1.4 Datagrams
Here is a list of datagrams with a brief description.

Header
Byte Use Note
0 KaD version the version of the datagram
1,2 size the size of the whole datagram (max 64KB)
3 type the nature of the datagram
4,5,6,7 random byte

tripla
0,1,2,3 IP the tripla’s IPv4
4,5 port the tripla’s listening port
6 + hash length ID the tripla’s ID

Ping

Ping and Ping check


Byte Use Note
8,9 port the client’s listening port
10 + hash length ID the ID’s client
Ping reply
Byte Use Note
8,9 port the client’s listening port
10 + hash length ID the ID’s client

Store

Byte Use Note


8,9 port the client’s listening port
10 + hash length ID the ID’s client
10 + hash length + hash length hash the resources’s hash
10 + hash length + hash length + tripla length tripla the answered triplas

46
Appendice

Find Node

Find Node

Byte Use Note


8,9 port the client’s listening port
10 + hash length ID the ID’s client
10 + hash length + hash length ID the node’s ID

Find Node reply

Byte Use Note


8,9 port the client’s listening port
10 + hash length ID the ID’s client
10 + hash length + triplaS length triplas a list of triplas

Find Value

Find Value

Byte Use Note


8,9 port the client’s listening port
10 + hash length ID the ID’s client
10 + hash length + hash length hash the resources’s hash

Find Value reply

Byte Use Note


8,9 port the client’s listening port
10 + hash length ID the ID’s client
10 + hash length + triplaS length triplas a list of triplas

Find - favorite mode

Byte Use Note


8,9 port 019
10 + hash length ID the ID’s client
10 + hash length + hash length hash the resources’s hash
10 + hash length + hash length + tripla lenght tripla the searcher’s tripla

Other notes: the random bytes are the same20 along the whole favorites chain.
20
Decided by the first node.

47
Documentazione del progetto

A.2 Core
This document describes the implementation of the core. The core is designed to
be as simpler as possible keeping the ability to manage the most different kinds
of plug-in.
The core is formed by two main structures and it is surrounded by two resource
managers. The main purpose of the core is to launch the plug-ins and to provide
to them a structure to communicate. The resource managers are inteded to let
the plug-ins use local resource such as disk capacity and connectivity.

A.2.1 The core


The first role of the core is to launch the plug-in. This is the routine to accomplish
this mission:
1. It reads the file, knowing the name, with method java.io.FileInputStream.

2. It defines the bytes read as a class with defineClass;

3. It instantiates the new object with methods from class java.lang.reflect.


The bounds to allow these operations are the following:

• the plug-in name is equal to the file name;

• the core has to pass to the plug-in, as an argument, the object manager21 ;

Every launched plug-in is associated to a java.util.concurrent.PriorityBlockinQueue.


These associations are stored in a simple HashTable. Every request for another
plug-in has to be pushed in the right queue. Consequently, every plug-in has to
check its own queue for incoming requests. The requests have to be encapsulated
in a cocoon to travel in the core. Every plug-in can define the type of request
to receive, this request will be encapsulated in cocoon.
cocoon is composed by 5 fields:
priority an int that indicates the cocoon’s priority;

orig a String that indicates the plug-in that generates this cocoon;

data the real payload (Object);

signature a long useful to track the question - answer matching;

leave a String containing the name of the plug-in to which sending the answer.
21
That represent the core itself

48
Appendice

A.2.2 Resource manager


The resource manager follows exactly the same bounds and structure of the other
plug-ins. Currently they are dataStorage and Connectivity.

Connectivity

This resource manager provides the functionality to send and receive streams of
byte over internet. The message for this plug-in is the object flux:

order a String that indicates the action to undertake;

protocol a byte that indicates the protocol to use22 ;

data the real payload (triplaDati);

speed a int that indicates the bandwidth to use23 ;

anonimato not yet implemented;

socketID a long that indicates the tcp socket to use.

This resource manager handles both the udp and the tcp protocol. A plug-in
that wants to use a port to listen on, sends a “book” request to Connectivity.
All the traffic towards that port will be forwarded to the booking plug-in. In
case of tcp communication the plug-in can re-use the same socket from which it
received the data.

dataStorage

This resource manager provides the functionality to save and retrieve files24 . The
message for this plug-in is the object chunk:

order a String that indicates the action to undertake;

name a String that indicates file name;

position a long that indicates the offset to start writing or reading from;

data the payload stored in a byte[];


22
Now only tcp and udp
23
Not yet implemented
24
Now only local operation

49
Documentazione del progetto

destination a String containing the name of the plug-in to send the answer to;

fraction a int that indicates the part to write or read;

size a long that indicates the size of the file;

fileHandler a File that represents the file;

This plug-in can undertake three different operations. It can manage entire
files, it can operate over pieces of file in a dumb mode or in an ensured mode.
Entire files are simply handled with the handler of java. This resource manager
allows the plug-ins to deal with pieces of file. It can assemble the pieces to make
a whole file or it can read pieces in any order from (un)complete files. While
assembling, it can check for overlapping problems avoiding them.

A.2.3 Classes
Here is a list of classes with a brief description.

core the main core class;

loader the class loader;

manager the monitor containing the hastable;

cocoon class to define the message of the core;

accept class to accept incoming tcp connections;

Daccept class to accept incoming udp connections;

connect a class to manage connections;

Connectivity a wrapper class to start Connectivity;

connectServer a thread of Connectivity to check the queue for incoming


requests;

flux class to define the message of Connectivity;

storage a class to manage disk space;

chunk class to define the message of dataStorage;

dataServer a thread of dataStorage to check the queue for incoming requests;

50
Appendice

dataStorage a wrapper class to start dataStorage;

fileChunk an ADT to keep information about pieces of files.

51
Documentazione del progetto

52
Bibliografia

[1] Petar Maymounkov and David Mazi‘eres. Kademlia: A


Peer-to-peer Information System Based on the XOR Metric.
http://kademlia.scs.cs.nyu.edu.

[2] A. S. Tanenbaum. Reti di Calcolatori - Quarta Edizione. Pearson Education


Italia, Milano, 2003.

[3] E. Peserico, A. Simonetto Progettazione e realizzazione in Java di una rete


P2P anonima e multifunzionale: connettività sicura e affidabile. Padova,
2005.

[4] Wikipedia http://it.wikipedia.org/wiki/P2P.

[5] Wikipedia http://it.wikipedia.org/wiki/BitTorrent.

[6] Wikipedia http://en.wikipedia.org/wiki/Chord project.

[7] http://research.microsoft.com/~
antr/PAST/pastry.pdf.

[8] Wikipedia http://it.wikipedia.org/wiki/MUTE.

[9] Wikipedia http://en.wikipedia.org/wiki/Gnutella.

53
BIBLIOGRAFIA

54
Elenco delle figure

1 La rete e gli host esterni. . . . . . . . . . . . . . . . . . . . . . . . 5

1.1 La struttura del client. . . . . . . . . . . . . . . . . . . . . . . . . 9


1.2 Formazione di tunnel per la comunicazione anonima. . . . . . . . 12

2.1 La Struttura del nucleo. . . . . . . . . . . . . . . . . . . . . . . . 16


2.2 L’incapsulamento dei messaggi. . . . . . . . . . . . . . . . . . . . 18
2.3 Albero di Kademlia: ad ogni salto durante la discesa si elimina
mezzo sotto-albero. . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.4 Il sistema del prediletto. . . . . . . . . . . . . . . . . . . . . . . . 27
2.5 Dirottamento di tutta la posta su host con ip statico. . . . . . . . 29
2.6 Uso di server DNS da host esterni la rete. . . . . . . . . . . . . . 30

3.1 Organizzazione delle risorse umane. . . . . . . . . . . . . . . . . . 34

55
ELENCO DELLE FIGURE

56
Elenco delle tabelle

1.1 Crittografia: RSA vs AES. . . . . . . . . . . . . . . . . . . . . . . 11

2.1 Pseudocodice: convenzioni . . . . . . . . . . . . . . . . . . . . . . 22


2.2 Pseudocodice: la ricerca in Kademlia . . . . . . . . . . . . . . . . 23
2.3 Pseudocodice: la ricerca in Kademlia col sistema del prediletto. . 26

57
ELENCO DELLE TABELLE

58
Ringraziamenti

• Daniela perchè c’è per farmi tendere sempre al meglio,

• Davide per il suo uso dell’algebra booleana e la sua funzione di censore,

• Anna per come si è dedicata col sorriso a tutto il reparto,

• Lorenzo per come ha saputo gestire il S.Giorgio,

• E.P. per l’entusiasmo che infonde,

• l’allegra compagnia della fine degli esami,

• i compagni del gruppo di ricerca di PariPari (presenti e passati),

• e tutti coloro che hanno contribuito in qualche maniera al raggiungimento


di questo risultato.

entia non sunt multiplicanda sine necessitate.

— Guglielmo di Occam

Potrebbero piacerti anche