changeset 12:418d2ce80dc8

Added support in configuration file for peers declaration
author Sebastien Decugis <sdecugis@nict.go.jp>
date Mon, 28 Sep 2009 17:29:25 +0900
parents 6576ef5e01eb
children ef9ef3bf4752
files doc/freediameter.conf.sample freeDiameter/fD.h freeDiameter/fdd.l freeDiameter/fdd.y freeDiameter/main.c freeDiameter/peers.c include/freeDiameter/freeDiameter.h
diffstat 7 files changed, 357 insertions(+), 62 deletions(-) [+]
line wrap: on
line diff
--- a/doc/freediameter.conf.sample	Fri Sep 25 18:05:06 2009 +0900
+++ b/doc/freediameter.conf.sample	Mon Sep 28 17:29:25 2009 +0900
@@ -6,23 +6,23 @@
 # The Diameter Identity of this daemon.
 # This must be a valid FQDN that resolves to the local host.
 # Default: hostname's FQDN
-#LocalIdentity = "aaa.koganei.wide.ad.jp";
+#Identity = "aaa.koganei.wide.ad.jp";
 
 # The Diameter Realm of this daemon.
-# Default: the domain part of LocalIdentity.
-#LocalRealm = "wide.ad.jp";
+# Default: the domain part of Identity.
+#Realm = "wide.ad.jp";
 
 ##############################################################
 ##  Transport protocol configuration
 
 # The port this peer is listening on for incoming connections (TCP and SCTP).
 # Default: 3868
-#LocalPort = 3868;
+#Port = 3868;
 
 # The port this peer is listening on for incoming TLS connections (TCP and SCTP).
 # See TLS_old_method for more information.
 # Default: 3869
-#LocalSecPort = 3869;
+#SecPort = 3869;
 
 # Use RFC3588 method for TLS protection, where TLS is negociated after CER/CEA
 # on the same port. This only affects outgoing connections. It can be overwritten
@@ -93,7 +93,7 @@
 # Default: Relaying is enabled.
 #NoRelay;
 
-# Other applications are configured by extensions.
+# Other applications are configured by loading appropriate extensions.
 
 ##############################################################
 ##  Extensions configuration
@@ -104,21 +104,51 @@
 # by loadable extensions (plug-ins).
 #  These extensions may in addition receive the name of a 
 # configuration file, the format of which is extension-specific.
-
+#
 # Format:
 #LoadExtension = "/path/to/extension" [ : "/optional/configuration/file" ] ;
+#
 # Exemples:
 #LoadExtension = "extensions/sample.so";
 #LoadExtension = "extensions/sample.so":"conf/sample.conf";
 
 
+##############################################################
+##  Peers configuration
+
+#  The local server listens for incoming connections. By default,
+# all unknown connecting peers are rejected. Extensions can override this behavior.
+# 
+#  In addition to incoming connections, the local peer can
+# be configured to establish and maintain connections to some 
+# Diameter nodes and allow connections from these nodes.
+#  This is achieved with the ConnectPeer directive described bellow.
+#
+# Note that the configured Diameter Id MUST match
+# the information received inside CEA, or the connection will be aborted.
+#
+# Format:
+#ConnectPeer = "diameterid" [ { parameter1; parameter2; ...} ] ;
+# Parameters that can be specified in the peer's parameter list:
+#  No_TCP; No_SCTP; No_IP; No_IPv6; Prefer_TCP; TLS_old_method;
+#  No_TLS;       # assume transparent security instead of TLS
+#  Port = 3868;  # The port to connect to
+#  SCTP_streams = 30;
+#  TcTimer = 30;
+#  TwTimer = 30;
+#  ConnectTo = "202.249.37.5";
+#  ConnectTo = "2001:200:903:2::202:1";
+# Examples:
+#ConnectPeer = "aaa.wide.ad.jp";
+#ConnectPeer = "old.diameter.serv" { TcTimer = 60; TLS_old_method; No_SCTP; } ;
+
 
 ##############################################################
 # -------- Test configuration ---------
