t_suspend() and t_continue() functions have been documented.
authorMiklos Tirpak <miklos@iptel.org>
Fri, 5 Dec 2008 13:59:35 +0000 (13:59 +0000)
committerMiklos Tirpak <miklos@iptel.org>
Fri, 5 Dec 2008 13:59:35 +0000 (13:59 +0000)
modules/tm/README
modules/tm/doc/api.xml
modules/tm/t_suspend.c

index 0c9da60..ecd5b9f 100644 (file)
@@ -1,3 +1,4 @@
+
 1. TM Module
 
 Jiri Kuthan
@@ -7,7 +8,7 @@ Jiri Kuthan
    Copyright © 2003 FhG FOKUS
    Revision History
    Revision $Revision$ $Date$
-     __________________________________________________________________
+     _________________________________________________________________
 
    1.1. Overview
    1.2. Known Issues
@@ -43,89 +44,94 @@ Jiri Kuthan
         1.4.1. t_relay_to_udp(ip, port), t_relay_to_udp(),
                 t_relay_to_tcp(ip, port) t_relay_to_tcp()
                 t_relay_to_tls(ip, port) t_relay_to_tls()
-                t_relay_to_sctp(ip, port) t_relay_to_sctp()
-
-        1.4.2. t_relay() t_relay(host, port)
-        1.4.3. t_on_failure(failure_route)
-        1.4.4. t_on_reply(onreply_route)
-        1.4.5. t_on_branch(branch_route)
-        1.4.6. append_branch()
-        1.4.7. t_newtran()
-        1.4.8. t_reply(code, reason_phrase)
-        1.4.9. t_lookup_request()
-        1.4.10. t_retransmit_reply()
-        1.4.11. t_release()
+                t_relay_to_sctp(ip, port) t_relay_to_sctp() 
+
+        1.4.2. t_relay() t_relay(host, port) 
+        1.4.3. t_on_failure(failure_route) 
+        1.4.4. t_on_reply(onreply_route) 
+        1.4.5. t_on_branch(branch_route) 
+        1.4.6. append_branch() 
+        1.4.7. t_newtran() 
+        1.4.8. t_reply(code, reason_phrase) 
+        1.4.9. t_lookup_request() 
+        1.4.10. t_retransmit_reply() 
+        1.4.11. t_release() 
         1.4.12. t_forward_nonack() t_forward_nonack(ip, port)
                 t_forward_nonack_udp(ip, port) t_forward_nonack_tcp(ip,
                 port) t_forward_nonack_tls(ip, port)
-                t_forward_nonack_sctp(ip, port)
-
-        1.4.13. t_set_fr(fr_inv_timeout [, fr_timeout])
-        1.4.14. t_reset_fr()
-        1.4.15. t_set_max_lifetime(inv_lifetime, noninv_lifetime)
-        1.4.16. t_reset_max_lifetime()
-        1.4.17. t_set_retr(retr_t1_interval, retr_t2_interval)
-        1.4.18. t_reset_retr()
-        1.4.19. t_set_auto_inv_100(0|1)
-        1.4.20. t_branch_timeout()
-        1.4.21. t_branch_replied()
-        1.4.22. t_any_timeout()
-        1.4.23. t_any_replied()
-        1.4.24. t_grep_status("code")
-        1.4.25. t_is_canceled()
-        1.4.26. t_relay_cancel()
-        1.4.27. t_drop_replies()
-        1.4.28. t_save_lumps()
+                t_forward_nonack_sctp(ip, port) 
+
+        1.4.13. t_set_fr(fr_inv_timeout [, fr_timeout]) 
+        1.4.14. t_reset_fr() 
+        1.4.15. t_set_max_lifetime(inv_lifetime, noninv_lifetime) 
+        1.4.16. t_reset_max_lifetime() 
+        1.4.17. t_set_retr(retr_t1_interval, retr_t2_interval) 
+        1.4.18. t_reset_retr() 
+        1.4.19. t_set_auto_inv_100(0|1) 
+        1.4.20. t_branch_timeout() 
+        1.4.21. t_branch_replied() 
+        1.4.22. t_any_timeout() 
+        1.4.23. t_any_replied() 
+        1.4.24. t_grep_status("code") 
+        1.4.25. t_is_canceled() 
+        1.4.26. t_relay_cancel() 
+        1.4.27. t_drop_replies() 
+        1.4.28. t_save_lumps() 
 
    1.5. TM Module API
 
         1.5.1. Defines
         1.5.2. Functions
 
-              1.5.2.1. register_tmcb(cb_type, cb_func)
-              1.5.2.2. load_tm(*import_structure)
+              1.5.2.1. register_tmcb(cb_type, cb_func) 
+              1.5.2.2. load_tm(*import_structure) 
+              1.5.2.3. int t_suspend(struct sip_msg *msg, unsigned int
+                      *hash_index, unsigned int *label) 
+
+              1.5.2.4. int t_continue(unsigned int hash_index, unsigned
+                      int label, struct action *route) 
 
 1.1. Overview
 
