RFC 3261 Capitolo 11: Modificare una sessione con il re-INVITE

RFC 3261: Il DNA del VoIP – Capitolo 11
Modificare una sessione con il re-INVITE

La chiamata è già attiva. Matteo e Daniele stanno parlando, il dialogo SIP è stato stabilito e i pacchetti RTP scorrono regolarmente. Matteo preme il tasto di attesa sul telefono. Nel tracciato pcap compare un nuovo INVITE. Non è una seconda chiamata e non sta creando una nuova sessione: sta proponendo di modificare quella esistente.

Questa situazione è molto comune. Lo stesso meccanismo può comparire quando cambia un indirizzo o una porta RTP, quando viene aggiunto un flusso video, quando si modifica la lista dei codec oppure quando un apparato vuole aggiornare il proprio indirizzo di contatto. Nel linguaggio operativo lo chiamiamo re-INVITE: un INVITE inviato all’interno del dialogo che ha già stabilito la sessione.

Chiariamo subito un equivoco frequente: re-INVITE non è un metodo SIP autonomo. Nella Request-Line il metodo scritto sul filo resta INVITE. Non esiste un metodo chiamato RE-INVITE e non lo troveremo nell’elenco dei metodi supportati da un apparato. Il prefisso re- descrive l’uso di un nuovo INVITE all’interno di un dialogo già esistente. Molti installatori lo immaginano come un messaggio diverso perché nei log dei PBX viene spesso etichettato così, ma sul protocollo resta un INVITE.

Nei capitoli precedenti abbiamo visto come INVITE avvia la sessione, ACK ne conferma l’accettazione e BYE la termina. Abbiamo anche osservato che OPTIONS interroga capacità e disponibilità senza modificare una chiamata. Ora seguiamo il passaggio successivo: cambiare una sessione mentre resta attiva. Analizzeremo la regola della RFC, i ruoli UAC e UAS, il modello di offerta e risposta, la messa in attesa, la risposta negativa e gli errori che si riconoscono nel tracciato pcap.

Che cosa definisce la RFC

La sezione 14 della RFC 3261 introduce il meccanismo con una definizione molto concreta:

“This is accomplished by sending a new INVITE request within the same dialog that established the session. An INVITE request sent within an existing dialog is known as a re-INVITE.”
La modifica viene realizzata inviando una nuova richiesta INVITE all’interno dello stesso dialogo che ha stabilito la sessione. Una richiesta INVITE inviata in un dialogo esistente è chiamata re-INVITE.

La parola decisiva è same: lo stesso dialogo. Call-ID e tag permettono di riconoscere la relazione già esistente, mentre il CSeq aumenta. Non serve attribuire per sempre a un telefono il ruolo di UAC e all’altro quello di UAS. In questo scambio, il dispositivo che genera il re-INVITE assume il ruolo logico di UAC; quello che lo riceve assume il ruolo di UAS. In un momento successivo i ruoli possono invertirsi.

La RFC elenca modifiche come indirizzi, porte, aggiunta o rimozione di flussi multimediali. Aggiunge anche che un singolo re-INVITE può aggiornare contemporaneamente parametri della sessione e informazioni del dialogo. Per esempio, il corpo SDP può proporre una nuova porta RTP, mentre il valore Contact può aggiornare il bersaglio verso cui l’altro apparato invierà le richieste successive. Sono due piani collegati, ma non identici.

La segnalazione SIP negozia il cambiamento; i flussi RTP trasportano la voce o gli altri contenuti. Vedere un 200 OK al re-INVITE conferma l’accettazione della richiesta SIP, ma per verificare che l’audio segua davvero i nuovi parametri bisogna osservare anche i pacchetti RTP.

Re-INVITE e nuova chiamata non sono la stessa cosa

Nel tracciato entrambi iniziano con la stessa parola: INVITE. La differenza emerge dal contesto. L’INVITE iniziale crea una nuova relazione SIP; il re-INVITE opera dentro una relazione già stabilita. Nel secondo caso troviamo il medesimo Call-ID e gli stessi tag locali e remoti della chiamata. Il numero CSeq, invece, deve avanzare secondo le regole delle richieste inviate nel dialogo.

