progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in...

88
UNIVERSITÀ DEGLI STUDI DI TRIESTE FACOLTÀ DI INGEGNERIA Tesi di Laurea Specialistica in INGEGNERIA INFORMATICA PROGETTO E REALIZZAZIONE DI UN KERNEL LINUX PER IL CONTROLLO DINAMICO DEGLI STIMATORI DI PERDITA SEGMENTI IN TCP Relatore Laureando Chiar.mo Prof. Alberto Bartoli Myrteza Kertusha Anno Accademico 2011/2012

Upload: myrteza-kertusha

Post on 13-Jun-2015

489 views

Category:

Documents


0 download

DESCRIPTION

Tesi formato pdf

TRANSCRIPT

Page 1: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

UNIVERSITÀ DEGLI STUDI DI TRIESTE

FACOLTÀ DI INGEGNERIA

Tesi di Laurea Specialistica in

INGEGNERIA INFORMATICA

PROGETTO E REALIZZAZIONE DI UN

KERNEL LINUX PER IL CONTROLLO

DINAMICO DEGLI STIMATORI DI PERDITA

SEGMENTI IN TCP

Relatore Laureando

Chiar.mo Prof. Alberto Bartoli Myrteza Kertusha

Anno Accademico 2011/2012

Page 2: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

1

INDICE

Indice delle figure .............................................................................................................................. 3

Introduzione ....................................................................................................................................... 4

1 Architettura ..................................................................................................................................... 6

1.1 Registrazione RTT e RTO ........................................................................................................... 6

1.1.1 Utilizzo ............................................................................................................................... 7

1.2 Formula aggiornamento dinamico RTO .................................................................................... 8

1.2.1 Utilizzo ............................................................................................................................... 9

1.2.1.1 Gestione formula per calcolo RTO ............................................................................. 9

1.2.1.2 Associazione ‘formula-connessione’ ......................................................................... 9

2 Implementazione .......................................................................................................................... 11

2.1 Registrazione RTT e RTO ......................................................................................................... 11

2.1.1 Contesto kernel ............................................................................................................... 11

2.1.1.1 Kernel built-in .......................................................................................................... 12

2.1.1.2 Modulo kernel ......................................................................................................... 15

2.1.2 Contesto utente ............................................................................................................... 17

2.1.2.1 Skeleton contesto kernel ......................................................................................... 17

2.1.3 Descrizione grafica .......................................................................................................... 18

2.2 Formula RTO ........................................................................................................................... 20

2.2.1 Contesto kernel ............................................................................................................... 20

2.2.1.1 Kernel built-in .......................................................................................................... 20

2.2.1.2 Modulo kernel ......................................................................................................... 23

2.2.2 Contesto utente ............................................................................................................... 24

2.3 Scelte implementative ............................................................................................................ 25

2.3.1 Interfaccia tra I due contesti ........................................................................................... 26

2.3.2 Accesso concorrenziale ................................................................................................... 27

2.3.3 Rilascio delle risorse ........................................................................................................ 28

3 Benchmark .................................................................................................................................... 32

3.1 Impatto modifiche apportate allo stack TCP .......................................................................... 33

Page 3: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

2

3.2 Impatto sessione di registrazione ........................................................................................... 36

4 Casi di studio ................................................................................................................................. 39

4.1 Formula ‘chu’ .......................................................................................................................... 40

4.1.1 Connessioni outgoing ...................................................................................................... 42

4.1.2 Connessioni incoming ...................................................................................................... 49

4.1.3 Riassunto ed osservazioni ............................................................................................... 52

4.2 Formula ‘speedy’ .................................................................................................................... 53

4.2.1 Connessioni outgoing ...................................................................................................... 55

4.2.2 Riassunto ed osservazioni ............................................................................................... 61

Conclusioni ....................................................................................................................................... 63

Referenze ......................................................................................................................................... 65

Appendice ........................................................................................................................................ 66

Page 4: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

3

INDICE DELLE FIGURE

Figura 2.1 Strutture di supporto alla registrazione RTT e RTO .................................................................................... 12

Figura 2.2 Associazione tra strutture di supporto alla registrazione e quella sock ..................................................... 13

Figura 2.3 Sessione di registrazione RTT e RTO. Buffer i – 2: già elaborato; i – 1: pieno, da elaborare; i + 2:

ancora da riempire ...................................................................................................................................................... 19

Figura 2.4 Associazione tra strutture di supporto all’aggiornamento dinamico di RTO e quella sock ........................ 21

Figura 2.5 Rilascio risorse relative ad una sessione di registrazione (1 di 2) ............................................................... 30

Figura 2.6 Rilascio risorse relative ad una sessione di registrazione (2 di 2) ............................................................... 31

Figura 3.1 Ambiente di test. Macchina A (Vbox): kernel NON modificato; macchina B (Vbox): kernel

modificato; macchina C: server in ascolto, in esecuzione sulla macchina ospite (Windows7) .................................... 34

Figura 3.2 Confronto in base alla “durata di upload” ................................................................................................. 35

Figura 3.3 Ambiente di test. Macchina A (Vbox): kernel modificato; macchina B (Vbox): kernel modificato

sessione di registrazione in atto; macchina C: server porta 80 in locale ..................................................................... 37

Figura 3.4 Confronto in base alla “durata di upload” ............................................................................................... 388

Figura 4.1 Ambiente di test ......................................................................................................................................... 42

Figura 4.2 Confronto in base alla “durata di upload” ................................................................................................. 43

Figura 4.3 Confronto in base alla “densità di probabilità” e “distribuzione cumulativa” ........................................... 43

Figura 4.4 Confronto in base alla “durata di upload” e “syn inviati” .......................................................................... 44

Figura 4.5 Confronto in base alla “densità di probabilità” e “distribuzione cumulativa” ........................................... 45

Figura 4.6 Ambiente di test ......................................................................................................................................... 46

Figura 4.7 Confronto in base alla “durata di upload” e “syn inviati” .......................................................................... 47

Figura 4.8 Confronto in base alla “densità di probabilità” e “distribuzione cumulativa” ........................................... 48

Figura 4.9 Confronto in base alla “durata di download” e “synack inviati” ................................................................ 50

Figura 4.10 Confronto in base alla “densità di probabilità” e “distribuzione cumulativa” ......................................... 51

Figura 4.11 Riassunto risultati ..................................................................................................................................... 52

Figura 4.12 Ambiente di test ....................................................................................................................................... 54

Figura 4.13 Confronto in base alla “durata di upload” e “rto scaduti” ....................................................................... 55

Figura 4.14 Confronto in base alla “densità di probabilità” e “distribuzione cumulativa” ......................................... 56

Figura 4.15 Confronto in base alla “durata di upload” e “rto scaduti” ....................................................................... 57

Figura 4.16 Confronto in base alla “densità di probabilità” e “distribuzione cumulativa” ......................................... 58

Figura 4.17 Confronto in base alla “durata di upload” e “rto scaduti” ....................................................................... 59

Figura 4.18 Confronto in base alla “densità di probabilità” e “distribuzione cumulativa” ......................................... 60

Figura 4.19 Riassunto risultati ..................................................................................................................................... 61

Page 5: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

4

INTRODUZIONE

TCP è un protocollo affidabile, che garantisce la trasmissione dei dati tra due endpoint

costituenti la connessione. Tale obiettivo viene raggiunto attuando delle politiche di

ritrasmissione. L’endpoint trasmittente, in mancanza di conferma dell’avvenuta ricezione

dei dati dall’endpoint remoto entro un tempo prestabilito (a causa di ritardi di rete o di

perdita), deve ritrasmettere i dati non ancora confermati. Essi vengono inviati nuovamente

allo scadere di RTO (Retransmission Timeout), grandezza stimata del timeout di

ritrasmissione ed aggiornata dinamicamente anche in base a RTT (Round Trip Time),

grandezza misurata del tempo d'andata e ritorno.

Le formule per l’aggiornamento dinamico di RTO utilizzate nei sistemi operativi odierni

sono quelle che col tempo si sono dimostrate migliori nei contesti più generici. In alcuni

campi particolari, tuttavia, in funzione dell'utilizzo (data streaming, command protocol,

ecc) oppure del mezzo di comunicazione (intranet vs internet, wired vs wireless, ecc),

formule alternative possono portare a risultati migliori. Tale formula per poter essere

utilizzata in un contesto reale, deve però essere sottoposta ad un processo iterativo di

analisi e test, al fine di valutare la sua efficacia e/o efficienza.

In questa tesi è stata costruita un infrastruttura basata su kernel Linux che consente di:

• ottenere informazioni sui valori di RTT e RTO relativi ad una connessione

• modificare la formula per l’aggiornamento dinamico di RTO: essa può essere

associata ad una singola connessione oppure a tutto il sistema

Grazie all’infrastruttura oggetto di questa tesi, è possibile modificare la formula per il

calcolo di RTO e testarne immediatamente gli effetti introdotti nella comunicazione, senza

dover far ripartire il sistema operativo, o tanto meno ricompilare il kernel. Volendo

analizzare più in dettaglio suddetti effetti si può accedere ai valori RTT e RTO relativi ad

una connessione TCP.

Il primo capitolo, Architettura, offre una panoramica generale dell’infrastruttura proposta.

Ulteriori dettagli realizzativi seguono nel secondo capitolo, Implementazione. La

Page 6: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

5

valuazione dell’impatto dovuto alle modifiche apportate, sulle performance del sistema è

l’argomento del terzo capitolo, Benchmark. Nel quarto capitolo, Casi di studio, vengono

analizzati due casi di studio utilizzando l’infrastruttura proposta.

Page 7: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

6

1. ARCHITETTURA

Da un punto di vista architetturale l’infrastruttura proposta è composta da due sottosistemi.

Al primo spetta il compito di bufferizzare i valori RTT e RTO in strutture dati in memoria,

nel contesto kernel, quindi la loro esportazione in quello utente per ulteriori elaborazioni. Il

secondo sottosistema invece, riguarda la formula per l’aggiornamento dinamico di RTO:

come crearle e/o modificarle, aggiungerle nel sistema ed infine associarle alle connessioni

TCP. Nonostante lo scopo del primo sottosistema è quello di rendere disponibili utili

informazioni al secondo, ognuno dei due può esistere indipendentemente dall’altro.

1.1 Registrazione RTT e RTO

I valori di RTT e RTO vengono calcolati quindi aggiornati nel contesto kernel. Le

condizioni per le quali questo avviene sono le seguenti:

• avvenuta ricezione di un pacchetto o insieme di

nel qual caso RTT e RTO vengono aggiornate

• timeout d’avvenuta ricezione per un pacchetto o insieme di

nel qual caso RTO viene aggiornata

• connessione appena stabilita

nel qual caso RTO viene aggiornata

• errore ‘host unreachable’ pervenuto dal modulo icmp

nel qual caso RTO viene aggiornata

Ogni volta che una delle condizioni di sopra ha luogo, i valori vengono memorizzati nelle

apposite strutture dati in memoria. La memorizzazione riguarda sia RTT che RTO

indipendentemente dalla condizione verificata. Può essere pensata come un’istantanea di

RTT e RTO, il cui scatto avviene a fronte di una delle condizioni di cui sopra. Assieme ai

Page 8: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

7

valori di RTT e RTO vengono memorizzati l'istante temporale e il tipo di condizione

verificatasi al fine poter distinguere successivamente nella fase di elaborazione.

Con l'utilizzo di un modulo kernel i valori bufferizzati vengono resi disponibili al contesto

utente. Pertanto vengono creati, durante la fase di boot, una serie di device il cui scopo è

proprio quello di accedere alle funzionalità del modulo kernel. Per accedere ai dati

d’interesse è stato implementato un ulteriore layer al fine di semplificare quanto più

possibile il processo da parte dell'operatore. L'unico compito spettante al programmatore è

appunto l'elaborazione stessa dei dati.

1.1.1 Utilizzo

Segue una breve descrizione, di una sequenza d’operazioni da eseguire per accedere ai

valori RTT e RTO relativi ad una connessione.

• apertura device

l'esecuzione di questa operazione richiede le seguenti informazioni passate a loro

volta tramite una struttura come parametro in ingresso:

o device

che verrà utilizzato come punto di ingresso al contesto kernel

• inizio sessione di registrazione

il concetto di sessione di registrazione è inteso come "registrazione dati in corso".

L'inizio della sessione richiede le seguenti informazioni passate a loro volta tramite

una struttura come parametro in ingresso:

o connessione tcp

identificata con la coppia [(ip:port)src, (ip:port)dst] ai quali valori di RTT e

RTO si dichiara l’interesse

o callback

Page 9: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

8

“un puntatore di funzione” nel contesto utente, che viene chiamato dal

contesto kernel in presenza di dati nuovi da elaborare

Nel caso l’operazione avesse esito positivo la connessione scelta non sarà più

disponibile per un’altra sessione di registrazione se non alla fine di quella già in

corso

• fine sessione di registrazione

alla fine di questa operazione, la connessione scelta diventa disponibile per una

successiva sessione di registrazione

• chiusura driver

La 2° e 3° operazione, ovvero inizio e fine di una sessione di registrazione, possono essere

reiterate pur utilizzando lo stesso device aperto, mantenendo però l’ordine. In questo modo

è possibile attuare più di una sessione in sequenza. Da evidenziare il fatto che la sessione

attiva ha l’esclusività sul device: non è possibile attuare una ulteriore se non alla fine di

quella già in corso. Per scelta, è stato preferito la semplicità di utilizzo (apertura di un

ulteriore driver) alla complesità richiesta (demultiplexing, api più complesse).

1.2 Formula aggiornamento dinamico RTO

Il secondo sottosistema riguarda la formula per l’aggiornamento dinamico di RTO. Esso

consente di creare e/o modificare, aggiungere e/o rimuovere le formule dal sistema. Inoltre,

è possibile impostare una formula di default (utilizzata da tutte le connessioni create da

quel momento in poi) oppure a scelta, specificatamente ad una connessione.

La formula per il calcolo di RTO utilizzata dal kernel è proposta nella forma di una

funzione. Tale funzione è presente nel codice kernel, quindi apportare modifiche equivale

ad una ricompilazione dello stesso. Purtroppo questa operazione richiede un tempo di

esecuzione non indifferente.

Page 10: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

9

Con lo strumento proposto in questa tesi, la formula per l’aggiornamento dinamico di RTO

viene caricata sotto forma di un modulo kernel. In questo modo essa si può modificare

senza dover ricompilare il kernel. Nel kernel vi sono state apportate delle modifiche al fine

di rendere disponibili tali moduli allo stack TCP. I moduli implementano le funzionalità

basi tra le quali la funzione che appunto aggiorna il valore RTO. Tale funzione viene

chiamata ogniqualvolta RTO viene aggiornata. La formula attualmente in uso nel kernel è

stata implementata come modulo, caricato automaticamente in fase di boot del sistema.

Utilizzando l'interfaccia ioctl-sockopt è possibile associare una formula a scelta tra quelle

disponibili nel sistema, ad una specifica connessione TCP. Infine utilizzando l'interfaccia

sysfs si può impostare una formula tra quelle disponibili come default.

1.2.1 Utilizzo

L'utilizzo della funzionalità offerta comprende da una parte la possibilità di modificare le

formule e dall'altra quella di associare esse ad una specifica connessione a scelta.

1.2.1.1 Gestione formula per calcolo RTO

