move the directory

This commit is contained in:
Sukchan Lee 2017-02-24 10:50:49 +09:00
parent c3d1807057
commit 1c15591aa8
16 changed files with 5560 additions and 9 deletions

View File

@ -256,9 +256,9 @@ AC_CONFIG_FILES([lib/logger/Makefile])
AC_CONFIG_FILES([lib/message/s1ap/asn1c/Makefile])
AC_CONFIG_FILES([lib/message/s1ap/Makefile])
AC_CONFIG_FILES([lib/message/nas/Makefile])
AC_CONFIG_FILES([lib/message/s6a/freeDiameter/Makefile])
AC_CONFIG_FILES([lib/message/s6a/Makefile])
AC_CONFIG_FILES([lib/message/Makefile])
AC_CONFIG_FILES([lib/s6a/freeDiameter/Makefile])
AC_CONFIG_FILES([lib/s6a/Makefile])
AC_CONFIG_FILES([lib/Makefile])
AC_CONFIG_FILES([src/Makefile])
AC_CONFIG_FILES([test/Makefile])

View File

@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = core logger message
SUBDIRS = core logger message s6a
MAINTAINERCLEANFILES = Makefile.in
MOSTLYCLEANFILES = *.stackdump

View File

@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = s1ap nas s6a
SUBDIRS = s1ap nas
MAINTAINERCLEANFILES = Makefile.in
MOSTLYCLEANFILES = *.stackdump

28
lib/s6a/Makefile.am Normal file
View File

@ -0,0 +1,28 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = freeDiameter
noinst_LTLIBRARIES = libs6a.la
libs6a_la_SOURCES = \
s6a_app.h
nodist_libs6a_la_SOURCES = \
s6a_app.c s6a_dict.c s6a_server.c s6a_client.c
libs6a_la_DEPENDENCIES = \
$(top_srcdir)/lib/s6a/freeDiameter/libs6afreeDiameter.la
libs6a_la_LIBADD = \
$(top_srcdir)/lib/s6a/freeDiameter/libs6afreeDiameter.la
AM_CPPFLAGS = \
-I$(top_srcdir)/lib/core/include
AM_CFLAGS = \
-Wall -Werror -Wno-unused
MAINTAINERCLEANFILES = Makefile.in
MOSTLYCLEANFILES = *.stackdump
EXTRA_DIST = .libs $(noinst_LTLIBRARIES)

View File

@ -0,0 +1,20 @@
## Process this file with automake to produce Makefile.in
noinst_LTLIBRARIES = libs6afreeDiameter.la
libs6afreeDiameter_la_SOURCES = \
extension.h
nodist_libs6afreeDiameter_la_SOURCES = \
dict_nas_mipv6.c dict_s6a.c
AM_CPPFLAGS = \
-I$(top_srcdir)/lib/s6a
AM_CFLAGS = \
-Wall -Werror
MAINTAINERCLEANFILES = Makefile.in
MOSTLYCLEANFILES = *.stackdump
EXTRA_DIST = .libs $(noinst_LTLIBRARIES)

View File

