6620
Comment:
|
12621
|
Deletions are marked like this. | Additions are marked like this. |
Line 2: | Line 2: |
<<TableOfContents(4)>> | |
Line 3: | Line 4: |
Rileva i nodi vicini raggiungibili attraverso una (o più) interfacce di rete e ne reperisce l'identificativo. |
Il modulo gestisce una o più interfacce di rete del nodo. Ad ognuna associa un indirizzo locale detto ''indirizzo di scheda''. |
Line 6: | Line 6: |
Con ogni vicino, poi, si accorda per la creazione (o meno) di un arco. L'accordo potrebbe non essere raggiunto perché uno dei due vertici ha già un numero di archi elevato, tutti con costo inferiore a questo. Oppure, più frequentemente, se i due vertici appartengono a reti distinte. |
Rileva i nodi vicini raggiungibili attraverso una (o più) interfacce di rete e ne reperisce l'identificativo. |
Line 11: | Line 8: |
Per ogni arco mantiene l'identificativo del vertice collegato e il costo. | Con ogni vicino, poi, si accorda per la creazione (o meno) di un arco. L'accordo potrebbe non essere raggiunto perché uno dei due vertici ha già un numero di archi elevato. |
Line 13: | Line 10: |
Nel tempo, gestisce la costituzione di nuovi archi, la rimozione di archi, i cambiamenti del costo degli archi. |
Per ogni arco creato il modulo mantiene l'identificativo del vertice collegato e il costo. Inoltre imposta le rotte nelle tabelle del kernel per rendere possibile la comunicazione via TCP con il vicino attraverso l'indirizzo di scheda. |
Line 16: | Line 12: |
=== Note === | Nel tempo, gestisce la costituzione di nuovi archi, la rimozione di archi, i cambiamenti del costo degli archi. |
Line 18: | Line 14: |
Tra due nodi vicini ci possono essere 2 o più archi, ma solo se sono su diversi domini di collisione. |
Il modulo fa uso delle [[Netsukuku/ita/docs/Librerie/TaskletSystem|tasklet]], un sistema di multithreading cooperativo. Attraverso di esso esegue il monitoraggio delle schede di rete lasciando libero il chiamante di svolgere altri task. |
Line 21: | Line 16: |
Da questo deriva che i messaggi inviati in UDP Unicast vanno elaborati dal solo nodo destinatario e solo una volta, cioè quando sono ricevuti dall'arco che li invia. Per questo il nodo che li invia su un certo arco compone l'oggetto UnicastID con l'identificativo del nodo destinatario e il MAC del nodo destinatario associato a quell'arco. |
Il modulo fa uso del framework [[Netsukuku/ita/docs/Librerie/ZCD|ZCD]], precisamente appoggiandosi ad una libreria intermedia prodotta con questo framework per formalizzare i metodi remoti usati nel demone ''ntkd''. === Caratteristiche degli archi === Quando si crea un arco esso esiste per entrambi i nodi. |
Line 28: | Line 22: |
Quando si crea un arco esso esiste per entrambi i nodi. Quindi ogni nodo può inoltrare i suoi pacchetti all'altro e deve inoltrare i pacchetti che provengono dall'altro. |
Tra due nodi vicini ci possono essere più archi, ma solo se sono su diversi domini di collisione. Di fatto il modulo consente la costituzione di un secondo arco solo se le interfacce di rete di entrambi i nodi sono diverse da quelle su cui è realizzato il primo arco. |
Line 33: | Line 25: |
Il costo di un arco in una direzione ( da A verso B ) può essere diverso dal costo nella direzione inversa. Questo non è utile quando il costo rappresenta il round-trip time, ma può esserlo se rappresenta la larghezza di banda in uscita. |
Il costo di un arco in una direzione ( da A verso B ) può essere diverso dal costo nella direzione inversa. Questo non è utile quando il costo rappresenta il round-trip time, ma può esserlo se rappresenta la larghezza di banda in uscita. |
Line 39: | Line 28: |
Quando un nodo rimuove un arco tenta di comunicarlo al vertice collegato perché faccia altrettanto. |
Quando un nodo rimuove un arco tenta di comunicarlo al vertice collegato perché faccia altrettanto. |
Line 44: | Line 31: |
* Implementazione del sistema di tasklet. | |
Line 46: | Line 33: |
* La (o le) interfaccia di rete da monitorare. <<BR>> Una interfaccia nic_xy è un oggetto che comprende: * il nome della interfaccia ( wlan0 ) * il MAC address della interfaccia ( CC:AF:78:2E:C8:B6 ) * Callback per misurare il RTT (ping) con un vicino. |
* La (o le) interfaccia di rete da monitorare. . Durante le operazioni del modulo è possibile aggiungere o rimuovere una interfaccia di rete da monitorare. |
Line 51: | Line 36: |
* Factory per ottenere uno "stub" per invocare metodi remoti nei nodi vicini. Durante le operazioni del modulo è possibile aggiungere o rimuovere una interfaccia di rete da monitorare. Quando si aggiunge una interfaccia al modulo, esso verifica che non sia un duplicato; se nome e MAC coincidono con una già inserita allora ignora la richiesta; se uno coincide e l'altro no, allora errore fatale. |
* Factory per creare uno "stub" per invocare metodi remoti nei nodi vicini. * Manager di indirizzi e rotte. |
Line 61: | Line 40: |
Line 63: | Line 41: |
* rilevamento di una collisione con altra rete; questo evento scatenerà la procedura di fusione delle due reti su un altro modulo. * costituzione di un arco. * rimozione di un arco. * variazione del costo di un arco. * Fornisce on demand: * elenco degli archi ora presenti. * dato il nome di una interfaccia di rete (e.g. wlan0) [che di norma si ottiene dal parametro _rpc_caller di un metodo remoto che è in esecuzione, il che fa presumere che la suddetta interfaccia è gestita dal modulo] l'oggetto interfaccia che la rappresenta, se tale interfaccia è al momento gestita dal modulo. Altrimenti un RPCError? * dato un UnicastID (identificativo di un unicast) ricevuto da una data interfaccia di rete, stabilire se è un messaggio da processare. * dato un arco, un oggetto stub utilizzabile per inviare un messaggio tramite questo arco al vicino (chiamare un metodo remoto in unicast) * un oggetto stub utilizzabile per inviare un messaggio (chiamare un metodo remoto in broadcast) a tutti i vicini; oppure, dato un identificativo di un vicino, a tutti i vicini tranne quello; oppure, data una interfaccia di rete, a tutti i vicini raggiungibili tramite quella. <<BR>> Quando si invia un messaggio tramite questo oggetto l'invio del messaggio è asincrono: procederà in una nuova tasklet, mentre il metodo non fornirà alcuna risposta al chiamante. E' possibile fornire una callback che verrà richiamata dopo un certo tempo se per qualcuno degli archi noti al modulo non si avrà ricevuto un messaggio di ACK dal vicino collegato. Questo controllo viene fatto sugli archi che sono esistenti al momento dell'invio AND sono ancora presenti alla scadenza del timeout. La callback viene chiamata una volta per ogni arco che fallisce e avrà quell'arco come argomento, così che il chiamante possa prendere un provvedimento, ad esempio forzando la rimozione dell'arco. <<BR>> Quando si invia un broadcast a più vicini può essere necessario inviarlo in broadcast su una o più interfacce di rete. * Ha un metodo per forzare la rimozione di un arco. |
* costituzione di un arco. * rimozione di un arco. * variazione del costo di un arco. * Fornisce metodi per: * Ottenere l'elenco degli archi ora presenti. * Dato l'identificativo di un messaggio in unicast ricevuto (una istanza di UnicastID) e dato il nome dell'interfaccia di rete da cui è stato ricevuto, stabilire se il messaggio è da processare. * Dato l'identificativo di un messaggio in broadcast ricevuto (una istanza di BroadcastID) e dato il nome dell'interfaccia di rete da cui è stato ricevuto, stabilire se il messaggio è da processare. * Dato un arco, ottenere un oggetto stub utilizzabile per inviare un messaggio (chiamare un metodo remoto) tramite questo arco al vicino ad esso collegato. Il messaggio viene inviato con protocollo reliable (TCP); questo significa che se non vengo notificato di un errore posso essere certo che il vicino ha ricevuto correttamente il mio messaggio e che l'eventuale risposta che ottengo è stata ricevuta correttamente. * Ottenere un oggetto stub utilizzabile per inviare un messaggio in broadcast. Questo tipo di stub si usa per richiamare metodi remoti che non restituiscono risultati (void e senza eccezioni). E' possibile specificare a questo metodo se lo stub sarà utilizzato per inviare messaggi destinati a tutti i vicini; oppure a tutti tranne uno, passandogli l'identificativo del vicino da escludere; oppure, passandogli una interfaccia di rete, a tutti i vicini raggiungibili tramite quella. . Quando non si specifica una interfaccia di rete, il modulo produrrà uno stub che si occuperà di inviare il messaggio in broadcast su tutte le interfacce di rete gestite. . Quando si invia un messaggio tramite questo oggetto l'invio del messaggio è asincrono: procederà in una nuova tasklet, mentre il metodo non fornirà alcuna risposta al chiamante. E' possibile fornire un oggetto in cui un determinato metodo (callback) verrà richiamato dopo un certo tempo se per qualcuno degli archi noti al modulo non si avrà ricevuto un messaggio di ACK dal vicino collegato. Questo controllo viene fatto sugli archi che sono esistenti al momento dell'invio '''e''' sono ancora presenti alla scadenza del timeout. Il metodo callback viene chiamato una volta per ogni arco che fallisce e avrà quell'arco come argomento, così che il chiamante possa prendere un provvedimento, ad esempio forzando la rimozione dell'arco. * Forzare la rimozione di un arco. |
Line 76: | Line 55: |
La stub factory è un oggetto di cui il modulo conosce l'interfaccia IStubFactory. Tramite essa il modulo può: * ottenere uno stub per chiamare un metodo in broadcast; il modulo può specificare l'oggetto BroadcastID per indicare quali vicini sono interessati; può inoltre indicare una callback da richiamare sugli archi per i quali non riceve il messaggio di ACK. * ottenere uno stub per chiamare un metodo su uno specifico vicino; il modulo specifica l'oggetto UnicastID e può specificare se si vuole ricevere una risposta o no. |
L'implementazione del sistema di tasklet è passata al modulo dal suo utilizzatore. Si tratta di una istanza dell'interfaccia INtkdTasklet che è descritta nel relativo [[Netsukuku/ita/docs/Librerie/TaskletSystem#Interfacce|documento]]. |
Line 83: | Line 58: |
Una interfaccia di rete passata al modulo è un oggetto istanza di una classe di cui il modulo conosce l'interfaccia INeighborhoodNetworkInterface. Tramite questa interfaccia il modulo può: | |
Line 84: | Line 60: |
L'identificativo del proprio nodo, come anche l'identificativo di ogni vertice rilevato, è un oggetto il cui contenuto non è noto al modulo neighborhood. L'interfaccia di questo oggetto nota al modulo gli consente di: * verificare se due identificativi sono identici (metodo 'equals'). * verificare se due identificativi appartengono alla stessa rete (metodo 'is_on_same_network'). |
* Leggere il nome dell'interfaccia di rete, es: wlan0 (proprietà 'i_neighborhood_dev'). * Leggere il MAC address dell'interfaccia di rete, es: CC:AF:78:2E:C8:B6 (proprietà 'i_neighborhood_mac'). * Misurare il round-trip time (la latenza) con un vicino. L'utilizzatore del modulo Neighborhood può fornire il meccanismo di misurazione della latenza (o in generale del costo associato ad un arco) secondo due modalità. Come primo tentativo il modulo chiama il metodo 'measure_rtt' passando alcune informazioni tra cui l'indirizzo di scheda (del vicino) associato all'arco. Se l'oggetto fornito dall'utilizzatore è in grado di misurare la latenza con accuratezza (ad esempio eseguendo un comando "ping") questo primo tentativo va a buon fine. Altrimenti il modulo procederà con il secondo meccanismo. Il meccanismo alternativo prevede la collaborazione del modulo nel nodo vicino. In questo caso il compito dell'oggetto fornito dall'utilizzatore, sia nel nodo che fa la misurazione sia nel nodo vicino, sarà quello di inviare e ascoltare un messaggio concordato su una porta UDP qualsiasi nella interfaccia di rete interessata. Con questa modalità la misurazione risulterà certamente meno accurata; questo è dovuto al fatto che il modulo utilizza dei thread cooperativi che non offrono tempi di risposta certi. |
Line 91: | Line 69: |
La stub factory è un oggetto di cui il modulo conosce l'interfaccia INeighborhoodStubFactory. Tramite essa il modulo può: | |
Line 92: | Line 71: |
Un arco è un oggetto noto al modulo. Grazie alle informazioni memorizzate in esso (my_nic) il modulo è in grado di produrre l'oggetto che realizza la chiamata di un metodo remoto in unicast. L'interfaccia dell'oggetto arco nota all'esterno del modulo, invece, permette solo un sottoinsieme di operazioni: * leggere l'identificativo del vicino. * leggere il MAC del vicino. * ottenere l'indirizzo IPv4 di scheda (vedi appunti, metodo 'string get_local_address') * leggere il costo dell'arco. * verificare se due archi sono identici (metodo 'equals'). * verificare se l'arco poggia su una data interfaccia di rete; abbiamo questo metodo, invece di avere direttamente l'interfaccia, per scoraggiare la creazione di un oggetto remoto unicast senza passare dal modulo. |
* Creare uno stub per chiamare un metodo via UDP in broadcast sui nodi vicini (metodo 'i_neighborhood_get_broadcast'); il modulo specifica una o più interfacce di rete sulle quali desidera che lo stub invii il messaggio; il modulo specifica l'oggetto BroadcastID che lo stub includerà nel messaggio per indicare a ogni vicino che lo riceve se debba considerarsi tra i destinatari; il modulo può inoltre indicare un'istanza dell'interfaccia !ModRpc.IAckCommunicator se vuole ricevere dopo il timeout la lista dei MAC address che hanno segnalato con un ACK la ricezione del messaggio. * Creare uno stub per chiamare un metodo via UDP su uno specifico vicino (metodo 'i_neighborhood_get_unicast'); il modulo specifica l'interfaccia di rete sulla quale desidera che lo stub invii il messaggio; il modulo specifica l'oggetto UnicastID che lo stub includerà nel messaggio per indicare a ogni vicino che lo riceve se è lui il destinatario; il modulo può specificare se si vuole attendere l'esecuzione del metodo da parte del vicino o no; il modulo lo usa per comunicare con un vicino quando ancora non è stata negoziata la creazione dell'arco e quindi non è ancora possibile realizzare la connessione via TCP. * Creare uno stub per chiamare un metodo via TCP su uno specifico indirizzo (metodo 'i_neighborhood_get_tcp'); il modulo lo usa per comunicare in modo reliable con un nodo vicino attraverso un suo arco, specificando l'indirizzo di scheda associato all'arco; il modulo può specificare se si vuole attendere l'esecuzione del metodo da parte del vicino o no, ma comunque se il metodo ritorna senza l'eccezione !StubError la ricezione da parte del vicino è garantita. |
Line 106: | Line 76: |
Il manager di rotte e indirizzi è un oggetto di cui il modulo conosce l'interfaccia INeighborhoodIPRouteManager. Tramite essa il modulo può: | |
Line 107: | Line 78: |
Il costo di un arco rilevato è la latenza, cioè il tempo che impiega un messaggio da noi a raggiungere il vertice collegato. In realtà quello che si può misurare, quindi quello che il modulo memorizza come costo, è il round-trip time (RTT). |
* Dato il nome di una interfaccia di rete e un indirizzo IP [[http://en.wikipedia.org/wiki/Link-local_address|link-local]] nella dotted form, aggiungere l'indirizzo IP all'interfaccia di rete (metodo 'i_neighborhood_add_address'); * Dato il nome di una interfaccia di rete, il suo indirizzo IP link-local associato e un altro indirizzo IP link-local nella dotted form, aggiungere la rotta con scope link verso un vicino sull'interfaccia specificando come src preferito l'indirizzo di scheda (metodo 'i_neighborhood_add_neighbor'); * Dato il nome di una interfaccia di rete, il suo indirizzo IP link-local associato e l'indirizzo IP link-local di un vicino, rimuovere la rotta con scope link verso il vicino dall'interfaccia (metodo 'i_neighborhood_remove_neighbor'); * Dato il nome di una interfaccia di rete e il suo indirizzo IP link-local associato, rimuovere l'indirizzo IP dall'interfaccia (metodo 'i_neighborhood_remove_address'). Il modulo lo usa per rendere possibile la comunicazione via TCP coi vicini tramite un indirizzo fisso. Il modulo associa ad ogni interfaccia di rete che gestisce un indirizzo detto ''indirizzo di scheda''. Per ogni arco che realizza, il modulo aggiunge la rotta con scope link verso l'indirizzo di scheda dell'interfaccia del vicino collegata all'arco. Quando rimuove l'arco rimuove anche la rotta. Quando il modulo cessa di gestire un'interfaccia rimuove il relativo indirizzo. ---- L'identificativo del proprio nodo, come anche l'identificativo di ogni vertice rilevato, è un oggetto il cui contenuto non è noto al modulo neighborhood. L'interfaccia di questo oggetto nota al modulo (INeighborhoodNodeID) gli consente di: * verificare se due identificativi sono identici (metodo 'i_neighborhood_equals'). ---- Un arco è un oggetto (!NeighborhoodRealArc) noto al modulo. Grazie alle informazioni memorizzate in esso (my_nic, mac) il modulo è in grado di evitare la creazione di ulteriori archi verso lo stesso vicino se non usano interfacce di rete distinte da ambo i lati, ed anche di segnalare che il vicino ad esso collegato non è fra i destinatari di un messaggio inviato in broadcast. Sempre con le informazioni memorizzate in questo oggetto (nic_addr) il modulo è in grado di produrre lo stub che realizza la chiamata di un metodo remoto in TCP (reliable). L'interfaccia dell'oggetto arco nota all'esterno del modulo, INeighborhoodArc, permette solo un sottoinsieme di operazioni: * Leggere l'identificativo del vicino (proprietà 'i_neighborhood_neighbour_id'). * Leggere il MAC del vicino (proprietà 'i_neighborhood_mac'). * Leggere il costo dell'arco (proprietà 'i_neighborhood_cost'). * Leggere l'interfaccia di rete dell'arco (proprietà 'i_neighborhood_nic'). * Data una istanza di !CallerInfo, passata all'inizio dell'esecuzione di un metodo remoto (vedi framework [[Netsukuku/ita/docs/Librerie/ZCD|ZCD]]), verificare se la chiamata del metodo è stata ricevuta tramite questo arco (metodo 'i_neighborhood_comes_from'). ---- Quando si chiama il metodo che produce uno stub per l'invio di messaggi in broadcast, può essere passato un oggetto che contiene il codice e i dati necessari a gestire l'evento di 'mancata ricezione di un ACK da un arco entro il timeout'. Tale oggetto implementa l'interfaccia INeighborhoodMissingArcHandler. L'interfaccia permette di: * lanciare il codice che gestisce una arco mancante, passandogli l'arco (metodo 'i_neighborhood_missing'). ---- Il costo di un arco può essere espresso con diverse metriche (latenza, larghezza di banda, ...). Attualmente l'implementazione del modulo misura la latenza e la esprime con un intero in microsecondi. La latenza è il tempo che impiega un messaggio da noi a raggiungere il vertice collegato. In realtà quello che si può misurare, quindi quello che il modulo memorizza come costo, è il round-trip time (RTT). |
Modulo Neighborhood - Analisi Funzionale
Contents
Il modulo gestisce una o più interfacce di rete del nodo. Ad ognuna associa un indirizzo locale detto indirizzo di scheda.
Rileva i nodi vicini raggiungibili attraverso una (o più) interfacce di rete e ne reperisce l'identificativo.
Con ogni vicino, poi, si accorda per la creazione (o meno) di un arco. L'accordo potrebbe non essere raggiunto perché uno dei due vertici ha già un numero di archi elevato.
Per ogni arco creato il modulo mantiene l'identificativo del vertice collegato e il costo. Inoltre imposta le rotte nelle tabelle del kernel per rendere possibile la comunicazione via TCP con il vicino attraverso l'indirizzo di scheda.
Nel tempo, gestisce la costituzione di nuovi archi, la rimozione di archi, i cambiamenti del costo degli archi.
Il modulo fa uso delle tasklet, un sistema di multithreading cooperativo. Attraverso di esso esegue il monitoraggio delle schede di rete lasciando libero il chiamante di svolgere altri task.
Il modulo fa uso del framework ZCD, precisamente appoggiandosi ad una libreria intermedia prodotta con questo framework per formalizzare i metodi remoti usati nel demone ntkd.
Caratteristiche degli archi
Quando si crea un arco esso esiste per entrambi i nodi.
Tra due nodi vicini ci possono essere più archi, ma solo se sono su diversi domini di collisione. Di fatto il modulo consente la costituzione di un secondo arco solo se le interfacce di rete di entrambi i nodi sono diverse da quelle su cui è realizzato il primo arco.
Il costo di un arco in una direzione ( da A verso B ) può essere diverso dal costo nella direzione inversa. Questo non è utile quando il costo rappresenta il round-trip time, ma può esserlo se rappresenta la larghezza di banda in uscita.
Quando un nodo rimuove un arco tenta di comunicarlo al vertice collegato perché faccia altrettanto.
Requisiti
- Implementazione del sistema di tasklet.
- Identificativo del proprio nodo.
- La (o le) interfaccia di rete da monitorare.
- Durante le operazioni del modulo è possibile aggiungere o rimuovere una interfaccia di rete da monitorare.
- Numero massimo di archi da realizzare.
- Factory per creare uno "stub" per invocare metodi remoti nei nodi vicini.
- Manager di indirizzi e rotte.
Deliverables
- Emette un segnale per:
- costituzione di un arco.
- rimozione di un arco.
- variazione del costo di un arco.
- Fornisce metodi per:
- Ottenere l'elenco degli archi ora presenti.
- Dato l'identificativo di un messaggio in unicast ricevuto (una istanza di UnicastID) e dato il nome dell'interfaccia di rete da cui è stato ricevuto, stabilire se il messaggio è da processare.
- Dato l'identificativo di un messaggio in broadcast ricevuto (una istanza di BroadcastID) e dato il nome dell'interfaccia di rete da cui è stato ricevuto, stabilire se il messaggio è da processare.
- Dato un arco, ottenere un oggetto stub utilizzabile per inviare un messaggio (chiamare un metodo remoto) tramite questo arco al vicino ad esso collegato. Il messaggio viene inviato con protocollo reliable (TCP); questo significa che se non vengo notificato di un errore posso essere certo che il vicino ha ricevuto correttamente il mio messaggio e che l'eventuale risposta che ottengo è stata ricevuta correttamente.
- Ottenere un oggetto stub utilizzabile per inviare un messaggio in broadcast. Questo tipo di stub si usa per richiamare metodi remoti che non restituiscono risultati (void e senza eccezioni). E' possibile specificare a questo metodo se lo stub sarà utilizzato per inviare messaggi destinati a tutti i vicini; oppure a tutti tranne uno, passandogli l'identificativo del vicino da escludere; oppure, passandogli una interfaccia di rete, a tutti i vicini raggiungibili tramite quella.
- Quando non si specifica una interfaccia di rete, il modulo produrrà uno stub che si occuperà di inviare il messaggio in broadcast su tutte le interfacce di rete gestite.
Quando si invia un messaggio tramite questo oggetto l'invio del messaggio è asincrono: procederà in una nuova tasklet, mentre il metodo non fornirà alcuna risposta al chiamante. E' possibile fornire un oggetto in cui un determinato metodo (callback) verrà richiamato dopo un certo tempo se per qualcuno degli archi noti al modulo non si avrà ricevuto un messaggio di ACK dal vicino collegato. Questo controllo viene fatto sugli archi che sono esistenti al momento dell'invio e sono ancora presenti alla scadenza del timeout. Il metodo callback viene chiamato una volta per ogni arco che fallisce e avrà quell'arco come argomento, così che il chiamante possa prendere un provvedimento, ad esempio forzando la rimozione dell'arco.
- Forzare la rimozione di un arco.
Classi e interfacce
L'implementazione del sistema di tasklet è passata al modulo dal suo utilizzatore. Si tratta di una istanza dell'interfaccia INtkdTasklet che è descritta nel relativo documento.
Una interfaccia di rete passata al modulo è un oggetto istanza di una classe di cui il modulo conosce l'interfaccia INeighborhoodNetworkInterface. Tramite questa interfaccia il modulo può:
- Leggere il nome dell'interfaccia di rete, es: wlan0 (proprietà 'i_neighborhood_dev').
Leggere il MAC address dell'interfaccia di rete, es: CC:AF:78:2E:C8:B6 (proprietà 'i_neighborhood_mac').
- Misurare il round-trip time (la latenza) con un vicino.
L'utilizzatore del modulo Neighborhood può fornire il meccanismo di misurazione della latenza (o in generale del costo associato ad un arco) secondo due modalità. Come primo tentativo il modulo chiama il metodo 'measure_rtt' passando alcune informazioni tra cui l'indirizzo di scheda (del vicino) associato all'arco. Se l'oggetto fornito dall'utilizzatore è in grado di misurare la latenza con accuratezza (ad esempio eseguendo un comando "ping") questo primo tentativo va a buon fine. Altrimenti il modulo procederà con il secondo meccanismo.
Il meccanismo alternativo prevede la collaborazione del modulo nel nodo vicino. In questo caso il compito dell'oggetto fornito dall'utilizzatore, sia nel nodo che fa la misurazione sia nel nodo vicino, sarà quello di inviare e ascoltare un messaggio concordato su una porta UDP qualsiasi nella interfaccia di rete interessata. Con questa modalità la misurazione risulterà certamente meno accurata; questo è dovuto al fatto che il modulo utilizza dei thread cooperativi che non offrono tempi di risposta certi.
La stub factory è un oggetto di cui il modulo conosce l'interfaccia INeighborhoodStubFactory. Tramite essa il modulo può:
Creare uno stub per chiamare un metodo via UDP in broadcast sui nodi vicini (metodo 'i_neighborhood_get_broadcast'); il modulo specifica una o più interfacce di rete sulle quali desidera che lo stub invii il messaggio; il modulo specifica l'oggetto BroadcastID che lo stub includerà nel messaggio per indicare a ogni vicino che lo riceve se debba considerarsi tra i destinatari; il modulo può inoltre indicare un'istanza dell'interfaccia ModRpc.IAckCommunicator se vuole ricevere dopo il timeout la lista dei MAC address che hanno segnalato con un ACK la ricezione del messaggio.
- Creare uno stub per chiamare un metodo via UDP su uno specifico vicino (metodo 'i_neighborhood_get_unicast'); il modulo specifica l'interfaccia di rete sulla quale desidera che lo stub invii il messaggio; il modulo specifica l'oggetto UnicastID che lo stub includerà nel messaggio per indicare a ogni vicino che lo riceve se è lui il destinatario; il modulo può specificare se si vuole attendere l'esecuzione del metodo da parte del vicino o no; il modulo lo usa per comunicare con un vicino quando ancora non è stata negoziata la creazione dell'arco e quindi non è ancora possibile realizzare la connessione via TCP.
Creare uno stub per chiamare un metodo via TCP su uno specifico indirizzo (metodo 'i_neighborhood_get_tcp'); il modulo lo usa per comunicare in modo reliable con un nodo vicino attraverso un suo arco, specificando l'indirizzo di scheda associato all'arco; il modulo può specificare se si vuole attendere l'esecuzione del metodo da parte del vicino o no, ma comunque se il metodo ritorna senza l'eccezione StubError la ricezione da parte del vicino è garantita.
Il manager di rotte e indirizzi è un oggetto di cui il modulo conosce l'interfaccia INeighborhoodIPRouteManager. Tramite essa il modulo può:
Dato il nome di una interfaccia di rete e un indirizzo IP link-local nella dotted form, aggiungere l'indirizzo IP all'interfaccia di rete (metodo 'i_neighborhood_add_address');
- Dato il nome di una interfaccia di rete, il suo indirizzo IP link-local associato e un altro indirizzo IP link-local nella dotted form, aggiungere la rotta con scope link verso un vicino sull'interfaccia specificando come src preferito l'indirizzo di scheda (metodo 'i_neighborhood_add_neighbor');
- Dato il nome di una interfaccia di rete, il suo indirizzo IP link-local associato e l'indirizzo IP link-local di un vicino, rimuovere la rotta con scope link verso il vicino dall'interfaccia (metodo 'i_neighborhood_remove_neighbor');
- Dato il nome di una interfaccia di rete e il suo indirizzo IP link-local associato, rimuovere l'indirizzo IP dall'interfaccia (metodo 'i_neighborhood_remove_address').
Il modulo lo usa per rendere possibile la comunicazione via TCP coi vicini tramite un indirizzo fisso. Il modulo associa ad ogni interfaccia di rete che gestisce un indirizzo detto indirizzo di scheda. Per ogni arco che realizza, il modulo aggiunge la rotta con scope link verso l'indirizzo di scheda dell'interfaccia del vicino collegata all'arco. Quando rimuove l'arco rimuove anche la rotta. Quando il modulo cessa di gestire un'interfaccia rimuove il relativo indirizzo.
L'identificativo del proprio nodo, come anche l'identificativo di ogni vertice rilevato, è un oggetto il cui contenuto non è noto al modulo neighborhood. L'interfaccia di questo oggetto nota al modulo (INeighborhoodNodeID) gli consente di:
- verificare se due identificativi sono identici (metodo 'i_neighborhood_equals').
Un arco è un oggetto (NeighborhoodRealArc) noto al modulo. Grazie alle informazioni memorizzate in esso (my_nic, mac) il modulo è in grado di evitare la creazione di ulteriori archi verso lo stesso vicino se non usano interfacce di rete distinte da ambo i lati, ed anche di segnalare che il vicino ad esso collegato non è fra i destinatari di un messaggio inviato in broadcast. Sempre con le informazioni memorizzate in questo oggetto (nic_addr) il modulo è in grado di produrre lo stub che realizza la chiamata di un metodo remoto in TCP (reliable).
L'interfaccia dell'oggetto arco nota all'esterno del modulo, INeighborhoodArc, permette solo un sottoinsieme di operazioni:
- Leggere l'identificativo del vicino (proprietà 'i_neighborhood_neighbour_id').
- Leggere il MAC del vicino (proprietà 'i_neighborhood_mac').
- Leggere il costo dell'arco (proprietà 'i_neighborhood_cost').
- Leggere l'interfaccia di rete dell'arco (proprietà 'i_neighborhood_nic').
Data una istanza di CallerInfo, passata all'inizio dell'esecuzione di un metodo remoto (vedi framework ZCD), verificare se la chiamata del metodo è stata ricevuta tramite questo arco (metodo 'i_neighborhood_comes_from').
Quando si chiama il metodo che produce uno stub per l'invio di messaggi in broadcast, può essere passato un oggetto che contiene il codice e i dati necessari a gestire l'evento di 'mancata ricezione di un ACK da un arco entro il timeout'. Tale oggetto implementa l'interfaccia INeighborhoodMissingArcHandler. L'interfaccia permette di:
- lanciare il codice che gestisce una arco mancante, passandogli l'arco (metodo 'i_neighborhood_missing').
Il costo di un arco può essere espresso con diverse metriche (latenza, larghezza di banda, ...). Attualmente l'implementazione del modulo misura la latenza e la esprime con un intero in microsecondi.
La latenza è il tempo che impiega un messaggio da noi a raggiungere il vertice collegato. In realtà quello che si può misurare, quindi quello che il modulo memorizza come costo, è il round-trip time (RTT).