RFC 3261: Il DNA del VoIP – Capitolo 13
CODICI DI RISPOSTA SIP: CLASSI 3XX E 4XX
Un interno chiama un collega, il telefono mostra per un istante “inoltro chiamata” e poi squilla un cellulare. In un altro caso la chiamata termina subito con “numero inesistente”. In un terzo il PBX riceve un 401 Unauthorized, invia un nuovo REGISTER e la registrazione si completa normalmente. Sono tre esperienze molto diverse, ma nel tracciato pcap compaiono risposte che appartengono alle classi 3xx e 4xx.
Durante l’analisi di un guasto è facile fermarsi al numero del codice e tradurlo in una conclusione troppo rapida: 302 uguale deviazione, 403 uguale password errata, 404 uguale numero inesistente, 408 uguale apparato non raggiungibile. Queste associazioni possono essere utili come primo orientamento, ma non bastano. Bisogna capire chi ha generato la risposta, a quale richiesta si riferisce, quali header la accompagnano e che cosa farà il dispositivo che la riceve.
Nel capitolo precedente abbiamo separato le risposte provvisorie 1xx dalle risposte positive 2xx. Le prime descrivono l’avanzamento della richiesta; le seconde confermano che la richiesta è stata eseguita con successo. Adesso incontriamo due famiglie differenti: le 3xx comunicano nuove possibilità di destinazione, mentre le 4xx indicano che uno specifico server non può soddisfare quella richiesta nella forma ricevuta.
Questo capitolo non vuole insegnare a memoria un catalogo. Vedremo i codici nel loro contesto operativo, collegandoli alle azioni di telefoni, PBX, proxy, registrar e SBC. L’autenticazione Digest sarà sviluppata nel Capitolo 15; qui chiariremo soltanto perché 401 e 407 possono essere passaggi previsti e non veri insuccessi.
Due classi, due decisioni diverse
La sezione 21.3 della RFC 3261 definisce così la classe 3xx:
“3xx responses give information about the user’s new location, or about alternative services that might be able to satisfy the call.”
Le risposte 3xx forniscono informazioni sulla nuova posizione dell’utente o su servizi alternativi che potrebbero soddisfare la chiamata.
Una risposta 3xx non dice semplicemente “chiamata fallita”. Comunica che la richiesta non è stata completata qui, ma esistono una o più destinazioni da valutare. Queste destinazioni sono normalmente indicate negli header Contact. Il client può costruire nuove richieste verso tali URI, oppure un proxy può usarle per proseguire l’instradamento senza mostrare la deviazione al terminale originante.
La sezione 21.4 della RFC 3261 descrive invece la classe 4xx:
“4xx responses are definite failure responses from a particular server. The client SHOULD NOT retry the same request without modification.”
Le risposte 4xx sono risposte definitive di fallimento provenienti da uno specifico server. Il client non dovrebbe ripetere la stessa richiesta senza modificarla.
La precisazione “da uno specifico server” è importante. Un 4xx chiude quella transaction, ma la medesima richiesta indirizzata a un altro server potrebbe avere successo. Inoltre alcuni codici indicano proprio quale modifica apportare: aggiungere le credenziali dopo un 401 o 407, aumentare l’intervallo di registrazione dopo un 423, rimuovere un’estensione non supportata dopo un 420. Non si deve quindi leggere l’intera classe come un divieto assoluto di riprovare.
Le risposte finali a un INVITE non-2xx, comprese 3xx e 4xx, vengono confermate con ACK. Questo ACK non trasforma il risultato in positivo: serve a completare correttamente lo scambio relativo alla risposta finale. La costruzione e la gestione dell’ACK sono state affrontate nel Capitolo 8; qui ci interessa ricordare che, se nel tracciato compare un 486 o un 488 seguito da ACK, la presenza dell’ACK è normale.
3xx: il destinatario può essere altrove
Immaginiamo che Matteo chiami Daniele all’indirizzo sip:daniele@example.com. Il server che conosce Daniele decide di non inoltrare direttamente l’INVITE al cellulare, ma restituisce al chiamante la nuova destinazione:
SIP/2.0 302 Moved Temporarily
Via: SIP/2.0/UDP 192.0.2.10:5060;branch=z9hG4bK-302a
From: "Matteo" <sip:matteo@example.net>;tag=73a9
To: "Daniele" <sip:daniele@example.com>;tag=redir21
Call-ID: 302-esempio-01@example.net
CSeq: 104 INVITE
Contact: <sip:daniele@mobile.example.com>
Content-Length: 0
La Status-Line identifica un 302 Moved Temporarily. Via, From, To, Call-ID e CSeq permettono al client di associare la risposta all’INVITE corretto. L’elemento operativo è il Contact: contiene l’URI da usare come Request-URI del nuovo tentativo. Il client invia prima l’ACK per la risposta non-2xx, poi costruisce un nuovo INVITE. Non modifica semplicemente il pacchetto precedente e non continua la stessa transaction.
La parola “temporaneamente” ha una conseguenza: il contatto ricevuto non deve diventare automaticamente la destinazione permanente per le chiamate future. La RFC indica che il client SHOULD, quindi dovrebbe, riprovare agli indirizzi forniti nel Contact e non deve memorizzare quel risultato per transaction future come se fosse un trasferimento definitivo dell’identità.
Nel linguaggio dei servizi telefonici si parla spesso di inoltro o deviazione di chiamata, in inglese call diversion. Quando il servizio viene realizzato restituendo un 302 al chiamante, il comportamento SIP è più precisamente una redirection, spesso indicata anche come call deflection: il server non crea direttamente la nuova tratta, ma comunica al client dove ritentare. Per seguire per filo e per segno questo specifico flusso, con la lettura dei messaggi coinvolti, si può consultare l’articolo VOIP.IT Inoltro di chiamata SIP con Status 302 Moved.
Il 301 Moved Permanently comunica invece che l’utente non si trova più all’indirizzo originale. Il client dovrebbe aggiornare rubriche, elenchi locali e cache di localizzazione. Nelle reti VoIP aziendali moderne 301 e 302 non sono necessariamente i meccanismi più comuni per realizzare una deviazione: spesso il PBX riceve la chiamata e crea direttamente una nuova tratta verso la destinazione inoltrata. In quel caso il chiamante potrebbe non vedere alcun 3xx. La funzione percepita dall’utente è la stessa, ma l’architettura SIP è differente.
Gli altri codici 3xx
Il 300 Multiple Choices indica che l’indirizzo richiesto corrisponde a più alternative. La risposta può contenere diversi Contact, eventualmente accompagnati da parametri che esprimono preferenze. Un utente potrebbe essere raggiungibile sul telefono fisso, su un’applicazione e su un altro dominio. Il dispositivo ricevente può scegliere, tentare in sequenza oppure presentare le alternative all’utilizzatore, secondo le proprie capacità e la propria configurazione.
Il 305 Use Proxy ordina di accedere alla risorsa attraverso il proxy indicato nel Contact. La RFC precisa che deve essere generato soltanto da un UAS. Il destinatario ripete quella singola richiesta attraverso il proxy indicato; il Contact non rappresenta in questo caso la nuova posizione dell’utente, ma il punto intermedio da utilizzare.
Il 380 Alternative Service segnala che la chiamata non è riuscita, ma sono disponibili servizi alternativi descritti nel corpo della risposta. La RFC 3261 non definisce il formato di tale corpo. È un buon esempio della differenza tra ciò che il protocollo consente e ciò che si incontra comunemente nei prodotti: la presenza del codice non garantisce che terminale, PBX o provider sappiano utilizzare la descrizione proposta.
Quando un proxy riceve una risposta 3xx può effettuare la cosiddetta ricorsione sui Contact: aggiunge le nuove URI all’insieme delle destinazioni e prova a raggiungerle. Se lo fa, il PBX originante potrebbe vedere soltanto il risultato finale, non il 302 intermedio. Se invece il 3xx viene inoltrato a monte, sarà il client precedente a decidere se e come riprovare. Per questo una deviazione apparentemente identica può produrre tracciati molto diversi.
4xx non significa sempre errore dell’utilizzatore
Il nome formale della classe è Request Failure. In molte descrizioni viene tradotto come “errore del client”, ma questa formula può indurre a cercare subito un guasto nel telefono. Più correttamente, il server sta dicendo che non può eseguire la richiesta così come l’ha ricevuta. La causa può essere nella sintassi, nelle credenziali, nella politica di autorizzazione, nell’indirizzo, nello stato del destinatario o nella negoziazione multimediale.
Occorre inoltre distinguere il codice SIP dall’esperienza dell’utente. Un 486 può far riprodurre localmente il tono di occupato, mostrare “occupato” sul display oppure attivare una deviazione configurata nel PBX. Un 404 può diventare un annuncio vocale generato dal provider. Un 480 può essere presentato come “utente non raggiungibile”. La frase visualizzata e il tono ascoltato sono scelte del prodotto o dell’operatore; il codice SIP resta il dato da verificare.
400, 404 e 410: richiesta malformata o destinazione assente
Il 400 Bad Request indica che la richiesta non è comprensibile a causa di una sintassi malformata. La Reason-Phrase dovrebbe fornire un dettaglio, per esempio un Call-ID mancante. In un impianto reale conviene confrontare la richiesta rifiutata con una richiesta funzionante dello stesso tipo: Request-Line, header obbligatori, separatori, Content-Length e coerenza del corpo. Il testo dopo il codice aiuta, ma non è sempre preciso e può essere personalizzato dal produttore.
Il 404 Not Found significa che il server possiede informazioni definitive sull’inesistenza dell’utente nel dominio specificato nella Request-URI. Può essere restituito anche quando quel dominio non appartiene a quelli gestiti dal server. Prima di concludere che il numero non esiste, bisogna quindi leggere la Request-URI realmente ricevuta dal server: un dominio errato, una manipolazione sbagliata del numero o un prefisso non rimosso possono produrre lo stesso codice.
Il 410 Gone è più specifico: la risorsa non è più disponibile e non è noto alcun indirizzo di inoltro; la condizione è considerata permanente. Se il server non sa stabilire se l’assenza sia permanente, dovrebbe usare 404. Nella pratica 410 si incontra meno spesso, ma la distinzione è utile quando si analizzano servizi dismessi o identità rimosse.
401 e 407: una richiesta di credenziali
Un 401 Unauthorized non prova da solo che nome utente o password siano errati. UAS e registrar lo usano per chiedere l’autenticazione. La risposta contiene normalmente WWW-Authenticate; il client calcola la risposta Digest e invia una nuova richiesta con Authorization. Se le credenziali sono corrette, lo scambio può concludersi con 200 OK.
Il 407 Proxy Authentication Required svolge un ruolo analogo quando la sfida proviene da un proxy. In questo caso si usano normalmente Proxy-Authenticate e Proxy-Authorization. La distinzione non è cosmetica: indica quale entità chiede di autenticarsi e quali header devono essere utilizzati.
SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 192.0.2.20:5060;branch=z9hG4bK-reg01;rport=5060;received=198.51.100.20
From: <sip:matteo@example.com>;tag=reg73
To: <sip:matteo@example.com>;tag=srv90
Call-ID: register-771@192.0.2.20
CSeq: 1 REGISTER
WWW-Authenticate: Digest realm="example.com", nonce="a84f90c1", algorithm=MD5, qop="auth"
Content-Length: 0
Il CSeq mostra che la risposta riguarda un REGISTER. WWW-Authenticate contiene almeno il realm e il nonce necessari per costruire le credenziali. Il nuovo REGISTER avrà un CSeq incrementato e un nuovo branch nel Via, perché costituisce una nuova transaction. Il Call-ID può rimanere lo stesso nell’ambito della sequenza di registrazione.
Se dopo il primo 401 arriva il REGISTER autenticato e poi 200 OK, il comportamento è ordinario. Se invece si ripete la coppia REGISTER/401, bisogna controllare realm, nome utente di autenticazione, password, URI, nonce e algoritmo supportato. Se arriva 403 dopo il tentativo autenticato, il server ha compreso la richiesta ma la rifiuta: le credenziali potrebbero essere valide ma non autorizzate a compiere quell’azione, oppure il prodotto può usare 403 per una propria politica. Il Capitolo 15 ricostruirà l’intero calcolo Digest.
403: richiesta compresa ma rifiutata
Con 403 Forbidden il server ha compreso la richiesta ma rifiuta di soddisfarla. La RFC precisa che una nuova autorizzazione non risolve la condizione e che la richiesta non dovrebbe essere ripetuta. In una rete VoIP il codice può derivare da una regola sulle destinazioni internazionali, dal CLI non autorizzato, da un indirizzo IP non ammesso, da un account sospeso o da una politica antifrode.
Dire “403 uguale password sbagliata” è quindi tecnicamente debole. Alcune piattaforme adottano questa mappatura per scelta implementativa o per non rivelare dettagli, ma la diagnosi richiede i log dell’apparato che ha generato la risposta e la conoscenza della politica applicata. Nel tracciato si può stabilire chi ha inviato il 403 e a quale richiesta; non sempre si può conoscere la regola interna che lo ha motivato.
405, 406, 415, 416, 420 e 421: capacità incompatibili
Il 405 Method Not Allowed compare quando il metodo è conosciuto, ma non è consentito per quella risorsa. La risposta deve includere Allow con l’elenco dei metodi validi. Se un apparato invia REFER verso una risorsa che non lo accetta, per esempio, il 405 descrive meglio il problema di un generico 400.
Il 406 Not Acceptable riguarda le caratteristiche del contenuto che il destinatario della richiesta è in grado di produrre rispetto agli header Accept ricevuti. Il 415 Unsupported Media Type indica invece che il formato del corpo della richiesta non è supportato per quel metodo. Il server deve indicare i formati accettabili tramite Accept, Accept-Encoding o Accept-Language, secondo la causa.
Non bisogna confondere 415 con il più comune 488 Not Acceptable Here. Un INVITE con Content-Type application/sdp può avere un tipo di corpo perfettamente supportato, ma proporre soltanto codec, indirizzi o parametri SDP non accettabili localmente. In tal caso 488 descrive l’incompatibilità della sessione proposta, non l’incapacità di interpretare il formato SDP.
Il 416 Unsupported URI Scheme segnala che lo schema della Request-URI non è conosciuto dal server. I codici 420 Bad Extension e 421 Extension Required operano in direzioni opposte: nel primo caso la richiesta pretende un’estensione non supportata e la risposta deve elencarla in Unsupported; nel secondo il server ha bisogno di un’estensione che il client non ha dichiarato in Supported e deve indicarla in Require.
408 e 480: il tempo scade, ma per ragioni diverse
Il 408 Request Timeout viene generato quando un server non riesce a produrre una risposta entro un tempo adeguato, per esempio perché non determina in tempo la posizione dell’utente. Il client può ripetere la richiesta in seguito senza modificarla. Non va confuso automaticamente con una perdita di pacchetti tra il PBX e il provider: è una risposta SIP ricevuta, dunque un server ha preso una decisione e l’ha comunicata.
Il 480 Temporarily Unavailable indica che il destinatario è noto, ma al momento non è raggiungibile. La causa può essere una registrazione assente, un terminale spento, la modalità non disturbare, una temporanea impossibilità di localizzare l’utente o una politica del servizio. La Reason-Phrase e l’eventuale Retry-After possono fornire informazioni aggiuntive, ma il significato operativo preciso dipende spesso dal sistema che genera la risposta.
Dal punto di vista dell’utilizzatore entrambi possono produrre un messaggio simile. Dal punto di vista tecnico, 408 descrive l’impossibilità del server di completare il trattamento entro il tempo previsto; 480 descrive la temporanea indisponibilità del destinatario. Chi svolge la ricerca del guasto deve correlare il codice con la sorgente della risposta e con il tempo trascorso dall’INVITE.
481, 482 e 483: stato e percorso della segnalazione
Il 481 Call/Transaction Does Not Exist indica che la richiesta ricevuta non corrisponde a un dialog o a una transaction esistente. Può comparire in risposta a un BYE, CANCEL o re-INVITE arrivato all’apparato sbagliato, troppo tardi oppure con identificatori incoerenti. Call-ID, tag From e To, CSeq, branch e percorso seguito vanno confrontati con i messaggi precedenti. L’analisi completa dei dialog arriverà nel Capitolo 17; per ora è sufficiente sapere che il solo Call-ID non identifica da solo ogni situazione.
Il 482 Loop Detected viene generato quando il server riconosce un ciclo di instradamento. Il 483 Too Many Hops compare invece quando Max-Forwards raggiunge zero. I due eventi sono collegati, ma non equivalenti: il primo nasce da un controllo del loop, il secondo dal consumo del contatore lungo il percorso. Un errore nelle regole di routing tra PBX, SBC e provider può far rimbalzare la stessa richiesta finché uno dei due meccanismi interrompe la catena.
484, 485 e 423: indirizzi e intervalli da correggere
Il 484 Address Incomplete indica una Request-URI incompleta. La RFC lo collega anche alla composizione sovrapposta, nella quale il client invia stringhe progressivamente più lunghe finché l’indirizzo diventa sufficiente. Nei sistemi aziendali può rivelare più semplicemente un piano di numerazione o una normalizzazione incompleti. Il 485 Ambiguous comunica invece che la Request-URI può corrispondere a più indirizzi non ambigui, eventualmente elencati nei Contact.
Il 423 Interval Too Brief viene spesso osservato durante il REGISTER. Il registrar rifiuta un intervallo di scadenza troppo breve e indica in Min-Expires il valore minimo accettato. Un client conforme può inviare un nuovo REGISTER aumentando Expires. Non è un’interruzione casuale del servizio: è una negoziazione esplicita della durata minima del binding.
486 e 600 non sono lo stesso occupato
Il 486 Busy Here indica che il destinatario è stato raggiunto, ma non può o non vuole accettare la chiamata in quella specifica posizione. Potrebbero esistere altre posizioni presso le quali l’utente è disponibile. Il codice 600 Busy Everywhere, che appartiene alla classe 6xx e sarà trattato nel prossimo capitolo, esprime invece un fallimento globale: l’utente è occupato in tutte le possibili destinazioni.
Questa differenza emerge soprattutto con il forking. Se un proxy prova contemporaneamente telefono fisso e applicazione mobile, un 486 proveniente dal fisso non dovrebbe necessariamente chiudere ogni altro ramo. La risposta finale vista a monte dipende da come il proxy raccoglie e seleziona le risposte. Il tono di occupato udito dal chiamante è una conseguenza applicativa, non la prova che sia stato ricevuto proprio un 486.
487: la richiesta è stata terminata
Il 487 Request Terminated è frequentemente interpretato come causa originaria del fallimento, mentre spesso è la conseguenza di un CANCEL. Matteo chiama Daniele, poi riaggancia prima della risposta. Il telefono di Matteo invia CANCEL per fermare l’INVITE ancora pendente. Il server risponde 200 OK al CANCEL e chiude l’INVITE con 487 Request Terminated. Seguono quindi due risposte riferite a due richieste differenti.
CANCEL sip:daniele@example.com SIP/2.0
Via: SIP/2.0/UDP 192.0.2.10:5060;branch=z9hG4bK-inv77
From: "Matteo" <sip:matteo@example.net>;tag=73a9
To: "Daniele" <sip:daniele@example.com>
Call-ID: chiamata-487@example.net
CSeq: 88 CANCEL
Content-Length: 0
SIP/2.0 200 OK
CSeq: 88 CANCEL
Content-Length: 0
SIP/2.0 487 Request Terminated
CSeq: 88 INVITE
Content-Length: 0
Il confronto del CSeq chiarisce tutto: 200 OK risponde al CANCEL, 487 risponde all’INVITE. Le righe sono state abbreviate per mettere in evidenza la correlazione; in un messaggio reale saranno presenti anche gli altri header necessari. Se il 487 arriva subito dopo un CANCEL generato dal chiamante o da un proxy, la causa da cercare è ciò che ha provocato il CANCEL, non il 487 stesso.
488 e la negoziazione multimediale
Il 488 Not Acceptable Here indica che alcuni aspetti della descrizione della sessione non sono accettabili per quella risorsa. Il caso tipico è un’offerta SDP senza codec comuni, ma possono essere coinvolti anche il tipo di flusso, la sicurezza richiesta, gli attributi o altre caratteristiche della sessione.
La segnalazione e il flusso reale vanno tenuti separati. Se l’INVITE viene respinto con 488, la sessione non viene stabilita e il normale flusso RTP non dovrebbe iniziare. Se invece la chiamata riceve 200 OK ma l’audio manca, il problema non si spiega con un 488 assente: bisogna confrontare gli SDP e verificare indirizzi, porte, NAT, firewall e pacchetti RTP.
Quando compare 488, confrontiamo l’offerta SDP con le capacità del destinatario: righe m=, payload type, associazioni a=rtpmap, protocollo di trasporto e attributi richiesti. Un SBC può risolvere l’incompatibilità transcodificando o modificando l’offerta, ma questa è una funzione di prodotto e non un obbligo generale della RFC.
Codici meno frequenti ma utili
Il 402 Payment Required è riservato per uso futuro nella RFC 3261. Il 413 Request Entity Too Large rifiuta un corpo troppo grande; se la condizione è temporanea, il server dovrebbe includere Retry-After. Il 414 Request-URI Too Long riguarda invece la lunghezza della Request-URI, non la dimensione complessiva del messaggio.
Il 491 Request Pending segnala che esiste un’altra richiesta in corso nello stesso dialog, situazione osservabile per esempio quando due re-INVITE si incrociano. Il client deve applicare le regole di nuovo tentativo previste dalla RFC, evitando di ripetere immediatamente lo stesso conflitto. Il 493 Undecipherable riguarda un corpo MIME cifrato che il destinatario non riesce a decifrare; la protezione S/MIME sarà affrontata nel Capitolo 28.
⚠ I CONSIGLI DI VOIP.IT
Prima di attribuire un 4xx al provider, annotate quattro dati: richiesta rifiutata, indirizzo IP dell’apparato che genera la risposta, tempo trascorso e header specifici contenuti nella risposta. Un 403 prodotto dal PBX locale non descrive una decisione del carrier; un 404 può dipendere dalla Request-URI costruita male; un 487 successivo a CANCEL è normalmente una conseguenza; un 488 richiede il confronto degli SDP. Il codice orienta l’analisi, ma sorgente, sequenza e contesto identificano la causa.
In Wireshark si può partire dal filtro sip, quindi restringere la singola comunicazione con Call-ID o con gli indirizzi IP coinvolti. La vista del diagramma di flusso aiuta a vedere chi ha originato ciascuna risposta. Per REGISTER, OPTIONS e altri scambi non associati a una chiamata è spesso più utile “Telefonia → Flussi SIP” rispetto alla sola vista “Chiamate VoIP”.
CONSIGLI PER WIRESHARK
L’obiettivo è distinguere una risposta che spiega la causa da una risposta che descrive una conseguenza o un nuovo tentativo. Selezionate il primo INVITE o REGISTER e correlate le risposte usando Call-ID, CSeq, metodo e branch del Via. Per un 302 controllate i Contact e cercate un nuovo INVITE con Request-URI corrispondente: il nuovo branch e il nuovo CSeq identificano una nuova transaction. Per 401 o 407 cercate la richiesta successiva con Authorization o Proxy-Authorization. Per 487 cercate immediatamente prima un CANCEL con lo stesso Call-ID e lo stesso numero CSeq dell’INVITE, ma metodo CANCEL. Per 488 aprite il corpo SDP dell’INVITE e confrontate codec, trasporto e attributi con una chiamata funzionante. Questa sequenza consente di stabilire se il sistema ha seguito l’indicazione ricevuta o si è fermato prima del nuovo tentativo.
Un metodo pratico di diagnosi
Quando incontriamo una risposta 3xx o 4xx possiamo seguire una procedura costante. Prima identifichiamo la richiesta associata tramite Call-ID, CSeq e branch. Poi individuiamo l’apparato che ha generato la risposta, senza confonderlo con quello che l’ha semplicemente inoltrata. Leggiamo gli header che rendono il codice operativo: Contact per 3xx, WWW-Authenticate o Proxy-Authenticate per le sfide, Allow per 405, Unsupported per 420, Require per 421, Min-Expires per 423, Retry-After quando presente.
Il passaggio successivo è osservare la reazione del client. Ha inviato l’ACK previsto? Ha costruito un nuovo INVITE verso il Contact del 302? Ha ripetuto il REGISTER con le credenziali? Ha aumentato Expires dopo 423? Ha terminato l’INVITE con CANCEL prima del 487? Una risposta non si interpreta soltanto leggendo la Status-Line: va verificato il comportamento che produce.
Infine colleghiamo la segnalazione all’effetto percepito. Se l’utente sente un annuncio, cerchiamo se è stato trasportato come early media prima della risposta finale o generato localmente dopo il codice. Se sente occupato, controlliamo quale risposta ha preceduto il tono. Se compare “non registrato”, ricostruiamo l’intera sequenza REGISTER, non soltanto l’ultimo 401. In questo modo il tracciato pcap diventa una cronologia tecnica e non una raccolta di numeri isolati.
Errori di interpretazione da evitare
Il primo errore è trattare ogni 4xx come guasto del telefono o del chiamante. Il codice descrive la richiesta rispetto al server che risponde; una politica, una destinazione temporaneamente assente o un conflitto di stato possono produrre la stessa classe.
Il secondo è considerare 401 e 407 fallimenti definitivi. La prima sfida è spesso parte del normale accesso. Diventa un problema quando il nuovo tentativo non arriva, usa header errati o riceve nuovamente una sfida senza raggiungere il 200 OK.
Il terzo è leggere 487 come origine dell’interruzione. Cercare il CANCEL e chi lo ha generato consente quasi sempre di ricostruire la causa reale: riaggancio dell’utente, scadenza di un timer, risposta positiva su un altro ramo o decisione del proxy.
Il quarto è confondere codice SIP e tono telefonico. I toni riproducono abitudini della telefonia tradizionale e possono essere generati dal terminale, dal PBX o trasportati in banda. La mancata riproduzione del tono atteso non dimostra da sola che il provider abbia inviato il codice sbagliato.
Il quinto è ignorare le traduzioni operate dagli elementi intermedi. Un SBC può sostituire un codice, nascondere dettagli, trasformare una causa interna in una risposta più generica o terminare una tratta e crearne un’altra. Quando sono disponibili acquisizioni su entrambi i lati, confrontarle permette di separare il comportamento della rete da quello dell’interfaccia osservata.
Conclusioni
Le classi 3xx e 4xx raccontano decisioni differenti. Le 3xx offrono nuove destinazioni o servizi alternativi; il client o il proxy può trasformare tali informazioni in nuovi tentativi. Le 4xx chiudono la richiesta presso uno specifico server, ma spesso spiegano anche che cosa manca, che cosa non è accettabile o quale condizione impedisce di procedere.
Per una lettura affidabile servono sempre quattro elementi: la richiesta originale, l’apparato che risponde, gli header collegati al codice e il messaggio successivo. Questo metodo evita le equivalenze semplicistiche e permette di distinguere una normale sfida Digest da credenziali rifiutate, una deviazione da un nuovo tentativo, un occupato locale da un fallimento globale e un 487 conseguente a CANCEL da una causa autonoma.
Nel prossimo capitolo completeremo il quadro con le classi 5xx e 6xx. Vedremo la differenza tra il fallimento di un server e un rifiuto globale, chiarendo perché 503 Service Unavailable, 500 Server Internal Error e 603 Decline richiedono strategie di diagnosi e di instradamento diverse.
