view waaad/message.h @ 411:7b3d4431610a

Improved support for creating error messages, even when no dictionary definition is present
author Sebastien Decugis <sdecugis@nict.go.jp>
date Thu, 11 Jun 2009 18:08:17 +0900
parents 237d245fd336
children
line wrap: on
line source

/*********************************************************************************************************
* Software License Agreement (BSD License)                                                               *
* Author: Sebastien Decugis <sdecugis@nict.go.jp>							 *
*													 *
* Copyright (c) 2008, 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.								 *
*********************************************************************************************************/

/* Messages module.
 * 
 * This module allows to manipulate the msg_t and msg_avp_t structures that represents a Diameter message in memory.
 * See message-api.h for more information on the functions and types involved.
 *
 * When a Diameter message is received on an interface, the process is as follow:
 *   - The peer thread receives the message from the transport layer and saves it as a buffer.
 *   - The Security module handles this message and decrypt the content as needed, as a new buffer.
 *   - The function "msg_parse_buffer" is called to quickly check the structure and coherency of the message.
 *   - A first level of filters is applied from header information: Answer message without corresponding request, ...
 *   - The function "msg_parse_dict" is called to save all AVP values in the msg structure. The buffer is then discarded.
 *   - The message is queued for handling by the routing daemon.
 *   - When the message is picked, the function will decide on the destination of the message and modify it accordingly.
 *     - If the message is put for local delivery, "msg_parse_rules" will be called. Conflicting messages can not be handled.
 *     - If the message is put for forwarding, the forwarding callbacks functions are called (to set the route-record and/or proxy information).
 *       - then the message is put in the outgoing global queue.
 *       - the routing daemon pick the message, determines the next hop, and put the message in the peer's outgoing queue.
 *       - the peer picks the message, set the hop-by-hop id, and call "msg_bufferize". The buffer is passed to the security module (encrypt) then to the transport layer (send).
 *        - the msg object may be saved in the "sent" peer queue for failover and for matching the answer; or the object is freed.
 */
 
#ifndef _MESSAGE_H
#define _MESSAGE_H

/* Include the API for the messages */
#include <waaad/message-api.h>

 
/* The following functions are called only from the daemon */

/*
 * FUNCTION:	msg_init
 *
 * PARAMETERS:
 *  -
 *
 * DESCRIPTION: 
 *  Initialize the message module. 
 *
 * RETURN VALUE:
 *   0	: Application is now ready to use the module.
 *  !0  : An error occurred. 
 */
int msg_init ( void );

/*
 * FUNCTION:	msg_fini
 *
 * PARAMETERS:
 *  -
 *
 * DESCRIPTION: 
 *  Terminates the module. No msg_* function must be called after this one.
 *
 * RETURN VALUE:
 *   0 : module closed properly.
 *  !0 : an error occurred (we may ignore it)
 */
int msg_fini ( void );


/*
 * FUNCTION:	msg_parse_buffer
 *
 * PARAMETERS:
 *  buffer 	: Pointer to a buffer containing a message received from the network. 
 *  buflen	: the size in bytes of the buffer.
 *  msg		: Upon success, this points to a valid msg_t object. No AVP value is resolved in this object, nor grouped AVP.
 *
 * DESCRIPTION: 
 *   This function parses a buffer an creates a msg_t object to represent the structure of the message.
 *  Since no dictionary lookup is performed, the values of the AVP are not interpreted. To achieve this,
 *  the returned message object must be passed to msg_parse_dict.
 *  The buffer pointer is saved inside the message and will be freed when not needed anymore.
 *
 * RETURN VALUE:
 *  0      	: The location has been written.
 *  ENOMEM	: Unable to allocate enough memory to create the msg_t object.
 *  EBADMSG	: The buffer does not contain a valid Diameter message.
 *  EINVAL 	: A parameter is invalid.
 */
int msg_parse_buffer ( unsigned char ** buffer, size_t buflen, msg_t ** msg );

