Aller au contenu principal

17. Transactions (Transactions)

SIP est un protocole transactionnel : les interactions entre composants se déroulent en une série d'échanges de messages indépendants. Plus précisément, une transaction SIP consiste en une seule requête et toutes les réponses à cette requête, qui incluent zéro ou plusieurs réponses provisoires et une ou plusieurs réponses finales. Dans le cas d'une transaction dont la requête était un INVITE (connue sous le nom de transaction INVITE), la transaction inclut également le ACK uniquement si la réponse finale n'était pas une réponse 2xx. Si la réponse était une 2xx, le ACK n'est pas considéré comme faisant partie de la transaction.

  La raison de cette séparation est ancrée dans l'importance de livrer toutes les réponses 200 (OK) à un INVITE au UAC. Pour les livrer toutes au UAC, le UAS prend seul la responsabilité de les retransmettre (voir section 13.3.1.4), et le UAC prend seul la responsabilité de les acquitter avec ACK (voir section 13.2.2.4). Comme ce ACK est retransmis uniquement par le UAC, il est effectivement considéré comme sa propre transaction.

Les transactions ont un côté client et un côté serveur. Le côté client est appelé transaction client et le côté serveur transaction serveur. La transaction client envoie la requête, et la transaction serveur envoie la réponse. Les transactions client et serveur sont des fonctions logiques intégrées dans un nombre quelconque d'éléments. Plus précisément, elles existent au sein des agents utilisateur et des serveurs proxy avec état. Considérez l'exemple de la section 4. Dans cet exemple, le UAC exécute la transaction client, et son proxy de sortie exécute la transaction serveur. Le proxy de sortie exécute également une transaction client, qui envoie la requête à une transaction serveur dans le proxy d'entrée. Ce proxy exécute également une transaction client, qui à son tour envoie la requête à une transaction serveur dans le UAS. Cela est illustré à la figure 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

              Figure 4 : Transaction relationships

Un proxy sans état ne contient pas de transaction client ou serveur. La transaction existe entre le UA ou le proxy avec état d'un côté, et le UA ou le proxy avec état de l'autre côté. En ce qui concerne les transactions SIP, les proxies sans état sont effectivement transparents. Le but de la transaction client est de recevoir une requête de l'élément dans lequel le client est intégré (appelons cet élément l'« Transaction User » ou TU ; il peut être un UA ou un proxy avec état), et de livrer de manière fiable la requête à une transaction serveur.