La formula viene implementata nella forma di un modulo kernel. La creazione della

formula quindi, equivale all'implementazione del modulo kernel. L'aggiunta e la rimozione

invece equivalgono all’inserimento ed alla rimozione di essa dalla lista dei moduli

disponibili.

Tramite l’interfaccia sysfs del kernel è possibile impostare una delle formule disponibili

come default. Ogni connessione nuova, se non diversamente specificato, utilizzerà la

formula di default per il calcolo dinamico di RTO.

1.2.1.2 Associazione ‘formula 2 connessione’

L’associazione di una specifica formula per l’aggiornamento dinamico di RTO ad una

connessione è realizzabile tramite l’utilizzo di due diverse interfacce. La prima interfaccia

è quella tipica per la configurazione delle connessioni tcp (setsockopt). Chiamare la suddetta

Page 11: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

10

syscall con il nome della formula scelta fa si che da quel istante in poi la, i valori di RTO

vengano calcolati con quella formula. E’ il caso di evidenziare che tale syscall implica che

la connessione TCP sulla quale si vuole intervenire è stata creata dal processo che sta

effettuando la chiamata stessa. Quest’ultimo è dovuto al fatto che il parametro passato in

ingresso alla setsockopt (file descriptor con la quale si identifica la connessione TCP), non è

dato a sapere se non nel contesto del processo dove la connessione stessa è stata creata.

Come seconda interfaccia, si può utilizzare quella per la sessione di registrazione dei valori

di RTT e RTO. Una volta aperto il device ed iniziata la sessione di registrazione, si può

utilizzare la funzionalità del device per l’impostazione di una formula specificatamente ad

una connessione TCP. In questo modo si ha la possibilità di intervenire anche su una

connessione creata da un altro processo.

Page 12: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

11

2. IMPLEMENTAZIONE

In questo capitolo viene fatta una descrizione più dettagliata dell’infrastruttura proposta.

Riallaciandosi all’aspetto funzionale, verrà puntata la lente d’ingrandimento su ognuno dei

due sottosistemi. La loro descrizione riguarderà l’implementazione sia nel contesto kernel

che quello utente. Per poi proseguire con una discussione su varie scelte implementative

fatte.

2.1 Registrazione RTT e RTO

La registrazione dei valori di RTT e RTO avviene sia nel contesto kernel che quello

utente. Nel contesto kernel, l’implementazione segue delle linee guida con un occhio di

riguardo alla prestazione ed alla stabilità. Un possibile errore in questo contesto

renderebbe il tutto instabile ed addirittura inutilizzabile. Nel contesto utente invece,

l’obiettivo è stato quello di fornire api ben progettate e semplici da utilizzare.

2.1.1 Contesto kernel

L’implementazione nel contesto kernel riguarda una componente “statica”, di supporto per

l’intera infrastruttura. In questa categoria fanno parte tutte le modifiche apportate nella

struttura del kernel che richiedono la sua ricompilazione. Le modifiche apportate alla

struttura sock, i punti individuati nel kernel ove le condizioni si verificano ne fanno parte.

La seconda categoria riguarda la parte “dinamica”, le cui modifiche non necessitano la

ricompilazione. Il modulo che si interfaccia con il contesto utente per l’esportazione dei

dati ne fa parte.

Page 13: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

12

2.1.1.1 Kernel built2in

Il termine built-in rende meglio l’idea sull’argomento di questo paragrafo. Infatti riguarda

tutte le modifiche integrate nel kernel stesso. Le modifiche fanno da ponte tra il kernel e la

nuova infrastruttura.

• strutture nuove aggiunte

La struttura zsample_buffer è il buffer dove i valori RTT e RTO vengono

bufferizzati. Essa ospita inoltre, delle variabili con le quali tra i due contesti viene

attuato del protocollo di comunicazione. La struttura zsample_buffer_holder è un

insieme di zsample_buffer. La suddivisione della memoria disponibile in tanti

buffer diminuisce la possibilità di problemi dovuti all’accesso concorrenziale.

Figura 2.1 Strutture di supporto alla registrazione RTT e RTO

La struttura zsample_sniff_session contiene tutto il necessario per una sessione di

registrazione. Essa contiene un riferimento all’array di buffer ove i valori RTT e

RTO vongono memorizzati. L’accesso al modulo è reso possibile con un

Page 14: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

13

‘puntatore di funzione‘ (take_sample). Infine, con la presenza di variabili flag, il

rilascio della memoria relativa alla sessione viene fatto in tutta sicurezza.

• associazione tra la connessione TCP e le strutture nuove

la struttura di supporto, zsample_sniff_session, viene associata a quella sock

indirettamente tramite una ulteriore, la zsample_sock_sniff_session_wrapper. In

questo modo si disaccoppia il corso d’azione tra lo stack TCP ed il modulo kernel.

Il processo che si occupa del rilascio delle risorse utilizza appunto questa struttura

per riconoscere se una connessione è chiusa, quindi rilasciare la relativa memoria

occupata da sessioni di registrazione.

Figura 2.2 Associazione tra strutture di supporto alla registrazione e quella sock

Le modifiche apportate alla struttura sock riguardano sia la registrazione che

l’utilizzo della formula per l’aggiornamento dinamico di RTO. I campi che

riguardano la registrazione sono necessari per la bufferizzazione e per il rilascio

Page 15: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

14

delle relative risorse. Invece i campi che riguardano l’aggiornamento dinamico

forniscono delle informazioni utili concernenti la connessione durante la fase

3WHS.

• inserite nel codice kernel le chiamate per la bufferizzazione dei dati

nel codice del kernel, nei punti dove le condizioni di aggiornamento di RTT e/o

RTO hanno luogo, sono state apportate delle funzioni. Tramite esse il corso

d’esecuzione viene instradato verso l’infrastruttura proposta. Ogni chiamata ha

come parametri la struttura sock appartenente ed il tipo di condizione verificata.

• sessioni di registrazione

onde permettere la registrazione dei valori RTT e RTO sono state implementate

delle api visibili solo nel contesto kernel (tipicamente i moduli).

o int take_sample(struct sock *sk, int origin, void *data)

la funzione con la quale il corso d’azione dello stack viene instradato nel

modulo kernel. L’implementazione di questa api consiste in una serie

opportuni controlli affinche i riferimenti alle varie strutture siano validi.

Successivamente viene fatta la chiamata al ‘puntatore di funzione’ (vedasi

zsample_sniff_session) definita nel modulo kernel. Tale funzione viene

chiamata ogni volta che una delle condizioni d’aggiornamento di RTT e

RTO ha luogo.

o struct zsample_sniff_session* connectionSearch(unsigned int saddr, unsigned int daddr, unsigned short sport, unsigned short dport, int *ret)

è la funzione che si occupa di individuare tra le connessioni attualmente

stabilite, quella identificata dai parametri in ingresso. Tale funzione viene

chiamata dal modulo kernel quando l’utente indica interesse nel registrare i

valori RTT e RTO di una connessione TCP. Nel caso la connessione

venisse individuate, la struttura zsample_sniff_session viene creata, quindi

ritornata come parametro di return. Qualora la connessione non venisse

Page 16: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

15

individuata oppure non fosse disponibile in quanto già utilizzata in un’altra

sessione il parametro ritornato è NULL.

o int connectionRelease(struct zsample_sniff_session *rttKernel)

tale funzione termina la sessione di registrazione. Successivamente la

connessione diventa disponibili a future sessioni e le relative risorse

vengono liberate. Le condizioni per cui una sessione di registrazione viene

terminata sono per scelta dell’applicativo nel contesto utente oppure perchè

la connessione TCP viene chiusa.

• processo di rilascio delle risorse

è il processo che si occupa del rilascio delle risorse dopo che una sessione di

registrazione viene terminata. Esso viene fatto partire già durante il boot del

sistema. Il suo compito è quello di mantenere traccia in una lista globale, di tutte le

strutture create come supporto alle sessioni di registrazione. Ad ogni sessione

nuova corrisponde un inserimento della relativa struttura nella lista globale (vedasi

connectionSearch). Rispettivamente ad ogni sessione terminata la relativa struttura

viene segnata come ‘da rimuovere’ (vedasi connectionRelease). Il rilascio della

memoria viene fatto in modalità deferred, ovvero posticipata per eliminare

l’overhead dovuto alla protezione dell’accesso concorrenziale tra lo stack tcp ed il

modulo kernel.

2.1.1.2 Modulo kernel

Le funzionalità integrate nel kernel vengono esposte al contesto utente con l’utilizzo dei

moduli kernel. Il loro compito è quello di interfacciarsi da una parte con lo stack TCP e

dall’altra con il contesto utente. Con il contesto utente tale interfacciamento è reso

possibile tramite un device a caratteri: infatti durante la fase di boot del sistema vengono

creati una serie di device, come specificato in /etc/rc.d/rc.modules. Invece dallo stack TCP il

modulo è raggiungibile tramite le api introdotte nella sezione precedente (vedasi

take_sample). Tale modulo viene caricato già nella fase di boot del sistema, come specificato

Page 17: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

16

in /etc/rc.d/rc.modules.

Interfaccia con il contesto kernel

Il modulo implementa la funzione take_sample (distinta da quella dello stesso nome

integrata nel kernel) che svolge effettivamente l’operazione di bufferizzazione dei valori

RTT e RTO. L’implementazione volutamente viene fatta nel modulo affinche sia

facilmente modificabile. E’ compito suo bufferizzare i dati opportunamente e soprattutto

notificare il contesto utente in caso si verifichi una condizione particolare (es. buffer

riempito ecc). Quando una sessione di registrazione inizia, uno dei parametri della relativa

struttura è appunto un puntatore di funzione a questa chiamata.

Interfaccia con il contesto utente

L’accesso al modulo, quindi al contesto kernel viene fatto utilizzando un device a caratteri.

Perciò per poter utilizzare le funzionalità offerte, in primis il device va aperto. Seguendo le

linee guida dell’interfaccia ioctl tipica dei device, sono state implementate tutte le

funzionalità richieste. Per quanto riguarda l’esportazione dei dati tra i due contesti esso

viene fatto tramite il memory mapping, ovvero una zona di memoria condivisa tra i due

contesti. In questo modo si risparmia una copia dei dati tra i due contesti. Segue una breve

descrizione delle api ioctl disponibili, in base al parametro ioctl_cmd:

• SESSION_ON_IOCTL

viene fatta la ricerca, tra quelle disponibili, sulla connessione TCP come dai parametri

in ingresso identificata. In caso tale ricerca avesse esito positivo, una struttura

(zsample_sniff_session) viene creata, pronta per l’uso. Alla struttura appena inizializzata,

viene passato sotto forma di un ‘puntatore di funzione’ il riferimento alla funzione

take_sample, ed anche l’oggetto wait_queue_head_t col quale viene segnalato il contesto

utente della ‘presenza di dati da elaborare’.

• WAIT_DATA_IOCTL

la chiamata blocca fino al massimo di 1 sec, in attesa di una segnalazione di ‘presenza

di dati da elaborare’ dal modulo kernel. Se entro tale tempo la segnalazione non

perviene, essa ritorna al chiamante ed è compito di quest’ultimo ritentare la chiamata.

Page 18: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

17

Nel caso la connessione TCP, oggetto della sessione di registrazione, venisse chiusa,

questo evento è segnalato al contesto utente.

• GET_RTO_FORMULA_IOCTL / SET_RTO_FORMULA_IOCTL

queste ioctl sono utili nel caso si volesse intervenire sulla formula per l’aggiornamento

dinamico di RTO, relative ad una connessione TCP creata da un altro processo.

• SESSION_OFF_IOCTL

la sessione va in ogni caso terminata, sia per iniziativa dell’applicativo nel contesto

utente oppure perchè la connessione viene chiusa. Essa svolge i seguenti compiti:

o rilascia la struttura dati relativa alla sessione di registrazione

o la connessione TCP viene segnata come libera, quindi candidata ad eventuali

future sessioni di registrazione

2.1.2 Contesto utente

Il contesto utente si interfaccia col modulo kernel tramite un device a caratteri.

Interfacciarsi col modulo implica l’esecuzione delle seguenti operazioni:

• apertura del device

• memory mapping

• estrazione dei dati dal contesto kernel

• chiusura del device

Onde rendere più semplice il compito al programmatore è stato implementato uno skeleton,

nella forma di un layer superiore. Si occupa di eseguire le operazioni di cui sopra,

nascondendo i dettagli e proponendo un’interfaccia più semplice.

2.1.2.1 Skeleton contesto utente

La struttura rtt_ctrl, creata come supporto all’infrastruttura, raggruppa tutto il necessario.

Riempita opportunatamente (device da utilizzare, puntatore di funzione da richiamare ecc)

essa verrà utilizzata successivamente come parametro di tutte le api. Uno dei parametri di

Page 19: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

18

tale struttura è il ‘puntatore di funzione’ che verrà chiamato in presenza di dati da

elaborare. Infatti, il thread creato dallo skeleton, che si occupa di estrarre i dati dal modulo

kernel, chiamerà tale puntatore di funzione per rendere disponibili al programmatore i dati.

Ovviamente l’implementazione di questa funzione spetta al programmatore stesso. Tipici

utilizzi sono: salvataggio in file, plot del grafico in tempo reale e via dicendo.

Le api begin_session e end_session possono essere chiamate in successione, pur mantenendo

aperto anche lo stesso device. In tutte le api il parametro err_code è di tipo ‘in uscita’ e ha

un significato particolare in funzione dell’api stessa.

• int open_device(rtt_ctrl* ctrl, int *err_code);

• int close_device(rtt_ctrl* ctrl, int *err_code);

• int begin_session(rtt_ctrl* ctrl, int *err_code);

• int end_session(rtt_ctrl* ctrl, int *err_code);

Le seguenti api vengono riportate per completezza, nonostante riguardano la parte che si

occupa della formula per l’aggiornamento dinamico di RTO. Le funzionalità offerte sono

facilmente intuibili dalle denomizazioni stesse.

• int get_available_rto_formula(char *holder, int max_len);

• int get_current_sniffing_connection_rto_formula(char *holder, int max_len);

• int set_current_sniffing_connection_rto_formula(char *holder);

2.1.3 Descrizione grafica

Il processo che si occupa della registrazione dei valori RTT e RTO viene eseguito sia nel

contesto kernel che quello utente. La generazione degli eventi, il passaggio tra i due

contesti rendono il tutto non facilmente intuibile. Con la seguente descrizione grafica ed i

seguenti commenti sui vari passaggi si cerca appunto di rendere più apprensibile tale

processo.

Page 20: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

19

Figura 2.3 Sessione di registrazione RTT e RTO. Buffer i – 2: già elaborato; i – 1: pieno, da elaborare; i + 2: ancora da

riempire

