mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
10 years ago | |
|---|---|---|
| .. | ||
| doc | 11 years ago | |
| Makefile | 11 years ago | |
| README | 10 years ago | |
| msrp_cmap.c | 10 years ago | |
| msrp_cmap.h | 11 years ago | |
| msrp_env.c | 11 years ago | |
| msrp_env.h | 11 years ago | |
| msrp_mod.c | 11 years ago | |
| msrp_netio.c | 11 years ago | |
| msrp_netio.h | 11 years ago | |
| msrp_parser.c | 11 years ago | |
| msrp_parser.h | 11 years ago | |
| msrp_vars.c | 11 years ago | |
| msrp_vars.h | 11 years ago | |
README
MSRP Module
Daniel-Constantin Mierla
<miconda@gmail.com>
Edited by
Daniel-Constantin Mierla
<miconda@gmail.com>
Edited by
Alex Balashov
<abalashov@evaristesys.com>
Copyright © 2012 asipto.com
__________________________________________________________________
Table of Contents
1. Admin Guide
1. Overview
2. Dependencies
2.1. Kamailio Modules
2.2. External Libraries or Applications
3. Parameters
3.1. sipmsg (int)
3.2. cmap_size (int)
3.3. timer_interval (int)
3.4. auth_min_expires (int)
3.5. auth_max_expires (int)
3.6. use_path_addr (str)
4. Functions
4.1. msrp_relay()
4.2. msrp_reply(code, text [, hdrs])
4.3. msrp_is_request()
4.4. msrp_is_reply()
4.5. msrp_set_dst(addr, sock)
4.6. msrp_relay_flags(flags)
4.7. msrp_reply_flags(flags)
4.8. msrp_cmap_save()
4.9. msrp_cmap_lookup()
5. Pseudo Variables
6. RPC Commands
6.1. msrp.cmaplist
7. Event Routes
8. Usage
List of Examples
1.1. Set sipmsg parameter
1.2. Set cmap_size parameter
1.3. Set timer_interval parameter
1.4. Set auth_min_expires parameter
1.5. Set auth_max_expires parameter
1.6. Set use_path_addr parameter
1.7. msrp_relay usage
1.8. msrp_reply usage
1.9. msrp_is_request usage
1.10. msrp_is_reply usage
1.11. msrp_set_dst usage
1.12. msrp_relay_flags usage
1.13. msrp_reply_flags usage
1.14. msrp_cmap_save usage
1.15. msrp_cmap_lookup usage
1.16. Event Route (using htable for MSRP connection tracking)
1.17. Event Route (using msrp_cmap_ functions for connection tracking)
Chapter 1. Admin Guide
Table of Contents
1. Overview
2. Dependencies
2.1. Kamailio Modules
2.2. External Libraries or Applications
3. Parameters
3.1. sipmsg (int)
3.2. cmap_size (int)
3.3. timer_interval (int)
3.4. auth_min_expires (int)
3.5. auth_max_expires (int)
3.6. use_path_addr (str)
4. Functions
4.1. msrp_relay()
4.2. msrp_reply(code, text [, hdrs])
4.3. msrp_is_request()
4.4. msrp_is_reply()
4.5. msrp_set_dst(addr, sock)
4.6. msrp_relay_flags(flags)
4.7. msrp_reply_flags(flags)
4.8. msrp_cmap_save()
4.9. msrp_cmap_lookup()
5. Pseudo Variables
6. RPC Commands
6.1. msrp.cmaplist
7. Event Routes
8. Usage
1. Overview
This module provides a MSRP routing engine, a.k.a. MSRP relay. MSRP
(Message Session Relay Protocol) is defined by RFC4975, and the
extensions for an MSRP relay are covered in RFC4976.
A typical use of MSRP is instant messaging sessions initiated via SIP.
Unlike page-mode instant messaging, which is done via the SIP MESSAGE
request, MSRP uses a different communication channel which is
negotiated via INVITE-200 OK-ACK.
However, MSRP is still a text-based protocol. It uses several routing
mechanisms similar to what exists in SIP. Furthermore, MSRP requires
TCP, and recommends TLS for confidentiality and security. In light of
the scalability and performance of Kamailio in handling TCP/TLS, this
module reuses Kamailio's core framework to offer MSRP routing
capabilities. Along with embedded Presence and XCAP servers, Kamailio
now offers a complete solution for SIP beyond VoIP.
One of the main benefits of this module is the ability to reuse all the
other extensions that exist in the SIP server, including accounting,
authentication, authorization to database connectors, security and DoS
attack protections.
Kamailio can handle SIP and MSRP traffic received on the same port; the
appropriate configuration file block being executed based on the type
of message. Therefore, you can use Kamailio as a stand-alone MSRP relay
or you can have an instance handling both SIP and MSRP. Another option
is to configure Kamailio to listen on multiple ports, some of them for
SIP and others for MSRP.
2. Dependencies
2.1. Kamailio Modules
2.2. External Libraries or Applications
2.1. Kamailio Modules
The following modules must be loaded before this module:
* None.
The following modules are required to make proper use of this module:
* tls.
2.2. External Libraries or Applications
The following libraries or applications must be installed before
running Kamailio with this module loaded:
* None
3. Parameters
3.1. sipmsg (int)
3.2. cmap_size (int)
3.3. timer_interval (int)
3.4. auth_min_expires (int)
3.5. auth_max_expires (int)
3.6. use_path_addr (str)
3.1. sipmsg (int)
If set to 1, the module will build a SIP message from MSRP frame
headers, providing it to “event_route[msrp:frame-in]”. All the config
file functions (apart from SIP request relay) that can be used in a
request route block can be used in the MSRP event_route.
Default value is '1'.
Example 1.1. Set sipmsg parameter
...
modparam("msrp", "sipmsg", 1)
...
3.2. cmap_size (int)
The size of connection map table, to be computed as power of 2 (e.g.,
if the value is 4, then the number of slots in map table is 2^4 = 16).
Default value is '0' (no internal map table to be used).
Example 1.2. Set cmap_size parameter
...
modparam("msrp", "cmap_size", 8)
...
3.3. timer_interval (int)
The timer interval in seconds to run the procedure for cleaning expired
connections.
Default value is '60'.
Example 1.3. Set timer_interval parameter
...
modparam("msrp", "timer_interval", 90)
...
3.4. auth_min_expires (int)
The minimum value accepted for the “Expires” header in AUTH requests.
Default value is '60'.
Example 1.4. Set auth_min_expires parameter
...
modparam("msrp", "auth_min_expiresl", 90)
...
3.5. auth_max_expires (int)
The maximum value accepted for “Expires” header in AUTH requests.
Default value is '3600'.
Example 1.5. Set auth_max_expires parameter
...
modparam("msrp", "auth_max_expiresl", 1800)
...
3.6. use_path_addr (str)
The hostname:port to be used when building the Path header.
Default value is NULL (server IP and port are used).
Example 1.6. Set use_path_addr parameter
...
modparam("msrp", "use_path_addr", "msrp.kamailio.org:5061")
...
4. Functions
4.1. msrp_relay()
4.2. msrp_reply(code, text [, hdrs])
4.3. msrp_is_request()
4.4. msrp_is_reply()
4.5. msrp_set_dst(addr, sock)
4.6. msrp_relay_flags(flags)
4.7. msrp_reply_flags(flags)
4.8. msrp_cmap_save()
4.9. msrp_cmap_lookup()
4.1. msrp_relay()
Relay MSRP frame according to the To-Path. This function has to be
executed for each MSRP request or reply that has to be forwarded. Note
that due to nature of the MSRP transport layer, which is reliable
(TCP/TLS), there is no retransmission of MSRP frames.
This function can be used in ANY_ROUTE.
Example 1.7. msrp_relay usage
...
event_route[msrp:frame-in] {
msrp_relay();
}
...
4.2. msrp_reply(code, text [, hdrs])
Send a reply for the current MSRP request, adding optional headers.
The parameter can be a pseudo-variable.
This function can be used in ANY_ROUTE.
Example 1.8. msrp_reply usage
...
event_route[msrp:frame-in] {
msrp_reply("403", "Not allowed");
}
...
4.3. msrp_is_request()
Return true if the MSRP frame is a request.
This function can be used in ANY_ROUTE.
Example 1.9. msrp_is_request usage
...
event_route[msrp:frame-in] {
if(msrp_is_request())
{
msrp_relay();
exit;
}
}
...
4.4. msrp_is_reply()
Return true if the MSRP frame is a reply.
This function can be used in ANY_ROUTE.
Example 1.10. msrp_is_reply usage
...
event_route[msrp:frame-in] {
if(msrp_is_reply())
{
msrp_relay();
exit;
}
}
...
4.5. msrp_set_dst(addr, sock)
Set destination attributes: addr - target address as MSRP URI; sock -
local socket to be used (format 'proto:ip:port').
The parameter can be a pseudo-variable.
This function can be used in ANY_ROUTE.
Example 1.11. msrp_set_dst usage
...
event_route[msrp:frame-in] {
...
msrp_set_dst("msrp://127.0.0.1:8000", "tcp:127.0.0.1:5060");
...
}
...
4.6. msrp_relay_flags(flags)
Set transport layer sending flags for forwarding current MSRP frame;
flags - a bitmask of flags - 1 (don't create a new connection), 2
(close connection after send).
The parameter can be a pseudo-variable.
This function can be used in ANY_ROUTE.
Example 1.12. msrp_relay_flags usage
...
event_route[msrp:frame-in] {
...
msrp_relay_flags("1");
...
}
...
4.7. msrp_reply_flags(flags)
Set transport layer sending flags for replies to the current MSRP
frame; flags - a bitmask of flags - 1 (don't create a new connection),
2 (close connection after send).
The parameter can be a pseudo-variable.
This function can be used in ANY_ROUTE.
Example 1.13. msrp_reply_flags usage
...
event_route[msrp:frame-in] {
...
msrp_reply_flags("1");
...
}
...
4.8. msrp_cmap_save()
Save details of a MSRP connection upon AUTH request inside the internal
map table, indexed by session id.
This function can be used in ANY_ROUTE.
Example 1.14. msrp_cmap_save usage
...
event_route[msrp:frame-in] {
...
if(method=="AUTH") { msrp_cmap_save(); exit; }
...
}
...
4.9. msrp_cmap_lookup()
Lookup MSRP connection details for current session id.
This function can be used in ANY_ROUTE.
Example 1.15. msrp_cmap_lookup usage
...
event_route[msrp:frame-in] {
...
if(method=="SEND" and $msrp(nexthops)==1) {
if(msrp_cmap_lookup()) {
msrp_relay();
} else {
msrp_reply("481", "Session not found");
}
}
...
}
...
5. Pseudo Variables
The module exports a pseudo-variable class, $msrp(key), to access the
MSRP frame (e.g. first line attributes, body, all frame content).
The module exports a transformations class, 'msrpuri', to allow access
attributes of a MSRP URI.
These are documented in the appropriate Wiki pages hosted on the
project web site.
6. RPC Commands
6.1. msrp.cmaplist
6.1. msrp.cmaplist
List active MSRP connections.
Example:
...
kamcmd msrp.cmaplist
...
7. Event Routes
For each MSRP frame received from the network, the module executes
event_route[msrp:frame-in] block in the config file.
8. Usage
When the sipmsg parameter is set to 1 (which is the default), the
module internally builds a SIP request from the MSRP frame and exposes
it to the config file interpreter. This way, all the functions that are
valid for SIP requests can be used safely in
event_route[msrp:frame-in].
To build the SIP request, the module takes the first line and the
headers from an MSRP message and appends them to a static buffer. The
next two examples show an MSRP frame and the resulting SIP request.
...
MSRP 6aef SEND
To-Path: msrps://a.example.org:9000/kjfjan;tcp \
msrps://b.example.net:9000/aeiug;tcp \
msrps://bob.example.net:8145/foo;tcp
From-Path: msrps://alice.example.org:7965/bar;tcp
Success-Report: yes
Byte-Range: 1-*/*
Message-ID: 87652
Content-Type: text/plain
Hi Bob, I'm about to send you a photo.
-------6aef$
...
...
MSRP sip:a@127.0.0.1 SIP/2.0
Via: SIP/2.0/UDP 127.0.0.1:9;branch=z9hG4bKa
From: <b@127.0.0.1>;tag=a
To: <a@127.0.0.1>
Call-ID: a
CSeq: 1 MSRP
Content-Length: 0
MSRP-First-Line: MSRP 6aef SEND
To-Path: msrps://a.example.org:9000/kjfjan;tcp \
msrps://b.example.net:9000/aeiug;tcp \
msrps://bob.example.net:8145/foo;tcp
From-Path: msrps://alice.example.org:7965/bar;tcp
Success-Report: yes
Byte-Range: 1-*/*
Message-ID: 87652
Content-Type: text/plain
...
Note that MSRP does not permit line folding. A "\" in the examples
shows a line continuation due to the limitations of line length of this
document. Neither the backslash nor the extra CRLF is included in the
actual request or response.
As can be observed, the MSRP frame content starts with the body of the
'MSRP-First-Line:' header. Using static content to get to a valid SIP
request is a perfect trade-off for performance.
Besides the option to access parts of MSRP frame via an
internally-built SIP message, the module exports a new pseudo-variable
class $msrp(key) which returns attributes from the MSRP frame. There is
also a new transformation, {msrpuri.key}, to get access to parts of an
MSRP URI. See the appropriate Wiki pages on the project's web site for
full details about new pseudo-variable and transformation classes.
Next is an example of configuration file with the routing block for
MSRP frames. In this config, the SIP traffic is rejected.
Example 1.16. Event Route (using htable for MSRP connection tracking)
...
#!KAMAILIO
debug=2
memdbg=5
memlog=5
children=4
log_stderror=yes
auto_aliases=no
tcp_accept_no_cl=yes
tcp_connection_lifetime=1810
listen=127.0.0.1:5060
mpath="modules_k/:modules/"
loadmodule "sl.so"
loadmodule "kex.so"
loadmodule "mi_fifo.so"
loadmodule "ctl.so"
loadmodule "msrp.so"
loadmodule "pv.so"
loadmodule "auth.so"
loadmodule "cfgutils.so"
loadmodule "htable.so"
loadmodule "xlog.so"
modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo")
modparam("auth", "nonce_count", 1)
modparam("auth", "qop", "auth")
#!substdef "!MSRP_MIN_EXPIRES!1800!g"
#!substdef "!MSRP_MAX_EXPIRES!3600!g"
modparam("htable", "htable", "msrp=>size=8;autoexpire=MSRP_MAX_EXPIRES;")
request_route {
sl_send_reply("403", "No SIP Here");
exit;
}
reply_route {
drop;
}
event_route[msrp:frame-in] {
xdbg("============#[[$msrp(method)]]===========\n");
xdbg("============*[[$si:$sp]]\n");
xdbg("============ crthop: [$msrp(crthop)]\n");
xdbg("============ prevhop: [$msrp(prevhop)]\n");
xdbg("============ nexthop: [$msrp(nexthop)]\n");
xdbg("============ firsthop: [$msrp(firsthop)]\n");
xdbg("============ lasthop: [$msrp(lasthop)]\n");
xdbg("============ prevhops: [$msrp(prevhops)]\n");
xdbg("============ nexthops: [$msrp(nexthops)]\n");
xdbg("============ srcaddr: [$msrp(srcaddr)]\n");
xdbg("============ srcsock: [$msrp(srcsock)]\n");
xdbg("============ sessid: [$msrp(sessid)]\n");
msrp_reply_flags("1");
if(msrp_is_reply())
{
msrp_relay();
}
else if($msrp(method)=="AUTH")
{
if($msrp(nexthops)>0)
{
msrp_relay();
exit;
}
# frame for local server - send Use-Path
# -- passwd can be loaded from DB based on $au
$var(passwd) = "xyz123";
if(!pv_www_authenticate("myrealm", "$var(passwd)", "0",
"$msrp(method)"))
{
if(auth_get_www_authenticate("myrealm", "1",
"$var(wauth)"))
{
msrp_reply("401", "Unauthorized",
"$var(wauth)");
} else {
msrp_reply("500", "Server Error");
}
exit;
}
if ($hdr(Expires) != $null) {
$var(expires) = (int) $hdr(Expires);
if ($var(expires) < MSRP_MIN_EXPIRES) {
msrp_reply("423", "Interval Out-of-Bounds",
"Min-Expires: MSRP_MIN_EXPIRES\r\n");
exit;
} else {
msrp_reply("423", "Interval Out-of-Bounds",
"Max-Expires: MSRP_MAX_EXPIRES\r\n");
exit;
}
} else
$var(expires) = MSRP_MAX_EXPIRES;
$var(cnt) = $var(cnt) + 1;
pv_printf("$var(sessid)", "s.$(pp).$(var(cnt)).$(RANDOM)");
$sht(msrp=>$var(sessid)::srcaddr) = $msrp(srcaddr);
$sht(msrp=>$var(sessid)::srcsock) = $msrp(srcsock);
$shtex(msrp=>$var(sessid)) = $var(expires) + 5;
# - Use-Path: the MSRP address for server + session id
$var(headers) = "Use-Path: msrp://127.0.0.1:5060/"
+ $var(sessid) + ";tcp\r\n"
+ "Expires: " + $var(expires) + "\r\n";
msrp_reply("200", "OK", "$var(headers)");
}
else if($msrp(method)=="SEND" || $msrp(method)=="REPORT")
{
if($msrp(nexthops)>1)
{
if ($msrp(method)!="REPORT")
{
msrp_reply("200", "OK");
}
msrp_relay();
exit;
}
$var(sessid) = $msrp(sessid);
if($sht(msrp=>$var(sessid)::srcaddr) == $null)
{
# one more hop, but we don't have address in htable
if ($msrp(method)!="REPORT")
{
msrp_reply("481", "Session-does-not-exist");
}
exit;
}
else if($msrp(method)!="REPORT")
{
msrp_reply("200", "OK");
}
msrp_relay_flags("1");
msrp_set_dst("$sht(msrp=>$var(sessid)::srcaddr)",
"$sht(msrp=>$var(sessid)::srcsock)");
msrp_relay();
}
else
{
msrp_reply("501", "Request-method-not-understood");
}
}
...
Example 1.17. Event Route (using msrp_cmap_ functions for connection
tracking)
...
#!KAMAILIO
debug=2
memdbg=5
memlog=5
children=4
log_stderror=yes
auto_aliases=no
tcp_accept_no_cl=yes
tcp_connection_lifetime=1810
listen=127.0.0.1:5060
mpath="modules_k/:modules/"
loadmodule "sl.so"
loadmodule "kex.so"
loadmodule "mi_fifo.so"
loadmodule "ctl.so"
loadmodule "msrp.so"
loadmodule "pv.so"
loadmodule "auth.so"
loadmodule "cfgutils.so"
loadmodule "xlog.so"
modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo")
modparam("auth", "nonce_count", 1)
modparam("auth", "qop", "auth")
modparam("msrp", "cmap_size", 8)
modparam("msrp", "use_path_addr", "msrp://127.0.0.1:5060")
request_route {
sl_send_reply("403", "No SIP Here");
exit;
}
reply_route {
drop;
}
event_route[msrp:frame-in] {
xdbg("============#[[$msrp(method)]]===========\n");
xdbg("============*[[$si:$sp]]\n");
xdbg("============ crthop: [$msrp(crthop)]\n");
xdbg("============ prevhop: [$msrp(prevhop)]\n");
xdbg("============ nexthop: [$msrp(nexthop)]\n");
xdbg("============ firsthop: [$msrp(firsthop)]\n");
xdbg("============ lasthop: [$msrp(lasthop)]\n");
xdbg("============ prevhops: [$msrp(prevhops)]\n");
xdbg("============ nexthops: [$msrp(nexthops)]\n");
xdbg("============ srcaddr: [$msrp(srcaddr)]\n");
xdbg("============ srcsock: [$msrp(srcsock)]\n");
xdbg("============ sessid: [$msrp(sessid)]\n");
msrp_reply_flags("1");
if (msrp_is_reply())
{
msrp_relay();
}
else if($msrp(method)=="AUTH")
{
if($msrp(nexthops)>0)
{
msrp_relay();
exit;
}
# frame for local server - send Use-Path
# -- passwd can be loaded from DB based on $au
$var(passwd) = "xyz123";
if(!pv_www_authenticate("myrealm", "$var(passwd)", "0",
"$msrp(method)"))
{
if(auth_get_www_authenticate("myrealm", "1",
"$var(wauth)"))
{
msrp_reply("401", "Unauthorized",
"$var(wauth)");
} else {
msrp_reply("500", "Server Error");
}
exit;
}
msrp_cmap_save();
}
else if ($msrp(method)=="SEND" || $msrp(method)=="REPORT")
{
if ($msrp(nexthops)>1)
{
if ($msrp(method)!="REPORT")
{
msrp_reply("200", "OK");
}
msrp_relay();
exit;
}
if (msrp_cmap_lookup())
{
if ($msrp(method)!="REPORT")
{
msrp_reply("200", "OK");
}
msrp_relay_flags("1");
msrp_relay();
}
else
{
msrp_reply("481", "Session-does-not-exist");
}
}
else
{
msrp_reply("501", "Request-method-not-understood");
}
}
...