La transaction client est également responsable de la réception des réponses et de leur livraison au TU, en filtrant toute retransmission de réponse ou toute réponse non autorisée (telle qu'une réponse à un ACK). De plus, dans le cas d'une requête INVITE, la transaction client est responsable de la génération de la requête ACK pour toute réponse finale acceptant une réponse 2xx.

De même, le but de la transaction serveur est de recevoir les requêtes de la couche transport et de les livrer au TU. La transaction serveur filtre toute retransmission de requête depuis le réseau. La transaction serveur accepte les réponses du TU et les livre à la couche transport pour transmission sur le réseau. Dans le cas d'une transaction INVITE, elle absorbe la requête ACK pour toute réponse finale excepté une réponse 2xx.

La réponse 2xx et son ACK reçoivent un traitement spécial. Cette réponse n'est retransmise que par un UAS, et son ACK n'est généré que par le UAC. Ce traitement de bout en bout est nécessaire pour qu'un appelant connaisse l'ensemble complet des utilisateurs ayant accepté l'appel. En raison de ce traitement spécial, les retransmissions de la réponse 2xx sont gérées par le cœur du UA, et non par la couche transaction. De même, la génération du ACK pour la 2xx est gérée par le cœur du UA. Chaque proxy sur le chemin se contente de transférer chaque réponse 2xx à l'INVITE et son ACK correspondant.

17.1 Transaction client (Client Transaction)​

La transaction client fournit sa fonctionnalité par la maintenance d'une machine à états.

Le TU communique avec la transaction client via une interface simple. Lorsque le TU souhaite initier une nouvelle transaction, il crée une transaction client et lui passe la requête SIP à envoyer et une adresse IP, un port et un transport vers lesquels l'envoyer. La transaction client commence l'exécution de sa machine à états. Les réponses valides sont remontées au TU depuis la transaction client.

Il existe deux types de machines à états de transaction client, selon la méthode de la requête passée par le TU. L'un gère les transactions client pour les requêtes INVITE. Ce type de machine est appelé transaction client INVITE. Un autre type gère les transactions client pour toutes les requêtes sauf INVITE et ACK. Il est appelé transaction client non INVITE. Il n'y a pas de transaction client pour ACK. Si le TU souhaite envoyer un ACK, il le passe directement à la couche transport pour transmission.

La transaction INVITE diffère de celles des autres méthodes en raison de sa longue durée. Normalement, une saisie humaine est nécessaire pour répondre à un INVITE. Les longs délais attendus pour envoyer une réponse plaident en faveur d'un acquittement à trois voies. D'un autre côté, les requêtes d'autres méthodes sont censées se terminer rapidement. En raison de la dépendance de la transaction non INVITE à un acquittement à deux voies, les TU DEVRAIENT répondre immédiatement aux requêtes non INVITE.

17.1.1 Transaction client INVITE (INVITE Client Transaction)​

17.1.1.1 Aperçu de la transaction INVITE (Overview of INVITE Transaction)​

La transaction INVITE consiste en un acquittement à trois voies. La transaction client envoie un INVITE, la transaction serveur envoie des réponses, et la transaction client envoie un ACK. Pour les transports non fiables (comme UDP), la transaction client retransmet les requêtes à un intervalle commençant à T1 secondes et doublant après chaque retransmission. T1 est une estimation du temps aller-retour (RTT), et vaut par défaut 500 ms. Presque tous les minuteries de transaction décrits ici sont mis à l'échelle avec T1, et changer T1 ajuste leurs valeurs. La requête n'est pas retransmise sur les transports fiables. Après réception d'une réponse 1xx, toute retransmission cesse complètement, et le client attend d'autres réponses. La transaction serveur peut envoyer des réponses 1xx supplémentaires, qui ne sont pas transmises de manière fiable par la transaction serveur. Finalement, la transaction serveur décide d'envoyer une réponse finale. Pour les transports non fiables, cette réponse est retransmise périodiquement, et pour les transports fiables, elle est envoyée une fois. Pour chaque réponse finale reçue à la transaction client, la transaction client envoie un ACK, dont le but est d'éteindre les retransmissions de la réponse.

17.1.1.2 Description formelle (Formal Description)​

La machine à états pour la transaction client INVITE est illustrée à la figure 5. L'état initial, « calling », DOIT être entré lorsque le TU initie une nouvelle transaction client avec une requête INVITE. La transaction client DOIT passer la requête à la couche transport pour transmission (voir section 18). Si un transport non fiable est utilisé, la transaction client DOIT démarrer le minuteur A avec une valeur de T1. Si un transport fiable est utilisé, la transaction client NE DEVRAIT PAS démarrer le minuteur A (le minuteur A contrôle les retransmissions de requête). Pour tout transport, la transaction client DOIT démarrer le minuteur B avec une valeur de 64*T1 secondes (le minuteur B contrôle les expirations de transaction).

Lorsque le minuteur A se déclenche, la transaction client DOIT retransmettre la requête en la passant à la couche transport, et DOIT réinitialiser le minuteur avec une valeur de 2*T1. La définition formelle de la retransmission dans le contexte de la couche transaction est de prendre le message précédemment envoyé à la couche transport et de le passer à nouveau à la couche transport.

Lorsque le minuteur A se déclenche 2*T1 secondes plus tard, la requête DOIT être retransmise à nouveau (en supposant que la transaction client soit toujours dans cet état). Ce processus DOIT continuer afin que la requête soit retransmise avec des intervalles qui doublent après chaque transmission. Ces retransmissions NE DEVRAIENT être faites que tant que la transaction client est dans l'état « calling ».

La valeur par défaut de T1 est 500 ms. T1 est une estimation du RTT entre les transactions client et serveur. Les éléments PEUVENT (bien que ce ne soit PAS RECOMMANDÉ) utiliser des valeurs de T1 plus petites dans des réseaux privés fermés ne permettant pas de connexion Internet générale. T1 PEUT être choisi plus grand, et cela est RECOMMANDÉ si le RTT est connu à l'avance comme étant plus grand (par exemple sur des liaisons d'accès à haute latence). Quelle que soit la valeur de T1, les replis exponentiels sur les retransmissions décrits dans cette section DOIVENT être utilisés.

