Index: freeDiameter/fD.h
===================================================================
--- freeDiameter/fD.h	(revision 25)
+++ freeDiameter/fD.h	(revision 28)
@@ -157,5 +157,5 @@
 	,FDEVP_TERMINATE
 	
-	/* A connection object has received a message. */
+	/* A connection object has received a message. (data contains the buffer) */
 	,FDEVP_CNX_MSG_RECV
 			 
@@ -166,6 +166,6 @@
 	,FDEVP_CNX_EP_CHANGE
 	
-	/* A message was received in the peer */
-	,FDEVP_MSG_INCOMING
+	/* A new connection has been established (data contains the appropriate info) */
+	,FDEVP_CNX_INCOMING
 	
 	/* The PSM state is expired */
@@ -185,9 +185,10 @@
 
 /* Functions */
-int fd_peer_fini();
+int  fd_peer_fini();
 void fd_peer_dump_list(int details);
 void fd_peer_dump(struct fd_peer * peer, int details);
-int fd_peer_alloc(struct fd_peer ** ptr);
-int fd_peer_free(struct fd_peer ** ptr);
+int  fd_peer_alloc(struct fd_peer ** ptr);
+int  fd_peer_free(struct fd_peer ** ptr);
+int fd_peer_handle_newCER( struct msg ** cer, struct cnxctx ** cnx, int tls_done );
 /* fd_peer_add declared in freeDiameter.h */
 
@@ -198,31 +199,31 @@
 
 /* Peer state machine */
-int fd_psm_start();
-int fd_psm_begin(struct fd_peer * peer );
-int fd_psm_terminate(struct fd_peer * peer );
+int  fd_psm_start();
+int  fd_psm_begin(struct fd_peer * peer );
+int  fd_psm_terminate(struct fd_peer * peer );
 void fd_psm_abord(struct fd_peer * peer );
 
 /* Server sockets */
 void fd_servers_dump();
-int fd_servers_start();
-int fd_servers_stop();
-
-/* Connection contexts */
+int  fd_servers_start();
+int  fd_servers_stop();
+
+/* Connection contexts -- there are also definitions in cnxctx.h for the relevant files */
 struct cnxctx * fd_cnx_serv_tcp(uint16_t port, int family, struct fd_endpoint * ep);
 struct cnxctx * fd_cnx_serv_sctp(uint16_t port, struct fd_list * ep_list);
-int fd_cnx_serv_listen(struct cnxctx * conn);
+int             fd_cnx_serv_listen(struct cnxctx * conn);
 struct cnxctx * fd_cnx_serv_accept(struct cnxctx * serv);
 struct cnxctx * fd_cnx_cli_connect_tcp(sSA * sa, socklen_t addrlen);
 struct cnxctx * fd_cnx_cli_connect_sctp(int no_ip6, uint16_t port, struct fd_list * list);
-char * fd_cnx_getid(struct cnxctx * conn);
-int fd_cnx_start_clear(struct cnxctx * conn, int loop);
-int fd_cnx_handshake(struct cnxctx * conn, int mode, char * priority);
-int fd_cnx_getcred(struct cnxctx * conn, const gnutls_datum_t **cert_list, unsigned int *cert_list_size);
-int fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * local, struct fd_list * remote);
-char * fd_cnx_getremoteid(struct cnxctx * conn);
-int fd_cnx_receive(struct cnxctx * conn, struct timespec * timeout, unsigned char **buf, size_t * len);
-int fd_cnx_recv_setaltfifo(struct cnxctx * conn, struct fifo * alt_fifo); /* send FDEVP_CNX_MSG_RECV event to the fifo list */
-int fd_cnx_send(struct cnxctx * conn, unsigned char * buf, size_t len);
-void fd_cnx_destroy(struct cnxctx * conn);
+char *          fd_cnx_getid(struct cnxctx * conn);
+int             fd_cnx_start_clear(struct cnxctx * conn, int loop);
+int             fd_cnx_handshake(struct cnxctx * conn, int mode, char * priority);
+int             fd_cnx_getcred(struct cnxctx * conn, const gnutls_datum_t **cert_list, unsigned int *cert_list_size);
+int             fd_cnx_getendpoints(struct cnxctx * conn, struct fd_list * local, struct fd_list * remote);
+char *          fd_cnx_getremoteid(struct cnxctx * conn);
+int             fd_cnx_receive(struct cnxctx * conn, struct timespec * timeout, unsigned char **buf, size_t * len);
+int             fd_cnx_recv_setaltfifo(struct cnxctx * conn, struct fifo * alt_fifo); /* send FDEVP_CNX_MSG_RECV event to the fifo list */
+int             fd_cnx_send(struct cnxctx * conn, unsigned char * buf, size_t len);
+void            fd_cnx_destroy(struct cnxctx * conn);
 
 
Index: freeDiameter/p_psm.c
===================================================================
--- freeDiameter/p_psm.c	(revision 27)
+++ freeDiameter/p_psm.c	(revision 28)
@@ -60,5 +60,5 @@
 		case_str(FDEVP_CNX_ERROR);
 		case_str(FDEVP_CNX_EP_CHANGE);
-		case_str(FDEVP_MSG_INCOMING);
+		case_str(FDEVP_CNX_INCOMING);
 		case_str(FDEVP_PSM_TIMEOUT);
 		
@@ -227,7 +227,4 @@
 	return NULL;
 }	
-	
-	
-
 
 /* Create the PSM thread of one peer structure */
