Mercurial > hg > freeDiameter
changeset 131:50d1dc19b221
Hopefully removed infinite loop
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Thu, 10 Dec 2009 17:18:59 +0900 |
parents | a16504d20ed1 |
children | 4e49c086d2c4 |
files | freeDiameter/p_ce.c freeDiameter/p_psm.c include/freeDiameter/libfreeDiameter.h |
diffstat | 3 files changed, 32 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/freeDiameter/p_ce.c Thu Dec 10 15:56:56 2009 +0900 +++ b/freeDiameter/p_ce.c Thu Dec 10 17:18:59 2009 +0900 @@ -260,7 +260,7 @@ } /* Extract information sent by the remote peer and save it in our peer structure */ -static int save_remote_CE_info(struct msg * msg, struct fd_peer * peer, char ** error_code) +static int save_remote_CE_info(struct msg * msg, struct fd_peer * peer, char ** error_code, uint32_t *rc) { struct avp * avp = NULL; @@ -291,12 +291,8 @@ goto next; } - /* We check that the CEA Result-Code is Success, otherwise we disconnect */ - if (hdr->avp_value->u32 != ER_DIAMETER_SUCCESS) { - TRACE_DEBUG(INFO, "Received CEA with Result-Code %d (expected %d), disconnect", hdr->avp_value->u32, ER_DIAMETER_SUCCESS); - return EBADMSG; - } - + if (rc) + *rc = hdr->avp_value->u32; break; case AC_ORIGIN_HOST: /* Origin-Host */ @@ -639,6 +635,7 @@ int fd_p_ce_msgrcv(struct msg ** msg, int req, struct fd_peer * peer) { char * ec; + uint32_t rc = 0; TRACE_ENTRY("%p %p", msg, peer); CHECK_PARAMS( msg && *msg && CHECK_PEER(peer) ); @@ -671,12 +668,36 @@ } /* Save info from the CEA into the peer */ - CHECK_FCT_DO( save_remote_CE_info(*msg, peer, &ec), goto cleanup ); + CHECK_FCT_DO( save_remote_CE_info(*msg, peer, &ec, &rc), goto cleanup ); /* Dispose of the message, we don't need it anymore */ CHECK_FCT_DO( fd_msg_free(*msg), /* continue */ ); *msg = NULL; + /* Check the Result-Code */ + switch (rc) { + case ER_DIAMETER_SUCCESS: + /* No problem, we can continue */ + break; + + case ER_DIAMETER_TOO_BUSY: + /* Retry later */ + TRACE_DEBUG(INFO, "Peer %s replied a CEA with Result-Code AVP DIAMETER_TOO_BUSY, will retry later.", peer->p_hdr.info.pi_diamid); + fd_psm_cleanup(peer, 0); + fd_psm_next_timeout(peer, 0, 300); + return 0; + + case ER_ELECTION_LOST: + /* Ok, just wait for a little while for the CER to be processed on the other connection. */ + TRACE_DEBUG(FULL, "Peer %s replied a CEA with Result-Code AVP ELECTION_LOST, waiting for events.", peer->p_hdr.info.pi_diamid); + return 0; + + default: + /* In any other case, we abort all attempts to connect to this peer */ + TRACE_DEBUG(INFO, "Peer %s replied a CEA with Result-Code AVP %d, aborting connection attempts.", peer->p_hdr.info.pi_diamid, rc); + return EINVAL; + } + /* Handshake if needed, start clear otherwise */ if ( ! fd_cnx_getTLS(peer->p_cnxctx) ) { int todo = peer->p_hdr.info.config.pic_flags.sec & peer->p_hdr.info.runtime.pir_isi ; @@ -712,11 +733,6 @@ return 0; cleanup: - if (*msg) { - CHECK_FCT_DO( fd_msg_free(*msg), /* continue */ ); - *msg = NULL; - } - fd_p_ce_clear_cnx(peer, NULL); /* Send the error to the peer */ @@ -740,7 +756,7 @@ peer->p_cer = NULL; /* Parse the content of the received CER */ - CHECK_FCT_DO( save_remote_CE_info(msg, peer, &ec), goto error_abort ); + CHECK_FCT_DO( save_remote_CE_info(msg, peer, &ec, NULL), goto error_abort ); /* Validate the peer if needed */ if (peer->p_flags.pf_responder) {
--- a/freeDiameter/p_psm.c Thu Dec 10 15:56:56 2009 +0900 +++ b/freeDiameter/p_psm.c Thu Dec 10 17:18:59 2009 +0900 @@ -531,10 +531,10 @@ CHECK_FCT_DO( fd_p_ce_process_receiver(peer), goto psm_end ); break; + case STATE_WAITCEA: case STATE_OPEN: case STATE_REOPEN: case STATE_WAITCNXACK: - case STATE_WAITCEA: case STATE_SUSPECT: default: /* Mark the connection problem */
--- a/include/freeDiameter/libfreeDiameter.h Thu Dec 10 15:56:56 2009 +0900 +++ b/include/freeDiameter/libfreeDiameter.h Thu Dec 10 17:18:59 2009 +0900 @@ -1382,6 +1382,7 @@ #define ER_DIAMETER_REALM_NOT_SERVED 3003 #define ER_DIAMETER_TOO_BUSY 3004 #define ER_DIAMETER_REDIRECT_INDICATION 3006 +#define ER_ELECTION_LOST 4003 /*============================================================*/