Navigation


Changeset 1010:357c2f892d24 in freeDiameter for libfdcore/p_dp.c


Ignore:
Timestamp:
Mar 26, 2013, 12:39:32 AM (11 years ago)
Author:
Sebastien Decugis <sdecugis@freediameter.net>
Branch:
default
Phase:
public
Message:

Implement a new counter on pending answers to send back to a peer.
Function fd_peer_get_load_pending updated to retrieve this counter as well.
When a peer has answers pending, the connection is not immediately teared down
upon DPR/DPA exchange, but a GRACE_TIMEOUT delay (default 1 sec) is granted.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libfdcore/p_dp.c

    r974 r1010  
    6363int fd_p_dp_handle(struct msg ** msg, int req, struct fd_peer * peer)
    6464{
     65        long to_receive, to_send;
    6566        TRACE_ENTRY("%p %d %p", msg, req, peer);
    6667       
     
    110111                CHECK_FCT( fd_msg_rescode_set( *msg, "DIAMETER_SUCCESS", NULL, NULL, 1 ) );
    111112               
    112                 /* Move to CLOSING state to failover outgoing messages (and avoid failing over the DPA...) */
    113                 CHECK_FCT( fd_psm_change_state(peer, STATE_CLOSING) );
    114                
    115                 /* Now send the DPA */
    116                 CHECK_FCT( fd_out_send( msg, NULL, peer, FD_CNX_ORDERED) );
    117                
    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);
     113                /* Do we have pending exchanges with this peer? */
     114                CHECK_FCT( fd_peer_get_load_pending(&peer->p_hdr, &to_receive, &to_send) );
     115               
     116                if ((to_receive == 0) && (to_send == 1 /* only the DPA */)) {
     117                        /* No pending exchange, move to CLOSING directly */
     118                        CHECK_FCT( fd_psm_change_state(peer, STATE_CLOSING) );
     119               
     120                        /* Now send the DPA */
     121                        CHECK_FCT( fd_out_send( msg, NULL, peer, FD_CNX_ORDERED) );
    122122                       
    123                 } else {
    124                         /* Move to CLOSED state */
     123                        /* and move to CLOSED */
    125124                        fd_psm_cleanup(peer, 0);
    126125
    127126                        /* Reset the timer for next connection attempt -- we'll retry sooner or later depending on the disconnection cause */
    128127                        fd_psm_next_timeout(peer, 1, fd_p_dp_newdelay(peer));
     128                } else {
     129                        /* We have pending exchanges, we move to CLOSING_GRACE which allows exchanges of answers but
     130                        not new requests */
     131                        CHECK_FCT( fd_psm_change_state(peer, STATE_CLOSING_GRACE) );
     132                        fd_psm_next_timeout(peer, 0, GRACE_TIMEOUT);
     133                       
     134                        /* Now send the DPA */
     135                        CHECK_FCT( fd_out_send( msg, NULL, peer, FD_CNX_ORDERED) );
    129136                }
    130137        } else {
    131138                /* We received a DPA */
    132139                int curstate = fd_peer_getstate(peer);
    133                 if (curstate != STATE_CLOSING) {
     140                if (curstate != STATE_CLOSING_GRACE) {
    134141                        TRACE_DEBUG(INFO, "Ignoring DPA received in state %s", STATE_STR(curstate));
    135142                }
     
    141148                *msg = NULL;
    142149               
    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);
     150                /* Do we still have pending exchanges with this peer? */
     151                CHECK_FCT( fd_peer_get_load_pending(&peer->p_hdr, &to_receive, &to_send) );
     152                if ((to_receive != 0) || (to_send != 0)) {
     153                        TRACE_DEBUG(INFO, "Received DPA but pending load: [%ld, %ld], giving grace delay before closing", to_receive, to_send);
     154                        fd_psm_next_timeout(peer, 0, GRACE_TIMEOUT);
    146155                        peer->p_flags.pf_localterm = 1;
    147                 }
    148                 /* otherwise, return in CLOSING state, the psm will handle it */
     156                } else {
     157                        /* otherwise, go to CLOSING state, the psm will handle terminating the connection */
     158                        CHECK_FCT( fd_psm_change_state(peer, STATE_CLOSING) );
     159                }
    149160        }
    150161       
     
    188199       
    189200        /* Update the peer state and timer */
    190         CHECK_FCT( fd_psm_change_state(peer, STATE_CLOSING) );
     201        CHECK_FCT( fd_psm_change_state(peer, STATE_CLOSING_GRACE) );
    191202        fd_psm_next_timeout(peer, 0, DPR_TIMEOUT);
    192203       
Note: See TracChangeset for help on using the changeset viewer.