th_msg.c

Go to the documentation of this file.
00001 
00028 #include <string.h>
00029 
00030 #include "../../dprint.h"
00031 #include "../../mem/mem.h"
00032 #include "../../data_lump.h"
00033 #include "../../forward.h"
00034 #include "../../trim.h"
00035 #include "../../msg_translator.h"
00036 #include "../../parser/parse_rr.h"
00037 #include "../../parser/parse_uri.h"
00038 #include "../../parser/parse_param.h"
00039 #include "../../parser/parse_from.h"
00040 #include "../../parser/parse_to.h"
00041 #include "../../parser/parse_via.h"
00042 #include "../../parser/contact/parse_contact.h"
00043 #include "../../parser/parse_refer_to.h"
00044 #include "th_mask.h"
00045 #include "th_msg.h"
00046 
00047 extern str th_cookie_name;
00048 extern str th_cookie_value;
00049 extern str th_via_prefix;
00050 extern str th_uri_prefix;
00051 extern str th_callid_prefix;
00052 
00053 extern str th_ip;
00054 extern str th_uparam_name;
00055 extern str th_uparam_prefix;
00056 extern str th_vparam_name;
00057 extern str th_vparam_prefix;
00058 
00059 extern int th_param_mask_callid;
00060 
00061 int th_skip_rw(char *s, int len)
00062 {
00063         while(len>0)
00064         {
00065                 if(s[len-1]==' ' || s[len-1]=='\t' || s[len-1]=='\n' || s[len-1]=='\r'
00066                                 || s[len-1]==',')
00067                         len--;
00068                 else return len;
00069         }
00070         return 0;
00071 }
00072 
00073 struct via_param *th_get_via_param(struct via_body *via, str *name)
00074 {
00075         struct via_param *p;
00076         for(p=via->param_lst; p; p=p->next)
00077         {
00078                 if(p->name.len==name->len
00079                                 && strncasecmp(p->name.s, name->s, name->len)==0)
00080                         return p;
00081         }
00082         return NULL;
00083 }
00084 
00085 int th_get_param_value(str *in, str *name, str *value)
00086 {
00087         param_t* params = NULL;
00088         param_t* p = NULL;
00089         param_hooks_t phooks;
00090         if (parse_params(in, CLASS_ANY, &phooks, &params)<0)
00091                 return -1;
00092         for (p = params; p; p=p->next)
00093         {
00094                 if (p->name.len==name->len
00095                                 && strncasecmp(p->name.s, name->s, name->len)==0)
00096                 {
00097                         *value = p->body;
00098                         free_params(params);
00099                         return 0;
00100                 }
00101         }
00102         
00103         if(params) free_params(params);
00104         return 1;
00105 
00106 }
00107 
00108 int th_get_uri_param_value(str *uri, str *name, str *value)
00109 {
00110         struct sip_uri puri;
00111 
00112         memset(value, 0, sizeof(str));
00113         if(parse_uri(uri->s, uri->len, &puri)<0)
00114                 return -1;
00115         return th_get_param_value(&puri.params, name, value);
00116 }
00117 
00118 int th_get_uri_type(str *uri, int *mode, str *value)
00119 {
00120         struct sip_uri puri;
00121         int ret;
00122         str r2 = {"r2", 2};
00123 
00124         memset(value, 0, sizeof(str));
00125         *mode = 0;
00126         if(parse_uri(uri->s, uri->len, &puri)<0)
00127                 return -1;
00128 
00129         LM_DBG("+++++++++++ PARAMS [%.*s]\n", puri.params.len, puri.params.s);
00130         if(puri.host.len==th_ip.len
00131                         && strncasecmp(puri.host.s, th_ip.s, th_ip.len)==0)
00132         {
00133                 /* host matches TH ip */
00134                 ret = th_get_param_value(&puri.params, &th_uparam_name, value);
00135                 if(ret<0)
00136                         return -1;
00137                 return 2; /* decode */
00138         } else {
00139                 if(check_self(&puri.host, (puri.port_no)?puri.port_no:SIP_PORT, 0)==1)
00140                 {
00141                         /* myself -- matched on all protos */
00142                         ret = th_get_param_value(&puri.params, &r2, value);
00143                         if(ret<0)
00144                                 return -1;
00145                         if(ret==1) /* not found */
00146                                 return 0; /* skip */
00147                         LM_DBG("+++++++++++++++++++************ [%.*s]\n",
00148                                         value->len, value->s);
00149                         if(value->len==2 && strncasecmp(value->s, "on", 2)==0)
00150                                 *mode = 1;
00151                         memset(value, 0, sizeof(str));
00152                         return 0; /* skip */
00153                 } else {
00154                         return 1; /* encode */
00155                 }
00156         }
00157 }
00158 
00159 int th_mask_via(sip_msg_t *msg)
00160 {
00161         hdr_field_t *hdr;
00162         struct via_body *via;
00163         struct lump* l;
00164         int i;
00165         str out;
00166         int vlen;
00167 
00168         i=0;
00169         for(hdr=msg->h_via1; hdr; hdr=next_sibling_hdr(hdr))
00170         {
00171                 for(via=(struct via_body*)hdr->parsed; via; via=via->next)
00172                 {
00173                         i++;
00174                         LM_DBG("=======via[%d]\n", i);
00175                         LM_DBG("hdr: [%.*s]\n", via->hdr.len, via->hdr.s);
00176                         vlen = th_skip_rw(via->name.s, via->bsize);
00177                         LM_DBG("body: %d: [%.*s]\n", vlen, vlen, via->name.s);
00178                         if(i!=1)
00179                         {
00180                                 out.s = th_mask_encode(via->name.s, vlen, &th_via_prefix,
00181                                                 &out.len);
00182                                 if(out.s==NULL)
00183                                 {
00184                                         LM_ERR("cannot encode via %d\n", i);
00185                                         return -1;
00186                                 }
00187                                         
00188                                 LM_DBG("+body: %d: [%.*s]\n", out.len, out.len, out.s);
00189                                 l=del_lump(msg, via->name.s-msg->buf, vlen, 0);
00190                                 if (l==0)
00191                                 {
00192                                         LM_ERR("failed deleting via [%d]\n", i);
00193                                         pkg_free(out.s);
00194                                         return -1;
00195                                 }
00196                                 if (insert_new_lump_after(l, out.s, out.len, 0)==0){
00197                                         LM_ERR("could not insert new lump\n");
00198                                         pkg_free(out.s);
00199                                         return -1;
00200                                 }
00201                         }
00202                 }
00203         }
00204         return 0;
00205 }
00206 
00207 int th_mask_callid(sip_msg_t *msg)
00208 {
00209         struct lump* l;
00210         str out;
00211 
00212         if(th_param_mask_callid==0)
00213                 return 0;
00214 
00215         if(msg->callid==NULL)
00216         {
00217                 LM_ERR("cannot get Call-Id header\n");
00218                 return -1;
00219         }
00220                                 
00221         out.s = th_mask_encode(msg->callid->body.s, msg->callid->body.len,
00222                                 &th_callid_prefix, &out.len);
00223         if(out.s==NULL)
00224         {
00225                 LM_ERR("cannot encode callid\n");
00226                 return -1;
00227         }
00228                                 
00229         l=del_lump(msg, msg->callid->body.s-msg->buf, msg->callid->body.len, 0);
00230         if (l==0)
00231         {
00232                 LM_ERR("failed deleting callid\n");
00233                 pkg_free(out.s);
00234                 return -1;
00235         }
00236         if (insert_new_lump_after(l, out.s, out.len, 0)==0) {
00237                 LM_ERR("could not insert new lump\n");
00238                 pkg_free(out.s);
00239                 return -1;
00240         }
00241 
00242         return 0;
00243 }
00244 
00245 int th_mask_contact(sip_msg_t *msg)
00246 {
00247         struct lump* l;
00248         str out;
00249         str in;
00250         char *p;
00251         contact_t *c;
00252 
00253         if(msg->contact==NULL) 
00254         {
00255                 LM_DBG("no contact header\n");
00256                 return 0;
00257         }
00258 
00259         if(parse_contact(msg->contact) < 0)
00260         {
00261                 LM_ERR("failed parsing contact header\n");
00262                 return -1;
00263         }
00264         
00265         c = ((contact_body_t*)msg->contact->parsed)->contacts;
00266         in = c->uri;
00267 
00268         out.s = th_mask_encode(in.s, in.len, &th_uri_prefix, &out.len);
00269         if(out.s==NULL)
00270         {
00271                 LM_ERR("cannot encode contact uri\n");
00272                 return -1;
00273         }
00274         if(*(in.s-1)!='<')
00275         {
00276                 /* add < > around contact uri if not there */
00277                 p = (char*)pkg_malloc(out.len+3);
00278                 if(p==NULL)
00279                 {
00280                         LM_ERR("failed to get more pkg\n");
00281                         pkg_free(out.s);
00282                         return -1;
00283                 }
00284                 *p = '<';
00285                 strncpy(p+1, out.s, out.len);
00286                 p[out.len+1] = '>';
00287                 p[out.len+2] = '\0';
00288                 pkg_free(out.s);
00289                 out.s = p;
00290                 out.len += 2;
00291         }
00292                                 
00293         l=del_lump(msg, in.s-msg->buf, in.len, 0);
00294         if (l==0)
00295         {
00296                 LM_ERR("failed deleting contact uri\n");
00297                 pkg_free(out.s);
00298                 return -1;
00299         }
00300         if (insert_new_lump_after(l, out.s, out.len, 0)==0) {
00301                 LM_ERR("could not insert new lump\n");
00302                 pkg_free(out.s);
00303                 return -1;
00304         }
00305 
00306         return 0;
00307 }
00308 
00309 int th_mask_record_route(sip_msg_t *msg)
00310 {
00311         hdr_field_t *hdr;
00312         struct lump* l;
00313         int i;
00314         rr_t *rr;
00315         str out;
00316 
00317         if(msg->record_route==NULL)
00318         {
00319                 LM_DBG("no record route header\n");
00320                 return 0;
00321         }
00322         hdr = msg->record_route;
00323         i = 0;
00324         while(hdr!=NULL) 
00325         {
00326                 if (parse_rr(hdr) < 0) 
00327                 {
00328                         LM_ERR("failed to parse RR\n");
00329                         return -1;
00330                 }
00331 
00332                 rr =(rr_t*)hdr->parsed;
00333                 while(rr)
00334                 {
00335                         i++;
00336                         if(i!=1)
00337                         {
00338                                 out.s = th_mask_encode(rr->nameaddr.uri.s, rr->nameaddr.uri.len,
00339                                                 &th_uri_prefix, &out.len);
00340                                 if(out.s==NULL)
00341                                 {
00342                                         LM_ERR("cannot encode r-r %d\n", i);
00343                                         return -1;
00344                                 }
00345                                 l=del_lump(msg, rr->nameaddr.uri.s-msg->buf,
00346                                                 rr->nameaddr.uri.len, 0);
00347                                 if (l==0)
00348                                 {
00349                                         LM_ERR("failed deleting r-r [%d]\n", i);
00350                                         pkg_free(out.s);
00351                                         return -1;
00352                                 }
00353                                 if (insert_new_lump_after(l, out.s, out.len, 0)==0){
00354                                         LM_ERR("could not insert new lump\n");
00355                                         pkg_free(out.s);
00356                                         return -1;
00357                                 }
00358                         }
00359                         rr = rr->next;
00360                 }
00361                 hdr = next_sibling_hdr(hdr);
00362         }
00363 
00364         return 0;
00365 }
00366 
00367 int th_unmask_via(sip_msg_t *msg, str *cookie)
00368 {
00369         hdr_field_t *hdr;
00370         struct via_body *via;
00371         struct via_body *via2;
00372         struct via_param *vp;
00373         struct lump* l;
00374         int i;
00375         str out;
00376         int vlen;
00377 
00378         i=0;
00379         for(hdr=msg->h_via1; hdr; hdr=next_sibling_hdr(hdr))
00380         {
00381                 for(via=(struct via_body*)hdr->parsed; via; via=via->next)
00382                 {
00383                         i++;
00384                         LM_DBG("=======via[%d]\n", i);
00385                         LM_DBG("hdr: [%.*s]\n", via->hdr.len, via->hdr.s);
00386                         vlen = th_skip_rw(via->name.s, via->bsize);
00387                         LM_DBG("body: %d: [%.*s]\n", vlen, vlen, via->name.s);
00388                         if(i!=1)
00389                         {
00390                                 vp = th_get_via_param(via, &th_vparam_name);
00391                                 if(vp==NULL)
00392                                 {
00393                                         LM_ERR("cannot find param in via %d\n", i);
00394                                         return -1;
00395                                 }
00396                                 if(i==2)
00397                                         out.s = th_mask_decode(vp->value.s, vp->value.len,
00398                                                         &th_vparam_prefix, CRLF_LEN+1, &out.len);
00399                                 else
00400                                         out.s = th_mask_decode(vp->value.s, vp->value.len,
00401                                                         &th_vparam_prefix, 0, &out.len);
00402                                 if(out.s==NULL)
00403                                 {
00404                                         LM_ERR("cannot encode via %d\n", i);
00405                                         return -1;
00406                                 }
00407                                         
00408                                 LM_DBG("+body: %d: [%.*s]\n", out.len, out.len, out.s);
00409                                 if(i==2)
00410                                 {
00411                                         via2=pkg_malloc(sizeof(struct via_body));
00412                                         if (via2==0)
00413                                         {
00414                                                 LM_ERR("out of memory\n");
00415                                                 pkg_free(out.s);
00416                                                 return -1;
00417 
00418                                         }
00419                                         
00420                                         memset(via2, 0, sizeof(struct via_body));
00421                                         memcpy(out.s+out.len, CRLF, CRLF_LEN);
00422                                         out.s[out.len+CRLF_LEN]='X';
00423                                         if(parse_via(out.s, out.s+out.len+CRLF_LEN+1, via2)==NULL)
00424                                         {
00425                                                 LM_ERR("error parsing decoded via2\n");
00426                                                 free_via_list(via2);
00427                                                 pkg_free(out.s);
00428                                                 return -1;
00429                                         }
00430                                         out.s[out.len] = '\0';
00431                                         vp = th_get_via_param(via2, &th_cookie_name);
00432                                         if(vp==NULL)
00433                                         {
00434                                                 LM_ERR("cannot find cookie in via2\n");
00435                                                 free_via_list(via2);
00436                                                 pkg_free(out.s);
00437                                                 return -1;
00438                                         }
00439                                         *cookie = vp->value;
00440                                         free_via_list(via2);
00441                                 }
00442                                 l=del_lump(msg, via->name.s-msg->buf, vlen, 0);
00443                                 if (l==0)
00444                                 {
00445                                         LM_ERR("failed deleting via [%d]\n", i);
00446                                         pkg_free(out.s);
00447                                         return -1;
00448                                 }
00449                                 if (insert_new_lump_after(l, out.s, out.len, 0)==0)
00450                                 {
00451                                         LM_ERR("could not insert new lump\n");
00452                                         pkg_free(out.s);
00453                                         return -1;
00454                                 }
00455                         }
00456                 }
00457         }
00458 
00459         return 0;
00460 }
00461 
00462 int th_unmask_callid(sip_msg_t *msg)
00463 {
00464         struct lump* l;
00465         str out;
00466         
00467         if(th_param_mask_callid==0)
00468                 return 0;
00469         
00470         if(msg->callid==NULL)
00471         {
00472                 LM_ERR("cannot get Call-Id header\n");
00473                 return -1;
00474         }
00475                                 
00476         out.s = th_mask_decode(msg->callid->body.s, msg->callid->body.len,
00477                                         &th_callid_prefix, 0, &out.len);
00478         if(out.s==NULL)
00479         {
00480                 LM_ERR("cannot decode callid\n");
00481                 return -1;
00482         }
00483                                 
00484         l=del_lump(msg, msg->callid->body.s-msg->buf, msg->callid->body.len, 0);
00485         if (l==0)
00486         {
00487                 LM_ERR("failed deleting callid\n");
00488                 pkg_free(out.s);
00489                 return -1;
00490         }
00491         if (insert_new_lump_after(l, out.s, out.len, 0)==0) {
00492                 LM_ERR("could not insert new lump\n");
00493                 pkg_free(out.s);
00494                 return -1;
00495         }
00496 
00497         return 0;
00498 }
00499 
00500 int th_flip_record_route(sip_msg_t *msg, int mode)
00501 {
00502         hdr_field_t *hdr;
00503         struct lump* l;
00504         int i;
00505         rr_t *rr;
00506         str out;
00507         int utype;
00508         str pval;
00509         int r2;
00510         int act;
00511 
00512         if(msg->record_route==NULL)
00513         {
00514                 LM_DBG("no record route header\n");
00515                 return 0;
00516         }
00517         hdr = msg->record_route;
00518         i = 0;
00519         act = 0;
00520         if(mode==1)
00521                 act = 2;
00522         while(hdr!=NULL) 
00523         {
00524                 if (parse_rr(hdr) < 0) 
00525                 {
00526                         LM_ERR("failed to parse RR\n");
00527                         return -1;
00528                 }
00529 
00530                 rr =(rr_t*)hdr->parsed;
00531                 while(rr)
00532                 {
00533                         i++;
00534                         r2 = 0;
00535                         utype = th_get_uri_type(&rr->nameaddr.uri, &r2, &pval);
00536                         if(utype==0 && mode==1)
00537                         {
00538                                 if(r2==1)
00539                                 {
00540                                         act--;
00541                                         if(act==0)
00542                                                 return 0;
00543                                         utype = 1;
00544                                 } else {
00545                                         return 0;
00546                                 }
00547                         }
00548                         out.s = NULL;
00549                         switch(utype) {
00550                                 case 1: /* encode */
00551                                         if(act!=0 && mode==1)
00552                                         {
00553                                                 out.s = th_mask_encode(rr->nameaddr.uri.s,
00554                                                         rr->nameaddr.uri.len, &th_uri_prefix, &out.len);
00555                                                 if(out.s==NULL)
00556                                                 {
00557                                                         LM_ERR("cannot encode r-r %d\n", i);
00558                                                         return -1;
00559                                                 }
00560                                         }
00561                                 break;
00562                                 case 2: /* decode */
00563                                         if(mode==0)
00564                                         {
00565                                                 out.s = th_mask_decode(pval.s,
00566                                                         pval.len, &th_uparam_prefix, 0, &out.len);
00567                                                 if(out.s==NULL)
00568                                                 {
00569                                                         LM_ERR("cannot decode r-r %d\n", i);
00570                                                         return -1;
00571                                                 }
00572                                         }
00573                                 break;
00574                         }
00575                         if(out.s!=NULL)
00576                         {
00577                                 l=del_lump(msg, rr->nameaddr.uri.s-msg->buf,
00578                                                 rr->nameaddr.uri.len, 0);
00579                                 if (l==0)
00580                                 {
00581                                         LM_ERR("failed deleting r-r [%d]\n", i);
00582                                         pkg_free(out.s);
00583                                         return -1;
00584                                 }
00585                                 if (insert_new_lump_after(l, out.s, out.len, 0)==0){
00586                                         LM_ERR("could not insert new lump\n");
00587                                         pkg_free(out.s);
00588                                         return -1;
00589                                 }
00590                         }
00591                         rr = rr->next;
00592                 }
00593                 hdr = next_sibling_hdr(hdr);
00594         }
00595 
00596         return 0;
00597 }
00598 
00599 int th_unmask_route(sip_msg_t *msg)
00600 {
00601         hdr_field_t *hdr;
00602         struct lump* l;
00603         int i;
00604         rr_t *rr;
00605         str out;
00606         str eval;
00607 
00608         if(msg->route==NULL)
00609         {
00610                 LM_DBG("no record route header\n");
00611                 return 0;
00612         }
00613         hdr = msg->route;
00614         i = 0;
00615         while(hdr!=NULL) 
00616         {
00617                 if (parse_rr(hdr) < 0) 
00618                 {
00619                         LM_ERR("failed to parse RR\n");
00620                         return -1;
00621                 }
00622 
00623                 rr =(rr_t*)hdr->parsed;
00624                 while(rr)
00625                 {
00626                         i++;
00627                         if(i!=1)
00628                         {
00629                                 if(th_get_uri_param_value(&rr->nameaddr.uri, &th_uparam_name,
00630                                                         &eval)<0 || eval.len<=0)
00631                                         return -1;
00632         
00633                                 out.s = th_mask_decode(eval.s, eval.len,
00634                                                         &th_uparam_prefix, 0, &out.len);
00635 
00636                                 if(out.s==NULL)
00637                                 {
00638                                         LM_ERR("cannot decode R %d\n", i);
00639                                         return -1;
00640                                 }
00641                                 l=del_lump(msg, rr->nameaddr.uri.s-msg->buf,
00642                                                 rr->nameaddr.uri.len, 0);
00643                                 if (l==0)
00644                                 {
00645                                         LM_ERR("failed deleting R [%d]\n", i);
00646                                         pkg_free(out.s);
00647                                         return -1;
00648                                 }
00649                                 if (insert_new_lump_after(l, out.s, out.len, 0)==0){
00650                                         LM_ERR("could not insert new lump\n");
00651                                         pkg_free(out.s);
00652                                         return -1;
00653                                 }
00654                         }
00655                         rr = rr->next;
00656                 }
00657                 hdr = next_sibling_hdr(hdr);
00658         }
00659 
00660         return 0;
00661 }
00662 
00663 int th_unmask_ruri(sip_msg_t *msg)
00664 {
00665         str eval;
00666         struct lump* l;
00667         str out;
00668 
00669         if(th_get_uri_param_value(&REQ_LINE(msg).uri, &th_uparam_name, &eval)<0
00670                         || eval.len<=0)
00671                 return -1;
00672         
00673         out.s = th_mask_decode(eval.s, eval.len,
00674                                 &th_uparam_prefix, 0, &out.len);
00675         if(out.s==NULL)
00676         {
00677                 LM_ERR("cannot decode r-uri\n");
00678                 return -1;
00679         }
00680                                         
00681         LM_DBG("+decoded: %d: [%.*s]\n", out.len, out.len, out.s);
00682         l=del_lump(msg, REQ_LINE(msg).uri.s-msg->buf, REQ_LINE(msg).uri.len, 0);
00683         if (l==0)
00684         {
00685                 LM_ERR("failed deleting r-uri\n");
00686                 pkg_free(out.s);
00687                 return -1;
00688         }
00689         if (insert_new_lump_after(l, out.s, out.len, 0)==0)
00690         {
00691                 LM_ERR("could not insert new lump\n");
00692                 pkg_free(out.s);
00693                 return -1;
00694         }
00695 
00696         return 0;
00697 }
00698 
00699 int th_unmask_refer_to(sip_msg_t *msg)
00700 {
00701         str eval;
00702         str *uri;
00703         int ulen;
00704         struct lump* l;
00705         str out;
00706 
00707         if(!((get_cseq(msg)->method_id)&(METHOD_REFER)))
00708                 return 0;
00709 
00710         if(parse_refer_to_header(msg)==-1)
00711         {
00712                 LM_DBG("no Refer-To header\n");
00713                 return 0;
00714         }
00715         if(msg->refer_to==NULL || get_refer_to(msg)==NULL)
00716         {
00717                 LM_DBG("Refer-To header not found\n");
00718                 return 0;
00719         }
00720 
00721         uri = &(get_refer_to(msg)->uri);
00722         if(th_get_uri_param_value(uri, &th_uparam_name, &eval)<0
00723                         || eval.len<=0)
00724                 return -1;
00725 
00726         out.s = th_mask_decode(eval.s, eval.len,
00727                                 &th_uparam_prefix, 0, &out.len);
00728         if(out.s==NULL)
00729         {
00730                 LM_ERR("cannot decode r-uri\n");
00731                 return -1;
00732         }
00733 
00734         LM_DBG("+decoded: %d: [%.*s]\n", out.len, out.len, out.s);
00735         for(ulen=0; ulen<uri->len; ulen++)
00736         {
00737                 if(uri->s[ulen]=='?')
00738                         break;
00739         }
00740 
00741         l=del_lump(msg, uri->s-msg->buf, ulen, 0);
00742         if (l==0)
00743         {
00744                 LM_ERR("failed deleting r-uri\n");
00745                 pkg_free(out.s);
00746                 return -1;
00747         }
00748         if (insert_new_lump_after(l, out.s, out.len, 0)==0)
00749         {
00750                 LM_ERR("could not insert new lump\n");
00751                 pkg_free(out.s);
00752                 return -1;
00753         }
00754 
00755         return 0;
00756 }
00757 
00758 int th_update_hdr_replaces(sip_msg_t *msg)
00759 {
00760         struct hdr_field *hf = NULL;
00761         str replaces;
00762         str rcallid;
00763         struct lump* l;
00764         str out;
00765 
00766         LM_DBG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
00767         if(th_param_mask_callid==0)
00768                 return 0;
00769 
00770         if(!((get_cseq(msg)->method_id)&(METHOD_INVITE)))
00771                 return 0;
00772 
00773         for (hf=msg->headers; hf; hf=hf->next)
00774         {
00775                 if (hf->name.len==8 && strncasecmp(hf->name.s, "Replaces", 8)==0)
00776                         break;
00777         }
00778 
00779         if(hf==NULL)
00780                 return 0;
00781 
00782         replaces = hf->body;
00783         trim(&replaces);
00784         rcallid.s = replaces.s;
00785         for(rcallid.len=0; rcallid.len<replaces.len; rcallid.len++)
00786         {
00787                 if(rcallid.s[rcallid.len]==';')
00788                         break;
00789         }
00790 
00791         if(rcallid.len>th_callid_prefix.len
00792                         && strncmp(rcallid.s, th_callid_prefix.s, th_callid_prefix.len)==0)
00793         {
00794                 /* value encoded - decode it */
00795                 out.s = th_mask_decode(rcallid.s, rcallid.len,
00796                                         &th_callid_prefix, 0, &out.len);
00797         } else {
00798                 /* value decoded - encode it */
00799                 out.s = th_mask_encode(rcallid.s, rcallid.len,
00800                                 &th_callid_prefix, &out.len);
00801         }
00802         if(out.s==NULL)
00803         {
00804                 LM_ERR("cannot update Replaces callid\n");
00805                 return -1;
00806         }
00807 
00808         l=del_lump(msg, rcallid.s-msg->buf, rcallid.len, 0);
00809         if (l==0)
00810         {
00811                 LM_ERR("failed deleting Replaces callid\n");
00812                 pkg_free(out.s);
00813                 return -1;
00814         }
00815         if (insert_new_lump_after(l, out.s, out.len, 0)==0) {
00816                 LM_ERR("could not insert new lump\n");
00817                 pkg_free(out.s);
00818                 return -1;
00819         }
00820 
00821         return 0;
00822 }
00823 
00824 char* th_msg_update(sip_msg_t *msg, unsigned int *olen)
00825 {
00826         struct dest_info dst;
00827 
00828         init_dest_info(&dst);
00829         dst.proto = PROTO_UDP;
00830         return build_req_buf_from_sip_req(msg,
00831                         olen, &dst, BUILD_NO_LOCAL_VIA|BUILD_NO_VIA1_UPDATE);
00832 }
00833 
00834 int th_add_via_cookie(sip_msg_t *msg, struct via_body *via)
00835 {
00836         struct lump* l;
00837         int viap;
00838         str out;
00839 
00840         if (via->params.s) {
00841                 viap = via->params.s - via->hdr.s - 1;
00842         } else {
00843                 viap = via->host.s - via->hdr.s + via->host.len;
00844                 if (via->port!=0)
00845                         viap += via->port_str.len + 1; /* +1 for ':'*/
00846         }
00847         l = anchor_lump(msg, via->hdr.s - msg->buf + viap, 0, 0);
00848         if (l==0)
00849         {
00850                 LM_ERR("failed adding cookie to via [%p]\n", via);
00851                 return -1;
00852         }
00853         
00854         out.len = 1+th_cookie_name.len+1+th_cookie_value.len+1;
00855         out.s = (char*)pkg_malloc(out.len+1);
00856         if(out.s==0)
00857         {
00858                 LM_ERR("no pkg memory\n");
00859                 return -1;
00860         }
00861         out.s[0] = ';';
00862         memcpy(out.s+1, th_cookie_name.s, th_cookie_name.len);
00863         out.s[th_cookie_name.len+1]='=';
00864         memcpy(out.s+th_cookie_name.len+2, th_cookie_value.s, th_cookie_value.len);
00865         out.s[out.len-1] = 'v';
00866         out.s[out.len] = '\0';
00867         if (insert_new_lump_after(l, out.s, out.len, 0)==0){
00868                 LM_ERR("could not insert new lump!\n");
00869                 pkg_free(out.s);
00870                 return -1;
00871         }
00872         return 0;
00873 }
00874 
00875 int th_add_hdr_cookie(sip_msg_t *msg)
00876 {
00877         struct lump* anchor;
00878         str h;
00879 
00880         h.len = th_cookie_name.len + 2 + th_cookie_value.len + 1 + CRLF_LEN;
00881         h.s = (char*)pkg_malloc(h.len+1);
00882         if(h.s == 0)
00883         {
00884                 LM_ERR("no more pkg\n");
00885                 return -1;
00886         }
00887         anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, 0);
00888         if(anchor == 0)
00889         {
00890                 LM_ERR("can't get anchor\n");
00891                 pkg_free(h.s);
00892                 return -1;
00893         }
00894         memcpy(h.s, th_cookie_name.s, th_cookie_name.len);
00895         memcpy(h.s+th_cookie_name.len, ": ", 2);
00896         memcpy(h.s+th_cookie_name.len+2, th_cookie_value.s, th_cookie_value.len);
00897         memcpy(h.s+th_cookie_name.len+2+th_cookie_value.len+1, CRLF, CRLF_LEN);
00898         h.s[h.len-1-CRLF_LEN] = 'h';
00899         h.s[h.len] = '\0';
00900         if (insert_new_lump_before(anchor, h.s, h.len, 0) == 0)
00901         {
00902                 LM_ERR("can't insert lump\n");
00903                 pkg_free(h.s);
00904                 return -1;
00905         }
00906         LM_DBG("+++++++++++++ added cookie header [%s]\n", h.s);
00907         return 0;
00908 }
00909 
00910 struct via_param *th_get_via_cookie(sip_msg_t *msg, struct via_body *via)
00911 {
00912         struct via_param *p;
00913         for(p=via->param_lst; p; p=p->next)
00914         {
00915                 if(p->name.len==th_cookie_name.len
00916                                 && strncasecmp(p->name.s, th_cookie_name.s,
00917                                         th_cookie_name.len)==0)
00918                         return p;
00919         }
00920         return NULL;
00921 }
00922 
00923 hdr_field_t *th_get_hdr_cookie(sip_msg_t *msg)
00924 {
00925         hdr_field_t *hf;
00926         for (hf=msg->headers; hf; hf=hf->next)
00927         {
00928                 if (hf->name.len==th_cookie_name.len
00929                                 && strncasecmp(hf->name.s, th_cookie_name.s,
00930                                         th_cookie_name.len)==0)
00931                         return hf;
00932         }
00933         return NULL;
00934 }
00935 
00936 int th_add_cookie(sip_msg_t *msg)
00937 {
00938         if(th_cookie_value.len<=0)
00939                 return 0;
00940         th_add_hdr_cookie(msg);
00941         th_add_via_cookie(msg, msg->via1);
00942         return 0;
00943 }
00944 
00945 int th_del_hdr_cookie(sip_msg_t *msg)
00946 {
00947         hdr_field_t *hf;
00948         struct lump* l;
00949         for (hf=msg->headers; hf; hf=hf->next)
00950         {
00951                 if (hf->name.len==th_cookie_name.len
00952                                 && strncasecmp(hf->name.s, th_cookie_name.s,
00953                                         th_cookie_name.len)==0)
00954                 {
00955                         l=del_lump(msg, hf->name.s-msg->buf, hf->len, 0);
00956                         if (l==0) {
00957                                 LM_ERR("unable to delete cookie header\n");
00958                                 return -1;
00959                         }
00960                         return 0;
00961                 }
00962         }
00963         return 0;
00964 }
00965 
00966 int th_del_via_cookie(sip_msg_t *msg, struct via_body *via)
00967 {
00968         struct via_param *p;
00969         struct lump* l;
00970         for(p=via->param_lst; p; p=p->next)
00971         {
00972                 if(p->name.len==th_cookie_name.len
00973                                 && strncasecmp(p->name.s, th_cookie_name.s,
00974                                         th_cookie_name.len)==0)
00975                 {
00976                         l=del_lump(msg, p->start-msg->buf-1, p->size+1, 0);
00977                         if (l==0) {
00978                                 LM_ERR("unable to delete cookie header\n");
00979                                 return -1;
00980                         }
00981                         return 0;
00982                 }
00983         }
00984         return 0;
00985 }
00986 
00987 int th_del_cookie(sip_msg_t *msg)
00988 {
00989         th_del_hdr_cookie(msg);
00990         if(msg->first_line.type==SIP_REPLY)
00991                 th_del_via_cookie(msg, msg->via1);
00992         return 0;
00993 }
00994 
00995 
00996 char* th_get_cookie(sip_msg_t *msg, int *clen)
00997 {
00998         hdr_field_t *hf;
00999         struct via_param *p;
01000 
01001         hf = th_get_hdr_cookie(msg);
01002         if(hf!=NULL)
01003         {
01004                 *clen = hf->body.len;
01005                 return hf->body.s;
01006         }
01007         p = th_get_via_cookie(msg, msg->via1);
01008         if(p!=NULL)
01009         {
01010                 *clen = p->value.len;
01011                 return p->value.s;
01012         }
01013 
01014         *clen = 3;
01015         return "xxx";
01016 }
01017 
01018 int th_route_direction(sip_msg_t *msg)
01019 {
01020         rr_t *rr;
01021         struct sip_uri puri;
01022         str ftn = {"ftag", 4};
01023         str ftv = {0, 0};
01024 
01025         if(get_from(msg)->tag_value.len<=0)
01026         {
01027                 LM_ERR("failed to get from header tag\n");
01028                 return -1;
01029         }
01030         if(msg->route==NULL)
01031         {
01032                 LM_DBG("no route header - downstream\n");
01033                 return 0;
01034         }
01035         if (parse_rr(msg->route) < 0) 
01036         {
01037                 LM_ERR("failed to parse route header\n");
01038                 return -1;
01039         }
01040 
01041         rr =(rr_t*)msg->route->parsed;
01042 
01043         if (parse_uri(rr->nameaddr.uri.s, rr->nameaddr.uri.len, &puri) < 0) {
01044                 LM_ERR("failed to parse the first route URI\n");
01045                 return -1;
01046         }
01047         if(th_get_param_value(&puri.params, &ftn, &ftv)!=0)
01048                 return 0;
01049 
01050         if(get_from(msg)->tag_value.len!=ftv.len
01051                         || strncmp(get_from(msg)->tag_value.s, ftv.s, ftv.len)!=0)
01052         {
01053                 LM_DBG("ftag mismatch\n");
01054                 return 1;
01055         }
01056         LM_DBG("ftag match\n");
01057         return 0;
01058 }
01059 
01060 int th_skip_msg(sip_msg_t *msg)
01061 {
01062         if (msg->cseq==NULL || get_cseq(msg)==NULL) {
01063                 LM_WARN("Invalid/Unparsed CSeq in message. Skipping.");
01064                 return 1;
01065         }
01066 
01067         if((get_cseq(msg)->method_id)&(METHOD_REGISTER|METHOD_PUBLISH))
01068                 return 1;
01069 
01070         return 0;
01071 }
01072