view waaad/peer-internal.h @ 132:9dfac05e0e48

Added some prototypes in peer module
author Sebastien Decugis <sdecugis@nict.go.jp>
date Tue, 19 Aug 2008 14:17:34 +0900
parents d1cef88ac5f2
children ee63e869c000
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.								 *
*********************************************************************************************************/

/* Peers management module - internal header.
 * 
 *  This header contains the private definitions to the peer module. 
 * It should not be included outside this module.
 *
 *
 *  Here is a little more design details:
 *
 *  Each peer to which the local host is directly connected is represented by a _peer_t object.
 * Such objects are created either explicitely by calls to peer_add, or implicitely when a new
 * incoming connection is accepted.
 *
 *  Once the peer_start function has been called, a thread is associated to each peer object to
 * handle this peer state machine, with the exception of peers in the STATE_DISABLED state.
 *
 *  In addition, the peer state machine thread creates more threads for the peer for specific tasks:
 * waiting for incoming messages on the socket, sending messages on the socket, ...
 *
 */

#ifndef _PEER_INTERNAL_H
#define _PEER_INTERNAL_H

#include <pthread.h>
#include <errno.h>
#include <sys/socket.h>
#include <time.h>

/* States of a peer */
typedef enum {
	/* Stable states */
	STATE_DISABLED = 1,	/* No connexion must be attempted */
	STATE_OPEN,		/* Connexion established */
	
	/* Peer state machine */
	STATE_CLOSED,		/* No connection established, will re-attempt after TcTimer. */
	STATE_CLOSING,		/* the connection is being shutdown (DPR/DPA in progress) */
	STATE_WAITCNXACK,	/* Attempting to establish transport-level connection */
	STATE_WAITCNXACK_ELEC,	/* Received a CER from this same peer on an incoming connection (other peer object), while we were waiting for cnx ack */
	STATE_WAITCEA,		/* Connection established, CER sent, waiting for CEA */
	STATE_WAITRETURNS_ELEC,	/* We have sent a CER on our initiated connection, and received a CER from the remote peer on another connection. Election.
				   If we win the election, we must disconnect the initiated connection and send a CEA on the other => we go to OPEN state.
				   If we lose, we disconnect the other connection (receiver) and fallback to WAITCEA state. */
	
	/* Failover state machine */
	STATE_SUSPECT,		/* A DWR was sent and not answered within TwTime. Failover in progress. */
	STATE_REOPEN		/* Connection has been re-established, waiting for 3 DWR/DWA exchanges before putting back to service */
	
} peer_state_t;

/* List of sent requests to this peer, ordered by hop-by-hop id */
typedef struct _sent_r {
	/* Chaining information */
	struct _sent_r	*next;	/* The next sent request */
	struct _sent_r	*prev;	/* The previous sent request */

	/* Pointer to the message */
	msg_t		*msg;

	/* The following two fields are copied from message for faster processing on message reception and failover */
	uint32_t	 hbh;	/* The hop-by-hop value of the message */
	int	 	 rtb;	/* Is this a routable message? => discarded or requeued on failover */
	
} _sent_req_t;

struct _peer;

/* A list element for peers lists */
typedef struct _pi {
	struct _pi 	*next;		/* next peer in the list */
	struct _pi 	*prev;		/* previous peer in the list */
	struct _peer	*top;		/* this peer */
	struct _pi 	*sentinel;	/* the head of the list */
} _pi_t;

/* Events that can be sent to the peer and handled by the peer state machine */
typedef enum {
	PEVENT_SHUTDOWN = 1,	/* The daemon requested to shutdown this peer resources */
	PEVENT_DISCONNECTED,	/* the socket has been disconnected */
	PEVENT_MAX	/* To be continued */
} pevent_t;

/* An event element */
typedef struct _pe {
	pevent_t	 event;	/* identifier of this event */
	void		*data;	/* the data associated to the event, if appropriate */
	struct _pe	*next;	/* next event in the list */
	struct _pe	*prev;	/* prev event in the list */
} _pe_t;
	

/* Flags definitions */
#define	PEERFL_DYNAMIC		( 1 << 0 )	/* The peer is not statically configured and will expire */
#define	PEERFL_EXPIRETS		( 1 << 1 )	/* The peer expires at the p_expire time. If not set, the (dynamic) peer expires at transport disconnection */
#define PEERFL_DW_PENDING	( 1 << 2 )	/* A DWR message was sent and not answered yet */
#define PEERFL_CNX_PB		( 1 << 3 )	/* The peer was disconnected because of watchdogs; must exchange 3 watchdogs before putting back to normal */

