Passa al contenuto principale

16. Comportamento del proxy (Proxy Behavior)

16.1 Panoramica (Overview)​

Un proxy SIP è un elemento che instrada le richieste SIP verso un user agent server (UAS) e le risposte SIP verso un user agent client (UAC). Una richiesta può attraversare più proxy prima di raggiungere il UAS. Ogni proxy prende una decisione di instradamento e modifica la richiesta prima di inoltrarla all'elemento successivo. Le risposte vengono instradate attraverso la stessa serie di proxy in ordine inverso fino a raggiungere il UAC.

Essere un proxy è un ruolo logico che un elemento SIP può svolgere. Quando arriva una richiesta, un elemento in grado di svolgere il ruolo di proxy deve prima determinare se deve rispondere direttamente alla richiesta. Ad esempio, la richiesta potrebbe essere mal formata o il proxy potrebbe richiedere credenziali dal client prima di agire come proxy. L'elemento può rispondere con un qualsiasi codice di errore appropriato (PUÒ). Se risponde direttamente alla richiesta, tale elemento svolge il ruolo di UAS e deve comportarsi conformemente alla sezione 8.2.

Un proxy PUÒ operare in modalità stateful o stateless per ogni nuova richiesta. Se è stateless, il proxy agisce come un semplice elemento di inoltro. Prende decisioni di targeting e instradamento basate sulla richiesta e inoltra la richiesta a un singolo elemento a valle. Tutte le risposte ricevute vengono semplicemente inoltrate a monte. Un proxy stateless elimina ogni informazione sulla richiesta dopo averla inoltrata. Un proxy stateful memorizza informazioni (in particolare lo stato della transazione) su ogni richiesta ricevuta e su ogni richiesta inviata come risultato dell'elaborazione di tale richiesta. Utilizza queste informazioni per influenzare l'elaborazione dei messaggi futuri correlati a tale richiesta. Un proxy stateful PUÒ "forkare" (instradare a più destinazioni) una richiesta. Le richieste inoltrate a più posizioni DEVONO essere elaborate in modalità stateful.

A seconda delle circostanze, un proxy PUÒ inoltrare una richiesta con stato di transazione privo di stato (stateless) su un trasporto con stato (come TCP) (PUÒ). Ad esempio, un proxy PUÒ inoltrare una richiesta senza stato di transazione tra due connessioni TCP purché includa nel messaggio informazioni sufficienti a inoltrare la risposta sulla stessa connessione da cui è arrivata la richiesta. Le richieste inoltrate tra diversi tipi di trasporto, in cui il TU deve assumersi un ruolo attivo per garantire la consegna affidabile su uno dei trasporti, DEVONO essere inoltrate con stato di transazione.

Sia che operi in modalità stateful o stateless, un proxy PUÒ passare a un comportamento stateless in qualsiasi momento durante l'elaborazione della richiesta (PUÒ), purché non abbia fatto qualcosa che preclude di essere stateless fin dall'inizio (come il forking o la generazione di una risposta 100). In questa transizione, elimina semplicemente tutto lo stato. Un proxy NON DOVREBBE iniziare richieste CANCEL.

Che il proxy operi in modalità stateful o stateless, la maggior parte dell'elaborazione della richiesta è identica. Le sottosezioni seguenti sono descritte dal punto di vista di un proxy stateful. L'ultima sezione indica dove un proxy stateless si comporta diversamente.

16.2 Proxy stateful (Stateful Proxy)​

Quando è stateful, il proxy è un motore di elaborazione delle transazioni SIP puro. Il suo comportamento è modellato qui in termini di transazioni server e client definite nella sezione 17. Un proxy stateful possiede, associate a una o più transazioni client, transazioni server gestite da un componente di elaborazione del proxy di livello superiore (vedere figura 3, chiamato core del proxy). Le richieste in entrata sono elaborate dalla transazione server. La richiesta proveniente dalla transazione server viene passata al core del proxy. Il core del proxy determina dove instradare la richiesta (una o più posizioni del hop successivo). L'invio della richiesta a ciascuna posizione del hop successivo è gestito da una transazione client associata. Il core del proxy raccoglie le risposte delle transazioni client e le utilizza per inviare le risposte sulla transazione server.

Per ogni nuova richiesta, un proxy stateful crea una nuova transazione server. Tutte le ritrasmissioni della richiesta sono gestite da tale transazione server conformemente alla sezione 17. Il core del proxy DEVE comportarsi come un UAS inviando una risposta provvisoria immediata (come 100 Trying) su tale transazione server, come descritto nella sezione 8.2.6. Pertanto, un proxy stateful NON DOVREBBE generare una risposta 100 (Trying) per una richiesta non INVITE.

Questo è un modello del comportamento del proxy, non un modello software. Le implementazioni sono libere di adottare qualsiasi approccio che riproduca il comportamento esterno definito da questo modello.

Per ogni nuova richiesta (incluse le modalità sconosciute), un elemento che intende proxificare la richiesta DEVE:

  1. Convalidare la richiesta (sezione 16.3)

2. Preelaborare le informazioni di instradamento (sezione 16.4)

3. Determinare i target della richiesta (sezione 16.5)

+--------------------+
| | +---+
| | | C |
| | | T |
| | +---+
+---+ | Proxy | +---+ CT = Client Transaction
| S | | "Higher" Layer | | C |
| T | | | | T | ST = Server Transaction
+---+ | | +---+
| | +---+
| | | C |
| | | T |
| | +---+
+--------------------+

Figura 3: Modello di proxy stateful

4. Inoltrare la richiesta a ciascun target (sezione 16.6)

5. Elaborare tutte le risposte (sezione 16.7)

16.3 Convalida della richiesta (Request Validation)​

Prima che un elemento proxifichi una richiesta, DEVE convalidare la validità del messaggio. Un messaggio valido DEVE superare i seguenti controlli.

  1. Sintassi ragionevole (Reasonable Syntax)

2. Schema URI (URI scheme)

3. Max-Forwards

4. (Opzionale) Rilevamento dei cicli (Loop Detection)

5. Proxy-Require

6. Proxy-Authorization

Se uno di questi controlli fallisce, l'elemento DEVE comportarsi come un server di agente utente (vedere sezione 8.2) e rispondere con un codice di errore.