/*
 * FUNCTION:	msg_bufferize
 *
 * PARAMETERS:
 *  msg		: A valid msg_t object. All AVP must have a value. 
 *  buffer 	: Upon success, this points to an allocated buffer of the message that can be passed to the security layer. 
 *		 The buffer may be freed after use.
 *  len		: if not NULL, the size of the buffer is written here. In any case, this size is updated in the msg header.
 *
 * DESCRIPTION: 
 *   Renders a message in memory as a buffer that can be sent over the network to the next peer.
 *
 * RETURN VALUE:
 *  0      	: The location has been written.
 *  EINVAL 	: The buffer does not contain a valid Diameter message.
 *  ENOMEM	: Unable to allocate enough memory to create the msg_t object.
 */
int msg_bufferize ( msg_t * msg, unsigned char ** buffer, size_t * len );

/*
 * FUNCTION:	msg_parse_dict
 *
 * PARAMETERS:
 *  msg		: A msg_t object as returned by msg_parse_buffer.
 *
 * DESCRIPTION: 
 *   This function looks for the command and each AVP definition in the dictionary.
 *  If the dictionary definition is found, avp_model is set and the value of the AVP is interpreted accordingly and:
 *   - for grouped AVPs, the children AVP are created and interpreted also.
 *   - for numerical AVPs, the value is converted to host byte order and saved to appropriate avp_data field.
 *   - for octetstring AVPs, the string is copied into a new buffer and its address is put in avp_data. 
 *  If the dictionary definition is not found, avp_model is left to NULL and
 *  the content of the AVP is saved as an octetstring in an internal structure. avp_data is NULL.
 *  As a result, after this function has been called, there is no more dependency of the msg object to the message buffer, that can be freed.
 *
 * RETURN VALUE:
 *  0      	: The message has been fully parsed as described.
 *  EINVAL 	: the msg parameter is invalid for this operation.
 *  ENOMEM	: Unable to allocate enough memory to complete the operation.
 *  ENOTSUP	: No dictionary definition for the command or one of the mandatory AVP.
 */
int msg_parse_dict ( msg_t * msg );

/*
 * FUNCTION:	msg_parse_dict_avp
 *
 * PARAMETERS:
 *  msg		: An AVP from the msg_t tree.
 *
 * DESCRIPTION: 
 *   This function is similar to msg_parse_dict, but only for one AVP of a message.
 *
 * RETURN VALUE:
 *  0      	: The message has been fully parsed as described.
 *  EINVAL 	: the msg parameter is invalid for this operation.
 *  ENOMEM	: Unable to allocate enough memory to complete the operation.
 *  ENOTSUP	: No dictionary definition for the command or one of the mandatory AVP.
 */
int msg_parse_dict_avp ( msg_avp_t * avp );

/*
 * FUNCTION:	msg_is_routable
 *
 * PARAMETERS:
 *  msg		: A msg_t object.
 *
 * DESCRIPTION: 
 *   This function returns a boolean telling if a given message is routable in the Diameter network, 
 *  or if it is a local link message only.
 *
 * RETURN VALUE:
 *  0      	: The message is not routable.
 *  1      	: The message is routable.
 */
int msg_is_routable ( msg_t * msg );

/*
 * FUNCTION:	msg_new_answer_from_req
 *
 * PARAMETERS:
 *  msg		: The location of the query on entry, and of answer on return.
 *  error       : Boolean to indicate if the answer is an error message (with 'E' bit set)
 *
 * DESCRIPTION: 
 *   This function creates the empty answer message for a request.
 *  The header is set properly (R flag, ccode, appid, hbhid, eteid)
 *  The Session-Id AVP is copied if present.
 *  The calling code should usually call msg_rescode_set function on the answer.
 *  Upon return, the original query may be retrieved by calling msg_answ_getq on the message.
 *
 * RETURN VALUE:
 *  0      	: Operation complete.
 *  !0      	: an error occurred.
 */
int msg_new_answer_from_req ( msg_t ** msg, int error );