Anche la Request-URI ha un ruolo operativo. Non identifica semplicemente l’indirizzo pubblico dell’utente, ma il bersaglio remoto appreso per quel dialogo. Per questo, spiega la RFC, un re-INVITE non viene inoltrato verso più destinazioni: è diretto all’istanza di User Agent con cui il dialogo è stato stabilito, non a un generico indirizzo dell’utente che potrebbe corrispondere a più contatti.

Il campo To continua a rappresentare il destinatario logico. La Request-URI guida invece l’instradamento della richiesta. Questa distinzione evita un errore frequente: confrontare solo il numero o l’URI nel To e concludere che il messaggio stia aprendo una chiamata diversa.

Il re-INVITE non azzera la chiamata. Non genera un nuovo Call-ID, non richiede una nuova fase di squillo per l’utente e non cancella automaticamente i parametri precedenti. Propone una nuova descrizione coerente della sessione; se la proposta non viene accettata, nella maggior parte dei casi la sessione continua con i parametri già negoziati.

RE-INVITE e PBX: Quando entra in gioco

In un impianto telefonico il re-INVITE compare quando un PBX, un telefono, un gateway o un SBC deve rinegoziare una sessione già attiva. Alcuni casi da manuale sono:

  • Messa in attesa e ripresa della chiamata: il nuovo SDP modifica la direzione del flusso audio, per esempio da sendrecv a sendonly, per poi ripristinarla.
  • Trasferimento di chiamata: il trasferimento può produrre nuovi dialoghi e una rinegoziazione dei flussi audio. Quando viene usato REFER, è REFER a richiedere il trasferimento; un eventuale re-INVITE modifica la sessione su uno dei dialoghi coinvolti, ma non sostituisce il metodo di trasferimento.
  • Passaggio del fax da audio a T.38: la chiamata può iniziare come audio RTP per trasportare i toni fax. Dopo il rilevamento, un gateway o un PBX invia spesso un re-INVITE con una nuova offerta SDP che propone il tipo image/t38, normalmente associato al trasporto udptl.
  • Cambio di indirizzo o porta del flusso audio: un terminale o un dispositivo che gestisce l’audio propone una nuova destinazione per i pacchetti RTP.
  • Rinegoziazione dei codec: cambia l’insieme dei formati offerti, per esempio dopo l’ingresso di un altro componente nel percorso audio.
  • Aggiunta o rimozione di un flusso: una sessione solo audio può aggiungere il video, oppure eliminare un flusso impostando a zero la relativa porta SDP.
  • Aggiornamento del Contact: il re-INVITE può aggiornare il bersaglio delle richieste SIP successive nello stesso dialogo.

Il caso fax merita una precisazione. T.38 descrive il trasporto del facsimile in tempo reale su rete IP; UDPTL è il trasporto comunemente indicato nell’SDP per i pacchetti T.38. La sezione 3.1 della RFC 3362 registra image/t38 come tipo di contenuto destinato a rappresentare un flusso T.38 nell’SDP. Un’offerta può contenere, per esempio, m=image 40002 udptl t38. Il re-INVITE trasporta la nuova offerta; non converte da solo il fax e non garantisce che gateway, firewall e apparato remoto supportino T.38.

Anche sul trasferimento conviene usare termini precisi. La RFC 3515 definisce REFER come metodo che può richiedere un trasferimento di chiamata. Nei PBX possono esistere trasferimenti gestiti internamente, trasferimenti con REFER, Replaces e più dialoghi. In queste sequenze il re-INVITE può rinegoziare indirizzi, porte o direzione dell’audio, ma dal solo re-INVITE non possiamo dedurre quale logica di trasferimento sia stata usata.

Il modello di offerta e risposta continua durante la sessione

La RFC 3261 richiama lo stesso modello di offerta e risposta usato dall’INVITE iniziale. Il re-INVITE può contenere una nuova offerta SDP e il 2xx può portare la risposta. È possibile anche inviare un re-INVITE senza descrizione di sessione: in quel caso la prima risposta affidabile che non segnala un errore contiene l’offerta e l’ACK deve completare lo scambio con la risposta. Nella pratica più comune, però, l’offerta è già nel re-INVITE.

“It is important to note that the full description of the session, not just the change, is sent.”
È importante notare che viene inviata la descrizione completa della sessione, non soltanto la modifica.