@ -0,0 +1,258 @@
/*********************************************************************************************************
* Software License Agreement (BSD License) *
* Author: Francois Bard <francois@tera.ics.keio.ac.jp> *
* *
* Copyright (c) 2010, Teraoka Laboratory, Keio University *
* 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 Teraoka Laboratory nor the *
* names of its contributors may be used to endorse or *
* promote products derived from this software without *
* specific prior written permission of Teraoka Laboratory *
* *
* *
* 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. *
*********************************************************************************************************/
/*
The following table lists the AVPs needed for the NAS to HAAA server interaction.
We try to keep the structure of the grouped AVP by declaring the contained AVPs just before the grouped AVP they depend on.
The number of '+' indicates the depth of the contained AVP.
DEPTH NAME AVP CODE RFC TYPE IMPLEMENTED NOTES
MIP6-Feature-Vector 124 5447 Unsigned64 yes
+ MIP-Home-Agent-Address 334 4004 Address not yet
++ Destination-Host 293 3588 DiameterIdentity no (Base)
++ Destination-Realm 283 3588 DiameterIdentity no (Base)
+ MIP-Home-Agent-Host 348 4004 Grouped not yet
+ MIP6-Home-Link-Prefix 125 5447 OctetString yes
MIP6-Agent-Info 486 5447 Grouped yes
*/
#include <freeDiameter/extension.h>
/* The content of this file follows the same structure as dict_base_proto.c */
#define CHECK_dict_new( _type, _data, _parent, _ref ) \
CHECK_FCT( fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref)) );
#define CHECK_dict_search( _type, _criteria, _what, _result ) \
CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) );
struct local_rules_definition {
char *avp_name;
enum rule_position position;
int min;
int max;
};
#define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 )
#define PARSE_loc_rules( _rulearray, _parent) { \
int __ar; \
for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \
struct dict_rule_data __data = { NULL, \
(_rulearray)[__ar].position, \
0, \
(_rulearray)[__ar].min, \
(_rulearray)[__ar].max}; \
__data.rule_order = RULE_ORDER(__data.rule_position); \
CHECK_FCT( fd_dict_search( \
fd_g_config->cnf_dict, \
DICT_AVP, \
AVP_BY_NAME, \
(_rulearray)[__ar].avp_name, \
&__data.rule_avp, 0 ) ); \
if ( !__data.rule_avp ) { \
TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_name ); \
return ENOENT; \
} \
CHECK_FCT_DO( fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &__data, _parent, NULL), \
{ \
TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \
(_rulearray)[__ar].avp_name ); \
return EINVAL; \
} ); \
} \
}
#define enumval_def_u32( _val_, _str_ ) \
{ _str_, { .u32 = _val_ }}
#define enumval_def_os( _len_, _val_, _str_ ) \
{ _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}}
/* Defines if there are any */
/* Define Flags for MIP6-Feature-Vector*/
#define MIP6_INTEGRATED 0x0000000000000001
#define LOCAL_HOME_AGENT_ASSIGNMENT 0x0000000000000002
/* Dictionary */
int dict_nas_mipv6_init(char * conffile)
{
struct dict_object * nas_mipv6;
{
struct dict_application_data data = { 5447, "MIPv6 NAS-to-HAAA Interaction" };
CHECK_dict_new( DICT_APPLICATION, &data , NULL, &nas_mipv6);
}
/* AVP section */
{
/* Loading the derived data formats */
struct dict_object * Address_type;
CHECK_dict_search( DICT_TYPE, TYPE_BY_NAME, "Address", &Address_type);
/* MIP6-Feature-Vector */
{
/*
*/
struct dict_avp_data data = {
124, /* Code */
0, /* Vendor */
"MIP6-Feature-Vector", /* Name */
AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
AVP_FLAG_MANDATORY, /* Fixed flag values */
AVP_TYPE_UNSIGNED64 /* base type of data */
};
CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
}
/* MIP-Home-Agent-Address - RFC 4004 */
{
/*
*/
struct dict_avp_data data = {
334, /* Code */
0, /* Vendor */
"MIP-Home-Agent-Address", /* Name */
AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
AVP_FLAG_MANDATORY, /* Fixed flag values */
AVP_TYPE_OCTETSTRING /* base type of data */
};
CHECK_dict_new( DICT_AVP, &data , Address_type, NULL);
}
/* Destination-Host - Base Protocol */
/* Destination-Realm - Base Protocol */
/* MIP-Home-Agent-Host - RFC 4004 */
{
/*
The MIP-Home-Agent-Host AVP (AVP Code 348) is of type Grouped and
contains the identity of the assigned Home Agent. If the MIP-Home-
Agent-Host AVP is present in the AMR, the AAAH MUST copy it into the
HAR.
MIP-Home-Agent-Host ::= < AVP Header: 348 >
{ Destination-Realm }
{ Destination-Host }
* [ AVP ]
*/
struct dict_object * avp;
struct dict_avp_data data = {
348, /* Code */
0, /* Vendor */
"MIP-Home-Agent-Host", /* Name */
AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
AVP_FLAG_MANDATORY, /* Fixed flag values */
AVP_TYPE_GROUPED /* base type of data */
};
struct local_rules_definition rules[] =
{ { "Destination-Realm", RULE_REQUIRED, -1, 1 }
,{ "Destination-Host", RULE_REQUIRED, -1, 1 }
};
CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
PARSE_loc_rules( rules, avp );
}
/* MIP6-Home-Link-Prefix */
{
/*
*/
struct dict_avp_data data = {
125, /* Code */
0, /* Vendor */
"MIP6-Home-Link-Prefix", /* Name */
AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
AVP_FLAG_MANDATORY, /* Fixed flag values */
AVP_TYPE_OCTETSTRING /* base type of data */
};
CHECK_dict_new( DICT_AVP, &data , NULL, NULL);
}
/* MIP6-Agent-Info */
{
/*
*/
struct dict_object * avp;
struct dict_avp_data data = {
486, /* Code */
0, /* Vendor */
"MIP6-Agent-Info", /* Name */
AVP_FLAG_VENDOR | AVP_FLAG_MANDATORY, /* Fixed flags */
AVP_FLAG_MANDATORY, /* Fixed flag values */
AVP_TYPE_GROUPED /* base type of data */
};
struct local_rules_definition rules[] =
{ { "MIP-Home-Agent-Address", RULE_OPTIONAL, -1, 2 }
,{ "MIP-Home-Agent-Host", RULE_OPTIONAL, -1, 1 }
,{ "MIP6-Home-Link-Prefix", RULE_OPTIONAL, -1, 1 }
};
CHECK_dict_new( DICT_AVP, &data , NULL, &avp);
PARSE_loc_rules( rules, avp );
}
}
LOG_D( "Dictionary Extension 'MIPv6 NAS-to-HAAA Interaction' initialized");
return 0;
}
EXTENSION_ENTRY("dict_nas_mipv6", dict_nas_mipv6_init);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,72 @@
/*********************************************************************************************************
* Software License Agreement (BSD License) *
* Author: Sebastien Decugis <sdecugis@freediameter.net> *
* *
* Copyright (c) 2013, 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. *
*********************************************************************************************************/
#ifndef _EXTENSION_H
#define _EXTENSION_H
#ifdef __cplusplus
extern "C" {
#endif
/* Include definition of freeDiameter API */
#include <freeDiameter/freeDiameter-host.h>
#include <freeDiameter/libfdcore.h>
/* Macro that define the entry point of the extension */
#define EXTENSION_ENTRY(_name, _function, _depends...) \
const char *fd_ext_depends_ ## _function[] = { _name , ## _depends , NULL }; \
static int extension_loaded_ ## _function = 0; \
int fd_ext_ ## _function(int major, int minor, char * conffile) { \
if ((major != FD_PROJECT_VERSION_MAJOR) \
|| (minor != FD_PROJECT_VERSION_MINOR)) { \
TRACE_ERROR("This extension (" _name ") was compiled for a different version of freeDiameter."); \
TRACE_DEBUG(INFO, "daemon %d.%d != ext %d.%d", \
major, minor, \
FD_PROJECT_VERSION_MAJOR, FD_PROJECT_VERSION_MINOR); \
return EINVAL; \
} \
if (extension_loaded_ ## _function) { \
TRACE_ERROR("Extension (" _name ") cannot be loaded twice!"); \
return ENOTSUP; \
} \
extension_loaded_ ## _function++; \
return (_function)(conffile); \
}
#ifdef __cplusplus
}
#endif
#endif /* _EXTENSION_H */