1 L’applicativo nel contesto utente dopo aver aperto il device, selezionato la connessione TCP d’interesse, effettua una chiamata ioctl bloccante-sincrona con timeout 2 La chiamata ioctl di cui sopra, ritorna al thread chiamante in presenza di dati da elaborare oppure per timeout. In ambedue i casi l’applicativo ritenta di nuovo la chiamata ioctl (fin tanto che non viene predisposto altrimenti es. CTRL-C od altro) 3 Nel frattempo eventuali condizioni verificate nello stack TCP (ack ricevuti, timeout scaduti) generano i valori RTT e RTO che vengono bufferizzati 4 Una volta che uno dei buffer viene riempito lo stesso stack TCP segnala il thread chiamante della presenza di dati da elaborare 5 A questo punto il thread chiamante a cavallo tra i contesti utente e kernel rientra da quest’ultimo in quello utente 6 Una volta ritornato al thread chiamante, riconoscendo la presenza nel buffer circolare di dati da elaborare, il thread si presta all’elaborazione dei dati come dalla logica richiesta (salvataggio in un file, esecuzione di statistiche storiche, visualizzazione del grafico in tempo reale ecc). Da notare come in questa fase la prossima chiamata ioctl viene effettuata solo dopo che tutti i dati (anche quelli che eventualmente arrivano nel frattempo) sono stati elaborati, onde eliminare quanto più possibile i cross-boundaries (le chiamate ioctl).

Page 21: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

20

2.2 Formula RTO

La formula per l’aggiornamento dinamico di RTO è implementata nella forma di un

modulo kernel. La sua implementazione segue le regole generali di un modulo kernel

(entry e exit point, ecc), ed inoltre implementa le api necessarie all’infrastruttura proposta.

2.2.1 Contesto kernel

Nel contesto kernel l’implementazione riguarda una componente “statica” che consente

l’interfacciarsi tra lo stack TCP ed i moduli kernel tramite i quali le formule stesse sono

implementate. Esso concerne tutte le modifiche apportate nella struttura del kernel che

richiedono la ricompilazione dello stesso. Le modifiche apportate alla struttura sock, i punti

individuati nel kernel dove la formula viene selezionata per la prima volta, dove viene

scelta una diversa formula rispetto a quella di default, dove le chiamate al modulo vengono

fatte ne fanno parte. L’altro componente riguarda la parte “dinamica” le cui modifiche non

necessitano la ricompilazione del kernel. Esso concerne i moduli kernel per le formule.

2.2.1.1 Kernel built2in

Il termine built-in rende meglio l’idea sull’argomento di questo paragrafo. Infatti riguarda

tutte le modifiche integrate nel kernel stesso.

• strutture nuove aggiunte

la struttura nuova aggiunta tcp_rto_formula_ops, oltre ai vari campi tipici dei

moduli kernel (es. owner) è composta da una serie di ‘puntatori di funzione’.

Page 22: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

21

Figura 2.4 Associazione tra strutture di supporto all’aggiornamento dinamico di RTO e quella sock

Alla creazione di una struttura sock segue anche un’opportuna inizializzazione del

modulo che calcolerà i valori di RTO. E’ appunto tramite questi puntatori, che lo

stack TCP raggiunge il modulo kernel.

• chiamate inserite nel codice dello stack TCP

in vari punti dello stack TCP sono state aggiunte le chiamate verso i moduli kernel.

In primis, alla creazione di una struttura sock è stata aggiunta della logica che

opportunamente associa la connessione tcp al modulo (*init). In questa fase

d’inizializzazione viene intanto aumentata la variabile ref_cnt del modulo kernel il

cui compito è quello di impedire che il modulo possa essere rimosso dal sistema

Page 23: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

22

mentre in uso. Poi vengono inizializzate una serie di costanti relativa alla formula

RTO. Infine la struttura nuova rappresentante il modulo viene aggiunta come

referenza a quella sock rendendosi cosi disponibile all’utilizzo. Nel kernel, ove

RTO viene aggiornata, il corso d’azione viene instradato tramite i puntatori di

funzione, al modulo kernel rappresentato dalla struttura referenziata. Le condizioni

per le quali questo si verifica sono le seguenti:

o ack di un pacchetto o insieme di

o RTO scaduto

o connessione appena stabilita

o evento di ‘host unreachable’ pervenuto dal modulo icmp

• modulo integrato nel kernel

avendo modificato opportunamente in vari punti lo stack TCP, si vuole altrettanto

fare il modo che il sistema sia comunque in una situazione ben definita. Infatti nel

kernel è stato aggiunto un modulo che implementa una formula di default, caricata

durante il boot del sistema. Essa implementa in dettaglio quanto già presente nel

kernel prima delle modifiche. Quindi tranne per il fatto che il corso d’azione viene

instradato nel modulo, l’implementazione di default non ha alcuna differenza

rispetto a quella precedentemente implementata dal kernel prima delle modifiche.

• chiamate per la gestione delle formule

una volta che una formula rto viene inserita nel kernel essa necessita qualche forma

di gestione. Per questo nel kernel sono state apportate delle modifiche onde

consentire:

o impostare una formula come globale o di default

o impostare una formula per una specifica connessione TCP

Nel primo caso viene utilizzata l’interfaccia sysctl del kernel. Invece l’associazione

di una formula ad una connessione TCP è resa possibile tramite l’interfaccia ioctl

stessa dei socket.

Page 24: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

23

2.2.1.2 Modulo kernel

I moduli kernel che aggiornano RTO devono implementare delle api con signature ben

definite. Per iniziare, api module_init ed module_exit le quali vengono chiamate

rispettivamente al caricamento ed alla rimozione del modulo stesso. Le seguenti api invece

riguardano l’implementazione della logica per l’aggiornamento dinamico di RTO:

• init

• release

• tcp_calc_synack_rto

• tcp_set_rto

• tcp_set_rtt

La funzione init è chiamata la prima volta che una connessione vuole utilizzare il modulo

in questione. Il modulo incrementa il valore ref_cnt affinche esso non possa essere

rimosso dal sistema mentre in uso. Nel nostro caso nella funzione init vengono inizializzate

variabili della struttura sock con le quali si controllano i valori massimi, minimi ed iniziali

di RTO, attualmente costanti nel kernel. Altre possibili operazioni possono essere

inizializzazioni di eventuale memoria da utilizzare, possibili riferimenti aggiornati ecc.

La funzione release è speculare alla init. Essa è chiamata quando la connessione TCP non

utilizzerà più il modulo in questione. Va evidenziato, che questa chiamata decrementa

anche la variabile ref_cnt del modulo, rendendolo cosi un possibile candidato alla

rimozione. Per questo motivo si deve essere assolutamente sicuri che il modulo non verrà

in alcun modo più utilizzato. Rispettivamente, possibili operazioni sono il rilascio di

eventuale memoria occupata, riferimenti aggiornati ecc.

Una connessione TCP appena creata e prima di essere stabilita si trova in uno dei seguenti

stati in base al tipo:

• connessione outgoing ovvero in uscita (connect)

stato TCP_SYN_SENT, intesa come ‘inviato un pacchetto SYN, quindi in attesa del

relativo ACK’

Page 25: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

24

• connessione incoming ovvero in ingresso (accept)

stato TCP_SYN_RECV, intesa come ‘inviato ACK ad un pacchetto SYN pervenuto,

quindi in attesa del relativo ACK’

A differenza delle altre, le connessioni incoming da un punto di vista delle strutture dati di

supporto, necessitano di una diversa implementazione. Infatti il kernel durante lo stato

TCP_SYN_RECV implementa la logica opportuna con una struttura (request_sock) dati di

supporto più “leggera” dal punto di vista della memoria. Quindi il modulo kernel esporta

due funzioni per il calcolo dinamico di RTO: una per le connessioni (sia incoming che

outgoing) una volta stabilite ed un’altra per le connessioni incoming nella fase

TCP_SYN_RECV ovvero prima che esse siano stabilite.

La funzione tcp_calc_synack_rto viene utilizzata per aggiornare il valore di RTO per una

connessione incoming non ancora stabilita. La connessione TCP entra in questo stato

appena risponde col proprio ACK ad un pacchetto SYN in ingresso. Rimane in questo stato

finche non riceve l’ACK relativo dall’altra estremità, dopo il quale la connessione si sposta

nello stato TCP_ESTABLISHED.

La funzione tcp_set_rto viene utilizzata per aggiornare il valore di RTO per una

connessione TCP in tutti gli altri casi tranne quello precedente.

La funzione tcp_set_rtt viene utilizzata per aggiornare il valore di RTT nella struttura

tcp_sock. Tale funzione è chiamata dallo stack quando un pacchetto o insieme di viene

confermato. In questo modo si ha la possibilità di accedere ai valori RTT nel contesto del

modulo kernel.

2.2.2 Contesto utente

L’interazione tra il contesto utente ed i moduli è riassunta nel loro caricamento e

rimozione. In Linux con l’utilizzo di comandi shell è possibile eseguire tali operazioni:

• caricamento - loading

Page 26: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

25

root# insmod nome_formula.ko

• rimozione - unloading

root# rmmod nome_formula

Una volta caricati nel sistema, i moduli sono posti in una lista globale. Tra le formule

disponibili una sarà quella di default, ovvero la formula che ogni connessione TCP

utilizzerà se non diversamente specificato. Tramite l’interfaccia sysfs è possibile avere

informazioni sulle formule disponibili nel sistema, leggere ed impostare quella di default:

• tcp_rto_formula, r/w per leggere/impostare la formula rto di default

cat /proc/sys/net/ipv4/tcp_rto_formula echo ‘aaa’ > /proc/sys/net/ipv4/tcp_rto_formula

• tcp_available_rto_formula, r per reperire la lista delle formule disponibili

cat /proc/sys/net/ipv4/tcp_available_rto_formula

Per impostare una particolare formula ad una specifica connessione vengono utilizzate le

syscall setsockopt/getsockopt. Esse sono delle chiamate simili alle ioctl, ma specifiche alle

socket.

• consente la lettura della formula associata alla connessione tcp (sockfd)

getsockopt(sockfd, IPPROTO_TCP, TCP_RTO_FORMULA, (void*)&rto[0], (socklen_t*)

&RTO_FORMULA_LEN)

• consente l’associazione della formula “speedy” alla connessione tcp (sockfd)

setsockopt(sockfd, IPPROTO_TCP, TCP_RTO_FORMULA, (void*)&”speedy”,

strlen(&”speedy”))

2.3 Scelte implementative

La registrazione dei valori RTT e RTO è un processo che merita qualche approfondimento

in più. Esso opera a cavallo tra i due contesti ed inoltre ha un proprio impatto sulle risorse

di memoria e cpu. Quindi vanno indirizzate le seguenti problematiche:

Page 27: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

26

• interfaccia per l’esportazione dei dati dal contesto kernel a quello utente

• accesso concorrenziale ai dati tra il produttore (stack TCP) ed il consumatore (skeleton)

• rilascio delle risorse utilizzate da sessioni di registrazione

2.3.1 Interfaccia tra i due contesti

I valori RTT e RTO memorizzati nel contesto kernel, affinche siano elaborati vanno

esportati in quello utente. Nel contesto utente si ha accesso ad un insieme di librerie più

ampio e ricco (basti pensare al floating point). Inoltre anche dal punto di vista della

conoscenza di programmazione, il contesto utente raggiunge una audience più ampia. Tale

processo non è una operazione semplice come ad esempio una copia dei dati da una zona

di memoria all’altra.

In un SO Linux, possibili interfacce tra il contesto kernel e quello utente sono le seguenti

(lista di certo non esaustiva):

• file

procfs, sysfs, configfs tipicamente utilizzate per la configurazione di parametri a livello kernel

• socket

tcp, udp e netlink tipicamente utilizzate per il passaggio di grandi quantità di dati. Da un punto di

vista della programmazione sono alquanto complessi, in compenso però godono delle proprietà

tipiche dei socket (caso tcp: l’affidabilità, caso udp: l’utilizzo dei datagram)

• ioctl

tipicamente tramite l’utilizzo di un device (a caratteri, blocchi ecc)

• mmap

memory mapping tipicamente utilizzati nei driver delle schede video per le alte prestazioni

offerte. In compenso però richiedono degli sforzi in più dal punto di vista della programmazione

Per adempiere ai compiti richiesti, fondamentalmente serve:

• un meccanismo che possa informare il contesto utente in caso di presenza di dati

• un meccanismo che consenta di esportare i dati dal contesto kernel a quello utente

Page 28: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

27

La soluzione meglio adatta all’infrastruttura proposta è la seguente:

• utilizzo di un device a caratteri

che fornisce l’interfaccia ioctl tramite la quale si possono ottenere informazioni dal contesto kernel

• utilizzo del mmap (memory mapping)

per l’esportazione dei dati nel contesto utente

La scelta di sopra è dettata nel primo caso dalla semplicità ovvero minimo sforzo possibile

per ottenere le funzionalità richieste: tra i vari possibili device, il più semplice è quello a

caratteri. Nel secondo caso invece la motivazione è la prestazione. Infatti con una diversa

interfaccia (es. copy_to_user, socket etc) si andrebbe incontro ad una copia in più per il

passaggio dei dati tra i due contesti. Il memory mapping invece, espone la zona di memoria

del kernel (tramite opportune api) al contesto utente come se fosse nel medesimo,

eliminando quindi la necessità di una copia tra i due contesti.

2.3.2 Accesso concorrenziale

Per il passaggio dei dati tra i due contesti (kernel ed utente) viene utilizzata una zona di

memoria condivisa nella forma di un buffer. Essendo esso condiviso tra il produttore (che

aggiunge dati) ed il consumatore (che preleva dati) il problema dell’accesso concorrenziale

va indirizzato. Nel caso in questione si tratta di un unico produttore ed un unico

consumatore il che semplifica di molto la situazione. Questo vorrebbe dire che il momento

in cui la contesa avrà luogo sarà solamente quando ambedue vi accedono al buffer. Nel

caso vi fossero più consumatori e/o produttori oltre alla contesa appena accennata vi

sarebbe anche un’altra che dovrebbe serializzare i multipli produttori e/o consumatori che

siano. L’accesso serializzato al buffer è necessario in quanto nell’aggiornare gli indici

dell’array sia il consumatore che il produttore devono essere sicuri di non interferire col

lavoro dell’altro. Infatti, la prassi in questi casi chiede che l’accesso vada protetto con dei

lock, ovvero il locking a livello kernel col minore overhead.

Il produttore, nel nostro caso lo stack TCP, non si può permettere di aspettare che il

consumatore finisca il suo lavoro. Questo introdurrebbe ritardi, anche minimi che siano, al

Page 29: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

28

corso d’azione dello stack TCP. Tali ritardi non solo graverebbero sulla performance del

sistema stesso, sull’andamento della connessione TCP, ma ‘sporcherebbero’ anche i valori

RTT e RTO stessi per i quali l’infrastruttura è stata costruita. Ne consegue che il corso

d’azione del produttore (lo stack TCP) non deve essere interrotto in alcun modo,

indipendentemente dalla velocità con la quale il consumatore possa elaborare i dati.

Una possibile soluzione al problema appena posto viene dall’utilizzo del buffer circolare.

In questo caso il produttore una volta raggiunto la fine del buffer, riparte dall’inizio. Ne

segue come corollario che se la velocità con la quale il produttore inserisce in coda i dati è

maggiore di quella con la quale il consumatore li rimuove, i dati più vecchi verrebbero

sovrascritti con i più nuovi. Ovviamente in tale situazione il produttore sposterebbe anche

l’indice del prossimo dato che il consumatore andrà a consumare e segnalare tale evento

tramite un flag. Sarà compito del consumatore riconoscere dal flag questa situazione e

comportarsi di conseguenza.

Con questa impostazione la contesa tra i due concorrenti non si verifica più: i corsi

d’azione di nessuno dei due viene interrotto in alcun modo dall’altro. Per quanto riguarda il

caso peggiore, ovvero la velocità del produttore maggiore di quella del consumatore,

