00001
00036 #include <stdio.h>
00037 #include <string.h>
00038 #include <stdlib.h>
00039 #include <unistd.h>
00040
00041 #include "../../sr_module.h"
00042 #include "../../events.h"
00043 #include "../../dprint.h"
00044 #include "../../tcp_options.h"
00045 #include "../../ut.h"
00046 #include "../../forward.h"
00047 #include "../../parser/msg_parser.h"
00048 #include "../../parser/parse_to.h"
00049 #include "../../parser/parse_from.h"
00050
00051 #include "../../modules/sanity/api.h"
00052
00053 #include "th_mask.h"
00054 #include "th_msg.h"
00055
00056 MODULE_VERSION
00057
00058
00060 str _th_key = { "aL9.n8~Hm]Z", 0 };
00061 str th_cookie_name = {"TH", 0};
00062 str th_cookie_value = {0, 0};
00063 str th_ip = {"10.1.1.10", 0};
00064 str th_uparam_name = {"line", 0};
00065 str th_uparam_prefix = {"sr-", 0};
00066 str th_vparam_name = {"branch", 0};
00067 str th_vparam_prefix = {"z9hG4bKsr-", 0};
00068
00069 str th_callid_prefix = {"!!:", 3};
00070 str th_via_prefix = {0, 0};
00071 str th_uri_prefix = {0, 0};
00072
00073 int th_param_mask_callid = 0;
00074
00075 int th_sanity_checks = 0;
00076 sanity_api_t scb;
00077
00078 int th_msg_received(void *data);
00079 int th_msg_sent(void *data);
00080
00082 static int mod_init(void);
00083
00084 static param_export_t params[]={
00085 {"mask_key", STR_PARAM, &_th_key.s},
00086 {"mask_ip", STR_PARAM, &th_ip.s},
00087 {"mask_callid", INT_PARAM, &th_param_mask_callid},
00088 {"uparam_name", STR_PARAM, &th_uparam_name.s},
00089 {"uparam_prefix", STR_PARAM, &th_uparam_prefix.s},
00090 {"vparam_name", STR_PARAM, &th_vparam_name.s},
00091 {"vparam_prefix", STR_PARAM, &th_vparam_prefix.s},
00092 {"callid_prefix", STR_PARAM, &th_callid_prefix.s},
00093 {"sanity_checks", INT_PARAM, &th_sanity_checks},
00094 {0,0,0}
00095 };
00096
00097
00099 struct module_exports exports= {
00100 "topoh",
00101 DEFAULT_DLFLAGS,
00102 0,
00103 params,
00104 0,
00105 0,
00106 0,
00107 0,
00108 mod_init,
00109 0,
00110 0,
00111 0
00112 };
00113
00117 static int mod_init(void)
00118 {
00119 if(th_sanity_checks!=0)
00120 {
00121 if(sanity_load_api(&scb)<0)
00122 {
00123 LM_ERR("cannot bind to sanity module\n");
00124 goto error;
00125 }
00126 }
00127 th_cookie_name.len = strlen(th_cookie_name.s);
00128 th_ip.len = strlen(th_ip.s);
00129 if(th_ip.len<=0)
00130 {
00131 LM_ERR("mask IP parameter is invalid\n");
00132 goto error;
00133 }
00134 if(check_self(&th_ip, 0, 0)==1)
00135 {
00136 LM_ERR("mask IP must be different than SIP server local IP\n");
00137 goto error;
00138 }
00139 th_uparam_name.len = strlen(th_uparam_name.s);
00140 th_uparam_prefix.len = strlen(th_uparam_prefix.s);
00141 th_vparam_name.len = strlen(th_vparam_name.s);
00142 th_vparam_prefix.len = strlen(th_vparam_prefix.s);
00143 th_callid_prefix.len = strlen(th_callid_prefix.s);
00144
00145
00146 th_via_prefix.len = 12 + th_ip.len + 1 + th_vparam_name.len + 1
00147 + th_vparam_prefix.len;
00148 th_via_prefix.s = (char*)pkg_malloc(th_via_prefix.len+1);
00149 if(th_via_prefix.s==NULL)
00150 {
00151 LM_ERR("via prefix parameter is invalid\n");
00152 goto error;
00153 }
00154
00155 th_uri_prefix.len = 4 + th_ip.len + 1 + th_uparam_name.len + 1
00156 + th_uparam_prefix.len;
00157 th_uri_prefix.s = (char*)pkg_malloc(th_uri_prefix.len+1);
00158 if(th_uri_prefix.s==NULL)
00159 {
00160 LM_ERR("uri prefix parameter is invalid\n");
00161 goto error;
00162 }
00163
00164 memcpy(th_via_prefix.s, "SIP/2.0/UDP ", 12);
00165 memcpy(th_via_prefix.s+12, th_ip.s, th_ip.len);
00166 th_via_prefix.s[12+th_ip.len] = ';';
00167 memcpy(th_via_prefix.s+12+th_ip.len+1, th_vparam_name.s,
00168 th_vparam_name.len);
00169 th_via_prefix.s[12+th_ip.len+1+th_vparam_name.len] = '=';
00170 memcpy(th_via_prefix.s+12+th_ip.len+1+th_vparam_name.len+1,
00171 th_vparam_prefix.s, th_vparam_prefix.len);
00172 th_via_prefix.s[th_via_prefix.len] = '\0';
00173 LM_DBG("VIA prefix: [%s]\n", th_via_prefix.s);
00174
00175 memcpy(th_uri_prefix.s, "sip:", 4);
00176 memcpy(th_uri_prefix.s+4, th_ip.s, th_ip.len);
00177 th_uri_prefix.s[4+th_ip.len] = ';';
00178 memcpy(th_uri_prefix.s+4+th_ip.len+1, th_uparam_name.s, th_uparam_name.len);
00179 th_uri_prefix.s[4+th_ip.len+1+th_uparam_name.len] = '=';
00180 memcpy(th_uri_prefix.s+4+th_ip.len+1+th_uparam_name.len+1,
00181 th_uparam_prefix.s, th_uparam_prefix.len);
00182 th_uri_prefix.s[th_uri_prefix.len] = '\0';
00183 LM_DBG("URI prefix: [%s]\n", th_uri_prefix.s);
00184
00185 th_mask_init();
00186 sr_event_register_cb(SREV_NET_DATA_IN, th_msg_received);
00187 sr_event_register_cb(SREV_NET_DATA_OUT, th_msg_sent);
00188 #ifdef USE_TCP
00189 tcp_set_clone_rcvbuf(1);
00190 #endif
00191 return 0;
00192 error:
00193 return -1;
00194 }
00195
00199 int th_prepare_msg(sip_msg_t *msg)
00200 {
00201 if (parse_msg(msg->buf, msg->len, msg)!=0)
00202 {
00203 LM_DBG("outbuf buffer parsing failed!");
00204 return 1;
00205 }
00206
00207 if (parse_headers(msg, HDR_EOH_F, 0)==-1)
00208 {
00209 LM_DBG("parsing headers failed");
00210 return 2;
00211 }
00212
00213 if(parse_from_header(msg)<0)
00214 {
00215 LM_ERR("cannot parse FROM header\n");
00216 return 3;
00217 }
00218
00219 return 0;
00220 }
00221
00225 int th_msg_received(void *data)
00226 {
00227 sip_msg_t msg;
00228 str *obuf;
00229 char *nbuf = NULL;
00230 int direction;
00231 int dialog;
00232
00233 obuf = (str*)data;
00234 memset(&msg, 0, sizeof(sip_msg_t));
00235 msg.buf = obuf->s;
00236 msg.len = obuf->len;
00237
00238 if(th_prepare_msg(&msg)!=0)
00239 {
00240 goto done;
00241 }
00242
00243 if(th_skip_msg(&msg))
00244 {
00245 goto done;
00246 }
00247
00248 direction = 0;
00249 th_cookie_value.s = "xx";
00250 th_cookie_value.len = 2;
00251 if(msg.first_line.type==SIP_REQUEST)
00252 {
00253 if(th_sanity_checks!=0)
00254 {
00255 if(scb.check_defaults(&msg)<1)
00256 {
00257 LM_ERR("sanity checks failed\n");
00258 goto done;
00259 }
00260 }
00261 dialog = (get_to(&msg)->tag_value.len>0)?1:0;
00262 if(dialog)
00263 {
00264 direction = th_route_direction(&msg);
00265 if(direction<0)
00266 {
00267 LM_ERR("not able to detect direction\n");
00268 goto done;
00269 }
00270 th_cookie_value.s = (direction==0)?"dc":"uc";
00271 } else {
00272 th_cookie_value.s = "di";
00273 }
00274 if(dialog)
00275 {
00276
00277 th_unmask_ruri(&msg);
00278 th_unmask_route(&msg);
00279 th_unmask_refer_to(&msg);
00280 if(direction==1)
00281 {
00282 th_unmask_callid(&msg);
00283 }
00284 }
00285 } else {
00286
00287 th_unmask_via(&msg, &th_cookie_value);
00288 th_flip_record_route(&msg, 0);
00289 if(th_cookie_value.s[0]=='u')
00290 {
00291 th_cookie_value.s = "dc";
00292 } else {
00293 th_cookie_value.s = "uc";
00294 th_unmask_callid(&msg);
00295 }
00296 th_cookie_value.len = 2;
00297 }
00298
00299 th_add_cookie(&msg);
00300 nbuf = th_msg_update(&msg, (unsigned int*)&obuf->len);
00301
00302 if(obuf->len>=BUF_SIZE)
00303 {
00304 LM_ERR("new buffer overflow (%d)\n", obuf->len);
00305 pkg_free(nbuf);
00306 return -1;
00307 }
00308 memcpy(obuf->s, nbuf, obuf->len);
00309 obuf->s[obuf->len] = '\0';
00310
00311 done:
00312 if(nbuf!=NULL)
00313 pkg_free(nbuf);
00314 free_sip_msg(&msg);
00315 return 0;
00316 }
00317
00321 int th_msg_sent(void *data)
00322 {
00323 sip_msg_t msg;
00324 str *obuf;
00325 int direction;
00326 int dialog;
00327 int local;
00328
00329 obuf = (str*)data;
00330 memset(&msg, 0, sizeof(sip_msg_t));
00331 msg.buf = obuf->s;
00332 msg.len = obuf->len;
00333
00334 if(th_prepare_msg(&msg)!=0)
00335 {
00336 goto done;
00337 }
00338
00339 if(th_skip_msg(&msg))
00340 {
00341 goto done;
00342 }
00343
00344 th_cookie_value.s = th_get_cookie(&msg, &th_cookie_value.len);
00345 LM_DBG("the COOKIE is [%.*s]\n", th_cookie_value.len, th_cookie_value.s);
00346 if(th_cookie_value.s[0]!='x')
00347 th_del_cookie(&msg);
00348 if(msg.first_line.type==SIP_REQUEST)
00349 {
00350 direction = (th_cookie_value.s[0]=='u')?1:0;
00351 dialog = (get_to(&msg)->tag_value.len>0)?1:0;
00352 local = (th_cookie_value.s[0]!='d'&&th_cookie_value.s[0]!='u')?1:0;
00353
00354 if(local)
00355 {
00356
00357 if(get_cseq(&msg)->method_id==METHOD_ACK
00358 || get_cseq(&msg)->method_id==METHOD_CANCEL)
00359 {
00360 th_mask_callid(&msg);
00361 goto ready;
00362 } else {
00363
00364 goto done;
00365 }
00366 }
00367 th_mask_via(&msg);
00368 th_mask_contact(&msg);
00369 th_mask_record_route(&msg);
00370 if(dialog)
00371 {
00372
00373 if(direction==0)
00374 {
00375
00376 th_mask_callid(&msg);
00377 }
00378 } else {
00379
00380 th_update_hdr_replaces(&msg);
00381 th_mask_callid(&msg);
00382 }
00383 } else {
00384
00385 if(th_cookie_value.s[th_cookie_value.len-1]=='x')
00386 {
00387
00388 goto done;
00389 }
00390 if(th_cookie_value.s[th_cookie_value.len-1]=='v')
00391 {
00392
00393 if(th_cookie_value.s[0]=='u')
00394 {
00395 th_mask_callid(&msg);
00396 }
00397 } else {
00398 th_flip_record_route(&msg, 1);
00399 th_mask_contact(&msg);
00400 if(th_cookie_value.s[0]=='d')
00401 {
00402 th_mask_callid(&msg);
00403 }
00404 }
00405 }
00406
00407 ready:
00408 obuf->s = th_msg_update(&msg, (unsigned int*)&obuf->len);
00409
00410 done:
00411 free_sip_msg(&msg);
00412 return 0;
00413 }
00414