/* Peer internal description */
typedef struct _peer {
	/* Chaining of the peer in global lists */
	_pi_t		 p_global;	/* List of peers this peer belongs to */
	_pi_t		 p_active;	/* Sublist containing only the active peers (in STATE_OPEN) */

	/* For debug */
	uint32_t	 p_eyec;	/* An eyecatcher to verify object is valid. Must be PEER_EYEC. */
	
	/* Peer data */
	char 		*p_diamid;	/* The Diameter-Id of this peer, once known */
	char 		*p_realm;	/* pointer to the beginning of the realm in the diamid string. */
	uint32_t	 p_hbh;		/* next Hop-by-hop free value */
	pthread_mutex_t	 p_lock;	/* Mutex to protect this object */
	uint32_t	 p_flags;	/* The PEERFL_* flags */
	struct timespec	 p_expire;	/* Lifetime of the peer, for dynamic peers */
	
	/* Peer state */
	peer_state_t	 p_state;	/* State of the peer */
	pthread_t	 p_psm;		/* The thread handling this peer state machine. */
	pthread_cond_t	 p_condvar;	/* The cond var to be waited in the peer state machine (for timeouts and DWR and events) */
	struct timespec	 p_ts;		/* multi-purpose timespec (meaning depends on the state) */
	_pe_t		 p_events;	/* queue of events received by the peer */
	
	/* Messages handling */
	meq_t 		*p_in_q;	/* Incoming (received) message queue */
	pthread_t	 p_in_th;	/* The thread handling messages reception, created by p_psm */
	meq_t 		*p_out_q;	/* Outgoing message queue */
	pthread_t	 p_out_th;	/* The thread handling messages envoy, created by p_psm */
	_sent_req_t	 p_sent;	/* List of sent requests without answer */
	
	/* Connection information */
	int		 p_sock;	/* We use standard Berkeley sockets for both TCP and SCTP connections */
	int		 p_sock_tmp;	/* In case of election, store the socket on which the CER was received here, temporarily */
	size_t		 p_peeraddr_sz;	/* Number of items in the array p_peeraddr bellow */
	sSS 		*p_peeraddr;	/* Array of the attachment points of the remote peer (received in Host-IP-Address AVPs) */
	
	/* Security information */
	_sec_item_t 	*p_sec_list;	/* Used only before a sucessful CER/CEA exchange */
	sec_mod_hdl_t 	*p_sec_hdl;	/* store reference to the security handler, to call sec_modunlink later */
	sec_module_t	*p_secmod;	/* the security callbacks */
	sec_session_t	 p_sec_session;	/* structure passed back to the security module, for connection information */
	void		*p_ext_session;	/* opaque data that can be used by the security extension to store internal states */
	
	/* Supported applications (result of CER/CEA) -- contains all applications advertized by remote */
	size_t		 p_app_size;	/* The size of the array pointed by p_app_list */
	peer_appl_t	*p_app_list;	/* points to an array of supported applications, of size p_app_size + 1, and the last element is always 0 */
	
} _peer_t;

/* The peers global vars */
extern _pi_t		g_peer_list_valid;	/* The peers for which the diameter id is known */
extern _pi_t		g_peer_list_active;	/* Sentinel for the p_active list, sublist of g_peer_list_all */
extern _pi_t		g_peer_list_unknown;	/* List of the peers that have not yet advertized their Diameter-Id */
extern _pi_t		g_peer_list_deleted;	/* Peers that have expired and are in grace period for being removed */
extern pthread_mutex_t	g_peer_list_lock;	/* Protect the lists. We use only one lock for simplicity. */

/* The eye-catcher value */
#define PEER_EYEC	0x23350B7

/* Cast macro */
#define _P( _peerptr_ ) ((_peer_t *)( _peerptr_ ))
#define _PI( _piptr_ )  ( (_pi_t *)   (_piptr_)  )

/* Check macro */
#define VALIDATE_PEER( _peer_ ) 				\
	(((_peer_) != NULL) 					\
	&& (_P(_peer_)->p_eyec == PEER_EYEC) 			\
	&& (_PI(_peer_)->sentinel != &g_peer_list_deleted))



/*
 * The functions 
 */

/* TCP-related functions */

/* SCTP-related functions */

/* Code of the listening thread (one per listening socket) */
void * _peer_listen_th(void * arg);

/* Code of the thread for the peer state machine (one per peer) */
void * _peer_state_machine_th(void * arg);

/* Sending events to a peer */
int _peer_sendevent(_peer_t * peer, pevent_t event, void * data);

/* Code of the thread for outgoing messages (one per peer) */
void * _peer_out_th(void * arg);

/* Code of the thread for incoming messages (one per peer) */
void * _peer_in_th(void * arg);

/* Terminate a thread by canceling it */
int _peer_cancel_th(pthread_t * thread);


#endif /* ! _PEER_INTERNAL_H */

"Welcome to our mercurial repository"