changeset 28:3628f7d2ba88

some new functions backbones
author Sebastien Decugis <sdecugis@nict.go.jp>
date Mon, 26 Oct 2009 18:07:24 +0900
parents b3a1773e9f46
children 5ba91682f0bc
files freeDiameter/fD.h freeDiameter/p_psm.c freeDiameter/peers.c freeDiameter/server.c
diffstat 4 files changed, 99 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/freeDiameter/fD.h	Mon Oct 26 16:48:47 2009 +0900
+++ b/freeDiameter/fD.h	Mon Oct 26 18:07:24 2009 +0900
@@ -156,7 +156,7 @@
 	/* request to terminate this peer : disconnect, requeue all messages */
 	,FDEVP_TERMINATE
 	
-	/* A connection object has received a message. */
+	/* A connection object has received a message. (data contains the buffer) */
 	,FDEVP_CNX_MSG_RECV
 			 
 	/* A connection object has encountered an error (disconnected). */
@@ -165,8 +165,8 @@
 	/* Endpoints of a connection have been changed (multihomed SCTP). */
 	,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 */
 	,FDEVP_PSM_TIMEOUT
@@ -184,11 +184,12 @@
 
 
 /* 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 */
 
 /* Peer expiry */
@@ -197,33 +198,33 @@
 int fd_p_expi_update(struct fd_peer * peer );
 
 /* 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();
+int  fd_servers_start();
+int  fd_servers_stop();
 
-/* Connection contexts */
+/* 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);
 
 
 #endif /* _FD_H */
--- a/freeDiameter/p_psm.c	Mon Oct 26 16:48:47 2009 +0900
+++ b/freeDiameter/p_psm.c	Mon Oct 26 18:07:24 2009 +0900
@@ -59,7 +59,7 @@
 		case_str(FDEVP_CNX_MSG_RECV);
 		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);
 		
 		default:
@@ -226,9 +226,6 @@
 	peer->p_psm = (pthread_t)NULL;
 	return NULL;
 }	
-	
-	
-
 
 /* Create the PSM thread of one peer structure */
 int fd_psm_begin(struct fd_peer * peer )
--- a/freeDiameter/peers.c	Mon Oct 26 16:48:47 2009 +0900
+++ b/freeDiameter/peers.c	Mon Oct 26 18:07:24 2009 +0900
@@ -130,9 +130,9 @@
 	CHECK_POSIX( pthread_rwlock_wrlock(&fd_g_peers_rw) );
 	
 	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)
 			ret = EEXIST;
@@ -374,3 +374,69 @@
 	CHECK_FCT_DO( pthread_rwlock_unlock(&fd_g_peers_rw), /* continue */ );
 }
 
+/* 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;
+}
--- a/freeDiameter/server.c	Mon Oct 26 16:48:47 2009 +0900
+++ b/freeDiameter/server.c	Mon Oct 26 18:07:24 2009 +0900
@@ -138,8 +138,8 @@
 	/* Try parsing this message */
 	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)) {
 		fd_log_debug("Received Diameter message from new client '%s':\n", fd_cnx_getid(c->conn));
@@ -148,16 +148,13 @@
 	
 	/* 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; } );
 	
+	/* 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 );
 	
-	TODO("Search matching peer");
-	TODO("Send event to the peer");
-	
-	TODO("(later) handshake or start_clear(.., 1)");
-	/* The end */
+	/* The end, we cleanup the client structure */
 cleanup:
 	/* Unlink the client structure */
 	CHECK_POSIX_DO( pthread_mutex_lock(&s->clients_mtx), goto fatal_error );
"Welcome to our mercurial repository"