• Non ci sono risultati.

Ogni nodo che riceve un pacchetto JOIN QUERY contenente advertisement di interesse, produce e trasmette un pacchetto JOIN REPLY indirizzato al nodo superiore lungo il path, ovvero al nodo da cui ha ricevuto il JOIN QUERY stesso.

Il pacchetto JOIN REPLY è così composto: • HEADER • PAYLOAD o n_filters o filter1 o filter2 o ... ODPSRP_HEADER DATA filter1 n_filters ... filter2 ... Figura 22

Ogni filtro è costituito da:

• name (nome del tipo di evento)

• operand (operando matematico del filtro {<,>,<=,>=,==,!=,>=<}) • value (valore del filtro)

• type (tipo di valore {INT,STRING}) • timestamp (tempo di inizio validità)

Ogni nodo inserisce all’interno del proprio JOIN REPLY tutti i filtri sottoscritti da Subscriber locali e tutti i filtri ancora validi ricevuti da altri nodi tramite JOIN REPLY (detti filtri di

forward).

I filtri sottoscritti da Subscriber locali avranno un timestamp pari all’istante di invio del JOIN REPLY, tutti gli altri invece manterranno il timestamp con il quale sono stati ricevuti.

All’interno di un JOIN REPLY viene inviato il subset minimo di filtri in modo da minimizzare l’overhead di comunicazione e di elaborazione; vediamo un esempio in Figura 23.

NODO PUBLISHER Publisher ODPSRP [X==-5] [X>0] NODO SUBSCRIBER Subscriber X>0 ODPSRP [X>0] JOIN REPLY [X>0] JOIN REPLY [X>0] [X==-5] NODO SUBSCRIBER Subscriber X>3 ODPSRP [X>3] NODO SUBSCRIBER Subscriber X==-5 ODPSRP [X==-5] [X>0] [X>3] JOIN REPLY [X>3] Figura 23

Ricordiamo che ogni filtro di forward scade dopo un tempo ODPSRP_FG_TIMEOUT; per ogni notifica ricevuta che risulta coperta da un filtro di forward, viene confrontato il campo timestamp del filtro di forward stesso con l’orologio di sistema: se dal confronto risulta che il filtro è scaduto, questo viene invalidato ed eliminato in quanto obsoleto.

I filtri sottoscritti localmente al contrario non scadono mai, ma vengono eliminati solo su ricezione di un’opportuna UNSUBSCRIBE dell’applicazione Subscriber che li ha generati. Da quanto detto pare necessaria la presenza di un meccanismo di sincronizzazione degli orologi di sistema dei vari nodi per garantire il corretto funzionamento del meccanismo di invalidazione dei filtri di forward. Tale meccanismo non è stato implementato all’interno del nostro sistema in quanto non necessario, dato che gli orologi di sistema di tutti i nodi sono perfettamente sincronizzati all’interno del simulatore Qualnet.

Osserviamo comunque che anche in una rete reale non ci sará bisogno di nessun meccanismo di sincronizzazione, ma sará sufficiente utilizzare dei tempi relativi inseriti all’interno del campo timestamp per specificare dal validitá di un dato filtro inviato ad un nodo vicino tramite un JOIN REPLY.

Ovviamente se un nodo non ha né sottoscrizioni locale né filtri di forward interessati agli advertisement contenuti in un JOIN QUERY, non invierà nessun JOIN REPLY.

Osserviamo che con il meccanismo descritto un nodo intermedio che riceve un filtro di forward diviene a tutti gli effetti un sottoscrittore egli stesso, infatti risponderá a tutti i successivi pacchetti JOIN QUERY contenenti advertisement di interesse fintanto che i filtri ricevuti rimangono validi, ovvero non sono ancora scaduti.

Questo a prima vista potrebbe essere un effetto indesiderato del sistema in quanto se ad un ciclo di costruzione della mesh di trasporto vengono attivati dei nodi lungo un cammino, questi rimangono attivi e si comportano come dei subscriber fintanto che il filtro precedentemente ricevuto non viene distrutto per vecchiaia, e tutto questo accade indipendentemente dal fatto che si trovino ancora su di un cammino utile verso il vero nodo Subscriber, attivando potenzialmente tutta una serie di nodi non effettivamente necessari al servizio di notifica e che potrebbero provocare una ridondanza di trasmissioni dannosa per l’efficienza ed efficacia del sistema.

