PERMESSO PERsistent MESSaging in ad hOc networks Massimo Benini – matr. 0000253860 C.d.L.S. Ingegneria Informatica Università di Bologna Reti di Calcolatori LS – Prof. Antonio Corradi – AA. 2006-07 Abstract Il progetto PERMESSO, acronimo di PERsistent MESSaging in ad hOc networks, è un sistema pensato per fornire un servizio di messaggistica persistente ad utenti di una rete ad-hoc (MANET), in modo spontaneo, ovvero senza un’infrastruttura predefinita, fra nodi che si auto-organizzano ed hanno caratteristiche tecniche eterogenee (smart-phone, palmari e portatili). Il progetto desidera sfruttare la dinamicità intrinseca nel modello delle reti MANET per fornire agli utenti soluzioni di instant messaging, in aree in cui l’infrastruttura di rete non è presente oppure in cui l’utilizzo della stessa risulta economicamente svantaggioso. In questa relazione verrà illustrato in particolare il servizio di chatting asincrono nelle sue due varianti. 1.Introduzione Le reti mobili ad hoc (Mobile Ad hoc NETwork -MANET) sono insiemi di nodi mobili interconnessi con link wireless. Questi nodi possono liberamente e dinamicamente muoversi auto-organizzandosi e creando una topologia temporanea ed arbitraria senza alcuna infrastruttura di rete preesistente. Considerando l’instabilità dei canali di comunicazione wireless e le possibilità di movimento degli utenti, tali reti risultano estremamente dinamiche. In questa topologia di architettura devono essere rivalutate la semantica e le proprietà della comunicazione, in quanto inevitabilmente si tratta di sistemi orientati a dinamiche di tipo best-effort in cui sono frequenti le perdite di messaggi e le cadute temporanee dei nodi. In particolare, le Mobile Ad-hoc NETwork (MANET) aprono ulteriori possibilità e abilitano la collaborazione fra utenti anche in assenza di una infrastruttura fissa e pre-pianificata: la dinamicità con cui tali reti tendono a formarsi le rende estremamente utili in condizioni in cui l’infrastruttura è assente o inutilizzabile (per esempio in ambito militare o in operazioni di soccorso o di emergenza in zone disastrate). La caratteristica comune di tutte le reti MANET è l’alto livello di dinamicità delle entità che la compongono; lo scopo fondamentale di una sistema collaborativo in ambiente MANET è quindi quello di fornire un supporto a tale dinamicità attraverso l’analisi dei requisiti derivanti. 1 L’impossibilità di sfruttare una conoscenza a priori della rete, dell’identità, dei nomi e delle caratteristiche dei nodi rende necessaria l’adozione di meccanismi di discovery dinamici: si necessita di protocolli attraverso i quali un dispositivo possa rilevare la presenza di altri dispositivi nelle vicinanze, condividere informazioni di configurazione e di servizi offerti da ciascuna entità e notificare quando un dispositivo risulti disponibile o meno (context awareness). Il processo di ricerca delle risorse deve essere in qualche modo continuo, per rilevare le modifiche topologiche significative della rete, ed efficiente, in modo da non sovraccaricare il traffico di rete. 2.PERMESSO PERMESSO è un progetto nato per lavorare all’interno di reti MANET e propone due distinti modelli di comunicazione: • Sincrono: utenti appartenenti alla stessa MANET possono comunicare direttamente. • Asincrono: utenti che desiderano comunicare e non si trovano connessi alla MANET in intervalli di tempo concomitanti possono lasciare messaggi o contenuti indirizzati ad un ben specificato utente. PERMESSO si preoccuperà di eseguirne il delivery quando il destinatario si collegherà alla MANET. PERMESSO è basato interamente su un’architettura a scambio di messaggi creata ad hoc (non si appoggia a nessun middleware preesistente) e si articola essenzialmente in tre moduli distinti: Figura 1 Schema generale PERMESSO. I. DISCOVERY: questo modulo si occupa della gestione degli ingressi dei nuovi nodi nella MANET, garantendo una conoscenza globale dello stato di tutti i membri della rete (nodi online e offline). Considerando la natura strettamente non affidabile delle reti MANET, ovvero che ogni nodo potrebbe cadere da un momento all’altro o non trovarsi più nel raggio di visibilità, questo servizio è reso affidabile da un sistema di REFRESH dello stato dei nodi 2 II. III. della rete,in cui ogni nodo deve comunicare periodicamente la sua presenza a tutti i nodi della rete. CHATTING SINCRONO: fornisce le funzionalità per lo scambio sincrono di messaggi fra due utenti appartenenti alla stessa MANET. Prevede la possibilità di instaurare delle chat con più utenti contemporaneamente. Lo scambio di messaggi avviene in maniera besteffort attraverso lo scambio di datagrammi udp (scelta dettata dalla teconologia). CHATTING ASINCRONO: questo modulo consente agli utenti di inviare messaggi ad altri utenti che in quel momento non sono connessi alla MANET (comunicazione permanente). PERMESSO provvedera ad eseguire la consegna dei messaggi quando i destinatari si collegheranno alla rete. Questo modulo si divide a sua volta in due sottoparti: nel primo si ipotizza la presenza di un particolare nodo (PERISTENT SERVER) all’interno della MANET, ovvero un server incaricato di mantenere in memoria i messaggi mandati da un nodo verso un altro nodo al momento offline, fino alla connessione del nodo destinatario; nel secondo caso si ipotizza la assenza del nodo PERSISTENT SERVER. I peer devono dunque supportare il servizio di chatting asincrono autonomamente. In tal caso i dispositivi riserveranno una quota del loro spazio di memoria per mantenere la corrispondenza asincrona propria e degli altri nodi e dovranno poi coordinarsi per eseguirne la consegna. Questo nuovo scenario introduce il nuovo problema derivante dall’abbandono di un nodo incaricato di consegnare messaggi messaggi asincroni dalla rete. Il progetto presentato affronta i problemi delle reti mobili ad-hoc costituiti principalmente dalla mancanza di coordinatori centrali, della scarsa affidabilità del mezzo di comunicazione e dalle limitate capacità di memorizzazione e computazionali dei dispositivi. Per la realizzazione abbiamo utilizzato come java virtual machine la J2ME (java 2 mobile edition), ovvero una versione lite di JAVA 2. L’ambiente di sviluppo ha indotto anche la scelta progettuale del protocollo di trasporto per la trasmissione dei messaggi; nella configurazione minima infatti (CLDC 1.0 e MIDP 2.0) esiste il supporto solo per la comunicazione con pacchetti datagram, senza quindi nessuna garanzia di affidabilità. Si è supposto che tutti i nodi appartenenti alla Manet siano a distanza 1-hop e che ci sia reciproca visibilità tra i partecipanti. La comunicazione tra i dispositivi avviene tramite l’interfaccia wireless 802.11. Per quanto riguarda gli indirizzi poi, si suppone che tutti i partecipanti abbiano IP statici e facciano parte della stessa sottorete X.Y.Z.[0...255]. 3.Chatting Asincrono 3.1 Persistent Server: Il Persistent Server è stato implementato come un dispositivo dedicato solo alla ricezione, alla memorizzazione e al delivery dei messaggi asincroni. Si è fatta l’ipotesi che il Persistent Server abbia una capacità di memorizzazione superiore rispetto gli altri nodi, per questo non è stata imposta nessuna limitazione sul numero di messaggi che il 3 dispositivo è in grado di memorizzare. Quando un nuovo utente entra nella MANET invia un messaggio di JOIN in broadcast alla rete, il Persistent Server dovrà avvisarlo della sua presenza (comunicandogli il suo ip) e inviare eventuali messaggi asincroni a lui destinati. Inoltre il PS attiverà, al suo avvio, un thread dedicato per il deposito di messaggi asincroni che da questo punto verranno convogliati da tutti i nodi verso di lui. Sarà poi compito del PS consegnare i messaggi asincroni una volta che il destinatario entra nella MANET. La presenza del PS non è sempre garantita, esso può entrare nella rete in un secondo momento comunicando a tutti il suo indirizzo ip. E’ compito dei nodi cambiare le modalità di chat asincrona da senza PS a con PS, ovvero mandando verso di lui tutto il traffico asincrono. 3.2 Ingresso Nodo con Persistent Server: Quando un nodo desidera entrare nel sistema deve come prima cosa inviare un messaggio broadcast di tipo JOIN in una predeterminata porta (DISCOVERY PORT) in modo che tutti i membri siano avvisati della sua presenza. A questo messaggio il Persistent Server dovrà rispondere con un messaggio di tipo HERE I AM (come tutti i nodi presenti nella rete) ma con testo del messaggio la stringa “PS“. In questo modo il nodo entrante viene avvisato della presenza del Persistent Server e può memorizzare l’indirizzo IP di quest’ultimo. Persistent Server Client X Client Y JOIN : DISCOVERY PORT HEREIAM: message = "PS" JOIN : DISCOVERY PORT HEREIAM: message = "PS" Fig 2. Ingresso nuovo nodo nella rete. Si è scelto di utilizzare questo semplice protocollo per non caricare ulteriormente la fase di discovery nella quale il dispositivo riceve e invia un gran numero di messaggi. Nel sistema PERMESSO i messaggi sono tutti standard e sono composti nella seguente maniera: -nodo sender. -nodo receiver. -nodo mailman (ovvero nodo che ha fatto da tramite per la consegna di messaggi asincroni). -tipo del messaggio. (JOIN, HEREIAM, SYN_CHAT_MSG, ……) -corpo del messaggio. Questo permette a qualsiasi nodo ricevente di risalire a chi ha spedito il messaggio come ad 4 esempio in questo caso permette al nodo appena entrato di memorizzare l’indirizzo IP del PS. Node Sender Node Receiver Node Mailman Message Type Payload Fig 3. Formato messaggi. 3.3 Ingresso Persistent Server: Se il sistema PERMESSO è già attivo senza la presenza del PS, e quindi il sistema di chat asincrono è gestito dai nodi stessi nella rete (come vedremo più avanti…), nel momento dell’ingresso nella MANET del PS tutti i nodi devono essere avvisati della presenza del PS e convogliare a lui tutto il traffico asincrono memorizzato. Inoltre devono cambiare la politica di gestione della chat asincrona da senza PS a con PS, spedendo verso il PS ogni nuovo messaggio asincrono. Il messaggio di JOIN del PS sarà ascoltato dal BroadCastListenerThread, un thread dedicato su ogni nodo all’ascolto dei messaggi di broadcast. Da questo messaggio i nodi estrapolano l’indirizzo IP del PS e da ora in poi spediranno verso di lui tutti i messaggi asincroni. Una volta percepita la presenza del PS ogni nodo controlla se ha messaggi asincroni memorizzati al suo interno e se presenti fa partire un Thread specifico per la consegna di questi al PS (AsyncMessageSenderThread). Il PS nel mentre ha già lanciato un Thread su una specifica porta di deposito (DEPOSIT PORT) che ascolta e serve tutte le richieste di deposito di messaggi asincroni (DEPOSIT THREAD). Il PS non fa altro che memorizzare questi messaggi in base al destinatario e al mittente e consegnarli al momento dell’ingresso del legittimo destinatario. ClientX ClientY BroadCastListenerX start PersistentServer BroadCastListenerY start JOIN: message = "PS" DepositThread start AsyncMsgSenderX start AsyncMsgSenderY start ASYNC_MSG: DEPOSIT PORT ASYNC_MSG: DEPOSIT PORT Fig 4. Ingresso PS nella rete. 5 3.4 Delivery messaggi asincroni: Finita la fase di discovery, se il PS ha in memoria messaggi il cui destinatario è il nodo appena entrato nella MANET, esso deve provvedere a inoltrare questi messaggi. Quindi subito dopo aver mandato il messaggio di HEREIAM al nuovo dispositivo entrato, il PS controlla se in memoria ha messaggi per lui (MainController.checkSender(joinMsg.getSender().getIp()) e se si provvede a far partire un Thread dedicato alla consegna di tutti i messaggi per quel preciso destinatario (DeliveryThread), considerando il fatto che ci possono essere messaggi per lui da destinatari diversi. Figura 5. Funzionamento Persistent Server. DeliveryThread manda un messaggio di tipo DELIVERY_REQUEST sulla MAIN PORT del destinatario in cui vi è già un DispatchingThread pronto ad ascoltare questo tipo di messaggi. A questo messaggio il DispatchingThread risponde con un DELIVERY_ACK e come corpo del messaggio viene indicata una porta su cui si instaurerà una connessione per il delivery dei messaggi veri e propri. Ora il PS procederà a mandare tutti i messaggi per quel destinatario per ogni mittente, sequenzializzando i messaggi di mittenti diversi con messaggi intermedi di tipo TEMP_END e attendendo messaggi di tipo TEMP_ACK come conferma di ricezione dei messaggi per uno specifico destinatario. In realtà tutti i messaggi di un mittente per un destinatario vengono accodati in un’unica stringa opportunamente formattata. Il risultato è che tutti i messaggi di un mittente vengono recapitati tramite un unico messaggio con l’effetto di generare minor traffico di rete. Lato client, per ogni DELIVERY_REQUEST ricevuta, viene creata un oggetto ChatForm a cui sono passati i messaggi da visualizzare. Questo protocollo permette lato client di diversificare i vari mittenti dei messaggi asincroni e quindi di visualizzare i messaggi inviati su diverse ChatForm in modalità asincrona, una per ogni mittente diverso. Alla fine del delivery il DeliveryThread manda un messaggio di DELIVERY_END per avvisare il nodo della fine del delivery. E’ utile sottolineare il fatto che ogni delivery per ogni destinatario viene effettuato su un 6 DeliveryThread dedicato, creato ad hoc per quel preciso nodo che entra nella rete. Inoltre le operazioni di memorizzazione e invio, quindi cancellazione sulla struttura dati contente i messaggi, sono assolutamente di tipo synchonized in modo da evitare inconsistenze semantiche. Nella prossima figura viene riportato l’esempio in cui il PS possiede e manda messaggi per il nodo appena entrato, provenienti da due mittenti diversi. Si ha dunque un protocollo iniziale per accetare i messaggi asincroni e poi tante fasi di handshake parziali quanti sono i diversi mittenti per il nodo destinatario appena entrato. Ed infine un unico messaggio finale di terminazione del Delivery. Persistent Server Client X JOIN: DISCOVERY PORT HEREIAM: DISCOVERY PORT, message = "PS" DeliveryThread Dispatching Thread start start DELIVERY REQ: MAIN PORT DELIVERY ACK: MAIN PORT, message = "port xxxx" ASYNC CHAT MSG : port xxxx TEMP END TEMP ACK ASYNC CHAT MSG : port xxxx TEMP END TEMP ACK DELIVERY END Figura 6. Delivery messaggi asincroni. 3.5 Invio messaggi asincroni lato client con Persistent Server: L’utente che vuole mandare un messaggio asincrono per prima cosa seleziona dalla MainChatList degli utenti amici il destinatario, poi scrive il testo in una ChatForm. La ChatForm è dello stesso tipo quella utilizzata per il servizio sincrono ma in modalità asincrona (all’apertura non si effettua il protocollo di handshaking e viene visualizzato un messaggio di user offline). Il messaggio asincrono (di tipo ASYNC_CHAT_MSG) viene spedito verso la DEPOSIT PORT del PS. Lato server il Deposit Thread è sempre in ascolto e appena riceve un messaggio ASYNC_CHAT_MSG lo salva in memoria. 7 Persistent Server ClientX Deposit Thread start ASYNC CHAT MSG : DEPOSIT PORT Figura 7. Deposito messaggi su Persistent Server. 4. Estensione dei servizi asincroni Si supponga ora che il PersistentServer non sia presente nella MANET. In tal caso, il messaggio da consegnare viene affidato ad un nodo scelto in maniera casuale. Un nuovo problema deriva dal possibile abbandono della MANET da parte di un nodo incaricato del delivery di messaggi asincroni. Si assume per semplicità che PERMESSO integri una funzione con cui un utente indica in maniera proattiva (cioè con un certo anticipo) le proprie intenzioni di abbandono (mediante il tasto exit). Dunque quando l'utente attiva tale funzione, il dispositivo provvede ad inviare i messaggi mantenuti a nodi scelti casualmente presenti all'interno della MANET. Rispetto al caso "con server" questa estensione offrirà un servizio best effort, nel senso che vi sarà un limite al numero di messaggi mantenuti da ciascun nodo nella tabella dei messaggi, superato il quale il nodo procederà allo scarto dei messaggi più vecchi (ApplicationConstants.MSG_LIMIT). 4.1 Invio messaggi asincroni: Nel caso in cui dalla schermata principale (MainChatList) venga selezionato un utente che risulta offline, la ChatForm viene aperta in modalità asincrona Nel momento in cui si decide di inviare il messaggio, si pone il problema di selezionare l’eventuale utente che deve occuparsi di memorizzarlo. Ogni nodo ha a disposizione uno spazio riservato e limitato per memorizzare i messaggi asincroni (propri o di altri utenti), si possono presentare diversi scenari: 1) Se la capacità della coda dei messaggi asincroni (messagesQueue) del nodo è inferiore o uguale al limite ApplicationConstants.MSG_LIMIT, il nodo memorizza il messaggio nella coda. 8 2) Altrimenti se è superiore viene scelto un nodo online a caso tramite il metodo GetRandomOnLineNode() . A questo punto il messaggio viene consegnato al nodo scelto tramite il metodo SendAsyncMessageWithoutPs(). Dall’altra parte, ovvero dalla parte del nodo scelto è presente un DepositThread, simile a quello visto per il caso con PS, che ascolta sulla porta DEPOSIT PORT, e che ha il compito di ricevere messaggi asincroni da altri pari. 3) Un terzo scenario è possibile nel caso in cui il numero dei messaggi accodati sia uguale al limite e non ci siano nodi online. In questo caso viene richiamato il metodo del nodo EnqueueMessage() che provvede a cancellare il messaggio più vecchio e a sostituirlo con quello nuovo. Fig 8. Invio messaggio asincrono senza PS 4.2 Consegna messagi asincroni: Il delivery dei messaggi potrà avvenire alla connessione di un nodo destinatario, in maniera del tutto simile a quella del servizio Chatting asincrono con PS, con totale trasparenza dal punto di vista dell’ utente. 9 E’ quindi presente in ogni client un BroadCastListenerThread che, per ogni ingresso di nodo nella rete, controlla se il dispositivo appena entrato è uno dei destinatari di almeno un messaggio nella propria coda dei messaggi. In caso affermativo, parte un DeliveryThread lato client che, con il medesimo protocollo usato dal PS descritto precedentemente, invia tutto il traffico asincrono al nuovo entrato. Dall’altra parte, il nodo appena entrato avrà fatto partire un DispatchingThread, che intercetta il messaggio DELIVERY_REQ del DeliveryThread e instaura una connessione per la ricezione dei messaggi. Crea un oggetto ChatForm in modalità asincrona e mostra i messaggi all’utente. 4.4 Uscita nodo: Come da specifica, un utente che intende lasciare l’applicazione deve, in maniera proattiva, comunicare la propria intenzione a tutti i nodi. Inoltre, se la propria coda di messaggi asincroni non è vuota deve provvedere alla loro consegna. Alla pressione del tasto EXIT sulla form principale (MAIN MIDLET), dopo aver fermato tutti i Thread, il controllore del nodo uscente come ultima istruzione chiama il metodo CheckAsyncStoredMessages() . Tramite questo metodo il nodo controlla se la propria coda è vuota e se non lo è sceglie un nodo a caso a cui consegnare i messaggi mediante la chiamata al metodo GetRandomOnLineNode(). Una volta individuato un nodo online a cui spedire i messaggi, viene svuotata la coda inviando tutto il suo contenuto sulla DEPOSIT PORT del nodo scelto. L’unica differenza con il caso precedente è lo scenario in cui non ci sono nodi online e quindi il nodo uscente non può consegnare la propria corrispondenza asincrona. Di conseguenza tali messaggi verranno persi. 4.5 Switching automatico della modalità di ChatForm: Come ulteriore servizio implementato nel progetto PERMESSO vi è lo switching automatico della modalità di chat, ovvero quando un nodo online instaura una chat con un altro nodo online, se quest’ultimo da online passa allo stato offline, PERMESSO riconosce che il nodo è uscito dalla rete e automaticamente cambia la modalità della chat da sincrona ad asincrona. Viceversa se un nodo instaura una chat asincrona con un nodo offline, e successivamente questo nodo entra nella rete, PERMESSO cambia automaticamente la modalità della chat da asincrona a sincrona, ovvero instaura una connessione per lo scambio sincrono di messaggi. La gestione dello switch è affidata al controllore delle chat (CHAT CONTROLLER). Se la ChatForm deve passare da asincrona a sincrona viene richiamato il controllore del nodo, che tramite il metodo DoChatRequest(), instaura una connessione sincrona con il nodo destinatario mandando un messaggio di tipo SYNC_CHAT_REQ_TRANS sulla MAIN_PORT del nodo destinatario. Il corpo del messaggio di richiesta di chat trasparente contiene il numero di porta per la connessione della chat appena instaurata. Viceversa, se un nodo con cui si ha una chat sincrona abbandona la rete, ovvero manda in broadcast un messaggio di LEFT, oppure non risponde dopo un tempo prestabilito al messaggio di REFRESH, PERMESSO cambia automaticamente la modalità della chat da sincrona a asincrona. 10 5. Conclusioni PERMESSO soddisfa a pieno le specifiche richieste con un buon compromesso tra efficacia ed efficienza: offre un servizio di chatting istantanea, persistente e affidabile, nonostante i limiti del canale di trasmissione utilizzato. Per quanto riguarda la comunicazione asincrona, all’utente viene fornita trasparenza sulla presenza o meno del PS. L’utilizzo di quest’ultimo evita la perdita di messaggi asincroni dovuta alla scarsa capacità di memorizzazione di dispositivi come PDA o smart phone, ma ha comunque il limite di non prevedere la replicazione del ruolo e di non essere quindi tollerante a guasti. Il servizio di chatting asincrono, con o senza PS, ha dato, empiricamente, buoni risultati, ma soffre un po’ dei ritardi dovuti all’elevato numero di messaggi. Per quanto riguarda invece il servizio di chatting sincrono sarebbe opportuno implementare un sistema di reliability dei messaggi, tramite ackowledgement dei messaggi ricevuti ed eventuali ritrasmissioni e un sistema di numerazione dei messaggi (es clock logico con Lamport). Inoltre PERMESSO presenta limiti alla scalabilità a causa dell’elevato numero di messaggi scambiati durante la fase di discovery, di refresh e di leave, che introducono ritardi nella comunicazione. 6. Sviluppi futuri Sono diverse le possibili estensioni di questo progetto: l’introduzione di un sistema di gruppi, quindi la possibilità di effettuare conferenze, ovvero chat con più di due partecipanti (distribuzione multicast dei messaggi scambiati); l’utilizzo di una rete multi-hop, la quale comporterebbe la necessità di implementare un servizio di routing fra nodi non visibili sulla stessa rete. Ulteriori modifiche potrebbero essere fatte a livello di replicazione e monitoraggio del PS, da parte di altri nodi. Inoltre si potrebbe modificare l’architettura del sistema suddividendo la MANET in partizioni, in modo da introdurre gerarchie di nodi affinché rendano più scalabile la fase di discovery, di refresh e di leave, snellendo così il traffico di rete. 7. Bibliografia I. II. A. Corradi, Slides corsi Reti di calcolatori LA, Reti di calcolatori LS. K. Topley, “J2ME in a nutshell”, O’Reilly, 2002 III. Chlamatac, M. Conti, JJN Li, “Mobile ad hoc networking: imperatives and challenger”, Elsevier Journal of Ad Hoc Networks, vol.1, no.1, 2003 IV. Mobile Information Device Profile @ http://developers.sun.com/mobility/midp/ 11 V. VI. VII. MID Overview @ http://java.sun.com/javame/reference/apis/jsr118/ CLDC Overview @ http://java.sun.com/javame/reference/apis/jsr139/ Java Mobile Platform @ http://java.sun.com/javame/index.jsp/ 12