PageRenderTime 52ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/opensips-1.8.0-beta-tls/modules/rr/rr_mod.c

#
C | 345 lines | 235 code | 55 blank | 55 comment | 27 complexity | 2bed5651734a8b308fdc99bab4892127 MD5 | raw file
Possible License(s): AGPL-1.0
  1. /*
  2. * $Id: rr_mod.c 8159 2011-07-12 15:48:55Z vladut-paiu $
  3. *
  4. * Route & Record-Route module
  5. *
  6. * Copyright (C) 2001-2003 FhG Fokus
  7. *
  8. * This file is part of opensips, a free SIP server.
  9. *
  10. * opensips is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version
  14. *
  15. * opensips is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  23. *
  24. * History:
  25. * --------
  26. * 2003-03-11 updated to the new module interface (andrei)
  27. * 2003-03-16 flags export parameter added (janakj)
  28. * 2003-03-19 all mallocs/frees replaced w/ pkg_malloc/pkg_free (andrei)
  29. * 2003-04-01 Added record_route with ip address parameter (janakj)
  30. * 2003-04-14 enable_full_lr parameter introduced (janakj)
  31. * 2005-04-10 add_rr_param() and check_route_param() added (bogdan)
  32. * 2006-02-14 record_route may take as param a string to be used as RR param;
  33. * record_route and record_route_preset accept pseudo-variables in
  34. * parameters; add_rr_param may be called from BRANCH and FAILURE
  35. * routes (bogdan)
  36. */
  37. /*!
  38. * \file
  39. * \brief Route & Record-Route module
  40. * \ingroup rr
  41. */
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <sys/types.h>
  45. #include <regex.h>
  46. #include "../../sr_module.h"
  47. #include "../../ut.h"
  48. #include "../../error.h"
  49. #include "../../pvar.h"
  50. #include "../../mem/mem.h"
  51. #include "../../mod_fix.h"
  52. #include "loose.h"
  53. #include "record.h"
  54. #include "rr_cb.h"
  55. #include "api.h"
  56. #ifdef ENABLE_USER_CHECK
  57. #include <string.h>
  58. #include "../../str.h"
  59. str i_user;
  60. char *ignore_user = NULL;
  61. #endif
  62. int append_fromtag = 1;
  63. int enable_double_rr = 1; /* Enable using of 2 RR by default */
  64. int add_username = 0; /* Do not add username by default */
  65. int enable_socket_mismatch_warning = 1; /* Enable socket mismatch warning */
  66. static unsigned int last_rr_msg;
  67. static int mod_init(void);
  68. static void mod_destroy(void);
  69. /* fixup functions */
  70. static int direction_fixup(void** param, int param_no);
  71. static int it_list_fixup(void** param, int param_no);
  72. /* wrapper functions */
  73. static int w_record_route(struct sip_msg *,char *, char *);
  74. static int w_record_route_preset(struct sip_msg *,char *, char *);
  75. static int w_add_rr_param(struct sip_msg *,char *, char *);
  76. static int w_check_route_param(struct sip_msg *,char *, char *);
  77. static int w_is_direction(struct sip_msg *,char *, char *);
  78. static int pv_get_rr_params(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
  79. /*! \brief
  80. * Exported functions
  81. */
  82. static cmd_export_t cmds[] = {
  83. {"loose_route", (cmd_function)loose_route, 0,
  84. 0, 0,
  85. REQUEST_ROUTE},
  86. {"record_route", (cmd_function)w_record_route, 0,
  87. 0, 0,
  88. REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
  89. {"record_route", (cmd_function)w_record_route, 1,
  90. it_list_fixup, 0,
  91. REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
  92. {"record_route_preset", (cmd_function)w_record_route_preset, 1,
  93. it_list_fixup, 0,
  94. REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
  95. {"record_route_preset", (cmd_function)w_record_route_preset, 2,
  96. it_list_fixup, 0,
  97. REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
  98. {"add_rr_param", (cmd_function)w_add_rr_param, 1,
  99. it_list_fixup, 0,
  100. REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
  101. {"check_route_param", (cmd_function)w_check_route_param, 1,
  102. fixup_regexp_null, fixup_free_regexp_null,
  103. REQUEST_ROUTE},
  104. {"is_direction", (cmd_function)w_is_direction, 1,
  105. direction_fixup, 0,
  106. REQUEST_ROUTE},
  107. {"load_rr", (cmd_function)load_rr, 0, 0, 0, 0},
  108. {0, 0, 0, 0, 0, 0}
  109. };
  110. /*! \brief
  111. * Exported parameters
  112. */
  113. static param_export_t params[] ={
  114. {"append_fromtag", INT_PARAM, &append_fromtag },
  115. {"enable_double_rr", INT_PARAM, &enable_double_rr },
  116. #ifdef ENABLE_USER_CHECK
  117. {"ignore_user", STR_PARAM, &ignore_user },
  118. #endif
  119. {"add_username", INT_PARAM, &add_username },
  120. {"enable_socket_mismatch_warning", INT_PARAM, &enable_socket_mismatch_warning},
  121. {0, 0, 0 }
  122. };
  123. /**
  124. * pseudo-variables exported by RR module
  125. */
  126. static pv_export_t mod_items[] = {
  127. { {"rr_params", sizeof("rr_params")-1}, 900, pv_get_rr_params, 0,
  128. 0, 0, 0, 0 },
  129. { {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
  130. };
  131. #ifdef STATIC_RR
  132. struct module_exports rr_exports = {
  133. #else
  134. struct module_exports exports = {
  135. #endif
  136. "rr",
  137. MODULE_VERSION,
  138. DEFAULT_DLFLAGS, /*!< dlopen flags */
  139. cmds, /*!< Exported functions */
  140. params, /*!< Exported parameters */
  141. 0, /*!< exported statistics */
  142. 0, /*!< exported MI functions */
  143. mod_items, /*!< exported pseudo-variables */
  144. 0, /*!< extra processes */
  145. mod_init, /*!< initialize module */
  146. 0, /*!< response function*/
  147. mod_destroy, /*!< destroy function */
  148. 0 /*!< per-child init function */
  149. };
  150. static int mod_init(void)
  151. {
  152. LM_INFO("rr - initializing\n");
  153. #ifdef ENABLE_USER_CHECK
  154. if(ignore_user)
  155. {
  156. i_user.s = ignore_user;
  157. i_user.len = strlen(ignore_user);
  158. }
  159. else
  160. {
  161. i_user.s = 0;
  162. i_user.len = 0;
  163. }
  164. #endif
  165. return 0;
  166. }
  167. static void mod_destroy(void)
  168. {
  169. destroy_rrcb_lists();
  170. }
  171. static int it_list_fixup(void** param, int param_no)
  172. {
  173. pv_elem_t *model;
  174. str s;
  175. if(*param)
  176. {
  177. s.s = (char*)(*param); s.len = strlen(s.s);
  178. if(pv_parse_format(&s, &model)<0)
  179. {
  180. LM_ERR("wrong format[%s]\n",(char*)(*param));
  181. return E_UNSPEC;
  182. }
  183. *param = (void*)model;
  184. }
  185. return 0;
  186. }
  187. static int direction_fixup(void** param, int param_no)
  188. {
  189. char *s;
  190. int n;
  191. if (!append_fromtag) {
  192. LM_ERR("usage of \"is_direction\" function requires parameter"
  193. "\"append_fromtag\" enabled!!");
  194. return E_CFG;
  195. }
  196. if (param_no==1) {
  197. n = 0;
  198. s = (char*) *param;
  199. if ( strcasecmp(s,"downstream")==0 ) {
  200. n = RR_FLOW_DOWNSTREAM;
  201. } else if ( strcasecmp(s,"upstream")==0 ) {
  202. n = RR_FLOW_UPSTREAM;
  203. } else {
  204. LM_ERR("unknown direction '%s'\n",s);
  205. return E_CFG;
  206. }
  207. /* free string */
  208. pkg_free(*param);
  209. /* replace it with the flag */
  210. *param = (void*)(unsigned long)n;
  211. }
  212. return 0;
  213. }
  214. static int pv_get_rr_params(struct sip_msg *msg, pv_param_t *param,
  215. pv_value_t *res)
  216. {
  217. str val;
  218. if(msg==NULL || res==NULL)
  219. return -1;
  220. /* obtain routed params */
  221. if (get_route_params(msg, &val) < 0 )
  222. return -1;
  223. res->rs.s = val.s;
  224. res->rs.len = val.len;
  225. res->flags = PV_VAL_STR;
  226. return 0;
  227. }
  228. static int w_record_route(struct sip_msg *msg, char *key, char *bar)
  229. {
  230. str s;
  231. if (msg->id == last_rr_msg) {
  232. LM_ERR("Double attempt to record-route\n");
  233. return -1;
  234. }
  235. if (key && pv_printf_s(msg, (pv_elem_t*)key, &s)<0) {
  236. LM_ERR("failed to print the format\n");
  237. return -1;
  238. }
  239. if ( record_route( msg, key?&s:0 )<0 )
  240. return -1;
  241. last_rr_msg = msg->id;
  242. return 1;
  243. }
  244. static int w_record_route_preset(struct sip_msg *msg, char *key, char *key2)
  245. {
  246. str s;
  247. if (msg->id == last_rr_msg) {
  248. LM_ERR("Duble attempt to record-route\n");
  249. return -1;
  250. }
  251. if (key2 && !enable_double_rr) {
  252. LM_ERR("Attempt to double record-route while 'enable_double_rr' "
  253. "param is disabled\n");
  254. return -1;
  255. }
  256. if (pv_printf_s(msg, (pv_elem_t*)key, &s)<0) {
  257. LM_ERR("failed to print the format\n");
  258. return -1;
  259. }
  260. if ( record_route_preset( msg, &s)<0 )
  261. return -1;
  262. if (!key2)
  263. goto done;
  264. if (pv_printf_s(msg, (pv_elem_t*)key2, &s)<0) {
  265. LM_ERR("failed to print the format\n");
  266. return -1;
  267. }
  268. if ( record_route_preset( msg, &s)<0 )
  269. return -1;
  270. done:
  271. last_rr_msg = msg->id;
  272. return 1;
  273. }
  274. static int w_add_rr_param(struct sip_msg *msg, char *key, char *foo)
  275. {
  276. str s;
  277. if (pv_printf_s(msg, (pv_elem_t*)key, &s)<0) {
  278. LM_ERR("failed to print the format\n");
  279. return -1;
  280. }
  281. return ((add_rr_param( msg, &s)==0)?1:-1);
  282. }
  283. static int w_check_route_param(struct sip_msg *msg,char *re, char *foo)
  284. {
  285. return ((check_route_param(msg,(regex_t*)re)==0)?1:-1);
  286. }
  287. static int w_is_direction(struct sip_msg *msg,char *dir, char *foo)
  288. {
  289. return ((is_direction(msg,(int)(long)dir)==0)?1:-1);
  290. }