-LocalIdentity = "aaa.koganei.wide.ad.jp";
-LocalRealm = "wide.ad.jp";
-LocalPort = 3866;
-LocalSecPort = 3867;
+Identity = "aaa.koganei.wide.ad.jp";
+Realm = "wide.ad.jp";
+Port = 3866;
+SecPort = 3867;
 TLS_old_method;
 No_IP;
 Prefer_TCP;
@@ -131,3 +161,4 @@
 LoadExtension = "extensions/dbg_monitor.fdx";
 LoadExtension = "extensions/dict_nasreq.fdx";
 LoadExtension = "extensions/dict_eap.fdx";
+ConnectPeer = "jules.nautilus6.org" ;
--- a/freeDiameter/fD.h	Fri Sep 25 18:05:06 2009 +0900
+++ b/freeDiameter/fD.h	Mon Sep 28 17:29:25 2009 +0900
@@ -71,18 +71,89 @@
 /* Peers */
 struct fd_peer { /* The "real" definition of the peer structure */
 	
-	struct peer_hdr	p_hdr; /* contains all public data */
+	/* The public data */
+	struct peer_hdr	 p_hdr;
 	
-	int		p_eyec;	/* Eye catcher, EYEC_PEER */
+	/* Eye catcher, EYEC_PEER */
+	int		 p_eyec;
 	#define EYEC_PEER	0x373C9336
 	
-	/* threads, message queues, socket & callbacks */
+	/* Origin of this peer object, for debug */
+	char		*p_dbgorig;
+	
+	/* Mutex that protect this peer structure */
+	pthread_mutex_t	 p_mtx;
+	
+	/* Reference counter -- freed only when this reaches 0 */
+	unsigned	 p_refcount;
+	
+	/* Chaining in peers sublists */
+	struct fd_list	 p_expiry; 	/* list of expiring peers, ordered by their timeout value */
+	struct fd_list	 p_actives;	/* list of peers in the STATE_OPEN state -- faster routing creation */
+	
+	/* The next hop-by-hop id value for the link */
+	uint32_t	 p_hbh;
+	
+	/* Some flags influencing the peer state machine */
+	struct {
+		unsigned pf_responder	: 1;	/* The local peer is responder on the connection */
+		
+		unsigned pf_dw_pending 	: 1;	/* A DWR message was sent and not answered yet */
+		
+		unsigned pf_cnx_pb	: 1;	/* The peer was disconnected because of watchdogs; must exchange 3 watchdogs before putting back to normal */
+		unsigned pf_reopen_cnt	: 2;	/* remaining DW to be exchanged after re-established connection */
+		
+		/* to be completed */
+		
+	}		 p_flags;
+	
+	/* The events queue, peer state machine thread, timer for states timeouts */
+	struct fifo	*p_events;
+	pthread_t	 p_psm;
+	struct timespec	 p_psm_timer;
+	
+	/* Received message queue, and thread managing reception of messages */
+	struct fifo	*p_recv;
+	pthread_t	 p_inthr;
+	
+	/* Outgoing message queue, and thread managing sending the messages */
+	struct fifo	*p_tosend;
+	pthread_t	 p_outthr;
+	
+	/* Sent requests (for fallback), list of struct sentreq ordered by hbh */
+	struct fd_list	 p_sentreq;
+	
+	/* connection context: socket & other metadata */
+	struct cnxctx	*p_cnxctx;
 	
 };
+#define CHECK_PEER( _p ) \
+	(((_p) != NULL) && (((struct fd_peer *)(_p))->p_eyec == EYEC_PEER))
 
+/* Events codespace for struct fd_peer->p_events */
+enum {
+	/* request to terminate this peer : disconnect, requeue all messages */
+	 FDEVP_TERMINATE = 2000
+	
+	/* Dump all info about this peer in the debug log */
+	,FDEVP_DUMP_ALL
+	
+	/* A message was received in the peer */
+	,FDEVP_MSG_INCOMING
+};
+
+/* Structure to store a sent request */
+struct sentreq {
+	struct fd_list	chain; 	/* the "o" field points directly to the hop-by-hop of the request (uint32_t *)  */
+	struct msg	*req;	/* A request that was sent and not yet answered. */
+};
+
+/* Functions */
 int fd_peer_init();
