File: routing_engine.xml

package info (click to toggle)
kamailio 5.6.3-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 68,332 kB
  • sloc: ansic: 744,091; xml: 196,848; cpp: 14,471; makefile: 8,859; sh: 8,814; sql: 7,844; yacc: 3,863; perl: 2,955; python: 2,710; java: 449; javascript: 269; php: 258; ruby: 225; cs: 40; awk: 27
file content (493 lines) | stat: -rw-r--r-- 17,481 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">

<section id="routing_engine" xmlns:xi="http://www.w3.org/2001/XInclude">
    <sectioninfo>
	<revhistory>
	    <revision>
		<revnumber>$Revision$</revnumber>
		<date>$Date$</date>
	    </revision>
	</revhistory>
    </sectioninfo>

    <title>The Routing Engine</title>
    <para>
	In a previous section we discussed how routing part of a config file
	gets translated into binary representation. In this section, we will
	discuss how the binary representation is used during message
	processing.
    </para>
    <para>
	Upon a <acronym>SIP</acronym> message receipt, the server performs some
	basic sanity checks and converts the message into
	<structname>sip_msg</structname> structure. After that the Routing
	Engine will start processing the message.
    </para>
    <para>
	The routing engine can be found in file <filename>action.c</filename>.
    </para>
    <para>
	The main function is <function>run_actions.</function> The function
	accepts two parameters. The first parameter is list of actions to be
	processed (Remember, the config file gets translated into array of
	linked lists. Each linked list in the array represents one "route" part
	of the config file). The second parameter is
	<structname>sip_msg</structname> structure representing the message to
	be processed.
    </para>
    <para>
	Upon a receipt of a request, the linked list representing the main
	route part will be processed so the first parameter will be
	<varname>rlist[0]</varname>. (The linked list of main route part is
	always at index 0).
    </para>
    <para>
	The function will then sequentially call <function>do_action</function>
	function for each element of the linked list. Return value of the
	function is important. If the function returns 0, processing of the
	list will be stopped. By returning 0 a command can indicate that
	processing of the message should be stopped and the message will be
	dropped.
    </para>
    <para>
	Modules may export so-called <emphasis>on_break handlers</emphasis>.
	<emphasis>on_break</emphasis> handler is a function, that will be
	called when processing of the linked-list is interrupted (ret ==
	0). All such handlers will be called when processing of the linked-list
	is finished and ret == 0.
    </para>

    <section id="do_action">
	<title><function>do_action</function> Function</title>
	<para>
	    <function>do_action</function> function is core of the routing
	    engine. There is a big <function>switch</function> statement. Each
	    case of the statements is one command handled by the server core
	    itself.
	</para>
	<para>
	    The following commands are handled by the <acronym>SER</acronym> core
	    itself:
	    <function>drop</function>,
	    <function>forward</function>,
	    <function>send</function>,
	    <function>log</function>,
	    <function>append_branch</function>,
	    <function>len_gt</function>,
	    <function>setflag</function>,
	    <function>resetflag</function>,
	    <function>isflagset</function>,
	    <function>setavpflag</function>,
	    <function>resetavpflag</function>,
	    <function>isavpflagset</function>,
	    <function>error</function>,
	    <function>route</function>,
	    <function>exec</function>,
	    <function>revert_uri</function>,
	    <function>set_host</function>,
	    <function>set_hostport</function>,
	    <function>set_user</function>,
	    <function>set_userpass</function>,
	    <function>set_port</function>,
	    <function>set_uri</function>,
	    <function>prefix</function>,
	    <function>strip</function>,
	    <function>if</function>,
	    <function>module</function>.
	</para>
	<para>
	    Each of the commands is represented by a <emphasis>case</emphasis>
	    statement in the switch.  (For example, if you are interested in
	    implementation of <function>drop</function> command, look at
	    "case DROP_T:" statement in the function.
	</para>
	<para>
	    The respective commands will be described now.
	</para>
	<itemizedlist>
	    <listitem>
		<para>
		    <function>drop</function> - This command is very simple, it
		    simply returns 0 which will result in abortion of
		    processing of the request. No other commands after
		    <function>drop</function> will be executed.
		</para>
	    </listitem>
	    <listitem>
		<para>
		    <function>forward</function> - The function will forward
		    the message further. The message will be either forwarded
		    to the Request <acronym>URI</acronym> of the message or to
		    <acronym>IP</acronym> or host given as parameter.
		</para>
		<para>
		    In the first case, host in the Request
		    <acronym>URI</acronym> must be converted into corresponding
		    <acronym>IP</acronym> address.  Function
		    <function>mk_proxy</function> converts hostname to
		    corresponding <acronym>IP</acronym> address.  The message
		    is then sent out using <function>forward_request</function>
		    function.
		</para>
		<para>
		    In the second case, hostname was converted to
		    <acronym>IP</acronym> address in fixup i.e. immediately
		    after the config file was compiled into its binary
		    representation. The first parameter is pointer to
		    <structname>proxy</structname> structure created in the
		    fixup and therefore we only need to call
		    <function>forward_request</function> here to forward the
		    message further.
		</para>
	    </listitem>
	    <listitem>
		<para>
		    <function>send</function> - This functions sends the
		    message to a third-party host. The message will be sent out
		    as is - i.e. without Request <acronym>URI</acronym> and Via
		    altering.
		</para>
		<para>
		    Hostname or <acronym>IP</acronym> address of the
		    third-party host is specified as a parameter of the
		    function.
		</para>
		<para>
		    The message will be sent out using
		    <function>udp_send</function> directly.
		</para>
	    </listitem>
	    <listitem>
		<para>
		    <function>log</function> - The message given as a parameter
		    will be logged using system logger. It can be either
		    <command>syslog</command> or <varname>stderr</varname>
		    (depends on configuration). The message is logged using
		    <function>LOG</function> which is a macro defined in
		    <filename>dprint.h</filename> header file.
		</para>
	    </listitem>
	    <listitem>
		<para>
		    <function>append_branch</function> - Append a new
		    <acronym>URI</acronym> for forking.
		</para>
		<para>
		    More than one destinations may be associated with a single
		    <acronym>SIP</acronym> request. If the server was
		    configured so, it will use all the destinations and fork
		    the request.
		</para>
		<para>
		    The server keeps an array of all destinations, that should
		    be used when forking. The array and related functions can
		    be found in file <filename>dset.c</filename>. There is
		    function <function>append_branch</function> which adds a
		    new destination to the set.
		</para>
		<para>
		    This command simply calls
		    <function>append_branch</function> function and adds a new
		    destination to the destination set.
		</para>
	    </listitem>
	    <listitem>
		<para>
		    <function>len_gt</function> - The command accepts one
		    number as a parameter. It then compares the number with
		    length of the message. If the message length is greater or
		    equal then the number then 1 will be returned otherwise the
		    function returns -1.
		</para>
	    </listitem>
	    <listitem>
		<para>
		    <function>setflag</function> - Sets a flag in the
		    message. The command simply calls
		    <function>setflags</function> function that will set the
		    flag. Fore more information see file
		    <filename>flag.c</filename>.
		</para>
	    </listitem>
	    <listitem>
		<para>
		    <function>resetflag</function> - Same as command
		    <function>setflag</function> - only resetflag will be
		    called instead of setflag.
		</para>
	    </listitem>
	    <listitem>
		<para>
		    <function>isflagset</function> - Test if the flag
		    is set or not.
		</para>
	    </listitem>
	    <listitem>
		<para>
		    <function>setavpflag(avp, flag_id)</function> - Sets a flag in the
		    AVP(s). The command simply set custom flag of AVP. The flags
		    may be used in script using <function>isavpflagset</function>
		    or in a module to perform specific operation on marked AVPs.
		    Flag identifier must be declared via <emphasis>avpflags</emphasis>
		    statement.
		</para>
	    </listitem>
	    <listitem>
		<para>
		    <function>resetavpflag(avp, flag_id)</function> - Same as command
		    <function>setavpflag</function> - only resetavpflag will be
		    called instead of setavpflag.
		</para>
	    </listitem>
	    <listitem>
		<para>
		    <function>isavpflagset(avp, flag_id)</function> - Test if the avp flag
		    is set or not.
		</para>
	    </listitem>
	    <listitem>
		<para>
		    <function>error</function> - Log a message with NOTICE log
		    level.
		</para>
	    </listitem>
	    <listitem>
		<para>
		    <function>route</function> - Execute another
		    route statement.
		</para>
		<para>
		    As we have mentioned already, there can be more that one
		    route statement in the config file. One of them is main
		    (without number), the other are additional. This command
		    makes it possible to execute an additional route statement.
		</para>
		<para>
		    The command accepts one parameter which is route statement
		    number.  First sanity checks over the parameter will be
		    performed. If the checks passed, function
		    <function>run_actions</function> will be called.  The
		    function accepts two parameters. The first one is linked
		    list to execute, the second one is
		    <structname>sip_msg</structname> structure representing the
		    message to be processed.
		</para>
		<para>
		    As you might remember, each route statement was compiled
		    into linked list of commands to be executed and head of the
		    linked list was stored in <varname>rlist</varname>
		    array. For example, head of linked list representing route
		    statement with number 4 will be stored at position 4 in the
		    array (position 0 is reserved for the main route
		    statement).
		</para>
		<para>
		    So the command will simply call
		    <function>run_actions(rlist[a->p1.number], msg)</function>
		    and that will execute route statement with number given as
		    parameter.
		</para>
	    </listitem>
	    <listitem>
		<para>
		    <function>exec</function> - Execute a shell command.
		</para>
		<para>
		    The command accepts one parameter of type
		    <type>char*</type>. The string given as parameter will be
		    passed to <function>system</function> function which will
		    in turn execute <function>/bin/sh -c
			&lt;string&gt;</function>.
		</para>
	    </listitem>
	    <listitem>
		<para>
		    <function>revert_uri</function> - Revert changes made to
		    the Request <acronym>URI</acronym>.
		</para>
		<para>
		    If there is a new <acronym>URI</acronym> stored in
		    <structfield>new_uri</structfield> of
		    <structname>sip_msg</structname> structure, it will be
		    freed. The original Request <acronym>URI</acronym> will be
		    used when forwarding the message.
		</para>
		<para>
		    If there is a valid <acronym>URI</acronym> in
		    <structfield>parsed_uri</structfield> field of
		    <structname>sip_msg</structname> structure (indicated by
		    <structfield>parsed_uri_ok</structfield> field), it will be
		    freed too.
		</para>
	    </listitem>
	    <listitem>
		<para>
		    <function>set_host</function> - Change hostname of Request
		    <acronym>URI</acronym> to value given as parameter.
		</para>
		<para>
		    If there is a <acronym>URI</acronym> in
		    <structfield>new_uri</structfield> field, it will be
		    modified, otherwise the original Request
		    <acronym>URI</acronym> will be modified.
		</para>
	    </listitem>
	    <listitem>
		<para>
		    <function>set_hostport</function> - change hostname and
		    port of Request <acronym>URI</acronym> to value given as
		    string parameter.
		</para>
		<para>
		    If there is a <acronym>URI</acronym> in
		    <structfield>new_uri</structfield> field, it will be
		    modified, otherwise the original Request
		    <acronym>URI</acronym> will be modified.  </para>
	    </listitem>
	    <listitem>
		<para>
		    <function>set_user</function> - Set username part of
		    Request <acronym>URI</acronym> to string given as
		    parameter.
		</para>
		<para>
		    If there is a <acronym>URI</acronym> in
		    <structfield>new_uri</structfield> field, it will be
		    modified, otherwise the original Request
		    <acronym>URI</acronym> will be modified.
		</para>
	    </listitem>
	    <listitem>
		<para>
		    <function>set_userpass</function> - Set username and
		    password part of Request <acronym>URI</acronym> to string
		    given as parameter.
		</para>
		<para>
		    If there is a <acronym>URI</acronym> in
		    <structfield>new_uri</structfield> field, it will be
		    modified, otherwise the original Request
		    <acronym>URI</acronym> will be modified.  </para>
	    </listitem>
	    <listitem>
		<para>
		    <function>set_port</function> - Set port of Request
		    <acronym>URI</acronym> to value given as parameter.
		</para>
		<para>
		    If there is a <acronym>URI</acronym> in
		    <structfield>new_uri</structfield> field, it will be
		    modified, otherwise the original Request
		    <acronym>URI</acronym> will be modified.
		</para>
	    </listitem>
	    <listitem>
		<para>
		    <function>set_uri</function> - Set a new Request
		    <acronym>URI</acronym>.
		</para>
		<para>
		    If there is a <acronym>URI</acronym> in
		    <structfield>new_uri</structfield> field, it will be
		    freed. If there is a valid <acronym>URI</acronym> in
		    <structfield>parsed_uri</structfield> field, it will be
		    freed too.
		</para>
		<para>
		    Then <acronym>URI</acronym> given as parameter will be
		    stored in <structfield>new_uri</structfield> field. (If
		    <structfield>new_uri</structfield> contains a
		    <acronym>URI</acronym> it will be used instead of Request
		    <acronym>URI</acronym> when forwarding the message).
		</para>
	    </listitem>
		<listitem>
		<para>
		    <function>prefix</function> - Set the parameter as username
		    prefix.
		</para>
		<para>
		    The string will be put immediately after "sip:" part of the
		    Request <acronym>URI</acronym>.
		</para>
		<para>
		    If there is a <acronym>URI</acronym> in
		    <structfield>new_uri</structfield> field, it will be
		    modified, otherwise the original Request
		    <acronym>URI</acronym> will be modified.
		</para>
	    </listitem>
	    <listitem>
		<para>
		    <function>strip</function> - Remove first n characters of
		    username in Request <acronym>URI</acronym>.
		</para>
		<para>
		    If there is a <acronym>URI</acronym> in <structfield>new_uri</structfield>
		    field, it will be modified, otherwise the original Request
		    <acronym>URI</acronym> will be modified.
		</para>
	    </listitem>
	    <listitem>
		<para>
		    <function>if</function> - if Statement.
		</para>
		<para>
		    There is an expression associated with the command and one
		    or two linked lists of commands. The expression is a
		    regular expression compiled into binary form in the fixup
		    when the config file was compiled.
		</para>
		<para>
		    The expression will be evaluated now. If the result is &gt;
		    0, the first linked list will be executed using
		    <function>run_action</function> function. The linked list
		    represents command enclosed in curly braces of
		    <function>if</function> command.
		</para>
		<para>
		    Otherwise, if there is the second list, it will be executed
		    in the same way. The second list represents commands of
		    <function>else</function> statement.
		</para>
	    </listitem>
	    <listitem>
		<para>
		    <function>module</function> - Execute a function exported by
		    a module.
		</para>
		<para>
		    When a command in a route statement is not recognized by
		    the core itself (i.e. it is not one of commands handled by
		    the core itself), list of exported functions of all loaded
		    modules will be searched for a function with corresponding
		    name and number of parameters.
		</para>
		<para>
		    If the function was found, <function>module</function>
		    command (this one) will be created and pointer to the
		    function will be stored in
		    <structfield>p1.data</structfield> field.
		</para>
		<para>
		    So, this command will simply call function whose pointer is
		    in <structfield>p1.data</structfield> field and will pass 2
		    parameters to the function. If one or both of the
		    parameters were not used, 0 will be passed instead.
		</para>
		<para>
		    Return value of the function will be returned as return
		    value of <function>module</function> command.
		</para>
		<para>
		    This command makes <acronym>SER</acronym> pretty extensible
		    while the core itself is still reasonably small and
		    clean. Additional functionality is put in modules and
		    loaded only when needed.
		</para>
	    </listitem>
	</itemizedlist>
    </section> <!-- do-action -->
</section>