Si la transaction client est toujours dans l'état « Calling » lorsque le minuteur B se déclenche, la transaction client DEVRAIT informer le TU qu'un délai d'attente est survenu. La transaction client NE DOIT PAS générer de ACK. La valeur de 64*T1 est égale au temps nécessaire pour envoyer sept requêtes dans le cas d'un transport non fiable.

Si la transaction client reçoit une réponse provisoire alors qu'elle est dans l'état « Calling », elle passe à l'état « Proceeding ». Dans l'état « Proceeding », la transaction client NE DEVRAIT PAS retransmettre la requête plus longtemps. En outre, la réponse provisoire DOIT être passée au TU. Toute réponse provisoire supplémentaire DOIT être remontée au TU tant que l'on est dans l'état « Proceeding ».

Lorsqu'on est dans l'état « Calling » ou « Proceeding », la réception d'une réponse avec un code d'état de 300-699 DOIT amener la transaction client à passer à « Completed ». La transaction client DOIT passer la réponse reçue au TU, et la transaction client DOIT générer une requête ACK, même si le transport est fiable (les directives pour construire le ACK à partir de la réponse sont données à la section 17.1.1.3) puis passer le ACK à la couche transport pour transmission. Le ACK DOIT être envoyé à la même adresse, au même port et sur le même transport que la requête originale. La transaction client DEVRAIT démarrer le minuteur D en entrant dans l'état « Completed », avec une valeur d'au moins 32 secondes pour les transports non fiables, et une valeur de zéro seconde pour les transports fiables. Le minuteur D reflète le temps pendant lequel la transaction serveur peut rester dans l'état « Completed » lorsque des transports non fiables sont utilisés. Cela est égal au minuteur H dans la transaction serveur INVITE, dont la valeur par défaut est 64*T1. Cependant, la transaction client ne connaît pas la valeur de T1 utilisée par la transaction serveur, donc un minimum absolu de 32 s est utilisé à la place de baser le minuteur D sur T1.

Toute retransmission de la réponse finale reçue dans l'état « Completed » DOIT amener le ACK à être repassé à la couche transport pour retransmission, mais la réponse nouvellement reçue NE DOIT PAS être remontée au TU. Une retransmission de la réponse est définie comme toute réponse qui correspondrait à la même transaction client selon les règles de la section 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|<--------------+ | | +-----------+

             Figure 5 : Transaction client INVITE

Si le minuteur D se déclenche alors que la transaction client est dans l'état « Completed », la transaction client DOIT passer à l'état terminé.

Lorsqu'on est dans l'état « Calling » ou « Proceeding », la réception d'une réponse 2xx DOIT amener la transaction client à entrer dans l'état « Terminated », et la réponse DOIT être remontée au TU. Le traitement de cette réponse dépend de si le TU est un cœur de proxy ou un cœur de UAC. Un cœur de UAC gérera la génération du ACK pour cette réponse, tandis qu'un cœur de proxy transférera toujours le 200 (OK) en amont. Le traitement différent du 200 (OK) entre proxy et UAC est la raison pour laquelle ce traitement ne se produit pas dans la couche transaction.