Un proxy non è tenuto a rilevare le richieste unite (merged) e NON DEVE trattarle come una condizione di errore. L'endpoint che riceve la richiesta risolve l'unione conformemente alla sezione 8.2.2.2.

  1. Controllo della sintassi ragionevole (Reasonable syntax check)

    La richiesta DEVE essere formattata in modo sufficiente per essere elaborata dalla transazione server. Tutti i componenti coinvolti nei passaggi di convalida o inoltro della richiesta successivi DEVONO essere formattati in modo sufficiente. Gli altri componenti DOVREBBERO essere ignorati, che il loro formato sia corretto o meno, e non essere modificati durante l'inoltro del messaggio. Ad esempio, un elemento non rifiuta una richiesta solo perché il campo di intestazione Date è mal formato. Allo stesso modo, un proxy non rimuove un campo di intestazione Date mal formattato prima di inoltrare la richiesta.

    Questo protocollo è progettato per essere esteso. Estensioni future possono definire nuovi metodi o campi di intestazione in qualsiasi momento. Un elemento NON DEVE rifiutarsi di proxificare una richiesta perché contiene metodi o campi di intestazione sconosciuti.

  2. Controllo dello schema URI (URI scheme check)

    Se il Request-URI è un URI il cui schema il proxy non comprende, il proxy DOVREBBE rifiutare la richiesta con una risposta 416 (Unsupported URI Scheme).

  3. Controllo Max-Forwards

    Il campo di intestazione Max-Forwards (sezione 20.22) è utilizzato per limitare il numero di elementi che una richiesta SIP può attraversare.

    Se la richiesta non contiene un campo di intestazione Max-Forwards, questo controllo passa.

    Se la richiesta contiene un campo di intestazione Max-Forwards con valore maggiore di zero, il controllo passa.

    Se la richiesta contiene un campo di intestazione Max-Forwards con valore zero (0), l'elemento NON DEVE inoltrare la richiesta. Se la richiesta era indirizzata a OPTIONS, l'elemento PUÒ agire come destinatario finale e rispondere conformemente alla sezione 11. Altrimenti, l'elemento DEVE restituire una risposta 483 (Too many hops).

  4. Controllo opzionale di rilevamento dei cicli (Optional Loop Detection check)

    Un elemento PUÒ verificare la presenza di cicli di inoltro prima di inoltrare una richiesta. Se la richiesta contiene un campo di intestazione Via con un valore sent-by uguale a quello che il proxy aveva precedentemente impostato, la richiesta è stata già inoltrata da questo elemento. La richiesta ha fatto un ciclo o è legittimamente spiraleggiata attraverso l'elemento. Per determinare se la richiesta ha fatto un ciclo, l'elemento PUÒ eseguire il calcolo del parametro branch descritto al passo 8 della sezione 16.6 su questo messaggio e confrontarlo con il parametro ricevuto in tale campo Via. Se i parametri corrispondono, la richiesta ha fatto un ciclo. Se differiscono, la richiesta è spiraleggiata e l'elaborazione prosegue. Se viene rilevato un ciclo, l'elemento PUÒ restituire una risposta 482 (Loop Detected).

  5. Controllo Proxy-Require

    Le estensioni future di questo protocollo possono introdurre funzionalità che richiedono un'elaborazione speciale da parte dei proxy. Gli endpoint includono un campo di intestazione Proxy-Require nelle richieste che utilizzano queste funzionalità, indicando al proxy di non elaborare la richiesta a meno che la funzionalità non sia compresa.

    Se la richiesta contiene un campo di intestazione Proxy-Require (sezione 20.29) con uno o più option-tag che questo elemento non comprende, l'elemento DEVE restituire una risposta 420 (Bad Extension). La risposta DEVE includere un campo di intestazione Unsupported (sezione 20.40) che elenca gli option-tag che l'elemento non ha compreso.

  6. Controllo Proxy-Authorization

    Se un elemento richiede credenziali prima di inoltrare una richiesta, DEVE ispezionarla conformemente alla sezione 22.3. Tale sezione definisce anche ciò che l'elemento deve fare in caso di fallimento dell'ispezione.

16.4 Preparazione della richiesta per l'instradamento (Preparing the Request for Routing)​

Prima di inoltrare la richiesta, l'elemento DEVE ispezionare e modificare i campi di intestazione che influenzano l'instradamento. Il campo di intestazione Record-Route (sezione 20.30) rimane nella richiesta così com'è. Inoltre, l'elemento DEVE eseguire i seguenti passaggi:

  1. Se la richiesta contiene un campo di intestazione Route (sezione 20.34) e il suo primo valore (più in alto) non indica l'elemento, l'elemento procede alla sezione 16.6 senza modificare la richiesta. L'elemento non inserisce un valore Record-Route nella richiesta. L'elemento inoltra la richiesta così com'è all'elemento successivo.

Nota: il fatto che il primo valore Route non indichi l'elemento significa che l'elemento sta elaborando un campo Route inserito da un elemento precedente che non implementa il loose routing.

2. Se la richiesta contiene un campo di intestazione Route (sezione 20.34) e il suo primo valore indica l'elemento:

Se l'elemento supporta il loose routing, l'elemento DEVE rimuovere il primo valore del campo di intestazione Route. Si applicano le procedure di loose routing.

Se l'elemento non implementa il loose routing, l'elemento DEVE eseguire le procedure di strict routing della RFC 2543.

3. Infine, l'elemento PUÒ aggiungere alla richiesta un valore Record-Route che lo indica.

16.5 Determinazione dei target della richiesta (Determining Request Targets)​

Quando un elemento elabora una richiesta che crea una finestra di dialogo (ad esempio INVITE), DEVE inizializzare l'insieme di instradamento (route set) della finestra di dialogo. L'insieme di instradamento viene inizializzato quando l'elemento inserisce un valore Record-Route nella richiesta.

Quando un elemento elabora una richiesta che crea una finestra di dialogo, DEVE inoltrare la richiesta a una o più posizioni. Ciò è chiamato insieme dei target (target set).

Il modo in cui l'elemento determina i target dipende dal tipo di richiesta (che crea una finestra di dialogo o in una finestra di dialogo) e dal fatto che il Request-URI indichi un dominio gestito dall'elemento.

  1. Se la richiesta non contiene un campo di intestazione Route, l'elemento DEVE verificare se la risorsa indicata dall'URI del Request-URI è di sua proprietà. Se l'URI indica una risorsa all'interno di un dominio gestito dall'elemento, DEVE sostituire il valore del Request-URI con un insieme che rappresenta la posizione di tale risorsa (ad esempio i Contact registrati o l'agente personale della risorsa). Ciò avviene in genere eseguendo il servizio di localizzazione dell'elemento. La posizione può derivare dalla registrazione (sezione 10), dal reindirizzamento o da altri mezzi.

Se il Request-URI non indica una risorsa di un dominio gestito, l'elemento inserisce il Request-URI nell'insieme dei target.

2. Se la richiesta contiene un campo di intestazione Route, l'elemento DEVE impostare l'insieme dei target sulla posizione indicata dal primo valore (più in alto) del campo di intestazione Route. Se l'elemento implementa il loose routing, il primo valore del campo Route è già stato rimosso (al passo 2 della sezione 16.4), quindi il valore Route successivo (se presente) diventa l'insieme dei target. L'URI del Request-URI non viene utilizzato per calcolare l'insieme dei target.

Per una richiesta all'interno di una finestra di dialogo (ad esempio BYE), l'elemento DEVE impostare l'insieme dei target sul primo valore dell'insieme di instradamento della finestra di dialogo. L'URI target remoto della finestra di dialogo non viene utilizzato per calcolare l'insieme dei target.

