فهرست منبع

tm: preserve forced sockets and send flags during dns failover

- fix for branches introduced as a result of dns failover not
  preserving the forced send socket.
- dns failover branches now preserve also the original branch send
  flags.
(cherry picked from commit 35755149a5baa028e5b0e441cebebd0d25d6063b)
Andrei Pelinescu-Onciul 16 سال پیش
والد
کامیت
43b0a4a332
1فایلهای تغییر یافته به همراه49 افزوده شده و 23 حذف شده
  1. 49 23
      modules/tm/t_fwd.c

+ 49 - 23
modules/tm/t_fwd.c

@@ -159,7 +159,7 @@ unsigned int get_on_branch(void)
    the sending information: t->uac[branch].request.dst, branch buffer, uri
    the sending information: t->uac[branch].request.dst, branch buffer, uri
    path vector a.s.o.) and runs the on_branch route.
    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, fproto and fsocket).
  * 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) and are supposed to be pre-filled.
  * (send_flags it's updated) and are supposed to be pre-filled.
  *
  *
@@ -174,6 +174,8 @@ unsigned int get_on_branch(void)
  *              for DNS resolution and the branch request.dst structure will
  *              for DNS resolution and the branch request.dst structure will
  *              be filled. If 0 the branch must already have
  *              be filled. If 0 the branch must already have
  *              a pre-filled valid request.dst.
  *              a pre-filled valid request.dst.
+ * @param fsocket - forced send socket for forwarding.
+ * @param send_flags - special flags for sending (see SND_F_* / snd_flags_t).
  * @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.
  *
  *
@@ -181,8 +183,10 @@ unsigned int get_on_branch(void)
  */
  */
 static int prepare_new_uac( 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,
-									int flags)
+									str* next_hop,
+									struct socket_info* fsocket,
+									snd_flags_t snd_flags,
+									int fproto, int flags)
 {
 {
 	char *shbuf;
 	char *shbuf;
 	struct lump* add_rm_backup, *body_lumps_backup;
 	struct lump* add_rm_backup, *body_lumps_backup;
@@ -198,6 +202,7 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
 	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 socket_info *force_send_socket_bak;
 	struct dest_info *dst;
 	struct dest_info *dst;
 
 
 	shbuf=0;
 	shbuf=0;
@@ -321,17 +326,22 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
 			   (
 			   (
 			 */
 			 */
 			if (exec_pre_script_cb(i_req, BRANCH_CB_TYPE)>0) {
 			if (exec_pre_script_cb(i_req, BRANCH_CB_TYPE)>0) {
-				/* backup ireq msg send flags */
+				/* backup ireq msg send flags and force_send_socket*/
 				fwd_snd_flags_bak=i_req->fwd_send_flags;;
 				fwd_snd_flags_bak=i_req->fwd_send_flags;;
 				rpl_snd_flags_bak=i_req->rpl_send_flags;
 				rpl_snd_flags_bak=i_req->rpl_send_flags;
-				i_req->fwd_send_flags=dst->send_flags /* intial value  */;
+				force_send_socket_bak=i_req->force_send_socket;
+				/* set the new values */
+				i_req->fwd_send_flags=snd_flags /* intial value  */;
+				set_force_socket(i_req, fsocket);
 				if (run_top_route(branch_rt.rlist[branch_route], i_req, 0) < 0)
 				if (run_top_route(branch_rt.rlist[branch_route], i_req, 0) < 0)
 				{
 				{
 					LOG(L_ERR, "Error in run_top_route\n");
 					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 */
+				/* update dst send_flags  and send socket*/
+				snd_flags=i_req->fwd_send_flags;
+				fsocket=i_req->force_send_socket;
+				/* restore ireq_msg force_send_socket & flags */
+				set_force_socket(i_req, force_send_socket_bak);
 				i_req->fwd_send_flags=fwd_snd_flags_bak;
 				i_req->fwd_send_flags=fwd_snd_flags_bak;
 				i_req->rpl_send_flags=rpl_snd_flags_bak;
 				i_req->rpl_send_flags=rpl_snd_flags_bak;
 				exec_post_script_cb(i_req, BRANCH_CB_TYPE);
 				exec_post_script_cb(i_req, BRANCH_CB_TYPE);
@@ -376,11 +386,12 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
 	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
-		if (uri2dst(&t->uac[branch].dns_h, dst, i_req,
+		if (uri2dst2(&t->uac[branch].dns_h, dst, fsocket, snd_flags,
 							next_hop?next_hop:uri, fproto) == 0)
 							next_hop?next_hop:uri, fproto) == 0)
 #else
 #else
 		/* dst filled from the uri & request (send_socket) */
 		/* dst filled from the uri & request (send_socket) */
-		if (uri2dst(dst, i_req, next_hop?next_hop:uri, fproto)==0)
+		if (uri2dst2(dst, fsocket, snd_flags,
+							next_hop?next_hop:uri, fproto)==0)
 #endif
 #endif
 		{
 		{
 			ret=E_BAD_ADDRESS;
 			ret=E_BAD_ADDRESS;
@@ -452,6 +463,7 @@ error03:
 	i_req->parsed_uri=parsed_uri_bak;
 	i_req->parsed_uri=parsed_uri_bak;
 	i_req->parsed_uri_ok=parsed_uri_ok_bak;
 	i_req->parsed_uri_ok=parsed_uri_ok_bak;
 	i_req->path_vec=path_bak;
 	i_req->path_vec=path_bak;
+	
 	/* Delete the duplicated lump lists, this will also delete
 	/* Delete the duplicated lump lists, this will also delete
 	 * all lumps created here, such as lumps created in per-branch
 	 * all lumps created here, such as lumps created in per-branch
 	 * routing sections, Via, and Content-Length headers created in
 	 * routing sections, Via, and Content-Length headers created in
@@ -603,6 +615,8 @@ int add_blind_uac( /*struct cell *t*/ )
  *                     uri format, e.g.: "<sip:1.2.3.4;lr>, <sip:5.6.7.8;lr>").
  *                     uri format, e.g.: "<sip:1.2.3.4;lr>, <sip:5.6.7.8;lr>").
  *  @param proxy    - proxy structure. If non-null it takes precedence over
  *  @param proxy    - proxy structure. If non-null it takes precedence over
  *                    next_hop/uri and it will be used for forwarding.
  *                    next_hop/uri and it will be used for forwarding.
+ *  @param fsocket  - forced forward send socket (can be 0).
+ *  @param snd_flags - special send flags (see SND_F_* / snd_flags_t)
  *  @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_new_uac().
  *  @param flags    - special flags passed to prepare_new_uac().
@@ -611,6 +625,7 @@ int add_blind_uac( /*struct cell *t*/ )
 */
 */
 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,
 					str* next_hop, str* path, struct proxy_l *proxy,
 					str* next_hop, str* path, struct proxy_l *proxy,
+					struct socket_info* fsocket, snd_flags_t snd_flags,
 					int proto, int flags)
 					int proto, int flags)
 {
 {
 
 
@@ -653,7 +668,8 @@ static int add_uac( struct cell *t, struct sip_msg *request, str *uri,
 
 
 	/* now message printing starts ... */
 	/* now message printing starts ... */
 	if (unlikely( (ret=prepare_new_uac(t, request, branch, uri, path,
 	if (unlikely( (ret=prepare_new_uac(t, request, branch, uri, path,
-											next_hop, proto, flags)) < 0)){
+										next_hop, fsocket, snd_flags,
+										proto, flags)) < 0)){
 		ser_error=ret;
 		ser_error=ret;
 		goto error01;
 		goto error01;
 	}
 	}
@@ -689,7 +705,10 @@ error:
    the failed branch to construct the new message in case of DNS failover.
    the failed branch to construct the new message in case of DNS failover.
 */
 */
 static int add_uac_from_buf( struct cell *t, struct sip_msg *request,
 static int add_uac_from_buf( struct cell *t, struct sip_msg *request,
-								str *uri, str* path, int proto,
+								str *uri, str* path,
+								struct socket_info* fsocket,
+								snd_flags_t send_flags,
+								int proto,
 								char *buf, short buf_len)
 								char *buf, short buf_len)
 {
 {
 
 
@@ -713,8 +732,8 @@ static int add_uac_from_buf( struct cell *t, struct sip_msg *request,
 		goto error;
 		goto error;
 	}
 	}
 
 
-	if (uri2dst(&t->uac[branch].dns_h, &t->uac[branch].request.dst,
-				request, uri, proto) == 0)
+	if (uri2dst2(&t->uac[branch].dns_h, &t->uac[branch].request.dst,
+					fsocket, send_flags, uri, proto) == 0)
 	{
 	{
 		ret=ser_error=E_BAD_ADDRESS;
 		ret=ser_error=E_BAD_ADDRESS;
 		goto error;
 		goto error;
@@ -820,21 +839,29 @@ int add_uac_dns_fallback(struct cell *t, struct sip_msg* msg,
 			dns_srv_handle_cpy(&t->uac[t->nr_of_outgoings].dns_h,
 			dns_srv_handle_cpy(&t->uac[t->nr_of_outgoings].dns_h,
 								&old_uac->dns_h);
 								&old_uac->dns_h);
 
 
-			if (cfg_get(tm, tm_cfg, reparse_on_dns_failover))
+			if (cfg_get(tm, tm_cfg, reparse_on_dns_failover)){
 				/* Reuse the old buffer and only replace the via header.
 				/* Reuse the old buffer and only replace the via header.
 				 * The drawback is that the send_socket is not corrected
 				 * The drawback is that the send_socket is not corrected
 				 * in the rest of the message, only in the VIA HF (Miklos) */
 				 * in the rest of the message, only in the VIA HF (Miklos) */
 				ret=add_uac_from_buf(t,  msg, &old_uac->uri,
 				ret=add_uac_from_buf(t,  msg, &old_uac->uri,
 							&old_uac->path,
 							&old_uac->path,
+							 (old_uac->request.dst.send_flags &
+								SND_F_FORCE_SOCKET)?
+									old_uac->request.dst.send_sock:0,
+							old_uac->request.dst.send_flags,
 							old_uac->request.dst.proto,
 							old_uac->request.dst.proto,
 							old_uac->request.buffer,
 							old_uac->request.buffer,
 							old_uac->request.buffer_len);
 							old_uac->request.buffer_len);
-			else
+			}else
 				/* add_uac will use dns_h => next_hop will be ignored.
 				/* add_uac will use dns_h => next_hop will be ignored.
 				 * Unfortunately we can't reuse the old buffer, the branch id
 				 * Unfortunately we can't reuse the old buffer, the branch id
 				 *  must be changed and the send_socket might be different =>
 				 *  must be changed and the send_socket might be different =>
 				 *  re-create the whole uac */
 				 *  re-create the whole uac */
 				ret=add_uac(t,  msg, &old_uac->uri, 0, &old_uac->path, 0,
 				ret=add_uac(t,  msg, &old_uac->uri, 0, &old_uac->path, 0,
+							 (old_uac->request.dst.send_flags &
+								SND_F_FORCE_SOCKET)?
+									old_uac->request.dst.send_sock:0,
+							old_uac->request.dst.send_flags,
 							old_uac->request.dst.proto, UAC_DNS_FAILOVER_F);
 							old_uac->request.dst.proto, UAC_DNS_FAILOVER_F);
 
 
 			if (ret<0){
 			if (ret<0){
@@ -906,7 +933,7 @@ int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel,
 		if (unlikely((ret=prepare_new_uac( 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)) <0)){
+									0, 0, 0, PROTO_NONE, 0)) <0)){
 			ser_error=ret;
 			ser_error=ret;
 			goto error;
 			goto error;
 		}
 		}
@@ -1242,7 +1269,7 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
 	int try_new;
 	int try_new;
 	int lock_replies;
 	int lock_replies;
 	str dst_uri, path;
 	str dst_uri, path;
-	struct socket_info* si, *backup_si;
+	struct socket_info* si;
 	flag_t backup_bflags = 0;
 	flag_t backup_bflags = 0;
 	flag_t bflags = 0;
 	flag_t bflags = 0;
 	
 	
@@ -1267,7 +1294,6 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
 		}
 		}
 	}
 	}
 
 
-	backup_si = p_msg->force_send_socket;
 	getbflagsval(0, &backup_bflags);
 	getbflagsval(0, &backup_bflags);
 
 
 	/* if no more specific error code is known, use this */
 	/* if no more specific error code is known, use this */
@@ -1303,7 +1329,8 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
 #endif
 #endif
 		try_new=1;
 		try_new=1;
 		branch_ret=add_uac( t, p_msg, GET_RURI(p_msg), GET_NEXT_HOP(p_msg),
 		branch_ret=add_uac( t, p_msg, GET_RURI(p_msg), GET_NEXT_HOP(p_msg),
-							&p_msg->path_vec, proxy, proto, 0);
+							&p_msg->path_vec, proxy, p_msg->force_send_socket,
+							p_msg->fwd_send_flags, proto, 0);
 		if (branch_ret>=0) 
 		if (branch_ret>=0) 
 			added_branches |= 1<<branch_ret;
 			added_branches |= 1<<branch_ret;
 		else
 		else
@@ -1314,12 +1341,12 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
 	while((current_uri.s=next_branch( &current_uri.len, &q, &dst_uri, &path,
 	while((current_uri.s=next_branch( &current_uri.len, &q, &dst_uri, &path,
 										&bflags, &si))) {
 										&bflags, &si))) {
 		try_new++;
 		try_new++;
-		p_msg->force_send_socket = si;
 		setbflagsval(0, bflags);
 		setbflagsval(0, bflags);
 
 
 		branch_ret=add_uac( t, p_msg, &current_uri,
 		branch_ret=add_uac( t, p_msg, &current_uri,
 							(dst_uri.len) ? (&dst_uri) : &current_uri,
 							(dst_uri.len) ? (&dst_uri) : &current_uri,
-							&path, proxy, proto, 0);
+							&path, proxy, si, p_msg->fwd_send_flags,
+							proto, 0);
 		/* pick some of the errors in case things go wrong;
 		/* pick some of the errors in case things go wrong;
 		   note that picking lowest error is just as good as
 		   note that picking lowest error is just as good as
 		   any other algorithm which picks any other negative
 		   any other algorithm which picks any other negative
@@ -1332,7 +1359,6 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
 	/* consume processed branches */
 	/* consume processed branches */
 	clear_branches();
 	clear_branches();
 
 
-	p_msg->force_send_socket = backup_si;
 	setbflagsval(0, backup_bflags);
 	setbflagsval(0, backup_bflags);
 
 
 	/* don't forget to clear all branches processed so far */
 	/* don't forget to clear all branches processed so far */