[Devel] PATCH: include qvalue in branches created by uac_redirect

Michael Samuel michael.samuel at ipsystems.com.au
Fri May 5 05:46:32 CEST 2006


Hi,

I came across the problem that uac_redirect was causing forks when what 
we really wanted was serialized branches.  I was glad to find that 
support for serialized branches was available in the devel version of 
openser, but it still wasn't working with uac_redirect.

Anyway, it seems that uac_redirect wasn't including the qvalue from the 
contact in the branches, causing it to fork anyway.

The diff also slightly changes the behaviour, in that if it can't parse 
the qvalue of a contact, it sets the qvalue to 0, rather than skipping 
the contact. (A side effect of my dismal attempt to keep the code clean 
by not duplicating the code I found elsewhere in the module)

Anyway, with the attached patch, I was able to support handling of a 
list of contacts in a 302, and fallback on failure worked nicely.

BTW, does anyone know the feasability of backporting the serialization 
stuff to the stable version of openser? (I need to use this in 
production rather soon)

I'm not subscribed to the list, so please CC me on any replies.

--
Michael Samuel
IP Systems Pty Ltd
-------------- next part --------------
diff -ur -x CVS -x '*.d' -x debian sip-server/modules/uac_redirect/rd_funcs.c sip-server-uacredirfix/modules/uac_redirect/rd_funcs.c
--- sip-server/modules/uac_redirect/rd_funcs.c	2006-05-04 22:15:44.000000000 +1000
+++ sip-server-uacredirfix/modules/uac_redirect/rd_funcs.c	2006-05-05 11:43:08.000000000 +1000
@@ -42,6 +42,22 @@
 static int shmcontact2dset(struct sip_msg *req, struct sip_msg *shrpl,
 			long max, str *reason);
 
+static qvalue_t para2q(param_t *q_para)
+{
+	qvalue_t q;
+
+	if (q_para==0 || q_para->body.len==0) {
+		return DEFAULT_Q_VALUE;
+	}
+
+	if (str2q( &q, q_para->body.s, q_para->body.len)!=0) {
+		LOG(L_ERR, "ERROR:uac_redirect:para2q: "
+			"invalid q param\n");
+		return (qvalue_t)0; /* FIXME: What if qvalue_t wasn't an integer? */
+	}
+
+	return q;
+}
 
 int get_redirect( struct sip_msg *msg , int maxt, int maxb, str *reason)
 {
@@ -112,7 +128,6 @@
 static int sort_contacts(contact_t *ct_list, contact_t **ct_array)
 {
 	static qvalue_t q_array[MAX_CONTACTS_PER_REPLY];
-	param_t *q_para;
 	qvalue_t q;
 	int n;
 	int i,j;
@@ -129,18 +144,9 @@
 			continue;
 		}
 		ct_list->uri.s[ct_list->uri.len] = backup;
-		/* does the contact has a q val? */
-		q_para = ct_list->q;
-		if (q_para==0 || q_para->body.len==0) {
-			q = DEFAULT_Q_VALUE;
-		} else {
-			if (str2q( &q, q_para->body.s, q_para->body.len)!=0) {
-				LOG(L_ERR, "ERROR:uac_redirect:sort_contacts: "
-					"invalid q param\n");
-				/* skip this contact */
-				continue;
-			}
-		}
+
+		q = para2q(ct_list->q);
+
 		DBG("DEBUG:uac_redirect:sort_contacts: <%.*s> q=%d\n",
 				ct_list->uri.len,ct_list->uri.s,q);
 		/*insert the contact into the sorted array */
@@ -269,7 +275,7 @@
 	for ( i=0 ; i<n ; i++ ) {
 		DBG("DEBUG:uac_redirect:shmcontact2dset: adding contact <%.*s>\n",
 			scontacts[i]->uri.len, scontacts[i]->uri.s);
-		if (append_branch( 0, &scontacts[i]->uri, 0, 0, Q_UNSPECIFIED, 0, 0)<0 ) {
+		if (append_branch( 0, &scontacts[i]->uri, 0, 0, para2q(scontacts[i]->q), 0, 0)<0 ) {
 			LOG(L_ERR,"ERROR:uac_redirect:shmcontact2dset: failed to add "
 				"contact to dset\n");
 		} else {


More information about the Devel mailing list