-void fd_peer_dump(int details);
+void fd_peer_dump_list(int details);
 int fd_peer_start();
 int fd_peer_waitstart();
 
+
+
 #endif /* _FD_H */
--- a/freeDiameter/fdd.l	Fri Sep 25 18:05:06 2009 +0900
+++ b/freeDiameter/fdd.l	Mon Sep 28 17:29:25 2009 +0900
@@ -111,10 +111,10 @@
 			}
 				
 	/* Full words tokens (keywords) */
-(?i:"LocalIdentity")	{ return LOCALIDENTITY;	}
-(?i:"LocalRealm")	{ return LOCALREALM;	}
-(?i:"LocalPort")	{ return LOCALPORT;	}
-(?i:"LocalSecPort")	{ return LOCALSECPORT;	}
+(?i:"Identity")		{ return IDENTITY;	}
+(?i:"Realm")		{ return REALM;   	}
+(?i:"Port")		{ return PORT;    	}
+(?i:"SecPort")		{ return SECPORT;  	}
 (?i:"No_IPv6")		{ return NOIP6;		}
 (?i:"No_IP")		{ return NOIP;		}
 (?i:"No_TCP")		{ return NOTCP;		}
@@ -127,6 +127,9 @@
 (?i:"TwTimer")		{ return TWTIMER;	}
 (?i:"NoRelay")		{ return NORELAY;	}
 (?i:"LoadExtension")	{ return LOADEXT;	}
+(?i:"ConnectPeer")	{ return CONNPEER;	}
+(?i:"ConnectTo")	{ return CONNTO;	}
+(?i:"No_TLS")		{ return NOTLS;		}
 
 
 	/* Valid single characters for yyparse */
--- a/freeDiameter/fdd.y	Fri Sep 25 18:05:06 2009 +0900
+++ b/freeDiameter/fdd.y	Mon Sep 28 17:29:25 2009 +0900
@@ -69,12 +69,19 @@
 		fprintf(stderr, "%s:%d.%d : %s\n", conf->cnf_file, ploc->first_line, ploc->first_column, s);
 }
 
+int got_peer_noip = 0;
+int got_peer_noipv6 = 0;
+int got_peer_notcp = 0;
+int got_peer_nosctp = 0;
+
+struct peer_info fddpi;
+
 %}
 
 /* Values returned by lex for token */
 %union {
-	char 		*string;	/* The string is allocated by strdup in lex.*/
-	int		 integer;	/* Store integer values */
+	char 		 *string;	/* The string is allocated by strdup in lex.*/
+	int		  integer;	/* Store integer values */
 }
 
 /* In case of error in the lexical analysis */
@@ -83,24 +90,27 @@
 %token <string>	QSTRING
 %token <integer> INTEGER
 
-%type <string> extconf
+%type <string> 	extconf
 
-%token		LOCALIDENTITY
-%token		LOCALREALM
-%token		LOCALPORT
-%token		LOCALSECPORT
+%token		IDENTITY
+%token		REALM
+%token		PORT
+%token		SECPORT
 %token		NOIP
 %token		NOIP6
 %token		NOTCP
 %token		NOSCTP
 %token		PREFERTCP
 %token		OLDTLS
+%token		NOTLS
 %token		SCTPSTREAMS
 %token		LISTENON
 %token		TCTIMER
 %token		TWTIMER
 %token		NORELAY
 %token		LOADEXT
+%token		CONNPEER
+%token		CONNTO
 
 
 /* -------------------------------------- */
@@ -108,12 +118,12 @@
 
 	/* The grammar definition - Sections blocs. */
 conffile:		/* Empty is OK */
-			| conffile localidentity
-			| conffile localrealm
+			| conffile identity
+			| conffile realm
 			| conffile tctimer
 			| conffile twtimer
-			| conffile localport
-			| conffile localsecport
+			| conffile port
+			| conffile secport
 			| conffile sctpstreams
 			| conffile listenon
 			| conffile norelay
@@ -124,15 +134,26 @@
 			| conffile prefertcp
 			| conffile oldtls
 			| conffile loadext
+			| conffile connpeer
+			| conffile errors
+			{
+				yyerror(&yylloc, conf, "An error occurred while parsing the configuration file");
+				return EINVAL;
+			}
 			;
 