223
lib/s6a/s6a_app.c Normal file
View File

@ -0,0 +1,223 @@
/*********************************************************************************************************
* Software License Agreement (BSD License) *
* Author: Sebastien Decugis <sdecugis@freediameter.net> *
* *
* Copyright (c) 2013, 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. *
*********************************************************************************************************/
/*
* Test application for freeDiameter.
*/
#include "s6a_app.h"
/* Initialize the configuration */
struct ta_conf * ta_conf = NULL;
static struct ta_conf _conf;
static pthread_t ta_stats_th = (pthread_t)NULL;
static int ta_conf_init(void)
{
ta_conf = &_conf;
memset(ta_conf, 0, sizeof(struct ta_conf));
/* Set the default values */
ta_conf->vendor_id = 999999; /* Dummy value */
ta_conf->appli_id = 0xffffff; /* dummy value */
ta_conf->cmd_id = 0xfffffe; /* Experimental */
ta_conf->avp_id = 0xffffff; /* dummy value */
ta_conf->long_avp_len = 5000;
ta_conf->mode = MODE_SERV | MODE_CLI;
ta_conf->dest_realm = strdup(fd_g_config->cnf_diamrlm);
ta_conf->dest_host = NULL;
ta_conf->signal = TEST_APP_DEFAULT_SIGNAL;
ta_conf->bench_concur = 100;
ta_conf->bench_duration = 10;
/* Initialize the mutex */
CHECK_POSIX( pthread_mutex_init(&ta_conf->stats_lock, NULL) );
return 0;
}
static void ta_conf_dump(void)
{
if (!TRACE_BOOL(INFO))
return;
fd_log_debug( "------- app_test configuration dump: ---------");
fd_log_debug( " Vendor Id .......... : %u", ta_conf->vendor_id);
fd_log_debug( " Application Id ..... : %u", ta_conf->appli_id);
fd_log_debug( " Command Id ......... : %u", ta_conf->cmd_id);
fd_log_debug( " AVP Id ............. : %u", ta_conf->avp_id);
fd_log_debug( " Long AVP Id ........ : %u", ta_conf->long_avp_id);
fd_log_debug( " Long AVP len ....... : %zu", ta_conf->long_avp_len);
fd_log_debug( " Mode ............... : %s%s%s", ta_conf->mode & MODE_SERV ? "Serv" : "", ta_conf->mode & MODE_CLI ? "Cli" : "", ta_conf->mode & MODE_BENCH ? " (Benchmark)" : "");
fd_log_debug( " Destination Realm .. : %s", ta_conf->dest_realm ?: "- none -");
fd_log_debug( " Destination Host ... : %s", ta_conf->dest_host ?: "- none -");
fd_log_debug( " Signal ............. : %i", ta_conf->signal);
fd_log_debug( "------- /app_test configuration dump ---------");
}
/* Function to display statistics periodically */
static void * ta_stats(void * arg) {
struct timespec start, now;
struct ta_stats copy;
/* Get the start time */
CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &start), );
/* Now, loop until canceled */
while (1) {
/* Display statistics every XX seconds */
sleep(ta_conf->bench_duration + 3);
/* Now, get the current stats */
CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), );
memcpy(&copy, &ta_conf->stats, sizeof(struct ta_stats));
CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), );
/* Get the current execution time */
CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &now), );
/* Now, display everything */
fd_log_debug( "------- app_test statistics ---------");
if (now.tv_nsec >= start.tv_nsec) {
fd_log_debug( " Executing for: %d.%06ld sec",
(int)(now.tv_sec - start.tv_sec),
(long)(now.tv_nsec - start.tv_nsec) / 1000);
} else {
fd_log_debug( " Executing for: %d.%06ld sec",
(int)(now.tv_sec - 1 - start.tv_sec),
(long)(now.tv_nsec + 1000000000 - start.tv_nsec) / 1000);
}
if (ta_conf->mode & MODE_SERV) {
fd_log_debug( " Server: %llu message(s) echoed", copy.nb_echoed);
}
if (ta_conf->mode & MODE_CLI) {
fd_log_debug( " Client:");
fd_log_debug( " %llu message(s) sent", copy.nb_sent);
fd_log_debug( " %llu error(s) received", copy.nb_errs);
fd_log_debug( " %llu answer(s) received", copy.nb_recv);
fd_log_debug( " fastest: %ld.%06ld sec.", copy.shortest / 1000000, copy.shortest % 1000000);
fd_log_debug( " slowest: %ld.%06ld sec.", copy.longest / 1000000, copy.longest % 1000000);
fd_log_debug( " Average: %ld.%06ld sec.", copy.avg / 1000000, copy.avg % 1000000);
}
fd_log_debug( "-------------------------------------");
}
return NULL; /* never called */
}
static struct fd_hook_hdl * hookhdl[2] = { NULL, NULL };
static void ta_hook_cb_silent(enum fd_hook_type type, struct msg * msg, struct peer_hdr * peer, void * other, struct fd_hook_permsgdata *pmd, void * regdata) {
}
static void ta_hook_cb_oneline(enum fd_hook_type type, struct msg * msg, struct peer_hdr * peer, void * other, struct fd_hook_permsgdata *pmd, void * regdata) {
char * buf = NULL;
size_t len;
CHECK_MALLOC_DO( fd_msg_dump_summary(&buf, &len, NULL, msg, NULL, 0, 0),
{ LOG_E("Error while dumping a message"); return; } );
LOG_N("{%d} %s: %s", type, (char *)other ?:"<nil>", buf ?:"<nil>");
free(buf);
}
/* entry point */
static int ta_entry(char * conffile)
{
TRACE_ENTRY("%p", conffile);
/* Initialize configuration */
CHECK_FCT( ta_conf_init() );
/* Parse configuration file */
if (conffile != NULL) {
CHECK_FCT( ta_conf_handle(conffile) );
}
TRACE_DEBUG(INFO, "Extension Test_App initialized with configuration: '%s'", conffile);
ta_conf_dump();
/* Install objects definitions for this test application */
CHECK_FCT( ta_dict_init() );
/* Install the handlers for incoming messages */
if (ta_conf->mode & MODE_SERV) {
CHECK_FCT( ta_serv_init() );
}
/* Start the signal handler thread */
if (ta_conf->mode & MODE_CLI) {
if (ta_conf->mode & MODE_BENCH) {
CHECK_FCT( ta_bench_init() );
} else {
CHECK_FCT( ta_cli_init() );
}
}
/* Advertise the support for the test application in the peer */
CHECK_FCT( fd_disp_app_support ( ta_appli, ta_vendor, 1, 0 ) );
if (ta_conf->mode & MODE_BENCH) {
/* Register an empty hook to disable the default handling */
CHECK_FCT( fd_hook_register( HOOK_MASK( HOOK_DATA_RECEIVED, HOOK_MESSAGE_RECEIVED, HOOK_MESSAGE_LOCAL, HOOK_MESSAGE_SENT, HOOK_MESSAGE_ROUTING_FORWARD, HOOK_MESSAGE_ROUTING_LOCAL ),
ta_hook_cb_silent, NULL, NULL, &hookhdl[0]) );
CHECK_FCT( fd_hook_register( HOOK_MASK( HOOK_MESSAGE_ROUTING_ERROR, HOOK_MESSAGE_DROPPED ),
ta_hook_cb_oneline, NULL, NULL, &hookhdl[1]) );
}
/* Start the statistics thread */
CHECK_POSIX( pthread_create(&ta_stats_th, NULL, ta_stats, NULL) );
return 0;
}
/* Unload */
void fd_ext_fini(void)
{
if (ta_conf->mode & MODE_CLI)
ta_cli_fini();
if (ta_conf->mode & MODE_SERV)
ta_serv_fini();
if (hookhdl[0])
fd_hook_unregister( hookhdl[0] );
if (hookhdl[1])
fd_hook_unregister( hookhdl[1] );
CHECK_FCT_DO( fd_thr_term(&ta_stats_th), );
CHECK_POSIX_DO( pthread_mutex_destroy(&ta_conf->stats_lock), );
}
EXTENSION_ENTRY("test_app", ta_entry);

