17. Transazioni (Transactions)
SIP è un protocollo transazionale: le interazioni tra i componenti si svolgono in una serie di scambi di messaggi indipendenti. Più precisamente, una transazione SIP consiste in una singola richiesta e in tutte le risposte a tale richiesta, che includono zero o più risposte provvisorie e una o più risposte finali. Nel caso di una transazione la cui richiesta era un INVITE (conosciuta come transazione INVITE), la transazione include anche l'ACK solo se la risposta finale non era una risposta 2xx. Se la risposta era una 2xx, l'ACK non è considerato parte della transazione.
La ragione di questa separazione affonda le radici nell'importanza di consegnare tutti i 200 (OK) a un INVITE al UAC. Per consegnarli tutti al UAC, il UAS assume da solo la responsabilità di ritrasmetterli (vedere sezione 13.3.1.4), e il UAC assume da solo la responsabilità di confermarli con ACK (vedere sezione 13.2.2.4). Poiché questo ACK è ritrasmesso solo dal UAC, è effettivamente considerato come una transazione a sé stante.
Le transazioni hanno un lato client e un lato server. Il lato client è chiamato transazione client e il lato server transazione server. La transazione client invia la richiesta e la transazione server invia la risposta. Le transazioni client e server sono funzioni logiche incorporate in un numero qualsiasi di elementi. Più precisamente, esse esistono all'interno degli user agent e dei server proxy stateful. Si consideri l'esempio della sezione 4. In questo esempio, il UAC esegue la transazione client e il suo proxy in uscita esegue la transazione server. Il proxy in uscita esegue anche una transazione client, che invia una richiesta a una transazione server nel proxy in entrata. Questo proxy esegue anche una transazione client, che a sua volta invia la richiesta a una transazione server nel UAS. Ciò è illustrato nella figura 4.
+---------+ +---------+ +---------+ +---------+ | +-+|Request |+-+ +-+|Request |+-+ +-+|Request |+-+ | | |C||------->||S| |C||------->||S| |C||------->||S| | | |l|| ||e| |l|| ||e| |l|| ||e| | | |i|| ||r| |i|| ||r| |i|| ||r| | | |e|| ||v| |e|| ||v| |e|| ||v| | | |n|| ||e| |n|| ||e| |n|| ||e| | | |t|| ||r| |t|| ||r| |t|| ||r| | | | || || | | || || | | || || | | | |T|| ||T| |T|| ||T| |T|| ||T| | | |r|| ||r| |r|| ||r| |r|| ||r| | | |a|| ||a| |a|| ||a| |a|| ||a| | | |n|| ||n| |n|| ||n| |n|| ||n| | | |s||Response||s| |s||Response||s| |s||Response||s| | | +-+|<-------|+-+ +-+|<-------|+-+ +-+|<-------|+-+ | +---------+ +---------+ +---------+ +---------+ UAC Outbound Inbound UAS Proxy Proxy
Figura 4: Relazioni di transazione
Un proxy stateless non contiene transazioni client o server. La transazione esiste tra il UA o proxy stateful da un lato e il UA o proxy stateful dall'altro. Per quanto riguarda le transazioni SIP, i proxy stateless sono effettivamente trasparenti. Lo scopo della transazione client è ricevere una richiesta dall'elemento in cui il client è incorporato (chiamiamo questo elemento "Transaction User" o TU; può essere un UA o un proxy stateful) e consegnare in modo affidabile la richiesta a una transazione server.
La transazione client è inoltre responsabile di ricevere le risposte e consegnarle al TU, filtrando qualsiasi ritrasmissione di risposta o qualsiasi risposta non autorizzata (come una risposta a un ACK). Inoltre, nel caso di una richiesta INVITE, la transazione client è responsabile della generazione della richiesta ACK per ogni risposta finale che accetta una risposta 2xx.
Allo stesso modo, lo scopo della transazione server è ricevere le richieste dal livello di trasporto e consegnarle al TU. La transazione server filtra qualsiasi ritrasmissione di richiesta dalla rete. La transazione server accetta le risposte dal TU e le consegna al livello di trasporto per la trasmissione sulla rete. Nel caso di una transazione INVITE, essa assorbe la richiesta ACK per ogni risposta finale eccetto una risposta 2xx.
La risposta 2xx e il suo ACK ricevono un trattamento speciale. Questa risposta è ritrasmessa solo da un UAS, e il suo ACK è generato solo dal UAC. Questo trattamento end-to-end è necessario affinché un chiamante conosca l'insieme completo degli utenti che hanno accettato la chiamata. A causa di questo trattamento speciale, le ritrasmissioni della risposta 2xx sono gestite dal core del UA, non dal livello di transazione. Allo stesso modo, la generazione dell'ACK per la 2xx è gestita dal core del UA. Ciascun proxy sul percorso si limita a inoltrare ciascuna risposta 2xx all'INVITE e il relativo ACK.
17.1 Transazione client (Client Transaction)
La transazione client fornisce la sua funzionalità attraverso la manutenzione di una macchina a stati.
Il TU comunica con la transazione client tramite un'interfaccia semplice. Quando il TU desidera avviare una nuova transazione, crea una transazione client e le passa la richiesta SIP da inviare e un indirizzo IP, una porta e un trasporto a cui inviarla. La transazione client avvia l'esecuzione della sua macchina a stati. Le risposte valide sono passate dal TU alla transazione client.
Esistono due tipi di macchine a stati di transazione client, a seconda del metodo della richiesta passata dal TU. Una gestisce le transazioni client per le richieste INVITE. Questo tipo di macchina è chiamata transazione client INVITE. Un altro tipo gestisce le transazioni client per tutte le richieste eccetto INVITE e ACK. È chiamata transazione client non INVITE. Non esiste una transazione client per ACK. Se il TU desidera inviare un ACK, lo passa direttamente al livello di trasporto per la trasmissione.
La transazione INVITE differisce da quelle di altri metodi a causa della sua lunga durata. Normalmente, per rispondere a un INVITE è necessaria l'immissione umana. I lunghi ritardi attesi nell'invio di una risposta favoriscono un handshake a tre vie. D'altra parte, le richieste di altri metodi dovrebbero concludersi rapidamente. A causa della dipendenza della transazione non INVITE da un handshake a due vie, i TU DOVREBBERO rispondere prontamente alle richieste non INVITE.
17.1.1 Transazione client INVITE (INVITE Client Transaction)
17.1.1.1 Panoramica della transazione INVITE (Overview of INVITE Transaction)
La transazione INVITE consiste in un handshake a tre vie. La transazione client invia un INVITE, la transazione server invia le risposte e la transazione client invia un ACK. Per i trasporti non affidabili (come UDP), la transazione client ritrasmette le richieste a un intervallo che inizia a T1 secondi e raddoppia dopo ciascuna ritrasmissione. T1 è una stima del tempo di andata e ritorno (RTT) e ha un valore predefinito di 500 ms. Quasi tutti i timer di transazione qui descritti sono scalati in base a T1 e modificare T1 ne adegua i valori. La richiesta non è ritrasmessa sui trasporti affidabili. Dopo la ricezione di una risposta 1xx, qualsiasi ritrasmissione cessa completamente e il client attende ulteriori risposte. La transazione server può inviare ulteriori risposte 1xx, che tuttavia non sono trasmesse in modo affidabile dalla transazione server. Infine, la transazione server decide di inviare una risposta finale. Per i trasporti non affidabili, tale risposta è ritrasmessa periodicamente, e per i trasporti affidabili è inviata una volta. Per ciascuna risposta finale ricevuta alla transazione client, la transazione client invia un ACK, il cui scopo è estinguere le ritrasmissioni della risposta.
17.1.1.2 Descrizione formale (Formal Description)
La macchina a stati per la transazione client INVITE è illustrata nella figura 5. Lo stato iniziale, "calling", DEVE essere sempre inserito quando il TU avvia una nuova transazione client con una richiesta INVITE. La transazione client DEVE passare la richiesta al livello di trasporto per la trasmissione (vedere sezione 18). Se viene utilizzato un trasporto non affidabile, la transazione client DEVE avviare il timer A con il valore T1. Se viene utilizzato un trasporto affidabile, la transazione client NON DOVREBBE avviare il timer A (il timer A controlla le ritrasmissioni della richiesta). Per qualsiasi trasporto, la transazione client DEVE avviare il timer B con un valore di 64*T1 secondi (il timer B controlla il timeout della transazione).
Quando il timer A scade, la transazione client DEVE ritrasmettere la richiesta passandola al livello di trasporto e DEVE reimpostare il timer con un valore di 2*T1. La definizione formale di ritrasmissione nel contesto del livello di transazione è prendere il messaggio precedentemente inviato al livello di trasporto e passarlo nuovamente al livello di trasporto.
Quando il timer A scade 2*T1 secondi dopo, la richiesta DEVE essere nuovamente ritrasmessa (sempre che la transazione client sia ancora in questo stato). Questo processo DEVE continuare affinché la richiesta sia ritrasmessa con intervalli che raddoppiano dopo ciascuna trasmissione. Queste ritrasmissioni DOVREBBERO essere effettuate solo finché la transazione client si trova nello stato "calling".
Il valore predefinito di T1 è 500 ms. T1 è una stima del RTT tra la transazione client e server. Gli elementi POSSONO (sebbene non sia RECOMANDATO) utilizzare valori di T1 più piccoli in reti private chiuse che non consentono connessioni Internet generali. T1 può essere scelto più grande, e ciò è RECOMANDATO se l'RTT è noto in anticipo come maggiore (ad esempio su linee di accesso ad alta latenza). Qualunque sia il valore di T1, DEVONO essere utilizzati i backoff esponenziali sulle ritrasmissioni descritti in questa sezione.
Se la transazione client è ancora nello stato "Calling" quando il timer B scade, la transazione client DOVREBBE informare il TU che si è verificato un timeout. La transazione client NON DEVE generare un ACK. Il valore di 64*T1 è pari al tempo necessario per inviare sette richieste nel caso di un trasporto non affidabile.
Se la transazione client riceve una risposta provvisoria mentre si trova nello stato "Calling", transita allo stato "Proceeding". Nello stato "Proceeding", la transazione client NON DOVREBBE ritrasmettere la richiesta. Inoltre, la risposta provvisoria DEVE essere passata al TU. Qualsiasi ulteriore risposta provvisoria nello stato "Proceeding" DEVE essere passata al TU.
Quando ci si trova negli stati "Calling" o "Proceeding", la ricezione di una risposta con codice di stato 300-699 DEVE portare la transazione client a transitare in "Completed". La transazione client DEVE passare la risposta ricevuta al TU e DEVE generare una richiesta ACK (anche se il trasporto è affidabile; le linee guida per costruire l'ACK dalla risposta sono nella sezione 17.1.1.3) e passare l'ACK al livello di trasporto per la trasmissione. L'ACK DEVE essere inviato allo stesso indirizzo, porta e trasporto della richiesta originale. La transazione client DOVREBBE avviare il timer D all'ingresso nello stato "Completed", con un valore di almeno 32 secondi per i trasporti non affidabili e di zero secondi per i trasporti affidabili. Il timer D riflette la quantità di tempo in cui la transazione server può rimanere nello stato "Completed" quando si utilizzano trasporti non affidabili. Ciò è pari al timer H nella transazione server INVITE, il cui valore predefinito è 64*T1. Tuttavia, la transazione client non conosce il valore di T1 utilizzato dalla transazione server, quindi invece di basare il timer D su T1 si utilizza un minimo assoluto di 32 secondi.
Qualsiasi ritrasmissione della risposta finale ricevuta nello stato "Completed" DEVE comportare che l'ACK sia nuovamente passato al livello di trasporto per la ritrasmissione, ma la risposta appena ricevuta NON DEVE essere passata al TU. Una ritrasmissione della risposta è definita come qualsiasi risposta che corrisponderebbe alla stessa transazione client secondo le regole della sezione 17.1.3.
|INVITE from TU
Timer A fires |INVITE sent
Reset A, V Timer B fires
INVITE sent +-----------+ or Transport Err.
+---------| |---------------+inform TU
| | Calling | |
+-------->| |-------------->|
+-----------+ 2xx |
| | 2xx to TU |
| |1xx |
300-699 +---------------+ |1xx to TU |
ACK sent | | | resp. to TU | 1xx V | | 1xx to TU -----------+ | | +---------| | | | | |Proceeding |-------------->| | +-------->| | 2xx | | +-----------+ 2xx to TU | | 300-699 | | | ACK sent, | | | resp. to TU| | | | | NOTE: | 300-699 V | | ACK sent +-----------+Transport Err. | transitions | +---------| |Inform TU | labeled with | | | Completed |-------------->| the event | +-------->| | | over the action | +-----------+ | to take | ^ | | | | | Timer D fires | +--------------+ | - | | | V | +-----------+ | | | | | Terminated|<--------------+ | | +-----------+
Figura 5: Transazione client INVITE
Se il timer D scade mentre la transazione client si trova nello stato "Completed", la transazione client DEVE transitare nello stato terminato.
Quando ci si trova negli stati "Calling" o "Proceeding", la ricezione di una risposta 2xx DEVE portare la transazione client a entrare nello stato "Terminated" e la risposta DEVE essere passata al TU. L'elaborazione di questa risposta dipende dal fatto che il TU sia un core di proxy o un core di UAC. Un core di UAC gestirà la generazione dell'ACK per questa risposta, mentre un core di proxy inoltrerà sempre il 200 (OK) a monte. Il diverso trattamento del 200 (OK) tra proxy e UAC è la ragione per cui questa elaborazione non avviene nel livello di transazione.
La transazione client DEVE essere distrutta nel momento in cui entra nello stato "Terminated". Ciò è in effetti necessario per garantire un corretto funzionamento. La ragione è che le risposte 2xx a un INVITE ricevono un trattamento diverso; ciascuna è inoltrata dai proxy e la gestione dell'ACK in un UAC è diversa. Pertanto, ciascun 2xx deve essere passato a un core di proxy (perché possa essere inoltrato) e a un core di UAC (perché possa essere confermato). Non ha luogo alcuna elaborazione del livello di transazione. Ogni volta che una risposta è ricevuta dal trasporto, se il livello di trasporto non trova alcuna transazione client corrispondente (utilizzando le regole della sezione 17.1.3), la risposta è passata direttamente al core. Poiché la transazione client corrispondente è distrutta dal primo 2xx, i successivi 2xx non troveranno corrispondenza e saranno quindi passati al core.
17.1.1.3 Costruzione della richiesta ACK (Construction of the ACK Request)
Questa sezione specifica la costruzione delle richieste ACK inviate nella transazione client. Un core di UAC che genera un ACK per una 2xx DEVE invece seguire le regole descritte nella sezione 13.
La richiesta ACK costruita dalla transazione client DEVE contenere valori per Call-ID, From e Request-URI che siano uguali ai valori di tali campi di intestazione nella richiesta passata al trasporto dalla transazione client (chiamiamola la "richiesta originale"). Il campo di intestazione To nell'ACK DEVE essere uguale al campo di intestazione To nella risposta confermata, e differirà quindi generalmente dal campo di intestazione To nella richiesta originale per l'aggiunta del parametro tag. L'ACK DEVE contenere un singolo campo di intestazione Via, e questo DEVE essere uguale al campo di intestazione Via più in alto della richiesta originale. Il campo di intestazione CSeq nell'ACK DEVE contenere lo stesso valore di numero di sequenza presente nella richiesta originale, ma il parametro di metodo DEVE essere uguale a "ACK".
Se la richiesta INVITE la cui risposta è confermata aveva campi di intestazione Route, tali campi di intestazione DEVONO apparire nell'ACK. Ciò è per garantire che l'ACK possa essere instradato correttamente attraverso qualsiasi proxy stateless a valle.
Sebbene qualsiasi richiesta possa contenere un corpo, un corpo in un ACK è speciale poiché la richiesta non può essere rifiutata se il corpo non è compreso. Pertanto, l'inserimento di un corpo in un ACK per non 2xx non è RECOMANDATO, ma se viene fatto, i tipi di corpo sono limitati a qualsiasi cosa sia apparsa nell'INVITE, supponendo che la risposta all'INVITE non fosse 415. Se lo era, il corpo nell'ACK PUÒ essere di qualsiasi tipo elencato nel campo di intestazione Accept del 415.
Si consideri ad esempio la seguente richiesta:
INVITE sip:[email protected] SIP/2.0
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKkjshdyff
To: Bob <sip:[email protected]>
From: Alice <sip:[email protected]>;tag=88sja8x
Max-Forwards: 70
Call-ID: 987asjd97y7atg
CSeq: 986759 INVITE
La richiesta ACK per una risposta finale non 2xx a questa richiesta sarebbe la seguente:
ACK sip:[email protected] SIP/2.0
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKkjshdyff
To: Bob <sip:[email protected]>;tag=99sa0xk
From: Alice <sip:[email protected]>;tag=88sja8x
Max-Forwards: 70
Call-ID: 987asjd97y7atg
CSeq: 986759 ACK
17.1.2 Transazione client non INVITE (Non-INVITE Client Transaction)
17.1.2.1 Panoramica della transazione non INVITE (Overview of the non-INVITE Transaction)
Le transazioni non INVITE non utilizzano ACK. Esse sono semplici interazioni richiesta-risposta. Per i trasporti non affidabili, le richieste sono ritrasmesse a un intervallo che inizia a T1 e raddoppia fino a raggiungere T2. Se viene ricevuta una risposta provvisoria, le ritrasmissioni continuano per i trasporti non affidabili, ma a un intervallo di T2. La transazione server ritrasmette l'ultima risposta inviata, che può essere provvisoria o finale, solo quando viene ricevuta una ritrasmissione della richiesta. Questa è la ragione per cui le ritrasmissioni della richiesta devono continuare anche dopo una risposta provvisoria; esse garantiscono la consegna affidabile della risposta finale.
A differenza di una transazione INVITE, una transazione non INVITE non ha alcun trattamento speciale per la risposta 2xx. Ne risulta che una sola risposta 2xx a una richiesta non INVITE viene mai consegnata a un UAC.
17.1.2.2 Descrizione formale (Formal Description)
La macchina a stati per la transazione client non INVITE è illustrata nella figura 6. È molto simile a quella per INVITE.
Lo stato "Trying" è inserito quando il TU avvia una nuova transazione client con una richiesta. All'ingresso in questo stato, la transazione client DOVREBBE impostare il timer F per scadere in 64T1 secondi. La richiesta DEVE essere passata al livello di trasporto per la trasmissione. Se viene utilizzato un trasporto non affidabile, la transazione client DEVE impostare il timer E per scadere in T1 secondi. Se il timer E scade mentre ci si trova ancora in questo stato, il timer è reimpostato, ma questa volta con un valore di MIN(2T1, T2). Quando scade nuovamente, è reimpostato a MIN(4*T1, T2). Questo processo continua affinché le ritrasmissioni avvengano con un intervallo in aumento esponenziale che si arresta a T2. Il valore predefinito di T2 è 4 s e rappresenta il tempo che una transazione server non INVITE impiegherà per rispondere a una richiesta, se non risponde immediatamente. Per i valori predefiniti di T1 e T2, ciò dà intervalli di 500 ms, 1 s, 2 s, 4 s, 4 s, 4 s, ecc.
Se il timer F scade mentre la transazione client è ancora nello stato "Trying", la transazione client DOVREBBE informare il TU del timeout, e DOVREBBE entrare nello stato "Terminated". Se nello stato "Trying" viene ricevuta una risposta provvisoria, la risposta DEVE essere passata al TU, poi la transazione client DOVREBBE transitare nello stato "Proceeding". Se nello stato "Trying" viene ricevuta una risposta finale (codici di stato 200-699), la risposta DEVE essere passata al TU e la transazione client DEVE transitare nello stato "Completed".
Se il timer E scade nello stato "Proceeding", la richiesta DEVE essere passata al livello di trasporto per la ritrasmissione e il timer E DEVE essere reimpostato con un valore di T2 secondi. Se il timer F scade nello stato "Proceeding", il TU DEVE essere informato di un timeout e la transazione client DEVE transitare nello stato terminato. Se nello stato "Proceeding" viene ricevuta una risposta finale (codici di stato 200-699), la risposta DEVE essere passata al TU e la transazione client DEVE transitare nello stato "Completed".
Una volta che la transazione client è entrata nello stato "Completed", DEVE impostare il timer K per scadere in T4 secondi per i trasporti non affidabili e in zero secondi per i trasporti affidabili. Lo stato "Completed" esiste per bufferizzare eventuali ritrasmissioni di risposta aggiuntive che potrebbero essere ricevute (ed è per questo che la transazione client vi rimane solo per i trasporti non affidabili). T4 rappresenta il tempo che la rete impiega per cancellare i messaggi tra le transazioni client e server. Il valore predefinito di T4 è 5 s. Una risposta è una ritrasmissione quando corrisponde alla stessa transazione secondo le regole specificate nella sezione 17.1.3. Se il timer K scade in questo stato, la transazione client DEVE transitare nello stato "Terminated".
Una volta che la transazione è nello stato terminato, DEVE essere distrutta immediatamente.
17.1.3 Corrispondenza delle risposte alle transazioni client (Matching Responses to Client Transactions)
Quando il livello di trasporto client riceve una risposta, deve determinare quale transazione client elaborerà tale risposta. Ciò determina l'elaborazione delle sezioni 17.1.1 e 17.1.2. A tale scopo, viene utilizzato il parametro branch del campo Via più in alto. Una risposta corrisponde a una transazione client se:
1. Il valore del parametro branch nel campo Via più in alto della risposta è uguale al valore del parametro branch nel campo Via più in alto della richiesta che ha creato la transazione.
2. Il parametro di metodo del campo CSeq corrisponde al metodo della richiesta che ha creato la transazione. Il metodo è necessario poiché una richiesta CANCEL costituisce una transazione diversa ma condivide lo stesso valore di parametro branch.
Se una richiesta è inviata tramite multicast, possono essere generate più risposte da diversi server. Tutte queste risposte avranno lo stesso parametro branch nel Via più in alto, ma tag To diversi. La prima risposta ricevuta è utilizzata secondo le regole sopra, e le altre sono trattate come ritrasmissioni. Ciò non è un errore. Il multicast SIP fornisce solo un servizio rudimentale di "scoperta a singolo hop", limitato all'elaborazione di una singola risposta. Vedere la sezione 18.1.1 per i dettagli.
17.1.4 Gestione degli errori di trasporto (Handling Transport Errors)
|Request from TU
|send request
Timer E V
send request +-----------+
+---------| |-------------------+
| | Trying | Timer F |
+-------->| | or Transport Err.|
+-----------+ inform TU |
200-699 | | |
resp. to TU | |1xx |
+---------------+ |resp. to TU |
| | |
| Timer E V Timer F |
| send req +-----------+ or Transport Err. |
| +---------| | inform TU |
| | |Proceeding |------------------>|
| +-------->| |-----+ |
| +-----------+ |1xx |
| | ^ |resp to TU |
| 200-699 | +--------+ |
| resp. to TU | |
| | |
| V |
| +-----------+ |
| | | |
| | Completed | |
| | | |
| +-----------+ |
| ^ | |
| | | Timer K |
+--------------+ | - |
| |
V |
NOTE: +-----------+ |
| | |
transitions | Terminated|\<------------------+
labeled with | |
the event +-----------+
over the action
to take
Figura 6: Transazione client non INVITE
Quando la transazione client trasmette una richiesta al livello di trasporto per la trasmissione, se il livello di trasporto indica un fallimento, procedere come segue.
La transazione client DOVREBBE informare il TU che si è verificato un errore di trasporto e la transazione client DOVREBBE transitare direttamente nello stato "Terminated". Il TU gestirà i meccanismi di failover descritti in [4].
17.2 Transazione server (Server Transaction)
La transazione server è responsabile della consegna delle richieste al TU e della trasmissione affidabile delle risposte. Ciò è ottenuto tramite una macchina a stati. La transazione server è creata dal core quando una richiesta è ricevuta e quando l'elaborazione di transazione per tale richiesta è desiderata (il che non avviene sempre).
Come per la transazione client, la macchina a stati dipende dal fatto che la richiesta ricevuta sia una richiesta INVITE.
17.2.1 Transazione server INVITE (INVITE Server Transaction)
Il diagramma di stato della transazione server INVITE è mostrato nella figura 7.
Quando per una richiesta è costruita una transazione server, essa entra nello stato "Proceeding". La transazione server DEVE generare una risposta 100 (Trying). Tuttavia, PUÒ non generare la risposta 100 (Trying) se sa che il TU invierà una risposta provvisoria o finale entro 200 ms (lo sa perché ha inviato la risposta 100 a una richiesta precedente nella stessa transazione). Questa risposta provvisoria è necessaria per estinguere prontamente le ritrasmissioni della richiesta per evitare la congestione della rete. La risposta 100 (Trying) è costruita seguendo le procedure della sezione 8.2.6, con l'eccezione che l'inserimento del tag nel campo To della risposta (se non presente nella richiesta) è degradata da MAY a SHOULD NOT. La richiesta DEVE essere passata al TU.
Il TU può passare un numero qualsiasi di risposte provvisorie alla transazione server. Finché la transazione server si trova nello stato "Proceeding", ciascuna di esse DEVE essere passata al livello di trasporto per la trasmissione. Esse non sono trasmesse in modo affidabile (ritrasmesse) dal livello di transazione e non provocano alcun cambiamento di stato della transazione server. Se nello stato "Proceeding" è ricevuta una ritrasmissione della richiesta, la risposta provvisoria più recente ricevuta dal TU DEVE essere passata al livello di trasporto per la ritrasmissione. Una richiesta è una ritrasmissione se corrisponde alla stessa transazione server secondo le regole della sezione 17.2.3.
Nello stato "Proceeding", se il TU passa una risposta 2xx alla transazione server, la transazione server DEVE passare questa risposta al livello di trasporto per la trasmissione. Essa non è ritrasmessa dalla transazione server e la ritrasmissione delle risposte 2xx è gestita dal TU. La transazione server DEVE quindi transitare nello stato "Terminated".
Nello stato "Proceeding", se il TU passa una risposta con codice di stato da 300 a 699 alla transazione server, tale risposta DEVE essere passata al livello di trasporto per la trasmissione e la macchina a stati DEVE entrare nello stato "Completed". Per i trasporti non affidabili, il timer G è impostato per scadere in T1 secondi, e per i trasporti affidabili non è impostato.
Ciò è un cambiamento rispetto alla RFC 2543, che ritrasmetteva sempre le risposte anche su un trasporto affidabile.
All'ingresso nello stato "Completed", il timer H DEVE essere impostato per scadere in 64T1 secondi per tutti i trasporti. Il timer H determina quando la transazione server abbandona le ritrasmissioni della risposta. Il suo valore è scelto per essere pari al timer B (il tempo in cui la transazione client continua a provare a inviare la richiesta). Se il timer G scade, la risposta è nuovamente passata al livello di trasporto per la ritrasmissione e il timer G è impostato per scadere in MIN(2T1, T2) secondi. Successivamente, ogni volta che il timer G scade, la risposta è nuovamente passata al trasporto per la trasmissione e il timer G è reimpostato a un valore raddoppiato, ma limitato a T2 se tale valore supera T2. Ciò è identico al comportamento di ritrasmissione della richiesta nello stato "Trying" della transazione client non INVITE. Inoltre, se nello stato "Completed" è ricevuta una ritrasmissione della richiesta, il server DOVREBBE passare la risposta al trasporto per la ritrasmissione.
Se la transazione server riceve un ACK mentre si trova nello stato "Completed", la transazione server DEVE transitare nello stato "Confirmed". In questo stato, il timer G è ignorato, quindi qualsiasi ritrasmissione della risposta cessa.
Se il timer H scade nello stato "Completed", ciò significa che non è stato ricevuto alcun ACK. In questo caso, la transazione server DEVE transitare nello stato "Terminated" e DEVE indicare al TU che si è verificato un errore di transazione.
|INVITE
|pass INV to TU
INVITE V send 100 if TU won't in 200ms
send response+-----------+
+--------| |--------+101-199 from TU
| | Proceeding| |send response
+------->| |\<-------+
| | Transport Err.
| | Inform TU
| |--------------->+
+-----------+ |
300-699 from TU | |2xx from TU |
send response | |send response |
| +------------------>+
| |
INVITE V Timer G fires |
send response+-----------+ send response |
+--------| |--------+ |
| | Completed | | |
+------->| |\<-------+ |
+-----------+ |
| | |
ACK | | |
- | +------------------>+
| Timer H fires |
V or Transport Err.|
+-----------+ Inform TU |
| | |
| Confirmed | |
| | |
+-----------+ |
| |
|Timer I fires |
|- |
| |
V |
+-----------+ |
| | |
| Terminated|\<---------------+
| |
+-----------+
Figura 7: Transazione server INVITE
Lo scopo dello stato "Confirmed" è assorbire i messaggi ACK aggiuntivi provocati dalle ritrasmissioni della risposta finale. All'ingresso in questo stato, il timer I è impostato per scadere in T4 secondi per i trasporti non affidabili e in zero secondi per i trasporti affidabili. Quando il timer I scade, il server DEVE transitare nello stato "Terminated".
Una volta che la transazione è nello stato "Terminated", DEVE essere distrutta immediatamente. Come per la transazione client, ciò è necessario per garantire l'affidabilità delle risposte 2xx a un INVITE.
17.2.2 Transazione server non INVITE (Non-INVITE Server Transaction)
La macchina a stati per la transazione server non INVITE è illustrata nella figura 8.
La macchina a stati è inizializzata nello stato "Trying" e alla sua inizializzazione riceve una richiesta diversa da INVITE o ACK. Tale richiesta è passata al TU. Una volta nello stato "Trying", qualsiasi ulteriore ritrasmissione della richiesta è scartata. Una richiesta è una ritrasmissione se corrisponde alla stessa transazione server secondo le regole specificate nella sezione 17.2.3.
Nello stato "Trying", se il TU passa una risposta provvisoria alla transazione server, la transazione server DEVE entrare nello stato "Proceeding". La risposta DEVE essere passata al livello di trasporto per la trasmissione. Nello stato "Proceeding", qualsiasi ulteriore risposta provvisoria ricevuta dal TU DEVE essere passata al livello di trasporto per la trasmissione. Nello stato "Proceeding", se è ricevuta una ritrasmissione della richiesta, l'ultima risposta provvisoria inviata DEVE essere passata al livello di trasporto per la ritrasmissione. Se il TU passa una risposta finale (codice di stato 200-699) al server nello stato "Proceeding", la transazione DEVE entrare nello stato "Completed" e la risposta DEVE essere passata al livello di trasporto per la trasmissione.
Una volta che la transazione server è entrata nello stato "Completed", DEVE impostare il timer J per scadere in 64*T1 secondi per i trasporti non affidabili e in zero secondi per i trasporti affidabili. Nello stato "Completed", la transazione server DEVE passare la risposta finale al livello di trasporto per la ritrasmissione ogni volta che è ricevuta una ritrasmissione della richiesta. Qualsiasi altra risposta finale passata alla transazione server nello stato "Completed" dal TU DEVE essere scartata. La transazione server rimane in questo stato finché il timer J non scade, momento in cui DEVE transitare nello stato "Terminated".
La transazione server DEVE essere distrutta nel momento in cui entra nello stato "Terminated".
17.2.3 Corrispondenza delle richieste alle transazioni server (Matching Requests to Server Transactions)
Quando un server riceve una richiesta dalla rete, deve farla corrispondere a una transazione esistente. Ciò è ottenuto come segue.
Il parametro branch del campo Via più in alto della richiesta è esaminato. Se è presente e inizia con il magic cookie "z9hG4bK", la richiesta è stata generata da una transazione client conforme a questa specifica. Pertanto, il parametro branch è univoco tra tutte le transazioni inviate da quel client. Una richiesta corrisponde a una transazione se:
1. Il parametro branch nella richiesta è uguale a quello nel campo Via più in alto della richiesta che ha creato la transazione, e
2. Il valore sent-by nel Via più in alto della richiesta è uguale a quello nella richiesta che ha creato la transazione, e
3. Il metodo della richiesta corrisponde al metodo che ha creato la transazione. Per ACK, tuttavia, il metodo che ha creato la transazione è INVITE.
Questa regola di corrispondenza si applica in modo uguale alle transazioni INVITE e non INVITE.
Il valore sent-by è utilizzato come parte del processo di corrispondenza poiché sono possibili duplicati accidentali o intenzionali del parametro branch da parte di client diversi.
Se il parametro branch del campo Via più in alto è assente o non contiene il magic cookie, sono utilizzate le seguenti procedure. Esse esistono per gestire la compatibilità con le implementazioni conformi alla RFC 2543.
Una richiesta INVITE corrisponde a una transazione se Request-URI, tag To, tag From, Call-ID, CSeq e campo Via più in alto corrispondono a quelli della richiesta INVITE che ha creato la transazione. In questo caso, l'INVITE è una ritrasmissione dell'originale che ha creato la transazione. Una richiesta ACK corrisponde a una transazione se Request-URI, tag From, Call-ID, numero CSeq (non il metodo) e campo Via più in alto corrispondono a quelli della richiesta INVITE che ha creato la transazione e se il tag To nell'ACK corrisponde al tag To della risposta inviata dalla transazione server. La corrispondenza si basa sulle regole di corrispondenza definite per ciascuno di tali campi di intestazione. L'inclusione del tag del campo To nel processo di corrispondenza ACK aiuta a rimuovere l'ambiguità nel proxy tra un ACK per una 2xx e un ACK per un'altra risposta. Il proxy potrebbe aver inoltrato entrambe le risposte (ciò può accadere in condizioni anomale, in particolare se il proxy forkizza la richiesta e poi va in crash, le risposte potrebbero essere consegnate a un altro proxy, che inoltrerebbe più risposte a monte). Una richiesta ACK che corrisponde a una transazione INVITE precedentemente abbinata da un ACK è trattata come una ritrasmissione di quel precedente ACK.
|Request received
|pass to TU
V
+-----------+
| |
| Trying |-------------+
| | |
+-----------+ |200-699 from TU
| |send response
|1xx from TU |
|send response |
| |
Request V 1xx from TU |
send response+-----------+send response|
+--------| |--------+ |
| | Proceeding| | |
+------->| |\<-------+ |
+\<--------------| | |
|Trnsprt Err +-----------+ |
|Inform TU | |
| | |
| |200-699 from TU |
| |send response |
| Request V |
| send response+-----------+ |
| +--------| | |
| | | Completed |\<------------+
| +------->| |
+\<--------------| |
|Trnsprt Err +-----------+
|Inform TU |
| |Timer J fires
| |-
| |
| V
| +-----------+
| | |
+-------------->| Terminated|
| |
+-----------+
Figura 8: Transazione server non INVITE
Per tutti gli altri metodi di richiesta, una richiesta corrisponde a una transazione se Request-URI, tag To, tag From, Call-ID, CSeq (incluso il metodo) e campo Via più in alto corrispondono a quelli della richiesta che ha creato la transazione. La corrispondenza si basa sulle regole di corrispondenza definite per ciascuno di tali campi di intestazione. Se una richiesta non INVITE corrisponde a una transazione esistente, essa è una ritrasmissione della richiesta che ha creato la transazione.
Poiché le regole di corrispondenza includono il Request-URI, un server non può far corrispondere una risposta a una transazione. Quando il TU passa una risposta a una transazione server, deve passarla alla specifica transazione server a cui la risposta è destinata.
17.2.4 Gestione degli errori di trasporto (Handling Transport Errors)
Quando la transazione server trasmette una risposta al livello di trasporto per la trasmissione, se il livello di trasporto indica un fallimento, procedere come segue.
In primo luogo, seguire le procedure di [4] per tentare di consegnare la risposta tramite un backup. Se tutte falliscono, sulla base della definizione di fallimento in [4], la transazione server DOVREBBE informare il TU che si è verificato un fallimento e DOVREBBE transitare nello stato terminato.