La transaction client DOIT être détruite à l'instant où elle entre dans l'état « Terminated ». Cela est en fait nécessaire pour garantir un fonctionnement correct. La raison est que les réponses 2xx à un INVITE sont traitées différemment ; chacune est transférée par les proxies, et le traitement du ACK dans un UAC est différent. Ainsi, chaque 2xx doit être passé à un cœur de proxy (pour qu'il puisse être transféré) et à un cœur de UAC (pour qu'il puisse être acquitté). Aucun traitement de couche transaction n'a lieu. Chaque fois qu'une réponse est reçue par le transport, si la couche transport ne trouve aucune transaction client correspondante (en utilisant les règles de la section 17.1.3), la réponse est passée directement au cœur. Comme la transaction client correspondante est détruite par le premier 2xx, les 2xx suivants ne trouveront aucune correspondance et seront donc passés au cœur.

17.1.1.3 Construction de la requête ACK (Construction of the ACK Request)​

Cette section spécifie la construction des requêtes ACK envoyées dans la transaction client. Un cœur de UAC qui génère un ACK pour une 2xx DOIT plutôt suivre les règles décrites à la section 13.

La requête ACK construite par la transaction client DOIT contenir des valeurs pour Call-ID, From et Request-URI qui sont égales aux valeurs de ces champs d'en-tête dans la requête passée à la couche transport par la transaction client (appelons cela la « requête originale »). Le champ d'en-tête To dans le ACK DOIT être égal au champ d'en-tête To dans la réponse acquittée, et différera donc généralement du champ d'en-tête To dans la requête originale par l'ajout du paramètre tag. Le ACK DOIT contenir un seul champ d'en-tête Via, et celui-ci DOIT être égal au champ d'en-tête Via le plus haut de la requête originale. Le champ d'en-tête CSeq dans le ACK DOIT contenir la même valeur pour le numéro de séquence que celle présente dans la requête originale, mais le paramètre de méthode DOIT être égal à « ACK ».

Si la requête INVITE dont la réponse est acquittée avait des champs d'en-tête Route, ces champs d'en-tête DOIVENT apparaître dans le ACK. Cela est pour s'assurer que le ACK peut être routé correctement à travers tout proxy sans état en aval.

Bien que toute requête PUISSE contenir un corps, un corps dans un ACK est spécial car la requête ne peut pas être rejetée si le corps n'est pas compris. Par conséquent, le placement de corps dans un ACK pour non 2xx n'est PAS RECOMMANDÉ, mais si cela est fait, les types de corps sont restreints à tout ce qui est apparu dans l'INVITE, en supposant que la réponse à l'INVITE n'était pas 415. Si elle l'était, le corps dans le ACK PEUT être de tout type listé dans le champ d'en-tête Accept du 415.

Par exemple, considérez la requête suivante :

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 requête ACK pour une réponse finale non 2xx à cette requête ressemblerait à ceci :

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 Transaction client non INVITE (Non-INVITE Client Transaction)​

17.1.2.1 Aperçu de la transaction non INVITE (Overview of the non-INVITE Transaction)​

Les transactions non INVITE n'utilisent pas de ACK. Ce sont de simples interactions requête-réponse. Pour les transports non fiables, les requêtes sont retransmises à un intervalle commençant à T1 et doublant jusqu'à atteindre T2. Si une réponse provisoire est reçue, les retransmissions continuent pour les transports non fiables, mais à un intervalle de T2. La transaction serveur retransmet la dernière réponse qu'elle a envoyée, qui peut être provisoire ou finale, uniquement lorsqu'une retransmission de la requête est reçue. C'est pourquoi les retransmissions de requête doivent continuer même après une réponse provisoire ; elles assurent la livraison fiable de la réponse finale.

Contrairement à une transaction INVITE, une transaction non INVITE n'a pas de traitement spécial pour la réponse 2xx. Il en résulte qu'une seule réponse 2xx à une requête non INVITE est jamais livrée à un UAC.

17.1.2.2 Description formelle (Formal Description)​

La machine à états pour la transaction client non INVITE est illustrée à la figure 6. Elle est très similaire à la machine à états pour INVITE.