L'elemento PUÒ eseguire controlli di policy locale sull'insieme dei target prima di inoltrarlo. L'elemento PUÒ modificare l'insieme dei target per ricorsione alla ricezione di una risposta 3xx.

16.6 Inoltro della richiesta (Forwarding the Request)​

Prima di inoltrare (o proxificare) una richiesta, l'elemento DEVE eseguire i seguenti passaggi per ciascuna destinazione del suo insieme di target:

  1. Creare una copia (Make a copy)

     L'elemento crea una copia della richiesta ricevuta e la modifica nei passaggi successivi. L'elemento NON DEVE modificare direttamente la richiesta ricevuta. Ciò consente all'elemento di inoltrare la richiesta originale in caso di errore o anomalia.

  2. Scambiare l'indirizzo multicast con un host multicast-capable (Swap multicast address for a multicast-capable host)

     Se la parte host del Request-URI è l'indirizzo di un gruppo IP multicast, l'elemento PUÒ sostituire la parte host con un indirizzo unicast di un host multicast-capable in grado di ascoltare il gruppo ed elaborare la richiesta. Ciò impedisce agli altri host del gruppo multicast di ricevere ed elaborare una copia della richiesta.

  3. Aggiungere un valore Record-Route se necessario (Add a Record-Route value if necessary)

     Se l'elemento inserisce un valore Record-Route, DEVE inserire all'inizio della copia un nuovo valore Record-Route uguale al seguente URI:

        o Se l'elemento ha ricevuto la richiesta tramite UDP ma la invia tramite TCP, l'URI DEVE essere una SIP URI e includere il nome host o l'indirizzo IP (e la porta opzionale) dell'elemento nonché un parametro transport che indica il trasporto ascoltato. Se l'elemento ha inizialmente ricevuto in UDP e invia tramite TCP, l'URI DEVE utilizzare lo schema sip.

        o Se l'elemento ha ricevuto la richiesta tramite TCP e la invia tramite UDP, l'URI DEVE essere una SIP URI e includere il nome host o l'indirizzo IP (e la porta opzionale) dell'elemento nonché un parametro transport=udp.

        o Se l'elemento ha ricevuto tramite TLS e invia tramite una connessione non TLS (o viceversa), l'URI DEVE essere una SIPS URI o una SIP URI a seconda che il trasporto di ricezione fosse TLS.

        o Altrimenti, l'elemento PUÒ utilizzare una SIP URI o SIPS URI contenente il suo nome host o il suo indirizzo IP (e la porta opzionale). L'elemento PUÒ ascoltare su una porta diversa da quella da cui è arrivata la richiesta. L'elemento PUÒ includere un parametro transport per indicare le sue capacità.

     L'elemento DEVE includere il parametro lr nell'URI che inserisce nel campo Record-Route (vedere sezione 19.1.1).

  4. Elaborare le informazioni di instradamento (Process routing information)

     Se l'elemento implementa il loose routing, non modifica il Request-URI. Altrimenti, se è uno strict router, l'elemento DEVE copiare il primo valore del campo Route nel Request-URI e rimuoverlo dal campo Route. L'elemento NON DEVE modificare i parametri in tale URI in alcun modo prima di inserirlo nel Request-URI.

     L'elemento PUÒ verificare se uno dei valori del campo Route lo indica. In tal caso, PUÒ rimuoverlo.

  5. Aggiungere il Request-URI alla copia (Add the Request-URI to the copy)

     Se l'elemento è uno strict router e il Request-URI della copia proviene dal primo valore del campo Route, DEVE rimuoverlo dal campo Route.

  6. Decrementare Max-Forwards (Decrement Max-Forwards)

     Se la copia non contiene un campo Max-Forwards, l'elemento DEVE impostarlo a 70. Altrimenti, l'elemento DEVE decrementare il valore del campo di 1.

  7. Determinare l'indirizzo, la porta e il trasporto del hop successivo (Determine the next-hop address, port, and transport)

     L'elemento determina, per un membro dell'insieme dei target, l'indirizzo, la porta e il trasporto.

     Se l'insieme dei target era un valore Route, l'indirizzo, la porta e il trasporto sono determinati risolvendo tale URI secondo le procedure descritte nell'appendice C della RFC 2543.

     Se l'insieme dei target era il Request-URI, le procedure della RFC 3263 vengono applicate utilizzando il metodo e il Request-URI.

  8. Aggiungere il proprio Via alla copia (Add own Via to the copy)

     L'elemento DEVE aggiungere all'inizio del campo Via della copia un nuovo valore Via che contiene il proprio indirizzo sent-by. L'indirizzo DEVE essere il luogo in cui l'elemento ascolta su tale trasporto e DEVE garantire che riceverà la risposta tramite tale connessione.

     Il valore Via DEVE includere il parametro branch scelto dall'elemento quando ha inviato la richiesta a tale destinazione su tale trasporto.

     Il parametro branch DEVE essere univoco per tutte le richieste inviate dall'elemento (tranne CANCEL e ACK non 2xx). Ciò richiede unicità nello spazio e nel tempo. Per calcolare tale parametro branch, l'elemento DEVE sottoporre a hash una parte specifica della richiesta (una stringa che inizia con il magic cookie "z9hG4bK" della RFC 3261).

     Quando un proxy inoltra una richiesta, crea una copia contenente tutti i valori ricevuti (incluso il Request-URI) e vi aggiunge il proprio Via. Tutti i parametri che costituiscono la sintassi della richiesta e tutti i valori di campo di intestazione che influenzano l'instradamento o l'accettazione della richiesta DEVONO essere inclusi nel calcolo dell'hash. Ciò è necessario per distinguere una richiesta che ha fatto un ciclo da una richiesta i cui parametri di instradamento sono stati modificati prima di tornare a questo server.

     Il metodo della richiesta NON DEVE essere incluso nel calcolo del parametro branch. In particolare, le richieste CANCEL e ACK (per risposte non 2xx) DEVONO avere lo stesso valore branch della richiesta corrispondente che annullano o confermano. Il parametro branch è utilizzato per correlare queste richieste sul server (vedere sezioni 17.2.3 e 9.2).

  9. Aggiungere un campo Content-Length se necessario (Add a Content-Length header field if necessary)

     Se la richiesta viene inviata al hop successivo tramite un trasporto basato su flusso e la copia non contiene un campo Content-Length, il proxy DEVE inserirne uno con il valore corretto per il corpo della richiesta (sezione 20.14).

  10. Inoltrare la richiesta (Forward Request)

      Un proxy stateful DEVE creare una nuova transazione client per questa richiesta come descritto nella sezione 17.1 e ordinare alla transazione di inviare la richiesta utilizzando l'indirizzo, la porta e il trasporto determinati al passo 7.

  11. Impostare il timer C (Set timer C)

      Per gestire il caso in cui una richiesta INVITE non generi mai una risposta finale, il TU utilizza un timer chiamato timer C. Quando una richiesta INVITE viene proxificata, il timer C DEVE essere impostato per ogni transazione client. Il timer DEVE essere superiore a 3 minuti. La sezione 16.7 punto 2 spiega come questo timer viene aggiornato con le risposte provvisorie e la sezione 16.8 spiega l'elaborazione al suo scadere.