-   TM module enables stateful processing of SIP transactions. The main use
-   of stateful logic, which is costly in terms of memory and CPU, is some
-   services inherently need state. For example, transaction-based
+   TM module enables stateful processing of SIP transactions. The main
+   use of stateful logic, which is costly in terms of memory and CPU, is
+   some services inherently need state. For example, transaction-based
    accounting (module acc) needs to process transaction state as opposed
    to individual messages, and any kinds of forking must be implemented
    statefully. Other use of stateful processing is it trading CPU caused
    by retransmission processing for memory. That makes however only sense
    if CPU consumption per request is huge. For example, if you want to
-   avoid costly DNS resolution for every retransmission of a request to an
-   unresolvable destination, use stateful mode. Then, only the initial
+   avoid costly DNS resolution for every retransmission of a request to
+   an unresolvable destination, use stateful mode. Then, only the initial
    message burdens server by DNS queries, subsequent retransmissions will
    be dropped and will not result in more processes blocked by DNS
    resolution. The price is more memory consumption and higher processing
    latency.
 
    From user's perspective, there are these major functions : t_relay,
-   t_relay_to_udp and t_relay_to_tcp. All of them setup transaction state,
-   absorb retransmissions from upstream, generate downstream
+   t_relay_to_udp and t_relay_to_tcp. All of them setup transaction
+   state, absorb retransmissions from upstream, generate downstream
    retransmissions and correlate replies to requests. t_relay forwards to
    current URI (be it original request's URI or a URI changed by some of
    URI-modifying functions, such as sethost). t_relay_to_udp and
    t_relay_to_tcp forward to a specific address over UDP or TCP
    respectively.
 
-   In general, if TM is used, it copies clones of received SIP messages in
-   shared memory. That costs the memory and also CPU time (memcpys,
-   lookups, shmem locks, etc.) Note that non-TM functions operate over the
-   received message in private memory, that means that any core operations
-   will have no effect on statefully processed messages after creating the
-   transactional state. For example, calling record_route after t_relay is
-   pretty useless, as the RR is added to privately held message whereas
-   its TM clone is being forwarded.
+   In general, if TM is used, it copies clones of received SIP messages
+   in shared memory. That costs the memory and also CPU time (memcpys,
+   lookups, shmem locks, etc.) Note that non-TM functions operate over
+   the received message in private memory, that means that any core
+   operations will have no effect on statefully processed messages after
+   creating the transactional state. For example, calling record_route
+   after t_relay is pretty useless, as the RR is added to privately held
+   message whereas its TM clone is being forwarded.
 
    TM is quite big and uneasy to program--lot of mutexes, shared memory
-   access, malloc and free, timers--you really need to be careful when you
-   do anything. To simplify TM programming, there is the instrument of
-   callbacks. The callback mechanisms allow programmers to register their
-   functions to specific event. See t_hooks.h for a list of possible
-   events.
+   access, malloc and free, timers--you really need to be careful when
+   you do anything. To simplify TM programming, there is the instrument
+   of callbacks. The callback mechanisms allow programmers to register
+   their functions to specific event. See t_hooks.h for a list of
+   possible events.
 
    Other things programmers may want to know is UAC--it is a very
    simplistic code which allows you to generate your own transactions.
@@ -136,16 +142,16 @@ Jiri Kuthan
 
 1.2. Known Issues
 
-     * Possibly, performance could be improved by not parsing non-INVITEs,
-       as they do not be replied with 100, and do not result in
-       ACK/CANCELs, and other things which take parsing. However, we need
-       to rethink whether we don't need parsed headers later for something
-       else. Remember, when we now conserver a request in sh_mem, we can't
-       apply any pkg_mem operations to it any more. (that might be
-       redesigned too).
-     * Another performance improvement may be achieved by not parsing CSeq
-       in replies until reply branch matches branch of an INVITE/CANCEL in
-       transaction table.
+     * Possibly, performance could be improved by not parsing
+       non-INVITEs, as they do not be replied with 100, and do not result
+       in ACK/CANCELs, and other things which take parsing. However, we
+       need to rethink whether we don't need parsed headers later for
+       something else. Remember, when we now conserver a request in
+       sh_mem, we can't apply any pkg_mem operations to it any more.
+       (that might be redesigned too).
+     * Another performance improvement may be achieved by not parsing
+       CSeq in replies until reply branch matches branch of an
+       INVITE/CANCEL in transaction table.
      * t_replicate should be done more cleanly--Vias, Routes, etc. should
        be removed from a message prior to replicating it (well, does not
        matter any longer so much as there is a new replication module).