L'état « Trying » est entré lorsque le TU initie une nouvelle transaction client avec une requête. En entrant dans cet état, la transaction client DEVRAIT régler le minuteur F pour se déclencher dans 64T1 secondes. La requête DOIT être passée à la couche transport pour transmission. Si un transport non fiable est utilisé, la transaction client DOIT régler le minuteur E pour se déclencher dans T1 secondes. Si le minuteur E se déclenche alors qu'on est encore dans cet état, le minuteur est réinitialisé, mais cette fois avec une valeur de MIN(2T1, T2). Lorsqu'il se déclenche à nouveau, il est réinitialisé à MIN(4*T1, T2). Ce processus continue afin que les retransmissions se produisent avec un intervalle augmentant de façon exponentielle qui plafonne à T2. La valeur par défaut de T2 est 4 s, et elle représente le temps qu'une transaction serveur non INVITE prendra pour répondre à une requête, si elle ne répond pas immédiatement. Pour les valeurs par défaut de T1 et T2, cela donne des intervalles de 500 ms, 1 s, 2 s, 4 s, 4 s, 4 s, etc.

Si le minuteur F se déclenche alors que la transaction client est encore dans l'état « Trying », la transaction client DEVRAIT informer le TU du délai d'attente, puis elle DEVRAIT entrer dans l'état « Terminated ». Si une réponse provisoire est reçue dans l'état « Trying », la réponse DOIT être passée au TU, puis la transaction client DEVRAIT passer à l'état « Proceeding ». Si une réponse finale (codes d'état 200-699) est reçue dans l'état « Trying », la réponse DOIT être passée au TU, et la transaction client DOIT passer à l'état « Completed ».

Si le minuteur E se déclenche dans l'état « Proceeding », la requête DOIT être passée à la couche transport pour retransmission, et le minuteur E DOIT être réinitialisé avec une valeur de T2 secondes. Si le minuteur F se déclenche dans l'état « Proceeding », le TU DOIT être informé d'un délai d'attente, et la transaction client DOIT passer à l'état terminé. Si une réponse finale (codes d'état 200-699) est reçue dans l'état « Proceeding », la réponse DOIT être passée au TU, et la transaction client DOIT passer à l'état « Completed ».

