I'm trying to understand stateful vs. stateless transactions.
A stateless 'transaction' simply lasts as long as it takes to process the current sip request. It is then forgotten.
However, a stateful transaction I'm having a little problem grasping. For instance, if I t_relay() an INVITE, logically the transaction is started....so when the response comes it isn't delivered to the main route {} block, but instead it is delivered to the awaiting stateful t_relay(), probably keyed by callid. So, for instance:
INVITE <- 401 Unauthorized ->
Is this entire sequence a transaction? Right after this the UA sends an ACK, this is a transaction unto itself?
ACK <-
The UA then sends :
INVITE <- 100 Trying -> 180 Ringing -> 200 OK ->
All of these messages are a 'transaction' handled by t_relay()? The next transaction is:
ACK <-
Finally, the last transaction would be (as an example):
BYE <- 200 OK ->
So the ser route{} block would need to recognize and handle
INVITE ACK BYE
in this context. Is that correct? If I was running 'statelessly' I would need to handle and send every single message listed?
---greg
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hello,
On 27-02 10:20, Greg Fausak wrote:
I'm trying to understand stateful vs. stateless transactions.
A stateless 'transaction' simply lasts as long as it takes to process the current sip request. It is then forgotten.
Yes, if you do not use tm module, the server will be stateless. Upon a message reception the server executes the route section of the configuration script. After that the server forgets everything and is ready to process next requests. Stateless servers process all requests and responses independently, they do not keep any state associated with them.
However, a stateful transaction I'm having a little problem grasping. For instance, if I t_relay() an INVITE, logically the transaction is started....so when the response comes it isn't delivered to the main route {} block, but instead it is delivered to the awaiting stateful t_relay(), probably keyed by callid. So, for instance:
t_relay is a stateful version of forward function. If you use t_relay, the server will forward the request _AND_ create an internal structure. The structure persists in the memory for some time (even if the original request has already been forwarded).
When a response to the request comes, the server tries to lookup the structure it previously created for the request. If there is a RFC3261 compatible branch in the topmost via, it serves as a key to the array of all the structures, if there is no such branch parametr, hash of various message headers is used as the key.
It is important to understand that the route script is executed for requests only, responses do not trigger execution of the script. (Although there are so called reply-route blocks which can be called from tm module for responses).
INVITE <- 401 Unauthorized ->
Is this entire sequence a transaction? Right after this the UA sends an ACK, this is a transaction unto itself?
When a 2xx response (to the original INVITE) comes, the INVITE transaction is destroyed immediately, that implies that ACK creates a new transaction.
When a 3xx-699 response come, the original transaction is not destroyed and ACK is part of the original transaction.
INVITE-100-200 belong to the same transaction (ACK is not part of the transaction) INVITE-300-ACK belong to the same transaction
ACK <-
The UA then sends :
INVITE <- 100 Trying -> 180 Ringing -> 200 OK ->
All of these messages are a 'transaction' handled by t_relay()? The next transaction is:
ACK <-
Finally, the last transaction would be (as an example):
BYE <- 200 OK ->
Yes.
So the ser route{} block would need to recognize and handle
INVITE ACK BYE
in this context. Is that correct? If I was running 'statelessly' I would need to handle and send every single message listed?
The only difference in the route script will be forward() instead of t_relay().
regards, Jan.
At 05:20 PM 2/27/2003, Greg Fausak wrote:
I'm trying to understand stateful vs. stateless transactions.
A stateless 'transaction' simply lasts as long as it takes to process the current sip request. It is then forgotten.
yes
However, a stateful transaction I'm having a little problem grasping.
it holds the original requests and for a while the received replies too. That's good when you wish to correlate these, for example for purpose of accounting, serial forking to somewhere else or parallel forking. none of these things works with "forward", you need "t_relay". Stateful proxy also carries out the retransmission job on behalf of the sender. See also http://www.iptel.org/ser/doc/seruser-html/x740.html#AEN839
For instance, if I t_relay() an INVITE, logically the transaction is started....so when the response comes it isn't delivered to the main route {} block, but instead it is delivered to the awaiting stateful t_relay(), probably keyed by callid. So, for instance:
Roughly like that. t_relay establishes a transaction, but it does not block. Replies are keyed through via/branch parameter.
INVITE <- 401 Unauthorized ->
Is this entire sequence a transaction? Right after this the UA sends an ACK, this is a transaction unto itself? ACK <-
If ser challenges, it does so statelessly to scale better. It would have to remember all unathenticated requests for some time (not good for your memory). When the 401 reply is lost and INVITE is retransmitted, ser challenges newly from scratch -- that costs more effort but less memory. If it was stateful, it would just resend the cached reply.
INV--> compute and forget 407<-- ACK-->
The stateful case occurs when ser acts as proxy server and relays the replies coming from downstream for requests previously processed using the t_relay family. ACK for negative replies is part of transaction (unlike ACK for 200). Its purpose is tranport confirmation of negative replies, which are retranmitted until ACK is received. They are local -- proxy confirms on behalf of client.
UAC SER/proxy UAS INV--> t_relay --> <--407 ACK--> (generated by ser to stop 407 retransmissions from downstream) <--407 ACK--> (generated by UAC to stop 407 retranmissions from ser in the middle)
The UA then sends :
INVITE <- 100 Trying -> 180 Ringing -> 200 OK ->
All of these messages are a 'transaction' handled by t_relay()?
yes
The next transaction is:
ACK <-
Yes. ACK for 200 is an interesting thing -- it does not belong to a transaction per specification. It is a request which is always processed statelessly.
Finally, the last transaction would be (as an example):
BYE <- 200 OK ->
So the ser route{} block would need to recognize and handle
INVITE ACK BYE
in this context. Is that correct? If I was running 'statelessly' I would need to handle and send every single message listed?
You need to handle all of these messages if you plan to deploy VoIP services, and you should not forget CANCEL either. It does not matter whether statelessly, or statefuly unless you need some of the things above (accounting, forking, ...)
-Jiri