Questa regola è essenziale durante la ricerca del guasto. Se cambia soltanto la direzione dell’audio, il nuovo SDP non contiene una singola riga isolata con a=sendonly. Contiene di nuovo versione, origine, connessione, tempo, descrizione del flusso, codec e attributi necessari a rappresentare lo stato proposto. Il destinatario deve poter interpretare la nuova offerta senza ricostruire ogni dettaglio da una serie di differenze parziali.

Nel campo o= dell’SDP compaiono un identificatore di sessione e una versione. Quando la descrizione cambia, chi formula l’offerta dovrebbe incrementare la versione. Chi riceve il re-INVITE deve verificare la versione oppure confrontare il contenuto quando il formato non dispone di un identificatore equivalente. Un SDP apparentemente nuovo con versione invariata può essere ignorato o trattato in modo inatteso da alcuni apparati.

Un re-INVITE per la messa in attesa

Vediamo un esempio semplificato. La chiamata fra Matteo e Daniele è stata stabilita con audio bidirezionale. Matteo preme attesa e il suo telefono propone un flusso sendonly.

INVITE sip:daniele@192.0.2.20:5060 SIP/2.0
Via: SIP/2.0/UDP 192.0.2.10:5060;branch=z9hG4bK-reinv-201
Max-Forwards: 70
From: "Matteo" <sip:matteo@voip.example>;tag=mt-7431
To: "Daniele" <sip:daniele@voip.example>;tag=dn-9824
Call-ID: 7f3a91c2@192.0.2.10
CSeq: 102 INVITE
Contact: <sip:matteo@192.0.2.10:5060>
Content-Type: application/sdp
Content-Length: 205

v=0
o=matteo 2890844526 2890844527 IN IP4 192.0.2.10
s=-
c=IN IP4 192.0.2.10
t=0 0
m=audio 40000 RTP/AVP 0 8 101
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=sendonly

La riga iniziale della richiesta indirizza il messaggio al bersaglio operativo appreso nel dialogo. Il nuovo valore branch identifica questo specifico scambio e non deve essere confuso con quello dell’INVITE iniziale. From, To con i rispettivi tag e Call-ID permettono di collegare il messaggio alla chiamata in corso. CSeq: 102 INVITE mostra un numero maggiore rispetto alle richieste precedenti inviate da Matteo.

Il Contact indica dove Matteo vuole ricevere richieste future nel dialogo. Nel corpo, l’indirizzo e la porta RTP restano disponibili, i codec vengono nuovamente elencati e l’attributo a=sendonly propone la nuova direzione del flusso.

La sezione 8.4 della RFC 3264 descrive la messa in attesa come un’offerta SDP aggiornata. Se un flusso era sendrecv, chi mette in attesa l’altro lo marca normalmente sendonly. L’altro apparato risponde in genere con la direzione complementare.

SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.0.2.10:5060;branch=z9hG4bK-reinv-201
From: "Matteo" <sip:matteo@voip.example>;tag=mt-7431
To: "Daniele" <sip:daniele@voip.example>;tag=dn-9824
Call-ID: 7f3a91c2@192.0.2.10
CSeq: 102 INVITE
Contact: <sip:daniele@192.0.2.20:5060>
Content-Type: application/sdp
Content-Length: 183

v=0
o=daniele 367493 367494 IN IP4 192.0.2.20
s=-
c=IN IP4 192.0.2.20
t=0 0
m=audio 41000 RTP/AVP 0 8 101
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=recvonly

La riga iniziale della risposta comunica l’accettazione. Via, tag, Call-ID e CSeq collegano la risposta al re-INVITE. Contact può aggiornare il bersaglio remoto di Matteo. Nell’SDP Daniele accetta di ricevere, ma non di inviare, il flusso audio. Matteo completa lo scambio con ACK. Soltanto dopo aver collegato re-INVITE, 200 OK e ACK abbiamo una lettura completa della negoziazione SIP.

La messa in attesa non significa necessariamente assenza assoluta di pacchetti. La direzione SDP descrive il flusso; per RTP, la RFC 3264 precisa che RTCP può continuare anche con le direzioni sendonly, recvonly o inactive. Inoltre la musica d’attesa, i dispositivi intermedi e le scelte del PBX possono produrre flussi diversi da quelli che ci aspetteremmo osservando soltanto i due telefoni.

