---
title: "Core functions"
description: "This section lists the all the functions exported by OpenSIPS core for script usage (to be used in opensips.cfg)"
---

This section lists the all the functions exported by **OpenSIPS** core for script usage (to be used in opensips.cfg)

## add_local_rport()

Add 'rport' parameter to the Via header generated by server (see RFC3581 for its meaning). It affects only the current processed request.

Example of usage:

```text
add_local_rport()
```

## assert(statement, [description])

Only works if [enable_asserts](https://docs.opensips.org/manual/3-6/script-coreparameters#memlog) is set to *true*. If the given expression evaluates to *false*, script execution is stopped and the [error_route](https://docs.opensips.org/manual/3-6/script-routes#error_route) is executed. If [abort_on_assert](https://docs.opensips.org/manual/3-6/script-coreparameters#dns_try_ipv6) is enabled, OpenSIPS will also shutdown.

Example of usage:
```text

    $var(i) = "1";
    $var(i) += "11";
    assert($var(i) == "111");

    $var(i) = 1;
    $var(i) += 11;
    assert($var(i) == 12);

    assert($ua != "friendly-scanner", "Forbidden UA: \"friendly-scanner\"");

```

## append_branch([uri], [qvalue])

> [!WARNING]
> TO BECOME OBSOLETE, replaced by [append_msg_branch()](#append_msg_branch).

Adds a new message branch, so it extends the destination set by a new entry. The difference is that current URI is taken as new entry.

Without parameter, the function copies the current URI into a new branch. Thus, leaving the main branch (the URI) for further manipulation.

With a parameter, the function copies the URI in the parameter into a new branch. Thus, the current URI is not manipulated.

Note that it's not possible to append a new branch in "on_failure_route" block if a 6XX response has been previously received (it would be against RFC 3261).

Parameters:
* *uri* (string, optional)
* *qvalue* (string, optional)

Example of usage:
```text

    # if someone calls B, the call should be forwarded to C too.
    #
    if ($rm=="INVITE" && $ru=~"sip:B@xx.xxx.xx ")
    {
        # copy the current branch (branches[0]) into
        # a new branch (branches[1])
        append_branch();
        # all URI manipulation functions work on branches[0]
        # thus, URI manipulation does not touch the 
        # appended branch (branches[1])
        seturi("sip:C@domain");
        
        # now: branch 0 = C@domain
        #      branch 1 = B@xx.xx.xx.xx
        
        # and if you need a third destination ...
        
        # copy the current branch (branches[0]) into
        # a new branch (branches[2])
        append_branch();
        
        # all URI manipulation functions work on branches[0]
        # thus, URI manipulation does not touch the 
        # appended branch (branches[1-2])
        seturi("sip:D@domain");
        
        # now: branch 0 = D@domain
        #      branch 1 = B@xx.xx.xx.xx
        #      branch 2 = C@domain
        
        t_relay();
        exit;
    };

    # You could also use append_branch("sip:C@domain") which adds a branch with the new URI:
    
    
    if(method=="INVITE" && uri=~"sip:B@xx.xxx.xx ") {
        # append a new branch with the second destination
        append_branch("sip:user@domain");
        # now: branch 0 = B@xx.xx.xx.xx
        # now: branch 1 = C@domain

        t_relay();
        exit;
}

```

## append_msg_branch(uri, [qvalue], [flags])

Adds a new message branch. The minimal information is the SIP URI of the branch. Optional, a q value may be provided.  

The "inherite" optional flag may dictate if the other branch properties (duri, q, path, socket, bflags) are to be inherited from the RURI branch or not. If not, all those properties will be NULL in the newly created branch (and this branch will have only a RURI field, nothing more).

## avp_print()

Prints the list with all the AVPs from memory. This is only a helper/debug function. 

## cache_store(storage_id, attribute, value, [timeout])

This sets in a memory-cache-like storage system a new value for an attribute. If the attribute does not already exist in the memcache, it will be inserted with the given value; if already present, its value will be replaced with the new one. The function may optionally take an extra parameter, a timeout (or lifetime) value for the attribute - after the lifetime is exceeded, the attribute is automatically purged from memcache.  If "timeout" is omitted or has a value or 0, the attribute/value pair will never expire.

Function returns true if the new attribute was successfully inserted.

Parameters:
* *storage_id* (string)
* *attribute* (string)
* *value* (string)
* *timeout* (int, optional)

```c

cache_store("local", "total_minutes_$fU", "$avp(mins)", 1200);

OR

modparam("cachedb_redis", "cachedb_url", "redis:cluster1://193.668.3.634:6379/")
...
cache_store("redis:cluster1", "passwd_$tu", "$var(x)");

```

More complex examples can be found in the [Key-Value Interface Tutorial](https://docs.opensips.org/tutorials-keyvalueinterface).

## cache_remove(storage_id, attribute)

This removes an attribute from a memory-cache-like storage system. Function returns false only if the *storage_id* is invalid.

Parameters:
* *storage_id* (string)
* *attribute* (string)

```c

cache_remove("local", "total_minutes_$fU");

OR

modparam("cachedb_redis", "cachedb_url", "redis:cluster1://193.668.3.634:6379/")
...
cache_remove("redis:cluster1", "total_minutes_$fU");

```

More complex examples can be found in the [Key-Value Interface Tutorial](https://docs.opensips.org/tutorials-keyvalueinterface).

## cache_fetch(storage_id, attribute, result)

Fetch the value of an attribute from a memory-cache-like storage system. On a successful fetch, the result will be stored in the variable specified by **result_pv**. 

Function returns *true* if the attribute was found and its value successfully returned.

Parameters:
* *storage_id* (string)
* *attribute* (string)
* *result_pv* (var)

```c

cache_fetch("local", "credit_$fU", $var(ret));

OR

modparam("cachedb_redis", "cachedb_url", "redis:cluster1://193.668.3.634:6379/")
...
cache_fetch("redis:cluster1", "credit_$fU", $var(ret));

```

More complex examples can be found in the [Key-Value Interface Tutorial](https://docs.opensips.org/tutorials-keyvalueinterface).

## cache_counter_fetch(storage_id, counter_attribute, result)

This function fetches from a memory-cache-like storage system the value of a counter. The result (if any) will be stored in the variable specified by **result**.

Function returns true if the attribute was found and its value returned.

Parameters:
* *storage_id* (string)
* *attribute* (string)
* *result* (var)

```c

cache_counter_fetch("local", "my_counter", $var(counter_val));

OR

modparam("cachedb_redis", "cachedb_url", "redis:cluster1://193.668.3.634:6379/")
...
cache_fetch("redis:cluster1", "my_counter", $var(redis_counter_val));

```

## cache_add( storage_id, attribute, increment, expire, [new_val])

This increments an attribute in a memory-cache-like storage system that supports such an operation. If the attribute does not exit, it will be created with the value of **increment**.

Function returns false if increment fails.

Parameters:
* *storage_id* (string)
* *attribute* (string)
* *increment* (int)
* *expire* (int) - if greater than 0, the key will also expire in the specified number of seconds
* *new_val* (var, optional) - variable in which to fetch the new value of the counter.

```c

modparam("cachedb_redis", "cachedb_url", "redis:cluster1://193.668.3.634:6379/")
...
cache_add("redis:cluster1", "my_counter", 5, 0);

```

More complex examples can be found in the [Key-Value Interface Tutorial](https://docs.opensips.org/tutorials-keyvalueinterface).

## cache_sub(storage_id, attribute, decrement, expire, [new_val])

This decrements an attribute in a memory-cache-like storage system that supports such an operation.

Function returns false if decrement fails.

Parameters:
* *storage_id* (string)
* *attribute* (string)
* *increment* (int)
* *expire* (int) - if greater than 0, the key will also expire in the specified number of seconds
* *new_val* (var, optional) - variable in which to fetch the new value of the counter.

```c

modparam("cachedb_redis", "cachedb_url", "redis:cluster1://193.668.3.634:6379/")
...
cache_sub("redis:cluster1", "my_counter", 5, 0);

```

More complex examples can be found in the [Key-Value Interface Tutorial](https://docs.opensips.org/tutorials-keyvalueinterface).

## cache_raw_query(storage_id, raw_query, result)

The function runs the provided raw query (in the back-end dependent language) and returns the results (if any) in the AVP (or AVP list) provided in *result*. This parameter may be missing, if the query returns no results.

Function returns false if query fails.

Parameters:
* *storage_id* (string)
* *raw_query* (string)
* *result* (string, optional, no expand)

```text

...
cache_raw_query("mongodb", "{ \"op\" : \"count\",\"query\": { \"username\" : $rU} }", "$avp(mongo_count_result)");
...

```

More complex examples can be found in the [Key-Value Interface Tutorial](https://docs.opensips.org/tutorials-keyvalueinterface).

## break()

Since v0.10.0-dev3, 'break' can no longer be used to stop the execution of a route. The only place to use is to end a 'case' block in a 'switch' statement. 'return' must be now used instead of old 'break'.

'return' and 'break' have now a similar meaning as in c/shell.

## construct_uri(proto,[user],domain,[port],[extra],result)
The function builds a valid sip uri based on the arguments it receives. The result (if any) will be stored in the **result** AVP variable.
If you want to omit a part of the sip uri, just omit the respective parameter.

Parameters:
* *proto* (string)
* *user* (string, optional)
* *domain* (string)
* *port* (string, optional)
* *extra* (string, optional)
* *result* (var)

Example usage:
```text

construct_uri("$var(proto)", "vlad", "$var(domain)", "", "$var(params)",$avp(s:newuri));
xlog("Constructed URI is <$avp(s:newuri)> \n");

```

## drop()

Stop the execution of the configuration script and alter the implicit action which is done afterwards.

If the function is called in a 'branch_route' then the branch is discarded (implicit action for 'branch_route' is to forward the request).

If the function is called in a 'onreply_route' then any provisional reply is discarded (implicit action for 'onreply_route' is to send the reply upstream according to Via header).

Example of usage:

```c
onreply_route {
if($rs=="183") {
drop();
}
}
```

## exit()

Stop the execution of the configuration script -- it has the same behaviour as return(0). It does not affect the implicit action to be taken after script execution. 

```bash
route {
if (route(2)) {
xlog("L_NOTICE","method $rm is INVITE\n");
} else {
xlog("L_NOTICE","method is $rm\n");
};
}
```

```c
route[2] {
if (is_method("INVITE")) {
return(1);
} else if (is_method("REGISTER")) {
return(-1);
} else if (is_method("MESSAGE")) {
sl_send_reply("403","IM not allowed");
exit;
};
}
```

## force_rport()
Force_rport() adds the rport parameter to the first Via header. Thus, **OpenSIPS** will add the received IP port to the top most via header in the SIP message, even if the client does not indicate support for rport. This enables subsequent SIP messages to return to the proper port later on in a SIP transaction.

The rport parameter is defined in RFC 3581.

Example of usage:

```text
force_rport();
```

## force_send_socket(proto:address[:port])

Force **OpenSIPS** to send the message from the specified socket (it _must_ be one of the sockets **OpenSIPS** listens on). If the protocol doesn't match (e.g. UDP message "forced" to a TCP socket) the closest socket of the same protocol is used.

Parameters:
* *socket* (string)

Example of usage:

```text
force_send_socket("tcp:10.10.10.10:5060");
```

## force_tcp_alias([port_alias])

Enables TCP connection reusage (RFC 5923) for the current TLS (or WSS, TCP, WS) connection (source IP + **source port** + transport), regardless if the Via header field contains an *";alias"* parameter or not. All backwards SIP requests, towards the same (source IP + **Via port** + transport) pair will be forced over this connection, for as long as it stays open. The main purpose of this function (and of RFC 5923) is to minimize the number of TLS connections a SIP proxy must set up, due to the significant CPU overhead of the TLS cipher negotiation phase.

Parameters:
* *port_alias* (int, optional)

  

> [!WARNING]
> Do not perform **force_tcp_alias()** for end-user initiated connections (who are most likely grouped by one or more public IPs), as this would create an open vector for call hijacking!

## forward(destination)

Forward the SIP request to the given destination in stateless mode. This has the format of [proto:]host[:port]. Host can be an IP or hostname; supported protocols are UDP, TCP and TLS. (For TLS, you need to compile the TLS support into core).
If proto or port are not specified, NAPTR and SRV lookups will be used to determine them (if possible).

Parameters:
* *destination* (string, optional) - if missing, the forward will be done based on RURI.

Example of usage:

```text
forward("10.0.0.10:5060");
#or
forward();
```

## get_timestamp(sec_avp,usec_avp)

Returns the current timestamp, seconds and microseconds of the current second, from a single system call.

Parameters:
* *sec_avp* (var)
* *usec_avp* (var)

Example of usage:

```text
get_timestamp($avp(sec),$avp(usec));
```

## isdsturiset()

Test if the dst_uri field (next hop address) is set.

Example of usage:

```text
if(isdsturiset()) {
log("dst_uri is set\n");
};
```

## isflagset(string)

Test if a flag is set for currently processed message.

For more see [Flags Documentation](Script-Flags.md).

Parameters:
* *flag* (string, static)

Example of usage:

```text

    if (isflagset("NAT_PING"))
        log("flag NAT_PING is set\n");

```

## isbflagset(flag, [branch_idx])

Test if a flag is set for a specific branch. "branch_idx" identifies the branch for which the flags are tested - it must be a positive number. Branch index 0 refers to the RURI branch. If this parameter is missing, 0 branch index is used as default.

For more about script flags, see [Flags Documentation](Script-Flags.md).

Parameters:
* *flag* (string, static)
* *branch_idx* (int, optional)

Example of usage:

```text

    if (isbflagset(1, "NAT_PING"))
        log("flag NAT_PING is set in branch 1\n");

```

## is_myself(host, [port])

Test if the host and optionally the port represent one of the addresses that OpenSIPS listens on. This checks the list of local IP addresses, hostnames and aliases that have been set in the OpenSIPS configuration file.

Parameters:
* host (string)
* port (int, optional)

Example of usage:

```bash
if (is_myself($rd, $rp)
xlog("the request is for local processing\n");
```

## log([level,] string)

Write text message to standard error terminal or syslog. You can specify the log level as first parameter.

Example of usage:

```text
log("just some text message\n");
```

## move_branch([src_idx], [dst_idx] [, keep])

Moves the whole information attached to the **src_idx** branch to the **dst_idx** branch. Both **src_idx** and **dst_idx** should be an integer value and should represent a valid branch index. If they are not provided, or have a negative value, the main/message branch is considered.
By default, the function removes the **src_idx** branch after moving it, and shifts all the remaining branches after it. If, however, the third parameter of the function is the **keep** string, the branch is not removed, and only copied to the **dst_idx** branch.

## next_branches()

Adds to the request a new destination set that includes all highest priority class contacts ('q' value based) from the serialized branches (see serialize_branches()). If called from a route block, it rewrites the request uri with first contact and adds the remaining contacts as parallel branches.  If called from failure route block, adds all contacts as parallel branches.  All used contacts are removes the serialized branches.

Returns true if at least one contact was added for the request's destination set - returns 1 if other branches are still pending and return 2 if no other branches are left for future processing - shortly, if 2: this is the last branch, if 1: other will follow. False is return is nothing was done (no more serialized branches).

Example of usage:

```text
next_branches();
```

## prefix(str)

Add the string parameter in front of username in R-URI.

Parameters:
* *str* (string)

Example of usage:

```text
prefix("00");
```

## pv_printf(pv, fmt_str)

Prints the formatted string 'fmt_str' in the AVP 'pv'. The 'fmt_str' parameter can include any pseudo-variable defined in **OpenSIPS**. The 'pv' can be any writable pseudo-variable -- e.g.,: AVPs, VARs, `$ru`, `$rU`, `$rd`, `$du`, `$br`, `$fs.`

Parameters:
* *pv* (var)
* *string* (string)

Example of usage:

```text
pv_printf($var(x), "r-uri: $ru");
pv_printf($avp(i:3), "from uri: $fu");
```

## raise_event(event, [attrs], [vals])

Raises from script an event through OpenSIPS Event Interface.

This function triggers an event for all subscribers for that event, regardless the transport module used.

Parameters:
* *event* (string) - the name of the event which should be raised
* *attrs* (var, optional) - AVP containing the the names of the attributes; if this parameter is missing and *vals* is provided, the attributes will be written as array(positional) params in the JSON-RPC payload
* *vals* (var, optional) - AVP containing values attached to the event; if this parameter is missing, the raised event will not have any attributes, even if the *attrs* parameter is provided.

Example of usage (raises an event with no attributes):

```text

raise_event("E_NO_PARAM");

```

Example of usage (raises an event with two attributes):

```text

$avp(attr-name) = "param1";
$avp(attr-name) = "param2";
$avp(attr-val) = 1;
$avp(attr-val) = "2";
raise_event("E_TWO_PARAMS", $avp(attr-name), $avp(attr-val));

```

Example of usage (raises an event with two unnamed attributes):

```text

$avp(attr-val) = 1;
$avp(attr-val) = "2";
raise_event("E_TWO_PARAMS", , $avp(attr-val));

```

## remove_msg_branch(branch_idx)

Removes a given branch.
Once a branch is removed, all the subsequent branches are shifted (i.e. if branch n is removed, then the old n+1 branch becomes the new n branch, the old n+2 branch becomes n+1 and so on).

Parameters:
* *branch_idx* (int)

Example of usage (remove all branches with URI hostname "127.0.0.1"):

```bash

$var(i) = 0;
while ($(branch(uri)[$var(i)]) != null) {
   xlog("L_INFO","$$(branch(uri)[$var(i)])=[$(branch(uri)[$var(i)])]\n");
   if ($(branch(uri)[$var(i)]{uri.host}) == "127.0.0.1") {
       xlog("L_INFO","removing branch $var(i) with URI=[$(branch(uri)[$var(i)])]\n");
       remove_msg_branch($var(i));
   } else {
       $var(i) = $var(i) + 1;
   }
}

```

## return(int)

The return() function allows you to return any integer value from a called route() block.
You can test the value returned by a route using "`$retcode`" variable.

return(0) is same as "exit()";

In bool expressions:

  * Negative and ZERO is FALSE
  * Positive is TRUE

Example usage: 

```text

route {
  if (route(2)) {
    xlog("L_NOTICE","method $rm is INVITE\n");
  } else {
    xlog("L_NOTICE","method $rm is REGISTER\n");
  };
}

```
```c

route[2] {
  if (is_method("INVITE")) {
    return(1);
  } else if (is_method("REGISTER")) {
    return(-1);
  } else {
    return(0);
  };
}

```

## resetdsturi()

Set the value of dst_uri filed to NULL. dst_uri field is usually set after loose_route() or lookup("location") if the contact address is behind a NAT.

Example of usage:

```text
resetdsturi();
```

## resetflag(flag)

Reset a flag for currently processed message (unset its value).

For more see [Flags Documentation](Script-Flags.md).

Parameters:
* *flags* (string, static)

Example of usage:

```text

    resetflag("NAT_PING");

```

## resetbflag(flag, [branch_idx])

Reset a flag for a specific branch (unset its value). "branch_idx" identifies the branch for which the flag is reset - it must be a positive number. Branch index 0 refers to the RURI branch. If this parameter is missing, 0 branch index is used as default.

Parameters:
* *flag* (string, static)
* *branch_idx* (int, optional)

For more about script flags, see [Flags Documentation](Script-Flags.md).

Example of usage:
```text

    resetbflag(1, "NAT_PING");
    # or
    resetbflag("NAT_PING"); # same as resetbflag(0, "NAT_PING")

```

## revert_uri()

Set the R-URI to the value of the R-URI as it was when the request was received by server (undo all changes of R-URI).

Example of usage:

```text
revert_uri();
```

## set_via_handling(flags)

Rewrite the domain part of the R-URI with the value of function's parameter. Other parts of the R-URI like username, port and URI parameters remain unchanged.

Parameters:
* *flags* (string) - a comma separated list of named flags
  * `force-rport` - adds the rport parameter to the first Via header; thus, **OpenSIPS** will add the received IP port to the top most via header in the SIP message, even if the client does not indicate support for rport. This enables subsequent SIP messages to return to the proper port later on in a SIP transaction.
  * `add-local-rport `- add 'rport' parameter to the Via header generated by server (see RFC3581 for its meaning); it affects only the current processed request.
  * `reply-to-via` - routes back the repies to the IP:port from the top VIA instead of the src IP:port of the requests
  * `force-tcp-alias` - see [force_tcp_alias()](#force_tcp_alias) function

Example of usage:

```text
set_via_handling("force-rport,reply-to-via");
```

## sethost(host)

Rewrite the domain part of the R-URI with the value of function's parameter. Other parts of the R-URI like username, port and URI parameters remain unchanged.

Parameters:
* *host* (string)

Example of usage:

```text
sethost("1.3.6.4");
```

## sethostport(hostport)

Rewrite the domain part and port of the R-URI with the value of function's parameter. Other parts of the R-URI like username and URI parameters remain unchanged.

Parameters:
* *hostport* (string)

Example of usage:

```text
sethostport("1.3.6.4:5080");
```

## setuser(user)

Rewrite the user part of the R-URI with the value of function's parameter.

Parameters:
* *user* (string)

Example of usage:

```text
setuser("newuser");
```

## setuserpass(pass)

Rewrite the password part of the R-URI with the value of function's parameter.

Parameters:
* *pass* (string)

Example of usage:

```text
setuserpass("my_secret_passwd");
```

## setport(port)

Rewrites/sets the port part of the R-URI with the value of function's parameter.

Parameters:
* *port* (string)

Example of usage:

```text
setport("5070");
```

## seturi(str)

Rewrite the request URI.

Parameters:
* *uri* (string)

Example of usage:

```text
seturi("sip:test@opensips.org");
```

## route(name [, param1 [, param2 [, ...] ] ] )

This function is used to run the code from the 'name' route, declared in the script. Optionally, it can receive several parameters (up to 7), that can be later retrieved using the '`$param(idx)`' pseudo-variable.

The name of the route is an identifier format, whereas the parameters can be either int, string, or a pseudo-variable.

Example of usage:

```text
route(HANDLE_SEQUENTIALS);
route(HANDLE_SEQUENTIALS, 1, "param", $var(param));
```

## script_trace([log_level, pv_format_string, [info]])

This function start the script tracing - this helps to better understand the flow of execution in the OpenSIPS script, like what function is executed, what line it is, etc. Moreover, you can also trace the values of pseudo-variables, as script execution progresses.

The blocks of the script where script tracing is enabled will print a line for each individual action that is done (e.g. assignments, conditional tests, module functions, core functions, etc.). Multiple pseudo-variables can be monitored by specifying a **pv_format_string** (e.g. "`$ru`---`$avp(var1)`").

The logs produced by multiple/different traced regions of your script can be differentiated (tagged) by specifying an additional plain string - **info_string** - as the 3rd parameter.

To disable script tracing, just do script_trace(). Otherwise, the tracing will automatically stop at the end the end of the top route.

Parameters:
* *log_level* (int, optional)
* *pv_format_string* (string, optional)
* *info* (string, static, optional)

Example of usage:
```text
script_trace( 1, "$rm from $si, ruri=$ru", "me");
```

will produce:
```text

    [line 578][me][module consume_credentials] -> (INVITE from 127.0.0.1 , ruri=sip:111211@opensips.org)
    [line 581][me][core setbflag] -> (INVITE from 127.0.0.1 , ruri=sip:111211@opensips.org)
    [line 583][me][assign equal] -> (INVITE from 127.0.0.1 , ruri=sip:111211@opensips.org)
    [line 592][me][core if] -> (INVITE from 127.0.0.1 , ruri=sip:tester@opensips.org)
    [line 585][me][module is_avp_set] -> (INVITE from 127.0.0.1 , ruri=sip:tester@opensips.org)
    [line 589][me][core if] -> (INVITE from 127.0.0.1 , ruri=sip:tester@opensips.org)
    [line 586][me][module is_method] -> (INVITE from 127.0.0.1 , ruri=sip:tester@opensips.org)
    [line 587][me][module trace_dialog] -> (INVITE 127.0.0.1 , ruri=sip:tester@opensips.org)
    [line 590][me][core setflag] -> (INVITE from 127.0.0.1 , ruri=sip:tester@opensips.org) 

```

## send(destination [, headers])

Send the original SIP message to a specific destination in stateless mode. This is definied as [proto:]host[:port]. No changes are applied to received message, no Via header is added, unless headers parameter is specified. Host can be an IP or hostname; supported protocols are UDP, TCP and TLS. (For TLS, you need to compile the TLS support into core). If proto or port are not specified, NAPTR and SRV lookups will be used to determine them (if possible). The headers parameter should end in '\r\n'.

Parameters:
* *destination* (string)
* *headers* (string, optional)

Example of usage:

```text
send("udp:10.10.10.10:5070");
send("udp:10.10.10.10:5070", "Server: opensips\r\n");
```

## serialize_branches(clear_previous[, keep_order])

Takes all currently added branches for parallel forking (e.g. with lookup() or append_branch()), as well as the current branch (R-URI (`$ru`) / outbound Proxy (`$du`) / q value (`$ru_q`) / branch flags / forced Path headers / forced send socket), and prepares them for serial forking instead. The ordering is done in decreasing "q" order. The serialized branches are internally stored in the "`$avp(serial_branch)`" AVP - this allows them to be manipulated by the "next_branches()" function, usually within a failure route.

  

NOTE that (according to RFC3261), the branches with the same "q" value will still be parallel forked during a certain step in the serial forking (it will result a combination of serial with parallel forking). In other words, this function will clear all added branches and keep re-adding them as long as they have identical highest "q" values, while throwing all other "lower-than-highest q" branches in the "`$avp(serial_branch)`". A similar grouping process takes place during each "next_branches()" function call.

  

NOTE that this function is not altering the current branch (R-URI, outbound proxy, etc.) - it is just preparing a serial forking set with the above-mentioned branches. You may need to call "next_branches()" immediately after calling this function, see the example below.

Parameters:
* *clear_previous* (int) - if set to non-zero, all previous results of another "serialize_branches()" (serial forking set which is no longer needed) will be deleted before starting a new set
* *keep_order* (int, optional) - if set to non-zero, the added branches as well as the current branch, will be serialized exactly in the order in which they are found.

Example of usage:

```text

    if (!lookup("location")) {
        t_reply("480", "Temporarily Unavailable");
        exit;
    }

    serialize_branches(1);
    next_branches(); # Pop the R-URI from the serialized branches set

```

## set_advertised_address(adv_addr)

Same as 'advertised_address' but it affects only the current message. It has priority if 'advertised_address' is also set.

Parameters:
* *adv_addr* (string)

Example of usage:

```text
set_advertised_address("opensips.org");
```

## set_advertised_port(adv_port)

Same as 'advertised_port' but it affects only the current message. It has priority over 'advertised_port'.

Parameters:
* *adv_port* (string)

Example of usage:

```text
set_advertised_port("5080");
```

## setdsturi(uri)

Explicitely set the dst_uri field to the value of the paramater. The parameter has to be a valid SIP URI.

Parameters:
* *uri* (string)

Example of usage:

```text
setdsturi("sip:10.10.10.10:5090");
```

## setflag(flag)

Set a flag for currently processed message. The flags are used to mark the message for special processing (e.g. pinging NAT'ed contacts, TCP connect behavior, etc.) or to keep some state (e.g. message authenticated). The OpenSIPS script supports, at most, 32 unique string flags.

Parameters:
* *flag* (string, static)

Example of usage:

```text

    setflag("NAT_PING");

```

## setbflag(flag, [branch_idx])

Set a flag for a specific branch. "branch_idx" identifies the branch for which the flag is set - it must be a positive number. Branch index 0 refers to the RURI branch. If this parameter is missing, 0 branch index is used as default.  The OpenSIPS script supports, at most, 32 unique string branch flags.

For more about script flags, see [Flags Documentation](Script-Flags.md).

Parameters:
* *flag* (string, static)
* *branch_idx* (int, optional)

Example of usage:

```text

    setbflag(1, "NAT_PING");
    # or
    setbflag("NAT_PING"); # same as setbflag(0, "NAT_PING")

```

## sr_check_status( group, [identifier])

Function to check the status of an 'status/report' identifier. Such checking is very useful for determining at script level the readiness of a module or core component (if able to provide its full functionality).

Parameters:
* *group* (string), the name of the 'status/report' group (the group exported by the OpenSIPS core is named "core", while the modules may export groups with their names.
* *identifier* (string, optional), the name of the identifier to be checked (what are the available identifiers, it depends on the party exporting the group). Possible values for this identifier are:
  * (1) name of an identifier
  * (2) NULL, to refer to the default (per group) identifier (converted internally into "main" identifier
  * (3) "all" to refer to all the identifiers in the group

The returned value, depending on the provided identifier value, may be:
* (1) the status of the given identifier
* (2) the status of the "main" identifier
* (3) the aggregated status over all identifiers, as -1 (if at least of identifier has a negative status) or 1 (if all identifiers have a positive status)

Example of usage:

```text

    # check if the "pstn" identifier (the "pstn" partition) from "drouting" module is ready (data is fully loaded)
    if (st_check_status( "drouting", "pstn") ) {}

    # check if the all identifiers (all partitions) from "drouting" module are ready (data is fully loaded)
    if (st_check_status( "drouting", "all") ) {}
    

```

## strip(n)

Strip the first N-th characters from username of R-URI (N is the value of the parameter).

Parameters:
* *n* (int)

Example of usage:

```text

    strip(3);

```

## strip_tail(n)

Strip the last N-th characters from username of R-URI (N is the value of the parameter).

Parameters:
* *n* (int)

Example of usage:

```text
strip_tail(3);
```

## subscribe_event(string, string [, int])

Subscribes an external application for a certain event for the OpenSIPS Event Interface. This is used for transport protocols that cannot subscribe by themselves (example event_rabbitmq). This function should be called only once in the startup_route if the subscription doesn't expire, or in a timer route if the subscription should be renewed once in a while.

Parameters:
* *event* (string) - the name of the event an external application should be notified for.
* *socket* (string) - the socket of the external application. Note that this socket should follow the syntax of an existing loaded Event Interface transport module (example: event_datagram, event_rabbitmq).
* *expire* (int, optional) - the expire time of the subscription. If it is not present, then the subscription does not expire at all.

Example of usage (subscriber that never expires, notified by the RabbitMQ module):

```c

startup_route {
    subscribe_event("E_PIKE_BLOCKED", "rabbitmq:127.0.0.1/pike");
}

```

Example of usage (subscriber expires every 5 seconds, notified through UDP):

```c

timer_route[event_subscribe, 4] {
    subscribe_event("E_PIKE_BLOCKED", "udp:127.0.0.1:5051", 5);
}

```

## swap_branches([br1_idx], [br2_idx])

Swaps the information between two branches, represented by the **br1_idx** and **br2_idx**. Both values should be an integer value and should represent a valid branch index. If they are not provided, or have a negative value, the main/message branch is considered.

## use_blacklist(bl_name)

Enables the DNS blacklist name received as parameter. Its primary purposes will be to prevent sending requests to critical IPs (like GWs) due DNS or to avoid sending to destinations that are known to be unavailable (temporary or permanent).

Parameters:
* *bl_name* (string)

```text

    use_blacklist("pstn-gws");

```

## unuse_blacklist(bl_name)

Disables the DNS blacklist name received as parameter.

Parameters:
* *bl_name* (string)

```text

    unuse_blacklist("pstn-gws");

```

## check_blacklist_rule([bl_name], ip[, port [, proto]])

Checks whether a specific proto:ip:port+pattern matches a blacklist, or all if *bl_name* is not specified.

Parameters:
* *bl_name* (string, optional) - if missing, the rule is matched against all used blacklists
* *ip* (string) - the IP to check against
* *port* (integer, optional) - the port to check against; if missing, 0 is considered, which will match only 0-port rules
* *proto* (string, optional) - the protocol to check against, or "any" if any protocol should be checked; if missing, "any" is considered, which will match only any proto rules
* *pattern* (string, optional) - the pattern to check against

```text

    if (check_blacklist("pstn-gws", $dd, $dp, $dP))
        xlog("REQUEST will be blocked\n");

```

## add_blacklist_rule([bl_name], ip[, port [, proto [, expire]]])

Adds a proto:ip:port+pattern rule to a blacklist.

Parameters:
* *bl_name* (string) - the blacklist to add the rule to
* *ip* (string) - the IP to add; if the IP starts with '!', the entire rule is negated
* *port* (integer, optional) - the port to add; if missing, 0/any port is used
* *proto* (string, optional) - the protocol to add, or "any" for any protocol; if missing, "any" is used
* *pattern* (string, optional) - the pattern to add
* *expire* (integer, optional) - if specified, provides the expiration time in seconds for the rule

```text

    add_blacklist_rule("filter", $si, $sp, "udp");

```

## del_blacklist_rule([bl_name], ip[, port [, proto]])

Removes a proto:ip:port+pattern rule from a blacklist.

Parameters:
* *bl_name* (string) - the blacklist to remove the rule from
* *ip* (string) - the IP to remove; if the IP starts with '!', the entire rule is negated
* *port* (integer, optional) - the port to remove; if missing, 0/any port is used
* *proto* (string, optional) - the protocol to remove, or "any" for any protocol; if missing, "any" is used
* *pattern* (string, optional) - the pattern to remove

```text

    del_blacklist_rule("filter", $si, $sp, "udp");

```

## xlog([log_level, ]format_string)

Allows various debugging / runtime / critical messages to be printed as the execution of the OpenSIPS script is done. All pseudo-variables included in the *format_string* parameter will be expanded. There are several optional logging levels which can be specified. They work in accordance with the severity levels of syslog. The levels are named as follows:

* L_ALERT (-3)
* L_CRIT (-2)
* L_ERR (-1) - this is used by default if log_level is omitted
* L_WARN (1)
* L_NOTICE (2)
* L_INFO (3)
* L_DBG (4)

  

```text

    # a few xlog scripting examples
    xlog("Received $rm from $fu (callid: $ci)\n");
    xlog("L_ERR", "key $var(username) not found in cache!\n");

```
