Changeset 706:4ffbc9f1e922 in freeDiameter for libfdcore/p_dp.c
- Timestamp:
- Feb 9, 2011, 3:26:58 PM (13 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libfdcore/p_dp.c
r662 r706 38 38 /* This file contains code to handle Disconnect Peer messages (DPR and DPA) */ 39 39 40 /* Delay to use before next reconnect attempt */ 41 int fd_p_dp_newdelay(struct fd_peer * peer) 42 { 43 int delay = peer->p_hdr.info.config.pic_tctimer ?: fd_g_config->cnf_timer_tc; 44 45 switch (peer->p_hdr.info.runtime.pir_lastDC) { 46 case ACV_DC_REBOOTING: 47 default: 48 /* We use TcTimer to attempt reconnection */ 49 break; 50 case ACV_DC_BUSY: 51 /* No need to hammer the overloaded peer */ 52 delay *= 10; 53 break; 54 case ACV_DC_NOT_FRIEND: 55 /* He does not want to speak to us... let's retry a *lot* later maybe */ 56 delay *= 200; 57 break; 58 } 59 return delay; 60 } 61 40 62 /* Handle a received message */ 41 63 int fd_p_dp_handle(struct msg ** msg, int req, struct fd_peer * peer) … … 44 66 45 67 if (req) { 46 /* We received a DPR, save the Disconnect-Cause and terminate the connection */68 /* We received a DPR, save the Disconnect-Cause and go to CLOSING_GRACE or terminate the connection */ 47 69 struct avp * dc; 48 int delay = peer->p_hdr.info.config.pic_tctimer ?: fd_g_config->cnf_timer_tc;49 70 50 71 CHECK_FCT( fd_msg_search_avp ( *msg, fd_dict_avp_DC, &dc )); 51 72 if (dc) { 52 /* Check the value is consistent with the saved one */53 73 struct avp_hdr * hdr; 54 74 CHECK_FCT( fd_msg_avp_hdr( dc, &hdr ) ); … … 60 80 } 61 81 82 /* save the cause */ 62 83 peer->p_hdr.info.runtime.pir_lastDC = hdr->avp_value->u32; 63 64 switch (hdr->avp_value->u32) {65 case ACV_DC_REBOOTING:66 default:67 /* We use TcTimer to attempt reconnection */68 break;69 case ACV_DC_BUSY:70 /* No need to hammer the overloaded peer */71 delay *= 10;72 break;73 case ACV_DC_NOT_FRIEND:74 /* He does not want to speak to us... let's retry a lot later maybe */75 delay *= 200;76 break;77 }78 84 } 79 85 if (TRACE_BOOL(INFO)) { 80 86 if (dc) { 81 struct dict_object * dictobj = NULL;87 struct dict_object * dictobj; 82 88 struct dict_enumval_request er; 83 89 memset(&er, 0, sizeof(er)); 90 91 /* prepare the request */ 84 92 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_TYPE, TYPE_OF_AVP, fd_dict_avp_DC, &er.type_obj, ENOENT ) ); 85 93 er.search.enum_value.u32 = peer->p_hdr.info.runtime.pir_lastDC; 94 95 /* Search the enum value */ 86 96 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &er, &dictobj, 0 ) ); 87 97 if (dictobj) { … … 100 110 CHECK_FCT( fd_msg_rescode_set( *msg, "DIAMETER_SUCCESS", NULL, NULL, 1 ) ); 101 111 102 /* Move to CLOSING state to failover outgoing messages (and avoid failing the DPA...) */112 /* Move to CLOSING state to failover outgoing messages (and avoid failing over the DPA...) */ 103 113 CHECK_FCT( fd_psm_change_state(peer, STATE_CLOSING) ); 104 114 … … 106 116 CHECK_FCT( fd_out_send( msg, NULL, peer, FD_CNX_ORDERED) ); 107 117 108 /* Move to CLOSED state */ 109 fd_psm_cleanup(peer, 0); 110 111 /* Reset the timer for next connection attempt -- we'll retry sooner or later depending on the disconnection cause */ 112 fd_psm_next_timeout(peer, 1, delay); 113 118 if (fd_cnx_isMultichan(peer->p_cnxctx)) { 119 /* There is a possibililty that messages are still in the pipe coming here, so let's grace for 1 second */ 120 CHECK_FCT( fd_psm_change_state(peer, STATE_CLOSING_GRACE) ); 121 fd_psm_next_timeout(peer, 0, 1); 122 123 } else { 124 /* Move to CLOSED state */ 125 fd_psm_cleanup(peer, 0); 126 127 /* Reset the timer for next connection attempt -- we'll retry sooner or later depending on the disconnection cause */ 128 fd_psm_next_timeout(peer, 1, fd_p_dp_newdelay(peer)); 129 } 114 130 } else { 115 131 /* We received a DPA */ 116 fd_cpu_flush_cache();117 if ( peer->p_hdr.info.runtime.pir_state != STATE_CLOSING) {118 TRACE_DEBUG(INFO, "Ignoring DPA received in state %s", STATE_STR( peer->p_hdr.info.runtime.pir_state));132 int curstate = fd_peer_getstate(peer); 133 if (curstate != STATE_CLOSING) { 134 TRACE_DEBUG(INFO, "Ignoring DPA received in state %s", STATE_STR(curstate)); 119 135 } 120 136 121 137 /* In theory, we should control the Result-Code AVP. But since we will not go back to OPEN state here anyway, let's skip it */ 138 139 /* TODO("Control Result-Code in the DPA") */ 122 140 CHECK_FCT_DO( fd_msg_free( *msg ), /* continue */ ); 123 141 *msg = NULL; 124 142 125 /* The calling function handles cleaning the PSM and terminating the peer since we return in CLOSING state */ 143 if (fd_cnx_isMultichan(peer->p_cnxctx)) { 144 CHECK_FCT( fd_psm_change_state(peer, STATE_CLOSING_GRACE) ); 145 fd_psm_next_timeout(peer, 0, 1); 146 peer->p_flags.pf_localterm = 1; 147 } 148 /* otherwise, return in CLOSING state, the psm will handle it */ 126 149 } 127 150 … … 153 176 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_TYPE, TYPE_OF_AVP, fd_dict_avp_DC, &er.type_obj, ENOENT ) ); 154 177 er.search.enum_name = reason ?: "REBOOTING"; 155 CHECK_FCT ( fd_dict_search( fd_g_config->cnf_dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &er, &dictobj, ENOENT ));178 CHECK_FCT_DO( fd_dict_search( fd_g_config->cnf_dict, DICT_ENUMVAL, ENUMVAL_BY_STRUCT, &er, &dictobj, ENOENT ), { ASSERT(0); /* internal error: unknown reason */ } ); 156 179 CHECK_FCT( fd_dict_getval( dictobj, &er.search ) ); 157 180
Note: See TracChangeset
for help on using the changeset viewer.