l’impostazione proposta è sempre preferibile all’interruzione di uno dei due, in attesa della

fine del lavoro dell’altro. Purtroppo non esiste una soluzione al caso peggiore: non esiste

un buffer infinito! Va detto però, che nel nostro caso, la velocità del produttore

difficilmente sarà maggiore di quella del consumatore anche se il sistema stesso fosse sotto

stress: gli eventi oggetti di studio non vengono generati con tale frequenza.

2.3.3 Rilascio delle risorse

La zona di memoria condivisa tra il contesto kernel e quello utente è pursempre una risorsa

di sistema: va comunque liberata dopo il suo utilizzo. Tale zona di memoria è condivisa tra

due processi implicando che il rilascio da parte di uno potrebbe compromettere il corso

d’azione dell’altro. Nel nostro caso uno dei due processi viene ospitato nel contesto kernel

il che peggiora la situazione ulteriormente: un accesso di tipo reference ad una struttura

NULL porterebbe ad un crash del SO intero.

Page 30: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

29

Proteggere l’accesso con un lock ha degli svantaggi. Lasciando stare per un attimo il

ritardo introdotto al processo in attesa di rilascio del lock, preoccupa molto di più il blocco

indefinito. Si pensi ad esempio ad un ‘process kill’ a livello utente che già mantiene il lock

sulla struttura. Bloccherebbe indefinitivamente il processo nel contesto kernel in attesa del

rilascio del lock. Anche nel caso in cui la chiusura della connessione TCP possa avere esito

positivo, le risorse (associate appunto alla connessione) non rilasciate, peserebbero a lungo

andare sulla stabilità del SO stesso.

La scelta fatta per l’infrastruttura proposta è quella del rilascio deferred ovvero posticipato.

Le risorse vengono rilasciate solamente quando ambedue i processi dichiarano che non ne

faranno più utilizzo. Ovviamente questo comporta della logica in più, ma consente anche

di eseguire l’operazione in tutta sicurezza. Per adempiere a questo compito l’infrastruttura

è stata dotata di una lista globale dove porre le strutture da rilasciare ed un processo che si

occuperà del loro rilascio. Sia la lista che il processo sono ospitati nel contesto kernel.

Ogni struttura inizializzata viene per prima associata a quella sock, ed in più aggiunta come

riferimento in tale lista. In questo modo si ha accesso alla struttura anche quando sia la

connessione che il processo nel contesto utente siano terminati. A quel punto, ovvero

quando la struttura viene segnalata da ambedue i processi come ‘da rilasciare’, il processo

percorrendo la lista e riconoscendola la rimuove, quindi ne rilascia le sue risorse

ritornandole al SO.

Sulla stessa connessione TCP, durante la sua vita, possono avere luogo diverse sessioni di

registrazione. Ognuna di queste sessioni avrà la propria struttura dati. Queste strutture dati

però, andranno rilasciate solamente quando la connessione tcp viene terminata ovvero

quando la struttura sock verrà rilasciata dallo stack tcp stesso. Fintanto che la connessione

TCP è ancora attiva non si può avere la certezza (alla luce anche di possibili future

modifiche del kernel) che nessun accesso verrà fatto dopo che le strutture della sessione

verranno rilasciate.

La lista di cui si accennava poco fa, in realtà è un insieme di due tali. Una legata allo stack

TCP, sock_wrapper_list e l’altra legata alle sessioni di registrazione, session_list. Segue un

esempio ed una descrizione grafica onde descrivere meglio il meccanismo.

Page 31: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

30

Con stack = 0 viene indicata una connessione TCP ancora attiva, che alla chiusura diventa

stack = 1. Lo stesso ragionamento vale anche per la variabile module riferita però al

modulo kernel. Sia aa1 una struttura sock al quale corrispondono le sessioni aa1: 1 e aa1:

2. La modifica apportata dallo stack TCP a fronte della chiusura della connessione, alla

struttura in sock_wrapper_list viene propagata alle rispettive in session_list dal processo

che si occupa del rilascio delle risorse.

Figura 2.5 Rilascio risorse relative ad una sessione di registrazione (1 di 2)

La propagazione dell’evento “connessione tcp chiusa” viene fatta in due fasi (ecco quindi la

necessità di due liste) proprio per disaccoppiare i corsi d’azione. La prima fase consiste

Page 32: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

31

nella segnalazione da parte dello stack TCP di questo evento ponendo la variabile stack del

relativo elemento nella lista sock_wrapper_list a 1. In questo modo lo stack TCP non è

obbligato a dover percorrere la session_list in cerca delle rispettive strutture riferite alle

sessioni. Infatti questo compito viene svolto dal processo di rilascio delle risorse.

Solamente quando anche i moduli segnaleranno di aver preso visione, quindi che non

utilizzeranno più le strutture condivise allora inizia la seconda fase. Anche in questo caso è

il processo di rilascio delle risorse che percorre la session_list liberando quindi le strutture

non più utilizzate.

Figura 2. 6 Rilascio risorse relative ad una sessione di registrazione (2 di 2)

Page 33: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

32

3. BENCHMARK

Le modifiche apportate nel kernel implicano indubbiamente un impatto sulla performance

del sistema. Alla struttura sock sono state aggiunte dei riferimenti a quella di supporto

all’infrastruttura proposta. La struttura riferita riguarda sia l’aspetto ‘registrazione di RTT

e RTO’ che ‘formula per l’aggiornamento dinamico di RTO’. Anche il processo che in

background si occupa di rilasciare le risorse non più utilizzate, ha la propria componente di

impatto sulla performance.

Quanto accennato riguarda il sistema nel suo intero indipendentemente dal fatto se una

registrazione è attiva o meno. Qualora lo fosse, alle variabili che influiscono sulla

performance vanno aggiunte delle ulteriori. La struttura dati inizializzata per il passaggio

dei dati tra il livello kernel ed utente. Inoltre il thread a livello utente che si occupa appunto

di esportare i dati dal contesto kernel, implica ulteriori risorse utlizzate sia di memoria che

cpu.

Ai fini di un’analisi più semplificata, suddivideremo il problema in due. Il primo

riguarderà solamente le modifiche apportate al kernel, lasciando fuori dall’equazione la

sessione di registrazione. Verranno messi a confronto un kernel modificato ed uno non. Il

secondo riguarderà solamente la sessione di registrazione. Verranno messi a confronto due

kernel modificati, su uno dei quali però una sessione di registrazione è attiva.

Modifiche apportate allo stack TCP

Le seguenti operazioni verranno effettuate ogniqualvolta una delle condizioni di

aggiornamento di RTO ha luogo:

• accesso al modulo per aggiornare il valore di RTO

• controllo se una sessione di registrazione è attiva

Nel caso la seconda operazione avesse esito positivo, altre, riguardanti la parte che si

occupa della registrazione dei valori RTT e RTO, ne seguirebbero. Esse non vengono prese

in considerazione ai fini dell’analisi in quanto hanno un impatto attribuibile allo stack TCP

Page 34: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

33

solamente quando una sessione di registrazione è in atto. Ambedue le operazioni hanno un

numero ben definito di istruzioni, non soggetto di alcun ritardo dovuto ad altri processi

quindi deterministiche.

Sessione di registrazione attiva

Nel caso di una sessione di registrazione saranno prese in considerazione le seguenti

operazioni:

• memorizzazione dei valori RTT e RTO nelle opportune strutture dati

• esportazione dei dati tra il contesto kernel e quello utente

In questo caso abbiamo trascurato di proposito l’operazione effettuata dall’applicativo sui

dati esportati. Possiamo considerare il caso in cui i dati ottenuti vengono semplicemente

scartati (es. instradati in /dev/null) onde semplificare l’analisi.

Per effettuare gli esperimenti sono stati costruiti due programmi di test. Un programma che

svolgerà il ruolo del client ed un altro quello del server. Ambedue i programmi tramite i

parametri a linea di comando sono configurabili in base alla:

• porta TCP sulla quale il server sarà in ascolto ovvero il client tenterà di connettersi

• formula utilizzata per le connessioni in caso di una sessione di registrazione

• nel caso del client, l’indirizzo (ip o web) dove il server risiede

Sia il programma client che quello server sono stati sviluppati sia per il sistema operativo

Linux (dove le modifiche tcp sono state apportate) e Windows 7.

3.1 Impatto modifiche apportate allo stack

TCP

Analizzare l’impatto dovuto all’utilizzo delle risorse (memoria, cpu, cache ..) di una

connessione TCP non è un’operazione semplice. Non è un processo sul quale tramite un

Page 35: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

34

utility del SO (systat, sysprof) si può applicare un profiling. Proprio per questo motivo lo è

ancora di più fare un confronto tra i 2 kernel, quello modificato o non.

E’ importante però, che le modifiche apportate non introducano alcun ritardo significativo

sul normale funzionamento dello stack TCP. Quindi è stato istituito un ambiente di test

dove l’unica variabile è l’implementazione del kernel onde poter sostenere che l’impatto

introdotto dalle modifiche sia accettabile.

Ambiente di test

Un kernel non modificato ospitato in una VirtualBox, A. Un kernel modificato in una

seconda VirtualBox, B. Su ognuno dei kernel, modificato e non, va in esecuzione

un’istanza dello stesso programma client. Un server C in ascolto sulla porta 80, situato

nella stessa macchina dove le macchine virtuali ospitanti i due kernel oggetto di studio

vanno in esecuzione.

Figura 3.1 Ambiente di test. Macchina A (Vbox): kernel NON modificato; macchina B (Vbox): kernel modificato;

macchina C: server in ascolto, in esecuzione sulla macchina ospite (Windows7)

Page 36: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

35

Come si può intuire dalla figura, l’unica variabile è il kernel. Il mezzo fisico di

comunicazione tra i client ed il server è lo stesso. Essendo che il mezzo fisico in questo

caso è la memoria, esso non introduce alcuna variabile al nostro ambiente.

Operazione

Nei kernel oggetto di valutazione, vanno in esecuzione simultaneamente i client che

effettuano dei file upload verso il server in ascolto sulla porta 80. Gli upload vengono

eseguiti in modo sequenziale; la dimensione dei file è fissa, 463917280 bytes; il numero totale

di upload effettuati è 60. Per ogni upload viene tenuta traccia del tempo impiegato. Alla

fine di questa serie di upload viene trovata una media del tempo impiegato. In conclusione

viene effettuato un confront tra I due kernel, in base alla media di upload. Ci si aspetta che

la differenza tra le due medie non sia significativa.

Risultati

Vengono riportati in seguito i risultati del test di cui sopra. Nel grafico seguente viene

tracciata la durata per ogni upload effettuato da ognuno dei client in esecuzione sui kernel

oggetto di confronto.

Figura 3.2 Confronto in base alla “durata di upload”

Page 37: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

36

La tabella seguente riassume la media e la durata complessiva di upload per i due kernel in

confronto.

Kernel NON modificato Kernel modificato

durata media upload (sec) 155.2 155.56

somma totale durata upload (sec) 9328.07 9334.01

Come dai risultati si evince, non vi è alcun ritardo significativo. Mediamente per ambedue

i campioni le grandezze, media e somma, sono praticamente uguali.

3.2 Impatto sessione di registrazione

Una sessione di registrazione attiva, trascurando per semplicità l’elaborazione dei dati in

contesto utente, comporta le seguenti operazioni:

• memorizzazione dei valori RTT e RTO nelle opportune strutture dati

• esportazione dei dati tra il contesto kernel e quello utente

Tali operazioni implicano per prima un consumo di memoria: i buffer creati dove i valori

RTT e RTO verranno memorizzati. Essendo l’esportazione attuata con il memory

mapping, la memoria allocata sarà la stessa dall’inizio alla fine della sessione, perciò la

possiamo considerare una costante della nostra funzione impatto. Quindi rimane solamente

il consumo di CPU.

Possiamo però, misurare l’impatto di una sessione di registrazione facendo un confronto

tra due campioni di connessioni TCP. Il primo campione viene da un kernel modificato e

sul quale non viene attuata alcuna sessione di registrazione. Il secondo campione viene

ugualmente da un kernel modificato sul quale però, una sessione di registrazione viene

attuata. Per entrambi i campioni la formula utilizzata è la stessa. In entrambi i casi

verranno effettuati una serie di file upload verso un server.

Page 38: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

37

Ambiente di test

L’esperimento è simile a quello precedentemente descritto nel paragrafo 3.1. A differenza

di prima, in questo caso in ambedue le macchine virtuali vi è in esecuzione un kernel

modificato. Inoltre, il client in esecuzione sul kernel ospitato nella VirtualBox B attua una

sessione di registrazione.

Operazione

L’esperimento è stato condotto esattamente come quello precedente, descritto nel

paragrafo 3.1.

Figura 3.3 Ambiente di test . Macchina A (Vbox): kernel modificato; macchina B (Vbox): kernel modificato sessione di

registrazione in atto; macchina C: server porta 80 in locale

Risultati

Vengono riportati in seguito i risultati del test di cui sopra. Nel grafico seguente viene

tracciata la durata per ogni upload effettuato da ognuno dei client in esecuzione sui kernel

in confronto.

Page 39: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

38

Figura 3.4 Confronto in base alla “durata di upload”

La tabella seguente riassume la media e la durata complessiva di upload per i due kernel in

confronto.

Kernel modificato Kernel modificato + sessione rto

durata media upload (sec) 155.9 156.04

somma totale durata upload (sec) 9354.31 9356.72

Come dai risultati si evince, anche in questo caso non vi è alcun ritardo significativo.

Mediamente per ambedue i campioni le grandezze, media e somma, sono praticamente

uguali.

Page 40: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

39

4. CASI DI STUDIO

Per rendere meglio l’idea di cosa offre e di come si può utilizzare l’infrastruttura proposta

sono stati presi in considerazione due casi di studio. Nel primo caso si tratta di una formula

già oggetto di ricerca (vedasi Referenze, [5]): ci si aspetta che i risultati ottenuti siano

allineati con quanto in letteratura riportato. Il secondo caso riguarda una seconda formula

di test, preparata al solo fine di dimostrare la flessibilità dello strumento proposto.

L’iter procedurale per ognuno dei casi, è il seguente:

• implementare un modulo kernel per l’aggiornamento dinamico di RTO, come la

formula oggetto di studio specifica

• effettuare, simultaneamente sulla stessa macchina virtuale col kernel modificato,

sia utilizzando la formula oggetto di studio che quella standard, una serie di file

upload, per ognuno dei quali attuare lato client una sessione di registrazione

• effettuare, solamente per il primo caso di studio, simultaneamente sulla stessa

macchina virtuale col kernel modificato, sia utilizzando la formula oggetto di

studio che quella standard, una serie di file download per ognuno dei quali attuare

lato server una sessione di registrazione

• confrontare il campione ottenuto con la formula oggetto di studio con quello della

standard, in base alle seguenti variabili:

o tempo medio di upload/download

o tempo totale (per l’intero campione) di upload/download

o numero di SYN inviati nella fase 3WHS (solamente per il primo caso di

studio)

o numero di RTO scaduti successivamente alla fase 3WHS (solamente per il

secondo caso di studio)

o numero di connessioni outgoing non riuscite

o ‘densità di probabilità’ funzione di ‘tempo upload/download’

o ‘distribuzione cumulativa’ funzione di ‘tempo upload/download’

Page 41: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

40

Per tutti gli esperimenti seguenti il numero dei ‘file upload/download’ è 60. La dimensione

