diff freeDiameter/p_psm.c @ 16:013ce9851131

Started including TLS code
author Sebastien Decugis <sdecugis@nict.go.jp>
date Fri, 02 Oct 2009 18:57:06 +0900
parents 14cf6daf716d
children 277ec00d793e
line wrap: on
line diff
--- a/freeDiameter/p_psm.c	Fri Oct 02 17:46:14 2009 +0900
+++ b/freeDiameter/p_psm.c	Fri Oct 02 18:57:06 2009 +0900
@@ -36,7 +36,7 @@
 #include "fD.h"
 
 const char *peer_state_str[] = { 
-	  "STATE_ZOMBIE"
+	  "STATE_NEW"
 	, "STATE_OPEN"
 	, "STATE_CLOSED"
 	, "STATE_CLOSING"
@@ -45,6 +45,7 @@
 	, "STATE_WAITCEA"
 	, "STATE_SUSPECT"
 	, "STATE_REOPEN"
+	, "STATE_ZOMBIE"
 	};
 
 const char * fd_pev_str(int event)
@@ -122,6 +123,7 @@
 #endif
 }
 
+/* Wait for the next event in the PSM, or timeout */
 static int psm_ev_timedget(struct fd_peer * peer, int *code, void ** data)
 {
 	struct fd_event * ev;
@@ -141,13 +143,15 @@
 	}
 	
 	return 0;
-}	
+}
 
-/* The state machine thread */
+/* The state machine thread (controler) */
 static void * p_psm_th( void * arg )
 {
 	struct fd_peer * peer = (struct fd_peer *)arg;
 	int created_started = started;
+	int event;
+	void * ev_data;
 	
 	CHECK_PARAMS_DO( CHECK_PEER(peer), ASSERT(0) );
 	
@@ -160,12 +164,12 @@
 		fd_log_threadname ( buf );
 	}
 	
-	/* Wait that the PSM are authorized to start in the daemon */
-	CHECK_FCT_DO( fd_psm_waitstart(), goto end );
-	
 	/* The state machine starts in CLOSED state */
 	peer->p_hdr.info.pi_state = STATE_CLOSED;
 	
+	/* Wait that the PSM are authorized to start in the daemon */
+	CHECK_FCT_DO( fd_psm_waitstart(), goto psm_end );
+	
 	/* Initialize the timer */
 	if (peer->p_flags.pf_responder) {
 		psm_next_timeout(peer, 0, INCNX_TIMEOUT);
@@ -173,27 +177,68 @@
 		psm_next_timeout(peer, created_started ? 0 : 1, 0);
 	}
 	
