Explorar o código

itm: init sock_str to null value if no sock pointer is set in branch

- case of creating branches from a 3xx reply
- reported by juliabo [at] gmail
- identation made coherent with tm module style
- corresponding to master commit 254d0c43a84ec87801e58b4f990a2029c0e27c6f
Daniel-Constantin Mierla %!s(int64=12) %!d(string=hai) anos
pai
achega
c3e5b2cbf9
Modificáronse 1 ficheiros con 598 adicións e 595 borrados
  1. 598 595
      modules/tm/t_serial.c

+ 598 - 595
modules/tm/t_serial.c

@@ -44,45 +44,45 @@
 
 /* Struture where information regarding contacts is stored */
 struct contact {
-    str uri;
-    qvalue_t q;
-    str dst_uri;
-    str path;
-    struct socket_info* sock;
-    str instance;
-    unsigned int flags;
-    unsigned short q_flag;
-    struct contact *next;
+	str uri;
+	qvalue_t q;
+	str dst_uri;
+	str path;
+	struct socket_info* sock;
+	str instance;
+	unsigned int flags;
+	unsigned short q_flag;
+	struct contact *next;
 };
 
 struct instance_list {
-    str instance;
-    struct instance_list *next;
+	str instance;
+	struct instance_list *next;
 };
 
 /* 
  * Frees contact list used by load_contacts function
  */
 static inline void free_contact_list(struct contact *curr) {
-    struct contact *prev;
-    while (curr) {
+	struct contact *prev;
+	while (curr) {
 		prev = curr;
 		curr = curr->next;
 		pkg_free(prev);
-    }
+	}
 }
 
 /* 
  * Frees instance list used by next_contacts function
  */
 static inline void free_instance_list(struct instance_list *curr) {
-    struct instance_list *prev;
-    while (curr) {
-	pkg_free(curr->instance.s);
-	prev = curr;
-	curr = curr->next;
-	pkg_free(prev);
-    }
+	struct instance_list *prev;
+	while (curr) {
+		pkg_free(curr->instance.s);
+		prev = curr;
+		curr = curr->next;
+		pkg_free(prev);
+	}
 }
 
 static str uri_name = {"uri", 3};