Che cosa sente chi viene messo in attesa

Se Matteo mette in attesa Daniele, Daniele sentirà una musica soltanto se un apparato la genera. Può farlo il telefono di Matteo, il PBX oppure un servizio dedicato alla musica di attesa. Il re-INVITE non contiene la musica: contiene la proposta con cui vengono regolati i flussi. La musica viaggia poi nei pacchetti RTP, esattamente come la voce.

Immaginiamo un PBX che gestisce separatamente le due parti della chiamata. Matteo preme il tasto di attesa. Sul collegamento fra Matteo e PBX compare un re-INVITE che segnala la nuova direzione. Il PBX smette di inoltrare la voce di Daniele verso Matteo e comincia a inviare a Daniele un file musicale o un annuncio. Da questo momento Daniele non sta ascoltando il microfono di Matteo: sta ricevendo un flusso RTP prodotto o controllato dal PBX.

Primo caso: il PBX mantiene invariato l’SDP verso Daniele. Se il PBX era già nel percorso dell’audio e continua a usare lo stesso indirizzo IP, la stessa porta e gli stessi codec, può sostituire la voce con la musica senza inviare un altro re-INVITE sul lato di Daniele. Nel tracciato vedremo il re-INVITE fra Matteo e PBX, ma potremmo non vederne uno fra PBX e Daniele. L’SDP di quel lato non cambia perché Daniele continua a ricevere RTP dalla destinazione già negoziata.

Secondo caso: il PBX rinegozia anche il lato di Daniele. Può accadere quando cambia il server che genera la musica, quando varia la porta RTP oppure quando il PBX vuole dichiarare esplicitamente che invierà soltanto audio. In questo caso il PBX può inviare a Daniele un re-INVITE con una descrizione simile:

INVITE sip:daniele@192.0.2.20:5060 SIP/2.0
Via: SIP/2.0/UDP 192.0.2.30:5060;branch=z9hG4bK-moh-301
Max-Forwards: 70
From: <sip:matteo@voip.example>;tag=pbx-a17
To: <sip:daniele@voip.example>;tag=dn-9824
Call-ID: 88c14d20@pbx.voip.example
CSeq: 204 INVITE
Contact: <sip:pbx@192.0.2.30:5060>
Content-Type: application/sdp
Content-Length: 142

v=0
o=pbx 77102 77103 IN IP4 192.0.2.30
s=-
c=IN IP4 192.0.2.30
t=0 0
m=audio 42000 RTP/AVP 8
a=rtpmap:8 PCMA/8000
a=sendonly

In questo esempio il PBX dichiara: invierò audio a Daniele, ma non ne riceverò su questo flusso. La riga a=sendonly è letta dal punto di vista del PBX. Daniele risponderà normalmente con a=recvonly. Le righe c= e m= indicano dove Daniele deve aspettarsi il flusso. Da quella destinazione arriverà la musica.

Non tutti i PBX producono lo stesso messaggio. Alcuni usano sendonly, altri mantengono sendrecv e controllano internamente quale audio inoltrare. Altri ancora coinvolgono un server multimediale e modificano indirizzo o porta. Per capire che cosa accade non basta trovare il re-INVITE: bisogna confrontare l’SDP prima e dopo e osservare da quale indirizzo arrivano realmente i pacchetti RTP.

Sendonly, recvonly e inactive

Gli attributi di direzione vanno letti dalla prospettiva di chi genera quella descrizione SDP. sendonly significa che quel partecipante intende soltanto inviare; recvonly significa che intende soltanto ricevere; inactive indica che al momento non intende né inviare né ricevere. sendrecv è bidirezionale ed è anche il comportamento predefinito quando l’attributo manca.

Non basta quindi cercare la parola hold in un messaggio: normalmente non esiste un header SIP chiamato Hold. La messa in attesa viene negoziata attraverso l’SDP. Bisogna confrontare offerta e risposta, tenendo conto del verso. Un’offerta sendonly riceve una risposta recvonly oppure inactive; un’offerta inactive deve ricevere inactive.

Nei sistemi derivati dalla precedente RFC 2543 si può ancora incontrare c=IN IP4 0.0.0.0 come metodo di messa in attesa. La RFC 3264 non lo raccomanda per questo uso: crea limiti con RTCP, IPv6 e flussi orientati alla connessione. La sua presenza in un impianto reale va interpretata come un comportamento ereditato da implementazioni precedenti o come una scelta del produttore, non come il modello oggi preferito.

