Browse code

modules/tm: Update t_next_contact_flows for use in branch_failure event_route

- Rename to t_next_contact_flow as only one flow will be used
- Selects and uses the next flow with the same instance_id as the failed branch

Hugh Waite authored on 26/03/2013 12:10:11
Showing 3 changed files
... ...
@@ -588,7 +588,7 @@ int t_next_contacts(struct sip_msg* msg, char* key, char* value)
588 588
         vavp = xavp_get(&ruid_name, xavp->val.v.xavp);
589 589
         ruid = vavp->val.v.s;
590 590
 
591
-	if (append_branch(msg, &uri, &dst_uri, &path, 0, flags, sock, 0, 0,
591
+	if (append_branch(msg, &uri, &dst_uri, &path, 0, flags, sock, &instance, 0,
592 592
 			  &ruid) != 1) {
593 593
 	    LM_ERR("appending branch failed\n");
594 594
 	    free_instance_list(il);
... ...
@@ -622,15 +622,17 @@ int t_next_contacts(struct sip_msg* msg, char* key, char* value)
622 622
  * Returns 1, if contact_flows_avp was not empty and a destination set was
623 623
  * successfully added.  Returns -2, if contact_flows_avp was empty and thus
624 624
  * there was nothing to do. Returns -1 in case of an error. */
625
-int t_next_contact_flows(struct sip_msg* msg, char* key, char* value)
625
+int t_next_contact_flow(struct sip_msg* msg, char* key, char* value)
626 626
 {
627 627
     str uri, dst_uri, path, instance, host, ruid;
628
+	str this_instance;
629
+	int this_branch;
628 630
     struct socket_info *sock;
629 631
     unsigned int flags;
630 632
     sr_xavp_t *xavp_list, *xavp, *next_xavp, *vavp;
631 633
     char *tmp;
632 634
     int port, proto;
633
-    struct instance_list *il, *ilp;
635
+	int q_dummy;
634 636
 
635 637
     /* Check if contact_flows_avp has been defined */
636 638
     if (contact_flows_avp.len == 0) {
... ...
@@ -640,208 +642,89 @@ int t_next_contact_flows(struct sip_msg* msg, char* key, char* value)
640 640
     }
641 641
 
642 642
     /* Load Request-URI and branches */
643
-
644
-    /* Find first contact_flows_avp value */
645
-    xavp_list = xavp_get(&contact_flows_avp, NULL);
646
-    if (!xavp_list) {
647
-	LM_DBG("no contacts in contact_flows_avp - we are done!\n");
648
-	return -2;
649
-    }
650
-
651
-    xavp = xavp_list;
652
-    next_xavp = xavp_get_next(xavp);
653
-
654
-    vavp = xavp_get(&uri_name, xavp->val.v.xavp);
655
-    uri = vavp->val.v.s;
656
-
657
-    vavp = xavp_get(&dst_uri_name, xavp->val.v.xavp);
658
-    if (vavp != NULL) {
659
-	dst_uri = vavp->val.v.s;
660
-    } else {
661
-	dst_uri.s = 0;
662
-	dst_uri.len = 0;
663
-    }
664
-
665
-    vavp = xavp_get(&path_name, xavp->val.v.xavp);
666
-    if (vavp != NULL) {
667
-	path = vavp->val.v.s;
668
-    } else {
669
-	path.s = 0;
670
-	path.len = 0;
671
-    }
672
-
673
-    vavp = xavp_get(&sock_name, xavp->val.v.xavp);
674
-    if (vavp != NULL) {
675
-	tmp = vavp->val.v.s.s;
676
-	if (parse_phostport(tmp, &host.s, &host.len, &port, &proto) != 0) {
677
-	    LM_ERR("parsing of socket info <%s> failed\n", tmp);
678
-	    xavp_destroy_list(&xavp_list);
679
-	    return -1;
643
+	this_branch = get_t_branch();
644
+	uri.s = get_branch(this_branch, &uri.len, &q_dummy, NULL, NULL, NULL, NULL, &this_instance);
645
+
646
+	/* Find first contact_flows_avp value */
647
+	xavp_list = xavp_get(&contact_flows_avp, NULL);
648
+	if (!xavp_list) {
649
+		LM_DBG("no contacts in contact_flows_avp - we are done!\n");
650
+		return -2;
680 651
 	}
681
-	sock = grep_sock_info(&host, (unsigned short)port,
682
-			      (unsigned short)proto);
683
-	if (sock == 0) {
684
-	    xavp_destroy_list(&xavp_list);
685
-	    return -1;
686
-	}
687
-    } else {
688
-	sock = NULL;
689
-    }
690
-
691
-    vavp = xavp_get(&flags_name, xavp->val.v.xavp);
692
-    flags = vavp->val.v.i;
693
-
694
-    vavp = xavp_get(&instance_name, xavp->val.v.xavp);
695
-    il = (struct instance_list *)0;
696
-    if ((vavp != NULL) && next_xavp) {
697
-	instance = vavp->val.v.s;
698
-	il = (struct instance_list *)pkg_malloc(sizeof(struct instance_list));
699
-	if (!il) {
700
-	    LM_ERR("no memory for instance list entry\n");
701
-	    return -1;
702
-	}
703
-	il->instance.s = pkg_malloc(instance.len);
704
-	if (!il->instance.s) {
705
-	    pkg_free(il);
706
-	    LM_ERR("no memory for instance list instance\n");
707
-	    return -1;
708
-	}
709
-	il->instance.len = instance.len;
710
-	memcpy(il->instance.s, instance.s, instance.len);
711
-	il->next = (struct instance_list *)0;
712
-    }
713
-
714
-    vavp = xavp_get(&ruid_name, xavp->val.v.xavp);
715
-    ruid = vavp->val.v.s;
716
-
717
-    /* Rewrite Request-URI */
718
-    rewrite_uri(msg, &uri);
719
-
720
-    if (dst_uri.len) {
721
-	set_dst_uri(msg, &dst_uri);
722
-    } else {
723
-	reset_dst_uri(msg);
724
-    }
725
-
726
-    if (path.len) {
727
-	set_path_vector(msg, &path);
728
-    } else {
729
-	reset_path_vector(msg);
730
-    }
731
-
732
-    set_force_socket(msg, sock);
733
-
734
-    set_ruid(msg, &ruid);
735
-
736
-    setbflagsval(0, flags);
737 652
 
738
-    /* Append branches until out of branches. */
739
-    /* Do not include a branch that has same instance value as some */
740
-    /* previous branch. */
653
+	xavp = xavp_list;
741 654
 
742
-    xavp_rm(xavp, NULL);
743
-    xavp = next_xavp;
655
+	while (xavp) {
656
+		next_xavp = xavp_get_next(xavp);
744 657
 
745
-    while (xavp) {
746
-	
747
-	next_xavp = xavp_get_next(xavp);
748
-
749
-	vavp = xavp_get(&instance_name, xavp->val.v.xavp);
750
-	if (vavp != NULL) {
751
-	    instance = vavp->val.v.s;
752
-	    ilp = il;
753
-	    while (ilp) {
754
-		if ((instance.len == ilp->instance.len) &&
755
-		    (strncmp(instance.s, ilp->instance.s, instance.len) == 0))
756
-		    break;
757
-		ilp = ilp->next;
758
-	    }
759
-	    if (ilp) {
760
-		/* skip already appended instance */
761
-		xavp = next_xavp;
762
-		continue;
763
-	    }
764
-	    if (next_xavp) {
765
-		ilp = (struct instance_list *)
766
-		pkg_malloc(sizeof(struct instance_list));
767
-		if (!ilp) {
768
-		    LM_ERR("no memory for new instance list entry\n");
769
-		    free_instance_list(il);
770
-		    return -1;
658
+	   	vavp = xavp_get(&instance_name, xavp->val.v.xavp);
659
+		if (vavp == NULL)
660
+		{
661
+			/* Does not match this instance */
662
+			goto next_xavp;
771 663
 		}
772
-		ilp->instance.s = pkg_malloc(instance.len);
773
-		if (!ilp->instance.s) {
774
-		    pkg_free(il);
775
-		    LM_ERR("no memory for instance list instance\n");
776
-		    return -1;
664
+		else
665
+		{
666
+			instance = vavp->val.v.s;
667
+			if ((instance.len != this_instance.len) ||
668
+			    (strncmp(instance.s, this_instance.s, instance.len) != 0))
669
+				/* Does not match this instance */
670
+				goto next_xavp;
777 671
 		}
778
-		ilp->instance.len = instance.len;
779
-		memcpy(ilp->instance.s, instance.s, instance.len);
780
-		ilp->next = il;
781
-		il = ilp;
782
-	    } else {
783
-		LM_ERR("instance missing from contact_flow_avp contact\n");
784
-		free_instance_list(il);
785
-		return -1;
786
-	    }
787
-	}
788 672
 
789
-	vavp = xavp_get(&uri_name, xavp->val.v.xavp);
790
-	uri = vavp->val.v.s;
673
+		vavp = xavp_get(&uri_name, xavp->val.v.xavp);
674
+		uri = vavp->val.v.s;
791 675
 
792
-	vavp = xavp_get(&dst_uri_name, xavp->val.v.xavp);
793
-	if (vavp != NULL) {
794
-	    dst_uri = vavp->val.v.s;
795
-	} else {
796
-	    dst_uri.len = 0;
797
-	}
676
+		vavp = xavp_get(&dst_uri_name, xavp->val.v.xavp);
677
+		if (vavp != NULL) {
678
+			dst_uri = vavp->val.v.s;
679
+		} else {
680
+			dst_uri.len = 0;
681
+		}
798 682
 
799
-	vavp = xavp_get(&path_name, xavp->val.v.xavp);
800
-	if (vavp != NULL) {
801
-	    path = vavp->val.v.s;
802
-	} else {
803
-	    path.len = 0;
804
-	}
683
+		vavp = xavp_get(&path_name, xavp->val.v.xavp);
684
+		if (vavp != NULL) {
685
+			path = vavp->val.v.s;
686
+		} else {
687
+			path.len = 0;
688
+		}
805 689
 
806
-	vavp = xavp_get(&sock_name, xavp->val.v.xavp);
807
-	if (vavp != NULL) {
808
-	    tmp = vavp->val.v.s.s;
809
-	    if (parse_phostport(tmp, &host.s, &host.len, &port, &proto) != 0) {
810
-		LM_ERR("parsing of socket info <%s> failed\n", tmp);
811
-		free_instance_list(il);
812
-		xavp_destroy_list(&xavp_list);
813
-		return -1;
814
-	    }
815
-	    sock = grep_sock_info(&host, (unsigned short)port,
690
+		vavp = xavp_get(&sock_name, xavp->val.v.xavp);
691
+		if (vavp != NULL) {
692
+			tmp = vavp->val.v.s.s;
693
+			if (parse_phostport(tmp, &host.s, &host.len, &port, &proto) != 0) {
694
+				LM_ERR("parsing of socket info <%s> failed\n", tmp);
695
+				xavp_rm(xavp, NULL);
696
+				return -1;
697
+			}
698
+			sock = grep_sock_info(&host, (unsigned short)port,
816 699
 				  (unsigned short)proto);
817
-	    if (sock == 0) {
818
-		free_instance_list(il);
819
-		xavp_destroy_list(&xavp_list);
820
-		return -1;
821
-	    }
822
-	} else {
823
-	    sock = NULL;
824
-	}
700
+			if (sock == 0) {
701
+				xavp_rm(xavp, NULL);
702
+				return -1;
703
+			}
704
+		} else {
705
+			sock = NULL;
706
+		}
825 707
 
826
-	vavp = xavp_get(&flags_name, xavp->val.v.xavp);
827
-	flags = vavp->val.v.i;
708
+		vavp = xavp_get(&flags_name, xavp->val.v.xavp);
709
+		flags = vavp->val.v.i;
828 710
 
829
-        vavp = xavp_get(&ruid_name, xavp->val.v.xavp);
830
-        ruid = vavp->val.v.s;
711
+		vavp = xavp_get(&ruid_name, xavp->val.v.xavp);
712
+		ruid = vavp->val.v.s;
831 713
 
832
-	if (append_branch(msg, &uri, &dst_uri, &path, 0, flags, sock, 0, 0,
714
+		if (append_branch(msg, &uri, &dst_uri, &path, 0, flags, sock, &instance, 0,
833 715
 			  &ruid) != 1) {
834
-	    LM_ERR("appending branch failed\n");
835
-	    free_instance_list(il);
836
-	    xavp_destroy_list(&xavp_list);
837
-	    return -1;
838
-	}
716
+			LM_ERR("appending branch failed\n");
717
+			xavp_destroy_list(&xavp_list);
718
+			return -1;
719
+		}
839 720
 
840
-	xavp_rm(xavp, NULL);
841
-	xavp = next_xavp;
842
-    }
721
+		xavp_rm(xavp, NULL);
722
+next_xavp:
723
+		xavp = next_xavp;
724
+	}
843 725
 
844
-    free_instance_list(il);
845 726
 
846
-    return 1;
727
+	return 1;
847 728
 }
... ...
@@ -34,4 +34,4 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value);
34 34
 
35 35
 int t_next_contacts(struct sip_msg* msg, char* key, char* value);
36 36
 
37
-int t_next_contact_flows(struct sip_msg* msg, char* key, char* value);
37
+int t_next_contact_flow(struct sip_msg* msg, char* key, char* value);
... ...
@@ -475,8 +475,8 @@ static cmd_export_t cmds[]={
475 475
 			REQUEST_ROUTE | FAILURE_ROUTE},
476 476
 	{"t_next_contacts", t_next_contacts,            0, 0,
477 477
 			REQUEST_ROUTE | FAILURE_ROUTE},
478
-	{"t_next_contact_flows", t_next_contact_flows,            0, 0,
479
-			REQUEST_ROUTE | FAILURE_ROUTE},
478
+	{"t_next_contact_flow", t_next_contact_flow,            0, 0,
479
+			REQUEST_ROUTE | BRANCH_FAILURE_ROUTE},
480 480
 
481 481
 	/* not applicable from the script */
482 482
 	{"load_tm",            (cmd_function)load_tm,           NO_SCRIPT,   0, 0},
... ...
@@ -1444,7 +1444,7 @@ inline static int _w_t_relay_to(struct sip_msg  *p_msg ,
1444 1444
 	struct cell *t;
1445 1445
 	int res;
1446 1446
 
1447
-	if (is_route_type(FAILURE_ROUTE)) {
1447
+	if (is_route_type(FAILURE_ROUTE|BRANCH_FAILURE_ROUTE)) {
1448 1448
 		t=get_t();
1449 1449
 		if (!t || t==T_UNDEFINED) {
1450 1450
 			LOG(L_CRIT, "BUG: w_t_relay_to: undefined T\n");