@@ -94,51 +94,51 @@ static str flags_name = {"flags", 5};
 static str q_flag_name = {"q_flag", 6};
 
 void add_contacts_avp(str *uri, str *dst_uri, str *path, str *sock_str,
-		      unsigned int flags, unsigned int q_flag, str *instance)
+		unsigned int flags, unsigned int q_flag, str *instance)
 {
-    sr_xavp_t *record;
-    sr_xval_t val;
+	sr_xavp_t *record;
+	sr_xval_t val;
 
-    record = NULL;
+	record = NULL;
 
-    val.type = SR_XTYPE_STR;
-    val.v.s = *uri;
-    xavp_add_value(&uri_name, &val, &record);
-
-    if (dst_uri->len > 0) {
 	val.type = SR_XTYPE_STR;
-	val.v.s = *dst_uri;
-	xavp_add_value(&dst_uri_name, &val, &record);
-    }
+	val.v.s = *uri;
+	xavp_add_value(&uri_name, &val, &record);
 
-    if (path->len > 0) {
-	val.type = SR_XTYPE_STR;
-	val.v.s = *path;
-	xavp_add_value(&path_name, &val, &record);
-    }
+	if (dst_uri->len > 0) {
+		val.type = SR_XTYPE_STR;
+		val.v.s = *dst_uri;
+		xavp_add_value(&dst_uri_name, &val, &record);
+	}
+
+	if (path->len > 0) {
+		val.type = SR_XTYPE_STR;
+		val.v.s = *path;
+		xavp_add_value(&path_name, &val, &record);
+	}
 
-    if (sock_str->len > 0) {
-	val.v.s = *sock_str;
-	xavp_add_value(&sock_name, &val, &record);
-    }
+	if (sock_str->len > 0) {
+		val.v.s = *sock_str;
+		xavp_add_value(&sock_name, &val, &record);
+	}
 
-    val.type = SR_XTYPE_INT;
-    val.v.i = flags;
-    xavp_add_value(&flags_name, &val, &record);
+	val.type = SR_XTYPE_INT;
+	val.v.i = flags;
+	xavp_add_value(&flags_name, &val, &record);
 
-    val.type = SR_XTYPE_INT;
-    val.v.i = q_flag;
-    xavp_add_value(&q_flag_name, &val, &record);
+	val.type = SR_XTYPE_INT;
+	val.v.i = q_flag;
+	xavp_add_value(&q_flag_name, &val, &record);
 
-    if (instance->len > 0) {
-	val.type = SR_XTYPE_STR;
-	val.v.s = *instance;
-	xavp_add_value(&instance_name, &val, &record);
-    }
+	if (instance->len > 0) {
+		val.type = SR_XTYPE_STR;
+		val.v.s = *instance;
+		xavp_add_value(&instance_name, &val, &record);
+	}
 
-    val.type = SR_XTYPE_XAVP;
-    val.v.xavp = record;
-    xavp_add_value(&contacts_avp, &val, NULL);
+	val.type = SR_XTYPE_XAVP;
+	val.v.xavp = record;
+	xavp_add_value(&contacts_avp, &val, NULL);
 }
 
 /* 
@@ -149,196 +149,199 @@ void add_contacts_avp(str *uri, str *dst_uri, str *path, str *sock_str,
  */
 int t_load_contacts(struct sip_msg* msg, char* key, char* value)
 {
-    branch_t *branch;
-    str *ruri, sock_str;
-    struct contact *contacts, *next, *prev, *curr;
-    int first_idx, idx, len;
-    char sock_buf[MAX_SOCKET_STR];
-
-    /* Check if contacts_avp has been defined */
-    if (contacts_avp.len == 0) {
-	LM_ERR("feature has been disabled - "
-	       "to enable define contacts_avp module parameter");
-	return -1;
-    }
-
-    /* Check if anything needs to be done */
-    LM_DBG("nr_branches is %d\n", nr_branches);
-
-    if ((nr_branches == 0) || ((nr_branches == 1) && !ruri_is_new)) {
-	LM_DBG("nothing to do - only one contact!\n");
-	return 1;
-    }
-
-    /* Allocate memory for first contact */
-    contacts = (struct contact *)pkg_malloc(sizeof(struct contact));
-    if (!contacts) {
-	LM_ERR("no memory for contact info\n");
-	return -1;
-    }
-
-    if (ruri_is_new) {
-	ruri = GET_RURI(msg);
-	if (!ruri) {
-	    LM_ERR("no Request-URI found\n");
-	    return -1;
-	}	
-	/* Insert Request-URI branch to first contact */
-	contacts->uri.s = ruri->s;
-	contacts->uri.len = ruri->len;
-	contacts->dst_uri = msg->dst_uri;
-	contacts->sock = msg->force_send_socket;
-	getbflagsval(0, &contacts->flags);
-	contacts->path = msg->path_vec;
-	contacts->q = get_ruri_q();
-	contacts->instance = msg->instance;
-	first_idx = 0;
-    } else {
-	/* Insert first branch to first contact */
-	branch = get_sip_branch(0);
-	contacts->uri.s = branch->uri;
-	contacts->uri.len = branch->len;
-	contacts->dst_uri.s = branch->dst_uri;
-	contacts->dst_uri.len = branch->dst_uri_len;
-	contacts->sock = branch->force_send_socket;
-	contacts->flags = branch->flags;
-	contacts->path.s = branch->path;
-	contacts->path.len = branch->path_len;
-	contacts->q = branch->q;
-	contacts->instance.s = branch->instance;
-	contacts->instance.len = branch->instance_len;
-	first_idx = 1;
-    }
-
-    contacts->next = (struct contact *)0;
-
-    /* Insert (remaining) branches to contact list in increasing q order */
-    for (idx = first_idx; (branch = get_sip_branch(idx)) != 0; idx++) {
-
-	next = (struct contact *)pkg_malloc(sizeof(struct contact));
-	if (!next) {
-	    LM_ERR("no memory for contact info\n");
-	    free_contact_list(contacts);
-	    return -1;
-	}
-
-	next->uri.s = branch->uri;
-	next->uri.len = branch->len;
-	next->dst_uri.s = branch->dst_uri;
-	next->dst_uri.len = branch->dst_uri_len;
-	next->sock = branch->force_send_socket;
-	next->flags = branch->flags;
-	next->path.s = branch->path;
-	next->path.len = branch->path_len;
-	next->q = branch->q;
-	next->instance.s = branch->instance;
-	next->instance.len = branch->instance_len;
-	next->next = (struct contact *)0;
-
-	prev = (struct contact *)0;
-	curr = contacts;
-	while (curr && (curr->q < branch->q)) {
-	    prev = curr;
-	    curr = curr->next;
+	branch_t *branch;
+	str *ruri, sock_str;
+	struct contact *contacts, *next, *prev, *curr;
+	int first_idx, idx, len;
+	char sock_buf[MAX_SOCKET_STR];
+
+	/* Check if contacts_avp has been defined */
+	if (contacts_avp.len == 0) {
+		LM_ERR("feature has been disabled - "
+				"to enable define contacts_avp module parameter");
+		return -1;
 	}
-	if (!curr) {
-	    next->next = (struct contact *)0;
-	    prev->next = next;
-	} else {
-	    next->next = curr;
-	    if (prev) {
-		prev->next = next;
-	    } else {
-		contacts = next;
-	    }
-	}    
-    }
-
-    /* Assign values for q_flags */
-    curr = contacts;
-    curr->q_flag = 0;
-    while (curr->next) {
-	if (curr->q < curr->next->q) {
-	    curr->next->q_flag = Q_FLAG;
+
+	/* Check if anything needs to be done */
+	LM_DBG("nr_branches is %d\n", nr_branches);
+
+	if ((nr_branches == 0) || ((nr_branches == 1) && !ruri_is_new)) {
+		LM_DBG("nothing to do - only one contact!\n");
+		return 1;
+	}
+
+	/* Allocate memory for first contact */
+	contacts = (struct contact *)pkg_malloc(sizeof(struct contact));
+	if (!contacts) {
+		LM_ERR("no memory for contact info\n");
+		return -1;
+	}
+
+	if (ruri_is_new) {
+		ruri = GET_RURI(msg);
+		if (!ruri) {
+			LM_ERR("no Request-URI found\n");
+			return -1;
+		}	
+		/* Insert Request-URI branch to first contact */
+		contacts->uri.s = ruri->s;
+		contacts->uri.len = ruri->len;
+		contacts->dst_uri = msg->dst_uri;
+		contacts->sock = msg->force_send_socket;
+		getbflagsval(0, &contacts->flags);
+		contacts->path = msg->path_vec;
+		contacts->q = get_ruri_q();
+		contacts->instance = msg->instance;
+		first_idx = 0;
 	} else {
-	    curr->next->q_flag = 0;
+		/* Insert first branch to first contact */
+		branch = get_sip_branch(0);
+		contacts->uri.s = branch->uri;
+		contacts->uri.len = branch->len;
+		contacts->dst_uri.s = branch->dst_uri;
+		contacts->dst_uri.len = branch->dst_uri_len;
+		contacts->sock = branch->force_send_socket;
+		contacts->flags = branch->flags;
+		contacts->path.s = branch->path;
+		contacts->path.len = branch->path_len;
+		contacts->q = branch->q;
+		contacts->instance.s = branch->instance;
+		contacts->instance.len = branch->instance_len;
+		first_idx = 1;
 	}
-	curr = curr->next;
-    }
 
-    /* Add contacts to contacts_avp */
-    curr = contacts;
-    while (curr) {
+	contacts->next = (struct contact *)0;
 
-	if (curr->sock) {
-	    len = MAX_SOCKET_STR - 1;
-	    if (socket2str(sock_buf, &len, curr->sock) < 0) {
-		LM_ERR("failed to convert socket to str\n");
-		return -1;
-	    }
-	    sock_buf[len] = 0;
-	    sock_str.s = sock_buf;
-	    sock_str.len = len + 1;
+	/* Insert (remaining) branches to contact list in increasing q order */
+	for (idx = first_idx; (branch = get_sip_branch(idx)) != 0; idx++) {
+
+		next = (struct contact *)pkg_malloc(sizeof(struct contact));
+		if (!next) {
+			LM_ERR("no memory for contact info\n");
+			free_contact_list(contacts);
+			return -1;
+		}
+
+		next->uri.s = branch->uri;
+		next->uri.len = branch->len;
+		next->dst_uri.s = branch->dst_uri;
+		next->dst_uri.len = branch->dst_uri_len;
+		next->sock = branch->force_send_socket;
+		next->flags = branch->flags;
+		next->path.s = branch->path;
+		next->path.len = branch->path_len;
+		next->q = branch->q;
+		next->instance.s = branch->instance;
+		next->instance.len = branch->instance_len;
+		next->next = (struct contact *)0;
+
+		prev = (struct contact *)0;
+		curr = contacts;
+		while (curr && (curr->q < branch->q)) {
+			prev = curr;
+			curr = curr->next;
+		}
+		if (!curr) {
+			next->next = (struct contact *)0;
+			prev->next = next;
+		} else {
+			next->next = curr;
+			if (prev) {
+				prev->next = next;
+			} else {
+				contacts = next;
+			}
+		}    
 	}
 
-	add_contacts_avp(&(curr->uri), &(curr->dst_uri), &(curr->path),
-			 &sock_str, curr->flags, curr->q_flag,
-			 &(curr->instance));
+	/* Assign values for q_flags */
+	curr = contacts;
+	curr->q_flag = 0;
+	while (curr->next) {
+		if (curr->q < curr->next->q) {
+			curr->next->q_flag = Q_FLAG;
+		} else {
+			curr->next->q_flag = 0;
+		}
+		curr = curr->next;
+	}
 
-	curr = curr->next;
-    }
+	/* Add contacts to contacts_avp */
+	curr = contacts;
+	while (curr) {
+
+		if (curr->sock) {
+			len = MAX_SOCKET_STR - 1;
+			if (socket2str(sock_buf, &len, curr->sock) < 0) {
+				LM_ERR("failed to convert socket to str\n");
+				return -1;
+			}
+			sock_buf[len] = 0;
+			sock_str.s = sock_buf;
+			sock_str.len = len + 1;
+		} else {
+			sock_str.s = 0;
+			sock_str.len = 0;
+		}
 
-    /* Clear all branches */
-    clear_branches();
+		add_contacts_avp(&(curr->uri), &(curr->dst_uri), &(curr->path),
+				&sock_str, curr->flags, curr->q_flag,
+				&(curr->instance));
 
-    /* Free contact list */
-    free_contact_list(contacts);
+		curr = curr->next;
+	}
+
+	/* Clear all branches */
+	clear_branches();
 
-    return 1;
+	/* Free contact list */
+	free_contact_list(contacts);
+
+	return 1;
 }
 
 void add_contact_flows_avp(str *uri, str *dst_uri, str *path, str *sock_str,
-			   unsigned int flags, str *instance)
+		unsigned int flags, str *instance)
 {
-    sr_xavp_t *record;
-    sr_xval_t val;
+	sr_xavp_t *record;
+	sr_xval_t val;
 
-    record = NULL;
+	record = NULL;
 
-    val.type = SR_XTYPE_STR;
-    val.v.s = *uri;
-    xavp_add_value(&uri_name, &val, &record);
-
-    if (dst_uri->len > 0) {
 	val.type = SR_XTYPE_STR;
-	val.v.s = *dst_uri;
-	xavp_add_value(&dst_uri_name, &val, &record);
-    }
+	val.v.s = *uri;
+	xavp_add_value(&uri_name, &val, &record);
 
-    if (path->len > 0) {
-	val.type = SR_XTYPE_STR;
-	val.v.s = *path;
-	xavp_add_value(&path_name, &val, &record);
-    }
+	if (dst_uri->len > 0) {
+		val.type = SR_XTYPE_STR;
+		val.v.s = *dst_uri;
+		xavp_add_value(&dst_uri_name, &val, &record);
+	}
 
-    if (sock_str->len > 0) {
-	val.v.s = *sock_str;
-	xavp_add_value(&sock_name, &val, &record);
-    }
+	if (path->len > 0) {
+		val.type = SR_XTYPE_STR;
+		val.v.s = *path;
+		xavp_add_value(&path_name, &val, &record);
+	}
 
-    if (instance->len > 0) {
-	val.type = SR_XTYPE_STR;
-	val.v.s = *instance;
-	xavp_add_value(&instance_name, &val, &record);
-    }
+	if (sock_str->len > 0) {
+		val.v.s = *sock_str;
+		xavp_add_value(&sock_name, &val, &record);
+	}
+
+	if (instance->len > 0) {
+		val.type = SR_XTYPE_STR;
+		val.v.s = *instance;
+		xavp_add_value(&instance_name, &val, &record);
+	}
 
-    val.type = SR_XTYPE_INT;
-    val.v.i = flags;
-    xavp_add_value(&flags_name, &val, &record);
+	val.type = SR_XTYPE_INT;
+	val.v.i = flags;
+	xavp_add_value(&flags_name, &val, &record);
 
-    val.type = SR_XTYPE_XAVP;
-    val.v.xavp = record;
-    xavp_add_value(&contact_flows_avp, &val, NULL);
+	val.type = SR_XTYPE_XAVP;
+	val.v.xavp = record;
+	xavp_add_value(&contact_flows_avp, &val, NULL);
 }
 
 /*
@@ -354,234 +357,234 @@ void add_contact_flows_avp(str *uri, str *dst_uri, str *path, str *sock_str,
  * there was nothing to do. Returns -1 in case of an error. */
 int t_next_contacts(struct sip_msg* msg, char* key, char* value)
 {
-    str uri, dst_uri, path, instance, host, sock_str;
-    struct socket_info *sock;
-    unsigned int flags, q_flag;
-    sr_xavp_t *xavp_list, *xavp, *prev_xavp, *vavp;
-    int port, proto;
-    struct instance_list *il, *ilp;
-
-    /* Check if contacts_avp has been defined */
-    if (contacts_avp.len == 0) {
-	LM_ERR("feature has been disabled - "
-	       "to enable define contacts_avp module parameter");
-	return -1;
-    }
-
-    /* Load Request-URI and branches */
-
-    /* Find first contacts_avp value */
-    xavp_list = xavp_get(&contacts_avp, NULL);
-    if (!xavp_list) {
-	LM_DBG("no contacts in contacts_avp - we are done!\n");
-	return -2;
-    }
-
-    xavp = xavp_list;
-
-    vavp = xavp_get(&uri_name, xavp->val.v.xavp);
-    uri = vavp->val.v.s;
-
-    vavp = xavp_get(&dst_uri_name, xavp->val.v.xavp);
-    if (vavp != NULL) {
-	dst_uri = vavp->val.v.s;
-    } else {
-	dst_uri.s = 0;
-	dst_uri.len = 0;
-    }
-
-    vavp = xavp_get(&path_name, xavp->val.v.xavp);
-    if (vavp != NULL) {
-	path = vavp->val.v.s;
-    } else {
-	path.s = 0;
-	path.len = 0;
-    }
-
-    vavp = xavp_get(&sock_name, xavp->val.v.xavp);
-    if (vavp != NULL) {
-	sock_str.s = vavp->val.v.s.s;
-	if (parse_phostport(sock_str.s, &host.s, &host.len, &port, &proto)
-	    != 0) {
-	    LM_ERR("parsing of socket info <%s> failed\n", sock_str.s);
-	    xavp_destroy_list(&xavp_list);
-	    return -1;
-	}
-	sock = grep_sock_info(&host, (unsigned short)port,
-			      (unsigned short)proto);
-	if (sock == 0) {
-	    xavp_destroy_list(&xavp_list);
-	    return -1;
-	}
-    } else {
-	sock = NULL;
-    }
-
-    vavp = xavp_get(&flags_name, xavp->val.v.xavp);
-    flags = vavp->val.v.i;
-
-    vavp = xavp_get(&q_flag_name, xavp->val.v.xavp);
-    q_flag = vavp->val.v.i;
-
-    vavp = xavp_get(&instance_name, xavp->val.v.xavp);
-    il = (struct instance_list *)0;
-    if ((vavp != NULL) && !q_flag) {
-	instance = vavp->val.v.s;
-	il = (struct instance_list *)pkg_malloc(sizeof(struct instance_list));
-	if (!il) {
-	    LM_ERR("no memory for instance list entry\n");
-	    return -1;
-	}
-	il->instance.s = pkg_malloc(instance.len);
-	if (!il->instance.s) {
-	    pkg_free(il);
-	    LM_ERR("no memory for instance list instance\n");
-	    return -1;
-	}
-	il->instance.len = instance.len;
-	memcpy(il->instance.s, instance.s, instance.len);
-	il->next = (struct instance_list *)0;
-    }
-
-    /* Rewrite Request-URI */
-    rewrite_uri(msg, &uri);
-
-    if (dst_uri.len) {
-	set_dst_uri(msg, &dst_uri);
-    } else {
-	reset_dst_uri(msg);
-    }
-
-    if (path.len) {
-	set_path_vector(msg, &path);
-    } else {
-	reset_path_vector(msg);
-    }
-
-    set_force_socket(msg, sock);
-
-    setbflagsval(0, flags);
-
-    /* Check if there was only one contact at this priority */
-    if (q_flag) {
-	xavp_rm(xavp, NULL);
-	return 1;
-    }
-		
-    /* Append branches until out of branches or Q_FLAG is set */
-    /* If a branch has same instance value as some previous branch, */
-    /* instead of appending it, add it to contact_flows_avp */
-
-    xavp_rm_by_name(&contact_flows_avp, 1, NULL);
-    prev_xavp = xavp;
+	str uri, dst_uri, path, instance, host, sock_str;
+	struct socket_info *sock;
+	unsigned int flags, q_flag;
+	sr_xavp_t *xavp_list, *xavp, *prev_xavp, *vavp;
+	int port, proto;
+	struct instance_list *il, *ilp;
+
+	/* Check if contacts_avp has been defined */
+	if (contacts_avp.len == 0) {
+		LM_ERR("feature has been disabled - "
+				"to enable define contacts_avp module parameter");
+		return -1;
+	}
 
-    while ((xavp = xavp_get_next(prev_xavp)) != NULL) {
+	/* Load Request-URI and branches */
 
-	xavp_rm(prev_xavp, NULL);
+	/* Find first contacts_avp value */
+	xavp_list = xavp_get(&contacts_avp, NULL);
+	if (!xavp_list) {
+		LM_DBG("no contacts in contacts_avp - we are done!\n");
+		return -2;
+	}
 
-	vavp = xavp_get(&q_flag_name, xavp->val.v.xavp);
-	q_flag = vavp->val.v.i;
+	xavp = xavp_list;
 
 	vavp = xavp_get(&uri_name, xavp->val.v.xavp);
 	uri = vavp->val.v.s;
 
 	vavp = xavp_get(&dst_uri_name, xavp->val.v.xavp);
 	if (vavp != NULL) {
-	    dst_uri = vavp->val.v.s;
+		dst_uri = vavp->val.v.s;
 	} else {
-	    dst_uri.len = 0;
+		dst_uri.s = 0;
+		dst_uri.len = 0;
 	}
 
 	vavp = xavp_get(&path_name, xavp->val.v.xavp);
 	if (vavp != NULL) {
-	    path = vavp->val.v.s;
+		path = vavp->val.v.s;
 	} else {
-	    path.len = 0;
+		path.s = 0;
+		path.len = 0;
 	}
 
 	vavp = xavp_get(&sock_name, xavp->val.v.xavp);
 	if (vavp != NULL) {
-	    sock_str = vavp->val.v.s;
-	    if (parse_phostport(sock_str.s, &host.s, &host.len, &port, &proto)
-		!= 0) {
-		LM_ERR("parsing of socket info <%s> failed\n", sock_str.s);
-		free_instance_list(il);
-		xavp_destroy_list(&xavp_list);
-		return -1;
-	    }
-	    sock = grep_sock_info(&host, (unsigned short)port,
-				  (unsigned short)proto);
-	    if (sock == 0) {
-		free_instance_list(il);
-		xavp_destroy_list(&xavp_list);
-		return -1;
-	    }
+		sock_str.s = vavp->val.v.s.s;
+		if (parse_phostport(sock_str.s, &host.s, &host.len, &port, &proto)
+				!= 0) {
+			LM_ERR("parsing of socket info <%s> failed\n", sock_str.s);
+			xavp_destroy_list(&xavp_list);
+			return -1;
+		}
+		sock = grep_sock_info(&host, (unsigned short)port,
+				(unsigned short)proto);
+		if (sock == 0) {
+			xavp_destroy_list(&xavp_list);
+			return -1;
+		}
 	} else {
-	    sock = NULL;
+		sock = NULL;
 	}
 
 	vavp = xavp_get(&flags_name, xavp->val.v.xavp);
 	flags = vavp->val.v.i;
 
+	vavp = xavp_get(&q_flag_name, xavp->val.v.xavp);
+	q_flag = vavp->val.v.i;
+
 	vavp = xavp_get(&instance_name, xavp->val.v.xavp);
-	if (vavp != NULL) {
-	    instance = vavp->val.v.s;
-	    ilp = il;
-	    while (ilp) {
-		if ((instance.len == ilp->instance.len) &&
-		    (strncmp(instance.s, ilp->instance.s, instance.len) == 0))
-		    break;
-		ilp = ilp->next;
-	    }
-	    if (ilp) {
-		add_contact_flows_avp(&uri, &dst_uri, &path, &sock_str,
-				      flags, &instance);
-		goto check_q_flag;
-	    }
-	    if (!q_flag) {
-		ilp = (struct instance_list *)
-		    pkg_malloc(sizeof(struct instance_list));
-		if (!ilp) {
-		    LM_ERR("no memory for instance list element\n");
-		    free_instance_list(il);
-		    return -1;
+	il = (struct instance_list *)0;
+	if ((vavp != NULL) && !q_flag) {
+		instance = vavp->val.v.s;
+		il = (struct instance_list *)pkg_malloc(sizeof(struct instance_list));
+		if (!il) {
+			LM_ERR("no memory for instance list entry\n");
+			return -1;
 		}
-		ilp->instance.s = pkg_malloc(instance.len);
-		if (!ilp->instance.s) {
-		    LM_ERR("no memory for instance list instance\n");
-		    pkg_free(ilp);
-		    free_instance_list(il);
-		    return -1;
+		il->instance.s = pkg_malloc(instance.len);
+		if (!il->instance.s) {
+			pkg_free(il);
+			LM_ERR("no memory for instance list instance\n");
+			return -1;
 		}
-		ilp->instance.len = instance.len;
-		memcpy(ilp->instance.s, instance.s, instance.len);
-		ilp->next = il;
-		il = ilp;
-	    }
+		il->instance.len = instance.len;
+		memcpy(il->instance.s, instance.s, instance.len);
+		il->next = (struct instance_list *)0;
+	}
+
+	/* Rewrite Request-URI */
+	rewrite_uri(msg, &uri);
+
+	if (dst_uri.len) {
+		set_dst_uri(msg, &dst_uri);
+	} else {
+		reset_dst_uri(msg);
 	}
 
-	if (append_branch(msg, &uri, &dst_uri, &path, 0, flags, sock, 0, 0)
-	    != 1) {
-	    LM_ERR("appending branch failed\n");
-	    free_instance_list(il);
-	    xavp_destroy_list(&xavp_list);
-	    return -1;
+	if (path.len) {
+		set_path_vector(msg, &path);
+	} else {
+		reset_path_vector(msg);
 	}
 
-    check_q_flag:
+	set_force_socket(msg, sock);
+
+	setbflagsval(0, flags);
+
+	/* Check if there was only one contact at this priority */
 	if (q_flag) {
-	    free_instance_list(il);
-	    xavp_rm(xavp, NULL);
-	    return 1;
+		xavp_rm(xavp, NULL);
+		return 1;
 	}
 
+	/* Append branches until out of branches or Q_FLAG is set */
+	/* If a branch has same instance value as some previous branch, */
+	/* instead of appending it, add it to contact_flows_avp */
+
+	xavp_rm_by_name(&contact_flows_avp, 1, NULL);
 	prev_xavp = xavp;
-    }
 
-    free_instance_list(il);
-    xavp_rm(prev_xavp, NULL);
+	while ((xavp = xavp_get_next(prev_xavp)) != NULL) {
+
+		xavp_rm(prev_xavp, NULL);
+
+		vavp = xavp_get(&q_flag_name, xavp->val.v.xavp);
+		q_flag = vavp->val.v.i;
+
+		vavp = xavp_get(&uri_name, xavp->val.v.xavp);
+		uri = vavp->val.v.s;
+
+		vavp = xavp_get(&dst_uri_name, xavp->val.v.xavp);
+		if (vavp != NULL) {
+			dst_uri = vavp->val.v.s;
+		} else {
+			dst_uri.len = 0;
+		}
+
+		vavp = xavp_get(&path_name, xavp->val.v.xavp);
+		if (vavp != NULL) {
+			path = vavp->val.v.s;
+		} else {
+			path.len = 0;
+		}
 
-    return 1;
+		vavp = xavp_get(&sock_name, xavp->val.v.xavp);
+		if (vavp != NULL) {
+			sock_str = vavp->val.v.s;
+			if (parse_phostport(sock_str.s, &host.s, &host.len, &port, &proto)
+					!= 0) {
+				LM_ERR("parsing of socket info <%s> failed\n", sock_str.s);
+				free_instance_list(il);
+				xavp_destroy_list(&xavp_list);
+				return -1;
+			}
+			sock = grep_sock_info(&host, (unsigned short)port,
+					(unsigned short)proto);
+			if (sock == 0) {
+				free_instance_list(il);
+				xavp_destroy_list(&xavp_list);
+				return -1;
+			}
+		} else {
+			sock = NULL;
+		}
+
+		vavp = xavp_get(&flags_name, xavp->val.v.xavp);
+		flags = vavp->val.v.i;
+
+		vavp = xavp_get(&instance_name, xavp->val.v.xavp);
+		if (vavp != NULL) {
+			instance = vavp->val.v.s;
+			ilp = il;
+			while (ilp) {
+				if ((instance.len == ilp->instance.len) &&
+						(strncmp(instance.s, ilp->instance.s, instance.len) == 0))
+					break;
+				ilp = ilp->next;
+			}
+			if (ilp) {
+				add_contact_flows_avp(&uri, &dst_uri, &path, &sock_str,
+						flags, &instance);
+				goto check_q_flag;
+			}
+			if (!q_flag) {
+				ilp = (struct instance_list *)
+					pkg_malloc(sizeof(struct instance_list));
+				if (!ilp) {
+					LM_ERR("no memory for instance list element\n");
+					free_instance_list(il);
+					return -1;
+				}
+				ilp->instance.s = pkg_malloc(instance.len);
+				if (!ilp->instance.s) {
+					LM_ERR("no memory for instance list instance\n");
+					pkg_free(ilp);
+					free_instance_list(il);
+					return -1;
+				}
+				ilp->instance.len = instance.len;
+				memcpy(ilp->instance.s, instance.s, instance.len);
+				ilp->next = il;
+				il = ilp;
+			}
+		}
+
+		if (append_branch(msg, &uri, &dst_uri, &path, 0, flags, sock, 0, 0)
+				!= 1) {
+			LM_ERR("appending branch failed\n");
+			free_instance_list(il);
+			xavp_destroy_list(&xavp_list);
+			return -1;
+		}
+
+check_q_flag:
+		if (q_flag) {
+			free_instance_list(il);
+			xavp_rm(xavp, NULL);
+			return 1;
+		}
+
+		prev_xavp = xavp;
+	}
+
+	free_instance_list(il);
+	xavp_rm(prev_xavp, NULL);
+
+	return 1;
 }
 
 /*
@@ -596,216 +599,216 @@ int t_next_contacts(struct sip_msg* msg, char* key, char* value)
  * there was nothing to do. Returns -1 in case of an error. */
 int t_next_contact_flows(struct sip_msg* msg, char* key, char* value)
 {
-    str uri, dst_uri, path, instance, host;
-    struct socket_info *sock;
-    unsigned int flags;
-    sr_xavp_t *xavp_list, *xavp, *next_xavp, *vavp;
-    char *tmp;
-    int port, proto;
-    struct instance_list *il, *ilp;
-
-    /* Check if contact_flows_avp has been defined */
-    if (contact_flows_avp.len == 0) {
-	LM_ERR("feature has been disabled - "
-	       "to enable define contact_flows_avp module parameter");
-	return -1;
-    }
-
-    /* Load Request-URI and branches */
-
-    /* Find first contact_flows_avp value */
-    xavp_list = xavp_get(&contact_flows_avp, NULL);
-    if (!xavp_list) {
-	LM_DBG("no contacts in contact_flows_avp - we are done!\n");
-	return -2;
-    }
-
-    xavp = xavp_list;
-    next_xavp = xavp_get_next(xavp);
-
-    vavp = xavp_get(&uri_name, xavp->val.v.xavp);
-    uri = vavp->val.v.s;
-
-    vavp = xavp_get(&dst_uri_name, xavp->val.v.xavp);
-    if (vavp != NULL) {
-	dst_uri = vavp->val.v.s;
-    } else {
-	dst_uri.s = 0;
-	dst_uri.len = 0;
-    }
-
-    vavp = xavp_get(&path_name, xavp->val.v.xavp);
-    if (vavp != NULL) {
-	path = vavp->val.v.s;
-    } else {
-	path.s = 0;
-	path.len = 0;
-    }
-
-    vavp = xavp_get(&sock_name, xavp->val.v.xavp);
-    if (vavp != NULL) {
-	tmp = vavp->val.v.s.s;
-	if (parse_phostport(tmp, &host.s, &host.len, &port, &proto) != 0) {
-	    LM_ERR("parsing of socket info <%s> failed\n", tmp);
-	    xavp_destroy_list(&xavp_list);
-	    return -1;
-	}
-	sock = grep_sock_info(&host, (unsigned short)port,
-			      (unsigned short)proto);
-	if (sock == 0) {
-	    xavp_destroy_list(&xavp_list);
-	    return -1;
-	}
-    } else {
-	sock = NULL;
-    }
-
-    vavp = xavp_get(&flags_name, xavp->val.v.xavp);
-    flags = vavp->val.v.i;
-
-    vavp = xavp_get(&instance_name, xavp->val.v.xavp);
-    il = (struct instance_list *)0;
-    if ((vavp != NULL) && next_xavp) {
-	instance = vavp->val.v.s;
-	il = (struct instance_list *)pkg_malloc(sizeof(struct instance_list));
-	if (!il) {
-	    LM_ERR("no memory for instance list entry\n");
-	    return -1;
-	}
-	il->instance.s = pkg_malloc(instance.len);
-	if (!il->instance.s) {
-	    pkg_free(il);
-	    LM_ERR("no memory for instance list instance\n");
-	    return -1;
-	}
-	il->instance.len = instance.len;
-	memcpy(il->instance.s, instance.s, instance.len);
-	il->next = (struct instance_list *)0;
-    }
-
-    /* Rewrite Request-URI */
-    rewrite_uri(msg, &uri);
-
-    if (dst_uri.len) {
-	set_dst_uri(msg, &dst_uri);
-    } else {
-	reset_dst_uri(msg);
-    }
-
-    if (path.len) {
-	set_path_vector(msg, &path);
-    } else {
-	reset_path_vector(msg);
-    }
-
-    set_force_socket(msg, sock);
-
-    setbflagsval(0, flags);
-
-    /* Append branches until out of branches. */
-    /* Do not include a branch that has same instance value as some */
-    /* previous branch. */
-
-    xavp_rm(xavp, NULL);
-    xavp = next_xavp;
-
-    while (xavp) {
-	
-	next_xavp = xavp_get_next(xavp);
-
-	vavp = xavp_get(&instance_name, xavp->val.v.xavp);
-	if (vavp != NULL) {
-	    instance = vavp->val.v.s;
-	    ilp = il;
-	    while (ilp) {
-		if ((instance.len == ilp->instance.len) &&
-		    (strncmp(instance.s, ilp->instance.s, instance.len) == 0))
-		    break;
-		ilp = ilp->next;
-	    }
-	    if (ilp) {
-		/* skip already appended instance */
-		xavp = next_xavp;
-		continue;
-	    }
-	    if (next_xavp) {
-		ilp = (struct instance_list *)
-		pkg_malloc(sizeof(struct instance_list));
-		if (!ilp) {
-		    LM_ERR("no memory for new instance list entry\n");
-		    free_instance_list(il);
-		    return -1;
-		}
-		ilp->instance.s = pkg_malloc(instance.len);
-		if (!ilp->instance.s) {
-		    pkg_free(il);
-		    LM_ERR("no memory for instance list instance\n");
-		    return -1;
-		}
-		ilp->instance.len = instance.len;
-		memcpy(ilp->instance.s, instance.s, instance.len);
-		ilp->next = il;
-		il = ilp;
-	    } else {
-		LM_ERR("instance missing from contact_flow_avp contact\n");
-		free_instance_list(il);
+	str uri, dst_uri, path, instance, host;
+	struct socket_info *sock;
+	unsigned int flags;
+	sr_xavp_t *xavp_list, *xavp, *next_xavp, *vavp;
+	char *tmp;
+	int port, proto;
+	struct instance_list *il, *ilp;
+
+	/* Check if contact_flows_avp has been defined */
+	if (contact_flows_avp.len == 0) {
+		LM_ERR("feature has been disabled - "
+				"to enable define contact_flows_avp module parameter");
 		return -1;
-	    }
 	}
 
+	/* Load Request-URI and branches */
+
+	/* Find first contact_flows_avp value */
+	xavp_list = xavp_get(&contact_flows_avp, NULL);
+	if (!xavp_list) {
+		LM_DBG("no contacts in contact_flows_avp - we are done!\n");
+		return -2;
+	}
+
+	xavp = xavp_list;
+	next_xavp = xavp_get_next(xavp);
+
 	vavp = xavp_get(&uri_name, xavp->val.v.xavp);
 	uri = vavp->val.v.s;
 
 	vavp = xavp_get(&dst_uri_name, xavp->val.v.xavp);
 	if (vavp != NULL) {
-	    dst_uri = vavp->val.v.s;
+		dst_uri = vavp->val.v.s;
 	} else {
-	    dst_uri.len = 0;
+		dst_uri.s = 0;
+		dst_uri.len = 0;
 	}
 
 	vavp = xavp_get(&path_name, xavp->val.v.xavp);
 	if (vavp != NULL) {
-	    path = vavp->val.v.s;
+		path = vavp->val.v.s;
 	} else {
-	    path.len = 0;
+		path.s = 0;
+		path.len = 0;
 	}
 
 	vavp = xavp_get(&sock_name, xavp->val.v.xavp);
 	if (vavp != NULL) {
-	    tmp = vavp->val.v.s.s;
-	    if (parse_phostport(tmp, &host.s, &host.len, &port, &proto) != 0) {
-		LM_ERR("parsing of socket info <%s> failed\n", tmp);
-		free_instance_list(il);
-		xavp_destroy_list(&xavp_list);
-		return -1;
-	    }
-	    sock = grep_sock_info(&host, (unsigned short)port,
-				  (unsigned short)proto);
-	    if (sock == 0) {
-		free_instance_list(il);
-		xavp_destroy_list(&xavp_list);
-		return -1;
-	    }
+		tmp = vavp->val.v.s.s;
+		if (parse_phostport(tmp, &host.s, &host.len, &port, &proto) != 0) {
+			LM_ERR("parsing of socket info <%s> failed\n", tmp);
+			xavp_destroy_list(&xavp_list);
+			return -1;
+		}
+		sock = grep_sock_info(&host, (unsigned short)port,
+				(unsigned short)proto);
+		if (sock == 0) {
+			xavp_destroy_list(&xavp_list);
+			return -1;
+		}
 	} else {
-	    sock = NULL;
+		sock = NULL;
 	}
 
 	vavp = xavp_get(&flags_name, xavp->val.v.xavp);
 	flags = vavp->val.v.i;
 
-	if (append_branch(msg, &uri, &dst_uri, &path, 0, flags, sock, 0, 0)
-	    != 1) {
-	    LM_ERR("appending branch failed\n");
-	    free_instance_list(il);
-	    xavp_destroy_list(&xavp_list);
-	    return -1;
+	vavp = xavp_get(&instance_name, xavp->val.v.xavp);
+	il = (struct instance_list *)0;
+	if ((vavp != NULL) && next_xavp) {
+		instance = vavp->val.v.s;
+		il = (struct instance_list *)pkg_malloc(sizeof(struct instance_list));
+		if (!il) {
+			LM_ERR("no memory for instance list entry\n");
+			return -1;
+		}
+		il->instance.s = pkg_malloc(instance.len);
+		if (!il->instance.s) {
+			pkg_free(il);
+			LM_ERR("no memory for instance list instance\n");
+			return -1;
+		}
+		il->instance.len = instance.len;
+		memcpy(il->instance.s, instance.s, instance.len);
+		il->next = (struct instance_list *)0;
 	}
 
+	/* Rewrite Request-URI */
+	rewrite_uri(msg, &uri);
+
+	if (dst_uri.len) {
+		set_dst_uri(msg, &dst_uri);
+	} else {
+		reset_dst_uri(msg);
+	}
+
+	if (path.len) {
+		set_path_vector(msg, &path);
+	} else {
+		reset_path_vector(msg);
+	}
+
+	set_force_socket(msg, sock);
+
+	setbflagsval(0, flags);
+
+	/* Append branches until out of branches. */
+	/* Do not include a branch that has same instance value as some */
+	/* previous branch. */
+
 	xavp_rm(xavp, NULL);
 	xavp = next_xavp;
-    }
 
-    free_instance_list(il);
+	while (xavp) {
+
+		next_xavp = xavp_get_next(xavp);
+
+		vavp = xavp_get(&instance_name, xavp->val.v.xavp);
+		if (vavp != NULL) {
+			instance = vavp->val.v.s;
+			ilp = il;
+			while (ilp) {
+				if ((instance.len == ilp->instance.len) &&
+						(strncmp(instance.s, ilp->instance.s, instance.len) == 0))
+					break;
+				ilp = ilp->next;
+			}
+			if (ilp) {
+				/* skip already appended instance */
+				xavp = next_xavp;
+				continue;
+			}
+			if (next_xavp) {
+				ilp = (struct instance_list *)
+					pkg_malloc(sizeof(struct instance_list));
+				if (!ilp) {
+					LM_ERR("no memory for new instance list entry\n");
+					free_instance_list(il);
+					return -1;
+				}
+				ilp->instance.s = pkg_malloc(instance.len);
+				if (!ilp->instance.s) {
+					pkg_free(il);
+					LM_ERR("no memory for instance list instance\n");
+					return -1;
+				}
+				ilp->instance.len = instance.len;
+				memcpy(ilp->instance.s, instance.s, instance.len);
+				ilp->next = il;
+				il = ilp;
+			} else {
+				LM_ERR("instance missing from contact_flow_avp contact\n");
+				free_instance_list(il);
+				return -1;
+			}
+		}
+
+		vavp = xavp_get(&uri_name, xavp->val.v.xavp);
+		uri = vavp->val.v.s;
+
+		vavp = xavp_get(&dst_uri_name, xavp->val.v.xavp);
+		if (vavp != NULL) {
+			dst_uri = vavp->val.v.s;
+		} else {
+			dst_uri.len = 0;
+		}
+
+		vavp = xavp_get(&path_name, xavp->val.v.xavp);
+		if (vavp != NULL) {
+			path = vavp->val.v.s;
+		} else {
+			path.len = 0;
+		}
+
+		vavp = xavp_get(&sock_name, xavp->val.v.xavp);
+		if (vavp != NULL) {
+			tmp = vavp->val.v.s.s;
+			if (parse_phostport(tmp, &host.s, &host.len, &port, &proto) != 0) {
+				LM_ERR("parsing of socket info <%s> failed\n", tmp);
+				free_instance_list(il);
+				xavp_destroy_list(&xavp_list);
+				return -1;
+			}
+			sock = grep_sock_info(&host, (unsigned short)port,
+					(unsigned short)proto);
+			if (sock == 0) {
+				free_instance_list(il);
+				xavp_destroy_list(&xavp_list);
+				return -1;
+			}
+		} else {
+			sock = NULL;
+		}
 
-    return 1;
+		vavp = xavp_get(&flags_name, xavp->val.v.xavp);
+		flags = vavp->val.v.i;
+
+		if (append_branch(msg, &uri, &dst_uri, &path, 0, flags, sock, 0, 0)
+				!= 1) {
+			LM_ERR("appending branch failed\n");
+			free_instance_list(il);
+			xavp_destroy_list(&xavp_list);
+			return -1;
+		}
+
+		xavp_rm(xavp, NULL);
+		xavp = next_xavp;
+	}
+
+	free_instance_list(il);
+
+	return 1;
 }