Browse code

- UAC redirection module initial commit

git-svn-id: https://openser.svn.sourceforge.net/svnroot/openser/trunk@58 689a6050-402a-0410-94f2-e92a70836424

Bogdan-Andrei Iancu authored on 23/06/2005 18:30:36
Showing 11 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,11 @@
1
+# example module makefile
2
+#
3
+# 
4
+# WARNING: do not run this directly, it should be run by the master Makefile
5
+
6
+include ../../Makefile.defs
7
+auto_gen=
8
+NAME=uac_redirect.so
9
+LIBS= 
10
+
11
+include ../../Makefile.modules
0 12
new file mode 100644
... ...
@@ -0,0 +1,404 @@
1
+
2
+UAC_REDIRECT Module
3
+
4
+Bogdan-Andrei Iancu
5
+
6
+   Voice System
7
+
8
+Edited by
9
+
10
+Bogdan-Andrei Iancu
11
+
12
+   Copyright � 2005 Voice Sistem
13
+     _________________________________________________________
14
+
15
+   Table of Contents
16
+   1. User's Guide
17
+
18
+        1.1. Overview
19
+        1.2. Accounting
20
+        1.3. Dependencies
21
+
22
+              1.3.1. OpenSER Modules
23
+              1.3.2. External Libraries or Applications
24
+
25
+        1.4. Exported Parameters
26
+
27
+              1.4.1. default_filter (string)
28
+              1.4.2. deny_filter (string)
29
+              1.4.3. accept_filter (string)
30
+              1.4.4. acc_function (string)
31
+              1.4.5. acc_db_table (string)
32
+
33
+        1.5. Exported Functions
34
+
35
+              1.5.1. set_deny_filter(filter,flags) 
36
+              1.5.2. set_accept_filter(filter,flags) 
37
+              1.5.3. get_redirects(max)
38
+              1.5.4. get_redirects(max,reason)
39
+
40
+        1.6. Script Example
41
+
42
+   2. Developer's Guide
43
+   3. Frequently Asked Questions
44
+
45
+   List of Examples
46
+   1-1. Set default_filter module parameter
47
+   1-2. Set deny_filter module parameter
48
+   1-3. Set accept_filter module parameter
49
+   1-4. Set acc_function parameter
50
+   1-5. Set acc_db_table parameter
51
+   1-6. set_deny_filter usage
52
+   1-7. set_accept_filter usage
53
+   1-8. get_redirects usage
54
+   1-9. get_redirects usage
55
+   1-10. Redirection script example
56
+     _________________________________________________________
57
+
58
+Chapter 1. User's Guide
59
+
60
+1.1. Overview
61
+
62
+   UAC REDIRECT - User Agent Client redirection - module enhance
63
+   OpenSER with the functionality of being able to handle
64
+   (interpret, filter, log and follow) redirect responses ( 3xx
65
+   replies class).
66
+
67
+   UAC REDIRECT module offer stateful processing, gathering the
68
+   contacts from all 3xx branches of a call.
69
+
70
+   The module provide a powerful mechanism for selecting and
71
+   filtering the contacts to be used for the new redirect:
72
+
73
+     * number based - limits like the number of total contacts to
74
+       be used or the maximum number of contacts per branch to be
75
+       selected.
76
+     * Regular Expression based - combinations of deny and accept
77
+       filters allow a strict control of the contacts to be used
78
+       for redirection.
79
+
80
+   When selecting from a 3xx branch the contacts to be used, the
81
+   contacts will be ordered and prioritized based on the "q"
82
+   value.
83
+     _________________________________________________________
84
+
85
+1.2. Accounting
86
+
87
+   UAC REDIRECT module allows to log all the redirection (to be
88
+   later used for CDR aggregation). This functionality may be
89
+   dynamically enabled for each redirection situation.
90
+
91
+   The logging will be done via the accounting module functions
92
+   (all are supported). The information to be logged will be the
93
+   same as the normal logged information direcly via ACC module,
94
+   but with differencies:
95
+
96
+     * reason phrase - which will be dynamically set by the
97
+       redirection function;
98
+     * outgoing URI - which will be the redirect URI.
99
+
100
+   For each redirect contact, a separate record will be logged.
101
+   For example, if a call is redirected to three new contacts,
102
+   the module will log three additional records corresponding to
103
+   each redirect URI.
104
+
105
+   For each redirect contact, a separate record will be logged.
106
+   For example, if a call is redirected to three new contacts,
107
+   the module will log three additional records corresponding to
108
+   each redirect URI.
109
+     _________________________________________________________
110
+
111
+1.3. Dependencies
112
+
113
+1.3.1. OpenSER Modules
114
+
115
+   The following modules must be loaded before this module:
116
+
117
+     * TM - Transaction Module, for accessing replies.
118
+     * ACC - Accounting Module, but only if the logging feature
119
+       is used.
120
+     _________________________________________________________
121
+
122
+1.3.2. External Libraries or Applications
123
+
124
+   The following libraries or applications must be installed
125
+   before running OpenSER with this module loaded:
126
+
127
+     * None
128
+     _________________________________________________________
129
+
130
+1.4. Exported Parameters
131
+
132
+1.4.1. default_filter (string)
133
+
134
+   The default behaviour in filtering contacts. It may be
135
+   "accept" or "deny".
136
+
137
+   The default value is "accept". 
138
+
139
+   Example 1-1. Set default_filter module parameter
140
+...
141
+modparam("uac_redirect","default_filter","deny")
142
+...
143
+     _________________________________________________________
144
+
145
+1.4.2. deny_filter (string)
146
+
147
+   The regular expression for default deny filtering. It make
148
+   sens to be defined on only if the default_filter parameter is
149
+   set to "accept". All contacts matching the deny_filter will be
150
+   rejected; the rest of them will be accepted for redirection.
151
+
152
+   The parameter may be defined only one - multiple definition
153
+   will overwrite the previous definitions. If more regular
154
+   expresion need to be defined, use the set_deny_filter()
155
+   scripting function.
156
+
157
+   This parameter is optional, it's default value being NULL. 
158
+
159
+   Example 1-2. Set deny_filter module parameter
160
+...
161
+modparam("uac_redirect","deny_filter",".*@siphub\.net")
162
+...
163
+     _________________________________________________________
164
+
165
+1.4.3. accept_filter (string)
166
+
167
+   The regular expression for default accept filtering. It make
168
+   sens to be defined on only if the default_filter parameter is
169
+   set to "deny". All contacts matching the accept_filter will be
170
+   accepted; the rest of them will be rejected for redirection.
171
+
172
+   The parameter may be defined only one - multiple definition
173
+   will overwrite the previous definitions. If more regular
174
+   expresion need to be defined, use the set_accept_filter()
175
+   scripting function.
176
+
177
+   This parameter is optional, it's default value being NULL. 
178
+
179
+   Example 1-3. Set accept_filter module parameter
180
+...
181
+modparam("uac_redirect","accept_filter",".*@siphub\.net")
182
+...
183
+     _________________________________________________________
184
+
185
+1.4.4. acc_function (string)
186
+
187
+   Specifies the accounting function to be used. Just be defining
188
+   this parameter, the accountign support will not be enabled.
189
+   Accountinf may only be enabled via two parameters
190
+   set_accept_filter() scripting function.
191
+
192
+   Its values my be:
193
+
194
+     * acc_log_request
195
+     * acc_db_request
196
+     * acc_rad_request
197
+     * acc_diam_request
198
+
199
+   The default value is "acc_log_request". 
200
+
201
+   Example 1-4. Set acc_function parameter
202
+...
203
+modparam("uac_redirect","acc_function","acc_db_request")
204
+...
205
+     _________________________________________________________
206
+
207
+1.4.5. acc_db_table (string)
208
+
209
+   Specifies the accounting table to be used if DB accounting was
210
+   choosen (acc_function was set to "acc_db_request"). Just be
211
+   defining this parameter, the accountign support will not be
212
+   enabled. Accountinf may only be enabled via two parameters
213
+   set_accept_filter() scripting function.
214
+
215
+   The default value is "acc". 
216
+
217
+   Example 1-5. Set acc_db_table parameter
218
+...
219
+modparam("uac_redirect","acc_db_table","acc_redirect")
220
+...
221
+     _________________________________________________________
222
+
223
+1.5. Exported Functions
224
+
225
+1.5.1. set_deny_filter(filter,flags)
226
+
227
+   Sets additionals deny filters. Maximum 6 may be combined. This
228
+   additional filter will apply only to the current message - it
229
+   will not have a global effect.
230
+
231
+   Default or prevoius added deny filter may be reset depending
232
+   of the flag parameter value:
233
+
234
+     * reset_all - reset both default and previous added deny
235
+       filters;
236
+     * reset_default - reset only the default deny filter;
237
+     * reset_added - reset only the previous added deny filters;
238
+     * empty - no reset, just add the filter.
239
+
240
+   Example 1-6. set_deny_filter usage
241
+...
242
+set_deny_filter(".*@domain2.net","reset_all");
243
+set_deny_filter(".*@domain1.net","");
244
+...
245
+     _________________________________________________________
246
+
247
+1.5.2. set_accept_filter(filter,flags)
248
+
249
+   Sets additionals accept filters. Maximum 6 may be combined.
250
+   This additional filter will apply only to the current message
251
+   - it will not have a global effect.
252
+
253
+   Default or prevoius added deny filter may be reset depending
254
+   of the flag parameter value:
255
+
256
+     * reset_all - reset both default and previous added accept
257
+       filters;
258
+     * reset_default - reset only the default accept filter;
259
+     * reset_added - reset only the previous added accept
260
+       filters;
261
+     * empty - no reset, just add the filter.
262
+
263
+   Example 1-7. set_accept_filter usage
264
+...
265
+set_accept_filter(".*@domain2.net","reset_added");
266
+set_accept_filter(".*@domain1.net","");
267
+...
268
+     _________________________________________________________
269
+
270
+1.5.3. get_redirects(max)
271
+
272
+   The function may be called only from failure routes. It will
273
+   extract the contacts from all 3xx branches and append them as
274
+   new branches. Note that the function will not forward the nw
275
+   brnaches, this must be done explicitly from script.
276
+
277
+   How many contacts (in total and per branch) are selected
278
+   depends of the max parameter values. Its syntax is:
279
+
280
+     * max = max_total [":" max_branch]
281
+     * max_total = number of total contacts to be selected
282
+     * max_branch = number of contacts per branch to be selected
283
+
284
+   Both "max_total" and "max_branch" are positive integer. To
285
+   specify unlimited values, use 0 value or "*" character.
286
+
287
+   NOTE that during the selection process, each set of contacts
288
+   from a specific branch are ordered based on "q" value.
289
+
290
+   This function will produce no accounting records.
291
+
292
+   Example 1-8. get_redirects usage
293
+...
294
+# max 2 contacts per branch, but no overall limit
295
+get_redirects("*:2");
296
+...
297
+# no limits per branch, but not more than 6 overall contacts
298
+get_redirects("6:*");
299
+...
300
+# no restrictions
301
+get_redirects("*");
302
+...
303
+     _________________________________________________________
304
+
305
+1.5.4. get_redirects(max,reason)
306
+
307
+   The function has same functionality as get_redirects(max)
308
+   function, but it will produce accounting records.
309
+
310
+   The accounting records will be mark by the reason phrase.
311
+
312
+   If this funtion appers in the script, at startup, the module
313
+   will import the accounting function. Otherwise not.
314
+
315
+   Example 1-9. get_redirects usage
316
+...
317
+get_redirects("4:1","Redirected");
318
+...
319
+     _________________________________________________________
320
+
321
+1.6. Script Example
322
+
323
+   Example 1-10. Redirection script example
324
+loadmodule "modules/sl/sl.so"
325
+loadmodule "modules/usrloc/usrloc.so"
326
+loadmodule "modules/registrar/registrar.so"
327
+loadmodule "modules/tm/tm.so"
328
+loadmodule "modules/acc/acc.so"
329
+loadmodule "modules/uac_redirect/uac_redirect.so"
330
+
331
+modparam("usrloc", "db_mode",   0)
332
+
333
+route{
334
+        if (uri==myself) {
335
+
336
+                if (method=="REGISTER") {
337
+                        save("location");
338
+                        break;
339
+                };
340
+
341
+                if (!lookup("location")) {
342
+                        sl_send_reply("404", "Not Found");
343
+                        break;
344
+                };
345
+                # do redirect with accounting
346
+                t_on_failure("2");
347
+        } else {
348
+                # just do redirect
349
+                t_on_failure("1");
350
+        }
351
+
352
+        if (!t_relay()) {
353
+                sl_reply_error();
354
+        };
355
+}
356
+
357
+failure_route[1] {
358
+        get_redirects("3:1");
359
+        t_relay();
360
+}
361
+
362
+failure_route[2] {
363
+        get_redirects("6:2","redirect");
364
+        t_relay();
365
+}
366
+     _________________________________________________________
367
+
368
+Chapter 2. Developer's Guide
369
+
370
+   The module does not provide any API to use in other OpenSER
371
+   modules.
372
+     _________________________________________________________
373
+
374
+Chapter 3. Frequently Asked Questions
375
+
376
+   3.1. Where can I find more about OpenSER?
377
+   3.2. Where can I post a question about this module?
378
+   3.3. How can I report a bug?
379
+
380
+   3.1. Where can I find more about OpenSER?
381
+
382
+   Take a look at http://openser.org/.
383
+
384
+   3.2. Where can I post a question about this module?
385
+
386
+   First at all check if your question was already answered on
387
+   one of our mailing lists:
388
+
389
+     * User Mailing List -
390
+       http://openser.org/mailman/listinfo/users
391
+     * Developer Mailing List -
392
+       http://openser.org/mailman/listinfo/devel
393
+
394
+   E-mails regarding any stable version should be sent to
395
+   <users@openser.org> and e-mail regarding development versions
396
+   or CVS snapshots should be send to <devel@openser.org>.
397
+
398
+   If you want to keep the mail private, send it to
399
+   <team@openser.org>.
400
+
401
+   3.3. How can I report a bug?
402
+
403
+   Please follow the guidelines provided at:
404
+   http://openser.org/bugs
0 405
new file mode 100644
... ...
@@ -0,0 +1,52 @@
1
+<!DOCTYPE Book PUBLIC "-//OASIS//DTD DocBook V4.2//EN" [
2
+
3
+
4
+<!ENTITY user SYSTEM "uac_redirect_user.sgml">
5
+<!ENTITY devel SYSTEM "uac_redirect_devel.sgml">
6
+<!ENTITY faq SYSTEM "uac_redirect_faq.sgml">
7
+
8
+<!-- Include general SER documentation entities -->
9
+<!ENTITY % serentities SYSTEM "../../../doc/entities.sgml">
10
+%serentities;
11
+
12
+]>
13
+
14
+<book>
15
+	<bookinfo>
16
+	<title>UAC_REDIRECT Module</title>
17
+	<productname class="trade">&sername;</productname>
18
+	<authorgroup>
19
+		<author>
20
+			<firstname>Bogdan-Andrei</firstname>
21
+			<surname>Iancu</surname>
22
+			<affiliation><orgname>Voice System</orgname></affiliation>
23
+			<address>
24
+				<email>bogdan@voice-system.ro</email>
25
+			</address>
26
+		</author>
27
+		<editor>
28
+			<firstname>Bogdan-Andrei</firstname>
29
+			<surname>Iancu</surname>
30
+			<address>
31
+				<email>bogdan@voice-system.ro</email>
32
+			</address>
33
+		</editor>
34
+	</authorgroup>
35
+	<copyright>
36
+		<year>2005</year>
37
+		<holder>Voice Sistem</holder>
38
+	</copyright>
39
+	<revhistory>
40
+		<revision>
41
+			<revnumber>$Revision$</revnumber>
42
+			<date>$Date$</date>
43
+		</revision>
44
+	</revhistory>
45
+	</bookinfo>
46
+	<toc></toc>
47
+
48
+	&user;
49
+	&devel;
50
+	&faq;
51
+
52
+</book>
0 53
new file mode 100644
... ...
@@ -0,0 +1,23 @@
1
+<!-- Module Developer's Guide -->
2
+
3
+<chapter>
4
+	<chapterinfo>
5
+	<revhistory>
6
+		<revision>
7
+		<revnumber>$Revision$</revnumber>
8
+		<date>$Date$</date>
9
+		</revision>
10
+	</revhistory>
11
+	</chapterinfo>
12
+	<title>Developer's Guide</title>
13
+	<para>
14
+	The module does not provide any <acronym>API</acronym> to use in 
15
+	other &ser; modules.
16
+	</para>
17
+</chapter>
18
+
19
+<!-- Keep this element at the end of the file
20
+Local Variables:
21
+sgml-parent-document: ("uac_redirect.sgml" "book" "chapter")
22
+End:
23
+-->
0 24
new file mode 100644
... ...
@@ -0,0 +1,67 @@
1
+<!-- Module FAQ -->
2
+
3
+<chapter>
4
+    <chapterinfo>
5
+	<revhistory>
6
+	    <revision>
7
+		<revnumber>$Revision$</revnumber>
8
+		<date>$Date$</date>
9
+	    </revision>
10
+	</revhistory>
11
+    </chapterinfo>
12
+    <title>Frequently Asked Questions</title>
13
+    <qandaset defaultlabel="number">
14
+	<qandaentry>
15
+	    <question>
16
+		<para>Where can I find more about &ser;?</para>
17
+	    </question>
18
+	    <answer>
19
+		<para>
20
+		    Take a look at &serhomelink;.
21
+		</para>
22
+	    </answer>
23
+	</qandaentry>
24
+	<qandaentry>
25
+	    <question>
26
+		<para>Where can I post a question about this module?</para>
27
+	    </question>
28
+	    <answer>
29
+		<para>
30
+		    First at all check if your question was already answered on one of
31
+		    our mailing lists: 
32
+		</para>
33
+		<itemizedlist>
34
+		    <listitem>
35
+			<para>User Mailing List - &seruserslink;</para>
36
+		    </listitem>
37
+		    <listitem>
38
+			<para>Developer Mailing List - &serdevlink;</para>
39
+		    </listitem>
40
+		</itemizedlist>
41
+		<para>
42
+		    E-mails regarding any stable version should be sent to &serusersmail; and e-mail
43
+		    regarding development versions or CVS snapshots should be send to &serdevmail;.
44
+		</para>
45
+		<para>
46
+		    If you want to keep the mail private, send it to &serhelpmail;.
47
+		</para>
48
+	    </answer>
49
+	</qandaentry>
50
+	<qandaentry>
51
+	    <question>
52
+		<para>How can I report a bug?</para>
53
+	    </question>
54
+	    <answer>
55
+		<para>
56
+		    Please follow the guidelines provided at: &serbugslink;
57
+		</para>
58
+	    </answer>
59
+	</qandaentry>
60
+    </qandaset>
61
+</chapter>
62
+
63
+<!-- Keep this element at the end of the file
64
+Local Variables:
65
+sgml-parent-document: ("uac_redirect.sgml" "Book" "chapter")
66
+End:
67
+-->
0 68
new file mode 100644
... ...
@@ -0,0 +1,523 @@
1
+<!-- Module User's Guide -->
2
+
3
+<chapter>
4
+	<chapterinfo>
5
+	<revhistory>
6
+		<revision>
7
+			<revnumber>$Revision$</revnumber>
8
+			<date>$Date$</date>
9
+		</revision>
10
+	</revhistory>
11
+	</chapterinfo>
12
+	<title>User's Guide</title>
13
+
14
+
15
+	<section>
16
+		<title>Overview</title>
17
+		<para>
18
+		UAC REDIRECT - User Agent Client redirection - module enhance &ser;
19
+		with the functionality of being able to handle (interpret, filter,
20
+		log and follow) redirect responses ( 3xx replies class).
21
+		</para>
22
+		<para>
23
+		UAC REDIRECT module offer stateful processing, gathering the
24
+		contacts from all 3xx branches of a call.
25
+		</para>
26
+		<para>
27
+		The module provide a powerful mechanism for selecting and filtering 
28
+		the contacts to be used for the new redirect:
29
+		</para>
30
+		<itemizedlist>
31
+			<listitem>
32
+			<para><emphasis>number based</emphasis> - limits like the 
33
+			number of total contacts to be used or the maximum number of 
34
+			contacts per branch to be selected.
35
+			</para>
36
+			</listitem>
37
+			<listitem>
38
+			<para><emphasis>Regular Expression based</emphasis> - combinations
39
+			of deny and accept filters allow a strict control of the 
40
+			contacts to be used for redirection.
41
+			</para>
42
+			</listitem>
43
+		</itemizedlist>
44
+		<para>
45
+		When selecting from a 3xx branch the contacts to be used, the contacts
46
+		will be ordered and prioritized based on the <quote>q</quote> value.
47
+		</para>
48
+	</section>
49
+
50
+	<section>
51
+		<title>Accounting</title>
52
+		<para>
53
+		UAC REDIRECT module allows to log all the redirection (to be later
54
+		used for CDR aggregation). This functionality may be dynamically
55
+		enabled for each redirection situation.
56
+		</para>
57
+		<para>
58
+		The logging will be done via the accounting module functions (all are
59
+		supported). The information to be logged will be the same as the 
60
+		normal logged information direcly via ACC module, but with 
61
+		differencies:
62
+		</para>
63
+		<itemizedlist>
64
+			<listitem>
65
+			<para><emphasis>reason phrase</emphasis> - which will be
66
+			dynamically set by the redirection function;
67
+			</para>
68
+			</listitem>
69
+			<listitem>
70
+			<para><emphasis>outgoing URI</emphasis> - which will be the
71
+			redirect URI.
72
+			</para>
73
+			</listitem>
74
+		</itemizedlist>
75
+		<para>
76
+		For each redirect contact, a separate record will be logged. For
77
+		example, if a call is redirected to three new contacts, the 
78
+		module will log three additional records corresponding to each
79
+		redirect URI.
80
+		</para>
81
+		<para>
82
+		For each redirect contact, a separate record will be logged. For
83
+		example, if a call is redirected to three new contacts, the 
84
+		module will log three additional records corresponding to each
85
+		redirect URI.
86
+		</para>
87
+	</section>
88
+
89
+
90
+	<section>
91
+		<title>Dependencies</title>
92
+		<section>
93
+			<title>&ser; Modules</title>
94
+			<para>
95
+			The following modules must be loaded before this module:
96
+			<itemizedlist>
97
+			<listitem>
98
+			<para>
99
+				<emphasis>TM</emphasis> - Transaction Module, for accessing
100
+				replies.
101
+			</para>
102
+			</listitem>
103
+			<listitem>
104
+			<para>
105
+				<emphasis>ACC</emphasis> - Accounting Module, but only if the
106
+				logging feature is used.
107
+			</para>
108
+			</listitem>
109
+			</itemizedlist>
110
+			</para>
111
+		</section>
112
+		<section>
113
+			<title>External Libraries or Applications</title>
114
+			<para>
115
+				The following libraries or applications must be installed 
116
+				before running &ser; with this module loaded:
117
+				<itemizedlist>
118
+				<listitem>
119
+				<para>
120
+					<emphasis>None</emphasis>
121
+				</para>
122
+				</listitem>
123
+				</itemizedlist>
124
+			</para>
125
+		</section>
126
+	</section>
127
+
128
+	<section>
129
+		<title>Exported Parameters</title>
130
+		<section>
131
+			<title><varname>default_filter</varname> (string)</title>
132
+			<para>
133
+			The default behaviour in filtering contacts. It may be 
134
+			<quote>accept</quote> or <quote>deny</quote>.
135
+			</para>
136
+			<para>
137
+				<emphasis>
138
+					The default value is <quote>accept</quote>.
139
+				</emphasis>
140
+			</para>
141
+			<example>
142
+				<title>Set <varname>default_filter</varname> 
143
+					module parameter</title>
144
+				<programlisting format="linespecific">
145
+...
146
+modparam("uac_redirect","default_filter","deny")
147
+...
148
+				</programlisting>
149
+			</example>
150
+		</section>
151
+		<section>
152
+			<title><varname>deny_filter</varname> (string)</title>
153
+			<para>
154
+			The regular expression for default deny filtering. It make sens
155
+			to be defined on only if the <varname>default_filter</varname>
156
+			parameter is set to <quote>accept</quote>. All contacts matching
157
+			the <varname>deny_filter</varname> will be rejected; the rest 
158
+			of them will be accepted for redirection.
159
+			</para>
160
+			<para>
161
+			The parameter may be defined only one - multiple definition will
162
+			overwrite the previous definitions. If more regular expresion 
163
+			need to be defined, use the 
164
+			<function moreinfo="none">set_deny_filter()</function> scripting
165
+			function.
166
+			</para>
167
+			<para>
168
+				<emphasis>
169
+					This parameter is optional, it's default 
170
+					value being NULL.
171
+				</emphasis>
172
+			</para>
173
+			<example>
174
+				<title>Set <varname>deny_filter</varname> 
175
+					module parameter</title>
176
+				<programlisting format="linespecific">
177
+...
178
+modparam("uac_redirect","deny_filter",".*@siphub\.net")
179
+...
180
+				</programlisting>
181
+			</example>
182
+		</section>
183
+		<section>
184
+			<title><varname>accept_filter</varname> (string)</title>
185
+			<para>
186
+			The regular expression for default accept filtering. It make sens
187
+			to be defined on only if the <varname>default_filter</varname>
188
+			parameter is set to <quote>deny</quote>. All contacts matching
189
+			the <varname>accept_filter</varname> will be accepted; the rest 
190
+			of them will be rejected for redirection.
191
+			</para>
192
+			<para>
193
+			The parameter may be defined only one - multiple definition will
194
+			overwrite the previous definitions. If more regular expresion 
195
+			need to be defined, use the 
196
+			<function moreinfo="none">set_accept_filter()</function> scripting
197
+			function.
198
+			</para>
199
+			<para>
200
+				<emphasis>
201
+					This parameter is optional, it's default 
202
+					value being NULL.
203
+				</emphasis>
204
+			</para>
205
+			<example>
206
+				<title>Set <varname>accept_filter</varname> 
207
+					module parameter</title>
208
+				<programlisting format="linespecific">
209
+...
210
+modparam("uac_redirect","accept_filter",".*@siphub\.net")
211
+...
212
+				</programlisting>
213
+			</example>
214
+		</section>
215
+		<section>
216
+			<title><varname>acc_function</varname> (string)</title>
217
+			<para>
218
+			Specifies the accounting function to be used. Just be defining 
219
+			this parameter, the accountign support will not be enabled. 
220
+			Accountinf may only be enabled via two parameters 
221
+			<function moreinfo="none">set_accept_filter()</function> 
222
+			scripting function.
223
+			</para>
224
+			<para>
225
+			Its values my be:
226
+			</para>
227
+			<itemizedlist>
228
+				<listitem>
229
+				<para><emphasis>acc_log_request</emphasis></para>
230
+				</listitem>
231
+				<listitem>
232
+				<para><emphasis>acc_db_request</emphasis></para>
233
+				</listitem>
234
+				<listitem>
235
+				<para><emphasis>acc_rad_request</emphasis></para>
236
+				</listitem>
237
+				<listitem>
238
+				<para><emphasis>acc_diam_request</emphasis></para>
239
+				</listitem>
240
+			</itemizedlist>
241
+			<para>
242
+				<emphasis>
243
+					The default value is <quote>acc_log_request</quote>.
244
+				</emphasis>
245
+			</para>
246
+			<example>
247
+				<title>Set <varname>acc_function</varname> parameter</title>
248
+				<programlisting format="linespecific">
249
+...
250
+modparam("uac_redirect","acc_function","acc_db_request")
251
+...
252
+				</programlisting>
253
+			</example>
254
+		</section>
255
+		<section>
256
+			<title><varname>acc_db_table</varname> (string)</title>
257
+			<para>
258
+			Specifies the accounting table to be used if DB accounting was 
259
+			choosen (<varname>acc_function</varname> was set to 
260
+			<quote>acc_db_request</quote>). Just be defining 
261
+			this parameter, the accountign support will not be enabled. 
262
+			Accountinf may only be enabled via two parameters 
263
+			<function moreinfo="none">set_accept_filter()</function> 
264
+			scripting function.
265
+			</para>
266
+			<para>
267
+				<emphasis>
268
+					The default value is <quote>acc</quote>.
269
+				</emphasis>
270
+			</para>
271
+			<example>
272
+				<title>Set <varname>acc_db_table</varname> parameter</title>
273
+				<programlisting format="linespecific">
274
+...
275
+modparam("uac_redirect","acc_db_table","acc_redirect")
276
+...
277
+				</programlisting>
278
+			</example>
279
+		</section>
280
+	</section>
281
+
282
+
283
+	<section>
284
+		<title>Exported Functions</title>
285
+		<section>
286
+			<title>
287
+				<function moreinfo="none">set_deny_filter(filter,flags)
288
+					</function>
289
+			</title>
290
+			<para>
291
+			Sets additionals deny filters. Maximum 6 may be combined. This
292
+			additional filter will apply only to the current message - it
293
+			will not have a global effect.
294
+			</para>
295
+			<para>
296
+			Default or prevoius added deny filter may be reset depending of
297
+			the <emphasis>flag</emphasis> parameter value:
298
+			</para>
299
+			<itemizedlist>
300
+				<listitem>
301
+				<para><emphasis>reset_all</emphasis> - reset both default
302
+				and previous added deny filters;
303
+				</para>
304
+				</listitem>
305
+				<listitem>
306
+				<para><emphasis>reset_default</emphasis> - reset only the
307
+				default deny filter;
308
+				</para>
309
+				</listitem>
310
+				<listitem>
311
+				<para><emphasis>reset_added</emphasis> - reset only the 
312
+				previous added deny filters;
313
+				</para>
314
+				</listitem>
315
+				<listitem>
316
+				<para><emphasis>empty</emphasis> - no reset, just add the
317
+				filter.
318
+				</para>
319
+				</listitem>
320
+			</itemizedlist>
321
+			<example>
322
+				<title><function>set_deny_filter</function> usage</title>
323
+				<programlisting format="linespecific">
324
+...
325
+set_deny_filter(".*@domain2.net","reset_all");
326
+set_deny_filter(".*@domain1.net","");
327
+...
328
+				</programlisting>
329
+			</example>
330
+		</section>
331
+
332
+		<section>
333
+			<title>
334
+				<function moreinfo="none">set_accept_filter(filter,flags)
335
+					</function>
336
+			</title>
337
+			<para>
338
+			Sets additionals accept filters. Maximum 6 may be combined. This
339
+			additional filter will apply only to the current message - it
340
+			will not have a global effect.
341
+			</para>
342
+			<para>
343
+			Default or prevoius added deny filter may be reset depending of
344
+			the <emphasis>flag</emphasis> parameter value:
345
+			</para>
346
+			<itemizedlist>
347
+				<listitem>
348
+				<para><emphasis>reset_all</emphasis> - reset both default
349
+				and previous added accept filters;
350
+				</para>
351
+				</listitem>
352
+				<listitem>
353
+				<para><emphasis>reset_default</emphasis> - reset only the
354
+				default accept filter;
355
+				</para>
356
+				</listitem>
357
+				<listitem>
358
+				<para><emphasis>reset_added</emphasis> - reset only the 
359
+				previous added accept filters;
360
+				</para>
361
+				</listitem>
362
+				<listitem>
363
+				<para><emphasis>empty</emphasis> - no reset, just add
364
+				the filter.
365
+				</para>
366
+				</listitem>
367
+			</itemizedlist>
368
+			<example>
369
+				<title><function>set_accept_filter</function> usage</title>
370
+				<programlisting format="linespecific">
371
+...
372
+set_accept_filter(".*@domain2.net","reset_added");
373
+set_accept_filter(".*@domain1.net","");
374
+...
375
+				</programlisting>
376
+			</example>
377
+		</section>
378
+
379
+		<section>
380
+			<title>
381
+				<function moreinfo="none">get_redirects(max)</function>
382
+			</title>
383
+			<para>
384
+				The function may be called only from failure routes. It will
385
+				extract the contacts from all 3xx branches and append them
386
+				as new branches. Note that the function will not forward the
387
+				nw brnaches, this must be done explicitly from script.
388
+			</para>
389
+			<para>
390
+				How many contacts (in total and per branch) are selected 
391
+				depends of the <emphasis>max</emphasis> parameter values.
392
+				Its syntax is:
393
+			</para>
394
+			<itemizedlist>
395
+				<listitem><para>
396
+				max = max_total [":" max_branch]
397
+				</para></listitem>
398
+				<listitem><para>
399
+				max_total = number of total contacts to be selected
400
+				</para></listitem>
401
+				<listitem><para>
402
+				max_branch = number of contacts per branch to be selected
403
+				</para></listitem>
404
+			</itemizedlist>
405
+			<para>
406
+				Both <quote>max_total</quote> and <quote>max_branch</quote>
407
+				are positive integer. To specify unlimited values, use 0 value
408
+				or "*" character.
409
+			</para>
410
+			<para>
411
+				NOTE that during the selection process, each set of contacts 
412
+				from a specific branch are ordered based on <quote>q</quote> 
413
+				value.
414
+			</para>
415
+			<para>
416
+				This function will produce no accounting records.
417
+			</para>
418
+			<example>
419
+				<title><function>get_redirects</function> usage</title>
420
+				<programlisting format="linespecific">
421
+...
422
+# max 2 contacts per branch, but no overall limit
423
+get_redirects("*:2");
424
+...
425
+# no limits per branch, but not more than 6 overall contacts
426
+get_redirects("6:*");
427
+...
428
+# no restrictions
429
+get_redirects("*");
430
+...
431
+				</programlisting>
432
+			</example>
433
+		</section>
434
+
435
+		<section>
436
+			<title>
437
+				<function moreinfo="none">get_redirects(max,reason)</function>
438
+			</title>
439
+			<para>
440
+				The function has same functionality as 
441
+				<function moreinfo="none">get_redirects(max)</function>
442
+				function, but it will produce accounting records.
443
+			</para>
444
+			<para>
445
+				The accounting records will be mark by the 
446
+				<emphasis>reason</emphasis> phrase.
447
+			</para>
448
+			<para>
449
+				If this funtion appers in the script, at startup, the module
450
+				will import the accounting function. Otherwise not.
451
+			</para>
452
+			<example>
453
+				<title><function>get_redirects</function> usage</title>
454
+				<programlisting format="linespecific">
455
+...
456
+get_redirects("4:1","Redirected");
457
+...
458
+				</programlisting>
459
+			</example>
460
+		</section>
461
+	</section>
462
+
463
+	<section>
464
+		<title>Script Example</title>
465
+		<example>
466
+			<title>Redirection script example</title>
467
+				<programlisting format="linespecific">
468
+loadmodule "modules/sl/sl.so"
469
+loadmodule "modules/usrloc/usrloc.so"
470
+loadmodule "modules/registrar/registrar.so"
471
+loadmodule "modules/tm/tm.so"
472
+loadmodule "modules/acc/acc.so"
473
+loadmodule "modules/uac_redirect/uac_redirect.so"
474
+
475
+modparam("usrloc", "db_mode",   0)
476
+
477
+route{
478
+	if (uri==myself) {
479
+
480
+		if (method=="REGISTER") {
481
+			save("location");
482
+			break;
483
+		};
484
+
485
+		if (!lookup("location")) {
486
+			sl_send_reply("404", "Not Found");
487
+			break;
488
+		};
489
+		# do redirect with accounting
490
+		t_on_failure("2");
491
+	} else {
492
+		# just do redirect
493
+		t_on_failure("1");
494
+	}
495
+
496
+	if (!t_relay()) {
497
+		sl_reply_error();
498
+	};
499
+}
500
+
501
+failure_route[1] {
502
+	get_redirects("3:1");
503
+	t_relay();
504
+}
505
+
506
+failure_route[2] {
507
+	get_redirects("6:2","redirect");
508
+	t_relay();
509
+}
510
+				</programlisting>
511
+			</example>
512
+
513
+	</section>
514
+
515
+
516
+
517
+</chapter>
518
+
519
+<!-- Keep this element at the end of the file
520
+Local Variables:
521
+sgml-parent-document: ("uac.sgml" "Book" "chapter")
522
+End:
523
+-->
0 524
new file mode 100644
... ...
@@ -0,0 +1,120 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ * Copyright (C) 2005 Voice Sistem SRL
5
+ *
6
+ * This file is part of openser, a free SIP server.
7
+ *
8
+ * openser is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU General Public License
10
+ * as published by the Free Software Foundation; either version 2
11
+ * of the License, or (at your option) any later version.
12
+ *
13
+ * openser is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program; if not, write to the Free Software
20
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21
+ *
22
+ *
23
+ * History:
24
+ * ---------
25
+ *  2005-06-22  first version (bogdan)
26
+ */
27
+
28
+
29
+#include <string.h>
30
+#include <sys/types.h> /* for regex */
31
+#include <regex.h>
32
+
33
+#include "../../dprint.h"
34
+#include "rd_filter.h"
35
+
36
+#define MAX_FILTERS 6
37
+
38
+static int default_rule = ACCEPT_RULE;
39
+
40
+static regex_t *rd_filters[NR_FILTER_TYPES][MAX_FILTERS];
41
+static int nr_filters[NR_FILTER_TYPES];
42
+static int start_filters[NR_FILTER_TYPES];
43
+
44
+
45
+void init_filters()
46
+{
47
+	memset( rd_filters , 0, NR_FILTER_TYPES*MAX_FILTERS*sizeof(regex_t*));
48
+	reset_filters();
49
+}
50
+
51
+
52
+void set_default_rule( int type )
53
+{
54
+	default_rule = type;
55
+}
56
+
57
+
58
+void reset_filters()
59
+{
60
+	nr_filters[ACCEPT_FILTER] = 1;
61
+	nr_filters[DENY_FILTER]   = 1;
62
+	start_filters[ACCEPT_FILTER] = 0;
63
+	start_filters[DENY_FILTER]   = 0;
64
+}
65
+
66
+
67
+void add_default_filter( int type, regex_t *filter)
68
+{
69
+	rd_filters[type][0] = filter;
70
+}
71
+
72
+
73
+int add_filter( int type, regex_t *filter, int flags)
74
+{
75
+	if ( nr_filters[type]==MAX_FILTERS ) {
76
+		LOG(L_ERR,"ERROR:uac_redirect:add_filter: too many filters type %d\n",
77
+				type);
78
+		return -1;
79
+	}
80
+
81
+	/* flags? */
82
+	if (flags&RESET_ADDED)
83
+		nr_filters[type] = 1;
84
+	if (flags&RESET_DEFAULT)
85
+		start_filters[type] = 1;
86
+
87
+	/* set filter */
88
+	rd_filters[type][ nr_filters[type]++ ] = filter;
89
+	return 0;
90
+}
91
+
92
+
93
+int run_filters(char *s)
94
+{
95
+	regmatch_t pmatch;
96
+	int i;
97
+
98
+	/* check for accept filters */
99
+	for( i=start_filters[ACCEPT_FILTER] ; i<nr_filters[ACCEPT_FILTER] ; i++ ) {
100
+		if (rd_filters[ACCEPT_FILTER][i]==0)
101
+			continue;
102
+		if (regexec(rd_filters[ACCEPT_FILTER][i], s, 1, &pmatch, 0)==0)
103
+			return 1;
104
+	}
105
+
106
+	/* if default rule is deny, don' check the deny rules */
107
+	if (default_rule!=DENY_RULE) {
108
+		/* check for deny filters */
109
+		for( i=start_filters[DENY_FILTER] ; i<nr_filters[DENY_FILTER] ; i++ ) {
110
+			if (rd_filters[DENY_FILTER][i]==0)
111
+				continue;
112
+			if (regexec(rd_filters[DENY_FILTER][i], s, 1, &pmatch, 0)==0)
113
+				return -1;
114
+		}
115
+	}
116
+
117
+	/* return default */
118
+	return (default_rule==ACCEPT_RULE)?1:-1;
119
+}
120
+
0 121
new file mode 100644
... ...
@@ -0,0 +1,52 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ * Copyright (C) 2005 Voice Sistem SRL
5
+ *
6
+ * This file is part of openser, a free SIP server.
7
+ *
8
+ * openser is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU General Public License
10
+ * as published by the Free Software Foundation; either version 2
11
+ * of the License, or (at your option) any later version.
12
+ *
13
+ * openser is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program; if not, write to the Free Software
20
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21
+ *
22
+ *
23
+ * History:
24
+ * ---------
25
+ *  2005-06-22  first version (bogdan)
26
+ */
27
+
28
+
29
+#ifndef _REDIRECT_FILTER_H
30
+#define _REDIRECT_FILTER_H
31
+
32
+#include <sys/types.h> /* for regex */
33
+#include <regex.h>
34
+
35
+#define ACCEPT_FILTER   0
36
+#define DENY_FILTER     1
37
+#define NR_FILTER_TYPES 2
38
+
39
+#define ACCEPT_RULE    11
40
+#define DENY_RULE      12
41
+
42
+#define RESET_ADDED    (1<<0)
43
+#define RESET_DEFAULT  (1<<1)
44
+
45
+void init_filters();
46
+void set_default_rule( int type );
47
+void reset_filters();
48
+void add_default_filter( int type, regex_t *filter);
49
+int add_filter( int type, regex_t *filter, int flags);
50
+int run_filters(char *s);
51
+
52
+#endif
0 53
new file mode 100644
... ...
@@ -0,0 +1,303 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ * Copyright (C) 2005 Voice Sistem SRL
5
+ *
6
+ * This file is part of openser, a free SIP server.
7
+ *
8
+ * openser is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU General Public License
10
+ * as published by the Free Software Foundation; either version 2
11
+ * of the License, or (at your option) any later version.
12
+ *
13
+ * openser is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program; if not, write to the Free Software
20
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21
+ *
22
+ *
23
+ * History:
24
+ * ---------
25
+ *  2005-06-22  first version (bogdan)
26
+ */
27
+
28
+
29
+#include "../../usr_avp.h"
30
+#include "../../dset.h"
31
+#include "../../dprint.h"
32
+#include "../../qvalue.h"
33
+#include "../../parser/contact/parse_contact.h"
34
+#include "../../qvalue.h"
35
+#include "rd_filter.h"
36
+#include "rd_funcs.h"
37
+
38
+
39
+#define MAX_CONTACTS_PER_REPLY   16
40
+#define DEFAULT_Q_VALUE          10
41
+
42
+static int shmcontact2dset(struct sip_msg *req, struct sip_msg *shrpl,
43
+			long max, char *reason);
44
+
45
+
46
+int get_redirect( struct sip_msg *msg , int maxt, int maxb, char *reason)
47
+{
48
+	struct cell *t;
49
+	str backup_uri;
50
+	int max;
51
+	int cts_added;
52
+	int n;
53
+	int i;
54
+
55
+	/* get transaction */
56
+	t = rd_tmb.t_gett();
57
+	if (t==T_UNDEFINED || t==T_NULL_CELL)
58
+	{
59
+		LOG(LOG_CRIT,"BUG:uac_redirect:get_redirect: no current "
60
+			"transaction found\n");
61
+		goto error;
62
+	}
63
+
64
+	DBG("DEBUG:uac_redirect:get_redirect: resume branch=%d\n",
65
+		t->first_branch);
66
+
67
+	cts_added = 0; /* no contact added */
68
+	backup_uri = msg->new_uri; /* shmcontact2dset will ater this value */
69
+
70
+	/* look if there are any 3xx branches starting from resume_branch */
71
+	for( i=t->first_branch ; i<t->nr_of_outgoings ; i++) {
72
+		DBG("DEBUG:uac_redirect:get_redirect: checking branch=%d "
73
+			"(added=%d)\n", i, cts_added);
74
+		/* is a redirected branch? */
75
+		if (t->uac[i].last_received<300 || t->uac[i].last_received>399)
76
+			continue;
77
+		DBG("DEBUG:uac_redirect:get_redirect: branch=%d is a redirect "
78
+			"(added=%d)\n", i, cts_added);
79
+		/* ok - we have a new redirected branch -> how many contacts can
80
+		 * we get from it*/
81
+		if (maxb==0) {
82
+			max = maxt?(maxt-cts_added):(-1);
83
+		} else {
84
+			max = maxt?((maxt-cts_added>=maxb)?maxb:(maxt-cts_added)):maxb;
85
+		}
86
+		if (max==0)
87
+			continue;
88
+		/* get the contact from it */
89
+		n = shmcontact2dset( msg, t->uac[i].reply, max, reason);
90
+		if ( n<0 ) {
91
+			LOG(L_ERR,"ERROR:uac_redirect:get_redirects: get contact from "
92
+				"shm_reply branch %d failed\n",i);
93
+			/* do not go to error, try next branches */
94
+		} else {
95
+			/* count the added contacts */
96
+			cts_added += n;
97
+		}
98
+	}
99
+
100
+	/* restore original new_uri */
101
+	msg->new_uri = backup_uri;
102
+
103
+	/* return false if no contact was appended */
104
+	return (cts_added>0)?1:-1;
105
+error:
106
+	return -1;
107
+}
108
+
109
+
110
+
111
+/* returns the number of contacts put in the sorted array */
112
+static int sort_contacts(contact_t *ct_list, contact_t **ct_array)
113
+{
114
+	static qvalue_t q_array[MAX_CONTACTS_PER_REPLY];
115
+	param_t *q_para;
116
+	qvalue_t q;
117
+	int n;
118
+	int i,j;
119
+	char backup;
120
+
121
+	n = 0; /* number of sorted contacts */
122
+
123
+	for( ; ct_list ; ct_list = ct_list->next ) {
124
+		/* check the filters first */
125
+		backup = ct_list->uri.s[ct_list->uri.len];
126
+		ct_list->uri.s[ct_list->uri.len] = 0;
127
+		if ( run_filters( ct_list->uri.s )==-1 ){
128
+			ct_list->uri.s[ct_list->uri.len] = backup;
129
+			continue;
130
+		}
131
+		ct_list->uri.s[ct_list->uri.len] = backup;
132
+		/* does the contact has a q val? */
133
+		q_para = ct_list->q;
134
+		if (q_para==0 || q_para->body.len==0) {
135
+			q = DEFAULT_Q_VALUE;
136
+		} else {
137
+			if (str2q( &q, q_para->body.s, q_para->body.len)!=0) {
138
+				LOG(L_ERR, "ERROR:uac_redirect:sort_contacts: "
139
+					"invalid q param\n");
140
+				/* skip this contact */