Commit ba423f26 authored by Sebastien Decugis's avatar Sebastien Decugis
Browse files

Added some support for peers

parent a9f583cd
......@@ -70,7 +70,11 @@ static void * mn_thr(void * arg)
/* Loop */
while (1) {
sleep(60);
#ifdef DEBUG
sleep(30);
#else /* DEBUG */
sleep(3600); /* 1 hour */
#endif /* DEBUG */
TRACE_DEBUG(NONE, "Monitor information");
CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_DUMP_QUEUES, NULL), /* continue */);
CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_DUMP_PEERS, NULL), /* continue */);
......
......@@ -14,6 +14,7 @@ SET(FD_COMMON_SRC
extensions.c
dict_base_proto.c
messages.c
peers.c
queues.c
)
......
......@@ -68,4 +68,21 @@ int fd_queues_fini(void);
/* Create all the dictionary objects defined in the Diameter base RFC. */
int fd_dict_base_protocol(struct dictionary * dict);
/* Peers */
struct fd_peer { /* The "real" definition of the peer structure */
struct peer_hdr p_hdr; /* contains all public data */
int p_eyec; /* Eye catcher, EYEC_PEER */
#define EYEC_PEER 0x373C9336
/* threads, message queues, socket & callbacks */
};
int fd_peer_init();
void fd_peer_dump(int details);
int fd_peer_start();
int fd_peer_waitstart();
#endif /* _FD_H */
......@@ -79,6 +79,7 @@ int main(int argc, char * argv[])
CHECK_FCT( fd_ext_init() );
CHECK_FCT( fd_queues_init() );
CHECK_FCT( fd_msg_init() );
CHECK_FCT( fd_peer_init() );
/* Parse the configuration file */
CHECK_FCT( fd_conf_parse() );
......@@ -87,7 +88,7 @@ int main(int argc, char * argv[])
CHECK_FCT( fd_ext_load() );
/* Start the peer state machines */
CHECK_FCT( fd_peer_start() );
/* Now, just wait for events */
TRACE_DEBUG(INFO, FD_PROJECT_BINARY " daemon initialized.");
......@@ -114,6 +115,9 @@ int main(int argc, char * argv[])
fd_conf_dump();
break;
case FDEV_DUMP_PEERS:
fd_peer_dump(FULL);
break;
case FDEV_TERMINATE:
ret = 0;
......
/*********************************************************************************************************
* 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. *
*********************************************************************************************************/
#include "fD.h"
const char *peer_state_str[] = { "<error>"
, "STATE_DISABLED"
, "STATE_OPEN"
, "STATE_CLOSED"
, "STATE_CLOSING"
, "STATE_WAITCNXACK"
, "STATE_WAITCNXACK_ELEC"
, "STATE_WAITCEA"
, "STATE_SUSPECT"
, "STATE_REOPEN"
};
#define STATE_STR(state) \
peer_state_str[ (state) <= STATE_REOPEN ? (state) : 0 ]
struct fd_list fd_g_peers;
pthread_rwlock_t fd_g_peers_rw;
static int started = 0;
static pthread_mutex_t started_mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t started_cnd = PTHREAD_COND_INITIALIZER;
/* Wait for start signal */
int fd_peer_waitstart()
{
CHECK_POSIX( pthread_mutex_lock(&started_mtx) );
awake:
if (! started) {
pthread_cleanup_push( fd_cleanup_mutex, &started_mtx );
CHECK_POSIX( pthread_cond_wait(&started_cnd, &started_mtx) );
pthread_cleanup_pop( 0 );
goto awake;
}
CHECK_POSIX( pthread_mutex_unlock(&started_mtx) );
return 0;
}
/* Allow the state machines to start */
int fd_peer_start()
{
CHECK_POSIX( pthread_mutex_lock(&started_mtx) );
started = 1;
CHECK_POSIX( pthread_cond_broadcast(&started_cnd) );
CHECK_POSIX( pthread_mutex_unlock(&started_mtx) );
return 0;
}
/* Initialize the peers list */
int fd_peer_init()
{
TRACE_ENTRY();
fd_list_init(&fd_g_peers, NULL);
CHECK_POSIX( pthread_rwlock_init(&fd_g_peers_rw, NULL) );
return 0;
}
/* Dump the list of peers */
void fd_peer_dump(int details)
{
struct fd_list * li;
fd_log_debug("Dumping list of peers :\n");
CHECK_FCT_DO( pthread_rwlock_rdlock(&fd_g_peers_rw), /* continue */ );
for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) {
struct fd_peer * np = (struct fd_peer *)li;
if (np->p_eyec != EYEC_PEER) {
fd_log_debug(" Invalid entry @%p !\n", li);
continue;
}
fd_log_debug(" %s %s", np->p_hdr.info.pi_diamid, STATE_STR(np->p_hdr.info.pi_state));
if (details > INFO) {
fd_log_debug(" (rlm:%s)", np->p_hdr.info.pi_realm);
if (np->p_hdr.info.pi_prodname)
fd_log_debug(" ['%s' %u]", np->p_hdr.info.pi_prodname, np->p_hdr.info.pi_firmrev);
}
fd_log_debug("\n");
}
CHECK_FCT_DO( pthread_rwlock_unlock(&fd_g_peers_rw), /* continue */ );
}
......@@ -159,7 +159,7 @@ enum peer_state {
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 */
};
extern char *peer_state_str[];
extern const char *peer_state_str[];
/* Information about a remote peer, used both for query and for creating a new entry */
struct peer_info {
......@@ -213,6 +213,73 @@ struct peer_info {
struct fd_list pi_apps; /* applications advertised by the remote peer, except relay (pi_flags.relay) */
};
struct peer_hdr {
struct fd_list chain; /* List of all the peers, ordered by their Diameter Id */
struct peer_info info; /* The public data */
/* This header is followed by more data in the private peer structure definition */
};
/* the global list of peers.
Since we are not expecting so many connections, we don't use a hash, but it might be changed.
The list items are peer_hdr structures (actually, fd_peer, but the cast is OK) */
extern struct fd_list fd_g_peers;
extern pthread_rwlock_t fd_g_peers_rw; /* protect the list */
/*
* FUNCTION: fd_peer_add
*
* PARAMETERS:
* info : Information to create the peer.
* cb : optional, a callback to call (once) when the peer connection is established or failed
* cb_data : opaque data to pass to the callback.
*
* DESCRIPTION:
* Add a peer to the list of peers to which the daemon must maintain a connexion.
* If cb is not null, the callback is called when the connection is in OPEN state or
* when an error has occurred. The callback should use the pi_state information to
* determine which one it is.
*
* RETURN VALUE:
* 0 : The peer is added.
* EINVAL : A parameter is invalid.
* EEXIST : A peer with the same Diameter-Id is already in the list.
* (other standard errors may be returned, too, with their standard meaning. Example:
* ENOMEM : Memory allocation for the new object element failed.)
*/
int fd_peer_add ( struct peer_info * info, void (*cb)(struct peer_info *, void *), void * cb_data );
/*
* FUNCTION: peer_validate_register
*
* PARAMETERS:
* peer_validate : Callback as defined bellow.
*
* DESCRIPTION:
* Add a callback to authorize / reject incoming peer connections.
* All registered callbacks are called until a callback sets auth = -1 or auth = 1.
* If no callback returns a clear decision, the default behavior is applied (reject unknown connections)
*
* RETURN VALUE:
* 0 : The callback is added.
* !0 : An error occurred.
*/
int fd_peer_validate_register ( int (*peer_validate)(struct peer_info * /* info */, int * /* auth */) );
/*
* CALLBACK: peer_validate
*
* PARAMETERS:
* info : Structure containing information about the peer attempting the connection.
* auth : Store there the result if the peer is accepted (1), rejected (-1), or unknown (0).
*
* DESCRIPTION:
* This callback is called when a new connection is being established from an unknown peer,
* after the CER is received. An extension must register such callback with peer_validate_register.
*
* RETURN VALUE:
* 0 : The authorization decision has been written in the location pointed by auth.
* !0 : An error occurred.
*/
/***************************************/
/* Sending a message on the network */
......
......@@ -116,9 +116,8 @@ void fd_fifo_dump(int level, char * name, struct fifo * queue, void (*dump_item)
}
CHECK_POSIX_DO( pthread_mutex_lock( &queue->mtx ), /* continue */ );
fd_log_debug(" %d elements in queue\n", queue->count);
fd_log_debug(" %d threads waiting\n", queue->thrs);
fd_log_debug(" thresholds: %d / %d, cb: %p / %p (%p), highest: %d\n",
fd_log_debug(" %d elements in queue / %d threads waiting\n", queue->count, queue->thrs);
fd_log_debug(" thresholds: %d / %d, cb: %p / %p (%p), highest: %d\n",
queue->high, queue->low,
queue->h_cb, queue->l_cb, queue->data,
queue->highest);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment