Browse code

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.

Andrei Pelinescu-Onciul authored on 05/11/2009 13:48:41
Showing 1 changed files
... ...
@@ -159,7 +159,7 @@ unsigned int get_on_branch(void)
159 159
    the sending information: t->uac[branch].request.dst, branch buffer, uri
160 160
    path vector a.s.o.) and runs the on_branch route.
161 161
  * t->uac[branch].request.dst will be filled if next_hop !=0 with the result
162
- * of the DNS resolution (next_hop and fproto).
162
+ * of the DNS resolution (next_hop, fproto and fsocket).
163 163
  * If next_hop is 0 all the dst members except the send_flags are read-only
164 164
  * (send_flags it's updated) and are supposed to be pre-filled.
165 165
  *
... ...
@@ -174,6 +174,8 @@ unsigned int get_on_branch(void)
174 174
  *              for DNS resolution and the branch request.dst structure will
175 175
  *              be filled. If 0 the branch must already have
176 176
  *              a pre-filled valid request.dst.
177
+ * @param fsocket - forced send socket for forwarding.
178
+ * @param send_flags - special flags for sending (see SND_F_* / snd_flags_t).
177 179
  * @param fproto - forced proto for forwarding. Used only if next_hop!=0.
178 180
  * @param flags - 0 or UAC_DNS_FAILOVER_F for now.
179 181
  *
... ...
@@ -181,8 +183,10 @@ unsigned int get_on_branch(void)
181 181
  */
182 182
 static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
183 183
 									int branch, str *uri, str* path,
184
-									str* next_hop, int fproto,
185
-									int flags)
184
+									str* next_hop,
185
+									struct socket_info* fsocket,
186
+									snd_flags_t snd_flags,
187
+									int fproto, int flags)
186 188
 {
187 189
 	char *shbuf;
188 190
 	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,
198 198
 	int backup_route_type;
199 199
 	snd_flags_t fwd_snd_flags_bak;
200 200
 	snd_flags_t rpl_snd_flags_bak;
201
+	struct socket_info *force_send_socket_bak;
201 202
 	struct dest_info *dst;
202 203
 
203 204
 	shbuf=0;
... ...
@@ -321,17 +326,22 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
321 321
 			   (
322 322
 			 */
323 323
 			if (exec_pre_script_cb(i_req, BRANCH_CB_TYPE)>0) {
324
-				/* backup ireq msg send flags */
324
+				/* backup ireq msg send flags and force_send_socket*/
325 325
 				fwd_snd_flags_bak=i_req->fwd_send_flags;;
326 326
 				rpl_snd_flags_bak=i_req->rpl_send_flags;
327
-				i_req->fwd_send_flags=dst->send_flags /* intial value  */;
327
+				force_send_socket_bak=i_req->force_send_socket;
328
+				/* set the new values */
329
+				i_req->fwd_send_flags=snd_flags /* intial value  */;
330
+				set_force_socket(i_req, fsocket);
328 331
 				if (run_top_route(branch_rt.rlist[branch_route], i_req, 0) < 0)
329 332
 				{
330 333
 					LOG(L_ERR, "Error in run_top_route\n");
331 334
 				}
332
-				/* update dst send_flags */
333
-				dst->send_flags=i_req->fwd_send_flags;
334
-				/* restore ireq_msg flags */
335
+				/* update dst send_flags  and send socket*/
336
+				snd_flags=i_req->fwd_send_flags;
337
+				fsocket=i_req->force_send_socket;
338
+				/* restore ireq_msg force_send_socket & flags */
339
+				set_force_socket(i_req, force_send_socket_bak);
335 340
 				i_req->fwd_send_flags=fwd_snd_flags_bak;
336 341
 				i_req->rpl_send_flags=rpl_snd_flags_bak;
337 342
 				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,
376 376
 	if (likely(next_hop!=0 || (flags & UAC_DNS_FAILOVER_F))){
377 377
 		/* next_hop present => use it for dns resolution */
378 378
 #ifdef USE_DNS_FAILOVER
379
-		if (uri2dst(&t->uac[branch].dns_h, dst, i_req,
379
+		if (uri2dst2(&t->uac[branch].dns_h, dst, fsocket, snd_flags,
380 380
 							next_hop?next_hop:uri, fproto) == 0)
381 381
 #else
382 382
 		/* dst filled from the uri & request (send_socket) */
383
-		if (uri2dst(dst, i_req, next_hop?next_hop:uri, fproto)==0)
383
+		if (uri2dst2(dst, fsocket, snd_flags,
384
+							next_hop?next_hop:uri, fproto)==0)
384 385
 #endif
385 386
 		{
386 387
 			ret=E_BAD_ADDRESS;
... ...
@@ -452,6 +463,7 @@ error03:
452 452
 	i_req->parsed_uri=parsed_uri_bak;
453 453
 	i_req->parsed_uri_ok=parsed_uri_ok_bak;
454 454
 	i_req->path_vec=path_bak;
455
+	
455 456
 	/* Delete the duplicated lump lists, this will also delete
456 457
 	 * all lumps created here, such as lumps created in per-branch
457 458
 	 * routing sections, Via, and Content-Length headers created in
... ...
@@ -603,6 +615,8 @@ int add_blind_uac( /*struct cell *t*/ )
603 603
  *                     uri format, e.g.: "<sip:1.2.3.4;lr>, <sip:5.6.7.8;lr>").
604 604
  *  @param proxy    - proxy structure. If non-null it takes precedence over
605 605
  *                    next_hop/uri and it will be used for forwarding.
606
+ *  @param fsocket  - forced forward send socket (can be 0).
607
+ *  @param snd_flags - special send flags (see SND_F_* / snd_flags_t)
606 608
  *  @param proto    - forced protocol for forwarding (overrides the protocol
607 609
  *                    in next_hop/uri or proxy if != PROTO_NONE).
608 610
  *  @param flags    - special flags passed to prepare_new_uac().
... ...
@@ -611,6 +625,7 @@ int add_blind_uac( /*struct cell *t*/ )
611 611
 */
612 612
 static int add_uac( struct cell *t, struct sip_msg *request, str *uri,
613 613
 					str* next_hop, str* path, struct proxy_l *proxy,
614
+					struct socket_info* fsocket, snd_flags_t snd_flags,
614 615
 					int proto, int flags)
615 616
 {
616 617
 
... ...
@@ -653,7 +668,8 @@ static int add_uac( struct cell *t, struct sip_msg *request, str *uri,
653 653
 
654 654
 	/* now message printing starts ... */
655 655
 	if (unlikely( (ret=prepare_new_uac(t, request, branch, uri, path,
656
-											next_hop, proto, flags)) < 0)){
656
+										next_hop, fsocket, snd_flags,
657
+										proto, flags)) < 0)){
657 658
 		ser_error=ret;
658 659
 		goto error01;
659 660
 	}
... ...
@@ -689,7 +705,10 @@ error:
689 689
    the failed branch to construct the new message in case of DNS failover.
690 690
 */
691 691
 static int add_uac_from_buf( struct cell *t, struct sip_msg *request,
692
-								str *uri, str* path, int proto,
692
+								str *uri, str* path,
693
+								struct socket_info* fsocket,
694
+								snd_flags_t send_flags,
695
+								int proto,
693 696
 								char *buf, short buf_len)
694 697
 {
695 698
 
... ...
@@ -713,8 +732,8 @@ static int add_uac_from_buf( struct cell *t, struct sip_msg *request,
713 713
 		goto error;
714 714
 	}
715 715
 
716
-	if (uri2dst(&t->uac[branch].dns_h, &t->uac[branch].request.dst,
717
-				request, uri, proto) == 0)
716
+	if (uri2dst2(&t->uac[branch].dns_h, &t->uac[branch].request.dst,
717
+					fsocket, send_flags, uri, proto) == 0)
718 718
 	{
719 719
 		ret=ser_error=E_BAD_ADDRESS;
720 720
 		goto error;
... ...
@@ -820,21 +839,29 @@ int add_uac_dns_fallback(struct cell *t, struct sip_msg* msg,
820 820
 			dns_srv_handle_cpy(&t->uac[t->nr_of_outgoings].dns_h,
821 821
 								&old_uac->dns_h);
822 822
 
823
-			if (cfg_get(tm, tm_cfg, reparse_on_dns_failover))
823
+			if (cfg_get(tm, tm_cfg, reparse_on_dns_failover)){
824 824
 				/* Reuse the old buffer and only replace the via header.
825 825
 				 * The drawback is that the send_socket is not corrected
826 826
 				 * in the rest of the message, only in the VIA HF (Miklos) */
827 827
 				ret=add_uac_from_buf(t,  msg, &old_uac->uri,
828 828
 							&old_uac->path,
829
+							 (old_uac->request.dst.send_flags &
830
+								SND_F_FORCE_SOCKET)?
831
+									old_uac->request.dst.send_sock:0,
832
+							old_uac->request.dst.send_flags,
829 833
 							old_uac->request.dst.proto,
830 834
 							old_uac->request.buffer,
831 835
 							old_uac->request.buffer_len);
832
-			else
836
+			}else
833 837
 				/* add_uac will use dns_h => next_hop will be ignored.
834 838
 				 * Unfortunately we can't reuse the old buffer, the branch id
835 839
 				 *  must be changed and the send_socket might be different =>
836 840
 				 *  re-create the whole uac */
837 841
 				ret=add_uac(t,  msg, &old_uac->uri, 0, &old_uac->path, 0,
842
+							 (old_uac->request.dst.send_flags &
843
+								SND_F_FORCE_SOCKET)?
844
+									old_uac->request.dst.send_sock:0,
845
+							old_uac->request.dst.send_flags,
838 846
 							old_uac->request.dst.proto, UAC_DNS_FAILOVER_F);
839 847
 
840 848
 			if (ret<0){
... ...
@@ -906,7 +933,7 @@ int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel,
906 906
 		if (unlikely((ret=prepare_new_uac( t_cancel, cancel_msg, branch,
907 907
 									&t_invite->uac[branch].uri,
908 908
 									&t_invite->uac[branch].path,
909
-									0, PROTO_NONE, 0)) <0)){
909
+									0, 0, 0, PROTO_NONE, 0)) <0)){
910 910
 			ser_error=ret;
911 911
 			goto error;
912 912
 		}
... ...
@@ -1242,7 +1269,7 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
1242 1242
 	int try_new;
1243 1243
 	int lock_replies;
1244 1244
 	str dst_uri, path;
1245
-	struct socket_info* si, *backup_si;
1245
+	struct socket_info* si;
1246 1246
 	flag_t backup_bflags = 0;
1247 1247
 	flag_t bflags = 0;
1248 1248
 	
... ...
@@ -1267,7 +1294,6 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
1267 1267
 		}
1268 1268
 	}
1269 1269
 
1270
-	backup_si = p_msg->force_send_socket;
1271 1270
 	getbflagsval(0, &backup_bflags);
1272 1271
 
1273 1272
 	/* 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 ,
1303 1303
 #endif
1304 1304
 		try_new=1;
1305 1305
 		branch_ret=add_uac( t, p_msg, GET_RURI(p_msg), GET_NEXT_HOP(p_msg),
1306
-							&p_msg->path_vec, proxy, proto, 0);
1306
+							&p_msg->path_vec, proxy, p_msg->force_send_socket,
1307
+							p_msg->fwd_send_flags, proto, 0);
1307 1308
 		if (branch_ret>=0) 
1308 1309
 			added_branches |= 1<<branch_ret;
1309 1310
 		else
... ...
@@ -1314,12 +1341,12 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
1314 1314
 	while((current_uri.s=next_branch( &current_uri.len, &q, &dst_uri, &path,
1315 1315
 										&bflags, &si))) {
1316 1316
 		try_new++;
1317
-		p_msg->force_send_socket = si;
1318 1317
 		setbflagsval(0, bflags);
1319 1318
 
1320 1319
 		branch_ret=add_uac( t, p_msg, &current_uri,
1321 1320
 							(dst_uri.len) ? (&dst_uri) : &current_uri,
1322
-							&path, proxy, proto, 0);
1321
+							&path, proxy, si, p_msg->fwd_send_flags,
1322
+							proto, 0);
1323 1323
 		/* pick some of the errors in case things go wrong;
1324 1324
 		   note that picking lowest error is just as good as
1325 1325
 		   any other algorithm which picks any other negative
... ...
@@ -1332,7 +1359,6 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
1332 1332
 	/* consume processed branches */
1333 1333
 	clear_branches();
1334 1334
 
1335
-	p_msg->force_send_socket = backup_si;
1336 1335
 	setbflagsval(0, backup_bflags);
1337 1336
 
1338 1337
 	/* don't forget to clear all branches processed so far */