del file varia, pertanto sarà specificato per ogni esperimento. Per i file upload è stato

implementato un programma client, il quale attua una sessione di registrazione. Per i file

download invece, è stato implementato un programma server, il quale attua una sessione di

registrazione. Quindi è importante che, solo dal lato dove la sessione di registrazione viene

attuata vi sia in esecuzione il kernel modificato. Per quanto riguarda la controparte è

indifferente: infatto in uno degli scenari seguente la controparte è un sito web.

Per quanto riguarda la ‘densità di probabilità’ e la ‘distribuzione cumulativa’ è stato

considerato il caso della distribuzione normale con media il mediano (Excel - MEDIAN), e

come varianza il quadrato della deviazione standard (Excel - STDDEV).

In seguito i termini outgoing e incoming verranno utilizzati per distinguere le connessioni

TCP come segue:

• outgoing

connessione TCP in uscita, risultato di una syscall connect (caso tipico di un client

che si collega ad un server)

• incoming

connessione TCP in ingresso, risultato di una syscall accept (caso tipico di un

server che accetta in ingresso una connessione da parte di un client)

4.1 Formula ‘chu’

In questo caso di studio è stata analizzata la formula per l’aggiornamento dinamico di RTO

proposta da H.K. Jerry Chu (vedasi Referenze, [5]). In particolare, l’unica modifica

proposta rispetto alla formula standard consiste nel valore iniziale di RTO al momento in

cui viene iniziato il protocollo di apertura connessione.

Page 42: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

41

La formula standard per l’aggiornamento dinamico di RTO è riportata in (rfc2988) ed

omessa da questo documento per brevità. La formula implementa un algoritmo sviluppato

da Van Jacobson nel 1988 ed utilizzato da allora in tutte le implementazioni di TCP. Il

documento rfc2988 specifica alcuni dettagli realizzativi necessari per l’applicazione pratica

dell’algoritmo di Van Jacobson.

In particolare, rfc2988 specifica che il valore iniziale per RTO quando non sono disponibili

misure di RTT è 3 s. La formula analizzata in questa sezione invece assume come valore

iniziale per RTO 1 s. Inoltre, a differenza di quella standard, allo scadere del 1° timeout di

ricezione, il valore di RTO rimane invariato.

Osservazioni sulla formula rto oggetto di studio

La motivazione di questa scelta, secondo l’autore, è riassunta nei seguenti punti:

• le reti moderni attuali sono più veloci (rispetto al momento in cui il valore iniziale di

RTO è stato impostato)

• studi (effettuati dallo stesso autore) dimostrano che il valore di RTT nel 97.5% delle

connessioni in un test a larga scala è minore di 1 secondo

• studi osservano che la percentuale di RTO scaduti nella fase 3WHS (3-way handshake)

è intorno al 2% (un valore di certo non trascurabile)

• per il 2.5% delle connessioni con un valore di RTT maggiore di 1 secondo, la formula

garantisce un rinvio (SYN or SYNACK) sia esso necessario o meno

Secondo le osservazioni dell’autore, la formula per l’aggiornamento dinamico di RTO

risulta utile nelle connessione a vita breve, per le quali il tempo di 3WHS è una

componente non trascurabile. E’ il caso tipico delle pagine html: esse sono composte da un

insieme di risorse tipicamente di piccole dimensioni. La durata di caricamento della pagina

html è il tempo della durata di caricamento massima tra quelle di ognuna delle risorse.

Pertanto diminuire la durata della fase 3WHS, nel caso essa sia comparabile con la durata

totale del trasferimento è importante.

Page 43: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

42

4.1.1 Connessioni outgoing

Per le connessioni outgoing vengono effettuati una serie di file upload verso un server

TCP - porta 80. Per ogni connessione viene attuata una sessione di registrazione.

Scenario 1

Figura 4.1 Ambiente di test

Vengono considerati più di un caso in base all’ubicazione del server, al valore iniziale di

RTO (rto_3whs) ed al layer di disturbo (tc) introdotto. Ognuno dei casi comporterà dei test

sia con la formula oggetto di studio che quella standard. Infine in base ai risultati ottenuti si

cercherà di trarre delle conclusioni.

La seguente figura riporta un confronto tra i campioni ottenuti con la formula standard e

quella oggetto di studio in base alla ‘durata upload’. Il grafico del numero dei ‘syn inviati’

necessari per stabilire la connessione viene omesso, in quanto i valori sono uguali a 1, tra

le due formule, per ogni upload.

Page 44: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

43

Figura 4.2 Confronto in base alla “durata di upload”

Segue il confronto tra i campioni ottenuti con la formula standard e quella oggetto di

studio, in base alla ‘densità di probabilità’ e ‘distribuzione cumulativa’, ambedue funzione

della ‘durata di upload’.

Figura 4.3 Confronto in base alla “densità di probabilità” e “distribuzione cumulativa”

La tabella seguente riassume la media, la durata complessiva, il numero medio di syn

inviati ed il numero di connessioni non riuscite per i campioni messi a confronto.

standard: rto_3whs = 3000msec chu: rto_3whs = 1000msec

durata media upload (sec) 0.55 0.56

somma totale durata upload (sec) 33.17 33.64

Page 45: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

44

media syn inviati 1 1

connessioni non riuscite 0 0

dimensione file 99399 99399

I risultati non riportano alcuna notevole differenza. Nessun timeout scaduto per un

pacchetto SYN e nessuna connessione non riuscita. Il valore iniziale RTO per la formula

oggetto di studio nonostante sia 3 volte più piccolo di quella standard è comunque

abbastanza alto. Infatti in base a registrazioni precedenti, il primo valore registrato RTT

(~50 msec) è ampiamente minore di quello iniziale RTO (1000 msec).

Scenario 2

Lo scenario è identico al precedente tranne che per il valore iniziale di RTO che a

differenza di prima è di 100 msec.

La seguente figura riporta il confronto tra i campioni ottenuti con la formula standard e

quella oggetto di studio in base alla ‘durata di upload’ e del numero dei ‘syn inviati’

necessari per stabilire la connessione.

Figura 4.4 Confronto in base alla “durata di upload” e “syn inviati”

Page 46: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

45

La formula per l’aggiornamento dinamico di RTO oggetto di studio comporta dei rinvii di

pacchetti SYN, mentre molto probabilmente l’ACK era in dirittura d’arrivo. Questi rinvii

penalizzano anche la stessa durata di upload. Va detto però che il valore iniziale RTO è

stato scelto all’incirca il doppio del 1° valore RTT (risultato di precedenti sessioni di

registrazione), come un caso limite appositamente per osservarne gli effetti.

Invece la seguente figura riporta un confronto tra i campioni ottenuti con la formula

standard e quella oggetto di studio in base alla ‘densità di probabilità’ e ‘distribuzione

cumulativa’, ambedue funzione della ‘durata di upload’.

Figura 4.5 Confronto in base alla “densità di probabilità” e “distribuzione cumulativa”

Il grafico riguardante la ‘densità di probabilità’ dimostra che il campione proveniente da

sessioni con la formula oggetto di studio nonostante abbia una media quasi uguale, è più

sparso rispetto a quello della formula standard. Infatti i valori troppo distanti dalla media

appartengono appunto a questo campione (tracciato color rosso).

La tabella seguente riassume la media, la durata complessiva, il numero medio si syn

inviati ed il numero di connessioni non riuscite per i campioni messi a confronto.

standard: rto_3whs = 3000msec chu: rto_3whs = 100msec

Page 47: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

46

durata media upload (sec) 0.55 0.67

somma totale durata upload (sec) 33.4 40.45

media syn inviati 1 1.06

connessioni non riuscite 0 0

dimensione file 99399 99399

Scenario 3

Figura 4.6 Ambiente di test

Nello scenario di un server situato nella macchina host e dove sul kernel è stato attivato un

layer di disturbo (tc) i risultati sono diversi in confronti a quelli precedenti.

Page 48: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

47

Figura 4.7 Confronto in base alla “durata di upload” e “syn inviati”

Si nota anche in questo caso un rinvio di pacchetti SYN più frequente per le connessioni

che utilizzano la formula oggetto di studio. A differenza della formula standard però, esso

reagisce più velocemente ad eventuali disturbi introdotti dal layer tc.

Segue il confronto tra i campioni ottenuti con la formula standard e quella oggetto di studio

in base alla ‘densità di probabilità’ e ‘distribuzione cumulativa’, ambedue funzione della

‘durata upload’. Anche in questo caso il campione proveniente da sessioni con la formula

oggetto di studio è più sparso. In compenso però la campana è centrata leggermente più a

sinistra di quella standard, indicando quindi una durata di upload media minore.

Page 49: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

48

Figura 4.8 Confronto in base alla “densità di probabilità” e “distribuzione cumulativa”

La tabella seguente riassume la media, la durata complessiva, il numero medio si syn

inviati ed il numero di connessioni non riuscite per i campioni messi a confronto.

standard: rto_3whs = 3000msec chu: rto_3whs = 100msec

durata media upload (sec) 0.91 0.88

somma totale durata upload (sec) 54.67 53.24

media syn inviati 1 1.26

connessioni non riuscite 4 0

dimensione file 99399 99399

Dal confronto tra i due campioni, nello scenario con un layer di disturbo, vanno sottolineati

i seguenti punti:

• la formula standard necessità 4 connessioni in più rispetto a quella oggetto di studio

• la media dei SYN, inviati prima che la connessione sia stabilita, per la formula

oggetto di studio è maggiore di quella standard

Page 50: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

49

• la media di ‘durata di upload’ per la formula oggetto di studio è minore di quella

standard

• la ‘durata totale’ dell’intero campione proveniente dalla formula oggetto di studio

è minore di quella standard

La maggiore durata ‘totale’ e ‘media’ nel caso della formula standard in parte è

dovuta anche a:

o l’informazione, sull’eventuale 2° pacchetto SYN non ancora confermato,

viene recuperata più tardi nel caso della formula standard (ricordiamo che

per la formula oggetto di studio, RTO rimane invariata al 1° timeout di

ricezione scaduto invece di crescere esponenzialmente come nel caso della

formula standard)

4.1.2 Connessioni incoming

Per le connessioni incoming vengono effettuati una serie di file download da parte di un

server tcp. Vengono eseguiti simultaneamente due applicativi server in una VirtualBox

ospitante un kernel modificato. Uno dei server utilizzerà la formula standard, invece l’altro

quella oggetto di studio per le connessioni accettate in ingresso. In ambiente Windows (dove la

VirtualBox viene ospitata) saranno messi in esecuzione due client che si connetterano ai server

effettuando quindi l’upload di un file di dimensione fissa.

Per ogni connessione accettata in ingresso ambedue i server attueranno una sessione di

registrazione. Il motivo della sessione non è tanto per i valori di RTT e RTO (infatti i server

solamente ricevono dati), se non per il numero di RTO scaduti durante la fase iniziale della

connessione. Al kernel modificato è stato applicato un layer tc che simula in qualche modo un

ambiente quanto più simile a quello reale.

La figura seguente riporta il confronto tra i campioni ottenuti con la formula standard e

quella oggetto di studio in base alla ‘durata di download’ ed al numero di ‘synack inviati’

necessari per stabilire la connessione.

Page 51: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

50

Figura 4.9 Confronto in base alla “durata di download” e “synack inviati”

In questo scenario i grafici della ‘durata di download’ sono molto simili nonostante le

oscillazioni. Va sottolineato il fatto che il campione proveniente da sessioni con la formula

oggetto di studio ha in media un numero di pacchetti SYNACK inviati maggiore (superiore

a 2) rispetto a quella standard.

La seguente figura invece, riporta un confronto tra i campioni ottenuti con la formula

standard e quella oggetto di studio in base alla ‘densità di probabilità’ ed alla

‘distribuzione cumulativa’ ambedue funzione della ‘durata di upload’. Essa conferma il

fatto che i due campioni sono molto simili sia dal punto di vista della media che della

varianza.

Page 52: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

51

Figura 4.10 Confronto in base alla “densità di probabilità” e “distribuzione cumulativa”

La tabella seguente riassume la media, la durata complessiva ed il numero medio si synack

inviati per i campioni messi a confronto. In questo scenario non è possibile conoscere il

numero delle connessioni non riuscite in quanto nel lato server questa informazione manca

ovvero le uniche connessioni di cui abbiamo traccia sono quelle accettate.

standard: rto_3whs = 3000msec chu: rto_3whs = 100msec

durata media download (sec) 4.12 4.05

somma totale durata download (sec) 247.22 243.1

media synack inviati 1.03 2.16

connessioni non riuscite non nota non nota

dimensione file 99399 99399

Dal confronto tra i due campioni vanno sottolineati i seguenti punti:

• la formula oggetto di studio comporta un numero di pacchetti SYNACK inviati

maggiore rispetto a quella standard

• il tempo impiegato per l’invio del file è più breve nel caso della formula oggetto di

studio

Page 53: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

52

4.1.3 Riassunto ed osservazioni

La tabella seguente riporta il riassunto dei risultati, per ogni esperimento effettuato.

Figura 4.11 Riassunto risultati

Di primo impatto può sembrare che la formula oggetto di studio sia controproducente, ma

ha pure i suoi punti di forza:

• nell’eventualità di un server non presente la connessione viene chiusa prima

essendo i tentativi di retry col rinvio del pacchetto SYN limitati, essi verranno

esauriti prima rispetto ad un caso con un valore iniziale RTO più alto. Nel caso di

un server web questo vorrebbe dire che risorse preziose vengono rilasciate il prima

possibile

Page 54: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

53

• nell’eventualità di una perdita di pacchetti il loro rinvio è più veloce

nel caso i pacchetti vadano persi un rinvio degli stessi avrà luogo prima, con

conseguenza un eventuale trasferimento più veloce. D’altra parte però, se i

pacchetti non sono persi, ma in dirittura d’arrivo questo implicherebbe della banda

occupata inutilmente. Ma se consideriamo il caso di un trasferimento dati di piccole

dimensioni (risorse pagine web) l’aumento d’occupazione della banda può essere

accettabile in compenso di un tempo di trasferimento più breve

• per percorsi specifici il primo valore RTT di una sessione di registrazione può

servire come base per il valore iniziale RTO

nel caso si volesse modellare l’andamento di RTO per un percorso o per un

intervallo giornaliero particolare verso un endpoint specifico, informazioni

ottenute da precedenti sessioni di registrazione possono tornare molto utili. Il primo

valore RTT registrato da una sessione attuata può servire come un punto di

partenza per impostare quello iniziale di RTO. Ovviamente un valore iniziale

RTO uguale a quello RTT comporterebbe un rinvio di pacchetti ‘aggressivo’.

Invece multipli del valore iniziale di RTT, a partire dal 2, potrebbe dare una

migliore prestazione delle connessioni verso quel endpoint.

4.2 Formula ‘speedy’

Il secondo caso di studio riguarda una formula per l’aggiornamento dinamico di RTO che

utilizza la seguente regola:

RTOi = (RTTi * α) + (RTTi-1 * β) + (RTTi-2 * γ) + (RTOi-1 * θ) dove:

• i indica il valore corrente, i-1 quello precedente e cosi via

• α,β,γ,θ costanti

Page 55: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

54

Essa è funzione degli ultimi 3 valori di RTT e dell’ultimo valore di RTO. La componente