-localidentity:		LOCALIDENTITY '=' QSTRING ';'
+			/* Lexical or syntax error */
+errors:			LEX_ERROR
+			| error
+			;
+
+identity:		IDENTITY '=' QSTRING ';'
 			{
 				conf->cnf_diamid = $3;
 			}
 			;
 
-localrealm:		LOCALREALM '=' QSTRING ';'
+realm:			REALM '=' QSTRING ';'
 			{
 				conf->cnf_diamrlm = $3;
 			}
@@ -154,7 +175,7 @@
 			}
 			;
 
-localport:		LOCALPORT '=' INTEGER ';'
+port:			PORT '=' INTEGER ';'
 			{
 				CHECK_PARAMS_DO( ($3 > 0) && ($3 < 1<<16),
 					{ yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
@@ -162,7 +183,7 @@
 			}
 			;
 
-localsecport:		LOCALSECPORT '=' INTEGER ';'
+secport:		SECPORT '=' INTEGER ';'
 			{
 				CHECK_PARAMS_DO( ($3 > 0) && ($3 < 1<<16),
 					{ yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
@@ -209,24 +230,54 @@
 
 noip:			NOIP ';'
 			{
+				if (got_peer_noipv6) { 
+					yyerror (&yylloc, conf, "No_IP conflicts with a ConnectPeer directive No_IPv6."); 
+					YYERROR; 
+				}
 				conf->cnf_flags.no_ip4 = 1;
 			}
 			;
 
 noip6:			NOIP6 ';'
 			{
+				if (got_peer_noip) { 
+					yyerror (&yylloc, conf, "No_IP conflicts with a ConnectPeer directive No_IP."); 
+					YYERROR; 
+				}
 				conf->cnf_flags.no_ip6 = 1;
 			}
 			;
 
 notcp:			NOTCP ';'
 			{
+				#ifdef DISABLE_SCTP
+				yyerror (&yylloc, conf, "No_TCP cannot be specified for daemon compiled with DISABLE_SCTP option."); 
+				YYERROR; 
+				#endif
+				if (conf->cnf_flags.no_sctp)
+				{
+					yyerror (&yylloc, conf, "No_TCP conflicts with No_SCTP directive." ); 
+					YYERROR; 
+				}
+				if (got_peer_nosctp) { 
+					yyerror (&yylloc, conf, "No_TCP conflicts with a ConnectPeer directive No_SCTP."); 
+					YYERROR; 
+				}
 				conf->cnf_flags.no_tcp = 1;
 			}
 			;
 
 nosctp:			NOSCTP ';'
 			{
+				if (conf->cnf_flags.no_tcp)
+				{
+					yyerror (&yylloc, conf, "No_SCTP conflicts with No_TCP directive." ); 
+					YYERROR; 
+				}
+				if (got_peer_notcp) { 
+					yyerror (&yylloc, conf, "No_SCTP conflicts with a ConnectPeer directive No_TCP.");
+					YYERROR;
+				}
 				conf->cnf_flags.no_sctp = 1;
 			}
 			;
@@ -259,3 +310,130 @@
 				$$ = $2;
 			}
 			;
+			
+connpeer:		{
+				memset(&fddpi, 0, sizeof(fddpi));
+			}
+			CONNPEER '=' QSTRING peerinfo ';'
+			{
+				fddpi.pi_diamid = $4;
+				CHECK_FCT_DO( fd_peer_add ( &fddpi, conf->cnf_file, NULL, NULL ),
+					{ yyerror (&yylloc, conf, "Error adding ConnectPeer information"); YYERROR; } );
+					
+				/* Now destroy any content in the structure */
+				free(fddpi.pi_diamid);
+				while (!FD_IS_LIST_EMPTY(&fddpi.pi_endpoints)) {
+					struct fd_list * li = fddpi.pi_endpoints.next;
+					fd_list_unlink(li);
+					free(li);
+				}
+			}
+			;
+			
+peerinfo:		/* empty */
+			| '{' peerparams '}'
+			;
+			
+peerparams:		/* empty */
+			| peerparams NOIP ';'
+			{
+				if ((conf->cnf_flags.no_ip6) || (fddpi.pi_flags.pro3 == PI_P3_IP)) { 
+					yyerror (&yylloc, conf, "No_IP conflicts with a No_IPv6 directive.");
+					YYERROR;
+				}
+				got_peer_noip++;
+				fddpi.pi_flags.pro3 = PI_P3_IPv6;
+			}
+			| peerparams NOIP6 ';'
+			{
+				if ((conf->cnf_flags.no_ip4) || (fddpi.pi_flags.pro3 == PI_P3_IPv6)) { 
+					yyerror (&yylloc, conf, "No_IPv6 conflicts with a No_IP directive.");
+					YYERROR;
+				}
+				got_peer_noipv6++;
+				fddpi.pi_flags.pro3 = PI_P3_IP;
+			}
+			| peerparams NOTCP ';'
+			{
+				#ifdef DISABLE_SCTP
+					yyerror (&yylloc, conf, "No_TCP cannot be specified in daemon compiled with DISABLE_SCTP option.");
+					YYERROR;
+				#endif
+				if ((conf->cnf_flags.no_sctp) || (fddpi.pi_flags.pro4 == PI_P4_TCP)) { 
+					yyerror (&yylloc, conf, "No_TCP conflicts with a No_SCTP directive.");
+					YYERROR;
+				}
+				got_peer_notcp++;
+				fddpi.pi_flags.pro4 = PI_P4_SCTP;
+			}
+			| peerparams NOSCTP ';'
+			{
+				if ((conf->cnf_flags.no_tcp) || (fddpi.pi_flags.pro4 == PI_P4_SCTP)) { 
+					yyerror (&yylloc, conf, "No_SCTP conflicts with a No_TCP directive.");
+					YYERROR;
+				}
+				got_peer_nosctp++;
+				fddpi.pi_flags.pro4 = PI_P4_TCP;
+			}
+			| peerparams PREFERTCP ';'
+			{
+				fddpi.pi_flags.alg = PI_ALGPREF_TCP;
+			}
+			| peerparams OLDTLS ';'
+			{
+				if (fddpi.pi_flags.sec == PI_SEC_NONE) { 
+					yyerror (&yylloc, conf, "ConnectPeer: TLS_old_method conflicts with No_TLS.");
+					YYERROR;
+				}
+				fddpi.pi_flags.sec = PI_SEC_TLS_OLD;
+			}
+			| peerparams NOTLS ';'
+			{
+				if (fddpi.pi_flags.sec == PI_SEC_TLS_OLD) { 
+					yyerror (&yylloc, conf, "ConnectPeer: No_TLS conflicts with TLS_old_method.");
+					YYERROR;
+				}
+				fddpi.pi_flags.sec = PI_SEC_NONE;
+			}
+			| peerparams PORT '=' INTEGER ';'
+			{
+				CHECK_PARAMS_DO( ($4 > 0) && ($4 < 1<<16),
+					{ yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
+				fddpi.pi_port = (uint16_t)$4;
+			}
+			| peerparams SCTPSTREAMS '=' INTEGER ';'
+			{
+				CHECK_PARAMS_DO( ($4 > 0) && ($4 < 1<<16),
+					{ yyerror (&yylloc, conf, "Invalid value"); YYERROR; } );
+				fddpi.pi_streams = (uint16_t)$4;
+			}
+			| peerparams TCTIMER '=' INTEGER ';'
+			{
+				fddpi.pi_tctimer = $4;
+			}
+			| peerparams TWTIMER '=' INTEGER ';'
+			{
+				fddpi.pi_twtimer = $4;
+			}
+			| peerparams CONNTO '=' QSTRING ';'
+			{
+				struct fd_endpoint * ep;
+				struct addrinfo hints, *ai;
+				int ret;
+				
+				CHECK_MALLOC_DO( ep = malloc(sizeof(struct fd_endpoint)),
+					{ yyerror (&yylloc, conf, "Out of memory"); YYERROR; } );
+				memset(ep, 0, sizeof(struct fd_endpoint));
+				fd_list_init(&ep->chain, NULL);
+				
+				memset(&hints, 0, sizeof(hints));
+				hints.ai_flags = AI_ADDRCONFIG;
+				ret = getaddrinfo($4, NULL, &hints, &ai);
+				if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); YYERROR; }
+				
+				memcpy(&ep->ss, ai->ai_addr, ai->ai_addrlen);
+				free($4);
+				freeaddrinfo(ai);
+				fd_list_insert_before(&fddpi.pi_endpoints, &ep->chain);
+			}
+			;
--- a/freeDiameter/main.c	Fri Sep 25 18:05:06 2009 +0900
+++ b/freeDiameter/main.c	Mon Sep 28 17:29:25 2009 +0900
@@ -116,7 +116,7 @@
 				break;
 			
 			case FDEV_DUMP_PEERS:
-				fd_peer_dump(FULL);
+				fd_peer_dump_list(FULL);
 				break;
 			
 			case FDEV_TERMINATE:
--- a/freeDiameter/peers.c	Fri Sep 25 18:05:06 2009 +0900
+++ b/freeDiameter/peers.c	Mon Sep 28 17:29:25 2009 +0900
@@ -46,8 +46,6 @@
 	, "STATE_SUSPECT"
 	, "STATE_REOPEN"
 	};
-#define STATE_STR(state) \
-	peer_state_str[ (state) <= STATE_REOPEN ? (state) : 0 ]
 
 struct fd_list   fd_g_peers;
 pthread_rwlock_t fd_g_peers_rw;
@@ -93,7 +91,7 @@
 }
 
 /* Dump the list of peers */
-void fd_peer_dump(int details)
+void fd_peer_dump_list(int details)
 {
 	struct fd_list * li;
 	
@@ -107,14 +105,21 @@
 			continue;
 		}
 		
-		fd_log_debug("   %s %s", np->p_hdr.info.pi_diamid, STATE_STR(np->p_hdr.info.pi_state));
+		fd_log_debug("   %s\t%s", STATE_STR(np->p_hdr.info.pi_state), np->p_hdr.info.pi_diamid);
 		if (details > INFO) {
-			fd_log_debug(" (rlm:%s)", np->p_hdr.info.pi_realm);
+			fd_log_debug("\t(rlm:%s)", np->p_hdr.info.pi_realm);
 			if (np->p_hdr.info.pi_prodname)
-				fd_log_debug(" ['%s' %u]", np->p_hdr.info.pi_prodname, np->p_hdr.info.pi_firmrev);
+				fd_log_debug("\t['%s' %u]", np->p_hdr.info.pi_prodname, np->p_hdr.info.pi_firmrev);
+			fd_log_debug("\t(from %s)", np->p_dbgorig);
 		}
 		fd_log_debug("\n");
 	}
 	
 	CHECK_FCT_DO( pthread_rwlock_unlock(&fd_g_peers_rw), /* continue */ );
 }
