changeset 167:967e579beb64

Backup work in progress on rt_default
author Sebastien Decugis <sdecugis@nict.go.jp>
date Fri, 29 Jan 2010 18:57:40 +0900
parents 6d166f75e25a
children 6db078b955e3
files doc/rt_default.conf.sample extensions/CMakeLists.txt extensions/rt_default/CMakeLists.txt extensions/rt_default/rt_default.c extensions/rt_default/rt_default.h extensions/rt_default/rtd_conf.l extensions/rt_default/rtd_conf.y extensions/rt_default/rtd_rules.c
diffstat 8 files changed, 811 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/rt_default.conf.sample	Fri Jan 29 18:57:40 2010 +0900
@@ -0,0 +1,91 @@
+# This file contains the configuration for the rt_default extension of freeDiameter.
+#
+# This extension provides configurable routing properties for freeDiameter.
+
+# Lines starting with a # are comments and ignored.
+
+##############################################################################
+# The freeDiameter daemon will not allow forwarding a message to a peer that:
+# - already forwarded the message (appear as Route-Record inside the message)
+# - connection is not in STATE_OPEN state.
+# We call here "eligible peer" a peer that is not screened out by one of these criteria.
+#
+# Even if a peer is specified as route for a message here, the daemon may
+# choose to send a message to another peer, or return a UNABLE_TO_DELIVER error, if that peer is not eligible 
+# at the time where the message is to be forwarded.
+#
+# Note also that defining a peer here will not result in the daemon trying to establish
+# a connection to this peer. For this purpose, the peer must be defined in the main
+# configuration (ConnectPeer), or connection established through other means (e.g. dynamic peer
+# discovery extension).
+#
+# The default forwarding behavior of freeDiameter is:
+# - if the message contains a Destination-Host AVP, and this the designated peer is an eligible candidate, send to this peer.
+# - if a peer does not support the message application or Relay application, give it a penalty for this message 
+#    (it means that unless overwritten by an extension, the message will not be sent to that peer)
+# - if one of the eligible peer advertised a realm matching the message's Destination-Realm, send to this peer.
+#
+# The mechanism is as follow:
+# - the daemon builds a list of eligible peers, then attributes a score to these peers (see enum fd_rt_out_score in freeDiameter.h)
+# - any number of extensions can register a callback and modify the score
+# - after all callbacks have been called, the message is sent to the peer with the higher score. If an error is received, it is retried to the next peer in the list, and so on,
+#   until the list is empty. In such situation, an error UNABLE_TO_DELIVER is generated.
+#
+# This extension allows to modify the score of some peers based on some criteria of the message.
+#
+# Finally, please note that the freeDiameter daemon does not support REDIRECT indications natively. 
+# You have to load the rt_redir extension to add this support.
+##############################################################################
+
+# This file contains a list of RULE elements.
+# Each RULE is made of three components:
+#  - a CRITERIA, which specifies which messages the RULE apply to.
+#  - a TARGET string, that specifies which peer(s) in the eligible list the rule is applied to
+#  - and a SCORE, that is added to the matching peer's current score.
+#
+# In the following definitions, "STR/REG" stands for:
+#   - a quoted string "some.peer" that will match exactly this string, or
+#   - a bracket-quoted string ["some regex"] that will be interpreted as a POSIX regular expression, and attempt to match the string.
+#
+# The RULE is specified as:
+#    CRITERIA : TARGET += SCORE ;
+#
+# The CRITERIA can be:
+#    *   		-> matches any message.
+#    oh="STR/REG"	-> selects the message if the string or regular expression matches the message's Origin-Host
+#    or="STR/REG"   	-> idem with Origin-Realm
+#    dh="STR/REG"   	-> idem with Destination-Host
+#    dr="STR/REG"   	-> idem with Destination-Realm
+#    un="STR/REG"   	-> idem with User-Name
+#    si="STR/REG"   	-> idem with Session-Id
+#
+# The TARGET is also of a similar form:
+#    i="STR/REG"	-> Will apply the score to this peer if its Diameter-Id is matched by the string or regular expression.
+#    r="STR/REG"	-> Idem with the peer's advertized Diameter-Realm.
+#
+# The SCORE is either numeric (positive or negative), or one of the following constants (see values in freeDiameter.h):
+#    NO_DELIVERY
+#    DEFAULT
+#    DEFAULT_REALM
+#    REALM
+#    REDIR_HOST     
+#    REDIR_APP      
+#    REDIR_REALM    
+#    REDIR_REALM_APP
+#    REDIR_USER     
+#    REDIR_SESSION  
+#    FINALDEST
+#
+#
+# Here are some examples:
+#  1) Rule to add a default next-hop to all messages:
+#    * : i="proxy.testbed.aaa" += DEFAULT ;
+#
+#  2) Rule to route messages for a given realm (realmA) through another realm (realmB):
+#    dr="realmA" : r="realmB" += DEFAULT_REALM ;
+#
+#  3) Avoid sending messages with decorated NAI to the proxy A:
+#    un=[".+!.+@.+"] : i="proxy.A" += NO_DELIVERY ;
+
+
+
--- a/extensions/CMakeLists.txt	Thu Jan 28 15:01:50 2010 +0900
+++ b/extensions/CMakeLists.txt	Fri Jan 29 18:57:40 2010 +0900
@@ -40,10 +40,10 @@
 ####
 # Routing extensions
 
