# &adminguide;

## Overview

This modules implements a dispatcher for destination addresses. It computes hashes over various parts of the request and selects an address from a destination set. The selected address is then used as outbound proxy.

The module can be used as a stateless load balancer, having no guarantee of fair distribution.

For the distribution algorithm, the module allows the definition of weights for the destination. This is useful in order to get a different ratio of traffic between destinations.

Since version 2.1 the dispatcher module keeps its destination sets into different partitions. Each partition is described by its own db_url, table_name, dst_avp, grp_avp, cnt_avp, sock_avp, attr_avp and blacklists. Setting any of this parameters using modparam will alter the default partition's properties. In order to create a new partition the "partition" parameter should be used (see below for more details). If none of the 8 partition specific parameters are defined for the default partition, then this partition will not be created. If the default partition is created each undefined parameter from all other partitions will take the value of the corresponding one from the default partition. If there is no default partition, the default value specified in the parameter's description will be used. Functions taking set arguments will now take a set number preceded by a partition name and colon(i.e "part_name: 5"). If a set is not preceded by any partition name the default partition will be used. Thus, the following arguments are equivalent: "default : 4" vs "4". Remember that in order to be able to use a table from a partition, its name must be found in the "version" table belonging to the database defined in the partition's db_url. Also, in version 2.1 the "flags" parameter has been moved to ds_select_dst() and ds_select_domain() along with "force_dst" and "use_default" flags.

## Dependencies

### &osips; modules

The following modules must be loaded before this module:

- TM - only if active recovery of failed hosts is required.

### External libraries or applications

The following libraries or applications must be installed before running &osips; with this module:

- none.

## Exported Parameters

### `db_url` (string)

Database where to load the destinations from. Setting this parameter will only change the default partition's db_url. Use the partition parameter to create and alter other partitions.

NOTE: if you intend to use the default partition you have to explicity set this default db_url, otherwise OpenSIPS will not start (he value of global default db_url is not inherited here! ).

Default value is NULL. At least one db_url should be defined for the dispatcher module to work.

#### Set the 'default' partition'sdb_url parameter

    ...
    modparam("dispatcher", "db_url", "mysql://user:passwb@localhost/database")
    ...

### `attrs_avp` (str)

The name of the avp to contain the attributes string of the current destination. When a destination is selected, automatically, this AVP will provide the attributes string - this is an opaque string (from OpenSIPS point of view) : it is loaded from destination definition ( via DB) and blindly provided in the script. Setting this parameter will only change the default partition's attrs_avp. Use the partition parameter to create and alter other partitions.

Default value is null - don't provide ATTRIBUTEs.

#### Set the 'default' partition's attrs_avp parameter

    ...
    modparam("dispatcher", "attrs_avp", "$avp(272)")
    ...

### `hash_pvar` (str)

String with PVs used for the hashing algorithm 7.

You must set this parameter if you want do hashing over custom message parts.

Default value is null - disabled.

#### Use $avp(273) for hashing:

    ...
    modparam("dispatcher", "hash_pvar", "$avp(273)")
    ...

#### Use combination of PVs for hashing:

    ...
    modparam("dispatcher", "hash_pvar", "hash the $fU@$ci")
    ...

### `setid_pvar` (str)

The name of the PV where to store the set ID (group ID) when calling ds_is_in_list() without group parameter (third parameter).

Default value is null - don't set PV.

#### Set the setid_pvar parameter

    ...
    modparam("dispatcher", "setid_pvar", "$var(setid)")
    ...

### `ds_ping_method` (string)

With this Method you can define, with which method you want to probe the failed gateways. This method is only available, if compiled with the probing of failed gateways enabled.

Default value is OPTIONS.

#### Set the ds_ping_method parameter

    ...
    modparam("dispatcher", "ds_ping_method", "INFO")
    ...

### `ds_ping_from` (string)

With this Method you can define the "From:"-Line for the request, sent to the failed gateways. This method is only available, if compiled with the probing of failed gateways enabled.

Default value is sip:dispatcher@localhost.

#### Set the ds_ping_from parameter

    ...
    modparam("dispatcher", "ds_ping_from", "sip:proxy@sip.somehost.com")
    ...

### `ds_ping_interval` (int)

With this Method you can define the interval for sending a request to a failed gateway. This parameter is only used, when the TM-Module is loaded. If set to 0, the pinging of failed requests is disabled.

