Commit 5c6b1578 authored by Sebastien Decugis's avatar Sebastien Decugis
Browse files

Initial commit for 1.1.0:

 * Restructuring:
   * libfreeDiameter:
     - renamed folder & binary into libfdproto
     - renamed libfD.h into fdproto-internal.h
     - removed signals management (replaced by triggers in libfdcore)

   * freeDiameter split into:
     - libfdcore (most contents)
        - renamed fD.h into fdcore-internal.h
	- added core.c for framework init/shutdown.
	- new triggers mechanism in events.c.

     - freeDiameterd (main, command line parsing, signals management)

   * tests:
     - now in top-level directory tests.

 * other changes:
   - fd_dict_new now returns 0 on duplicate identical entries.
   - fixes in dict_legacy_xml
   - fixes in some dictionaries
   - moved FD_DEFAULT_CONF_FILENAME definition to freeDiameter-host.h
parent 71c4a373
......@@ -10,11 +10,11 @@ SET(FD_PROJECT_COPYRIGHT "Copyright (c) 2008-2011, WIDE Project (www.wide.ad.jp)
# Version of the source code
SET(FD_PROJECT_VERSION_MAJOR 1)
SET(FD_PROJECT_VERSION_MINOR 0)
SET(FD_PROJECT_VERSION_REV 4)
SET(FD_PROJECT_VERSION_MINOR 1)
SET(FD_PROJECT_VERSION_REV 0)
# Version of the API with the library
SET(FD_PROJECT_VERSION_API 3)
SET(FD_PROJECT_VERSION_API 4)
# The test framework, using CTest and CDash.
INCLUDE(CTest)
......@@ -30,7 +30,7 @@ SET(DEFAULT_CONF_PATH ${CMAKE_INSTALL_PREFIX}/etc/freeDiameter CACHE PATH "Defau
SET(INSTALL_HEADERS_SUFFIX include/freeDiameter CACHE PATH "Directory where the headers are installed (relative to CMAKE_INSTALL_PREFIX).")
SET(INSTALL_DAEMON_SUFFIX bin CACHE PATH "Directory where the daemon binary is installed (relative to CMAKE_INSTALL_PREFIX).")
SET(INSTALL_LIBRARY_SUFFIX lib CACHE PATH "Directory where the libfreeDiameter library is installed (relative to CMAKE_INSTALL_PREFIX).")
SET(INSTALL_LIBRARY_SUFFIX lib CACHE PATH "Directory where the freeDiameter libraries are installed (relative to CMAKE_INSTALL_PREFIX).")
SET(INSTALL_EXTENSIONS_SUFFIX ${INSTALL_LIBRARY_SUFFIX}/freeDiameter CACHE PATH "Directory where the extensions are installed / searched (relative to CMAKE_INSTALL_PREFIX).")
# All source code should be POSIX 200112L compatible, but some other extensions might be used, so:
......@@ -76,8 +76,15 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/include)
SUBDIRS(include/freeDiameter)
# Location for the source code
SUBDIRS(libfreeDiameter)
SUBDIRS(freeDiameter)
SUBDIRS(libfdproto)
SUBDIRS(libfdcore)
SUBDIRS(freeDiameterd)
# Extensions (there is no use of freeDiameter without any extension)
SUBDIRS(extensions)
# The unary tests directory
IF ( BUILD_TESTING )
SUBDIRS(tests)
ENDIF ( BUILD_TESTING )
......@@ -12,8 +12,8 @@ Homepage: http://www.freediameter.net
Package: freediameter-common
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: The libfreeDiameter library.
This library is required by all freeDiameter components.
Description: The freeDiameter libraries.
This package contains the libraries required by all freeDiameter components.
It may also be useful for other projects which need to
perform operations on Diameter messages.
.
......
usr/lib/libfreeDiameter.so*
usr/lib/libfdproto.so*
usr/lib/libfdcore.so*
......@@ -15,8 +15,8 @@ SET(CMAKE_SWIG_FLAGS -castmode -threads)
# Add the dependencies for re-swig-ing the file
SET(SWIG_MODULE_fDpy_EXTRA_DEPS
${CMAKE_BINARY_DIR}/include/freeDiameter/freeDiameter-host.h
${CMAKE_SOURCE_DIR}/include/freeDiameter/libfreeDiameter.h
${CMAKE_SOURCE_DIR}/include/freeDiameter/freeDiameter.h
${CMAKE_SOURCE_DIR}/include/freeDiameter/libfdcore.h
${CMAKE_SOURCE_DIR}/include/freeDiameter/libfdproto.h
lists.i
dictionary.i
sessions.i
......
......@@ -58,7 +58,7 @@ static void * myinterp (void * arg)
fd_log_threadname ( "fDpy" );
CHECK_FCT_DO(fd_wait_initialization_complete(), goto end);
CHECK_FCT_DO(fd_core_waitstartcomplete(), goto end);
fd_log_debug("\nStarting interactive python interpreter [experimental].\n");
if (!arg)
......
......@@ -158,8 +158,8 @@ int fd_sess_fromsid ( char * STRING, size_t LENGTH, struct session ** OUTPUT, in
Now, create wrappers for (almost) all objects from fD API
*********************************************************/
%include "freeDiameter/freeDiameter-host.h"
%include "freeDiameter/libfreeDiameter.h"
%include "freeDiameter/freeDiameter.h"
%include "freeDiameter/libfdproto.h"
%include "freeDiameter/libfdcore.h"
/* Most of the functions from the API are not directly usable "as is".
See the specific following files and the dbg_interactive.py.sample file
......
......@@ -77,7 +77,7 @@ static void * mn_thr(void * arg)
}
/* Function called on receipt of MONITOR_SIGNAL */
static void got_sig(int signal)
static void got_sig()
{
fd_log_debug("[dbg_monitor] Dumping extra information\n");
CHECK_FCT_DO(fd_event_send(fd_g_config->cnf_main_ev, FDEV_DUMP_DICT, 0, NULL), /* continue */);
......@@ -91,7 +91,7 @@ static int monitor_main(char * conffile)
TRACE_ENTRY("%p", conffile);
/* Catch signal SIGUSR1 */
CHECK_FCT( fd_sig_register(MONITOR_SIGNAL, "dbg_monitor", got_sig));
CHECK_FCT( fd_event_trig_regcb(MONITOR_SIGNAL, "dbg_monitor", got_sig));
CHECK_POSIX( pthread_create( &thr, NULL, mn_thr, NULL ) );
return 0;
......
......@@ -295,7 +295,7 @@ static int deap_entry(char * conffile)
struct dict_cmd_data data = {
268, /* Code */
"Diameter-EAP-Request", /* Name */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_RETRANSMIT | CMD_FLAG_ERROR, /* Fixed flags */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */
};
struct local_rules_definition rules[] =
......
......@@ -932,6 +932,13 @@ static void SAXstartelem (void * ctx, const xmlChar * name, const xmlChar ** att
CHECK_PARAMS_DO(xname,
{ TRACE_DEBUG(INFO, "Invalid 'type' tag found without 'name' attribute."); goto xml_tree_error; } );
/* Check there is only 1 type */
if (!FD_IS_LIST_EMPTY(&data->cur_avp->type)) {
TRACE_DEBUG(INFO, "Multiple 'type' tags found for AVP.");
goto xml_tree_error;
}
/* Add the new type */
CHECK_FCT_DO( new_avptype(&data->cur_avp->type, xname),
{ TRACE_DEBUG(INFO, "An error occurred while parsing a type tag. Entry ignored."); goto xml_tree_error; } )
......@@ -1010,6 +1017,15 @@ xml_tree_error:
TRACE_DEBUG(INFO, "Unexpected XML element found: '%s'. Ignoring...", name);
}
data->error_depth += 1;
if (data->cur_app || data->cur_cmd || data->cur_avp) {
TRACE_DEBUG(INFO, "Error encountered while parsing tag of:");
if (data->cur_app)
fd_log_debug(" Application: '%s'\n", data->cur_app->name);
if (data->cur_cmd)
fd_log_debug(" Command : '%s'\n", data->cur_cmd->name);
if (data->cur_avp)
fd_log_debug(" AVP : '%s'\n", data->cur_avp->name);
}
return;
}
......@@ -1386,7 +1402,8 @@ static int rules_to_fD_onelist(struct dictionary * fD_dict, struct dict_object *
CHECK_FCT(ret);
/* Now create the new rule */
CHECK_FCT( fd_dict_new ( fD_dict, DICT_RULE, &rd, parent, NULL ) );
CHECK_FCT_DO( ret = fd_dict_new ( fD_dict, DICT_RULE, &rd, parent, NULL ),
{ TRACE_DEBUG(INFO, "Error creating rule for sub-AVP '%s'", r->avpname); return ret; } );
if (nb_added)
*nb_added += 1;
}
......@@ -1397,12 +1414,17 @@ static int rules_to_fD_onelist(struct dictionary * fD_dict, struct dict_object *
/* Process lists of rules */
static int rules_to_fD(struct dictionary * fD_dict, struct dict_object * parent, struct fd_list * fixed, struct fd_list * required, struct fd_list * optional, int * nb_added)
{
int ret;
TRACE_ENTRY("%p %p %p %p %p %p", fD_dict, parent, fixed, required, optional, nb_added);
/* Process the rules */
CHECK_FCT( rules_to_fD_onelist(fD_dict, parent, RULE_FIXED_HEAD, fixed, nb_added) );
CHECK_FCT( rules_to_fD_onelist(fD_dict, parent, RULE_REQUIRED, required, nb_added) );
CHECK_FCT( rules_to_fD_onelist(fD_dict, parent, RULE_OPTIONAL, optional, nb_added) );
CHECK_FCT_DO( ret = rules_to_fD_onelist(fD_dict, parent, RULE_FIXED_HEAD, fixed, nb_added),
{ TRACE_DEBUG(INFO, "Error processing FIXED rules"); return ret; } );
CHECK_FCT_DO( ret = rules_to_fD_onelist(fD_dict, parent, RULE_REQUIRED, required, nb_added),
{ TRACE_DEBUG(INFO, "Error processing REQUIRED rules"); return ret; } );
CHECK_FCT_DO( ret = rules_to_fD_onelist(fD_dict, parent, RULE_OPTIONAL, optional, nb_added),
{ TRACE_DEBUG(INFO, "Error processing OPTIONAL rules"); return ret; } );
return 0;
}
......@@ -1424,12 +1446,15 @@ static int avp_to_fD(struct t_avp * a, struct dictionary * fD_dict, struct dict_
ad.avp_code = a->code;
ad.avp_vendor = a->vendor;
ad.avp_name = (char *)a->name;
ad.avp_flag_mask = a->fmask;
ad.avp_flag_mask = a->fmask | AVP_FLAG_VENDOR;
ad.avp_flag_val = a->flags;
if (!FD_IS_LIST_EMPTY(&a->type)) {
/* special exception: we use per-AVP enumerated types in fD */
if (strcasecmp("Enumerated", (char *)((struct t_avptype *)a->type.next)->type_name))
if (!strcasecmp("Enumerated", (char *)((struct t_avptype *)a->type.next)->type_name))
goto enumerated;
/* Let's allow "Unsigned32" instead of "Enumerated" also... */
if ((!FD_IS_LIST_EMPTY(&a->enums)) && (!strcasecmp("Unsigned32", (char *)((struct t_avptype *)a->type.next)->type_name)))
goto enumerated;
/* The type was explicitly specified, resolve it */
......@@ -1440,12 +1465,13 @@ static int avp_to_fD(struct t_avp * a, struct dictionary * fD_dict, struct dict_
|| !FD_IS_LIST_EMPTY(&a->grouped_required)
|| !FD_IS_LIST_EMPTY(&a->grouped_fixed) ) {
/* The AVP has rules, it is a grouped AVP */
CHECK_PARAMS( FD_IS_LIST_EMPTY(&a->enums) );
CHECK_PARAMS_DO( FD_IS_LIST_EMPTY(&a->enums),
{ TRACE_DEBUG(INFO, "Conflict: The AVP '%s' has both enum values and rules.", ad.avp_name); return EINVAL; } );
ad.avp_basetype = AVP_TYPE_GROUPED;
} else {
/* It should be an enumerated AVP... */
if (FD_IS_LIST_EMPTY(&a->enums)) {
TRACE_DEBUG(INFO, "[dict_legacy_xml] Error: Missing type information for AVP '%s'", ad.avp_name);
TRACE_DEBUG(INFO, "Error: Missing type information for AVP '%s'", ad.avp_name);
return EINVAL;
} else {
/* We create a new type to hold the enumerated values -- fD specifics */
......@@ -1491,8 +1517,12 @@ enumerated:
inside:
/* Now, the inner elements, if any */
if ( (!FD_IS_LIST_EMPTY(&a->enums)) && (ad.avp_basetype != AVP_TYPE_UNSIGNED32)) {
TRACE_DEBUG(INFO, "AVP '%s' type is not an Unsigned32 but it has enum values (invalid in this extension).", ad.avp_name);
return EINVAL;
}
/* In case of enumeration, define the enum values */
ASSERT( FD_IS_LIST_EMPTY(&a->enums) || (type && (ad.avp_basetype == AVP_TYPE_UNSIGNED32)) ); /* u32 type must be defined for enumerators */
for (li = a->enums.next; li != &a->enums; li = li->next) {
struct t_enum * e = (struct t_enum *)li;
struct dict_enumval_data ed;
......@@ -1501,7 +1531,11 @@ inside:
ed.enum_name = (char *)e->name;
ed.enum_value.u32 = e->code;
CHECK_FCT( fd_dict_new ( fD_dict, DICT_ENUMVAL, &ed, type, NULL ) );
CHECK_FCT_DO( ret = fd_dict_new ( fD_dict, DICT_ENUMVAL, &ed, type, NULL ),
{
TRACE_DEBUG(INFO, "Error defining constant value '%s' for AVP '%s': %s", ed.enum_name, ad.avp_name, strerror(ret));
return ret;
} );
if (nb_added)
*nb_added += 1;
}
......@@ -1510,8 +1544,10 @@ inside:
if ( !FD_IS_LIST_EMPTY(&a->grouped_optional)
|| !FD_IS_LIST_EMPTY(&a->grouped_required)
|| !FD_IS_LIST_EMPTY(&a->grouped_fixed) ) {
CHECK_PARAMS( ad.avp_basetype == AVP_TYPE_GROUPED );
CHECK_FCT( rules_to_fD(fD_dict, prev, &a->grouped_fixed, &a->grouped_required, &a->grouped_optional, nb_added) );
CHECK_PARAMS_DO( ad.avp_basetype == AVP_TYPE_GROUPED,
{ TRACE_DEBUG(INFO, "Got rules for non-grouped AVP '%s'", ad.avp_name); return EINVAL;} );
CHECK_FCT_DO( ret = rules_to_fD(fD_dict, prev, &a->grouped_fixed, &a->grouped_required, &a->grouped_optional, nb_added),
{ TRACE_DEBUG(INFO, "Error processing rules for AVP '%s': %s", ad.avp_name, strerror(ret)); return ret; } );
}
/* done! */
......@@ -1535,7 +1571,7 @@ static int cmd_to_fD(struct t_cmd * c, struct dictionary * fD_dict, struct dict_
cd.cmd_code = c->code;
snprintf(cmdname, sizeof(cmdname), "%s-Request", (char *)c->name);
cd.cmd_name = &cmdname[0];
cd.cmd_flag_mask = c->fmask | CMD_FLAG_REQUEST;
cd.cmd_flag_mask = c->fmask | CMD_FLAG_REQUEST | CMD_FLAG_ERROR;
cd.cmd_flag_val = c->flags | CMD_FLAG_REQUEST;
/* Create or search in the dictionary */
......@@ -1563,6 +1599,7 @@ answer:
/* update data for the answer */
snprintf(cmdname, sizeof(cmdname), "%s-Answer", (char *)c->name);
cd.cmd_flag_val &= ~CMD_FLAG_REQUEST;
cd.cmd_flag_mask &= ~CMD_FLAG_ERROR;
ret = fd_dict_new ( fD_dict, DICT_COMMAND, &cd, fd_appl, &ans );
if (ret == EEXIST) {
......@@ -1584,8 +1621,16 @@ answer:
rules:
/* Now process the rules inside the command */
CHECK_FCT( rules_to_fD(fD_dict, req, &c->reqrules_fixed, &c->reqrules_required, &c->reqrules_optional, nb_added) );
CHECK_FCT( rules_to_fD(fD_dict, ans, &c->ansrules_fixed, &c->ansrules_required, &c->ansrules_optional, nb_added) );
CHECK_FCT_DO( ret = rules_to_fD(fD_dict, req, &c->reqrules_fixed, &c->reqrules_required, &c->reqrules_optional, nb_added),
{
TRACE_DEBUG(INFO, "Error converting data from request rules: %s", strerror(ret));
return ret;
} );
CHECK_FCT_DO( ret = rules_to_fD(fD_dict, ans, &c->ansrules_fixed, &c->ansrules_required, &c->ansrules_optional, nb_added),
{
TRACE_DEBUG(INFO, "Error converting data from answer rules: %s", strerror(ret));
return ret;
} );
/* Done */
return 0;
......@@ -1640,17 +1685,29 @@ inside:
/* First, define all the types */
for (li = a->types.next; li != &a->types; li = li->next) {
CHECK_FCT( typdefn_to_fD((struct t_typedefn *)li, fD_dict, prev, NULL, nb_added) );
CHECK_FCT_DO( ret = typdefn_to_fD((struct t_typedefn *)li, fD_dict, prev, NULL, nb_added),
{
TRACE_DEBUG(INFO, "Error converting data from typedefn '%s': %s", ((struct t_typedefn *)li)->name, strerror(ret));
return ret;
} );
}
/* Then, AVPs, enums, and grouped AVP rules */
for (li = a->avps.next; li != &a->avps; li = li->next) {
CHECK_FCT( avp_to_fD((struct t_avp *)li, fD_dict, prev, NULL, nb_added) );
CHECK_FCT_DO( ret = avp_to_fD((struct t_avp *)li, fD_dict, prev, NULL, nb_added),
{
TRACE_DEBUG(INFO, "Error converting data from AVP '%s': %s", ((struct t_avp *)li)->name, strerror(ret));
return ret;
} );
}
/* Finally, the commands and rules */
for (li = a->commands.next; li != &a->commands; li = li->next) {
CHECK_FCT( cmd_to_fD((struct t_cmd *)li, fD_dict, prev, NULL, nb_added) );
CHECK_FCT_DO( ret = cmd_to_fD((struct t_cmd *)li, fD_dict, prev, NULL, nb_added),
{
TRACE_DEBUG(INFO, "Error converting data from command '%s': %s", ((struct t_cmd *)li)->name, strerror(ret));
return ret;
} );
}
/* done! */
......@@ -1661,6 +1718,7 @@ inside:
static int dict_to_fD(struct dictionary * fD_dict, struct t_dictionary * xmldict, int * nb_added)
{
struct fd_list * li;
int ret;
TRACE_ENTRY("%p %p %p", fD_dict, xmldict, nb_added);
......@@ -1670,13 +1728,25 @@ static int dict_to_fD(struct dictionary * fD_dict, struct t_dictionary * xmldict
/* Create all the vendors */
for (li = xmldict->vendors.next; li != &xmldict->vendors; li = li->next) {
CHECK_FCT( vend_to_fD((struct t_vend *)li, fD_dict, NULL, nb_added) );
CHECK_FCT_DO( ret = vend_to_fD((struct t_vend *)li, fD_dict, NULL, nb_added),
{
TRACE_DEBUG(INFO, "Error converting data from vendor '%s': %s", ((struct t_vend *)li)->name, strerror(ret));
return ret;
} );
}
/* Now, process each application */
CHECK_FCT( appl_to_fD(&xmldict->base_and_applications, fD_dict, NULL, nb_added) );
CHECK_FCT_DO( ret = appl_to_fD(&xmldict->base_and_applications, fD_dict, NULL, nb_added),
{
TRACE_DEBUG(INFO, "Error converting data from Base application: %s", strerror(ret));
return ret;
} );
for (li = xmldict->base_and_applications.chain.next; li != &xmldict->base_and_applications.chain; li = li->next) {
CHECK_FCT( appl_to_fD((struct t_appl *) li, fD_dict, NULL, nb_added) );
CHECK_FCT_DO( ret = appl_to_fD((struct t_appl *) li, fD_dict, NULL, nb_added),
{
TRACE_DEBUG(INFO, "Error converting data from application '%s': %s", ((struct t_appl *)li)->name, strerror(ret));
return ret;
} );
}
/* Complete! */
......@@ -1724,15 +1794,20 @@ int dict_lxml_parse(char * xmlfilename)
return -1;
}
TRACE_DEBUG(FULL, "XML file parsing complete.");
TRACE_DEBUG(FULL, "XML file parsing, 1st pass completed.");
if (TRACE_BOOL(ANNOYING)) {
dump_dict(&data.dict);
}
/* Now, convert all the objects from the temporary tree into the freeDiameter dictionary */
CHECK_FCT_DO( dict_to_fD(fd_g_config->cnf_dict, &data.dict, &ret), { del_dict_contents(&data.dict); return -1; } );
TRACE_DEBUG(FULL, "Conversion to freeDiameter internal format complete.");
CHECK_FCT_DO( dict_to_fD(fd_g_config->cnf_dict, &data.dict, &ret),
{
TRACE_DEBUG(INFO, "Error while converting data read from file '%s'", xmlfilename);
del_dict_contents(&data.dict);
return -1;
} );
TRACE_DEBUG(FULL, "Conversion from '%s' to freeDiameter internal format complete.", xmlfilename);
if (TRACE_BOOL(ANNOYING)) {
fd_dict_dump(fd_g_config->cnf_dict);
}
......
......@@ -3004,7 +3004,7 @@ static int dnr_entry(char * conffile)
struct dict_cmd_data data = {
265, /* Code */
"AA-Request", /* Name */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_RETRANSMIT | CMD_FLAG_ERROR, /* Fixed flags */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE | CMD_FLAG_ERROR, /* Fixed flags */
CMD_FLAG_REQUEST | CMD_FLAG_PROXIABLE /* Fixed flag values */
};
struct local_rules_definition rules[] =
......
......@@ -207,7 +207,7 @@ out:
}
/* The function called when the signal is received */
static void ta_bench_start(int sig) {
static void ta_bench_start() {
struct timespec end_time, now;
struct ta_stats start, end;
......@@ -273,14 +273,14 @@ int ta_bench_init(void)
{
CHECK_SYS( sem_init( &ta_sem, 0, ta_conf->bench_concur) );
CHECK_FCT( fd_sig_register(ta_conf->signal, "test_app.bench", ta_bench_start ) );
CHECK_FCT( fd_event_trig_regcb(ta_conf->signal, "test_app.bench", ta_bench_start ) );
return 0;
}
void ta_bench_fini(void)
{
CHECK_FCT_DO( fd_sig_unregister(ta_conf->signal), /* continue */ );
// CHECK_FCT_DO( fd_sig_unregister(ta_conf->signal), /* continue */ );
CHECK_SYS_DO( sem_destroy(&ta_sem), );
......
......@@ -135,7 +135,7 @@ static void ta_cb_ans(void * data, struct msg ** msg)
}
/* Create a test message */
static void ta_cli_test_message(int sig)
static void ta_cli_test_message()
{
struct msg * req = NULL;
struct avp * avp;
......@@ -235,14 +235,14 @@ int ta_cli_init(void)
{
CHECK_FCT( fd_sess_handler_create(&ta_cli_reg, free, NULL) );
CHECK_FCT( fd_sig_register(ta_conf->signal, "test_app.cli", ta_cli_test_message ) );
CHECK_FCT( fd_event_trig_regcb(ta_conf->signal, "test_app.cli", ta_cli_test_message ) );
return 0;
}
void ta_cli_fini(void)
{
CHECK_FCT_DO( fd_sig_unregister(ta_conf->signal), /* continue */ );
// CHECK_FCT_DO( fd_sig_unregister(ta_conf->signal), /* continue */ );
CHECK_FCT_DO( fd_sess_handler_destroy(&ta_cli_reg, NULL), /* continue */ );
......
......@@ -214,9 +214,9 @@ int ts_entry(char * conffile)
*/
CHECK_FCT(fd_sess_handler_create(&ts_sess_hdl, free, NULL));
//CHECK_FCT( fd_sig_register(30, "test_sip", (void *)test_sipSL_LIR_cb ) );
CHECK_FCT( fd_sig_register(30, "test_sip", (void *)test_sip_SAR_cb ) );
CHECK_FCT( fd_sig_register(31, "test_sip", (void *)test_sip_LIR_cb ) );
//CHECK_FCT( fd_event_trig_regcb(30, "test_sip", (void *)test_sipSL_LIR_cb ) );
CHECK_FCT( fd_event_trig_regcb(30, "test_sip", (void *)test_sip_SAR_cb ) );
CHECK_FCT( fd_event_trig_regcb(31, "test_sip", (void *)test_sip_LIR_cb ) );
return 0;
}
......
# The subproject name
Project("freeDiameter simple daemon" C)
# Build the executable
ADD_EXECUTABLE(freeDiameterd main.c)
# The version
SET_TARGET_PROPERTIES(freeDiameterd PROPERTIES
VERSION ${FD_PROJECT_VERSION_MAJOR}.${FD_PROJECT_VERSION_MINOR}.${FD_PROJECT_VERSION_REV})
# The link command
TARGET_LINK_LIBRARIES(freeDiameterd libfdproto libfdcore)
####
## INSTALL section ##
INSTALL(TARGETS freeDiameterd
RUNTIME DESTINATION ${INSTALL_DAEMON_SUFFIX}
COMPONENT freeDiameter-daemon)
......@@ -33,157 +33,128 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
*********************************************************************************************************/
#include "fD.h"
#include <freeDiameter/freeDiameter-host.h>
#include <freeDiameter/libfdcore.h>
#include <signal.h>
#include <getopt.h>
#include <locale.h>
#include <gcrypt.h>
/* forward declarations */
static void fd_shutdown(int signal);
static int main_cmdline(int argc, char *argv[]);
static void main_version(void);
static void main_help( void );
static int signal_framework_ready(void);
static void * catch_signals(void * arg);
static pthread_t signals_thr;
static char *conffile = NULL;
static int gnutls_debug = 0;
/* The static configuration structure */
static struct fd_config conf;
struct fd_config * fd_g_config = &conf;
/* gnutls debug */
static void fd_gnutls_debug(int level, const char * str) {
fd_log_debug(" [gnutls:%d] %s", level, str);
}
/* gcrypt functions to support posix threads */
GCRY_THREAD_OPTION_PTHREAD_IMPL;
/* freeDiameter starting point */
int main(int argc, char * argv[])
{
int ret;
sigset_t sig_all;
memset(fd_g_config, 0, sizeof(struct fd_config));
/* Initialize the library -- must come first since it initializes the debug facility */
CHECK_FCT( fd_lib_init(1) );
TRACE_DEBUG(INFO, "libfreeDiameter initialized.");
/* Name this thread */
fd_log_threadname("Main");
/* Block all signals from the current thread and all its future children */
sigfillset(&sig_all);
ret = pthread_sigmask(SIG_BLOCK, &sig_all, NULL);
ASSERT(ret == 0);
/* Initialize gcrypt and gnutls */
GNUTLS_TRACE( (void) gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread) );
GNUTLS_TRACE( (void) gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0) );
CHECK_GNUTLS_DO( gnutls_global_init(), return EINVAL );
if ( ! gnutls_check_version(GNUTLS_VERSION) ) {
fprintf(stderr, "The GNUTLS library is too old; found '%s', need '" GNUTLS_VERSION "'\n", gnutls_check_version(NULL));
return EINVAL;
} else {
TRACE_DEBUG(INFO, "libgnutls '%s', libgcrypt '%s', initialized.", gnutls_check_version(NULL), gcry_check_version(NULL) );
/* Parse the command-line */
ret = main_cmdline(argc, argv);
if (ret != 0) {
return ret;
}
/* Initialize the config */
CHECK_FCT( fd_conf_init() );
/* Parse the command-line */
CHECK_FCT( main_cmdline(argc, argv) );
/* Initialize the core library */
ret = fd_core_initialize();
if (ret != 0) {
fprintf(stderr, "An error occurred during freeDiameter core library initialization.\n");
return ret;
}
/* Set gnutls debug level ? */
if (gnutls_debug) {
gnutls_global_set_log_function((gnutls_log_func)fd_gnutls_debug);
gnutls_global_set_log_level (gnutls_debug);
TRACE_DEBUG(INFO, "Enabled GNUTLS debug at level %d", gnutls_debug);
}
/* Allow SIGINT and SIGTERM from this point to terminate the application */
CHECK_FCT( fd_sig_register(SIGINT, "freeDiameter.main", fd_shutdown) );
CHECK_FCT( fd_sig_register(SIGTERM, "freeDiameter.main", fd_shutdown) );
/* Add definitions of the base protocol */
CHECK_FCT( fd_dict_base_protocol(fd_g_config->cnf_dict) );
/* Initialize other modules */
CHECK_FCT( fd_queues_init() );
CHECK_FCT( fd_msg_init() );
CHECK_FCT( fd_sess_start() );
CHECK_FCT( fd_p_expi_init() );
CHECK_POSIX( pthread_create(&signals_thr, NULL, catch_signals, NULL) );
/* Parse the configuration file */
CHECK_FCT( fd_conf_parse() );
/* Create the daemon's threads */
CHECK_FCT( fd_rtdisp_init() );
/* Load the dynamic extensions */
CHECK_FCT( fd_ext_load() );
fd_conf_dump();
fd_sig_dump(FULL, 1);
CHECK_FCT( fd_core_parseconf(conffile) );
/* Start the servers */
CHECK_FCT( fd_servers_start() );
/* Start the peer state machines */