1<?xml version="1.0" encoding='ISO-8859-1'?>
2<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
3"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
4
5<!-- Include general documentation entities -->
6<!ENTITY % docentities SYSTEM "../../../../doc/docbook/entities.xml">
7%docentities;
8
9]>
10<!-- Module User's Guide -->
11
12<chapter>
13
14	<title>&adminguide;</title>
15
16	<section id="msrp.overview">
17	<title>Overview</title>
18	<para>
19		This module provides a MSRP routing engine, a.k.a. MSRP relay.
20		MSRP (Message Session Relay Protocol) is defined by RFC4975,
21		and the extensions for an MSRP relay are covered in RFC4976.
22	</para>
23	<para>
24		A typical use of MSRP is instant messaging sessions initiated
25		via SIP. Unlike page-mode instant messaging, which is done via the SIP
26		MESSAGE request, MSRP uses a different communication channel which
27		is negotiated via INVITE-200 OK-ACK.
28	</para>
29	<para>
30		However, MSRP is still a text-based protocol. It uses several routing
31		mechanisms similar to what exists in SIP. Furthermore,
32		MSRP requires TCP, and recommends TLS for confidentiality and security.
33		In light of the scalability and performance of &kamailio; in handling
34		TCP/TLS, this module reuses &kamailio;'s core framework to
35		offer MSRP routing capabilities. Along with embedded Presence and XCAP
36		servers, &kamailio; now offers a complete solution for SIP beyond VoIP.
37	</para>
38	<para>
39		One of the main benefits of this module is the ability to reuse
40		all the other extensions that exist in the SIP server, including
41	        accounting, authentication, authorization to database connectors,
42		security and DoS attack protections.
43	</para>
44	<para>
45		&kamailio; can handle SIP and MSRP traffic received on the same port;
46		the appropriate configuration file block being executed based on the
47		type of message. Therefore, you can use &kamailio; as a stand-alone
48		MSRP relay or you can have an instance handling both SIP and MSRP. Another
49		option is to configure &kamailio; to listen on multiple ports, some
50		of them for SIP and others for MSRP.
51	</para>
52	</section>
53
54	<section>
55	<title>Dependencies</title>
56	<section>
57		<title>&kamailio; Modules</title>
58		<para>
59		The following modules must be loaded before this module:
60			<itemizedlist>
61			<listitem>
62			<para>
63				<emphasis>None</emphasis>.
64			</para>
65			</listitem>
66			</itemizedlist>
67		</para>
68		<para>
69		The following modules are required to make proper use of this
70		module:
71			<itemizedlist>
72			<listitem>
73			<para>
74				<emphasis>tls</emphasis>.
75			</para>
76			</listitem>
77			</itemizedlist>
78		</para>
79	</section>
80	<section>
81		<title>External Libraries or Applications</title>
82		<para>
83		The following libraries or applications must be installed before running
84		&kamailio; with this module loaded:
85			<itemizedlist>
86			<listitem>
87			<para>
88				<emphasis>None</emphasis>
89			</para>
90			</listitem>
91			</itemizedlist>
92		</para>
93	</section>
94	</section>
95	<section>
96	<title>Parameters</title>
97	<section id="msrp.p.sipmsg">
98		<title><varname>sipmsg</varname> (int)</title>
99		<para>
100			If set to 1, the module will build a SIP message from MSRP frame headers,
101			providing it to <quote>event_route[msrp:frame-in]</quote>.
102			All the config file functions (apart from SIP request relay) that can be used
103			in a request route block can be used in the MSRP event_route.
104		</para>
105		<para>
106		<emphasis>
107			Default value is '1'.
108		</emphasis>
109		</para>
110		<example>
111		<title>Set <varname>sipmsg</varname> parameter</title>
112		<programlisting format="linespecific">
113...
114modparam("msrp", "sipmsg", 1)
115...
116</programlisting>
117		</example>
118	</section>
119	<section id="msrp.p.cmap_size">
120		<title><varname>cmap_size</varname> (int)</title>
121		<para>
122		The size of connection map table, to be computed as power of 2 (e.g.,
123		if the value is 4, then the number of slots in map table is 2^4 = 16).
124		</para>
125		<para>
126		<emphasis>
127			Default value is '0' (no internal map table to be used).
128		</emphasis>
129		</para>
130		<example>
131		<title>Set <varname>cmap_size</varname> parameter</title>
132		<programlisting format="linespecific">
133...
134modparam("msrp", "cmap_size", 8)
135...
136</programlisting>
137		</example>
138	</section>
139	<section id="msrp.p.timer_interval">
140		<title><varname>timer_interval</varname> (int)</title>
141		<para>
142		The timer interval in seconds to run the procedure for cleaning
143		expired connections.
144		</para>
145		<para>
146		<emphasis>
147			Default value is '60'.
148		</emphasis>
149		</para>
150		<example>
151		<title>Set <varname>timer_interval</varname> parameter</title>
152		<programlisting format="linespecific">
153...
154modparam("msrp", "timer_interval", 90)
155...
156</programlisting>
157		</example>
158	</section>
159	<section id="msrp.p.auth_min_expires">
160		<title><varname>auth_min_expires</varname> (int)</title>
161		<para>
162		The minimum value accepted for the <quote>Expires</quote> header in AUTH requests.
163		</para>
164		<para>
165		<emphasis>
166			Default value is '60'.
167		</emphasis>
168		</para>
169		<example>
170		<title>Set <varname>auth_min_expires</varname> parameter</title>
171		<programlisting format="linespecific">
172...
173modparam("msrp", "auth_min_expiresl", 90)
174...
175</programlisting>
176		</example>
177	</section>
178	<section id="msrp.p.auth_max_expires">
179		<title><varname>auth_max_expires</varname> (int)</title>
180		<para>
181		The maximum value accepted for <quote>Expires</quote> header in AUTH requests.
182		</para>
183		<para>
184		<emphasis>
185			Default value is '3600'.
186		</emphasis>
187		</para>
188		<example>
189		<title>Set <varname>auth_max_expires</varname> parameter</title>
190		<programlisting format="linespecific">
191...
192modparam("msrp", "auth_max_expiresl", 1800)
193...
194</programlisting>
195		</example>
196	</section>
197	<section id="msrp.p.use_path_addr">
198		<title><varname>use_path_addr</varname> (str)</title>
199		<para>
200		The hostname:port to be used when building the Path header.
201		</para>
202		<para>
203		<emphasis>
204			Default value is NULL (server IP and port are used).
205		</emphasis>
206		</para>
207		<example>
208		<title>Set <varname>use_path_addr</varname> parameter</title>
209		<programlisting format="linespecific">
210...
211modparam("msrp", "use_path_addr", "msrp.kamailio.org:5061")
212...
213</programlisting>
214		</example>
215	</section>
216	<section id="msrp.p.event_callback">
217		<title><varname>event_callback</varname> (str)</title>
218		<para>
219			The name of the function in the kemi configuration file (embedded
220			scripting language such as Lua, Python, ...) to be executed instead
221			of event_route[...] blocks.
222		</para>
223		<para>
224			The function receives a string parameter with the name of the event,
225			the values can be: 'msrp:frame-in'.
226		</para>
227		<para>
228		<emphasis>
229			Default value is 'empty' (no function is executed for events).
230		</emphasis>
231		</para>
232		<example>
233		<title>Set <varname>event_callback</varname> parameter</title>
234		<programlisting format="linespecific">
235...
236modparam("msrp", "event_callback", "ksr_msrp_event")
237...
238-- event callback function implemented in Lua
239function ksr_msrp_event(evname)
240	KSR.info("===== msrp module triggered event: " .. evname .. "\n");
241	return 1;
242end
243...
244</programlisting>
245		</example>
246	</section>
247	</section>
248
249	<section>
250	<title>Functions</title>
251	<section id="msrp.f.msrp_relay">
252	    <title>
253		<function moreinfo="none">msrp_relay()</function>
254	    </title>
255	    <para>
256			Relay MSRP frame according to the To-Path. This function has to be
257			executed for each MSRP request or reply that has to be forwarded. Note
258			that due to nature of the MSRP transport layer, which is reliable
259			(TCP/TLS), there is no retransmission of MSRP frames.
260		</para>
261
262		<para>
263		This function can be used in ANY_ROUTE.
264		</para>
265		<example>
266		<title><function>msrp_relay</function> usage</title>
267		<programlisting format="linespecific">
268...
269event_route[msrp:frame-in] {
270    msrp_relay();
271}
272...
273</programlisting>
274	    </example>
275	</section>
276
277	<section id="msrp.f.msrp_reply">
278	    <title>
279		<function moreinfo="none">msrp_reply(code, text [, hdrs])</function>
280	    </title>
281	    <para>
282		Send a reply for the current MSRP request, adding optional headers.
283		</para>
284		<para>
285		The parameter can be a pseudo-variable.
286		</para>
287		<para>
288		This function can be used in ANY_ROUTE.
289		</para>
290		<example>
291		<title><function>msrp_reply</function> usage</title>
292		<programlisting format="linespecific">
293...
294event_route[msrp:frame-in] {
295    msrp_reply("403", "Not allowed");
296}
297...
298</programlisting>
299	    </example>
300	</section>
301
302	<section id="msrp.f.msrp_is_request">
303	    <title>
304		<function moreinfo="none">msrp_is_request()</function>
305	    </title>
306	    <para>
307			Return true if the MSRP frame is a request.
308		</para>
309		<para>
310		This function can be used in ANY_ROUTE.
311		</para>
312		<example>
313		<title><function>msrp_is_request</function> usage</title>
314		<programlisting format="linespecific">
315...
316event_route[msrp:frame-in] {
317    if(msrp_is_request())
318    {
319        msrp_relay();
320        exit;
321    }
322}
323...
324</programlisting>
325	    </example>
326	</section>
327
328
329	<section id="msrp.f.msrp_is_reply">
330	    <title>
331		<function moreinfo="none">msrp_is_reply()</function>
332	    </title>
333	    <para>
334			Return true if the MSRP frame is a reply.
335		</para>
336		<para>
337		This function can be used in ANY_ROUTE.
338		</para>
339		<example>
340		<title><function>msrp_is_reply</function> usage</title>
341		<programlisting format="linespecific">
342...
343event_route[msrp:frame-in] {
344    if(msrp_is_reply())
345    {
346        msrp_relay();
347        exit;
348    }
349}
350...
351</programlisting>
352	    </example>
353	</section>
354
355	<section id="msrp.f.msrp_set_dst">
356	    <title>
357		<function moreinfo="none">msrp_set_dst(addr, sock)</function>
358	    </title>
359	    <para>
360		Set destination attributes: addr - target address as MSRP URI;
361		sock - local socket to be used (format 'proto:ip:port').
362		</para>
363		<para>
364		The parameter can be a pseudo-variable.
365		</para>
366		<para>
367		This function can be used in ANY_ROUTE.
368		</para>
369		<example>
370		<title><function>msrp_set_dst</function> usage</title>
371		<programlisting format="linespecific">
372...
373event_route[msrp:frame-in] {
374    ...
375    msrp_set_dst("msrp://127.0.0.1:8000", "tcp:127.0.0.1:5060");
376    ...
377}
378...
379</programlisting>
380	    </example>
381	</section>
382
383	<section id="msrp.f.msrp_relay_flags">
384	    <title>
385		<function moreinfo="none">msrp_relay_flags(flags)</function>
386	    </title>
387	    <para>
388		Set transport layer sending flags for forwarding current MSRP frame;
389		flags - a bitmask of flags - 1 (don't create a new connection), 2
390		(close connection after send).
391		</para>
392		<para>
393		The parameter can be a pseudo-variable.
394		</para>
395		<para>
396		This function can be used in ANY_ROUTE.
397		</para>
398		<example>
399		<title><function>msrp_relay_flags</function> usage</title>
400		<programlisting format="linespecific">
401...
402event_route[msrp:frame-in] {
403    ...
404    msrp_relay_flags("1");
405    ...
406}
407...
408</programlisting>
409	    </example>
410	</section>
411
412	<section id="msrp.f.msrp_reply_flags">
413	    <title>
414		<function moreinfo="none">msrp_reply_flags(flags)</function>
415	    </title>
416	    <para>
417		Set transport layer sending flags for replies to the current MSRP frame;
418		flags - a bitmask of flags - 1 (don't create a new connection),
419		2 (close connection after send).
420		</para>
421		<para>
422		The parameter can be a pseudo-variable.
423		</para>
424		<para>
425		This function can be used in ANY_ROUTE.
426		</para>
427		<example>
428		<title><function>msrp_reply_flags</function> usage</title>
429		<programlisting format="linespecific">
430...
431event_route[msrp:frame-in] {
432    ...
433    msrp_reply_flags("1");
434    ...
435}
436...
437</programlisting>
438	    </example>
439	</section>
440
441	<section id="msrp.f.msrp_cmap_save">
442	    <title>
443		<function moreinfo="none">msrp_cmap_save()</function>
444	    </title>
445	    <para>
446		Save details of a MSRP connection upon AUTH request inside
447		the internal map table, indexed by session id.
448		</para>
449		<para>
450		This function can be used in ANY_ROUTE.
451		</para>
452		<example>
453		<title><function>msrp_cmap_save</function> usage</title>
454		<programlisting format="linespecific">
455...
456event_route[msrp:frame-in] {
457    ...
458	if(method=="AUTH") { msrp_cmap_save(); exit; }
459    ...
460}
461...
462</programlisting>
463	    </example>
464	</section>
465
466	<section id="msrp.f.msrp_cmap_lookup">
467	    <title>
468		<function moreinfo="none">msrp_cmap_lookup()</function>
469	    </title>
470	    <para>
471		Lookup MSRP connection details for current session id.
472		</para>
473		<para>
474		This function can be used in ANY_ROUTE.
475		</para>
476		<example>
477		<title><function>msrp_cmap_lookup</function> usage</title>
478		<programlisting format="linespecific">
479...
480event_route[msrp:frame-in] {
481    ...
482	if(method=="SEND" and $msrp(nexthops)==1) {
483		if(msrp_cmap_lookup()) {
484			msrp_relay();
485		} else {
486			msrp_reply("481", "Session not found");
487		}
488	}
489    ...
490}
491...
492</programlisting>
493	    </example>
494	</section>
495
496	</section>
497
498	<section>
499		<title>Pseudo Variables</title>
500		<para>
501			The module exports a pseudo-variable class, $msrp(key), to access
502			the MSRP frame (e.g. first line attributes, body, all frame
503			content).
504		</para>
505		<para>
506			The module exports a transformations class, 'msrpuri', to allow
507			access attributes of a MSRP URI.
508		</para>
509		<para>
510			These are documented in the appropriate Wiki pages hosted on the
511			project web site.
512		</para>
513	</section>
514
515	<section>
516	<title>RPC Commands</title>
517	<section id="msrp.r.msrp.cmaplist">
518		<title>
519		<function moreinfo="none">msrp.cmaplist</function>
520		</title>
521		<para>
522		List active MSRP connections.
523		</para>
524		<para>
525		Example:
526		</para>
527<programlisting  format="linespecific">
528...
529&sercmd; msrp.cmaplist
530...
531</programlisting>
532    </section>
533    </section>
534
535	<section>
536		<title>Event Routes</title>
537		<para>
538			For each MSRP frame received from the network, the module executes
539			event_route[msrp:frame-in] block in the config file.
540		</para>
541	</section>
542
543	<section id="msrp.usage">
544		<title>Usage</title>
545		<para>
546			When the <varname>sipmsg</varname> parameter is set to 1 (which is the
547			default), the module internally builds a SIP request from the MSRP frame
548			and exposes it to the config file interpreter. This way, all the functions
549			that are valid for SIP requests can be used safely in event_route[msrp:frame-in].
550		</para>
551		<para>
552			To build the SIP request, the module takes the first line and the
553			headers from an MSRP message and appends them to a static buffer. The
554			next two examples show an MSRP frame and the resulting SIP request.
555		</para>
556		<programlisting format="linespecific">
557<![CDATA[
558...
559MSRP 6aef SEND
560To-Path: msrps://a.example.org:9000/kjfjan;tcp \
561  msrps://b.example.net:9000/aeiug;tcp \
562  msrps://bob.example.net:8145/foo;tcp
563From-Path: msrps://alice.example.org:7965/bar;tcp
564Success-Report: yes
565Byte-Range: 1-*/*
566Message-ID: 87652
567Content-Type: text/plain
568
569Hi Bob, I'm about to send you a photo.
570-------6aef$
571...
572]]>
573</programlisting>
574
575		<programlisting format="linespecific">
576<![CDATA[
577...
578MSRP sip:a@127.0.0.1 SIP/2.0
579Via: SIP/2.0/UDP 127.0.0.1:9;branch=z9hG4bKa
580From: <b@127.0.0.1>;tag=a
581To: <a@127.0.0.1>
582Call-ID: a
583CSeq: 1 MSRP
584Content-Length: 0
585MSRP-First-Line: MSRP 6aef SEND
586To-Path: msrps://a.example.org:9000/kjfjan;tcp \
587  msrps://b.example.net:9000/aeiug;tcp \
588  msrps://bob.example.net:8145/foo;tcp
589From-Path: msrps://alice.example.org:7965/bar;tcp
590Success-Report: yes
591Byte-Range: 1-*/*
592Message-ID: 87652
593Content-Type: text/plain
594
595...
596]]>
597</programlisting>
598		<para>
599			Note that MSRP does not permit line folding.  A "\" in the examples
600			shows a line continuation due to the limitations of line length of this
601			document.  Neither the backslash nor the extra CRLF is included in
602			the actual request or response.
603		</para>
604		<para>
605			As can be observed, the MSRP frame content starts with the body
606			of the 'MSRP-First-Line:' header. Using static content to get to a
607			valid SIP request is a perfect trade-off for performance.
608		</para>
609		<para>
610			Besides the option to access parts of MSRP frame via an
611			internally-built SIP message, the module exports a new pseudo-variable
612			class $msrp(key) which returns attributes from the MSRP frame. There is
613			also a new transformation, {msrpuri.key}, to get access to parts
614			of an MSRP URI. See the appropriate Wiki pages on the project's
615			web site for full details about new pseudo-variable and
616			transformation classes.
617		</para>
618		<para>
619			Next is an example of configuration file with the routing block
620			for MSRP frames. In this config, the SIP traffic is rejected.
621		</para>
622		<example>
623		<title>Event Route (using htable for MSRP connection tracking)</title>
624		<programlisting format="linespecific">
625...
626<![CDATA[
627#!KAMAILIO
628
629debug=2
630memdbg=5
631memlog=5
632
633children=4
634
635log_stderror=yes
636auto_aliases=no
637
638tcp_accept_no_cl=yes
639tcp_connection_lifetime=1810
640
641listen=127.0.0.1:5060
642
643mpath="modules_k/:modules/"
644
645loadmodule "sl.so"
646loadmodule "kex.so"
647loadmodule "mi_fifo.so"
648loadmodule "ctl.so"
649loadmodule "msrp.so"
650loadmodule "pv.so"
651loadmodule "auth.so"
652loadmodule "cfgutils.so"
653loadmodule "htable.so"
654loadmodule "xlog.so"
655
656modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo")
657
658modparam("auth", "nonce_count", 1)
659modparam("auth", "qop", "auth")
660
661#!substdef "!MSRP_MIN_EXPIRES!1800!g"
662#!substdef "!MSRP_MAX_EXPIRES!3600!g"
663modparam("htable", "htable", "msrp=>size=8;autoexpire=MSRP_MAX_EXPIRES;")
664
665request_route {
666	sl_send_reply("403", "No SIP Here");
667	exit;
668}
669
670reply_route {
671	drop;
672}
673
674event_route[msrp:frame-in] {
675	xdbg("============#[[$msrp(method)]]===========\n");
676	xdbg("============*[[$si:$sp]]\n");
677	xdbg("============ crthop:   [$msrp(crthop)]\n");
678	xdbg("============ prevhop:  [$msrp(prevhop)]\n");
679	xdbg("============ nexthop:  [$msrp(nexthop)]\n");
680	xdbg("============ firsthop: [$msrp(firsthop)]\n");
681	xdbg("============ lasthop:  [$msrp(lasthop)]\n");
682	xdbg("============ prevhops: [$msrp(prevhops)]\n");
683	xdbg("============ nexthops: [$msrp(nexthops)]\n");
684	xdbg("============ srcaddr:  [$msrp(srcaddr)]\n");
685	xdbg("============ srcsock:  [$msrp(srcsock)]\n");
686	xdbg("============ sessid:   [$msrp(sessid)]\n");
687
688	msrp_reply_flags("1");
689
690	if(msrp_is_reply())
691	{
692		msrp_relay();
693	}
694	else if($msrp(method)=="AUTH")
695	{
696		if($msrp(nexthops)>0)
697		{
698			msrp_relay();
699			exit;
700		}
701
702		# frame for local server - send Use-Path
703		# -- passwd can be loaded from DB based on $au
704		$var(passwd) = "xyz123";
705		if(!pv_www_authenticate("myrealm", "$var(passwd)", "0",
706					"$msrp(method)"))
707		{
708			if(auth_get_www_authenticate("myrealm", "1",
709							"$var(wauth)"))
710			{
711				msrp_reply("401", "Unauthorized",
712						"$var(wauth)");
713			} else {
714				msrp_reply("500", "Server Error");
715			}
716			exit;
717		}
718
719		if ($hdr(Expires) != $null) {
720			$var(expires) = (int) $hdr(Expires);
721			if ($var(expires) < MSRP_MIN_EXPIRES) {
722				msrp_reply("423", "Interval Out-of-Bounds",
723					"Min-Expires: MSRP_MIN_EXPIRES\r\n");
724				exit;
725			} else {
726				msrp_reply("423", "Interval Out-of-Bounds",
727					"Max-Expires: MSRP_MAX_EXPIRES\r\n");
728				exit;
729			}
730
731		} else
732			$var(expires) = MSRP_MAX_EXPIRES;
733
734		$var(cnt) = $var(cnt) + 1;
735		pv_printf("$var(sessid)", "s.$(pp).$(var(cnt)).$(RANDOM)");
736		$sht(msrp=>$var(sessid)::srcaddr) = $msrp(srcaddr);
737		$sht(msrp=>$var(sessid)::srcsock) = $msrp(srcsock);
738		$shtex(msrp=>$var(sessid)) = $var(expires) + 5;
739		# - Use-Path: the MSRP address for server + session id
740		$var(headers) = "Use-Path: msrp://127.0.0.1:5060/"
741				+ $var(sessid) + ";tcp\r\n"
742				+ "Expires: " + $var(expires) + "\r\n";
743		msrp_reply("200", "OK", "$var(headers)");
744	}
745	else if($msrp(method)=="SEND" || $msrp(method)=="REPORT")
746	{
747		if($msrp(nexthops)>1)
748		{
749			if ($msrp(method)!="REPORT")
750			{
751				msrp_reply("200", "OK");
752			}
753			msrp_relay();
754			exit;
755		}
756		$var(sessid) = $msrp(sessid);
757		if($sht(msrp=>$var(sessid)::srcaddr) == $null)
758		{
759			# one more hop, but we don't have address in htable
760			if ($msrp(method)!="REPORT")
761			{
762				msrp_reply("481", "Session-does-not-exist");
763			}
764			exit;
765		}
766		else if($msrp(method)!="REPORT")
767		{
768			msrp_reply("200", "OK");
769		}
770		msrp_relay_flags("1");
771		msrp_set_dst("$sht(msrp=>$var(sessid)::srcaddr)",
772				"$sht(msrp=>$var(sessid)::srcsock)");
773		msrp_relay();
774	}
775	else
776	{
777		msrp_reply("501", "Request-method-not-understood");
778	}
779}
780]]>
781...
782</programlisting>
783		</example>
784		<example>
785		<title>Event Route (using msrp_cmap_ functions for connection tracking)</title>
786		<programlisting format="linespecific">
787...
788<![CDATA[
789#!KAMAILIO
790
791debug=2
792memdbg=5
793memlog=5
794
795children=4
796
797log_stderror=yes
798auto_aliases=no
799
800tcp_accept_no_cl=yes
801tcp_connection_lifetime=1810
802
803listen=127.0.0.1:5060
804
805mpath="modules_k/:modules/"
806
807loadmodule "sl.so"
808loadmodule "kex.so"
809loadmodule "mi_fifo.so"
810loadmodule "ctl.so"
811loadmodule "msrp.so"
812loadmodule "pv.so"
813loadmodule "auth.so"
814loadmodule "cfgutils.so"
815loadmodule "xlog.so"
816
817modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo")
818
819modparam("auth", "nonce_count", 1)
820modparam("auth", "qop", "auth")
821
822modparam("msrp", "cmap_size", 8)
823modparam("msrp", "use_path_addr", "msrp://127.0.0.1:5060")
824
825request_route {
826	sl_send_reply("403", "No SIP Here");
827	exit;
828}
829
830reply_route {
831	drop;
832}
833
834event_route[msrp:frame-in] {
835	xdbg("============#[[$msrp(method)]]===========\n");
836	xdbg("============*[[$si:$sp]]\n");
837	xdbg("============ crthop:   [$msrp(crthop)]\n");
838	xdbg("============ prevhop:  [$msrp(prevhop)]\n");
839	xdbg("============ nexthop:  [$msrp(nexthop)]\n");
840	xdbg("============ firsthop: [$msrp(firsthop)]\n");
841	xdbg("============ lasthop:  [$msrp(lasthop)]\n");
842	xdbg("============ prevhops: [$msrp(prevhops)]\n");
843	xdbg("============ nexthops: [$msrp(nexthops)]\n");
844	xdbg("============ srcaddr:  [$msrp(srcaddr)]\n");
845	xdbg("============ srcsock:  [$msrp(srcsock)]\n");
846	xdbg("============ sessid:   [$msrp(sessid)]\n");
847
848	msrp_reply_flags("1");
849
850	if (msrp_is_reply())
851	{
852		msrp_relay();
853	}
854	else if($msrp(method)=="AUTH")
855	{
856		if($msrp(nexthops)>0)
857		{
858			msrp_relay();
859			exit;
860		}
861
862		# frame for local server - send Use-Path
863		# -- passwd can be loaded from DB based on $au
864		$var(passwd) = "xyz123";
865		if(!pv_www_authenticate("myrealm", "$var(passwd)", "0",
866					"$msrp(method)"))
867		{
868			if(auth_get_www_authenticate("myrealm", "1",
869							"$var(wauth)"))
870			{
871				msrp_reply("401", "Unauthorized",
872						"$var(wauth)");
873			} else {
874				msrp_reply("500", "Server Error");
875			}
876			exit;
877		}
878
879		msrp_cmap_save();
880	}
881	else if ($msrp(method)=="SEND" || $msrp(method)=="REPORT")
882	{
883		if ($msrp(nexthops)>1)
884		{
885			if ($msrp(method)!="REPORT")
886			{
887				msrp_reply("200", "OK");
888			}
889			msrp_relay();
890			exit;
891		}
892
893		if (msrp_cmap_lookup())
894		{
895			if ($msrp(method)!="REPORT")
896			{
897				msrp_reply("200", "OK");
898			}
899			msrp_relay_flags("1");
900			msrp_relay();
901		}
902		else
903		{
904			msrp_reply("481", "Session-does-not-exist");
905		}
906	}
907	else
908	{
909		msrp_reply("501", "Request-method-not-understood");
910	}
911}
912]]>
913...
914</programlisting>
915		</example>
916
917	</section>
918
919</chapter>
920
921