|
@@ -81,7 +81,9 @@
|
|
* 2009-06-01 Pre- and post-script callbacks of branch route are
|
|
* 2009-06-01 Pre- and post-script callbacks of branch route are
|
|
* executed (Miklos)
|
|
* executed (Miklos)
|
|
* 2009-10-26 support for changing dst_uri in branch routes,
|
|
* 2009-10-26 support for changing dst_uri in branch routes,
|
|
- * s/print_uac_request/prepare_uac_request/ (andrei)
|
|
|
|
|
|
+ * s/print_uac_request/prepare_new_uac/ (andrei)
|
|
|
|
+ * 2009-10-28 support for changing r-uris and path in branch routes; more of
|
|
|
|
+ * add_uac() functionality moved into prepare_new_uac() (andrei)
|
|
*/
|
|
*/
|
|
|
|
|
|
#include "defs.h"
|
|
#include "defs.h"
|
|
@@ -148,17 +150,18 @@ unsigned int get_on_branch(void)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-/* prepare_uac_request flags */
|
|
|
|
|
|
+/* prepare_new_uac flags */
|
|
#define UAC_DNS_FAILOVER_F 1 /**< new branch due to dns failover */
|
|
#define UAC_DNS_FAILOVER_F 1 /**< new branch due to dns failover */
|
|
|
|
|
|
|
|
|
|
-/** create a branch "buffer".
|
|
|
|
- * Creates the buffer used in the branch rb, fills the sending information
|
|
|
|
- * (t->uac[branch].request.dst) if next_hop!=0 and runs the on_branch route.
|
|
|
|
|
|
+/** prepares a new branch "buffer".
|
|
|
|
+ * Creates the buffer used in the branch rb, fills everything needed (
|
|
|
|
+ the sending information: t->uac[branch].request.dst, branch buffer, uri
|
|
|
|
+ path vector a.s.o.) and runs the on_branch route.
|
|
* t->uac[branch].request.dst will be filled if next_hop !=0 with the result
|
|
* t->uac[branch].request.dst will be filled if next_hop !=0 with the result
|
|
* of the DNS resolution (next_hop and fproto).
|
|
* of the DNS resolution (next_hop and fproto).
|
|
* If next_hop is 0 all the dst members except the send_flags are read-only
|
|
* If next_hop is 0 all the dst members except the send_flags are read-only
|
|
- * (send_flags it's updated).
|
|
|
|
|
|
+ * (send_flags it's updated) and are supposed to be pre-filled.
|
|
*
|
|
*
|
|
* @param t - transaction
|
|
* @param t - transaction
|
|
* @param i_req - corresponding sip_msg, must be non-null, flags might be
|
|
* @param i_req - corresponding sip_msg, must be non-null, flags might be
|
|
@@ -173,39 +176,42 @@ unsigned int get_on_branch(void)
|
|
* a pre-filled valid request.dst.
|
|
* a pre-filled valid request.dst.
|
|
* @param fproto - forced proto for forwarding. Used only if next_hop!=0.
|
|
* @param fproto - forced proto for forwarding. Used only if next_hop!=0.
|
|
* @param flags - 0 or UAC_DNS_FAILOVER_F for now.
|
|
* @param flags - 0 or UAC_DNS_FAILOVER_F for now.
|
|
- * @param len - resul parameter, it will be filled with the created buffer
|
|
|
|
- * length.
|
|
|
|
- * @return pointer to shm alloc'ed buffer on success (*len and dst
|
|
|
|
- * are filled/modified), 0 on failure and sets ser_error.
|
|
|
|
|
|
+ *
|
|
|
|
+ * @return 0 on success, < 0 (ser_errror E***) on failure.
|
|
*/
|
|
*/
|
|
-static char *prepare_uac_request( struct cell *t, struct sip_msg *i_req,
|
|
|
|
|
|
+static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
|
|
int branch, str *uri, str* path,
|
|
int branch, str *uri, str* path,
|
|
str* next_hop, int fproto,
|
|
str* next_hop, int fproto,
|
|
- int flags,
|
|
|
|
- unsigned int *len)
|
|
|
|
|
|
+ int flags)
|
|
{
|
|
{
|
|
- char *buf, *shbuf;
|
|
|
|
- str* msg_uri;
|
|
|
|
|
|
+ char *shbuf;
|
|
struct lump* add_rm_backup, *body_lumps_backup;
|
|
struct lump* add_rm_backup, *body_lumps_backup;
|
|
struct sip_uri parsed_uri_bak;
|
|
struct sip_uri parsed_uri_bak;
|
|
- int parsed_uri_ok_bak, uri_backed_up;
|
|
|
|
|
|
+ int ret;
|
|
|
|
+ unsigned int len;
|
|
|
|
+ int parsed_uri_ok_bak, free_new_uri;
|
|
str msg_uri_bak;
|
|
str msg_uri_bak;
|
|
str dst_uri_bak;
|
|
str dst_uri_bak;
|
|
|
|
+ int dst_uri_backed_up;
|
|
str path_bak;
|
|
str path_bak;
|
|
- int path_backed_up;
|
|
|
|
|
|
+ int free_path;
|
|
int backup_route_type;
|
|
int backup_route_type;
|
|
snd_flags_t fwd_snd_flags_bak;
|
|
snd_flags_t fwd_snd_flags_bak;
|
|
snd_flags_t rpl_snd_flags_bak;
|
|
snd_flags_t rpl_snd_flags_bak;
|
|
struct dest_info *dst;
|
|
struct dest_info *dst;
|
|
|
|
|
|
shbuf=0;
|
|
shbuf=0;
|
|
|
|
+ ret=E_UNSPEC;
|
|
msg_uri_bak.s=0; /* kill warnings */
|
|
msg_uri_bak.s=0; /* kill warnings */
|
|
msg_uri_bak.len=0;
|
|
msg_uri_bak.len=0;
|
|
parsed_uri_ok_bak=0;
|
|
parsed_uri_ok_bak=0;
|
|
- uri_backed_up=0;
|
|
|
|
|
|
+ free_new_uri=0;
|
|
|
|
+ dst_uri_bak.s=0;
|
|
|
|
+ dst_uri_bak.len=0;
|
|
|
|
+ dst_uri_backed_up=0;
|
|
path_bak.s=0;
|
|
path_bak.s=0;
|
|
path_bak.len=0;
|
|
path_bak.len=0;
|
|
- path_backed_up=0;
|
|
|
|
|
|
+ free_path=0;
|
|
dst=&t->uac[branch].request.dst;
|
|
dst=&t->uac[branch].request.dst;
|
|
|
|
|
|
/* ... we calculate branch ... */
|
|
/* ... we calculate branch ... */
|
|
@@ -213,39 +219,12 @@ static char *prepare_uac_request( struct cell *t, struct sip_msg *i_req,
|
|
&i_req->add_to_branch_len ))
|
|
&i_req->add_to_branch_len ))
|
|
{
|
|
{
|
|
LOG(L_ERR, "ERROR: print_uac_request: branch computation failed\n");
|
|
LOG(L_ERR, "ERROR: print_uac_request: branch computation failed\n");
|
|
- ser_error=E_UNSPEC;
|
|
|
|
|
|
+ ret=E_UNSPEC;
|
|
goto error00;
|
|
goto error00;
|
|
}
|
|
}
|
|
-
|
|
|
|
- /* ... update uri ... */
|
|
|
|
- msg_uri=GET_RURI(i_req);
|
|
|
|
- if ((msg_uri->s!=uri->s) || (msg_uri->len!=uri->len)){
|
|
|
|
- msg_uri_bak=i_req->new_uri;
|
|
|
|
- parsed_uri_ok_bak=i_req->parsed_uri_ok;
|
|
|
|
- parsed_uri_bak=i_req->parsed_uri;
|
|
|
|
- i_req->new_uri=*uri;
|
|
|
|
- i_req->parsed_uri_ok=0;
|
|
|
|
- uri_backed_up=1;
|
|
|
|
- }
|
|
|
|
- /* update path_vec */
|
|
|
|
- if (unlikely((i_req->path_vec.s!=path->s) ||
|
|
|
|
- (i_req->path_vec.len!=path->len))){
|
|
|
|
- path_bak=i_req->path_vec;
|
|
|
|
- i_req->path_vec=*path;
|
|
|
|
- path_backed_up=1;
|
|
|
|
- }
|
|
|
|
- /* backup dst uri & zero it*/
|
|
|
|
- dst_uri_bak=i_req->dst_uri;
|
|
|
|
- i_req->dst_uri.s=0;
|
|
|
|
- i_req->dst_uri.len=0;
|
|
|
|
- if (likely(next_hop)){
|
|
|
|
- /* set dst uri to next_hop for the on_branch route */
|
|
|
|
- if (unlikely(set_dst_uri(i_req, next_hop)<0)){
|
|
|
|
- ser_error=E_OUT_OF_MEM;
|
|
|
|
- goto error03;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
+ /* dup lumps
|
|
|
|
+ * TODO: clone lumps only if needed */
|
|
#ifdef POSTPONE_MSG_CLONING
|
|
#ifdef POSTPONE_MSG_CLONING
|
|
/* lumps can be set outside of the lock, make sure that we read
|
|
/* lumps can be set outside of the lock, make sure that we read
|
|
* the up-to-date values */
|
|
* the up-to-date values */
|
|
@@ -253,45 +232,149 @@ static char *prepare_uac_request( struct cell *t, struct sip_msg *i_req,
|
|
#endif
|
|
#endif
|
|
add_rm_backup = i_req->add_rm;
|
|
add_rm_backup = i_req->add_rm;
|
|
body_lumps_backup = i_req->body_lumps;
|
|
body_lumps_backup = i_req->body_lumps;
|
|
- i_req->add_rm = dup_lump_list(i_req->add_rm);
|
|
|
|
- i_req->body_lumps = dup_lump_list(i_req->body_lumps);
|
|
|
|
-
|
|
|
|
- if (unlikely(branch_route)) {
|
|
|
|
- /* run branch_route actions if provided */
|
|
|
|
- backup_route_type = get_route_type();
|
|
|
|
- set_route_type(BRANCH_ROUTE);
|
|
|
|
- tm_ctx_set_branch_index(branch+1);
|
|
|
|
- if (exec_pre_script_cb(i_req, BRANCH_CB_TYPE)>0) {
|
|
|
|
- /* backup ireq msg send flags */
|
|
|
|
- fwd_snd_flags_bak=i_req->fwd_send_flags;;
|
|
|
|
- rpl_snd_flags_bak=i_req->rpl_send_flags;
|
|
|
|
- i_req->fwd_send_flags=dst->send_flags /* intial value */;
|
|
|
|
- if (run_top_route(branch_rt.rlist[branch_route], i_req, 0) < 0) {
|
|
|
|
- LOG(L_ERR, "Error in run_top_route\n");
|
|
|
|
- }
|
|
|
|
- /* update dst send_flags */
|
|
|
|
- dst->send_flags=i_req->fwd_send_flags;
|
|
|
|
- /* restore ireq_msg flags */
|
|
|
|
- i_req->fwd_send_flags=fwd_snd_flags_bak;
|
|
|
|
- i_req->rpl_send_flags=rpl_snd_flags_bak;
|
|
|
|
- exec_post_script_cb(i_req, BRANCH_CB_TYPE);
|
|
|
|
|
|
+ i_req->add_rm=0;
|
|
|
|
+ i_req->body_lumps=0;
|
|
|
|
+ if (unlikely(i_req->add_rm)){
|
|
|
|
+ i_req->add_rm = dup_lump_list(i_req->add_rm);
|
|
|
|
+ if (unlikely(i_req->add_rm==0)){
|
|
|
|
+ ret=E_OUT_OF_MEM;
|
|
|
|
+ goto error04;
|
|
}
|
|
}
|
|
- tm_ctx_set_branch_index(0);
|
|
|
|
- set_route_type(backup_route_type);
|
|
|
|
}
|
|
}
|
|
-
|
|
|
|
- /* run the specific callbacks for this transaction */
|
|
|
|
- if (unlikely(has_tran_tmcbs(t, TMCB_REQUEST_FWDED)))
|
|
|
|
- run_trans_callbacks( TMCB_REQUEST_FWDED , t, i_req, 0,
|
|
|
|
- -i_req->REQ_METHOD);
|
|
|
|
|
|
+ if (unlikely(i_req->body_lumps)){
|
|
|
|
+ i_req->body_lumps = dup_lump_list(i_req->body_lumps);
|
|
|
|
+ if (unlikely(i_req->body_lumps==0)){
|
|
|
|
+ ret=E_OUT_OF_MEM;
|
|
|
|
+ goto error04;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ /* backup uri & path: we need to change them so that build_req...()
|
|
|
|
+ will use uri & path and not the ones in the original msg (i_req)
|
|
|
|
+ => we must back them up so that we can restore them to the original
|
|
|
|
+ value after building the send buffer */
|
|
|
|
+ msg_uri_bak=i_req->new_uri;
|
|
|
|
+ parsed_uri_bak=i_req->parsed_uri;
|
|
|
|
+ parsed_uri_ok_bak=i_req->parsed_uri_ok;
|
|
|
|
+ path_bak=i_req->path_vec;
|
|
|
|
|
|
- if (likely( !(flags & UAC_DNS_FAILOVER_F) && i_req->dst_uri.s &&
|
|
|
|
- i_req->dst_uri.len)){
|
|
|
|
- /* no dns failover and non-empty dst_uri => use it as dst
|
|
|
|
- (on dns failover dns_h will be non-empty => next_hop will be
|
|
|
|
- ignored) */
|
|
|
|
- next_hop=&i_req->dst_uri;
|
|
|
|
|
|
+ if (unlikely(branch_route || has_tran_tmcbs(t, TMCB_REQUEST_FWDED))){
|
|
|
|
+ /* dup uris, path a.s.o. if we have a branch route or callback */
|
|
|
|
+ /* ... set ruri ... */
|
|
|
|
+ /* if uri points to new_uri, it needs to be "fixed" so that we can
|
|
|
|
+ change msg->new_uri */
|
|
|
|
+ if (uri==&i_req->new_uri)
|
|
|
|
+ uri=&msg_uri_bak;
|
|
|
|
+ i_req->parsed_uri_ok=0;
|
|
|
|
+ i_req->new_uri.s=pkg_malloc(uri->len);
|
|
|
|
+ if (unlikely(i_req->new_uri.s==0)){
|
|
|
|
+ ret=E_OUT_OF_MEM;
|
|
|
|
+ goto error03;
|
|
|
|
+ }
|
|
|
|
+ free_new_uri=1;
|
|
|
|
+ memcpy(i_req->new_uri.s, uri->s, uri->len);
|
|
|
|
+ i_req->new_uri.len=uri->len;
|
|
|
|
+
|
|
|
|
+ /* update path_vec */
|
|
|
|
+ /* if path points to msg path_vec, it needs to be "fixed" so that we
|
|
|
|
+ can change/update msg->path_vec */
|
|
|
|
+ if (path==&i_req->path_vec)
|
|
|
|
+ path=&path_bak;
|
|
|
|
+ /* zero it first so that set_path_vector will work */
|
|
|
|
+ i_req->path_vec.s=0;
|
|
|
|
+ i_req->path_vec.len=0;
|
|
|
|
+ if (unlikely(path)){
|
|
|
|
+ if (unlikely(set_path_vector(i_req, path)<0)){
|
|
|
|
+ ret=E_OUT_OF_MEM;
|
|
|
|
+ goto error03;
|
|
|
|
+ }
|
|
|
|
+ free_path=1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* backup dst uri & zero it*/
|
|
|
|
+ dst_uri_bak=i_req->dst_uri;
|
|
|
|
+ dst_uri_backed_up=1;
|
|
|
|
+ /* if next_hop points to dst_uri, it needs to be "fixed" so that we
|
|
|
|
+ can change msg->dst_uri */
|
|
|
|
+ if (next_hop==&i_req->dst_uri)
|
|
|
|
+ next_hop=&dst_uri_bak;
|
|
|
|
+ /* zero it first so that set_dst_uri will work */
|
|
|
|
+ i_req->dst_uri.s=0;
|
|
|
|
+ i_req->dst_uri.len=0;
|
|
|
|
+ if (likely(next_hop)){
|
|
|
|
+ /* set dst uri to next_hop for the on_branch route */
|
|
|
|
+ if (unlikely(set_dst_uri(i_req, next_hop)<0)){
|
|
|
|
+ ret=E_OUT_OF_MEM;
|
|
|
|
+ goto error03;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (likely(branch_route)) {
|
|
|
|
+ /* run branch_route actions if provided */
|
|
|
|
+ backup_route_type = get_route_type();
|
|
|
|
+ set_route_type(BRANCH_ROUTE);
|
|
|
|
+ tm_ctx_set_branch_index(branch+1);
|
|
|
|
+ /* no need to backup/set avp lists: the on_branch route is run
|
|
|
|
+ only in the main route context (e.g. t_relay() in the main
|
|
|
|
+ route) or in the failure route context (e.g. append_branch &
|
|
|
|
+ t_relay()) and in both cases the avp lists are properly set
|
|
|
|
+ Note: the branch route is not run on delayed dns failover
|
|
|
|
+ (for that to work one would have to set branch_route prior to
|
|
|
|
+ calling add_uac(...) and then reset it afterwards).
|
|
|
|
+ (
|
|
|
|
+ */
|
|
|
|
+ if (exec_pre_script_cb(i_req, BRANCH_CB_TYPE)>0) {
|
|
|
|
+ /* backup ireq msg send flags */
|
|
|
|
+ fwd_snd_flags_bak=i_req->fwd_send_flags;;
|
|
|
|
+ rpl_snd_flags_bak=i_req->rpl_send_flags;
|
|
|
|
+ i_req->fwd_send_flags=dst->send_flags /* intial value */;
|
|
|
|
+ if (run_top_route(branch_rt.rlist[branch_route], i_req, 0) < 0)
|
|
|
|
+ {
|
|
|
|
+ LOG(L_ERR, "Error in run_top_route\n");
|
|
|
|
+ }
|
|
|
|
+ /* update dst send_flags */
|
|
|
|
+ dst->send_flags=i_req->fwd_send_flags;
|
|
|
|
+ /* restore ireq_msg flags */
|
|
|
|
+ i_req->fwd_send_flags=fwd_snd_flags_bak;
|
|
|
|
+ i_req->rpl_send_flags=rpl_snd_flags_bak;
|
|
|
|
+ exec_post_script_cb(i_req, BRANCH_CB_TYPE);
|
|
|
|
+ }
|
|
|
|
+ tm_ctx_set_branch_index(0);
|
|
|
|
+ set_route_type(backup_route_type);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* run the specific callbacks for this transaction */
|
|
|
|
+ if (unlikely(has_tran_tmcbs(t, TMCB_REQUEST_FWDED)))
|
|
|
|
+ run_trans_callbacks( TMCB_REQUEST_FWDED , t, i_req, 0,
|
|
|
|
+ -i_req->REQ_METHOD);
|
|
|
|
+
|
|
|
|
+ if (likely( !(flags & UAC_DNS_FAILOVER_F) && i_req->dst_uri.s &&
|
|
|
|
+ i_req->dst_uri.len)){
|
|
|
|
+ /* no dns failover and non-empty dst_uri => use it as dst
|
|
|
|
+ (on dns failover dns_h will be non-empty => next_hop will be
|
|
|
|
+ ignored) */
|
|
|
|
+ next_hop=&i_req->dst_uri;
|
|
|
|
+ }
|
|
|
|
+ }else{
|
|
|
|
+ /* no branch route and no TMCB_REQUEST_FWDED callback => set
|
|
|
|
+ msg uri and path to the new values (if needed) */
|
|
|
|
+ if (unlikely((uri->s!=i_req->new_uri.s || uri->len!=i_req->new_uri.len)
|
|
|
|
+ && (i_req->new_uri.s!=0 ||
|
|
|
|
+ uri->s!=i_req->first_line.u.request.uri.s ||
|
|
|
|
+ uri->len!=i_req->first_line.u.request.uri.len) )){
|
|
|
|
+ /* uri is different from i_req uri => replace i_req uri and force
|
|
|
|
+ uri re-parsing */
|
|
|
|
+ i_req->new_uri=*uri;
|
|
|
|
+ i_req->parsed_uri_ok=0;
|
|
|
|
+ }
|
|
|
|
+ if (unlikely(path && (i_req->path_vec.s!=path->s ||
|
|
|
|
+ i_req->path_vec.len!=path->len))){
|
|
|
|
+ i_req->path_vec=*path;
|
|
|
|
+ }else if (unlikely(path==0 && i_req->path_vec.len!=0)){
|
|
|
|
+ i_req->path_vec.s=0;
|
|
|
|
+ i_req->path_vec.len=0;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+
|
|
if (likely(next_hop!=0 || (flags & UAC_DNS_FAILOVER_F))){
|
|
if (likely(next_hop!=0 || (flags & UAC_DNS_FAILOVER_F))){
|
|
/* next_hop present => use it for dns resolution */
|
|
/* next_hop present => use it for dns resolution */
|
|
#ifdef USE_DNS_FAILOVER
|
|
#ifdef USE_DNS_FAILOVER
|
|
@@ -302,7 +385,7 @@ static char *prepare_uac_request( struct cell *t, struct sip_msg *i_req,
|
|
if (uri2dst(dst, i_req, next_hop?next_hop:uri, fproto)==0)
|
|
if (uri2dst(dst, i_req, next_hop?next_hop:uri, fproto)==0)
|
|
#endif
|
|
#endif
|
|
{
|
|
{
|
|
- ser_error=E_BAD_ADDRESS;
|
|
|
|
|
|
+ ret=E_BAD_ADDRESS;
|
|
goto error01;
|
|
goto error01;
|
|
}
|
|
}
|
|
} /* else next_hop==0 =>
|
|
} /* else next_hop==0 =>
|
|
@@ -314,59 +397,77 @@ static char *prepare_uac_request( struct cell *t, struct sip_msg *i_req,
|
|
LOG(L_ERR, "ERROR: can't fwd to af %d, proto %d "
|
|
LOG(L_ERR, "ERROR: can't fwd to af %d, proto %d "
|
|
" (no corresponding listening socket)\n",
|
|
" (no corresponding listening socket)\n",
|
|
dst->to.s.sa_family, dst->proto );
|
|
dst->to.s.sa_family, dst->proto );
|
|
- ser_error=E_NO_SOCKET;
|
|
|
|
|
|
+ ret=E_NO_SOCKET;
|
|
goto error01;
|
|
goto error01;
|
|
}
|
|
}
|
|
/* ... and build it now */
|
|
/* ... and build it now */
|
|
- buf=build_req_buf_from_sip_req( i_req, len, dst, 0);
|
|
|
|
|
|
+ shbuf=build_req_buf_from_sip_req( i_req, &len, dst, BUILD_IN_SHM);
|
|
|
|
+ if (!shbuf) {
|
|
|
|
+ LOG(L_ERR, "ERROR: print_uac_request: no shm mem\n");
|
|
|
|
+ ret=E_OUT_OF_MEM;
|
|
|
|
+ goto error01;
|
|
|
|
+ }
|
|
#ifdef DBG_MSG_QA
|
|
#ifdef DBG_MSG_QA
|
|
- if (buf[*len-1]==0) {
|
|
|
|
|
|
+ if (shbuf[len-1]==0) {
|
|
LOG(L_ERR, "ERROR: print_uac_request: sanity check failed\n");
|
|
LOG(L_ERR, "ERROR: print_uac_request: sanity check failed\n");
|
|
abort();
|
|
abort();
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
- if (!buf) {
|
|
|
|
- LOG(L_ERR, "ERROR: print_uac_request: no pkg_mem\n");
|
|
|
|
- ser_error=E_OUT_OF_MEM;
|
|
|
|
- goto error01;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- shbuf=(char *)shm_malloc(*len);
|
|
|
|
- if (!shbuf) {
|
|
|
|
- ser_error=E_OUT_OF_MEM;
|
|
|
|
- LOG(L_ERR, "ERROR: print_uac_request: no shmem\n");
|
|
|
|
- goto error02;
|
|
|
|
|
|
+ /* things went well, move ahead and install new buffer! */
|
|
|
|
+ t->uac[branch].request.buffer=shbuf;
|
|
|
|
+ t->uac[branch].request.buffer_len=len;
|
|
|
|
+ t->uac[branch].uri.s=t->uac[branch].request.buffer+
|
|
|
|
+ i_req->first_line.u.request.method.len+1;
|
|
|
|
+ t->uac[branch].uri.len=GET_RURI(i_req)->len;
|
|
|
|
+ if (unlikely(i_req->path_vec.s && i_req->path_vec.len)){
|
|
|
|
+ t->uac[branch].path.s=shm_malloc(i_req->path_vec.len+1);
|
|
|
|
+ if (unlikely(t->uac[branch].path.s==0)) {
|
|
|
|
+ shm_free(shbuf);
|
|
|
|
+ t->uac[branch].request.buffer=0;
|
|
|
|
+ t->uac[branch].request.buffer_len=0;
|
|
|
|
+ t->uac[branch].uri.s=0;
|
|
|
|
+ t->uac[branch].uri.len=0;
|
|
|
|
+ ret=E_OUT_OF_MEM;
|
|
|
|
+ goto error01;
|
|
|
|
+ }
|
|
|
|
+ t->uac[branch].path.len=i_req->path_vec.len;
|
|
|
|
+ t->uac[branch].path.s[i_req->path_vec.len]=0;
|
|
|
|
+ memcpy( t->uac[branch].path.s, i_req->path_vec.s, i_req->path_vec.len);
|
|
}
|
|
}
|
|
- memcpy( shbuf, buf, *len );
|
|
|
|
|
|
+ ret=0;
|
|
|
|
|
|
-error02:
|
|
|
|
- pkg_free( buf );
|
|
|
|
error01:
|
|
error01:
|
|
- /* Delete the duplicated lump lists, this will also delete
|
|
|
|
- * all lumps created here, such as lumps created in per-branch
|
|
|
|
- * routing sections, Via, and Content-Length headers created in
|
|
|
|
- * build_req_buf_from_sip_req
|
|
|
|
- */
|
|
|
|
|
|
+error03:
|
|
|
|
+ /* restore the new_uri & path from the backup */
|
|
|
|
+ if (unlikely(free_new_uri && i_req->new_uri.s)){
|
|
|
|
+ pkg_free(i_req->new_uri.s);
|
|
|
|
+ }
|
|
|
|
+ if (unlikely(free_path)){
|
|
|
|
+ reset_path_vector(i_req);
|
|
|
|
+ }
|
|
|
|
+ if (dst_uri_backed_up){
|
|
|
|
+ reset_dst_uri(i_req); /* free dst_uri */
|
|
|
|
+ i_req->dst_uri=dst_uri_bak;
|
|
|
|
+ }
|
|
|
|
+ /* restore original new_uri and path values */
|
|
|
|
+ i_req->new_uri=msg_uri_bak;
|
|
|
|
+ i_req->parsed_uri=parsed_uri_bak;
|
|
|
|
+ i_req->parsed_uri_ok=parsed_uri_ok_bak;
|
|
|
|
+ i_req->path_vec=path_bak;
|
|
|
|
+ /* Delete the duplicated lump lists, this will also delete
|
|
|
|
+ * all lumps created here, such as lumps created in per-branch
|
|
|
|
+ * routing sections, Via, and Content-Length headers created in
|
|
|
|
+ * build_req_buf_from_sip_req
|
|
|
|
+ */
|
|
|
|
+error04:
|
|
free_duped_lump_list(i_req->add_rm);
|
|
free_duped_lump_list(i_req->add_rm);
|
|
free_duped_lump_list(i_req->body_lumps);
|
|
free_duped_lump_list(i_req->body_lumps);
|
|
/* Restore the lists from backups */
|
|
/* Restore the lists from backups */
|
|
i_req->add_rm = add_rm_backup;
|
|
i_req->add_rm = add_rm_backup;
|
|
i_req->body_lumps = body_lumps_backup;
|
|
i_req->body_lumps = body_lumps_backup;
|
|
-error03:
|
|
|
|
- /* restore the new_uri from the backup */
|
|
|
|
- if (uri_backed_up){
|
|
|
|
- i_req->new_uri=msg_uri_bak;
|
|
|
|
- i_req->parsed_uri=parsed_uri_bak;
|
|
|
|
- i_req->parsed_uri_ok=parsed_uri_ok_bak;
|
|
|
|
- }
|
|
|
|
- if (unlikely(path_backed_up)){
|
|
|
|
- i_req->path_vec=path_bak;
|
|
|
|
- }
|
|
|
|
- reset_dst_uri(i_req); /* free dst_uri */
|
|
|
|
- i_req->dst_uri=dst_uri_bak;
|
|
|
|
|
|
|
|
error00:
|
|
error00:
|
|
- return shbuf;
|
|
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef USE_DNS_FAILOVER
|
|
#ifdef USE_DNS_FAILOVER
|
|
@@ -506,8 +607,8 @@ int add_blind_uac( /*struct cell *t*/ )
|
|
* next_hop/uri and it will be used for forwarding.
|
|
* next_hop/uri and it will be used for forwarding.
|
|
* @param proto - forced protocol for forwarding (overrides the protocol
|
|
* @param proto - forced protocol for forwarding (overrides the protocol
|
|
* in next_hop/uri or proxy if != PROTO_NONE).
|
|
* in next_hop/uri or proxy if != PROTO_NONE).
|
|
- * @param flags - special flags passed to prepare_uac_request().
|
|
|
|
- * @see prepare_uac_request().
|
|
|
|
|
|
+ * @param flags - special flags passed to prepare_new_uac().
|
|
|
|
+ * @see prepare_new_uac().
|
|
* @returns branch id (>=0) or error (<0)
|
|
* @returns branch id (>=0) or error (<0)
|
|
*/
|
|
*/
|
|
static int add_uac( struct cell *t, struct sip_msg *request, str *uri,
|
|
static int add_uac( struct cell *t, struct sip_msg *request, str *uri,
|
|
@@ -517,8 +618,9 @@ static int add_uac( struct cell *t, struct sip_msg *request, str *uri,
|
|
|
|
|
|
int ret;
|
|
int ret;
|
|
unsigned short branch;
|
|
unsigned short branch;
|
|
- char *shbuf;
|
|
|
|
|
|
+#ifdef TM_UAC_FLAGS
|
|
unsigned int len;
|
|
unsigned int len;
|
|
|
|
+#endif /* TM_UAC_FLAGS */
|
|
|
|
|
|
branch=t->nr_of_outgoings;
|
|
branch=t->nr_of_outgoings;
|
|
if (branch==MAX_BRANCHES) {
|
|
if (branch==MAX_BRANCHES) {
|
|
@@ -552,34 +654,11 @@ static int add_uac( struct cell *t, struct sip_msg *request, str *uri,
|
|
}
|
|
}
|
|
|
|
|
|
/* now message printing starts ... */
|
|
/* now message printing starts ... */
|
|
- shbuf=prepare_uac_request(t, request, branch, uri, path, next_hop,
|
|
|
|
- proto, flags, &len);
|
|
|
|
- if (!shbuf) {
|
|
|
|
- ret=ser_error<0?ser_error:E_BUG;
|
|
|
|
|
|
+ if (unlikely( (ret=prepare_new_uac(t, request, branch, uri, path,
|
|
|
|
+ next_hop, proto, flags)) < 0)){
|
|
|
|
+ ser_error=ret;
|
|
goto error01;
|
|
goto error01;
|
|
}
|
|
}
|
|
-
|
|
|
|
- /* things went well, move ahead and install new buffer! */
|
|
|
|
- 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=uri->len;
|
|
|
|
- if (unlikely(path && path->s)){
|
|
|
|
- t->uac[branch].path.s=shm_malloc(path->len+1);
|
|
|
|
- if (unlikely(t->uac[branch].path.s==0)) {
|
|
|
|
- shm_free(shbuf);
|
|
|
|
- t->uac[branch].request.buffer=0;
|
|
|
|
- t->uac[branch].request.buffer_len=0;
|
|
|
|
- t->uac[branch].uri.s=0;
|
|
|
|
- t->uac[branch].uri.len=0;
|
|
|
|
- ret=ser_error=E_OUT_OF_MEM;
|
|
|
|
- goto error01;
|
|
|
|
- }
|
|
|
|
- t->uac[branch].path.len=path->len;
|
|
|
|
- t->uac[branch].path.s[path->len]=0;
|
|
|
|
- memcpy( t->uac[branch].path.s, path->s, path->len);
|
|
|
|
- }
|
|
|
|
#ifdef TM_UAC_FLAGS
|
|
#ifdef TM_UAC_FLAGS
|
|
len = count_applied_lumps(request->add_rm, HDR_RECORDROUTE_T);
|
|
len = count_applied_lumps(request->add_rm, HDR_RECORDROUTE_T);
|
|
if(len==1)
|
|
if(len==1)
|
|
@@ -812,39 +891,37 @@ int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel,
|
|
}
|
|
}
|
|
shbuf=build_local_reparse( t_invite, branch, &len, CANCEL,
|
|
shbuf=build_local_reparse( t_invite, branch, &len, CANCEL,
|
|
CANCEL_LEN, &t_invite->to);
|
|
CANCEL_LEN, &t_invite->to);
|
|
-
|
|
|
|
|
|
+ if (unlikely(!shbuf)) {
|
|
|
|
+ LOG(L_ERR, "e2e_cancel_branch: printing e2e cancel failed\n");
|
|
|
|
+ ret=ser_error=E_OUT_OF_MEM;
|
|
|
|
+ goto error;
|
|
|
|
+ }
|
|
|
|
+ /* install buffer */
|
|
|
|
+ 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;
|
|
} else {
|
|
} else {
|
|
- /* buffer is constructed from the received CANCEL with applying lumps */
|
|
|
|
|
|
+ /* buffer is constructed from the received CANCEL with lumps applied */
|
|
/* t_cancel...request.dst is already filled (see above) */
|
|
/* t_cancel...request.dst is already filled (see above) */
|
|
- shbuf=prepare_uac_request( t_cancel, cancel_msg, branch,
|
|
|
|
|
|
+ if (unlikely((ret=prepare_new_uac( t_cancel, cancel_msg, branch,
|
|
&t_invite->uac[branch].uri,
|
|
&t_invite->uac[branch].uri,
|
|
&t_invite->uac[branch].path,
|
|
&t_invite->uac[branch].path,
|
|
- 0, PROTO_NONE, 0,
|
|
|
|
- &len);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (!shbuf) {
|
|
|
|
- LOG(L_ERR, "ERROR: e2e_cancel_branch: printing e2e cancel failed\n");
|
|
|
|
- ret=ser_error=E_OUT_OF_MEM;
|
|
|
|
- goto error;
|
|
|
|
|
|
+ 0, PROTO_NONE, 0)) <0)){
|
|
|
|
+ ser_error=ret;
|
|
|
|
+ goto error;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
-
|
|
|
|
- /* install buffer */
|
|
|
|
- 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;
|
|
|
|
-
|
|
|
|
-
|
|
|
|
/* success */
|
|
/* success */
|
|
ret=1;
|
|
ret=1;
|
|
|
|
|
|
-
|
|
|
|
error:
|
|
error:
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+
|
|
void e2e_cancel( struct sip_msg *cancel_msg,
|
|
void e2e_cancel( struct sip_msg *cancel_msg,
|
|
struct cell *t_cancel, struct cell *t_invite )
|
|
struct cell *t_cancel, struct cell *t_invite )
|
|
{
|
|
{
|