00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <sys/types.h>
00034 #include <regex.h>
00035
00036 #include "../../sr_module.h"
00037 #include "../../ut.h"
00038 #include "../../error.h"
00039 #include "../../pvar.h"
00040 #include "../../mem/mem.h"
00041 #include "../../mod_fix.h"
00042 #include "../../parser/parse_rr.h"
00043 #include "loose.h"
00044 #include "record.h"
00045 #include "rr_cb.h"
00046 #include "api.h"
00047
00048 #ifdef ENABLE_USER_CHECK
00049 #include <string.h>
00050 #include "../../str.h"
00051 str i_user;
00052 char *ignore_user = NULL;
00053 #endif
00054
00055 int append_fromtag = 1;
00056 int enable_double_rr = 1;
00057 int enable_full_lr = 0;
00058 int add_username = 0;
00059 int enable_socket_mismatch_warning = 1;
00061 static unsigned int last_rr_msg;
00062
00063 MODULE_VERSION
00064
00065 static int mod_init(void);static void mod_destroy(void);
00066
00067 static int direction_fixup(void** param, int param_no);
00068 static int it_list_fixup(void** param, int param_no);
00069
00070 static int w_loose_route(struct sip_msg *, char *, char *);
00071 static int w_record_route(struct sip_msg *, char *, char *);
00072 static int w_record_route_preset(struct sip_msg *,char *, char *);
00073 static int w_record_route_advertised_address(struct sip_msg *, char *, char *);
00074 static int w_add_rr_param(struct sip_msg *,char *, char *);
00075 static int w_check_route_param(struct sip_msg *,char *, char *);
00076 static int w_is_direction(struct sip_msg *,char *, char *);
00077
00078 static int pv_get_route_uri_f(struct sip_msg *, pv_param_t *, pv_value_t *);
00082 static cmd_export_t cmds[] = {
00083 {"loose_route", (cmd_function)w_loose_route, 0, 0, 0,
00084 REQUEST_ROUTE},
00085 {"record_route", (cmd_function)w_record_route, 0, 0, 0,
00086 REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
00087 {"record_route", (cmd_function)w_record_route, 1, it_list_fixup, 0,
00088 REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
00089 {"record_route_preset", (cmd_function)w_record_route_preset, 1, it_list_fixup, 0,
00090 REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
00091 {"record_route_preset", (cmd_function)w_record_route_preset, 2, it_list_fixup, 0,
00092 REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
00093 {"record_route_advertised_address", (cmd_function)w_record_route_advertised_address, 1, it_list_fixup, 0,
00094 REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
00095 {"add_rr_param", (cmd_function)w_add_rr_param, 1, it_list_fixup, 0,
00096 REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
00097 {"check_route_param", (cmd_function)w_check_route_param, 1, fixup_regexp_null, fixup_free_regexp_null,
00098 REQUEST_ROUTE},
00099 {"is_direction", (cmd_function)w_is_direction, 1, direction_fixup, 0,
00100 REQUEST_ROUTE},
00101 {"load_rr", (cmd_function)load_rr, 0, 0, 0, 0},
00102 {0, 0, 0, 0, 0, 0}
00103 };
00104
00105
00109 static param_export_t params[] ={
00110 {"append_fromtag", INT_PARAM, &append_fromtag},
00111 {"enable_double_rr", INT_PARAM, &enable_double_rr},
00112 {"enable_full_lr", INT_PARAM, &enable_full_lr},
00113 #ifdef ENABLE_USER_CHECK
00114 {"ignore_user", STR_PARAM, &ignore_user},
00115 #endif
00116 {"add_username", INT_PARAM, &add_username},
00117 {"enable_socket_mismatch_warning",INT_PARAM,&enable_socket_mismatch_warning},
00118 {0, 0, 0 }
00119 };
00120
00124 static pv_export_t mod_pvs[] = {
00125 {{"route_uri", (sizeof("route_uri")-1)},
00126 PVT_OTHER, pv_get_route_uri_f, 0, 0, 0, 0, 0},
00127 {{0, 0}, 0, 0, 0, 0, 0, 0, 0}
00128 };
00129
00130
00131
00132 struct module_exports exports = {
00133 "rr",
00134 DEFAULT_DLFLAGS,
00135 cmds,
00136 params,
00137 0,
00138 0,
00139 mod_pvs,
00140 0,
00141 mod_init,
00142 0,
00143 mod_destroy,
00144 0
00145 };
00146
00147
00148 static int mod_init(void)
00149 {
00150 #ifdef ENABLE_USER_CHECK
00151 if(ignore_user)
00152 {
00153 i_user.s = ignore_user;
00154 i_user.len = strlen(ignore_user);
00155 }
00156 else
00157 {
00158 i_user.s = 0;
00159 i_user.len = 0;
00160 }
00161 #endif
00162 return 0;
00163 }
00164
00165
00166 static void mod_destroy(void)
00167 {
00168 destroy_rrcb_lists();
00169 }
00170
00171
00172 static int it_list_fixup(void** param, int param_no)
00173 {
00174 pv_elem_t *model;
00175 str s;
00176 if(*param)
00177 {
00178 s.s = (char*)(*param); s.len = strlen(s.s);
00179 if(pv_parse_format(&s, &model)<0)
00180 {
00181 LM_ERR("wrong format[%s]\n",(char*)(*param));
00182 return E_UNSPEC;
00183 }
00184 *param = (void*)model;
00185 }
00186 return 0;
00187 }
00188
00189
00190 static int direction_fixup(void** param, int param_no)
00191 {
00192 char *s;
00193 int n;
00194
00195 if (!append_fromtag) {
00196 LM_ERR("usage of \"is_direction\" function requires parameter"
00197 "\"append_fromtag\" enabled!!");
00198 return E_CFG;
00199 }
00200 if (param_no==1) {
00201 n = 0;
00202 s = (char*) *param;
00203 if ( strcasecmp(s,"downstream")==0 ) {
00204 n = RR_FLOW_DOWNSTREAM;
00205 } else if ( strcasecmp(s,"upstream")==0 ) {
00206 n = RR_FLOW_UPSTREAM;
00207 } else {
00208 LM_ERR("unknown direction '%s'\n",s);
00209 return E_CFG;
00210 }
00211
00212 pkg_free(*param);
00213
00214 *param = (void*)(unsigned long)n;
00215 }
00216 return 0;
00217 }
00218
00222 static int w_loose_route(struct sip_msg *msg, char *p1, char *p2)
00223 {
00224 return loose_route(msg);
00225 }
00226
00230 static int w_record_route(struct sip_msg *msg, char *key, char *bar)
00231 {
00232 str s;
00233
00234 if (msg->id == last_rr_msg) {
00235 LM_ERR("Double attempt to record-route\n");
00236 return -1;
00237 }
00238
00239 if (key && pv_printf_s(msg, (pv_elem_t*)key, &s)<0) {
00240 LM_ERR("failed to print the format\n");
00241 return -1;
00242 }
00243 if ( record_route( msg, key?&s:0 )<0 )
00244 return -1;
00245
00246 last_rr_msg = msg->id;
00247 return 1;
00248 }
00249
00250
00251 static int w_record_route_preset(struct sip_msg *msg, char *key, char *key2)
00252 {
00253 str s;
00254
00255 if (msg->id == last_rr_msg) {
00256 LM_ERR("Duble attempt to record-route\n");
00257 return -1;
00258 }
00259 if (key2 && !enable_double_rr) {
00260 LM_ERR("Attempt to double record-route while 'enable_double_rr' param is disabled\n");
00261 return -1;
00262 }
00263
00264 if (pv_printf_s(msg, (pv_elem_t*)key, &s)<0) {
00265 LM_ERR("failed to print the format\n");
00266 return -1;
00267 }
00268 if ( record_route_preset( msg, &s)<0 )
00269 return -1;
00270
00271 if (!key2)
00272 goto done;
00273
00274 if (pv_printf_s(msg, (pv_elem_t*)key2, &s)<0) {
00275 LM_ERR("failed to print the format\n");
00276 return -1;
00277 }
00278 if ( record_route_preset( msg, &s)<0 )
00279 return -1;
00280
00281 done:
00282 last_rr_msg = msg->id;
00283 return 1;
00284 }
00285
00286
00290 static int w_record_route_advertised_address(struct sip_msg *msg, char *addr, char *bar)
00291 {
00292 str s;
00293
00294 if (msg->id == last_rr_msg) {
00295 LM_ERR("Double attempt to record-route\n");
00296 return -1;
00297 }
00298
00299 if (pv_printf_s(msg, (pv_elem_t*)addr, &s) < 0) {
00300 LM_ERR("failed to print the format\n");
00301 return -1;
00302 }
00303 if ( record_route_advertised_address( msg, &s ) < 0)
00304 return -1;
00305
00306 last_rr_msg = msg->id;
00307 return 1;
00308 }
00309
00310
00311 static int w_add_rr_param(struct sip_msg *msg, char *key, char *foo)
00312 {
00313 str s;
00314
00315 if (pv_printf_s(msg, (pv_elem_t*)key, &s)<0) {
00316 LM_ERR("failed to print the format\n");
00317 return -1;
00318 }
00319 return ((add_rr_param( msg, &s)==0)?1:-1);
00320 }
00321
00322
00323
00324 static int w_check_route_param(struct sip_msg *msg,char *re, char *foo)
00325 {
00326 return ((check_route_param(msg,(regex_t*)re)==0)?1:-1);
00327 }
00328
00329
00330
00331 static int w_is_direction(struct sip_msg *msg,char *dir, char *foo)
00332 {
00333 return ((is_direction(msg,(int)(long)dir)==0)?1:-1);
00334 }
00335
00336
00337
00338
00339
00340 static int
00341 pv_get_route_uri_f(struct sip_msg *msg, pv_param_t *param,
00342 pv_value_t *res)
00343 {
00344 struct hdr_field* hdr;
00345 rr_t* rt;
00346 str uri;
00347
00348 if (!msg) {
00349 LM_ERR("No message?!?\n");
00350 return -1;
00351 }
00352
00353
00354 if (parse_headers(msg, HDR_ROUTE_F, 0) == -1) {
00355 LM_ERR("while parsing message\n");
00356 return -1;
00357 }
00358
00359 if (!msg->route) {
00360 LM_INFO("No route header present.\n");
00361 return -1;
00362 }
00363 hdr = msg->route;
00364
00365
00366 if (parse_rr(hdr) == -1) {
00367 LM_ERR("Error while parsing Route header\n");
00368 return -1;
00369 }
00370
00371
00372
00373 rt = (rr_t*)hdr->parsed;
00374 uri = rt->nameaddr.uri;
00375
00376 return pv_get_strval(msg, param, res, &uri);
00377 }
00378