@@ -207,8 +213,8 @@ modparam("tm", "fr_inv_timer", 180000)
    fr_inv_timer will still be restarted for each increasing reply (e.g.
    180, 181, 182, ...). Another example when a transaction can live
    substantially more then its fr_inv_timer and where max_inv_lifetime
-   will help is when dns failover is used (each failed dns destination can
-   introduce a new branch).
+   will help is when dns failover is used (each failed dns destination
+   can introduce a new branch).
 
    The default value is 180000 ms (180 seconds - the rfc3261 timer C
    value).
@@ -241,7 +247,8 @@ modparam("tm", "max_inv_lifetime", 150000)
    failover is used (each failed dns destination can introduce a new
    branch).
 
-   The default value is 32000 ms (32 seconds - the rfc3261 timer F value).
+   The default value is 32000 ms (32 seconds - the rfc3261 timer F
+   value).
 
    See also: max_inv_lifetime, t_set_max_lifetime() (allows changing
    max_noninv_lifetime on a per transaction basis), t_reset_max_lifetime
@@ -254,11 +261,11 @@ modparam("tm", "max_inv_lifetime", 30000)
 
 1.3.5. wt_timer (integer)
 
-   Time for which a transaction stays in memory to absorb delayed messages
-   after it completed (in milliseconds); also, when this timer hits,
-   retransmission of local cancels is stopped (a puristic but complex
-   behavior would be not to enter wait state until local branches are
-   finished by a final reply or FR timer--we simplified).
+   Time for which a transaction stays in memory to absorb delayed
+   messages after it completed (in milliseconds); also, when this timer
+   hits, retransmission of local cancels is stopped (a puristic but
+   complex behavior would be not to enter wait state until local branches
+   are finished by a final reply or FR timer--we simplified).
 
    Default value is 5000 ms (5 seconds).
 
@@ -272,8 +279,8 @@ modparam("tm", "wt_timer", 1000)
    Time after which a to-be-deleted transaction currently ref-ed by a
    process will be tried to be deleted again (in milliseconds).
 
-   Note: this parameter is obsolete for ser 2.1 (in 2.1 the transaction is
-   deleted the moment it's not referenced anymore).
+   Note: this parameter is obsolete for ser 2.1 (in 2.1 the transaction
+   is deleted the moment it's not referenced anymore).
 
    Default value is 200 milliseconds.
 
@@ -308,15 +315,16 @@ modparam("tm", "retr_timer2", 2000)
 
 1.3.9. noisy_ctimer (integer)
 
-   If set, INVITE transactions that time-out (FR INV timer) will be always
-   replied. If it's not set, the transaction has only one branch and no
-   response was ever received on this branch, it will be silently dropped
-   (no 408 reply will be generated) This behavior is overridden if a
-   request is forked, the transaction has a failure route or callback, or
-   some functionality explicitly turned it on for a transaction (like acc
-   does to avoid unaccounted transactions due to expired timer). Turn this
-   off only if you know the client UACs will timeout and their timeout
-   interval for INVITEs is lower or equal than tm's fr_inv_timer.
+   If set, INVITE transactions that time-out (FR INV timer) will be
+   always replied. If it's not set, the transaction has only one branch
+   and no response was ever received on this branch, it will be silently
+   dropped (no 408 reply will be generated) This behavior is overridden
+   if a request is forked, the transaction has a failure route or
+   callback, or some functionality explicitly turned it on for a
+   transaction (like acc does to avoid unaccounted transactions due to
+   expired timer). Turn this off only if you know the client UACs will
+   timeout and their timeout interval for INVITEs is lower or equal than
+   tm's fr_inv_timer.
 
    Default value is 1 (on).
 
@@ -329,9 +337,9 @@ modparam("tm", "noisy_ctimer", 1)
 
    If set (default), the fr_inv_timer for an INVITE transaction will be
    restarted for each provisional reply received (rfc3261 mandated
-   behaviour). If not set, the fr_inv_timer will be restarted only for the
-   first provisional replies and for increasing replies greater or equal
-   180 (e.g. 180, 181, 182, 185, ...).
+   behaviour). If not set, the fr_inv_timer will be restarted only for
+   the first provisional replies and for increasing replies greater or
+   equal 180 (e.g. 180, 181, 182, 185, ...).
 
    Setting it to 0 is especially useful when dealing with bad UAs that
    continuously retransmit 180s, not allowing the transaction to timeout
@@ -354,8 +362,8 @@ modparam("tm", "restart_fr_on_each_reply", 0)
    Setting it to 0 one can be used to enable doing first some tests or
    pre-processing on the INVITE and only if some conditions are met
    manually send a 100 (using t_reply()). Note however that in this case
-   all the 100s have to be sent "by hand". t_set_auto_inv_100() might help
-   to selectively turn off this feature only for some specific
+   all the 100s have to be sent "by hand". t_set_auto_inv_100() might
+   help to selectively turn off this feature only for some specific
    transactions.
 
    Default value is 1 (on).
@@ -371,8 +379,8 @@ modparam("tm", "auto_inv_100", 0)
 
    Unix socket transmission timeout, in milliseconds.
 
-   If unix sockets are used (e.g.: to communicate with sems) and sending a
-   message on a unix socket takes longer then unix_tx_timeout, the send
+   If unix sockets are used (e.g.: to communicate with sems) and sending
+   message on a unix socket takes longer then unix_tx_timeout, the send
    will fail.
 
    The default value is 500 milliseconds.
@@ -389,8 +397,8 @@ modparam("tm", "unix_tx_timeout", 250)
    Proxy-Authenticate headers from all the 401 and 407 replies will be
    aggregated in a new final reply. If only one branch received the
    winning 401 or 407 then this reply will be forwarded (no new one will
-   be built). If 0 only the first 401, or if no 401 was received the first
-   407, will be forwarded (no header aggregation).
+   be built). If 0 only the first 401, or if no 401 was received the
+   first 407, will be forwarded (no header aggregation).
 
    Default value is 1 (required by rfc3261).
 
