瀏覽代碼

Added the possibility to set priorities of URIs in the destination set.

Jan Janak 21 年之前
父節點
當前提交
035f593ca5
共有 5 個文件被更改,包括 205 次插入92 次删除
  1. 2 1
      action.c
  2. 5 3
      cfg.y
  3. 153 60
      dset.c
  4. 43 26
      dset.h
  5. 2 2
      modules/tm/t_fwd.c

+ 2 - 1
action.c

@@ -280,7 +280,8 @@ int do_action(struct action* a, struct sip_msg* msg)
 				break;
 				break;
 			}
 			}
 			ret=append_branch( msg, a->p1.string, 
 			ret=append_branch( msg, a->p1.string, 
-				a->p1.string ? strlen(a->p1.string):0 );
+					   a->p1.string ? strlen(a->p1.string):0,
+					   a->p2.number);
 			break;
 			break;
 
 
 		/* jku begin: is_length_greater_than */
 		/* jku begin: is_length_greater_than */

+ 5 - 3
cfg.y

@@ -76,6 +76,7 @@
 #include "name_alias.h"
 #include "name_alias.h"
 #include "usr_avp.h"
 #include "usr_avp.h"
 #include "ut.h"
 #include "ut.h"
+#include "dset.h"
 
 
 
 
 #include "config.h"
 #include "config.h"
