siputils.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. /*
  2. * $Id$
  3. *
  4. * Copyright (C) 2008-2009 1&1 Internet AG
  5. * Copyright (C) 2001-2003 FhG Fokus
  6. *
  7. * This file is part of SIP-router, a free SIP server.
  8. *
  9. * SIP-router is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version
  13. *
  14. * SIP-router is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. */
  23. /*!
  24. * \file
  25. * \brief Module with several utiltity functions related to SIP messages handling
  26. * \ingroup siputils
  27. * - Module \ref siputils
  28. */
  29. /*!
  30. * \defgroup siputils SIPUTILS :: Various SIP message handling functions
  31. *
  32. * \note A Kamailio module (modules_k)
  33. *
  34. This module implement various functions and checks related to
  35. SIP message handling and URI handling.
  36. It offers some functions related to handle ringing. In a
  37. parallel forking scenario you get several 183s with SDP. You
  38. don't want that your customers hear more than one ringtone or
  39. answer machine in parallel on the phone. So its necessary to
  40. drop the 183 in this cases and send a 180 instead.
  41. This module provides a function to answer OPTIONS requests
  42. which are directed to the server itself. This means an OPTIONS
  43. request which has the address of the server in the request
  44. URI, and no username in the URI. The request will be answered
  45. with a 200 OK which the capabilities of the server.
  46. To answer OPTIONS request directed to your server is the
  47. easiest way for is-alive-tests on the SIP (application) layer
  48. from remote (similar to ICMP echo requests, also known as
  49. "ping", on the network layer).
  50. */
  51. #include <assert.h>
  52. #include "../../sr_module.h"
  53. #include "../../mem/mem.h"
  54. #include "../../dprint.h"
  55. #include "../../script_cb.h"
  56. #include "../../locking.h"
  57. #include "../../ut.h"
  58. #include "../../mod_fix.h"
  59. #include "../../error.h"
  60. #include "../../parser/parse_option_tags.h"
  61. #include "ring.h"
  62. #include "options.h"
  63. #include "checks.h"
  64. #include "rpid.h"
  65. #include "siputils.h"
  66. #include "utils.h"
  67. #include "contact_ops.h"
  68. #include "sipops.h"
  69. #include "config.h"
  70. MODULE_VERSION
  71. /* rpid handling defs */
  72. #define DEF_RPID_PREFIX ""
  73. #define DEF_RPID_SUFFIX ";party=calling;id-type=subscriber;screen=yes"
  74. #define DEF_RPID_AVP "$avp(s:rpid)"
  75. /*! Default Remote-Party-ID prefix */
  76. str rpid_prefix = {DEF_RPID_PREFIX, sizeof(DEF_RPID_PREFIX) - 1};
  77. /*! Default Remote-Party-IDD suffix */
  78. str rpid_suffix = {DEF_RPID_SUFFIX, sizeof(DEF_RPID_SUFFIX) - 1};
  79. /*! Definition of AVP containing rpid value */
  80. char* rpid_avp_param = DEF_RPID_AVP;
  81. gen_lock_t *ring_lock = NULL;
  82. unsigned int ring_timeout = 0;
  83. /* for options functionality */
  84. str opt_accept = str_init(ACPT_DEF);
  85. str opt_accept_enc = str_init(ACPT_ENC_DEF);
  86. str opt_accept_lang = str_init(ACPT_LAN_DEF);
  87. str opt_supported = str_init(SUPT_DEF);
  88. /** SL API structure */
  89. sl_api_t opt_slb;
  90. static int mod_init(void);
  91. static void mod_destroy(void);
  92. /* Fixup functions to be defined later */
  93. static int fixup_set_uri(void** param, int param_no);
  94. static int fixup_free_set_uri(void** param, int param_no);
  95. static int fixup_tel2sip(void** param, int param_no);
  96. static int fixup_get_uri_param(void** param, int param_no);
  97. static int free_fixup_get_uri_param(void** param, int param_no);
  98. static int fixup_option(void** param, int param_no);
  99. char *contact_flds_separator = DEFAULT_SEPARATOR;
  100. static cmd_export_t cmds[]={
  101. {"ring_insert_callid", (cmd_function)ring_insert_callid, 0, ring_fixup,
  102. 0, REQUEST_ROUTE|FAILURE_ROUTE},
  103. {"options_reply", (cmd_function)opt_reply, 0, 0,
  104. 0, REQUEST_ROUTE},
  105. {"is_user", (cmd_function)is_user, 1, fixup_str_null,
  106. 0, REQUEST_ROUTE|LOCAL_ROUTE},
  107. {"has_totag", (cmd_function)has_totag, 0, 0,
  108. 0, ANY_ROUTE},
  109. {"uri_param", (cmd_function)uri_param_1, 1, fixup_str_null,
  110. 0, REQUEST_ROUTE|LOCAL_ROUTE},
  111. {"uri_param", (cmd_function)uri_param_2, 2, fixup_str_str,
  112. 0, REQUEST_ROUTE|LOCAL_ROUTE},
  113. {"add_uri_param", (cmd_function)add_uri_param, 1, fixup_str_null,
  114. 0, REQUEST_ROUTE},
  115. {"get_uri_param", (cmd_function)get_uri_param, 2, fixup_get_uri_param,
  116. free_fixup_get_uri_param, REQUEST_ROUTE|LOCAL_ROUTE},
  117. {"tel2sip", (cmd_function)tel2sip, 3, fixup_tel2sip, 0,
  118. REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE},
  119. {"is_e164", (cmd_function)is_e164, 1, fixup_pvar_null,
  120. fixup_free_pvar_null, REQUEST_ROUTE|FAILURE_ROUTE|LOCAL_ROUTE},
  121. {"is_uri_user_e164", (cmd_function)w_is_uri_user_e164, 1, fixup_pvar_null,
  122. fixup_free_pvar_null, ANY_ROUTE},
  123. {"encode_contact", (cmd_function)encode_contact, 2, 0,
  124. 0, REQUEST_ROUTE|ONREPLY_ROUTE},
  125. {"decode_contact", (cmd_function)decode_contact, 0, 0,
  126. 0, REQUEST_ROUTE},
  127. {"decode_contact_header", (cmd_function)decode_contact_header, 0, 0,
  128. 0,REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE},
  129. {"cmp_uri", (cmd_function)w_cmp_uri, 2, fixup_spve_spve,
  130. 0, ANY_ROUTE},
  131. {"cmp_aor", (cmd_function)w_cmp_aor, 2, fixup_spve_spve,
  132. 0, ANY_ROUTE},
  133. {"is_rpid_user_e164", (cmd_function)is_rpid_user_e164, 0, 0,
  134. 0, REQUEST_ROUTE},
  135. {"append_rpid_hf", (cmd_function)append_rpid_hf, 0, 0,
  136. 0, REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
  137. {"append_rpid_hf", (cmd_function)append_rpid_hf_p, 2, fixup_str_str,
  138. 0, REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
  139. {"set_uri_user", (cmd_function)set_uri_user, 2, fixup_set_uri,
  140. fixup_free_set_uri, ANY_ROUTE},
  141. {"set_uri_host", (cmd_function)set_uri_host, 2, fixup_set_uri,
  142. fixup_free_set_uri, ANY_ROUTE},
  143. {"bind_siputils", (cmd_function)bind_siputils, 1, 0,
  144. 0, 0},
  145. {"is_request", (cmd_function)w_is_request, 0, 0,
  146. 0, ANY_ROUTE},
  147. {"is_reply", (cmd_function)w_is_reply, 0, 0,
  148. 0, ANY_ROUTE},
  149. {"is_gruu", (cmd_function)w_is_gruu, 0, 0,
  150. 0, ANY_ROUTE},
  151. {"is_gruu", (cmd_function)w_is_gruu, 1, fixup_spve_null,
  152. 0, ANY_ROUTE},
  153. {"is_supported", (cmd_function)w_is_supported, 1, fixup_option,
  154. 0, ANY_ROUTE},
  155. {"is_first_hop", (cmd_function)w_is_first_hop, 0, 0,
  156. 0, ANY_ROUTE},
  157. {0,0,0,0,0,0}
  158. };
  159. static param_export_t params[] = {
  160. {"ring_timeout", INT_PARAM, &default_siputils_cfg.ring_timeout},
  161. {"options_accept", PARAM_STR, &opt_accept},
  162. {"options_accept_encoding", PARAM_STR, &opt_accept_enc},
  163. {"options_accept_language", PARAM_STR, &opt_accept_lang},
  164. {"options_support", PARAM_STR, &opt_supported},
  165. {"contact_flds_separator", PARAM_STRING, &contact_flds_separator},
  166. {"rpid_prefix", PARAM_STR, &rpid_prefix },
  167. {"rpid_suffix", PARAM_STR, &rpid_suffix },
  168. {"rpid_avp", PARAM_STRING, &rpid_avp_param },
  169. {0, 0, 0}
  170. };
  171. struct module_exports exports= {
  172. "siputils",
  173. DEFAULT_DLFLAGS, /* dlopen flags */
  174. cmds, /* Exported functions */
  175. params, /* param exports */
  176. 0, /* exported statistics */
  177. 0, /* exported MI functions */
  178. 0, /* exported pseudo-variables */
  179. 0, /* extra processes */
  180. mod_init, /* initialization function */
  181. 0, /* Response function */
  182. mod_destroy, /* Destroy function */
  183. 0, /* Child init function */
  184. };
  185. static int mod_init(void)
  186. {
  187. if(default_siputils_cfg.ring_timeout > 0) {
  188. ring_init_hashtable();
  189. ring_lock = lock_alloc();
  190. assert(ring_lock);
  191. if (lock_init(ring_lock) == 0) {
  192. LM_CRIT("cannot initialize lock.\n");
  193. return -1;
  194. }
  195. if (register_script_cb(ring_filter, PRE_SCRIPT_CB|ONREPLY_CB, 0) != 0) {
  196. LM_ERR("could not insert callback");
  197. return -1;
  198. }
  199. }
  200. /* bind the SL API */
  201. if (sl_load_api(&opt_slb)!=0) {
  202. LM_ERR("cannot bind to SL API\n");
  203. return -1;
  204. }
  205. if ( init_rpid_avp(rpid_avp_param)<0 ) {
  206. LM_ERR("failed to init rpid AVP name\n");
  207. return -1;
  208. }
  209. if(cfg_declare("siputils", siputils_cfg_def, &default_siputils_cfg, cfg_sizeof(siputils), &siputils_cfg)){
  210. LM_ERR("Fail to declare the configuration\n");
  211. return -1;
  212. }
  213. return 0;
  214. }
  215. static void mod_destroy(void)
  216. {
  217. if (ring_lock) {
  218. lock_destroy(ring_lock);
  219. lock_dealloc((void *)ring_lock);
  220. ring_lock = NULL;
  221. }
  222. ring_destroy_hashtable();
  223. }
  224. /*!
  225. * \brief Bind function for the SIPUTILS API
  226. * \param api binded API
  227. * \return 0 on success, -1 on failure
  228. */
  229. int bind_siputils(siputils_api_t* api)
  230. {
  231. if (!api) {
  232. LM_ERR("invalid parameter value\n");
  233. return -1;
  234. }
  235. get_rpid_avp( &api->rpid_avp, &api->rpid_avp_type );
  236. api->has_totag = has_totag;
  237. api->is_uri_user_e164 = is_uri_user_e164;
  238. return 0;
  239. }
  240. /*
  241. * Fix set_uri_* function params: uri (writable pvar) and value (pvar)
  242. */
  243. static int fixup_set_uri(void** param, int param_no)
  244. {
  245. if (param_no == 1) {
  246. if (fixup_pvar_null(param, 1) != 0) {
  247. LM_ERR("failed to fixup uri pvar\n");
  248. return -1;
  249. }
  250. if (((pv_spec_t *)(*param))->setf == NULL) {
  251. LM_ERR("uri pvar is not writeble\n");
  252. return -1;
  253. }
  254. return 0;
  255. }
  256. if (param_no == 2) {
  257. return fixup_pvar_null(param, 1);
  258. }
  259. LM_ERR("invalid parameter number <%d>\n", param_no);
  260. return -1;
  261. }
  262. /*
  263. * Free set_uri_* params.
  264. */
  265. static int fixup_free_set_uri(void** param, int param_no)
  266. {
  267. return fixup_free_pvar_null(param, 1);
  268. }
  269. /*
  270. * Fix tel2sip function params: uri and hostpart pvars and
  271. * result writable pvar.
  272. */
  273. static int fixup_tel2sip(void** param, int param_no)
  274. {
  275. if ((param_no == 1) || (param_no == 2)) {
  276. if (fixup_var_str_12(param, 1) < 0) {
  277. LM_ERR("failed to fixup uri or hostpart pvar\n");
  278. return -1;
  279. }
  280. return 0;
  281. }
  282. if (param_no == 3) {
  283. if (fixup_pvar_null(param, 1) != 0) {
  284. LM_ERR("failed to fixup result pvar\n");
  285. return -1;
  286. }
  287. if (((pv_spec_t *)(*param))->setf == NULL) {
  288. LM_ERR("result pvar is not writeble\n");
  289. return -1;
  290. }
  291. return 0;
  292. }
  293. LM_ERR("invalid parameter number <%d>\n", param_no);
  294. return -1;
  295. }
  296. /* */
  297. static int fixup_get_uri_param(void** param, int param_no) {
  298. if (param_no == 1) {
  299. return fixup_str_null(param, 1);
  300. }
  301. if (param_no == 2) {
  302. if (fixup_pvar_null(param, 1) != 0) {
  303. LM_ERR("failed to fixup result pvar\n");
  304. return -1;
  305. }
  306. if (((pv_spec_t *)(*param))->setf == NULL) {
  307. LM_ERR("result pvar is not writeble\n");
  308. return -1;
  309. }
  310. return 0;
  311. }
  312. LM_ERR("invalid parameter number <%d>\n", param_no);
  313. return -1;
  314. }
  315. /* */
  316. static int free_fixup_get_uri_param(void** param, int param_no) {
  317. if (param_no == 1) {
  318. LM_WARN("free function has not been defined for spve\n");
  319. return 0;
  320. }
  321. if (param_no == 2) {
  322. return fixup_free_pvar_null(param, 1);
  323. }
  324. LM_ERR("invalid parameter number <%d>\n", param_no);
  325. return -1;
  326. }
  327. /* */
  328. static int fixup_option(void** param, int param_no) {
  329. char *option;
  330. unsigned int option_len, res;
  331. option = (char *)*param;
  332. option_len = strlen(option);
  333. if (param_no != 1) {
  334. LM_ERR("invalid parameter number <%d>\n", param_no);
  335. return -1;
  336. }
  337. switch (option_len) {
  338. case 4:
  339. if (strncasecmp(option, "path", 4) == 0)
  340. res = F_OPTION_TAG_PATH;
  341. else if (strncasecmp(option, "gruu", 4) == 0)
  342. res = F_OPTION_TAG_GRUU;
  343. else {
  344. LM_ERR("unknown option <%s>\n", option);
  345. return -1;
  346. }
  347. break;
  348. case 5:
  349. if (strncasecmp(option, "timer", 5) == 0)
  350. res = F_OPTION_TAG_TIMER;
  351. else {
  352. LM_ERR("unknown option <%s>\n", option);
  353. return -1;
  354. }
  355. break;
  356. case 6:
  357. if (strncasecmp(option, "100rel", 6) == 0)
  358. res = F_OPTION_TAG_100REL;
  359. else {
  360. LM_ERR("unknown option <%s>\n", option);
  361. return -1;
  362. }
  363. break;
  364. case 8:
  365. if (strncasecmp(option, "outbound", 8) == 0)
  366. res = F_OPTION_TAG_OUTBOUND;
  367. else {
  368. LM_ERR("unknown option <%s>\n", option);
  369. return -1;
  370. }
  371. break;
  372. case 9:
  373. if (strncasecmp(option, "eventlist", 9) == 0)
  374. res = F_OPTION_TAG_EVENTLIST;
  375. else {
  376. LM_ERR("unknown option <%s>\n", option);
  377. return -1;
  378. }
  379. break;
  380. default:
  381. LM_ERR("unknown option <%s>\n", option);
  382. return -1;
  383. }
  384. *param = (void *)(long)res;
  385. return 0;
  386. }