-# OPTION(BUILD_RT_DEFAULT "Build rt_default? (Routing extension using Destination-Host, Destination-Realm, and static configuration)" ON)
-# 	IF (BUILD_RT_DEFAULT)
-# 	   SUBDIRS(rt_default)
-# 	ENDIF (BUILD_RT_DEFAULT)
+OPTION(BUILD_RT_DEFAULT "Build rt_default? (Configurable routing rules for freeDiameter)" ON)
+	IF (BUILD_RT_DEFAULT)
+	   SUBDIRS(rt_default)
+	ENDIF (BUILD_RT_DEFAULT)
 
 
 ####
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/rt_default/CMakeLists.txt	Fri Jan 29 18:57:40 2010 +0900
@@ -0,0 +1,20 @@
+# The rt_default extension
+PROJECT("Configurable routing extension" C)
+
+# Parser files
+BISON_FILE(rtd_conf.y)
+FLEX_FILE(rtd_conf.l)
+SET_SOURCE_FILES_PROPERTIES(lex.rtd_conf.c rtd_conf.tab.c PROPERTIES COMPILE_FLAGS "-I ${CMAKE_CURRENT_SOURCE_DIR}")
+
+# List of source files
+SET( RT_DEFAULT_SRC
+	rt_default.c
+	rt_default.h
+	lex.rtd_conf.c
+	rtd_conf.tab.c
+	rtd_conf.tab.h
+	rtd_rules.c
+)
+
+# Compile these files as a freeDiameter extension
+FD_ADD_EXTENSION(rt_default ${RT_DEFAULT_SRC})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/rt_default/rt_default.c	Fri Jan 29 18:57:40 2010 +0900
@@ -0,0 +1,98 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License)                                                               *
+* Author: Sebastien Decugis <sdecugis@nict.go.jp>							 *
+*													 *
+* Copyright (c) 2009, WIDE Project and NICT								 *
+* All rights reserved.											 *
+* 													 *
+* Redistribution and use of this software in source and binary forms, with or without modification, are  *
+* permitted provided that the following conditions are met:						 *
+* 													 *
+* * Redistributions of source code must retain the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer.										 *
+*    													 *
+* * Redistributions in binary form must reproduce the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer in the documentation and/or other						 *
+*   materials provided with the distribution.								 *
+* 													 *
+* * Neither the name of the WIDE Project or NICT nor the 						 *
+*   names of its contributors may be used to endorse or 						 *
+*   promote products derived from this software without 						 *
+*   specific prior written permission of WIDE Project and 						 *
+*   NICT.												 *
+* 													 *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 	 *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 	 *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF   *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.								 *
+*********************************************************************************************************/
+
+/* 
+ * Configurable routing of messages for freeDiameter.
+ */
+
+#include "rt_default.h"
+
+/* The callback called on new messages */
+static int rtd_out(void * cbdata, struct msg * msg, struct fd_list * candidates)
+{
+	TRACE_ENTRY("%p %p %p", cbdata, msg, candidates);
+	
+	CHECK_PARAMS(msg && candidates);
+	
+	/* Simply pass it to the appropriate function */
+	if (FD_IS_LIST_EMPTY(candidates)) {
+		return 0;
+	} else {
+		return rtd_process( msg, candidates );
+	}
+}
+
+/* handler */
+static struct fd_rt_out_hdl * rtd_hdl = NULL;
+
+/* entry point */
+static int rtd_entry(char * conffile)
+{
+	TRACE_ENTRY("%p", conffile);
+	
+	/* Initialize the repo */
+	CHECK_FCT( rtd_init() );
+	
+	/* Parse the configuration file */
+	CHECK_FCT( rtd_conf_handle(conffile) );
+	
+#if 1
+	/* Dump the rules */
+	rtd_dump();
+#endif /* 0 */
+	
+	/* Register the callback */
+	CHECK_FCT( fd_rt_out_register( rtd_out, NULL, 5, &rtd_hdl ) );
+	
+	/* We're done */
+	return 0;
+}
+
+/* Unload */
+void fd_ext_fini(void)
+{
+	TRACE_ENTRY();
+	
+	/* Unregister the cb */
+	CHECK_FCT_DO( fd_rt_out_unregister ( rtd_hdl, NULL ), /* continue */ );
+	
+	/* Destroy the data */
+	rtd_fini();
+	
+	/* Done */
+	return ;
+}
+
+EXTENSION_ENTRY("rt_default", rtd_entry);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/rt_default/rt_default.h	Fri Jan 29 18:57:40 2010 +0900
@@ -0,0 +1,82 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License)                                                               *
+* Author: Sebastien Decugis <sdecugis@nict.go.jp>							 *
+*													 *
+* Copyright (c) 2009, WIDE Project and NICT								 *
+* All rights reserved.											 *
+* 													 *
+* Redistribution and use of this software in source and binary forms, with or without modification, are  *
+* permitted provided that the following conditions are met:						 *
+* 													 *
+* * Redistributions of source code must retain the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer.										 *
+*    													 *
+* * Redistributions in binary form must reproduce the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer in the documentation and/or other						 *
+*   materials provided with the distribution.								 *
+* 													 *
+* * Neither the name of the WIDE Project or NICT nor the 						 *
+*   names of its contributors may be used to endorse or 						 *
+*   promote products derived from this software without 						 *
+*   specific prior written permission of WIDE Project and 						 *
+*   NICT.												 *
+* 													 *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 	 *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 	 *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF   *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.								 *
+*********************************************************************************************************/
+
+/* Header file for the rt_default extension. 
+ *
+ *  See the rt_default.conf.sample file for the format of the configuration file.
+ */
+ 
+#include <freeDiameter/extension.h>
+
+/* Parse the configuration file */
+int rtd_conf_handle(char * conffile);
+
+/* Initialize the rules repository */
+int rtd_init(void);
+
+/* Destroy the rules repository */
+void rtd_fini(void);
+
+/* Some constants definitions */
+enum rtd_crit_type {
+	RTD_CRI_ALL	= 0,
+	RTD_CRI_OH,
+	RTD_CRI_OR,
+	RTD_CRI_DH,
+	RTD_CRI_DR,
+	RTD_CRI_UN,
+	RTD_CRI_SI,
+	
+	RTD_CRI_MAX
+};
+
+enum rtd_targ_type {
+	RTD_TAR_ID     = 0,
+	RTD_TAR_REALM,
+	
+	RTD_TAR_MAX
+};
+
+#define RTD_CRIT_REG	0x1
+#define RTD_TARG_REG	0x2
+
+/* Add a rule */
+int rtd_add(enum rtd_crit_type ct, char * criteria, enum rtd_targ_type tt, char * target, int score, int flags);
+
+/* Process a message & peer list through the rules repository, updating the scores */
+int rtd_process( struct msg * msg, struct fd_list * candidates );
+
+/* For debug: dump the rule repository */
+void rtd_dump(void);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/rt_default/rtd_conf.l	Fri Jan 29 18:57:40 2010 +0900
@@ -0,0 +1,147 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License)                                                               *
+* Author: Sebastien Decugis <sdecugis@nict.go.jp>							 *
+*													 *
+* Copyright (c) 2009, WIDE Project and NICT								 *
+* All rights reserved.											 *
+* 													 *
+* Redistribution and use of this software in source and binary forms, with or without modification, are  *
+* permitted provided that the following conditions are met:						 *
+* 													 *
+* * Redistributions of source code must retain the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer.										 *
+*    													 *
+* * Redistributions in binary form must reproduce the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer in the documentation and/or other						 *
+*   materials provided with the distribution.								 *
+* 													 *
+* * Neither the name of the WIDE Project or NICT nor the 						 *
+*   names of its contributors may be used to endorse or 						 *
+*   promote products derived from this software without 						 *
+*   specific prior written permission of WIDE Project and 						 *
+*   NICT.												 *
+* 													 *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 	 *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 	 *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF   *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.								 *
+*********************************************************************************************************/
+
+/* Tokenizer
+ *
+ */
+
+%{
+#include "rt_default.h"
+/* Include yacc tokens definitions */
+#include "rtd_conf.tab.h"
+
+/* Update the column information */
+#define YY_USER_ACTION { 						\
+	yylloc->first_column = yylloc->last_column + 1; 		\
+	yylloc->last_column = yylloc->first_column + yyleng - 1;	\
+}
+
+/* Avoid warning with newer flex */
+#define YY_NO_INPUT
+
+%}
+
+qstring		\"[^\"\n]*\"
+
+
+%option bison-bridge bison-locations
+%option noyywrap
+%option nounput
+
+%%
+
+	/* Update the line count */
+\n			{
+				yylloc->first_line++; 
+				yylloc->last_line++; 
+				yylloc->last_column=0; 
+			}
+	 
+	/* Eat all spaces but not new lines */
+([[:space:]]{-}[\n])+	;
+	/* Eat all comments */
+#.*$			;
+
+	/* Recognize any integer */
+[-]?[[:digit:]]+	{
+				/* Convert this to an integer value */
+				int ret=0;
+				ret = sscanf(yytext, "%i", &yylval->integer);
+				if (ret != 1) {
+					/* No matching: an error occurred */
+					fd_log_debug("Unable to convert the value '%s' to a valid number: %s\n", yytext, strerror(errno));
+					return LEX_ERROR; /* trig an error in yacc parser */
+					/* Maybe we could REJECT instead of failing here? */
+				}
+				return INTEGER;
+			}
+			
+	/* In addition, recognize some constant names as integers also */
+(?i:"NO_DELIVERY")	{	yylval->integer = FD_SCORE_NO_DELIVERY;		return INTEGER;		}
+(?i:"DEFAULT")		{	yylval->integer = FD_SCORE_DEFAULT; 		return INTEGER;		}
+(?i:"DEFAULT_REALM")	{	yylval->integer = FD_SCORE_DEFAULT_REALM; 	return INTEGER;		}
+(?i:"REALM")		{	yylval->integer = FD_SCORE_REALM; 		return INTEGER;		}
+(?i:"REDIR_HOST")	{	yylval->integer = FD_SCORE_REDIR_HOST; 		return INTEGER;		}
+(?i:"REDIR_APP")	{	yylval->integer = FD_SCORE_REDIR_APP; 		return INTEGER;		}
+(?i:"REDIR_REALM")	{	yylval->integer = FD_SCORE_REDIR_REALM; 	return INTEGER;		}
+(?i:"REDIR_REALM_APP")	{	yylval->integer = FD_SCORE_REDIR_REALM_APP; 	return INTEGER;		}
+(?i:"REDIR_USER")	{	yylval->integer = FD_SCORE_REDIR_USER; 		return INTEGER;		}
+(?i:"REDIR_SESSION")	{	yylval->integer = FD_SCORE_REDIR_SESSION; 	return INTEGER;		}
+(?i:"FINALDEST")	{	yylval->integer = FD_SCORE_FINALDEST; 		return INTEGER;		}
+
+	/* Recognize bracketed quoted strings */
+[[]{qstring}[]] 	{
+				/* Match a quoted string containing a regex */
+				CHECK_MALLOC_DO( yylval->string = strdup(yytext+2), 
+				{
+					TRACE_DEBUG(INFO, "Unable to copy the string '%s': %s\n", yytext, strerror(errno));
+					return LEX_ERROR; /* trig an error in yacc parser */
+				} );
+				yylval->string[strlen(yytext) - 4] = '\0';
+				return BQSTRING;
+			}
+			
+	/* Recognize quoted strings */
+{qstring}		{
+				/* Match a quoted string. */
+				CHECK_MALLOC_DO( yylval->string = strdup(yytext+1), 
+				{
+					TRACE_DEBUG(INFO, "Unable to copy the string '%s': %s\n", yytext, strerror(errno));
+					return LEX_ERROR; /* trig an error in yacc parser */
+				} );
+				yylval->string[strlen(yytext) - 2] = '\0';
+				return QSTRING;
+			}
+	
+	/* The key words */	
+(?i:"oh")	 	{	return OH;	}
+(?i:"or")	 	{	return OR;	}
+(?i:"dh")	 	{	return DH;	}
+(?i:"dr")	 	{	return DR;	}
+(?i:"un")	 	{	return UN;	}
+(?i:"si")	 	{	return SI;	}
+(?i:"i")	 	{	return IDENTITY;}
+(?i:"r")	 	{	return REALM;	}
+			
+	/* Valid single characters for yyparse */
+[*:=+;]			{ return yytext[0]; }
+
+	/* Unrecognized sequence, if it did not match any previous pattern */
+[^[:space:]\"*:=+;\n]+	{ 
+				fd_log_debug("Unrecognized text on line %d col %d: '%s'.\n", yylloc->first_line, yylloc->first_column, yytext);
+			 	return LEX_ERROR; 
+			}
+
+%%
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/rt_default/rtd_conf.y	Fri Jan 29 18:57:40 2010 +0900
@@ -0,0 +1,256 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License)                                                               *
+* Author: Sebastien Decugis <sdecugis@nict.go.jp>							 *
+*													 *
+* Copyright (c) 2009, WIDE Project and NICT								 *
+* All rights reserved.											 *
+* 													 *
+* Redistribution and use of this software in source and binary forms, with or without modification, are  *
+* permitted provided that the following conditions are met:						 *
+* 													 *
+* * Redistributions of source code must retain the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer.										 *
+*    													 *
+* * Redistributions in binary form must reproduce the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer in the documentation and/or other						 *
+*   materials provided with the distribution.								 *
+* 													 *
+* * Neither the name of the WIDE Project or NICT nor the 						 *
+*   names of its contributors may be used to endorse or 						 *
+*   promote products derived from this software without 						 *
+*   specific prior written permission of WIDE Project and 						 *
+*   NICT.												 *
+* 													 *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 	 *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 	 *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF   *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.								 *
+*********************************************************************************************************/
+
+/* Yacc extension's configuration parser.
+ * See doc/rt_default.conf.sample for configuration file format
+ */
+
+/* For development only : */
+%debug 
+%error-verbose
+
+/* The parser receives the configuration file filename as parameter */
+%parse-param {char * conffile}
+
+/* Keep track of location */
+%locations 
+%pure-parser
+
+%{
+#include "rt_default.h"
+#include "rtd_conf.tab.h"	/* bison is not smart enough to define the YYLTYPE before including this code, so... */
+
+/* Forward declaration */
+int yyparse(char * conffile);
+
+static int rules_added = 0;
+
+/* Parse the configuration file */
+int rtd_conf_handle(char * conffile)
+{
+	extern FILE * rtd_confin;
+	int ret;
+	
+	TRACE_ENTRY("%p", conffile);
+	
+	TRACE_DEBUG (FULL, "Parsing configuration file: %s...", conffile);
+	
+	rtd_confin = fopen(conffile, "r");
+	if (rtd_confin == NULL) {
+		ret = errno;
+		fd_log_debug("Unable to open extension configuration file %s for reading: %s\n", conffile, strerror(ret));
+		TRACE_DEBUG (INFO, "Error occurred, message logged -- configuration file.");
+		return ret;
+	}
+
+	ret = yyparse(conffile);
+
+	fclose(rtd_confin);
+
+	if (ret != 0) {
+		TRACE_DEBUG (INFO, "Unable to parse the configuration file.");
+		return EINVAL;
+	} else {
+		TRACE_DEBUG(FULL, "Added %d RULES routing entries successfully.", rules_added);
+	}
+	
+	return 0;
+}
+
+/* The Lex parser prototype */
+int rtd_conflex(YYSTYPE *lvalp, YYLTYPE *llocp);
+
+/* Function to report the errors */
+void yyerror (YYLTYPE *ploc, char * conffile, char const *s)
+{
+	TRACE_DEBUG(INFO, "Error in configuration parsing");
+	
+	if (ploc->first_line != ploc->last_line)
+		fd_log_debug("%s:%d.%d-%d.%d : %s\n", conffile, ploc->first_line, ploc->first_column, ploc->last_line, ploc->last_column, s);
+	else if (ploc->first_column != ploc->last_column)
+		fd_log_debug("%s:%d.%d-%d : %s\n", conffile, ploc->first_line, ploc->first_column, ploc->last_column, s);
+	else
+		fd_log_debug("%s:%d.%d : %s\n", conffile, ploc->first_line, ploc->first_column, s);
+}
+
+%}
+
+/* Values returned by lex for token */
+%union {
+	int		 integer;	/* Store integer values */
+	char 		*string;	/* The string is allocated by strdup in lex.*/
+	struct {
+		char * str;
+		int regex;
+	}		 tstring;	/* typed string */
+	struct {
+		char * str;
+		int    regex;
+		enum rtd_crit_type type;
+	}		 criteria;
+	struct {
+		char * str;
+		int    regex;
+		enum rtd_targ_type type;
+	}		 target;
+}
+
+/* In case of error in the lexical analysis */
+%token 		LEX_ERROR
+
+/* A (de)quoted string (malloc'd in lex parser; it must be freed after use) */
+%token <string>	QSTRING
+/* A (de)bracket-quoted string (malloc'd in lex parser; it must be freed after use): ["blahblah"] */
+%token <string>	BQSTRING
+
+/* An integer value */
+%token <integer> INTEGER
+
+/* The types for this gramar */
+%type <tstring>  TSTRING
+%type <criteria> CRITERIA
+%type <target> 	 TARGET
+
+/* Tokens */
+%token 		OH
+%token 		OR
+%token 		DH
+%token 		DR
+%token 		UN
+%token 		SI
+
+%token 		IDENTITY
+%token 		REALM
+
+
+
+/* -------------------------------------- */
+%%
+
+	/* The grammar definition */
+conffile:		/* empty grammar is OK */
+			| conffile rule
+			;
+			
+	/* a RULE entry */
+rule:			CRITERIA ':' TARGET '+' '=' INTEGER ';'
+			{
+				int flag = 0;
+				if ($1.regex)
+					flag |= RTD_CRIT_REG;
+				if ($3.regex)
+					flag |= RTD_TARG_REG;
+					
+				/* Add this rule to the repository */
+				CHECK_FCT_DO( rtd_add($1.type, $1.str, $3.type, $3.str, $6, flag),
+					{
+						yyerror (&yylloc, conffile, "An error occurred while adding a rule, aborting...");
+						YYERROR;
+					} );
+			}
+			;
+	
+	/* QSTRING and BQSTRING are equivalent in the grammar */
+TSTRING:		QSTRING
+			{
+				$$.str = $1;
+				$$.regex = 0;
+			}
+			| BQSTRING
+			{
+				$$.str = $1;
+				$$.regex = 1;
+			}
+			;
+
+	/* Details of the CRITERIA type */
+CRITERIA:		'*'
+			{
+				$$.str = NULL;
+				$$.regex = 0;
+				$$.type = RTD_CRI_ALL;
+			}
+			| OH '=' TSTRING
+			{
+				$$.str = $3.str;
+				$$.regex =$3.regex;
+				$$.type = RTD_CRI_OH;
+			}
+			| OR '=' TSTRING
+			{
+				$$.str = $3.str;
+				$$.regex =$3.regex;
+				$$.type = RTD_CRI_OR;
+			}
+			| DH '=' TSTRING
+			{
+				$$.str = $3.str;
+				$$.regex =$3.regex;
+				$$.type = RTD_CRI_DH;
+			}
+			| DR '=' TSTRING
+			{
+				$$.str = $3.str;
+				$$.regex =$3.regex;
+				$$.type = RTD_CRI_DR;
+			}
+			| UN '=' TSTRING
+			{
+				$$.str = $3.str;
+				$$.regex =$3.regex;
+				$$.type = RTD_CRI_UN;
+			}
+			| SI '=' TSTRING
+			{
+				$$.str = $3.str;
+				$$.regex =$3.regex;
+				$$.type = RTD_CRI_SI;
+			}
+			;
+
+	/* Details of the TARGET type */
+TARGET:			IDENTITY '=' TSTRING
+			{
+				$$.str = $3.str;
+				$$.regex =$3.regex;
+				$$.type = RTD_TAR_ID;
+			}
+			| REALM '=' TSTRING
+			{
+				$$.str = $3.str;
+				$$.regex =$3.regex;
+				$$.type = RTD_TAR_REALM;
+			}
+			;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/rt_default/rtd_rules.c	Fri Jan 29 18:57:40 2010 +0900
@@ -0,0 +1,113 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License)                                                               *
+* Author: Sebastien Decugis <sdecugis@nict.go.jp>							 *
+*													 *
+* Copyright (c) 2009, WIDE Project and NICT								 *
+* All rights reserved.											 *
+* 													 *
+* Redistribution and use of this software in source and binary forms, with or without modification, are  *
+* permitted provided that the following conditions are met:						 *
+* 													 *
+* * Redistributions of source code must retain the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer.										 *
+*    													 *
+* * Redistributions in binary form must reproduce the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer in the documentation and/or other						 *
+*   materials provided with the distribution.								 *
+* 													 *
+* * Neither the name of the WIDE Project or NICT nor the 						 *
+*   names of its contributors may be used to endorse or 						 *
+*   promote products derived from this software without 						 *
+*   specific prior written permission of WIDE Project and 						 *
+*   NICT.												 *
+* 													 *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 	 *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 	 *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF   *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.								 *
+*********************************************************************************************************/
+
+#include "rt_default.h"
+
+/* The regular expressions header */
+#include <regex.h>
+
+/* We will search for each candidate peer all the rules that are defined, and check which one applies to the message
+ * Therefore our repository is organized hierarchicaly.
+ *  At the top level, we have two lists of TARGETS (one for IDENTITY, one for REALM), ordered as follow:
+ *   - first, the TARGETS defined with a regular expression. We will try matching all regexp to all candidates in the list.
+ *   - then, the TARGETS defined by a plain text. We don't have to compare the whole list to each candidate since the list is ordered.
+ *
+ *  Under each TARGET element, we have the list of RULES that are defined for this target, ordered by CRITERIA type, then is_regex, then string value.
+ *
+ * Note: Except during configuration parsing and module termination, the lists are only ever accessed read-only, so we do not need a lock.
+ */
+
+/* Structure to hold the data that is used for matching. Note that in case is_regex is true, the string to be matched must be \0-terminated. */
+struct match_data {
+	int	 is_regex;	/* determines how the string is matched */
+	char 	*plain;		/* match this value with strcasecmp if is_regex is false. The string is allocated by the lex tokenizer, must be freed at the end. */
+	regex_t  preg;		/* match with regexec if is_regex is true. regfree must be called at the end. A copy of the original string is anyway saved in plain. */
+};
+
+/* Structure of a TARGET element */
+struct target {
+	struct fd_list		chain;	/* link in the top-level list */
+	struct match_data	md;	/* the data to determine if the current candidate matches this element */
+	struct fd_list		rules;	/* Sentinel for the list of rules applying to this target */
+	/* note : we do not need the rtd_targ_type here, it is implied by the root of the list this target element is attached to */
+};
+
+/* Structure of a RULE element */
+struct rule {
+	struct fd_list		chain;	/* link in the parent target list */
+	enum rtd_crit_type	type;	/* What kind of criteria the message must match for the rule to apply */
+	struct match_data	md;	/* the data that the criteria must match, if it is different from RTD_CRI_ALL */
+	int			score;	/* The score added to the candidate, if the message matches this criteria */
+};
+
+/* The sentinels for the TARGET lists */
+static struct fd_list	TARGETS[RTD_TAR_MAX];
+
+
+
+int rtd_init(void)
+{
+	TRACE_ENTRY();
+	
+	return 0;
+}
+
+void rtd_fini(void)
+{
+	TRACE_ENTRY();
+
+}
+
+int rtd_add(enum rtd_crit_type ct, char * criteria, enum rtd_targ_type tt, char * target, int score, int flags)
+{
+	TRACE_ENTRY("%d %p %d %p %d %x", ct, criteria, tt, target, score, flags);
+	
+	CHECK_PARAMS((ct < RTD_CRI_MAX) && ((ct == 0) || criteria) && (tt < RTD_TAR_MAX) && target);
+	
+	
+	
+	return 0;
+}
+
+int rtd_process( struct msg * msg, struct fd_list * candidates )
+{
+	return ENOTSUP;
+}
+
+void rtd_dump(void)
+{
+	fd_log_debug("[rt_default] Dumping rules repository...\n");
+	fd_log_debug("[rt_default] End of dump\n");
+}
"Welcome to our mercurial repository"