Une fois la transaction client entrée dans l'état « Completed », elle DOIT régler le minuteur K pour se déclencher dans T4 secondes pour les transports non fiables, et zéro seconde pour les transports fiables. L'état « Completed » existe pour tamponner toute retransmission de réponse supplémentaire qui pourrait être reçue (c'est pourquoi la transaction client y reste uniquement pour les transports non fiables). T4 représente le temps que le réseau mettra pour effacer les messages entre les transactions client et serveur. La valeur par défaut de T4 est 5 s. Une réponse est une retransmission lorsqu'elle correspond à la même transaction, en utilisant les règles spécifiées à la section 17.1.3. Si le minuteur K se déclenche dans cet état, la transaction client DOIT passer à l'état « Terminated ».

Une fois la transaction dans l'état terminé, elle DOIT être détruite immédiatement.

17.1.3 Correspondance des réponses aux transactions client (Matching Responses to Client Transactions)​

Lorsque la couche transport client reçoit une réponse, elle doit déterminer quelle transaction client traitera cette réponse. Ce faisant, le traitement des sections 17.1.1 et 17.1.2 a lieu. À cette fin, le paramètre branch du champ Via le plus haut est utilisé. Une réponse correspond à une transaction client si :

  1. La valeur du paramètre branch dans le champ Via le plus haut de la réponse est égale à la valeur du paramètre branch dans le champ Via le plus haut de la requête ayant créé la transaction.

2. Le paramètre de méthode du champ d'en-tête CSeq correspond à la méthode de la requête ayant créé la transaction. La méthode est nécessaire car une requête CANCEL constitue une transaction différente mais partage la même valeur de paramètre branch.

Si une requête est envoyée via multicast, plusieurs réponses de différents serveurs peuvent être générées. Toutes ces réponses auront le même paramètre branch dans le Via le plus haut, mais des tags To différents. La première réponse reçue est utilisée selon les règles ci-dessus, et les autres sont traitées comme des retransmissions. Ce n'est pas une erreur. Le multicast SIP ne fournit qu'un service rudimentaire de « découverte à saut unique », limité au traitement d'une seule réponse. Voir la section 18.1.1 pour plus de détails.

17.1.4 Gestion des erreurs de transport (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

             Figure 6 : transaction client non INVITE

Lorsque la transaction client transmet une requête à la couche transport pour transmission, si la couche transport indique un échec, procédez comme suit.

La transaction client DEVRAIT informer le TU qu'une défaillance de transport s'est produite, et la transaction client DEVRAIT passer directement à l'état « Terminated ». Le TU gérera les mécanismes de basculement décrits dans [4].

17.2 Transaction serveur (Server Transaction)​

La transaction serveur est responsable de la livraison des requêtes au TU et de la transmission fiable des réponses. Elle y parvient par le biais d'une machine à états. La transaction serveur est créée par le cœur lorsqu'une requête est reçue, et lorsque le traitement de transaction pour cette requête est souhaité (ce qui n'arrive pas toujours).

Comme pour la transaction client, la machine à états dépend de si la requête reçue est une requête INVITE.

17.2.1 Transaction serveur INVITE (INVITE Server Transaction)​

Le diagramme d'état de la transaction serveur INVITE est donné à la figure 7.

Lorsqu'une transaction serveur est construite pour une requête, elle entre dans l'état « Proceeding ». La transaction serveur DOIT générer une réponse 100 (Trying). Cependant, elle PEUT ne pas générer la réponse 100 (Trying) si elle sait que le TU enverra une réponse provisoire ou finale dans les 200 ms (elle sait cela car elle a envoyé la réponse 100 à une requête précédente dans la même transaction). Cette réponse provisoire est nécessaire pour éteindre rapidement les retransmissions de requête afin d'éviter la congestion du réseau. La réponse 100 (Trying) est construite en suivant les procédures de la section 8.2.6, à l'exception que l'insertion du tag dans le champ d'en-tête To de la réponse (si elle n'était pas présente dans la requête) est rétrogradée de MAY à SHOULD NOT. La requête DOIT être passée au TU.

Le TU peut passer un nombre quelconque de réponses provisoires à la transaction serveur. Tant que la transaction serveur est dans l'état « Proceeding », chacune d'elles DOIT être passée à la couche transport pour transmission. Elles ne sont pas transmises de manière fiable (retransmises) par la couche transaction, et ne provoquent aucun changement d'état de la transaction serveur. Si une retransmission de la requête est reçue dans l'état « Proceeding », la réponse provisoire la plus récente reçue du TU DOIT être passée à la couche transport pour retransmission. Une requête est une retransmission si elle correspond à la même transaction serveur selon les règles de la section 17.2.3.

Dans l'état « Proceeding », si le TU passe une réponse 2xx à la transaction serveur, la transaction serveur DOIT passer cette réponse à la couche transport pour transmission. Elle n'est pas retransmise par la transaction serveur, et la retransmission des réponses 2xx est gérée par le TU. La transaction serveur DOIT alors passer à l'état « Terminated ».

Dans l'état « Proceeding », si le TU passe une réponse avec un code d'état de 300 à 699 à la transaction serveur, cette réponse DOIT être passée à la couche transport pour transmission, et la machine à états DOIT entrer dans l'état « Completed ». Pour les transports non fiables, le minuteur G est réglé pour se déclencher dans T1 secondes, et pour les transports fiables, il n'est pas réglé pour se déclencher.

  Cela est un changement par rapport à la RFC 2543, qui retransmettait toujours les réponses même sur un transport fiable.

En entrant dans l'état « Completed », le minuteur H DOIT être réglé pour se déclencher dans 64T1 secondes pour tous les transports. Le minuteur H détermine quand la transaction serveur abandonne les retransmissions de la réponse. Sa valeur est choisie pour être égale au minuteur B (le temps pendant lequel la transaction client continue d'essayer d'envoyer la requête). Si le minuteur G se déclenche, la réponse est repassée à la couche transport pour retransmission, et le minuteur G est réglé pour se déclencher dans MIN(2T1, T2) secondes. Par la suite, chaque fois que le minuteur G se déclenche, la réponse est repassée au transport pour transmission, et le minuteur G est réinitialisé à une valeur doublée, mais plafonnée à T2 si cette valeur dépasse T2. Cela est identique au comportement de retransmission de la requête dans l'état « Trying » de la transaction client non INVITE. De plus, si une retransmission de la requête est reçue dans l'état « Completed », le serveur DEVRAIT passer la réponse au transport pour retransmission.

Si la transaction serveur reçoit un ACK alors qu'elle est dans l'état « Completed », la transaction serveur DOIT passer à l'état « Confirmed ». Dans cet état, le minuteur G est ignoré, donc toute retransmission de la réponse cesse.

Si le minuteur H se déclenche dans l'état « Completed », cela signifie qu'aucun ACK n'a été reçu. Dans ce cas, la transaction serveur DOIT passer à l'état « Terminated », et DOIT indiquer au TU qu'une défaillance de transaction s'est produite.

                           |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|\<---------------+
                     |           |
                     +-----------+

          Figure 7 : transaction serveur INVITE

L'objectif de l'état « Confirmed » est d'absorber les messages ACK supplémentaires déclenchés par les retransmissions de la réponse finale. En entrant dans cet état, le minuteur I est réglé pour se déclencher dans T4 secondes pour les transports non fiables, et zéro seconde pour les transports fiables. Lorsque le minuteur I se déclenche, le serveur DOIT passer à l'état « Terminated ».

Une fois la transaction dans l'état « Terminated », elle DOIT être détruite immédiatement. Comme pour la transaction client, cela est nécessaire pour garantir la fiabilité des réponses 2xx à un INVITE.

17.2.2 Transaction serveur non INVITE (Non-INVITE Server Transaction)​

La machine à états pour la transaction serveur non INVITE est illustrée à la figure 8.

La machine à états est initialisée dans l'état « Trying », et à l'initialisation reçoit une requête autre que INVITE ou ACK. Cette requête est passée au TU. Une fois dans l'état « Trying », toute retransmission supplémentaire de la requête est ignorée. Une requête est une retransmission si elle correspond à la même transaction serveur selon les règles spécifiées à la section 17.2.3.

Dans l'état « Trying », si le TU passe une réponse provisoire à la transaction serveur, la transaction serveur DOIT entrer dans l'état « Proceeding ». La réponse DOIT être passée à la couche transport pour transmission. Dans l'état « Proceeding », toute réponse provisoire supplémentaire reçue du TU DOIT être passée à la couche transport pour transmission. Dans l'état « Proceeding », si une retransmission de la requête est reçue, la réponse provisoire la plus récemment envoyée DOIT être passée à la couche transport pour retransmission. Si le TU passe une réponse finale (code d'état 200-699) au serveur dans l'état « Proceeding », la transaction DOIT entrer dans l'état « Completed », et la réponse DOIT être passée à la couche transport pour transmission.

Une fois la transaction serveur entrée dans l'état « Completed », elle DOIT régler le minuteur J pour se déclencher dans 64*T1 secondes pour les transports non fiables, et zéro seconde pour les transports fiables. Dans l'état « Completed », la transaction serveur DOIT passer la réponse finale à la couche transport pour retransmission chaque fois qu'une retransmission de la requête est reçue. Toute autre réponse finale passée au serveur dans l'état « Completed » DOIT être ignorée. La transaction serveur reste dans cet état jusqu'à ce que le minuteur J se déclenche, momento où elle DOIT passer à l'état « Terminated ».

La transaction serveur DOIT être détruite à l'instant où elle entre dans l'état « Terminated ».

17.2.3 Correspondance des requêtes aux transactions serveur (Matching Requests to Server Transactions)​

Lorsqu'un serveur reçoit une requête depuis le réseau, il doit la faire correspondre à une transaction existante. Cela est accompli comme suit.

Le paramètre branch du champ Via le plus haut de la requête est examiné. S'il est présent et commence par le magic cookie « z9hG4bK », la requête a été générée par une transaction client conforme à cette spécification. Par conséquent, le paramètre branch est unique parmi toutes les transactions envoyées par ce client. Une requête correspond à une transaction si :

  1. Le paramètre branch dans la requête est égal à celui dans le champ Via le plus haut de la requête ayant créé la transaction, et

2. La valeur sent-by dans le Via le plus haut de la requête est égale à celle dans la requête ayant créé la transaction, et

3. La méthode de la requête correspond à la méthode ayant créé la transaction. Cependant, pour ACK, la méthode de la requête ayant créé la transaction est INVITE.

Cette règle de correspondance s'applique de manière égale aux transactions INVITE et non INVITE.

   La valeur sent-by est utilisée dans le processus de correspondance car des doublons accidentels ou malveillants du paramètre branch de différents clients sont possibles.

Si le paramètre branch du champ Via le plus haut est absent ou ne contient pas le magic cookie, les procédures suivantes sont utilisées. Elles existent pour gérer la compatibilité descendante avec les implémentations conformes à la RFC 2543.

Une requête INVITE correspond à une transaction si le Request-URI, le tag To, le tag From, le Call-ID, le CSeq et le champ Via le plus haut correspondent à ceux de la requête INVITE ayant créé la transaction. Dans ce cas, l'INVITE est une retransmission de l'original ayant créé la transaction. Une requête ACK correspond à une transaction si le Request-URI, le tag From, le Call-ID, le numéro CSeq (pas la méthode) et le champ Via le plus haut correspondent à ceux de la requête INVITE ayant créé la transaction, et si le tag To dans le ACK correspond au tag To de la réponse envoyée par la transaction serveur. La correspondance est basée sur les règles de correspondance définies pour chacun de ces champs d'en-tête. L'inclusion du tag du champ To dans le processus de correspondance ACK aide à lever l'ambiguïté au proxy entre un ACK pour une 2xx et un ACK pour une autre réponse. Le proxy peut avoir transféré les deux réponses (cela peut se produire dans des conditions anormales, en particulier si le proxy fork la requête puis plante, les réponses pourraient être livrées à un autre proxy, qui transférerait plusieurs réponses en amont). Une requête ACK correspondant à une transaction INVITE précédemment mise en correspondance par un ACK est traitée comme une retransmission de ce ACK précédent.

                              |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|
| |
+-----------+

Figure 8 : transaction serveur non INVITE

Pour toutes les autres méthodes de requête, une requête correspond à une transaction si le Request-URI, le tag To, le tag From, le Call-ID, le CSeq (y compris la méthode) et le champ Via le plus haut correspondent à ceux de la requête ayant créé la transaction. La correspondance est basée sur les règles de correspondance définies pour chacun de ces champs d'en-tête. Si une requête non INVITE correspond à une transaction existante, elle est une retransmission de la requête ayant créé la transaction.

Parce que les règles de correspondance incluent le Request-URI, un serveur ne peut pas faire correspondre une réponse à une transaction. Lorsque le TU passe une réponse à une transaction serveur, il doit la passer à la transaction serveur spécifique à laquelle la réponse est destinée.

17.2.4 Gestion des erreurs de transport (Handling Transport Errors)​

Lorsque la transaction serveur transmet une réponse à la couche transport pour transmission, si la couche transport indique un échec, procédez comme suit.

Tout d'abord, suivez les procédures de [4] pour tenter de livrer la réponse via une sauvegarde. Si elles échouent toutes, sur la base de la définition de l'échec dans [4], la transaction serveur DEVRAIT informer le TU qu'une défaillance s'est produite, et elle DEVRAIT passer à l'état terminé.