117
lib/s6a/s6a_app.h Normal file
View File

@ -0,0 +1,117 @@
/*********************************************************************************************************
* Software License Agreement (BSD License) *
* Author: Sebastien Decugis <sdecugis@freediameter.net> *
* *
* Copyright (c) 2013, 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. *
*********************************************************************************************************/
/* Header file for the app_test extension.
*
* This extension provides a way to send configurable messages on the network
*
* See the app_test.conf.sample file for the format of the configuration file.
*/
#include <freeDiameter/extension.h>
#include <signal.h>
#ifndef TEST_APP_DEFAULT_SIGNAL
#define TEST_APP_DEFAULT_SIGNAL SIGUSR1
#endif /* TEST_APP_DEFAULT_SIGNAL */
/* Mode for the extension */
#define MODE_SERV 0x1
#define MODE_CLI 0x2
#define MODE_BENCH 0x4
/* The module configuration */
struct ta_conf {
uint32_t vendor_id; /* default 999999 */
uint32_t appli_id; /* default 123456 */
uint32_t cmd_id; /* default 234567 */
uint32_t avp_id; /* default 345678 */
uint32_t long_avp_id; /* default 0 */
size_t long_avp_len; /* default 5000 */
int mode; /* default MODE_SERV | MODE_CLI */
char * dest_realm; /* default local realm */
char * dest_host; /* default NULL */
char * user_name; /* default NULL */
int signal; /* default TEST_APP_DEFAULT_SIGNAL */
int bench_concur; /* default 100 */
int bench_duration; /* default 10 */
struct ta_stats {
unsigned long long nb_echoed; /* server */
unsigned long long nb_sent; /* client */
unsigned long long nb_recv; /* client */
unsigned long long nb_errs; /* client */
unsigned long shortest; /* fastest answer, in microseconds */
unsigned long longest; /* slowest answer, in microseconds */
unsigned long avg; /* average answer time, in microseconds */
} stats;
pthread_mutex_t stats_lock;
};
extern struct ta_conf * ta_conf;
/* Parse the configuration file */
int ta_conf_handle(char * conffile);
/* Handle incoming messages (server) */
int ta_serv_init(void);
void ta_serv_fini(void);
/* Create outgoing message (client) */
int ta_cli_init(void);
void ta_cli_fini(void);
/* Benchmark flavour */
int ta_bench_init(void);
void ta_bench_fini(void);
/* Initialize dictionary definitions */
int ta_dict_init(void);
/* Some global variables for dictionary */
extern struct dict_object * ta_vendor;
extern struct dict_object * ta_appli;
extern struct dict_object * ta_cmd_r;
extern struct dict_object * ta_cmd_a;
extern struct dict_object * ta_avp;
extern struct dict_object * ta_avp_long;
extern struct dict_object * ta_sess_id;
extern struct dict_object * ta_origin_host;
extern struct dict_object * ta_origin_realm;
extern struct dict_object * ta_dest_host;
extern struct dict_object * ta_dest_realm;
extern struct dict_object * ta_user_name;
extern struct dict_object * ta_res_code;