+
+/* Add a new peer entry */
+int fd_peer_add ( struct peer_info * info, char * orig_dbg, void (*cb)(struct peer_info *, void *), void * cb_data )
+{
+	return ENOTSUP;
+}
--- a/include/freeDiameter/freeDiameter.h	Fri Sep 25 18:05:06 2009 +0900
+++ b/include/freeDiameter/freeDiameter.h	Mon Sep 28 17:29:25 2009 +0900
@@ -124,12 +124,12 @@
 
 /* Events codespace for fd_g_config->cnf_main_ev */
 enum {
-	FDEV_TERMINATE = 1000,	/* request to terminate */
-	FDEV_DUMP_DICT,		/* Dump the content of the dictionary */
-	FDEV_DUMP_EXT,		/* Dump state of extensions */
-	FDEV_DUMP_QUEUES,	/* Dump the message queues */
-	FDEV_DUMP_CONFIG,	/* Dump the configuration */
-	FDEV_DUMP_PEERS		/* Dump the list of peers */
+	 FDEV_TERMINATE = 1000	/* request to terminate */
+	,FDEV_DUMP_DICT		/* Dump the content of the dictionary */
+	,FDEV_DUMP_EXT		/* Dump state of extensions */
+	,FDEV_DUMP_QUEUES	/* Dump the message queues */
+	,FDEV_DUMP_CONFIG	/* Dump the configuration */
+	,FDEV_DUMP_PEERS	/* Dump the list of peers */
 };
 
 
