00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <sys/types.h>
00033 #include <regex.h>
00034
00035 #include "../../sr_module.h"
00036 #include "../../ut.h"
00037 #include "../../error.h"
00038 #include "../../pvar.h"
00039 #include "../../mem/mem.h"
00040 #include "../../mod_fix.h"
00041 #include "loose.h"
00042 #include "record.h"
00043 #include "rr_cb.h"
00044 #include "api.h"
00045
00046 #ifdef ENABLE_USER_CHECK
00047 #include <string.h>
00048 #include "../../str.h"
00049 str i_user;
00050 char *ignore_user = NULL;
00051 #endif
00052
00053 int append_fromtag = 1;
00054 int enable_double_rr = 1;
00055 int enable_full_lr = 0;
00056 int add_username = 0;
00057
00058 static unsigned int last_rr_msg;
00059
00060 MODULE_VERSION
00061
00062 static int mod_init(void);static void mod_destroy(void);
00063
00064 static int direction_fixup(void** param, int param_no);
00065 static int it_list_fixup(void** param, int param_no);
00066
00067 static int w_record_route(struct sip_msg *,char *, char *);
00068 static int w_record_route_preset(struct sip_msg *,char *, char *);
00069 static int w_add_rr_param(struct sip_msg *,char *, char *);
00070 static int w_check_route_param(struct sip_msg *,char *, char *);
00071 static int w_is_direction(struct sip_msg *,char *, char *);
00072
00073
00074
00075
00076 static cmd_export_t cmds[] = {
00077 {"loose_route", (cmd_function)loose_route, 0, 0, 0,
00078 REQUEST_ROUTE},
00079 {"record_route", (cmd_function)w_record_route, 0, 0, 0,
00080 REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
00081 {"record_route", (cmd_function)w_record_route, 1, it_list_fixup, 0,
00082 REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
00083 {"record_route_preset", (cmd_function)w_record_route_preset, 1, it_list_fixup, 0,
00084 REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
00085 {"add_rr_param", (cmd_function)w_add_rr_param, 1, it_list_fixup, 0,
00086 REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE},
00087 {"check_route_param", (cmd_function)w_check_route_param, 1, fixup_regexp_null, fixup_free_regexp_null,
00088 REQUEST_ROUTE},
00089 {"is_direction", (cmd_function)w_is_direction, 1, direction_fixup, 0,
00090 REQUEST_ROUTE},
00091 {"load_rr", (cmd_function)load_rr, 0, 0, 0, 0},
00092 {0, 0, 0, 0, 0, 0}
00093 };
00094
00095
00096
00097
00098
00099 static param_export_t params[] ={
00100 {"append_fromtag", INT_PARAM, &append_fromtag},
00101 {"enable_double_rr", INT_PARAM, &enable_double_rr},
00102 {"enable_full_lr", INT_PARAM, &enable_full_lr},
00103 #ifdef ENABLE_USER_CHECK
00104 {"ignore_user", STR_PARAM, &ignore_user},
00105 #endif
00106 {"add_username", INT_PARAM, &add_username},
00107 {0, 0, 0 }
00108 };
00109
00110
00111 struct module_exports exports = {
00112 "rr",
00113 DEFAULT_DLFLAGS,
00114 cmds,
00115 params,
00116 0,
00117 0,
00118 0,
00119 0,
00120 mod_init,
00121 0,
00122 mod_destroy,
00123 0
00124 };
00125
00126
00127 static int mod_init(void)
00128 {
00129 #ifdef ENABLE_USER_CHECK
00130 if(ignore_user)
00131 {
00132 i_user.s = ignore_user;
00133 i_user.len = strlen(ignore_user);
00134 }
00135 else
00136 {
00137 i_user.s = 0;
00138 i_user.len = 0;
00139 }
00140 #endif
00141 return 0;
00142 }
00143
00144
00145 static void mod_destroy(void)
00146 {
00147 destroy_rrcb_lists();
00148 }
00149
00150
00151 static int it_list_fixup(void** param, int param_no)
00152 {
00153 pv_elem_t *model;
00154 str s;
00155 if(*param)
00156 {
00157 s.s = (char*)(*param); s.len = strlen(s.s);
00158 if(pv_parse_format(&s, &model)<0)
00159 {
00160 LM_ERR("wrong format[%s]\n",(char*)(*param));
00161 return E_UNSPEC;
00162 }
00163 *param = (void*)model;
00164 }
00165 return 0;
00166 }
00167
00168
00169 static int direction_fixup(void** param, int param_no)
00170 {
00171 char *s;
00172 int n;
00173
00174 if (!append_fromtag) {
00175 LM_ERR("usage of \"is_direction\" function requires parameter"
00176 "\"append_fromtag\" enabled!!");
00177 return E_CFG;
00178 }
00179 if (param_no==1) {
00180 n = 0;
00181 s = (char*) *param;
00182 if ( strcasecmp(s,"downstream")==0 ) {
00183 n = RR_FLOW_DOWNSTREAM;
00184 } else if ( strcasecmp(s,"upstream")==0 ) {
00185 n = RR_FLOW_UPSTREAM;
00186 } else {
00187 LM_ERR("unknown direction '%s'\n",s);
00188 return E_CFG;
00189 }
00190
00191 pkg_free(*param);
00192
00193 *param = (void*)(unsigned long)n;
00194 }
00195 return 0;
00196 }
00197
00198
00199 static int w_record_route(struct sip_msg *msg, char *key, char *bar)
00200 {
00201 str s;
00202
00203 if (msg->id == last_rr_msg) {
00204 LM_ERR("Double attempt to record-route\n");
00205 return -1;
00206 }
00207
00208 if (key && pv_printf_s(msg, (pv_elem_t*)key, &s)<0) {
00209 LM_ERR("failed to print the format\n");
00210 return -1;
00211 }
00212 if ( record_route( msg, key?&s:0 )<0 )
00213 return -1;
00214
00215 last_rr_msg = msg->id;
00216 return 1;
00217 }
00218
00219
00220 static int w_record_route_preset(struct sip_msg *msg, char *key, char *bar)
00221 {
00222 str s;
00223
00224 if (msg->id == last_rr_msg) {
00225 LM_ERR("Duble attempt to record-route\n");
00226 return -1;
00227 }
00228
00229 if (pv_printf_s(msg, (pv_elem_t*)key, &s)<0) {
00230 LM_ERR("failed to print the format\n");
00231 return -1;
00232 }
00233 if ( record_route_preset( msg, &s)<0 )
00234 return -1;
00235
00236 last_rr_msg = msg->id;
00237 return 1;
00238 }
00239
00240
00241 static int w_add_rr_param(struct sip_msg *msg, char *key, char *foo)
00242 {
00243 str s;
00244
00245 if (pv_printf_s(msg, (pv_elem_t*)key, &s)<0) {
00246 LM_ERR("failed to print the format\n");
00247 return -1;
00248 }
00249 return ((add_rr_param( msg, &s)==0)?1:-1);
00250 }
00251
00252
00253
00254 static int w_check_route_param(struct sip_msg *msg,char *re, char *foo)
00255 {
00256 return ((check_route_param(msg,(regex_t*)re)==0)?1:-1);
00257 }
00258
00259
00260
00261 static int w_is_direction(struct sip_msg *msg,char *dir, char *foo)
00262 {
00263 return ((is_direction(msg,(int)(long)dir)==0)?1:-1);
00264 }