Default value is 0 (disabled).

#### Set the ds_ping_interval parameter

    ...
    modparam("dispatcher", "ds_ping_interval", 30)
    ...

### `ds_probing_sock` (str)

A socket description [proto:]host[:port] of the local socket (which is used by OpenSIPS for SIP traffic) to be used (if multiple) for sending the probing messages from.

Default value is NULL(none).

#### Set the ds_probing_sock parameter

    ...
    modparam("dispatcher", "ds_probing_sock", "udp:192.168.1.100:5077")
    ...

### `ds_probing_threshhold` (int)

If you want to set a gateway into probing mode, you will need a specific number of requests until it will change from "active" to probing. The number of attempts can be set with this parameter.

Default value is 3.

#### Set the ds_probing_threshhold parameter

    ...
    modparam("dispatcher", "ds_probing_threshhold", 10)
    ...

### `ds_probing_mode` (int)

Controls what gateways are tested to see if they are reachable. If set to 0, only the gateways with state PROBING are tested, if set to 1, all gateways are tested. If set to 1 and the response is 408 (timeout), an active gateway is set to PROBING state.

Default value is 0.

#### Set the ds_probing_mode parameter

    ...
    modparam("dispatcher", "ds_probing_mode", 1)
    ...

### `ds_probing_list` (str)

Defines a list of one or more setids that limits which destinations are probed if probing is active. This is useful when multiple proxies share the same dispatcher table, but you want to limit which ones are responsible for probing specific destinations.

Default value is NULL(none).

#### Set the ds_probing_list parameter

    ...
    modparam("dispatcher", "ds_probing_list", "1,2,3")
    ...

### `ds_define_blacklist` (str)

Defines a blacklist based on a dispatching setid from the 'default' partition. This list will contain the IPs (no port, all protocols) of the destinations matching the given setid. Use the 'partition' parameter if you want to define blacklists based on other partitions' sets.

Multiple instances of this param are allowed.

Default value is NULL.

#### Set the 'default' partition's ds_define_blacklist parameter

    ...
    modparam("dispatcher", "ds_define_blacklist", "list= 1,4,3")
    modparam("dispatcher", "ds_define_blacklist", "blist2= 2,10,6")
    ...

### `options_reply_codes` (str)

This parameter must contain a list of SIP reply codes separated by comma. The codes defined here will be considered as valid reply codes for OPTIONS messages used for pinging, apart for 200.

Default value is NULL.

#### Set the options_reply_codes parameter

    ...
    modparam("dispatcher", "options_reply_codes", "501, 403")
    ...

### `dst_avp` (str)

This is mainly for internal usage and represents the name of the avp which will hold the list with addresses, in the order they have been selected by the chosen algorithm. If use_default is 1, the value of last dst_avp_id is the last address in destination set. The first dst_avp_id is the selected destinations. All the other addresses from the destination set will be added in the avp list to be able to implement serial forking. Setting this parameter will only change the default partition's dst_avp. Use the partition parameter to create and alter other partitions.

For the 'default' partition the default value is $avp(ds_dst_failover). For any other partition, the default value is $avp(ds_dst_failover_partitionname).

#### Set the 'default' partition's dst_avp parameter

    ...
    modparam("dispatcher", "dst_avp", "$avp(271)")
    ...

### `grp_avp` (str)

This is mainly for internal usage and represents the name of the avp storing the group id of the destination set. Good to have it for later usage or checks. Setting this parameter will only change the default partition's grp_avp. Use the partition parameter to create and alter other partitions.

For the 'default' partition the default value is $avp(ds_grp_failover). For any other partition, the default value is $avp(ds_grp_failover_partitionname).

#### Set the 'default' partition's grp_avp parameter

    ...
    modparam("dispatcher", "grp_avp", "$avp(273)")
    ...

### `cnt_avp` (str)

This is mainly for internal usage and represents the name of the avp storing the number of destination addresses kept in dst_avp avps. Setting this parameter will only change the default partition's cnt_avp. Use the partition parameter to create and alter other partitions.

For the 'default' partition the default value is $avp(ds_cnt_failover). For any other partition, the default value is $avp(ds_cnt_failover_partitionname).

#### Set the 'default' partition's cnt_avp parameter

    ...
    modparam("dispatcher", "cnt_avp", "$avp(274)")
    ...

### `sock_avp` (str)

