Mercurial > hg > freeDiameter
changeset 79:d273a2ce19c8
Fix problem in DPR handling
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Wed, 02 Dec 2009 10:25:59 +0900 |
parents | a58f0757c06a |
children | 56f0b629e036 |
files | freeDiameter/p_dp.c freeDiameter/p_psm.c |
diffstat | 2 files changed, 29 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/freeDiameter/p_dp.c Tue Dec 01 16:24:06 2009 +0900 +++ b/freeDiameter/p_dp.c Wed Dec 02 10:25:59 2009 +0900 @@ -40,12 +40,12 @@ /* Handle a received message */ int fd_p_dp_handle(struct msg ** msg, int req, struct fd_peer * peer) { - int delay = 0; TRACE_ENTRY("%p %d %p", msg, req, peer); if (req) { /* We received a DPR, save the Disconnect-Cause and terminate the connection */ struct avp * dc; + int delay = peer->p_hdr.info.config.pic_tctimer ?: fd_g_config->cnf_timer_tc; CHECK_FCT_DO( fd_msg_search_avp ( *msg, fd_dict_avp_DC, &dc ), return ); if (dc) { @@ -60,6 +60,21 @@ } peer->p_hdr.info.runtime.pir_lastDC = hdr->avp_value->u32; + + switch (hdr->avp_value->u32) { + case ACV_DC_REBOOTING: + default: + /* We use TcTimer to attempt reconnection */ + break; + case ACV_DC_BUSY: + /* No need to hammer the overloaded peer */ + delay *= 10; + break; + case ACV_DC_NOT_FRIEND: + /* He does not want to speak to us... let's retry a lot later maybe */ + delay *= 200; + break; + } } if (TRACE_BOOL(INFO)) { if (dc) { @@ -91,21 +106,25 @@ /* Now send the DPA */ CHECK_FCT( fd_out_send( msg, NULL, peer) ); + /* Move to CLOSED state */ + fd_psm_cleanup(peer, 0); + + /* Reset the timer for next connection attempt -- we'll retry sooner or later depending on the disconnection cause */ + fd_psm_next_timeout(peer, 1, delay); + } else { /* We received a DPA */ if (peer->p_hdr.info.runtime.pir_state != STATE_CLOSING) { TRACE_DEBUG(INFO, "Ignore DPA received in state %s", STATE_STR(peer->p_hdr.info.runtime.pir_state)); } + /* 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 */ + CHECK_FCT_DO( fd_msg_free( *msg ), /* continue */ ); + *msg = NULL; + + /* The calling function handles cleaning the PSM and terminating the peer since we return in CLOSING state */ } - if (*msg) { - /* In theory, we should control the Result-Code AVP. But since we will not go back to OPEN state here, let's skip it */ - CHECK_FCT_DO( fd_msg_free( *msg ), /* continue */ ); - *msg = NULL; - } - - /* The calling function handles cleaning the PSM and terminating the peer */ return 0; }
--- a/freeDiameter/p_psm.c Tue Dec 01 16:24:06 2009 +0900 +++ b/freeDiameter/p_psm.c Wed Dec 02 10:25:59 2009 +0900 @@ -538,11 +538,8 @@ peer->p_flags.pf_cnx_pb = 1; case STATE_CLOSING: - /* Cleanup the peer */ - fd_psm_cleanup(peer, 0); - - /* Reset the timer */ - fd_psm_next_timeout(peer, 1, peer->p_hdr.info.config.pic_tctimer ?: fd_g_config->cnf_timer_tc); + /* We sent a DPR so we are terminating, do not wait for DPA */ + goto psm_end; case STATE_CLOSED: /* Just ignore */