Ripresa della conversazione

Quando Matteo toglie la chiamata dalla messa in attesa, il telefono invia un altro re-INVITE con un CSeq ancora maggiore. La nuova offerta ripristina a=sendrecv, o omette l’attributo poiché sendrecv è il valore predefinito. Daniele risponde con il proprio SDP e Matteo invia ACK.

Nel tracciato dobbiamo quindi aspettarci due negoziazioni distinte: una per mettere in attesa e una per riprendere. Ognuna ha il proprio branch e il proprio CSeq, pur conservando gli identificatori del dialogo. Se l’interfaccia mostra soltanto il primo scambio, non possiamo concludere che la ripresa sia avvenuta correttamente.

Un caso tipico di audio assente dopo la messa in attesa nasce da una porta o da un indirizzo SDP modificato nella ripresa. La segnalazione può risultare perfetta: re-INVITE, 200 OK e ACK sono presenti. L’RTP, tuttavia, continua verso la destinazione precedente oppure viene bloccato da NAT, firewall o da un dispositivo intermedio. Occorre allora confrontare le righe c= e m= prima della messa in attesa, durante la messa in attesa e dopo la ripresa.

Modificare indirizzo, porta, codec o tipo di flusso

Il re-INVITE non serve soltanto all’attesa. Un terminale o un SBC può proporre una nuova porta RTP, per esempio dopo una riallocazione delle risorse. Può cambiare l’indirizzo di connessione quando l’audio viene fatto passare attraverso un dispositivo intermedio. Può rinegoziare l’insieme dei codec o aggiungere un flusso video a una sessione nata con il solo audio.

La sezione 8 della RFC 3264 disciplina la modifica della sessione. Un flusso esistente viene rimosso impostando a zero la porta della relativa riga m=. Quasi tutte le caratteristiche di un flusso possono cambiare, ma durante la transizione gli apparati devono evitare interruzioni inutili e rispettare le regole sui numeri di payload dinamici.

Quando cambia la porta, guardare soltanto il SIP può nascondere la causa del problema. Chi formula l’offerta deve prepararsi a ricevere sui parametri nuovi, mantenendo per il tempo necessario la capacità di ricevere su quelli vecchi. Un apparato che chiude immediatamente la vecchia porta può perdere audio mentre il destinatario sta elaborando l’offerta.

Quando cambia la lista dei codec, il numero di payload dinamico assegnato a un determinato codec non deve essere reinterpretato arbitrariamente nella stessa sessione. Se il payload 101 indicava telephone-event, non dovrebbe diventare un codec audio nel re-INVITE. Errori di questo tipo possono produrre audio apparentemente regolare ma DTMF non riconosciuti, oppure decodifiche incoerenti.

⚠ I CONSIGLI DI VOIP.IT

Quando un problema compare dopo la messa in attesa, un trasferimento o un cambio di rete, costruisci una tabella con tre stati: SDP iniziale, SDP del re-INVITE e SDP del 200 OK. Confronta la versione nella riga o=, l’indirizzo c=, la porta e i codec nella riga m=, gli attributi di direzione e le associazioni rtpmap. Solo dopo verifica dove viaggiano davvero i pacchetti RTP. Questo metodo separa rapidamente una negoziazione errata da un problema di instradamento dell’audio.

Quando la modifica non viene accettata

Un re-INVITE è una proposta, non un ordine di cambiare unilateralmente la sessione. Se l’altro apparato restituisce una risposta finale non-2xx, i parametri della sessione devono restare invariati, come se il re-INVITE non fosse stato inviato. Questa proprietà evita che i due lati applichino configurazioni incompatibili dopo un rifiuto.

“If a UA receives a non-2xx final response to a re-INVITE, the session parameters MUST remain unchanged, as if no re-INVITE had been issued.”
Se uno User Agent riceve una risposta finale non-2xx a un re-INVITE, i parametri della sessione devono rimanere invariati, come se il re-INVITE non fosse stato inviato.