@@ -403,15 +411,15 @@ modparam("tm", "aggregate_challenges", 0)
 
    If set (default), the CANCEL and negative ACK requests are constructed
    from the INVITE message which was sent out instead of building them
-   from the received request. The disadvantage is that the outgoing INVITE
-   has to be partially re-parsed, the advantage is that the CANCEL/ACK is
-   always RFC 3261-compliant, it always contains the same route-set as the
-   INVITE message. Do not disable the INVITE re-parsing for example in the
-   following cases:
+   from the received request. The disadvantage is that the outgoing
+   INVITE has to be partially re-parsed, the advantage is that the
+   CANCEL/ACK is always RFC 3261-compliant, it always contains the same
+   route-set as the INVITE message. Do not disable the INVITE re-parsing
+   for example in the following cases:
 
    - The INVITE contains a preloaded route-set, and SER forwards the
-   message to the next hop according to the Route header. The Route header
-   is not removed in the CANCEL without reparse_invite=1.
+   message to the next hop according to the Route header. The Route
+   header is not removed in the CANCEL without reparse_invite=1.
 
    - SER record-routes, thus an in-dialog INVITE contains a Route header
    which is removed during loose routing. If the in-dialog INVITE is
@@ -431,8 +439,8 @@ modparam("tm", "reparse_invite", 0)
    CANCEL and negative ACK messages if they were present in the outgoing
    INVITE.
 
-   Note, that the parameter value effects only those headers which are not
-   covered by RFC-3261 (which are neither mandatory nor prohibited in
+   Note, that the parameter value effects only those headers which are
+   not covered by RFC-3261 (which are neither mandatory nor prohibited in
    CANCEL and ACK), and the parameter can be used only together with
    reparse_invite=1.
 
@@ -448,8 +456,8 @@ modparam("tm", "ac_extra_hdrs", "myfavoriteheaders-")
    If set and the blacklist support is enabled, every 503 reply source is
    added to the blacklist. The initial blacklist timeout (or ttl) depends
    on the presence of a Retry-After header in the reply and the values of
-   the following tm parameters: blst_503_def_timeout, blst_503_min_timeout
-   and blst_503_max_timeout.
+   the following tm parameters: blst_503_def_timeout,
+   blst_503_min_timeout and blst_503_max_timeout.
 
    WARNING:blindly allowing 503 blacklisting could be very easily
    exploited for DOS attacks in most network setups.
@@ -550,8 +558,8 @@ modparam("tm", "blst_methods_lookup", 1)
    values are 0, 1, and 2.
 
    0 will immediately stop the request (INVITE) retransmission on the
-   branch and it will behave as if the branch was immediately replied with
-   a 487 (a fake internal 487 reply). The advantage is the unreplied
+   branch and it will behave as if the branch was immediately replied
+   with a 487 (a fake internal 487 reply). The advantage is the unreplied
    branches will be terminated immediately. However it introduces a race
    risk with a possible slightly delayed 2xx reply. In this case we could
    have an UA receiving a 2xx after a 487. Moreover this risk is greatly
@@ -563,16 +571,16 @@ modparam("tm", "blst_methods_lookup", 1)
    1 will keep retransmitting the request on unreplied branches. If a
    provisional answer is later received a CANCEL will be immediately sent
    back (attempting to quickly trigger a 487). This approach is race free
-   and avoids the 2xx after 487 problem, but it's more resource intensive:
-   faced with a branch towards and UA that doesn't answer, a CANCEL
-   attempt will keep the transaction alive for the whole timeout interval
-   (fr_timer).
+   and avoids the 2xx after 487 problem, but it's more resource
+   intensive: faced with a branch towards and UA that doesn't answer, a
+   CANCEL attempt will keep the transaction alive for the whole timeout
+   interval (fr_timer).
 
    2 will send and retransmit CANCEL even on unreplied branches, stopping
-   the request retransmissions. This has the same advantages as 1 and also
-   avoids the extra roundtrip in the case of the provisional reply, but
-   it's not RFC 3261 conforming (the RFC allows sending CANCELs only on
-   pending branches).
+   the request retransmissions. This has the same advantages as 1 and
+   also avoids the extra roundtrip in the case of the provisional reply,
+   but it's not RFC 3261 conforming (the RFC allows sending CANCELs only
+   on pending branches).
 
    The default value is 1.
 
