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
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 #include "../../dprint.h"
00084 #include "../../parser/parser_f.h"
00085 #include "../../parser/parse_from.h"
00086 #include "../../ut.h"
00087 #include "../../timer.h"
00088 #include "../../hash_func.h"
00089 #include "../../forward.h"
00090 #include "t_funcs.h"
00091 #include "config.h"
00092 #include "sip_msg.h"
00093 #include "t_hooks.h"
00094 #include "t_lookup.h"
00095 #include "dlg.h"
00096 #include "t_msgbuilder.h"
00097 #include "t_fwd.h"
00098
00099 #define EQ_VIA_LEN(_via)\
00100 ( (p_msg->via1->bsize-(p_msg->_via->name.s-(p_msg->_via->hdr.s+p_msg->_via->hdr.len)))==\
00101 (t_msg->via1->bsize-(t_msg->_via->name.s-(t_msg->_via->hdr.s+t_msg->_via->hdr.len))) )
00102
00103
00104
00105 #define EQ_LEN(_hf) (t_msg->_hf->body.len==p_msg->_hf->body.len)
00106 #define EQ_REQ_URI_LEN\
00107 (p_msg->first_line.u.request.uri.len==t_msg->first_line.u.request.uri.len)
00108
00109 #define EQ_STR(_hf) (memcmp(t_msg->_hf->body.s,\
00110 p_msg->_hf->body.s, \
00111 p_msg->_hf->body.len)==0)
00112 #define EQ_REQ_URI_STR\
00113 ( memcmp( t_msg->first_line.u.request.uri.s,\
00114 p_msg->first_line.u.request.uri.s,\
00115 p_msg->first_line.u.request.uri.len)==0)
00116 #define EQ_VIA_STR(_via)\
00117 ( memcmp( t_msg->_via->name.s,\
00118 p_msg->_via->name.s,\
00119 (t_msg->via1->bsize-(t_msg->_via->name.s-(t_msg->_via->hdr.s+t_msg->_via->hdr.len)))\
00120 )==0 )
00121 #define EQ_STRS( _s1, _s2 ) \
00122 ( (_s1).len==(_s2).len && memcmp((_s1).s,(_s2).s,(_s2).len)==0)
00123
00124
00125 #define HF_LEN(_hf) ((_hf)->len)
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 int ruri_matching=1;
00136 int via1_matching=1;
00137
00138
00139
00140
00141
00142
00143
00144
00145 static struct cell *T;
00146
00147
00148
00149
00150
00151 static struct cell *cancelled_T;
00152
00153
00154
00155
00156
00157 static struct cell *e2eack_T;
00158
00159
00160
00161 struct cell *get_t(void) { return T; }
00162 void set_t(struct cell *t) { T=t; }
00163
00164 void init_t(void) {set_t(T_UNDEFINED);}
00165
00166 struct cell *get_cancelled_t(void) { return cancelled_T; }
00167 void reset_cancelled_t(void) { cancelled_T=T_UNDEFINED; }
00168
00169 struct cell *get_e2eack_t(void) { return e2eack_T; }
00170 void reset_e2eack_t(void) { e2eack_T=T_UNDEFINED; }
00171
00172
00173
00174
00175
00176
00177
00178 static inline int parse_dlg( struct sip_msg *msg )
00179 {
00180 if (parse_headers(msg, HDR_FROM_F | HDR_CSEQ_F | HDR_TO_F, 0)==-1) {
00181 LM_ERR("From or Cseq or To invalid\n");
00182 return 0;
00183 }
00184 if ((msg->from==0)||(msg->cseq==0)||(msg->to==0)) {
00185 LM_ERR("missing From or Cseq or To\n");
00186 return 0;
00187 }
00188
00189 if (parse_from_header(msg)<0) {
00190 LM_ERR("From broken\n");
00191 return 0;
00192 }
00193
00194
00195 return 1;
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 static inline int partial_dlg_matching(struct sip_msg *t_msg, struct sip_msg *p_msg)
00209 {
00210 struct to_body *inv_from;
00211
00212 if (!EQ_LEN(callid)) return 0;
00213 if (get_cseq(t_msg)->number.len!=get_cseq(p_msg)->number.len)
00214 return 0;
00215 inv_from=get_from(t_msg);
00216 if (!inv_from) {
00217 LM_ERR("INV/From not parsed\n");
00218 return 0;
00219 }
00220 if (inv_from->tag_value.len!=get_from(p_msg)->tag_value.len)
00221 return 0;
00222 if (!EQ_STR(callid))
00223 return 0;
00224 if (memcmp(get_cseq(t_msg)->number.s, get_cseq(p_msg)->number.s,
00225 get_cseq(p_msg)->number.len)!=0)
00226 return 0;
00227 if (memcmp(inv_from->tag_value.s, get_from(p_msg)->tag_value.s,
00228 get_from(p_msg)->tag_value.len)!=0)
00229 return 0;
00230 return 1;
00231 }
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 static inline int dlg_matching(struct cell *p_cell, struct sip_msg *ack )
00243 {
00244 if (get_to(ack)->tag_value.len!=p_cell->uas.local_totag.len)
00245 return 0;
00246 if (memcmp(get_to(ack)->tag_value.s,p_cell->uas.local_totag.s,
00247 p_cell->uas.local_totag.len)!=0)
00248 return 0;
00249 return 1;
00250 }
00251
00252
00253
00254
00255
00256
00257 static inline int ack_matching(struct cell *p_cell, struct sip_msg *p_msg)
00258 {
00259
00260
00261 if (!partial_dlg_matching(p_cell->uas.request, p_msg))
00262 return 0;
00263
00264
00265
00266
00267
00268 if (p_cell->relayed_reply_branch!=-2) {
00269 return 2;
00270 }
00271
00272 if (dlg_matching(p_cell, p_msg)) {
00273 return 2;
00274 }
00275 return 0;
00276 }
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 static inline int via_matching( struct via_body *inv_via,
00287 struct via_body *ack_via )
00288 {
00289 if (inv_via->tid.len!=ack_via->tid.len)
00290 return 0;
00291 if (memcmp(inv_via->tid.s, ack_via->tid.s,
00292 ack_via->tid.len)!=0)
00293 return 0;
00294
00295
00296
00297
00298 if (inv_via->host.len!=ack_via->host.len)
00299 return 0;;
00300 if (memcmp(inv_via->host.s, ack_via->host.s,
00301 ack_via->host.len)!=0)
00302 return 0;
00303 if (inv_via->port!=ack_via->port)
00304 return 0;
00305 if (inv_via->transport.len!=ack_via->transport.len)
00306 return 0;
00307 if (memcmp(inv_via->transport.s, ack_via->transport.s,
00308 ack_via->transport.len)!=0)
00309 return 0;
00310
00311 return 1;
00312 }
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 static int matching_3261( struct sip_msg *p_msg, struct cell **trans,
00327 enum request_method skip_method)
00328 {
00329 struct cell *p_cell;
00330 struct sip_msg *t_msg;
00331 struct via_body *via1;
00332 int is_ack;
00333 int dlg_parsed;
00334 int ret = 0;
00335 struct cell *e2e_ack_trans;
00336 int e2e_ack_ret = 0;
00337
00338 e2e_ack_trans=0;
00339 via1=p_msg->via1;
00340 is_ack=p_msg->REQ_METHOD==METHOD_ACK;
00341 dlg_parsed=0;
00342
00343 via1->tid.s=via1->branch->value.s+MCOOKIE_LEN;
00344 via1->tid.len=via1->branch->value.len-MCOOKIE_LEN;
00345
00346 for ( p_cell = get_tm_table()->entrys[p_msg->hash_index].first_cell;
00347 p_cell; p_cell = p_cell->next_cell )
00348 {
00349 t_msg=p_cell->uas.request;
00350 if (!t_msg) continue;
00351 if (skip_method & t_msg->REQ_METHOD) continue;
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 if (is_ack && e2e_ack_trans==0 &&
00368 p_cell->uas.status>=200 && p_cell->uas.status<300) {
00369
00370
00371 if (!dlg_parsed) {
00372 dlg_parsed=1;
00373 if (!parse_dlg(p_msg)) {
00374 LM_ERR("dlg parsing failed\n");
00375 return 0;
00376 }
00377 }
00378 ret=ack_matching(p_cell , p_msg );
00379 if (ret>0) {
00380 e2e_ack_trans=p_cell;
00381 e2e_ack_ret = ret;
00382 continue;
00383 }
00384
00385
00386
00387 continue;
00388 }
00389
00390
00391 if (!via_matching(t_msg->via1 , via1 ))
00392 continue;
00393
00394 LM_DBG("RFC3261 transaction matched, tid=%.*s\n",
00395 via1->tid.len, via1->tid.s);
00396
00397 *trans=p_cell;
00398 return 1;
00399 }
00400
00401
00402
00403 if (e2e_ack_trans) {
00404 *trans=e2e_ack_trans;
00405 return e2e_ack_ret;
00406 }
00407 LM_DBG("RFC3261 transaction matching failed\n");
00408 return 0;
00409 }
00410
00411
00412
00413
00414
00415
00416
00417 int t_lookup_request( struct sip_msg* p_msg , int leave_new_locked )
00418 {
00419 struct cell *p_cell;
00420 unsigned int isACK;
00421 struct sip_msg *t_msg;
00422 int ret, match_status;
00423 struct via_param *branch;
00424 struct cell *e2e_ack_trans;
00425
00426 isACK = p_msg->REQ_METHOD==METHOD_ACK;
00427
00428 if (isACK) {
00429 if (e2eack_T==NULL)
00430 return -1;
00431 if (e2eack_T!=T_UNDEFINED)
00432 return -2;
00433 }
00434
00435
00436 if (check_transaction_quadruple(p_msg)==0) {
00437 LM_ERR("too few headers\n");
00438 set_t(0);
00439
00440 return 0;
00441 }
00442
00443
00444 if (!p_msg->hash_index)
00445 p_msg->hash_index=tm_hash( p_msg->callid->body ,
00446 get_cseq(p_msg)->number ) ;
00447 LM_DBG("start searching: hash=%d, isACK=%d\n",
00448 p_msg->hash_index,isACK);
00449
00450
00451
00452 ret=-1;
00453 e2e_ack_trans=0;
00454
00455
00456
00457
00458
00459 if (!p_msg->via1) {
00460 LM_ERR("no via\n");
00461 set_t(0);
00462 return 0;
00463 }
00464 branch=p_msg->via1->branch;
00465 if (branch && branch->value.s && branch->value.len>MCOOKIE_LEN
00466 && memcmp(branch->value.s,MCOOKIE,MCOOKIE_LEN)==0) {
00467
00468 LOCK_HASH(p_msg->hash_index);
00469 match_status=matching_3261(p_msg,&p_cell,
00470
00471
00472 isACK ? ~METHOD_INVITE: ~p_msg->REQ_METHOD);
00473 switch(match_status) {
00474 case 0: goto notfound;
00475 case 1: goto found;
00476 case 2:
00477 LM_DBG("RFC3261 ACK matched\n");
00478 goto e2e_ack;
00479 }
00480 }
00481
00482
00483
00484
00485 LM_DBG("proceeding to pre-RFC3261 transaction matching\n");
00486
00487
00488 LOCK_HASH(p_msg->hash_index);
00489
00490
00491 for ( p_cell = get_tm_table()->entrys[p_msg->hash_index].first_cell;
00492 p_cell; p_cell = p_cell->next_cell )
00493 {
00494 t_msg = p_cell->uas.request;
00495
00496 if (!t_msg) continue;
00497
00498 if (!isACK) {
00499
00500 if (!EQ_LEN(callid)) continue;
00501 if (!EQ_LEN(cseq)) continue;
00502 if (!EQ_LEN(from)) continue;
00503 if (!EQ_LEN(to)) continue;
00504 if (ruri_matching && !EQ_REQ_URI_LEN) continue;
00505 if (via1_matching && !EQ_VIA_LEN(via1)) continue;
00506
00507
00508 if (!EQ_STR(callid)) continue;
00509 if (!EQ_STR(cseq)) continue;
00510 if (!EQ_STR(from)) continue;
00511 if (!EQ_STR(to)) continue;
00512 if (ruri_matching && !EQ_REQ_URI_STR) continue;
00513 if (via1_matching && !EQ_VIA_STR(via1)) continue;
00514
00515
00516 LM_DBG("non-ACK matched\n");
00517 goto found;
00518 } else {
00519
00520 if (t_msg->REQ_METHOD!=METHOD_INVITE) continue;
00521
00522
00523
00524 if (!EQ_LEN(callid)) continue;
00525
00526 if (get_cseq(t_msg)->number.len!=get_cseq(p_msg)->number.len)
00527 continue;
00528 if (! EQ_LEN(from)) continue;
00529
00530 if (get_to(t_msg)->uri.len!=get_to(p_msg)->uri.len)
00531 continue;
00532 if (!EQ_STR(callid)) continue;
00533 if (memcmp(get_cseq(t_msg)->number.s, get_cseq(p_msg)->number.s,
00534 get_cseq(p_msg)->number.len)!=0) continue;
00535 if (!EQ_STR(from)) continue;
00536 if (memcmp(get_to(t_msg)->uri.s, get_to(p_msg)->uri.s,
00537 get_to(t_msg)->uri.len)!=0) continue;
00538
00539
00540 if (p_cell->uas.status<300) {
00541 if (e2e_ack_trans==0) {
00542
00543 if (p_cell->relayed_reply_branch!=-2) {
00544 e2e_ack_trans=p_cell;
00545 continue;
00546 }
00547
00548 if (dlg_matching(p_cell, p_msg))
00549 {
00550 LM_DBG("preRFC3261 ACK matched\n");
00551 goto e2e_ack;
00552 }
00553 continue;
00554 }
00555 continue;
00556 }
00557
00558
00559
00560
00561
00562
00563 if (ruri_matching && !EQ_REQ_URI_LEN ) continue;
00564 if (via1_matching && !EQ_VIA_LEN(via1)) continue;
00565 if (ruri_matching && !EQ_REQ_URI_STR) continue;
00566 if (via1_matching && !EQ_VIA_STR(via1)) continue;
00567
00568
00569 LM_DBG("non-2xx ACK matched\n");
00570 goto found;
00571 }
00572 }
00573
00574 notfound:
00575 if (e2e_ack_trans) {
00576 p_cell=e2e_ack_trans;
00577 goto e2e_ack;
00578 }
00579
00580
00581 set_t(0);
00582 e2eack_T = NULL;
00583 if (!leave_new_locked || isACK) {
00584 UNLOCK_HASH(p_msg->hash_index);
00585 }
00586 LM_DBG("no transaction found\n");
00587 return -1;
00588
00589 e2e_ack:
00590
00591 if((p_cell->nr_of_outgoings==0) ||
00592 (p_cell->nr_of_outgoings==1 && (p_cell->flags&T_BLIND_UAC)))
00593 {
00594 UNLOCK_HASH(p_msg->hash_index);
00595
00596 t_release_transaction(p_cell);
00597 set_t(0);
00598 LM_DBG("local ACK found - nothing to forward\n");
00599 return -3;
00600 }
00601
00602 REF_UNSAFE( p_cell );
00603 UNLOCK_HASH(p_msg->hash_index);
00604 e2eack_T = p_cell;
00605 set_t(0);
00606 LM_DBG("e2e proxy ACK found\n");
00607 return -2;
00608
00609 found:
00610 set_t(p_cell);
00611 REF_UNSAFE( T );
00612 set_kr(REQ_EXIST);
00613 UNLOCK_HASH( p_msg->hash_index );
00614 LM_DBG("transaction found (T=%p)\n",T);
00615 return 1;
00616 }
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628 struct cell* t_lookupOriginalT( struct sip_msg* p_msg )
00629 {
00630 struct cell *p_cell;
00631 unsigned int hash_index;
00632 struct sip_msg *t_msg;
00633 struct via_param *branch;
00634 int ret;
00635
00636
00637 if (cancelled_T!=T_UNDEFINED)
00638 return cancelled_T;
00639
00640
00641 hash_index = p_msg->hash_index;
00642 LM_DBG("searching on hash entry %d\n",hash_index );
00643
00644
00645
00646
00647
00648
00649 if (!p_msg->via1) {
00650 LM_ERR("no via\n");
00651 cancelled_T = NULL;
00652 return 0;
00653 }
00654 branch=p_msg->via1->branch;
00655 if (branch && branch->value.s && branch->value.len>MCOOKIE_LEN
00656 && memcmp(branch->value.s,MCOOKIE,MCOOKIE_LEN)==0) {
00657
00658 LOCK_HASH(hash_index);
00659 ret=matching_3261(p_msg, &p_cell,
00660
00661
00662
00663 METHOD_CANCEL);
00664 if (ret==1) goto found; else goto notfound;
00665 }
00666
00667
00668
00669 LOCK_HASH(hash_index);
00670
00671
00672 for (p_cell=get_tm_table()->entrys[hash_index].first_cell;
00673 p_cell; p_cell = p_cell->next_cell )
00674 {
00675 t_msg = p_cell->uas.request;
00676
00677 if (!t_msg) continue;
00678
00679
00680 if (t_msg->REQ_METHOD==METHOD_CANCEL)
00681 continue;
00682
00683
00684 if (!EQ_LEN(callid))
00685 continue;
00686 if (get_cseq(t_msg)->number.len!=get_cseq(p_msg)->number.len)
00687 continue;
00688 if (!EQ_LEN(from))
00689 continue;
00690 #ifdef CANCEL_TAG
00691 if (!EQ_LEN(to))
00692 continue;
00693 #else
00694
00695
00696
00697
00698 if (get_to(t_msg)->uri.len!=get_to(p_msg)->uri.len)
00699 continue;
00700 #endif
00701 if (ruri_matching && !EQ_REQ_URI_LEN)
00702 continue;
00703 if (via1_matching && !EQ_VIA_LEN(via1))
00704 continue;
00705
00706
00707 if (!EQ_STR(callid))
00708 continue;
00709 if (memcmp(get_cseq(t_msg)->number.s,
00710 get_cseq(p_msg)->number.s,get_cseq(p_msg)->number.len)!=0)
00711 continue;
00712 if (!EQ_STR(from))
00713 continue;
00714 #ifdef CANCEL_TAG
00715 if (!EQ_STR(to))
00716 continue;
00717 #else
00718 if (memcmp(get_to(t_msg)->uri.s, get_to(p_msg)->uri.s,
00719 get_to(t_msg)->uri.len)!=0)
00720 continue;
00721 #endif
00722 if (ruri_matching && !EQ_REQ_URI_STR)
00723 continue;
00724 if (via1_matching && !EQ_VIA_STR(via1))
00725 continue;
00726
00727
00728 goto found;
00729 }
00730
00731 notfound:
00732
00733 LM_DBG("no CANCEL matching found! \n" );
00734 UNLOCK_HASH(hash_index);
00735 cancelled_T = NULL;
00736 LM_DBG("t_lookupOriginalT completed\n");
00737 return 0;
00738
00739 found:
00740 LM_DBG("canceled transaction found (%p)! \n",p_cell );
00741 cancelled_T = p_cell;
00742 REF_UNSAFE( p_cell );
00743 UNLOCK_HASH(hash_index);
00744 LM_DBG("t_lookupOriginalT completed\n");
00745 return p_cell;
00746 }
00747
00748
00749
00750
00751
00752
00753 int t_reply_matching( struct sip_msg *p_msg , int *p_branch )
00754 {
00755 struct cell* p_cell;
00756 int hash_index, entry_label, branch_id, hashl, branchl, scan_space, loopl, synl;
00757 hash_index = entry_label = branch_id = loopl = synl = 0;
00758 char *hashi, *branchi, *p, *n, *loopi, *syni;
00759 loopi = syni = NULL;
00760 struct cseq_body *cseq;
00761
00762
00763
00764
00765 if (!(p_msg->via1 && p_msg->via1->branch && p_msg->via1->branch->value.s))
00766 goto nomatch2;
00767
00768
00769
00770 if (p_msg->via1->branch->value.len<=MCOOKIE_LEN)
00771 goto nomatch2;
00772 if (memcmp(p_msg->via1->branch->value.s, MCOOKIE, MCOOKIE_LEN)!=0)
00773 goto nomatch2;
00774
00775 p=p_msg->via1->branch->value.s+MCOOKIE_LEN;
00776 scan_space=p_msg->via1->branch->value.len-MCOOKIE_LEN;
00777
00778
00779
00780 n=eat_token2_end( p, p+scan_space, BRANCH_SEPARATOR);
00781 hashl=n-p;
00782 scan_space-=hashl;
00783 if (!hashl || scan_space<2 || *n!=BRANCH_SEPARATOR) goto nomatch2;
00784 hashi=p;
00785 p=n+1;scan_space--;
00786
00787 if (!syn_branch) {
00788
00789 n=eat_token2_end( p, p+scan_space, BRANCH_SEPARATOR );
00790 loopl = n-p;
00791 scan_space-= loopl;
00792 if (n==p || scan_space<2 || *n!=BRANCH_SEPARATOR)
00793 goto nomatch2;
00794 loopi=p;
00795 p=n+1; scan_space--;
00796 } else {
00797
00798 n=eat_token2_end( p, p+scan_space, BRANCH_SEPARATOR);
00799 synl=n-p;
00800 scan_space-=synl;
00801 if (!synl || scan_space<2 || *n!=BRANCH_SEPARATOR)
00802 goto nomatch2;
00803 syni=p;
00804 p=n+1;scan_space--;
00805 }
00806
00807
00808 n=eat_token_end( p, p+scan_space );
00809 branchl=n-p;
00810 if (!branchl ) goto nomatch2;
00811 branchi=p;
00812
00813
00814 if ((hash_index=reverse_hex2int(hashi, hashl))<0
00815 ||hash_index>=TM_TABLE_ENTRIES
00816 || (branch_id=reverse_hex2int(branchi, branchl))<0
00817 ||branch_id>=MAX_BRANCHES
00818 || (syn_branch ? (entry_label=reverse_hex2int(syni, synl))<0
00819 : loopl!=MD5_LEN )
00820 ) {
00821 LM_DBG("poor reply labels %d label %d branch %d\n",
00822 hash_index, entry_label, branch_id );
00823 goto nomatch2;
00824 }
00825
00826 LM_DBG("hash %d label %d branch %d\n",hash_index, entry_label, branch_id);
00827
00828 cseq = get_cseq(p_msg);
00829
00830
00831
00832 LOCK_HASH(hash_index);
00833
00834 for (p_cell = get_tm_table()->entrys[hash_index].first_cell; p_cell;
00835 p_cell=p_cell->next_cell) {
00836
00837
00838 if (syn_branch) {
00839 if (p_cell->label != entry_label)
00840 continue;
00841 } else {
00842 if ( memcmp(p_cell->md5, loopi,MD5_LEN)!=0)
00843 continue;
00844 }
00845
00846
00847 if ( branch_id>=p_cell->nr_of_outgoings )
00848 continue;
00849
00850
00851
00852 if (!(
00853 (cseq->method_id==METHOD_CANCEL && is_invite(p_cell)
00854 && p_cell->uac[branch_id].local_cancel.buffer.len )
00855
00856 || ((cseq->method_id!=METHOD_OTHER && p_cell->uas.request)?
00857 (cseq->method_id==REQ_LINE(p_cell->uas.request).method_value)
00858 :(EQ_STRS(cseq->method,p_cell->method)))
00859 ))
00860 continue;
00861
00862
00863
00864
00865 set_t(p_cell);
00866 *p_branch = branch_id;
00867 REF_UNSAFE( T );
00868 UNLOCK_HASH(hash_index);
00869 LM_DBG("reply matched (T=%p)!\n",T);
00870
00871
00872
00873
00874
00875
00876 if (is_invite(p_cell) && p_msg->REPLY_STATUS>=200
00877 && p_msg->REPLY_STATUS<300
00878 && ( (!is_local(p_cell) &&
00879 has_tran_tmcbs(p_cell,
00880 TMCB_RESPONSE_PRE_OUT|TMCB_RESPONSE_OUT|TMCB_E2EACK_IN) )
00881 || (is_local(p_cell)&&has_tran_tmcbs(p_cell,TMCB_LOCAL_COMPLETED))
00882 )) {
00883 if (parse_headers(p_msg, HDR_TO_F, 0)==-1) {
00884 LM_ERR("to parsing failed\n");
00885 }
00886 }
00887 if (!is_local(p_cell)) {
00888 run_trans_callbacks( TMCB_RESPONSE_IN, T, T->uas.request, p_msg,
00889 p_msg->REPLY_STATUS);
00890 }
00891 return 1;
00892 }
00893
00894
00895 UNLOCK_HASH(hash_index);
00896 LM_DBG("no matching transaction exists\n");
00897
00898 nomatch2:
00899 LM_DBG("failure to match a transaction\n");
00900 *p_branch = -1;
00901 set_t(0);
00902 return -1;
00903 }
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919 int t_check( struct sip_msg* p_msg , int *param_branch )
00920 {
00921 int local_branch;
00922
00923
00924 LM_DBG("start=%p\n", T);
00925 if ( T==T_UNDEFINED )
00926 {
00927
00928 if ( p_msg->first_line.type==SIP_REQUEST ) {
00929
00930 if (parse_headers(p_msg, HDR_EOH_F, 0 )==-1) {
00931 LM_ERR("parsing error\n");
00932 return -1;
00933 }
00934
00935
00936
00937
00938
00939 if (p_msg->REQ_METHOD==METHOD_INVITE
00940 && parse_from_header(p_msg)<0) {
00941 LM_ERR("from parsing failed\n");
00942 return -1;
00943 }
00944 t_lookup_request( p_msg , 0 );
00945 } else {
00946
00947
00948
00949 if ( parse_headers(p_msg, HDR_VIA1_F|HDR_CSEQ_F, 0 )==-1
00950 || !p_msg->via1 || !p_msg->cseq ) {
00951 LM_ERR("reply cannot be parsed\n");
00952 return -1;
00953 }
00954
00955
00956
00957 if ( get_cseq(p_msg)->method_id==METHOD_INVITE ) {
00958 if (parse_headers(p_msg, HDR_TO_F, 0)==-1 || !p_msg->to) {
00959 LM_ERR("INVITE reply cannot be parsed\n");
00960 return -1;
00961 }
00962 }
00963
00964 t_reply_matching( p_msg ,
00965 param_branch!=0?param_branch:&local_branch );
00966
00967 }
00968 #ifdef EXTRA_DEBUG
00969 if ( T && T!=T_UNDEFINED && T->damocles) {
00970 LM_ERR("transaction %p scheduled for deletion "
00971 "and called from t_check\n", T);
00972 abort();
00973 }
00974 #endif
00975 LM_DBG("end=%p\n",T);
00976 } else {
00977 if (T)
00978 LM_DBG("transaction already found!\n");
00979 else
00980 LM_DBG("transaction previously sought and not found\n");
00981 }
00982
00983 return T ? (T==T_UNDEFINED ? -1 : 1 ) : 0;
00984 }
00985
00986 int init_rb( struct retr_buf *rb, struct sip_msg *msg)
00987 {
00988
00989 struct via_body* via;
00990 int proto;
00991
00992 via=msg->via1;
00993 if (!reply_to_via) {
00994 update_sock_struct_from_ip( &rb->dst.to, msg );
00995 proto=msg->rcv.proto;
00996 } else {
00997
00998 if (update_sock_struct_from_via( &(rb->dst.to), msg, via )==-1) {
00999 LM_ERR("init_rb: cannot lookup reply dst: %.*s\n",
01000 via->host.len, via->host.s );
01001 ser_error=E_BAD_VIA;
01002 return 0;
01003 }
01004 proto=via->proto;
01005 }
01006 rb->dst.proto=proto;
01007 rb->dst.proto_reserved1=msg->rcv.proto_reserved1;
01008
01009 rb->dst.send_sock=msg->rcv.bind_address;
01010 return 1;
01011 }
01012
01013
01014
01015
01016
01017
01018
01019
01020 static inline void init_new_t(struct cell *new_cell, struct sip_msg *p_msg)
01021 {
01022 struct sip_msg *shm_msg;
01023
01024 shm_msg=new_cell->uas.request;
01025 new_cell->from.s=shm_msg->from->name.s;
01026 new_cell->from.len=HF_LEN(shm_msg->from);
01027 new_cell->to.s=shm_msg->to->name.s;
01028 new_cell->to.len=HF_LEN(shm_msg->to);
01029 new_cell->callid.s=shm_msg->callid->name.s;
01030 new_cell->callid.len=HF_LEN(shm_msg->callid);
01031 new_cell->cseq_n.s=shm_msg->cseq->name.s;
01032 new_cell->cseq_n.len=get_cseq(shm_msg)->number.s
01033 +get_cseq(shm_msg)->number.len
01034 -shm_msg->cseq->name.s;
01035
01036 new_cell->method=new_cell->uas.request->first_line.u.request.method;
01037 if (p_msg->REQ_METHOD==METHOD_INVITE) new_cell->flags |= T_IS_INVITE_FLAG;
01038 new_cell->on_negative=get_on_negative();
01039 new_cell->on_reply=get_on_reply();
01040 new_cell->on_branch=get_on_branch();
01041 }
01042
01043
01044
01045
01046
01047
01048 static inline int new_t(struct sip_msg *p_msg)
01049 {
01050 struct cell *new_cell;
01051
01052
01053 if (p_msg->REQ_METHOD==METHOD_INVITE && parse_from_header(p_msg)<0) {
01054 LM_ERR("no valid From in INVITE\n");
01055 return E_BAD_REQ;
01056 }
01057
01058 if (parse_sip_msg_uri(p_msg)<0) {
01059 LM_ERR("uri invalid\n");
01060 return E_BAD_REQ;
01061 }
01062
01063
01064 new_cell = build_cell( p_msg ) ;
01065 if ( !new_cell ){
01066 LM_ERR("out of mem\n");
01067 return E_OUT_OF_MEM;
01068 }
01069
01070 insert_into_hash_table_unsafe( new_cell, p_msg->hash_index );
01071 set_t(new_cell);
01072 INIT_REF_UNSAFE(T);
01073
01074
01075
01076 init_new_t(new_cell, p_msg);
01077 return 1;
01078 }
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088 int t_newtran( struct sip_msg* p_msg )
01089 {
01090 int lret, my_err;
01091
01092
01093 LM_DBG("transaction on entrance=%p\n",T);
01094
01095 if ( T && T!=T_UNDEFINED ) {
01096 LM_ERR("transaction already in process %p\n", T );
01097 return E_SCRIPT;
01098 }
01099
01100 T = T_UNDEFINED;
01101
01102
01103
01104
01105
01106
01107
01108 if (parse_headers(p_msg, HDR_EOH_F, 0 )<0) {
01109 LM_ERR("parse_headers failed\n");
01110 return E_BAD_REQ;
01111 }
01112 if ((p_msg->parsed_flag & HDR_EOH_F)!=HDR_EOH_F) {
01113 LM_ERR("EoH not parsed\n");
01114 return E_OUT_OF_MEM;
01115 }
01116
01117
01118 check_hdrs_changes(p_msg);
01119
01120
01121
01122
01123
01124 lret = t_lookup_request( p_msg, 1 );
01125
01126
01127
01128 if (lret==0) return E_BAD_TUPEL;
01129
01130
01131 if (lret>0) {
01132 if (p_msg->REQ_METHOD==METHOD_ACK) {
01133 t_release_transaction(T);
01134 } else {
01135 t_retransmit_reply(T);
01136 }
01137
01138 return 0;
01139 }
01140
01141
01142
01143 if (lret==-2) {
01144 LM_DBG("building branch for end2end ACK\n");
01145
01146
01147
01148
01149
01150
01151 if (!t_calc_branch(e2eack_T, e2eack_T->nr_of_outgoings+1,
01152 p_msg->add_to_branch_s, &p_msg->add_to_branch_len )) {
01153 LM_ERR("ACK branch computation failed\n");
01154 }
01155
01156
01157 if ( !has_tran_tmcbs(e2eack_T,TMCB_E2EACK_IN) )
01158 return 1;
01159
01160
01161
01162
01163
01164
01165 if (unmatched_totag(e2eack_T, p_msg)) {
01166 run_trans_callbacks( TMCB_E2EACK_IN , e2eack_T, p_msg, 0,
01167 -p_msg->REQ_METHOD );
01168 }
01169 return 1;
01170 }
01171
01172
01173
01174 if (p_msg->REQ_METHOD==METHOD_ACK)
01175 return 1;
01176
01177 my_err=new_t(p_msg);
01178 if (my_err<0) {
01179 LM_ERR("new_t failed\n");
01180 goto new_err;
01181 }
01182
01183
01184 UNLOCK_HASH(p_msg->hash_index);
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194 if (!init_rb( &T->uas.response, p_msg)) {
01195 LM_ERR("unresolvable via1\n");
01196 put_on_wait( T );
01197 t_unref(p_msg);
01198 return E_BAD_VIA;
01199 }
01200
01201 return 1;
01202 new_err:
01203 UNLOCK_HASH(p_msg->hash_index);
01204 return my_err;
01205
01206 }
01207
01208
01209
01210
01211
01212 int t_unref( struct sip_msg* p_msg )
01213 {
01214 enum kill_reason kr;
01215
01216 if (T==T_UNDEFINED)
01217 return -1;
01218 if (T!=T_NULL_CELL) {
01219 if (p_msg->first_line.type==SIP_REQUEST){
01220 kr=get_kr();
01221 if (kr==0
01222 ||(p_msg->REQ_METHOD==METHOD_ACK && !(kr & REQ_RLSD))) {
01223 LM_WARN("script writer didn't release transaction\n");
01224 t_release_transaction(T);
01225 }
01226 }
01227 UNREF( T );
01228 }
01229 set_t(T_UNDEFINED);
01230 return 1;
01231 }
01232
01233
01234 void t_unref_cell(struct cell *c)
01235 {
01236 UNREF(c);
01237 }
01238
01239
01240
01241
01242
01243
01244 int t_get_trans_ident(struct sip_msg* p_msg, unsigned int* hash_index,
01245 unsigned int* label)
01246 {
01247 struct cell* t;
01248 if(t_check(p_msg,0) != 1){
01249 LM_ERR("no transaction found\n");
01250 return -1;
01251 }
01252 t = get_t();
01253 if(!t){
01254 LM_ERR("transaction found is NULL\n");
01255 return -1;
01256 }
01257
01258 *hash_index = t->hash_index;
01259 *label = t->label;
01260
01261 return 1;
01262 }
01263
01264
01265
01266
01267
01268
01269 int t_lookup_ident(struct cell ** trans, unsigned int hash_index,
01270 unsigned int label)
01271 {
01272 struct cell* p_cell;
01273
01274 if(hash_index >= TM_TABLE_ENTRIES){
01275 LM_ERR("invalid hash_index=%u\n",hash_index);
01276 return -1;
01277 }
01278
01279 LOCK_HASH(hash_index);
01280
01281
01282 for ( p_cell = get_tm_table()->entrys[hash_index].first_cell;
01283 p_cell; p_cell = p_cell->next_cell )
01284 {
01285 if(p_cell->label == label){
01286 REF_UNSAFE(p_cell);
01287 UNLOCK_HASH(hash_index);
01288 set_t(p_cell);
01289 *trans=p_cell;
01290 LM_DBG("transaction found\n");
01291 return 1;
01292 }
01293 }
01294
01295 UNLOCK_HASH(hash_index);
01296 set_t(0);
01297 *trans=p_cell;
01298
01299 LM_DBG("transaction not found\n");
01300 return -1;
01301 }
01302
01303
01304
01305
01306
01307
01308 int t_is_local(struct sip_msg* p_msg)
01309 {
01310 struct cell* t;
01311 if(t_check(p_msg,0) != 1){
01312 LM_ERR("no transaction found\n");
01313 return -1;
01314 }
01315 t = get_t();
01316 if(!t){
01317 LM_ERR("transaction found is NULL\n");
01318 return -1;
01319 }
01320
01321 return is_local(t);
01322 }
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336 int t_lookup_callid(struct cell ** trans, str callid, str cseq) {
01337 struct cell* p_cell;
01338 unsigned int hash_index;
01339
01340
01341 char callid_header[MAX_HEADER], cseq_header[MAX_HEADER];
01342
01343 char* endpos;
01344
01345
01346
01347 str invite_method;
01348 char* invite_string = INVITE;
01349
01350 invite_method.s = invite_string;
01351 invite_method.len = INVITE_LEN;
01352
01353
01354 hash_index=tm_hash(callid, cseq);
01355
01356 if(hash_index >= TM_TABLE_ENTRIES){
01357 LM_ERR("invalid hash_index=%u\n",hash_index);
01358 return -1;
01359 }
01360
01361
01362 endpos = print_callid_mini(callid_header, callid);
01363 LM_DBG("created comparable call_id header field: >%.*s<\n",
01364 (int)(endpos - callid_header), callid_header);
01365
01366 endpos = print_cseq_mini(cseq_header, &cseq, &invite_method);
01367 LM_DBG("created comparable cseq header field: >%.*s<\n",
01368 (int)(endpos - cseq_header), cseq_header);
01369
01370 LOCK_HASH(hash_index);
01371
01372
01373 p_cell = get_tm_table()->entrys[hash_index].first_cell;
01374 for ( ; p_cell; p_cell = p_cell->next_cell ) {
01375
01376
01377 LM_DBG(" <%.*s> <%.*s>\n", p_cell->callid.len, p_cell->callid.s,
01378 p_cell->cseq_n.len,p_cell->cseq_n.s);
01379 if ( (strncmp(callid_header, p_cell->callid.s, p_cell->callid.len) == 0)
01380 && (strncasecmp(cseq_header, p_cell->cseq_n.s, p_cell->cseq_n.len) == 0) ) {
01381 LM_DBG("we have a match: callid=>>%.*s<< cseq=>>%.*s<<\n",
01382 p_cell->callid.len,p_cell->callid.s, p_cell->cseq_n.len,
01383 p_cell->cseq_n.s);
01384 REF_UNSAFE(p_cell);
01385 UNLOCK_HASH(hash_index);
01386 set_t(p_cell);
01387 *trans=p_cell;
01388 LM_DBG("transaction found.\n");
01389 return 1;
01390 }
01391 LM_DBG("NO match: callid=%.*s cseq=%.*s\n",
01392 p_cell->callid.len, p_cell->callid.s,
01393 p_cell->cseq_n.len, p_cell->cseq_n.s);
01394 }
01395
01396 UNLOCK_HASH(hash_index);
01397 LM_DBG("transaction not found.\n");
01398
01399 return -1;
01400 }