![Free-eBooks.net](/resources/img/logo-nfe.png)
![All New Design](/resources/img/allnew.png)
loadmodule "modules/sl/sl.so"
loadmodule "modules/tm/tm.so"
# ----------------- setting module-specific parameters ---------------
# -- tm params --
# set time for which ser will be waiting for a final response;
# fr_inv_timer sets value for INVITE transactions, fr_timer
# for all others
modparam("tm", "fr_inv_timer", 15 )
modparam("tm", "fr_timer", 10 )
# ------------------------- request routing logic -------------------
# main routing logic
route{
# for testing purposes, simply okay all REGISTERs
if (method=="REGISTER") {
log("REGISTER");
sl_send_reply("200", "ok");
break;
};
# try these two destinations first in parallel; the second
# destination is targeted to sink port -- that will make ser
# wait until timer hits
seturi("sip:nobody@iptel.org");
append_branch("sip:parallel@iptel.org:9");
# if we do not get a positive reply, continue at reply_route[1]
t_on_failure("1");
# forward the request to all destinations in destination set now
t_relay();
}
failure_route[1] {
# forwarding failed -- try again at another destination
append_branch("sip:nonsense@iptel.org");
P.110
[IP Telephony Cookbook] / Setting Up Basic Services
log(1,"first redirection\n");
# if this alternative destination fails too, proceed to ...
t_on_failure("2");
t_relay();
}
failure_route[2] {
# try out the last resort destination
append_branch("sip:foo@iptel.org");
log(1, "second redirection\n");
# we no more call t_on_negative here; if this destination
# fails too, transaction will complete
t_relay();
}
4.6.2.4.5 Accounting
In some scenarios, like termination of calls in the PSTN, SIP administrators may wish to keep track of placed calls. SER can be configured to report on completed transactions. Reports are sent by default to the syslog facility. Support for RADIUS and MySQL accounting exists as well.
Note that SER is by no means call-stateful. It reports on completed transactions, i.e., after a successful call set up is reported, it drops any call-related state.When a call is terminated, a transactional state for the BYE request is created and forgotten again after the transaction completes.This is a feature and not a bug. Keeping the state information during transactions only allows the achievement of significantly higher scalability. It is then up to the accounting application to correlate call initiation and termination events.
To enable call accounting, tm and acc modules need to be loaded and requests need to be processed statefully and labelled for accounting.This means that if you want a transaction to be reported, the initial request must have taken the path setflag(X), t_relay in the SER script. X
must have the value configured in the acc_flag configuration option.
Also note, that, by default, only transactions that initiate a SIP dialogue (typically INVITE) visit a proxy server. Subsequent transactions are exchanged directly between end-devices, do not visit proxy server and cannot be reported.To be able to report on subsequent transactions, you need to force them to visit the proxy server by turning on record routing.
Example 4.6 Configuration with enabled accounting
#
# example: accounting calls to numerical destinations
#
# ------------------ module loading ----------------------------------
loadmodule "modules/tm/tm.so"
loadmodule "modules/acc/acc.so"
loadmodule "modules/sl/sl.so"
P.111
[IP Telephony Cookbook] / Setting Up Basic Services
loadmodule "modules/maxfwd/maxfwd.so"
loadmodule "modules/rr/rr.so"
# ----------------- setting module-specific parameters ---------------
# -- acc params --
# set the reporting log level
modparam("acc", "log_level", 1)
# number of flag, which will be used for accounting; if a message is
# labeled with this flag, its completion status will be reported
modparam("acc", "log_flag", 1 )
# ------------------------- request routing logic -------------------
# main routing logic
route{
/* ********* ROUTINE CHECKS ********************************** */
# filter too old messages
if (!mf_process_maxfwd_header("10")) {
log("LOG: Too many hops\n");
sl_send_reply("483","Too Many Hops");
break;
};
if (len_gt( max_len )) {
sl_send_reply("513", "Wow -- Message too large"); break;
};
# Process record-routing
if (loose_route()) { t_relay(); break; };
# labeled all transaction for accounting
setflag(1);
# record-route INVITES to make sure BYEs will visit our server too if (method=="INVITE") record_route();
P.112
[IP Telephony Cookbook] / Setting Up Basic Services
# forward the request statefuly now; (we need *stateful* forwarding,
# because the stateful mode correlates requests with replies and
# drops retransmissions; otherwise, we would have to report on
# every single message received)
if (!t_relay()) {
sl_reply_error();
break;
};
}
4.6.2.4.6 Reporting missed calls
SER can report missed calls via the syslog facility or to MySQL. Mysql reporting can be utilised by SER's complementary Web interface, Serweb.
Reporting of missed calls is enabled by the acc module.There are two cases, in which you want to report.The first case is when a called party is offline.The other case is when a user is online, but call establishment fails.There may be many reasons for failure (call cancellation, inactive phone, busy phone, server timer, etc.), all of them leading to a negative (>=300) reply sent to the calling party.The acc module can be configured to issue a missed-call report whenever a transaction completes with a negative status.
The following configuration fragment reports a missed call in both cases.The top half of the condition reports on calls missed due to offline called party status, using the acc_request action.
The action is wrapped in transactional processing (t_newtran) to guarantee that reports are not duplicated on receipt of retransmissions.
The bottom half of the condition marks transactions to online users in order to be reported on failure.That is what the setflag (3) action is responsible for, along with the configuration option log_missed_flag.This option configures SER to report on all transactions, which were marked with flag 3.
loadmodule("modules/tm/tm.so");
loadmodule("modules/acc/acc.so");
....
# if a call is labeled using setflag(3) and is missed, it will
# be reported
...
modparam("acc", "log_missed_flag", 3 );
if (!lookup("location")) {
# call invitations to off-line users are reported using the
# acc_request action; to avoid duplicate reports on request
# retransmissions, request is processed statefuly (t_newtran,
# t_reply)
if ((method=="INVITE" || method=="ACK") && t_newtran() ) {
t_reply("404", "Not Found");
acc_request("404 Not Found");
break;
P.113
[IP Telephony Cookbook] / Setting Up Basic Services
};
# all other requests to off-line users are simply replied
# statelessly and no reports are issued
sl_send_reply("404", "Not Found");
break;
} else {
# user on-line; report on failed transactions; mark the
# transaction for reporting using the same number as
# configured above; if the call is really missed, a report
# will be issued
setflag(3);
# forward to user's current destination
t_relay();
break;
};
4.6.2.4.7 User aliases
Frequently, it is desirable for a user to have multiple addresses in a domain. For example, a user with username ‘john.doe’ wants to be reachable at a shorter address ‘john’ or at a numerical address ‘12335’, so that PSTN calling parties with numeric-only key-pads can reach him as well.
With SER, you can maintain a special user location table and translate existing aliases to canonical usernames using the lookup action from the usrloc module.The following script fragment demonstrates the use of lookup for this purpose.
Example 4.7 Configuration of use of aliases
if (!uri==myself) { # request not for our domain...
route(1); # go somewhere else, where outbound requests are processed break;
};
# the request is for our domain -- process registrations first
if (method=="REGISTER") { route(3); break; };
# look now, if there is an alias in the "aliases" table; do not care
# about return value: whether there is some or not, move ahead then lookup("aliases");
# there may be aliases which translate to other domain and for which
# local processing is not appropriate; check again, if after the
# alias translation, the request is still for us
if (!uri==myself) { route(1); break; };
# continue with processing for our domain...
...
P.114
[IP Telephony Cookbook] / Setting Up Basic Services
The table with aliases is updated using the serctl tool.The command serctl alias add <alias>
<uri> adds a new alias, the command serctl alias show <user> prints an existing alias, and the command serctl alias rm <user> removes it.
[jiri@cat sip_router]$ serctl alias add 1234 sip:john.doe@foo.bar
sip:john.doe@foo.bar
200 Added to table
('1234','sip:john.doe@foo.bar') to 'aliases'
[jiri@cat sip_router]$ serctl alias add john sip:john.doe@foo.bar
sip:john.doe@foo.bar
200 Added to table
('john','sip:john.doe@foo.bar') to 'aliases'
[jiri@cat sip_router]$ serctl alias show john
<sip:john.doe@foo.bar>;q=1.00;expires=1073741811
[jiri@cat sip_router]$ serctl alias rm john
200 user (aliases, john) deleted
Note that the persistence of records needs to be turned on in the usrloc module. All changes to aliases would otherwise be lost on server reboot.To enable the persistence, set the db_mode usrloc parameter to a non-zero value.
# ....load module ...
loadmodule "modules/usrloc/usrloc.so"
# ... turn on persistence -- all changes to user tables are immediately
# flushed to mysql
modparam("usrloc", "db_mode", 1)
# the SQL address:
modparam("usrloc", "db_url","mysql://ser:secret@dbhost/ser")
~ 4.6.2.5 Operation
4.6.2.5.1 User management
There are two tasks related to the management of SIP users: maintaining user accounts and maintaining user contacts. Both of these jobs can be done using the serctl command-line tool.
The complimentary Web interface, Serweb, can be used for this purpose as well.
If user authentication is turned on, which is highly advisable, user accounts must be created before users can log in.To create a new user account, use the serctl add utility with the username, password and e-mail as parameters. It is important that the environment variable SIP_DOMAIN
is set to your domain and matches the realm values used in your script.The realm value is used for calculation of credentials stored in the subscriber database, which are bound permanently to this value.
[jiri@cat gen_ha1]$ export SIP_DOMAIN=foo.bar
[jiri@cat gen_ha1]$ serctl add newuser secret newuser@foo.bar
MySql Password:
new user added
P.115
[IP Telephony Cookbook] / Setting Up Basic Services
serctl can also change the user's password or remove existing accounts from the system permanently.
[jiri@cat gen_ha1]$ serctl passwd newuser newpassword
MySql Password:
password change succeeded
[jiri@cat gen_ha1]$ serctl rm newuser
MySql Password:
user removed
Typically, user contacts are automatically uploaded by SIP phones to the server during the registration process and administrators do not need to worry about them. However, users may wish to append permanent contacts to PSTN gateways or to locations in other administrative domains.To manipulate the contacts in such cases, use the serctl ul tool. Note that this is the only correct way to update contacts -- direct changes of the back-end MySQL database do not affect a server's memory. Also note, that if persistence is turned off (usrloc db_mode parameter set to 0), all contacts will be lost on server reboot. Make sure that the persistence is enabled if you add permanent contacts.
To add a new permanent contact for a user, call serctl ul add <username> <contact> .To delete all users’ contacts, call serctl ul rm <username> .The command serctl ul show
<username> prints all current contacts of this user.
[jiri@cat gen_ha1]$ serctl ul add newuser sip:666@gateway.foo.bar
sip:666@gateway.foo.bar
200 Added to table
('newuser','sip:666@gateway.foo.bar') to 'location'
[jiri@cat gen_ha1]$ serctl ul show newuser
<sip:666@gateway.foo.bar>;q=1.00;expires=1073741812
[jiri@cat gen_ha1]$ serctl ul rm newuser
200 user (location, newuser) deleted
[jiri@cat gen_ha1]$ serctl ul show newuser
404 Username newuser in table location not found
4.6.2.5.2 Access control (PSTN gateway)
It is often important to exercise some sort of access control. A typical case is when SER is used to guard a PSTN gateway. If a gateway could not be well-guarded, unauthorised users would be able to use it to make calls to the PSTN, inflicting high costs.
There are a few issues you need to understand when configuring SER for this purpose. First, if a gateway is built or configured to accept calls from anywhere, calling parties may easily bypass your access control server and communicate with the gateway directly.You then need to enforce, at transport layer, that signalling is only accepted if coming via SER and deny SIP packets coming from other hosts and port numbers.Your network must be configured not to allow forged IP
addresses. Also, you need to turn on record routing to assure that all session requests will travel via SER. Otherwise, calling party’s devices would send subsequent SIP requests directly to your gateway, which would fail because of transport filtering.
P.116
[IP Telephony Cookbook] / Setting Up Basic Services
Authorisation (i.e., the process of determining who may call where) is facilitated in SER using the group membership concept. Scripts make decisions on whether a calling party is authorised to make a call to a specific destination, based on the user's membership in a group. For example, a policy may be set up to allow calls to international destinations, only to users who are members of
‘int’ group. Before a user's group membership is checked, his identity must be verified.Without cryptographic verification of the user's identity, it would be impossible to confirm that a calling party really is who he claims to be.
The following script demonstrates how to configure SER as an access control server for a PSTN
gateway.The script verifies user identity using digest authentication, checks user's privileges, and forces all requests to visit the server.
Example 4.8 Script for gateway access control
loadmodule "modules/sl/sl.so"
loadmodule "modules/tm/tm.so"
loadmodule "modules/acc/acc.so"
loadmodule "modules/rr/rr.so"
loadmodule "modules/maxfwd/maxfwd.so"
loadmodule "modules/mysql/mysql.so"
loadmodule "modules/auth/auth.so"
loadmodule "modules/auth_db/auth_db.so"
loadmodule "modules/group/group.so"
loadmodule "modules/uri/uri.so"
# ----------------- setting module-specific parameters ---------------
modparam("auth_db", "db_url","mysql:ser:heslo@localhost/ser") modparam("auth_db", "calculate_ha1", yes)
modparam("auth_db", "password_column", "password")
# -- acc params --
modparam("acc", "log_level", 1)
# that is the flag for which we will account -- don't forget to
# set the same one :-)
modparam("acc", "log_flag", 1 )
# ------------------------- request routing logic -------------------
# main routing logic
route{
/* ********* ROUTINE CHECKS ********************************** */
# filter too old messages
if (!mf_process_maxfwd_header("10")) {
log("LOG: Too many hops\n");
sl_send_reply("483","Too Many Hops");
break;
P.117
[IP Telephony Cookbook] / Setting Up Basic Services
};
if (len_gt( max_len )) {
sl_send_reply("513", "Wow -- Message too large"); break;
};
/* ********* RR ********************************** */
/* grant Route routing if route headers present */
if (loose_route()) { t_relay(); break; };
/* record-route INVITEs -- all subsequent requests must visit us */
if (method=="INVITE") {
record_route();
};
# now check if it really is a PSTN destination which should be handled
# by our gateway; if not, and the request is an invitation, drop it --
# we cannot terminate it in PSTN; relay non-INVITE requests -- it may
# be for example BYEs sent by gateway to call originator
if (!uri=~"sip:\+?[0-9]+@.*") {
if (method=="INVITE") {
sl_send_reply("403", "Call cannot be served here");
} else {
forward(uri:host, uri:port);
};
break;
};
# account completed transactions via syslog
setflag(1);
# free call destinations ... no authentication needed
if ( is_user_in("Request-URI", "free-pstn") /* free destinations */
| uri=~"sip:[79][0-9][0-9][0-9]@.*" /* local PBX */
| uri=~"sip:98[0-9][0-9][0-9][0-9]") {
log("free call");
} else if (src_ip==192.168.0.10) {
# our gateway does not support digest authentication;
# verify that a request is coming from it by source
# address
log("gateway-originated request");
} else {
# in all other cases, we need to check the request against
# access control lists; first of all, verify request
# originator's identity
if (!proxy_authorize( "gateway" /* realm */,
"subscriber" /* table name */)) {
proxy_challenge( "gateway" /* realm */, "0" /* no qop */ ); P.118
[IP Telephony Cookbook] / Setting Up Basic Services
break;
};
# authorise only for INVITEs -- RR/Contact may result in weird
# things showing up in d-uri that would break our logic; our
# major concern is INVITE which causes PSTN costs
if (method=="INVITE") {
# does the authenticated user have a permission for local
# calls (destinations beginning with a single zero)?
# (i.e., is he in the "local" group?)
if (uri=~"sip:0[1-9][0-9]+@.*") {
if (!is_user_in("credentials", "local")) {
sl_send_reply("403", "No permission for local calls"); break;
};
# the same for long-distance (destinations begin with two zeros")
} else if (uri=~"sip:00[1-9][0-9]+@.*") {
if (!is_user_in("credentials", "ld")) {
sl_send_reply("403", " no permission for LD "); break;
};
# the same for international calls (three zeros)
} else if (uri=~"sip:000[1-9][0-9]+@.*") {
if (!is_user_in("credentials", "int")) {
sl_send_reply("403", "International permissions needed"); break;
};
# everything else (e.g., interplanetary calls) is denied
} else {
sl_send_reply("403", "Forbidden");
break;
};
}; # INVITE to authorised PSTN
}; # authorised PSTN
# if you have passed through all the checks, let your call go to GW!
rewritehostport("192.168.0.10:5060");
# forward the request now
if (!t_relay()) {
sl_reply_error();
break;
};
}
P.119
[IP Telephony Cookbook] / Setting Up Basic Services
Use the serctl tool to maintain group membership.The command serctl acl grant <username>
<group> makes a user member of a group, the command serctl acl show <username> shows groups of which a user is member, and the command serctl acl revoke <username>
[<group>] revokes a user's membership in one or all groups.
[jiri@cat sip_router]$ serctl acl grant john int
MySql Password:
+------+-----+---------------------+
| user | grp | last_modified |
+------+-----+---------------------+
| john | int | 2002-12-08 02:09:20 |
+------+-----+---------------------+
~ 4.6.3 Asterisk
In this section we will describe an example configuration of the Asterisk PBX.We will focus mainly on the configuration of the SIP part.
~ 4.6.3.1 Getting Asterisk
Asterisk can be downloaded from http://www.digium.com
~ 4.6.3.2 Installation
Download the tarball and untar it using:
tar xvfz asterisk-0.5.0.tar.gz
Compile the sources:
- # cd asterisk-0.5.0
- # make
- # make install
- # make samples
~ 4.6.3.3 Configuration
The configuration files can be found in the /etc/asterisk directory.The most important files are: sip.conf which contains configuration of SIP user agent and extensions.conf which defines the dialling plan.
In this simple example, Asterisk is configured to act as a simple back-to-back user agent. It will allow SIP user agents to register to it and make calls which will be routed to an outbound proxy.
P.120
[IP Telephony Cookbook] / Setting Up Basic Services
The file sip.conf contains the following settings:
;
; SIP Configuration for Asterisk
;
[general]
port = 5060 ; Port to bind to
bindaddr = 0.0.0.0 ; Address to bind to
context = from-sip ; Default for incoming calls
;
register => asterisk:password@iptel.org/jan ; Register with a SIP
provider
[iptel]
type=friend
username=asterisk
secret=password
fromdomain=iptel.org
host=iptel.org
[jan]
type=friend
username=jan
;secret=blah
host=dynamic
canreinvite=no
Section general contains some generic settings. Configure Asterisk to listen on port 5060 and to listen on all available interfaces. Specify context to be from-sip.The same context must be later configured in extensions.conf !
The line beginning with register instructs Asterisk to act as a user agent and register with the iptel.org server as user asterisk with password, password.The /jan part indicates that all incoming calls to user asterisk will be forwarded to user ‘jan’, registered at the Asterisk server.
Section iptel contains configuration of a peer. In this case, it is the iptel.org proxy server, because we will be using this server as an outbound proxy. In this section, the parameter fromdomain is specified, because we want all outgoing messages to have this domain in the From header field.
The last section, jan, contains credentials and data for a user that will be able to register with the Asterisk server. In this case, one SIP phone is configured with username jan and with an empty password and with a phone that will be registered with the Asterisk server to receive calls for username jan.
P.121
[IP Telephony Cookbook] / Setting Up Basic Services
The file extensions.conf contains the following settings:
[from-sip]
exten => jan,1,Dial(SIP/jan)
exten => jan,2,Hangup
exten => _3.,1