294
lib/s6a/s6a_client.c Normal file
View File

@ -0,0 +1,294 @@
/*********************************************************************************************************
* Software License Agreement (BSD License) *
* Author: Sebastien Decugis <sdecugis@freediameter.net> *
* *
* Copyright (c) 2013, 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. *
*********************************************************************************************************/
/* Create and send a message, and receive it */
/* Note that we use both sessions and the argument to answer callback to pass the same value.
* This is just for the purpose of checking everything went OK.
*/
#include "s6a_app.h"
#include <stdio.h>
static struct session_handler * ta_cli_reg = NULL;
struct sess_state {
int32_t randval; /* a random value to store in Test-AVP */
struct timespec ts; /* Time of sending the message */
} ;
/* Cb called when an answer is received */
static void ta_cb_ans(void * data, struct msg ** msg)
{
struct sess_state * mi = NULL;
struct timespec ts;
struct session * sess;
struct avp * avp;
struct avp_hdr * hdr;
unsigned long dur;
int error = 0;
CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &ts), return );
/* Search the session, retrieve its data */
{
int new;
CHECK_FCT_DO( fd_msg_sess_get(fd_g_config->cnf_dict, *msg, &sess, &new), return );
ASSERT( new == 0 );
CHECK_FCT_DO( fd_sess_state_retrieve( ta_cli_reg, sess, &mi ), return );
TRACE_DEBUG( INFO, "%p %p", mi, data);
ASSERT( (void *)mi == data );
}
/* Now log content of the answer */
fprintf(stderr, "RECV ");
/* Value of Test-AVP */
CHECK_FCT_DO( fd_msg_search_avp ( *msg, ta_avp, &avp), return );
if (avp) {
CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return );
if (hdr->avp_value->i32 == mi->randval) {
fprintf(stderr, "%x (%s) ", hdr->avp_value->i32, "Ok");
} else {
fprintf(stderr, "%x (%s) ", hdr->avp_value->i32, "PROBLEM");
error++;
}
} else {
fprintf(stderr, "no_Test-AVP ");
error++;
}
/* Value of Result Code */
CHECK_FCT_DO( fd_msg_search_avp ( *msg, ta_res_code, &avp), return );
if (avp) {
CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return );
fprintf(stderr, "Status: %d ", hdr->avp_value->i32);
if (hdr->avp_value->i32 != 2001)
error++;
} else {
fprintf(stderr, "no_Result-Code ");
error++;
}
/* Value of Origin-Host */
CHECK_FCT_DO( fd_msg_search_avp ( *msg, ta_origin_host, &avp), return );
if (avp) {
CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return );
fprintf(stderr, "From '%.*s' ", (int)hdr->avp_value->os.len, hdr->avp_value->os.data);
} else {
fprintf(stderr, "no_Origin-Host ");
error++;
}
/* Value of Origin-Realm */
CHECK_FCT_DO( fd_msg_search_avp ( *msg, ta_origin_realm, &avp), return );
if (avp) {
CHECK_FCT_DO( fd_msg_avp_hdr( avp, &hdr ), return );
fprintf(stderr, "('%.*s') ", (int)hdr->avp_value->os.len, hdr->avp_value->os.data);
} else {
fprintf(stderr, "no_Origin-Realm ");
error++;
}
CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), );
dur = ((ts.tv_sec - mi->ts.tv_sec) * 1000000) + ((ts.tv_nsec - mi->ts.tv_nsec) / 1000);
if (ta_conf->stats.nb_recv) {
/* Ponderate in the avg */
ta_conf->stats.avg = (ta_conf->stats.avg * ta_conf->stats.nb_recv + dur) / (ta_conf->stats.nb_recv + 1);
/* Min, max */
if (dur < ta_conf->stats.shortest)
ta_conf->stats.shortest = dur;
if (dur > ta_conf->stats.longest)
ta_conf->stats.longest = dur;
} else {
ta_conf->stats.shortest = dur;
ta_conf->stats.longest = dur;
ta_conf->stats.avg = dur;
}
if (error)
ta_conf->stats.nb_errs++;
else
ta_conf->stats.nb_recv++;
CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), );
/* Display how long it took */
if (ts.tv_nsec > mi->ts.tv_nsec) {
fprintf(stderr, "in %d.%06ld sec",
(int)(ts.tv_sec - mi->ts.tv_sec),
(long)(ts.tv_nsec - mi->ts.tv_nsec) / 1000);
} else {
fprintf(stderr, "in %d.%06ld sec",
(int)(ts.tv_sec + 1 - mi->ts.tv_sec),
(long)(1000000000 + ts.tv_nsec - mi->ts.tv_nsec) / 1000);
}
fprintf(stderr, "\n");
fflush(stderr);
/* Free the message */
CHECK_FCT_DO(fd_msg_free(*msg), return);
*msg = NULL;
free(mi);
return;
}
/* Create a test message */
static void ta_cli_test_message()
{
struct msg * req = NULL;
struct avp * avp;
union avp_value val;
struct sess_state * mi = NULL, *svg;
struct session *sess = NULL;
TRACE_DEBUG(FULL, "Creating a new message for sending.");
/* Create the request */
CHECK_FCT_DO( fd_msg_new( ta_cmd_r, MSGFL_ALLOC_ETEID, &req ), goto out );
/* Create a new session */
#define TEST_APP_SID_OPT "app_test"
CHECK_FCT_DO( fd_msg_new_session( req, (os0_t)TEST_APP_SID_OPT, CONSTSTRLEN(TEST_APP_SID_OPT) ), goto out );
CHECK_FCT_DO( fd_msg_sess_get(fd_g_config->cnf_dict, req, &sess, NULL), goto out );
/* Create the random value to store with the session */
mi = malloc(sizeof(struct sess_state));
if (mi == NULL) {
fd_log_debug("malloc failed: %s", strerror(errno));
goto out;
}
mi->randval = (int32_t)random();
/* Now set all AVPs values */
/* Set the Destination-Realm AVP */
{
CHECK_FCT_DO( fd_msg_avp_new ( ta_dest_realm, 0, &avp ), goto out );
val.os.data = (unsigned char *)(ta_conf->dest_realm);
val.os.len = strlen(ta_conf->dest_realm);
CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out );
CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out );
}
/* Set the Destination-Host AVP if needed*/
if (ta_conf->dest_host) {
CHECK_FCT_DO( fd_msg_avp_new ( ta_dest_host, 0, &avp ), goto out );
val.os.data = (unsigned char *)(ta_conf->dest_host);
val.os.len = strlen(ta_conf->dest_host);
CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out );
CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out );
}
/* Set Origin-Host & Origin-Realm */
CHECK_FCT_DO( fd_msg_add_origin ( req, 0 ), goto out );
/* Set the User-Name AVP if needed*/
if (ta_conf->user_name) {
CHECK_FCT_DO( fd_msg_avp_new ( ta_user_name, 0, &avp ), goto out );
val.os.data = (unsigned char *)(ta_conf->user_name);
val.os.len = strlen(ta_conf->user_name);
CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out );
CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out );
}
/* Set the Test-AVP AVP */
{
CHECK_FCT_DO( fd_msg_avp_new ( ta_avp, 0, &avp ), goto out );
val.i32 = mi->randval;
CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out );
CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out );
}
/* Set the Test-Payload-AVP AVP */
if (ta_conf->long_avp_id) {
int l;
CHECK_FCT_DO( fd_msg_avp_new ( ta_avp_long, 0, &avp ), goto out );
CHECK_MALLOC_DO( val.os.data = malloc(ta_conf->long_avp_len), goto out);
val.os.len = ta_conf->long_avp_len;
for (l=0; l < ta_conf->long_avp_len; l++)
val.os.data[l]=l;
CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out );
free(val.os.data);
CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out );
}
CHECK_SYS_DO( clock_gettime(CLOCK_REALTIME, &mi->ts), goto out );
/* Keep a pointer to the session data for debug purpose, in real life we would not need it */
svg = mi;
/* Store this value in the session */
CHECK_FCT_DO( fd_sess_state_store ( ta_cli_reg, sess, &mi ), goto out );
/* Log sending the message */
fprintf(stderr, "SEND %x to '%s' (%s)\n", svg->randval, ta_conf->dest_realm, ta_conf->dest_host?:"-" );
fflush(stderr);
/* Send the request */
CHECK_FCT_DO( fd_msg_send( &req, ta_cb_ans, svg ), goto out );
/* Increment the counter */
CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), );
ta_conf->stats.nb_sent++;
CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), );
out:
return;
}
int ta_cli_init(void)
{
CHECK_FCT( fd_sess_handler_create(&ta_cli_reg, (void *)free, NULL, NULL) );
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_sess_handler_destroy(&ta_cli_reg, NULL), /* continue */ );
return;
};

