Mercurial > hg > freeDiameter
changeset 13:ef9ef3bf4752
Progress on peer state machine
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Wed, 30 Sep 2009 18:25:46 +0900 |
parents | 418d2ce80dc8 |
children | 14cf6daf716d |
files | doc/freediameter.conf.sample freeDiameter/CMakeLists.txt freeDiameter/fD.h freeDiameter/fdd.y freeDiameter/main.c freeDiameter/p_expiry.c freeDiameter/p_psm.c freeDiameter/peers.c freeDiameter/queues.c include/freeDiameter/CMakeLists.txt include/freeDiameter/freeDiameter-host.h.in include/freeDiameter/freeDiameter.h include/freeDiameter/libfreeDiameter.h |
diffstat | 13 files changed, 510 insertions(+), 50 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/freediameter.conf.sample Mon Sep 28 17:29:25 2009 +0900 +++ b/doc/freediameter.conf.sample Wed Sep 30 18:25:46 2009 +0900 @@ -162,3 +162,4 @@ LoadExtension = "extensions/dict_nasreq.fdx"; LoadExtension = "extensions/dict_eap.fdx"; ConnectPeer = "jules.nautilus6.org" ; +ConnectPeer = "aaa.nautilus6.org" { No_TLS; No_IP; No_TCP; SCTP_streams = 60; } ;
--- a/freeDiameter/CMakeLists.txt Mon Sep 28 17:29:25 2009 +0900 +++ b/freeDiameter/CMakeLists.txt Wed Sep 30 18:25:46 2009 +0900 @@ -14,8 +14,10 @@ extensions.c dict_base_proto.c messages.c + queues.c peers.c - queues.c + p_expiry.c + p_psm.c ) SET(FD_COMMON_GEN_SRC
--- a/freeDiameter/fD.h Mon Sep 28 17:29:25 2009 +0900 +++ b/freeDiameter/fD.h Wed Sep 30 18:25:46 2009 +0900 @@ -126,6 +126,10 @@ /* connection context: socket & other metadata */ struct cnxctx *p_cnxctx; + /* Callback on initial connection success / failure */ + void (*p_cb)(struct peer_info *, void *); + void *p_cb_data; + }; #define CHECK_PEER( _p ) \ (((_p) != NULL) && (((struct fd_peer *)(_p))->p_eyec == EYEC_PEER)) @@ -150,10 +154,21 @@ /* Functions */ int fd_peer_init(); +int fd_peer_fini(); void fd_peer_dump_list(int details); -int fd_peer_start(); -int fd_peer_waitstart(); +/* fd_peer_add declared in freeDiameter.h */ +int fd_peer_rc_decr(struct fd_peer **ptr, int locked); +/* Peer expiry */ +int fd_p_expi_init(void); +int fd_p_expi_fini(void); +int fd_p_expi_update(struct fd_peer * peer, int locked ); +int fd_p_expi_unlink(struct fd_peer * peer, int locked ); +/* Peer state machine */ +int fd_psm_start(); +int fd_psm_begin(struct fd_peer * peer ); +int fd_psm_terminate(struct fd_peer * peer ); +void fd_psm_abord(struct fd_peer * peer ); #endif /* _FD_H */
--- a/freeDiameter/fdd.y Mon Sep 28 17:29:25 2009 +0900 +++ b/freeDiameter/fdd.y Wed Sep 30 18:25:46 2009 +0900 @@ -209,12 +209,13 @@ { yyerror (&yylloc, conf, "Out of memory"); YYERROR; } ); memset(ep, 0, sizeof(struct fd_endpoint)); fd_list_init(&ep->chain, NULL); + ep->meta.conf = 1; memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; ret = getaddrinfo($3, NULL, &hints, &ai); - if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); YYERROR; } - + if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); free(ep); YYERROR; } + ASSERT( ai->ai_addrlen <= sizeof(sSS) ); memcpy(&ep->ss, ai->ai_addr, ai->ai_addrlen); free($3); freeaddrinfo(ai); @@ -425,11 +426,17 @@ { yyerror (&yylloc, conf, "Out of memory"); YYERROR; } ); memset(ep, 0, sizeof(struct fd_endpoint)); fd_list_init(&ep->chain, NULL); - + ep->meta.conf = 1; memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_ADDRCONFIG; + hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICHOST; ret = getaddrinfo($4, NULL, &hints, &ai); - if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); YYERROR; } + if (ret == EAI_NONAME) { + /* The name was maybe not numeric, try again */ + ep->meta.disc = 1; + hints.ai_flags &= ~ AI_NUMERICHOST; + ret = getaddrinfo($4, NULL, &hints, &ai); + } + if (ret) { yyerror (&yylloc, conf, gai_strerror(ret)); free(ep); YYERROR; } memcpy(&ep->ss, ai->ai_addr, ai->ai_addrlen); free($4);
--- a/freeDiameter/main.c Mon Sep 28 17:29:25 2009 +0900 +++ b/freeDiameter/main.c Wed Sep 30 18:25:46 2009 +0900 @@ -88,7 +88,7 @@ CHECK_FCT( fd_ext_load() ); /* Start the peer state machines */ - CHECK_FCT( fd_peer_start() ); + CHECK_FCT( fd_psm_start() ); /* Now, just wait for events */ TRACE_DEBUG(INFO, FD_PROJECT_BINARY " daemon initialized.");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/freeDiameter/p_expiry.c Wed Sep 30 18:25:46 2009 +0900 @@ -0,0 +1,78 @@ +/********************************************************************************************************* +* 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" + + + + +/* Initialize peers expiry mechanism */ +int fd_p_expi_init(void) +{ + TODO(""); + return ENOTSUP; +} + +/* Finish peers expiry mechanism */ +int fd_p_expi_fini(void) +{ + TODO(""); + return ENOTSUP; +} + +/* Add a peer in the expiry list if needed */ +int fd_p_expi_update(struct fd_peer * peer, int locked ) +{ + TODO(""); + + /* if peer expires */ + /* add to the expiry list in appropriate position */ + /* increment peer refcount */ + /* signal the expiry thread if we added in first position */ + + return ENOTSUP; +} + +/* Remove a peer from expiry list if needed */ +int fd_p_expi_unlink(struct fd_peer * peer, int locked ) +{ + TODO(""); + /* if peer is in expiry list */ + /* remove from the list */ + /* decrement peer refcount */ + /* no need to signal the expiry thread ... */ + + return ENOTSUP; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/freeDiameter/p_psm.c Wed Sep 30 18:25:46 2009 +0900 @@ -0,0 +1,92 @@ +/********************************************************************************************************* +* 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" + +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 */ +static int fd_psm_waitstart() +{ + TRACE_ENTRY(""); + 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_psm_start() +{ + TRACE_ENTRY(""); + 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; +} + +/* Create the PSM thread of one peer structure */ +int fd_psm_begin(struct fd_peer * peer ) +{ + TRACE_ENTRY("%p", peer); + TODO(""); + return ENOTSUP; +} + +/* End the PSM (clean ending) */ +int fd_psm_terminate(struct fd_peer * peer ) +{ + TRACE_ENTRY("%p", peer); + TODO(""); + return ENOTSUP; +} + +/* End the PSM violently */ +void fd_psm_abord(struct fd_peer * peer ) +{ + TRACE_ENTRY("%p", peer); + TODO(""); + return; +} +
--- a/freeDiameter/peers.c Mon Sep 28 17:29:25 2009 +0900 +++ b/freeDiameter/peers.c Wed Sep 30 18:25:46 2009 +0900 @@ -50,35 +50,6 @@ 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() { @@ -87,6 +58,20 @@ fd_list_init(&fd_g_peers, NULL); CHECK_POSIX( pthread_rwlock_init(&fd_g_peers_rw, NULL) ); + CHECK_FCT(fd_p_expi_init()); + + return 0; +} + +/* Terminate peer module (destroy all peers) */ +int fd_peer_fini() +{ + TRACE_ENTRY(); + + CHECK_FCT_DO(fd_p_expi_fini(), /* continue */); + + TODO("Complete this function") + return 0; } @@ -118,8 +103,235 @@ CHECK_FCT_DO( pthread_rwlock_unlock(&fd_g_peers_rw), /* continue */ ); } +/* Alloc / reinit a peer structure. if *ptr is not NULL, it must already point to a valid struct fd_peer. */ +static int fd_sp_reinit(struct fd_peer ** ptr) +{ + struct fd_peer *p; + + TRACE_ENTRY("%p", ptr); + CHECK_PARAMS(ptr); + + if (*ptr) { + p = *ptr; + } else { + CHECK_MALLOC( p = malloc(sizeof(struct fd_peer)) ); + *ptr = p; + } + + /* Now initialize the content */ + memset(p, 0, sizeof(struct fd_peer)); + + fd_list_init(&p->p_hdr.chain, p); + + fd_list_init(&p->p_hdr.info.pi_endpoints, NULL); + p->p_hdr.info.pi_state = STATE_DISABLED; + fd_list_init(&p->p_hdr.info.pi_apps, NULL); + + p->p_eyec = EYEC_PEER; + CHECK_POSIX( pthread_mutex_init(&p->p_mtx, NULL) ); + fd_list_init(&p->p_expiry, p); + fd_list_init(&p->p_actives, p); + p->p_hbh = lrand48(); + CHECK_FCT( fd_fifo_new(&p->p_events) ); + CHECK_FCT( fd_fifo_new(&p->p_recv) ); + CHECK_FCT( fd_fifo_new(&p->p_tosend) ); + fd_list_init(&p->p_sentreq, p); + + return 0; +} + +#define free_null( _v ) \ + if (_v) { \ + free(_v); \ + (_v) = NULL; \ + } + +#define free_list( _l ) \ + while (!FD_IS_LIST_EMPTY(_l)) { \ + struct fd_list * __li = ((struct fd_list *)(_l))->next; \ + fd_list_unlink(__li); \ + free(__li); \ + } + +/* Destroy a structure once all cleanups have been performed */ +static int fd_sp_destroy(struct fd_peer ** ptr) +{ + struct fd_peer *p; + void * t; + + TRACE_ENTRY("%p", ptr); + CHECK_PARAMS(ptr); + p = *ptr; + *ptr = NULL; + CHECK_PARAMS(p); + + CHECK_PARAMS( (p->p_refcount == 0) && FD_IS_LIST_EMPTY(&p->p_hdr.chain) ); + + free_null(p->p_hdr.info.pi_diamid); + free_null(p->p_hdr.info.pi_realm); + free_list( &p->p_hdr.info.pi_endpoints ); + /* Assume the security data is already freed */ + free_null(p->p_hdr.info.pi_prodname); + free_list( &p->p_hdr.info.pi_apps ); + + free_null(p->p_dbgorig); + CHECK_POSIX( pthread_mutex_destroy(&p->p_mtx) ); + ASSERT(FD_IS_LIST_EMPTY(&p->p_expiry)); + ASSERT(FD_IS_LIST_EMPTY(&p->p_actives)); + + CHECK_FCT( fd_thr_term(&p->p_psm) ); + while ( fd_fifo_tryget(p->p_events, &t) == 0 ) { + struct fd_event * ev = t; + TRACE_DEBUG(FULL, "Found event %d(%p) in queue of peer %p being destroyed", ev->code, ev->data, p); + free(ev); + } + CHECK_FCT( fd_fifo_del(&p->p_events) ); + + CHECK_FCT( fd_thr_term(&p->p_inthr) ); + while ( fd_fifo_tryget(p->p_recv, &t) == 0 ) { + struct msg * m = t; + TRACE_DEBUG(FULL, "Found message %p in incoming queue of peer %p being destroyed", m, p); + /* We simply destroy, the remote peer will re-send to someone else...*/ + CHECK_FCT(fd_msg_free(m)); + } + CHECK_FCT( fd_fifo_del(&p->p_recv) ); + + CHECK_FCT( fd_thr_term(&p->p_outthr) ); + while ( fd_fifo_tryget(p->p_tosend, &t) == 0 ) { + struct msg * m = t; + TRACE_DEBUG(FULL, "Found message %p in outgoing queue of peer %p being destroyed, requeue", m, p); + /* We simply requeue in global, the routing thread will re-handle it. */ + + } + CHECK_FCT( fd_fifo_del(&p->p_tosend) ); + + while (!FD_IS_LIST_EMPTY(&p->p_sentreq)) { + struct sentreq * sr = (struct sentreq *)(p->p_sentreq.next); + fd_list_unlink(&sr->chain); + TRACE_DEBUG(FULL, "Found message %p in list of sent requests to peer %p being destroyed, requeue (fallback)", sr->req, p); + CHECK_FCT(fd_fifo_post(fd_g_outgoing, &sr->req)); + free(sr); + } + + TRACE_DEBUG(NONE, "TODO: destroy p->p_cnxctx here"); + + if (p->p_cb) + (*p->p_cb)(NULL, p->p_cb_data); + + free(p); + + return 0; +} + +/* Decrement refcount, delete if 0 */ +int fd_peer_rc_decr(struct fd_peer **ptr, int locked) +{ + int count; + struct fd_peer *p; + TRACE_ENTRY("%p %d", p, locked); + + CHECK_PARAMS(ptr && CHECK_PEER( *ptr )); + p = *ptr; + + if (!locked) { + CHECK_POSIX( pthread_rwlock_rdlock(&fd_g_peers_rw) ); + CHECK_POSIX( pthread_mutex_lock( &p->p_mtx ) ); + CHECK_POSIX( pthread_rwlock_unlock(&fd_g_peers_rw) ); + } + + count = --(p->p_refcount); + + if (!locked) { + CHECK_POSIX( pthread_mutex_unlock( &p->p_mtx ) ); + } + + if (count <= 0) { + /* All links have already been removed, we can destroy */ + CHECK_FCT( fd_sp_destroy(ptr) ); + } + return 0; +} + /* Add a new peer entry */ int fd_peer_add ( struct peer_info * info, char * orig_dbg, void (*cb)(struct peer_info *, void *), void * cb_data ) { - return ENOTSUP; + struct fd_peer *p = NULL; + struct fd_list * li; + int ret = 0; + TRACE_ENTRY("%p %p %p %p", info, orig_dbg, cb, cb_data); + CHECK_PARAMS(info && info->pi_diamid); + + /* Create a structure to contain the new peer information */ + CHECK_FCT( fd_sp_reinit(&p) ); + + /* Copy the informations from the parameters received */ + CHECK_MALLOC( p->p_hdr.info.pi_diamid = strdup(info->pi_diamid) ); + if (info->pi_realm) { + CHECK_MALLOC( p->p_hdr.info.pi_realm = strdup(info->pi_realm) ); + } + + p->p_hdr.info.pi_flags.pro3 = info->pi_flags.pro3; + p->p_hdr.info.pi_flags.pro4 = info->pi_flags.pro4; + p->p_hdr.info.pi_flags.alg = info->pi_flags.alg; + p->p_hdr.info.pi_flags.sec = info->pi_flags.sec; + p->p_hdr.info.pi_flags.exp = info->pi_flags.exp; + + p->p_hdr.info.pi_lft = info->pi_lft; + p->p_hdr.info.pi_streams = info->pi_streams; + p->p_hdr.info.pi_port = info->pi_port; + p->p_hdr.info.pi_tctimer = info->pi_tctimer; + p->p_hdr.info.pi_twtimer = info->pi_twtimer; + + /* Move the items from one list to the other */ + while (!FD_IS_LIST_EMPTY( &info->pi_endpoints ) ) { + li = info->pi_endpoints.next; + fd_list_unlink(li); + fd_list_insert_before(&p->p_hdr.info.pi_endpoints, li); + } + + p->p_hdr.info.pi_sec_module = info->pi_sec_module; + memcpy(&p->p_hdr.info.pi_sec_data, &info->pi_sec_data, sizeof(info->pi_sec_data)); + + /* The internal data */ + if (orig_dbg) { + CHECK_MALLOC( p->p_dbgorig = strdup(orig_dbg) ); + } else { + CHECK_MALLOC( p->p_dbgorig = strdup("unknown") ); + } + p->p_cb = cb; + p->p_cb_data = cb_data; + + /* Ok, now check if we don't already have an entry with the same Diameter Id, and insert this one */ + CHECK_POSIX( pthread_rwlock_wrlock(&fd_g_peers_rw) ); + CHECK_POSIX( pthread_mutex_lock( &p->p_mtx ) ); + + for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) { + struct fd_peer * prev = (struct fd_peer *)li; + int cmp = strcasecmp( p->p_hdr.info.pi_diamid, prev->p_hdr.info.pi_diamid ); + if (cmp < 0) + continue; + if (cmp == 0) + ret = EEXIST; + break; + } + + /* We can insert the new peer object */ + if (! ret) { + /* Update expiry list */ + CHECK_FCT_DO( ret = fd_p_expi_update( p, 1 ), goto out ); + + /* Insert the new element in the list */ + fd_list_insert_before( li, &p->p_hdr.chain ); + p->p_refcount++; + } + +out: + CHECK_POSIX( pthread_mutex_unlock( &p->p_mtx ) ); + CHECK_POSIX( pthread_rwlock_unlock(&fd_g_peers_rw) ); + if (ret) { + CHECK_FCT( fd_sp_destroy(&p) ); + } else { + CHECK_FCT( fd_psm_start(p) ); + } + return ret; }
--- a/freeDiameter/queues.c Mon Sep 28 17:29:25 2009 +0900 +++ b/freeDiameter/queues.c Wed Sep 30 18:25:46 2009 +0900 @@ -56,10 +56,15 @@ TRACE_ENTRY(); /* Stop the providing threads */ + TODO("Stop the providing threads"); + /* Empty all contents */ + TODO("Empty all contents (dump to log file ?)"); + /* Now, delete the queues */ CHECK_FCT( fd_fifo_del ( &fd_g_incoming ) ); CHECK_FCT( fd_fifo_del ( &fd_g_outgoing ) ); CHECK_FCT( fd_fifo_del ( &fd_g_local ) ); + return 0; }
--- a/include/freeDiameter/CMakeLists.txt Mon Sep 28 17:29:25 2009 +0900 +++ b/include/freeDiameter/CMakeLists.txt Wed Sep 30 18:25:46 2009 +0900 @@ -11,6 +11,9 @@ # Disable SCTP support completly ? OPTION(DISABLE_SCTP "Disable SCTP support?") +# Disable SCTP support completly ? +OPTION(ERRORS_ON_TODO "(development) Generate compilation errors on TODO items ?" OFF) + ######################## # System checks
--- a/include/freeDiameter/freeDiameter-host.h.in Mon Sep 28 17:29:25 2009 +0900 +++ b/include/freeDiameter/freeDiameter-host.h.in Wed Sep 30 18:25:46 2009 +0900 @@ -44,7 +44,7 @@ #cmakedefine HOST_BIG_ENDIAN @HOST_BIG_ENDIAN@ #cmakedefine DISABLE_SCTP - +#cmakedefine ERRORS_ON_TODO #cmakedefine DEBUG #cmakedefine FD_PROJECT_BINARY "@FD_PROJECT_BINARY@"
--- a/include/freeDiameter/freeDiameter.h Mon Sep 28 17:29:25 2009 +0900 +++ b/include/freeDiameter/freeDiameter.h Wed Sep 30 18:25:46 2009 +0900 @@ -80,6 +80,15 @@ struct fd_endpoint { struct fd_list chain; /* link in cnf_endpoints list */ sSS ss; /* the socket information. */ + struct { + unsigned conf : 1; /* This endpoint is statically configured in a configuration file */ + unsigned disc : 1; /* This endpoint was resolved from the Diameter Identity or other DNS query */ + unsigned adv : 1; /* This endpoint was advertized in Diameter CER/CEA exchange */ + unsigned ll : 1; /* Lower layer mechanism provided this endpoint */ + + /* To add: a validity timestamp for DNS records ? How do we retrieve this lifetime from DNS ? */ + + } meta; /* Additional information about the endpoint */ }; /* Applications */ @@ -163,11 +172,11 @@ #define STATE_STR(state) \ peer_state_str[ ((unsigned)(state)) <= STATE_REOPEN ? ((unsigned)(state)) : 0 ] -/* Information about a remote peer, used both for query and for creating a new entry */ +/* Information about a remote peer. Same structure is used for creating a new entry, but not all fields are meaningful in that case */ struct peer_info { - char * pi_diamid; /* UTF-8, \0 terminated. The Diameter Identity of the remote peer */ - char * pi_realm; /* idem, its realm. */ + char * pi_diamid; /* UTF-8, \0 terminated. The Diameter Identity of the remote peer */ + char * pi_realm; /* Its realm, as received in CER/CEA exchange. */ struct { #define PI_P3_DEFAULT 0 /* Use the default L3 protocol configured for the host */ @@ -190,7 +199,7 @@ unsigned sec :2; #define PI_EXP_NONE 0 /* the peer entry does not expire */ - #define PI_EXP_INACTIVE 1 /* the peer entry expires after pi_lft seconds without activity */ + #define PI_EXP_INACTIVE 1 /* the peer entry expires (i.e. is deleted) after pi_lft seconds without activity */ unsigned exp :1; /* Following flags are read-only and received from remote peer */ @@ -198,17 +207,35 @@ #define PI_INB_TLS 2 /* Remote peer advertised inband-sec-id 1 (TLS) */ unsigned inband :2; /* This is only meaningful with pi_flags.sec == 3 */ - unsigned relay :1; /* The remote peer advertized the relay application */ - } pi_flags; + unsigned relay :1; /* The remote peer advertized the relay application */ + + } pi_flags; /* Some flags */ /* Additional parameters */ - uint32_t pi_lft; /* lifetime of entry without activity (except watchdogs) (see pi_flags.exp definition) */ + uint32_t pi_lft; /* lifetime of this peer when inactive (see pi_flags.exp definition) */ uint16_t pi_streams; /* number of streams for SCTP. 0 = default */ uint16_t pi_port; /* port to connect to. 0: default. */ int pi_tctimer; /* use this value for TcTimer instead of global, if != 0 */ int pi_twtimer; /* use this value for TwTimer instead of global, if != 0 */ - struct fd_list pi_endpoints; /* Endpoint(s) of the remote peer (discovered or advertized). list of struct fd_endpoint. DNS resolved if empty. */ + struct fd_list pi_endpoints; /* Endpoint(s) of the remote peer (configured, discovered, or advertized). list of struct fd_endpoint. DNS resolved if empty. */ + + /* TLS specific data -- the exact data pointed here depends on the security module in use (ex: gnutls, ...) */ + enum { + PI_SEC_GNUTLS = 0, /* The security module is GNUTLS, this is the default */ + PI_SEC_OTHER /* Another security module (TBD) */ + } pi_sec_module; + union { + /* Security data when pi_sec_module == PI_SEC_GNUTLS */ + struct { + void * CA; /* Authority to use to validate this peer credentials (a CA or root certificate) -- use default if NULL */ + void * cred; /* The (valid) credentials that the peer has presented */ + } gnutls; + /* Security data when pi_sec_module == PI_SEC_OTHER */ + struct { + void * dummy; /* Something meaningful for the other security module */ + } other; + } pi_sec_data; /* The remaining information is read-only, not used for peer creation */ enum peer_state pi_state; @@ -243,9 +270,18 @@ * * 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 + * + * The content of info parameter is copied, except for the list of endpoints if + * not empty, which is simply moved into the created object. It means that the list + * items must have been malloc'd, so that they can be freed. + * + * 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. + * determine which one it is. If the first parameter of the called callback is NULL, it + * means that the peer is being destroyed before attempt success / failure. + * cb is called to allow freeing cb_data in * this case. + * + * The orig_dbg string is only useful for easing debug, and can be left to NULL. * * RETURN VALUE: * 0 : The peer is added.
--- a/include/freeDiameter/libfreeDiameter.h Mon Sep 28 17:29:25 2009 +0900 +++ b/include/freeDiameter/libfreeDiameter.h Wed Sep 30 18:25:46 2009 +0900 @@ -189,6 +189,15 @@ #define TRACE_DEBUG_ALL( str ) \ TRACE_DEBUG(CALL, str ); +/* For development only, to keep track of TODO locations in the code */ +#ifndef ERRORS_ON_TODO +#define TODO( _msg, _args... ) \ + TRACE_DEBUG(NONE, _msg , ##_args); +#else /* ERRORS_ON_TODO */ +#define TODO( _msg, _args... ) \ + "TODO" = _msg ## _args; /* just a stupid compilation error to spot the todo */ +#endif /* ERRORS_ON_TODO */ + /* Macros to check a return value and branch out in case of error. * These macro must be used only when errors are highly improbable, not for expected errors.