Login | Register

Documentation

Documentation -> Development Manual -> RR Module API

This page has been visited 228 times.



RR Module API

The RR ( Record Route ) module API is exported by the modules/rr/api.h file.
From a general functionality point of view, the RR module is the one responsible for controlling the Record-Route part for requests, and then routing the sequential requests based on the Route headers. The RR module is the simplest module that provides very simple dialog-aware functionality, by allowing the storage of information ( parameters ) in the Record-Route headers, which can be later retrieved from the Route headers.
First, you will have to bind to the RR module's API and get the structure which you will further use. The binding function is :

/*
Parameters : rrb is the API output to be further used

Returns : 0 in case of success and -1 in case of failure
*/

inline static int load_rr_api( struct rr_binds *rrb );

The rr_binds structure is exemplified below :

struct rr_binds {
        add_rr_param_t      add_rr_param;
        check_route_param_t check_route_param;
        is_direction_t      is_direction;
        get_route_param_t   get_route_param;
        register_rrcb_t     register_rrcb;
        get_remote_target_t get_remote_target;
        get_route_set_t     get_route_set;
        /* whether or not the append_fromtag parameter is enabled in the RR module */
        int                 append_fromtag;
        /* the number of routes removed within the loose routing process */
        int*                removed_routes;
        /* the type of routing done, when comparing the previous and the next hop
        Both can be either strict or loose routers, thus here we have 4 different options :
        ROUTING_LL - loose to loose routing
        ROUTING_SL - strict to loose routing
        ROUTING_SS - strict to strict routing
        ROUTING_LS - loose to strict routing
        */

        int*                routing_type;

        loose_route_t       loose_route;
        record_route_t      record_route;
};


Find below the API function signatures along with their usage :

/* Adds a parameter to the requests's Record-Route URI. The API supports the use case
   where the Record-Routed header will be further added.
   The function is to be used for marking certain dialogs that can
   be identified from the sequential requests - since the Route
   headers in the sequential requests will also contain our added
   params, which we'll be able to fetch with get_route_param ( see below )

   The function returns 0 on success. Otherwise, -1 is returned.

   Parameters :
     * struct sip_msg* msg - request that will has the parameter
       “param” added to its Record-Route header.
     * str* param - parameter to be added to the Record-Route
       header - it must be in “;name=value” format.
*/

typedef  int (*add_rr_param_t)(struct sip_msg* msg, str* param);


/*    The function checks for the request “msg” if the URI parameters
   of the local Route header (corresponding to the local server)
   matches the given regular expression “re”. It MUST be call
   after the loose_route was done.

   The function returns 0 on success. Otherwise, -1 is returned.

   * struct sip_msg* msg - request that will has the Route
       header parameters checked.
   * regex_t* re - compiled regular expression to be checked
       against the Route header parameters.
*/

int (*check_route_param_t)(struct sip_msg* msg, regex_t* rem);


/*    The function checks the flow direction of the request “msg”. As
   for checking it's used the “ftag” Route header parameter, the
   append_fromtag (see Section 1.4.1, “append_fromtag (integer)”
   module parameter must be enables. Also this must be call only
   after the loose_route is done.

   The function returns 0 if the “dir” is the same with the
   request's flow direction. Otherwise, -1 is returned.

   Meaning of the parameters is as follows:
     * struct sip_msg* msg - request that will have the direction
       checked.
     * int direction - direction to be checked against. It may be
       RR_FLOW_UPSTREAM ( from callee to caller ) or
       RR_FLOW_DOWNSTREAM ( from caller to callee ).
*/

typedef  int (*is_direction_t)(struct sip_msg* msg, int direction);


/*
   The function search in to the “msg”'s Route header parameters
   the parameter called “name” and returns its value into “val”.
   It must be call only after the loose_route is done.

   The function returns 0 if parameter was found (even if it has
   no value). Otherwise, -1 is returned.

   Meaning of the parameters is as follows:
     * struct sip_msg* msg - request that will have the Route
       header parameter searched.
     * str *name - contains the Route header parameter to be
       serached.
     * str *val - returns the value of the searched Route header
       parameter if found. It might be empty string if the
       parameter had no value.
*/

typedef  int (*get_route_param_t)(struct sip_msg*, str*, str*);