Se la nuova descrizione non è accettabile, il UAS può rispondere 488 Not Acceptable Here e dovrebbe includere Warning. Un esempio concreto è una proposta che rimuove tutti i codec utilizzabili dal destinatario. La chiamata non deve essere considerata automaticamente terminata: resta valida la negoziazione precedente.

Esistono eccezioni operative importanti. Una risposta 481 indica che l’altro apparato non riconosce il dialogo; 408 o l’assenza completa di risposta indicano che la richiesta non ha raggiunto un esito utile. In questi casi la RFC collega il fallimento alla terminazione del dialogo, normalmente tramite BYE per un dialogo nato da INVITE. Perciò non tutti i non-2xx hanno lo stesso effetto.

Re-INVITE contemporanei e 491 Request Pending

Entrambi i partecipanti possono decidere di modificare la sessione. Se lo fanno quasi nello stesso istante, le due richieste possono incrociarsi. Questa sovrapposizione è spesso chiamata glare nella documentazione tecnica. La RFC impedisce di avviare un nuovo scambio INVITE nel dialogo mentre un altro scambio INVITE è in corso in una delle due direzioni.

Se un User Agent riceve un INVITE mentre è ancora in corso un INVITE che esso stesso ha inviato nello stesso dialogo, deve rispondere 491 Request Pending. Chi riceve 491 non dovrebbe riprovare immediatamente: la RFC definisce un intervallo di attesa con una componente casuale, differenziando il comportamento in base a chi ha generato il Call-ID. La casualità riduce la probabilità che i due lati ripetano ancora insieme.

Un caso diverso si presenta quando il UAS riceve un secondo INVITE prima di aver inviato la risposta finale al primo INVITE con CSeq inferiore nello stesso dialogo. Deve restituire 500 Server Internal Error e includere Retry-After con un valore casuale fra 0 e 10 secondi. Un 500 osservato durante una rinegoziazione non prova quindi che il server sia guasto: il contesto e la sequenza dei CSeq possono rivelare una sovrapposizione di INVITE.

Le frequenze di ritentativo implementate dai prodotti vanno confrontate con le regole normative e con la documentazione del costruttore. Un PBX che invia re-INVITE ripetuti senza attendere può creare una cascata di 491 o 500, mascherando l’evento che ha dato origine al problema.

Cosa guardare nel tracciato pcap

La prima operazione consiste nell’isolare la chiamata usando il Call-ID. Poi si ordina la sequenza temporale e si individua ogni INVITE. Il primo stabilisce la sessione; i successivi con gli stessi tag appartengono al dialogo esistente. Il confronto dei CSeq consente di riconoscere l’ordine logico, mentre i branch Via separano gli scambi.

Per ogni re-INVITE bisogna annotare la coppia offerta/risposta e il relativo ACK. Nell’SDP si confrontano almeno: versione o=, indirizzo c=, tipo di flusso, porta, numeri di payload, attributi rtpmap e direzione. Se cambia Contact, si verifica anche la destinazione delle richieste SIP successive.

Dopo l’analisi della segnalazione si passa ai flussi RTP. Gli indirizzi IP e le porte catturati devono essere confrontati con quelli negoziati. Bisogna controllare quando il vecchio flusso si interrompe, quando nasce il nuovo, in quale direzione scorrono i pacchetti e se un SBC riscrive l’SDP. Le ritrasmissioni SIP possono indicare perdita di pacchetti o mancata risposta, ma non vanno confuse con re-INVITE distinti: una ritrasmissione conserva branch e CSeq.

CONSIGLI PER WIRESHARK

Per distinguere un INVITE iniziale da un re-INVITE, filtra prima la chiamata con sip.Call-ID == "7f3a91c2@192.0.2.10", adattando il valore al tracciato, e ordina i pacchetti nel tempo. L’INVITE iniziale apre la sequenza e nel campo To normalmente non contiene ancora il tag remoto. Un re-INVITE compare dopo che il dialogo è stato stabilito: conserva lo stesso Call-ID e gli stessi tag From/To del dialogo, usa un CSeq più alto e un nuovo branch Via. Verifica poi che abbia la propria risposta finale e il proprio ACK. Non usare la sola parola INVITE come criterio, perché sul filo entrambi i messaggi dichiarano lo stesso metodo. Il diagramma Telefonia → Flussi SIP rende immediatamente visibile la posizione della richiesta nella sequenza.

Errori di lettura ricorrenti

