/* introduce a new uac to transaction; returns its branch id (>=0) or error (<0); it doesn't send a message yet -- a reply to it might interfere with the processes of adding multiple branches */ static int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop, unsigned int bflags, str* path, struct proxy_l *proxy) { unsigned short branch; struct sip_msg_body *body_clone=NO_BODY_CLONE_MARKER; int do_free_proxy; int ret; branch=t->nr_of_outgoings; if (branch==MAX_BRANCHES) { LM_ERR("maximum number of branches exceeded\n"); ret=E_CFG; goto error; } /* check existing buffer -- rewriting should never occur */ if (t->uac[branch].request.buffer.s) { LM_CRIT("buffer rewrite attempt\n"); ret=ser_error=E_BUG; goto error; } /* set proper RURI to request to reflect the branch */ request->new_uri=*uri; request->parsed_uri_ok=0; request->dst_uri=*next_hop; request->path_vec=*path; request->ruri_bflags=bflags; if ( pre_print_uac_request( t, branch, request, &body_clone)!= 0 ) { ret = -1; goto error01; } /* check DNS resolution */ if (proxy){ do_free_proxy = 0; }else { proxy=uri2proxy( request->dst_uri.len ? &request->dst_uri:&request->new_uri, request->force_send_socket ? request->force_send_socket->proto : PROTO_NONE ); if (proxy==0) { ret=E_BAD_ADDRESS; goto error01; } do_free_proxy = 1; } msg_callback_process(request, REQ_PRE_FORWARD, (void *)proxy); if ( !(t->flags&T_NO_DNS_FAILOVER_FLAG) ) { t->uac[branch].proxy = shm_clone_proxy( proxy , do_free_proxy ); if (t->uac[branch].proxy==NULL) { ret = E_OUT_OF_MEM; goto error02; } } /* use the first address */ hostent2su( &t->uac[branch].request.dst.to, &proxy->host, proxy->addr_idx, proxy->port ? proxy->port:SIP_PORT); t->uac[branch].request.dst.proto = proxy->proto; /* do print of the uac request */ if ( update_uac_dst( request, &t->uac[branch] )!=0) { ret = ser_error; goto error02; } /* things went well, move ahead */ t->uac[branch].uri.s=t->uac[branch].request.buffer.s+ request->first_line.u.request.method.len+1; t->uac[branch].uri.len=request->new_uri.len; t->uac[branch].br_flags = request->ruri_bflags; t->uac[branch].added_rr = count_local_rr( request ); t->nr_of_outgoings++; /* done! */ ret=branch; error02: if(do_free_proxy) { free_proxy( proxy ); pkg_free( proxy ); } error01: post_print_uac_request( request, uri, next_hop, body_clone); if (ret < 0) { /* destroy all the bavps added, the path vector and the destination, * since this branch will never be properly added to * the UAC list, otherwise we'll have memory leaks - razvanc */ clean_branch(t->uac[branch]); memset(&t->uac[branch], 0, sizeof(t->uac[branch])); init_branch(&t->uac[branch], branch, t->wait_tl.set, t); } error: return ret; }
int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel, struct cell *t_invite, int branch ) { int ret; char *shbuf; unsigned int len; str bk_dst_uri; str bk_path_vec; if (t_cancel->uac[branch].request.buffer.s) { LM_CRIT("buffer rewrite attempt\n"); ret=ser_error=E_BUG; goto error; } cancel_msg->new_uri = t_invite->uac[branch].uri; cancel_msg->parsed_uri_ok=0; bk_dst_uri = cancel_msg->dst_uri; bk_path_vec = cancel_msg->path_vec; /* force same path as for request */ cancel_msg->path_vec = t_invite->uac[branch].path_vec; if ( pre_print_uac_request( t_cancel, branch, cancel_msg)!= 0 ) { ret = -1; goto error01; } /* force same uri as in INVITE */ if (cancel_msg->new_uri.s!=t_invite->uac[branch].uri.s) { pkg_free(cancel_msg->new_uri.s); cancel_msg->new_uri = t_invite->uac[branch].uri; /* and just to be sure */ cancel_msg->parsed_uri_ok = 0; } /* print */ shbuf=print_uac_request( cancel_msg, &len, t_invite->uac[branch].request.dst.send_sock, t_invite->uac[branch].request.dst.proto); if (!shbuf) { LM_ERR("printing e2e cancel failed\n"); ret=ser_error=E_OUT_OF_MEM; goto error01; } /* install buffer */ t_cancel->uac[branch].request.dst=t_invite->uac[branch].request.dst; t_cancel->uac[branch].request.buffer.s=shbuf; t_cancel->uac[branch].request.buffer.len=len; t_cancel->uac[branch].uri.s=t_cancel->uac[branch].request.buffer.s+ cancel_msg->first_line.u.request.method.len+1; t_cancel->uac[branch].uri.len=t_invite->uac[branch].uri.len; t_cancel->uac[branch].br_flags = cancel_msg->flags; /* success */ ret=1; error01: post_print_uac_request( cancel_msg, &t_invite->uac[branch].uri, &bk_dst_uri); cancel_msg->dst_uri = bk_dst_uri; cancel_msg->path_vec = bk_path_vec; error: return ret; }
int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel, struct cell *t_invite, int branch ) { int ret; char *shbuf; unsigned int len; str bk_dst_uri; if (t_cancel->uac[branch].request.buffer) { LOG(L_CRIT, "ERROR: e2e_cancel_branch: buffer rewrite attempt\n"); ret=ser_error=E_BUG; goto error; } /* note -- there is a gap in proxy stats -- we don't update proxy stats with CANCEL (proxy->ok, proxy->tx, etc.) */ cancel_msg->new_uri = t_invite->uac[branch].uri; cancel_msg->parsed_uri_ok=0; bk_dst_uri = cancel_msg->dst_uri; if ( pre_print_uac_request( t_cancel, branch, cancel_msg)!= 0 ) { ret = -1; goto error01; } /* force same uri as in INVITE */ if (cancel_msg->new_uri.s!=t_invite->uac[branch].uri.s) { pkg_free(cancel_msg->new_uri.s); cancel_msg->new_uri = t_invite->uac[branch].uri; /* and just to be sure */ cancel_msg->parsed_uri_ok = 0; } /* print */ shbuf=print_uac_request( cancel_msg, &len, t_invite->uac[branch].request.dst.send_sock, t_invite->uac[branch].request.dst.proto); if (!shbuf) { LOG(L_ERR, "ERROR: e2e_cancel_branch: printing e2e cancel failed\n"); ret=ser_error=E_OUT_OF_MEM; goto error01; } /* install buffer */ t_cancel->uac[branch].request.dst=t_invite->uac[branch].request.dst; t_cancel->uac[branch].request.buffer=shbuf; t_cancel->uac[branch].request.buffer_len=len; t_cancel->uac[branch].uri.s=t_cancel->uac[branch].request.buffer+ cancel_msg->first_line.u.request.method.len+1; t_cancel->uac[branch].uri.len=t_invite->uac[branch].uri.len; t_cancel->uac[branch].br_flags = cancel_msg->flags&(~gflags_mask); /* success */ ret=1; error01: post_print_uac_request( cancel_msg, &t_invite->uac[branch].uri, &bk_dst_uri); cancel_msg->dst_uri = bk_dst_uri; error: return ret; }
/* introduce a new uac to transaction; returns its branch id (>=0) or error (<0); it doesn't send a message yet -- a reply to it might interfere with the processes of adding multiple branches */ static int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop, str* path, struct proxy_l *proxy) { unsigned short branch; int do_free_proxy; int ret; branch=t->nr_of_outgoings; if (branch==MAX_BRANCHES) { LM_ERR("maximum number of branches exceeded\n"); ret=E_CFG; goto error; } /* check existing buffer -- rewriting should never occur */ if (t->uac[branch].request.buffer.s) { LM_CRIT("buffer rewrite attempt\n"); ret=ser_error=E_BUG; goto error; } /* set proper RURI to request to reflect the branch */ request->new_uri=*uri; request->parsed_uri_ok=0; request->dst_uri=*next_hop; request->path_vec=*path; if ( pre_print_uac_request( t, branch, request)!= 0 ) { ret = -1; goto error01; } /* check DNS resolution */ if (proxy){ do_free_proxy = 0; }else { proxy=uri2proxy( request->dst_uri.len ? &request->dst_uri:&request->new_uri, PROTO_NONE ); if (proxy==0) { ret=E_BAD_ADDRESS; goto error01; } do_free_proxy = 1; } msg_callback_process(request, REQ_PRE_FORWARD, (void *)proxy); if ( !(t->flags&T_NO_DNS_FAILOVER_FLAG) ) { t->uac[branch].proxy = shm_clone_proxy( proxy , do_free_proxy ); if (t->uac[branch].proxy==NULL) { ret = E_OUT_OF_MEM; goto error02; } } /* use the first address */ hostent2su( &t->uac[branch].request.dst.to, &proxy->host, proxy->addr_idx, proxy->port ? proxy->port:SIP_PORT); t->uac[branch].request.dst.proto = proxy->proto; if ( update_uac_dst( request, &t->uac[branch] )!=0) { ret = ser_error; goto error02; } /* things went well, move ahead */ t->uac[branch].uri.s=t->uac[branch].request.buffer.s+ request->first_line.u.request.method.len+1; t->uac[branch].uri.len=request->new_uri.len; t->uac[branch].br_flags = getb0flags(); t->uac[branch].added_rr = count_local_rr( request ); t->nr_of_outgoings++; /* done! */ ret=branch; error02: if(do_free_proxy) { free_proxy( proxy ); pkg_free( proxy ); } error01: post_print_uac_request( request, uri, next_hop); error: return ret; }
/* introduce a new uac to transaction; returns its branch id (>=0) or error (<0); it doesn't send a message yet -- a reply to it might interfere with the processes of adding multiple branches */ int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop, struct proxy_l *proxy, int proto ) { int ret; short temp_proxy; union sockaddr_union to; unsigned short branch; struct socket_info* send_sock; char *shbuf; unsigned int len; branch=t->nr_of_outgoings; if (branch==MAX_BRANCHES) { LOG(L_ERR, "ERROR:tm:add_uac: maximum number of branches exceeded\n"); ret=E_CFG; goto error; } /* check existing buffer -- rewriting should never occur */ if (t->uac[branch].request.buffer) { LOG(L_CRIT, "ERROR:tm:add_uac: buffer rewrite attempt\n"); ret=ser_error=E_BUG; goto error; } /* set proper RURI to request to reflect the branch */ request->new_uri=*uri; request->parsed_uri_ok=0; request->dst_uri=*next_hop; if ( pre_print_uac_request( t, branch, request)!= 0 ) { ret = -1; goto error01; } /* check DNS resolution */ if (proxy){ temp_proxy=0; proto=get_proto(proto, proxy->proto); }else { proxy=uri2proxy( request->dst_uri.len ? &request->dst_uri:&request->new_uri, proto ); if (proxy==0) { ret=E_BAD_ADDRESS; goto error01; } proto=proxy->proto; /* uri2proxy will fix it for us */ temp_proxy=1; } if (proxy->ok==0) { if (proxy->host.h_addr_list[proxy->addr_idx+1]) proxy->addr_idx++; else proxy->addr_idx=0; proxy->ok=1; } hostent2su( &to, &proxy->host, proxy->addr_idx, proxy->port ? proxy->port:SIP_PORT); send_sock=get_send_socket( request, &to , proto); if (send_sock==0) { LOG(L_ERR, "ERROR:tm:add_uac: can't fwd to af %d, proto %d " " (no corresponding listening socket)\n", to.s.sa_family, proto ); ret=ser_error=E_NO_SOCKET; goto error02; } /* now message printing starts ... */ shbuf=print_uac_request( request, &len, send_sock, proto ); if (!shbuf) { ret=ser_error=E_OUT_OF_MEM; goto error02; } /* things went well, move ahead and install new buffer! */ t->uac[branch].request.dst.to=to; t->uac[branch].request.dst.send_sock=send_sock; t->uac[branch].request.dst.proto=proto; t->uac[branch].request.dst.proto_reserved1=0; t->uac[branch].request.buffer=shbuf; t->uac[branch].request.buffer_len=len; t->uac[branch].uri.s=t->uac[branch].request.buffer+ request->first_line.u.request.method.len+1; t->uac[branch].uri.len=request->new_uri.len; t->uac[branch].br_flags = request->flags&(~gflags_mask); t->nr_of_outgoings++; /* update stats */ proxy->tx++; proxy->tx_bytes+=len; /* done! */ ret=branch; error02: if (temp_proxy) { free_proxy( proxy ); pkg_free( proxy ); } error01: post_print_uac_request( request, uri, next_hop); error: return ret; }