... | ... |
@@ -26,8 +26,10 @@ |
26 | 26 |
* |
27 | 27 |
* History: |
28 | 28 |
* ------- |
29 |
- * 2001-01-23 support for determination of outbound interface added : |
|
29 |
+ * 2003-01-23 support for determination of outbound interface added : |
|
30 | 30 |
* get_out_socket (jiri) |
31 |
+ * 2003-01-24 reply to rport support added, contributed by |
|
32 |
+ * Maxim Sobolev <sobomax@FreeBSD.org> and modified by andrei |
|
31 | 33 |
* |
32 | 34 |
*/ |
33 | 35 |
|
... | ... |
@@ -153,7 +155,7 @@ struct socket_info* get_send_socket(union sockaddr_union* to, int proto) |
153 | 155 |
#ifdef USE_TCP |
154 | 156 |
if (proto==PROTO_TCP){ |
155 | 157 |
/* on tcp just use the "main address", we don't really now the |
156 |
- * sending address (we can find it out, but we'll find also to see |
|
158 |
+ * sending address (we can find it out, but we'll need also to see |
|
157 | 159 |
* if we listen on it, and if yes on which port -> too complicated*/ |
158 | 160 |
switch(to->s.sa_family){ |
159 | 161 |
case AF_INET: send_sock=sendipv4_tcp; |
... | ... |
@@ -288,10 +290,6 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p, int proto) |
288 | 290 |
if it is turned on, we don't care about reboot; we simply put a simple |
289 | 291 |
value in there; better for performance |
290 | 292 |
*/ |
291 |
- |
|
292 |
-#ifdef USE_TCP |
|
293 |
- if (msg->rcv.proto==PROTO_TCP) id=msg->rcv.proto_reserved1; |
|
294 |
-#endif |
|
295 | 293 |
if (syn_branch ) { |
296 | 294 |
*msg->add_to_branch_s='0'; |
297 | 295 |
msg->add_to_branch_len=1; |
... | ... |
@@ -367,19 +365,28 @@ int update_sock_struct_from_via( union sockaddr_union* to, |
367 | 365 |
{ |
368 | 366 |
struct hostent* he; |
369 | 367 |
str* name; |
368 |
+ int err; |
|
370 | 369 |
unsigned short port; |
371 | 370 |
|
372 |
- |
|
371 |
+ port=0; |
|
372 |
+ if (via->rport && via->rport->value.s){ |
|
373 |
+ port=str2s(via->rport->value.s, via->rport->value.len, &err); |
|
374 |
+ if (err){ |
|
375 |
+ LOG(L_NOTICE, "ERROR: forward_reply: bad rport value(%.*s)\n", |
|
376 |
+ via->rport->value.len, via->rport->value.s); |
|
377 |
+ port=0; |
|
378 |
+ } |
|
379 |
+ } |
|
373 | 380 |
if (via->received){ |
374 | 381 |
DBG("update_sock_struct_from_via: using 'received'\n"); |
375 | 382 |
name=&(via->received->value); |
376 | 383 |
/* making sure that we won't do SRV lookup on "received" |
377 | 384 |
* (possible if no DNS_IP_HACK is used)*/ |
378 |
- port=via->port?via->port:SIP_PORT; |
|
385 |
+ if (port==0) port=via->port?via->port:SIP_PORT; |
|
379 | 386 |
}else{ |
380 | 387 |
DBG("update_sock_struct_from_via: using via host\n"); |
381 | 388 |
name=&(via->host); |
382 |
- port=via->port; |
|
389 |
+ if (port==0) port=via->port; |
|
383 | 390 |
} |
384 | 391 |
/* we do now a malloc/memcpy because gethostbyname loves \0-terminated |
385 | 392 |
strings; -jiri |
... | ... |
@@ -397,6 +404,7 @@ int update_sock_struct_from_via( union sockaddr_union* to, |
397 | 404 |
name->len, name->s); |
398 | 405 |
return -1; |
399 | 406 |
} |
407 |
+ |
|
400 | 408 |
hostent2su(to, he, 0, htons(port)); |
401 | 409 |
return 1; |
402 | 410 |
} |
... | ... |
@@ -413,7 +421,6 @@ int forward_reply(struct sip_msg* msg) |
413 | 421 |
int proto; |
414 | 422 |
#ifdef USE_TCP |
415 | 423 |
char* s; |
416 |
- char* p; |
|
417 | 424 |
int len; |
418 | 425 |
int id; |
419 | 426 |
#endif |
... | ... |
@@ -479,24 +486,13 @@ int forward_reply(struct sip_msg* msg) |
479 | 486 |
#ifdef USE_TCP |
480 | 487 |
else if (proto==PROTO_TCP){ |
481 | 488 |
id=0; |
482 |
- /* find id in branch if it exists */ |
|
483 |
- if ((msg->via1->branch)&&(msg->via1->branch->value.len>MCOOKIE_LEN) && |
|
484 |
- (memcmp(msg->via1->branch->value.s, MCOOKIE, MCOOKIE_LEN)==0)){ |
|
485 |
- DBG("forward_reply: found branch\n"); |
|
486 |
- s=msg->via1->branch->value.s+MCOOKIE_LEN; |
|
487 |
- len=msg->via1->branch->value.len-MCOOKIE_LEN; |
|
488 |
- for (p=s; p<s+len && *p!=BRANCH_SEPARATOR; p++); |
|
489 |
- p++; |
|
490 |
- for(;p<s+len && *p!=BRANCH_SEPARATOR; p++); |
|
491 |
- p++; |
|
492 |
- if (p<s+len){ |
|
493 |
- /* we found the second BRANCH_SEPARATOR, p points after it */ |
|
494 |
- len-=(int)(p-s); |
|
495 |
- id=reverse_hex2int(p, len); |
|
496 |
- DBG("forward_reply: id= %x\n", id); |
|
497 |
- }else{ |
|
498 |
- DBG("forward_reply: no id in branch\n"); |
|
499 |
- } |
|
489 |
+ /* find id in i param if it exists */ |
|
490 |
+ if (msg->via1->i&&msg->via1->i->value.s){ |
|
491 |
+ s=msg->via1->i->value.s; |
|
492 |
+ len=msg->via1->i->value.len; |
|
493 |
+ DBG("forward_reply: i=%.*s\n",len, s); |
|
494 |
+ id=reverse_hex2int(s, len); |
|
495 |
+ DBG("forward_reply: id= %x\n", id); |
|
500 | 496 |
} |
501 | 497 |
|
502 | 498 |
if (tcp_send(new_buf, new_len, to, id)==-1) |
... | ... |
@@ -32,6 +32,8 @@ |
32 | 32 |
* 2003-01-23 added rport patches, contributed by |
33 | 33 |
* Maxim Sobolev <sobomax@FreeBSD.org> and heavily modified by me |
34 | 34 |
* (andrei) |
35 |
+ * 2003-01-24 added i param to via of outgoing requests (used by tcp), |
|
36 |
+ * modified via_builder params (andrei) |
|
35 | 37 |
* |
36 | 38 |
*/ |
37 | 39 |
|
... | ... |
@@ -240,6 +242,37 @@ char* rport_builder(struct sip_msg *msg, unsigned int *rport_len) |
240 | 242 |
|
241 | 243 |
|
242 | 244 |
|
245 |
+char* id_builder(struct sip_msg* msg, unsigned int *id_len) |
|
246 |
+{ |
|
247 |
+ char* buf; |
|
248 |
+ int len, value_len; |
|
249 |
+ char revhex[sizeof(int)*2]; |
|
250 |
+ char* p; |
|
251 |
+ int size; |
|
252 |
+ |
|
253 |
+ size=sizeof(int)*2; |
|
254 |
+ p=&revhex[0]; |
|
255 |
+ if (int2reverse_hex(&p, &size, msg->rcv.proto_reserved1)==-1){ |
|
256 |
+ LOG(L_CRIT, "BUG: id_builder: not enough space for id\n"); |
|
257 |
+ return 0; |
|
258 |
+ } |
|
259 |
+ value_len=p-&revhex[0]; |
|
260 |
+ len=ID_PARAM_LEN+value_len+1; /* place for ending \0 */ |
|
261 |
+ buf=pkg_malloc(sizeof(char)*len); |
|
262 |
+ if (buf==0){ |
|
263 |
+ ser_error=E_OUT_OF_MEM; |
|
264 |
+ LOG(L_ERR, "ERROR: rport_builder: out of memory\n"); |
|
265 |
+ return 0; |
|
266 |
+ } |
|
267 |
+ memcpy(buf, ID_PARAM, ID_PARAM_LEN); |
|
268 |
+ memcpy(buf+ID_PARAM_LEN, revhex, value_len); |
|
269 |
+ buf[len]=0; /* null terminate it */ |
|
270 |
+ *id_len=len; |
|
271 |
+ return buf; |
|
272 |
+} |
|
273 |
+ |
|
274 |
+ |
|
275 |
+ |
|
243 | 276 |
/* computes the "unpacked" len of a lump list, |
244 | 277 |
code moved from build_req_from_req */ |
245 | 278 |
static inline int lumps_len(struct lump* l) |
... | ... |
@@ -436,7 +469,19 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg, |
436 | 469 |
unsigned int offset, s_offset, size; |
437 | 470 |
struct lump* anchor; |
438 | 471 |
int r; |
439 |
- |
|
472 |
+ str branch; |
|
473 |
+ str extra_params; |
|
474 |
+ |
|
475 |
+#ifdef USE_TCP |
|
476 |
+ char* id_buf; |
|
477 |
+ int id_len; |
|
478 |
+ |
|
479 |
+ |
|
480 |
+ id_buf=0; |
|
481 |
+ id_len=0; |
|
482 |
+#endif |
|
483 |
+ extra_params.len=0; |
|
484 |
+ extra_params.s=0; |
|
440 | 485 |
uri_len=0; |
441 | 486 |
orig=msg->orig; |
442 | 487 |
buf=msg->buf; |
... | ... |
@@ -446,10 +491,25 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg, |
446 | 491 |
new_buf=0; |
447 | 492 |
received_buf=0; |
448 | 493 |
rport_buf=0; |
494 |
+ line_buf=0; |
|
449 | 495 |
|
450 |
- |
|
451 |
- line_buf = via_builder( &via_len, send_sock, |
|
452 |
- msg->add_to_branch_s, msg->add_to_branch_len, proto); |
|
496 |
+ |
|
497 |
+#ifdef USE_TCP |
|
498 |
+ /* add id if tcp */ |
|
499 |
+ if (msg->rcv.proto==PROTO_TCP){ |
|
500 |
+ if ((id_buf=id_builder(msg, &id_len))==0){ |
|
501 |
+ LOG(L_ERR, "ERROR: build_req_buf_from_sip_req:" |
|
502 |
+ " id_builder failed\n"); |
|
503 |
+ goto error01; /* free everything */ |
|
504 |
+ } |
|
505 |
+ extra_params.s=id_buf; |
|
506 |
+ extra_params.len=id_len; |
|
507 |
+ } |
|
508 |
+#endif |
|
509 |
+ branch.s=msg->add_to_branch_s; |
|
510 |
+ branch.len=msg->add_to_branch_len; |
|
511 |
+ line_buf = via_builder( &via_len, send_sock, &branch, |
|
512 |
+ extra_params.len?&extra_params:0, proto); |
|
453 | 513 |
if (!line_buf){ |
454 | 514 |
LOG(L_ERR,"ERROR: build_req_buf_from_sip_req: no via received!\n"); |
455 | 515 |
goto error00; |
... | ... |
@@ -558,6 +618,9 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg, |
558 | 618 |
|
559 | 619 |
error01: |
560 | 620 |
pkg_free(line_buf); |
621 |
+#ifdef USE_TCP |
|
622 |
+ if (id_buf) pkg_free(id_buf); |
|
623 |
+#endif |
|
561 | 624 |
error02: |
562 | 625 |
if (received_buf) pkg_free(received_buf); |
563 | 626 |
error03: |
... | ... |
@@ -934,7 +997,7 @@ int branch_builder( unsigned int hash_index, |
934 | 997 |
|
935 | 998 |
char* via_builder( unsigned int *len, |
936 | 999 |
struct socket_info* send_sock, |
937 |
- char *branch, int branch_len, int proto ) |
|
1000 |
+ str* branch, str* extra_params, int proto ) |
|
938 | 1001 |
{ |
939 | 1002 |
unsigned int via_len, extra_len; |
940 | 1003 |
char *line_buf; |
... | ... |
@@ -942,9 +1005,11 @@ char* via_builder( unsigned int *len, |
942 | 1005 |
|
943 | 1006 |
|
944 | 1007 |
max_len=MY_VIA_LEN+send_sock->address_str.len /* space in MY_VIA */ |
945 |
- +2 /* just in case it it a v6 address ... [ ] */ |
|
1008 |
+ +2 /* just in case it is a v6 address ... [ ] */ |
|
946 | 1009 |
+send_sock->port_no_str.len |
947 |
- +MY_BRANCH_LEN+branch_len+CRLF_LEN+1; |
|
1010 |
+ +(branch)?(MY_BRANCH_LEN+branch->len):0 |
|
1011 |
+ +(extra_params)?extra_params->len:0 |
|
1012 |
+ +CRLF_LEN+1; |
|
948 | 1013 |
line_buf=pkg_malloc( max_len ); |
949 | 1014 |
if (line_buf==0){ |
950 | 1015 |
ser_error=E_OUT_OF_MEM; |
... | ... |
@@ -982,10 +1047,18 @@ char* via_builder( unsigned int *len, |
982 | 1047 |
} |
983 | 1048 |
|
984 | 1049 |
/* branch parameter */ |
985 |
- memcpy(line_buf+via_len, MY_BRANCH, MY_BRANCH_LEN ); |
|
986 |
- via_len+=MY_BRANCH_LEN; |
|
987 |
- memcpy(line_buf+via_len, branch, branch_len ); |
|
988 |
- via_len+=branch_len; |
|
1050 |
+ if (branch){ |
|
1051 |
+ memcpy(line_buf+via_len, MY_BRANCH, MY_BRANCH_LEN ); |
|
1052 |
+ via_len+=MY_BRANCH_LEN; |
|
1053 |
+ memcpy(line_buf+via_len, branch->s, branch->len ); |
|
1054 |
+ via_len+=branch->len; |
|
1055 |
+ } |
|
1056 |
+ /* extra params */ |
|
1057 |
+ if (extra_params){ |
|
1058 |
+ memcpy(line_buf+via_len, extra_params->s, extra_params->len); |
|
1059 |
+ via_len+=extra_params->len; |
|
1060 |
+ } |
|
1061 |
+ |
|
989 | 1062 |
memcpy(line_buf+via_len, CRLF, CRLF_LEN); |
990 | 1063 |
via_len+=CRLF_LEN; |
991 | 1064 |
line_buf[via_len]=0; /* null terminate the string*/ |
... | ... |
@@ -57,12 +57,8 @@ char * build_res_buf_from_sip_req( unsigned int code , |
57 | 57 |
|
58 | 58 |
char* via_builder( unsigned int *len, |
59 | 59 |
struct socket_info* send_sock, |
60 |
- char *branch, int branch_len, int proto ); |
|
60 |
+ str *branch, str* extra_params, int proto ); |
|
61 | 61 |
|
62 |
-#ifdef _OBSOLETED |
|
63 |
-char* via_builder( struct sip_msg *msg , |
|
64 |
- unsigned int *len, struct socket_info* send_sock); |
|
65 |
-#endif |
|
66 | 62 |
|
67 | 63 |
int branch_builder( unsigned int hash_index, |
68 | 64 |
/* only either parameter useful */ |