Ciononostante abbiamo deciso di optare per questa soluzione in quanto garantisce una maggiore robustezza del sistema e una maggiore efficacia del servizio controbilanciata da un costo non esiguo in termini di efficienza; immaginiamo ad esempio cosa potrebbe accadere se un nodo Subscriber non riceve una JOIN QUERY ad un ciclo di ricostruzione della mesh, oppure se il suo JOIN REPLY non viene ricevuto da nessun: in questo caso la mobilitá dei nodi potrebbe aver reso il precedente path di forward del tutto incapace di operare il servizio di notifica; dando a tutti i nodi con filtri di forward ancora validi il potere di attivare dei propri cammini ad ogni ciclo di ricostruzione della mesh possiamo invece avere una maggiore probabilitá che il sistema riesca a continuare a servire il nodo Subscriber.

I pacchetti JOIN REPLY possono essere inviati in unicast o in broadcast a seconda del valore del parametro ODPSRP_REPLY_METHOD.

Per inviare tali pacchetti in broadcast è sufficiente inserire nel file di configurazione la seguente stringa:

ODPSRP_REPLY_METHOD BROADCASTt

Alternativamente si può utilizzare il meccanismo di invio di JOIN REPLY in unicast inserendo la stringa:

ODPSRP_REPLY_METHOD UNICAST

Nel caso non venga inserita nessuna delle due precedenti stringhe il sistema utilizzerá per default il metodo broadcast.

Quando operiamo in modalità unicast i pacchetti JOIN REPLY vengono inviati direttamente al NodeUp contenuto nella TABELLA DI FORWARD descritta nella precedente sezione [3.3.2].

Al contrario, quando operiamo in modalità broadcast i pacchetti JOIN REPLY vengono inviati con un indirizzo broadcast, quindi verranno recevuti da tutti i nodi nel raggio di copertura dell’antenna.

Di tutti questi nodi solo uno non deve scartare tale pacchetto, ovvero il NodeUp appena descritto, ovvero il nodo che si trova a monte lungo il path verso il nodo pubblicatore; per fare questo il nodo che invia il JOIN REPLY inserisce nell’header del pacchetto nel campo hopCount l’indirizzo del NodeUp.

Tutti i nodi che ricevono un pacchetto JOIN REPLY durante la modalità broadcast quindi controllano se il campo hopCount dell’header coincide con il proprio indirizzo: in caso affermativo processano il pacchetto, altrimenti lo scartano.

Il vantaggio di operare in modalità broadcast consiste nella maggiore velocità di risposta che il sistema sperimenta grazie alla possibilità di evitare di attraversare lo strato di routing che può introdurre ritardi e latenze; inoltre permette un risparmio di pacchetti grazie alla mancanza di messaggi di acknowledgement e all’utilizzo del meccanismo da noi denominato PASSIVE REPLY ACKNOWLEDGEMENT descritto in dettaglio nella sezione [3.3.7.5].

I pacchetti JOIN REPLY sono molto delicati per il protocollo e una loro mancata ricezione potrebbe causare una perdita di notifiche anche consistente: da qui la necessità di avere un meccanismo di acknowledgement che garantisca la corretta trasmissione e ricezione.

Particolarmente delicato è il problema di quando rispondere a un pacchetto JOIN QUERY con l’invio di un pacchetto JOIN REPLY: se ad esempio rispondiamo appena riceviamo un JOIN QUERY, i nodi vicini al nodo publisher risponderanno per primi; successivamente i nodi distanti 2 Hop invieranno il loro proprio JOIN REPLY; tale pacchetto dovrà essere ritrasmesso dai nodi distanti un solo Hop; a questo punto risponderanno i nodi distanti 3 hop e tali pacchetti andranno ritrasmessi dai nodi distanti 2 e 1 hop e così via…

Avremo quindi una grossa inefficienza dovuta a nodi distanti che faranno crescere esponenzialmente il numero di pacchetti JOIN REPLY trasmessi nell’intera rete.

La situazione rimane invariata se ogni nodo attende un intervallo fisso prima di inviare il proprio JOIN REPLY.

Per risolvere questo inconveniente propongo una mia personale soluzione dettagliata nella sezione [3.3.7.2].

Documenti correlati