Mercurial > hg > waaad
view waaad/peer-dwr_dwa.c @ 401:860f41038ea2
Updated copyright information
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Tue, 02 Jun 2009 15:10:55 +0900 |
parents | 316bb3f38d04 |
children |
line wrap: on
line source
/********************************************************************************************************* * Software License Agreement (BSD License) * * Author: Sebastien Decugis <sdecugis@nict.go.jp> * * * * Copyright (c) 2009, WIDE Project and NICT * * All rights reserved. * * * * Redistribution and use of this software in source and binary forms, with or without modification, are * * permitted provided that the following conditions are met: * * * * * Redistributions of source code must retain the above * * copyright notice, this list of conditions and the * * following disclaimer. * * * * * Redistributions in binary form must reproduce the above * * copyright notice, this list of conditions and the * * following disclaimer in the documentation and/or other * * materials provided with the distribution. * * * * * Neither the name of the WIDE Project or NICT nor the * * names of its contributors may be used to endorse or * * promote products derived from this software without * * specific prior written permission of WIDE Project and * * NICT. * * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *********************************************************************************************************/ /* Peers facility. * * DWR / DWA messages management * * See peer-api.h and peer.h for more information on the functions * */ #include "waaad-internal.h" #include "peer-internal.h" /* Dictionary objects for PSM */ static dict_object_t * dict_DWR = NULL; static dict_object_t * dict_DWA = NULL; int _peer_dwr_dwa_init(void) { CHECK_FCT( dict_search( DICT_COMMAND, CMD_BY_NAME, "Device-Watchdog-Request", &dict_DWR, ENOENT) ); CHECK_FCT( dict_search( DICT_COMMAND, CMD_BY_NAME, "Device-Watchdog-Answer", &dict_DWA, ENOENT) ); return 0; } int _peer_dwr_dwa_fini(void) { /* nothing special to do */ return 0; } /***********************************************************************/ /* Diameter Base Protocol: Device-Watchdog messages */ /***********************************************************************/ /* Create a DWR message */ int _peer_dwr_create( _peer_t * peer, msg_t ** dwr ) { TRACE_ENTRY("%p", dwr); /* NULL is not allowed */ CHECK_PARAMS( dwr ); /* Create an empty DWR */ CHECK_FCT( msg_new( dict_DWR, 0, dwr ) ); /* Add standard Origin-Host, Origin-Realm and Origin-State-Id AVPs */ CHECK_FCT( msg_add_origin( *dwr, 1 ) ); /* Set the DWR header: end-to-end id ( hop-by-hop is set when sending ) */ { msg_data_t * dwr_data = NULL; CHECK_FCT( msg_data( *dwr, &dwr_data ) ); dwr_data->msg_eteid = msg_get_eteid(); } /* Make sure the DWR message is valid -- mostly for debug here... */ CHECK_FCT( msg_parse_rules( *dwr, NULL ) ); /* The DWR is now ready */ TRACE_DEBUG(FULL, "DWR Ready"); msg_dump_walk(FULL, *dwr); return 0; } /* Parse a received DWR */ int _peer_dwr_parse( msg_t * dwr, _peer_t * peer ) { msg_avp_t * avp = NULL; CHECK_PARAMS( VALIDATE_PEER( peer ) && dwr ); CHECK_FCT( msg_browse(dwr, MSG_BRW_FIRST_CHILD, &avp, NULL) ); /* Now loop on all AVPs -- we will break when last AVP was parsed */ while (avp) { msg_avp_data_t * avpdata; CHECK_FCT( msg_avp_data( avp, &avpdata ) ); if (avpdata->avp_flags & AVP_FLAG_VENDOR) { /* Ignore all vendor-specific AVPs in DWR ... because we don't support any currently */ TRACE_DEBUG(FULL, "Ignored a vendor AVP in DWR"); msg_dump_one(FULL, avp); goto next; } if (avpdata->avp_data == NULL) { /* Ignore if the data is not set -- this is more like a sanity check */ TRACE_DEBUG(FULL, "Ignored an AVP with unset value in DWR"); msg_dump_one(FULL, avp); ASSERT(0); /* To check if this really happens, and understand why... */ goto next; } switch (avpdata->avp_code) { case AC_ORIGIN_HOST: /* Origin-Host */ /* Verify that the advertized Origin-Host is conform to the peer name */ if (strncasecmp(peer->p_diamid, (char *)avpdata->avp_data->os.data, avpdata->avp_data->os.len)) { log_error("DWR Received from '%s' with invalid Origin-Host value.\n", peer->p_diamid); msg_dump_one(0, avp); return EBADMSG; } break; case AC_ORIGIN_REALM: /* Origin-Realm */ /* Verify that the advertized Origin-Realm is conform to the peer realm */ if (strncasecmp(peer->p_realm, (char *)avpdata->avp_data->os.data, avpdata->avp_data->os.len)) { log_error("DWR Received with invalid Origin-Realm value.\n"); msg_dump_one(0, avp); return EBADMSG; } break; case AC_ORIGIN_STATE_ID: /* Origin-State-Id */ /* Check if the remote peer has lost its state, in which case we must close the connection */ if ( peer->p_orstate != avpdata->avp_data->u32 ) { /* The easiest way here is to return an error, this should never happen anyway */ log_error("DWR received from '%s' with a new Origin-State-Id value.\n", peer->p_diamid); msg_dump_one(0, avp); return EBADMSG; } break; default: /* Other AVP */ TRACE_DEBUG(FULL, "Ignored AVP in DWR"); msg_dump_one(FULL, avp); } next: /* Go to next AVP */ CHECK_FCT( msg_browse(avp, MSG_BRW_NEXT, &avp, NULL) ); } return 0; } /* Create an answer */ int _peer_dwa_create( _peer_t * peer, msg_t ** dwa, uint32_t eteid, uint32_t hbhid ) { TRACE_ENTRY("%p %p %u %u", peer, dwa, eteid, hbhid); /* NULL is not allowed */ CHECK_PARAMS( dwa ); /* Create an empty DWA */ CHECK_FCT( msg_new( dict_DWA, 0, dwa ) ); /* Note: the Result-Code AVP will be added later outside this function */ /* Add standard Origin-Host, Origin-Realm and Origin-State-Id AVPs */ CHECK_FCT( msg_add_origin( *dwa, 1 ) ); /* Set the DWA header: end-to-end id */ { msg_data_t * dwa_data = NULL; CHECK_FCT( msg_data( *dwa, &dwa_data ) ); dwa_data->msg_eteid = eteid; dwa_data->msg_hbhid = hbhid; } return 0; } /* Parse a received answer */ int _peer_dwa_parse( msg_t * dwa, _peer_t * peer ) { msg_avp_t * avp = NULL; uint32_t errorcode = 0; CHECK_PARAMS( VALIDATE_PEER( peer ) && dwa ); CHECK_FCT( msg_browse(dwa, MSG_BRW_FIRST_CHILD, &avp, NULL) ); /* Now loop on all AVPs -- we will break when last AVP was parsed */ while (avp) { msg_avp_data_t * avpdata; CHECK_FCT( msg_avp_data( avp, &avpdata ) ); if (avpdata->avp_flags & AVP_FLAG_VENDOR) { /* Ignore all vendor-specific AVPs ... because we don't support any currently */ TRACE_DEBUG(FULL, "Ignored a vendor AVP in DWA"); msg_dump_one(FULL, avp); goto next; } if (avpdata->avp_data == NULL) { /* Ignore if the data is not set -- this is more like a sanity check */ TRACE_DEBUG(FULL, "Ignored an AVP with unset value in DWA"); msg_dump_one(FULL, avp); ASSERT(0); /* To check if this really happens, and understand why... */ goto next; } switch (avpdata->avp_code) { case AC_ORIGIN_HOST: /* Origin-Host */ /* Check that the remote peer is what we expect */ if (strncasecmp(peer->p_diamid, (char *)avpdata->avp_data->os.data, avpdata->avp_data->os.len)) { log_error("The DWA received from peer '%s' contains invalid Origin-Host (bad IP?), resetting connection", peer->p_diamid); msg_dump_one(0, avp); return EBADMSG; } break; case AC_ORIGIN_REALM: /* Origin-Realm */ /* Verify that the advertized Origin-Realm is conform to the peer realm */ if (strncasecmp(peer->p_realm, (char *)avpdata->avp_data->os.data, avpdata->avp_data->os.len)) { log_error("DWA received with invalid Origin-Realm value.\n"); msg_dump_one(0, avp); return EBADMSG; } break; case AC_ORIGIN_STATE_ID: /* Origin-State-Id */ /* Check if the remote peer has lost its state, in which case we must close the connection */ if ( peer->p_orstate != avpdata->avp_data->u32 ) { /* The easiest way here is to return an error, this should never happen anyway */ log_error("DWA received from '%s' with a new Origin-State-Id value.\n", peer->p_diamid); msg_dump_one(0, avp); return EBADMSG; } break; case AC_RESULT_CODE: /* Result-Code */ errorcode = avpdata->avp_data->u32; break; case AC_ERROR_MESSAGE: /* Error-Message */ log_normal("The DWA received from peer '%s' contains an Error-Message AVP", peer->p_diamid); msg_dump_one(INFO, avp); break; default: /* Other AVP */ TRACE_DEBUG(FULL, "Ignored AVP in DWA"); msg_dump_one(FULL, avp); } next: /* Go to next AVP */ CHECK_FCT( msg_browse(avp, MSG_BRW_NEXT, &avp, NULL) ); } /* Ok, now check the error code */ if ( errorcode != ER_DIAMETER_SUCCESS ) { /* We do not allow another error code here */ log_error("Received DWA with Result-Code value %u from %s.\n", errorcode, peer->p_diamid); return EBADMSG; } return 0; }