@@ -1431,11 +1432,12 @@ cmd:		FORWARD LPAREN host RPAREN	{ $$=mk_action(	FORWARD_T,
 		| STRIP error { $$=0; yyerror("missing '(' or ')' ?"); }
 		| STRIP error { $$=0; yyerror("missing '(' or ')' ?"); }
 		| STRIP LPAREN error RPAREN { $$=0; yyerror("bad argument, "
 		| STRIP LPAREN error RPAREN { $$=0; yyerror("bad argument, "
 														"number expected"); }
 														"number expected"); }
-
+                | APPEND_BRANCH LPAREN STRING COMMA NUMBER RPAREN { $$=mk_action( APPEND_BRANCH_T,
+										                        STRING_ST, NUMBER_ST, $3, (void *)$5) ; }
 		| APPEND_BRANCH LPAREN STRING RPAREN { $$=mk_action( APPEND_BRANCH_T,
 		| APPEND_BRANCH LPAREN STRING RPAREN { $$=mk_action( APPEND_BRANCH_T,
-													STRING_ST, 0, $3, 0) ; }
+													STRING_ST, NUMBER_ST, $3, (void *)Q_UNSPECIFIED) ; }
 		| APPEND_BRANCH LPAREN RPAREN { $$=mk_action( APPEND_BRANCH_T,
 		| APPEND_BRANCH LPAREN RPAREN { $$=mk_action( APPEND_BRANCH_T,
-													STRING_ST, 0, 0, 0 ) ; }
+													STRING_ST, NUMBER_ST, 0, (void *)Q_UNSPECIFIED ) ; }
 		| APPEND_BRANCH {  $$=mk_action( APPEND_BRANCH_T, STRING_ST, 0, 0, 0 ) ; }
 		| APPEND_BRANCH {  $$=mk_action( APPEND_BRANCH_T, STRING_ST, 0, 0, 0 ) ; }
 
 
 		| SET_HOSTPORT LPAREN STRING RPAREN { $$=mk_action( SET_HOSTPORT_T, 
 		| SET_HOSTPORT LPAREN STRING RPAREN { $$=mk_action( SET_HOSTPORT_T, 

+ 153 - 60
dset.c

@@ -3,7 +3,7 @@
  *
  *
  * destination set
  * destination set
  *
  *
- * Copyright (C) 2001-2003 Fhg Fokus
+ * Copyright (C) 2001-2004 FhG FOKUS
  *
  *
  * This file is part of ser, a free SIP server.
  * This file is part of ser, a free SIP server.
  *
  *
@@ -27,143 +27,236 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
  */
 
 
-
 #include <string.h>
 #include <string.h>
-
 #include "dprint.h"
 #include "dprint.h"
 #include "config.h"
 #include "config.h"
 #include "parser/parser_f.h"
 #include "parser/parser_f.h"
 #include "parser/msg_parser.h"
 #include "parser/msg_parser.h"
 #include "ut.h"
 #include "ut.h"
 #include "hash_func.h"
 #include "hash_func.h"
-#include "dset.h"
 #include "error.h"
 #include "error.h"
+#include "dset.h"
 
 
+#define CONTACT "Contact: "
+#define CONTACT_LEN (sizeof(CONTACT) - 1)
 
 
+#define CONTACT_DELIM ", "
+#define CONTACT_DELIM_LEN (sizeof(CONTACT_DELIM) - 1)
+
+#define Q_PARAM ">;q="
+#define Q_PARAM_LEN (sizeof(Q_PARAM) - 1)
+
+struct branch
+{
+	char uri[MAX_URI_SIZE];
+	unsigned int len;
+	int q; /* Preference of the contact among
+		* contact within the array */
+};
+
+
+/* 
+ * Where we store URIs of additional transaction branches
+ * (-1 because of the default branch, #0)
+ */
+static struct branch branches[MAX_BRANCHES - 1];
 
 
-/* where we store URIs of additional transaction branches
-  (-1 because of the default branch, #0)
-*/
-static struct branch branches[ MAX_BRANCHES - 1 ];
 /* how many of them we have */
 /* how many of them we have */
-static unsigned int nr_branches=0;
+static unsigned int nr_branches = 0;
+
 /* branch iterator */
 /* branch iterator */
-static int branch_iterator=0;
+static int branch_iterator = 0;
+
+/* The q parameter of the Request-URI */
+static qvalue_t ruri_q = Q_UNSPECIFIED; 
+
 
 
+/*
+ * Intialize the branch iterator, the next
+ * call to next_branch will return the first
+ * contact from the dset array
+ */
 void init_branch_iterator(void)
 void init_branch_iterator(void)
 {
 {
-	branch_iterator=0;
+	branch_iterator = 0;
 }
 }
 
 
-char *next_branch( int *len )
+
+/*
+ * Return the next branch from the dset
+ * array, 0 is returned if there are no
+ * more branches
+ */
+char* next_branch(int* len, qvalue_t* q)
 {
 {
 	unsigned int i;
 	unsigned int i;
 
 
-	i=branch_iterator;
-	if (i<nr_branches) {
+	i = branch_iterator;
+	if (i < nr_branches) {
 		branch_iterator++;
 		branch_iterator++;
-		*len=branches[i].len;
+		*len = branches[i].len;
+		*q = branches[i].q;
 		return branches[i].uri;
 		return branches[i].uri;
 	} else {
 	} else {
-		*len=0;
+		*len = 0;
+		*q = Q_UNSPECIFIED;
 		return 0;
 		return 0;
 	}
 	}
 }
 }
 
 
-void clear_branches()
+
+/*
+ * Empty the dset array
+ */
+void clear_branches(void)
 {
 {
-	nr_branches=0;
+	nr_branches = 0;
+	ruri_q = Q_UNSPECIFIED;
 }
 }
 
 
-/* add a new branch to current transaction */
-int append_branch( struct sip_msg *msg, char *uri, int uri_len )
+
+/* 
+ * Add a new branch to current transaction 
+ */
+int append_branch(struct sip_msg* msg, char* uri, int uri_len, qvalue_t q)
 {
 {
-	/* if we have already set up the maximum number
-	   of branches, don't try new ones */
-	if (nr_branches==MAX_BRANCHES-1) {
+	     /* if we have already set up the maximum number
+	      * of branches, don't try new ones 
+	      */
+	if (nr_branches == MAX_BRANCHES - 1) {
 		LOG(L_ERR, "ERROR: append_branch: max nr of branches exceeded\n");
 		LOG(L_ERR, "ERROR: append_branch: max nr of branches exceeded\n");
-		ser_error=E_TOO_MANY_BRANCHES;
+		ser_error = E_TOO_MANY_BRANCHES;
 		return -1;
 		return -1;
 	}
 	}
 
 
-	if (uri_len>MAX_URI_SIZE-1) {
+	if (uri_len > MAX_URI_SIZE - 1) {
 		LOG(L_ERR, "ERROR: append_branch: too long uri: %.*s\n",
 		LOG(L_ERR, "ERROR: append_branch: too long uri: %.*s\n",
-			uri_len, uri );
+		    uri_len, uri);
 		return -1;
 		return -1;
 	}
 	}
 
 
-	/* if not parameterized, take current uri */
-	if (uri==0) {
+	     /* if not parameterized, take current uri */
+	if (uri == 0) {
 		if (msg->new_uri.s) { 
 		if (msg->new_uri.s) { 
-			uri=msg->new_uri.s;
-			uri_len=msg->new_uri.len;
+			uri = msg->new_uri.s;
+			uri_len = msg->new_uri.len;
 		} else {
 		} else {
-			uri=msg->first_line.u.request.uri.s;
-			uri_len=msg->first_line.u.request.uri.len;
+			uri = msg->first_line.u.request.uri.s;
+			uri_len = msg->first_line.u.request.uri.len;
 		}
 		}
 	}
 	}
 	
 	
-	memcpy( branches[nr_branches].uri, uri, uri_len );
-	/* be safe -- add zero termination */
-	branches[nr_branches].uri[uri_len]=0;
-	branches[nr_branches].len=uri_len;
+	memcpy(branches[nr_branches].uri, uri, uri_len);
+	     /* be safe -- add zero termination */
+	branches[nr_branches].uri[uri_len] = 0;
+	branches[nr_branches].len = uri_len;
+	branches[nr_branches].q = q;
 	
 	
 	nr_branches++;
 	nr_branches++;
 	return 1;
 	return 1;
 }
 }
 
 
 
 
-
-char *print_dset( struct sip_msg *msg, int *len ) 
+/*
+ * Create a Contact header field from the dset
+ * array
+ */
+char* print_dset(struct sip_msg* msg, int* len) 
 {
 {
-	int cnt;
+	int cnt, i;
+	qvalue_t q;
 	str uri;
 	str uri;
-	char *p;
-	int i;
+	char* p;
 	static char dset[MAX_REDIRECTION_LEN];
 	static char dset[MAX_REDIRECTION_LEN];
 
 
 	if (msg->new_uri.s) {
 	if (msg->new_uri.s) {
-		cnt=1;
-		*len=msg->new_uri.len;
+		cnt = 1;
+		*len = msg->new_uri.len;
+		if (ruri_q != Q_UNSPECIFIED) {
+			*len += 1 + Q_PARAM_LEN + len_q(ruri_q);
+		}
 	} else {
 	} else {
-		cnt=0;
-		*len=0;
+		cnt = 0;
+		*len = 0;
 	}
 	}
 
 
 	init_branch_iterator();
 	init_branch_iterator();
-	while ((uri.s=next_branch(&uri.len))) {
+	while ((uri.s = next_branch(&uri.len, &q))) {
 		cnt++;
 		cnt++;
-		*len+=uri.len;
+		*len += uri.len;
+		if (q != Q_UNSPECIFIED) {
+			*len += 1 + Q_PARAM_LEN + len_q(q);
+		}
 	}
 	}
 
 
-	if (cnt==0) return 0;	
+	if (cnt == 0) return 0;	
 
 
-	*len+=CONTACT_LEN+CRLF_LEN+(cnt-1)*CONTACT_DELIM_LEN;
+	*len += CONTACT_LEN + CRLF_LEN + (cnt - 1) * CONTACT_DELIM_LEN;
 
 
-	if (*len+1>MAX_REDIRECTION_LEN) {
+	if (*len + 1 > MAX_REDIRECTION_LEN) {
 		LOG(L_ERR, "ERROR: redirection buffer length exceed\n");
 		LOG(L_ERR, "ERROR: redirection buffer length exceed\n");
 		return 0;
 		return 0;
 	}
 	}
 
 
-	memcpy(dset, CONTACT, CONTACT_LEN );
-	p=dset+CONTACT_LEN;
+	memcpy(dset, CONTACT, CONTACT_LEN);
+	p = dset + CONTACT_LEN;
 	if (msg->new_uri.s) {
 	if (msg->new_uri.s) {
+		if (ruri_q != Q_UNSPECIFIED) {
+			*p++ = '<';
+		}
+
 		memcpy(p, msg->new_uri.s, msg->new_uri.len);
 		memcpy(p, msg->new_uri.s, msg->new_uri.len);
-		p+=msg->new_uri.len;
-		i=1;
-	} else i=0;
+		p += msg->new_uri.len;
+
+		if (ruri_q != Q_UNSPECIFIED) {
+			memcpy(p, Q_PARAM, Q_PARAM_LEN);
+			p += Q_PARAM_LEN;
+			p += print_q(p, q);
+		}
+		i = 1;
+	} else {
+		i = 0;
+	}
 
 
 	init_branch_iterator();
 	init_branch_iterator();
-	while ((uri.s=next_branch(&uri.len))) {
+	while ((uri.s = next_branch(&uri.len, &q))) {
 		if (i) {
 		if (i) {
-			memcpy(p, CONTACT_DELIM, CONTACT_DELIM_LEN );
-			p+=2;
+			memcpy(p, CONTACT_DELIM, CONTACT_DELIM_LEN);
+			p += CONTACT_DELIM_LEN;
+		}
+
+		if (q != Q_UNSPECIFIED) {
+			*p++ = '<';
 		}
 		}
+
 		memcpy(p, uri.s, uri.len);
 		memcpy(p, uri.s, uri.len);
-		p+=uri.len;
+		p += uri.len;
+		if (q != Q_UNSPECIFIED) {
+			memcpy(p, Q_PARAM, Q_PARAM_LEN);
+			p += Q_PARAM_LEN;
+			p += print_q(p, q);
+		}
 		i++;
 		i++;
 	}
 	}
-	memcpy(p, CRLF " ", CRLF_LEN+1);
+
+	memcpy(p, CRLF " ", CRLF_LEN + 1);
 	return dset;
 	return dset;
 }
 }
 
 
+
+/*
+ * Sets the q parameter of the Request-URI
+ */
+void set_ruri_q(qvalue_t q)
+{
+	ruri_q = q;
+}
+
+
+/*
+ * Return the q value of the Request-URI
+ */
+qvalue_t get_ruri_q(void)
+{
+	return ruri_q;
+}

+ 43 - 26
dset.h

@@ -1,7 +1,7 @@
 /*
 /*
  * $Id$
  * $Id$
  *
  *
- * Copyright (C) 2001-2003 Fhg Fokus
+ * Copyright (C) 2001-2004 FhG FOKUS
  *
  *
  * This file is part of ser, a free SIP server.
  * This file is part of ser, a free SIP server.
  *
  *
@@ -25,36 +25,53 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
  */
 
 
+#ifndef _DSET_H
+#define _DSET_H
 
 
-#ifndef _T_FORKS_H
-#define _T_FORKS_H
+#include "qvalue.h"
 
 
-#include "config.h"
+struct sip_msg;
 
 
-#define CONTACT "Contact: "
-#define CONTACT_LEN 9
-#define CONTACT_DELIM ", "
-#define CONTACT_DELIM_LEN 2
+/* 
+ * Add a new branch to current transaction 
+ */
+int append_branch(struct sip_msg* msg, char* uri, int uri_len, qvalue_t q);
 
 
 
 
-struct branch
-{
-	char uri[MAX_URI_SIZE];
-	unsigned int len;
-};
+/* 
+ * Iterate through the list of transaction branches 
+ */
+void init_branch_iterator(void);
+
+
+/*
+ * Get the next branch in the current transaction
+ */
+char* next_branch(int* len, qvalue_t* q);
+
+
+/*
+ * Empty the array of branches
+ */
+void clear_branches(void);
 
 
-struct sip_msg;
 
 
 /*
 /*
-typedef int (*tfork_f)( struct sip_msg *msg, char *uri, int uri_len );
-*/
-
-/* add a new branch to current transaction */
-int append_branch( struct sip_msg *msg, char *uri, int uri_len );
-/* iterate through list of new transaction branches */
-void init_branch_iterator();
-char *next_branch( int *len );
-void clear_branches();
-
-char *print_dset( struct sip_msg *msg, int *len );
-#endif
+ * Create a Contact header field from the
+ * list of current branches
+ */
+char* print_dset(struct sip_msg* msg, int* len);
+
+
+/* 
+ * Set the q value of the Request-URI
+ */
+void set_ruri_q(qvalue_t q);
+
+
+/* 
+ * Get the q value of the Request-URI
+ */
+qvalue_t get_ruri_q(void);
+
+#endif /* _DSET_H */

+ 2 - 2
modules/tm/t_fwd.c

@@ -403,7 +403,7 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
 	str current_uri;
 	str current_uri;
 	branch_bm_t	added_branches;
 	branch_bm_t	added_branches;
 	int first_branch;
 	int first_branch;
-	int i;
+	int i, q;
 	struct cell *t_invite;
 	struct cell *t_invite;
 	int success_branch;
 	int success_branch;
 	int try_new;
 	int try_new;
@@ -444,7 +444,7 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
 	} else try_new=0;
 	} else try_new=0;
 
 
 	init_branch_iterator();
 	init_branch_iterator();
-	while((current_uri.s=next_branch( &current_uri.len))) {
+	while((current_uri.s=next_branch( &current_uri.len, &q))) {
 		try_new++;
 		try_new++;
 		branch_ret=add_uac( t, p_msg, &current_uri, 
 		branch_ret=add_uac( t, p_msg, &current_uri, 
 				    (p_msg->dst_uri.len) ? (&p_msg->dst_uri) : &current_uri, 
 				    (p_msg->dst_uri.len) ? (&p_msg->dst_uri) : &current_uri,