166
lib/s6a/s6a_dict.c Normal file
View File

@ -0,0 +1,166 @@
/*********************************************************************************************************
* Software License Agreement (BSD License) *
* Author: Sebastien Decugis <sdecugis@freediameter.net> *
* *
* Copyright (c) 2013, 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. *
*********************************************************************************************************/
/* Install the dictionary objects */
#include "s6a_app.h"
struct dict_object * ta_vendor = NULL;
struct dict_object * ta_appli = NULL;
struct dict_object * ta_cmd_r = NULL;
struct dict_object * ta_cmd_a = NULL;
struct dict_object * ta_avp = NULL;
struct dict_object * ta_avp_long = NULL;
struct dict_object * ta_sess_id = NULL;
struct dict_object * ta_origin_host = NULL;
struct dict_object * ta_origin_realm = NULL;
struct dict_object * ta_dest_host = NULL;
struct dict_object * ta_dest_realm = NULL;
struct dict_object * ta_user_name = NULL;
struct dict_object * ta_res_code = NULL;
int ta_dict_init(void)
{
TRACE_DEBUG(FULL, "Initializing the dictionary for test");
/* Create the Test Vendor */
{
struct dict_vendor_data data;
data.vendor_id = ta_conf->vendor_id;
data.vendor_name = "app_test vendor";
CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_VENDOR, &data, NULL, &ta_vendor));
}
/* Create the Test Application */
{
struct dict_application_data data;
data.application_id = ta_conf->appli_id;
data.application_name = "app_test application";
CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_APPLICATION, &data, ta_vendor, &ta_appli));
}
/* Create the Test-Request & Test-Answer commands */
{
struct dict_cmd_data data;
data.cmd_code = ta_conf->cmd_id;
data.cmd_name = "Test-Request";
data.cmd_flag_mask = CMD_FLAG_PROXIABLE | CMD_FLAG_REQUEST;
data.cmd_flag_val = CMD_FLAG_PROXIABLE | CMD_FLAG_REQUEST;
CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_COMMAND, &data, ta_appli, &ta_cmd_r));
data.cmd_name = "Test-Answer";
data.cmd_flag_val = CMD_FLAG_PROXIABLE;
CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_COMMAND, &data, ta_appli, &ta_cmd_a));
}
/* Create the Test AVP */
{
struct dict_avp_data data;
data.avp_code = ta_conf->avp_id;
data.avp_vendor = ta_conf->vendor_id;
data.avp_name = "Test-AVP";
data.avp_flag_mask = AVP_FLAG_VENDOR;
data.avp_flag_val = AVP_FLAG_VENDOR;
data.avp_basetype = AVP_TYPE_INTEGER32;
CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_AVP, &data, NULL, &ta_avp));
}
/* Create the Test Payload AVP */
if (ta_conf->long_avp_id) {
struct dict_avp_data data;
data.avp_code = ta_conf->long_avp_id;
data.avp_vendor = ta_conf->vendor_id;
data.avp_name = "Test-Payload-AVP";
data.avp_flag_mask = AVP_FLAG_VENDOR;
data.avp_flag_val = AVP_FLAG_VENDOR;
data.avp_basetype = AVP_TYPE_OCTETSTRING;
CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_AVP, &data, NULL, &ta_avp_long));
}
/* Now resolve some other useful AVPs */
CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &ta_sess_id, ENOENT) );
CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-Host", &ta_origin_host, ENOENT) );
CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-Realm", &ta_origin_realm, ENOENT) );
CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Host", &ta_dest_host, ENOENT) );
CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Realm", &ta_dest_realm, ENOENT) );
CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "User-Name", &ta_user_name, ENOENT) );
CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Result-Code", &ta_res_code, ENOENT) );
/* Create the rules for Test-Request and Test-Answer */
{
struct dict_rule_data data;
data.rule_min = 1;
data.rule_max = 1;
/* Session-Id is in first position */
data.rule_avp = ta_sess_id;
data.rule_position = RULE_FIXED_HEAD;
data.rule_order = 1;
CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &data, ta_cmd_r, NULL));
CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &data, ta_cmd_a, NULL));
data.rule_position = RULE_REQUIRED;
/* Test-AVP is mandatory */
data.rule_avp = ta_avp;
CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &data, ta_cmd_r, NULL));
CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &data, ta_cmd_a, NULL));
/* idem for Origin Host and Realm */
data.rule_avp = ta_origin_host;
CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &data, ta_cmd_r, NULL));
CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &data, ta_cmd_a, NULL));
data.rule_avp = ta_origin_realm;
CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &data, ta_cmd_r, NULL));
CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &data, ta_cmd_a, NULL));
/* And Result-Code is mandatory for answers only */
data.rule_avp = ta_res_code;
CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &data, ta_cmd_a, NULL));
/* And Destination-Realm for requests only */
data.rule_avp = ta_dest_realm;
CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &data, ta_cmd_r, NULL));
/* And Destination-Host optional for requests only */
data.rule_position = RULE_OPTIONAL;
data.rule_min = 0;
data.rule_avp = ta_dest_host;
CHECK_FCT(fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &data, ta_cmd_r, NULL));
}
return 0;
}

