Lo strato applicativo di Internet
All'inizio di questo corso si è fatto notare come la trasmissione a pacchetto dei dati, caratteristica della rete Internet, si pone in diretta contrapposizione alla modalità di trasmissione realizzata dalle reti a commutazione di circuito su cui si è evoluta la telefonia e la trasmissione del segnale vocale. Ciononostante, a seguito dello sviluppo di Internet, della banda disponibile, e della velocità dei nodi di commutazione, la trasmissione vocale è divenuta possibile (e di fatto, estensivamente praticata) anche su reti a pacchetto, e nel caso di reti IP, prende il nome di Voice over IP (VoIP).
Per molti, le telefonate Internet sono automaticamente associate all'uso di Skype, che gode di un particolare successo di diffusione e di immagine, ma i cui protocolli operativi sono proprietari e quasi sconosciuti. D'altra parte, la possibilità di usare le reti per dati anche a scopo di trasmissione vocale è stata a lungo inseguita dagli operatori telefonici tradizionali, prima offrendo un accesso numerico con ISDN, poi integrando la trasmissione di voce e dati su di una stessa rete ATM. Al punto che in sede ITU fu standardizzata la famiglia di protocolli aperti H.323, orientata ad offrire servizi multimediali su reti a pacchetto, facilitando allo stesso tempo l'interoperabilità con le reti a circuito preesistenti. Nel frattempo, il WG MMUSIC di IETF stava procedendo a investigare le modalità di realizzazione di servizi multimediali (come videoconferenze e streaming) su rete Internet, definendo
Da
un lato, l'ITU adottò e fece proprie alcune scelte di IETF,
incorporando il trasporto RTP in H.323; da un altro canto lo scenario
preconizzato da IETF, che prevedeva la diffusione globale
dell'instradamento multicast,
venne in parte a decadere. Allo stesso tempo, i meccanismi previsti
dall'H.323 si rivelarono piuttosto macchinosi, a causa del tentativo di
replicare su Internet i protocolli di segnalazione SS7
preesistenti sulle reti a circuito. Fu a questo punto, che venne definito
in sede IETF un nuovo protocollo di segnalazione, il Session
Initiation Protocol (SIP), in grado di declinare le funzioni di controllo
chiamata adottando messaggi testuali in stile SMTP
e HTTP, e di integrarsi armonicamente con le
funzioni già assolte da SDP e RTP.
Al giorno d'oggi, mentre sono tuttora in uso dispositivi (MCU)
di videoconferenza basati su H.323, praticamente ogni operatore che
intende offrire un servizio VoIP si basa sulla adozione di SIP, al
punto che questo è anche alla base dello sviluppo
dell'IP
Multimedia Subsystem
(IMS) che rappresenta l'architettura per la fornitura dei servizi
multimediali offerti dagli operatori di telefonia mobile di terza
generazione (3G).
La tecnologia VoIP SIP si basa sulla definizione di una serie di entità, mostrate a lato, e descritte nel seguito.
Abbreviato come UA, è il dispositivo mediante il quale gli umani possono comunicare: in questo senso, è l'analogo del tradizionale telefono, con la differenza che mentre un telefono è associato ad un determinato numero, legato alla presa telefonica od alla SIM del cellulare, uno UA viene configurato per corrispondere ad una URI simile a quella di una email, come ad esempio sip:alef@ing.uniroma1.it, che è proprietà dell'utente, dovunque egli la usi, permettendone la mobilità.
La parte di URI nome_utente@dominio_voip viene indicata come Address of Record (AoR), e rappresenta l'identità di una persona fisica, immutabile e indipendente dalla posizione effettiva dell'individuo nella rete, e dal dispositivo usato per collegarsi. Uno UA può essere realizzato mediante
Dato che una chiamata che ha origine da uno UA, viene terminata su di un altro UA, questo può pensarsi scomposto in due componenti:
Per questo motivo, il VoIP non viene identificato come un protocollo Client-Server, ma Peer to Peer.
E' l'elemento a cui uno UA comunica (registra) l'indirizzo IP mediante il quale è raggiungibile via Internet (indicato anche come Contact Address) e da associare all'AoR, mediante il quale può essere contattato. Questa corrispondenza può essere trattenuta presso il Registrar, oppure memorizzata presso un'entità indicata come Location Server (vedi figura seguente). Il Registrar viene amministrato dal fornitore di servizio (provider) VoIP che ha rilasciato l'AoR all'utente, e che amministra il DNS autorevole per il nome a dominio che compare nell'AoR.
Uno UA individua l'identità del Registrar presso cui registrare il proprio Contact Address in base alla componente dominio del proprio AoR, usato da chi vuol chiamarlo. In questo senso il Registrar è l'analogo di un server SMTP di destinazione, con la differenza che mentre le email in arrivo si fermano lì, quando una chiamata VoIP entrante raggiunge il Registrar, questa viene immediatamente inoltrata verso il Contact Address che è stato registrato in corrispondenza dell'AoR, supportando così la mobilità dell'utente, e l'uso di indirizzi IP dinamici, come nel caso di una connessione on-demand. Spesso, l'entità che ospita il Registrar è la stessa che ospita anche un elemento Proxy.
Diversi UA possono registrare diversi Contact Address per uno stesso AoR, ad es. perché uno UA è il tel VoIP sul tavolo, un'altro è un softphone sul computer, ed un altro ancora un cordless VoIP su WiFi. In questo caso la chiamata entrante per un AoR viene inoltrata a tutti i Contact Address associati, provocando il forking del controllo, in modo da far squillare tutti gli UA presso cui può trovarsi il chiamato.
E' un elemento che ha la capacità di inoltrare
i messaggi SIP, ed in questo senso, si può pensare che il suo ruolo sia
per certi versi simile a quello di un router di
livello applicativo. Un classico esempio di utilizzo si ha quando
uno User Agent recapita al Proxy la propria chiamata (uscente),
facendogli assumere un ruolo analogo a quello di un server SMTP di
uscita: in questo caso, il proxy prende il nome di Outbound
Proxy.
Tra le prerogative di un Proxy, possiamo elencare quelle di
La sua funzione è quella di interfacciare il VoIP SIP con altre
reti
multimediali, come nel caso in cui la rete di destinazione/provenienza
della chiamata, è quella telefonica (PSTN), H.323, di telefonia mobile
(GSM o IMS-3G), una rete VoIM,
o associata ad altro protocollo VoIP.
La presenza di un Gateway da/verso PSTN consente di raggiungere anche gli utenti di telefonia fissa, usando Internet per trasportare la chiamata il più vicino possibile alla località del numero chiamato, e quindi (lì) attraversare un secondo Gateway, rendendo la chiamata equivalente ad una locale.
La funzione del Gateway può essere ulteriormente scomposta in
Al fine di incentivare l'interoperabilità tra
apparati, la comunicazione tra MG e MGC può avvenire mediante un ulteriore
protocollo pubblico, noto come Media
Gateway Control Protocol, la cui implementazione è formalizzata
ulteriormente dalla raccomandazione H.248.
Nella figura che segue si mostra come le componenti di una rete PSTN (Time Division Multiplex per le reti PDH
o SDH,
SS7 per
la segnalazione a canale comune)
possano efficientemente utilizzare una rete IP, qualora la segnalazione
venga convertita in SIP o H.323, mentre il segnale audio,
opportunamente transcodificato, sia incapsulato in RTP. In particolare,
è posto in evidenza il controllo dei MG da parte dei MGC. Riportiamo
inoltre i links agli approfondimenti delle altre sigle presenti: Q.Sig,
SigTran, ISUP.
Un Gateway che abbia la funzione di interconnettere direttamente dei telefoni (tradizionali o VoIP) di una stessa organizzazione, così come avviene nel caso di un centralino, è a volte indicato con il termine di SoftSwitch (come è, ad es., Asterisk), e può usare interfacce più o meno intelligenti. Anche se il termine Softswitch viene spesso usato in modo più o meno vago ed intercambiabile, ogni volta che si deve descrivere qualcosa che somiglia ad un dispositivo di commutazione telefonica, ma che non lo è, recentemente il suo uso si è ristretto ad indicare un dispositivo completamente residente su di un unico computer, e che interconnette fisicamente telefoni IP, rete Internet, telefoni tradizionali, e linee PSTN.
Alcuni elementi della architettura SIP offrono funzionalità aggiuntive, che ne arricchiscono le potenzialità:
Il Session Initiation Protocol (SIP) è un protocollo di segnalazione definito nella RFC 3261, e il suo sviluppo coinvolge praticamente tutti i gruppi di lavoro IETF che fanno parte dell'area Real-time Applications and Infrastructure (RAI). La quantità di specifiche che si sono aggiunte a quelle iniziali è via via cresciuta, e per orientarsi tra le stesse può essere opportuno consultare prima una guida per l'autostoppista di SIP, pubblicata come RFC 5411.
Sebbene l'architettura VoIP definita sia basata su di un modello peer
to peer,
SIP opera sulla base di messaggi che utilizzano un modello di
comunicazione di tipo client-server. Inoltre, nessuno degli elementi
prima esposti è strettamente indispensabile, a parte ovviamente gli UA:
infatti, è possibile per uno UA, inviare una chiamata direttamente
verso la URI di un secondo UA, a patto ovviamente che il nome a dominio
che compare nell'AoR chiamato, si risolva effettivamente nell'indirizzo
IP del computer presso il quale lo UA chiamato è in esecuzione. D'altra
parte, sono proprio gli altri elementi dell'architettura che rendono il
VoIP interessante e competitivo rispetto alle modalità di comunicazione
alternative, come PSTN e VoIM.
SIP non si occupa né di negoziare il tipo di formato multimediale da usare nella comunicazione, né di trasportare il segnale digitalizzato: questi due compiti sono invece svolti rispettivamente da SDP e RTP. Al contrario, SIP si occupa di mettere in contatto le parti coinvolte nella comunicazione, in modo da definire una sessione in comune tra loro, e permettergli di utilizzare i servizi offerti da altre entità. Ciò consente di declinare i principi della Service Creation in accordo al paradigma Internet, secondo cui l'intelligenza è posta ai bordi della rete, in contrapposizione al punto di vista degli operatori di telecomunicazioni, che invece accentrano i servizi all'interno delle reti, relegando i dispositivi di accesso ad un ruolo assolutamente passivo.
Affrontiamo ora la descrizione dei tipi e dei formati dei messaggi SIP. Sebbene ciò possa risultare tedioso e oltremodo formale, gli esempi forniti di seguito sono un ottimo modo di verificare strada facendo la semantica delle diverse componenti dei messaggi. Pertanto si consiglia di alternare l'esame dei capture forniti, con la descrizione formale delle sintassi incontrate.
I messaggi possono essere di due tipi, richieste o risposte, e aderiscono alla sintassi definita da una ABNF del tutto simile a quella già vista nel caso dell'HTTP e SMTP, ossia sono composti da
I messaggi SIP sono generati dallo strato applicativo, e tipicamente incapsulati su UDP con porta di destinazione ben nota 5060, in modo da velocizzare al massimo il loro recapito. In alternativa, i messaggi di richiesta-risposta tra due entità SIP possono essere trasportati su TCP, sempre verso la porta 5060; la decisione di usare TCP anziché UDP viene presa dallo UAC, quando ad esempio la dimensione del messaggio è tale da non entrare in un singolo pacchetto UDP, oppure la comunicazione è ritenuta a priori inaffidabile. Infine, lo strato di trasporto può essere reso sicuro mediante l'uso di una connessione TLS, indirizzata questa volta verso la porta ben nota 5061. In quest'ultimo caso, la URI di destinazione userà lo schema sips anziché sip come ad es. sips:alef@ing.uniroma1.it.
Nel caso del trasporto UDP, SIP fa uso di una macchina a stati che definisce i parametri della seguente modalità di ri-trasmissione. Se lo UAC non riceve risposta ad un suo messaggio entro un tempo T1 (posto a 500 msec), lo re-invia di nuovo, e raddoppia il valore del timer T1. Al nuovo scadere di T1, ripete ancora l'invio del messaggio, e raddoppia di nuovo T1, e così via (ritrasmette e raddoppia il timer) finché
In questo modo, mentre si sfruttano i vantaggi di velocità connessi all'uso di UDP, si aggiunge una funzione di affidabilità al trasporto, per gestire il caso dei pacchetti scartati.
La prima riga di una richiesta SIP presenta il formato
Method SP Request-URI SP SIP-Version CRLF |
in cui Method individua la semantica del messaggio, Request-URI indica il destinatario della richiesta, espresso nella forma sip:alef@ing.uniroma1.it, SIP-Version è 2.0 per i messaggi che aderiscono alla RFC 3261, SP rappresenta uno spazio, e CRLF sono i due bytes x0D x0A che codificano un a capo.
I seguenti metodi possono comparire nei messaggi SIP inviati (se non indicato diversamente) da uno UAC, ed il loro elenco completo è mantenuto aggiornato presso IANA.
Metodo | Commento | RFC | Esempio |
REGISTER | inviato al Registrar relativo al Dominio di un AoR, per associare l'AoR con un Contact Address | 3261 (s10) | registrazione |
INVITE | inviato verso il proprio Outbound Proxy, oppure verso il Registrar autorevole per l'AoR del chiamato, allo scopo di instaurare una sessione. Dato che, tipicamente, lo UA chiamato inizierà a squillare, e si dovrà attendere che qualcuno risponda, viene subito inviata una risposta provvisoria, e solo successivamente, una risposta definitiva (positiva o negativa) | " | invito e route set |
ACK | inviato dallo UA chiamante, verso lo UA chiamato, per confermare la ricezione di una risposta definitiva ad un INVITE. L'INVITE è l'unico metodo che attua questa forma di tree way handshake, inviando una risposta alla risposta. | " | invito e route set |
OPTIONS | inviato ad un altro UA od un Proxy, per chiedere le funzionalità disponibili all'altro estremo | 3261 (s11) | |
BYE | inviato da uno UA coinvolto in una sessione con uno o più altri UA, per manifestare l'intenzione di abbandonare la sessione, e che viene inoltrato agli altri UA in sessione. Non può essere usato per annullare un INVITE che non ha ricevuto ancora una risposta definitiva | " | invito e route set |
CANCEL | inviato per annullare una richiesta INVITE anche se non è ancora stata ricevuta una risposta definitiva, e può essere emesso oltre che da uno UA, anche da un proxy intermedio | 3261 (s9) | |
INFO | usato per inviare ad uno UA con cui si è già instaurata una sessione, delle informazioni relative ad eventi che avvengono dall'altro lato, come ad esempio, la pressione dei tasti del telefono. Questi vengono quindi trasmessi nel body di un messaggio INFO, descritto da un apposito header Content-Type: application/dtmf-relay | 2976 | |
REFER | viene tipicamente usato tra due parti che sono già in comunicazione, mettendo in grado chi lo riceve di eseguire una nuova chiamata, verso una destinazione indicata (da chi lo invia) mediante l'header Refer-to. Lo UA che riceve il REFER, dopo aver chiesto conferma (all'umano che lo gestisce), di eseguire la nuova chiamata, emette un nuovo INVITE verso la URI indicata, mentre il mittente del REFER viene notificato (mediante il metodo NOTIFY) dell'esito dell'operazione. | 3515 | |
SUBSCRIBE | consente a chi lo invia, di manifestare l'interesse a ricevere delle notifiche (mediante messaggi NOTIFY) della evoluzione di alcune variabili di stato, indicate mediante l'intestazione Event, in cui si fa riferimento ad un event package | 3265 | |
NOTIFY | tiene uno UA al corrente della evoluzione di alcune variabili di stato, può essere inviato anche senza aver prima ricevuto un SUBSCRIBE | " | |
PUBLISH | consente di aggiornare il valore delle variabili di stato, per le quali altre entità possono aver manifestato interesse mediante un SUBSCRIBE. | 3903 | |
MESSAGE | permette l'invio di messaggi istantanei, ospitati nel body e descritti da una intestazione Content-Type, convertendo lo UA in un messenger. | 3428 | |
PRACK | un messaggio di richiesta di Provisional Response ACK (PRACK) viene inviato da uno UAC che vuole riscontrare la ricezione di risposte temporanee ad un INVITE già inviato. Infatti, mentre le risposte definitive sono riscontrate dall'ACK, quelle temporanee no, e lo UAS che le invia, resta nel dubbio se siano arrivate. Alla ricezione del PRACK (che è una richiesta), lo UAS invia una risposta 200 OK (che non è quella all'INVITE, ma al PRACK), e lo UAC cessa di inviare PRACK | 3262 | |
UPDATE | permette di modificare i parametri di una sessione SIP (come l'insieme dei media e dei codec) senza alterare lo stato del dialogo; in particolare, può essere inviato prima di avere ricevuto una risposta definita all'INVITE iniziale. Alternativamente, può anche essere usato per modificare l'identità di un partecipante [RFC4916], senza determinare un nuovo scambio di offerta/risposta SDP. | 3311 |
In analogia a SMTP e HTTP, anche per SIP la prima linea dei messaggi di risposta ha un aspetto del tipo
SIP-Version SP Status-Code SP Reason-Phrase CRLF |
in cui la prima cifra dello Status-Code identifica la categoria della risposta in una delle seguenti classi:
La RFC 3261 contiene una sezione in cui si descrivono una serie di possibili messaggi di risposta.
Anche le intestazioni SIP hanno un aspetto del tutto simile a quelle già incontrate per l'SMTP e l'HTTP, sia pure con qualche differenza. Per uno stesso header possono infatti essere presenti più valori, separati da virgole, come espresso dalla ABNF:
header = "header-name" HCOLON header-value *(COMMA header-value) |
mentre per ogni valore, possono essere specificati dei parametri aggiuntivi, ognuno con il proprio valore, e separati da punto e virgola, in modo da arricchirne il potere espressivo, e permettere lo sviluppo di nuove estensioni
header-value = value *(;parameter-name=parameter-value) |
Un esempio di questa sintassi, può essere osservato in corrispondenza dell'header Contact del pacchetto n. 10 presente nel capture dell'esempio di registrazione.
La RFC 3261 contiene una sezione che elenca una grande quantità di header, assieme ad una tabella che ne specifica l'applicabilità nei contesti dei metodi di richiesta e dei codici di risposta, e del tipo di entità che li possono inserire, rimuovere e modificare; il loro elenco è mantenuto aggiornato presso IANA. In particolare, molte intestazioni sono semplicemente copiate nei pacchetti di risposta, a partire da quelle presenti nei pacchetti di richiesta. Per alcune di esse, ne viene indicato appresso l'utilizzo:
Intestazione | Commento | RFC | Esempio |
To | la URI del destinatario della richiesta | 3261 | |
From | rappresenta la URI di chi invia la richiesta; nelle risposte, sia From che To restano invariati | " | |
Call-ID | Un identificatore semi-casuale, che resta uguale per tutti i messaggi di uno stesso dialogo, ovvero è univocamente associato ad un INVITE iniziale | " | |
CSeq | è costituito da un numero seguito dal nome del metodo che ha dato inizio alla transazione. Il numero si incrementa di uno ad ogni nuova transazione di uno stesso dialogo, e resta uguale per tutti i messaggi della stessa transazione. | " | |
Via | inserito da ogni UAC che invia (o inoltra) una richiesta SIP, in cui indica il proprio indirizzo, porta, trasporto, ed un parametro branch utile per distinguere le diramazioni di un messaggio forkato. Ogni elemento di transito che deve inoltrare la risposta, rimuove l'intestazione da lui inserita, ed usa quella rimasta in cima per determinare a chi inviarla. In questo modo non occorre consultare il DNS, ed è sufficiente un Proxy Stateless | " | via |
Max-Forwards | utile per limitare il numero di volte che un messaggio è inoltrato | " | |
Contact | contiene uno o più URI presso le quali il mittente di una richiesta desidera essere ricontattato | " | |
Allow | annuncia i metodi supportati da una entità | " | |
Supported | elenca le estensioni supportate, tra quelle elencate presso IANA | " | |
Record-Route | specifica la volontà di un Proxy, di essere mantenuto nel path dei futuri messaggi del dialogo | " | |
Route | indica la sequenza di Proxy che il messaggio dovrà attraversare, determinato a seguito delle richieste espresse mediante gli header Record-Route, come descritto più avanti | " | invito e route set |
Per la definizione di SIP si è fatto ricorso alla suddivisione delle sue funzioni in termini stratificati, distinguendo, dal basso verso l'alto
Per quanto appena discusso, osserviamo che mentre lo strato di transazione si prende carico dell'effettivo scambio di tutti i messaggi che intercorrono tra UAC e UAS, necessari allo svolgimento di una funzione elementare di SIP, i pacchetti effettivamente scambiati a questo fine, sono visti dal TU come una unica Transazione.
La RFC 3261 distingue i comportamenti associati a transazioni iniziate con un INVITE o meno.
Nel primo caso, se la risposta definitiva è 200 OK, la trasmissione dell'ACK non viene considerata parte della transazione, ed è effettuata a cura del TU dello UAC. Dal lato del chiamato, è il TU dello UAS che si prende carico di ritrasmettere il 200 OK, finché non riceve il corrispettivo ACK. Se invece la risposta appartiene alle classi 3xx-6xx, questa viene assorbita dallo strato di transazione dello UAC, che provvede a generare per suo conto l'ACK, mentre lo strato di transazione dello UAS provvede a ritrasmettere le risposte, finché non sono riscontrate dall'ACK.
Nel caso di transazioni non legate ad una richiesta INVITE, lo strato di transazione dello UAC continua autonomamente a reinviare la richiesta finché non riceve una risposta, mentre è lo strato di transazione dello UAS a re-inviare le risposte, per ogni richiesta ricevuta.
Quando un UAC riceve una risposta, deve ricombinarla assieme alla richiesta originaria. Per questo, devono corrispondere due cose:
![]() |
![]() |
Tutti i messaggi scambiati tra due UA dall'inizio di una comunicazione alla sua conclusione, vanno a costituire un dialogo, che è individuato presso ogni UA in base al valore della intestazione Call-ID, al tag locale, ed al tag remoto. Questi tag sono stringhe inserite dagli UA come parametri degli header From: e To:, come ad es.
From: "alef"
<sip:alef@ing.uniroma1.it>;tag=xglhe To: "aalef_59" <sip:aalef_59@proxy01.sipphone.com>;tag=n448pds8f6igkkn3gt0ehij2 |
Il valore (ed associato tag) degli header To e From presente nelle risposte si mantiene lo stesso di quello che compare nelle relative richieste, cosicché i tag si scambiano di ruolo: presso il chiamante, il tag locale è espresso come parametro del From, e quello remoto viene letto dal parametro tag associato al To, al momento della ricezione della risposta. Presso il chiamato invece, il tag locale è assocato al To, e quello remoto al From.
La tripla di valori Call-ID, from-tag e to-tag inizia ad esistere su entrambi gli UA, a seguito della ricezione da parte dello UA chiamante di una risposta provvisoria 1xx contenente il to-tag, ponendo il dialogo in una fase precoce, che diviene confermata quando lo stesso to-tag è presente anche nella risposta definitiva 200 OK. Il dialogo cessa di esistere nel caso in cui non pervenga nessuna risposta definitiva, o se previene un CANCEL prima della stessa, oppure se la risposta definitiva non è un successo, mentre se è un successo, cessa di esistere a seguito della ricezione di una richiesta di BYE, e della relativa risposta.
Durante il dialogo, la tripla che lo individua è presente in tutti i messaggi che vi fanno parte, permettendone la contestualizzazione da parte di chi li riceve, in base alla esistenza di uno stato condiviso rappresentato dagli altri parametri del dialogo, come i valori dei CSeq delle due parti (che si incrementano ad ogni transazione del dialogo, ma restano costanti per i diversi messaggi della stessa transazione), le URI locale e remota, i parametri usati dalle estensioni, e la lista dei Proxy che deve essere attraversata dagli altri messaggi del dialogo.
Per un esempio, possiamo fare riferimento al capture della procedura di INVITE.
Una Sessione è individuata, oltre che dalla relazione tra una (o più) coppia di entità definita dal dialogo, anche dal (dai) tipo di media che verrà usato nel corso della stessa. Il desiderio di creare una nuova sessione è espresso con l'invio di un messaggio iniziale di INVITE, mediante il quale avviene la negoziazione dei parametri necessari alla trasmissione multimediale, basata su di un paradigma offerta-risposta; la sessione è quindi definitivamente creata a seguito dell'individuazione dell'insieme dei tipi di media che saranno usati per la comunicazione. L'offerta può essere formalizzata
La risposta all'offerta consiste in una scelta tra le possibilità offerte, e viene veicolata nei due casi, rispettivamente, mediante l'inserimento di una descrizione SDP nel body del primo messaggio di risposta definitiva, ovvero nel body del messaggio di ACK.
Nel caso in cui pervengano più risposte definitive per lo stesso INVITE, come nel caso in cui questo sia stato forkato, oppure inviato in multicast, ognuna di queste determina la creazione di un diverso dialogo, e tutti i dialoghi vengono a far pare della medesima sessione.
Una sessione può essere modificata durante la sua esistenza mediante l'invio di un nuovo INVITE (detto re-INVITE), da parte di una delle parti che aderiscono alla sessione, ossia anche su iniziativa del chiamato. La modifica può riguardare, ad esempio, l'aggiunta di un nuovo media (ad esempio, video) alla sessione, e consistere quindi nell'inizio di un nuovo ciclo di offerta-risposta, attuato come già illustrato. A differenza dell'INVITE originario, un re-INVITE non può essere forkato, in quanto diretto alle parti già in comunicazione.
Una sessione può essere terminata mediante l'invio di un BYE su iniziativa di una delle due parti dell'unico dialogo della sessione, mentre se la sessione è condivisa tra più parti, il BYE termina unicamente il dialogo corrispondente. Alternativamente, la sessione viene terminata a seguito della ricezione di una risposta definitiva di tipo diverso da 2xx. Infine, la sessione può essere terminata a seguito della ricezione di una richiesta CANCEL.
L'associazione di un Contact Address con un AoR che si realizza ad opera di uno UA che contatta un Registrar è una operazione che, se eseguita senza autenticare lo UA e verificarne l'autorizzazione ad usare quell'AoR, permetterebbe a chiunque di ricevere le telefonate SIP in realtà dirette a qualcun altro. Pertanto, qualunque provider VoIP minimamente serio svolge in tal caso una verifica del possesso, da parte dello UA che richiede la registrazione, delle credenziali. In linea con il resto delle specifiche, anche l'autenticazione SIP ricalca i metodi già visti per l'HTTP, e si basa sul metodo Digest, ovvero il Registrar risponde allo UA con una status line 401 Unauthorized, in cui inserisce anche l'intestazione di sfida WWW-Authenticate. Per rispondere alla sfida, l'utente dello UA utilizzerà il segreto condiviso, o password, concordato a tale scopo con il provider VoIP che gestisce il Registrar, e che gli ha rilasciato l'AoR.
Allo stesso modo, anche i messaggi inviati da uno UA al proprio Outbound Proxy devono essere autenticati, in modo da impedire al Proxy di comportarsi come un OpenRelay, non consentendo perciò di inoltrare richieste provenienti da chiamanti sconosciuti. Nel caso (come è spesso) in cui Registrar e Outbound Proxy coincidano, viene ovviamente usata la stessa password stabilita in precedenza; altrimenti, occorre far riferimento da parte di entrambi, ad uno stesso authentication server.
Le procedure di autenticazione illustrate risolvono però solo in parte il problema; infatti resta aperta la questione di come realizzare l'autenticazione tra Outbound Proxy di partenza, e Registrar di destinazione, nel caso in cui questo dipenda da un diverso provider VoIP, senza contare la presenza di eventuali altri Proxy intermedi. Mentre infatti tra UA, Registrar, e Outbound Proxy, i rapporti sono diretti, e mediati da uno stesso soggetto VoIP provider, non è pensabile poter stabilire un segreto condiviso tra tutte le coppie di Proxy presenti in Internet, e quindi non si può realizzare una catena di fiducia, rischiando replicare il fenomeno dello spam email nella forma di telefonate anonime o da numeri falsi. Per non appesantire la trattazione, si rimanda alle soluzioni illustrate nella successiva sezione su Sip Peering.
Ogni entità che invia (o inoltra) una richiesta, aggiunge una intestazione Via al messaggio, in cima a quelle già presenti, in cui sono indicati l'indirizzo IP, il trasporto, e la porta usati dallo UAC, più un parametro branch che contiene una stringa creata semi-casualmente per l'occasione, e che viene citata nelle risposte, allo scopo di distinguere tra loro le diverse risposte che possono provenire da UAS situati su rami diversi di un fork. Lo UAS che riceve la richiesta è in grado di correggere l'intestazione Via, nel caso in cui l'indirizzo IP e/o la porta citati dal mittente, siano differenti da quelli effettivamente osservati dal socket su cui la richiesta è pervenuta, ad es. perché il richiedente è NATtato: in questo caso, viene aggiunto al Via un parametro received= in cui si indicano i dati corretti e/o mancanti, come nell'esempio seguente.
Quando una richiesta raggiunge lo UAS di destinazione, e questo genera una risposta, non inserisce nessuna nuova intestazione Via, ma usa quella in cima a tutte, per determinare a chi inviare la risposta, in cui include anche tutte le altre intestazioni Via. Se la risposta è ricevuta da un Proxy intermedio, questo dopo aver rimosso l'intestazione Via che lui stesso aveva inserito, usa a sua volta il Via in cima alla pila, per individuare a chi restituire la risposta, e così via, fino allo UAC originario.
Quando un Proxy inoltra una richiesta che determina la creazione di un dialogo (tipicamente, un INVITE), può richiedere di rimanere nel path delle successive transazioni appartenenti allo stesso dialogo. Per questo, prima di inoltrare il messaggio, vi inserisce un header Record-Route in cui dichiara la propria URI. Se anche altri Proxy lungo il tragitto della richiesta di inizio dialogo vogliono restare nel path, aggiungono a loro volta una intestazione Record-Route in testa alle altre. Quando la richiesta arriva allo UA di destinazione, questo memorizza gli indirizzi trovati nelle intestazioni Record-Route in un route set, che entrerà a far parte del contesto da applicare agli altri messaggi del dialogo, non appena la sua creazione verrà confermata dal messaggio di ACK.
La risposta che ora lo UA chiamato invia verso il chiamante utilizza la catena dei Via per ritrovare la strada verso il chiamante, e contiene inalterata la lista dei Record-Route costruita nel viaggio di andata, dato che i Proxy aggiungono i Record-Route nelle richieste, e non nelle risposte. Quando la risposta arriva allo UA chiamante, se questa è di successo, il route set viene memorizzato anche da questo lato.
Da questo momento in poi, quando uno UA invia una richiesta appartenente ad un dialogo, vi inserisce un header Route, in cui copia il route set associato al dialogo; quindi, aggiunge un Via con il proprio indirizzo, ed usa il primo elemento del route set, per determinare a chi inviare la richiesta, indipendentemente dal valore della intestazione To, e della request-URI. Nel caso in cui si sia configurato un Outbound Proxy, questo comparirà come primo elemento del route set. Il Proxy che riceve questa richiesta, rimuove il proprio indirizzo dall'elenco che compare nel Route, ed usa l'indirizzo successivo, per inoltrare a sua volta la richiesta.
Con questo termine, i Proxy SIP annunciano la propria conformità alla RFC 3261, in contrapposizione a quelli il cui comportamento è definito dalla precedente RFC 2543, detti Strict Routers. Un Proxy annuncia il proprio comportamento da loose router aggiungendo nelle intestazioni che modifica, il parametro ;lr, oppure ;lr=on.
Nella procedura di registrazione uno UA invia al proprio Registrar una richiesta (con il metodo REGISTER) con cui si richiede di associare il proprio AoR all'indirizzo IP comunicato mediante l'header Contact: nel caso in cui l'operazione vada a buon fine, il Registrar invia il messaggio di risposta 200 OK. Come risultato, il Registrar ha memorizzato la corrispondenza AoR-Contact in un Location Database, che verrà interrogato in seguito, nel caso di chiamate entranti, per localizzare l'utente.
In questo file di capture, relativo alla procedura di registrazione per l'AoR alef@ing.uniroma1.it e catturato presso lo UA, possiamo apprezzare il formato dei messaggi, e svolgere una serie di interessanti osservazioni.
Via: SIP/2.0/UDP 192.168.1.100;rport=1024;branch=z9hG4bKscwclcls;received=151.49.83.143 |
Contact:
<sip:alef@192.168.1.101;transport=UDP>;expires=2590; received="sip:151.49.83.143:5060", <sip:alef@192.168.1.100>;expires=3600; received="sip:151.49.83.143:1024" |
La possibilità di associare un medesimo AoR a diversi Contact Address che possono cambiare cambiare di volta in volta, è la caratteristica di SIP che permette ad un utente di poter continuare ad utilizzare il servizio anche a partire da punti di accesso alla rete di volta in volta diversi.
Nella procedura di invito, è pratica comune che la richiesta INVITE,
prima di raggiungere lo UAS chiamato, attraversi almeno due proxy: l'Outbound Proxy del chiamante, e il Proxy/Registrar
del chiamato. Questa forma di instradamento prende il nome di trapezoide
SIP, in base al particolare modo di raffigurare l'instradamento,
riportato a fianco.
Notiamo che nell'esempio riportato, la richiesta BYE che termina la comunicazione viene inviata direttamente, senza attraversare i due proxy. Questo può avvenire per il verificarsi di due condizioni:
Qui sotto, osserviamo un nuovo disegno un pò più dettagliato, che mette in evidenza la fase di richiesta al DNS necessaria a scoprire il proxy server di destinazione. Ciò che invece non è mostrato, è l'interrogazione del Proxy di destinazione al Location Database mantenuto aggiornato dal Registrar di b.com: evidentemente, in questo caso il location database risulta residente nel medesimo computer che ospita il Proxy.
Nel diagramma di flusso che segue è riportato un esempio in cui l'Outbound Proxy ed il Registrar vengono a coincidere, e viene posta in evidenza la sequenza dei messaggi che vengono scambiati tra UAC del chiamante e lo UAS del Proxy, e quindi tra lo UAC del Proxy e lo UAS del chiamato.
Come si vede, il Proxy invia immediatamente una risposta temporanea di tipo 100 Trying, allo scopo di riscontrare lo UAC della avvenuta ricezione della richiesta INVITE, ed arrestare il re-invio della richiesta. Quindi,
Siamo ora pronti ad esaminare il risultato di un Capture di traffico reale, così come ottenuto presso il chiamante, e relativo alla chiamata che alef@ing.uniroma1.it esegue verso aalef_59@proxy01.sipphone.com, utilizzando come Outbound Proxy il nome a dominio ing.uniroma1.it. Possiamo osservare che:
From: "alef"
<sip:alef@ing.uniroma1.it>;tag=xglhe Call-ID: yptkdmnnttnquhc@192.168.1.101 CSeq: 986 INVITE |
Content-Type: application/sdp Allow: INVITE,ACK,BYE,CANCEL,OPTIONS,PRACK,REFER,NOTIFY,SUBSCRIBE,INFO Supported: replaces,norefersub,100rel |
Record-Route:
<sip:198.65.166.131;ftag=xglhe;lr;transport=UDP>, <sip:aalef_59@151.100.122.144:5060;nat=yes;ftag=xglhe;lr=on> To: "aalef_59@proxy01.sipphone.com" <sip:aalef_59@proxy01.sipphone.com>;tag=n448pds8f6igkkn3gt0ehij2 Contact: <sip:aalef_59@151.49.97.148:5060;transport=UDP;nat=yes> Allow: INVITE,ACK,BYE,CANCEL,REFER,NOTIFY,OPTIONS,PRACK |
ACK
sip:aalef_59@151.49.97.148:5060;transport=UDP;nat=yes SIP/2.0 Route: <sip:aalef_59@151.100.122.144:5060;nat=yes;ftag=xglhe;lr=on>, <sip:198.65.166.131;ftag=xglhe;lr;transport=UDP> To: "aalef_59@proxy01.sipphone.com" <sip:aalef_59@proxy01.sipphone.com>;tag=n448pds8f6igkkn3gt0ehij2 CSeq: 986 ACK |
Sempre prendendo ad esempio il Capture già esaminato, possiamo osservare che al pacchetto numero 1099 lo UA chiamante invia un messaggio SIP di BYE, instradato mediante l'ultimo Proxy presente nella catena descritta dal Record-Route (151.100.122.144), e le cui intestazioni lo mettono in relazione con il dialogo corrente. Quindi, al pacchetto 1103 sempre lo UA chiamante invia un pacchetto RTCP con PT 203 (Goodbye) direttamente allo UA chiamato, cessando al contempo l'invio di pacchetti RTP, e chiudendo il socket sul quale riceveva l'RTP del chiamato, causando da quel momento in poi una serie di messaggi ICMP Port unreachable. Dopo circa 500 msec, al pacchetto numero 1134, il messaggio SIP di BYE viene reiterato, e quindi, sono ricevute (dal proprio Proxy) due risposte 200 OK, una per ogni BYE, in cui l'intestazione RemoteIP comunica l'indirizzo dello UA remoto (151.49.97.148) a cui si riferisce il dialogo (e la sessione) che si sta chiudendo.
Lo scopo di SIP non è affatto limitato a raggiungere altre URI SIP, ma (mediante dispositivi gateway) è possibile contattare anche telefoni fissi e mobili, o essere raggiunti dagli stessi presso il proprio softphone: in entrambi i casi, occorre affidarsi ad un meccanismo capace di mettere in relazione le URI letterali del mondo SIP, con i numeri di telefono E.164 del mondo PSTN.
Qualora uno UA emetta un INVITE la cui Request-URI è un numero E.164 anziché un AoR, l'outbound Proxy se ne accorge, ed anziché interrogare il DNS per individuare il Registrar del(l'omesso) dominio di destinazione, interroga il DNS per scoprire se esistono RR NAPTR che (in accordo ad ENUM) mappano il numero su di una URI SIP. In caso negativo, inoltra l'INVITE al dispositivo gateway che è configurato ad usare, eventualmente scelto in base al prefisso E.164, che a sua volta si avvarrà della segnalazione PSTN per realizzare l'instradamento su rete telefonica.
Se viceversa è un telefono PSTN a voler chiamare uno UA SIP, non avendo a disposizione altro che i numeri della tastiera telefonica, il numero chiamato dovrà essere proprietà di un provider VoIP, e da questi assegnato ad un proprio utente. Il provider VoIP inoltra quindi la chiamata al proprio gateway PSTN-SIP e che raggiunge così l'utente chiamato.
La tecnica indicata come ENUM permette ad un utente VoIP di pubblicizzare come proprio unico contatto il solo numero telefonico, che se chiamato a partire da uno UA SIP, viene convertito nell'AoR dell'utente, a cui è quindi inoltrata la chiamata via VoIP.
Il Session Description Protocol (SDP) non definisce un insieme di messaggi (come è invece per SIP) che possono essere scambiati tra dispositivi in rete, bensì costituisce una sintassi in grado di descrivere i parametri che caratterizzano una trasmissione multimediale Internet, che a sua volta ha luogo mediante incapsulamento RTP.
SDP è descritto dalla RFC 4566 del 2006, ma la sua prima definizione iniziale risale al 1998, come meccanismo per distribuire gli annunci di sessione relativi alle conferenze multicast di Mbone, in modo da indicare il tipo di codifica audio-video mediante i quali sono distribuiti i media, e gli indirizzi IP multicast e di trasporto, presso i quali gli aderenti si dovevano (per così dire) sintonizzare.
Oltre all'uso originale, una descrizione SDP può essere distribuita mediante una URI HTTP, oppure come parte MIME di una email, utilizzando un header Content-Type: application/sdp. In questo caso, l'SDP può ancora essere usato per ricevere una sessione multicast, ammesso che l'instradamento multicast raggiunga il potenziale partecipante. D'altra parte, non necessariamente una sessione multimediale deve rappresentare una conferenza tra più parti, bidirezionale, ed in tempo reale: più banalmente, può essere unidirezionale, e/o relativa ad un evento registrato. Per questo, è stato definito l'RTSP, mediante il quale dei player unicast possono richiedere la ricezione di un contentuto multimediale, e che pure usa l'SDP come sintassi di descrizione dei contenuti, mentre altri aspetti della negoziazione dei parametri di trasmissione, sono gestiti dall'RTSP.
La particolarità dell'uso di SDP nel contesto di SIP, è quello di consentire l'attuazione di un meccanismo di offerta/risposta (descritto nella RFC 3264), tale da permettere a due entità di accordarsi su modalità comuni di trasmissione multimediale.
Analizziamo gli elementi di una descrizione SDP, a partire da quella contenuta nel pacchetto numero 8 del capture relativo all'esempio dell'INVITE, a cui per chiarezza sono stati aggiunti dei commenti:
v=0
# version o=alef 326810211 397034952 IN IP4 192.168.1.101 # origin s=- # session name c=IN IP4 192.168.1.101 # contact t=0 0 # tempo di inizio e fine m=audio 8000 RTP/AVP 98 97 8 0 3 101 # media description a=rtpmap:98 speex/16000 # attributo sottotipo del PT 98 a=rtpmap:97 speex/8000 a=rtpmap:8 PCMA/8000 a=rtpmap:0 PCMU/8000 a=rtpmap:3 GSM/8000 a=rtpmap:101 telephone-event/8000 a=fmtp:101 0-15 # formato per il Payload Type 101 a=ptime:20 # intervallo tra pacchetti di # 20 msec |
Un SDP è composto da una serie di linee, dove il primo carattere individua un elemento sintattico, ed il cui tipo determina la semantica di ciò che segue il segno di uguale. La prima linea v= indica la versione dell'SDP (per ora, esiste solo la versione 0), e individua la sezione di SDP comune a tutta la sessione. Ogni linea che inizia per m= indica l'inizio della sezione specifica di un media. Gli elementi comuni mostrati nell'esempio sono solo quelli obbligatori, mentre la RFC 4566 ne prevede diversi altri opzionali.
L'elemento s= indica il session name, utile nel caso di conferenze Multicast, mentre per l'uso con SIP è irrilevante, e quindi sostituito da un segno meno; un discorso analogo vale per l'elemento time t=. L'elemento Origin o= ha una sintassi
o=<username> <sess-id> <sess-version> <nettype> <addrtype> <unicast-address> |
e, a parte per il campo <sess-version>, costituisce un identificativo della sessione globalmente unico, mentre <sess-version> permette di distinguere tra versioni successive della stessa sessione. Il campo <unicast-address> indica il computer presso il quale la sessione è state definita.
L'elemento contact c= può comparire solo nella sezione generale, oppure in ogni sezione specifica di un media, e indica l'indirizzo del computer che eroga i (il) media, oppure il gruppo multicast verso cui viene trasmessa; in quest'ultimo caso, occorre specificare anche un Time To Live multicast.
L'elemento media description m= ha un formato
m=<media> <port> <proto> <fmt> ... |
in cui
Gli elementi attribute a= sono il meccanismo con cui è possibile estendere l'espressività di SDP, per mezzo della definizione di nuovi nomi. Possono comparire sia nella sezione generale, tipicamente per meglio caratterizzare una sessione multicast, ad esempio descrivendola in termini di parole chiave, o categorie gerarchiche, oppure ancora, indicare il verso della comunicazione, come nel caso di a=recvonly, a=sendonly, a=sendrecv, (che è il default, se non specificato).
Quando invece gli elementi a= compaiono nella sezione specifica per un media, possono veicolare informazioni relative alla temporizzazione, alla qualità, a parametri del codec, ma l'uso più diffuso è quello di associare a ciascuno dei PT dichiarati dall'elemento m=, e non completamente descritti dall'AVP, il corrispettivo codec, frequenza di campionamento, ed eventuali altri parametri, in accordo alla sintassi
a=rtpmap:<payload type> <encoding name>/<clock rate> [/<encoding parameters>] |
in cui encoding name è scelto in modo che, combinandolo assieme al nome del media che compare nell'elemento m= relativo, si ottenga il nome di un MIME Type costruito come media/encoding name, del tipo di quelli registrati presso IANA.
Così, tornando ad esaminare l'esempio fornito, osserviamo che chi invia l'SDP comunica l'intenzione di ricevere il media audio sulla porta 8000, pacchettizzato in RTP su UDP, e dichiara di essere in grado di ricevere 6 diversi PT, i primi cinque dei quali sono relativi a codec audio, di cui il primo wideband (campionato a 16 KHz), mentre il sesto PT rappresenta la pressione di un tasto del telefono, e l'elemento a= viene usato per specificare in formato del media (a=fmtp:101 0-15 individua uno dei sedici DTMF). Infine, con a=ptime:20 viene specificato che ogni pacchetto RTP, corrisponde a 20 msec di segnale.
La RFC 3264
descrive le modalità secondo cui SDP può essere usato, assieme a SIP,
per negoziare i parametri di una trasmissione multimediale. In questo
modo, chi invia l'offerta compila una lista di media e di Payload Type
(PT) che è in grado di gestire, in ordine di preferenza, e permette a
chi invia la risposta di esprimere la sua scelta, allegando un diverso
SDP, creato sulla base di quello ricevuto, ed in cui sono indicati i PT
disponibili tra quelli indicati nell'offerta.
La risposta conterrà una diversa linea o=, indicativa di chi risponde, una linea t= uguale a quella dell'offerta, ed un numero di sezioni media pari al numero di sezioni presenti nell'offerta, disposte secondo lo stesso ordine. Il numero di porta indicato nelle linee m= indica ora la porta su cui chi risponde intende ricevere il media incapsulato in RTP, e per rifiutare in toto un determinato media, viene indicato un numero di porta pari a zero. Nel caso di sessioni unidirezionali, anche chi trasmette solamente dovrà indicare un numero di porta diverso da zero, consentendo comunque la ricezione del canale RTCP di ritorno. Accettando l'offerta per un media classificato come sendonly o receiveonly, nell'SDP di risposta si indicherà per lo stesso una modalità rispettivamente receiveonly o sendonly. Chi risponde, può specificare un intervallo di pacchettizzazione (con a=ptime:xx) diverso da quello dell'offerta.
Una volta inviata la risposta, il chiamato deve essere pronto a ricevere i media per i quali ha individuato dei codec opportuni, usando i parametri indicati nella risposta, e può iniziare a trasmettere, in accordo ai parametri contenuti nell'offerta. Una volta ricevuta la risposta, il chiamante deve iniziare a ricevere l'RTP sulla porta indicata nell'offerta, ed a trasmettere verso la porta indicata nella risposta. Per ogni media e per ognuna delle due parti, la trasmissione avviene usando uno dei PT presenti in entrambi gli SDP scambiati, con l'ordine di preferenza indicato. Durante la sessione, una delle due parti può cambiare il codec usato per la trasmissione, e usarne un altro scelto tra quelli negoziati, per attuare ad esempio una codifica a bassa velocità nei periodi di silenzio, oppure per inviare dei DTMF via RTP.
Durante la conversazione, una delle due parti può iniziare un nuovo ciclo di offerta-risposta, inviando un nuovo INVITE, allo scopo di modificare i parametri della sessione multimediale. Può essere proposto un nuovo insieme di PT per gli stessi media (ad esempio, a causa di una variazione di potenza computazionale, in base a considerazioni di risparmio energetico, oppure a mutate condizioni di qualità del collegamento), oppure possono essere aggiunti e/o rimossi nuovi media (ad es., video), e/o modificati indirizzo e porta del collegamento, oppure l'altra parte può essere messa in attesa.
Ritornando ad esaminare il capture relativo all'esempio dell'INVITE, ecco di seguito l'SDP di risposta contenuto al pacchetto numero 11:
v=0 o=Nokia-SIPUA 326810212 397034953 IN IP4 151.49.97.148 s=- c=IN IP4 198.65.166.131 t=0 0 m=audio 40822 RTP/AVP 8 101 a=ptime:20 a=maxptime:200 a=fmtp:101 0-15 a=rtpmap:8 PCMA/8000/1 a=rtpmap:101 telephone-event/8000/1 a=nortpproxy:yes |
Questo SDP è generato da uno UA cordless VoIP, come risulta dalla linea o=, dove compare l'IP pubblico del router WiFi da cui ottiene la connettività Internet. Ciononostante, nella linea c= è riportato l'indirizzo IP di un elemento RTP proxy inserito nel path dei media, dal provider VoIP. Per quanto riguarda il media audio, la risposta presenta un unico valore di PT, il pcm legge A. Oltre a confermare (a=ptime:20) un intervallo tra pacchetti di 20 msec, l'SDP avverte che questo può crescere fino a 200 msec (a=maxptime:200). Infine, l'attributo non-standard a=nortpproxy:yes segnala che non occorre provvedere all'inserimento di altri elementi di attraversamento NAT.
L'RTP è attualmente formalizzato dalla RFC 3550 del 2003, ma il suo primo draft risale al 1993. Rappresenta la modalità con cui lo strato applicativo incapsula i dati multimediali, prima di consegnarli ad un trasporto basato su UDP, in accordo allo schema riportato appresso, assieme al quale è indicato il calcolo della quantità minima totale delle informazioni di overhead; notiamo inoltre che il carico utile, ossia i dati multimediali trasportati, è indicato come payload.
![]() |
|
I motivi per cui si preferisce usare UDP piuttosto che TCP, possono riassumersi in
D'altra parte, l'assenza totale di funzionalità di controllo (di flusso, di errore e di congestione) da parte dell'UDP, viene sanata dall'uso congiunto del Real Time Transport Control Protocol (RTCP), che anzichè trasportare dati, invia all'indietro (ad una velocità molto ridotta) informazioni di controllo come numero di pacchetti persi, ritardo e jitter. RTCP viene altresì inviato anche nella stessa direzione dell'RTP, per trasportare informazioni aggiuntive sul media contenuto nell'RTP. Contrariamente a molti altri casi discussi finora, l'RTP non usa un numero di porta ben nota, e l'unica convenzione adottata è di inviarlo su di un numero di porta pari, mentre sul numero di porta dispari immediatamente successivo, viene inviato l'RTCP.
Inoltre, le particolarità che i dati multimediali trasportati impongono all'RTP sono descritte da un profilo di utilizzo dell'RTP stesso, ovvero da un documento addizionale che specifica l'interpretazione da dare ad alcuni campi dell'RTP che sono specificatamente previsti per la descrizione della natura del payload, ed agli elementi informativi che RTP prevede per quel payload. In particolare, la quasi totalità delle applicazioni aderisce all'Audio Video Profile, o AVP, descritto nel seguito.
Infine, una applicazione che voglia trasmettere/riprodurre dati multimediali trasportati su RTP necessita di ulteriori specifiche, ovvero la definizione dei formati di codifica, che descrivono come una particolare rappresentazione dei dati (codec) determini la modalità di interpretazione di quanto è contenuto nel payload, e come i dati multimediali codificati siano segmentati e pacchettizzati.
Prima di descrivere il formato delle intestazioni RTP, che concretizzano gli aspetti ora introdotti, svolgiamo alcune considerazioni più generali, relative alla problematica della trasmissione multimediale su IP.
Mentre nella trasmissione dati è inammissibile che alcuni
pacchetti vadano persi, nelle trasmissioni multimediali le eventuali
discontinuità nella trasmissione vengono interpolate
cognitivamente,
e non costituiscono un reale impedimento alla comunicazione
(ovviamente, entro certi limiti). Invece, un elemento determinante ai
fini della usabilità della comunicazione interattiva è costitito dal
ritardo di Round Trip Time percepito, che
dovrebbe essere mantenuto al disotto dei 200 msec, in modo da preservare
la piena interattività dell'interloquio.
Occorre inoltre tenere conto che il ritardo di propagazione p della rete può variare, e la quantificazione di tale variazione è indicata con il termine di Jitter, anche se questo termine nasce per indicare solo le irregolarità statistiche di un dispositivo di temporizzazione (ad esempio, nell'audio HiFi). Le cause dell'insorgenza del Jitter in Internet sono le più disparate, ma l'effetto è che, prima di procedere alla riproduzione del segnale ricevuto, questo deve essere accodato in un buffer in modo da assorbire le variazioni di ritardo.
La
figura
a lato ci aiuta a definire il criterio di dimensionamento del
buffer di riproduzione. Sulle ordinate è riportata la percentuale di
pacchetti che pervengono con un ritardo compreso in una griglia di
intervalli temporali mostrati in ascissa, con gli intervalli di durata
pari al tempo necessario a produrre il segnale codificato in un
pacchetto; sempre sulle ascisse è quindi mostrata la playout
buffer size necessaria ad assorbire
gran parte della variabilità dei ritardi, determinata in modo che
la percentuale di pacchetti
pervenuti in tempo utile (per poter riprodurre il segnale che
trasportano) sia sufficentemente elevata, in modo da non penalizzare
troppo la qualità dell'ascolto; allo stesso tempo, il ritardo
introdotto deve essere mantenuto basso, in modo da non pregiudicare
l'interattività della conversazione.
Per fissare le idee, consideriamo l'array
circolare mostrato
a lato, in cui i dati sono scritti e letti da sinistra a
destra, alla/dalla posizione di memoria individuata dai puntatori di
scrittura e lettura; quando uno di questi arriva in fondo, ricomincia
dall'inizio. Ad inizio operazioni entrambi i puntatori sono a
zero, e man mano che arrivano pacchetti, questi sono scritti in
sequenza ed il puntatore di scrittura incrementato (tralasciamo per
semplicità la gestione degli arrivi fuori sequenza). Quando la distanza
tra puntatori è pari alla dimensione del playout buffer, viene inviato
in riproduzione il primo pacchetto arrivato, ed il
puntatore di lettura incrementato, pronto a leggere il secondo
pacchetto, al termine della riproduzione del primo, e così via. Qualora
il ritmo di arrivo si riduca, ovvero in presenza di un sensibile
aumento del ritardo di propagazione, può accadere che il puntatore di
lettura si sovrapponga a quello di scrittura, ed in tal caso si
verifica l'evento di perdita di pacchetto.
Dato che la distribuzione dei ritardi deve essere valutata in base alle condizioni di rete effettive, ed al fine di individuare una soluzione di compromesso tra le due esigenze contrastanti di pochi pacchetti scartati e basso ritardo, le soluzioni migliori sono quelle che effettuano un dimensionamento adattativo del buffer di riproduzione, tipicamente riducendone la dimensione nei momenti di inattività vocale, e aumentandola se la percentuale di pacchetti scartati tende ad aumentare.
Osserviamo infine che nel caso in cui la quantità di dati (bit) trasportati sia uguale per ogni pacchetto, la dimensione del buffer corrisponde ad una estensione di memoria fisica, mentre se la quantità di bit a pacchetto è variabile, rappresenta unicamente il numero di pacchetti da accodare nel buffer.
La RFC 3550
descrive un metodo di calcolo idoneo a fornire come risultato un intero a
32 bit da inserire nel campo Reception Report
dei pacchetti RTCP di tipo Receiver Report, e che esprime la stima del jitter
in unità di timestamp,
ossia di quanti campioni (in più o in meno) l'intervallo medio tra i
tempi di arrivo di due pacchetti si discosta rispetto all'intervallo
nominale previsto. Ad esempio,
se il timestamp
si incrementa di 160 campioni ad ogni pacchetto (pari a 20 msec per un
segnale campionato a 8 kHz), mentre il tempo che intercorre tra
l'arrivo di due pacchetti si alterna tra i valori di 30 e 10 msec
(equivalenti ad una distanza, espressa in numero di campioni, pari a
240 e 80 campioni rispettivamente), allora il jitter, corrispondente a
10 msec, può essere espresso come pari a 80 campioni.
In questi termini, se indichiamo con Si il timestamp del pacchetto i e con Pi il suo tempo di propagazione, allora Ri = Si+Pi rappresenta il suo tempo di arrivo espresso in unità di timestamp, e la differenza D tra i tempi di propagazione di due pacchetti i e j (i<j) rispetto al caso di uguali tempi di propagazione, può essere espressa come
D(i,j) = Pj - Pi = (Rj - Sj) - (Ri - Si) = (Rj - Ri) - (Sj - Si) |
che fornisce zero in assenza di jitter, od un numero positivo o negativo in sua presenza. Anche se il ricevitore non conosce il tempo di propagazione, può comunque calcolare D(i,j) in quanto conosce gli istanti di arrivo, e trova quelli di partenza nei timestamp presenti nell'RTP. La stima del jitter medio J si ottiene quindi realizzando una operazione di media mobile mediante la formula ricorsiva
J(i) = J(i-1) + (|D(i-1,i)| - J(i-1))/16 |
che possiamo commentare così:
Anche
se un accurato dimensionamento del buffer può riuscire a scongiurare
quasi completamente il rischio di ricevere i pacchetti con eccessivo
ritardo, nulla si può fare nel caso in cui alcuni pacchetti siano stati
completamente scartati lungo il tragitto da
sorgente a destinazione. In tal caso l'unico rimedio è quello di
ricorrere a tecniche di protezione di tipo FEC (Forward
Error Correction), realizzate inserendo in ogni pacchetto, oltre
ai dati prodotti dal codec per l'i-esima
finestra di segnale, anche i dati prodotti per la finestra i-1,
in modo da poter ripristinare i dati del pacchetto mancante, oppure
i-2, per proteggersi da perdite di due pacchetti consecutivi. Allo
scopo di non aumentare di molto la velocità di trasmissione, si accetta
per i dati ridondati una drastica riduzione di qualità, legata all'uso
di un codec con maggiori perdite.
La tecnica esposta si è tradotta nella definizione di un ulteriore sotto-tipo MIME del tipo audio chiamato red (per redundant), descritto nella RFC 2198, e che prevede un payload contenitore dotato di un suo ulteriore header che ne descrive l'effettiva ripartizione. Anche il codek SILK di Skype prevede la possibilità di adottare una forma di FEC, e rende pubblico un formato di payload RTP.
Un codificatore di segnale opera tipicamente su intervalli temporali costanti, e suoi multipli naturali, e produce in uscita delle unità dati che, essendo generate a livello applicativo, vengono indicate come Application Data Unit (ADU). Ad esempio, un codificatore vocale basato su di un modello di sorgente vocale opera su intervalli di 10-40 msec (pari a 80-320 campioni, se il segnale è campionato a 8 KHz), mentre un codificatore video con frame rate (ad es) di 16 quadri/sec, produce ADU distanziate di 62,5 msec.
Il numero effettivo di bit di cui ogni ADU è composta, dipenderà dal tipo di codificatore in uso; in linea generale, le ADU devono essere ricevute (correttamente) per intero, pena l'impossibilità di procedere alla loro riproduzione. Quest'ultima considerazione è un ulteriore motivo fondante della trasmissione via UDP, poiché a differenza del TCP, è lo strato applicativo (in cui è in esecuzione il codificatore) che effettua la suddivisione delle ADU nei pacchetti da trasmettere.
A questo punto, si possono presentare le seguenti eventualità:
Dal
lato della riproduzione, una volta che le ADU sono state ricomposte, il
jitter è stato assorbito dal buffer di riproduzione, ed il processo di
codifica attuato in partenza è stato invertito, occorre ristabilire
l'esatto ordinamento temporale, in modo che gli intervalli di segnale
usati in partenza, vengano riprodotti con la medesima cadenza. Per
questo, il processo di pacchettizzazione RTP inserisce delle
informazioni temporali, tali da mettere in grado il lato ricevente di
svolgere questo compito.
Nel caso in cui la trasmissione consista in due o più media mutuamente sincronizzati prodotti da una medesima sorgente, (come ad esempio un video, ed il relativo audio), dal lato ricevente occorre prevedere l'esistenza di un agente di sincronizzazione, in grado di usare i riferimenti temporali presenti nei due flussi per controllare entrambi i ritardi di riproduzione, ristabilendo la corretta sincronizzazione congiunta.
I campi della intestazione RTP sono stati definiti allo scopo di permettere la soluzione delle problematiche fin qui accennate, e sono organizzati in tre (o più) gruppi di quattro byte, in accordo allo schema seguente:
2 | 3 | 4 | 8 | 9 | 16bit | 32bit |
V | P | X | CSRC count | M | Payload type | Sequence number |
Timestamp | ||||||
Synchronization source (SSRC) | ||||||
Contributing source (CSRC: variable 0 - 15 items, 4 octets each) |
i cui campi sono descritti come
La RFC 3551 descrive un profilo chiamato RTP/AVP, che definisce un insieme di corrispondenze di default tra i codici dei Payload Type RTP ed i formati di codifica del segnale audio e video, descrivendo quindi per gli stessi la sintassi con la quale il segnale codificato è rappresentato nel payload; inoltre, sono individuate le implementazioni di riferimento dei codificatori. Come anticipato nella discussione sull'SDP, il payload RTP può essere messo in corrispondenza con un MIME Type mediante gli elementi m= ed a=rtpmap: le RFC 4855 e 4856 specificano le procedure per registrare nuovi formati di payload RTP, e presso IANA è accessibile un registro dei parametri RTP che sono stati definiti.
Un intervallo di codici di Payload Type viene riservato per la descrizione di formati di codifica statici, ovvero i cui parametri sono pienamente descritti dalla RFC 3551, e per i quali l'elemento a=rtpmap può essere omesso nell'SDP che descrive la sessione. Via via che sono definiti nuovi metodi di codifica, l'uso di corrispondenze statiche tra i codici dei PT ed i formati di codifica, potrebbe determinare il rapido esaurimento dei codici disponibili. Pertanto, i codici da 96 a 127 sono riservati per poter dichiarare fino a 32 payload dinamici per una stessa sessione, ovvero associazioni tra un codice di PT ed un formato di codifica valido solo per la durata della sessione, e identificate in base alla corrispondenza tra il codice del PT, e l'elemento a=rtpmap relativo allo stesso codice di Payload dinamico, presente nell'SDP che definisce la sessione di cui il media fa parte. I possibili valori del media subtype mostrato nell'elemento SDP a=rtpmap: sono elencati presso IANA, e per ognuno di essi esiste un documento che li descrive (come ad es. per il codec audio speex).
Come già accennato, l'RTP è affiancato da un protocollo di controllo, l'RTCP, che non trasporta dati multimediali, utilizza la porta UDP dispari immediatamente successiva a quella (pari) utilizzata dal flusso RTP a cui è associato, e viene inviato sia dai ricevitori che dai trasmettitori. Il formato di pacchetto è simile a quello dell'RTP, ed i primi 8 byte hanno la struttura
2 | 3 | 8 | 16bit | 32bit |
V | P | count | Packet Type | Length |
SSRC or CSRC |
a cui poi fanno seguito una serie di count sezioni, la cui composizione dipende dal valore del campo Packet Type, che indica uno tra i seguenti tipi di pacchetto:
In uno stesso pacchetto RTCP si può trovare più di una delle sezioni descritte sopra, come ad esempio il caso in cui un SR viaggia assieme ad una SDES.
I problemi del VoIP con i Firewall ed i NAT sono molteplici, e si può dire, che esistono fin dalle origini di entrambi.
Per quanto riguarda i Firewall, questi sono dispostivi Router (eventualmente realizzati in Software come applicazioni eseguite presso lo stesso computer sorgente/destinazione del traffico) che applicano una politica che permette l'ingresso del solo traffico diretto verso un numero ristretto di porte ben note. Se si è a conoscenza dell'intervallo di porte che RTP userà per ricevere, possiamo tentare di includerle nella access list del Firewall; altrimenti, questo dovrebbe essere dotato di un Application Level Gateway in grado di esaminare i messaggi SIP, rilevare le porte RTP annunciate mediante l'offerta/risposta SDP, ed aprirle. Oppure, lasciare tutte le porte aperte. Ma allora, che firewall sarebbe?
Per quanto riguarda i NAT, anche questi sono dei router, usati come Default Gateway per interconnettere una LAN (ai cui computer corrispondono indirizzi IP privati) con il resto di Internet, ovvero con dispositivi dotati di IP pubblici. Il Source NAT (SNAT) sostituisce alla coppia (IP, porta)LAN del mittente dei pacchetti in uscita dalla LAN, una coppia (IP, porta)NAT in cui compare il proprio IP pubblico, ed un numero di porta scelto a caso. Quindi, SNAT crea uno stato della connessione, memorizzando questa associazione.
Nel caso di una connessione TCP uscente, i pacchetti di ritorno sono diretti verso (IP, porta)NAT, ed il NAT provvede a re-impostare la coppia (IP, porta)LAN originaria come indirizzo di destinazione. Nel caso dell'UDP usato per l'RTP, e per SIP, questo meccanismo in generale non funziona, perché
Certo, se nell'SDP uscente ci fosse scritto l'indirizzo IP pubblico del proprio NAT, anziché quello privato dello UA, i flussi RTP entranti potrebbero essere correttamente instradati dai router di Internet. Inoltre, se l'RTP usasse lo stesso numero di porta sia per inviare che per ricevere, allora l'RTP uscente abiliterebbe anche quello entrante, ed i pacchetti potrebbero arrivare. Infine, se le richieste SIP entranti usassero una porta diversa, per ogni UA raggiungibile, il NAT potrebbe distinguerli l'uno dall'altro. In estrema sintesi, abbiamo descritto ciò che viene realizzato con le tecniche che andiamo ad esporre.
Intanto, prendiamo atto che non tutti i NAT sono uguali, e possiamo distinguerli in
Letteralmente, si tratta di bucare il NAT, e consiste nella generazione preventiva di traffico UDP uscente, per poter poi ricevere quello entrante. Di fatto, questo metodo funziona a patto che solo uno dei due dispositivi in comunicazione sia NATtato.
Quando uno UA si registra, invia un pacchetto UDP verso la porta 5060 del Registrar, ed in questo modo, genera nel NAT la corrispondenza necessaria a ricevere la risposta. Il Registrar osserva la coppia (IP, porta)NAT da cui proviene la richiesta, ed la usa come Contact Address dello UA. Quando successivamente il Registrar riceve un INVITE destinato allo UA, usa questo Contact Address, e l'INVITE viene felicemente inoltrato dal NAT verso lo UA corretto. Sempre a patto che.... non sia scaduto il tempo per il quale il NAT mantiene l'informazione di stato! Infatti, allo scopo di poter ri-usare le porte impegnate, dopo che è trascorso un tempo (dai 30 ai 180 secondi) senza osservare traffico uscente, il NAT dimentica questa corrispondenza. La soluzione a questo problema, consiste nel continuare a generare traffico uscente, detto keep alive, ad esempio mediante messaggi SIP di rinnovo registrazione, oppure usando il metodo OPTION, oppure semplicemente inviando pacchetti UDP vuoti diretti al Registrar.
Mentre
per SIP è previsto di usare lo stesso numero di porta UDP sia come
sorgente che come destinazione del traffico, non c'è nulla che
prescriva la stessa cosa per l'RTP. D'altra parte, la possibilità di forare
il NAT, consentita dall'uso (presso una entità NATata) della stessa
porta come sorgente e destinazione, ha determinato la formalizzazione
(RFC 4961)
di questa pratica, che prescrive per l'entità NATtata, di iniziare a
generare traffico in uscita il prima possibile, usando come numero di
porta sorgente, lo stesso numero su cui si desidera ricevere il
traffico entrante, annunciato nell'SDP. A differenza del SIP, nel caso
dell'RTP simmetrico, l'entità corrispondente (non NATtata) può non
utilizzare l'RTP simmetrico, e se lo adotta, non è necessario che usi
le stesse porte dell'entità NATtata. Restano comunque ancora aperti i
problemi di:
Mentre per SIP è praticamente certo che il path di segnalazione attraversi un Registrar/Proxy dotato di IP pubblico, grazie al quale attivare il pinhole del NAT, per l'RTP invece questa soluzione di fatto non funziona, dato che è molto probabile che entrambi gli UA in comunicazione siano NATtati. In questo caso, si aprono due alternative:
In questo caso lo UA è completamente ignaro di risiedere dietro un NAT, e deve adottare la modalità di trasmissione via RTP simmetrico. In queste ipotesi, lo UA può comunicare anche se pure l'altro UA è NATtato, a patto che un elemento di transito (il Registrar, l'Outbound Proxy, od un ALG che si trova nel path) ospiti un elemento Back-to-back UA, e modifichi gli indirizzi presenti nell'SDP in modo da riferire all'entità remota, anziché quelli forniti dallo UA di origine, quelli messi a disposizione da una entità (RTPproxy) attraverso la quale verrà triangolato il traffico RTP. In particolare:
A
questo punto entrambi gli UA, pur credendo di inviare l'RTP
direttamente al corrispondente, lo inviano invece all'RTPproxy.
Quest'ultimo, non appena riceve dei pacchetti RTP da uno degli UA,
prende nota dell'IP e della porta mittente, che evidentemente
corrispondono al NAT dello UA, in modo da poter inoltrare verso di essi
l'RTP proveniente dall'altro UA. In questo modo però, nessuno UA può
ricevere, se prima non ha iniziato a trasmettere. Pertanto, sia per
aprire il pinhole nel NAT, sia per permettere
l'associazione tra la propria (IP, porta)NAT
ed il traffico proveniente dall'altro estremo, entrambi gli UA iniziano
ad inviare l'RTP il prima possibile. L'elemento RTPproxy può essere
co-residente con il B2BUA, oppure essere scelto da quest'ultimo, tra
una serie di alternative possibili, in modo da ridurre al minimo
l'aumento di latenza legato al maggior percorso del traffico RTP.
Nonostante questa tecnica funzioni benissimo, viene criticata in quanto prefigura un vero e proprio attacco MITM, rendendo problematico un controllo di integrità sui messaggi SIP.
Session Traversal Utilities for NAT (STUN) è l'acronimo della metodologia descritta nella RFC 5389, e che utilizza un server STUN presente sulla Internet pubblica per permettere ad uno UA NATtato di scoprire il tipo di NAT (o Firewall) presente, qual'é il suo IP pubblico, e quale porta esterna viene scelta, in corrispondenza alla porta interna utilizzata dallo UA.
STUN permette
la comunicazione anche tra UA entrambi NATtati, usando l'RTP simmetrico,
ma non funziona se uno UA è dietro ad un NAT
simmetrico. Gli altri tipi di NAT infatti, mantengono una specifica
coppia (IP, porta)NAT
associata con continuità alla stessa coppia (IP,
porta)LAN, per tutto il
periodo di validità. Pertanto lo UA, prima di effettuare una chiamata,
contatta il server STUN usando la stessa (IP, porta)LAN, che userà per l'RTP successivo, in
modo che il server STUN gli comunichi la coppia (IP,
porta)NAT corrispondente.
Quindi, lo UA userà questi ultimi valori, per costruire il proprio SDP.
Per risolvere il problema dei NAT simmetrici, la RFC 5766 denominata Traversal Using Relays around NAT (TURN) prevede infine che lo UA, prima di iniziare una comunicazione, contatti un server situato presso l'Internet pubblica (il server TURN), che stavolta offre anche un servizio di RTPproxy. Il server TURN comunica quindi allo UA una coppia (IP, porta)TURN che l'RTPproxy ha riservato per gestire il traffico destinato a quello UA: tutti i pacchetti che l'RTPproxy riceverà su (IP, porta)TURN, verranno re-inviati alla (IP, porta)NAT associata, permettendo al NAT di consegnarli alla (IP, porta)LAN corrispondente. A questo punto, lo UA userà la coppia (IP, porta)TURN per costruire l'SDP da allegare alle chiamate uscenti, come fosse un proprio fermo posta.
A differenza della soluzione realizzata mediante il B2BUA, stavolta è lo UA a decidere cosa fare. Dato che l'RTPproxy viene a costituire un punto critico della architettura, con potenziali problemi di scalabilità, e che il suo uso è necessario solo nel caso di un NAT simmetrico, allora è preferibile usare un server STUN ogni volta che è possibile, e solo in caso di fallimento, usare il server TURN. Questo è proprio l'approccio seguito dalla RFC 5245 detta Interactive Connectivity Establishment (ICE).
Con questo termine si intendono i casi in cui chiamato e chiamante sono
serviti da SIP Service Provider
(SSP) differenti. In tal caso la segnalazione SIP finora descritta è
esposta a diversi rischi di sicurezza, come ad es. nel caso già
descritto, di possibili telefonate anonime o da AoR falsi. Mentre la
RFC 6404 svolge una
analisi completa dei rischi collegati, le RFC
5486 e 6406
definiscono rispettivamente una terminologia
ed una architettura
idonee a descrivere questi casi (e non solo), che illustriamo con
l'ausilio della figura che segue, in cui sono rappresentati i punti di uscita ed ingresso
per la segnalazione di due diversi SSP, indicati come SBE (Signaling
path Border Element), mentre le interfacce per i flussi
multimediali sono indicati come DBE (Data
path Border Element).
+=============++ ++=============+ |
Il DBE, oltre ad espletare la funzione di inoltro, può realizzare anche quella di transcodifica e/o attraversamento NAT, eventualmente sotto il controllo dell'SBE. L'SBE dal canto suo è ulteriormente suddiviso in
Le informazioni raccolte da LUF e LRF sono denominate Session Establishment Data (SED) e rappresentano i dati necessari ad instradare la chiamata verso il next hop associato con il punto di ingresso del dominio chiamato, ed oltre agli indirizzi possono comprendere anche informazioni legate alla sicurezza, come ad es. quali certificati X.509 presentare e richiedere nel caso di una connessione TLS, e quale CA debba averli firmati.
Lo schema mostrato in figura rappresenta un caso di peering diretto, in cui alcuni accordi (ad es., la CA che firma i certificati) possono essere prestabiliti, e la politica di controllo di accesso dell'SSP di destinazione accetta esplicitamete la segnalazione proveniente dall'SSP di origine. Può invece presentarsi il caso (RFC 6405) in cui il peering avvenga in modo indiretto, e quindi la segnalazione attraversi uno o più SSP di transito prima di giungere a destinazione, come appunto qualora in cui non sussistano accordi prestabiliti con l'SSP di destinazione, mentre lo siano con SSP terzi che svolgono il ruolo di intermediari fidati per entrambe le parti. Infine, nel caso in cui non esista un SSP di transito che abbia sottoscritto accordi di peering con le due parti, queste potranno ancora scambiarsi la segnalazione in modalità on-demand, ed in questo caso può venire meno la possibilità di autenticare la controparte, a meno che entrambi gli SSP non aderiscano ad un medesima federazione, nel qual caso condividono l'adesione a parametri di comunicazione comuni.
Seguendo l'impostazione della RFC 6404, illustriamo prima le minacce insite nella architettura di peering, e quindi le contromisure corrispondenti. In particolare, illustriamo come le funzioni di LookUp (LUF), di Location Routing (LRF), di Segnalazione (SF) e di trasmissione dei Media (MF) siano sensibili ad attacchi alla confidenzialità, integrità e disponibilità.
LUF - permette di determinare l'identità della risorsa richiesta presso l'SSP di destinazione, e può essere abusata per scoprire informazioni utili a realizzare altri tipi di attacchi. Essendo il LUF realizzato mediante un database, sono posibili atacchi all'integrità dello stesso realizzati mediante la tecnica SQL iniection. Può inoltre essere portato un attacco alla disponibilità mediante interrogazioni mal formate o incomplete, tali da creare esaurimento memoria.
LRF - localizza la funzione di segnalazione (SF) per il dominio di destinazione di una richiesta, e può essere ripetutamente invocata da un attaccante per scoprire gli indirizzi degli User Agent, che possono poi essere attaccati direttamente, o inseriti in campagne di telemarketing. Intercettando le intestazioni Via e Record-Route si possono scoprire gli indirizzi dei dispositivi di segnalazione intermedi, ed eventualmente attaccare questi ultimi. Se i messaggi in transito posso essere modificati, si possono verificare attacchi di tipo Man-in-the-Middle, in cui un attaccante inserisce nel percorso della segnalazione un proprio elemento e da quel momento è in grado di modificare tutti messaggi in transito, compresa la possibilità di sostituire le risposte di LRF e redirigere le chiamate verso una diversa destinazione, a scopo di voice phishing e attacchi DOS.
SF - mediante la funzione di segnalazione uno UA asserisce la propria identità ed il SSP autorizza l'uso di risorse fatturabili. L'intercettazione dei messaggi di segnalazione, anche da parte di un SSP rivale, viola la privacy di chi telefona, svelando i suoi orari ed i suoi contatti. L'autenticazione Digest può subire un attacco di forza bruta e permettere a terzi di impersonare l'utente la cui password è stata violata. Qualora i messaggi SIP possano essere modificati e/o inseriti, un attaccante può causare la chiusura di una sessione, intestare la fatturazione ad altri, od impersonare altri; possono inoltre essere inviati falsi messaggi di risposta, con il risultato di impedire la creazione di una sessione, o dirottarla verso una diversa destinazione. Inoltre, la modifica dei messaggi SIP e dell'SDP può determinare l'uso di un codec scadente, o ridurre il livello di sicurezza successivo. Infine, la disponibilità della SF è vulnerabile ad attacchi di tipo flooding, oppure un MITM può scartare gli INVITE impedendo di creare nuovi dialoghi.
MF - è responsabile del
recapito effettivo della comunicazione multimediale, e se intercettata
si incorre in evidenti violazioni della privacy, oppure l'attaccante
può a quel punto creare falsi pacchetti RTP con numero di sequenza e
timestamp corretti, causando dal lato ricevente lo scarto dei pacchetti
originali, ed una impersonificazione del vero interlocutore. La
comunicazione può inoltre essere interrotta inviando falsi pacchetti RTP
BYE, oppure falsi pachetti RTCP possono degradare la qualità della
comunicazione simulando una cattiva ricezione, forzando così l'uso di un
codec più scadente.
Considerando che le funzioni di LUF e LRF sono svolte mediante l'interrogazione del DNS, una delle prime difese possibili è quella di adottare le estensioni di sicurezza DNSSEC (RFC 4033, 34 e 35), che si basano su di una PKI per realizzare l'autenticazione delle risposte del DNS, e garantirne l'integrità mediante firma digitale. In tal modo si evitano i rischi di manomissione resi possibili da un attacco MITM. Allo stesso tempo, gli attacchi DOS che minano la disponibilità delle funzioni legate al DNS possono essere mitigati ricorrendo alla replicazione dei name server sensibili.
Per neutralizzare gli attacchi legati alla SF è opportuno che i messaggi SIP vengano crittografati prima del loro invio, ricorrendo a connessioni TLS o DTLS (RFC 4347), ottenendo così anche la mutua autenticazione tra le parti, sempre nell'ipotesi che esista una PKI di supporto. Mentre quest'ultima può essere specificata all'atto della adesione, da parte degli SSP, ad una federazione, notiamo che per questa via risultano neutralizzati gli attacchi legati all'invio fraudolento di falsi messaggi SIP, così come diviene arduo il dirottamento delle chiamate verso terze parti. La RFC 5922 descrive le particolarità dei certificati e delle CA da adottare per questo scopo.
Sebbene l'identità del chiamante sia verificata dall'SSP di origine, la stessa verifica non è possibile da parte di quello di destinazione, rendendo possibile lo SPIT (SPam over Ip Telephony), per contrastare il quale sono possibili due approcci: la fiducia transitiva e la firma digitale. La prima tecnica consiste nello stabilire una catena di fiducia tra gli SSP coinvolti, compresi quelli di transito, come specificato nelle RFC 3324 e 25. Attualmente si preferisce però seguire le indicazioni della RFC 3893, che si ispira alle specifiche S/MIME per le email, e che definisce un Authenticated Identity Body come un frammento SIP contenente gli header utili alla identificazione del chiamante, che va inserito nel body del messaggio originale e quindi firmato digitalmente, in modo da garantirne autenticità ed integrità. A questo scopo la RFC 4474 definisce due nuove intestazioni (Identity e Identity-Info) che permettono all'SSP di origine di firmare digitalmente le richieste inoltrate per conto di UA che sono stati localmente autenticati.
Allo scopo di proteggersi dagli attacchi alla MF, è consigliabile ricorrere al Secure Real-time Transport Protocol o SRTCP (RFC 3711), che aggiunge confidenzialità, integrità ed autenticazione ai pacchetti mutimediali scambiati, sempre ovviamente in presenza di una PKI comune alle parti in comunicazione.
Per gli altri dettagli rispetto ai possibili attacchi e relative
contromisure, si consulti la RFC
6404.
Dal TCP al VoIP, dal DNS all'Email alla crittografia, tutto ciò che accade
dietro le quinte di Internet, completo di cattura del traffico.
Scopri
come effettuare il download,
ricevere gli aggiornamenti,
e contribuire!