16.7 Elaborazione delle risposte (Response Processing)​

Quando un elemento riceve una risposta, tenta prima di individuare una transazione client (sezione 17.1.3) corrispondente alla risposta. Se non ne trova, l'elemento DEVE elaborare la risposta (anche se si tratta di una risposta informativa) come un proxy stateless (vedere sotto). Se viene trovata una corrispondenza, la risposta viene consegnata alla transazione client.

  Inoltrare le risposte per le quali non viene trovata alcuna transazione client (o più in generale alcuna conoscenza di una richiesta associata inviata) migliora la robustezza. In particolare, ciò garantisce che le risposte 2xx "ritardate" alle richieste INVITE vengano inoltrate correttamente.

Quando le transazioni client consegnano le risposte al livello proxy, DEVE aver luogo la seguente elaborazione:

  1. Trovare il contesto di risposta appropriato

2. Aggiornare il timer C per le risposte provvisorie

3. Rimuovere il Via più in alto

4. Aggiungere la risposta al contesto

5. Verificare se questa risposta deve essere inoltrata immediatamente

6. Se necessario, selezionare la migliore risposta finale dal contesto di risposta

Se nessuna risposta finale è stata inoltrata dopo che tutte le transazioni client associate a tale contesto di risposta sono terminate, il proxy DEVE scegliere e inoltrare la migliore risposta tra quelle che ha visto finora.

La seguente elaborazione DEVE essere eseguita su ogni risposta inoltrata. È probabile che vengano inoltrate più risposte per ciascuna richiesta: almeno ogni provvisoria e una risposta finale.

  7. Aggregare i valori dei campi di intestazione Authorization se necessario

8. Riscrivere facoltativamente i valori dei campi Record-Route

9. Inoltrare la risposta

10. Generare le richieste CANCEL necessarie