154
lib/s6a/s6a_server.c Normal file
View File

@ -0,0 +1,154 @@
/*********************************************************************************************************
* Software License Agreement (BSD License) *
* Author: Sebastien Decugis <sdecugis@freediameter.net> *
* *
* Copyright (c) 2013, 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. *
*********************************************************************************************************/
/* Install the dispatch callbacks */
#include "s6a_app.h"
static struct disp_hdl * ta_hdl_fb = NULL; /* handler for fallback cb */
static struct disp_hdl * ta_hdl_tr = NULL; /* handler for Test-Request req cb */
/* Default callback for the application. */
static int ta_fb_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act)
{
/* This CB should never be called */
TRACE_ENTRY("%p %p %p %p", msg, avp, sess, act);
fd_log_debug("Unexpected message received!");
return ENOTSUP;
}
/* Callback for incoming Test-Request messages */
static int ta_tr_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act)
{
struct msg *ans, *qry;
struct avp * a;
TRACE_ENTRY("%p %p %p %p", msg, avp, sess, act);
if (msg == NULL)
return EINVAL;
/* Value of Origin-Host */
if (! (ta_conf->mode & MODE_BENCH)) {
fprintf(stderr, "ECHO Test-Request received from ");
CHECK_FCT( fd_msg_search_avp ( *msg, ta_origin_host, &a) );
if (a) {
struct avp_hdr * hdr;
CHECK_FCT( fd_msg_avp_hdr( a, &hdr ) );
fprintf(stderr, "'%.*s'", (int)hdr->avp_value->os.len, hdr->avp_value->os.data);
} else {
fprintf(stderr, "no_Origin-Host");
}
fprintf(stderr, ", replying...\n");
}
/* Create answer header */
qry = *msg;
CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) );
ans = *msg;
/* Set the Test-AVP AVP */
{
struct avp * src = NULL;
struct avp_hdr * hdr = NULL;
CHECK_FCT( fd_msg_search_avp ( qry, ta_avp, &src) );
CHECK_FCT( fd_msg_avp_hdr( src, &hdr ) );
CHECK_FCT( fd_msg_avp_new ( ta_avp, 0, &avp ) );
CHECK_FCT( fd_msg_avp_setvalue( avp, hdr->avp_value ) );
CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
}
/* Set the Test-Payload-AVP AVP */
if (ta_conf->long_avp_id) {
struct avp * src = NULL;
struct avp_hdr * hdr = NULL;
CHECK_FCT( fd_msg_search_avp ( qry, ta_avp_long, &src) );
CHECK_FCT( fd_msg_avp_hdr( src, &hdr ) );
CHECK_FCT( fd_msg_avp_new ( ta_avp_long, 0, &avp ) );
CHECK_FCT( fd_msg_avp_setvalue( avp, hdr->avp_value ) );
CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
}
/* Set the Origin-Host, Origin-Realm, Result-Code AVPs */
CHECK_FCT( fd_msg_rescode_set( ans, "DIAMETER_SUCCESS", NULL, NULL, 1 ) );
/* Send the answer */
CHECK_FCT( fd_msg_send( msg, NULL, NULL ) );
/* Add this value to the stats */
CHECK_POSIX_DO( pthread_mutex_lock(&ta_conf->stats_lock), );
ta_conf->stats.nb_echoed++;
CHECK_POSIX_DO( pthread_mutex_unlock(&ta_conf->stats_lock), );
return 0;
}
int ta_serv_init(void)
{
struct disp_when data;
TRACE_DEBUG(FULL, "Initializing dispatch callbacks for test");
memset(&data, 0, sizeof(data));
data.app = ta_appli;
data.command = ta_cmd_r;
/* fallback CB if command != Test-Request received */
CHECK_FCT( fd_disp_register( ta_fb_cb, DISP_HOW_APPID, &data, NULL, &ta_hdl_fb ) );
/* Now specific handler for Test-Request */
CHECK_FCT( fd_disp_register( ta_tr_cb, DISP_HOW_CC, &data, NULL, &ta_hdl_tr ) );
return 0;
}
void ta_serv_fini(void)
{
if (ta_hdl_fb) {
(void) fd_disp_unregister(&ta_hdl_fb, NULL);
}
if (ta_hdl_tr) {
(void) fd_disp_unregister(&ta_hdl_tr, NULL);
}
return;
}

