Il livello di Trasporto
Questa sezione è dedicata all'analisi dei protocolli di livello 4 dell'Internet Protocol Suite: TCP e UDP .
TCP
Il simulatore NS permette di utilizzare diversi tipi di Agents TCP che sono raggruppati in due classi principali: TCP-oneway e Full-TCP. Nel primo caso è possibile creare solo connessioni sbilanciate e non c'è traccia né del Three-way-handshake, né dei pacchetti di FIN per la chiusura della connessione. Al contrario gli agents della classe Full-TCP possono instaurare connessioni bilanciate e mostrano tutti i pacchetti di controllo spediti.
TCP-oneway
Il simulatore permette di utilizzare diversi agents di tipo TCP-oneway.
Gli agents TCP sono configurati in base al valore di alcune variabili definite ed inizializzate nel file ns-default.tcl e che possono essere modificate dall'utente nei seguenti modi:
1.Agent/TCP set window_ 100 : questa stringa imposta il valore di window_ a 100 per tutti gli agent TCP presenti nella simulazione.
2.$tcp0 set window_ 100 : con questa stringa si limita la precedente impostazione al solo agent $tcp0
Connessioni TCP-oneway
Per creare una connessione tra due nodi è possibile utilizzare la procedura di NS create-connection{} nel seguente modo:
set <name_connection> [$ns create-connection <source_agent> <source_node> <destination_agent> <destination_node> <flow_identifier>]
Ad esempio il file tcp1w02.tcl contiene la seguente riga di codice:
set tcp02 [$ns create-connection TCP $n0 TCPSink $n2 0]
Trasmissione dati
E' possibile impostare alcune variabili:
packetSize_ : dimensione in byte del pacchetto TCP comprendente l'header IP. In pratica si stabilisce la dimensione del pacchetto di livello3. Il valore di default è 1000.
overhead_ : se impostata ad 1 introduce un ritardo random tra due trasmissioni successive. Il valore di default è zero.
Controllo di congestione
cwnd_ : valore della finestra di congestione in numero di pacchetti. Viene inizializzata a windowInit_ ,il cui valore di default è 1. cwnd_ limita il numero massimo di pacchetti non riscontrati che la sorgente può avere in giro per la rete.Durante Slow-Start (cwnd_ < ssthresh_), la finestra viene aumentata di uno per ogni nuovo ack arrivato. Durante un'azione di "congestion-avoidance" (cwnd_ > ssthresh_), viene aumentata di (1/cwnd_) per ogni nuovo ack.
ssthresh_ : valore della soglia in numero di pacchetti. Default 0.
La congestione viene rilevata in presenza di un numero maggiore di NUMDUPACKS (definita in tcp.h) ack duplicati ,o in caso di un pacchetto in timeout.
A seconda del tipo di agent TCP reagisce in modo leggermente diverso ad una congestione. Nei nostri esempi abbiamo utilizzato l'agent TCP il quale adotta la seguente strategia:
Imposta ssthresh_ a metà della corrente finestra (minimo tra cwnd_ e window_) se è maggiore di due,oppure a 2. cwnd_ viene riportata a windowInit_.
L'esempio cong_mu_cod.tcl (visualizza o scarica il file) mostra una situazione del genere.
Controllo di flusso
window_ : valore della finestra di controlllo di flusso in numero di pacchetti.Default 20. Viene impostata sull'agent sorgente e dovrebbe recitare il ruolo della finestra mostrata dal ricevente. Il problema è che non viene aggiornata durante la simulazione.
Ritrasmissione
La documentazione al riguardo è insufficiente. Nelle simulazioni effettuate non abbiamo trovato riscontri con molte delle formule indicate.
Il simulatore utilizza le seguenti variabili per il calcolo del timeout:
rtt_ : round trip time.
srtt_ : smoothed (averaged) rtt.
rttvar_ : mean deviation of rtt.
backoff_ : non documentato
maxrto_ : valore massimo del timeout. Default 10000 (secondi).
queste variabili sono utilizzate dalle funzioni definite nel file tcp.cc
In caso di ritrasmissioni multiple viene utilizzato l'algoritmo di Karn.
Esempi TCP-oneway
1)Esempio tcp1wtout.tcl : visualizza o scarica questo file.
Abbiamo impostato maxrto_ 4. La prima ritrasmissione avviene dopo 2300 ms. Il link è ancora rotto, per cui si procede ad una seconda ritrasmissione che, secondo l'algoritmo di Karn, dovrebbe avvenire dopo 4600ms. Avviene invece dopo 4000ms.
Quando il link va di nuovo giù il timeout iniziale è di 1s. Anche in questo caso si arriva fino a 4s.
2)Esempio distvec2.tcl : visualizza o scarica questo file.
Ritrasmissione secondo l'algoritmo di Karn.
3)Esempio tcp_anello.tcl : visualizza o scarica questo file.
Ritrasmissione secondo l'algoritmo di Karn.
4)Esempio tcp1w02.tcl : visualizza o scarica questo file.
Questo esempio simula il comportamento di una connessione in cui il destinatario mostra inizialmente una finestra di controllo di flusso pari a 8 pacchetti ( variabile window_ impostata al valore 8 ). Il valore iniziale della soglia è quello standard previsto da TCP, ossia 64KB ( variabile ssthresh_ impostata a 64 pacchetti e packet_size_ a 1000 byte). La sorgente inizia ad inviare pacchetti secondo la politica di Slow-Start non trasmettendo burst più grandi di 8 pacchetti. Dopo un certo numero di burst ci saremmo aspettati una riduzione dei dati inviati in seguito ad una variazione della finestra di controllo di flusso, ma ciò non avviene perché la variabile window_ non viene aggiornata da NS durante la simulazione: il destinatario è sempre in grado di ricevere 8 pacchetti tutti insieme, ma non di più.
=> Ciò dipende dal fatto che NS non prevede agents destinatari del livello di applicazione, ma solo del livello di trasporto; quindi non è possibile simulare l'acquisizione dei pacchetti da parte di quel processo che sta usufruendo della connessione. Pertanto è necessario che l'utente imponga la variazione della finestra di controllo di flusso.Nell'esempio in questione la finestra passa a 16 nell'istante 2.0 e conseguentemente la sorgente emette un burst di 16 pacchetti.
5)Esempio tcp1wdelack.tcl : visualizza o scarica questo file.
L'esempio mostra una connessione tcp-oneway in cui l'agent destinatario è TCPSink/DelAck. Esso cerca di riscontrare due pacchetti con un singolo ack; quindi dopo l'arrivo di un pacchetto aspetta fino a interval_ secondi (default 100ms) l'arrivo del secondo. Se ciò non avviene è costretto ad inviare l'ack ugualmente. Nell'esempio in questione il primo pacchetto viene riscontrato da solo poichè, a causa di Slow-Start, il secondo non viene inviato di seguito. Successivamente i pacchetti sono riscontrati a due a due.
=> il difetto di questa simulazione è che
l'arrivo di un ack, benchè sia riferito a due pacchetti, provoca l'aumento di cwnd_
di una sola unità e non di due; pertanto il minor numero di ack si paga con una minore
quantità di dati inviati. Impostando nello stesso esempio il TCPSink (invece del
TCPSink/DelAck), si ha conferma di quanto detto. Vedi o scarica tcp1wnormack.tcl.
Questo tipo di agent permette una simulazione più realistica del traffico TCP, ma è ancora in fase di sviluppo, così come molte altre cose in NS.
Le principali caratteristiche sono:
1)Vengono generati i pacchetti del Three-way-handshake e della chiusura della connessione.
2)E' possibile instaurare una connessione bilanciata. Non è previsto il piggybacking.
3)I numeri di sequenza sono riferiti ai byte invece che ai pacchtti.
4)La ritrasmissione è di tipo TCP Reno.
Creazione di una connessione Full-TCP
set ftcp0 [new Agent/TCP/FullTcp]
set ftcp2 [new Agent/TCP/FullTcp]
$ns attach-agent $n0 $ftcp0
$ns attach-agent $n2 $ftcp2
$ftcp0 set fid_ 0
$ftcp2 set fid_ 2
$ns color 0 red
$ns color 2 blue
$ns connect $ftcp0 $ftcp2
$ftcp2 listen (L'agent che riceverà la richiesta di connessione deve essere in ascolto)
$ftcp2 set window_ 16
$ftcp0 set window_ 8
La richiesta di connessione viene inoltrata quando l'applicazione che si appoggia sull'agent non in "listen" inizia a trasmettere. L'altra applicazione deve aspettare che la connessione sia avvenuta per trasmettere dati.
Quando uno dei due agent invia un pacchetto di FIN l'altro continua ad inviare dati ed a ricevere ack. Una volta chiusa la connessione con il FIN inviato dal secondo agent, potrebbero esserci ancora pacchetti nella rete. Ciò comporta la segnalazione di errori da parte di NS.
Nell'esempio fulltcp02.tcl (visualizza o scarica il file) l'agent che ha chiuso per secondo la connessione, riceve successivamente gli ack degli ultimi dati da esso inviati. NS stampa alcune stringhe di errore la cui sintassi non è purtroppo documentata. Sembra che si riferiscano a questi ack che probabilmente vengono rifiutati dal ricevente.
=>Da questo punto di vista la simulazione è deficitaria poichè, nella realtà, prima di chiudere una connessione bisognerebbe aspettare che tutti i pacchetti siano riscontrati.
L'utente può impostare le variabili di configurazione degli agent. Alcune di esse sono:
segsperack_ :numero di pacchetti riscontrati con un ack. Default 1.
segsize_ :MTU. Default 536.A differenza degli agent TCP-oneway questo valore è riferito al payload del pacchetto TCP . Negli output del NAM e nei trace file la dimensione di questi pacchetti è (segsize_ + 40), ossia gli vengono sommati l'header IP e TCP .
Inoltre nei suddetti output tutti i pacchetti provenienti dall'agent che ha richiesto la connessione sono chiamati "tcp" (anche gli ack), mentre quelli in senso contrario "ack". Ciò rende meno immediata la comprensione della simulazione.
L'agent UDP prende pacchetti da una sorgente di traffico ed eventualmente li frammenta se eccedono l'MTU.
L'utente può impostare la variabile packetSize_
Un esmpio di definizione di agent UDP è:
set udp0 [new Agent /UDP]
$ns attach-agent $n0 $udp0
$udp0 packetSize_ 536
Nonostante il protocollo UDP reale non lo preveda il simulatore assegna un numero di sequenza ad ogni pacchetto per facilitare il monitoraggio del traffico da parte dell'utente, senza però introdurre overhead aggiuntivo. Nell'output del NAM i pacchetti UDP portano il nome della sorgente di livello superiore che li ha generati.
Esempi di UDP:
routeStatic.tcl ; routeSession.tcl ;distvec1.tcl