Ciascuno dei passaggi precedenti è dettagliato di seguito:

  1. Trovare il contesto (Find Context)

     Il proxy individua il "contesto di risposta" che ha creato prima di inoltrare la richiesta originale utilizzando la chiave descritta nella sezione 16.6. I restanti passaggi di elaborazione avvengono in questo contesto.

  2. Aggiornare il timer C per le risposte provvisorie (Update timer C for provisional responses)

     Per una transazione INVITE, se la risposta è una risposta provvisoria con codice di stato da 101 a 199 incluso (ovvero diversa da 100), il proxy DEVE reimpostare il timer C di tale transazione client. Il timer PUÒ essere reimpostato su un valore diverso, ma tale valore DEVE essere superiore a 3 minuti.

  3. Via

     Il proxy rimuove il valore più in alto del campo di intestazione Via dalla risposta.

     Se nella risposta non rimane alcun valore Via, la risposta era destinata a questo elemento e NON DEVE essere inoltrata. La restante elaborazione di questa sezione non viene eseguita su questo messaggio; invece, vengono seguite le regole di elaborazione UAC della sezione 8.1.3 (l'elaborazione del livello di trasporto è già avvenuta).

     Ciò si verifica, ad esempio, quando l'elemento genera richieste CANCEL come descritto nella sezione 10.

  4. Aggiungere la risposta al contesto (Add response to context)

     Le risposte finali ricevute vengono memorizzate nel contesto di risposta fino all'invio di una risposta finale sulla transazione server associata a tale contesto. La risposta può essere candidata per la migliore risposta finale da restituire su tale transazione server. Le informazioni di tale risposta possono essere necessarie per formare la migliore risposta, anche se tale risposta non viene selezionata.

     Se il proxy sceglie di ricorsione su un qualsiasi Contact di una risposta 3xx aggiungendolo all'insieme dei target, DEVE rimuoverlo dalla risposta prima di aggiungere la risposta al contesto di risposta. Tuttavia, un proxy NON DOVREBBE ricorsionare verso un URI non SIPS se il Request-URI della richiesta originale era un URI SIPS. Se il proxy ricorsiona su tutti i Contact di una risposta 3xx, NON DOVREBBE aggiungere la risposta risultante senza Contact al contesto di risposta.

     Rimuovere il Contact prima di aggiungere la risposta al contesto di risposta impedisce al successivo elemento a monte di riprovare una posizione già tentata da questo proxy.

     Le risposte 3xx possono contenere una miscela di URI SIP, SIPS e non SIP. Un proxy può scegliere di ricorsionare sulle URI SIP e SIPS e di inserire il resto nel contesto di risposta per essere restituito, eventualmente, nella risposta finale.

     Se un proxy riceve una risposta 416 (Unsupported URI Scheme) a una richiesta il cui schema del Request-URI non era SIP, ma lo schema della richiesta originariamente ricevuta era SIP o SIPS (ovvero il proxy ha cambiato lo schema da SIP o SIPS ad altro proxificando la richiesta), il proxy DOVREBBE aggiungere una nuova URI all'insieme dei target. Tale URI DOVREBBE essere una versione SIP URI della URI non SIP appena tentata. Nel caso di un URL tel, ciò si ottiene inserendo la parte telephone-subscriber dell'URL tel nella parte user della SIP URI e impostando l'hostpart sul dominio a cui è stata inviata la richiesta precedente. Vedere la sezione 19.1.6 per i dettagli sulla formazione di SIP URI a partire da URL tel.

     Come per una risposta 3xx, se un proxy "ricorsiona" sul 416 provando invece una SIP URI o SIPS URI, la risposta 416 NON DOVREBBE essere aggiunta al contesto di risposta.

  5. Verificare la risposta per l'inoltro (Check response for forwarding)

     Fino all'invio di una risposta finale sulla transazione server, le risposte seguenti DEVONO essere inoltrate immediatamente:

     - Qualsiasi risposta provvisoria diversa da 100 (Trying)

     - Qualsiasi risposta 2xx

     Se viene ricevuta una risposta 6xx, non viene inoltrata immediatamente, ma il proxy stateful DOVREBBE annullare tutte le transazioni client in attesa come descritto nella sezione 10 e NON DEVE creare nuovi rami in questo contesto.

     Questa è una modifica rispetto alla RFC 2543, che imponeva al proxy di inoltrare immediatamente la risposta 6xx. Per una transazione INVITE, questo approccio presentava il problema che una risposta 2xx poteva arrivare su un altro ramo, nel qual caso il proxy dovrebbe inoltrare il 2xx. Il risultato era che il UAC poteva ricevere una risposta 6xx seguita da una risposta 2xx, il che non dovrebbe mai essere permesso. Secondo le nuove regole, alla ricezione di un 6xx, un proxy emette una richiesta CANCEL, che in genere comporta risposte 487 da tutte le transazioni client in attesa, dopodiché il 6xx viene inoltrato a monte.

     Dopo che una risposta finale è stata inviata sulla transazione server, le risposte seguenti DEVONO essere inoltrate immediatamente:

     - Qualsiasi risposta 2xx a una richiesta INVITE

     Un proxy stateful NON DEVE inoltrare immediatamente alcuna altra risposta. In particolare, un proxy stateful NON DEVE inoltrare una risposta 100 (Trying). Le risposte candidate per un successivo inoltro come "migliore" risposta sono state raccolte come descritto al passo "Aggiungere la risposta al contesto".

     Qualsiasi risposta scelta per un inoltro immediato DEVE essere elaborata come descritto nei passi "Aggregare i valori dei campi Authorization" fino a "Record-Route".

     Questo passo, combinato con il successivo, garantisce che un proxy stateful inoltrerà esattamente una risposta finale a una richiesta non INVITE e o una sola risposta non 2xx o una o più risposte 2xx a una richiesta INVITE.

  6. Scegliere la migliore risposta (Choosing the best response)

     Un proxy stateful DEVE inviare una risposta finale al contesto di risposta della transazione server se nessuna risposta finale è stata inoltrata immediatamente dalle regole sopra e tutte le transazioni client di tale contesto sono terminate.

     Il proxy stateful DEVE scegliere la migliore risposta finale tra quelle ricevute e memorizzate nel contesto di risposta.

     Se nel contesto non vi è alcuna risposta finale, il proxy DEVE inviare una risposta 408 (Request Timeout) alla transazione server.

     Altrimenti, il proxy DEVE inoltrare una risposta tra quelle memorizzate nel contesto di risposta. DEVE scegliere tra le risposte di classe 6xx se presenti nel contesto. Se non vi è alcuna risposta di classe 6xx, il proxy DOVREBBE scegliere dalla classe di risposta più bassa memorizzata nel contesto di risposta. Il proxy PUÒ selezionare qualsiasi risposta all'interno di tale classe scelta. Il proxy DOVREBBE dare la preferenza alle risposte che forniscono informazioni che influenzano il reinvio di questa richiesta, come 401, 407, 415, 420 e 484 se viene scelta la classe 4xx.

     Un proxy che riceve una risposta 503 (Service Unavailable) NON DOVREBBE inoltrarla a monte a meno che non possa determinare che qualsiasi richiesta successiva che potrebbe proxificare genererà anch'essa un 503. In altre parole, inoltrare un 503 significa che il proxy sa di non poter servire alcuna richiesta, non solo quella del Request-URI che ha generato il 503. Se l'unica risposta ricevuta è un 503, il proxy DOVREBBE generare una risposta 500 e inoltrarla a monte.

     La risposta inoltrata DEVE essere elaborata come descritto nei passi "Aggregare i valori dei campi Authorization" fino a "Record-Route".

     Ad esempio, se un proxy inoltra una richiesta a 4 posizioni e riceve le risposte 503, 407, 501, 404, può scegliere di inoltrare la risposta 407 (Proxy Authentication Required).

     Le risposte 1xx e 2xx possono essere coinvolte nell'instaurazione delle finestre di dialogo. Quando una richiesta non contiene un tag To, il tag To della risposta è utilizzato dal UAC per distinguere più risposte a una richiesta che crea una finestra di dialogo. Un proxy NON DEVE inserire un tag nel campo To di una risposta 1xx o 2xx se la richiesta non ne conteneva uno. Un proxy NON DEVE modificare il tag nel campo To di una risposta 1xx o 2xx.

     Poiché un proxy non può inserire un tag nel campo To di una risposta 1xx a una richiesta che non ne contiene uno, non può emettere di propria iniziativa risposte provvisorie non 100. Può tuttavia diramare la richiesta verso un UAS che condivide lo stesso elemento del proxy. Tale UAS può restituire le proprie risposte provvisorie, entrando in una finestra di dialogo precoce con l'iniziatore della richiesta. Il UAS non deve essere un processo distinto dal proxy. Può essere un UAS virtuale implementato nello stesso spazio di codice del proxy.

     Le risposte 3-6xx vengono consegnate hop-by-hop. Emanando una risposta 3-6xx, l'elemento agisce efficacemente come un UAS, emettendo la propria risposta, generalmente basata sulle risposte ricevute dagli elementi a valle. Un elemento DOVREBBE preservare il tag To quando inoltra semplicemente una risposta 3-6xx a una richiesta priva di tag To.

     Un proxy NON DEVE modificare il tag To in qualsiasi risposta inoltrata a una richiesta contenente un tag To.

     Sebbene non faccia alcuna differenza per gli elementi a monte se il proxy sostituisce il tag To in una risposta 3-6xx inoltrata, conservare il tag originale può essere utile per il debug.

     Quando il proxy aggrega informazioni da più risposte, la scelta di un tag To tra esse è arbitraria e generare un nuovo tag To può facilitare il debug. Ciò accade, ad esempio, combinando le sfide 401 (Unauthorized) e 407 (Proxy Authentication Required) o combinando valori Contact da risposte 3xx non crittografate e non autenticate.

  7. Aggregare i valori dei campi Authorization (Aggregate Authorization Header Field Values)

     Se la risposta selezionata è una 401 (Unauthorized) o 407 (Proxy Authentication Required), il proxy DEVE raccogliere tutti i valori dei campi WWW-Authenticate e Proxy-Authenticate di tutte le altre risposte 401 e 407 ricevute finora in questo contesto di risposta e aggiungerli a questa risposta senza modificarla prima dell'inoltro. La risposta 401 o 407 risultante potrebbe avere più valori di campo WWW-Authenticate E Proxy-Authenticate.

     Ciò è necessario poiché uno o tutti i destinatari verso cui è stata inoltrata la richiesta potrebbero aver richiesto credenziali. Il client deve ricevere tutte queste sfide e fornire le credenziali per ciascuna quando ritenta la richiesta. La motivazione di questo comportamento è fornita nella sezione 26.

  8. Record-Route

     Se la risposta selezionata contiene un valore di campo Record-Route originariamente fornito da questo proxy, il proxy PUÒ scegliere di riscrivere il valore prima di inoltrare la risposta. Ciò consente al proxy di fornire URI diversi per sé stesso agli elementi successivi a monte e a valle. Un proxy può scegliere di utilizzare questo meccanismo per qualsiasi motivo. Ad esempio, è utile per gli host multihomed.

     Se il proxy ha ricevuto la richiesta tramite TLS e l'ha inviata tramite una connessione non TLS, il proxy DEVE riscrivere l'URI nel campo Record-Route in una SIPS URI. Se il proxy ha ricevuto la richiesta tramite una connessione non TLS e l'ha inviata tramite TLS, il proxy DEVE riscrivere l'URI nel campo Record-Route in una SIP URI.

     La nuova URI fornita dal proxy DEVE soddisfare le stesse restrizioni sulle URI inserite nei campi Record-Route delle richieste (vedere passo 4 della sezione 16.6) con le seguenti modifiche:

     L'URI NON DOVREBBE contenere il parametro transport a meno che il proxy non sappia che il successivo elemento a monte (non a valle) sul percorso delle richieste successive supporta tale trasporto.

     Quando un proxy decide di modificare il valore del campo Record-Route nella risposta, una delle operazioni che esegue è l'individuazione del valore Record-Route che ha inserito. Se la richiesta è spiraleggiata e il proxy ha inserito un valore Record-Route a ogni iterazione della spirale, individuare il valore corretto nella risposta (che deve essere l'iterazione appropriata nella direzione inversa) è delicato. Le regole sopra raccomandano che un proxy che desidera riscrivere i valori Record-Route inserisca nel campo Record-Route URI sufficientemente distinte affinché quella corretta possa essere selezionata per la riscrittura. Un meccanismo raccomandato per ciò è che il proxy aggiunga un identificatore univoco dell'istanza di proxy alla parte user dell'URI.

     Quando la risposta arriva, il proxy modifica il primo Record-Route il cui identificatore corrisponde all'istanza di proxy. La modifica produce un URI privo di quel frammento di dati aggiunto alla parte user dell'URI. Alla successiva iterazione, lo stesso algoritmo (trovare il valore Record-Route più in alto con il parametro) estrarrà correttamente il valore Record-Route successivo inserito da questo proxy.

     Non tutte le risposte a una richiesta a cui un proxy aggiunge un valore Record-Route conterranno necessariamente un campo Record-Route. Se la risposta contiene un campo Record-Route, esso contiene il valore aggiunto dal proxy.

  9. Inoltrare la risposta (Forward response)

     Dopo aver eseguito l'elaborazione descritta nei passi "Aggregare i valori dei campi Authorization" fino a "Record-Route", il proxy PUÒ eseguire qualsiasi manipolazione specifica di funzionalità sulla risposta selezionata. Il proxy NON DEVE aggiungere, modificare o rimuovere il corpo del messaggio. Se non diversamente specificato, il proxy NON DEVE rimuovere altri valori di campo di intestazione oltre al valore Via discusso all'articolo 3 della sezione 16.7. In particolare, il proxy NON DEVE rimuovere un parametro "received" che potrebbe aver aggiunto al valore Via successivo quando ha elaborato la richiesta associata a questa risposta. Il proxy DEVE consegnare la risposta alla transazione server associata al contesto di risposta. Ciò comporterà l'invio della risposta alla posizione ora indicata nel valore Via più in alto. Se la transazione server non è più disponibile per gestire l'invio, l'elemento DEVE inoltrare la risposta in modo stateless inviandola al trasporto server. La transazione server può indicare un errore di invio o segnalare un timeout nella sua macchina a stati. Tali errori sarebbero registrati a scopo diagnostico, ma il protocollo non richiede alcuna misura correttiva da parte del proxy.

     Il proxy DEVE mantenere il contesto di risposta finché tutte le transazioni associate non sono terminate, anche dopo aver inoltrato una risposta finale.

  10. Generare CANCEL (Generate CANCELs)

      Se la risposta inoltrata era una risposta finale, il proxy DEVE generare una richiesta CANCEL per tutte le transazioni client in attesa associate a tale contesto di risposta. Un proxy DOVREBBE inoltre generare una richiesta CANCEL per tutte le transazioni client in attesa associate a tale contesto di risposta quando riceve una risposta 6xx. Una transazione client in attesa è quella che ha ricevuto una risposta provvisoria ma non una risposta finale (si trova nello stato proceeding) e per la quale non è stato generato alcun CANCEL associato. La generazione di richieste CANCEL è descritta nella sezione 9.1.

      Il requisito di annullare le transazioni client in attesa all'inoltro di una risposta finale non garantisce che un endpoint non riceva più risposte 200 (OK) a un INVITE. Risposte 200 (OK) su più rami potrebbero essere generate prima che le richieste CANCEL possano essere inviate ed elaborate. Inoltre, è ragionevole aspettarsi che un'estensione futura sostituisca questo requisito di emissione di CANCEL.