View File

@ -20,14 +20,14 @@ libcellwire_la_DEPENDENCIES = \
$(top_srcdir)/lib/logger/liblogger.la \
$(top_srcdir)/lib/message/s1ap/libmessages1ap.la \
$(top_srcdir)/lib/message/nas/libmessagenas.la \
$(top_srcdir)/lib/message/s6a/libmessages6a.la
$(top_srcdir)/lib/s6a/libs6a.la
libcellwire_la_LIBADD = \
$(top_srcdir)/lib/core/src/libcore.la \
$(top_srcdir)/lib/logger/liblogger.la \
$(top_srcdir)/lib/message/s1ap/libmessages1ap.la \
$(top_srcdir)/lib/message/nas/libmessagenas.la \
$(top_srcdir)/lib/message/s6a/libmessages6a.la
$(top_srcdir)/lib/s6a/libs6a.la
AM_CPPFLAGS = \
-I$(top_srcdir)/include \
@ -35,7 +35,7 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/lib/message/s1ap/asn1c \
-I$(top_srcdir)/lib/message/s1ap \
-I$(top_srcdir)/lib/message/nas \
-I$(top_srcdir)/lib/message/s6a
-I$(top_srcdir)/lib/s6a
AM_CFLAGS = \
-Wall -Werror

View File

@ -7,7 +7,6 @@
#include "cellwire.h"
#include "context.h"
#include "s1ap_message.h"
#include "s6a_message.h"
static mme_ctx_t self;

View File

@ -7,7 +7,7 @@
#include "core_debug.h"
#include "core_thread.h"
#include "s6a_message.h"
#include "s6a_app.h"
#include "context.h"
#include "event.h"
@ -20,7 +20,9 @@ static thread_id mme_net_thread;
status_t cellwire_initialize(char *config_path)
{
status_t rv;
#if 0
s6a_conf_t conf;
#endif
srand(time(NULL)*getpid());
@ -28,6 +30,7 @@ status_t cellwire_initialize(char *config_path)
if (rv != CORE_OK)
return rv;
#if 0
rv = s6a_initialize();
if (rv != CORE_OK)
return rv;
@ -37,6 +40,7 @@ status_t cellwire_initialize(char *config_path)
rv = s6a_conf_handle(&conf);
s6a_conf_show();
#endif
return CORE_OK;
}
@ -122,14 +126,18 @@ void threads_start()
d_assert(rv == CORE_OK, return,
"MME Network socket recv thread creation failed");
#if 0
rv = s6a_thread_start();
d_assert(rv == CORE_OK, return,
"HSS thread creation failed");
#endif
}
void threads_stop()
{
#if 0
s6a_thread_stop();
#endif
thread_delete(mme_net_thread);
thread_delete(mme_sm_thread);
}