RTO è utile particolarmente nel caso in cui non vi è più alcun aggiornamento sui valori di

RTT (ovvero nessun ACK in arrivo). In mancanza di questa componente, la RTO

rimarrebbe invariata, quando invece è ragionevole che la mancanza di ACK sia una chiara

indicazione che la RTO vada aumentata.

La seguente figura fornisce un idea sull’ambiente in cui gli esperimenti sono stati svolti. A

differenza degli scenari con la formula ‘chu’, in questa sezione saranno considerati

solamente le connessioni outgoing.

Figura 4.12 Ambiente di test

Inoltre, oggetto di confronto tra le due formule saranno gli ‘rto scaduti’ piuttosto che gli

‘syn inviati’, in quanto più significativi.

L’unica differenza tra i seguenti scenari sarà la formula stessa. Modificando

opportunamente le costanti di cui sopra è possibile avere formule anche molto diverse.

Infatti per gli esperimenti seguenti verranno utilizzati valori differenti proprio per

Page 56: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

55

evidenziare sia situazioni ‘normali’ che casi limite.

4.2.1 Connessioni outgoing

Scenario 1

In questo scenario i valori delle costanti sono:

α = 1, β = 0.5, γ = 0.25, θ = 0.5 quindi la formula è:

RTOi = RTTi + (RTTi-1 / 2) + (RTTi-2 / 4) + (RTOi-1 / 2)

La seguente figura riporta il confronto tra i campioni ottenuti con la formula standard e

quella oggetto di studio in base alla ‘durata di upload’ e dei ‘rto scaduti’.

Figura 4.13 Confronto in base alla “durata di upload” e “rto scaduti”

Aparte occasionali differenze, in media sia la ‘durata di upload’ che gli ‘rto scaduti’ tra le

due formule sono praticamente uguali.

Page 57: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

56

Segue il confronto tra i campioni ottenuti con la formula standard e quella oggetto di studio

in base alla ‘densità di probabilità’ e ‘distribuzione cumulativa’, ambedue funzione della

‘durata upload’.

Figura 4.14 Confronto in base alla “densità di probabilità” e “distribuzione cumulativa”

Il grafico della ‘densità di probabilità’ conferma il fatto che ambedue i campioni hanno

media quasi uguale. Infatti le loro campane sono quasi centrate nello stesso punto. La

varianza del campione della formula oggetto di studio ha un valore minore, motivo per cui

il relativo grafico di ‘densità di probabilità’ è meno schiacciato di quello standard.

La tabella seguente riassume la media, la durata complessiva, il numero medio di rto

scaduti ed il numero di connessioni non riuscite.

standard: rto_3whs = 3000msec speedy: rto_3whs = 100msec

durata media upload (sec) 177.24 174.987

somma totale durata upload (sec) 10634.43 10499.24

media rto scaduti 67.5 71.5

connessioni non riuscite 0 0

dimensione file 1372160 1372160

Page 58: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

57

Scenario 2 In questo scenario i valori delle costanti sono:

α = 1, β = 0.25, γ = 0.125, θ = 0.125 quindi la formula è:

RTOi = RTTi + (RTTi-1 / 4) + (RTTi-2 / 8) + (RTOi-1 / 8)

Rispetto allo scenario precedente i valori RTO calcolati sono in media minori. Questo

implica che il numero di eventuali ritrasmissioni di un pacchetto o insieme di, non ancora

confermato, sarà maggiore. Si può dire che suddetta formula è ‘aggressiva’ in quanto

molto sensibile ad eventuali ritardi nella ‘conferma dell’avvenuta ricezione’.

La seguente figura riporta il confronto tra i campioni ottenuti con la formula standard e

quella oggetto di studio in base alla ‘durata di upload’ e del numero dei ‘rto scaduti’.

Figura 4.15 Confronto in base alla “durata di upload” e “rto scaduti”

Il grafico di ‘durata di upload’ dimostra in maniera evidente come la formula oggetto di

studio effettua il trasferimento dei file in un tempo mediamente minore. Questo risultato

Page 59: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

58

arriva a discapito della banda: infatti il numero dei RTO scaduti, quindi delle ritrasmissioni

è maggiore rispetto alla formula standard.

La seguente figura riporta il confronto tra i campioni ottenuti con la formula standard e

quella oggetto di studio in base alla ‘densità di probabilità’ e ‘distribuzione cumulativa’,

ambedue funzione della ‘durata upload’. In linea con quanto scritto poc’anzi si nota come

la campana nel caso della formula oggetto di studio si trova alla sinistra di quella standard.

Figura 4.16 Confronto in base alla “densità di probabilità” e “distribuzione cumulativa”

La tabella seguente riassume la media, la durata complessiva, il numero medio di rto

scaduti ed il numero di connessioni non riuscite per i campioni messi a confronto.

standard: rto_3whs = 3000msec speedy: rto_3whs = 100msec

durata media upload (sec) 172.5962 163.1614

somma totale durata upload (sec) 10355.77 9789.681

media rto scaduti 66.85 118.58

connessioni non riuscite 0 0

dimensione file 1372160 1372160

Page 60: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

59

Scenario 3 In questo scenario i valori delle costanti sono:

α = 1, β = 1, γ = 0.5, θ = 0.5 quindi la formula è:

RTOi = RTTi + RTTi-1 + (RTTi-2 / 2) + (RTOi-1 / 2)

Rispetto al 1° scenario, i valori RTO calcolati sono in media maggiori. Questo implica che

il numero di eventuali ritrasmissioni di un pacchetto o insieme di non ancora confermato,

sarà minore. Si può dire che suddetta formula è ‘lenta’ in quanto poco sensibile ad

eventuali ritardi nella ‘conferma dell’avvenuta ricezione’.

Figura 4.17 Confronto in base alla “durata di upload” e “rto scaduti”

Il grafico della ‘durata upload’ dimostra in maniera evidente come la formula oggetto di

studio effettua il trasferimento dei file in un tempo mediamente maggiore. In compenso

però il numero dei RTO scaduti è minore rispetto alla formula standard. Lo scenario

corrente è un altro caso limite, opposto a quello precedente.

La seguente figura riporta un confronto tra i campioni ottenuti con la formula standard e

quella oggetto di studio in base alla ‘densità di probabilità’ e ‘distribuzione cumulativa’,

Page 61: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

60

ambedue funzione della ‘durata upload’. In linea con quanto scritto poc’anzi si nota come

la campana nel caso della formula oggetto di studio si trova alla destra di quella standard.

Figura 4.18 Confronto in base alla “densità di probabilità” e “distribuzione cumulativa”

La tabella seguente riassume la media, la durata complessiva, il numero medio di rto

scaduti ed il numero di connessioni non riuscite per i campioni messi a confronto.

standard: rto_3whs = 3000msec speedy: rto_3whs = 100msec

durata media upload (sec) 180.381 205.295

somma totale durata upload (sec) 10822.87 12317.73

media syn inviati 70.86 52.08

connessioni non riuscite 0 0

dimensione file 1372160 1372160

Page 62: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

61

4.2.2 Riassunto ed osservazioni La tabella seguente riporta un riassunto dei risultati di ciascuno degli esperimenti effettuati.

Figura 4.19 Riassunto risultati

Come evidenziato in precedenza il motivo degli esperimenti di questa sezione è solamente

quello di utilizzare lo strumento proposto. Utilizzando una formula per il calcolo dinamico

RTO, funzione dei valori precedenti di RTT e RTO, opportunamente pesati, si è visto che

si possono ottenere diversi risultati. In particolare:

• utilizzando una formula ‘aggressiva’, in media i trasferimenti sono di durata

minore rispetto alla formula standard. Ovviamente a discapito della banda: un

numero maggiore di rto scaduti implica un numero maggiore di ritrasmissioni

Page 63: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

62

• utilizzando una formula ‘lenta’, in media i trasferimenti sono di durata maggiore

rispetto alla formula standard. In compenso però si ha un occhio di riguardo alla

banda

• utilizzando una formula ‘equilibrata’, ovvero i cui valori RTO sono compresi tra il

minimo ed il massimo dei due scenari precedenti, in media i trasferimenti sono

simili alla formula standard

Page 64: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

63

CONCLUSIONI

Oggetto di studio di questo elaborato è stato la realizzazione di un’infrastruttura per attuare

politiche alternative di ritrasmissione in TCP. Essendo esso un protocollo affidabile, il

trasferimento dei dati tra due endpoint deve essere garantito. Spesso i dati inviati oppure la

risposta stessa dell’avvenuta ricezione inviata dal ricevente vanno persi. Quindi allo

scadere di RTO, i dati non ancora confermati devono essere ritrasmessi. Tale processo

avviene appunto con delle politiche di ritrasmissione.

In linea con gli obiettivi prefissi è stata costruita l’infrastruttura seguente che consente di:

• ottenere informazioni sui valori di RTT e RTO relativi ad una connessione

• modificare la formula per l’aggiornamento dinamico di RTO: essa può essere

associata ad una singola connessione oppure a tutto il sistema

Con l’infrastruttura proposta è possibile modificare la formula per il calcolo di RTO e

testarne immediatamente gli effetti introdotti nella comunicazione, senza dover far ripartire

il sistema operativo, o tanto meno ricompilare il kernel. Inoltre volendo approfondire

ulteriormente l’analisi si può avere accesso ai valori RTT e RTO relativi ad una

connessione TCP.

Nella progettazione di questa infastruttura un occhio di riguardo in più è stato posto sulla

performance e la semplicità d’utilizzo. La performance non è intesa solamente come

prestazioni dal punto di vista della cpu, ma anche come “interferire il meno possibile” col

corso d’azione dello stack TCP. La semplicità d’utilizzo è importante in quanto un sistema

di test non può in alcun modo avere un tempo di set-up tale da renderlo inutilizzabile.

Una serie di test effettuati su campioni di connessioni TCP hanno evidenziato che

l’impatto delle modifiche apportate non ha in alcun modo compromesso il normale

funzionamento del kernel o le sue perfomance. Anche l’impatto delle sessioni di

registrazione attuate su connessioni TCP non interferisce sulle loro performance.

Page 65: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

64

Con l’intenzione di dimostrare la semplicità e flessibilità d’utilizzo dello strumento

proposto sono stati presi in considerazione come casi di studio due formule per

l’aggiornamento dinamico di RTO: ‘chu’ e ‘speedy’. Nel primo caso si tratta di una

formula già oggetto di ricerca (vedasi Referenze Jerry Chu [5]), per la quale tra l’altro si è

verificato che i risultati sono in linea con quanto riportato in literatura. Il secondo caso

invece riguarda una formula di test pensata piuttosto come un ulteriore esempio.

Ovviamente l’infrastruttura in futuro richiederà modifiche e miglioramenti. Per iniziare,

ulteriori informazioni sulla connessione TCP, che durante l’utilizzo potrebbe nascere la

necessità di avere. Un ulteriore miglioramente è l’aggiornamento dinamico della formula

RTO in tempo reale, in funzione delle elaborazioni effettuate su sessioni di registrazione.

In tempo reale i valori RTT e RTO su specifiche connessioni, vengono elaborate ed il

risultato di questa elaborazione viene utilizzato per modificare la formula. Questo

ovviamente implica un’altra infrastruttura affiancata alla corrente. Alcuni possibili scenari

ove tale miglioramento può risultare utile sono:

• ottimizzare il trasferimento dei dati tra due reti aziendali divise da Internet, che si

adatta a possibili ritardi della rete (intervalli giornalieri, router intermedi non

funzionanti ecc)

• adeguarsi alle caratteristiche della rete nella quale un dispositivo mobile si muove

Page 66: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

65

Referenze

[1] Gary R. Wright, Richard Stevens “Tcp/Ip illustrated, Volume 2: The

implementation”

[2] Daniel P. Bovet, Marco Cesati “Understanding Linux Kernel, 3rd Edition”

[3] Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman “Linux Device

Drivers 3rd Edition”

[4] Robert Love “Linux Kernel Development 2nd Edition”

[5] http://www.ietf.org/proceedings/75/slides/tcpm-1.pdf

[6] Nabil Seddigh “Performance analysis of TCP’s Retransmission Timeout

Mechanism”

[7] www. http://people.ee.ethz.ch/~arkeller/linux/kernel_user_space_howto.html

[8] http://www.linuxfoundation.org/collaborate/workgroups/networking/tcp_testing

[9] http://www.ibm.com/developerworks/library/j-zerocopy/

[10] http://www.mjmwired.net/kernel/Documentation/memory-barriers.txt

[11] http://www.mjmwired.net/kernel/Documentation/circular-buffers.txt

[12] http://www.mjmwired.net/kernel/Documentation/atomic_ops.txt

[13] http://blogs.arm.com/software-enablement/448-memory-access-ordering-part-2-

barriers-and-the-linux-kernel/

[14] http://www.mjmwired.net/kernel/Documentation/networking/packet_mmap.txt

[15] http://www.rossbencina.com/code/lockfree

[16] http://www.shorewall.net/traffic_shaping.htm

[17] http://lartc.org/howto/

[18] http://www.guyrutenberg.com/2007/09/22/profiling-code-using-clock_gettime/

Page 67: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

66

Appendice

I file sorgente modificati e quelli nuovi sia a livello kernel che utente sono raggruppati in

un’unica directory, che a sua volta contiene le seguenti subdirectory:

• include

si trovano tutti i file header a livello kernel. In particolare si trovano i vari header

kernel modificati, ma anche quelli creati ex novo.

• net

si trovano tutti i file sorgente a livello kernel. In particolare si trovano i vari file

kernel modificati, ma anche quelli creati ex novo.

• tesi

si trova il resto dei file. Vi si trovano i vari moduli kernel, sia quello della formula

rto che quello della registrazione RTT e RTO. Infine si trovano anche tutti gli

applicativi a livello utente.

A. Installazione

La versione Linux utilizzata è la Slackware 13.1. Nel nostro caso per semplicità esso è

stato installato in una macchina virtuale, VirtualBox. Per ulteriori dettagli su come

installare la VirtualBox, quindi Slackware si riporta nei vari tutorial disponibili in rete. Una

volta installata la versione base si procederà con la compilazione del kernel ‘vanilla’,

versione 2.6.34.7. Prima della compilazione vanno riportate le modifiche necessarie: in

parte modifiche al codice esistente ed in parte l’aggiunta di file sorgenti e header. Dopo la

compilazione vanno modificate opportunamente i file di conf affinche al boot venga

proposto anche il nuovo kernel tra le opzioni.

Una volta effettuato il boot con il kernel modificato, verranno compilati i vari moduli

kernel. Quello riguardante la registrazione RTT e RTO e quello delle formule rto. Infine

Page 68: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

67

verranno compilati lo skeleton e i programmi utilizzati per gli esperimenti: client e server.

In seguito verranno descritti più in dettaglio i passaggi tranne l’installazione della versione

Linux di base, per la quale si riporta nei vari tutorial disponibili in rete.

A.1 Upgrade del kernel

- decomprimere il kernel nella directory di destinazione

In questo caso la directory è “/usr/src/”.

tar -C /usr/src/ -xvf linux-2.6.34.7.tar.gz

cd /usr/src

rm linux

ln -s linux-2.6.34.7 linux

- copiare il file config esistente nella directory del nuovo kernel

zcat /proc/config.gz > /usr/src/linux/.config

cd linux-2.6.34.7

- preparare il file config

Il seguente comando ripercorrerà il file config esistente, utilizzandolo come configurazione

