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 #include "../../hash_func.h"
00048 #include "../../dprint.h"
00049 #include "../../parser/parser_f.h"
00050 #include "../../ut.h"
00051 #include "../../parser/msg_parser.h"
00052 #include "../../parser/contact/parse_contact.h"
00053 #include "t_funcs.h"
00054 #include "t_msgbuilder.h"
00055 #include "uac.h"
00056
00057
00058 #define ROUTE_PREFIX "Route: "
00059 #define ROUTE_PREFIX_LEN (sizeof(ROUTE_PREFIX) - 1)
00060
00061 #define ROUTE_SEPARATOR ", "
00062 #define ROUTE_SEPARATOR_LEN (sizeof(ROUTE_SEPARATOR) - 1)
00063
00064 #define LOCAL_MAXFWD_HEADER "Max-Forwards: " LOCAL_MAXFWD_VALUE CRLF
00065 #define LOCAL_MAXFWD_HEADER_LEN (sizeof(LOCAL_MAXFWD_HEADER) - 1)
00066
00067
00068 #define LC(_cp) ((*(_cp))|0x20)
00069 #define SET_FOUND(_new_state) \
00070 do{\
00071 fill->s=b;fill->len=p-b;\
00072 LM_DBG("hdr %d extracted as <%.*s>\n",\
00073 flag,fill->len,fill->s);\
00074 flags&=~(flag);\
00075 if (flags) {state=_new_state;}\
00076 else {goto done;}\
00077 }while(0)
00078 #define GET_CSEQ() \
00079 do{\
00080 for(p++;p<end&&isspace((int)*p);p++);\
00081 for(fill->s=b;p<end&&isdigit((int)*p);p++);\
00082 fill->len=p-fill->s;\
00083 if ( (flags&=~(flag))==0) goto done;\
00084 state=1;\
00085 }while(0)
00086 static int extract_hdrs( char *buf, int len, str *from, str *to, str *cseq)
00087 {
00088 char *end, *p;
00089 char *b;
00090 str *fill;
00091 int state;
00092 int flags;
00093 int flag;
00094
00095 p = buf;
00096 end = buf+len;
00097 state = 1;
00098 b = 0;
00099 flags = ((from!=0)?0x1:0) | ((to!=0)?0x2:0) | ((cseq!=0)?0x4:0);
00100 flag = 0;
00101 fill = 0;
00102
00103 while(p<end) {
00104 switch (*p) {
00105 case '\n':
00106 case '\r':
00107 switch (state) {
00108 case 4: state=5;break;
00109 case 5: case 6: state=6;break;
00110 default : state=2;break;
00111 }
00112 break;
00113 case ' ':
00114 case '\t':
00115 switch (state) {
00116 case 4: case 6: state=5; break;
00117 case 2: state=1; break;
00118 }
00119 break;
00120 case ':':
00121 switch (state) {
00122 case 4:case 5: state=5;if(flag==0x04)GET_CSEQ();break;
00123 case 6: SET_FOUND(1);break;
00124 case 2: state=1;break;
00125 }
00126 break;
00127 case 'f':
00128 case 'F':
00129 if (state==5) break;
00130 if (state==6) SET_FOUND(2);;
00131 if (state!=2) {state = 1;break;}
00132
00133 if (from==0) break;
00134 b = p;
00135 if (p+3<end && LC(p+1)=='r' && LC(p+2)=='o' && LC(p+3)=='m')
00136 p+=3;
00137 state = 4;
00138 fill = from;
00139 flag = 0x1;
00140 break;
00141 case 't':
00142 case 'T':
00143 if (state==5) break;
00144 if (state==6) SET_FOUND(2);;
00145 if (state!=2) {state = 1;break;}
00146
00147 if (to==0) break;
00148 b = p;
00149 if (p+1<end && LC(p+1)=='o')
00150 p+=1;
00151 state = 4;
00152 fill = to;
00153 flag = 0x2;
00154 break;
00155 case 'c':
00156 case 'C':
00157 if (state==5) break;
00158 if (state==6) SET_FOUND(2);;
00159 if (state!=2) {state = 1;break;}
00160
00161 if (cseq==0) break;
00162 if (p+3<end && LC(p+1)=='s' && LC(p+2)=='e' && LC(p+3)=='q') {
00163 b = p;
00164 p+=3;
00165 state = 4;
00166 fill = cseq;
00167 flag = 0x4;
00168 }
00169 break;
00170 default:
00171 switch (state) {
00172 case 2:case 4: state=1; break;
00173 case 6: SET_FOUND(1);break;;
00174 }
00175 }
00176 p++;
00177 }
00178
00179 LM_CRIT("no hdrs found in outgoing buffer\n");
00180 return -1;
00181 done:
00182 return 0;
00183 }
00184
00185
00186 static inline struct hdr_field* extract_parsed_hdrs( char *buf, int len)
00187 {
00188 char *p;
00189 static struct sip_msg msg;
00190 struct hdr_field *hdr;
00191
00192 LM_DBG("----parsing the buf req - first line\n");
00193
00194 p = eat_line( buf, len);
00195 if (p>=buf+len)
00196 return 0;
00197
00198 memset( &msg, 0, sizeof(struct sip_msg) );
00199 msg.buf = buf;
00200 msg.len = len;
00201 msg.unparsed = p;
00202
00203
00204 if (parse_headers( &msg, HDR_EOH_F, 0)==-1)
00205 goto error;
00206
00207 hdr = msg.headers;
00208 msg.headers = 0;
00209
00210 free_sip_msg( &msg );
00211 return hdr;
00212 error:
00213 free_sip_msg( &msg );
00214 return 0;
00215 }
00216
00217
00218
00219
00220
00221 char *build_local(struct cell *Trans,unsigned int branch,
00222 unsigned int *len, char *method, int method_len, str *uas_to)
00223 {
00224 char *cancel_buf, *p, *via;
00225 unsigned int via_len;
00226 struct hdr_field *buf_hdrs;
00227 struct hdr_field *hdr;
00228 struct sip_msg *req;
00229 char branch_buf[MAX_BRANCH_PARAM_LEN];
00230 str branch_str;
00231 struct hostport hp;
00232 str from;
00233 str to;
00234 str cseq_n;
00235
00236 req = Trans->uas.request;
00237 from = Trans->from;
00238 cseq_n = Trans->cseq_n;
00239 to = *uas_to;
00240 buf_hdrs = 0;
00241
00242 if (req
00243 && ( req->msg_flags&(FL_USE_UAC_FROM|FL_USE_UAC_CSEQ)
00244 || (method_len!=ACK_LEN && (req->msg_flags&FL_USE_UAC_TO)) )
00245 )
00246 {
00247 if ( extract_hdrs( Trans->uac[branch].request.buffer.s,
00248 Trans->uac[branch].request.buffer.len,
00249 (req->msg_flags&FL_USE_UAC_FROM)?&from:0 ,
00250 (req->msg_flags&FL_USE_UAC_TO && method_len!=ACK_LEN)?&to:0 ,
00251 (req->msg_flags&FL_USE_UAC_CSEQ)?&cseq_n:0 )!=0 ) {
00252 LM_ERR("build_local: failed to extract UAC hdrs\n");
00253 goto error;
00254 }
00255 }
00256 LM_DBG("using FROM=<%.*s>, TO=<%.*s>, CSEQ_N=<%.*s>\n",
00257 from.len,from.s , to.len,to.s , cseq_n.len,cseq_n.s);
00258
00259
00260 *len=SIP_VERSION_LEN + method_len + 2 + CRLF_LEN;
00261 *len+=Trans->uac[branch].uri.len;
00262
00263
00264 branch_str.s=branch_buf;
00265 if (!t_calc_branch(Trans, branch, branch_str.s, &branch_str.len ))
00266 goto error;
00267 set_hostport(&hp, (is_local(Trans))?0:req);
00268 via=via_builder(&via_len, Trans->uac[branch].request.dst.send_sock,
00269 &branch_str, 0, Trans->uac[branch].request.dst.proto, &hp );
00270 if (!via){
00271 LM_ERR("no via header got from builder\n");
00272 goto error;
00273 }
00274 *len+= via_len;
00275
00276 *len+=from.len+Trans->callid.len+to.len+cseq_n.len+1+method_len+CRLF_LEN;
00277
00278
00279
00280 if (!is_local(Trans)) {
00281 buf_hdrs = extract_parsed_hdrs(Trans->uac[branch].request.buffer.s,
00282 Trans->uac[branch].request.buffer.len );
00283 if (buf_hdrs==NULL) {
00284 LM_ERR("failed to reparse the request buffer\n");
00285 goto error01;
00286 }
00287 for ( hdr=buf_hdrs ; hdr ; hdr=hdr->next )
00288 if (hdr->type==HDR_ROUTE_T)
00289 *len+=hdr->len;
00290 }
00291
00292
00293 if (server_signature) {
00294 *len += user_agent_header.len + CRLF_LEN;
00295 }
00296
00297 *len+=LOCAL_MAXFWD_HEADER_LEN + CONTENT_LENGTH_LEN+1 + CRLF_LEN + CRLF_LEN;
00298
00299 cancel_buf=shm_malloc( *len+1 );
00300 if (!cancel_buf)
00301 {
00302 LM_ERR("no more share memory\n");
00303 goto error02;
00304 }
00305 p = cancel_buf;
00306
00307 append_str( p, method, method_len );
00308 *(p++) = ' ';
00309 append_str( p, Trans->uac[branch].uri.s, Trans->uac[branch].uri.len);
00310 append_str( p, " " SIP_VERSION CRLF, 1+SIP_VERSION_LEN+CRLF_LEN );
00311
00312
00313 append_str(p,via,via_len);
00314
00315
00316 append_str( p, from.s, from.len );
00317 append_str( p, Trans->callid.s, Trans->callid.len );
00318 append_str( p, to.s, to.len );
00319
00320 append_str( p, cseq_n.s, cseq_n.len );
00321 *(p++) = ' ';
00322 append_str( p, method, method_len );
00323 append_str( p, CRLF LOCAL_MAXFWD_HEADER,
00324 CRLF_LEN+LOCAL_MAXFWD_HEADER_LEN );
00325
00326
00327 for ( hdr=buf_hdrs ; hdr ; hdr=hdr->next )
00328 if(hdr->type==HDR_ROUTE_T) {
00329 append_str(p, hdr->name.s, hdr->len );
00330 }
00331
00332
00333 if (server_signature) {
00334 append_str(p, user_agent_header.s, user_agent_header.len);
00335 append_str(p, CRLF CONTENT_LENGTH "0" CRLF CRLF ,
00336 CRLF_LEN+CONTENT_LENGTH_LEN+1 + CRLF_LEN + CRLF_LEN);
00337 } else {
00338 append_str(p, CONTENT_LENGTH "0" CRLF CRLF ,
00339 CONTENT_LENGTH_LEN+1 + CRLF_LEN + CRLF_LEN);
00340 }
00341 *p=0;
00342
00343 pkg_free(via);
00344 free_hdr_field_lst(buf_hdrs);
00345 return cancel_buf;
00346 error02:
00347 free_hdr_field_lst(buf_hdrs);
00348 error01:
00349 pkg_free(via);
00350 error:
00351 return NULL;
00352 }
00353
00354
00355 struct rte {
00356 rr_t* ptr;
00357 struct rte* next;
00358 };
00359
00360
00361 static inline void free_rte_list(struct rte* list)
00362 {
00363 struct rte* ptr;
00364
00365 while(list) {
00366 ptr = list;
00367 list = list->next;
00368 pkg_free(ptr);
00369 }
00370 }
00371
00372
00373 static inline int process_routeset(struct sip_msg* msg, str* contact, struct rte** list, str* ruri, str* next_hop)
00374 {
00375 struct hdr_field* ptr;
00376 rr_t* p;
00377 struct rte* t, *head;
00378 struct sip_uri puri;
00379
00380 ptr = msg->record_route;
00381 head = 0;
00382 while(ptr) {
00383 if (ptr->type == HDR_RECORDROUTE_T) {
00384 if (parse_rr(ptr) < 0) {
00385 LM_ERR("failed to parse Record-Route header\n");
00386 return -1;
00387 }
00388
00389 p = (rr_t*)ptr->parsed;
00390 while(p) {
00391 t = (struct rte*)pkg_malloc(sizeof(struct rte));
00392 if (!t) {
00393 LM_ERR("no more pkg memory\n");
00394 free_rte_list(head);
00395 return -1;
00396 }
00397 t->ptr = p;
00398 t->next = head;
00399 head = t;
00400 p = p->next;
00401 }
00402 }
00403 ptr = ptr->next;
00404 }
00405
00406 if (head) {
00407 if (parse_uri(head->ptr->nameaddr.uri.s, head->ptr->nameaddr.uri.len, &puri) < 0) {
00408 LM_ERR("failed to parse URI\n");
00409 free_rte_list(head);
00410 return -1;
00411 }
00412
00413 if (puri.lr.s) {
00414
00415 *ruri = *contact;
00416 *next_hop = head->ptr->nameaddr.uri;
00417 } else {
00418
00419 *ruri = head->ptr->nameaddr.uri;
00420 *next_hop = *ruri;
00421 t = head;
00422 head = head->next;
00423 pkg_free(t);
00424 }
00425 } else {
00426
00427 *ruri = *contact;
00428 *next_hop = *contact;
00429 }
00430
00431 *list = head;
00432 return 0;
00433 }
00434
00435
00436 static inline int calc_routeset_len(struct rte* list, str* contact)
00437 {
00438 struct rte* ptr;
00439 int ret;
00440
00441 if (list || contact) {
00442 ret = ROUTE_PREFIX_LEN + CRLF_LEN;
00443 } else {
00444 return 0;
00445 }
00446
00447 ptr = list;
00448 while(ptr) {
00449 if (ptr != list) {
00450 ret += ROUTE_SEPARATOR_LEN;
00451 }
00452 ret += ptr->ptr->len;
00453 ptr = ptr->next;
00454 }
00455
00456 if (contact) {
00457 if (list) ret += ROUTE_SEPARATOR_LEN;
00458 ret += 2 + contact->len;
00459 }
00460
00461 return ret;
00462 }
00463
00464
00465
00466
00467
00468 static inline char* print_rs(char* p, struct rte* list, str* contact)
00469 {
00470 struct rte* ptr;
00471
00472 if (list || contact) {
00473 append_str(p, ROUTE_PREFIX, ROUTE_PREFIX_LEN);
00474 } else {
00475 return p;
00476 }
00477
00478 ptr = list;
00479 while(ptr) {
00480 if (ptr != list) {
00481 append_str(p, ROUTE_SEPARATOR, ROUTE_SEPARATOR_LEN);
00482 }
00483
00484 append_str(p, ptr->ptr->nameaddr.name.s, ptr->ptr->len);
00485 ptr = ptr->next;
00486 }
00487
00488 if (contact) {
00489 if (list) append_str(p, ROUTE_SEPARATOR, ROUTE_SEPARATOR_LEN);
00490 *p++ = '<';
00491 append_str(p, contact->s, contact->len);
00492 *p++ = '>';
00493 }
00494
00495 append_str(p, CRLF, CRLF_LEN);
00496 return p;
00497 }
00498
00499
00500
00501
00502
00503
00504 static inline int get_contact_uri(struct sip_msg* msg, str* uri)
00505 {
00506 contact_t* c;
00507
00508 uri->len = 0;
00509 if (!msg->contact) return 1;
00510
00511 if (parse_contact(msg->contact) < 0) {
00512 LM_ERR("failed to parse Contact body\n");
00513 return -1;
00514 }
00515
00516 c = ((contact_body_t*)msg->contact->parsed)->contacts;
00517
00518 if (!c) {
00519 LM_ERR("body or * contact\n");
00520 return -2;
00521 }
00522
00523 *uri = c->uri;
00524 return 0;
00525 }
00526
00527
00528
00529
00530
00531
00532
00533 char *build_dlg_ack(struct sip_msg* rpl, struct cell *Trans,
00534 unsigned int branch, str* to, unsigned int *len)
00535 {
00536 char *req_buf, *p, *via;
00537 unsigned int via_len;
00538 char branch_buf[MAX_BRANCH_PARAM_LEN];
00539 int branch_len;
00540 str branch_str;
00541 struct hostport hp;
00542 struct rte* list;
00543 str contact, ruri, *cont;
00544 struct socket_info* send_sock;
00545 str next_hop;
00546
00547
00548 if (rpl->first_line.u.reply.statuscode < 300 ) {
00549
00550 if (get_contact_uri(rpl, &contact) < 0) {
00551 return 0;
00552 }
00553
00554 if (process_routeset(rpl, &contact, &list, &ruri, &next_hop) < 0) {
00555 return 0;
00556 }
00557
00558 if ((contact.s != ruri.s) || (contact.len != ruri.len)) {
00559
00560
00561
00562
00563
00564 cont = &contact;
00565 } else {
00566
00567 cont = 0;
00568 }
00569 } else {
00570
00571
00572 ruri = Trans->uac[branch].uri;
00573 cont = 0;
00574 list = 0;
00575 }
00576
00577
00578 *len = SIP_VERSION_LEN + ACK_LEN + 2 + CRLF_LEN;
00579 *len += ruri.len;
00580
00581
00582 send_sock = Trans->uac[branch].request.dst.send_sock;
00583
00584 if (!t_calc_branch(Trans, branch, branch_buf, &branch_len)) goto error;
00585 branch_str.s = branch_buf;
00586 branch_str.len = branch_len;
00587 set_hostport(&hp, 0);
00588
00589
00590 via = via_builder(&via_len, send_sock, &branch_str, 0,
00591 send_sock->proto, &hp);
00592 if (!via) {
00593 LM_ERR("no via header got from builder\n");
00594 goto error;
00595 }
00596 *len+= via_len;
00597
00598
00599 *len += Trans->from.len + Trans->callid.len + to->len +
00600 Trans->cseq_n.len + 1 + ACK_LEN + CRLF_LEN;
00601
00602
00603 *len += calc_routeset_len(list, cont);
00604
00605
00606 if (server_signature)
00607 *len += user_agent_header.len + CRLF_LEN;
00608
00609
00610 *len += CONTENT_LENGTH_LEN + 1 + CRLF_LEN + CRLF_LEN;
00611
00612 req_buf = shm_malloc(*len + 1);
00613 if (!req_buf) {
00614 LM_ERR("no more share memory\n");
00615 goto error01;
00616 }
00617 p = req_buf;
00618
00619 append_str( p, ACK " ", ACK_LEN+1 );
00620 append_str(p, ruri.s, ruri.len );
00621 append_str( p, " " SIP_VERSION CRLF, 1 + SIP_VERSION_LEN + CRLF_LEN);
00622
00623
00624 append_str(p, via, via_len);
00625
00626
00627 append_str(p, Trans->from.s, Trans->from.len);
00628 append_str(p, Trans->callid.s, Trans->callid.len);
00629 append_str(p, to->s, to->len);
00630
00631 append_str(p, Trans->cseq_n.s, Trans->cseq_n.len);
00632 *(p++) = ' ';
00633 append_str(p, ACK CRLF, ACK_LEN+CRLF_LEN);
00634
00635
00636 p = print_rs(p, list, cont);
00637
00638
00639 if (server_signature) {
00640 append_str(p, user_agent_header.s, user_agent_header.len);
00641 append_str(p, CRLF CONTENT_LENGTH "0" CRLF CRLF,
00642 CRLF_LEN+CONTENT_LENGTH_LEN + 1 + CRLF_LEN + CRLF_LEN);
00643 } else {
00644 append_str(p, CONTENT_LENGTH "0" CRLF CRLF,
00645 CONTENT_LENGTH_LEN + 1 + CRLF_LEN + CRLF_LEN);
00646 }
00647 *p = 0;
00648
00649 pkg_free(via);
00650 free_rte_list(list);
00651 return req_buf;
00652 error01:
00653 pkg_free(via);
00654 error:
00655 free_rte_list(list);
00656 return 0;
00657 }
00658
00659
00660
00661
00662
00663 static inline int print_content_length(str* dest, str* body)
00664 {
00665 static char content_length[INT2STR_MAX_LEN];
00666 int len;
00667
00668
00669 if (body && body->len) {
00670 dest->s = int2bstr(body->len, content_length, &len);
00671 dest->len = len;
00672 } else {
00673 dest->s = "0";
00674 dest->len = 1;
00675 }
00676 return 0;
00677 }
00678
00679
00680
00681
00682
00683 static inline int print_cseq_num(str* _s, dlg_t* _d)
00684 {
00685 static char cseq[INT2STR_MAX_LEN];
00686 int len;
00687
00688 _s->s = int2bstr(_d->loc_seq.value, cseq, &len);
00689 _s->len = len;
00690 return 0;
00691 }
00692
00693
00694
00695
00696
00697 static inline int assemble_via(str* dest, struct cell* t, struct socket_info* sock, int branch)
00698 {
00699 static char branch_buf[MAX_BRANCH_PARAM_LEN];
00700 char* via;
00701 int len;
00702 unsigned int via_len;
00703 str branch_str;
00704 struct hostport hp;
00705
00706 if (!t_calc_branch(t, branch, branch_buf, &len)) {
00707 LM_ERR("branch calculation failed\n");
00708 return -1;
00709 }
00710
00711 branch_str.s = branch_buf;
00712 branch_str.len = len;
00713
00714 #ifdef XL_DEBUG
00715 printf("!!!proto: %d\n", sock->proto);
00716 #endif
00717
00718 set_hostport(&hp, 0);
00719 via = via_builder(&via_len, sock, &branch_str, 0, sock->proto, &hp);
00720 if (!via) {
00721 LM_ERR("via building failed\n");
00722 return -2;
00723 }
00724
00725 dest->s = via;
00726 dest->len = via_len;
00727 return 0;
00728 }
00729
00730
00731
00732
00733
00734 static inline char* print_request_uri(char* w, str* method, dlg_t* dialog, struct cell* t, int branch)
00735 {
00736 append_str(w, method->s, method->len);
00737 append_str(w, " ", 1);
00738
00739 t->uac[branch].uri.s = w;
00740 t->uac[branch].uri.len = dialog->hooks.request_uri->len;
00741
00742 append_str(w, dialog->hooks.request_uri->s, dialog->hooks.request_uri->len);
00743 append_str(w, " " SIP_VERSION CRLF, 1 + SIP_VERSION_LEN + CRLF_LEN);
00744 LM_DBG("%.*s\n",dialog->hooks.request_uri->len, dialog->hooks.request_uri->s );
00745 return w;
00746 }
00747
00748
00749
00750
00751
00752 static inline char* print_to(char* w, dlg_t* dialog, struct cell* t)
00753 {
00754 t->to.s = w;
00755 t->to.len = TO_LEN + dialog->rem_uri.len + CRLF_LEN;
00756
00757 append_str(w, TO, TO_LEN);
00758
00759 if(dialog->rem_dname.len) {
00760 t->to.len += dialog->rem_dname.len + 1;
00761 append_str(w, dialog->rem_dname.s, dialog->rem_dname.len);
00762 append_str(w, "<", 1);
00763 }
00764
00765 append_str(w, dialog->rem_uri.s, dialog->rem_uri.len);
00766
00767 if(dialog->rem_dname.len) {
00768 t->to.len += 1;
00769 append_str(w, ">", 1);
00770 }
00771
00772 if (dialog->id.rem_tag.len) {
00773 t->to.len += TOTAG_LEN + dialog->id.rem_tag.len ;
00774 append_str(w, TOTAG, TOTAG_LEN);
00775 append_str(w, dialog->id.rem_tag.s, dialog->id.rem_tag.len);
00776 }
00777
00778 append_str(w, CRLF, CRLF_LEN);
00779 return w;
00780 }
00781
00782
00783
00784
00785
00786 static inline char* print_from(char* w, dlg_t* dialog, struct cell* t)
00787 {
00788 t->from.s = w;
00789 t->from.len = FROM_LEN + dialog->loc_uri.len + CRLF_LEN;
00790
00791 append_str(w, FROM, FROM_LEN);
00792
00793 if(dialog->loc_dname.len) {
00794 t->from.len += dialog->loc_dname.len + 1;
00795 append_str(w, dialog->loc_dname.s, dialog->loc_dname.len);
00796 append_str(w, "<", 1);
00797 }
00798
00799 append_str(w, dialog->loc_uri.s, dialog->loc_uri.len);
00800
00801 if(dialog->loc_dname.len) {
00802 t->from.len += 1;
00803 append_str(w, ">", 1);
00804 }
00805
00806 if (dialog->id.loc_tag.len) {
00807 t->from.len += FROMTAG_LEN + dialog->id.loc_tag.len;
00808 append_str(w, FROMTAG, FROMTAG_LEN);
00809 append_str(w, dialog->id.loc_tag.s, dialog->id.loc_tag.len);
00810 }
00811
00812 append_str(w, CRLF, CRLF_LEN);
00813 return w;
00814 }
00815
00816
00817
00818
00819
00820 char* print_cseq_mini(char* target, str* cseq, str* method) {
00821 append_str(target, CSEQ, CSEQ_LEN);
00822 append_str(target, cseq->s, cseq->len);
00823 append_str(target, " ", 1);
00824 append_str(target, method->s, method->len);
00825 return target;
00826 }
00827
00828 static inline char* print_cseq(char* w, str* cseq, str* method, struct cell* t)
00829 {
00830 t->cseq_n.s = w;
00831
00832
00833 t->cseq_n.len = CSEQ_LEN + cseq->len;
00834 w = print_cseq_mini(w, cseq, method);
00835 return w;
00836 }
00837
00838
00839
00840
00841
00842
00843 char* print_callid_mini(char* target, str callid) {
00844 append_str(target, CALLID, CALLID_LEN);
00845 append_str(target, callid.s, callid.len);
00846 append_str(target, CRLF, CRLF_LEN);
00847 return target;
00848 }
00849
00850 static inline char* print_callid(char* w, dlg_t* dialog, struct cell* t)
00851 {
00852
00853 append_str(w, CRLF, CRLF_LEN);
00854 t->callid.s = w;
00855 t->callid.len = CALLID_LEN + dialog->id.call_id.len + CRLF_LEN;
00856
00857 w = print_callid_mini(w, dialog->id.call_id);
00858 return w;
00859 }
00860
00861
00862
00863
00864
00865 char* build_uac_req(str* method, str* headers, str* body, dlg_t* dialog,
00866 int branch, struct cell *t, int* len)
00867 {
00868 char* buf, *w;
00869 str content_length, cseq, via;
00870
00871 if (!method || !dialog) {
00872 LM_ERR("inalid parameter value\n");
00873 return 0;
00874 }
00875 if (print_content_length(&content_length, body) < 0) {
00876 LM_ERR("failed to print content-length\n");
00877 return 0;
00878 }
00879 if (print_cseq_num(&cseq, dialog) < 0) {
00880 LM_ERR("failed to print CSeq number\n");
00881 return 0;
00882 }
00883 *len = method->len + 1 + dialog->hooks.request_uri->len + 1 +
00884 SIP_VERSION_LEN + CRLF_LEN;
00885
00886 if (assemble_via(&via, t, dialog->send_sock, branch) < 0) {
00887 LM_ERR("failed to assemble Via\n");
00888 return 0;
00889 }
00890 *len += via.len;
00891
00892
00893 *len += TO_LEN
00894 + (dialog->rem_dname.len ? (2 + dialog->rem_dname.len) : 0)
00895 + dialog->rem_uri.len
00896 + (dialog->id.rem_tag.len ? (TOTAG_LEN + dialog->id.rem_tag.len) : 0)
00897 + CRLF_LEN;
00898
00899 *len += FROM_LEN
00900 + (dialog->loc_dname.len ? (2 + dialog->loc_dname.len) : 0)
00901 + dialog->loc_uri.len
00902 + (dialog->id.loc_tag.len ? (FROMTAG_LEN + dialog->id.loc_tag.len):0)
00903 + CRLF_LEN;
00904
00905 *len += CALLID_LEN + dialog->id.call_id.len + CRLF_LEN;
00906
00907 *len += CSEQ_LEN + cseq.len + 1 + method->len + CRLF_LEN;
00908
00909 *len += calculate_routeset_length(dialog);
00910
00911 *len += CONTENT_LENGTH_LEN + content_length.len + CRLF_LEN;
00912
00913 *len += (server_signature ? (user_agent_header.len + CRLF_LEN) : 0);
00914
00915 *len += (headers ? headers->len : 0);
00916
00917 *len += (body ? body->len : 0);
00918
00919 *len += CRLF_LEN;
00920
00921 buf = shm_malloc(*len + 1);
00922 if (!buf) {
00923 LM_ERR("no more share memory\n");
00924 goto error;
00925 }
00926
00927 w = buf;
00928
00929 w = print_request_uri(w, method, dialog, t, branch);
00930 append_str(w, via.s, via.len);
00931 w = print_to(w, dialog, t);
00932 w = print_from(w, dialog, t);
00933 w = print_cseq(w, &cseq, method, t);
00934 w = print_callid(w, dialog, t);
00935 w = print_routeset(w, dialog);
00936
00937
00938 append_str(w, CONTENT_LENGTH, CONTENT_LENGTH_LEN);
00939 append_str(w, content_length.s, content_length.len);
00940 append_str(w, CRLF, CRLF_LEN);
00941
00942
00943 if (server_signature) {
00944 append_str(w, user_agent_header.s, user_agent_header.len);
00945 append_str(w, CRLF, CRLF_LEN);
00946 }
00947 if (headers)
00948 append_str(w, headers->s, headers->len);
00949 append_str(w, CRLF, CRLF_LEN);
00950 if (body)
00951 append_str(w, body->s, body->len);
00952
00953 #ifdef EXTRA_DEBUG
00954 if (w-buf != *len ) abort();
00955 #endif
00956
00957 pkg_free(via.s);
00958 return buf;
00959
00960 error:
00961 pkg_free(via.s);
00962 return 0;
00963 }
00964
00965
00966 int t_calc_branch(struct cell *t,
00967 int b, char *branch, int *branch_len)
00968 {
00969 return syn_branch ?
00970 branch_builder( t->hash_index,
00971 t->label, 0,
00972 b, branch, branch_len )
00973 : branch_builder( t->hash_index,
00974 0, t->md5,
00975 b, branch, branch_len );
00976 }
00977
00978 char *build_uac_cancel(str *headers,str *body,struct cell *cancelledT,
00979 unsigned int branch, unsigned int *len)
00980 {
00981 char *cancel_buf, *p, *via;
00982 unsigned int via_len;
00983 char branch_buf[MAX_BRANCH_PARAM_LEN];
00984 str branch_str;
00985 struct hostport hp;
00986 str content_length;
00987
00988 LM_DBG("sing FROM=<%.*s>, TO=<%.*s>, CSEQ_N=<%.*s>\n",
00989 cancelledT->from.len, cancelledT->from.s, cancelledT->to.len,
00990 cancelledT->to.s, cancelledT->cseq_n.len, cancelledT->cseq_n.s);
00991
00992 branch_str.s=branch_buf;
00993 if (!t_calc_branch(cancelledT, branch, branch_str.s, &branch_str.len )){
00994 LM_ERR("failed to create branch !\n");
00995 goto error;
00996 }
00997 set_hostport(&hp,0);
00998 via=via_builder(&via_len, cancelledT->uac[branch].request.dst.send_sock,
00999 &branch_str, 0, cancelledT->uac[branch].request.dst.proto, &hp );
01000 if (!via){
01001 LM_ERR("no via header got from builder\n");
01002 goto error;
01003 }
01004
01005
01006 *len=CANCEL_LEN + 2 +SIP_VERSION_LEN + CRLF_LEN;
01007 *len+=cancelledT->uac[branch].uri.len;
01008
01009 *len+= via_len;
01010
01011 *len+=cancelledT->from.len;
01012
01013 *len+=cancelledT->to.len;
01014
01015 *len+=cancelledT->callid.len;
01016
01017 *len+=cancelledT->cseq_n.len+1+CANCEL_LEN+CRLF_LEN;
01018
01019 if (server_signature) {
01020 *len += USER_AGENT_LEN + CRLF_LEN;
01021 }
01022
01023 if (print_content_length(&content_length, body) < 0) {
01024 LM_ERR("failed to print content-length\n");
01025 return 0;
01026 }
01027
01028 *len += (body ? (CONTENT_LENGTH_LEN + content_length.len + CRLF_LEN) : 0);
01029
01030 *len += (headers ? headers->len : 0);
01031
01032 *len+= CRLF_LEN;
01033
01034 *len += (body ? body->len : 0);
01035
01036 cancel_buf=shm_malloc( *len+1 );
01037 if (!cancel_buf)
01038 {
01039 LM_ERR("no more share memory\n");
01040 goto error01;
01041 }
01042 p = cancel_buf;
01043
01044 append_str( p, CANCEL, CANCEL_LEN );
01045 *(p++) = ' ';
01046 append_str( p, cancelledT->uac[branch].uri.s,
01047 cancelledT->uac[branch].uri.len);
01048 append_str( p, " " SIP_VERSION CRLF, 1+SIP_VERSION_LEN+CRLF_LEN );
01049
01050
01051 append_str(p,via,via_len);
01052
01053
01054 append_str( p, cancelledT->from.s, cancelledT->from.len );
01055 append_str( p, cancelledT->callid.s, cancelledT->callid.len );
01056 append_str( p, cancelledT->to.s, cancelledT->to.len );
01057
01058 append_str( p, cancelledT->cseq_n.s, cancelledT->cseq_n.len );
01059 *(p++) = ' ';
01060 append_str( p, CANCEL, CANCEL_LEN );
01061 append_str( p, CRLF, CRLF_LEN );
01062
01063
01064 if (server_signature) {
01065 append_str(p,USER_AGENT CRLF, USER_AGENT_LEN+CRLF_LEN );
01066 }
01067
01068 if (body) {
01069 append_str(p, CONTENT_LENGTH, CONTENT_LENGTH_LEN);
01070 append_str(p, content_length.s, content_length.len);
01071 append_str(p, CRLF, CRLF_LEN);
01072 }
01073 if(headers && headers->len){
01074 append_str(p,headers->s,headers->len);
01075 }
01076
01077 append_str(p,CRLF,CRLF_LEN);
01078 if(body && body->len){
01079 append_str(p,body->s,body->len);
01080 }
01081 *p=0;
01082 pkg_free(via);
01083 return cancel_buf;
01084 error01:
01085 pkg_free(via);
01086 error:
01087 return NULL;
01088 }
01089
01090
01091
01092
01093 void check_hdrs_changes(struct sip_msg *msg)
01094 {
01095 struct lump *t;
01096 unsigned int flags;
01097 char *pos;
01098
01099 flags = FL_USE_UAC_FROM|FL_USE_UAC_TO|FL_USE_UAC_CSEQ;
01100
01101
01102 if((msg->msg_flags&flags) == flags)
01103 return;
01104
01105 for (t=msg->add_rm;t;t=t->next) {
01106 if ((t->op==LUMP_DEL)||(t->op==LUMP_NOP))
01107 {
01108 pos = msg->buf + t->u.offset;
01109
01110 if( ((msg->msg_flags&FL_USE_UAC_FROM)==0)
01111 && (msg->from!=NULL)
01112 && (( pos < msg->from->name.s
01113 && pos + t->len > msg->from->name.s )
01114 || (pos >= msg->from->name.s
01115 && pos <= msg->from->name.s+msg->from->len)
01116 )
01117 )
01118 msg->msg_flags |= FL_USE_UAC_FROM;
01119
01120 if( ((msg->msg_flags&FL_USE_UAC_TO)==0)
01121 && (msg->to!=NULL)
01122 && (( pos < msg->to->name.s
01123 && pos + t->len > msg->to->name.s )
01124 || (pos >= msg->to->name.s
01125 && pos <= msg->to->name.s+msg->to->len)
01126 )
01127 )
01128 msg->msg_flags |= FL_USE_UAC_TO;
01129
01130 if( ((msg->msg_flags&FL_USE_UAC_CSEQ)==0)
01131 && (msg->cseq!=NULL)
01132 && (( pos < msg->cseq->name.s
01133 && pos + t->len > msg->cseq->name.s )
01134 || (pos >= msg->cseq->name.s
01135 && pos <= msg->cseq->name.s+msg->cseq->len)
01136 )
01137 )
01138 msg->msg_flags |= FL_USE_UAC_CSEQ;
01139
01140
01141 if((msg->msg_flags&flags) == flags)
01142 return;
01143 }
01144 }
01145 }
01146