Asterisk is primarily designed to run on a single system. However, as requirements for scalability increase, it is common for deployments to require multiple Asterisk servers. Since that has become increasingly common, some features have been added to make it easier to coordinate multiple Asterisk servers. One of those features is distributed device state support.
What this means is that if a device is on a call on one Asterisk server, the state of that device on all servers reflects that. To be more specific, the way this works is that every server knows the state of each device from the perspective of each server. Using this collection of states, each server will calculate what the overall device state value is to report to the rest of Asterisk.
To accomplish distributed device state, some sort of messaging mechanism must be used for the servers to communicate with each other. Two such mechanisms are supported as of Asterisk 1.8: AIS and XMPP.
The Application Interface Specification (AIS) is a standardized set of messaging middleware APIs. The definition for the APIs is provided by the Service Availability Forum. The open source implementation of AIS that was used for the development and testing of this functionality is OpenAIS, which is built on Corosync.
Corosync, and thus OpenAIS, is built in such a way that nodes must be located on the same high-speed, low-latency LAN. If your deployment is geographically distributed, you should use the XMPP-based distributed device state support, which is discussed in the section called “Using XMPP”.
The first step to getting the necessary components installed is to install Corosync and OpenAIS. Corosync depends on the NSS library. Install the libnss3-dev package on Ubuntu or the nss-devel package on CentOS.
Next, install Corosync and OpenAIS. There may be packages available, but they are also fairly straightforward to install from source. Download the latest releases from the Corosync and OpenAIS home pages. Then, execute the following commands to compile and install each package:
$
tar xvzf corosync-1.2.8.tar.gz
$
cd corosync-1.2.8
$
./configure
$
make
$
sudo make install
$
tar xvzf openais-1.1.4.tar.gz
$
cd openais-1.1.4
$
./configure
$
make
$
sudo make install
If you installed Asterisk prior to installing Corosync and OpenAIS, you will need to re-compile and reinstall Asterisk to get AIS support. Start by running the Asterisk configure script. The configure script is responsible for inspecting the system to find out which optional dependencies can be found so that the build system knows which modules can be built:
$
cd /path/to/asterisk
$
./configure
After running the
configure script, run the
menuselect tool to ensure that
Asterisk has been told to build the
res_ais
module (this module can be found in the
Resource Modules section of
menuselect):
$
make menuselect
Finally, compile and install Asterisk:
$
make
$
sudo make install
This is a pretty quick and crude set of instructions for compiling and installing Asterisk. For a much more complete set of instructions, please see Chapter 3, Installing Asterisk.
Now that OpenAIS has been installed, it needs to be
configured. There is a configuration file for both OpenAIS and
Corosync that must be put in place. Check to see if
/etc/ais/openais.conf
and
/etc/corosync/corosync.conf
exist. If they do not
exist, copy in the sample configuration files:
$
sudo mkdir -p /etc/ais
$
cd openais-1.1.4
$
sudo cp conf/openais.conf.sample /etc/ais/openais.conf
$
sudo mkdir -p /etc/corosync
$
cd corosync-1.2.8
$
sudo cp conf/corosync.conf.sample /etc/corosync/corosync.conf
Next, you will need to edit both
the openais.conf
and
corosync.conf
files. There are a number of
options here, but the most important one that must be changed is the
bindnetaddr
option in the
totem-interface
section. This must be set to the IP
address of the network interface that this node will use to
communicate with the rest of the cluster:
totem { ... interface { ringnumber: 0 bindnetaddr: 10.24.22.144 mcastaddr: 226.94.1.1 mcastport: 5405 } }
For detailed documentation on the rest of the options in these configuration files, see the associated manpages:
$
man openais.conf
$
man corosync.conf
To get started with testing out basic OpenAIS connectivity, try starting the aisexec application in the foreground and watching the output:
$
sudo aisexec -f
For example, if you watch the output of aisexec on the first node while you bring up the second node, you should see output that reflects that the cluster now has two connected nodes:
Nov 13 06:55:30 corosync [CLM ] CLM CONFIGURATION CHANGE Nov 13 06:55:30 corosync [CLM ] New Configuration: Nov 13 06:55:30 corosync [CLM ] r(0) ip(10.24.22.144) Nov 13 06:55:30 corosync [CLM ] r(0) ip(10.24.22.242) Nov 13 06:55:30 corosync [CLM ] Members Left: Nov 13 06:55:30 corosync [CLM ] Members Joined: Nov 13 06:55:30 corosync [CLM ] r(0) ip(10.24.22.242) Nov 13 06:55:30 corosync [TOTEM ] A processor joined or left the membership and a new membership was formed. Nov 13 06:55:30 corosync [MAIN ] Completed service synchronization, ready to provide service.
The res_ais
module for
Asterisk has a single configuration file,
/etc/asterisk/ais.conf
. One short section is
required in this file to enable distributed device state in an AIS
cluster. Place the following contents in the
/etc/asterisk/ais.conf
file:
[device_state] type = event_channel publish_event = device_state subscribe_event = device_state
There is an Asterisk CLI command that can be used to ensure that this configuration has been loaded properly:
*CLI>
ais evt show event channels
============================================================= === Event Channels ========================================== ============================================================= === === --------------------------------------------------------- === Event Channel Name: device_state === ==> Publishing Event Type: device_state === ==> Subscribing to Event Type: device_state === --------------------------------------------------------- === =============================================================
Another useful
Asterisk CLI command provided by the
res_ais
module is used to list the members of the
AIS cluster:
*CLI>
ais clm show members
============================================================= === Cluster Members ========================================= ============================================================= === === --------------------------------------------------------- === Node Name: 10.24.22.144 === ==> ID: 0x9016180a === ==> Address: 10.24.22.144 === ==> Member: Yes === --------------------------------------------------------- === === --------------------------------------------------------- === Node Name: 10.24.22.242 === ==> ID: 0xf216180a === ==> Address: 10.24.22.242 === ==> Member: Yes === --------------------------------------------------------- === =============================================================
Now that you’ve set up and configured distributed device
state using OpenAIS, there are some simple tests that can be done
using custom device states to ensure that device states are being
communicated between the servers. Start by creating a test hint in the
Asterisk dialplan,
/etc/asterisk/extensions.conf
:
[devstate_test] exten => foo,hint,Custom:abc
Now, you can adjust the custom device state from the Asterisk CLI using the dialplan set global CLI command and then check the state on each server using the core show hints command. For example, we can use this command to set the state on one server:
pbx1*CLI>
dialplan set global DEVICE_STATE(Custom:abc) INUSE
-- Global variable 'DEVICE_STATE(Custom:abc)' set to 'INUSE'
and then, check the state on another server using this command:
*CLI>
core show hints
-= Registered Asterisk Dial Plan Hints =- foo@devstatetest : Custom:abc State:InUse Watchers 0
If you would like to dive deeper
into the processing of distributed device state changes, there are
some useful debug messages that can be enabled. First, enable debug on
the Asterisk console in
/etc/asterisk/logger.conf
. Then, enable debugging
at the Asterisk CLI:
*CLI>
core set debug 1
With the debug output enabled, you will see some messages that show how Asterisk is processing each state change. When the state of a device changes on one server, Asterisk checks the state information it has for that device on all servers and determines the overall device state. The following examples illustrate:
*CLI>
dialplan set global DEVICE_STATE(Custom:abc) NOT_INUSE
-- Global variable 'DEVICE_STATE(Custom:abc)' set to 'NOT_INUSE' [Nov 13 13:27:12] DEBUG[14801]: devicestate.c:652 handle_devstate_change: Processing device state change for 'Custom:abc' [Nov 13 13:27:12] DEBUG[14801]: devicestate.c:602 process_collection: Adding per-server state of 'Not in use' for 'Custom:abc' [Nov 13 13:27:12] DEBUG[14801]: devicestate.c:602 process_collection: Adding per-server state of 'Not in use' for 'Custom:abc' [Nov 13 13:27:12] DEBUG[14801]: devicestate.c:609 process_collection: Aggregate devstate result is 'Not in use' for 'Custom:abc' [Nov 13 13:27:12] DEBUG[14801]: devicestate.c:631 process_collection: Aggregate state for device 'Custom:abc' has changed to 'Not in use'*CLI>
dialplan set global DEVICE_STATE(Custom:abc) INUSE
-- Global variable 'DEVICE_STATE(Custom:abc)' set to 'INUSE' [Nov 13 13:29:30] DEBUG[14801]: devicestate.c:652 handle_devstate_change: Processing device state change for 'Custom:abc' [Nov 13 13:29:30] DEBUG[14801]: devicestate.c:602 process_collection: Adding per-server state of 'Not in use' for 'Custom:abc' [Nov 13 13:29:30] DEBUG[14801]: devicestate.c:602 process_collection: Adding per-server state of 'In use' for 'Custom:abc' [Nov 13 13:29:30] DEBUG[14801]: devicestate.c:609 process_collection: Aggregate devstate result is 'In use' for 'Custom:abc' [Nov 13 13:29:30] DEBUG[14801]: devicestate.c:631 process_collection: Aggregate state for device 'Custom:abc' has changed to 'In use'
The eXtensible Messaging and Presence Protocol (XMPP), formerly (and still commonly) known as Jabber, is an IETF standardized communications protocol. It is most commonly known as an IM protocol, but it can be used for a number of other interesting applications as well. The XMPP Standards Foundation (XSF) works to standardize extensions to the XMPP protocol. One such extension, referred to as PubSub, provides a publish/subscribe mechanism.
Asterisk has the ability to use XMPP PubSub to distribute device state information. One of the nice things about using XMPP to accomplish this is that it works very well for geographically distributed Asterisk servers.
To distribute device states using XMPP, you will need an XMPP server that supports PubSub. One such server that has been successfully tested against Asterisk is Tigase.
The Tigase website has instructions for installing and configuring the Tigase server. We suggest that you follow those instructions (or the instructions provided for whatever other server you may choose to use) and come back to this book when you’re ready to work on the Asterisk-specific parts.
On the Asterisk side of things, you
will need to ensure that you have installed the
res_jabber
module. You can check to see if it is
already loaded at the Asterisk CLI:
*CLI>
module show like jabber
Module Description Use Count res_jabber.so AJI - Asterisk Jabber Interface 0 1 modules loaded
If you are using a custom
/etc/asterisk/modules.conf
file that lists only
specific modules to be loaded, you can also check the filesystem to
see if the module was compiled and installed:
$
ls -l /usr/lib/asterisk/modules/res_jabber.so
-rwxr-xr-x 1 root root 837436 2010-11-12 15:33 /usr/lib/asterisk/modules/res_jabber.so
If you do not yet have
res_jabber
installed, you will need to install the
iksemel
and
OpenSSL libraries. Then, you will need to
recompile and reinstall Asterisk. Start by
running the Asterisk
configure script, which is responsible for
inspecting the system and locating optional dependencies, so that the
build system knows which modules can be built:
$
cd /path/to/asterisk
$
./configure
After running the
configure script, run the
menuselect tool to ensure that
Asterisk has been told to build the
res_jabber
module. This module can be found in the
Resource Modules section of
menuselect:
$
make menuselect
Finally, compile and install Asterisk:
$
make
$
sudo make install
This is a pretty quick and crude set of instructions for compiling and installing Asterisk. For a much more complete set of instructions, please see Chapter 3, Installing Asterisk.
Unfortunately, Asterisk is currently not able to register new accounts on an XMPP server. You will have to create an account for each server via some other mechanism. The method we used while testing was to use an XMPP client such as Pidgin to complete the account registration process. After account registration is complete, the XMPP client is no longer needed. For the rest of the examples, we will use the following two buddies, both of which are on the server jabber.shifteight.org:
The /etc/asterisk/jabber.conf
file
will need to be configured on each server. We will show the
configuration for a two-server setup here, but the configuration can
easily be expanded to more servers as needed. Example 14.2, “jabber.conf for server1” shows the contents of the
configuration file for server 1 and Example 14.3, “jabber.conf for server2” shows the contents of the
configuration file for server 2. For additional information on the
jabber.conf
options associated with distributed
device states, see the configs/jabber.conf.sample
file that is included in the Asterisk source tree.
Example 14.2. jabber.conf for server1
[general] autoregister = yes [asterisk] type = client serverhost = jabber.shifteight.org pubsub_node = pubsub.jabber.shifteight.org username = server1@jabber.shifteight.org/astvoip1 secret = mypassword distribute_events = yes status = available usetls = no usesasl = yes buddy = server2@jabber.shifteight.org/astvoip2
Example 14.3. jabber.conf for server2
[general] autoregister = yes [asterisk] type = client serverhost = jabber.shifteight.org pubsub_node = pubsub.jabber.shifteight.org username = server2@jabber.shifteight.org/astvoip2 secret = mypassword distribute_events = yes status = available usetls = no usesasl = yes buddy = server1@jabber.shifteight.org/astvoip1
To ensure that everything is working properly, start by
doing some verification of the jabber.conf
settings on each server. There are a couple of relevant
Asterisk CLI commands that can be used
here. The first is the jabber show connected
command, which will verify that Asterisk has successfully logged
in with an account on the jabber server. The
output of this command on the first server shows:
*CLI>
jabber show connected
Jabber Users and their status: User: server1@jabber.shifteight.org/astvoip1 - Connected ---- Number of users: 1
Meanwhile, if jabber show connected is executed on the second server, it shows:
*CLI>
jabber show connected
Jabber Users and their status: User: server2@jabber.shifteight.org/astvoip2 - Connected ---- Number of users: 1
The next useful command for verifying the setup is jabber show buddies. This command allows you to verify that the other server is correctly listed on your buddy list. It also lets you see if the other server is seen as currently connected. If you were to run this command on the first server without Asterisk currently running on the second server, the output would look like this:
*CLI>
jabber show buddies
Jabber buddy lists Client: server1@jabber.shifteight.org/astvoip1 Buddy: server2@jabber.shifteight.org Resource: None Buddy: server2@jabber.shifteight.org/astvoip2 Resource: None
Next, start Asterisk on the second server and run jabber show buddies on that server. The output will contain more information, since the second server will see the first server online:
*CLI>
jabber show buddies
Jabber buddy lists Client: server2@jabber.shifteight.org/astvoip2 Buddy: server1@jabber.shifteight.org Resource: astvoip1 node: http://www.asterisk.org/xmpp/client/caps version: asterisk-xmpp Jingle capable: yes Status: 1 Priority: 0 Buddy: server1@jabber.shifteight.org/astvoip1 Resource: None
At this point, you should be ready to test out the distribution of device states. The procedure is the same as that for testing device states over AIS, which can be found in the section called “Testing device state changes”.