relazione
Transcript
relazione
Università degli studi di Bologna Alma Mater Studiorum Facoltà di Ingegneria Corso di Laurea in Ingegneria informatica Progetto in Reti di Calcolatori M Kamailio: una modifica per Load Balancing e QoS Docente Autore Prof. Antonio Corradi Stefano Poli Anno Accademico 2009/2010 Indice 1 Presentazione 4 1.1 Obiettivi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.2 Presentity, Watcher e Presence Server . . . . . . . . . . . . . . 5 1.3 Vincoli tecnologici . . . . . . . . . . . . . . . . . . . . . . . . 7 1.4 Panoramica su questa relazione . . . . . . . . . . . . . . . . . 8 2 Protocollo SIP 9 2.1 Architettura SIP . . . . . . . . . . . . . . . . . . . . . . . . . 10 2.2 Struttura SIP . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 2.3 2.2.1 Syntax and Encoding layer . . . . . . . . . . . . . . . . 12 2.2.2 Transport layer . . . . . . . . . . . . . . . . . . . . . . 12 2.2.3 Transaction layer . . . . . . . . . . . . . . . . . . . . . 13 2.2.4 Transaction User layer . . . . . . . . . . . . . . . . . . 13 Messaggio SIP . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.3.1 Request-Line . . . . . . . . . . . . . . . . . . . . . . . 14 2.3.2 Response-Line . . . . . . . . . . . . . . . . . . . . . . . 15 2.3.3 Headers . . . . . . . . . . . . . . . . . . . . . . . . . . 16 2.3.4 Corpo del messaggio . . . . . . . . . . . . . . . . . . . 18 2.3.5 SIP URI . . . . . . . . . . . . . . . . . . . . . . . . . . 18 1 INDICE 2 3 Presence Service 19 3.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 3.2 Sorgenti delle informazioni di presenza . . . . . . . . . . . . . 24 3.3 Standard per protocolli di presenza: SIMPLE . . . . . . . . . 25 3.3.1 Metodi PUBLISH, SUBSCRIBE e NOTIFY . . . . . . 29 3.3.2 Presence Information Data Format . . . . . . . . . . . 30 3.4 Gestione dei conflitti delle informazioni . . . . . . . . . . . . . 33 3.5 Metodi per l’utilizzo del servizio di presenza . . . . . . . . . . 35 4 Tecnologie utilizzate 40 4.1 Presence Server Kamailio . . . . . . . . . . . . . . . . . . . . . 40 4.2 JAIN-SIP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 5 Soluzione del progetto 44 5.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 5.2 Client SIP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 5.3 5.4 5.2.1 PUBLISH . . . . . . . . . . . . . . . . . . . . . . . . . 50 5.2.2 SUBSCRIBE e UNSUBSCRIBE . . . . . . . . . . . . . 51 Presence Server Kamailio . . . . . . . . . . . . . . . . . . . . . 52 5.3.1 Modifica della gestione dei messaggi SUBSCRIBE . . . 53 5.3.2 Modifica della gestione dei messaggi PUBLISH . . . . . 56 Risultati sperimentali . . . . . . . . . . . . . . . . . . . . . . . 62 A Configurazione di kamailio 67 A.1 Prerequisiti . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 A.2 Download . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 A.3 Compilazione e installazione . . . . . . . . . . . . . . . . . . . 68 A.4 Configurazione . . . . . . . . . . . . . . . . . . . . . . . . . . 70 A.4.1 File di configurazione per ogni istanza . . . . . . . . . 72 INDICE B Modulo di presenza modificato 3 81 B.1 Compilazione ed installazione . . . . . . . . . . . . . . . . . . 81 B.2 Configurazione . . . . . . . . . . . . . . . . . . . . . . . . . . 82 Bibliografia 88 Capitolo 1 Presentazione 1.1 Obiettivi Il progetto si propone di sviluppare un sistema di supporto per la distribuzione di dati di presenza (ad esempio stato e contatti dell’utente, informazioni di localizzazione, informazioni sul contesto di esecuzione, ...) su larga scala. Tale sistema deve essere in grado di mettere in comunicazione fonti (presentity) e fruitori (watcher) dei dati di presenza, anche quando presentity e watcher si trovano su server differenti. Oltre a ciò, si vuole progettare un’infrastruttura di supporto in grado di abilitare alta scalabilità di tutto il sistema attraverso tecniche di bilanciamento del carico. Infine, si vuole dare la possibilità anche a terminali mobili di accedere in modo continuativo al servizio di presenza (sia in spedizione che in ricezione) nonostante possibili disconnessioni. 4 CAPITOLO 1. PRESENTAZIONE 1.2 5 Presentity, Watcher e Presence Server Il sistema è composto da tre entità principali: le presentity, i presence server (servizio di presenza) e i watcher (figura 1.1) Figura 1.1: Sistema Le presentity In generale si ipotizzi di avere diverse fonti di informazioni di presenza che, agendo da presentity, generano i dati di presenza da distribuire a tutti i sottoscrittori registrati. Ogni presentity deve essere in grado di: • collegarsi a un server di presenza e inviare un messaggio contenente il suo stato (es. online, non al computer, a pranzo); • migrare su di un server alternativo in caso il server non sia disponibile o sovraccarico. CAPITOLO 1. PRESENTAZIONE 6 I watcher I watcher, in modo duale rispetto presentity, rappresentano le entità interessate alla ricezione delle informazioni di presenza. Ogni watcher deve essere in grado di: • collegarsi a un server di presenza e sottoscrivere lo stato della sua lista di contatti; • ricevere le informazioni di presenza dei propri contatti dal server; • migrare su di un server alternativo in caso il server non sia disponibile o sovraccarico. Il Presence Server Il presence server ha lo scopo di portare le informazioni di presenza dalle presentity ai watcher. Aspetto importante nella realizzazione/configurazione del servizio di presenza è che si vuole garantire la possibilità di accesso al servizio di presenza in ambienti distribuiti nei qualle presentity e watcher afferiscano a server diversi. In aggiunta, ogni server deve avere un ruolo attivo nel bilanciare il carico degli utenti utilizzando le informazioni che è in grado di raccogliere. In particolare, le varie istanze del sistema devono adattare il servizio in base alle abitudini degli utenti favorendo, ad esempio, gli utenti molto attivi o quelli che hanno un contratto particolare (si pensi alla possibilità di gestire livelli di qualità di servizio differenziati). Ogni server di presenza deve: • all’atto di una pubblicazione, salvare lo stato della presentity e notificare eventuali watcher; CAPITOLO 1. PRESENTAZIONE 7 • all’atto di una sottoscrizione fornire lo stato più aggiornato relativo alla presentity sottoscritta; • profilare i client, ossia raccogliere informazioni circa il numero dei watcher interessati allo stato del client, il numero dei contatti del client e la frequenza di pubblicazione delle informazioni; • utilizzare le informazioni precedenti per minimizzare i messaggi di segnalazione attuando eventualmente politiche di migrazione. Per la realizzazione del presence service si considerino le specifiche SIP (Session Initiation Protocol) dei Presence Service. 1.3 Vincoli tecnologici Il progetto dovrà seguire i seguenti vincoli tecnologici: • i client di presenza potranno essere sviluppati in C o in Java ma la parte di comunicazione dovrà utilizzare esclusivamente il protocollo SIP (Session Initiation Protocol). In particolare si chiede che i client supportino solo tre tipi di messaggio (SUBSCRIBE, PUBLISH e NOTIFY) nella loro versione più semplice; • per i server è richiesto l’uso di un server OpenSER (a scelta tra OpenSIPS o Kamailio), disponibile in versione OpenSource in linguaggio C. I server OpenSER già implementano tutta la parte di comunicazione con i client e la persistenza delle informazioni. Per i protocolli di comunicazione server-to-server non si impongono vincoli progettuali ma si raccomanda l’utilizzo di semplici meccanismi come socket UDP (eventualmente multicast). CAPITOLO 1. PRESENTAZIONE 8 Le tecnologie coinvolte sono: • Presence Server: OpenSER, da poco suddiviso nei progetti OpenSIPS e Kamalio; • JAIN SIP e JSR281 API (esistono alcune prime implementazioni come quella di Ericsson). 1.4 Panoramica su questa relazione Nel capitolo 2 verranno illustrate le caratteristiche principali del protocollo SIP. Nel capitolo 3 verranno illustrate le caratteristiche principali del servizio di presenza. Nel capitolo 4 verranno illustrate le tecnologie utilizzate durante la realizzazione di questo progetto. Nel capitolo 5 verrà illustrata la soluzione proposta per raggiungere gli obiettivi enunciati nel paragrafo 1.1. Capitolo 2 Protocollo SIP SIP è un protocollo applicativo usato per instaurare, modificare e terminare sessioni multimediali in una rete basata su IP. Una sessione multimediale, consiste in uno scambio di flussi multimediali tra due o più interlocutori. Per permettere l’inizio, la modifica, e il termine di tale scambio, è necessario che il mittente segnali al destinatario la volontà di instaurare una sessione con esso, ricorrendo all’uso di un protocollo di segnalazione. SIP è standardizzato dall’Internet Engineering Task Force (IETF) e le sue applicazioni includono voce, video, gaming, controllo di chiamata, servizio di presenza, ecc. SIP è un protocollo di segnalazione adottato, per la sua semplicità, come protocollo di segnalazione del Voice over IP (VoIP), e diventato poi standard nel 1999 e descritto nella [6]. Esso è stato ridisegnato più volte per aggiungere al suo interno nuove funzionalità, generando il nuovo standard definito in [9]. 9 CAPITOLO 2. PROTOCOLLO SIP 2.1 10 Architettura SIP SIP è basato sul Hypertext Transfer Protocol (HTTP) e sul Simple Mail Transfer Protocol (SMTP) ed è stato creato per raggiungere i seguenti obiettivi: • indipendenza dal protocollo di trasporto – SIP può utilizzare sia il protocollo TCP che UDP; • instradamento in base alla richiesta – un messaggio SIP può essere instradato direttamente verso il destinatario, o instradato da un proxy intermedio; • separazione tra informazioni di segnalazione e contenuti multimediali; • estensibilità; • utilizzabile in mobilità. L’architettura SIP prevede degli User Agents (UAs) e degli intermediari (servers). Lo UA è il terminale della comunicazione, come ad esempio un telefono cellulare, e si divide in: • User Agent Client (UAC) – il mittente della richiesta; • User Agent Server (UAS) – il destinatario della richiesta, colui che la accetta, rifiuta o ridirige ed invia le risposte. Gli intermediari, sono entità logiche attraverso le quali passa la richiesta per raggiungere il destinatario. Gli intermediari si dividono in: • Proxy Server o SIP Server – riceve ed inoltra la richiesta SIP; può modificare alcune parti del messaggio senza interferire con lo stato della richiesta o del dialogo tra i due interlocutori; CAPITOLO 2. PROTOCOLLO SIP 11 • Redirect Server – ha il compito di sostituire l’indirizzo destinatario della richiesta, con un nuovo indirizzo; non partecipa alla transazione; • Location Server – tiene traccia della posizione degli utenti; utile soprattutto se gli utenti sono in mobilità; • Registrar Server – accetta le richieste di tipo REGISTER; viene utilizzato per memorizzare l’associazione tra indirizzo dell’utente e indirizzo del terminale da cui esso effettua la richiesta o su cui vuole ricevere nuove richieste; • Application Server – è un’entità di rete che fornisce servizi agli utenti; un tipico esempio è il Presence Server, che offre il servizio di presenza. • Back-to-back-user-agent (B2BUA) – agisce come un User Agent a entrambe le estremità di una sessione o chiamata SIP. Il B2BUA è responsabile per la gestione della segnalazione della chiamata (instaurazione, mantenimento, chiusura) sia sul chiamante che sul chiamato. Ogni chiamata è monitorata dall’inizio alla fine, permettendo agli operatori di offrire attraverso il B2BUA una funzionalità aggiuntiva per la chiamata. Per i client SIP, il B2BUA agisce come un UAS su un lato e come un UAC sugli altri lati. 2.2 Struttura SIP SIP, è un protocollo strutturato a livelli, i quali consentono di ottenere indipendenza tra le funzionalità da esso offerte. La struttura a livelli è rappresentata in figura 2.1. CAPITOLO 2. PROTOCOLLO SIP 12 Figura 2.1: Struttura SIP a livelli 2.2.1 Syntax and Encoding layer Il livello più basso della struttura, è denominato Syntax and Encoding, e ha il compito di definire la sintassi e la codifica di un messaggio SIP. La codifica, è specificata con una grammatica di tipo augmented Backus-Naur Form (BNF), definita in [9]. La grammatica BNF, definisce in che modo devono essere codificate le informazioni, ad esempio con la sintassi name: value 2.2.2 Transport layer Il livello di trasporto, o Transport layer, specifica come i clients devono inviare richieste e ricevere risposte, e come i servers devono ricevere richieste ed inviare risposte. Basandosi sulla sintassi e sulla codifica di un messaggio SIP definiti al livello sottostante, il livello di trasporto introduce gli headers SIP necessari all’instradamento di richieste e risposte da parte degli interlocutori. Un esempio tipico, è l’introduzione degli headers Via. CAPITOLO 2. PROTOCOLLO SIP 2.2.3 13 Transaction layer Il terzo livello, prende il nome di Transaction layer. Una transazione SIP (SIP transaction), è costituita da una richiesta e dall’insieme delle risposte ad essa associate. Il Transaction layer ha il compito di mantenere le associazioni tra richieste e risposte. Le transazioni SIP si dividono in: • transazioni client – instaurate dal client che vuole inviare una richiesta e ricevere delle risposte; • transazioni server – instaurate dal server che riceve una richiesta ed invia le risposte. Questo livello, utilizza il Transport layer per inviare e ricevere richieste e risposte. 2.2.4 Transaction User layer Il livello più alto della struttura SIP, prende il nome di Transaction User layer. Questo livello, ha il compito di instaurare transazioni client e server. Quando un client vuole inviare una richiesta SIP, crea un’istanza di una transazione client, ed invia la richiesta insieme all’indirizzo IP del destinatario, alla porta, e al nome del protocollo di trasporto da utilizzare. I Transaction User, sono definiti per essere UAC e UAS. Gli UAC creano ed inviano richieste, e ricevono risposte, mentre gli UAS ricevono richieste, e creano ed inviano risposte, utilizzando il Transaction layer. 2.3 Messaggio SIP Un messaggio SIP, è composto da tre parti: CAPITOLO 2. PROTOCOLLO SIP 14 • request line (per le richieste) o status line (per le risposte) – contengono le informazioni relative al tipo di richiesta o risposta; • headers – aggiungono informazioni al messaggio; • corpo del messaggio – contiene informazioni di interesse per il destinatario. Un esempio di richiesta SIP è il seguente: INVITE sip:[email protected] SIP/2.0 Via: SIP/2.0/UDP cscf1.open-ims.test:5060;branch=z9hG4bK8542.1 Via: SIP/2.0/UDP [5555::1:2:3:4]:5060;branch=z9hG4bK45a35h76 Max-Forwards: 69 From: Alice <sip:[email protected]>;tag=312345 To: Bob Smith <sip:[email protected]> Call-ID: 105637921 CSeq: 1 INVITE Contact: sip:alice@[5555::1:2:3:4] Content-Type: application/sdp Content-Length: 159 [body] 2.3.1 Request-Line La request line è costituita da tre componenti: • Method – indica il tipo di richiesta; • Request URI – indirizzo SIP del destinatario della richiesta; CAPITOLO 2. PROTOCOLLO SIP 15 • Protocol version – versione del protocollo SIP utilizzato; la versione specificata in [9] è la 2.0. Il Method, può assumere i seguenti valori: • REGISTER – usato da un UAC per notificare il suo indirizzo IP e l’URL per il quale vuole ricevere chiamate; • INVITE – usato per instaurare una sessione multimediale; • ACK – usato per confermare l’avvenuto scambio di messaggi; • CANCEL – usato per cancellare una richiesta pendente, ovvero non ancora accettata; • BYE – usato per terminare una sessione multimediale; • OPTION – usato per richiedere informazioni relative alle capacità del terminale dell’utente chiamato, senza instaurare una sessione. Un esempio di request line è il seguente: INVITE sip:[email protected] SIP/2.0 Questo esempio, si riferisce ad un messaggio di tipo INVITE (definito nel Method), cioè destinato ad instaurare una comunicazione con il destinatario (definito nella Request URI). 2.3.2 Response-Line La response line è costituita da tre componenti: • Protocol version – identica alla request line; • Status code – codice di tre cifre che identifica il tipo di risposta; CAPITOLO 2. PROTOCOLLO SIP 16 • Reason phrase – testo libero per una descrizione più precisa dello status code. Lo status code è classificato in sei categorie: • 1XX – indica che la richiesta è stata ricevuta ed in fase di elaborazione; • 2XX – indica che la richiesta è stata ricevuta, processata e accettata; • 3XX – indica una redirezione della richiesta per ulteriori elaborazioni; • 4XX – indica un errore di sintassi nella richiesta; • 5XX – indica un errore da parte del server; • 6XX – indica un errore globale; la richiesta non può essere servita da nessun server. Un esempio di Response line, è il seguente: SIP/2.0 480 Temporarily Unavailable riferito ad una risposta di errore di tipo 480 (Status code) descritta dalla Reason phrase “Temporarily Unavailable”. 2.3.3 Headers Gli headers, contribuiscono ad aggiungere informazioni alla richiesta, come ad esempio, il mittente, il destinatario e gli identificatori degli utenti. Il formato di un header è il seguente: Header-name: header-value Alcuni headers sono obbligatori sia nelle richieste che nelle risposte: CAPITOLO 2. PROTOCOLLO SIP 17 • To header - To: SIP-URI(;parametri) – indica il nome del destinatario del messaggio; • From header - From: SIP-URI(;parametri) – indica il nome del mittente del destinatario; • Call-ID header - Call-ID: unique-id – identifica un messaggio all’interno di una sessione; • CSeq header - CSeq: digit method – identifica una risposta ad una precisa richiesta; • Via header - Via:SIP/2.0/[transport-protocol] sent-by(;parametri) – consente di instradare le risposte attraverso lo stesso percorso seguito dalla richiesta; • Max-Forwards header - Max-Forwards: digit – indica il numero massimo di nodi che il messaggio può attraversare prima di raggiungere la destinazione; • Contact header - Contact: SIP-URI(;parameters) – indica l’indirizzo (generalmente SIP), del mittente del messaggio. Dove appare (;parametri), significa che è possibile aggiungere alcuni parametri separati da punto e virgola. Un esempio di header SIP è il seguente: Via: SIP/2.0/UDP 192.168.0.101:5062 Questo header indica che il messaggio in cui è contenuto deve passare per il nodo 192.168.0.101 sulla porta 5062 utilizzando il protocollo UDP. CAPITOLO 2. PROTOCOLLO SIP 2.3.4 18 Corpo del messaggio Il corpo del messaggio può contenere qualsiasi tipo di informazione dipendentemente dal tipo di richiesta o risposta per cui il messaggio è stato generato. Nel nostro progetto, viene spesso inserito un documento XML contenente le informazioni di presenza. 2.3.5 SIP URI Il SIP URI, rappresenta l’indirizzo SIP con il quale è possibile raggiungere un terminale dell’utente. Esso ha la forma di un indirizzo e-mail: sip:[email protected] Il SIP URI può essere di due tipi: • Address Of Record (AOR) – è un indirizzo SIP che identifica un utente; è più facile da memorizzare, ed è quindi utilizzato principalmente dagli utenti umani e gestito in modo simile ad un numero telefonico; un esempio è sip:[email protected] in questa forma, l’indirizzamento del messaggio necessita di interrogazioni al server DNS per individuare l’indirizzo IP del dominio realm.com; • Fully Qualified Domain Name (FQDN) o indirizzo IP – identifica un dispositivo dell’utente; un esempio è sip:[email protected] in questa forma, l’indirizzamento del messaggio non necessita di interrogazioni al server DNS, in quanto l’indirizzo IP del dominio è specificato esplicitamente dopo il simbolo @. Capitolo 3 Presence Service 3.1 Introduzione Il concetto di presenza (Presence) ha potenziato i servizi di messaggistica istantanea, oggi diffusissimi in tutto il mondo per la loro capacità di far comunicare persone collocate geograficamente molto lontane tra loro. Il concetto di presenza può essere visto come la capacità di un utente di percepire lo stato di altri, cosı̀ come gli altri percepiscono quello dell’utente stesso. In altre parole un utente viene rappresentato da una insieme di informazioni che definiscono il suo stato, e quello dei dispositivi di comunicazione cui ha accesso. Tale stato contiene quindi informazioni come la locazione geografica dell’utente, il contesto in cui si trova (posizione fissa, in movimento, all’aperto, in ufficio, ecc.), le capacità comunicative dei terminali in suo possesso (se supportano sessioni voce, video, sms, di messaggistica istantanea, ecc.), il metodo di contatto preferito (via telefono cellulare, fax, computer dell’ufficio, ecc.), i servizi che l’utente è disposto ad utilizzare (servizi voce, video, di messaggistica istantanea, ecc.), le attività che sta svolgendo in un certo momento (riunione, guida, pranzo, ecc.), ed altre. Come definito in [10], in 19 CAPITOLO 3. PRESENCE SERVICE 20 definitiva, il servizio di presenza esprime la possibilità e la volontà dell’utente di comunicare attraverso un insieme di dispositivi. Il servizio di presenza, poggia sul modello publish/subscribe. Il modello publish/subscribe, è un paradigma di interazione che vede coinvolte due entità: produttori (publisher ) e consumatori (subscriber, o sottoscrittori). Consente ai sottoscrittori di esprimere i propri interessi verso un certo tipo di evento o un pattern di eventi, con lo scopo di essere successivamente notificati con eventi compatibili con gli interessi espressi. In altre parole, i produttori pubblicano informazioni su un canale di eventi e i sottoscrittori si sottoscrivono al canale per ricevere informazioni di loro interesse (figura 3.1). Figura 3.1: Modello Publish/Subscribe Il modello base del sistema per l’interazione publish/subscribe si basa su un servizio di notifica di eventi (event notification service, o più semplicemente event service), il quale memorizza e gestisce le sottoscrizioni e consegna gli eventi. L’event service funge da mediatore tra i publisher, che svolgono la funzione di produttori di eventi, e i subscriber, che svolgono la funzione di consumatori di eventi. I subscriber registrano i propri interes- CAPITOLO 3. PRESENCE SERVICE 21 si verso un certo tipo di evento attraverso la funzione subscribe() dell’event service, senza essere a conoscenza dell’effettiva sorgente dell’evento. Seguendo questo modello, il servizio di presenza, consente ad un utente di far sapere, a chiunque voglia, come e quando essere contattato semplicemente pubblicando il proprio stato, che viene poi ricevuto dagli altri utenti. Alice può, ad esempio, pubblicare un messaggio che specifica su quali dispositivi può essere contattata in quel momento (telefono cellulare, computer dell’ufficio, ecc.); Bob, che vuole contattare Alice, riceve le sue informazioni di presenza, e valuta in che modo contattarla (se Alice è disponibile). Il concetto di presenza si concretizza quindi in un profilo dinamico dell’utente visibile ad altri, e in grado di rappresentare sé stesso, condividere informazioni e controllare servizi. Il servizio di presenza può essere utilizzato da chiunque, sia esso un informatico, un impiegato, un cuoco, un anziano o un bambino. Si presta a diverse applicazioni, e non solo al servizio di messaggistica istantanea per cui è stato originariamente pensato, ma anche, ad esempio, ai servizi che offrono la possibilità di videogiocare in rete, o ai servizi che consentono di incrementare l’efficienza sul lavoro. Il servizio di presenza rappresenta inoltre un business non sottovalutabile per i fornitori di servizi, che possono contare quindi su un’importantissima funzionalità aggiuntiva per rendere le loro offerte più complete e accattivanti. I fornitori di servizi possono, infatti, contare su un supporto base di molti servizi. Pensiamo, ad esempio, al servizio di messaggistica istantanea: un utente deve sapere se può avviare una sessione di messaggistica istantanea con un altro utente, e quindi deve essere a conoscenza dello stato di presenza relativo al servizio di instant messaging. Disporre del servizio di presenza rappresenta perciò, per il fornitore, la base per poter offrire un servizio di messaggistica istantanea. Pensando poi CAPITOLO 3. PRESENCE SERVICE 22 a nuovi servizi, possiamo immaginare l’implementazione di un meccanismo di segnalazione di emergenze: un utente in difficoltà, premendo un semplice tasto sul telefono cellulare, è in grado, senza parlare, di informare i soccorsi fornendo le sue coordinate geografiche. Anche per un servizio di questo tipo, la base implementativa sta nel servizio di presenza, che è in grado di ricevere le coordinate geografiche dell’utente e notificarle ai soccorsi. Risulta chiaro che questi servizi aggiuntivi che poggiano sul servizio di presenza possono avvantaggiare un fornitore sugli altri, oltre ad incrementare il traffico tariffabile all’interno della rete. Il nostro progetto si concentra proprio sul servizio di presenza per aggiungervi QoS. Come descritto in [5] esistono due tipi di utilizzatori non esclusivi (cioè un utilizzatore può essere di entrambi i tipi): • presentity: chi fornisce le proprie informazioni di presenza per essere memorizzate e distribuite; • watcher : chi richiede e riceve le informazioni di presenza riguardanti altri utenti e servizi. Le informazioni di presenza possono essere costruite direttamente dal presentity o prelevate da dispositivi esterni come PC, cellulari, sensori, antenne GPS, ecc. (figura 3.2). Di questo si parlerà nel paragrafo 3.2. CAPITOLO 3. PRESENCE SERVICE 23 Figura 3.2: Relazione tra presentity e watcher La figura, mostra un possibile reperimento di informazioni di presenza da antenne e sensori. Notiamo che il modello segue il modello publish/subscribe sopra descritto. Le molte informazioni di presenza che un presentity può fornire, possono essere difficili da gestire per un watcher, in quanto errate, contraddittorie o ridondanti. Un utente umano è in grado di risolvere questi problemi analizzando le informazioni ricevute, ma un utente costituito da un’applicazione software può scontrarsi con molte difficoltà. Questi problemi saranno trattati nel paragrafo 3.4. Il protocollo utilizzato dal servizio di presenza è il SIMPLE (Session initiation protocol for Instant Messaging and Presence Leveraging Extensions), standard gestito dalla IETF. Il formato generale delle informazioni di presenza è descritto in [10] ed è rappresentato da un documento XML diviso in tuple, ognuna delle quali contiene informazioni riguardanti l’utente umano, i servizi utilizzati per comunicare e i dispositivi di cui l’utente è in possesso. Tutto questo sarà trattato nel paragrafo 3.3. CAPITOLO 3. PRESENCE SERVICE 3.2 24 Sorgenti delle informazioni di presenza Come descritto in [12], le informazioni di presenza possono essere ricavate da sorgenti esterne. Possiamo classificare i dati di presenza nelle seguenti categorie: • segnalati in tempo reale, sono forniti dal presentity in tempo reale, ma sono considerati poco attendibili col passare del tempo in quanto l’utente potrebbe avere difficoltà ad aggiornare costantemente le informazioni; • segnalati in modo pianificato, consistono nelle informazioni che vengono aggiornate automaticamente in base alla pianificazione dei propri impegni da parte dell’utente utilizzando applicazioni come il calendario elettronico. L’affidabilità di queste informazioni dipende dalla scrupolosità dell’utente nell’aggiornare i propri calendari e sorgenti simili; • ricavati dall’utilizzo di un dispositivo, sono dedotti dall’impiego di dispositivi di comunicazione come l’atto di inoltrare o ricevere una chiamata o dalla potenza del segnale di un cellulare. In questo caso la principale motivazione di errore può essere data dal fatto che l’utilizzatore potrebbe non corrispondere alla persona della quale si vogliono pubblicare le informazioni; • ricavati da sensori, sono estrapolati da sensori e consistono in informazioni come la posizione geografica, il tipo di ambiente (abitazione, automobile, ecc.), l’attività dell’utente, ecc. Esempi di sensori sono il GPS o segnalazioni Bluetooth che indicano il tipo di ambiente circostante. Il vantaggio dei sensori è che non fanno affidamento sull’ag- CAPITOLO 3. PRESENCE SERVICE 25 giornamento delle informazioni da parte dell’utente, ma sono soggetti ad errori di misurazione. Ad esempio un sensore PIR (Passive InfraRed sensor), può rilevare la presenza di un soggetto in ufficio, ma non accertare se si tratta della persona interessata o dell’addetto alle pulizie. Un sensore GPS non può rilevare se il cellulare è utilizzato dal suo proprietario o da qualcun altro; • dedotti indirettamente da una sorgente di informazioni, ad esempio non interessa se l’utente è in macchina (informazione ricavata da un sensore), ma il fatto che sta guidando (informazione dedotta). I dati, una volta acquisiti, vengono incapsulati nel corpo del messaggio di presenza (vedere paragrafo 3.3) ed inviati al Presence Server per la pubblicazione. 3.3 Standard per protocolli di presenza: SIMPLE SIMPLE (Session initiation protocol for Instant Messaging and Presence Leveraging Extensions) è un protocollo standard basato su SIP e utilizzato per la messaggistica istantanea e per il servizio di presenza. SIMPLE estende il protocollo SIP per adattarlo alle esigenze del servizio di presenza. Sostanzialmente aggiunge una nuova tipologia di evento denominata presence. Il documento [7], individua due tipi di entità per il servizio di presenza: • Presence Agent (PA), il quale è in grado di memorizzare le sottoscrizioni e generare le notifiche; CAPITOLO 3. PRESENCE SERVICE 26 • Presence User Agent (PUA), il quale manipola e pubblica le informazioni di presenza per un presentity. Il processo di pubblicazione, è consentito dall’esistenza del metodo PUBLISH, mentre per potersi registrare al servizio di presenza di un certo utente per poterne ricevere le notifiche, si ricorre al metodo SUBSCRIBE. Il corpo del messaggio NOTIFY, contiene, invece, le informazioni di presenza riguardanti il presentity che le vuole pubblicare. Grazie all’esistenza del MIME (Multipurpose Internet Mail Extension), che offre la possibilità di inserire nel corpo del messaggio diversi tipi di dati, è possibile codificare le informazioni di presenza utilizzando il linguaggio XML (eXtensible Markup Language). All’interno dell’evento presence, esiste un sottoevento denominato winfo (watchers informations) che viene identificato come presence.winfo. Questo evento, consente, ad un presentity, di ricevere informazioni circa lo stato dei watchers a lui sottoscritti. In particolare, se un presentity si sottoscrive all’evento presence.winfo, riceve le informazioni riguardanti lo stato dei watchers a lui sottoscritti e quelle riguardanti l’evento che ha causato la modifica dello stato. Gli stati che un watcher può assumere nei confronti di un presentity non sono gli stessi che possono essere pubblicati da un generico presentity, ma sono differenti in quanto hanno lo scopo di descrivere l’attività del watcher all’interno del servizio di presenza. Un presentity, può decidere di limitare la consegna delle notifiche relative al proprio stato, soltanto a determinati watcher. Un presentity ha quindi la possibilità di creare delle regole (o policy) che hanno il compito di determinare chi può sottoscriversi al servizio di presenza del presentity stesso. Ad esempio, Alice può negare il recapito a Bob delle notifiche relative al proprio stato, ma consentirlo a John. Ogni watcher, assume quindi uno stato nei confronti di Alice. Tali CAPITOLO 3. PRESENCE SERVICE 27 stati sono descritti in [8] e sono i seguenti: • Init: nessuno stato del watcher disponibile. Init è uno stato transitorio, che viene assunto dal watcher nel momento della sottoscrizione al servizio di presenza del presentity, poi verrà assunto lo stato in funzione delle regole esistenti; • Terminated : esiste una regola che vieta al watcher di sottoscriversi al servizio di presenza del presentity; • Active: esiste una regola che consente al watcher di sottoscriversi al servizio di presenza del presentity e ricevere le notifiche di cambiamento del suo stato; • Pending: non esiste nessuna regola definita per il watcher che resta, quindi, in attesa della creazione di una politica di accesso ad esso associata; • Waiting: simile al Pending, ma indica che un utente ha cercato di sottoscriversi al servizio di presenza del presentity e che tale sottoscrizione è scaduta prima che venisse creata una regola. In ogni momento il server di presenza può decidere di chiudere una sottoscrizione in stato di Pending o Waiting per liberare le proprie risorse interne, quali memoria e CPU. Riprendendo l’esempio precedente, Bob entra nello stato Terminated, mentre John nello stato Active. Il diagramma degli stati che un watcher può assumere, è riportato in figura 3.3. CAPITOLO 3. PRESENCE SERVICE 28 Figura 3.3: Diagramma degli stati dei watcher La figura, mostra i motivi per cui un watcher può cambiare stato. Al momento della sottoscrizione, un watcher entra nello stato Init. Se esiste una regola (policy), il watcher assume lo stato da questa imposto, ovvero Active se esiste una regola che consente al watcher di essere notificato sullo stato del presentity, oppure Terminated se esiste una regola che nega il recapito delle notifiche a quel preciso watcher. Se non esiste nessuna policy, il watcher assume lo stato di Pending, e vi resta fino a che non viene creata una regola che accetta o scarta il watcher. Il watcher non può, però, restare nello stato di Waiting all’infinito, quindi, se dopo un determinato periodo di tempo non è ancora stata creata nessuna regola, passa nello stato di Waiting, per poi passare nello stato di Terminated. Lo stato di Waiting, ha quindi lo scopo di avvertire che la sottoscrizione è scaduta prima che sia stata accettata o rifiutata esplicitamente dal presentity. Le sottoscrizioni, hanno un determinato periodo di validità, al termine del quale il watcher passa dallo stato Active, allo stato di Terminated. CAPITOLO 3. PRESENCE SERVICE 3.3.1 29 Metodi PUBLISH, SUBSCRIBE e NOTIFY Come anticipato nel paragrafo precedente, per poter pubblicare il proprio stato è necessario ricorrere al metodo SIP PUBLISH definito all’interno di SIMPLE. Il procedimento di pubblicazione prevede una singola richiesta di PUBLISH e una singola risposta che informa il mittente del successo o fallimento della procedura. L’utente al quale si riferisce la pubblicazione è specificato nella Request URI, mentre le informazioni di presenza sono inserite nel corpo del messaggio SIP. Il metodo SUBSCRIBE consente ad un utente di sottoscriversi al servizio di presenza di un altro utente, in modo da poter ricevere le successive notifiche circa il suo cambiamento si stato. Anche la procedura di SUBSCRIBE prevede l’invio di una richiesta e la ricezione di una risposta, con lo scopo di informare il mittente sull’esito dell’operazione. Il messaggio di risposta può essere positiva (la sottoscrizione è andata a buon fine) o negativo (la sottoscrizione è fallita). La sottoscrizione al servizio di presenza, ha una durata limitata e deve quindi essere rinnovata prima della sua scadenza. Per cancellare una sottoscrizione prima della sua scadenza, è necessario inviare un messaggio di SUBSCRIBE contenente l’header Expires uguale a zero. Il metodo NOTIFY viene ricevuto dall’utente che si è sottoscritto ad un servizio di presenza, e ha lo scopo di notificare il cambiamento di stato da parte dell’utente osservato. Le informazioni di stato, sono contenuto all’interno del corpo del messaggio in formato XML. Alla ricezione del messaggio NOTIFY, il client deve rispondere con un messaggio di conferma, per avvertire la sorgente (tipicamente un presence server) dell’avvenuta ricezione. CAPITOLO 3. PRESENCE SERVICE 3.3.2 30 Presence Information Data Format Le informazioni di presenza vengono codificate in linguaggio XML per essere facilmente trasmesse ed elaborate dai vari organi della rete. Il documento XML è strutturato in elementi definiti dal Presence Information Data Format (PIDF) [13] che è poi stato esteso dal Rich presence extensions to the Presence Information Data format (RPID) [11]. I principali elementi predefiniti sono: • presence: è l’elemento radice. Contiene un attributo entity il cui valore rappresenta l’URI del presentity che pubblica il documento. Deve specificare il namespace di default urn:ietf:params:xml:ns:pidf ; • tuple: rappresenta un servizio. Deve contenere un attributo id il cui valore differenzia un elemento tuple dagli altri all’interno dello stesso presentity. Deve inoltre contenere l’elemento status e può contenere gli elementi contact, note, timestamp ed altri elementi di estensione; • status: può contenere un elemento basic e una serie di altri elementi di estensione. • basic: può contenere la stringa open o closed per indicare se il contatto associato è raggiungibile o meno. • contact: è opzionale e definisce un indirizzo al quale poter contattare il presentity; • note: contiene una stringa qualsiasi che serve soltanto all’utente umano; • timestamp: contiene la data e l’ora in cui l’elemento padre è stato modificato; CAPITOLO 3. PRESENCE SERVICE 31 • person: descrive le caratteristiche di un utente umano. Deve contenere un attributo id che lo identifica dagli altri elementi person. Può contenere più elementi note e un elemento timestamp; • device: descrive le caratteristiche di un terminale in possesso del presentity. Deve contenere un attributo id che lo identifica dagli altri elementi device all’interno dello stesso presentity. Deve contenere un elemento deviceID. Può contenere una serie di elementi note, un elemento timestamp ed altri elementi di estensione; • deviceID: contiene una stringa identificativa del dispositivo in questione (ad esempio il codice seriale). Un esempio di codifica XML delle informazioni di presenza è il seguente: <?xml version="1.0" encoding="UTF-8"?> <presence xmlns="urn:ietf:params:xml:ns:pidf" entity="sip:[email protected]"> <tuple id="sg89ae"> <status> <basic>open</basic> </status> <contact>tel:+39012345678</contact> </tuple> <tuple id="rt62yp"> <status> <basic>closed</basic> </status> <contact>tel:+39087654321</contact> </tuple> CAPITOLO 3. PRESENCE SERVICE 32 <device id="pc147"> <user-input last-input="2009-09-08T13:20:00-05:00"> idle <\user-input> <deviceID>urn:device:0003ba4811e3<\deviceID> <note>PC<\note> </device> </presence> Notiamo che l’elemento presence contiene l’attributo che definisce il namespace del documento: xmlns="urn:ietf:params:xml:ns:pidf" inoltre è presente un altro attributo obbligatorio: entity="pres:[email protected]" che definisce l’entità cui appartengono le informazioni di presenza. Il valore di tale attributo è solitamente un Public User Identity dell’utente. Gli elementi tuple contengono entrambi l’attributo obbligatorio id che permette di identificarli e distinguerli l’uno dall’altro. L’elemento tuple descrive lo stato di un servizio, quindi possiamo concludere che il servizio identificato dalla stringa “sg89ae” per l’utente “sip:[email protected]” è disponibile (open), e raggiungibile componendo il numero di telefono “+39012345678” (campo contact). Al contrario, il servizio identificato dalla stringa “rt62yp”, raggiungibile al numero telefonico “+39087654321”, non è al momento disponibile (closed). Proseguiamo analizzando la sezione device: l’utente dispone di un dispositivo il cui id è rappresentato dalla stringa “urn:device:0003ba4811e3” CAPITOLO 3. PRESENCE SERVICE 33 contenuta nell’elemento deviceID. Notiamo che l’elemento device è identificato dalla stringa “pc147” per differenziarlo da eventuali altri elementi device inseribili nel documento XML. Dall’elemento note, un utente umano può dedurre che il dispositivo in questione è un PC; l’elemento note, come già detto, ha l’unico scopo di aggiungere informazioni comprensibili soltanto da un utente umano. Il PC non è attualmente utilizzato, come si può dedurre dal contenuto dell’elemento user-input, che indica lo stato di utilizzo del dispositivo a cui è associato. L’ultima volta che il PC è stato utilizzato è in data 2009-09-08 alle ore 13:20:00. 3.4 Gestione dei conflitti delle informazioni Come già accennato, un presentity può pubblicare le proprie informazioni di presenza in diversi modi e attraverso dispositivi differenti, generando cosı̀ possibili conflitti di informazioni. Ad esempio, l’auto di Alice dispone di un sensore che, quando rileva la presenza di una persona alla guida, pubblica automaticamente lo stato di non disponibilità di Alice a ricevere telefonate. Supponiamo che Bob, marito di Alice, prenda in prestito l’auto della moglie e, contemporaneamente, Alice pubblichi la sua disponibilità a ricevere telefonate: a questo punto Alice è rintracciabile o no? Generalmente i conflitti di informazioni possono essere di varia natura, e il primo passo da eseguire per rimuovere le informazioni inaccurate consiste nell’individuare tali conflitti. Come visto nel paragrafo precedente, lo stato di un utente può essere rappresentato da numerosi elementi, alcuni dei quali possono contraddirsi a vicenda. Ad esempio, una persona non può essere in due luoghi differenti nello stesso momento, quindi, se due elementi place-is hanno valori diversi, significa che uno dei due è errato. Per altri tipi di infor- CAPITOLO 3. PRESENCE SERVICE 34 mazione che vengono prelevati automaticamente da sorgenti esterne, i valori che possono assumere potrebbero, in certi casi, essere esclusivi. Ad esempio, l’elemento place-type non può assumere contemporaneamente i valori “office” e “outdoors”, ma potrebbe assumere i valori “outdoors” e “stadium”. La difficoltà sta quindi nel capire quando un elemento assume valori contraddittori o soltanto differenti nella loro specificità. Quando viene rilevato un conflitto bisogna prendere una decisione per gestirlo in modo adeguato. In alcuni casi non deve essere effettuata nessuna azione, ad esempio non è dato sapere quali valori sono in conflitto per gli elementi activities o mood, a causa dei molteplici valori che possono assumere. Un approccio conservativo per gestire alcuni conflitti, potrebbe essere semplicemente listare tutti i valori. In questi casi, vengono presentati al watcher versioni multiple dello stesso elemento e starà quindi a lui il compito di determinare quello corretto. Per limitare il numero di informazioni recapitate al watcher si può scegliere un solo valore escludendo tutti gli altri. Per prendere questa decisione, si può procedere in modi differenti: • scegliere il valore dell’elemento più recente: si tratta di optare per il valore pubblicato più di recente. In questo caso, si rischia di scartare un valore corretto e mantenere quello errato; • scegliere l’elemento più affidabile: l’affidabilità può essere basata sull’identità della sorgente, come ad esempio il cellulare dell’utente. In alternativa si può dare un ordine di fiducia ai tipi di sorgente delle informazioni, ad esempio, “segnalati in tempo reale”, “ricavati dall’utilizzo di un dispositivo”, “ricavati da sensori”, “segnalati in modo pianificato”; • scegliere in base al valore di un altro elemento: gli altri elementi potreb- CAPITOLO 3. PRESENCE SERVICE 35 bero indicare un valore che potrebbe essere più affidabile. Ad esempio, l’elemento user-input, potrebbe indicare che un dispositivo che fornisce indicazioni di presenza è attualmente in uso e un altro no. I valori che non vengono scelti, vengono definitivamente scartati. [12] Il meccanismo per risolvere i conflitti di informazione viene implementato all’interno del Presence Server. Nel nostro progetto viene utilizzato il Presence Server Kamailio, il quale risolve i conflitti scegliendo, per ogni elemento, il valore pubblicato più recentemente. 3.5 Metodi per l’utilizzo del servizio di presenza In questo paragrafo viene illustrato il contenuto dei metodi utilizzati per sfruttare il servizio di presenza. Sono illustrati i metodi PUBLISH, SUBSCRIBE e NOTIFY. SUBSCRIBE e NOTIFY In figura 3.4 è raffigurato il processo di sottoscrizione da parte di un watcher (Bob) al servizio di presenza relativo ad un presentity (Alice). Bob si sottoscrive al servizio di presenza relativo ad Alice inviando un messaggio di tipo SUBSCRIBE al Presence Server (PS). Quest’ultimo accetta la sottoscrizione rispondendo con un messaggio di tipo 200 OK per indicare a Bob che la richiesta è stata ricevuta e processata con successo. Il Presence Server provvede ad inviare subito a Bob un messaggio di tipo NOTIFY contenente le informazioni di presenza di Alice in suo possesso. CAPITOLO 3. PRESENCE SERVICE 36 Figura 3.4: Processo di SUBSCRIBE Bob risponde con un messaggio di tipo 200 OK per confermare la ricezione del messaggio NOTIFY. Il messaggio di SUBSCRIBE è cosı̀ formato: SUBSCRIBE sip:[email protected] SIP/2.0 Via: SIP/2.0/UDP host.example.com;branch=z9hG4bKnashds7 To: <sip:[email protected]> From: <sip:[email protected]>;tag=12341234 Call-ID: [email protected] CSeq: 1 SUBSCRIBE Max-Forwards: 70 Expires: 3600 Event: presence Content-Length: 0 CAPITOLO 3. PRESENCE SERVICE 37 Descriviamo brevemente il contenuto del messaggio. Nella prima riga (Request-Line) compaiono il metodo (SUBSCRIBE), la Request URI (sip:[email protected]) e la versione del protocollo (SIP/2.0). I successivi campi del messaggio sono gli headers, necessari per aggiungere informazioni di servizio al messaggio. L’header To contiene l’URI del presentity a cui il watcher vuole sottoscriversi, mentre l’header From contiene l’URI del mittente (watcher nel caso di messaggi SUBSCRIBE). Altro header importante è Event, il quale contiene l’indicazione del tipo di servizio al quale Bob vuole sottoscriversi. Gli header Via (possono essercene anche molti) tengono traccia del percorso che il messaggio effettua per arrivare a destinazione e che dovrà essere seguito (a ritroso) dai futuri messaggi di risposta. Infine descriviamo l’header Expires, che informa circa il periodo di validità della sottoscrizione: il valore 3600 indica che per i prossimi 3600 seondi Bob riceverà notifiche riguardanti i cambiamenti di stato di Alice, dopodiché la sottoscrizione scadrà e Bob dovrà rinnovarla. Questo header, se settato a 0, indica al Presence Server che il mittente non vuole più ricevere notifiche riguardanti il servizio di presenza circa il presentity specificato nella Request-Line. PUBLISH In figura 3.5 è raffigurato il processo di sottoscrizione da parte di un watcher (Bob) al servizio di presenza relativo ad un presentity (Alice). Alice pubblica le proprie informazioni di presenza inviando un messaggio di tipo PUBLISH al Presence Server (PS), il quale conferma la ricezione della richiesta rispondendo con un messaggio di tipo 200 OK. CAPITOLO 3. PRESENCE SERVICE 38 Figura 3.5: Processo di PUBLISH Il messaggio di PUBLISH è cosı̀ formato: PUBLISH sip:[email protected] SIP/2.0 Via: SIP/2.0/UDP pua.example.com;branch=z9hG4bK652hsge To: <sip:[email protected]> From: <sip:[email protected]>;tag=1234wxyz Call-ID: [email protected] CSeq: 1 PUBLISH Max-Forwards: 70 Expires: 3600 Event: presence Content-Type: application/pidf+xml Content-Length: ... [Published PIDF document] Notiamo che gli headers To e From contengono entrambi l’URI di Alice, ovvero del presentity che pubblica il messaggio. Gli header Event e Expires e Via hanno significati analoghi a quelli degli stessi header contenuti nel messaggio di SUBSCRIBE. CAPITOLO 3. PRESENCE SERVICE 39 L’Header Content-Type indica il tipo di contenuto del corpo del messaggio; essendovi contenuto un testo XML con struttura adeguata al servizio di presenza, il valore di tale header è application/pidf+xml. L’header Content-Lenght specifica la lunghezza in byte del corpo del messaggio. Capitolo 4 Tecnologie utilizzate Di seguito vengono introdotte le principali tecnologie utilizzate all’interno del progetto. 4.1 Presence Server Kamailio Questo progetto ha lo scopo di estendere il servizio di presenza offerto da un Presence Server introducendo Load Balancing. Come Presence Server è stato scelto Kamailio (OpenSER) [3] per la sua completezza e solidità. In realtà, OpenSER è un progetto che si pone l’obiettivo di realizzare un software completo per l’implementazione di un sistema basato su protocollo SIP, ovvero un SIP server. Esso è scritto in linguaggio C, ed è estensibile per consentire l’aggiunta di moduli atti ad implementare nuovi servizi. OpenSER ha cambiato nome nel 2008 a causa di alcuni conflitti di interesse, diventando Kamailio. Alcune funzionalità di Kamailio sono: • SIP registrar server • SIP Location server 40 CAPITOLO 4. TECNOLOGIE UTILIZZATE 41 • SIP Proxy server • SIP Application server • SIP Dispatcher server; • SIMPLE Presence Server (rich presence) • Presence User Agent • supporto a XCAP • Instant Messaging e molte altre. Come già anticipato, Kamailio è strutturato in moduli, ognuno dei quali implementa funzionalità specifiche ai fini di integrare più servizi in un unico server. Ogni modulo è indipendente dagli altri e sta a noi scegliere come configurare l’istanza di Kamailio perchè carichi i moduli necessari ad offrire i servizi che vogliamo. I passi per configurare Kamailio sono riportati in appendice A. Per questo progetto ci siamo concentrati sul modulo di presenza, denominato appunto presence e scritto interamente in linguaggio C. 4.2 JAIN-SIP JAIN (Java in Advanced Intelligent Networks) è una comunità di aziende creata con lo scopo specifico di definire delle API [1] per raggiungere la portabilità dei servizi, convergenza e accessi sicuri verso reti telefoniche e dati (Internet). Si basa esclusivamente sulla tecnologia Java, ed anche il suo CAPITOLO 4. TECNOLOGIE UTILIZZATE 42 sviluppo segue le specifiche di sviluppo e licenza SUN (JSPA Java Specification Participation Agreement, JCP Java Community Process, SCSL Sun Community Source Code Licensing). JAIN si occupa di definire due diverse serie di API riguardo le NGN: API verso i protocolli e API verso le applicazioni. Le prime specificano le interfaccie verso i protocolli di reti IP, wireless e telefoniche; le seconde vengono utilizzate per la creazione di servizi fornendo un framework java per l’utilizzo dei protocolli che sono gestiti dal primo gruppi di API. L’API JAIN SIP [2] fornisce un’interfaccia Java standard e portabile per condividere informazioni tra client SIP e server SIP, mettendo a disposizione funzionalità per il controllo delle chiamate e quindi fornendo un’infrastruttura per lo sviluppo di applicazioni su reti convergenti. Questa API permette la creazione rapida e l’attivazione di servizi dinamici di telefonia all’interno di piattaforme Java. Le applicazioni di telefonia hanno bisogno di risorse costose per il loro sviluppo, le prove a la messa in funzione. Un componente JAIN SIP può essere creato rapidamente, provato e integrato in una gran varietà di piattaforme avendo a già disposizione un buon numero di strumenti e utility. Una soluzione inter piattaforma basata su JAIN offre ai gestori telefonici, ai fornitori di servizi e di componenti di rete, un ambiente di sviluppo aperto e consistente dove sviluppare e integrare servizi di telefonia altamente riutilizzabili. Un’applicazione JAIN SIP può essere scritta come programma, applet, servlet o bean. Le API mettono a disposizione le potenzialità presenti nelle diverse versioni di SIP in un’interfaccia Java comune. JAIN SIP non fornisce l’implementazione dello stack SIP, ma si occupa soltanto di fornire un’interfaccia standard. Nella figura 4.1 è visibile la struttura di una generica applicazione che si CAPITOLO 4. TECNOLOGIE UTILIZZATE 43 basa su questa API, in particolare vengono gestiti tutti gli aspetti relativi alla comunicazione attraverso SIP, come ad esempio la risposta alle richieste che arrivano al programma, attraverso opportune interfacce che gestiscono gli eventi relativi ai vari eventi SIP (come l’arrivo di richieste o di risposte, o la scadenza di timeout), o la creazione e gestione degli indirizzi, messaggi ed elementi del pacchetto SIP. Figura 4.1: Schema di un’applicazione JAIN-SIP Capitolo 5 Soluzione del progetto 5.1 Introduzione La soluzione proposta per raggiungere gli obiettivi specificati nel paragrafo 1.1, consiste nella realizzazione di un client sviluppato in linguaggio Java utilizzando le API JAIN SIP [2], e nella modifica di alcune parti del modulo di presenza presence integrato in Kamailio. Topologia della rete di riferimento Per lo sviluppo di questo progetto, facciamo riferimento ad una ben definita rete di nodi sui quali girano diverse istanze del presence server Kamailio opportunamente configurate. I vari nodi della rete dovranno comunicare tra loro per sincronizzarsi, garantendo cosı̀ la possibilità di accesso al servizio di presenza in ambienti distribuiti nei quali presentity e watcher afferiscano a server diversi. Altro scopo della sincronizzazione, è quello di bilanciare il carico degli utenti utilizzando le informazioni che ogni nodo è in grado di raccogliere. (figura 5.1). 44 CAPITOLO 5. SOLUZIONE DEL PROGETTO 45 Figura 5.1: Sistema Client SIP Il client SIP è stato sviluppato in linguaggio Java utilizzando la tecnologia JAIN SIP già citata nel paragrafo 4.2. Tale client implementa le funzionalità di base per l’utilizzo del servizio di presenza, il quale è offerto da una rete di presence server Kamailio. Modifiche al modulo di presenza presence Il modulo di presenza presence integrato in Kamailio realizza le funzionalità necessarie per offrire il servizio di presenza, ed è il cuore del nostro progetto. Modificando tale modulo, è possibile sviluppare un meccanismo di bilanciamento del carico di lavoro in modo che le varie richieste entranti vengano smistate su più nodi della rete dediti a fornire il servizio di presenza. Il primo passo da affrontare per realizzare una soluzione funzionante che soddisfi gli obiettivi preposti, consiste nello studio del funzionamento CAPITOLO 5. SOLUZIONE DEL PROGETTO 46 del modulo di presenza integrato in Kamailio. Tale modulo è suddiviso in sottomoduli, ognuno dei quali implementa un sottoinsieme ben preciso di funzionalità. Le nostre modifiche coinvolgono il processo di gestione delle richieste di pubblicazione e quello di gestione delle richieste di sottoscrizione. In particolare è necessario introdurre un controllo della frequenza di arrivo delle richieste e del numero di watcher presenti sul presene server. Nel caso in cui la frequenza di arrivo delle richieste di pubblicazine sia troppo elavata, il presence server rifiuta la pubblicazione comunicandolo al client che potrà gestire l’errore a suo piacimento, ad esempio inoltrando la richiesta ad un altro presence server. Come già illustrato, all’arrivo di un messaggio di PUBLISH da parte di un presentity, il presence server inoltra un messaggio di tipo NOTIFY a tutti i watcher sottoscritti al servizio di presenza di quel presentity. Questo meccanismo può congestionare il server nel caso in cui un presentity abbia un gran numero di sottoscritti o nel caso in cui pubblichi informazioni troppo frequentemente; si rivela quindi necessario gestire questi due casi. La soluzione proposta prevede un controllo sulla frequenza di pubblicazione del presentity ed il numero di watcher che vogliono sottoscriversi al servizio di presenza di un certo utente. Nel caso in cui un presentity pubblichi informazioni molto frequentemente, il presence server evita di attuare il processo di notifica a tutti i sottoscrittori per ogni pubblicazione ricevuta, ma lo attua soltanto ad intervalli prestabiliti, riducendo cosı̀ il numero di notifiche generate. Qualora un utente voglia sottoscriversi al servizio di presenza relativo ad un presentity che conta già molti sottoscritti, la richiesta viene rifiutata dal server, il quale provvede a rispondere al client richiedente con un messaggio che CAPITOLO 5. SOLUZIONE DEL PROGETTO 47 gli indica uno stato di temporanea indisponibilità del servizio presso il server stesso. Questo ha lo scopo di evitare che, all’arrivo di un aggiornamento di stato da parte di un presentity, il server debba notificare una quantità di watcher molto elevata, cosa che potrebbe portare ad uno stato di congestione del server stesso e del canale di comunicazione. Il nostro sistema dispone di più nodi interconnessi tra loro, che offrono un servizio di presenza a tutti i client. Da questo, nasce il problema della decentralizzazione delle informazioni pubblicate su nodi differenti. Per ovviare a questo inconveniente, la nostra soluzione prevede la configurazione delle istanze di Kamailio in esecuzione, in modo che tutte si interfaccino ad un database centralizzato che contiene le varie informazioni utili ad attuare il servizio da offrire. In questo modo tutti i presence server sono a conoscenza delle ultime informazioni pubblicate da ciascun presentity, e ognuno può attuare il processo di notifica a tutti i watcher sottoscritti a quel presentity presso il server stesso. Ogni server, all’arrivo di una pubblicazione da parte di un presentity, deve, inoltre, avvisare tutti gli altri server del sistema sull’avvenuta pubblicazione di nuove informazioni da parte di quel preciso presentity, in modo che ognuno possa notificare l’evento a tutti i propri sottoscrittori. Abbiamo, quindi, una centralizzazione delle informazioni di presenza per ogni presentity, ed una distribuzione dei sottoscrittori sui vari nodi del sistema. La soluzione prevede, inoltre, la distribuzione, sui vari nodi, del carico di lavoro portato dalla gestione di una pubblicazione di informazioni (figura 5.2). CAPITOLO 5. SOLUZIONE DEL PROGETTO 48 Figura 5.2: Sistema con database centralizzato Per l’installazione e la configurazione del modulo di presenza modificato, si rimanda all’appendice B 5.2 Client SIP Il client SIP è stato sviluppato in linguaggio Java utilizzando la tecnologia JAIN SIP. Il client deve: CAPITOLO 5. SOLUZIONE DEL PROGETTO 49 • sottoscriversi al servizio di presenza presso un presence server; • pubblicare informazioni di presenza presso un presence server; • ricevere notifiche da uno o più presence server; • eventualmente, ridirezionare le sue richieste di sottoscrizione e pubblicazione su presence server differenti in caso di indisponibilità di quello scelto. In figura 5.3 è riportata una schermata del client. Figura 5.3: Sistema Il client è munito di: • una text area (Received Messages) nel quale vengono visualizzati tutti i messaggi ricevuti dai presence client; • una text field (Set status) in cui settare il proprio stato; CAPITOLO 5. SOLUZIONE DEL PROGETTO 50 • una text field (From) in cui viene visualizzato il proprio indirizzo sip; • una text field (To) in cui specificare l’indirizzo sip del contatto a cui ci si vuole sottoscrivere; • una combo box (PS ) in cui selezionare il presence server a cui inoltrare la richiesta. Esaminiamo ora il comportamento del client a seguito dei vari comandi impartiti dall’utente, ed in particolare le azioni di PUBLISH, SUBSCRIBE e UNSUBSCRIBE. 5.2.1 PUBLISH Premendo il pulsante Pub del client, l’applicazione invia un messaggio SIP di tipo PUBLISH al presence server specificato nella combo box PS. Nel caso in cui il server risponda con un messaggio di errore, il client provvede ad inoltrare automaticamente il messaggio di PUBLISH ad un presence server differente che, se non è in uno stato critico di possibile sovraccarico, accetta e gestisce adeguatamente la richiesta (figura 5.4). CAPITOLO 5. SOLUZIONE DEL PROGETTO 51 Figura 5.4: Richiesta di PUBLISH Nel caso in cui tutti i server siano indisponibili, il client interrompe l’invio automatico delle richieste e mostra un avviso all’utente. 5.2.2 SUBSCRIBE e UNSUBSCRIBE Analogamente a quanto avviene per la pubblicazione, premendo il pulsante Sub del client si avvia il processo di sottoscrizione. L’applicazione inoltra un messaggio di SUBSCRIBE verso il presence server selezionato nella combo box PS e relativo al presentity specificato nella text field To e, se il server non è disponibile, invia automaticamente la richiesta ad un altro nodo (figura 5.5). CAPITOLO 5. SOLUZIONE DEL PROGETTO 52 Figura 5.5: Richiesta di SUBSCRIBE Il processo di UNSUBSCRIBE scatenato dalla pressione del pulsante UnSub, provvede ad inviare una richiesta di SUBSCRIBE con header Expires a 0 (cancellazione della sottoscrizione) verso il presence server selezionato nella combo box PS e relativo al presentity specificato nella text field To. Nel caso in cui tutti i server siano indisponibili, il client interrompe l’invio automatico delle richieste e mostra un avviso all’utente. 5.3 Presence Server Kamailio Come già accennato in precedenza, per raggiungere gli obiettivi preposti, la nostra soluzione si concentra sulla modifica del modulo di presenza presence di Kamailio scritto interamente in linguaggio C. CAPITOLO 5. SOLUZIONE DEL PROGETTO 53 Per la configurazione completa del modulo di presenza modificato si rimanda all’appendice B. 5.3.1 Modifica della gestione dei messaggi SUBSCRIBE Una delle modifiche apportate al modulo di presenza, consiste nell’implementazione di un meccanismo che controlli e limiti la frequenza ed il numero di richieste di sottoscrizione che arrivano al server. Per fare questo, definiamo una frequenza massima di ricezione delle richieste che, se superata, determina una risposta di redirezione al client da parte del server. Questo ha lo scopo di evitare un sovraccarico del server nel breve periodo, nel caso in cui le richieste entranti siano in numero troppo elevato per poterle gestire tutte correttamente. In figura 5.6 è rappresentato un esempio in cui presentity 1, presentity 2 e presentity 3 determinano un superamento della frequenza massima tollerabile di ricezione di richieste SUBSCRIBE da parte del PS, portando quindi il server a rifiutare la richiesta di presentity 4. CAPITOLO 5. SOLUZIONE DEL PROGETTO 54 Figura 5.6: Rifiuto delle richieste di SUBSCRIBE Analogamente al meccanismo appena descritto, il server è stato modificato inserendo un controllo sul numero di watcher “globalmente” attivi sul server stesso al momento della ricezione di una nuova richiesta di sottoscrizione, ed un controllo sul numero di watcher attivi verso il presentity per il quale arriva la richiesta di sottoscrizione. Troppi watcher attivi possono, infatti, portare ad una congestione del server durante il processo di notifica delle informazioni pubblicate dai presentity. Supponiamo, ad esempio, che un presentity abbia 1000 utenti sottoscritti al proprio servizio di presenza: quando il presentity pubblica informazioni, il PS deve inviare una notifica verso ogni watcher attivo, ovvero 1000 notifiche. Questo può portare ad un sovraccarico del server e ad una congestione del canale di comunicazione, quindi la CAPITOLO 5. SOLUZIONE DEL PROGETTO 55 soluzione prevede di limitare il numero massimo di watcher attivi per ogni presentity. Nel momento in cui arriva una richiesta di sottoscrizione relativa al servizio di presenza di un presentity P (figura 5.7), il server controlla il numero di watcher “globalmente” attivi che possiede e: • se è sopra la soglia massima rifiuta la richiesta rispondendo al client con un messaggio di tipo 302 Moved temporarily; • se è sotto la soglia massima controlla il numero di watcher attivi che possiede verso il presentity P per cui è arrivata la nuova richiesta e: – se è sopra la soglia massima rifiuta la richiesta rispondendo al client con un messaggio di tipo 302 Moved temporarily; – se è sotto la soglia massima accetta la nuova richiesta. Figura 5.7: Controllo sul numero di watcher attivi CAPITOLO 5. SOLUZIONE DEL PROGETTO 5.3.2 56 Modifica della gestione dei messaggi PUBLISH La soluzione proposta prevede anche la modifica del meccanismo di gestione delle pubblicazioni implementato nel modulo di presenza integrato in Kamailio. Tale modulo è stato modificato inserendo un controllo sulla frequenza di arrivo dei messaggi PUBLISH, in modo da salvaguardare il server da possibili congestioni dovute alla loro gestione. Il controllo viene effettuato sia sulla frequenza di arrivo delle pubblicazioni indipendentemente dal presentity che le pubblica, sia sulla frequenza di pubblicazione di un singolo presentity. All’arrivo di un messaggio di tipo PUBLISH, il presence server provvede a verificare la frequenza “globale” di pubblicazione (frequenza di pubblicazione di tutti i presentity del PS) registrata in un intervallo temporale subito precedente (figura 5.8), e: • se supera la frequenza massima tollerabile di pubblicazione, il PS risponde al client con un messaggio di tipo 302 Moved temporarily; • se non supera la frequenza massima, il PS controlla la frequenza di pubblicazione (nell’ultimo intervallo temporale) del presentity richiedente e: – se supera la frequenza massima tollerabile di pubblicazione, il PS registra la pubblicazione senza inviare le notifiche, che invierà in intervalli di tempo prestabiliti per ottimizzare il numero di messaggi scambiati; – se non supera la frequenza massima, il PS accetta la richiesta, avvisa gli altri server del sistema dell’avvenuta pubblicazione di nuove informazioni ed invia le notifiche ai watcher sottoscritti presso di lui. CAPITOLO 5. SOLUZIONE DEL PROGETTO 57 Figura 5.8: Controllo sulla frequenza di pubblicazione (solo comunicazione PS - presentity) Nelle figure successive è riportato lo schema completo dei messaggi scambiati nel sistema nel caso in cui la frequenza “globale” di pubblicazione non sia superata. CAPITOLO 5. SOLUZIONE DEL PROGETTO 58 Figura 5.9: Scambio di messaggi per il processo di pubblicazione (frequenza presentity non superata) Dalla figura 5.9 notiamo che, nel caso in cui la frequenza “globale” di pubblicazione non sia stata superata e la frequenza di pubblicazione del presentity richiedente sia sotto la soglia massima, il PS accetta la richiesta, inoltra le notifiche ai watcher ed avvisa gli altri server dell’avvenuta pubblicazione di nuove informazioni di presenza, in modo che ognuno possa notificare i propri sottoscrittori. CAPITOLO 5. SOLUZIONE DEL PROGETTO 59 Figura 5.10: Scambio di messaggi per il processo di pubblicazione (frequenza presentity superata) Dalla figura 5.10 notiamo che, nel caso in cui la frequenza “globale” di pubblicazione non sia stata superata e la frequenza di pubblicazione del presentity richiedente sia sopra la soglia massima, il PS accetta la richiesta, attende per un periodo di tempo prestabilito (in cui potrebbero arrivare nuovi PUBLISH dallo stesso presentity), inoltra le notifiche ai watcher ed avvisa gli altri server dell’avvenuta pubblicazione di nuove informazioni di presenza, in modo che ognuno possa notificare i propri sottoscrittori. L’attesa permette di evitare la generazione e l’invio di notifiche troppo frequenti verso i watcher CAPITOLO 5. SOLUZIONE DEL PROGETTO 60 di uno specifico presentity, escludendo cosı̀ i rischi di congestione del server. Tutti i messaggi di pubblicazione ricevuti durante il periodo di attesa verranno accettati dal PS (rispettando la frequenza “globale” di pubblicazione), e le informazioni in essi contenute verranno salvate in un database centralizzato accessibile poi da ogni altro server del sistema. La soluzione prevede, inoltre, che ogni server sia in ascolto su un indirizzo multicast per essere avvisato dagli altri PS sull’avvenuta pubblicazione di informazioni di presenza da parte di un presentity. Come già detto, infatti, quando un PS riceve un messaggio PUBLISH da un presentity P, salva le informazioni di presenza nel database centralizzato, notifica i propri watcher ed avvisa gli altri PS che il presentity P ha pubblicato nuove informazioni; gli altri PS recuperano le informazioni dal database e notificano i propri watcher (figura 5.11). CAPITOLO 5. SOLUZIONE DEL PROGETTO 61 Figura 5.11: Scambio di messaggi per il processo di pubblicazione La soluzione prevede, in realtà, due soglie di frequenza massima “globale” di pubblicazione, a seconda che il presentity sia “privilegiato” o meno. Queste soglie distinte consentono di trattare con maggiore riguardo gli utenti più attivi rispetto a quelli che lo sono meno, aggiungendo un minimo di qualità al servizio. Nello specifico, il server, all’arrivo di un messaggio PUBLISH proveniente dal presentity P, controlla il numero di pubblicazioni che P ha effettuato nell’ultima ora e, se supera un certo livello L (configurabile CAPITOLO 5. SOLUZIONE DEL PROGETTO 62 dal file di configurazione di Kamailio), P viene considerato “privilegiato”. Successivamente, il PS controlla la frequenza “globale” di pubblicazione e, se l’utente è “privilegiato”, la soglia massima da considerare è pari ad un valore S (configurabile dal file di configurazione di Kamailio); se l’utente è “non privilegiato”, la soglia massima da considerare è 23 S. 5.4 Risultati sperimentali Per testare il modulo di presenza presence di Kamailio da noi modificato, abbiamo eseguito alcuni test e misurato i tempi di risposta del server. Per il test abbiamo utilizzato un programma denominato sipp [4], che consente di creare scenari personalizzati volti ad istruire l’applicazione riguardo a quali messaggi inviare e a quali aspettarsi in fase di ricezione. L’applicazione consente, inoltre, di configurare la frequenza di invio di messaggi, in modo da poter testare il funzionamento del nostro server in casi estremi. Per avere una migliore idea sul significato dei tempi di risposta, abbiamo effettuato gli setssi test integrando in Kamailio il modulo di presenza originale, cioè non modificato da noi. Le tabelle sotto riportate mostrano i vari risultati ottenuti per il processo di pubblicazione di informazioni di presenza. Legenda colonne: • RATIO: frequenza di invio messaggi ([msg/msec]); • SENT: numero di messaggi inviati; • TIME: tempo impiegato dal server per gestire tutti i messaggi ([sec]); • 200: numero di risposte di tipo 200 OK da parte del server; • 302: numero di risposte di tipo 302 Moved temporarily da parte del server. CAPITOLO 5. SOLUZIONE DEL PROGETTO 63 Messaggi PUBLISH RATIO SENT TIME 200 302 100/1000 5000 50,01 5000 / 150/1000 5000 33,35 5000 / 200/1000 5000 25,01 5000 / 250/1000 5000 20,52 5000 / 300/1000 5000 30,13 5000 / 350/1000 5000 33,88 5000 / 400/1000 5000 33,16 5000 / Tabella 5.1: Modulo di presenza originale Messaggi PUBLISH RATIO SENT TIME 200 302 100/1000 5000 50,01 5000 71 150/1000 5000 33,34 5000 1396 200/1000 5000 25,01 5000 1628 250/1000 5000 20,01 5000 2000 300/1000 5000 16,67 5000 2000 350/1000 5000 14,29 5000 3500 400/1000 5000 28,12 5000 2000 Tabella 5.2: Modulo di presenza modificato CAPITOLO 5. SOLUZIONE DEL PROGETTO 64 Notiamo che, con il modulo di presenza originale, Kamailio inizia ad avere difficoltà a frequenze di 300 messaggi al secondo. Alla stessa frequenza, il modulo di presenza modificato risponde in tempi decisamente inferiori, in quanto rifiuta le richieste che possono causare congestione e lentezza di risposta del server; in questo caso il client può reinviare la stessa richiesta ad un altro presence server per poter ottenere una risposta in tempi brevi. Le tabelle successive mostrano i vari risultati ottenuti per il processo di sottoscrizione. Legenda colonne: • RATIO: frequenza di invio messaggi ([msg/msec]); • SENT: numero di messaggi inviati; • TIME: tempo impiegato dal server per gestire tutti i messaggi ([sec]); • 202: numero di risposte di tipo 202 OK da parte del server; • 302: numero di risposte di tipo 302 Moved temporarily da parte del server; • NOT: numero di messaggi NOTIFY inviati dal server a seguito della ricezione di un SUBSCRIBE; • UN: numero di messaggi inaspettati inviati dal server a seguito della ricezione di un SUBSCRIBE (causati da errori interni al server); • TO: numero di richieste andate in timeout (non hanno ricevuto risposta dal server). CAPITOLO 5. SOLUZIONE DEL PROGETTO 65 Messaggi SUBSCRIBE RATIO SENT TIME 202 302 NOT UN TO 100/1000 5000 50,02 5000 / 5000 0 0 150/1000 5000 33,34 5000 / 5000 0 0 200/1000 5000 25,01 5000 / 5000 0 0 250/1000 5000 20,01 5000 / 5000 0 0 300/1000 5000 27,15 4816 / 4815 184 0 350/1000 5000 26,15 4788 / 4785 212 0 400/1000 5000 16,82 4617 / 4615 383 0 Tabella 5.3: Modulo di presenza originale Messaggi SUBSCRIBE RATIO SENT TIME 100/1000 5000 150/1000 202 302 NOT 50,01 2725 2275 2725 0 0 5000 33,34 2008 2992 2008 0 0 200/1000 5000 25,00 2104 2896 2104 0 0 250/1000 5000 20,01 3144 1856 3144 0 0 300/1000 5000 16,67 3403 1597 3403 0 0 350/1000 5000 14,76 3772 1228 2772 0 0 400/1000 5000 12,51 4004 4004 253 0 743 UN TO Tabella 5.4: Modulo di presenza modificato CAPITOLO 5. SOLUZIONE DEL PROGETTO 66 Notiamo come il modulo di presenza modificato gestisca le richieste di sottoscrizione meglio dell’originale, perdendo (colonna TO) o rispondendo in modo errato (colonna UN ) a molti meno messaggi e in tempi inferiori. I client che ricevono un messaggio 302 Moved temporarily in risposta, possono reinoltrare la richiesta di sottoscrizione ad un altro presence server con un carico di lavoro inferiore. Appendice A Configurazione di kamailio Per i nostri scopi, è sufficiente configurare Kamailio come standalone Presence Server. I paragrafi successivi illustrano i vari passi da seguire per scaricare, installare e configurare correttamente il nostro Presence Server. A.1 Prerequisiti Kamailio funziona su sistema operativo Linux, come ad esempio Linux Ubuntu 9.10. Per poter compilare con successo i file sorgenti di Kamailio, è necessario installare i software gcc, flex, bison e make; è inoltre necessario procurarsi la libreria libmysqlclient15-dev. Su un sistema Linux Ubuntu, è possibile recuperare tutti i requistiti attraverso il comando sudo apt-get install gcc flex bison make libmysqlclient15-dev Soddisfatti questi requisiti, è possibile procedere con il download, la compilazione e la configurazione del presence server. 67 APPENDICE A. CONFIGURAZIONE DI KAMAILIO A.2 68 Download I sorgenti di Kamailio sono scaricabili dal sito ufficiale al link http://www.kamailio.org/mos/view/Download/ attraverso diversi meccanismi. Avendo precedentemente installato Subversion, possiamo scaricare i sorgenti utilizzando tale software. I sorgenti di Kamailio sono pre-configurati per lavorare da un percorso standard. Possiamo quindi creare la cartella /usr/local/src/kamailio-1.5.2 dove preferiamo, e spostarci all’interno di essa; procediamo poi con il download via svn: mkdir -p /usr/local/src/kamailio-1.5.2 cd /usr/local/src/kamailio-1.5.2 svn co http://openser.svn.sourceforge.net/svnroot/openser/branches/1.5 sip-server Effettuato il download, possiamo procedere alla compilazione dei sorgenti. A.3 Compilazione e installazione Per configurare correttamente Kamailio come standalone Presence Server, dobbiamo seguire i seguenti passi: • includere i moduli di presenza e mysql nella compilazione, modificando il file Makefile.vars; • compilare i file sorgenti; • installare i file binari. Per includere il modulo di presenza, dobbiamo modificare il file Makefile.vars situato nella cartella principale, decommentando la riga APPENDICE A. CONFIGURAZIONE DI KAMAILIO 69 MODS_PRESENCE=on Per permettere a Kamailio di utilizzare il database MySQL, è necessario decommentare anche la riga MODS_MYSQL=on Fatto questo, possiamo procedere alla compilazione dei sorgenti eseguendo il comando sudo make all Questo ultimo comando, potrebbero richiedere molto tempo, a seconda delle prestazioni della macchina sulla quale viene eseguito. Procediamo ora all’installazione dei file appena compilati, eseguendo il comando sudo make install Lo script di installazione, provvede a creare una serie di cartelle nelle quali inserisce i file di Kamailio: • /usr/local/sbin: inserisce i binari e gli script di avvio kamailio, kamctl, kamdbctl ; • /usr/local/lib/kamailio/modules/ : inserisce i moduli necessari a kamailio; • /usr/local/etc/kamailio/ : inserisce il file di configurazione kamailio.cfg. A questo punto, possiamo passare alla configurazione di Kamailio come standalone Presence Server ed alla creazione del database necessario. APPENDICE A. CONFIGURAZIONE DI KAMAILIO A.4 70 Configurazione Come già detto, ci interessa configurare Kamailio come semplice Presence Server. Per fare questo, è necessario modificare il file kamailio.cfg che si trova nella cartella /usr/local/etc/kamailio/. Risulta più facile e veloce sostituire il suddetto file con il file di esempio presence.cfg situato nella cartella /usr/local/src/kamailio1.5.2/test, ed andare poi a modificare tale file per settare i parametri che ci interessano. Andiamo, infine, a creare il database necessario a kamailio. Innanzitutto effettuiamo un backup del file originale kamailio.cfg mv /usr/local/etc/kamailio/kamailio.cfg /usr/local/etc/kamailio/kamailio.cfg.bk Copiamo il file di esempio al posto dell’originale cp /usr/local/src/kamailio-1.5.2/test/presence.cfg /usr/local/etc/kamailio/kamailio.cfg Sostituiamo il file sostituendo la riga port=5059 con la riga port=5060 Questa modifica, indica al server di presenza, di mettersi in ascolto di nuove richieste entranti sulla porta 5060. Sostituiamo poi la riga modparam("presence", "server_address", "sip:10.10.10.10:5060") APPENDICE A. CONFIGURAZIONE DI KAMAILIO 71 con la riga modparam("presence", "server_address", "sip:127.0.0.1:5060") Questo ci consente di settare una variabile interna a Kamailio che indica quale indirizzo SIP inserire nell’header Contact dei messaggi inviati da Kamailio stesso. A questo punto, kamailio è configurato per funzionare come standalone presence server in ascolto all’indirizzo 127.0.0.1 (localhost) sulla porta 5060. Passiamo ora alla configurazione del database. Innanzitutto, dobbiamo modificare il file kamctlrc situato nella cartella /usr/local/etc/kamailio/ per specificare il DBMS utilizzato e il dominio della nostra rete, poi andiamo a creare il database. Entriamo nella cartella /usr/local/etc/kamailio/ cd /usr/local/etc/kamailio/ modifichiamo la riga SIP_DOMAIN=kamailio.org con SIP_DOMAIN=kamailio.test aggiungiamo, o decommentiamo se già presente, la riga DBENGINE=MYSQL la quale consente di specificare il DBMS che Kamailio deve utilizzare. A questo punto possiamo passare alla creazione del database. Kamailio offre uno script che configura automaticamente il database, digitiamo quindi il comando APPENDICE A. CONFIGURAZIONE DI KAMAILIO 72 sudo kamdbctl create Abbiamo ora terminato la configurazione di Kamailio, e possiamo quindi farlo partire con il comando sudo kamctl start Per fermarlo digitiamo sudo kamctl stop In questo modo possiamo far partire una sola istanza di Kamailio su questa macchina, in quanto la porta di ascolto del server è specificata nel file di configurazione. Se vogliamo avviare più istanze di Kamailio sulla stessa macchina, possiamo fare riferimento al paragrafo A.4.1. A.4.1 File di configurazione per ogni istanza Se vogliamo far girare più istanze di Kamailio sulla stessa macchina è necessario seguire i seguenti passi: • creare un file di configurazione per ogni istanza di Kamailio; • creare un file di script per l’avvio di ogni istanza di Kamailio. Ogni istanza di Kamailio necessita di un file di configurazione che deve essere in parte diverso da ogni altro file di configurazione delle varie istanze. In particolare è necessario che ogni istanza sia in ascolto su una porta diversa. Per fare questo, possiamo creare, per ogni istanza che vogliamo, un file di configurazione a partire da quello creato precedentemente: cd /usr/local/etc/kamailio/ cp kamailio.cfg kamailio1.cfg cp kamailio.cfg kamailio2.cfg APPENDICE A. CONFIGURAZIONE DI KAMAILIO 73 In questo modo abbiamo creato due file di configurazione identici per avviare due istanze di kamailio sulla stessa macchina. Ora procediamo alla modifica della porta di ascolto dei due server modificando, nel secondo file (kamailio2.cfg), la riga port=5060 con port=5070 e la riga modparam("presence", "server_address", "sip:127.0.0.1:5060") con modparam("presence", "server_address", "sip:127.0.0.1:5070") In questo modo, la seconda istanza di Kamailio sarà in ascolto sulla porta 5070 di localhost. A questo punto procediamo creando gli script di avvio per le due istanze. Innanzitutto creiamo uno script denominato kamailio.base contenente le seguenti righe: ##### ----------------------------------------------- ##### #### Common functions mdbg() { if [ "0$VERBOSE" -ne 0 ] ; then APPENDICE A. CONFIGURAZIONE DI KAMAILIO if [ -t 1 -a -z "$NOHLPRINT" ] ; then echo -e "\033[1m$1\033[0m" else echo "$1" fi fi } mwarn() { if [ -t 1 -a -z "$NOHLPRINT" ] ; then echo -e ’\E[37;32m’"\033[1mWARNING: $1\033[0m" else echo "** WARNING: $1" fi } minfo() { if [ -t 1 -a -z "$NOHLPRINT" ] ; then echo -e ’\E[37;33m’"\033[1mINFO: $1\033[0m" else echo "** INFO: $1" fi } mecho() { if [ -t 1 -a -z "$NOHLPRINT" ] ; then echo -e "\033[1m$1\033[0m" 74 APPENDICE A. CONFIGURAZIONE DI KAMAILIO else echo "$1" fi } merr() { if [ -t 1 -a -z "$NOHLPRINT" ] ; then echo -e ’\E[37;31m’"\033[1mERROR: $1\033[0m" else echo "** ERROR: $1" fi } print_usage() { mwarn "usage: $0 (start|stop|restart)" } # ##### ------------------------------------------------ ##### ### openser_start # openser_start() { echo minfo "...Starting Kamailio... " echo /usr/local/sbin/kamailio -f $CONFIG_FILE -P $PID_FILE 75 APPENDICE A. CONFIGURAZIONE DI KAMAILIO 76 sleep 3 echo minfo "started (pid: ‘cat $PID_FILE‘)" echo } # ##### ------------------------------------------------ ##### ### openser_stop # openser_stop() { echo minfo "...Stopping Kamailio... " echo if [ -r $PID_FILE ] ; then kill ‘cat $PID_FILE‘ minfo "stopped" echo else merr "No PID file found ($PID_FILE)! Kamailio not running" echo #minfo "check with ’ps axw | $EGREP kamailio’" exit 1 fi } Queste sono le funzioni comuni ai due script di avvio. Creaimo poi lo script di avvio kamailio1.sh contenente le seguenti righe: APPENDICE A. CONFIGURAZIONE DI KAMAILIO #!/bin/bash # ## Init script for kamailio ## With this script you can run more kamailio instances ## N.B. Remember to generate kamailio configuration file ## (i.e. kamailio3.cfg) in /usr/local/etc/kamailio/ # # ##### ------------------------------------------------ ##### ### Script configuration parameters # KAMAILIO="kamailio1" PID_FILE="/var/run/kamailio1.pid" CONFIG_FILE="/usr/local/etc/kamailio/kamailio1.cfg" MYLIBDIR="." VERBOSE=1 # 1-Print debug messages # 0-Don’t print debug messages #NOHLPRINT=1 # Decomment for not colored text # ##### ------------------------------------------------ ##### ### load base functions # 77 APPENDICE A. CONFIGURAZIONE DI KAMAILIO if [ -f "$MYLIBDIR/kamailio.base" ]; then . "$MYLIBDIR/kamailio.base" else echo -e "Cannot load core functions ’$MYLIBDIR/kamailio.base’ - exiting ...\n" exit -1 fi # ##### ------------------------------------------------ ##### ### Parameters check # if [ $# -ne 1 ] then echo print_usage echo exit 1 fi # ##### ------------------------------------------------ ##### ### dispatcher # case $1 in start) openser_start 78 APPENDICE A. CONFIGURAZIONE DI KAMAILIO 79 ;; stop) openser_stop ;; restart) openser_stop sleep 3 openser_start ;; *) echo print_usage echo ;; esac Notiamo che lo script contiene tre variabili KAMAILIO="kamailio1" PID_FILE="/var/run/kamailio1.pid" CONFIG_FILE="/usr/local/etc/kamailio/kamailio1.cfg" che riferiscono alla prima istanza di Kamailio. Creaiamo, ora, un file identico ma nominato kamailio2.sh e modifichiamo le suddette variabili con KAMAILIO="kamailio2" APPENDICE A. CONFIGURAZIONE DI KAMAILIO 80 PID_FILE="/var/run/kamailio2.pid" CONFIG_FILE="/usr/local/etc/kamailio/kamailio2.cfg" riferendoci cosı̀ alla seconda istanza di Kamailio. Possiamo ora far partire le due istanze di Kamailio digitando i seguenti comandi: ./kamailio1.sh start ./kamailio2.sh start Per fermare le istanze: ./kamailio1.sh stop ./kamailio2.sh stop Per riavviare le due istanze: ./kamailio1.sh restart ./kamailio2.sh restart Appendice B Modulo di presenza modificato In questa appendice descriviamo come installare e configurare il modulo di presenza da noi modificato. Per farlo dobbiamo: • compilare il modulo di presenza modificato; • installare il modulo di presenza modificato; • configurare il modulo di rpesenza modificato. B.1 Compilazione ed installazione Per compilare ed installare il modulo di presenza modificato, dobbiamo: • entrare nella cartella presence mod ; • compilare i sorgenti con lo strumento make; • copiare il modulo presence.so nella cartella modules/presence di Kamailio sostituendo quello esistente. Iniziamo dunque spostandoci nella cartella presence mod e lanciando il comando make: 81 APPENDICE B. MODULO DI PRESENZA MODIFICATO 82 cd /path/presence_mod/ make terminata la compilazione, copiamo il modulo presence.so nella cartella modules/presence di Kamailio sostituendo quello già esistente: cp /path/presence_mod/presence.so /usr/local/lib/kamailio/modules/presence.so Abbiamo cosı̀ installato il modulo di presenza modificato. B.2 Configurazione Per configurare il modulo di presenza modificato, è necessario modificaze il file di configurazione di Kamailio nella cartella /usr/local/etc/kamailio/. Se abbiamo installato più istanze di Kamailio sulla stessa macchina come descritto in appendice A.4, dobbiamo modificare il file di configurazione di ogni istanza. Un esempio di file di configurazione è il seguente: # # $Id$ # # simple quick-start config script - Stand-alone presence server # # ----------- global configuration parameters ------------------- debug=1 fork=yes # debug level (cmd line: -dddddddddd) APPENDICE B. MODULO DI PRESENZA MODIFICATO log_stderror=no 83 # (cmd line: -E) children=4 log_facility=LOG_LOCAL0 listen=127.0.0.1 port=5060 dns=no rev_dns=no # ------------------ module loading ----------------------------- #set module path mpath="/usr/local/lib/kamailio/modules/" loadmodule "db_mysql.so" loadmodule "sl.so" loadmodule "maxfwd.so" loadmodule "textops.so" loadmodule "tm.so" loadmodule "rr.so" loadmodule "presence.so" loadmodule "presence_xml.so" loadmodule "avpops.so" loadmodule "mi_fifo.so" # ----------------- setting module-specific parameters ---------- APPENDICE B. MODULO DI PRESENZA MODIFICATO 84 # -- rr params -# add value to ;lr param to make some broken UAs happy modparam("rr", "enable_full_lr", 1) # -- presence params -modparam("presence|presence_xml", "db_url", "mysql://openser:openserrw@localhost/openser") modparam("presence_xml", "force_active", 1) modparam("presence", "server_address", "sip:127.0.0.1:5060") modparam("presence", "max_publ", 1500) modparam("presence", "max_publ_pres", 100) modparam("presence", "intervallo_timer", 60) modparam("presence", "max_sub", 2500) modparam("presence", "interval", 10) modparam("presence", "max_watchers", 2000) modparam("presence", "max_watchers_pres", 1000) modparam("presence", "soglia_privileg", 100) modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo_presence") modparam("presence", "fallback2db", 0) APPENDICE B. MODULO DI PRESENZA MODIFICATO # ------------------------- request routing logic -------------- # main routing logic route{ # initial sanity checks -- messages with # max_forwards==0, or excessively long requests if (!mf_process_maxfwd_header("10")) { sl_send_reply("483","Too Many Hops"); exit; }; if (msg:len >= 2048 ) { sl_send_reply("513", "Message too big"); exit; }; if (!is_method("SUBSCRIBE|PUBLISH")) { sl_send_reply("488", "Not Acceptable Here"); exit; } # presence handling if (! t_newtran()) { sl_reply_error(); exit; 85 APPENDICE B. MODULO DI PRESENZA MODIFICATO 86 }; if(is_method("PUBLISH")) { handle_publish(); t_release(); } else if( is_method("SUBSCRIBE")) { handle_subscribe(); t_release(); }; exit; } Con le istruzioni modparam(...) andiamo a modificare il valore di alcuni parametri interni ai vari moduli. Notiamo che, in questo file di esempio, i vari parametri del modulo di presenza modificato sono settati come segue: • max publ = 1500: si accettano al massimo 1500 pubblicazioni nell’intervallo di tempo ‘interval’; • max publ pres = 100: se un presentity invia meno di 100 pubblicazioni nell’intervallo ‘interval’, allora in corrispondenza di ognuna vengono inviate le varie notifiche ai watcher, altrimenti le notifiche vengono inviate dopo un tempo ‘intervallo timer’; APPENDICE B. MODULO DI PRESENZA MODIFICATO 87 • intervallo timer = 60: tempo di attesa in secondi dopo cui inviare le notifiche ai watcher nel caso in cui la frequenza di pubblicazione di un presentity superi la soglia ‘max publ pres’; • max sub = 2500: si accettano al massimo 2500 sottoscrizioni nell’intervallo di tempo ‘interval’; • interval = 10: intervallo di 10 secondi entro cui verificare il numero di PUBLISH e SUBSCRIBE ricevuti; • max watchers = 2000: si accettano al massimo 2000 watcher attivi su questo server; • max watchers pres = 1000: si accettano al massimo 1000 watcher attivi per ogni presentity su questo server; • soglia privileg = 100: se un presentity invia almeno 100 PUBLISH in un’ora, allora viene considerato “privilegiato”. Bibliografia [1] JAIN. http://java.sun.com/products/jain/. [2] JAIN-SIP. https://jain-sip.dev.java.net/. [3] Kamailio (openser). http://www.kamailio.org. [4] SIPp. http://sipp.sourceforge.net/. [5] M. Day, Lotusa, J. Rosenberg, dynamicsoft, H. Sugano, and Fujitsu. A model for presence and instant messaging, February 2000. [6] M. Handley, ACIRI, H. Schulzrinne, Columbia U., E. Schooler, CalTech, J. Rosenberg, and Bell Labs. SIP: Session Initiation Protocol, March 1999. [7] J. Rosenberg and dynamicsoft. A presence event package for the session initiation protocol (sip), August 2004. [8] J. Rosenberg and dynamicsoft. A watcher information event templatepackage for the session initiation protocol (sip), August 2004. [9] J. Rosenberg, dynamicsoft, H. Schulzrinne, Columbia U., G. Camarillo, Ericsson, A. Johnston, WorldCom, J. Peterson, Neustar, R. Sparks, dynamicsoft, M., ICIR, E. Schooler, and AT&T. SIP: Session Initiation Protocol, June 2002. 88 BIBLIOGRAFIA 89 [10] J. Rosenberg and Cisco Systems. A data model for presence, July 2006. [11] H. Schulzrinne, Columbia U., V. Gurbani, Lucent, P. Kyzivat, J. Rosenberg, and Cisco. Rpid: Rich presence extensions to the presence information data format (pidf), July 2006. [12] Ron Shacham and Henning Schulzrinne. Compisition for enhanced sip presence. [13] H. Sugano, S. Fujimoto, Fujitsua, G. Klyne, Nine by Nine, A. Bateman, VisionTech, W. Carr, Intel, J., and NeuStar. Presence information data format (pidf), August 2004.