16.8 Elaborazione del timer C (Processing Timer C)​

Se il timer C scade, il proxy DEVE o reimpostarlo con il valore di sua scelta o terminare la transazione client. Se la transazione client aveva ricevuto una risposta provvisoria, il proxy DEVE generare una richiesta CANCEL corrispondente a tale transazione. Se la transazione client non aveva ricevuto una risposta provvisoria, il proxy DEVE comportarsi come se la transazione avesse ricevuto una risposta 408 (Request Timeout).

Consentire al proxy di reimpostare il timer gli permette di estendere dinamicamente la durata della transazione in base alle condizioni correnti (come l'utilizzo) al momento della scadenza.

16.9 Gestione degli errori di trasporto (Handling Transport Errors)​

Se il livello di trasporto notifica a un proxy un errore nel tentativo di inoltrare una richiesta (vedere sezione 18.4), il proxy DEVE comportarsi come se la richiesta inoltrata avesse ricevuto una risposta 503 (Service Unavailable).

Se al proxy viene notificato un errore durante l'inoltro di una risposta, esso scarta la risposta. Il proxy NON DOVREBBE annullare le transazioni client in attesa associate a tale contesto di risposta a causa di tale notifica.

  Se un proxy annulla le sue transazioni client in attesa, un singolo client malintenzionato o malfunzionante può far fallire tutte le transazioni attraverso il proprio campo Via.

16.10 Elaborazione di CANCEL (CANCEL Processing)​

Un proxy stateful PUÒ generare un CANCEL verso qualsiasi altra richiesta che ha generato in qualsiasi momento (purché riceva una risposta provvisoria a tale richiesta come descritto nella sezione 9.1). Un proxy DEVE annullare tutte le transazioni client in attesa associate a un contesto di risposta quando riceve una richiesta CANCEL corrispondente.

Un proxy stateful PUÒ generare richieste CANCEL per le transazioni client INVITE in attesa in base alla scadenza del campo Expires dell'INVITE. Ciò è tuttavia generalmente inutile poiché gli endpoint interessati si occuperanno di segnalare la fine della transazione.

Sebbene una richiesta CANCEL sia elaborata in un proxy stateful dalla sua propria transazione server, non viene creato alcun nuovo contesto di risposta per essa. Invece, il livello proxy cerca nei suoi contesti di risposta esistenti la transazione server che gestisce la richiesta associata a tale CANCEL. Se viene trovato un contesto di risposta corrispondente, l'elemento DEVE restituire immediatamente una risposta 200 (OK) alla richiesta CANCEL. In questo caso, l'elemento agisce come un server di agente utente definito nella sezione 8.2. Inoltre, l'elemento DEVE generare richieste CANCEL per tutte le transazioni client in attesa nel contesto come descritto al passo 10 della sezione 16.7.

Se non viene trovato alcun contesto di risposta, l'elemento non possiede alcuna conoscenza della richiesta a cui applicare il CANCEL. DEVE inoltrare la richiesta CANCEL in modo stateless (potrebbe aver già inoltrato la richiesta associata in modo stateless in precedenza).

16.11 Proxy stateless (Stateless Proxy)​

Quando opera in modo stateless, un proxy è un semplice inoltratore di messaggi. Gran parte dell'elaborazione eseguita in modo stateless è identica a quella eseguita in modo stateful. Le differenze sono dettagliate qui.

Un proxy stateless non ha nozione di transazione né del concetto di contesto di risposta utilizzato per descrivere il comportamento del proxy stateful. Invece, il proxy stateless prende i messaggi, sia richieste che risposte, direttamente dal livello di trasporto (vedere sezione 18). Pertanto, i proxy stateless non ritrasmettono messaggi di propria iniziativa. Inoltrano tuttavia tutte le ritrasmissioni ricevute (non possono distinguere una ritrasmissione dal messaggio originale). Inoltre, nell'elaborazione stateless di una richiesta, un elemento NON DEVE generare la propria risposta 100 (Trying) o qualsiasi altra risposta provvisoria.

Un proxy stateless DEVE convalidare una richiesta come descritto nella sezione 16.3.

Un proxy stateless DEVE seguire i passi di elaborazione della richiesta delle sezioni 16.4 a 16.5 con la seguente eccezione:

  o Un proxy stateless DEVE scegliere uno e un solo target dall'insieme dei target. Tale scelta NON DEVE dipendere che dai campi del messaggio e da proprietà invarianti nel tempo del server. In particolare, una richiesta ritrasmessa DEVE essere inoltrata alla stessa destinazione a ogni elaborazione. Inoltre, le richieste CANCEL e ACK non instradate DEVONO generare la stessa scelta della loro INVITE associata.

Un proxy stateless DEVE seguire i passi di elaborazione della richiesta della sezione 16.6 con le seguenti eccezioni:

  o Il requisito di identificatori branch univoci nello spazio e nel tempo si applica anche ai proxy stateless. Tuttavia, un proxy stateless non può semplicemente utilizzare un generatore di numeri casuali per calcolare la prima componente dell'identificatore branch, come descritto al passo 8 della sezione 16.6. Ciò è dovuto al fatto che le ritrasmissioni di una richiesta devono avere lo stesso valore e un proxy stateless non può distinguere una ritrasmissione dalla richiesta originale. Pertanto, la componente del parametro branch che lo rende univoco DEVE essere la stessa a ogni inoltro di una richiesta ritrasmessa. Pertanto, per un proxy stateless, il parametro branch DEVE essere calcolato come una funzione combinante parametri di messaggio invarianti per ritrasmissione.

     Il proxy stateless PUÒ utilizzare qualsiasi tecnica desideri per garantire l'unicità dei propri identificatori branch tra le transazioni. Tuttavia, si raccomanda la procedura seguente. Il proxy esamina l'identificatore branch nel campo Via più in alto della richiesta ricevuta. Se inizia con il magic cookie, la prima componente dell'identificatore branch della richiesta in uscita è calcolata come hash dell'identificatore branch ricevuto. Altrimenti, la prima componente è calcolata come hash del Via più in alto, del tag nel campo To, del tag nel campo From, del campo Call-ID, del numero CSeq (ma non del metodo) e del Request-URI della richiesta ricevuta. Uno di questi campi varierà sempre tra due transazioni diverse.

  o Tutte le altre trasformazioni di messaggio specificate nella sezione 16.6 DEVONO produrre la stessa trasformazione di una richiesta ritrasmessa. In particolare, se il proxy inserisce un valore Record-Route o inserisce URI nel campo Route, DEVE inserire gli stessi valori nelle ritrasmissioni della richiesta. Come per il parametro Via branch, ciò implica che le trasformazioni DEVONO essere basate su configurazione invariante nel tempo o proprietà invarianti per ritrasmissione della richiesta.

  o Un proxy stateless determina dove inoltrare la richiesta come descritto per i proxy stateful all'articolo 10 della sezione 16.6. La richiesta è inviata direttamente al livello di trasporto invece che tramite una transazione client.

     Poiché un proxy stateless deve inoltrare le richieste ritrasmesse alla stessa destinazione e aggiungere parametri branch identici a ciascuna, può utilizzare solo informazioni dal messaggio stesso e dati di configurazione invarianti nel tempo per tali calcoli. Se lo stato di configurazione non è invariante nel tempo (ad esempio se una tabella di instradamento viene aggiornata), le richieste che potrebbero essere interessate dalla modifica potrebbero non essere inoltrate in modo stateless per un intervallo uguale alla finestra di timeout della transazione prima o dopo la modifica. Il metodo di elaborazione delle richieste interessate durante tale intervallo è una decisione di implementazione. Una soluzione comune è inoltrarle con stato di transazione.

I proxy stateless NON DEVONO eseguire alcuna elaborazione speciale per le richieste CANCEL. Esse sono gestite dalle regole sopra come qualsiasi altra richiesta. In particolare, un proxy stateless applica la stessa elaborazione del campo Route alle richieste CANCEL che a qualsiasi altra richiesta.

L'elaborazione delle risposte descritta nella sezione 16.7 non si applica a un proxy che opera in modo stateless. Quando una risposta arriva a un proxy stateless, il proxy DEVE ispezionare il valore sent-by nel primo (più in alto) valore del campo Via. Se tale indirizzo corrisponde al proxy (è uguale a un valore che questo proxy ha inserito in richieste precedenti), il proxy DEVE rimuovere tale valore dal campo Via della risposta e inoltrare il risultato alla posizione indicata nel valore Via successivo. Il proxy NON DEVE aggiungere, modificare o rimuovere il corpo del messaggio. Se non diversamente specificato, il proxy NON DEVE rimuovere altri valori di campo di intestazione. Se l'indirizzo non corrisponde al proxy, il messaggio DEVE essere scartato silenziosamente.

16.12 Riepilogo dell'elaborazione delle route del proxy (Summary of Proxy Route Processing)​

In assenza di policy locale contraria, l'elaborazione che un proxy esegue su una richiesta contenente un campo di intestazione Route può essere riassunta nei passi seguenti.

  1. Il proxy ispezionerà il Request-URI. Se indica una risorsa di proprietà di questo proxy, il proxy lo sostituirà con i risultati dell'esecuzione di un servizio di localizzazione. Altrimenti, il proxy non modificherà il Request-URI.

2. Il proxy ispezionerà l'URI nel primo valore del campo Route. Se indica questo proxy, il proxy lo rimuove dal campo Route (questo nodo di route è stato raggiunto).

3. Il proxy inoltrerà la richiesta alla risorsa indicata dall'URI nel primo valore del campo Route o, se non vi è alcun campo Route, dal Request-URI. Il proxy determina l'indirizzo, la porta e il trasporto da utilizzare nell'inoltro della richiesta applicando le procedure di [4] a tale URI.

Se non viene incontrato alcun elemento strict-routing sul percorso della richiesta, il Request-URI indicherà sempre il target della richiesta.

16.12.1 Esempi (Examples)​

16.12.1.1 Trapezio SIP di base (Basic SIP Trapezoid)​

Questo scenario è il trapezio SIP di base, U1 -> P1 -> P2 -> U2, con entrambi i proxy che effettuano il record-routing. Il flusso è il seguente.

U1 invia:

  INVITE sip:[email protected] SIP/2.0
Contact: sip:[email protected]

a P1. P1 è un proxy in uscita. P1 non gestisce domain.com, quindi lo cerca nel DNS e lo invia lì. Aggiunge inoltre un valore Record-Route:

  INVITE sip:[email protected] SIP/2.0
Contact: sip:[email protected]
      Record-Route: `<sip:p1.example.com;lr>`

P2 riceve ciò. P2 gestisce domain.com, quindi esegue un servizio di localizzazione e riscrive il Request-URI. Aggiunge inoltre un valore Record-Route. Non vi è alcun campo Route, quindi risolve il nuovo Request-URI per determinare dove inviare la richiesta:

  INVITE sip:[email protected] SIP/2.0
Contact: sip:[email protected]
Record-Route: `<sip:p2.domain.com;lr>`
Record-Route: `<sip:p1.example.com;lr>`

Il chiamato su u2.domain.com riceve ciò e risponde con 200 OK:

  SIP/2.0 200 OK
Contact: sip:[email protected]
Record-Route: `<sip:p2.domain.com;lr>`
Record-Route: `<sip:p1.example.com;lr>`

Il chiamato su u2 imposta inoltre l'URI target remoto del suo stato di finestra di dialogo a sip:[email protected] e il suo insieme di instradamento a:

  (`<sip:p2.domain.com;lr>`,`<sip:p1.example.com;lr>`)

Ciò viene inoltrato normalmente da P2 a P1 a U1. Ora, U1 imposta l'URI target remoto del suo stato di finestra di dialogo a sip:[email protected] e il suo insieme di instradamento a:

  (`<sip:p1.example.com;lr>`,`<sip:p2.domain.com;lr>`)

Poiché tutti gli elementi dell'insieme di instradamento contengono il parametro lr, U1 costruisce la seguente richiesta BYE:

  BYE sip:[email protected] SIP/2.0
Route: `<sip:p1.example.com;lr>`,`<sip:p2.domain.com;lr>`

Come qualsiasi altro elemento (inclusi i proxy), risolve l'URI nel primo valore del campo Route tramite DNS per determinare dove inviare la richiesta. Ciò va a P1. P1 nota che non gestisce la risorsa indicata dal Request-URI, quindi non la modifica. Vede che è il primo valore nel campo Route, quindi lo rimuove e inoltra la richiesta a P2:

  BYE sip:[email protected] SIP/2.0
Route: `<sip:p2.domain.com;lr>`

P2 nota anch'esso di non gestire la risorsa indicata dal Request-URI (gestisce domain.com, non u2.domain.com), quindi non la modifica. Si vede nel primo valore del campo Route, quindi lo rimuove e inoltra quanto segue a u2.domain.com in base a una ricerca DNS del Request-URI:

  BYE sip:[email protected] SIP/2.0

16.12.1.2 Attraversamento di un proxy strict-routing (Traversing a Strict-Routing Proxy)​

In questo scenario, una finestra di dialogo è stabilita attraverso quattro proxy, ciascuno dei quali aggiunge valori Record-Route. Il terzo proxy implementa le procedure strict-routing specificate nella RFC 2543 e in molti documenti di lavoro.

  U1->P1->P2->P3->P4->U2

L'INVITE in arrivo a U2 contiene:

  INVITE sip:[email protected] SIP/2.0
Contact: sip:[email protected]
Record-Route: `<sip:p4.domain.com;lr>`
Record-Route: `<sip:p3.middle.com>`
Record-Route: `<sip:p2.example.com;lr>`
Record-Route: `<sip:p1.example.com;lr>`

A cui U2 risponde con un 200 OK. Successivamente, U2 invia la seguente richiesta BYE a P4 basata sul primo valore del campo Route.

  BYE sip:[email protected] SIP/2.0
Route: `<sip:p4.domain.com;lr>`
Route: `<sip:p3.middle.com>`
Route: `<sip:p2.example.com;lr>`
Route: `<sip:p1.example.com;lr>`

P4 non gestisce la risorsa indicata dal Request-URI, quindi la lascia invariata. Nota che è l'elemento nel primo valore del campo Route, quindi lo rimuove. Prepara quindi l'invio della richiesta basandosi sul valore Route ora primo sip:p3.middle.com, ma nota che tale URI non contiene il parametro lr, quindi riformatta la richiesta prima dell'invio:

  BYE sip:p3.middle.com SIP/2.0
Route: `<sip:p2.example.com;lr>`
Route: `<sip:p1.example.com;lr>`
Route: `<sip:[email protected]>`

P3 è uno strict router, quindi inoltra quanto segue a P2:

  BYE sip:p2.example.com;lr SIP/2.0
Route: `<sip:p1.example.com;lr>`
Route: `<sip:[email protected]>`

P2 vede che il request-URI è un valore che ha inserito in un campo Record-Route, quindi riscrive la richiesta prima di ulteriore elaborazione:

  BYE sip:[email protected] SIP/2.0
Route: `<sip:p1.example.com;lr>`

P2 non gestisce u1.example.com, quindi invia la richiesta a P1 in base alla risoluzione del valore del campo Route.

P1 nota la propria presenza nel valore Route più in alto, quindi lo rimuove, ottenendo:

  BYE sip:[email protected] SIP/2.0

Poiché P1 non gestisce u1.example.com e non vi è alcun campo Route, P1 inoltrerà la richiesta a u1.example.com in base al Request-URI.

16.12.1.3 Riscrivere i valori dei campi Record-Route (Rewriting Record-Route Header Field Values)​

In questo scenario, U1 e U2 si trovano in spazi dei nomi privati diversi e intraprendono una finestra di dialogo tramite un proxy P1 che funge da gateway tra gli spazi dei nomi.

  U1->P1->U2

U1 invia:

  INVITE sip:[email protected] SIP/2.0
Contact: `<sip:[email protected]>`

P1 utilizza il suo servizio di localizzazione e invia quanto segue a U2:

  INVITE sip:[email protected] SIP/2.0
Contact: `<sip:[email protected]>`
Record-Route: `<sip:gateway.rightprivatespace.com;lr>`

U2 restituisce questo 200 (OK) a P1:

  SIP/2.0 200 OK
Contact: `<sip:[email protected]>`
Record-Route: `<sip:gateway.rightprivatespace.com;lr>`

P1 riscrive il suo parametro Record-Route per fornire un valore utile a U1 e invia quanto segue a U1:

  SIP/2.0 200 OK
Contact: `<sip:[email protected]>`
Record-Route: `<sip:gateway.leftprivatespace.com;lr>`

Successivamente, U1 invia la seguente richiesta BYE a P1:

  BYE sip:[email protected] SIP/2.0
Route: `<sip:gateway.leftprivatespace.com;lr>`

che P1 inoltra a U2 nella forma:

  BYE sip:[email protected] SIP/2.0