Differences between revisions 3 and 4
Revision 3 as of 2015-03-09 20:56:05
Size: 6558
Editor: lukisi
Comment:
Revision 4 as of 2015-06-25 09:14:04
Size: 5006
Editor: lukisi
Comment:
Deletions are marked like this. Additions are marked like this.
Line 17: Line 17:
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, il modulo Neighborhood in esso comunica (preferibilmente via TCP che è reliable) un numero random ''guid'' al modulo nel nodo ''b''. Immediatamente il modulo nel nodo ''b'' richiama su questo oggetto il metodo {{{ i_neighborhood_prepare_ping(guid) }}}. Dopo circa un secondo il modulo Neighborhood nel nodo ''a'' richiama su questo oggetto il metodo {{{ i_neighborhood_get_usec_rtt(guid) }}} ed ottiene la misura del RTT. Tutto il resto dell'implementazione è a carico dell'oggetto passato al modulo. 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.
Line 19: Line 19:
L'istanza di questo oggetto passato al modulo è legata alla specifica interfaccia di rete (''dev_a'' nel nodo ''a'', ''dev_b'' nel nodo ''b'' del nostro esempio). Essa ha un riferimento all'istanza di UDPServer (libreria ZCD) che è associata a quel device, sia in scrittura che in ascolto. E' tramite l'uso delle API di questa libreria che l'oggetto svolge il suo compito. 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:
 * 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.
Line 21: Line 35:
=== Modifiche alla libreria ZCD ===
L'oggetto nel nodo ''b'', associato al device ''dev_b'', richiama un metodo sul relativo UDPServer con il quale lo informa che sta per ricevere un messaggio PING_XXX dove XXX è il numero ''guid''. L'UDPServer inserisce il messaggio indicato in una collezione.

Dopo circa 1 secondo l'oggetto nel nodo ''a'', associato al device ''dev_a'', richiama un metodo sul relativo UDPServer che inizia la procedura di 'ping' descritta di seguito con il valore ''guid''. L'UDPServer in questo metodo inserisce il messaggio PONG_XXX in una collezione. Poi invia sul device interessato il messaggio PING_XXX in broadcast UDP. Inoltre registra un Channel che sarà messaggiato alla ricezione del PONG, e si mette in attesa su quel channel. Quando il nodo ''b'' riceve il messaggio PING, il metodo handle_request del suo UDPServer verificherà per prima cosa che il messaggio sia un PING atteso. Se lo è invia sul device interessato il messaggio PONG_XXX in broadcast UDP e rimuove dalla lista degli attesi il PING_XXX. Quando il nodo ''a'' riceve il messaggio PONG, il metodo handle_request del suo UDPServer verificherà per prima cosa che il messaggio sia un PONG atteso. Se lo è messaggia il Channel precedentemente registrato. A questo punto il metodo che era stato inizialmente chiamato sul UDPServer del nodo ''a'' va a terminare, misurando il RTT.

Questo giro consente di evitare gran parte dell'overhead introdotto dalla libreria 'ZCD' nelle chiamate a metodi remoti, ottenendo quindi un RTT più accurato.

'''Nota''': se la misurazione del RTT va in timeout il metodo di UDPServer restituisce un'eccezione !ChannelError. L'oggetto che implementa INeighborhoodNetworkInterface la traduce in un'eccezione !NeighborhoodGetRttError, che è prevista dalla firma del metodo i_neighborhood_get_usec_rtt. Il modulo Neighborhood non elabora questa misurazione fallita, senza per questo rimuovere l'arco, in quanto l'UDP è di natura un protocollo non reliable.
'''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.
Line 33: Line 40:
Usando questo metodo sull'oggetto che implementa questa interfaccia il modulo potrà indicare una istanza dell'interfaccia IAcknowledgementsCommunicator per ricevere dopo il timeout la lista dei MAC address che hanno segnalato con un ACK la ricezione del messaggio. Il modulo Neigborhood riceve dal suo utilizzatore una istanza dell'interfaccia INeighborhoodStubFactory, che ha il metodo i_neighborhood_get_broadcast per ottenere uno stub.
Line 35: Line 42:
=== Modifiche alla libreria ZCD ===
La libreria 'ZCD', quando usata per l'invio di messaggi in broadcast, offre la possibilità di ricevere un acknowledgement dai nodi che ricevono correttamente il messaggio. Infatti l'invio del messaggio in UDP non garantisce la sua ricezione. Va detto che anche il messaggio di ACK potrebbe perdersi, ma in generale avere la certezza della ricezione o in caso contrario il dubbio è sufficiente.

Gran parte delle operazioni necessarie per questa feature sono svolte dalla libreria ZCD.

Per tutti i messaggi in broadcast viene inviato un pacchetto ACK dai nodi che lo ricevono.

Il nodo che invia il messaggio crea un'istanza dell'oggetto UDPMessage. L'istanza genera un identificativo di 10 cifre con {{{ Random.int_range(1000000000, 1999999999) }}} di modo che entri in un int32 e abbia una rappresentazione a stringa di sempre 10 cifre.

Il nodo che riceve il messaggio, quando ha ricomposto l'oggetto UDPMessage, compone il messaggio {{{ ACK_1234567890_CC:AF:78:2E:C8:B6 }}}. I caratteri da 4 a 13 sono l'identificativo della UDPMessage ricevuta. I caratteri da 15 a 31 sono il MAC dell'interfaccia su cui la UDPMessage è stata ricevuta, in maiuscolo e con il separatore ':'. Quindi invia il messaggio in broadcast UDP sulla stessa interfaccia di rete.

Un generico !BroadcastClient (o uno specifico, per esempio !AddressManagerBroadcastClient) nel costruttore può ricevere e memorizzare una istanza della interfaccia IAcknowledgementsCommunicator. Questa specifica il metodo 'prepare()' che restituisce un oggetto 'Tasklets.Channel'.

Chi vuole inviare un messaggio quindi può istanziare una sua classe che implementi questo metodo. Esso viene chiamato quando sul !BroadcastClient viene invocato un metodo remoto; il chiamante fa in modo che questo metodo prepari un Channel. Poi l'invio del messaggio avviene e 'ZCD' si occupa di stare attento a quali MAC segnalino entro un certo tempo con un ACK la ricezione del messaggio. Al termine di questo tempo 'ZCD' segnala questo elenco di MAC inviando la lista in un unico messaggio attraverso il Channel suddetto.
Il modulo lo usa sempre immediatamente prima di chiamare un metodo remoto in broadcast, e può qui indicare una istanza dell'interfaccia !ModRpc.IAckCommunicator per ricevere dopo il timeout la lista dei MAC address che hanno segnalato con un ACK la ricezione del messaggio.

Modulo Neighborhood - Requisiti / Dipendenze

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. 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.

INeighborhoodStubFactory - metodo i_neighborhood_get_broadcast

Il modulo Neigborhood riceve dal suo utilizzatore una istanza dell'interfaccia INeighborhoodStubFactory, che ha il metodo i_neighborhood_get_broadcast per ottenere uno stub.

Il modulo lo usa sempre immediatamente prima di chiamare un metodo remoto in broadcast, e può qui indicare una istanza dell'interfaccia ModRpc.IAckCommunicator per ricevere dopo il timeout la lista dei MAC address che hanno segnalato con un ACK la ricezione del messaggio.

Netsukuku/ita/docs/ModuloNeighborhood/Requisiti (last edited 2016-02-25 17:19:27 by lukisi)