left.gif (284 bytes)  up.gif (289 bytes)  right.gif (280 bytes)

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:

  1. header
  2. nest_params
  3. real_params
  4. nodes
  5. edges

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:

  1. TIME TICKS
  2. SIMULATION REPORT
  1. I Time Ticks sono delle linee di valori che vengono stampate ogni print_interval durante la simulazione sullo standard output per mostrare cosa sta accadendo.
  2. Il Simulation Report viene stampato in un file chiamato "dump" e consta di due parti: una tabella costituita da print_interval/end_simulation righe, ed un sommario.

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.

left.gif (284 bytes)  up.gif (289 bytes)  right.gif (280 bytes)