routing_engine.xml 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
  3. "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
  4. <section id="routing_engine" xmlns:xi="http://www.w3.org/2001/XInclude">
  5. <sectioninfo>
  6. <revhistory>
  7. <revision>
  8. <revnumber>$Revision$</revnumber>
  9. <date>$Date$</date>
  10. </revision>
  11. </revhistory>
  12. </sectioninfo>
  13. <title>The Routing Engine</title>
  14. <para>
  15. In a previous section we discussed how routing part of a config file
  16. gets translated into binary representation. In this section, we will
  17. discuss how the binary representation is used during message
  18. processing.
  19. </para>
  20. <para>
  21. Upon a <acronym>SIP</acronym> message receipt, the server performs some
  22. basic sanity checks and converts the message into
  23. <structname>sip_msg</structname> structure. After that the Routing
  24. Engine will start processing the message.
  25. </para>
  26. <para>
  27. The routing engine can be found in file <filename>action.c</filename>.
  28. </para>
  29. <para>
  30. The main function is <function>run_actions.</function> The function
  31. accepts two parameters. The first parameter is list of actions to be
  32. processed (Remember, the config file gets translated into array of
  33. linked lists. Each linked list in the array represents one "route" part
  34. of the config file). The second parameter is
  35. <structname>sip_msg</structname> structure representing the message to
  36. be processed.
  37. </para>
  38. <para>
  39. Upon a receipt of a request, the linked list representing the main
  40. route part will be processed so the first parameter will be
  41. <varname>rlist[0]</varname>. (The linked list of main route part is
  42. always at index 0).
  43. </para>
  44. <para>
  45. The function will then sequentially call <function>do_action</function>
  46. function for each element of the linked list. Return value of the
  47. function is important. If the function returns 0, processing of the
  48. list will be stopped. By returning 0 a command can indicate that
  49. processing of the message should be stopped and the message will be
  50. dropped.
  51. </para>
  52. <para>
  53. Modules may export so-called <emphasis>on_break handlers</emphasis>.
  54. <emphasis>on_break</emphasis> handler is a function, that will be
  55. called when processing of the linked-list is interrupted (ret ==
  56. 0). All such handlers will be called when processing of the linked-list
  57. is finished and ret == 0.
  58. </para>
  59. <section id="do_action">
  60. <title><function>do_action</function> Function</title>
  61. <para>
  62. <function>do_action</function> function is core of the routing
  63. engine. There is a big <function>switch</function> statement. Each
  64. case of the statements is one command handled by the server core
  65. itself.
  66. </para>
  67. <para>
  68. The following commands are handled by the <acronym>SER</acronym> core
  69. itself:
  70. <function>drop</function>,
  71. <function>forward</function>,
  72. <function>send</function>,
  73. <function>log</function>,
  74. <function>append_branch</function>,
  75. <function>len_gt</function>,
  76. <function>setflag</function>,
  77. <function>resetflag</function>,
  78. <function>isflagset</function>,
  79. <function>setavpflag</function>,
  80. <function>resetavpflag</function>,
  81. <function>isavpflagset</function>,
  82. <function>error</function>,
  83. <function>route</function>,
  84. <function>exec</function>,
  85. <function>revert_uri</function>,
  86. <function>set_host</function>,
  87. <function>set_hostport</function>,
  88. <function>set_user</function>,
  89. <function>set_userpass</function>,
  90. <function>set_port</function>,
  91. <function>set_uri</function>,
  92. <function>prefix</function>,
  93. <function>strip</function>,
  94. <function>if</function>,
  95. <function>module</function>.
  96. </para>
  97. <para>
  98. Each of the commands is represented by a <emphasis>case</emphasis>
  99. statement in the switch. (For example, if you are interested in
  100. implementation of <function>drop</function> command, look at
  101. "case DROP_T:" statement in the function.
  102. </para>
  103. <para>
  104. The respective commands will be described now.
  105. </para>
  106. <itemizedlist>
  107. <listitem>
  108. <para>
  109. <function>drop</function> - This command is very simple, it
  110. simply returns 0 which will result in abortion of
  111. processing of the request. No other commands after
  112. <function>drop</function> will be executed.
  113. </para>
  114. </listitem>
  115. <listitem>
  116. <para>
  117. <function>forward</function> - The function will forward
  118. the message further. The message will be either forwarded
  119. to the Request <acronym>URI</acronym> of the message or to
  120. <acronym>IP</acronym> or host given as parameter.
  121. </para>
  122. <para>
  123. In the first case, host in the Request
  124. <acronym>URI</acronym> must be converted into corresponding
  125. <acronym>IP</acronym> address. Function
  126. <function>mk_proxy</function> converts hostname to
  127. corresponding <acronym>IP</acronym> address. The message
  128. is then sent out using <function>forward_request</function>
  129. function.
  130. </para>
  131. <para>
  132. In the second case, hostname was converted to
  133. <acronym>IP</acronym> address in fixup i.e. immediately
  134. after the config file was compiled into its binary
  135. representation. The first parameter is pointer to
  136. <structname>proxy</structname> structure created in the
  137. fixup and therefore we only need to call
  138. <function>forward_request</function> here to forward the
  139. message further.
  140. </para>
  141. </listitem>
  142. <listitem>
  143. <para>
  144. <function>send</function> - This functions sends the
  145. message to a third-party host. The message will be sent out
  146. as is - i.e. without Request <acronym>URI</acronym> and Via
  147. altering.
  148. </para>
  149. <para>
  150. Hostname or <acronym>IP</acronym> address of the
  151. third-party host is specified as a parameter of the
  152. function.
  153. </para>
  154. <para>
  155. The message will be sent out using
  156. <function>udp_send</function> directly.
  157. </para>
  158. </listitem>
  159. <listitem>
  160. <para>
  161. <function>log</function> - The message given as a parameter
  162. will be logged using system logger. It can be either
  163. <command>syslog</command> or <varname>stderr</varname>
  164. (depends on configuration). The message is logged using
  165. <function>LOG</function> which is a macro defined in
  166. <filename>dprint.h</filename> header file.
  167. </para>
  168. </listitem>
  169. <listitem>
  170. <para>
  171. <function>append_branch</function> - Append a new
  172. <acronym>URI</acronym> for forking.
  173. </para>
  174. <para>
  175. More than one destinations may be associated with a single
  176. <acronym>SIP</acronym> request. If the server was
  177. configured so, it will use all the destinations and fork
  178. the request.
  179. </para>
  180. <para>
  181. The server keeps an array of all destinations, that should
  182. be used when forking. The array and related functions can
  183. be found in file <filename>dset.c</filename>. There is
  184. function <function>append_branch</function> which adds a
  185. new destination to the set.
  186. </para>
  187. <para>
  188. This command simply calls
  189. <function>append_branch</function> function and adds a new
  190. destination to the destination set.
  191. </para>
  192. </listitem>
  193. <listitem>
  194. <para>
  195. <function>len_gt</function> - The command accepts one
  196. number as a parameter. It then compares the number with
  197. length of the message. If the message length is greater or
  198. equal then the number then 1 will be returned otherwise the
  199. function returns -1.
  200. </para>
  201. </listitem>
  202. <listitem>
  203. <para>
  204. <function>setflag</function> - Sets a flag in the
  205. message. The command simply calls
  206. <function>setflags</function> function that will set the
  207. flag. Fore more information see file
  208. <filename>flag.c</filename>.
  209. </para>
  210. </listitem>
  211. <listitem>
  212. <para>
  213. <function>resetflag</function> - Same as command
  214. <function>setflag</function> - only resetflag will be
  215. called instead of setflag.
  216. </para>
  217. </listitem>
  218. <listitem>
  219. <para>
  220. <function>isflagset</function> - Test if the flag
  221. is set or not.
  222. </para>
  223. </listitem>
  224. <listitem>
  225. <para>
  226. <function>setavpflag(avp, flag_id)</function> - Sets a flag in the
  227. AVP(s). The command simply set custom flag of AVP. The flags
  228. may be used in script using <function>isavpflagset</function>
  229. or in a module to perform specific operation on marked AVPs.
  230. Flag identifier must be declared via <emphasis>avpflags</emphasis>
  231. statement.
  232. </para>
  233. </listitem>
  234. <listitem>
  235. <para>
  236. <function>resetavpflag(avp, flag_id)</function> - Same as command
  237. <function>setavpflag</function> - only resetavpflag will be
  238. called instead of setavpflag.
  239. </para>
  240. </listitem>
  241. <listitem>
  242. <para>
  243. <function>isavpflagset(avp, flag_id)</function> - Test if the avp flag
  244. is set or not.
  245. </para>
  246. </listitem>
  247. <listitem>
  248. <para>
  249. <function>error</function> - Log a message with NOTICE log
  250. level.
  251. </para>
  252. </listitem>
  253. <listitem>
  254. <para>
  255. <function>route</function> - Execute another
  256. route statement.
  257. </para>
  258. <para>
  259. As we have mentioned already, there can be more that one
  260. route statement in the config file. One of them is main
  261. (without number), the other are additional. This command
  262. makes it possible to execute an additional route statement.
  263. </para>
  264. <para>
  265. The command accepts one parameter which is route statement
  266. number. First sanity checks over the parameter will be
  267. performed. If the checks passed, function
  268. <function>run_actions</function> will be called. The
  269. function accepts two parameters. The first one is linked
  270. list to execute, the second one is
  271. <structname>sip_msg</structname> structure representing the
  272. message to be processed.
  273. </para>
  274. <para>
  275. As you might remember, each route statement was compiled
  276. into linked list of commands to be executed and head of the
  277. linked list was stored in <varname>rlist</varname>
  278. array. For example, head of linked list representing route
  279. statement with number 4 will be stored at position 4 in the
  280. array (position 0 is reserved for the main route
  281. statement).
  282. </para>
  283. <para>
  284. So the command will simply call
  285. <function>run_actions(rlist[a->p1.number], msg)</function>
  286. and that will execute route statement with number given as
  287. parameter.
  288. </para>
  289. </listitem>
  290. <listitem>
  291. <para>
  292. <function>exec</function> - Execute a shell command.
  293. </para>
  294. <para>
  295. The command accepts one parameter of type
  296. <type>char*</type>. The string given as parameter will be
  297. passed to <function>system</function> function which will
  298. in turn execute <function>/bin/sh -c
  299. &lt;string&gt;</function>.
  300. </para>
  301. </listitem>
  302. <listitem>
  303. <para>
  304. <function>revert_uri</function> - Revert changes made to
  305. the Request <acronym>URI</acronym>.
  306. </para>
  307. <para>
  308. If there is a new <acronym>URI</acronym> stored in
  309. <structfield>new_uri</structfield> of
  310. <structname>sip_msg</structname> structure, it will be
  311. freed. The original Request <acronym>URI</acronym> will be
  312. used when forwarding the message.
  313. </para>
  314. <para>
  315. If there is a valid <acronym>URI</acronym> in
  316. <structfield>parsed_uri</structfield> field of
  317. <structname>sip_msg</structname> structure (indicated by
  318. <structfield>parsed_uri_ok</structfield> field), it will be
  319. freed too.
  320. </para>
  321. </listitem>
  322. <listitem>
  323. <para>
  324. <function>set_host</function> - Change hostname of Request
  325. <acronym>URI</acronym> to value given as parameter.
  326. </para>
  327. <para>
  328. If there is a <acronym>URI</acronym> in
  329. <structfield>new_uri</structfield> field, it will be
  330. modified, otherwise the original Request
  331. <acronym>URI</acronym> will be modified.
  332. </para>
  333. </listitem>
  334. <listitem>
  335. <para>
  336. <function>set_hostport</function> - change hostname and
  337. port of Request <acronym>URI</acronym> to value given as
  338. string parameter.
  339. </para>
  340. <para>
  341. If there is a <acronym>URI</acronym> in
  342. <structfield>new_uri</structfield> field, it will be
  343. modified, otherwise the original Request
  344. <acronym>URI</acronym> will be modified. </para>
  345. </listitem>
  346. <listitem>
  347. <para>
  348. <function>set_user</function> - Set username part of
  349. Request <acronym>URI</acronym> to string given as
  350. parameter.
  351. </para>
  352. <para>
  353. If there is a <acronym>URI</acronym> in
  354. <structfield>new_uri</structfield> field, it will be
  355. modified, otherwise the original Request
  356. <acronym>URI</acronym> will be modified.
  357. </para>
  358. </listitem>
  359. <listitem>
  360. <para>
  361. <function>set_userpass</function> - Set username and
  362. password part of Request <acronym>URI</acronym> to string
  363. given as parameter.
  364. </para>
  365. <para>
  366. If there is a <acronym>URI</acronym> in
  367. <structfield>new_uri</structfield> field, it will be
  368. modified, otherwise the original Request
  369. <acronym>URI</acronym> will be modified. </para>
  370. </listitem>
  371. <listitem>
  372. <para>
  373. <function>set_port</function> - Set port of Request
  374. <acronym>URI</acronym> to value given as parameter.
  375. </para>
  376. <para>
  377. If there is a <acronym>URI</acronym> in
  378. <structfield>new_uri</structfield> field, it will be
  379. modified, otherwise the original Request
  380. <acronym>URI</acronym> will be modified.
  381. </para>
  382. </listitem>
  383. <listitem>
  384. <para>
  385. <function>set_uri</function> - Set a new Request
  386. <acronym>URI</acronym>.
  387. </para>
  388. <para>
  389. If there is a <acronym>URI</acronym> in
  390. <structfield>new_uri</structfield> field, it will be
  391. freed. If there is a valid <acronym>URI</acronym> in
  392. <structfield>parsed_uri</structfield> field, it will be
  393. freed too.
  394. </para>
  395. <para>
  396. Then <acronym>URI</acronym> given as parameter will be
  397. stored in <structfield>new_uri</structfield> field. (If
  398. <structfield>new_uri</structfield> contains a
  399. <acronym>URI</acronym> it will be used instead of Request
  400. <acronym>URI</acronym> when forwarding the message).
  401. </para>
  402. </listitem>
  403. <listitem>
  404. <para>
  405. <function>prefix</function> - Set the parameter as username
  406. prefix.
  407. </para>
  408. <para>
  409. The string will be put immediately after "sip:" part of the
  410. Request <acronym>URI</acronym>.
  411. </para>
  412. <para>
  413. If there is a <acronym>URI</acronym> in
  414. <structfield>new_uri</structfield> field, it will be
  415. modified, otherwise the original Request
  416. <acronym>URI</acronym> will be modified.
  417. </para>
  418. </listitem>
  419. <listitem>
  420. <para>
  421. <function>strip</function> - Remove first n characters of
  422. username in Request <acronym>URI</acronym>.
  423. </para>
  424. <para>
  425. If there is a <acronym>URI</acronym> in <structfield>new_uri</structfield>
  426. field, it will be modified, otherwise the original Request
  427. <acronym>URI</acronym> will be modified.
  428. </para>
  429. </listitem>
  430. <listitem>
  431. <para>
  432. <function>if</function> - if Statement.
  433. </para>
  434. <para>
  435. There is an expression associated with the command and one
  436. or two linked lists of commands. The expression is a
  437. regular expression compiled into binary form in the fixup
  438. when the config file was compiled.
  439. </para>
  440. <para>
  441. The expression will be evaluated now. If the result is &gt;
  442. 0, the first linked list will be executed using
  443. <function>run_action</function> function. The linked list
  444. represents command enclosed in curly braces of
  445. <function>if</function> command.
  446. </para>
  447. <para>
  448. Otherwise, if there is the second list, it will be executed
  449. in the same way. The second list represents commands of
  450. <function>else</function> statement.
  451. </para>
  452. </listitem>
  453. <listitem>
  454. <para>
  455. <function>module</function> - Execute a function exported by
  456. a module.
  457. </para>
  458. <para>
  459. When a command in a route statement is not recognized by
  460. the core itself (i.e. it is not one of commands handled by
  461. the core itself), list of exported functions of all loaded
  462. modules will be searched for a function with corresponding
  463. name and number of parameters.
  464. </para>
  465. <para>
  466. If the function was found, <function>module</function>
  467. command (this one) will be created and pointer to the
  468. function will be stored in
  469. <structfield>p1.data</structfield> field.
  470. </para>
  471. <para>
  472. So, this command will simply call function whose pointer is
  473. in <structfield>p1.data</structfield> field and will pass 2
  474. parameters to the function. If one or both of the
  475. parameters were not used, 0 will be passed instead.
  476. </para>
  477. <para>
  478. Return value of the function will be returned as return
  479. value of <function>module</function> command.
  480. </para>
  481. <para>
  482. This command makes <acronym>SER</acronym> pretty extensible
  483. while the core itself is still reasonably small and
  484. clean. Additional functionality is put in modules and
  485. loaded only when needed.
  486. </para>
  487. </listitem>
  488. </itemizedlist>
  489. </section> <!-- do-action -->
  490. </section>