This is mainly for internal usage and represents the name of the avp storing the sockets to be used for the destination addresses kept in dst_avp avps. Setting this parameter will only change the default partition's sock_avp. Use the partition parameter to create and alter other partitions.

For the 'default' partition the default value is $avp(ds_sock_failover). For any other partition, the default value is $avp(ds_sock_failover_partitionname).

#### Set the 'default' partition's sock_avp parameter

    ...
    modparam("dispatcher", "sock_avp", "$avp(275)")
    ...

### `pvar_algo_pattern` (str)

This parameter is used by the PVAR(9) algorithm to specify the pseudovariable pattern used to detect the load of each destination. The name of the pseudovariable should contain the string %u, which will be internally replaced by the module with the uri of the destination.

Default value is none.

#### Set the pvar_algo_pattern parameter

    ...
    modparam("dispatcher", "pvar_algo_pattern", "$stat(load_%u)")
    ...

### `persistent_state` (int)

Specifies whether the state column should be loaded at startup and flushed during runtime or not.

Default value is 1 (enabled).

#### Set the `persistent_state` parameter

    ...
    # disable all DB operations with the state of a destination
    modparam("dispatcher", "persistent_state", 0)
    ...

### `table_name` (string)

If you want to load the sets of gateways from the database you must set this parameter as the database name. Setting this parameter will only change the default partition's table_name. Use the partition parameter to create and alter other partitions.

For every partition the default value is dispatcher.

#### Set the 'default' partition's table_name parameter

    ...
    modparam("dispatcher", "table_name", "my_dispatcher")
    ...

### `partition` (string)

Using this parameter the partition specific parameters (db_url, table_name, dst_avp, grp_avp, cnt_avp, sock_avp, attrs_avp, ds_define_blacklist) can be defined.

The syntax is: "partition_name: param1 = value1; param2 = value2; param3 = value3". Each value format is the same as the one used to define a specific parameter using modparam.

Whenever a new partition_name is provided, a new partition will be automatically created. The 'default' partition can also be defined using this parameter.

