Changeset 36:1498b3c7304c in freeDiameter
- Timestamp:
- Nov 2, 2009, 5:31:36 PM (15 years ago)
- Branch:
- default
- Phase:
- public
- Files:
-
- 2 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
freeDiameter/CMakeLists.txt
r35 r36 21 21 peers.c 22 22 p_ce.c 23 p_dw.c 24 p_dp.c 23 25 p_expiry.c 24 26 p_out.c -
freeDiameter/fD.h
r35 r36 232 232 int fd_psm_terminate(struct fd_peer * peer ); 233 233 void fd_psm_abord(struct fd_peer * peer ); 234 void fd_psm_next_timeout(struct fd_peer * peer, int add_random, int delay); 235 int fd_psm_change_state(struct fd_peer * peer, int new_state); 236 void fd_psm_cleanup(struct fd_peer * peer); 234 237 235 238 /* Peer out */ … … 243 246 void fd_p_sr_failover(struct sr_list * srlist); 244 247 245 /* Capabilities Exchange */ 246 int fd_p_ce_merge(struct fd_peer * peer, struct msg * cer); 248 /* Local Link messages (CER/CEA, DWR/DWA, DPR/DPA) */ 249 int fd_p_ce_handle(struct msg ** msg, struct fd_peer * peer); 250 int fd_p_ce_handle_newCER(struct msg ** msg, struct fd_peer * peer, struct cnxctx ** cnx, int valid); 251 int fd_p_dw_handle(struct msg ** msg, struct fd_peer * peer); 252 int fd_p_dw_timeout(struct fd_peer * peer); 253 int fd_p_dp_handle(struct msg ** msg, struct fd_peer * peer); 254 int fd_p_dp_initiate(struct fd_peer * peer); 247 255 248 256 /* Active peers -- routing process should only ever take the read lock, the write lock is managed by PSMs */ -
freeDiameter/fdd.y
r24 r36 318 318 fd_list_init( &fddpi.pi_endpoints, NULL ); 319 319 fd_list_init( &fddpi.pi_apps, NULL ); 320 fddpi.pi_flags.persist = PI_PRST_ALWAYS; 320 321 } 321 322 CONNPEER '=' QSTRING peerinfo ';' -
freeDiameter/p_ce.c
r35 r36 38 38 /* This file contains code to handle Capabilities Exchange messages (CER and CEA) */ 39 39 40 int fd_p_ce_ merge(struct fd_peer * peer, struct msg * cer)40 int fd_p_ce_handle(struct msg ** msg, struct fd_peer * peer) 41 41 { 42 /* Save all information from the CER into the peer structure, after cleaning old information if any */42 TODO("Handle depending on CER or CEA and peer state"); 43 43 44 44 return ENOTSUP; 45 45 } 46 47 int fd_p_ce_handle_newCER(struct msg ** msg, struct fd_peer * peer, struct cnxctx ** cnx, int valid) 48 { 49 switch (peer->p_hdr.info.pi_state) { 50 case STATE_CLOSED: 51 TODO("Handle the CER, validate the peer if needed (and set expiry), set the alt_fifo in the connection, reply a CEA, eventually handshake, move to OPEN or REOPEN state"); 52 /* In case of error : DIAMETER_UNKNOWN_PEER */ 53 break; 54 55 case STATE_WAITCNXACK: 56 case STATE_WAITCEA: 57 TODO("Election"); 58 break; 59 60 default: 61 TODO("Reply with error CEA"); 62 TODO("Close the connection"); 63 /* reject_incoming_connection */ 64 65 } 66 67 68 return ENOTSUP; 69 } -
freeDiameter/p_expiry.c
r25 r36 36 36 #include "fD.h" 37 37 38 /* Delay for garbage collection of expired threads, in seconds */39 #define GC_TIME 6038 /* Delay for garbage collection of expired peers, in seconds */ 39 #define GC_TIME 120 40 40 41 41 static pthread_t exp_thr; … … 64 64 continue; 65 65 66 if (peer->p_hdr.info.pi_flags. exp == PI_EXP_NONE)67 continue; /* This peer was not supposed to expire, keep it in the list*/66 if (peer->p_hdr.info.pi_flags.persist == PI_PRST_ALWAYS) 67 continue; /* This peer was not supposed to terminate, keep it in the list for debug */ 68 68 69 69 /* Ok, the peer was expired, let's remove it */ -
freeDiameter/p_psm.c
r35 r36 146 146 /************************************************************************/ 147 147 /* Change state */ 148 static intchange_state(struct fd_peer * peer, int new_state)148 int fd_psm_change_state(struct fd_peer * peer, int new_state) 149 149 { 150 150 int old; … … 171 171 } 172 172 173 if ((new_state == STATE_CLOSED) && (peer->p_hdr.info.pi_flags.persist == PI_PRST_NONE)) { 174 CHECK_FCT( fd_event_send(peer->p_events, FDEVP_TERMINATE, 0, NULL) ); 175 } 176 173 177 return 0; 174 178 } 175 179 176 180 /* Set timeout timer of next event */ 177 static voidpsm_next_timeout(struct fd_peer * peer, int add_random, int delay)181 void fd_psm_next_timeout(struct fd_peer * peer, int add_random, int delay) 178 182 { 179 183 /* Initialize the timer */ … … 203 207 } 204 208 209 /* Cleanup the peer */ 210 void fd_psm_cleanup(struct fd_peer * peer) 211 { 212 /* Move to CLOSED state */ 213 CHECK_FCT_DO( fd_psm_change_state(peer, STATE_CLOSED), /* continue */ ); 214 215 /* Destroy the connection */ 216 if (peer->p_cnxctx) { 217 fd_cnx_destroy(peer->p_cnxctx); 218 peer->p_cnxctx = NULL; 219 } 220 221 /* What else ? */ 222 TODO("..."); 223 224 } 225 205 226 206 227 /************************************************************************/ … … 208 229 /************************************************************************/ 209 230 /* Cancelation cleanup : set ZOMBIE state in the peer */ 210 void cleanup_s tate(void * arg)231 void cleanup_setstate(void * arg) 211 232 { 212 233 struct fd_peer * peer = (struct fd_peer *)arg; … … 227 248 CHECK_PARAMS_DO( CHECK_PEER(peer), ASSERT(0) ); 228 249 229 pthread_cleanup_push( cleanup_s tate, arg );250 pthread_cleanup_push( cleanup_setstate, arg ); 230 251 231 252 /* Set the thread name */ … … 244 265 /* Initialize the timer */ 245 266 if (peer->p_flags.pf_responder) { 246 psm_next_timeout(peer, 0, INCNX_TIMEOUT);267 fd_psm_next_timeout(peer, 0, INCNX_TIMEOUT); 247 268 } else { 248 psm_next_timeout(peer, created_started, 0);269 fd_psm_next_timeout(peer, created_started, 0); 249 270 } 250 271 … … 279 300 if (event == FDEVP_TERMINATE) { 280 301 switch (peer->p_hdr.info.pi_state) { 302 case STATE_OPEN: 303 case STATE_REOPEN: 304 /* We cannot just close the conenction, we have to send a DPR first */ 305 CHECK_FCT_DO( fd_p_dp_initiate(peer), goto psm_end ); 306 goto psm_loop; 307 308 /* 281 309 case STATE_CLOSING: 282 310 case STATE_WAITCNXACK: … … 284 312 case STATE_WAITCEA: 285 313 case STATE_SUSPECT: 286 /* In these cases, we just cleanup the peer object and terminate now */287 TODO("Cleanup the PSM: terminate connection object, ...");288 314 case STATE_CLOSED: 289 /* Then we just terminate the PSM */ 315 */ 316 default: 317 /* In these cases, we just cleanup the peer object (if needed) and terminate */ 290 318 goto psm_end; 291 292 case STATE_OPEN:293 case STATE_REOPEN:294 /* We cannot just close the conenction, we have to send a DPR first */295 TODO("Send DPR, mark the peer as CLOSING");296 goto psm_loop;297 319 } 298 320 } … … 311 333 } ); 312 334 313 TRACE_DEBUG(FULL, "Received this message from '%s':", peer->p_hdr.info.pi_diamid);314 fd_msg_dump_walk(FULL , msg);335 TRACE_DEBUG(FULL, "Received a message (%zdb) from '%s'", ev_sz, peer->p_hdr.info.pi_diamid); 336 fd_msg_dump_walk(FULL + 1, msg); 315 337 316 338 /* Extract the header */ … … 333 355 } 334 356 335 /* We received a valid message, update the expiry timer */336 CHECK_FCT_DO( fd_p_expi_update(peer), goto psm_end );337 338 357 /* Now handle non-link-local messages */ 339 358 if (fd_msg_is_routable(msg)) { … … 344 363 fd_msg_free(msg); 345 364 } else { 365 /* We received a valid message, update the expiry timer */ 366 CHECK_FCT_DO( fd_p_expi_update(peer), goto psm_end ); 367 346 368 /* Set the message source and add the Route-Record */ 347 369 CHECK_FCT_DO( fd_msg_source_set( msg, peer->p_hdr.info.pi_diamid, 1, fd_g_config->cnf_dict ), goto psm_end); … … 352 374 /* Update the peer timer */ 353 375 if (!peer->p_flags.pf_dw_pending) { 354 psm_next_timeout(peer, 1, peer->p_hdr.info.pi_twtimer ?: fd_g_config->cnf_timer_tw);376 fd_psm_next_timeout(peer, 1, peer->p_hdr.info.pi_twtimer ?: fd_g_config->cnf_timer_tw); 355 377 } 356 378 } … … 374 396 } 375 397 398 ASSERT( hdr->msg_appl == 0 ); /* buggy fd_msg_is_routable() ? */ 399 376 400 /* Handle the LL message and update the expiry timer appropriately */ 377 TODO("..."); 401 switch (hdr->msg_code) { 402 case CC_DEVICE_WATCHDOG: 403 CHECK_FCT_DO( fd_p_dw_handle(&msg, peer), goto psm_end ); 404 break; 405 406 case CC_DISCONNECT_PEER: 407 CHECK_FCT_DO( fd_p_dp_handle(&msg, peer), goto psm_end ); 408 break; 409 410 case CC_CAPABILITIES_EXCHANGE: 411 CHECK_FCT_DO( fd_p_ce_handle(&msg, peer), goto psm_end ); 412 break; 413 414 default: 415 /* Unknown / unexpected / invalid message */ 416 TODO("Log, return error message if request"); 417 }; 418 419 /* At this point the message must have been fully handled already */ 420 if (msg) { 421 fd_log_debug("Internal error: unhandled message (discarded)!\n"); 422 fd_msg_dump_walk(NONE, msg); 423 fd_msg_free(msg); 424 } 425 426 goto psm_loop; 378 427 } 379 428 380 429 /* The connection object is broken */ 381 430 if (event == FDEVP_CNX_ERROR) { 382 TODO("Destroy the connection object"); 383 TODO("Mark the error in the peer (pf_cnx_pb)"); 384 TODO("Move to closed state, Requeue all messages to a different connection (failover)"); 385 TODO("If pi_flags.exp, terminate the peer"); 431 /* Cleanup the peer */ 432 fd_psm_cleanup(peer); 433 434 /* Mark the connection problem */ 435 peer->p_flags.pf_cnx_pb = 1; 436 437 /* Move to CLOSED */ 438 CHECK_FCT_DO( fd_psm_change_state(peer, STATE_CLOSED), goto psm_end ); 439 440 /* Reset the timer */ 441 fd_psm_next_timeout(peer, 1, peer->p_hdr.info.pi_tctimer ?: fd_g_config->cnf_timer_tc); 442 443 /* Loop */ 444 goto psm_loop; 386 445 } 387 446 … … 409 468 ASSERT(params); 410 469 411 switch (peer->p_hdr.info.pi_state) { 412 case STATE_CLOSED: 413 TODO("Handle the CER, validate the peer if needed (and set expiry), set the alt_fifo in the connection, reply a CEA, eventually handshake, move to OPEN or REOPEN state"); 414 /* In case of error : DIAMETER_UNKNOWN_PEER */ 415 416 CHECK_FCT_DO( fd_p_ce_merge(peer, params->cer), 417 { 418 419 } ); 420 421 break; 422 423 case STATE_WAITCNXACK: 424 case STATE_WAITCEA: 425 TODO("Election"); 426 break; 427 428 default: 429 TODO("Reply with error CEA"); 430 TODO("Close the connection"); 431 /* reject_incoming_connection */ 432 433 } 434 470 /* Handle the message */ 471 CHECK_FCT_DO( fd_p_ce_handle_newCER(¶ms->cer, peer, ¶ms->cnx, params->validate), goto psm_end ); 472 473 /* Cleanup if needed */ 474 if (params->cnx) { 475 fd_cnx_destroy(params->cnx); 476 params->cnx = NULL; 477 } 478 if (params->cer) { 479 CHECK_FCT_DO( fd_msg_free(params->cer), ); 480 params->cer = NULL; 481 } 482 483 /* Loop */ 435 484 free(ev_data); 436 485 goto psm_loop; … … 440 489 if (event == FDEVP_PSM_TIMEOUT) { 441 490 switch (peer->p_hdr.info.pi_state) { 442 443 491 case STATE_OPEN: 492 case STATE_REOPEN: 493 CHECK_FCT_DO( fd_p_dw_timeout(peer), goto psm_end ); 494 break; 495 496 case STATE_CLOSED: 497 TODO("Initiate a new connection"); 498 break; 499 500 case STATE_CLOSING: 501 case STATE_SUSPECT: 502 case STATE_WAITCNXACK: 503 case STATE_WAITCEA: 504 /* Destroy the connection, restart the timer to a new connection attempt */ 505 fd_psm_cleanup(peer); 506 fd_psm_next_timeout(peer, 1, peer->p_hdr.info.pi_tctimer ?: fd_g_config->cnf_timer_tc); 507 CHECK_FCT_DO( fd_psm_change_state(peer, STATE_CLOSED), goto psm_end ); 508 break; 509 510 case STATE_WAITCNXACK_ELEC: 511 TODO("Abort initiating side, handle the receiver side"); 512 break; 444 513 } 445 514 } … … 449 518 if (event == FDEVP_PSM_TIMEOUT) { 450 519 /* We have not handled timeout in this state, let's postpone next alert */ 451 psm_next_timeout(peer, 0, 60);520 fd_psm_next_timeout(peer, 0, 60); 452 521 } 453 522 … … 455 524 456 525 psm_end: 526 fd_psm_cleanup(peer); 457 527 pthread_cleanup_pop(1); /* set STATE_ZOMBIE */ 458 528 peer->p_psm = (pthread_t)NULL; -
freeDiameter/peers.c
r34 r36 102 102 } 103 103 104 p->p_hdr.info.pi_flags.pro3 = info->pi_flags.pro3; 105 p->p_hdr.info.pi_flags.pro4 = info->pi_flags.pro4; 106 p->p_hdr.info.pi_flags.alg = info->pi_flags.alg; 107 p->p_hdr.info.pi_flags.sec = info->pi_flags.sec; 108 p->p_hdr.info.pi_flags.exp = info->pi_flags.exp; 109 110 p->p_hdr.info.pi_lft = info->pi_lft; 111 p->p_hdr.info.pi_port = info->pi_port; 112 p->p_hdr.info.pi_tctimer = info->pi_tctimer; 113 p->p_hdr.info.pi_twtimer = info->pi_twtimer; 104 p->p_hdr.info.pi_flags.pro3 = info->pi_flags.pro3; 105 p->p_hdr.info.pi_flags.pro4 = info->pi_flags.pro4; 106 p->p_hdr.info.pi_flags.alg = info->pi_flags.alg; 107 p->p_hdr.info.pi_flags.sec = info->pi_flags.sec; 108 p->p_hdr.info.pi_flags.exp = info->pi_flags.exp; 109 p->p_hdr.info.pi_flags.persist = info->pi_flags.persist; 110 111 p->p_hdr.info.pi_lft = info->pi_lft; 112 p->p_hdr.info.pi_port = info->pi_port; 113 p->p_hdr.info.pi_tctimer = info->pi_tctimer; 114 p->p_hdr.info.pi_twtimer = info->pi_twtimer; 114 115 115 116 if (info->pi_sec_data.priority) { … … 442 443 peer->p_flags.pf_responder = 1; 443 444 445 /* Set this peer to expire on inactivity */ 446 peer->p_hdr.info.pi_flags.exp = PI_EXP_INACTIVE; 447 peer->p_hdr.info.pi_lft = 3600 * 3; /* 3 hours without any message */ 448 444 449 /* Upgrade the lock to write lock */ 445 450 CHECK_POSIX_DO( ret = pthread_rwlock_wrlock(&fd_g_peers_rw), goto out ); -
include/freeDiameter/freeDiameter.h
r34 r36 248 248 If we win the election, we must disconnect the initiated connection and send a CEA on the other => we go to OPEN state. 249 249 If we lose, we disconnect the other connection (receiver) and fallback to WAITCEA state. */ 250 STATE_OPEN_HANDSHAKE, /* TLS Handshake and validation are in progress in open state */250 STATE_OPEN_HANDSHAKE, /* TLS Handshake and validation are in progress in open state -- we show the state because it can last a long time */ 251 251 252 252 /* Failover state machine */ … … 307 307 unsigned exp :1; 308 308 309 #define PI_PRST_NONE 0 /* the peer entry is deleted after disconnection / error */ 310 #define PI_PRST_ALWAYS 1 /* the peer entry is persistant (will be kept as ZOMBIE in case of error) */ 311 unsigned persist :1; 312 309 313 unsigned inband_none :1; /* This is only meaningful with pi_flags.sec == 3 */ 310 314 unsigned inband_tls :1; /* This is only meaningful with pi_flags.sec == 3 */
Note: See TracChangeset
for help on using the changeset viewer.