REAL 5.0
Originariamente avremmo dovuto svolgere la nostra
tesina utilizzando
REAL 5.0 (http://www.cs.cornell.edu/skeshav/real/overview.html), un simulatore di reti di calcolatori sviluppato dalla Cornell University, e attualmente installato nel Dipartimento di Informatica e Automazione su piattaforma Linux.
Real 5.0, che da come viene presentato sembra essere un ottimo simulatore da utilizzare soprattutto per studiare il controllo di flusso ed il controllo di congestione nelle reti, ci ha deluso molto. Abbiamo incontrato notevoli difficoltà nell'acquisire padronanza del sistema sin dalle prime simulazioni di semplici configurazioni di rete. La documentazione disponibile su Real 5.0 è decisamente insufficiente. Mentre la mailing list di NS è piuttosto attiva e vi partecipano numerose persone che stanno effettivamente utilizzando il simulatore, la mailing list di NS è scarsamente frequentata e le domande che vengono poste riguardano nella maggioranza dei casi l'installazione del simulatore: questo significa non solo che se si vuole usare Real si hanno pochissime persone con le quali scambiare opinioni e alle quali chiedere consigli, ma anche che evidentemente il simulatore è stato pressoché abbandonato.
Inoltre, a prescindere da quelle che sono state le
difficoltà che abbiamo incontrato con Real 5.0, quando siamo entrati in contatto con NS
ci siamo subito resi conto che quest'ultimo simulatore presenta potenzialità decisamente
superiori ed è molto più interessante da studiare.
Se qualcuno desidera provare ad utilizzare il simulatore Real 5.0, deve avere un account AFS e loggarsi su una piattaforma Linux. Real 5.0 si trova nella directory afs/vn.uniroma3.it/group/proto/protoman. Siccome sotto l'utenza protoman è possibile leggere i file ma non è possibile modificarli o scriverne di nuovi, bisogna ricreare sotto il proprio account un ambiente per lavorare con il simulatore. E' necessario copiare in una directory la libreria di funzioni e realizzare un link simbolico all'eseguibile "simulate".
Per far partire Real 5.0 si deve eseguire il comando "simulate <nomefile.l>" dove <nomefile.l> è un file con estensione .l, scritto in NetLanguage, nel quale viene descritto lo scenario di una rete che si desidera simulare. In questo file di input si determina cioè la topologia della rete, si specificano i protocolli usati, il carico di dati generato da ogni sorgente e alcuni parametri di controllo quali le latenze, le larghezze di banda, le dimensioni dei pacchetti, ecc.
L'esecuzione di Real 5.0 crea degli output contenenti
i risultati della simulazione come ad esempio il numero di pacchetti spediti da ogni
sorgente, i ritardi in coda nei vari router, il numero di pacchetti dropped, il numero di
ritrasmissioni e così via.
Una rete viene modellata in Real 5.0 come un grafo dove i nodi possono essere sorgenti, destinatari o router.
Ci sono circa 30 diverse sorgenti, classificabili in due tipi fondamentali: quelle che realizzano controllo di flusso e quelle che non lo realizzano. Le sorgenti che realizzano controllo di flusso usano acknowledgements e timeouts per modellare un livello di trasporto connesso e affidabile, le altre generano pacchetti con una distribuzione nota a prescindere da ciò che accade nella rete e modellano un livello di trasporto non connesso.
Tra le sorgenti che operano un controllo di flusso ci sono "generic" (TCP con finestra di controllo di flusso costante), "telnet" (distribuzione temporale di tipo Poissoniano del carico di dati), "jk_reno" e "jk_tahoe" (due tipi di sorgenti TCP con finestra di controllo di flusso che varia dinamicamente).
Se si esclude telnet, a tutte queste sorgenti è possibile assegnare un numero finito di pacchetti da spedire. Una sorgente ftp non è disponibile. Tra le sorgenti che non operano un controllo di flusso ci sono "poisson", "background" (sorgente utile per creare e rimuovere colli di bottiglia: spedisce a rate costante per un certo periodo di tempo, è inattiva per un altro periodo e poi riprende il ciclo), "trace" (sorgente che legge un trace file e spedisce pacchetti in accordo con ciò che vi trova scritto). Il protocollo http non è implementato. Non si può porre più di una sorgente sullo stesso nodo, il che costituisce una severa limitazione. Inoltre non si possono porre l'una sull'altra sorgenti appartenenti a livelli ISO-OSI diversi.
Vi sono alcuni tipi di router disponibili, tra i quali i più semplici sono "fifo" (che utilizza una disciplina di gestione della coda di tipo fifo) e "fq" (coda fair queueing). I router sono dei semplici ripetitori dei quali si può scegliere la disciplina di gestione della coda, ma mancano dei veri e propri protocolli di routing.
Per i destinatari, si può utilizzare il nodo
di tipo "sink" che, a seconda del tipo di sorgente che gli spedisce i pacchetti,
invia o meno acknowledgements.
Il file di input scritto in NetLanguage deve contenere i seguenti campi, che si devono succedere nell'ordine indicato:
Il campo header ha la seguente struttura:
header {
network = nome_file
version = 0
}
nome_file è il nome del file che si sta scrivendo
version vale sempre 0
Il campo nest_params ha la seguente struttura:
nest_params {
passtime = . ;
maxnodes = . ;
monitor = custom_monitor;
}
passtime va espresso in sec,µsec e indica ogni quanto tempo vanno calcolate le statistiche da fornire alla fine della simulazione, il valore consigliato è 1 sec e più si aumenta questo valore più il simulatore sarà lento perché dovrà svolgere più calcoli.
maxnodes è il numero massimo di nodi della rete da
simulare.
Il campo real_params ha la seguente struttura:
real_params {
inter_pkt_delay = ;
random_seed = ;
buffer_size = ;
telnet_pkt_size = ;
ack_size = ;
telnet_window = ;
decongestion_mechanism = ;
end_simulation = ;
print_interval = ;
scale_factor = ;
}
Non tutti questi parametri devono essere necessariamente presenti.
inter_pkt_delay, end_simulation, print_interval, scale_factor, vanno espressi in secondi; print_interval indica ogni quanti secondi va stampato un rapporto con le statistiche calcolate; scale_factor è un fattore di scala temporale: se vale 1000, 1 secondo simulato corrisponde a 1 ms reale. Qualcosa di questo fattore di scala sembra non funzionare, in quanto impostando un fattore di scala uguale a 1 e una durata della simulazione uguale a 1000, non si ottiene una simulazione di 1000 secondi ma bensì una simulazione di pochi secondi.
random_seed è il seme utilizzato per inizializzare il generatore di numeri casuali: se vale 0 il seme viene scelto a caso ogni volta che si esegue la simulazione, e dunque si ottiene ogni volta una simulazione diversa; se invece è un numero diverso da zero (intero) la simulazione si ripete identica ad ogni esecuzione.
buffer_size va espresso in byte e indica la dimensione delle code di uscita dei vari nodi presenti nella rete. Quindi tutti i router devono avere la stessa dimensione della coda!
telnet_pkt_size e ack_size vanno espressi in byte. Ma non abbiamo capito a quale livello della pila ISO-OSI si riferisce la dimensione del pacchetto.
telnet_window va espresso in pacchetti e rappresenta il valore massimo che può essere assunto dalle finestre di congestione.
decongestion_mechanism può valere 0, 1, 2, 3: quando
una coda è piena, se questo parametro vale 0 viene gettato il pacchetto che si trova in
testa, se vale 1 viene gettato l'ultimo pacchetto, se vale 2 viene gettato un pacchetto a
caso, se vale 3 il nodo getta via l'intera coda.
Il campo nodes contiene un sottocampo "default" in cui viene definito un nodo di default, e poi una serie di sottocampi in cui per ogni nodo della rete si definiscono solo i parametri che assumono valori diversi da quelli di default.
nodes {
default {
function = ; #tipo di nodo
dest = ; #ID del destinatario (ignorato da nodi sink)
start_time = sec,µsec ; #istante in cui il nodo diviene attivo
plot=false ; #da settare se si vuole un grafico in output
num_pkts = ; #n.ro di pacchetti da spedire
on_time = ; #per sorgenti on-off
off_time = ; #per sorgenti on-off
peak = bit/sec ; #velocità massima di trasm.della sorgente
average = bit/sec ; #velocità media di trasm. della sorgente
jitter = µsec ; #massimo jitter desiderato
sch_policy = ; #1=fifo, 2=fq, 3=decbit, 4=fqbit, 5=hrr
}
node1 { ; ; ;}
node2 { ; ; ;}
}
Per i nodi sink l'ultimo parametro deve essere location = sorg. , dest;
Il campo edges è costituito da un sottocampo "default" in cui si stabiliscono i valori di default per i link e poi da un elenco di sottocampi che rappresentano i vari link della rete.
edges {
default {
bandwidth = bit/sec ;
latency = µsec ;
loss_prob = . ; #probabilità di perdere un burst di dati
loss_burst_size = . ; #n.ro medio pacchetti di un burst
corruption_prob = . ; #probabilità di errore su un bit
}
{ID sorgente à ID destinatario ;..parametri diversi da quelli di default.}
{ID sorgente à ID destinatario ;..parametri diversi da quelli di default.}
..
}
Output della simulazione
Il simulatore produce due tipi di output:
La tabella ha la forma seguente:
| Time | # | Type | G/w | Nxmit | Xmit | Q'ing | # | Drops | Retx | RTT |
| Una riga ogni print_interval | ID sorgente | Tipo di sorgente | ID router attraversato | pacchetti trasmessi | pacchetti trasmessi | Ritardo in coda min, medio, max | n.ro pacchetti in coda | totalepacchetti della sorgente persi | ritrasmissioni della sorgente | Rtt min medio max |
| ID sorgente | Tipo di sorgente | |||||||||
Dunque ogni print_interval viene stampata una riga per ogni sorgente e, se i pacchetti generati da una sorgente hanno attraversato più di un router, viene stampata una riga per ogni router attraversato.
Non ci è chiaro quale sia l'esatto significato di
vari parametri della tabella, e quali siano le relazioni che intercorrono tra di essi.
Sembra che la differenza tra Nxmit e Xmit sia che Nxmit non include le ritrasmissioni
mentre Xmit le include; si dovrebbe allora avere Xmit = Nxmit + Retx, ma raramente questa
relazione è verificata. Se Drops è il numero di pacchetti trasmessi dalla sorgente che
sono andati persi e Retx sono i pacchetti ritrasmessi della sorgente, si dovrebbe avere
Drops<=Retx, ma non sempre ciò accade. Forse vanno individuate relazioni tra i
parametri di righe diverse. Inoltre in alcuni casi la tabella riporta un numero diverso da
zero di Drops e ritardi in coda nulli, ma se i ritardi in coda sono nulli come possono
esserci Drops
Il Sommario è una tabella che contiene una riga per
ogni sorgente ed ha la forma seguente:
| Node | G/W | T'put | Q'ing | RTT | Drops | Retxs |
| ID sorgente | ID primo router attraversato | Throughput medio e varianza | Ritardo medio in coda e varianza | Rtt medio e varianza | pacchetti della sorgente andati persi | ritrasmissioni della sorgente |
Per far apparire nella tabella i dati relativi a tutti i router attraversati dai pacchetti generati da una sorgente bisogna operare delle modifiche al file kernel/table.c.