--- modules/sl/sl_funcs.c.orig Mon Oct 21 23:30:15 2002 +++ modules/sl/sl_funcs.c Sat Jan 11 06:09:54 2003 @@ -121,7 +121,7 @@ to.sin_family = AF_INET; */ if (reply_to_via) { - if (update_sock_struct_from_via( &(to), msg->via1 )==-1) + if (update_sock_struct_from_via( &(to), msg->via1, msg)==-1) { LOG(L_ERR, "ERROR: sl_send_reply: " "cannot lookup reply dst: %s\n", --- modules/tm/t_lookup.c.orig Mon Oct 21 22:21:50 2002 +++ modules/tm/t_lookup.c Sat Jan 11 06:09:54 2003 @@ -717,7 +717,7 @@ } else { via=msg->via1; /*init retrans buffer*/ - if (update_sock_struct_from_via( &(rb->to),via )==-1) { + if (update_sock_struct_from_via( &(rb->to),via,msg )==-1) { LOG(L_ERR, "ERROR: init_rb: cannot lookup reply dst: %.*s\n", via->host.len, via->host.s ); ser_error=E_BAD_VIA; --- parser/msg_parser.h.orig Wed Oct 23 18:12:20 2002 +++ parser/msg_parser.h Sat Jan 11 06:15:11 2003 @@ -118,6 +118,7 @@ char* unparsed; /* here we stopped parsing*/ struct ip_addr src_ip; + unsigned short src_port_no; struct ip_addr dst_ip; char* orig; /* original message copy */ --- parser/parse_via.c.orig Thu Sep 19 15:23:55 2002 +++ parser/parse_via.c Sat Jan 11 06:09:54 2003 @@ -87,8 +87,10 @@ MADDR1, MADDR2, MADDR3, MADDR4, RECEIVED1, RECEIVED2, RECEIVED3, RECEIVED4, RECEIVED5, RECEIVED6, RECEIVED7, + RPORT1, RPORT2, RPORT3, /* fin states (227-...)*/ FIN_HIDDEN = 230, FIN_TTL, FIN_BRANCH, FIN_MADDR, FIN_RECEIVED, + FIN_RPORT, /*GEN_PARAM, PARAM_ERROR*/ /* declared in msg_parser.h*/ }; @@ -125,6 +127,7 @@ case FIN_TTL: case FIN_MADDR: case FIN_RECEIVED: + case FIN_RPORT: *tmp=0; param->type=state; param->name.len=tmp-param->name.s; @@ -160,6 +163,7 @@ case FIN_TTL: case FIN_MADDR: case FIN_RECEIVED: + case FIN_RPORT: *tmp=0; param->type=state; param->name.len=tmp-param->name.s; @@ -200,6 +204,7 @@ case FIN_TTL: case FIN_MADDR: case FIN_RECEIVED: + case FIN_RPORT: *tmp=0; param->type=state; param->name.len=tmp-param->name.s; @@ -231,6 +236,7 @@ case FIN_TTL: case FIN_MADDR: case FIN_RECEIVED: + case FIN_RPORT: *tmp=0; param->type=state; param->name.len=tmp-param->name.s; @@ -267,6 +273,7 @@ case FIN_MADDR: case FIN_TTL: case FIN_RECEIVED: + case FIN_RPORT: LOG(L_ERR, "ERROR: parse_via: invalid char <%c> in" " state %d\n", *tmp, state); goto error; @@ -296,6 +303,7 @@ case FIN_MADDR: case FIN_TTL: case FIN_RECEIVED: + case FIN_RPORT: LOG(L_ERR, "ERROR: parse_via_param: new via found" "(',') when '=' expected (state %d=)\n", state); @@ -458,6 +466,9 @@ case TTL1: state=TTL2; break; + case RPORT3: + state=FIN_RPORT; + break; case GEN_PARAM: break; case F_CR: @@ -545,6 +556,9 @@ case BRANCH1: state=BRANCH2; break; + case RPORT2: + state=RPORT3; + break; case GEN_PARAM: break; case F_CR: @@ -619,7 +633,36 @@ state=GEN_PARAM; } break; - + case 'p': + case 'P': + switch(state){ + case RECEIVED1: + state=RPORT1; + break; + case F_CR: + case F_LF: + case F_CRLF: + state=END_OF_HEADER; + goto end_via; + default: + state=GEN_PARAM; + } + break; + case 'o': + case 'O': + switch(state){ + case RPORT1: + state=RPORT2; + break; + case F_CR: + case F_LF: + case F_CRLF: + state=END_OF_HEADER; + goto end_via; + default: + state=GEN_PARAM; + } + break; default: switch(state){ case F_PARAM: @@ -750,6 +793,11 @@ param->value.len=tmp-param->value.s; state=F_PARAM; goto endofvalue; + case F_VALUE: + *tmp=0; + param->value.len=0; + state=F_PARAM; + goto endofvalue; case P_STRING: break; /* what to do? */ case F_LF: @@ -1681,6 +1729,8 @@ vb->branch=param; else if (param->type==PARAM_RECEIVED) vb->received=param; + else if (param->type==PARAM_RPORT) + vb->rport=param; break; case P_PARAM: break; --- parser/parse_via.h.orig Mon Oct 21 18:46:27 2002 +++ parser/parse_via.h Sat Jan 11 06:09:54 2003 @@ -36,7 +36,7 @@ */ enum { PARAM_HIDDEN=230, PARAM_TTL, PARAM_BRANCH, - PARAM_MADDR, PARAM_RECEIVED, GEN_PARAM, + PARAM_MADDR, PARAM_RECEIVED, PARAM_RPORT, GEN_PARAM, PARAM_ERROR }; @@ -70,6 +70,7 @@ struct via_param* branch; str tid; /* transaction id, part of branch */ struct via_param* received; + struct via_param* rport; struct via_body* next; /* pointer to next via body string if compact via or null */ --- config.h.orig Mon Oct 21 22:21:50 2002 +++ config.h Sat Jan 11 06:09:54 2003 @@ -82,6 +82,9 @@ #define RECEIVED ";received=" #define RECEIVED_LEN 10 +#define RPORT ";rport=" +#define RPORT_LEN 7 + #define SRV_PREFIX "_sip._udp." #define SRV_PREFIX_LEN 10 @@ -112,6 +115,7 @@ /* forwarding -- Via buffer dimensioning */ #define MAX_VIA_LINE_SIZE 240 #define MAX_RECEIVED_SIZE 57 +#define MAX_RPORT_SIZE 13 /* maximum number of branches per transaction */ #define MAX_BRANCHES 4 --- forward.h.orig Wed Oct 23 18:12:20 2002 +++ forward.h Sat Jan 11 06:09:54 2003 @@ -40,7 +40,7 @@ int check_self(str* host, unsigned short port); int forward_request( struct sip_msg* msg, struct proxy_l* p); int update_sock_struct_from_via( union sockaddr_union* to, - struct via_body* via ); + struct via_body* via, struct sip_msg *msg ); int update_sock_struct_from_ip( union sockaddr_union* to, struct sip_msg *msg ); int forward_reply( struct sip_msg* msg); --- ip_addr.h.orig Mon Nov 4 19:05:32 2002 +++ ip_addr.h Sat Jan 11 06:09:54 2003 @@ -201,6 +201,21 @@ } } +static inline unsigned int su2port_no(union sockaddr_union* su) +{ + switch(su->s.sa_family){ + case AF_INET: + return ntohs(su->sin.sin_port); +#ifdef USE_IPV6 + case AF_INET6: + return ntohs(su->sin6.sin6_port); +#endif + default: + LOG(L_CRIT,"su2port_no: BUG: unknown address family %d\n", + su->s.sa_family); + } + return 0; +} /* ip_addr2su -> the same as init_su*/ #define ip_addr2su init_su --- msg_translator.c.orig Mon Oct 21 22:21:50 2002 +++ msg_translator.c Sat Jan 11 06:09:54 2003 @@ -145,9 +145,10 @@ else foo=&(msg->first_line.u.request.uri); print_len=snprintf(buf+fix_len, MAX_WARNING_LEN-fix_len, - "pid=%d req_src_ip=%s in_uri=%.*s out_uri=%.*s via_cnt%c=%d\"", + "pid=%d req_src_ip=%s req_src_port=%d in_uri=%.*s out_uri=%.*s via_cnt%c=%d\"", my_pid(), ip_addr2a(&msg->src_ip), + msg->src_port_no, msg->first_line.u.request.uri.len, msg->first_line.u.request.uri.s, foo->len, foo->s, msg->parsed_flag & HDR_EOH ? '=' : '>', /* should be = */ @@ -208,7 +209,26 @@ return buf; } +char *rport_builder(struct sip_msg *msg, unsigned int *rport_len) +{ + char *buf; + buf=pkg_malloc(sizeof(char)*MAX_RPORT_SIZE); + if (buf==0){ + ser_error=E_OUT_OF_MEM; + LOG(L_ERR, "ERROR: rport_builder: out of memory\n"); + return 0; + } + /* + * Don't need any sanity checks here, because + * msg->src_port_no is unsigned int, which means + * that it couldn't be more than 5 chars long in + * string representation. + */ + *rport_len = snprintf(buf, MAX_RPORT_SIZE, "%s%u", RPORT, msg->src_port_no); + + return buf; +} /* computes the "unpacked" len of a lump list, code moved from build_req_from_req */ @@ -395,9 +415,10 @@ unsigned int *returned_len, struct socket_info* send_sock) { - unsigned int len, new_len, received_len, uri_len, via_len; + unsigned int len, new_len, received_len, rport_len, uri_len, via_len; char* line_buf; char* received_buf; + char* rport_buf; char* new_buf; char* orig; char* buf; @@ -411,8 +432,10 @@ buf=msg->buf; len=msg->len; received_len=0; + rport_len=0; new_buf=0; received_buf=0; + rport_buf=0; line_buf = via_builder( &via_len, send_sock, @@ -430,6 +453,11 @@ if ((received_buf=received_builder(msg,&received_len))==0) goto error01; /* free also line_buf */ } + /* check if rport needs to be updated */ + if (msg->via1->rport && msg->via1->rport->value.s==0) { + if ((rport_buf=rport_builder(msg,&rport_len))==0) + goto error01; /* free also line_buf */ + } /* add via header to the list */ /* try to add it before msg. 1st via */ @@ -459,6 +487,14 @@ if (insert_new_lump_after(anchor, received_buf, received_len, HDR_VIA) ==0 ) goto error02; /* free also line_buf */ } + /* if rport needs to be updated do it */ + if (rport_len){ + offset = msg->via1->rport->value.s - buf - 1; + anchor=del_lump(&msg->add_rm, offset, msg->via1->rport->size + 1, HDR_VIA); + if (anchor==0) goto error02; /* free also line_buf */ + if (insert_new_lump_after(anchor, rport_buf, rport_len, HDR_VIA) + ==0 ) goto error02; /* free also line_buf */ + } /* compute new msg len and fix overlapping zones*/ new_len=len+lumps_len(msg->add_rm); @@ -507,6 +543,7 @@ pkg_free(line_buf); error02: if (received_buf) pkg_free(received_buf); + if (rport_buf) pkg_free(rport_buf); error00: *returned_len=0; return 0; @@ -587,14 +624,18 @@ int i; char backup; char *received_buf; + char *rport_buf; unsigned int received_len; + unsigned int rport_len; char *warning; unsigned int warning_len; int r; str to_tag; received_buf=0; + rport_buf=0; received_len=0; + rport_len=0; buf=0; /* make -Wall happy */ warning=0; @@ -621,6 +662,15 @@ goto error00; } } + /* check if rport needs to be updated */ + if (msg->via1->rport && msg->via1->rport->value.s==0) { + if ((rport_buf=rport_builder(msg,&rport_len))==0) { + LOG(L_ERR, "ERROR: build_res_buf_from_sip_req: " + "alas, rport_builder failed\n"); + goto error00; + } + rport_len -= msg->via1->rport->size; + } /*computes the lenght of the new response buffer*/ len = 0; @@ -641,7 +691,7 @@ len+=new_tag_len+5/*";tag="*/; } case HDR_VIA: - if (hdr==msg->h_via1) len += received_len; + if (hdr==msg->h_via1) len += received_len + rport_len; case HDR_FROM: case HDR_CALLID: case HDR_CSEQ: @@ -716,10 +766,23 @@ break; } case HDR_VIA: - append_str_trans( p, hdr->name.s , + if (hdr==msg->h_via1 && rport_buf) { + append_str_trans( p, hdr->name.s , + msg->via1->rport->name.s - hdr->name.s - 1, msg); + append_str( p, rport_buf, + rport_len + msg->via1->rport->size, msg); + append_str_trans( p, msg->via1->rport->name.s + + msg->via1->rport->size, + hdr->body.s + hdr->body.len - + msg->via1->rport->name.s - + msg->via1->rport->size, msg); + } else { + append_str_trans( p, hdr->name.s , ((hdr->body.s+hdr->body.len )-hdr->name.s ),msg); + } if (hdr==msg->h_via1 && received_buf) append_str( p, received_buf, received_len, msg); + append_str( p, CRLF,CRLF_LEN,msg); break; case HDR_FROM: @@ -763,10 +826,12 @@ needs to be deleted here */ if (received_buf) pkg_free(received_buf); + if (rport_buf) pkg_free(rport_buf); return buf; error01: if (received_buf) pkg_free(received_buf); + if (rport_buf) pkg_free(rport_buf); error00: *returned_len=0; return 0; --- receive.c.orig Thu Oct 3 23:06:10 2002 +++ receive.c Sat Jan 11 06:09:54 2003 @@ -77,6 +77,7 @@ useful as most of the work is done with scrath-pad; -jiri */ buf[len]=0; su2ip_addr(&msg->src_ip, src_su); + msg->src_port_no=su2port_no(src_su); msg->dst_ip=bind_address->address; /* won't work if listening on 0.0.0.0 */ msg->id=msg_no; /* make a copy of the message */ --- forward.c.orig Thu Oct 24 17:21:08 2002 +++ forward.c Sat Jan 11 06:21:11 2003 @@ -240,14 +240,21 @@ int update_sock_struct_from_ip( union sockaddr_union* to, struct sip_msg *msg ) { + unsigned short port_no; - init_su(to, &msg->src_ip, - (msg->via1->port)?htons(msg->via1->port): htons(SIP_PORT) ); + if (msg->src_port_no) + port_no = msg->src_port_no; + else if (msg->via1->port) + port_no = msg->via1->port; + else + port_no = SIP_PORT; + + init_su(to, &msg->src_ip, htons(port_no)); return 1; } int update_sock_struct_from_via( union sockaddr_union* to, - struct via_body* via ) + struct via_body* via, struct sip_msg *msg ) { struct hostent* he; char *host_copy; @@ -266,6 +273,11 @@ name=&(via->host); port=via->port; } + if (via->rport && via->rport->value.s) { + port=atoi(via->rport->value.s); + } else if (via->rport && via->rport->value.s==0 && !via->received) { + return update_sock_struct_from_ip( to, msg); + } /* we do now a malloc/memcpy because gethostbyname loves \0-terminated strings; -jiri but only if host is not null terminated @@ -353,7 +365,7 @@ goto error; } - if (update_sock_struct_from_via( to, msg->via2 )==-1) goto error; + if (update_sock_struct_from_via( to, msg->via2, msg)==-1) goto error; send_sock=get_send_socket(to); if (send_sock==0){ LOG(L_ERR, "forward_reply: ERROR: no sending socket found\n");