di partenza. Per funzionalità nuove chiederà l’intervento dell’operatore: almeno che non si

sappia esattamente cosa fare, si consiglia di confermare tutte le possibili scelte che a loro

volta sono quelle di default.

make oldconfig

- sovrascrivere i file del kernel 2.6.34.7 copiati in “/usr/src” con quelli modificati in questo

elaborato

In seguito vengono riportati i passi da seguire (si ricorda che /usr/src/linux-2.6.34.7 è la

directory dove il kernel nuovo è stato decompresso).

Page 69: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

68

cp ./include/net/rtt_data.h /usr/src/linux-2.6.34.7/include/net/

cp ./include/net/rtt_sampling.h /usr/src/linux-2.6.34.7/include/net/

cp ./include/net/tcp.h /usr/src/linux-2.6.34.7/include/net/

cp ./include/net/sock.h /usr/src/linux-2.6.34.7/include/net/

cp ./include/net/request_sock.h /usr/src/linux-2.6.34.7/include/net/

cp ./include/net/Kbuild /usr/src/linux-2.6.34.7/include/net/

cp ./net/ipv4/Kconfig /usr/src/linux-2.6.34.7/net/ipv4/ NO

- aggiungere nel file “/usr/src/linux-2.6.34.7/net/ipv4/Kconfig”, fine pagina il seguente

contenuto:

menuconfig TCP_RTO_FORMULA_ADVANCED

bool "TCP: advanced rto formula"

###help###

Support for selection of various TCP rto formula

modules.

Nearly all users can safely say no here, and a safe default

selection will be made (default rot formula as a fallback).

if TCP_RTO_FORMULA_ADVANCED

config TCP_RTO_FORMULA_CASA

tristate "TCP Rto casa"

depends on EXPERIMENTAL

default y

###help###

Formula default calcolo RTO

choice

prompt "Default TCP rto formula"

default TCP_RTO_FORMULA_CASA

help

Select the TCP rto formula that will be used by default

for all connections.

config DEFAULT_CASA

bool "casa"

endchoice

Page 70: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

69

endif

config TCP_RTO_FORMULA_CASA

tristate

depends on !TCP_RTO_FORMULA_ADVANCED

default y

config DEFAULT_TCP_RTO_FORMULA

string

default "casa"

- aggiungere al file “/usr/src/linux-2.6.34.7/net/ipv4/Makefile”:

a) obj-y: …

tcp_rto_formula.o rtt_sampling.o \ b) fine pagina obj-$(CONFIG_TCP_RTO_FORMULA_CASA) += tcp_rto_casa.o cp ./net/ipv4/rtt_sampling.c /usr/src/linux-2.6.34.7/net/ipv4/ cp ./net/ipv4/sysctl_net_ipv4.c /usr/src/linux-2.6.34.7/net/ipv4/ cp ./net/ipv4/tcp.c /usr/src/linux-2.6.34.7/net/ipv4/ cp ./net/ipv4/tcp_input.c /usr/src/linux-2.6.34.7/net/ipv4/ cp ./net/ipv4/tcp_ipv4.c /usr/src/linux-2.6.34.7/net/ipv4/ cp ./net/ipv4/tcp_output.c /usr/src/linux-2.6.34.7/net/ipv4/ cp ./net/ipv4/tcp_rto_casa.c /usr/src/linux-2.6.34.7/net/ipv4/ cp ./net/ipv4/tcp_rto_formula.c /usr/src/linux-2.6.34.7/net/ipv4/ cp ./net/ipv4/tcp_timer.c /usr/src/linux-2.6.34.7/net/ipv4/ cp ./net/ipv4/inet_connection_sock.c /usr/src/linux-2.6.34.7/net/ipv4/ cp ./net/ipv4/tcp_minisocks.c /usr/src/linux-2.6.34.7/net/ipv4/ cp ./net/core/sock.c /usr/src/linux-2.6.34.7/net/core/ ln -s /usr/src/linux-2.6.34.7/include/net/rtt_data.h /usr/include/net/rtt_data.h - compilazione cd /usr/src/linux-2.6.34.7 make menuconfig Attenzione: selezionare Networking support ---> Networking options ---> TCP: advanced rto formula (NEW) --->

assicurarsi di check-arlo (verrà selezionata la formula rto di default ‘casa’)

Page 71: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

70

alla fine prima di Exit salvare, rispondendo ‘yes’

make bzImage modules

L’operazione può richiedere 1 ora o più in base alla potenza del processore ed anche della

configurazione stessa

make modules_install

- posizionare opportunamente i kernel nuovi appena compilati

cp arch/x86/boot/bzImage /boot/vmlinuz-rtt-2.6.34.7

cp System.map /boot/System.map-rtt-2.6.34.7

cp .config /boot/config-custom-2.6.34.7

- modificare opportunamente i riferimenti simbolici ai file di config e mappa dei simboli

cd /boot

rm config

ln -s config-custom-2.6.34.7 config

rm System.map

ln -s System.map-rtt-2.6.34.7 System.map

- creare il file di init

Sostituire /dev/sda2 come dal caso voluto

mkinitrd -c -k 2.6.34.7-smp -m mbcache:jbd:ext4 -f ext4 -r /dev/sda2

- aggiungere alla fine di /etc/lilo.conf

image = /boot/vmlinuz-rtt-2.6.34.7

root = /dev/sda2

label = Linux-rtt

read-only

addappend = "rootfstype=ext4"

Page 72: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

71

- eseguire lilo affinche le modifiche abbiano luogo

lilo

Una volta fatto ripartire il kernel, compilare ogni subdirectory per verifica. Una volta che

la compilazione va a buon fine aggiungere in /etc/modules/rc.modules-2.6.33.4-smp, le

seguenti righe per installare al boot i device e caricare i moduli in automatico:

# loading our modules

if [ "$RELEASE" = "2.6.34.7#smp" ]; then

insmod /lib/modules/2.6.34.7#smp/rtto.ko

mknod /dev/rtto0 c 245 0

mknod /dev/rtto1 c 245 1

mknod /dev/rtto2 c 245 2

mknod /dev/rtto3 c 245 3