#### Create a new partition called 'part2'

    ...
    modparam("dispatcher", "partition",
                    "part2:
                        db_url = mysql://user:passwd@localhost/database;
                        table_name = ds_table;
                        attrs_avp = $avp(ds_attr_part2);
                        ds_define_blacklist = list2 = 4,6;")
    ...

### `setid_col` (string)

The column's name in the database storing the gateway's group id.

Default value is setid.

#### Set setid_col parameter

    ...
    modparam("dispatcher", "setid_col", "groupid")
    ...

### `destination_col` (string)

The column's name in the database storing the destination's sip uri.

Default value is destination.

#### Set destination_col parameter

    ...
    modparam("dispatcher", "destination_col", "uri")
    ...

### `state_col` (string)

The column's name in the database storing the state of the destination uri.

Default value is state.

#### Set state_col parameter

    ...
    modparam("dispatcher", "state_col", "dststate")
    ...

### `weight_col` (string)

The column's name in the database storing the weight for destination uri.

Default value is weight.

#### Set weight_col parameter

    ...
    modparam("dispatcher", "weight_col", "dstweight")
    ...

### `priority_col` (string)

The column's name in the database storing the priority for destination uri.

Default value is priority.

#### Set priority_col parameter

    ...
    modparam("dispatcher", "priority_col", "dstprio")
    ...

### `attrs_col` (string)

The column's name in the database storing the attributes (opaque string) for destination uri.

Default value is attrs.

#### Set attrs_col parameter

    ...
    modparam("dispatcher", "attrs_col", "dstattrs")
    ...

### `socket_col` (string)

The column's name in the database storing the socket (as string) for destination uri.

Default value is socket.

#### Set socket_col parameter

    ...
    modparam("dispatcher", "socket_col", "my_sock")
    ...

## Exported Functions

### `ds_select_dst(set, alg [, (flags M max_results)*])`

The method selects a destination from the given set of addresses. It will overwrite the "destination URI" of a SIP request ($du).

Meaning of the parameters is as follows:

- set - a partition name followed by colon and an id of the set or a list of sets from where to pick up destination address (variables are accepted). If the partition name is missing, the default partition will be used.

- alg - the algorithm(s) used to select the destination address (variables are accepted).

  - 0 - hash over callid

  - 1 - hash over from uri.

  - 2 - hash over to uri.

  - 3 - hash over request-uri.

  - 4 - round-robin (next destination).

  - 5 - hash over authorization-username (Proxy-Authorization or "normal" authorization). If no username is found, round robin is used.

  - 6 - random (using rand()).

  - 7 - hash over the content of PVs string. Note: This works only when the parameter hash_pvar is set.

  - 8 - the first entry in set is chosen.

  - 9 - The pvar_algo_pattern parameter is used to determine the load on each server. If the parameter is not specified, then the first entry in the set is chosen.

  - X - if the algorithm is not implemented, the first entry in set is chosen.

- flags M max_results - If specified, this will be the flags which in previous versions were specified at startup. The flags are:

  - 'f'/'F' - the failover support flag,

  - 'u'/'U' - the user only flag - will specify that only the uri user part will be used for hashing,

  - 'S'/'s' - the force destination flag - which will skip overwriting the destination address if it is already set,

  - 'D'/'d' - the use default flag('D','d') - which will use the last address in destination set as last option to send the message.

  You can also specify these flags using PVs. The flags are being kept per partition.

  The second paramater, max_results represents that only a maximum of max_results will be put into the specified avp for failover. This allows having many destinations but limit the useless traffic in case of a number that is bound to fail everywhere. Since version 2.1, the last paramater cand be represented by a list of flags and max_results, separated by comma. You can specify either only the flags, either only the max_results paramater, but if you want to specify them together you have to use the 'M' character like this: flags M max_results.

If the character 'f' in 'flags' is set, the rest of the addresses from the destination set is stored in AVP list. You can use 'ds_next_dst()' to use next address to achieve serial forking to all possible destinations. If multiple dispatching groups are used, the AVP list is constructed based on the position of each dispatching id in the list: first one has the higher priority, followed by the second one and so on.

This function can be used from REQUEST_ROUTE and FAILURE_ROUTE.

#### `ds_select_dst` usage

    ...
    ds_select_dst("1", "0");
    ...
    ds_select_dst("part2 : 1", "0", "5");
    ...
    ds_select_dst("part3 : 1", "0", "fUsD");
    ...
    ds_select_dst("part4 : 2,3", "0,1", "fuD M 5, fuS M 2");
    ...
    # dispatch over multiple dispatching groups
    $var(part_name) = "p4"
    $var(setid) = "1, 2";
    $var(alg) = "4, 2";
    $var(flags) = " sFDU M 2, fuS M 3";
    ds_select_dst("$var(part_name):$var(setid)","$var(alg)","$var(flags)");
    ...

### `ds_select_domain(set, alg [, "[flags] [M max_results]"])`

The method selects a destination from addresses set and rewrites the host and port from R-URI. The parameters have same meaning as for ds_select_dst().

If the character 'f' in 'flags' is set, the rest of the addresses from the destination set is stored in AVP list. You can use 'ds_next_domain()' to use next address to achieve serial forking to all possible destinations.

This function can be used from REQUEST_ROUTE and FAILURE_ROUTE.

### `ds_next_dst([partition_name])`

Takes the next destination address from the AVPs with id partition.'dst_avp_id' and sets the dst_uri (outbound proxy address). If partition_name is omitted, the default partition will be used.This function is using the flags set in ds_select_dst or ds_select_domain.

This function can be used from REQUEST_ROUTE and FAILURE_ROUTE.

### `ds_next_domain([partition_name])`

Takes the next destination address from the AVPs with id partition.'dst_avp_id' and sets the domain part of the request uri. If partition_name is omitted, the default partition will be used.This function is using the flags set in ds_select_dst or ds_select_domain.

This function can be used from REQUEST_ROUTE and FAILURE_ROUTE.

### `ds_mark_dst()`

Mark the last used address from the 'default' partition's destination set as inactive, in order to be ignored in the future. In this way it can be implemented an automatic detection of failed gateways. When an address is marked as inactive, it will be ignored by 'ds_select_dst' and 'ds_select_domain'. This function is using the flags set in ds_select_dst or ds_select_domain.

This function can be used from REQUEST_ROUTE and FAILURE_ROUTE.

### `ds_mark_dst([partition_name], "s")`

Mark the last used address from partition's destination set as inactive ("i"/"I"/"0"), active ("a"/"A"/"1") or probing ("p"/"P"/"2"). With this function, an automatic detection of failed gateways can be implemented. When an address is marked as inactive or probing, it will be ignored by 'ds_select_dst' and 'ds_select_domain'. If partition_name is omitted, the default partition will be used. This function is using the flags set in ds_select_dst or ds_select_domain.

possible parameters:

- "i", "I" or "0" - the last destination should be set to inactive and will be ignored in future requests.

- "a", "A" or "1" - the last destination should be set to active.

- "p", "P" or "2" - the last destination will be set to probing. Note: You will need to call this function "threshold"-times, before it will be actually set to probing.

This function can be used from REQUEST_ROUTE and FAILURE_ROUTE.

### `ds_count(set, filter, result)`

Returns the number of active, inactive or probing destinations in a partition's set, or combinations between these properties.

Meaning of the parameters:

- set - a partition name followed by colon and an id of a set of dispatching destinations (variables are accepted). If the partition name is missing, the default partition will be used.

- filter - which destinations should be counted. Either active destinations("a", "A" or "1"), inactive destinations("i", "I" or "0") or probing ones("p", "P" or "2") or different combinations between these flags, such as "pI", "1i", "ipA"... The filter parameter can have the following types:

  - string - the filtering flags are statically assigned

- result - A pseudovariable for storing the result.

This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, LOCAL_ROUTE, TIMER_ROUTE, EVENT_ROUTE

#### `ds_count` usage

    ...
    if (ds_count("1", "a", "$avp(result)")) {
    	...
    }
    ...
    if (ds_count("$avp(partition) : $avp(set)", "ip", "$avp(result)")) {
    	...
    }
    ...

### `ds_is_in_list(ip, port [,set [,active_only]])`

This function returns true, if the parameters ip and port point to a host from the dispatcher-list; otherwise false.

Meaning of the parameters:

- ip - string / pseudo-variable (as string) containing the IP to test against the dispatcher list. This cannot be empty.

- port - int / pseudo-variable (as int) containing the PORT to test against the dispatcher list. This can be empty - in this case the port will excluded from the matching of IP against the dispatcher list.

- set (optional) - a partition name followed by colon and the set ID of a dispatcher list to test against. If the partition name is omitted the default partition will be used. If the set id is missing, all the dispatching sets will the checked. If a partition name is specified then it must be followed by colon regardless of the set id being specified or not. -1 can be used as a wildcard to check in all sets.

- active_only (optional) - search only through the active destinations (ignore the ones in probing and inactive mode).

This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE and ONREPLY_ROUTE.

#### `ds_is_in_list` usage

    ...
    if (ds_is_in_list("$si", "$sp")) {
    	# source IP:PORT is in a dispatcher list
    }
    ...
    if (ds_is_in_list("$rd", "$rp", "2")) {
    	# source RURI (ip and port) is in the dispatcher list id "2" of the default partition
    }
    ...
    if (ds_is_in_list("$rd", "$rp", "part2:2")) {
    	# source RURI (ip and port) is in the dispatcher list id "2" of the partition called 'part2'
    }
    ...

## Exported MI Functions

### `ds_set_state`

Sets the status for a destination address (can be use to mark the destination as active or inactive).

Name: ds_set_state

Parameters:

- _state_ : state of the destination address

  - a: active

  - i: inactive

  - p: probing

- _group_: partition name followed by colon and destination group id. If the partition name is omitted, the default partition will be used

- _address_: address of the destination in the _group_

MI FIFO Command Format:

    :ds_set_state:_reply_fifo_file_
    _state_
    _group_
    _address_
    _empty_line_

### `ds_list`

It lists the groups and included destinations of all the partitions.

Name: ds_list

Parameters:

- full (optional) - adds the weight, priority and description fields to the listing

MI FIFO Command Format:

    :ds_list:_reply_fifo_file_
    _empty_line_

### `ds_reload`

It reloads the groups and included destinations for a specified partition or all partitions.

Name: ds_reload

Parameters:

- partition (optional) - name of the partition to be reloaded.

MI DATAGRAM Command Format:

    ":ds_reload:\n."

## Exported Events

### `E_DISPATCHER_STATUS`

This event is raised when the dispatcher module marks a destination as activated or deactivated.

Parameters:

- partition - the partition name of the destination.

- group - the group of the destination.

- address - the address of the destination.

- status - active if the destination gets activated or inactive if the destination is detected unresponsive.

## Installation and Running

### &osips; config file

Next picture displays a sample usage of dispatcher.

#### &osips; config script - sample dispatcher usage

    ...
    &dispatchercfg;
    ...