/*
   The function register a new callback (along with its
   parameter). The callback will be called when a loose route will
   succesfully be performed for the local address.

   The function returns 0 on success. Otherwise, -1 is returned.

    Meaning of the parameters is as follows:
     * rr_cb_t func - callback function to be registered.
     * void *param - parameter to be passed to the callback
       function.
     * short prior - parameter to set the priority. The callbacks
        will be executed in order from small to big priority - thus
        to be used for ordering callbacks that depend on each other.

*/

typedef int (*register_rrcb_t)( rr_cb_t func, void *param, short prior);


/* Function to be registered as callback within the RR API :
     * struct sip_msg* req - request that is currently being processed
     * str *rr_param - the parameters in our server's Route header
     * str *param - the custom parameter provided at the callback registration
*/

typedef void (rr_cb_t) (struct sip_msg* req, str *rr_param, void *param);


/*
   Function used to fetch the far-end remote target for the current message.
   Depending on the type routing done ( see the '''routing_type''' API member )
   the remote target can be either in the initial Request URI, in the current
   Request-URI or in the last route header. The API function take care to
   correctly identify which scenario is correct.
   The API function MUST be called after loose_route() was called.

   The function returns the str pointer with the remote target, or NULL in case of error.

   Meaning of the parameters is as follows:
        -* struct sip_msg* msg - request that the remote target will be extracted from
*/

typedef  str* (*get_remote_target_t)(struct sip_msg* msg);


/*
    Function used to fetch the route set from the current SIP message.
    The function takes into account the actual loose_route() done, and properly discards
    the proxy's own Route headers from the SIP message. Thus, the function must be called
    after loose_route() was done.

    The function will return an array of str structures, or NULL in case of error. The
    nr_routes parameter will indicate the size of the returned array

    Meaning of the parameters is as follows:
        -* struct sip_msg* msg - request that the remote target will be extracted from
        -* int* nr_routes - the size of the returned array
*/

typedef  str* (*get_route_set_t)(struct sip_msg*,int *nr_routes);


/*
    Function to be used when for routing a request according to the Route headers present
    in it and to the type of Routing ( loose vs strict ) that needs to be used.

    The function will return 0 in case of success ( request is succesfully routed ). Otherwise,
    -1 is returned.

   Meaning of the parameters is as follows:
        -* struct sip_msg* msg - request to be routed

*/

typedef  int (*loose_route_t)(struct sip_msg* msg);


/*
    Function to be used when record-routing an initial request. The function will add
    one or two Record-Route headers , depending if there are any interface changes and
    if r2 is enabled. Also, if any parameters are provided, they will be added to all the
    Record-Route headers that the function internally adds.

    Returns 0 in case of success. Otherwise, -1 will be returned.

    Meaning of the parameters is as follows:
        -* struct sip_msg* msg - request to be record routed
        -* str* params - parameters to be added to the Record-Route headers
*/

typedef  int (*record_route_t)(struct sip_msg* msg, str* params);
 


See below an example of binding to the RR API from another module, registering a callback and then checking the direction of the sequential request and also checking for the existence of a certain parameter.

...
#include "../rr/api.h"
...
struct rr_binds my_rrb;
...
...
int mod_init(void) {
        ...
        ...
        /* load the RR API */
        if (load_rr_api( &my_rrb )!=0) {
            LM_ERR("can't load RR API\n");
            goto error;
        }

        if (!my_rrb.append_fromtag) {
            LM_ERR("The append_fromtag parameter is not set, but we need it for detecting the direction of requests \n");
            goto error;
        }
        ...
        ...
        /* register a RR callback */
        if (my_rrb.register_rrcb(my_callback,0,0))!=0) {
            LM_ERR("can't register RR callback\n");
            goto error;
        }
        ...
        ...
}

void my_callback(struct sip_msg* msg,str* rr_param,void *param)
{
        str name = str_init("ftag");
        str val;

        LM_INFO("Received a new sequential request from %s\n",
        my_rrb.is_direction( msg, RR_FLOW_UPSTREAM)?"callee":"caller");

        if (my_rrb.get_route_param(msg,&name,&val) == 0) {
                LM_INFO("We have the ftag parameter with value [%.*s]\n",val.len,val.s);
        }
}

Page last modified on May 31, 2024, at 09:59 AM