Size: 4452
Comment:
|
Size: 6975
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 19: | Line 19: |
Tramite l'oggetto che implementa questa interfaccia dovrà essere possibile misurare il RTT tra l'interfaccia di rete ''dev_a'' del nodo ''a'' e l'interfaccia di rete ''dev_b'' del nodo ''b''. Se il nodo ''a'' è quello che inizia la procedura: | Tramite l'oggetto che implementa questa interfaccia dovrà essere possibile misurare il RTT tra l'interfaccia di rete ''dev_a'' del nodo ''a'' e l'interfaccia di rete ''dev_b'' del nodo ''b''. Il modulo Neighborhood prevede un meccanismo per fare tale misurazione in autonomia. Prima di illustrarlo, però, va detto che esso per forza di cose risulta molto inaccurato, in quanto il modulo fa uso di tasklet, cioè thread cooperativi, che non possono essere accurati nei tempi di risposta. Quindi questo metodo viene fornito come estrema risorsa laddove non fosse possibile l'uso di altri meccanismi. Se il nodo ''a'' è quello che inizia la procedura: |
Line 36: | Line 40: |
=== Meccanismi alternativi === Se l'utilizzatore del modulo Neighborhood è in grado di misurare con maggiore accuratezza il RTT di un certo arco lo può fare implementando il metodo ''measure_rtt'' dell'interfaccia INeighborhoodNetworkInterface. Altrimenti in questo metodo va lanciata l'eccezione !NeighborhoodGetRttError. Il modulo Neighborhood lo richiama come primo tentativo per stabilire il costo (in latenza) di un arco, e passa come parametro l'indirizzo di scheda del vicino. Se riceve l'eccezione il modulo passa al meccanismo sopra esposto. Quando il nodo ''a'' ha un vicino ''b'' questi possono avere più di un arco che li unisce. Ma ogni arco ha una interfaccia esclusiva su entrambi i nodi. Per esempio il nodo ''a'' può avere solo un arco che parte dalla sua interfaccia ''eth0'' e arriva al nodo ''b''. Un altro arco potrebbe ad esempio partire dall'interfaccia ''eth1'' di ''a'' e arrivare a ''b''. Allo stesso modo il nodo ''b'' deve avere più interfacce di rete per avere due archi verso ''a''. Ogni interfaccia di rete di ogni nodo, inoltre, ha un indirizzo di scheda univoco. Di conseguenza, quando il nodo ''a'' indica un indirizzo di scheda del suo vicino ''b'', il nodo ''a'' indica precisamente un arco che lo congiunge a ''b'' attraverso due specifiche interfacce di rete ''dev_a'' e ''dev_b''. Sapendo questo, ad esempio in Linux, il comando {{{ ping -q -n -c 1 169.254.21.36 }}} potrà essere usato per misurare la latenza esattamente dell'arco che ci interessa, anche nel caso in cui per lo stesso vicino esistano due o più archi. Questa misurazione è molto più accurata di quanto si possa ottenere con un software che usa thread cooperativi. Il modulo non esclude altri meccanismi di misurazione del costo. Per dare il massimo supporto al suo utilizzatore, nel metodo ''measure_rtt'' sono passate queste informazioni relative all'arco: * ''string peer_addr'' - l'indirizzo di scheda della interfaccia del vicino, * ''string peer_mac'' - il MAC della interfaccia del vicino, * ''string my_addr'' - l'indirizzo di scheda della interfaccia del nodo. |
Modulo Neighborhood - Requisiti / Dipendenze
Contents
INeighborhoodIPRouteManager
Tramite l'oggetto che implementa questa interfaccia dovrà essere possibile apportare delle modifiche al sistema. Per un sistema Linux ad esempio, dotato del software iproute, questo si traduce nell'esecuzione di questi comandi:
Metodi |
Comandi |
i_neighborhood_add_address |
ip address add 169.254.1.1 dev wlan0 |
i_neighborhood_add_neighbor |
ip route add 169.254.22.33 dev wlan0 src 169.254.1.1 |
i_neighborhood_remove_neighbor |
ip route del 169.254.22.33 dev wlan0 src 169.254.1.1 |
i_neighborhood_remove_address |
ip address del 169.254.1.1/32 dev wlan0 |
INeighborhoodNetworkInterface
Una istanza di tale interfaccia viene passata al modulo quando l'utilizzatore gli chiede di monitorare una interfaccia di rete (metodo start_monitor). L'istanza di questo oggetto passato al modulo è legata alla specifica interfaccia di rete.
Tramite l'oggetto che implementa questa interfaccia dovrà essere possibile misurare il RTT tra l'interfaccia di rete dev_a del nodo a e l'interfaccia di rete dev_b del nodo b.
Il modulo Neighborhood prevede un meccanismo per fare tale misurazione in autonomia. Prima di illustrarlo, però, va detto che esso per forza di cose risulta molto inaccurato, in quanto il modulo fa uso di tasklet, cioè thread cooperativi, che non possono essere accurati nei tempi di risposta. Quindi questo metodo viene fornito come estrema risorsa laddove non fosse possibile l'uso di altri meccanismi.
Se il nodo a è quello che inizia la procedura:
Nel nodo a il modulo Neighborhood sceglie una sequenza string s_a di pochi bytes random.
Nel nodo a il modulo Neighborhood crea un canale ch_a di comunicazione tra due tasklet.
Nel nodo a il modulo Neighborhood si mette in ascolto sull'interfaccia dev_a su una porta uint16 p_a random (verifica che non sia già occupata?)
Questo lo fa usando il metodo expect_pong dell'interfaccia INeighborhoodNetworkInterface. Tale metodo riceve la stringa s_a e il canale ch_a e restituisce la porta p_a. Prima di restituire la porta, avvia una tasklet che controllerà la porta in attesa del messaggio s_a. Appena lo riceve comunica true nel canale ch_a. Se dopo una attesa massima non lo riceve, allora cessa di ascoltare, libera la porta e comunica false nel canale ch_a.
Nel nodo a il modulo Neighborhood comunica (con protocollo TCP che è reliable) p_a ed s_a al modulo nel nodo b.
- Se la comunicazione avviene correttamente:
Nel nodo b il modulo Neighborhood riceve la comunicazione attraverso una interfaccia di rete e la riconduce alla relativa istanza dell'interfaccia INeighborhoodNetworkInterface.
Nel nodo b il modulo Neighborhood si mette in ascolto sull'interfaccia dev_b su una porta uint16 p_b random (verifica che non sia già occupata?)
Questo lo fa usando il metodo expect_ping dell'interfaccia INeighborhoodNetworkInterface. Tale metodo riceve la stringa s_a e la porta p_a e restituisce la porta p_b. Prima di restituire la porta, avvia una tasklet che controllerà la porta p_b in attesa del messaggio s_a. Appena lo riceve trasmette il messaggio s_a in broadcast verso la porta p_a. Se dopo una attesa massima non lo riceve, allora cessa di ascoltare e libera la porta.
Nel nodo b il modulo Neighborhood risponde alla comunicazione restituendo p_b al modulo nel nodo a.
Immediatamente nel nodo a il modulo Neighborhood trasmette il messaggio s_a in broadcast verso la porta p_b.
Questo lo fa usando il metodo send_ping dell'interfaccia INeighborhoodNetworkInterface. Tale metodo riceve la stringa s_a, la porta p_b e il canale ch_a. Avvia un timer. Trasmette in broadcast s_a verso la porta p_b e attende la risposta sul canale ch_a. Se riceve true stoppa il timer e restituisce il RTT. Se riceve false (o se dopo una attesa massima non riceve nulla) lancia una eccezione NeighborhoodGetRttError per indicare che la misurazione non ha avuto buon esito.
- Altrimenti, se la comunicazione con protocollo reliable lancia un errore:
Nel nodo a il modulo Neighborhood rimuove l'arco.
Nota: se la misurazione del RTT va in timeout (cioè il metodo send_ping lancia una eccezione NeighborhoodGetRttError) il modulo Neighborhood non elabora questa misurazione fallita, senza per questo rimuovere l'arco, in quanto l'UDP è di natura un protocollo non reliable.
Meccanismi alternativi
Se l'utilizzatore del modulo Neighborhood è in grado di misurare con maggiore accuratezza il RTT di un certo arco lo può fare implementando il metodo measure_rtt dell'interfaccia INeighborhoodNetworkInterface. Altrimenti in questo metodo va lanciata l'eccezione NeighborhoodGetRttError.
Il modulo Neighborhood lo richiama come primo tentativo per stabilire il costo (in latenza) di un arco, e passa come parametro l'indirizzo di scheda del vicino. Se riceve l'eccezione il modulo passa al meccanismo sopra esposto.
Quando il nodo a ha un vicino b questi possono avere più di un arco che li unisce. Ma ogni arco ha una interfaccia esclusiva su entrambi i nodi. Per esempio il nodo a può avere solo un arco che parte dalla sua interfaccia eth0 e arriva al nodo b. Un altro arco potrebbe ad esempio partire dall'interfaccia eth1 di a e arrivare a b. Allo stesso modo il nodo b deve avere più interfacce di rete per avere due archi verso a.
Ogni interfaccia di rete di ogni nodo, inoltre, ha un indirizzo di scheda univoco. Di conseguenza, quando il nodo a indica un indirizzo di scheda del suo vicino b, il nodo a indica precisamente un arco che lo congiunge a b attraverso due specifiche interfacce di rete dev_a e dev_b.
Sapendo questo, ad esempio in Linux, il comando ping -q -n -c 1 169.254.21.36 potrà essere usato per misurare la latenza esattamente dell'arco che ci interessa, anche nel caso in cui per lo stesso vicino esistano due o più archi. Questa misurazione è molto più accurata di quanto si possa ottenere con un software che usa thread cooperativi.
Il modulo non esclude altri meccanismi di misurazione del costo. Per dare il massimo supporto al suo utilizzatore, nel metodo measure_rtt sono passate queste informazioni relative all'arco:
string peer_addr - l'indirizzo di scheda della interfaccia del vicino,
string peer_mac - il MAC della interfaccia del vicino,
string my_addr - l'indirizzo di scheda della interfaccia del nodo.