Raport
Instytutu Automatyki i
Informatyki Stosowanej
Politechniki Warszawskiej
Wprowadzenie do symulatora
sieci NS-2
Andrzej Sikora
Ewa Niewiadomska-Szynkiewicz
E-mail: e-n-s@ia.pw.edu.pl
Raport nr: 02-14
Warszawa, 2002
Copyright 2000 by Instytut Automatyki i Informatyki Stosowanej
Politechniki Warszawskiej. Fragmenty tej publikacji mogą być kopiowane i
cytowane pod warunkiem zachowania tekstu niniejszych zastrzeżeń w każdej kopii
oraz powiadomienia Instytutu Automatyki i Informatyki Stosowanej.
Raport wykonany w ramach projektu KBN
nr.134/E-365/SPUB-M5.PR/DZ 320/2000-2002.
Rozdział 1 „Interfejs użytkownika”
Rozdział 2 „Podstawy symulatora”
2.1
Część zarządzająca i obliczeniowa NS-2
2.2
Węzły i przesyłanie pakietów
Rozdział 4 „Sieci lokalne LAN”
Rozdział 5 „Struktura adresowa w NS-2”
6.3
Modele propagacji radiowej
Rozdział 8 „Protokoły transportu”
Rozdział 9 „Inne moduły i aplikacje”
9.3
Monitorowanie i zapis przebiegu symulacji
9.7 NAM – The Network Animator
DODATEK A – przykład użycia NS-2
NS-2 realizuje symulację ze zmiennym zmiennym
krokiem czasowym (opartą na zdarzeniach). Może być wykorzystany do badania
różnych mechanizmów stosowanych w sieciach komputerowych. Praca z systemem
rozpoczyna się od zdefiniowania topologii badanej sieci. Następnie dostarczane
są szczegółowe informacje dotyczące węzłów sieci, sposobów transmisji (użyte
protokoły, algorytmy rutingu), parametrów transmisji (częstotliwość,
opóźnienia, itp.).
Konfiguracja
symulatora wprowadzana jest w postaci skryptu OTcl. Część obliczeniowa
zrealizowana jest w języku C++. NS-2 dostarcza wielu modułów realizujących
różne protokoły sieciowe, uwzględniając połączenia stałe, radiowe i
satelitarne. Dostępnych jest również kilka mechanizmów rutingu, od statycznego
do dynamicznego. Mechanizmy umożliwiające wprowadzenie zróżnicowania jakości
usług pozwalają na wykonywanie badań przy założeniu różnych gwarancji jakości
(SLA Service-Level-Agreement). NS-2 udostępnia narzędzia do
monitorowania przebiegu symulacji oraz archiwizowania jej wyników.
System
jest zrealizowany zgodnie ze standardem architektury otwartej oprogramowania.
Dzięki odpowiedniej dekompozycji kodu jest przejrzysty i stosunkowo przyjazny
użytkownikowi. Jest elastyczny i może być również w łatwy sposób rozbudowywany.
NS-2 jest
aplikacją jednowątkową, a więc obliczenia są realizowane przez pojedynczy
procesor. Może stanowić to istotną wadę systemu w przypadku badań rozległych,
złożonych sieci. Proponowane są w tym przypadku różne rozwiązania
wykorzystujące agregację i wykonanie obliczeń dla podsystemów, ale mają one
różne wady.
Symulator
powstał w ramach projektu VINT przy współpracy z UC
Berkeley, LBL, USC/ISI
i Xerox PARC. Oryginalna dokumentacja
dostępna jest pod internetowym adresem http://www.isi.edu/nsnam/ns/ns-documentation.html
Symulator NS-2 jest drugą wersją aplikacji. Wersja ta różni się od poprzednika przede wszystkim:
Symulator
NS często wzbogacany jest o nowe protokoły, niestety niniejszy dokument nie
jest w stanie objąć informacji o wszystkich wprowadzonych modelach i
szczegółach technicznych rozwiązania. Bardzo często modele te powstają w sposób
niezależny, w różnych instytucjach i grupach badawczych i nie są w pełni
przetestowane. Wiele prac nad modułami symulatora pozostaje ciągle otwartych i
konieczne są uaktualnienia. Autorzy implementacji modeli oczekują od
użytkowników ich uwag oraz informacji o ewentualnych błędach w programie.
Symulator
używa dwóch języków, C++ i OTcl , ponieważ zadanie, które wykonuje można
podzielić na dwie grupy:
Klasy interpretera OTcl:
Interfejs
symulatora obsługiwany JEST przez język Tcl (../ns-2/tcl/lib/ns-lib.tcl).
Służy on do zdefiniowania modelu symulowanego systemu tj. wprowadzenia jego
pełnej konfiguracji, dodawania zdarzeń, wyboru ich typów, itp. Napisany w
języku Tcl skrypt symulacyjny rozpoczyna się zwykle od stworzenia instancji
klasy odpowiadającej za symulację, następnie wywołania metod tworzących węzły i
topologię symulowanej sieci oraz konfiguracji niektórych parametrów modelu.
Procedura
inicjalizacji:
Symulator
NS jest symulatorem opartym na zdarzeniach. Jest to program jednowątkowym,
dlatego w danym momencie fizycznie obsługiwane jest tylko jedno zdarzenie z
listy – wybierane przez odpowiedniego zarządcę. Jednostką czasu wykorzystywaną
przez zarządcę zdarzeń jest sekunda.
W budowie
symulatora można wyróżnić cztery typy
zarządców zdarzeń (różnią się wykorzystywaną strukturą danych):
Moduły
współpracujące z symulatorem:
W
rozdziale tym przedstawiony jest podstawowy element topologii sieci
komputerowej – węzeł. Pod pojęciem węzła rozumiemy fizyczny element sieci
komputerowej, który wysyła lub odbiera pakiety (np. host, ruter, hub, itp.).
Definicja
klasy węzła (plik node.h)
class Node : public ParentNode {
public:
Node(void);
~Node();
inline int
address() { return address_;}
inline int
nodeid() { return nodeid_;}
inline
bool exist_namchan() const { return (namChan_ != 0); }
virtual
int command(int argc, const char*const* argv);
virtual
void namlog(const char *fmt, ...);
NsObject*
intf_to_target(int32_t);
static
struct node_head nodehead_; // static
head of list of nodes
inline
void insert(struct node_head* head) {
LIST_INSERT_HEAD(head,
this, entry);
}
inline
Node* nextnode() { return entry.le_next; }
// The
remaining objects handle a (static) linked list of nodes
// Used by
Tom's satallite code and the wireless code
inline
const struct if_head& ifhead() const { return ifhead_; }
inline
const struct linklist_head& linklisthead() const {
return
linklisthead_;
}
//
lista węzłów sąsiednich
neighbor_list_node* neighbor_list_;
void
addNeighbor(Node *node);
static
Node* get_node_by_address(nsaddr_t);
//
obiekty zarządzające rutingiem
void route_notify (RoutingModule *rtm);
void unreg_route_notify(RoutingModule *rtm);
void
add_route (char *dst, NsObject *target);
void
delete_route (char *dst, NsObject *nullagent);
void
set_table_size(int nn);
void
set_table_size(int level, int csize);
protected:
LIST_ENTRY(Node) entry; // deklaracja
listy wejść do węzła
int address_; // unikalny adres
węzła
int nodeid_; // unikalny numer
id węzła
// zmienne dla programu NAM
Tcl_Channel namChan_;
// Single
thread ns, so we can use one global storage for all
// node
objects
static
char nwrk_[NODE_NAMLOG_BUFSZ];
void
namdump();
struct
if_head ifhead_; // list of phys for this node
struct
linklist_head linklisthead_; // list of link heads on node
// pointer
to head of rtmodule chain
RoutingModule*
rtnotif_;
#ifdef NIXVECTOR
NixNode*
nixnode_; // used for nix routing (on-demand source routing for simulator
performance)
#endif /* NIXVECTOR */
public:
// XXX
Energy related stuff. Should be moved later to a wireless
// routing
plugin module instead of sitting here.
inline
EnergyModel* energy_model() { return energy_model_; }
inline
Location* location() { return location_; }
protected:
EnergyModel*
energy_model_;
// XXX
Currently this is a placeholder only. It is supposed to
// hold
the position-related stuff in MobileNode. Yet another
// 'Under
Construction' sign :(
Location*
location_;
};
Procedura
konstruktora węzła tworzy dodatkowo obiekty klasyfikatorów objectsSectionsec:node:classifiers. Funkcją
klasyfikatorów jest odpowiednie dystrybuowanie wędrujących pakietów pomiędzy
węzłami sieci i ich wewnętrznymi strukturami (symulowanie działania sieci
komputerowej). Typowa budowa węzła (unicast) przedstawiona została na
rysunku 1. Ta prosta architektura zawiera dwa klasyfikatory:
Inne
używane klasyfikatory to:
Rys.1.
Węzeł unicast.
Rys. 2. Węzeł multicast.
Domyślnie
węzły przygotowane są do symulacji typu unicast. Kiedy w symulacji
wykorzystywany jest ruting multicast, najwyższy bit adresu określa, czy
adres jest typu unicast (wartość – 0) czy multicast (wartość inna niż 0).
Procedury
służące do konfiguracji węzła można podzielić na cztery kategorie:
Dostępne
opcje konfiguracji węzła:
Opcja |
Możliwe wartości |
Domyślnie |
Podstawowe |
||
AddressType |
flat,
hierarchical |
Flat |
MPLS
|
ON,
OFF |
OFF |
Podstawowe, satelitarne i radiowe |
||
WiredRouting
|
ON,
OFF |
OFF |
llType
|
LL,
LL/Sat |
""
|
macType
|
Mac/802_11,
Mac/Csma/Ca, Mac/Sat, |
|
|
Mac/Sat/UnslottedAloha,
Mac/Tdma |
""
|
ifqType
|
Queue/DropTail,
Queue/DropTail/PriQueue |
""
|
phyType
|
Phy/WirelessPhy,
Phy/Sat |
""
|
Radiowe
|
||
adhocRouting
|
DIFFUSION/RATE,
DIFFUSION/PROB, DSDV, |
|
|
DSR,
FLOODING, OMNIMCAST, AODV, TORA |
"" |
propType
|
Propagation/TwoRayGround,
Propagation/Shadowing |
"" |
propInstance
|
Propagation/TwoRayGround,
Propagation/Shadowing |
"" |
antType
|
Antenna/OmniAntenna
|
"" |
channel
|
Channel/WirelessChannel,
Channel/Sat |
"" |
topoInstance
|
<topology
file> |
"" |
mobileIP
|
ON,
OFF |
OFF
|
energyModel
|
EnergyModel
|
""
|
initialEnergy
|
<value
in Joules> |
""
|
rxPower
|
<value
in W> |
""
|
txPower
|
<value
in W> |
""
|
idlePower
|
<value
in W> |
""
|
agentTrace
|
ON,
OFF |
OFF
|
routerTrace
|
ON,
OFF |
OFF
|
macTrace
|
ON,
OFF |
OFF
|
movementTrace
|
ON,
OFF |
OFF
|
errProc
|
UniformErrorProc
|
""
|
FECProc
|
?
|
?
|
toraDebug
|
ON,
OFF |
OFF
|
Satelitarne |
||
satNodeType
|
polar,
geo, terminal, geo-repeater |
""
|
downlinkBW
|
<bandwidth
value, e.g. "2Mb"> |
"" |
Po
zdefiniowaniu węzłów sieci komputerowej należy określić ich wzajemne
powiązania. Topologię sieci wprowadza się za pomocą odpowiednich poleceń,
takich jak przedstawione poniżej:
set
ns [new Simulator] $ns
simplex-link \tup{node0}
\tup{node1} \tup{bandwidth} \tup{delay}
\tup{queue_type}
W ten
sposób tworzone jest łącze z węzła node0 do node1, oraz
ustalana częstotliwość przesyłania pakietów, opóźnienie transmisyjne i wartość
ttl. z określeniem częstotliwości, opóźnienia i wartości TTL. Wykorzystywaną
strukturą danych będzie kolejka typu queue_type.
Podstawowe
zmienne dla obiektu łącza:
head – wskazuje na pierwszy obiekt
połaczenia,
queue –
referencja do kolejki elementów w łączu, zwykłe łącza mają przeważnie jedną
kolejkę, bardziej złożone mogą mieć więcej kolejek,
link –
referencja do obiektu, który aktualnie modeluje połączenie (zawiera wartości
charakterystyczne dla łącza np. opóźnienie),
ttl –
referencja do obiektu, który steruje wartością ttl dla każdego
pakietu,
drophead –
referencja do obiektu, który jest pierwszym elementem w kolejce połączenia
(pakiet).
Zmienne
śledzące ścieżki pakietów:
enqT – referencja do obiektu, który
śledzi elementy wchodzące do kolejki,
deqT – referencja do obiektu, który
śledzi elementy opuszczające kolejkę,
drpT – referencja od obiektu, który
śledzi zagubione pakiety,
rcvT –
referencja do obiektu, który śledzi pakiety odebrane przez następny węzeł.
Rys.3.
Struktura połączenia.
Proste
połączenie zbudowane jest z sekwencji połączonych kolejno obiektów. Każdy z
tych obiektów otrzymuje pakiet, wykonuje operacje na nim, przekazuje pakiet do
sąsiedniego węzła lub umieszcza pakiet w zbiorze pakietów straconych. Można
wyróżnić następujące grupy obiektów
składowych łącza:
Kolejki przechowują pakiety,
które będą dalej obsługiwane, oraz pakiety „zagubione”. Zarządzanie pakietami
pole na wybraniu pakietu, który powinien w danej chwili zostać obsłużony.
Dodatkowo kolejki implementują wybrane reguły zarządzania buforem z danymi. Są
to np.:
Każdy typ
kolejki posiada własne charakterystyczne zmienne i parametry.
Opóźnienie
na łączach może być symulowane przez blokowanie kolejki łącza przez wybrany
węzeł sąsiedni. Kolejka jest blokowana przeważnie wtedy, gdy pakiet jest
przesyłany z kolejki do następnego węzła.
Model
łącza wyróżnia dwa rodzaje: łącze dynamiczne (nawiązywanie i zrywanie
połączenia o określonym czasie) i statyczne (stałe).
Dodatkowa
kolejka zawierająca pakiety „zagubione” służy jedynie do celów statystycznych.
Opóźnienie
reprezentuje czas potrzebny na pokonanie łącza przez pakiet. Specjalna wersja
tego obiektu służy także do symulowania uszkodzeń na łączach.
Opóźnienie
w NS-2 zależy od:
Implementacja
opóźnienia łącza jest ściśle powiązana z procedurami blokującymi kolejki.
NS-2
zawiera moduł DiffServ (ang. Differentiated Services), który pozwala na
zróżnicowanie usług, jest to rodzaj architektury QoS dla IP. Działanie modułu
DiffServ polega na znakowaniu pakietów i dzieleniu ruchu w sieci na różne
kategorie. Każdej z kategorii przypisany jest odpowiedni priorytet, w
zależności od wymagań użytkowników. W przypadku wystąpienia zatorów, pakiety o
większym priorytecie mają większe prawa kosztem pakietów o mniejszym
priorytecie (wybierane wg reguł WIRR (Weighted Interleaved Round Robin), RR
(Round Robin) lub PRI (Priority); domyślnie przyjmowana jest reguła RR.
Moduł ten został zaimplementowany przez grupę Advanced IP Networks w firmie Nortel Networks.
Domyślnie
DiffServ wyróżnia cztery różne kategorie pakietów (RED), w każdym z nich
dodatkowo wyróżniono po trzy podkategorie pakietów. Podkategorie te
zaimplementowano w postaci trzech wirtualnych kolejek – najczęściej pobierane
są pakiety z kolejki mającej pierwszeństwo.
Główne
komponenty modułu:
Obszar
działania QoS DiffServ ograniczony jest przez skrajne rutery.
Obiekty
klasy Agent reprezentują punkty sieci, gdzie
pakiety są tworzone, konsumowane lub przetwarzane. Każdy z obiektów węzła sieci
(Node) zawiera obiekty typu Agent, które
tworzą „miniprogramy” odpowiedzialne całościowo za działanie węzła. Są one
używane np. przy implementacji elementów protokołów różnych warstw sieci (np.
TCP) oraz warstwy aplikacji (np. ping, itp.). Obiekty agentów warstwy aplikacji
współpracują z agentami symulującymi działanie protokołów.
class Agent : public Connector {
public:
Agent(packet_t
pktType);
virtual
~Agent();
void
recv(Packet*, Handler*);
//added
for edrop tracing - ratul
void
recvOnly(Packet *) {};
void
send(Packet* p, Handler* h) { target_->recv(p, h); }
virtual
void timeout(int tno);
virtual
void sendmsg(int sz, AppData*, const char* flags = 0);
virtual
void send(int sz, AppData *data) { sendmsg(sz, data, 0); }
virtual
void sendto(int sz, AppData*, const char* flags = 0);
virtual
void sendmsg(int nbytes, const char *flags = 0);
virtual
void send(int nbytes) { sendmsg(nbytes); }
virtual
void sendto(int nbytes, const char* flags, nsaddr_t dst);
virtual
void connect(nsaddr_t dst);
virtual
void close();
virtual
void listen();
virtual
void attachApp(Application* app);
virtual
int& size() { return size_; }
inline
nsaddr_t& addr() { return here_.addr_; }
inline
nsaddr_t& port() { return here_.port_; }
inline
nsaddr_t& daddr() { return dst_.addr_; }
inline
nsaddr_t& dport() { return dst_.port_; }
void
set_pkttype(packet_t pkttype) { type_ = pkttype; }
protected:
int
command(int argc, const char*const* argv);
virtual
void delay_bind_init_all();
virtual int
delay_bind_dispatch(const char *varName, const char *localName, TclObject
*tracer);
virtual
void recvBytes(int bytes);
virtual
void idle();
Packet*
allocpkt() const; // alloc + set up
new pkt
Packet*
allocpkt(int) const; // same, but w/data
buffer
void
initpkt(Packet*) const; // set up fields
in a pkt
ns_addr_t
here_; // address of this
agent
ns_addr_t
dst_; // destination
address for pkt flow
int size_; // fixed packet size
packet_t
type_; // type to
place in packet header
int fid_; // for IPv6 flow id field
int prio_; // for IPv6 prio field
int
flags_; // for
experiments (see ip.h)
int
defttl_; // default ttl
for outgoing pkts
#ifdef notdef
int
seqno_; /* current seqno */
int
class_; /* class to place in
packet header */
#endif
static int
uidcnt_;
Tcl_Channel
channel_;
char
*traceName_; // name used in
agent traces
OldValue
*oldValueList_;
Application
*app_; // ptr to application
for callback
virtual
void trace(TracedVar *v);
void
deleteAgentTrace();
void
addAgentTrace(const char *name);
void
monitorAgentTrace();
OldValue*
lookupOldValue(TracedVar *v);
void
insertOldValue(TracedVar *v, const char *value);
void
dumpTracedVars();
private:
void
flushAVar(TracedVar *v);
};
Elementem
klasy Agent są m.in. parametry służące do
określania wartości różnych pól tworzonych pakietów. Do parametrów tych należą:
addr – adres węzła sieciowego (adres źródłowy dla
pakietu),
dst – adres docelowy dla tworzonych pakietów,
size – rozmiar pakietu w bajtach,
type – typ pakietu,
fid – identyfikator dla IP,
prio – priorytet dla IP,
flags – flagi pakietu,
defttl – domyślna wartość ttl dla IP,
Klasa Agent posłużyła
jako klasa bazowa dla wielu innych klas w NS-2, są to np.:
Klasa Timer używana
jest najczęściej przy tworzeniu agentów. Zawiera szereg funkcji ułatwiających
zarządzanie wirtualnym czasem symulacji.
Klasa Packet jest
najważniejszą daną wymienianą w procesie komunikacji między dwoma procesami symulatora.
Klasa pakietu dostarcza wielu danych wykorzystywanych podczas symulacji.
Informacje te zawarte są w nagłówku pakietu. Możliwość rozszerzenia nagłówka
pozwala implementować nowe protokoły.
Podczas
inicjalizacji symulatora użytkownik może wybrać tylko podzbiór interesujących
go formatów pakietu. Pozwala to zmniejszyć obciążenie pamięci maszyny, na
której przeprowadzana jest symulacja.
Zarządzanie wyborem formatu pakietów odbywa się przez specjalny zewnętrzny
moduł zarządzający pakietami. W przypadku próby odwołania do zablokowanego
formatu pakietu, aplikacja generuje błąd.
Klasy
wykorzystywane w procesie zarządzania pakietami:
Rys.4.
Obiekt Packet - szczegóły.
W systemie
NS-2 zdefiniowane są pewne modele błędów opisujące sytuację utraty pakietów.
Symulacja wystąpienia błędu jest realizowana poprzez znakowanie pakietu
odpowiednią flagą błędu lub przekazanie pakietu do specjalnego odbiorcy
błędnych pakietów (do celów statystycznych).
Błędy mogą
być generowane za pomocą prostego modelu lub bardziej złożonych statystycznych
lub empirycznych modeli. Możliwość powstania błędu możemy wyspecyfikować na
różnych poziomach złożoności symulatora.
Klasa ErrorModel,
definiująca typ obiektów symulujących wystąpienie błędów w testowanej sieci
komputerowej, dziedziczy cechy po klasie Connector (klasa
bazowa dla połączenia), dlatego może być powiązana - z jednej strony z dowolnym
obiektem (w którym będą powstawały błędy), a z drugiej strony z odbiorcą
błędnych, utraconych pakietów (gdzie zostaną umieszczone utracone dane).
Jednocześnie klasa ErrorModel może po prostu znaczyć pakiety
flagą błędu, bez ich dalszej obsługi.
Dodatkowym,
prostym w użyciu mechanizmem, jest możliwość określenia dla wybranego elementu
symulatora pewnego procentu utraconych pakietów lub odpowiednio - wartości
losowej z przedziału 0-1.
Istnieje
możliwość określenie wielostanowego modelu błędów. W tym przypadku każdy
element symulatora w wyniku wystąpienia danego błędu może przejść do innych
błędnych stanów (wg tablicy przejść). Przejścia te mogą następować wg
przyjętych reguł, po określonym opóźnieniu, itp.
Specyfika
sieci lokalnych (np. łącza typu point-to-point, współdzielenie zasobów)
spowodowała konieczność implementacji oddzielnej klasy LanNode, definiującej typy węzłów będących elementami takich
sieci.
Wyróżnione
warstwy sieci LAN:
Rys.5.
Warstwy sieci LAN.
Warstwa
fizyczna jest odpowiedzialna za symulację transmisji pakietów po łączu
fizycznym. Realizuje ją klasa Channel. Prosta wersja tej klasy
implementuje łącze współdzielone, z rywalizacją o dostęp do nośnika. W wyniku
wystąpienia kolizji (dwie transmisje w tym samym czasie) obiekt tej klasy
sygnalizuje warstwie MAC wykrycie kolizji. Powstałe opóźnienie transmisyjne
jest sumą czasu transmisji (zależy od rozmiaru pakietu) i stałego opóźnienia na
łączu.
Obiekt Classifier/Mac
pośredniczy w wymianie pakietów pomiędzy węzłami sieci.
Realizacja
warstwy MAC – klasa MAC symuluje protokoły dostępu do
medium pośredniczącego w wymianie danych. Zależnie od typu warstwy fizycznej,
warstwa MAC musi realizować operacje takie, jak np.: wykrywanie nośnej,
detekcja kolizji, unikanie kolizji itp. W przypadku wysyłania danych, obiekt MAC jest
odpowiedzialny za dodanie nagłówka MAC oraz transmisję pakietu do łącza
pośredniczącego (obiektu Channel). W przypadku odbioru danych,
obiekt MAC asynchronicznie odbiera pakiety z klasyfikatorów
warstwy fizycznej i przekazuje je do warstwy LL.
Rozszerzeniem
możliwości tej klasy są klasy implementujące mechanizmy CSMA/CD i CSMA/CA (np.
wykrywanie kolizji).
Warstwa LL
jest odpowiedzialna za symulowanie protokołów łączy. Dotyczy to np.
fragmentacji i ponownego łączenia pakietów. Inną ważną funkcją tej warstwy jest
ustawienie adresu docelowego w nagłówku MAC (znalezienie adres IP następnego
węzła next-hop w przypadku rutingu i przekształcanie adresu IP w adres MAC - ARP – mapowanie adresów MAC i IP).
Sieci LAN
mają jeden domyślny model rutera – LanRouter.
W
przypadku umieszczania sieci LAN w strukturze większej sieci rozległej, sieć
LAN jest widoczna tak, jak na rysunku 6. Węzeł sieci lokalnej jest
identyfikowany hierarchicznie przez adres rutera sieci LAN oraz wewnętrzny
adres węzła w sieci LAN.
Rys.6.
Model rutera sieci LAN.
W
rozdziale tym zostanie przedstawiony interfejs, który może zostać użyty do
alokacji bitów w struktury adresów NS-2. Pole adresu w symulatorze składa się z
n bitów (domyślnie 16), gdzie n może przyjmować różne wartości,
zależnie od wymagań symulacji (n z przedziału 16 – 32 bity).
Adres
składa się z dwóch części: identyfikatora węzła (najwyższe bity) i
identyfikatora portu lub agenta przypisanego do węzła (pozostałe bity).
Domyślny
format adresu:
32
najniższe bity – identyfikator portu
1 wyższy
bit – multicast
pozostałe
bity – identyfikator węzła
Domyślny
hierarchiczny format adresu:
32 bity
identyfikatora węzła podzielono na trzy poziomy po (10 11 11) bitów każdy (gdy
uruchomiony jest tryb multicast (9 11 11))
Określany
hierarchiczny format adresu:
Przestrzeń
identyfikatora węzła dzielona jest na określoną liczbę poziomów z określoną
liczbą bitów przypisanych do każdego poziomu.
Symulator
NS-2 implementuje również modele sieci bezprzewodowych, zwanych mobilnymi
(model CMU/Monarch). Zaimplementowane są modele ruchomego węzła, generatory
ruchu i scenariusze, odpowiednie mechanizmy rutingu (DSDV, DSR, AODV, TORA) i
komponenty sieci zapewniające jej poprawne działanie. Rozszerzenia modelu CMU
pozwalają łączyć sieci bezprzewodowe i przewodowe oraz wprowadzają model
MobileIP.
NS-2
implementuje również złożone modele połączeń satelitarnych. Należą do nich:
„Modele
propagacja radiowej”
Modele
propagacji radiowej używane są do predykcji siły otrzymywanego sygnału dla
każdego z pakietów. W warstwie fizycznej każdego z bezprzewodowych węzłów sieci
określony jest dolny próg błędu. Jeżeli sygnał otrzymanego pakietu jest słabszy
niż wartość progowa, pakiet znakowany jest flagą błędu.
Zaimplementowane
modele propagacji radiowej:
Model
energii jest jednym z atrybutów modelu węzła. Reprezentuje poziom energii
mobilnego hosta (np. notebook). Jego atrybuty to energia początkowa, zużycie
energii na wysłanie lub odebranie jednego pakietu.
Jak
przedstawiono wcześniej węzeł sieci komputerowej jest zestawem odpowiednich
klasyfikatorów pełniących różne funkcje. Prosty węzeł (unicast) zawiera
tylko jeden klasyfikator określający adres i jeden klasyfikator określający
port. Jeżeli chcemy rozszerzyć funkcjonalność węzła możemy dodać kolejne
klasyfikatory realizujące inne operacje. Wszystkie powiązane ze sobą
klasyfikatory tworzą razem moduł, który wyznacza trasę przesyłania pakietu.
Wyznaczona trasa jest przekazywana do modułu rutingu.
Ogólnie
każda implementacja rutingu składa się z trzech bloków funkcyjnych:
Istnieje
możliwość napisania własnego modułu rutingu w oparciu o istniejące elementy
aplikacji.
Istniejące moduły rutingu:
Nazwa
modułu |
Funkcjonalność |
RtModule/Base |
Interfejs
do protokołu rutingu unicast. Dostarcza prostych funkcji do dodawania
i usuwania tras oraz aktywowania/dezaktywowania wybranych agentów. |
RtModule/Mcast |
Interfejs do rutingu typu multicast. Wprowadza większą liczbę
klasyfikatorów. Wszystkie pozostałe funkcje rutingu multicast
zostały zaimplementowane bezpośrednio
w węźle. |
RtModule/Hier |
Ruting hierarchiczny. Jest to moduł zawierający zarządzanie
hierarchicznymi klasyfikatorami i architekturą tras (omówiony w rozdziale
7.4). Może współpracować z innymi modułami
rutingu. |
RtModule/Manual |
Ruting statyczny. |
RtModule/VC |
Używa
wirtualnych klasyfikatorów. |
RtModule/MPLS |
Implementuje
funkcjonalność MPLS. |
Realizacja symulacji wymaga
określenia strategii rutingu. Możemy wyróżnić cztery podstawowe strategie:
· statyczny (algorytm SPF
Dijkstra) –algorytm uruchamiany jest raz, na początku symulacji. Trasy są
obliczane na podstawie macierzy sąsiedztwa i macierzy kosztów pokonania trasy;
domyślna strategia rutingu dla symulatora,
· sesji (algorytm SPF Dijkstra)
– algorytm bardzo podobny do poprzedniego, ale obliczanie tablic jest
realizowane wiele razy (po ewentualnych zmianach w strukturze sieci),
· dynamiczny (rozproszony
algorytm Bellmana-Forda - DV),
· manualny – tablica rutingu
ustalana przez użytkownika.
Możemy wyróżnić dwa rodzaje
rutingu:
ruting asymetryczny – różna
droga z węzła A do B i z węzła B do A,
ruting multipath – wiele
różnych ścieżek dla pakietu (tylko dla rutingu dynamicznego).
Sieci wirtualne
określone jako grupa multicast
Aby zrozumieć
metodę tworzenia sieci wirtualnych określonych jako grupa multicast
należy wyjaśnić znaczenie terminu - wiadomość typu multicast. Multicast z
natury jest bardzo podobny do pakietu rozgłoszeniowego (broadcast) z tą
jedynie różnicą, że pakiety multicast są adresowane nie tylko do określonej
grupy użytkowników, a do wszystkich użytkowników danego segmentu sieci. W
obrębie sieci wirtualnej określonej jako grupa multicast pakiety te są
kierowane do wszystkich użytkowników tej sieci, przez co działają identycznie
jak pakiety rozgłoszeniowe. Znaczenie opisywanej metody tworzenia sieci
wirtualnych stale wzrasta i ma związek z coraz szerszym zastosowaniem techniki
wideokonferencji wykorzystujących do przesyłania danych właśnie technikę multicastu.
Strategia rutingu multicast
jest mechanizmem służącym do wyznaczenia drzewa dystrybucji. Wyróżniamy trzy
zaimplementowane strategie:
· scentralizowana (PIM-SM),
·
dense mode (DM),
·
shared tree mode (ST),
Ruting ten został wymyślony
głównie po to, aby ograniczyć wymagania pamięci dla symulacji rozległych sieci
o znacznych rozmiarach. Duża sieć jest dzielona na kilka warstw – podsieci
(proponują 3). Pozwala to na zmniejszenie rozmiaru tablicy rutingu. Konieczne
jest jednak wprowadzenie węzłów o hierarchicznej strukturze adresów.
Rys.7. Klasyfikator
hierarchiczny
W NS-2 zrealizowano
następujące protokoły transportu
· protokół UDP,
· protokół TCP
(jednokierunkowy – klasa nadawcy i klasa odbiorcy, dwukierunkowy – jedna klasa
nadawcy i odbiorcy – klasa jeszcze nie w pełni funkcjonalna)
-
TCP – implementacja BSD Tahoe TCP,
-
TCP/Reno – implementacja BSD Reno TCP,
-
TCP/Newreno – modyfikacja BSD Reno TCP,
-
TCP/Vegas,
-
TCP/Sackl – implementacja BSD
Reno TCP z SAE (Selective Acknowledgement Extensions),
-
TCP/FACK – implementacja BSD
Reno TCP z FA (Forward Acknowledgement),
-
TCP/FULLTCP
- ftp://ftp.ee.lbl.gov/papers/fulltcp.ps
-
TCPSINK – implementacja odbiorcy pakietów TCP,
-
TCPSINK/DELACK – odbiorca TCP
typu delayed-ACK,
-
TCPSINK/SACKI – odbiorca TCP typu SACK,
-
TCPSINK/SACKI/DELACK –
odbiorca TCP typu delayed-SACK,
Symulator NS-2 posiada kilka
możliwości uruchomienia programu typu debugger do testowania i analizy
przebiegu symulacji:
·
debugger Tcl,
·
debugger C++,
· połączony debugger C++ i
Tcl,
· debugger zużycia pamięci
systemu,
Symulator NS-2 zawiera małą
kolekcję funkcji matematycznych używanych do implementacji generatorów
losowych, zmiennych losowych i funkcji statystycznych.
Symulator udostępnia kilka
możliwości zapisu danych z przebiegu symulacji. Ogólnie dane te są wyświetlane
bezpośrednio po zakończeniu symulacji lub zapisywane w pliku. Wyróżniamy dwa
różne typy monitoringu symulacji:
· traces – zapis każdego pakietu
indywidualnie w momencie jego wysłania, odbioru lub utraty.
· monitors – zapis wartości różnych
interesujących nas parametrów symulacji związanych z wszystkimi pakietami lub
elementami uczestniczącymi w przepływie pakietów.
Pierwszy typ monitoringu
wspierany jest poprzez dodanie do każdego pakietu specjalnego nagłówka common,
który zawiera unikalny identyfikator pakietu, pole typu pakietu, rozmiar pakietu
i nazwę interfejsu.
W oparciu o agentów
protokołów transportu powstały aplikacje – generatory ruchu i symulowane
aplikacje (np. telnet, ftp). Użytkownik ma możliwość tworzenia modeli własnych
aplikacji, wraz z przypisanymi im scenariuszami ruchu lub generatorami.
Zaimplementowane generatory
ruchu:
· EXPOO_Traffic – generator
ruchu wg rozkładu ekspotencjalnego On/Off,
·
POO_Traffic – generator ruchu wg rozkładu
Pareto On/Off,
· CBR_Traffic –
deterministyczny generator ruchu CBR,
· TrafficTrace – generuje ruch
zgodny z zapisanym w pliku tekstowym,
Rys.8. Przykład aplikacji.
W przypadku aplikacji bardzo
ważnym jest także ruch www. W symulatorze NS-2 znalazł się bardzo dokładny
model protokołu http, modele stron www, serwera, klienta, Proxy, modele pamięci
cache (przechowywanie stron w pamięci podręcznej i zapamiętywanie ich daty),
generatory ruchu w sieci web, itp.
W przypadku symulatora sieci
bardzo dużej i złożonej nie zawsze można spełnić wymagania dotyczące pamięci
maszyny, na której uruchamiamy symulację. W tym celu wprowadzono możliwość
symulowania dużych sieci na bardziej zagregowanym modelu. Niestety w wyniku
agregacji tracimy niektóre informacje (np. opóźnienie podczas kolejkowania) i
musimy badać bardziej ogólne wartości.
Jednak możliwość taka wydaje
się być bardzo przydatna.
Dodatkową możliwością
symulatora NS-2 jest uruchomienie symulacji w połączeniu z rzeczywistą siecią
komputerową. Część sieci komputerowej działa wtedy w sposób rzeczywisty a część
jest symulowana. Rozwój tego modułu ciągle trwa i nie jest on jeszcze w pełni
funkcjonalny.
Wyniki symulacji możemy
zapisać w odpowiednim pliku tekstowym. Jednak nie zawsze jest on czytelny i
zrozumiały, dlatego bardzo przydatne wydaje się narzędzie NAM, które potrafi na
podstawie pliku z wynikami przeprowadzić animację odpowiadającą działaniu
sieci. Korzystanie z narzędzi NAM wymaga wprowadzenia topologii sieci i
odpowiedniego jej skonfigurowania. Służy do tego interfejs graficzny aplikacji.
Rys. 1. Ekran NAM.
- połączenia
stałe, radiowe i satelitarne,
- TCP,
UDP,
- web,
telnet, ftp,
- ruting
statyczny i dynamiczny,
- infrastruktura:
statystyki, śledzenie ruchu, modele błędów, itp.
-
projektowanie protokołów, studiowanie ruchu w sieciach,
-
porównanie protokołów,
- darmowa
dystrybucja, open source,
-
łatwe porównanie prostych protokołów,
-
duże zaufanie do wyników symulacji,
Przedstawiony skrypt definiuje topologię z czterema węzłami, agentem TCP i agentem UDP z generatorem ruchu CBR. Wyniki symulacji zapisywane są w dwóch plikach: out.tr i out.nam. Po zakończeniu symulacji jej przebieg zostanie przedstawiony w postaci animacji programu NAM (Network Animator).
Plik skryptu OTcl
# The preamble
set ns [new Simulator] # initialise the simulation;
# Predefine tracing
set f [open out.tr w]
$ns trace-all $f
set nf [open out.nam w]
$ns namtrace-all $nf
\clearpage
# so, we lied. now, we define the topology
#
# n0
# \bs
# 5Mb \bs
# 2ms \bs
# \bs
# n2 --------- n3
# / 1.5Mb
# 5Mb / 10ms
# 2ms /
# /
# n1
#
set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]
set n3 [$ns node]
$ns duplex-link $n0 $n2 5Mb 2ms DropTail
$ns duplex-link $n1 $n2 5Mb 2ms DropTail
$ns duplex-link $n2 $n3 1.5Mb 10ms DropTail
# Some agents.
set udp0 [new Agent/UDP] # A UDP agent;
$ns attach-agent $n0 $udp0 # on node $n0;
set cbr0 [new Application/Traffic/CBR] # A CBR traffic generator agent;
$cbr0 attach-agent $udp0 # attached to the UDP agent;
$udp0 set class_ 0 # actually, the default, but\ldots;
set null0 [new Agent/Null] # Its sink;
$ns attach-agent $n3 $null0 # on node $n3;
$ns connect $udp0 $null0
$ns at 1.0 "$cbr0 start"
puts [$cbr0 set packetSize_]
puts [$cbr0 set interval_]
# A FTP over TCP/Tahoe from $n1 to $n3, flowid 2
set tcp [new Agent/TCP]
$tcp set class_ 1
$ns attach-agent $n1 $tcp
set sink [new Agent/TCPSink]
$ns attach-agent $n3 $sink
set ftp [new Application/FTP] # TCP does not generate its own traffic;
$ftp attach-agent $tcp
$ns at 1.2 "$ftp start"
$ns connect $tcp $sink
$ns at 1.35 "$ns detach-agent $n0 $tcp ; $ns detach-agent $n3 $sink"
\clearpage
# The simulation runs for \(3s\).
# The simulation comes to an end when the scheduler invokes the finish{} procedure below.
# This procedure closes all trace files, and invokes nam visualization on one of the trace files.
$ns at 3.0 "finish"
proc finish {} {
global ns f nf
$ns flush-trace
close $f
close $nf
puts "running nam..."
exec nam out.nam &
exit 0
}
# Finally, start the simulation.
$ns run