@@ -595,11 +603,11 @@ modparam("tm", "cancel_b_method", 1)
    Note: If the parameter is set, branch route block and
    TMCB_REQUEST_FWDED callback are not called in case of the failover.
 
-   Disadvantage: only the via header is replaced in the message buffer, so
-   the outgoing socket address is not corrected in any other part of the
-   message. It is dangerous on multihomed hosts: when the new SIP request
-   after the DNS failover is sent via different interface than the first
-   request, the message can contain incorrect ip address in the
+   Disadvantage: only the via header is replaced in the message buffer,
+   so the outgoing socket address is not corrected in any other part of
+   the message. It is dangerous on multihomed hosts: when the new SIP
+   request after the DNS failover is sent via different interface than
+   the first request, the message can contain incorrect ip address in the
    Record-Route header for instance.
 
    Default value is 1.
@@ -612,9 +620,9 @@ modparam("tm", "reparse_on_dns_failover", 0)
 1.3.24. on_sl_reply (string)
 
    Sets reply route block, to which control is passed when a reply is
-   received that has no associated transaction. The reply is passed to the
-   core for stateless forwarding after the route block execution unless it
-   returns 0.
+   received that has no associated transaction. The reply is passed to
+   the core for stateless forwarding after the route block execution
+   unless it returns 0.
 
    Example 24. Set on_sl_reply parameter
 ...
@@ -648,8 +656,8 @@ t_relay_to_sctp(ip, port) t_relay_to_sctp()
      * port - Port number.
 
    If no parameters are specified the message is sent to a destination
-   derived from the message uri (using sip sepcific DNS lookups), but with
-   the protocol corresponding to the function name.
+   derived from the message uri (using sip sepcific DNS lookups), but
+   with the protocol corresponding to the function name.
 
    Example 25. t_relay_to_udp usage
 ...
@@ -662,21 +670,22 @@ else
 1.4.2.  t_relay() t_relay(host, port)
 
    Relay a message statefully either to the destination indicated in the
-   current URI (if called without any parameters) or to the specified host
-   and port. In the later case (host and port specified) the protocol used
-   is the same protocol on which the message was received.
+   current URI (if called without any parameters) or to the specified
+   host and port. In the later case (host and port specified) the
+   protocol used is the same protocol on which the message was received.
 
    t_relay() is the statefull version for forward(uri:host, uri:port)
    while t_relay(host, port) is similar to forward(host, port).
 
    In the forward to uri case (t_relay()), if the original URI was
    rewritten (by UsrLoc, RR, strip/prefix, etc.) the new URI will be
-   taken). The destination (including the protocol) is determined from the
-   uri, using SIP specific DNS resolving if needed (NAPTR, SRV a.s.o
+   taken). The destination (including the protocol) is determined from
+   the uri, using SIP specific DNS resolving if needed (NAPTR, SRV a.s.o
    depending also on the dns options).
 
    Returns a negative value on failure--you may still want to send a
-   negative reply upstream statelessly not to leave upstream UAC in lurch.
+   negative reply upstream statelessly not to leave upstream UAC in
+   lurch.
 
    Example 26. t_relay usage
 ...
@@ -690,19 +699,19 @@ if (!t_relay())
 1.4.3.  t_on_failure(failure_route)
 
    Sets failure routing block, to which control is passed after a
