Changeset 33:e6fcdf12b9a0 in freeDiameter for freeDiameter/p_psm.c
- Timestamp:
- Oct 29, 2009, 6:05:45 PM (15 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
freeDiameter/p_psm.c
r29 r33 36 36 #include "fD.h" 37 37 38 const char *peer_state_str[] = { 39 "STATE_NEW" 40 , "STATE_OPEN" 41 , "STATE_CLOSED" 42 , "STATE_CLOSING" 43 , "STATE_WAITCNXACK" 44 , "STATE_WAITCNXACK_ELEC" 45 , "STATE_WAITCEA" 46 , "STATE_OPEN_HANDSHAKE" 47 , "STATE_SUSPECT" 48 , "STATE_REOPEN" 49 , "STATE_ZOMBIE" 50 }; 51 52 const char * fd_pev_str(int event) 53 { 54 switch (event) { 55 #define case_str( _val )\ 56 case _val : return #_val 57 case_str(FDEVP_DUMP_ALL); 58 case_str(FDEVP_TERMINATE); 59 case_str(FDEVP_CNX_MSG_RECV); 60 case_str(FDEVP_CNX_ERROR); 61 case_str(FDEVP_CNX_EP_CHANGE); 62 case_str(FDEVP_CNX_INCOMING); 63 case_str(FDEVP_PSM_TIMEOUT); 64 65 default: 66 TRACE_DEBUG(FULL, "Unknown event : %d", event); 67 return "Unknown event"; 68 } 69 } 70 71 38 /* The actual declaration of peer_state_str */ 39 DECLARE_STATE_STR(); 40 41 /* Helper for next macro */ 42 #define case_str( _val ) \ 43 case _val : return #_val 44 45 DECLARE_PEV_STR(); 46 47 /************************************************************************/ 48 /* Delayed startup */ 49 /************************************************************************/ 72 50 static int started = 0; 73 51 static pthread_mutex_t started_mtx = PTHREAD_MUTEX_INITIALIZER; … … 90 68 } 91 69 92 /* Cancelation cleanup : set ZOMBIE state in the peer */ 93 void cleanup_state(void * arg) 94 { 95 struct fd_peer * peer = (struct fd_peer *)arg; 96 CHECK_PARAMS_DO( CHECK_PEER(peer), return ); 97 peer->p_hdr.info.pi_state = STATE_ZOMBIE; 98 return; 70 /* Allow the state machines to start */ 71 int fd_psm_start() 72 { 73 TRACE_ENTRY(""); 74 CHECK_POSIX( pthread_mutex_lock(&started_mtx) ); 75 started = 1; 76 CHECK_POSIX( pthread_cond_broadcast(&started_cnd) ); 77 CHECK_POSIX( pthread_mutex_unlock(&started_mtx) ); 78 return 0; 79 } 80 81 82 /************************************************************************/ 83 /* Manage the list of active peers */ 84 /************************************************************************/ 85 86 87 /* Enter/leave OPEN state */ 88 static int enter_open_state(struct fd_peer * peer) 89 { 90 CHECK_POSIX( pthread_rwlock_wrlock(&fd_g_activ_peers_rw) ); 91 TODO(" insert in fd_g_activ_peers "); 92 93 CHECK_POSIX( pthread_rwlock_unlock(&fd_g_activ_peers_rw) ); 94 95 /* Start the thread to handle outgoing messages */ 96 CHECK_FCT( fd_out_start(peer) ); 97 98 return ENOTSUP; 99 } 100 static int leave_open_state(struct fd_peer * peer) 101 { 102 TODO("Remove from active list"); 103 104 /* Stop the "out" thread */ 105 CHECK_FCT( fd_out_stop(peer) ); 106 107 TODO("Failover pending messages: requeue in global structures"); 108 109 return ENOTSUP; 110 } 111 112 /************************************************************************/ 113 /* Helpers for state changes */ 114 /************************************************************************/ 115 /* Change state */ 116 static int change_state(struct fd_peer * peer, int new_state) 117 { 118 int old; 119 120 TRACE_ENTRY("%p %d(%s)", peer, new_state, STATE_STR(new_state)); 121 CHECK_PARAMS( CHECK_PEER(peer) ); 122 old = peer->p_hdr.info.pi_state; 123 if (old == new_state) 124 return 0; 125 126 TRACE_DEBUG(FULL, "'%s'\t-> '%s'\t'%s'", 127 STATE_STR(old), 128 STATE_STR(new_state), 129 peer->p_hdr.info.pi_diamid); 130 131 if (old == STATE_OPEN) { 132 CHECK_FCT( leave_open_state(peer) ); 133 } 134 135 peer->p_hdr.info.pi_state = new_state; 136 137 if (new_state == STATE_OPEN) { 138 CHECK_FCT( enter_open_state(peer) ); 139 } 140 141 return 0; 99 142 } 100 143 … … 128 171 } 129 172 173 174 /************************************************************************/ 175 /* The PSM thread */ 176 /************************************************************************/ 177 /* Cancelation cleanup : set ZOMBIE state in the peer */ 178 void cleanup_state(void * arg) 179 { 180 struct fd_peer * peer = (struct fd_peer *)arg; 181 CHECK_PARAMS_DO( CHECK_PEER(peer), return ); 182 peer->p_hdr.info.pi_state = STATE_ZOMBIE; 183 return; 184 } 185 130 186 /* The state machine thread (controler) */ 131 187 static void * p_psm_th( void * arg ) … … 171 227 /* Now, the action depends on the current state and the incoming event */ 172 228 173 /* The following twostates are impossible */229 /* The following states are impossible */ 174 230 ASSERT( peer->p_hdr.info.pi_state != STATE_NEW ); 175 231 ASSERT( peer->p_hdr.info.pi_state != STATE_ZOMBIE ); 232 ASSERT( peer->p_hdr.info.pi_state != STATE_OPEN_HANDSHAKE ); /* because it exists only between two loops */ 176 233 177 234 /* Purge invalid events */ 178 if (!CHECK_ EVENT(event)) {235 if (!CHECK_PEVENT(event)) { 179 236 TRACE_DEBUG(INFO, "Invalid event received in PSM '%s' : %d", peer->p_hdr.info.pi_diamid, event); 180 237 goto psm_loop; 238 } 239 240 /* Call the extension callback if needed */ 241 if (peer->p_cb) { 242 /* Check if we must call it */ 243 /* */ 244 /* OK */ 245 TODO("Call CB"); 246 TODO("Clear CB"); 181 247 } 182 248 … … 207 273 goto psm_loop; 208 274 } 275 } 276 277 /* A message was received */ 278 if (event == FDEVP_CNX_MSG_RECV) { 279 TODO("Parse the buffer into a message"); 280 /* parse_and_get_local_ccode */ 281 TODO("Check if it is a local message (CER, DWR, ...)"); 282 TODO("If not, check we are in OPEN state"); 283 TODO("Update expiry timer if needed"); 284 TODO("Handle the message"); 285 } 286 287 /* The connection object is broken */ 288 if (event == FDEVP_CNX_ERROR) { 289 TODO("Destroy the connection object"); 290 TODO("Mark the error in the peer (pf_cnx_pb)"); 291 TODO("Move to closed state, Requeue all messages to a different connection (failover)"); 292 TODO("If pi_flags.exp, terminate the peer"); 293 } 294 295 /* The connection notified a change in endpoints */ 296 if (event == FDEVP_CNX_EP_CHANGE) { 297 /* Cleanup the remote LL and primary addresses */ 298 CHECK_FCT_DO( fd_ep_filter( &peer->p_hdr.info.pi_endpoints, EP_FL_CONF | EP_FL_DISC | EP_FL_ADV ), /* ignore the error */); 299 CHECK_FCT_DO( fd_ep_clearflags( &peer->p_hdr.info.pi_endpoints, EP_FL_PRIMARY ), /* ignore the error */); 300 301 /* Get the new ones */ 302 CHECK_FCT_DO( fd_cnx_getendpoints(peer->p_cnxctx, NULL, &peer->p_hdr.info.pi_endpoints), /* ignore the error */); 303 304 if (TRACE_BOOL(ANNOYING)) { 305 fd_log_debug("New remote endpoint(s):\n"); 306 fd_ep_dump(6, &peer->p_hdr.info.pi_endpoints); 307 } 308 309 /* Done */ 310 goto psm_loop; 209 311 } 210 312 … … 235 337 } 236 338 237 /* MSG_RECEIVED: fd_p_expi_update(struct fd_peer * peer ) */ 238 /* If timeout or OPEN : call cb if defined */ 239 240 /* Default action : the handling has not yet been implemented. */ 339 /* The timeout for the current state has been reached */ 340 if (event == FDEVP_PSM_TIMEOUT) { 341 switch (peer->p_hdr.info.pi_state) { 342 343 344 } 345 } 346 347 /* Default action : the handling has not yet been implemented. [for debug only] */ 241 348 TODO("Missing handler in PSM : '%s'\t<-- '%s'", STATE_STR(peer->p_hdr.info.pi_state), fd_pev_str(event)); 242 349 if (event == FDEVP_PSM_TIMEOUT) { … … 252 359 pthread_detach(pthread_self()); 253 360 return NULL; 254 } 255 361 } 362 363 364 /************************************************************************/ 365 /* Functions to control the PSM */ 366 /************************************************************************/ 256 367 /* Create the PSM thread of one peer structure */ 257 368 int fd_psm_begin(struct fd_peer * peer ) … … 283 394 } 284 395 285 /* End the PSM violently*/396 /* End the PSM & cleanup the peer structure */ 286 397 void fd_psm_abord(struct fd_peer * peer ) 287 398 { 288 399 TRACE_ENTRY("%p", peer); 289 400 TODO("Cancel PSM thread"); 290 TODO("Cancel IN thread");291 401 TODO("Cancel OUT thread"); 292 402 TODO("Cleanup the peer connection object"); 293 403 TODO("Cleanup the message queues (requeue)"); 404 TODO("Call p_cb with NULL parameter if needed"); 405 294 406 return; 295 407 } 296 408 297 /* Allow the state machines to start */298 int fd_psm_start()299 {300 TRACE_ENTRY("");301 CHECK_POSIX( pthread_mutex_lock(&started_mtx) );302 started = 1;303 CHECK_POSIX( pthread_cond_broadcast(&started_cnd) );304 CHECK_POSIX( pthread_mutex_unlock(&started_mtx) );305 return 0;306 }307
Note: See TracChangeset
for help on using the changeset viewer.