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
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 #include <sys/types.h>
00118 #include <sys/socket.h>
00119 #include <netdb.h>
00120 #include <string.h>
00121 #include <stdio.h>
00122 #include <stdlib.h>
00123
00124 #include "msg_translator.h"
00125 #include "globals.h"
00126 #include "error.h"
00127 #include "mem/mem.h"
00128 #include "dprint.h"
00129 #include "config.h"
00130 #include "md5utils.h"
00131 #include "data_lump.h"
00132 #include "data_lump_rpl.h"
00133 #include "ip_addr.h"
00134 #include "resolve.h"
00135 #include "ut.h"
00136 #include "pt.h"
00137
00138 extern char version[];
00139 extern int version_len;
00140
00141
00142
00143
00144
00145
00146
00147 static int check_via_address(struct ip_addr* ip, str *name,
00148 unsigned short port, unsigned short proto, int resolver)
00149 {
00150 struct hostent* he;
00151 int i, len;
00152 char* s;
00153
00154
00155 s=ip_addr2a(ip);
00156 if (s){
00157 LM_DBG("params %s, %.*s, %d\n", s, name->len, name->s, resolver);
00158 len=strlen(s);
00159
00160 #ifdef USE_IPV6
00161
00162 if ((ip->af==AF_INET6) &&
00163 ( ((len==name->len)&&(strncasecmp(name->s, s, name->len)==0))
00164 ||
00165 ((len==(name->len-2))&&(name->s[0]=='[')&&
00166 (name->s[name->len-1]==']')&&
00167 (strncasecmp(name->s+1, s, len)==0))
00168 )
00169 )
00170 return 0;
00171 else
00172 #endif
00173
00174 if (strncmp(name->s, s, name->len)==0)
00175 return 0;
00176 }else{
00177 LM_CRIT("could not convert ip address\n");
00178 return -1;
00179 }
00180
00181 if (port==0) port=SIP_PORT;
00182 if (resolver&DO_DNS){
00183 LM_DBG("doing dns lookup\n");
00184
00185 he=sip_resolvehost(name, &port, &proto, 0, 0);
00186 if (he && (int)ip->af==he->h_addrtype){
00187 for(i=0;he && he->h_addr_list[i];i++){
00188 if ( memcmp(&he->h_addr_list[i], ip->u.addr, ip->len)==0)
00189 return 0;
00190 }
00191 }
00192 }
00193 if (resolver&DO_REV_DNS){
00194 LM_DBG("doing rev. dns lookup\n");
00195
00196 he=rev_resolvehost(ip);
00197 if (he && (strncmp(he->h_name, name->s, name->len)==0))
00198 return 0;
00199 for (i=0; he && he->h_aliases[i];i++){
00200 if (strncmp(he->h_aliases[i],name->s, name->len)==0)
00201 return 0;
00202 }
00203 }
00204 return -1;
00205 }
00206
00207
00208
00209 int received_test( struct sip_msg *msg )
00210 {
00211 int rcvd;
00212
00213 if(msg->via1->received !=NULL)
00214 return 1;
00215
00216 if(msg->via1->maddr){
00217 rcvd = check_via_address(&msg->rcv.src_ip, &msg->via1->maddr->value,
00218 msg->via1->port, msg->via1->proto, received_dns);
00219 } else {
00220 rcvd = check_via_address(&msg->rcv.src_ip,
00221 &msg->via1->host, msg->via1->port, msg->via1->proto, received_dns);
00222 }
00223
00224 return rcvd;
00225 }
00226
00227
00228 static char * warning_builder( struct sip_msg *msg, unsigned int *returned_len)
00229 {
00230 static char buf[MAX_WARNING_LEN];
00231 str *foo;
00232 int print_len, l, clen;
00233 char* t;
00234
00235 #define str_print(string, string_len) \
00236 do{ \
00237 l=(string_len); \
00238 if ((clen+l)>MAX_WARNING_LEN) \
00239 goto error_overflow; \
00240 memcpy(buf+clen, (string), l); \
00241 clen+=l; \
00242 }while(0)
00243
00244 #define str_lenpair_print(string, string_len, string2, string2_len) \
00245 do{ \
00246 str_print(string, string_len); \
00247 str_print(string2, string2_len);\
00248 }while(0)
00249
00250 #define str_pair_print( string, string2, string2_len) \
00251 str_lenpair_print((string), strlen((string)), (string2), (string2_len))
00252
00253 #define str_int_print(string, intval)\
00254 do{\
00255 t=int2str((intval), &print_len); \
00256 str_pair_print(string, t, print_len);\
00257 } while(0)
00258
00259 #define str_ipaddr_print(string, ipaddr_val)\
00260 do{\
00261 t=ip_addr2a((ipaddr_val)); \
00262 print_len=strlen(t); \
00263 str_pair_print(string, t, print_len);\
00264 } while(0)
00265
00266 clen=0;
00267 str_lenpair_print(WARNING, WARNING_LEN,
00268 msg->rcv.bind_address->name.s,
00269 msg->rcv.bind_address->name.len);
00270 str_lenpair_print(":", 1, msg->rcv.bind_address->port_no_str.s,
00271 msg->rcv.bind_address->port_no_str.len);
00272 str_print(WARNING_PHRASE, WARNING_PHRASE_LEN);
00273
00274
00275 if (msg->new_uri.s)
00276 foo=&(msg->new_uri);
00277 else
00278 foo=&(msg->first_line.u.request.uri);
00279
00280 str_int_print(" pid=", my_pid());
00281
00282 str_ipaddr_print(" req_src_ip=", &msg->rcv.src_ip);
00283 str_int_print(" req_src_port=", msg->rcv.src_port);
00284 str_pair_print(" in_uri=", msg->first_line.u.request.uri.s,
00285 msg->first_line.u.request.uri.len);
00286 str_pair_print(" out_uri=", foo->s, foo->len);
00287 str_pair_print(" via_cnt",
00288 (msg->parsed_flag & HDR_EOH_F)==HDR_EOH_F ? "=" : ">", 1);
00289 str_int_print("=", via_cnt);
00290 if (clen<MAX_WARNING_LEN){ buf[clen]='"'; clen++; }
00291 else goto error_overflow;
00292
00293
00294 *returned_len=clen;
00295 return buf;
00296 error_overflow:
00297 LM_ERR("buffer size exceeded\n");
00298 *returned_len=0;
00299 return 0;
00300 }
00301
00302
00303
00304
00305 char* received_builder(struct sip_msg *msg, unsigned int *received_len)
00306 {
00307 char *buf, *tmp;
00308 int len, tmp_len;
00309 struct ip_addr *source_ip;
00310
00311 source_ip=&msg->rcv.src_ip;
00312
00313 buf=pkg_malloc(sizeof(char)*MAX_RECEIVED_SIZE);
00314 if (buf==0){
00315 ser_error=E_OUT_OF_MEM;
00316 LM_ERR("out of pkg memory\n");
00317 return 0;
00318 }
00319 memcpy(buf, RECEIVED, RECEIVED_LEN);
00320 if ( (tmp=ip_addr2a(source_ip))==0)
00321 return 0;
00322 tmp_len=strlen(tmp);
00323 len=RECEIVED_LEN+tmp_len;
00324
00325 memcpy(buf+RECEIVED_LEN, tmp, tmp_len);
00326 buf[len]=0;
00327
00328 *received_len = len;
00329 return buf;
00330 }
00331
00332
00333
00334 char* rport_builder(struct sip_msg *msg, unsigned int *rport_len)
00335 {
00336 char* buf, * tmp;
00337 int len, tmp_len;
00338
00339 tmp_len=0;
00340 tmp=int2str(msg->rcv.src_port, &tmp_len);
00341 len=RPORT_LEN+tmp_len;
00342 buf=pkg_malloc(sizeof(char)*(len+1));
00343 if (buf==0){
00344 ser_error=E_OUT_OF_MEM;
00345 LM_ERR("out of pkg memory\n");
00346 return 0;
00347 }
00348 memcpy(buf, RPORT, RPORT_LEN);
00349 memcpy(buf+RPORT_LEN, tmp, tmp_len);
00350 buf[len]=0;
00351
00352 *rport_len=len;
00353 return buf;
00354 }
00355
00356
00357
00358 char* id_builder(struct sip_msg* msg, unsigned int *id_len)
00359 {
00360 char* buf, *p;
00361 int len, value_len, size;
00362 char revhex[sizeof(int)*2];
00363
00364 size=sizeof(int)*2;
00365 p=&revhex[0];
00366 if (int2reverse_hex(&p, &size, msg->rcv.proto_reserved1)==-1){
00367 LM_CRIT("not enough space for id\n");
00368 return 0;
00369 }
00370 value_len=p-&revhex[0];
00371 len=ID_PARAM_LEN+value_len;
00372 buf=pkg_malloc(sizeof(char)*(len+1));
00373 if (buf==0){
00374 ser_error=E_OUT_OF_MEM;
00375 LM_ERR("out of pkg memory\n");
00376 return 0;
00377 }
00378 memcpy(buf, ID_PARAM, ID_PARAM_LEN);
00379 memcpy(buf+ID_PARAM_LEN, revhex, value_len);
00380 buf[len]=0;
00381 *id_len=len;
00382 return buf;
00383 }
00384
00385
00386
00387 char* clen_builder(struct sip_msg* msg, int *clen_len, int diff)
00388 {
00389 char *buf, *body, * value_s;
00390 int len, value, value_len;
00391
00392 body=get_body(msg);
00393 if (body==0){
00394 ser_error=E_BAD_REQ;
00395 LM_ERR("no message body found (missing crlf?)");
00396 return 0;
00397 }
00398 value=msg->len-(int)(body-msg->buf)+diff;
00399 value_s=int2str(value, &value_len);
00400 LM_DBG("content-length: %d (%s)\n", value, value_s);
00401
00402 len=CONTENT_LENGTH_LEN+value_len+CRLF_LEN;
00403 buf=pkg_malloc(sizeof(char)*(len+1));
00404 if (buf==0){
00405 ser_error=E_OUT_OF_MEM;
00406 LM_ERR("out of pkg memory\n");
00407 return 0;
00408 }
00409 memcpy(buf, CONTENT_LENGTH, CONTENT_LENGTH_LEN);
00410 memcpy(buf+CONTENT_LENGTH_LEN, value_s, value_len);
00411 memcpy(buf+CONTENT_LENGTH_LEN+value_len, CRLF, CRLF_LEN);
00412 buf[len]=0;
00413 *clen_len=len;
00414 return buf;
00415 }
00416
00417
00418
00419
00420
00421 static inline int lump_check_opt( struct lump *l,
00422 struct sip_msg* msg,
00423 struct socket_info* snd_s
00424 )
00425 {
00426 struct ip_addr* ip;
00427 unsigned short port;
00428 int proto;
00429
00430 #define get_ip_port_proto \
00431 if (snd_s==0){ \
00432 LM_CRIT("null send socket\n"); \
00433 return 1; \
00434 } \
00435 if (msg->rcv.bind_address){ \
00436 ip=&msg->rcv.bind_address->address; \
00437 port=msg->rcv.bind_address->port_no; \
00438 proto=msg->rcv.bind_address->proto; \
00439 }else{ \
00440 ip=&msg->rcv.dst_ip; \
00441 port=msg->rcv.dst_port; \
00442 proto=msg->rcv.proto; \
00443 } \
00444
00445 switch(l->u.cond){
00446 case COND_FALSE:
00447 return 0;
00448 case COND_TRUE:
00449 l->flags |= LUMPFLAG_COND_TRUE;
00450 return 1;
00451 case COND_IF_DIFF_REALMS:
00452 get_ip_port_proto;
00453
00454 if ((port==snd_s->port_no)&&(proto==snd_s->proto)&&
00455 (ip_addr_cmp(ip, &snd_s->address)))
00456 return 0;
00457 l->flags |= LUMPFLAG_COND_TRUE;
00458 return 1;
00459 case COND_IF_DIFF_AF:
00460 get_ip_port_proto;
00461 if (ip->af==snd_s->address.af) return 0;
00462 l->flags |= LUMPFLAG_COND_TRUE;
00463 return 1;
00464 case COND_IF_DIFF_PROTO:
00465 get_ip_port_proto;
00466 if (proto==snd_s->proto) return 0;
00467 l->flags |= LUMPFLAG_COND_TRUE;
00468 return 1;
00469 case COND_IF_DIFF_PORT:
00470 get_ip_port_proto;
00471 if (port==snd_s->port_no) return 0;
00472 l->flags |= LUMPFLAG_COND_TRUE;
00473 return 1;
00474 case COND_IF_DIFF_IP:
00475 get_ip_port_proto;
00476 if (ip_addr_cmp(ip, &snd_s->address)) return 0;
00477 l->flags |= LUMPFLAG_COND_TRUE;
00478 return 1;
00479 default:
00480 LM_CRIT("unknown lump condition %d\n", l->u.cond);
00481 }
00482 return 0;
00483 }
00484
00485
00486
00487
00488
00489 static inline int lumps_len(struct sip_msg* msg, struct lump* lumps,
00490 struct socket_info* send_sock)
00491 {
00492 unsigned int s_offset, new_len;
00493 struct lump *t, *r;
00494 str *send_address_str, *send_port_str;
00495
00496 #define SUBST_LUMP_LEN(subst_l) \
00497 switch((subst_l)->u.subst){ \
00498 case SUBST_RCV_IP: \
00499 if (msg->rcv.bind_address){ \
00500 new_len+=msg->rcv.bind_address->address_str.len; \
00501 }else{ \
00502 \
00503 LM_CRIT("fixme:null bind_address\n"); \
00504 }; \
00505 break; \
00506 case SUBST_RCV_PORT: \
00507 if (msg->rcv.bind_address){ \
00508 new_len+=msg->rcv.bind_address->port_no_str.len; \
00509 }else{ \
00510 \
00511 LM_CRIT("fixme: null bind_address\n"); \
00512 }; \
00513 break; \
00514 case SUBST_RCV_PROTO: \
00515 if (msg->rcv.bind_address){ \
00516 switch(msg->rcv.bind_address->proto){ \
00517 case PROTO_NONE: \
00518 case PROTO_UDP: \
00519 case PROTO_TCP: \
00520 case PROTO_TLS: \
00521 new_len+=3; \
00522 break; \
00523 case PROTO_SCTP: \
00524 new_len+=4; \
00525 break; \
00526 default: \
00527 LM_CRIT("unknown proto %d\n", \
00528 msg->rcv.bind_address->proto); \
00529 }\
00530 }else{ \
00531 \
00532 LM_CRIT("fixme: null bind_address\n"); \
00533 }; \
00534 break; \
00535 case SUBST_RCV_ALL: \
00536 if (msg->rcv.bind_address){ \
00537 new_len+=msg->rcv.bind_address->address_str.len; \
00538 if (msg->rcv.bind_address->port_no!=SIP_PORT){ \
00539 \
00540 new_len+=1+msg->rcv.bind_address->port_no_str.len; \
00541 }\
00542 \
00543 switch(msg->rcv.bind_address->proto){ \
00544 case PROTO_NONE: \
00545 case PROTO_UDP: \
00546 break; \
00547 case PROTO_TCP: \
00548 case PROTO_TLS: \
00549 new_len+=TRANSPORT_PARAM_LEN+3; \
00550 break; \
00551 case PROTO_SCTP: \
00552 new_len+=TRANSPORT_PARAM_LEN+4; \
00553 break; \
00554 default: \
00555 LM_CRIT("unknown proto %d\n", \
00556 msg->rcv.bind_address->proto); \
00557 }\
00558 }else{ \
00559 \
00560 LM_CRIT("fixme: null bind_address\n"); \
00561 }; \
00562 break; \
00563 case SUBST_SND_IP: \
00564 if (send_sock){ \
00565 new_len+=send_address_str->len; \
00566 }else{ \
00567 LM_CRIT("fixme: lumps_len called with" \
00568 " null send_sock\n"); \
00569 }; \
00570 break; \
00571 case SUBST_SND_PORT: \
00572 if (send_sock){ \
00573 new_len+=send_port_str->len; \
00574 }else{ \
00575 LM_CRIT("lumps_len called with" \
00576 " null send_sock\n"); \
00577 }; \
00578 break; \
00579 case SUBST_SND_PROTO: \
00580 if (send_sock){ \
00581 switch(send_sock->proto){ \
00582 case PROTO_NONE: \
00583 case PROTO_UDP: \
00584 case PROTO_TCP: \
00585 case PROTO_TLS: \
00586 new_len+=3; \
00587 break; \
00588 case PROTO_SCTP: \
00589 new_len+=4; \
00590 break; \
00591 default: \
00592 LM_CRIT("unknown proto %d\n", \
00593 send_sock->proto); \
00594 }\
00595 }else{ \
00596 LM_CRIT("lumps_len called with" \
00597 " null send_sock\n"); \
00598 }; \
00599 break; \
00600 case SUBST_SND_ALL: \
00601 if (send_sock){ \
00602 new_len+=send_address_str->len; \
00603 if ((send_sock->port_no!=SIP_PORT) || \
00604 (send_port_str!=&(send_sock->port_no_str))){ \
00605 \
00606 new_len+=1+send_port_str->len; \
00607 }\
00608 \
00609 switch(send_sock->proto){ \
00610 case PROTO_NONE: \
00611 case PROTO_UDP: \
00612 break; \
00613 case PROTO_TCP: \
00614 case PROTO_TLS: \
00615 new_len+=TRANSPORT_PARAM_LEN+3; \
00616 break; \
00617 case PROTO_SCTP: \
00618 new_len+=TRANSPORT_PARAM_LEN+4; \
00619 break; \
00620 default: \
00621 LM_CRIT("unknown proto %d\n", \
00622 send_sock->proto); \
00623 }\
00624 }else{ \
00625 \
00626 LM_CRIT("lumps_len called with" \
00627 " null send_sock\n"); \
00628 }; \
00629 break; \
00630 case SUBST_NOP: \
00631 break; \
00632 default: \
00633 LM_CRIT("unknown subst type %d\n", \
00634 (subst_l)->u.subst); \
00635 }
00636
00637 s_offset=0;
00638 new_len=0;
00639
00640 if (msg->set_global_address.len)
00641 send_address_str=&(msg->set_global_address);
00642 else
00643 send_address_str=&(send_sock->address_str);
00644 if (msg->set_global_port.len)
00645 send_port_str=&(msg->set_global_port);
00646 else
00647 send_port_str=&(send_sock->port_no_str);
00648
00649
00650 for(t=lumps;t;t=t->next){
00651
00652 if ((t->op==LUMP_ADD_OPT) && !lump_check_opt(t, msg, send_sock))
00653 continue;
00654 for(r=t->before;r;r=r->before){
00655 switch(r->op){
00656 case LUMP_ADD:
00657 new_len+=r->len;
00658 break;
00659 case LUMP_ADD_SUBST:
00660 SUBST_LUMP_LEN(r);
00661 break;
00662 case LUMP_ADD_OPT:
00663
00664
00665 if (!lump_check_opt(r, msg, send_sock))
00666 goto skip_before;
00667 break;
00668 default:
00669
00670 LM_CRIT("invalid op for data lump (%x)\n", r->op);
00671 }
00672 }
00673 skip_before:
00674 switch(t->op){
00675 case LUMP_ADD:
00676 new_len+=t->len;
00677 break;
00678 case LUMP_ADD_SUBST:
00679 SUBST_LUMP_LEN(t);
00680 break;
00681 case LUMP_ADD_OPT:
00682
00683
00684 break;
00685 case LUMP_DEL:
00686
00687 if (t->u.offset < s_offset){
00688
00689 if (t->len>s_offset-t->u.offset)
00690 t->len-=s_offset-t->u.offset;
00691 else t->len=0;
00692 t->u.offset=s_offset;
00693 }
00694 s_offset=t->u.offset+t->len;
00695 new_len-=t->len;
00696 break;
00697 case LUMP_NOP:
00698
00699 if (t->u.offset < s_offset){
00700 t->u.offset=s_offset;
00701 }else
00702 s_offset=t->u.offset;
00703
00704 break;
00705 default:
00706 LM_CRIT("op for data lump (%x)\n", r->op);
00707 }
00708 for (r=t->after;r;r=r->after){
00709 switch(r->op){
00710 case LUMP_ADD:
00711 new_len+=r->len;
00712 break;
00713 case LUMP_ADD_SUBST:
00714 SUBST_LUMP_LEN(r);
00715 break;
00716 case LUMP_ADD_OPT:
00717
00718
00719 if (!lump_check_opt(r, msg, send_sock))
00720 goto skip_after;
00721 break;
00722 default:
00723
00724 LM_CRIT("invalid op for data lump (%x)\n", r->op);
00725 }
00726 }
00727 skip_after:
00728 ;
00729 }
00730 return new_len;
00731 }
00732
00733
00734
00735
00736
00737
00738 static inline void process_lumps( struct sip_msg* msg,
00739 struct lump* lumps,
00740 char* new_buf,
00741 unsigned int* new_buf_offs,
00742 unsigned int* orig_offs,
00743 struct socket_info* send_sock)
00744 {
00745 struct lump *t, *r;
00746 char* orig;
00747 unsigned int size, offset, s_offset;
00748 str *send_address_str, *send_port_str;
00749
00750 #define SUBST_LUMP(subst_l) \
00751 switch((subst_l)->u.subst){ \
00752 case SUBST_RCV_IP: \
00753 if (msg->rcv.bind_address){ \
00754 memcpy(new_buf+offset, msg->rcv.bind_address->address_str.s, \
00755 msg->rcv.bind_address->address_str.len); \
00756 offset+=msg->rcv.bind_address->address_str.len; \
00757 }else{ \
00758 \
00759 LM_CRIT("null bind_address\n"); \
00760 }; \
00761 break; \
00762 case SUBST_RCV_PORT: \
00763 if (msg->rcv.bind_address){ \
00764 memcpy(new_buf+offset, msg->rcv.bind_address->port_no_str.s, \
00765 msg->rcv.bind_address->port_no_str.len); \
00766 offset+=msg->rcv.bind_address->port_no_str.len; \
00767 }else{ \
00768 \
00769 LM_CRIT("null bind_address\n"); \
00770 }; \
00771 break; \
00772 case SUBST_RCV_ALL: \
00773 if (msg->rcv.bind_address){ \
00774 \
00775 memcpy(new_buf+offset, msg->rcv.bind_address->address_str.s, \
00776 msg->rcv.bind_address->address_str.len); \
00777 offset+=msg->rcv.bind_address->address_str.len; \
00778 \
00779 if (msg->rcv.bind_address->port_no!=SIP_PORT){ \
00780 new_buf[offset]=':'; offset++; \
00781 memcpy(new_buf+offset, \
00782 msg->rcv.bind_address->port_no_str.s, \
00783 msg->rcv.bind_address->port_no_str.len); \
00784 offset+=msg->rcv.bind_address->port_no_str.len; \
00785 }\
00786 switch(msg->rcv.bind_address->proto){ \
00787 case PROTO_NONE: \
00788 case PROTO_UDP: \
00789 break; \
00790 case PROTO_TCP: \
00791 memcpy(new_buf+offset, TRANSPORT_PARAM, \
00792 TRANSPORT_PARAM_LEN); \
00793 offset+=TRANSPORT_PARAM_LEN; \
00794 memcpy(new_buf+offset, "tcp", 3); \
00795 offset+=3; \
00796 break; \
00797 case PROTO_TLS: \
00798 memcpy(new_buf+offset, TRANSPORT_PARAM, \
00799 TRANSPORT_PARAM_LEN); \
00800 offset+=TRANSPORT_PARAM_LEN; \
00801 memcpy(new_buf+offset, "tls", 3); \
00802 offset+=3; \
00803 break; \
00804 case PROTO_SCTP: \
00805 memcpy(new_buf+offset, TRANSPORT_PARAM, \
00806 TRANSPORT_PARAM_LEN); \
00807 offset+=TRANSPORT_PARAM_LEN; \
00808 memcpy(new_buf+offset, "sctp", 4); \
00809 offset+=4; \
00810 break; \
00811 default: \
00812 LM_CRIT("unknown proto %d\n", \
00813 msg->rcv.bind_address->proto); \
00814 } \
00815 }else{ \
00816 \
00817 LM_CRIT("null bind_address\n"); \
00818 }; \
00819 break; \
00820 case SUBST_SND_IP: \
00821 if (send_sock){ \
00822 memcpy(new_buf+offset, send_address_str->s, \
00823 send_address_str->len); \
00824 offset+=send_address_str->len; \
00825 }else{ \
00826 \
00827 LM_CRIT("called with null send_sock\n"); \
00828 }; \
00829 break; \
00830 case SUBST_SND_PORT: \
00831 if (send_sock){ \
00832 memcpy(new_buf+offset, send_port_str->s, \
00833 send_port_str->len); \
00834 offset+=send_port_str->len; \
00835 }else{ \
00836 \
00837 LM_CRIT("called with null send_sock\n"); \
00838 }; \
00839 break; \
00840 case SUBST_SND_ALL: \
00841 if (send_sock){ \
00842 \
00843 memcpy(new_buf+offset, send_address_str->s, \
00844 send_address_str->len); \
00845 offset+=send_address_str->len; \
00846 \
00847 if ((send_sock->port_no!=SIP_PORT) || \
00848 (send_port_str!=&(send_sock->port_no_str))){ \
00849 new_buf[offset]=':'; offset++; \
00850 memcpy(new_buf+offset, send_port_str->s, \
00851 send_port_str->len); \
00852 offset+=send_port_str->len; \
00853 }\
00854 switch(send_sock->proto){ \
00855 case PROTO_NONE: \
00856 case PROTO_UDP: \
00857 break; \
00858 case PROTO_TCP: \
00859 memcpy(new_buf+offset, TRANSPORT_PARAM, \
00860 TRANSPORT_PARAM_LEN); \
00861 offset+=TRANSPORT_PARAM_LEN; \
00862 memcpy(new_buf+offset, "tcp", 3); \
00863 offset+=3; \
00864 break; \
00865 case PROTO_TLS: \
00866 memcpy(new_buf+offset, TRANSPORT_PARAM, \
00867 TRANSPORT_PARAM_LEN); \
00868 offset+=TRANSPORT_PARAM_LEN; \
00869 memcpy(new_buf+offset, "tls", 3); \
00870 offset+=3; \
00871 break; \
00872 case PROTO_SCTP: \
00873 memcpy(new_buf+offset, TRANSPORT_PARAM, \
00874 TRANSPORT_PARAM_LEN); \
00875 offset+=TRANSPORT_PARAM_LEN; \
00876 memcpy(new_buf+offset, "sctp", 4); \
00877 offset+=4; \
00878 break; \
00879 default: \
00880 LM_CRIT("unknown proto %d\n", \
00881 send_sock->proto); \
00882 } \
00883 }else{ \
00884 \
00885 LM_CRIT("null bind_address\n"); \
00886 }; \
00887 break; \
00888 case SUBST_RCV_PROTO: \
00889 if (msg->rcv.bind_address){ \
00890 switch(msg->rcv.bind_address->proto){ \
00891 case PROTO_NONE: \
00892 case PROTO_UDP: \
00893 memcpy(new_buf+offset, "udp", 3); \
00894 offset+=3; \
00895 break; \
00896 case PROTO_TCP: \
00897 memcpy(new_buf+offset, "tcp", 3); \
00898 offset+=3; \
00899 break; \
00900 case PROTO_TLS: \
00901 memcpy(new_buf+offset, "tls", 3); \
00902 offset+=3; \
00903 break; \
00904 case PROTO_SCTP: \
00905 memcpy(new_buf+offset, "sctp", 4); \
00906 offset+=4; \
00907 break; \
00908 default: \
00909 LM_CRIT("unknown proto %d\n", \
00910 msg->rcv.bind_address->proto); \
00911 } \
00912 }else{ \
00913 \
00914 LM_CRIT("called with null send_sock \n"); \
00915 }; \
00916 break; \
00917 case SUBST_SND_PROTO: \
00918 if (send_sock){ \
00919 switch(send_sock->proto){ \
00920 case PROTO_NONE: \
00921 case PROTO_UDP: \
00922 memcpy(new_buf+offset, "udp", 3); \
00923 offset+=3; \
00924 break; \
00925 case PROTO_TCP: \
00926 memcpy(new_buf+offset, "tcp", 3); \
00927 offset+=3; \
00928 break; \
00929 case PROTO_TLS: \
00930 memcpy(new_buf+offset, "tls", 3); \
00931 offset+=3; \
00932 break; \
00933 case PROTO_SCTP: \
00934 memcpy(new_buf+offset, "sctp", 4); \
00935 offset+=4; \
00936 break; \
00937 default: \
00938 LM_CRIT("unknown proto %d\n", \
00939 send_sock->proto); \
00940 } \
00941 }else{ \
00942 \
00943 LM_CRIT("called with null send_sock \n"); \
00944 }; \
00945 break; \
00946 default: \
00947 LM_CRIT("unknown subst type %d\n", \
00948 (subst_l)->u.subst); \
00949 } \
00950 \
00951
00952
00953 if (msg->set_global_address.len)
00954 send_address_str=&(msg->set_global_address);
00955 else
00956 send_address_str=&(send_sock->address_str);
00957 if (msg->set_global_port.len)
00958 send_port_str=&(msg->set_global_port);
00959 else
00960 send_port_str=&(send_sock->port_no_str);
00961
00962
00963 orig=msg->buf;
00964 offset=*new_buf_offs;
00965 s_offset=*orig_offs;
00966
00967 for (t=lumps;t;t=t->next){
00968 switch(t->op){
00969 case LUMP_ADD:
00970 case LUMP_ADD_SUBST:
00971 case LUMP_ADD_OPT:
00972
00973
00974 if ((t->op==LUMP_ADD_OPT) &&
00975 (!lump_check_opt(t, msg, send_sock)))
00976 continue;
00977
00978
00979 for(r=t->before;r;r=r->before){
00980 switch (r->op){
00981 case LUMP_ADD:
00982
00983 memcpy(new_buf+offset, r->u.value, r->len);
00984 offset+=r->len;
00985 break;
00986 case LUMP_ADD_SUBST:
00987 SUBST_LUMP(r);
00988 break;
00989 case LUMP_ADD_OPT:
00990
00991
00992 if (!lump_check_opt(r, msg, send_sock))
00993 goto skip_before;
00994 break;
00995 default:
00996
00997 LM_CRIT("invalid op for data lump (%x)\n", r->op);
00998 }
00999 }
01000 skip_before:
01001
01002 switch(t->op){
01003 case LUMP_ADD:
01004 memcpy(new_buf+offset, t->u.value, t->len);
01005 offset+=t->len;
01006 break;
01007 case LUMP_ADD_SUBST:
01008 SUBST_LUMP(t);
01009 break;
01010 case LUMP_ADD_OPT:
01011
01012 break;
01013 default:
01014
01015 LM_CRIT("unhandled data lump op %d\n", t->op);
01016 }
01017
01018 for(r=t->after;r;r=r->after){
01019 switch (r->op){
01020 case LUMP_ADD:
01021
01022 memcpy(new_buf+offset, r->u.value, r->len);
01023 offset+=r->len;
01024 break;
01025 case LUMP_ADD_SUBST:
01026 SUBST_LUMP(r);
01027 break;
01028 case LUMP_ADD_OPT:
01029
01030
01031 if (!lump_check_opt(r, msg, send_sock))
01032 goto skip_after;
01033 break;
01034 default:
01035
01036 LM_CRIT("invalid op for data lump (%x)\n", r->op);
01037 }
01038 }
01039 skip_after:
01040 break;
01041 case LUMP_NOP:
01042 case LUMP_DEL:
01043
01044 if (s_offset>t->u.offset){
01045 LM_WARN("(%d) overlapped lumps offsets,"
01046 " ignoring(%x, %x)\n", t->op, s_offset,t->u.offset);
01047
01048
01049 break;
01050 }
01051 size=t->u.offset-s_offset;
01052 if (size){
01053 memcpy(new_buf+offset, orig+s_offset,size);
01054 offset+=size;
01055 s_offset+=size;
01056 }
01057
01058 for(r=t->before;r;r=r->before){
01059 switch (r->op){
01060 case LUMP_ADD:
01061
01062 memcpy(new_buf+offset, r->u.value, r->len);
01063 offset+=r->len;
01064 break;
01065 case LUMP_ADD_SUBST:
01066 SUBST_LUMP(r);
01067 break;
01068 case LUMP_ADD_OPT:
01069
01070
01071 if (!lump_check_opt(r, msg, send_sock))
01072 goto skip_nop_before;
01073 break;
01074 default:
01075
01076 LM_CRIT("invalid op for data lump (%x)\n",r->op);
01077 }
01078 }
01079 skip_nop_before:
01080
01081 if (t->op==LUMP_DEL){
01082
01083 s_offset+=t->len;
01084 }
01085
01086 for(r=t->after;r;r=r->after){
01087 switch (r->op){
01088 case LUMP_ADD:
01089
01090 memcpy(new_buf+offset, r->u.value, r->len);
01091 offset+=r->len;
01092 break;
01093 case LUMP_ADD_SUBST:
01094 SUBST_LUMP(r);
01095 break;
01096 case LUMP_ADD_OPT:
01097
01098
01099 if (!lump_check_opt(r, msg, send_sock))
01100 goto skip_nop_after;
01101 break;
01102 default:
01103
01104 LM_CRIT("invalid op for data lump (%x)\n", r->op);
01105 }
01106 }
01107 skip_nop_after:
01108 break;
01109 default:
01110 LM_CRIT("unknown op (%x)\n", t->op);
01111 }
01112 }
01113 *new_buf_offs=offset;
01114 *orig_offs=s_offset;
01115 }
01116
01117
01118
01119
01120
01121 static inline int adjust_clen(struct sip_msg* msg, int body_delta, int proto)
01122 {
01123 struct lump* anchor;
01124 char* clen_buf;
01125 int clen_len;
01126
01127
01128
01129
01130
01131
01132 clen_buf = 0;
01133 anchor=0;
01134
01135
01136 #ifdef USE_TCP
01137 if (proto == PROTO_TCP
01138 #ifdef USE_TLS
01139 || proto == PROTO_TLS
01140 #endif
01141 ) {
01142 if (parse_headers(msg, HDR_CONTENTLENGTH_F, 0)==-1){
01143 LM_ERR("parsing content-length\n");
01144 goto error;
01145 }
01146 if (msg->content_length==0){
01147
01148
01149
01150
01151 anchor=anchor_lump(msg, msg->unparsed-msg->buf, 0,
01152 HDR_CONTENTLENGTH_T);
01153 if (anchor==0){
01154 LM_ERR("cannot set clen anchor\n");
01155 goto error;
01156 }
01157 }
01158 }
01159 #endif
01160
01161
01162 if ((anchor==0) && body_delta){
01163 if (parse_headers(msg, HDR_CONTENTLENGTH_F, 0) == -1) {
01164 LM_ERR("parsing Content-Length\n");
01165 goto error;
01166 }
01167
01168
01169
01170
01171
01172
01173 if ((msg->content_length==0)){
01174
01175
01176
01177
01178 if (proto!=PROTO_UDP){
01179 anchor=anchor_lump(msg, msg->unparsed-msg->buf, 0,
01180 HDR_CONTENTLENGTH_T);
01181 if (anchor==0){
01182 LM_ERR("cannot set clen anchor\n");
01183 goto error;
01184 }
01185 }else{
01186 LM_DBG("the UDP packet has no clen => not adding one \n");
01187 }
01188 }else{
01189
01190 anchor = del_lump( msg, msg->content_length->name.s - msg->buf,
01191 msg->content_length->len, HDR_CONTENTLENGTH_T);
01192 if (anchor==0) {
01193 LM_ERR("can't remove original Content-Length\n");
01194 goto error;
01195 }
01196 }
01197 }
01198
01199 if (anchor){
01200 clen_buf = clen_builder(msg, &clen_len, body_delta);
01201 if (!clen_buf) goto error;
01202 if (insert_new_lump_after(anchor, clen_buf, clen_len,
01203 HDR_CONTENTLENGTH_T) == 0)
01204 goto error;
01205 }
01206
01207 return 0;
01208 error:
01209 if (clen_buf) pkg_free(clen_buf);
01210 return -1;
01211 }
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221 #define ROUTE_STR "Route: "
01222 #define ROUTE_LEN (sizeof(ROUTE_STR)-1)
01223 static inline int insert_path_as_route(struct sip_msg* msg, str* path)
01224 {
01225 struct lump *anchor;
01226 char *route;
01227 struct hdr_field *hf, *last_via=0;
01228
01229 for (hf = msg->headers; hf; hf = hf->next) {
01230 if (hf->type == HDR_ROUTE_T) {
01231 break;
01232 } else if (hf->type == HDR_VIA_T) {
01233 last_via = hf;
01234 }
01235 }
01236 if (hf) {
01237
01238 anchor = anchor_lump(msg, hf->name.s - msg->buf, 0, 0);
01239 } else if(last_via) {
01240 if (last_via->next) {
01241
01242 anchor = anchor_lump(msg, last_via->next->name.s - msg->buf, 0, 0);
01243 } else {
01244
01245 anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, 0);
01246 }
01247 } else {
01248
01249 anchor = anchor_lump(msg, msg->headers->name.s - msg->buf, 0, 0);
01250 }
01251
01252 if (anchor == 0) {
01253 LM_ERR("failed to get anchor\n");
01254 return -1;
01255 }
01256
01257 route = pkg_malloc(ROUTE_LEN + path->len + CRLF_LEN);
01258 if (!route) {
01259 LM_ERR("out of pkg memory\n");
01260 return -1;
01261 }
01262 memcpy(route, ROUTE_STR, ROUTE_LEN);
01263 memcpy(route + ROUTE_LEN, path->s, path->len);
01264 memcpy(route + ROUTE_LEN + path->len, CRLF, CRLF_LEN);
01265
01266 if (insert_new_lump_before(anchor, route, ROUTE_LEN + path->len + CRLF_LEN, 0) == 0) {
01267 LM_ERR("failed to insert lump\n");
01268 return -1;
01269 }
01270
01271 return 0;
01272 }
01273
01274
01275 char * build_req_buf_from_sip_req( struct sip_msg* msg,
01276 unsigned int *returned_len,
01277 struct socket_info* send_sock, int proto,
01278 unsigned int flags)
01279 {
01280 unsigned int len, new_len, received_len, rport_len, uri_len, via_len, body_delta;
01281 char *line_buf, *received_buf, *rport_buf, *new_buf, *buf, *id_buf;
01282 unsigned int offset, s_offset, size, id_len;
01283 struct lump *anchor, *via_insert_param;
01284 str branch, extra_params;
01285 struct hostport hp;
01286
01287 id_buf=0;
01288 id_len=0;
01289 via_insert_param=0;
01290 extra_params.len=0;
01291 extra_params.s=0;
01292 uri_len=0;
01293 buf=msg->buf;
01294 len=msg->len;
01295 received_len=0;
01296 rport_len=0;
01297 new_buf=0;
01298 received_buf=0;
01299 rport_buf=0;
01300 line_buf=0;
01301
01302 if (msg->path_vec.len) {
01303 if (insert_path_as_route(msg, &msg->path_vec) < 0) {
01304 LM_ERR("adding path lumps failed\n");
01305 goto error;
01306 }
01307 }
01308
01309
01310
01311
01312 body_delta = lumps_len(msg, msg->body_lumps, send_sock);
01313 if (adjust_clen(msg, body_delta, proto) < 0) {
01314 LM_ERR("failed to adjust Content-Length\n");
01315 goto error;
01316 }
01317
01318 if (flags&MSG_TRANS_NOVIA_FLAG)
01319 goto build_msg;
01320
01321 #ifdef USE_TCP
01322
01323 if (msg->rcv.proto==PROTO_TCP
01324 #ifdef USE_TLS
01325 || msg->rcv.proto==PROTO_TLS
01326 #endif
01327 ){
01328 if ((id_buf=id_builder(msg, &id_len))==0){
01329 LM_ERR("id_builder failed\n");
01330 goto error;
01331
01332 }
01333 LM_DBG("id added: <%.*s>, rcv proto=%d\n",
01334 (int)id_len, id_buf, msg->rcv.proto);
01335 extra_params.s=id_buf;
01336 extra_params.len=id_len;
01337 }
01338 #endif
01339
01340
01341 if(msg->msg_flags&FL_FORCE_LOCAL_RPORT) {
01342 id_buf=extra_params.s;
01343 id_len=extra_params.len;
01344 extra_params.len += RPORT_LEN-1;
01345
01346
01347 extra_params.s = (char*)pkg_malloc(extra_params.len+1);
01348 if(extra_params.s==0) {
01349 LM_ERR("extra params building failed\n");
01350 if (id_buf) pkg_free(id_buf);
01351 goto error;
01352 }
01353
01354 if(id_buf!=0) {
01355 memcpy(extra_params.s, id_buf, id_len);
01356 pkg_free(id_buf);
01357 }
01358 memcpy(extra_params.s+id_len, RPORT, RPORT_LEN-1);
01359 extra_params.s[extra_params.len]='\0';
01360 LM_DBG("extra param added: <%.*s>\n",extra_params.len, extra_params.s);
01361 }
01362
01363 branch.s=msg->add_to_branch_s;
01364 branch.len=msg->add_to_branch_len;
01365 set_hostport(&hp, msg);
01366 line_buf = via_builder( &via_len, send_sock, &branch,
01367 extra_params.len?&extra_params:0, proto, &hp);
01368 if (!line_buf){
01369 LM_ERR("no via received!\n");
01370 goto error00;
01371 }
01372
01373
01374
01375
01376
01377 if ( msg->via1->rport || (msg->msg_flags&FL_FORCE_RPORT) ||
01378 received_test(msg) ) {
01379 if ((received_buf=received_builder(msg,&received_len))==0){
01380 LM_ERR("received_builder failed\n");
01381 goto error01;
01382 }
01383 }
01384
01385
01386
01387
01388
01389
01390 if ((msg->msg_flags&FL_FORCE_RPORT)||
01391 (msg->via1->rport )){
01392 if ((rport_buf=rport_builder(msg, &rport_len))==0){
01393 LM_ERR("rport_builder failed\n");
01394 goto error01;
01395 }
01396 }
01397
01398
01399
01400
01401 anchor=anchor_lump(msg, msg->via1->hdr.s-buf, 0, HDR_VIA_T);
01402 if (anchor==0) goto error01;
01403 if (insert_new_lump_before(anchor, line_buf, via_len, HDR_VIA_T)==0)
01404 goto error01;
01405
01406
01407 if (msg->via1->params.s){
01408 size= msg->via1->params.s-msg->via1->hdr.s-1;
01409
01410 }else{
01411 size= msg->via1->host.s-msg->via1->hdr.s+msg->via1->host.len;
01412 if (msg->via1->port!=0){
01413
01414 size += msg->via1->port_str.len + 1;
01415 }
01416 }
01417
01418
01419 if (received_len){
01420 if (msg->via1->received){
01421 via_insert_param=del_lump(msg,
01422 msg->via1->received->start-buf-1,
01423 msg->via1->received->size+1, HDR_VIA_T);
01424 }else if (via_insert_param==0){
01425 via_insert_param=anchor_lump(msg,
01426 msg->via1->hdr.s-buf+size,0, HDR_VIA_T);
01427 }
01428 if (via_insert_param==0) goto error02;
01429 if (insert_new_lump_after(via_insert_param, received_buf, received_len,
01430 HDR_VIA_T) ==0 ) goto error02;
01431 }
01432
01433 if (rport_len){
01434 if (msg->via1->rport){
01435 via_insert_param=del_lump(msg,
01436 msg->via1->rport->start-buf-1,
01437 msg->via1->rport->size+1 , HDR_VIA_T);
01438 }else if (via_insert_param==0){
01439
01440 via_insert_param=anchor_lump(msg,
01441 msg->via1->hdr.s-buf+size,0, HDR_VIA_T);
01442 }
01443 if (via_insert_param==0) goto error03;
01444 if (insert_new_lump_after(via_insert_param, rport_buf, rport_len,
01445 HDR_VIA_T) ==0 )
01446 goto error03;
01447 }
01448
01449 build_msg:
01450
01451 new_len=len+body_delta+lumps_len(msg, msg->add_rm, send_sock);
01452 #ifdef XL_DEBUG
01453 LM_DBG("new_len(%d)=len(%d)+lumps_len\n", new_len, len);
01454 #endif
01455
01456 if (msg->new_uri.s){
01457 uri_len=msg->new_uri.len;
01458 new_len=new_len-msg->first_line.u.request.uri.len+uri_len;
01459 }
01460 if (flags&MSG_TRANS_SHM_FLAG)
01461 new_buf=(char*)shm_malloc(new_len+1);
01462 else
01463 new_buf=(char*)pkg_malloc(new_len+1);
01464 if (new_buf==0){
01465 ser_error=E_OUT_OF_MEM;
01466 LM_ERR("out of pkg memory\n");
01467 goto error00;
01468 }
01469
01470 offset=s_offset=0;
01471 if (msg->new_uri.s){
01472
01473 size=msg->first_line.u.request.uri.s-buf;
01474 memcpy(new_buf, buf, size);
01475 offset+=size;
01476 s_offset+=size;
01477
01478 memcpy(new_buf+offset, msg->new_uri.s, uri_len);
01479 offset+=uri_len;
01480 s_offset+=msg->first_line.u.request.uri.len;
01481 }
01482 new_buf[new_len]=0;
01483
01484 process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, send_sock);
01485 process_lumps(msg, msg->body_lumps, new_buf, &offset, &s_offset,send_sock);
01486
01487 memcpy(new_buf+offset, buf+s_offset, len-s_offset);
01488 new_buf[new_len]=0;
01489
01490 *returned_len=new_len;
01491
01492 if (extra_params.s) pkg_free(extra_params.s);
01493 return new_buf;
01494
01495 error01:
01496 if (line_buf) pkg_free(line_buf);
01497 error02:
01498 if (received_buf) pkg_free(received_buf);
01499 error03:
01500 if (rport_buf) pkg_free(rport_buf);
01501 error00:
01502 if (extra_params.s) pkg_free(extra_params.s);
01503 error:
01504 *returned_len=0;
01505 return 0;
01506 }
01507
01508
01509
01510 char * build_res_buf_from_sip_res( struct sip_msg* msg,
01511 unsigned int *returned_len)
01512 {
01513 unsigned int new_len, via_len, body_delta, len;
01514 char *new_buf, *buf;
01515 unsigned offset, s_offset, via_offset;
01516
01517 buf=msg->buf;
01518 len=msg->len;
01519 new_buf=0;
01520
01521 if (msg->via1->next) {
01522 via_len=msg->via1->bsize;
01523 via_offset=msg->h_via1->body.s-buf;
01524 } else {
01525 via_len=msg->h_via1->len;
01526 via_offset=msg->h_via1->name.s-buf;
01527 }
01528
01529
01530
01531
01532 body_delta = lumps_len(msg, msg->body_lumps, 0);
01533 if (adjust_clen(msg, body_delta, (msg->via2? msg->via2->proto:PROTO_UDP))
01534 < 0) {
01535 LM_ERR("failed to adjust Content-Length\n");
01536 goto error;
01537 }
01538
01539
01540 if (del_lump( msg, via_offset, via_len, HDR_VIA_T)==0){
01541 LM_ERR("failed to remove first via\n");
01542 goto error;
01543 }
01544
01545 new_len=len+body_delta+lumps_len(msg, msg->add_rm, 0);
01546
01547
01548 LM_DBG(" old size: %d, new size: %d\n", len, new_len);
01549 new_buf=(char*)pkg_malloc(new_len+1);
01550
01551 if (new_buf==0){
01552 LM_ERR("out of pkg mem\n");
01553 goto error;
01554 }
01555 new_buf[new_len]=0;
01556 offset=s_offset=0;
01557
01558 process_lumps(msg, msg->add_rm, new_buf, &offset, &s_offset, 0);
01559 process_lumps(msg, msg->body_lumps, new_buf, &offset, &s_offset, 0);
01560
01561 memcpy(new_buf+offset,
01562 buf+s_offset,
01563 len-s_offset);
01564
01565 if ( msg->first_line.u.reply.statuscode==503 )
01566 new_buf[(int)(msg->first_line.u.reply.status.s-msg->buf)+2] = '0';
01567
01568 LM_DBG("copied size: orig:%d, new: %d, rest: %d"
01569 " msg=\n%s\n", s_offset, offset, len-s_offset, new_buf);
01570
01571 *returned_len=new_len;
01572 return new_buf;
01573 error:
01574 *returned_len=0;
01575 return 0;
01576 }
01577
01578
01579 char * build_res_buf_from_sip_req( unsigned int code, str *text ,str *new_tag,
01580 struct sip_msg* msg, unsigned int *returned_len, struct bookmark *bmark)
01581 {
01582 char *buf, *p, *received_buf, *rport_buf, *warning_buf, *content_len_buf, *after_body, *totags;
01583 unsigned int len, foo, received_len, rport_len, warning_len, content_len_len;
01584 struct hdr_field *hdr;
01585 struct lump_rpl *lump, *body;
01586 int i;
01587 str to_tag;
01588
01589 body = 0;
01590 buf=0;
01591 to_tag.s = 0;
01592 to_tag.len = 0;
01593 received_buf=rport_buf=warning_buf=content_len_buf=0;
01594 received_len=rport_len=warning_len=content_len_len=0;
01595
01596
01597
01598
01599
01600 if (parse_headers( msg, HDR_EOH_F, 0 )==-1) {
01601 LM_ERR("parse_headers failed\n");
01602 goto error00;
01603 }
01604
01605
01606 len = 0;
01607
01608
01609
01610 if ((received_test(msg)) || (msg->msg_flags&FL_FORCE_RPORT)) {
01611 if ((received_buf=received_builder(msg,&received_len))==0) {
01612 LM_ERR("received_builder failed\n");
01613 goto error00;
01614 }
01615 }
01616
01617 if ( (msg->msg_flags&FL_FORCE_RPORT)||
01618 (msg->via1->rport )){
01619 if ((rport_buf=rport_builder(msg, &rport_len))==0){
01620 LM_ERR("rport_builder failed\n");
01621 goto error01;
01622 }
01623 if (msg->via1->rport)
01624 len -= msg->via1->rport->size+1;
01625 }
01626
01627
01628 len += SIP_VERSION_LEN + 1 + 3 + 1 +
01629 text->len + CRLF_LEN;
01630
01631 for ( hdr=msg->headers ; hdr ; hdr=hdr->next ) {
01632 switch (hdr->type) {
01633 case HDR_TO_T:
01634 if (new_tag && new_tag->len) {
01635 to_tag=get_to(msg)->tag_value;
01636 if (to_tag.len )
01637 len+=new_tag->len-to_tag.len;
01638 else
01639 len+=new_tag->len+TOTAG_TOKEN_LEN;
01640 }
01641 len += hdr->len;
01642 break;
01643 case HDR_VIA_T:
01644
01645 len+=(hdr->body.s+hdr->body.len)-hdr->name.s+CRLF_LEN;
01646 if (hdr==msg->h_via1) len += received_len+rport_len;
01647 break;
01648 case HDR_RECORDROUTE_T:
01649
01650 if (code<180 || code>=300)
01651 break;
01652 case HDR_FROM_T:
01653 case HDR_CALLID_T:
01654 case HDR_CSEQ_T:
01655
01656 len += hdr->len;
01657 break;
01658 default:
01659
01660 ;
01661 }
01662 }
01663
01664 for(lump=msg->reply_lump;lump;lump=lump->next) {
01665 len += lump->text.len;
01666 if (lump->flags&LUMP_RPL_BODY)
01667 body = lump;
01668 }
01669
01670 if (server_signature)
01671 len += server_header.len + CRLF_LEN;
01672
01673 if (sip_warning) {
01674 warning_buf = warning_builder(msg,&warning_len);
01675 if (warning_buf) len += warning_len + CRLF_LEN;
01676 else LM_WARN("warning skipped -- too big\n");
01677 }
01678
01679 if (body) {
01680 content_len_buf = int2str(body->text.len, (int*)&content_len_len);
01681 len += CONTENT_LENGTH_LEN + content_len_len + CRLF_LEN;
01682 } else {
01683 len += CONTENT_LENGTH_LEN + 1 + CRLF_LEN;
01684 }
01685
01686 len += CRLF_LEN;
01687
01688
01689 buf = (char*) pkg_malloc( len+1 );
01690 if (!buf)
01691 {
01692 LM_ERR("out of pkg memory ; needs %d\n",len);
01693 goto error01;
01694 }
01695
01696
01697 p=buf;
01698
01699 memcpy( p , SIP_VERSION , SIP_VERSION_LEN );
01700 p += SIP_VERSION_LEN;
01701 *(p++) = ' ' ;
01702
01703 for ( i=2 , foo = code ; i>=0 ; i-- , foo=foo/10 )
01704 *(p+i) = '0' + foo - ( foo/10 )*10;
01705 p += 3;
01706 *(p++) = ' ' ;
01707 memcpy( p , text->s , text->len );
01708 p += text->len;
01709 memcpy( p, CRLF, CRLF_LEN );
01710 p+=CRLF_LEN;
01711
01712 for ( hdr=msg->headers ; hdr ; hdr=hdr->next ) {
01713 switch (hdr->type)
01714 {
01715 case HDR_VIA_T:
01716 if (hdr==msg->h_via1){
01717 if (rport_buf){
01718 if (msg->via1->rport){
01719
01720 append_str( p, hdr->name.s ,
01721 msg->via1->rport->start-hdr->name.s-1);
01722
01723 append_str(p, rport_buf, rport_len);
01724
01725 append_str(p, msg->via1->rport->start+
01726 msg->via1->rport->size,
01727 hdr->body.s+hdr->body.len-
01728 msg->via1->rport->start-
01729 msg->via1->rport->size);
01730 }else{
01731
01732 append_str( p, hdr->name.s ,
01733 (hdr->body.s+hdr->body.len)-hdr->name.s);
01734 append_str(p, rport_buf, rport_len);
01735 }
01736 }else{
01737
01738 append_str( p, hdr->name.s ,
01739 (hdr->body.s+hdr->body.len)-hdr->name.s);
01740 }
01741 if (received_buf)
01742 append_str( p, received_buf, received_len);
01743 }else{
01744
01745 append_str( p, hdr->name.s,
01746 (hdr->body.s+hdr->body.len)-hdr->name.s);
01747 }
01748 append_str( p, CRLF,CRLF_LEN);
01749 break;
01750 case HDR_RECORDROUTE_T:
01751
01752 if (code<180 || code>=300) break;
01753 append_str(p, hdr->name.s, hdr->len);
01754 break;
01755 case HDR_TO_T:
01756 if (new_tag && new_tag->len){
01757 if (to_tag.len ) {
01758
01759 append_str( p, hdr->name.s, to_tag.s-hdr->name.s);
01760
01761 bmark->to_tag_val.s=p;
01762 bmark->to_tag_val.len=new_tag->len;
01763 append_str( p, new_tag->s,new_tag->len);
01764
01765 append_str( p, to_tag.s+to_tag.len,
01766 hdr->name.s+hdr->len-(to_tag.s+to_tag.len));
01767 }else{
01768 after_body=hdr->body.s+hdr->body.len;
01769 append_str( p, hdr->name.s, after_body-hdr->name.s);
01770 append_str(p, TOTAG_TOKEN, TOTAG_TOKEN_LEN);
01771 bmark->to_tag_val.s=p;
01772 bmark->to_tag_val.len=new_tag->len;
01773 append_str( p, new_tag->s,new_tag->len);
01774 append_str( p, after_body,
01775 hdr->name.s+hdr->len-after_body);
01776 }
01777 break;
01778 }
01779 totags=((struct to_body*)(hdr->parsed))->tag_value.s;
01780 if (totags) {
01781 bmark->to_tag_val.s=p+(totags-hdr->name.s);
01782 bmark->to_tag_val.len=
01783 ((struct to_body*)(hdr->parsed))->tag_value.len;
01784 } else {
01785 bmark->to_tag_val.s = NULL;
01786 bmark->to_tag_val.len = 0;
01787 }
01788 case HDR_FROM_T:
01789 case HDR_CALLID_T:
01790 case HDR_CSEQ_T:
01791 append_str(p, hdr->name.s, hdr->len);
01792 break;
01793 default:
01794
01795 ;
01796 }
01797 }
01798
01799 for(lump=msg->reply_lump;lump;lump=lump->next)
01800 if (lump->flags&LUMP_RPL_HDR){
01801 memcpy(p,lump->text.s,lump->text.len);
01802 p += lump->text.len;
01803 }
01804
01805 if (server_signature) {
01806 append_str( p, server_header.s, server_header.len);
01807 append_str( p, CRLF, CRLF_LEN );
01808 }
01809
01810 if (content_len_len) {
01811 append_str( p, CONTENT_LENGTH, CONTENT_LENGTH_LEN);
01812 append_str( p, content_len_buf, content_len_len );
01813 append_str( p, CRLF, CRLF_LEN );
01814 } else {
01815 append_str( p, CONTENT_LENGTH"0"CRLF,CONTENT_LENGTH_LEN+1+CRLF_LEN);
01816 }
01817
01818 if (warning_buf) {
01819 append_str( p, warning_buf, warning_len );
01820 append_str( p, CRLF, CRLF_LEN );
01821 }
01822
01823 memcpy( p, CRLF, CRLF_LEN );
01824 p+=CRLF_LEN;
01825
01826 if (body) {
01827 append_str( p, body->text.s, body->text.len );
01828 }
01829
01830 if (len!=(unsigned long)(p-buf))
01831 LM_CRIT("diff len=%d p-buf=%d\n", len, (int)(p-buf));
01832
01833 *(p) = 0;
01834 *returned_len = len;
01835
01836
01837
01838 if (received_buf) pkg_free(received_buf);
01839 if (rport_buf) pkg_free(rport_buf);
01840 return buf;
01841
01842 error01:
01843 if (received_buf) pkg_free(received_buf);
01844 if (rport_buf) pkg_free(rport_buf);
01845 error00:
01846 *returned_len=0;
01847 return 0;
01848 }
01849
01850
01851
01852
01853
01854
01855 int branch_builder( unsigned int hash_index,
01856
01857 unsigned int label, char * char_v,
01858 int branch,
01859 char *branch_str, int *len )
01860 {
01861
01862 char *begin;
01863 int size;
01864
01865
01866 size=MAX_BRANCH_PARAM_LEN;
01867 begin=branch_str;
01868 *len=0;
01869
01870 memcpy(begin, MCOOKIE, MCOOKIE_LEN );
01871 size-=MCOOKIE_LEN;begin+=MCOOKIE_LEN;
01872
01873 if (int2reverse_hex( &begin, &size, hash_index)==-1)
01874 return 0;
01875
01876 if (size) {
01877 *begin=BRANCH_SEPARATOR;
01878 begin++; size--;
01879 } else return 0;
01880
01881
01882 if (char_v) {
01883 if (memcpy(begin,char_v,MD5_LEN)) {
01884 begin+=MD5_LEN; size-=MD5_LEN;
01885 } else return 0;
01886 } else {
01887 if (int2reverse_hex( &begin, &size, label )==-1)
01888 return 0;
01889 }
01890
01891 if (size) {
01892 *begin=BRANCH_SEPARATOR;
01893 begin++; size--;
01894 } else return 0;
01895
01896 if (int2reverse_hex( &begin, &size, branch)==-1)
01897 return 0;
01898
01899 *len=MAX_BRANCH_PARAM_LEN-size;
01900 return size;
01901
01902 }
01903
01904
01905 char* via_builder( unsigned int *len,
01906 struct socket_info* send_sock,
01907 str* branch, str* extra_params, int proto, struct hostport* hp)
01908 {
01909 unsigned int via_len, extra_len;
01910 char *line_buf;
01911 int max_len, local_via_len=MY_VIA_LEN;
01912 str* address_str;
01913 str* port_str;
01914
01915
01916 if ( hp && hp->host->len)
01917 address_str=hp->host;
01918 else
01919 address_str=&(send_sock->address_str);
01920 if (hp && hp->port->len)
01921 port_str=hp->port;
01922 else
01923 port_str=&(send_sock->port_no_str);
01924
01925 max_len=local_via_len+address_str->len
01926 +2
01927 +1 +port_str->len
01928 +(branch?(MY_BRANCH_LEN+branch->len):0)
01929 +(extra_params?extra_params->len:0)
01930 +CRLF_LEN+1;
01931 line_buf=pkg_malloc( max_len );
01932 if (line_buf==0){
01933 ser_error=E_OUT_OF_MEM;
01934 LM_ERR("out of pkg memory\n");
01935 return 0;
01936 }
01937
01938 extra_len=0;
01939
01940 memcpy(line_buf, MY_VIA, local_via_len);
01941 if (proto==PROTO_UDP){
01942
01943 }else if (proto==PROTO_TCP){
01944 memcpy(line_buf+local_via_len-4, "TCP ", 4);
01945 }else if (proto==PROTO_TLS){
01946 memcpy(line_buf+local_via_len-4, "TLS ", 4);
01947 }else if(proto==PROTO_SCTP){
01948 memcpy(line_buf+local_via_len-4, "SCTP ", 5);
01949 local_via_len++;
01950 }else{
01951 LM_CRIT("unknown proto %d\n", proto);
01952 return 0;
01953 }
01954
01955 via_len=local_via_len+address_str->len;
01956
01957 memcpy(line_buf+local_via_len+extra_len, address_str->s, address_str->len);
01958 if ((send_sock->port_no!=SIP_PORT) || (port_str!=&send_sock->port_no_str)){
01959 line_buf[via_len]=':'; via_len++;
01960 memcpy(line_buf+via_len, port_str->s, port_str->len);
01961 via_len+=port_str->len;
01962 }
01963
01964 if (branch){
01965 memcpy(line_buf+via_len, MY_BRANCH, MY_BRANCH_LEN );
01966 via_len+=MY_BRANCH_LEN;
01967 memcpy(line_buf+via_len, branch->s, branch->len );
01968 via_len+=branch->len;
01969 }
01970
01971 if (extra_params){
01972 memcpy(line_buf+via_len, extra_params->s, extra_params->len);
01973 via_len+=extra_params->len;
01974 }
01975
01976 memcpy(line_buf+via_len, CRLF, CRLF_LEN);
01977 via_len+=CRLF_LEN;
01978 line_buf[via_len]=0;
01979
01980 *len = via_len;
01981 return line_buf;
01982 }