/*
 * FUNCTION:	msg_rescode_set
 *
 * PARAMETERS:
 *  msg		: A msg_t object -- it must be an answer.
 *  rescode	: The name of the returned error code (ex: "DIAMETER_INVALID_AVP")
 *  errormsg    : (optional) human-readable error message to put in Error-Message AVP
 *  optavp	: (optional) If provided, the content will be put inside a Failed-AVP
 *  type_id	: 0 => nothing; 1 => adds Origin-Host and Origin-Realm with local info. 2=> adds Error-Reporting-Host.
 *
 * DESCRIPTION: 
 *   This function adds a Result-Code AVP to a message, and optionally
 *  - sets the 'E' error flag in the header,
 *  - adds Error-Message, Error-Reporting-Host and Failed-AVP AVPs.
 *
 * RETURN VALUE:
 *  0      	: Operation complete.
 *  !0      	: an error occurred.
 */
int msg_rescode_set( msg_t * msg, char * rescode, char * errormsg, msg_avp_t * optavp, int type_id );

/*
 * FUNCTION:	msg_source_(g/s)et
 *
 * PARAMETERS:
 *  msg		: A msg_t object.
 *  diamid	: The diameter id of the peer from which this message was received.
 *  hash	: The hash for the diamid value.
 *
 * DESCRIPTION: 
 *   Store or retrieve the diameted id of the peer from which this message was received.
 * Will be used for example by the routing module to add the Route-Record AVP in forwarded requests,
 * or to direct answers to the appropriate peer.
 *
 * RETURN VALUE:
 *  0      	: Operation complete.
 *  !0      	: an error occurred.
 */
int msg_source_set( msg_t * msg, char * diamid, uint32_t hash, int add_rr );
int msg_source_get( msg_t * msg, char ** diamid, uint32_t *hash );

/*
 * FUNCTION:	msg_answ_associate, msg_answ_getq, msg_answ_detach
 *
 * PARAMETERS:
 *  answer	: the received answer message
 *  query	: the corresponding query that had been sent
 *
 * DESCRIPTION:
 *  Associate a query msg with the received answer. Query is retrieved with msg_answ_getq.
 * If answer message is freed, the query is also freed.
 * If the msg_answ_detach function is called, the association is removed.
 *
 * RETURN VALUE:
 *  0 	  : ok
 *  EINVAL: a parameter is invalid
 */
int msg_answ_associate( msg_t * answer, msg_t * query );
int msg_answ_getq     ( msg_t * answer, msg_t ** query );
int msg_answ_detach   ( msg_t * answer );

/* Retrieve the callback registered within the msg_send function */
int msg_get_anscb(msg_t * msg, void (**anscb)(void *, msg_t **), void ** data );

/*
 * FUNCTION:	msg_rt_associate, msg_rt_get
 *
 * PARAMETERS:
 *  msg		: the query message to be sent
 *  list	: the ordered list of possible next-peers
 *
 * DESCRIPTION:
 *  Associate a routing list with a query, and retrieve it.
 * If the message is freed, the list is also freed.
 *
 * RETURN VALUE:
 *  0 	  : ok
 *  EINVAL: a parameter is invalid
 */
int msg_rt_associate( msg_t * msg, rt_dpl_t ** list );
int msg_rt_get      ( msg_t * msg, rt_dpl_t ** list );

/*
 * FUNCTION:	msg_dump_*
 *
 * PARAMETERS:
 *  obj		: A msg_t or msg_avp_t object.
 *
 * DESCRIPTION: 
 *   These functions dump the content of a message to the log facility (using log_debug)
 *
 * RETURN VALUE:
 *   -
 */
void msg_dump_walk ( int level, void * obj );
void msg_dump_one  ( int level, void * obj );


/* The following functions are used to achieve frequent operations on the messages */
int msg_add_origin ( msg_t * msg, int osi ); /* Add Origin-Host, Origin-Realm, (if osi) Origin-State-Id AVPS at the end of the message */



#endif /* _MESSAGE_H */
"Welcome to our mercurial repository"