-   transaction completed with a negative result but before sending a final
-   reply. In the referred block, you can either start a new branch (good
-   for services such as forward_on_no_reply) or send a final reply on your
-   own (good for example for message silo, which received a negative reply
-   from upstream and wants to tell upstream "202 I will take care of it").
-   Note that the set of commands which are usable within failure_routes is
-   strictly limited to rewriting URI, initiating new branches, logging,
-   and sending stateful replies (t_reply). Any other commands may result
-   in unpredictable behavior and possible server failure. Note that
-   whenever failure_route is entered, uri is reset to value which it had
-   on relaying. If it temporarily changed during a reply_route processing,
-   subsequent reply_route will ignore the changed value and use again the
-   original one.
+   transaction completed with a negative result but before sending a
+   final reply. In the referred block, you can either start a new branch
+   (good for services such as forward_on_no_reply) or send a final reply
+   on your own (good for example for message silo, which received a
+   negative reply from upstream and wants to tell upstream "202 I will
+   take care of it"). Note that the set of commands which are usable
+   within failure_routes is strictly limited to rewriting URI, initiating
+   new branches, logging, and sending stateful replies (t_reply). Any
+   other commands may result in unpredictable behavior and possible
+   server failure. Note that whenever failure_route is entered, uri is
+   reset to value which it had on relaying. If it temporarily changed
+   during a reply_route processing, subsequent reply_route will ignore
+   the changed value and use again the original one.
 
    Meaning of the parameters is as follows:
      * failure_route - Failure route block to be called.
@@ -746,8 +755,8 @@ route {
 onreply_route[1] {
         if (status=~ "(183)|2[0-9][0-9]"){
                 force_rtp_proxy();
-                search_append('^(Contact|m)[ \t]*:.*sip:[^>[:cntrl:]]*', ';nat=y
-es');
+                search_append('^(Contact|m)[ \t]*:.*sip:[^>[:cntrl:]]*', ';nat=
+yes');
         }
         if (nat_uac_test("1")){
                 fix_nated_contact();
@@ -756,11 +765,12 @@ es');
 
 1.4.5.  t_on_branch(branch_route)
 
-   Sets the branch routing block, to which control is passed after forking
-   (when a new branch is created). For now branch routes are intended only
-   for last minute changes of the SIP messages (like adding new headers).
-   Note that the set of commands which are usable within branch_routes is
-   very limited. It is not possible to drop a message or generate a reply.
+   Sets the branch routing block, to which control is passed after
+   forking (when a new branch is created). For now branch routes are
+   intended only for last minute changes of the SIP messages (like adding
+   new headers). Note that the set of commands which are usable within
+   branch_routes is very limited. It is not possible to drop a message or
+   generate a reply.
 
    Meaning of the parameters is as follows:
      * branch_route - branch route block to be called.
@@ -848,8 +858,8 @@ t_retransmit_reply();
 
 1.4.11.  t_release()
 
-   Remove transaction from memory (it will be first put on a wait timer to
-   absorb delayed messages).
+   Remove transaction from memory (it will be first put on a wait timer
+   to absorb delayed messages).
 
    Example 35. t_release usage
 ...
@@ -907,9 +917,9 @@ branch_route[1] {
 
 1.4.14.  t_reset_fr()
 
-   Resets the fr_inv_timer and fr_timer for the current transaction to the
-   default values (set using the tm module parameters fr_inv_timer and
-   fr_timer).
+   Resets the fr_inv_timer and fr_timer for the current transaction to
+   the default values (set using the tm module parameters fr_inv_timer
+   and fr_timer).
 
    It will effectively cancel any previous calls to t_set_fr for the same
    transaction.
@@ -928,9 +938,9 @@ route {
 
    Sets the maximum lifetime for the current INVITE or non-INVITE
    transaction, or for transactions created during the same script
-   invocation, after calling this function (that's why it takes values for
-   both INVITE and non-INVITE). If one of the parameters is 0, its value
-   won't be changed.
+   invocation, after calling this function (that's why it takes values
+   for both INVITE and non-INVITE). If one of the parameters is 0, its
+   value won't be changed.
 
    It works as a per transaction max_inv_lifetime or max_noninv_lifetime.
 
@@ -959,8 +969,8 @@ route {
    transaction to the default value (set using the tm module parameter
    max_inv_lifetime or max_noninv_lifetime).
 
-   It will effectively cancel any previous calls to t_set_max_lifetime for
-   the same transaction.
+   It will effectively cancel any previous calls to t_set_max_lifetime
+   for the same transaction.
 
    See also: max_inv_lifetime, max_noninv_lifetime, t_set_max_lifetime.
 
@@ -976,9 +986,9 @@ route {
 
    Sets the retr_t1_interval and retr_t2_interval for the current
    transaction or for transactions created during the same script
-   invocation, after calling this function. If one of the parameters is 0,
-   it's value won't be changed. If the transaction is already created (e.g
-   called after t_relay() or in an onreply_route) all the existing
+   invocation, after calling this function. If one of the parameters is
+   0, it's value won't be changed. If the transaction is already created
+   (e.g called after t_relay() or in an onreply_route) all the existing
    branches will have their retransmissions intervals updated on-the-fly:
    if the retransmission interval for the branch has not yet reached T2
    the interval will be reset to retr_t1_interval, else to
@@ -986,11 +996,11 @@ route {
    interval expires (after the next retransmission, the next-next
    retransmission will take place at retr_t1_interval or
    retr_t2_interval). All new branches of the same transaction will start
-   with the new values. This function will work even if it's called in the
-   script before a transaction creating function (e.g.: t_set_retr(500,
-   4000); t_relay()). All new transaction created after this function
-   call, during the same script invocation will use the new values. Note
-   that this function will work only if tm is compile with
+   with the new values. This function will work even if it's called in
+   the script before a transaction creating function (e.g.:
+   t_set_retr(500, 4000); t_relay()). All new transaction created after
+   this function call, during the same script invocation will use the new
+   values. Note that this function will work only if tm is compile with
    -DTM_DIFF_RT_TIMEOUT (which increases every transaction size with 4
    bytes).
 
@@ -1146,11 +1156,11 @@ failure_route[0]{
 
 1.4.26.  t_relay_cancel()
 
-   Forwards the CANCEL if the corresponding INVITE transaction exists. The
-   function is supposed to be used at the very beginning of the script,
-   because the CANCELs can be caught and the rest of the script can be
-   bypassed this way. Do not disable reparse_invite module parameter, and
-   call t_relay_cancel() right after the sanity tests.
+   Forwards the CANCEL if the corresponding INVITE transaction exists.
+   The function is supposed to be used at the very beginning of the
+   script, because the CANCELs can be caught and the rest of the script
+   can be bypassed this way. Do not disable reparse_invite module
+   parameter, and call t_relay_cancel() right after the sanity tests.
 
    Return value is 0 (drop) if the corresponding INVITE was found and the
    CANCELs were successfully sent to the pending branches, true if the
@@ -1284,21 +1294,21 @@ end of body
 1.5.1. Defines
 
      * ACK_TAG enables stricter matching of acknowledgments including
-       to-tags. Without it, to-tags are ignored. It is disabled by default
-       for two reasons:
+       to-tags. Without it, to-tags are ignored. It is disabled by
+       default for two reasons:
           + It eliminates an unlikely race condition in which
-            transaction's to-tag is being rewritten by a 200 OK whereas an
-            ACK is being looked up by to-tag.
+            transaction's to-tag is being rewritten by a 200 OK whereas
+            an ACK is being looked up by to-tag.
           + It makes UACs happy who set wrong to-tags.
        It should not make a difference, as there may be only one negative
-       reply sent upstream and 200/ACKs are not matched as they constitute
-       another transaction. It will make no difference at all when the new
-       magic cookie matching is enabled anyway.
+       reply sent upstream and 200/ACKs are not matched as they
+       constitute another transaction. It will make no difference at all
+       when the new magic cookie matching is enabled anyway.
      * CANCEL_TAG similarly enables strict matching of CANCELs including
        to-tags--act of mercy to UACs, who screw up the to-tags (however,
-       it still depends on how forgiving the downstream UAS is). Like with
-       ACK_TAG, all this complex transactions matching goes with RFC3261's
-       magic cookie away anyway.
+       it still depends on how forgiving the downstream UAS is). Like
+       with ACK_TAG, all this complex transactions matching goes with
+       RFC3261's magic cookie away anyway.
 
 1.5.2. Functions
 
@@ -1318,3 +1328,57 @@ end of body
 
    Meaning of the parameters is as follows:
      * import_structure - Pointer to the import structure.
+
+1.5.2.3.  int t_suspend(struct sip_msg *msg, unsigned int *hash_index,
+unsigned int *label)
+
+   For programmatic use only. This function together with t_continue()
+   can be used to implement asynchronous actions: t_suspend() saves the
+   transaction, returns its identifiers, and t_continue() continues the
+   SIP request processing. (The request processing does not continue from
+   the same point in the script, a separate route block defined by the
+   parameter of t_continue() is executed instead. The reply lock is held
+   during the route block execution.) FR timer is ticking while the
+   transaction is suspended, and the transaction's failure route is
+   executed if t_continue() is not called in time.
+
+   Missing: message lumps are saved by t_suspend() and are not updated by
+   the subsequent t_relay(). This means that the modifications made
+   between them are lost.
+
+   Meaning of the parameters is as follows:
+     * msg - SIP message pointer.
+     * hash_index - transaction identifier.
+     * label - transaction identifier.
+
+   Return value: 0 - success, <0 - error.
+
+   Usage: Allocate a memory block for storing the transaction identifiers
+   (hash_index and label), and for storing also any variable related to
+   the async query. Before calling t_suspend(), register for the
+   following callbacks, and pass the pointer to the allocated shared
+   memory as a parameter: TMCB_ON_FAILURE, TMCB_DESTROY, and
+   TMCB_E2ECANCEL_IN (in case of INVITE transaction). The async operation
+   can be cancelled, if it is still pending, when TMCB_ON_FAILURE or
+   TMCB_E2ECANCEL_IN is called. TMCB_DESTROY is suitable to free the
+   shared memory allocated for the async and SIP transaction identifiers.
+   Once the async query result is available call t_continue(), see below.
+   The SIP transaction must exist before calling t_suspend(), and the
+   module function calling t_suspend() should return 0 to make sure that
+   the script processing does not continue.
+
+1.5.2.4.  int t_continue(unsigned int hash_index, unsigned int label, struct
+action *route)
+
+   For programmatic use only. This function is the pair of t_suspend(),
+   and is supposed to be called when the asynchronous query result is
+   available. The function executes a route block with the saved SIP
+   message. It is possible to add more branches to the transaction, or
+   send a reply from the route block.
+
+   Meaning of the parameters is as follows:
+     * hash_index - transaction identifier.
+     * label - transaction identifier.
+     * route - route block to execute.
+
+   Return value: 0 - success, <0 - error.
index 0879422..da75a8d 100644 (file)
@@ -155,6 +155,93 @@ end of body
                </listitem>
            </itemizedlist>
        </section>
+
+       <section id="t_suspend">
+           <title>
+               <function>int t_suspend(struct sip_msg *msg,
+                       unsigned int *hash_index, unsigned int *label)</function>
+           </title>
+           <para>
+               For programmatic use only.
+               This function together with t_continue() can be used to
+               implement asynchronous actions: t_suspend() saves the transaction,
+               returns its identifiers, and t_continue() continues the
+               SIP request processing. (The request processing does not continue
+               from the same point in the script, a separate route block defined
+               by the parameter of t_continue() is executed instead. The reply lock
+               is held during the route block execution.)
+               FR timer is ticking while the transaction is suspended, and the
+               transaction's failure route is executed if t_continue() is not
+               called in time.
+           </para>
+           <para>
+               Missing: message lumps are saved by t_suspend() and are not updated by
+               the subsequent t_relay(). This means that the modifications made
+               between them are lost.
+           </para>
+           <para>Meaning of the parameters is as follows:</para>
+           <itemizedlist>
+               <listitem>
+                   <para><emphasis>msg</emphasis> - SIP message pointer.
+                   </para>
+               </listitem>
+               <listitem>
+                   <para><emphasis>hash_index</emphasis> - transaction identifier.
+                   </para>
+               </listitem>
+               <listitem>
+                   <para><emphasis>label</emphasis> - transaction identifier.
+                   </para>
+               </listitem>
+           </itemizedlist>
+           <para>Return value: 0 - success, &lt;0 - error.</para>
+           <para>
+               Usage: Allocate a memory block for storing the transaction identifiers
+               (hash_index and label), and for storing also any variable related to
+               the async query. Before calling t_suspend(), register for the following
+               callbacks, and pass the pointer to the allocated shared memory as
+               a parameter: TMCB_ON_FAILURE, TMCB_DESTROY, and TMCB_E2ECANCEL_IN
+               (in case of INVITE transaction). The async operation can be
+               cancelled, if it is still pending, when TMCB_ON_FAILURE or
+               TMCB_E2ECANCEL_IN is called. TMCB_DESTROY is suitable to free
+               the shared memory allocated for the async and SIP transaction identifiers.
+               Once the async query result is available call t_continue(), see below.
+               The SIP transaction must exist before calling t_suspend(), and the module
+               function calling t_suspend() should return 0 to make sure that the script
+               processing does not continue.
+           </para>
+       </section>
+
+       <section id="t_continue">
+           <title>
+               <function>int t_continue(unsigned int hash_index, unsigned int label,
+                               struct action *route)</function>
+           </title>
+           <para>
+               For programmatic use only.
+               This function is the pair of t_suspend(), and is supposed
+               to be called when the asynchronous query result is available.
+               The function executes a route block with the saved SIP message.
+               It is possible to add more branches to the transaction, or send
+               a reply from the route block.
+           </para>
+           <para>Meaning of the parameters is as follows:</para>
+           <itemizedlist>
+               <listitem>
+                   <para><emphasis>hash_index</emphasis> - transaction identifier.
+                   </para>
+               </listitem>
+               <listitem>
+                   <para><emphasis>label</emphasis> - transaction identifier.
+                   </para>
+               </listitem>
+               <listitem>
+                   <para><emphasis>route</emphasis> - route block to execute.
+                   </para>
+               </listitem>
+           </itemizedlist>
+           <para>Return value: 0 - success, &lt;0 - error.</para>
+       </section>
     </section>
     
 </section>
index 21b66fa..9b418c1 100644 (file)
 #include "timer.h"
 #include "t_suspend.h"
 
+/* Suspends the transaction for later use.
+ * Save the returned hash_index and label to get
+ * back to the SIP request processing, see the readme.
+ *
+ * Return value:
+ *     0  - success
+ *     <0 - failure
+ */
 int t_suspend(struct sip_msg *msg,
                unsigned int *hash_index, unsigned int *label)
 {
@@ -85,6 +93,14 @@ int t_suspend(struct sip_msg *msg,
        return 0;
 }
 
+/* Continues the SIP request processing previously saved by
+ * t_suspend(). The script does not continue from the same
+ * point, but a separate route block is executed instead.
+ *
+ * Return value:
+ *     0  - success
+ *     <0 - failure
+ */
 int t_continue(unsigned int hash_index, unsigned int label,
                struct action *route)
 {