-psm:
-	do {
-		int event;
-		void * ev_data;
-		
-		/* Get next event */
-		CHECK_FCT_DO( psm_ev_timedget(peer, &event, &ev_data), goto end );
-		TRACE_DEBUG(FULL, "'%s'\t<-- '%s'\t(%p)\t'%s'",
-				STATE_STR(peer->p_hdr.info.pi_state),
-				fd_pev_str(event), ev_data,
-				peer->p_hdr.info.pi_diamid);
-		
-		/* Now, the action depends on the current state and the incoming event */
-		
+psm_loop:
+	/* Get next event */
+	CHECK_FCT_DO( psm_ev_timedget(peer, &event, &ev_data), goto psm_end );
+	TRACE_DEBUG(FULL, "'%s'\t<-- '%s'\t(%p)\t'%s'",
+			STATE_STR(peer->p_hdr.info.pi_state),
+			fd_pev_str(event), ev_data,
+			peer->p_hdr.info.pi_diamid);
+
+	/* Now, the action depends on the current state and the incoming event */
+
+	/* The following two states are impossible */
+	ASSERT( peer->p_hdr.info.pi_state != STATE_NEW );
+	ASSERT( peer->p_hdr.info.pi_state != STATE_ZOMBIE );
+
+	/* Purge invalid events */
+	if (!CHECK_EVENT(event)) {
+		TRACE_DEBUG(INFO, "Invalid event received in PSM '%s' : %d", peer->p_hdr.info.pi_diamid, event);
+		goto psm_loop;
+	}
+
+	/* Handle the (easy) debug event now */
+	if (event == FDEVP_DUMP_ALL) {
+		fd_peer_dump(peer, ANNOYING);
+		goto psm_loop;
+	}
+
+	/* Requests to terminate the peer object */
+	if (event == FDEVP_TERMINATE) {
+		switch (peer->p_hdr.info.pi_state) {
+			case STATE_CLOSING:
+			case STATE_WAITCNXACK:
+			case STATE_WAITCNXACK_ELEC:
+			case STATE_WAITCEA:
+			case STATE_SUSPECT:
+				/* In these cases, we just cleanup the peer object and terminate now */
+				TODO("Cleanup the PSM: terminate connection object, ...");
+			case STATE_CLOSED:
+				/* Then we just terminate the PSM */
+				goto psm_end;
+				
+			case STATE_OPEN:
+			case STATE_REOPEN:
+				/* We cannot just close the conenction, we have to send a DPR first */
+				TODO("Send DPR, mark the peer as CLOSING");
+				goto psm_loop;
+		}
+	}
 	
-	} while (1);	
-	
+	/* MSG_RECEIVED: fd_p_expi_update(struct fd_peer * peer ) */
+	/* If timeout or OPEN : call cb if defined */
+
+	/* Default action : the handling has not yet been implemented. */
+	TODO("Missing handler in PSM : '%s'\t<-- '%s'", STATE_STR(peer->p_hdr.info.pi_state), fd_pev_str(event));
+	if (event == FDEVP_PSM_TIMEOUT) {
+		/* We have not handled timeout in this state, let's postpone next alert */
+		psm_next_timeout(peer, 0, 60);
+	}
 	
-end:	
-	/* set STATE_ZOMBIE */
-	pthread_cleanup_pop(1);
+	goto psm_loop;
+	
+psm_end:
+	pthread_cleanup_pop(1); /* set STATE_ZOMBIE */
 	return NULL;
 }	
 	
@@ -204,8 +249,15 @@
 int fd_psm_begin(struct fd_peer * peer )
 {
 	TRACE_ENTRY("%p", peer);
-	TODO("");
-	return ENOTSUP;
+	
+	/* Check the peer and state are OK */
+	CHECK_PARAMS( CHECK_PEER(peer) && (peer->p_hdr.info.pi_state == STATE_NEW) );
+	
+	/* Create the PSM controler thread */
+	CHECK_POSIX( pthread_create( &peer->p_psm, NULL, p_psm_th, peer ) );
+	
+	/* We're done */
+	return 0;
 }
 
 /* End the PSM (clean ending) */
@@ -213,7 +265,11 @@
 {
 	TRACE_ENTRY("%p", peer);
 	CHECK_PARAMS( CHECK_PEER(peer) );
-	CHECK_FCT( fd_event_send(peer->p_events, FDEVP_TERMINATE, NULL) );
+	if (peer->p_hdr.info.pi_state != STATE_ZOMBIE) {
+		CHECK_FCT( fd_event_send(peer->p_events, FDEVP_TERMINATE, NULL) );
+	} else {
+		TRACE_DEBUG(FULL, "Peer '%s' was already terminated", peer->p_hdr.info.pi_diamid);
+	}
 	return 0;
 }
 
@@ -224,7 +280,8 @@
 	TODO("Cancel PSM thread");
 	TODO("Cancel IN thread");
 	TODO("Cancel OUT thread");
-	TODO("Cleanup the connection");
+	TODO("Cleanup the peer connection object");
+	TODO("Cleanup the message queues (requeue)");
 	return;
 }
 
"Welcome to our mercurial repository"