progettazione e realizzazione in java di una rete peer to peer ...

dei.unipd.it

progettazione e realizzazione in java di una rete peer to peer ...

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 distribuito 1 . Parallelamente,

è esploso il fenomeno del file sharing grazie a client estremamente semplici e

funzionali come eMule 2 . 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 cronaca 3 , 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 rete 4 .

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

Bittorrent 5 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-

tralizzati 6 . 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 Chord 7 , Pastry 8 , 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 probabilistico 9 . 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 Freenet 11 , che fornisce servizi di

webhosting anonimo e Skype 12 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 meglio 13 è 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

9Cfr. [8]

10Cfr. http://en.wikipedia.org/wiki/Network effect

11http://freenetproject.org/ 12http://www.skype.com/ 13Valutandolo 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 GPL 1 .

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.

1.2 Serverless

Figura 1.1: La struttura del client.

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 bit 3 . 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


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.

1.4 I CREDITI

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 Sibilla 4 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 errati 1

(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 Europeo 2 .

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

00

0 1

01

000 001 010 011

10

11

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 Gnutella 3 , 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


Figura 2.4: Il sistema del prediletto.

27

2.2 KADEMLIA


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:

prima:

• 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

• 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

stmp.gmail.com

ip dinamico

ip statico

ip dinamico

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 utenti 4 .

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


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.0


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 possibile 1 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 modulo 2 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 running 1 .

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 sizes 2

dopArray.

dopArray is built coupling two simple arrays:

1. Long[];

2. tripla[].

The first one stores a long value 3 that represents the timestamp obtained

running the java method System.currentTimeMillis. A -1 value in this field denotes

an empty tripla. So the erasing procedure 4 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 value 5 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 procedure 6 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 value 7 that represents the timestamp obtained

running the java method System.currentTimeMillis. A -1 value in this field denotes

an empty tripla. So the erasing procedure 8 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 common 9 .

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


Ping

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

Appendice

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 metric 10 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 bucket 11 for the oldest inserted node and then

tries to ping check 12 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 node 13 . This task is accom-

plished by the thread kadStorer. kadStorer calling other class and methods,

later examined, finds the right collection of nodes 14 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 = 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

processes 15 .

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 tripla 16 .

15 fing sink in class kadAdt.

16 Otherwise it follows the behaviour of find node

44


Find - favorite mode

Appendice

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 bucket 17 ;

triplArray ADT to implement table of random bytes;

cop ADT used in kadAdt 18 ;

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

tripla

Ping

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

Ping and Ping check

Store

Ping reply

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

Byte Use Note

8,9 port the client’s listening port

10 + hash length ID the ID’s client

Byte Use Note

8,9 port the client’s listening port

10 + hash length ID the ID’s client

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


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

Appendice

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 0 19

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 same 20 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 manager 21 ;

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


A.2.2 Resource manager

Appendice

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 use 22 ;

data the real payload (triplaDati);

speed a int that indicates the bandwidth to use 23 ;

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 files 24 . 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


dataStorage a wrapper class to start dataStorage;

fileChunk an ADT to keep information about pieces of files.

51

Appendice


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

More magazines by this user
Similar magazines