chgrp "root" /dev/rtto[0#3]

chmod 766 /dev/rtto[0#3]

fi

if [ "$RELEASE" = "2.6.34.7#smp" ]; then

insmod /lib/modules/2.6.34.7#smp/rto_chu.ko

fi

if [ "$RELEASE" = "2.6.34.7#smp" ]; then

insmod /lib/modules/2.6.34.7#smp/speedy.ko

fi

- ricompilazione

make bzImage modules

make modules_install

cp arch/x86/boot/bzImage /boot/vmlinuz-rtt-2.6.34.7

cp System.map /boot/System.map-rtt-2.6.34.7

cd /boot

mkinitrd -c -k 2.6.34.7-smp -m mbcache:jbd:ext4 -f ext4 -r /dev/sda2

lilo

Page 73: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

72

B. Modifiche apportate nel kernel

Le modifiche apportate nel kernel riguardano sia le strutture dati che il codice stesso. Per

quanto riguarda le strutture si tratta sia di quelle nuove che delle modifiche a quelle già

esistenti con le quali sono associate. Nel codice si tratta di modifiche apportate al codice

esistente ma anche di codice inserito ex novo.

B.1 Struttura tree modificato

In seguito viene riportata parte della struttura tree del sorgente kernel evidenziando

solamente le modifiche e file nuovi aggiunti (seguiti da *).

… include net request_sock.h

rtt_data.h* rtt_sampling.h* sock.h tcp.h Kbuild

net core sock.c ipv4 inet_connection_sock.c

rtt_sampling.c*

sysctl_net_ipv4.c

tcp.c

tcp_input.c

tcp_ipv4.c tcp_minisocks.c tcp_output.c tcp_rto_casa.c* tcp_rto_formula.c* tcp_timer.c

Kconfig

Makefile

Page 74: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

73

Segue il nome del file di configurazione dove tipicamente risiede del codice che si occupa

di far partire automaticamente servizi e/o applicativi. Nel caso in questione sono stati

aggiunti i moduli kernel sia quello per la registrazione RTT e RTO che le varie formula rto

utilizzate negli esperimenti.

/etc/modules/rc.modules-2.6.33.4-smp

B.2 Strutture nuove aggiunte

Strutture aggiunte nel kernel come supporto alla nuova infrastruttura.

./include/net/rtt_data.h

In esso vi sono definite le strutture basi, contenitori dei dati registrati nel contesto kernel.

Essendo il passaggio dei dati tra i due contesti perfezionato con il memory mapping, tali

strutture sono visibili anche nel contesto utente.

La seguente struttura viene utilizzata per il passaggio del campione RTT e RTO dallo stack

TCP all’infrastruttura proposta.

struct zsample

{

__u32 rtt;

__u32 rto;

long jiff_secs;

long jiff_nsecs;

__u8 type;

};

La struttura precedente non è un ottimo candidato per diventare l’elemento di un array. In

un architettura a 32 bit, il campo type, consumerebbe inutilmente 3 byte. La situazione

peggiora ulteriormente nel caso di un architettura a 64 bit. Ecco quindi la necessità dei

primi 5 campi della struttura seguente. I successivi campi, filled e emptied, sono utili al

produttore (chi aggiunge i dati) ed il consumatore (chi consuma i dati). I loro valori sono

intesi nel range [0 : BUFF_LEN - 1], indicando quindi l’elemento dell’array su cui sta

Page 75: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

74

lavorando, rispettivamente il produttore ed il consumatore.

struct zsample_buffer

{

__u32 rtts[BUFF_LEN];

__u32 rtos[BUFF_LEN];

long jiff_secs[BUFF_LEN];

long jiff_nsecs[BUFF_LEN];

__u8 types[BUFF_LEN];

__u32 filled;

__u32 emptied;

};

La seguente struttura raggruppa un insieme delle strutture appena descritta. I campi

filled_buffs e emptied_buffs, i cui valori sono intesi nel range [0 : BUFFERS - 1] si riferiscono

all’elemento dell’array buffs, su cui sta lavorando, rispettivamente il produttore e il

consumatore. Il campo overruns, modificato in scrittura solamente dal produttore, viene

incrementato quando esso sovvrascrive un array sul quale il consumatore sta lavorando. E’

compito del consumatore accorgersi di questa evenienza, quindi comportarsi di

conseguenza.

struct zsample_buffer_holder

{

struct zsample_buffer buffs[BUFFERS];

__u32 filled_buffs;

__u32 emptied_buffs;

__u32 overruns;

};

./include/net/rtt_sampling.h

struct zsample_sniff_session

{

struct zsample_buffer_holder data;

int (*take_sample) (struct sock *sk, struct zsample val);

__u32 stack_done;

__u32 module_release_data_called;

Page 76: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

75

long secs_from_epoch;

struct sock *sk;

void *private_data;

u32 zsynacks_sent;

u32 zsyn_sent;

};

• data : struttura dove i valori RTT e RTO vanno memorizzati

• take_sample : puntatore alla funzione che instrada il corso d’azione al modulo per la

registrazione di RTT e RTO

• stack_done : un flag inizialmente a 0 il cui valore viene cambiato a 1 dal processo di

rilascio delle risorse una volta che la connessione TCP a cui e associato viene

chiusa. Da quel momento, la struttura appartenente non sarà più referenziata dallo

stack TCP

• module_release_data_called : un flag inzialmente a 0 il cui valore viene cambiato a 1

dal modulo alla fine di una sessione di registrazione. Da quel momento la struttura

appartenente non sarà più referenziata dal modulo delle sessioni di registrazione

• secs_from_epoch : un timestamp in secondi. Viene aggiornato dal processo di rilascio

delle risorse quando i flag stack_done e module_release_data_called diventano uguali a

1. Successivamente quando il timestamp è “vecchio” (di 20 sec) la struttura

corrente viene rimossa dalla lista e la relativa memoria rilasciata

• sk : la struct sock alla quale una sessione di registrazione è associata. Alla fine di

una sessione tramite questo riferimento la connessione viene resa disponibile a

future sessioni

• private_data : è un riferimento ad una struttura per un utilizzo futuro. Attualmente

viene utilizzata per tenere un riferimento ad una struttura col quale si segnala al

contesto utente la presenza di buffer pieno

• zsynacks_sent : è un valore reso disponibile ad un eventuale sessione di registrazione.

Esso contiene il numero di pacchetti SYNACK inviati ad un endpoint remoto in

risposta ad un pacchetto SYN in ingresso

• zsyns_sent : è un valore reso disponibile ad un eventuale sessione di registrazione.

Esso contiene il numero di pacchetti SYN inviati per stabilire una connessione con

un endpoint remoto

Page 77: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

76

struct zsample_sock_sniff_session_wrapper

{

int stack_done;

long secs_from_epoch;

struct zsample_sniff_session *rttKernel;

};

Tale struttura inserita come referenza a quella sock, fa da ponte tra lo stack TCP ed il

modulo kernel delle sessioni di registrazione.

• stack_done : un flag inizialmente a 0 il cui valore viene cambiato a 1 dallo stack

quando la connessione TCP viene chiusa. Da quel momento la struttura

appartenente non sarà più referenziata dallo stack TCP

• secs_from_epoch : un timestamp in secondi. Viene aggiornato dal processo di rilascio

delle risorse quando i flag stack_done diventa uguali a 1. Successivamente quando

il timestamp è “vecchio” (di 20 sec) la struttura corrente viene rimossa dalla lista e

la relativa memoria rilasciata

• rttKernel : la struttura tramite la quale viene implementata la logica di una sessione

di registrazione. Tramite tale referenza lo stack TCP accede alle funzionalità del

modulo kernel

Le seguenti due strutture dati sono state progettate come nodi di una lista ad accesso

sequenziale. Contengono dei dati di payload/utili ed un riferimento al prossimo nodo nella

lista. La creazione di tali liste rende disponibili le referenze ai dati le cui risorse andranno

rilasciate.

struct zsample_sock_sniff_session_wrapper_node_list

{

struct zsample_sock_sniff_session_wrapper *data;

struct zsample_sock_sniff_session_wrapper_node_list *next;

};

Struttura dati contenitrice, progettata per essere un nodo di una lista sequenziale.

Page 78: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

77

• data : struttura dati associata a quella sock. Tale referenza è utile nella fase di

rilascio delle risorse

• next : il prossimo elemento nella lista

struct zsample_sniff_session_node_list

{

struct zsample_sniff_session *data;

struct zsample_sock_sniff_session_wrapper_node_list *node_father;

struct zsample_sniff_session_node_list *next;

};

Struttura dati contenitrice, progettata per essere un nodo di una lista sequenziale

• data : struttura dati rappresentante una sessione di registrazione. Tale referenza è

utile nella fase di rilascio delle risorse

• node_father : struttura dati rappresentante la connessione TCP. In questo modo è

possibile risalire alle strutture delle sessioni di registrazione, che verranno rimosse

una volta che una connessione TCP viene chiusa. Tale referenza è utile nella fase di

rilascio delle risorse

• next : il prossimo elemento nella lista

Le seguenti strutture sono utilizzate per implementare la logica delle formule rto. struct tcp_rto_formula_ops { struct list_head list; unsigned long flags; char name[TCP_RTO_FORMULA_NAME_MAX]; struct module *owner; void (*init)(struct sock *sk); void (*release)(struct sock *sk); void (*tcp_set_rto)(struct sock *sk, int origin, void *ptr); void (*tcp_set_rtt)(struct sock *sk, u32 rtt); unsigned long (*tcp_calc_synack_rto)(const struct request_sock *req); };

• list_head : un riferimento al primo elemento della lista a cui appartiene

• flags : campo utile all’implementazione del modulo kernel

• name : nome col quale il modulo kernel viene identificato

Page 79: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

78

• owner : un riferimento al modulo al quale la struttura corrente è associata

• init : puntatore a funzione nel modulo kernel che va chiamato una volta solamente e

prima di qualsiasi altra, quando una connessione tcp utilizza la formula corrente.

Tipicamente il suo utilizzo concerne inizializzazioni riguardanti la connessione

TCP.

• release : puntatore a funzione nel modulo kernel che va chiamato una volta

solamente ed alla fine, quando una connessione TCP non utilizza più la formula

corrente. Tipicamente il suo utilizzo concerne de-inizializzazioni riguardanti la

connessione. Speculare al puntatore a funzione precedente.

• tcp_set_rto : puntatore a funzione nel modulo kernel col quale viene aggiornato il

valore RTO.

• tcp_set_rtt : puntatore a funzione nel modulo kernel col quale viene aggiornato il

valore RTT. Il suo motivo non è solamente per l’aggiornamento di RTT, ma anche

per il fatto di rendere tale valore disponibile al modulo kernel

• tcp_calc_synack_rto : puntatore a funzione nel modulo kernel col quale viene

calcolato il valore di RTO durante la fase 3WHS

La struttura seguente fa da ponte tra la struttura precedentemente descritta e la struttura

sock. Esse sono definite in net/sock.h.

struct tcp_rto_formula_specific

{

const struct tcp_rto_formula_ops *ops;

__u32 rto_formula_rto_max;

__u32 rto_formula_rto_min;

__u32 rto_formula_rto_initial;

__u32 rto_formula_rto_three_whs;

void *data;

};

• ops : la struttura rappresentante il modulo kernel che implementa la logica della

formula rto

• rto_formula_rto_max : indica il valore massimo che RTO può avere

• rto_formula_rto_min : indica il valore minimo che RTO può avere

Page 80: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

79

• rto_formula_rto_initial : indica il valore iniziale che RTO ha, appena la connessione

tcp viene istituita

• rto_formula_rto_three_3whs : indica il valore che RTO ha inizialmente nella fase

3WHS

• data : tale campo è stato pensato per un utilizzo futuro. Consente alla connessione

di avere una propria struttura dati in relazione col modulo kernel

B.3 Strutture esistenti modificate

Le strutture nuove poc’anzi descritte sono associate a quelle già esistenti. La seguente

struttura viene utilizzata dal sistema nella fase 3WHS. Una volta che la connessione viene

stabilita essa viene rimpiazzata dalla struttura sock. Definita in include/net/request_sock.h.

struct request_sock

{

...

u32 zsynacks_sent;

unsigned long calced_rto;

};

• zsynacks_sent : contatore, tiene traccia degli SYNACK inviati durante la fase di

3WHS

• calced_rto : contiene l’ultimo valore aggiornato di RTO durante la fase 3WHS

Le seguenti modifiche riguardano la struttura sock. Tramite tali campi lo stack tcp

raggiunge sia il modulo kernel della formula rto che quello delle sessioni di registrazione.

Definita in include/net/sock.h

struct sock

{

struct zsample_sock_sniff_session_wrapper *zrtt_private;

u32 meas_rtt;

atomic_t tcp_deallocing;

atomic_t sniff_available;

Page 81: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

80

u32 zsynacks_sent;

u32 zsyns_sent;

struct tcp_rto_formula_specific rto_formula;

};

• zsample_sock_sniff_session_wrapper : la struttura tramite la quale lo stack TCP

raggiunge il modulo kernel che si occupa delle sessioni di registrazione

• meas_rtt : viene memorizzato l’ultimo valore ‘grezzo’ di RTT

• tcp_deallocing : viene posta a 1 quando la struttura sock viene rilasciata. In questo

modo viene informata la parte che si occupa delle sessioni di registrazione che il

riferimento alla struttura sock associata ormai è NULL

• sniff_available : viene posta a 1 quando una sessione di registrazione termina. In

questo modo la relativa connessione TCP è disponibile ad ulteriori sessioni

• zsynacks_sent : contatore, tiene traccia del numero di pacchetti SYNACK inviati

durante la fase 3WHS

• zsyns_sent : contatore, tiene traccia del numero di pacchetti SYN inviati durante la

fase 3WHS

• rto_formula : la struttura tramite la quale lo stack TCP raggiunge il modulo kernel

per l’aggiornamento dinamico di RTO

B.4 Codice ex novo

net/ipv4/rtt_sampling.c

Viene implementata la logica relativa alle sessioni di registrazione. Riguarda sia le

funzioni con le quali esso si interfaccia col modulo kernel per l’inizio e termine delle

sessioni di registrazione, che quelle con le quali si interfaccia con lo stack TCP. Inoltre vi

si trovano tutte le funzioni riguardanti il rilascio delle risorse occupate per le sessioni di

registrazione. Per ulteriori dettagli fare riferimento al codice sorgente stesso.

net/ipv4/tcp_rto_formula.c

Viene implementata la logica relativa alle formule per l’aggiornamento dinamico di RTO.

Una parte delle funzioni implementate, riguarda l’interfaccia con il contesto utente: come

aggiungere e rimuovere una formula oppure fornire la lista di quelle disponibili nel

Page 82: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

81

sistema. Dall’altra parte ci sono le funzioni riguardanti l’interfaccia con lo stack TCP. Ci si

riferisce alle funzioni con le quali una connessione viene associata/deassociata con/da una

formula rto. Infine viene fornita una formula per il calcolo di RTO che verrà utilizzata da

connessioni TCP finchè non si disporrà diversamente: associare la formula di default

oppure una a scelta. Tale formula implementa quella attualmente utilizzata nel kernel. Il

suo motivo è semplicemente quello di avere il sistema sempre in una situazione stabile.

net/ipv4/tcp_rto_casa.c

E’ la formula rto disponibile nel sistema già dall’inizio. Essa inizialmente è l’unica

formula disponibile, quindi quella di default. Implementa il calcolo di RTO come

attualmente nel kernel viene fatto. Il modulo kernel col quale tale logica è implementata

non è rimovibile, affinche il sistema abbia sempre una formula rto disponibile.

B.5 Codice esistente modificato

In molti punti nel codice del kernel sono state apportati delle modifiche. Le righe di codice

nuove aggiunte verranno precedute da ‘/*NEW*/’, invece quelle commentate da

‘/*OBSOLETE*/’. Per ognuno dei file sorgente modificati seguono una descrizione dei

punti più importanti.

net/ipv4/inet_connection_sock.c

• inet_csk_reqsk_queue_prune : il corso d’esecuzione dello stack tcp viene deviato per il

modulo kernel che implementa la formula rto (vedasi tcp_synack_calc_rto)

net/ipv4/sysctl_net_ipv4.c

Viene reso possibile tramite l’interfaccia /proc/sysctl la gestione delle formule rto:

inserimento/rimozione e lista delle formule disponibili.

Page 83: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

82

net/ipv4/tcp.c

Viene reso possibile tramite l’interfaccia get/setsockopt l’associazione di una formula rto a

scelta tra quelle disponibili alla connessione TCP corrente.

net/ipv4/tcp_minisocks.c

• tcp_create_openreq_child : tale funzione viene chiamata quando una connessione

incoming viene stabilita. Dalla struttura request_sock viene costruita una sock,

copiando anche il numero di pacchetti SYNACK inviati e l’ultimo valore

aggiornato di RTO durante la fase 3WHS.

net/ipv4/tcp_input.c

• tcp_init_metrics : tale funzione viene chiamata appena una connessione TCP viene

stabilita. Il corso d’esecuzione dello stack viene deviato nel modulo kernel che

implementa la formula rto. Inoltre nel caso una sessione di registrazione fosse

attiva viene inoltre fatta una chiamata al rispettivo modulo.

• tcp_valid_rtt_meas : tale funzione viene chiamata ogni volta che un ACK di

pacchetto/i viene elaborato. Il corso d’esecuzione dello stack viene deviato nel

modulo kernel che implementa la formula rto. Inoltre nel caso una sessione di

registrazione fosse attiva viene inoltre fatta una chiamata al rispettivo modulo.

net/ipv4/tcp_ipv4.c

• tcp_v4_err : tale funzione viene chiamata quando il modulo icmp rileva un errore es.

HOST_UNREACHABLE. Il corso d’esecuzione dello stack viene deviato nel

modulo kernel che implementa la formula rto. Inoltre nel caso una sessione di

registrazione fosse attiva viene inoltre fatta una chiamata al rispettivo modulo.

• tcp_v4_send_synack : tale funzione viene chiamata ogni volta che un pacchetto

SYNACK viene inviato. La modifica riguarda l’aggiornamento del contatore di

SYNACK inviati.

Page 84: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

83

• tcp_v4_syn_recv_sock : tale funzione viene chiamata appena una connessione TCP

incoming viene stabilita. La connessione TCP appena creata, eredita la formula rto

del padre ovvero della connessione TCP in accept dalla quale proviene.

• tcp_v4_init_sock : tale funzione viene chiamata quando una struttura sock viene

creata. Oltre ad associare alla struttura la formula rto di default disponibile, essa

inizializza una serie di variabili.

• tcp_v4_destroy_sock : tale funzione viene chiamata quando una struttura sock viene

rilasciata. L’implementazione riguarda l’aggiornamento di variabili utili per il

rilascio delle risorse di eventuali sessioni di registrazione. Inoltre il riferimento al

modulo della formula rto viene rimosso.

net/ipv4/tcp_timer.c

• tcp_retransmit_timer : tale funzione viene chiamata quando il timer RTO scade. Il

corso d’esecuzione dello stack viene deviato nel modulo kernel che implementa la

formula rto. Inoltre nel caso una sessione di registrazione fosse attiva viene inoltre

fatta una chiamata al rispettivo modulo.

net/ipv4/Kconfig

le modifiche riguardano la configurazione fatta per la compilazione del kernel. In sostanza

riguardano la scelta della formula rto da compilare integrata nel kernel.

net/ipv4/Makefile

le modifiche riguardano i vari object header files da includere nella fase di compilazione.

In particolare la componente che implementa le sessioni di registrazione e la gestione delle

formule rto.

rc.modules-2.6.33

le modifiche riguardano l’esecuzione automatica nella fase di boot del sistema. In

particolare la creazione dei device per le sessioni di registrazione oppure varie formule rto

sperimentali.

Page 85: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

84

C. Moduli kernel

I moduli kernel creati riguardano:

• formula per l’aggiornamento dinamico di RTO

• sessione di registrazione

C.1 Modulo formula rto

Il modulo implementa le api tipiche register e unregister le quali vengono chiamate al

caricamento ed alla rimozione del modulo stesso. Seguono le api con le quali il modulo

stesso viene associato alla connessione tcp: xxx_init e xxx_release. Infine le api utilizzate

dallo stack tcp per aggiornare RTO: xxx_set_rto, xxx_set_rtt, xxx_tcp_calc_synack_rto. E’

proprio in questo modulo che viene implementata la funzione che aggiorna RTO in

funzione delle condizioni per cui si verifica:

• ack ricevuto

• rto scaduto

• connessione appena stabilita

• errore modulo icmp

Il contenuto (file sorgente + Makefile) di questo modulo si trovano nella subdirectory:

tesi/chu per la formula rto ‘chu’ e tesi/speedy per la formula rto ‘speedy’.

C.2 Modulo sessione di registrazione

Il modulo implementa le api tipiche xxx_init e xxx_exit le quali vengono chiamate al

caricamento ed alla rimozione del modulo stesso. Seguono le api per la gestione del

device: apertura e chiusura ed infine le chiamate ioctl. Queste ultime in base ai parametri si

distinguono in:

Page 86: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

85

• inizio sessione

• attesa di dati in arrivo

• lettura della formula rto associata alla connessione TCP

• associazione di una formula rto a scelta tra quelle disponibili alla connessione TCP

• fine sessione

L’apertura e la chiusura del device coincide con la creazione e la rimozione di una zona di

memoria per il memory mapping. Infine in questo modulo viene implementata anche la

funzione che si occupa di immagazzinare opportunamente i valori RTT e RTO nelle

relative strutture dati, quindi informare il contesto utente in presenza di.

Il contenuto (file sorgente + Makefile) di questo modulo si trovano nella subdirectory:

tesi/rtto.

D. Contesto utente: skeleton, client, server

Nel contesto utente è stato implementato un layer per le sessioni di registrazione al fine di

semplificarne l’utilizzo. Utilizzando questo layer sono stati implementati anche gli altri

due programmi di test: client e server.

D.1 Skeleton

Lo skeleton oltre a nascondere i dettagli riguardanti l’apertura/chiusura del device e

inizio/fine della sessione si occupa anche di prelevare i dati dal contesto kernel per poi

consegnarli a quello utente. Quest’ultima operazione è resa possibile tramite un puntatore

di funzione col quale lo skeleton invia i dati all’applicativo. Segue il necessario per iniziare

una sessione di registrazione.

Il contenuto (file sorgente + Makefile) di questo modulo si trovano nella subdirectory:

tesi/xskeleton.

Page 87: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

86

/*****************************************************************************************/

rtt_ctrl* driver_ctrl;

static void wrapper_take_data_pointer(void *ptr, struct zsample samples[], int len)

{

// elaborazione dei dati

}

main

{

// apertura device

driver_ctrl.state = 0;

driver_ctrl.take_data_cplus = wrapper_take_data_pointer;

driver_ctrl.driver_name = ”/dev/rtto0”;

open_device(&driver_ctrl, &err_code);

// inizio sessione

driver_ctrl.conn.saddr = inet_addr(“192.168.1.101”);

driver_ctrl.conn.daddr = inet_addr(“85.11.172.64”);

driver_ctrl.conn.sport = 54708;

driver_ctrl.conn.dport = 80;

begin_session(&driver_ctrl, &err_code);

// loop continuo

while(1) sleep(1);

}

/*****************************************************************************************/

D.2 Client

L’applicativo client si collega alla porta 80 di un indirizzo ip (oppure web previa

risoluzione dns), quindi effettua il file upload. Nel caso specifico il sito web sul quale è

stato testato è “upload.factory.com”: un sito web che offre gratis la possibilità di file

Page 88: Progetto e realizzazione di un kernel linux per il controllo dinamico degli stimatori di perdita in tcp

87

upload/download. Ovviamente un altro sito web che offre le stesse funzionalità può

richiedere delle modifiche nel modo in cui la richiesta http viene fatta. Inoltre esso inizia

una sessione di registrazione per ogni file upload. Con i parametri di comando passati in

ingresso è possibile selezionare l’indirizzo di destinazione, il device da utilizzare per le

sessioni, la formula rto da utilizzare ed infine il nome file per l’upload.

Il contenuto (file sorgente + Makefile) di questo modulo si trovano nella subdirectory:

tesi/xuploader.

D.3 Server

L’applicativo server offre le stesse funzionalità di quello client. Tra i parametri passati in

ingresso l’indirizzo ip destinatario viene sostituito dalla porta TCP sulla quale il server

starà in ascolto.

Il contenuto (file sorgente + Makefile) di questo modulo si trovano nella subdirectory:

tesi/xserver.