Changeset 78:a58f0757c06a in freeDiameter
- Timestamp:
- Dec 1, 2009, 4:24:06 PM (14 years ago)
- Branch:
- default
- Phase:
- public
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
freeDiameter/fD.h
r70 r78 91 91 struct dict_object * fd_dict_cmd_CER; /* Capabilities-Exchange-Request */ 92 92 struct dict_object * fd_dict_cmd_DWR; /* Device-Watchdog-Request */ 93 struct dict_object * fd_dict_avp_DC; /* Disconnect-Cause */ 93 94 struct dict_object * fd_dict_cmd_DPR; /* Disconnect-Peer-Request */ 94 95 … … 257 258 int fd_psm_start(); 258 259 int fd_psm_begin(struct fd_peer * peer ); 259 int fd_psm_terminate(struct fd_peer * peer );260 int fd_psm_terminate(struct fd_peer * peer, char * reason ); 260 261 void fd_psm_abord(struct fd_peer * peer ); 261 262 void fd_psm_next_timeout(struct fd_peer * peer, int add_random, int delay); … … 287 288 int fd_p_dw_reopen(struct fd_peer * peer); 288 289 int fd_p_dp_handle(struct msg ** msg, int req, struct fd_peer * peer); 289 int fd_p_dp_initiate(struct fd_peer * peer );290 int fd_p_dp_initiate(struct fd_peer * peer, char * reason); 290 291 291 292 /* Active peers -- routing process should only ever take the read lock, the write lock is managed by PSMs */ -
freeDiameter/messages.c
r66 r78 45 45 struct dict_object * fd_dict_cmd_CER = NULL; /* Capabilities-Exchange-Request */ 46 46 struct dict_object * fd_dict_cmd_DWR = NULL; /* Device-Watchdog-Request */ 47 struct dict_object * fd_dict_avp_DC = NULL; /* Disconnect-Cause */ 47 48 struct dict_object * fd_dict_cmd_DPR = NULL; /* Disconnect-Peer-Request */ 48 49 … … 61 62 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Error-Reporting-Host", &dict_avp_ERH , ENOENT) ); 62 63 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Failed-AVP", &dict_avp_FAVP, ENOENT) ); 64 65 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Disconnect-Cause", &fd_dict_avp_DC , ENOENT) ); 63 66 64 67 CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Capabilities-Exchange-Request", &fd_dict_cmd_CER, ENOENT ) ); -
freeDiameter/p_ce.c
r66 r78 763 763 { 764 764 TRACE_DEBUG(INFO, "Validation callback rejected the peer %s after handshake", peer->p_hdr.info.pi_diamid); 765 CHECK_FCT( fd_psm_terminate( peer ) );765 CHECK_FCT( fd_psm_terminate( peer, "DO_NOT_WANT_TO_TALK_TO_YOU" ) ); 766 766 return 0; 767 767 } ); -
freeDiameter/p_cnx.c
r70 r78 88 88 if (ret) { 89 89 fd_log_debug("Unable to resolve address for peer '%s' (%s), aborting\n", peer->p_hdr.info.pi_diamid, gai_strerror(ret)); 90 fd_psm_terminate( peer );90 fd_psm_terminate( peer, NULL ); 91 91 return 0; 92 92 } … … 110 110 if (FD_IS_LIST_EMPTY(&peer->p_hdr.info.pi_endpoints)) { 111 111 fd_log_debug("No address %savailable to connect to peer '%s', aborting\n", peer->p_hdr.info.config.pic_flags.pro3 ? "in the configured family " : "", peer->p_hdr.info.pi_diamid); 112 fd_psm_terminate( peer );112 fd_psm_terminate( peer, NULL ); 113 113 return 0; 114 114 } -
freeDiameter/p_dp.c
r40 r78 41 41 int fd_p_dp_handle(struct msg ** msg, int req, struct fd_peer * peer) 42 42 { 43 TODO("Handle depending on DPR or DPA and peer state"); 43 int delay = 0; 44 TRACE_ENTRY("%p %d %p", msg, req, peer); 44 45 45 return ENOTSUP; 46 if (req) { 47 /* We received a DPR, save the Disconnect-Cause and terminate the connection */ 48 struct avp * dc; 49 50 CHECK_FCT_DO( fd_msg_search_avp ( *msg, fd_dict_avp_DC, &dc ), return ); 51 if (dc) { 52 /* Check the value is consistent with the saved one */ 53 struct avp_hdr * hdr; 54 CHECK_FCT_DO( fd_msg_avp_hdr( dc, &hdr ), return ); 55 if (hdr->avp_value == NULL) { 56 /* This is a sanity check */ 57 TRACE_DEBUG(NONE, "BUG: Unset value in Disconnect-Cause in DPR"); 58 fd_msg_dump_one(NONE, dc); 59 ASSERT(0); /* To check if this really happens, and understand why... */ 60 } 61 62 peer->p_hdr.info.runtime.pir_lastDC = hdr->avp_value->u32; 63 } 64 if (TRACE_BOOL(INFO)) { 65 if (dc) { 66 struct dict_object * dictobj = NULL; 67 struct dict_enumval_request er; 68 memset(&er, 0, sizeof(er)); 69 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_TYPE, TYPE_OF_AVP, fd_dict_avp_DC, &er.type_obj, ENOENT ) ); 70 er.search.enum_value.u32 = peer->p_hdr.info.runtime.pir_lastDC; 71 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &er, &dictobj, 0 ) ); 72 if (dictobj) { 73 CHECK_FCT( fd_dict_getval( dictobj, &er.search ) ); 74 fd_log_debug("Peer '%s' sent a DPR with cause: %s\n", peer->p_hdr.info.pi_diamid, er.search.enum_name); 75 } else { 76 fd_log_debug("Peer '%s' sent a DPR with unknown cause: %u\n", peer->p_hdr.info.pi_diamid, peer->p_hdr.info.runtime.pir_lastDC); 77 } 78 } else { 79 fd_log_debug("Peer '%s' sent a DPR without Disconnect-Cause AVP\n", peer->p_hdr.info.pi_diamid); 80 } 81 } 82 83 /* Now reply with a DPA */ 84 CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) ); 85 CHECK_FCT( fd_msg_rescode_set( *msg, "DIAMETER_SUCCESS", NULL, NULL, 0 ) ); 86 CHECK_FCT( fd_msg_add_origin ( *msg, 0 ) ); 87 88 /* Move to CLOSING state to failover outgoing messages (and avoid failing the DPA...) */ 89 CHECK_FCT( fd_psm_change_state(peer, STATE_CLOSING) ); 90 91 /* Now send the DPA */ 92 CHECK_FCT( fd_out_send( msg, NULL, peer) ); 93 94 } else { 95 /* We received a DPA */ 96 if (peer->p_hdr.info.runtime.pir_state != STATE_CLOSING) { 97 TRACE_DEBUG(INFO, "Ignore DPA received in state %s", STATE_STR(peer->p_hdr.info.runtime.pir_state)); 98 } 99 100 } 101 102 if (*msg) { 103 /* In theory, we should control the Result-Code AVP. But since we will not go back to OPEN state here, let's skip it */ 104 CHECK_FCT_DO( fd_msg_free( *msg ), /* continue */ ); 105 *msg = NULL; 106 } 107 108 /* The calling function handles cleaning the PSM and terminating the peer */ 109 return 0; 46 110 } 47 111 48 112 /* Start disconnection of a peer: send DPR */ 49 int fd_p_dp_initiate(struct fd_peer * peer )113 int fd_p_dp_initiate(struct fd_peer * peer, char * reason) 50 114 { 51 TODO("Create the DPR message"); 52 TODO("Send it"); 53 TODO("Mark the peer as CLOSING"); 54 TODO("Reset the timer"); 115 struct msg * msg = NULL; 116 struct dict_object * dictobj = NULL; 117 struct avp * avp = NULL; 118 struct dict_enumval_request er; 119 union avp_value val; 55 120 56 return ENOTSUP; 121 TRACE_ENTRY("%p %p", peer, reason); 122 123 /* Create a new DWR instance */ 124 CHECK_FCT( fd_msg_new ( fd_dict_cmd_DPR, MSGFL_ALLOC_ETEID, &msg ) ); 125 126 /* Add the Origin information */ 127 CHECK_FCT( fd_msg_add_origin ( msg, 0 ) ); 128 129 /* Add the Disconnect-Cause */ 130 CHECK_FCT( fd_msg_avp_new ( fd_dict_avp_DC, 0, &avp ) ); 131 132 /* Search the value in the dictionary */ 133 memset(&er, 0, sizeof(er)); 134 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_TYPE, TYPE_OF_AVP, fd_dict_avp_DC, &er.type_obj, ENOENT ) ); 135 er.search.enum_name = reason ?: "REBOOTING"; 136 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &er, &dictobj, ENOENT ) ); 137 CHECK_FCT( fd_dict_getval( dictobj, &er.search ) ); 138 139 /* Set the value in the AVP */ 140 val.u32 = er.search.enum_value.u32; 141 CHECK_FCT( fd_msg_avp_setvalue( avp, &val ) ); 142 CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp ) ); 143 144 /* Save the value also in the peer */ 145 peer->p_hdr.info.runtime.pir_lastDC = val.u32; 146 147 /* Now send this message */ 148 CHECK_FCT( fd_out_send(&msg, NULL, peer) ); 149 150 /* Update the peer state and timer */ 151 CHECK_FCT( fd_psm_change_state(peer, STATE_CLOSING) ); 152 fd_psm_next_timeout(peer, 0, DPR_TIMEOUT); 153 154 return 0; 57 155 } -
freeDiameter/p_expiry.c
r37 r78 132 132 /* Now, the first peer in the list is expired; signal it */ 133 133 fd_list_unlink( &first->p_expiry ); 134 CHECK_FCT_DO( fd_event_send(first->p_events, FDEVP_TERMINATE, 0, NULL), goto error );134 CHECK_FCT_DO( fd_event_send(first->p_events, FDEVP_TERMINATE, 0, "DO_NOT_WANT_TO_TALK_TO_YOU"), goto error ); 135 135 136 136 } while (1); -
freeDiameter/p_psm.c
r76 r78 94 94 CHECK_FCT_DO( (*peer->p_cb2)(&peer->p_hdr.info), 95 95 { 96 TRACE_DEBUG(FULL, "Validation failed, moving to state CLOSING"); 97 peer->p_hdr.info.runtime.pir_state = STATE_CLOSING; 98 fd_psm_terminate(peer); 96 TRACE_DEBUG(FULL, "Validation failed, terminating the connection"); 97 fd_psm_terminate(peer, "DO_NOT_WANT_TO_TALK_TO_YOU" ); 99 98 } ); 100 99 peer->p_cb2 = NULL; … … 161 160 break; 162 161 162 case FDEVP_TERMINATE: 163 /* Do not free the string since it is a constant */ 164 break; 165 163 166 case FDEVP_CNX_INCOMING: { 164 167 struct cnx_incoming * evd = ev->data; … … 216 219 void fd_psm_next_timeout(struct fd_peer * peer, int add_random, int delay) 217 220 { 221 TRACE_DEBUG(FULL, "Peer timeout reset to %d seconds%s", delay, add_random ? " (+/- 2)" : "" ); 222 218 223 /* Initialize the timer */ 219 224 CHECK_POSIX_DO( clock_gettime( CLOCK_REALTIME, &peer->p_psm_timer ), ASSERT(0) ); … … 235 240 236 241 peer->p_psm_timer.tv_sec += delay; 237 238 TRACE_DEBUG(FULL, "Peer timeout reset to %d seconds%s", delay, add_random ? " (+/- 2)" : "" );239 242 240 243 #ifdef SLOW_PSM … … 348 351 case STATE_REOPEN: 349 352 /* We cannot just close the conenction, we have to send a DPR first */ 350 CHECK_FCT_DO( fd_p_dp_initiate(peer ), goto psm_end );353 CHECK_FCT_DO( fd_p_dp_initiate(peer, ev_data), goto psm_end ); 351 354 goto psm_loop; 352 355 … … 471 474 case CC_DISCONNECT_PEER: 472 475 CHECK_FCT_DO( fd_p_dp_handle(&msg, (hdr->msg_flags & CMD_FLAG_REQUEST), peer), goto psm_end ); 476 if (peer->p_hdr.info.runtime.pir_state == STATE_CLOSING) 477 goto psm_end; 473 478 break; 474 479 … … 712 717 713 718 /* End the PSM (clean ending) */ 714 int fd_psm_terminate(struct fd_peer * peer )719 int fd_psm_terminate(struct fd_peer * peer, char * reason ) 715 720 { 716 721 TRACE_ENTRY("%p", peer); … … 718 723 719 724 if (peer->p_hdr.info.runtime.pir_state != STATE_ZOMBIE) { 720 CHECK_FCT( fd_event_send(peer->p_events, FDEVP_TERMINATE, 0, NULL) );725 CHECK_FCT( fd_event_send(peer->p_events, FDEVP_TERMINATE, 0, reason) ); 721 726 } else { 722 727 TRACE_DEBUG(FULL, "Peer '%s' was already terminated", peer->p_hdr.info.pi_diamid); -
freeDiameter/peers.c
r48 r78 255 255 256 256 if (peer->p_hdr.info.runtime.pir_state != STATE_ZOMBIE) { 257 CHECK_FCT_DO( fd_psm_terminate(peer ), /* continue */ );257 CHECK_FCT_DO( fd_psm_terminate(peer, "REBOOTING"), /* continue */ ); 258 258 } else { 259 259 li = li->prev; /* to avoid breaking the loop */ -
include/freeDiameter/freeDiameter.h
r43 r78 338 338 int pir_isi; /* Inband-Security-Id advertised (PI_SEC_* bits) */ 339 339 340 uint32_t pir_lastDC; /* The last Disconnect-Cause value received */ 341 340 342 int pir_proto; /* The L4 protocol currently used with the peer (IPPROTO_TCP or IPPROTO_SCTP) */ 341 343 const gnutls_datum_t *pir_cert_list; /* The (valid) credentials that the peer has presented, or NULL if TLS is not used */
Note: See TracChangeset
for help on using the changeset viewer.