Considerare ogni INVITE una nuova chiamata. La presenza dello stesso Call-ID non basta da sola, ma Call-ID, tag e contesto mostrano se la richiesta opera nel dialogo esistente. Il CSeq maggiore non crea una nuova sessione.

Leggere soltanto l’attributo di direzione. La messa in attesa può coincidere con un cambio di porta, indirizzo o codec. Se ci fermiamo a sendonly e recvonly, rischiamo di perdere la vera causa dell’audio assente dopo la ripresa.

Credere che 200 OK garantisca l’audio. La risposta conferma l’accordo SIP. Non dimostra che NAT, firewall, instradamento e dispositivi intermedi consentano all’RTP di raggiungere la destinazione negoziata.

Trattare 488 come fine automatica della chiamata. Il rifiuto della modifica conserva normalmente i parametri precedenti. Bisogna osservare se segue un BYE e chi lo genera, invece di dedurre la terminazione dal solo 488.

Interpretare 491 come indisponibilità dell’altro apparato. Il significato è una richiesta INVITE pendente nello stesso dialogo. L’apparato è raggiungibile e ha risposto; serve analizzare l’incrocio delle richieste e il tentativo successivo.

Confondere una ritrasmissione con una nuova negoziazione. Pacchetti identici con lo stesso branch e CSeq possono essere ritrasmissioni. Un nuovo re-INVITE usa un nuovo branch e un CSeq coerentemente incrementato.

Dare per obbligatorio il comportamento di un prodotto. PBX e SBC possono decidere quando generare re-INVITE per servizi, intervalli interni, gestione centralizzata dell’audio o ottimizzazioni. La RFC definisce come costruire e gestire lo scambio, non impone ogni evento applicativo che lo attiva.

Un metodo pratico per cercare il guasto

Partiamo dal sintomo e dal momento preciso: audio perso durante la messa in attesa, alla ripresa, durante un trasferimento o dopo alcuni minuti. Isoliamo il Call-ID e ricostruiamo la sequenza SIP completa. Identifichiamo chi ha generato il re-INVITE, quale modifica ha proposto e quale risposta ha ricevuto.

Confrontiamo poi l’SDP nuovo con quello precedentemente valido. Se la versione non cambia, annotiamolo. Se cambiano IP o porta, seguiamo i nuovi flussi. Se cambia la direzione, leggiamola dalla prospettiva dell’autore dell’SDP. Se cambia la lista dei codec, verifichiamo che offerta e risposta condividano almeno un formato utilizzabile e che i payload dinamici conservino un significato coerente.

In presenza di 491 o 500 con Retry-After, controlliamo l’ordine temporale degli INVITE e i relativi CSeq. In presenza di 488, analizziamo Warning e contenuto dell’offerta. Con 408, 481 o timeout, allarghiamo l’analisi al percorso di segnalazione, agli indirizzi Contact e alle eventuali riscritture di proxy o SBC.

Infine colleghiamo SIP e RTP. Se la negoziazione è corretta ma l’audio non segue i nuovi parametri, il problema si sposta verso NAT, firewall, instradamento, dispositivi intermedi o comportamento del terminale. Questa separazione riduce le ipotesi e rende il tracciato pcap una prova, non una semplice raccolta di pacchetti.

Conclusione

Il re-INVITE permette di modificare una sessione senza distruggerla e ricrearla. Mantiene il contesto del dialogo, usa nuovamente il modello di offerta e risposta e può cambiare direzione, indirizzi, porte, codec o composizione dei flussi. La descrizione inviata rappresenta l’intera sessione proposta; l’altro apparato può accettarla, rifiutarla oppure richiedere un nuovo tentativo quando un altro INVITE è ancora pendente.

Per leggerlo bene servono tre confronti: identificatori SIP per riconoscere il dialogo, SDP per capire la modifica e pacchetti RTP o UDPTL per verificare il risultato reale. Con questo metodo messa in attesa, ripresa, trasferimento e passaggio a T.38 diventano sequenze osservabili.

Nel prossimo capitolo entreremo nelle classi 1xx e 2xx dei codici di risposta SIP. Le risposte provvisorie e positive viste finora saranno analizzate non come un elenco numerico, ma come segnali che descrivono l’avanzamento e l’esito di una richiesta.

Tags: