Navigation


source: freeDiameter/libfdcore/p_dw.c @ 662:2e94ef0515d7

1.1.0-rc1
Last change on this file since 662:2e94ef0515d7 was 662:2e94ef0515d7, checked in by Sebastien Decugis <sdecugis@nict.go.jp>, 11 years ago

Updated copyright information

File size: 6.0 KB
Line 
1/*********************************************************************************************************
2* Software License Agreement (BSD License)                                                               *
3* Author: Sebastien Decugis <sdecugis@nict.go.jp>                                                        *
4*                                                                                                        *
5* Copyright (c) 2011, WIDE Project and NICT                                                              *
6* All rights reserved.                                                                                   *
7*                                                                                                        *
8* Redistribution and use of this software in source and binary forms, with or without modification, are  *
9* permitted provided that the following conditions are met:                                              *
10*                                                                                                        *
11* * Redistributions of source code must retain the above                                                 *
12*   copyright notice, this list of conditions and the                                                    *
13*   following disclaimer.                                                                                *
14*                                                                                                        *
15* * Redistributions in binary form must reproduce the above                                              *
16*   copyright notice, this list of conditions and the                                                    *
17*   following disclaimer in the documentation and/or other                                               *
18*   materials provided with the distribution.                                                            *
19*                                                                                                        *
20* * Neither the name of the WIDE Project or NICT nor the                                                 *
21*   names of its contributors may be used to endorse or                                                  *
22*   promote products derived from this software without                                                  *
23*   specific prior written permission of WIDE Project and                                                *
24*   NICT.                                                                                                *
25*                                                                                                        *
26* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
27* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
28* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
29* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT     *
30* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS    *
31* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
32* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF   *
33* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                                                             *
34*********************************************************************************************************/
35
36#include "fdcore-internal.h"
37
38/* This file contains code to handle Device Watchdog messages (DWR and DWA) */
39
40/* Check the value of Origin-State-Id is consistent in a DWR or  DWA -- we just log if it is not the case */
41static void check_state_id(struct msg * msg, struct fd_peer * peer)
42{
43        struct avp * osi;
44        /* Check if the request contains the Origin-State-Id */
45        CHECK_FCT_DO( fd_msg_search_avp ( msg, fd_dict_avp_OSI, &osi ), return );
46        if (osi) {
47                /* Check the value is consistent with the saved one */
48                struct avp_hdr * hdr;
49                CHECK_FCT_DO(  fd_msg_avp_hdr( osi, &hdr ), return  );
50                if (hdr->avp_value == NULL) {
51                        /* This is a sanity check */
52                        TRACE_DEBUG(NONE, "BUG: Unset value in Origin-State-Id in DWR / DWA");
53                        fd_msg_dump_one(NONE, osi);
54                        ASSERT(0); /* To check if this really happens, and understand why... */
55                }
56
57                if (peer->p_hdr.info.runtime.pir_orstate != hdr->avp_value->u32) {
58                        fd_log_debug("Received a new Origin-State-Id from peer %s! (%x / %x)\n", 
59                                peer->p_hdr.info.pi_diamid, 
60                                hdr->avp_value->u32,
61                                peer->p_hdr.info.runtime.pir_orstate );
62                }
63        }
64}
65
66/* Create and send a DWR */
67static int send_DWR(struct fd_peer * peer)
68{
69        struct msg * msg = NULL;
70       
71        /* Create a new DWR instance */
72        CHECK_FCT( fd_msg_new ( fd_dict_cmd_DWR, MSGFL_ALLOC_ETEID, &msg ) );
73       
74        /* Add the content of the message (only the origin) */
75        CHECK_FCT( fd_msg_add_origin ( msg, 1 ) );
76       
77        /* Now send this message */
78        CHECK_FCT( fd_out_send(&msg, NULL, peer, FD_CNX_ORDERED) );
79       
80        /* And mark the pending DW */
81        peer->p_flags.pf_dw_pending = 1;
82       
83        return 0;
84}
85
86/* Handle an incoming message */
87int fd_p_dw_handle(struct msg ** msg, int req, struct fd_peer * peer)
88{
89        int reset_tmr = 0;
90       
91        TRACE_ENTRY("%p %d %p", msg, req, peer);
92       
93        /* Check the value of OSI for information */
94        check_state_id(*msg, peer);
95       
96        if (req) {
97                /* If we receive a DWR, send back a DWA */
98                CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) );
99                CHECK_FCT( fd_msg_rescode_set( *msg, "DIAMETER_SUCCESS", NULL, NULL, 0 ) );
100                CHECK_FCT( fd_msg_add_origin ( *msg, 1 ) );
101                CHECK_FCT( fd_out_send( msg, peer->p_cnxctx, peer, FD_CNX_ORDERED) );
102               
103        } else {
104                /* Just discard the DWA */
105                CHECK_FCT_DO( fd_msg_free(*msg), /* continue */ );
106                *msg = NULL;
107               
108                /* And clear the pending DW flag */
109                peer->p_flags.pf_dw_pending = 0;
110        }
111       
112        /* Now update timeout */
113        if (req) {
114                /* Update timeout only if we did not already send a DWR ourselves */
115                reset_tmr = !peer->p_flags.pf_dw_pending;
116        } else {
117                /* Reset the timer */
118                reset_tmr = 1;
119        }
120        if (reset_tmr) {
121                fd_psm_next_timeout(peer, 1, peer->p_hdr.info.config.pic_twtimer ?: fd_g_config->cnf_timer_tw);
122        }
123       
124        /* If we are in REOPEN state, increment the counter */
125        fd_cpu_flush_cache();
126        if (peer->p_hdr.info.runtime.pir_state == STATE_REOPEN) {
127                peer->p_flags.pf_reopen_cnt += 1;
128               
129                if (peer->p_flags.pf_reopen_cnt) {
130                        /* Send a new DWR */
131                        CHECK_FCT( send_DWR(peer) );
132                } else {
133                        /* Move to OPEN state */
134                        CHECK_FCT( fd_psm_change_state(peer, STATE_OPEN) );
135                }
136        }
137               
138        return 0;
139}
140
141/* Handle a timeout in the PSM (OPEN or REOPEN state only) */
142int fd_p_dw_timeout(struct fd_peer * peer)
143{
144        TRACE_ENTRY("%p", peer);
145
146        if (peer->p_flags.pf_dw_pending) {
147                /* We have sent a DWR and received no answer during TwTimer */
148                CHECK_FCT( fd_psm_change_state(peer, STATE_SUSPECT) );
149                fd_psm_next_timeout(peer, 0, 2 * (peer->p_hdr.info.config.pic_twtimer ?: fd_g_config->cnf_timer_tw) );
150        } else {
151                /* The timeout has expired, send a DWR */
152                CHECK_FCT( send_DWR(peer) );
153                fd_psm_next_timeout(peer, 0, peer->p_hdr.info.config.pic_twtimer ?: fd_g_config->cnf_timer_tw );
154        }
155       
156        return 0;
157}
158
159/* Handle DW exchanges after the peer has come alive again */
160int fd_p_dw_reopen(struct fd_peer * peer)
161{
162        TRACE_ENTRY("%p", peer);
163
164        peer->p_flags.pf_reopen_cnt = 1;
165        peer->p_flags.pf_cnx_pb = 0;
166        CHECK_FCT( send_DWR(peer) );
167       
168        return 0;
169}
170
171
Note: See TracBrowser for help on using the repository browser.