@@ -160,32 +160,38 @@
 	STATE_REOPEN		/* Connection has been re-established, waiting for 3 DWR/DWA exchanges before putting back to service */
 };
 extern const char *peer_state_str[];
+#define STATE_STR(state) \
+	peer_state_str[ ((unsigned)(state)) <= STATE_REOPEN ? ((unsigned)(state)) : 0 ]
 
 /* Information about a remote peer, used both for query and for creating a new entry */
 struct peer_info {
 	
-	/* This information is always there */
 	char * pi_diamid;	/* UTF-8, \0 terminated. The Diameter Identity of the remote peer */
 	char * pi_realm;	/* idem, its realm. */
 	
-	/* Flags */
 	struct {
-		#define PI_PROT_DEFAULT	0	/* Use the default algorithm configured for the host */
-		#define PI_PROT_TCP	1
-		#define PI_PROT_SCTP	2
-		unsigned	proto :2;
+		#define PI_P3_DEFAULT	0	/* Use the default L3 protocol configured for the host */
+		#define PI_P3_IP	1	/* Use only IP to connect to this peer */
+		#define PI_P3_IPv6	2	/* resp, IPv6 */
+		unsigned	pro3 :2;
 		
-		#define PI_SEC_DEFAULT	0	/* The default behavior configured for the host */
+		#define PI_P4_DEFAULT	0	/* Use the default L4 proto configured for the host */
+		#define PI_P4_TCP	1	/* Only use TCP */
+		#define PI_P4_SCTP	2	/* Only use SCTP */
+		unsigned	pro4 :2;
+		
+		#define PI_ALGPREF_SCTP	0	/* SCTP is initially attempted */
+		#define PI_ALGPREF_TCP	1	/* TCP is initially attempted */
+		unsigned	alg :1;
+		
+		#define PI_SEC_DEFAULT	0	/* New TLS security (dedicated port protecting also CER/CEA) */
 		#define PI_SEC_NONE	1	/* Transparent security with this peer (IPsec) */
-		#define PI_SEC_TLS_NEW	2	/* New TLS security (dedicated port protecting also CER/CEA) */
-		#define PI_SEC_TLS_OLD	3	/* Old TLS security (inband on default port) */
+		#define PI_SEC_TLS_OLD	2	/* Old TLS security (inband on default port) */
 		unsigned	sec :2;
 		
-		#define PI_EXP_DEFAULT	0
-		#define PI_EXP_NONE	1	/* the peer entry does not expire */
-		#define PI_EXP_INACTIVE	2	/* the peer entry expires after pi_lft seconds without activity */
-		#define PI_EXP_LIFETIME	3	/* the peer SA information is destroyed after lft seconds (example: DNS timeout) */
-		unsigned	exp :2;
+		#define PI_EXP_NONE	0	/* the peer entry does not expire */
+		#define PI_EXP_INACTIVE	1	/* the peer entry expires after pi_lft seconds without activity */
+		unsigned	exp :1;
 		
 		/* Following flags are read-only and received from remote peer */
 		#define PI_INB_NONE	1	/* Remote peer advertised inband-sec-id 0 (None) */
@@ -231,6 +237,7 @@
  *
  * PARAMETERS:
  *  info 	: Information to create the peer.
+ *  orig_dbg	: A string indicating the origin of the peer information, for debug (ex: conf, redirect, ...)
  *  cb		: optional, a callback to call (once) when the peer connection is established or failed
  *  cb_data	: opaque data to pass to the callback.
  *
@@ -247,7 +254,7 @@
  *  (other standard errors may be returned, too, with their standard meaning. Example:
  *    ENOMEM 	: Memory allocation for the new object element failed.)
  */
-int fd_peer_add ( struct peer_info * info, void (*cb)(struct peer_info *, void *), void * cb_data );
+int fd_peer_add ( struct peer_info * info, char * orig_dbg, void (*cb)(struct peer_info *, void *), void * cb_data );
 
 /*
  * FUNCTION:	peer_validate_register
"Welcome to our mercurial repository"