Index: freeDiameter/peers.c
===================================================================
--- freeDiameter/peers.c	(revision 22)
+++ freeDiameter/peers.c	(revision 28)
@@ -131,7 +131,7 @@
 	
 	for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) {
-		struct fd_peer * prev = (struct fd_peer *)li;
-		int cmp = strcasecmp( p->p_hdr.info.pi_diamid, prev->p_hdr.info.pi_diamid );
-		if (cmp < 0)
+		struct fd_peer * next = (struct fd_peer *)li;
+		int cmp = strcasecmp( p->p_hdr.info.pi_diamid, next->p_hdr.info.pi_diamid );
+		if (cmp > 0)
 			continue;
 		if (cmp == 0)
@@ -375,2 +375,68 @@
 }
 
+/* Handle an incoming CER request on a new connection */
+int fd_peer_handle_newCER( struct msg ** cer, struct cnxctx ** cnx, int tls_done )
+{
+	struct msg * msg;
+	struct dict_object *avp_oh_model;
+	avp_code_t code = AC_ORIGIN_HOST;
+	struct avp *avp_oh;
+	struct avp_hdr * avp_hdr;
+	struct fd_list * li;
+	int found = 0;
+	struct fd_peer * peer;
+	
+	TRACE_ENTRY("%p %p %d", cer, cnx, tls_done);
+	CHECK_PARAMS(cer && *cer && cnx && *cnx);
+	
+	msg = *cer; 
+	
+	/* Find the Diameter Identity of the remote peer in the message */
+	CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_CODE, &code, &avp_oh_model, ENOENT) );
+	CHECK_FCT( fd_msg_search_avp ( msg, avp_oh_model, &avp_oh ) );
+	CHECK_FCT( fd_msg_avp_hdr ( avp_oh, &avp_hdr ) );
+	
+	/* Search if we already have this peer id in our list */
+	CHECK_POSIX( pthread_rwlock_rdlock(&fd_g_peers_rw) );
+	
+	for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) {
+		peer = (struct fd_peer *)li;
+		int cmp = strncasecmp( avp_hdr->avp_value->os.data, peer->p_hdr.info.pi_diamid, avp_hdr->avp_value->os.len );
+		if (cmp > 0)
+			continue;
+		if (cmp == 0)
+			found = 1;
+		break;
+	}
+	
+	if (!found) {
+		
+		TODO("Create a new peer entry with this diameter id (pf_responder = 1)");
+		TODO("Upgrade the lock to wr");
+		TODO("Add the new peer in the list");
+		TODO("Release the wr lock");
+		TODO("Start the peer PSM, which will have to validate if this peer is authorized to connect, and so on");
+	}
+		
+	TODO("Send the new connection event to the peer SM with the appropriate data: msg, conn, tls_done, found");
+	/* FDEVP_CNX_INCOMING */
+	
+	/* Reset the "out" parameters, so that they are not cleanup on function return. */
+	*cer = NULL;
+	*cnx = NULL;
+	
+	CHECK_POSIX( pthread_rwlock_unlock(&fd_g_peers_rw) );
+
+	
+	TODO("(later if not tls_done) handshake or start_clear(.., 1) ");
+	
+	return 0;
+}
+
+/* Save a callback to accept / reject incoming unknown peers */
+int fd_peer_validate_register ( int (*peer_validate)(struct peer_info * /* info */, int * /* auth */, int (**cb2)(struct peer_info *)) )
+{
+	
+	TODO("...");
+	return ENOTSUP;
+}
Index: freeDiameter/server.c
===================================================================
--- freeDiameter/server.c	(revision 27)
+++ freeDiameter/server.c	(revision 28)
@@ -139,6 +139,6 @@
 	CHECK_FCT_DO( fd_msg_parse_buffer( &buf, bufsz, &msg ), /* Parsing failed */ goto cleanup );
 	
-	/* We expect a CER, it must parse with our dictionary */
-	CHECK_FCT_DO( fd_msg_parse_dict( msg, fd_g_config->cnf_dict ), /* Parsing failed */ goto cleanup );
+	/* We expect a CER, it must parse with our dictionary and rules */
+	CHECK_FCT_DO( fd_msg_parse_rules( msg, fd_g_config->cnf_dict, NULL ), /* Parsing failed -- trace details ? */ goto cleanup );
 	
 	if (TRACE_BOOL(FULL)) {
@@ -149,14 +149,11 @@
 	/* Now check we received a CER */
 	CHECK_FCT_DO( fd_msg_hdr ( msg, &hdr ), goto fatal_error );
-	
 	CHECK_PARAMS_DO( (hdr->msg_appl == 0) && (hdr->msg_flags & CMD_FLAG_REQUEST) && (hdr->msg_code == CC_CAPABILITIES_EXCHANGE),
 		{ fd_log_debug("Connection '%s', expecting CER, received something else, closing...\n", fd_cnx_getid(c->conn)); goto cleanup; } );
 	
-	
-	TODO("Search matching peer");
-	TODO("Send event to the peer");
-	
-	TODO("(later) handshake or start_clear(.., 1)");
-	/* The end */
+	/* Finally, pass the information to the peers module which will handle it next */
+	CHECK_FCT_DO( fd_peer_handle_newCER( &msg, &c->conn, s->secur ), goto fatal_error );
+	
+	/* The end, we cleanup the client structure */
 cleanup:
 	/* Unlink the client structure */
