Navigation


Changes in / [1331:229ecec59ff5:1349:73b9f2aefb75] in freeDiameter


Ignore:
Files:
33 added
17 edited

Legend:

Unmodified
Added
Removed
  • INSTALL.pkgsrc

    r811 r1334  
    1212and follow the usual installation note.
    1313
    14 NetBSD does not support SCTP, so you have to add
    15         -DDISABLE_SCTP:BOOL=ON
    16 to the cmake command line.
     14For the optional extensions, you need mysql*-client, postgres*-client,
     15libxml2, jsoncpp, and json-schema.  For the debugging extensions,
     16you also need swig and a python -- install as usual.
    1717
    18 For the optional extensions, you need mysql*-client, postgres*-client,
    19 libxml2.  For the debugging extensions, you also need swig and a
    20 python -- install as usual.
    21 
  • LICENSE

    r1331 r1349  
    33Software License Agreement (BSD License)
    44
    5 Copyright (c) 2008-2018, WIDE Project and NICT
     5Copyright (c) 2008-2019, WIDE Project and NICT
    66All rights reserved.
    77
     
    5353 * Thomas Klausner:
    5454  several extensions and numerous fixes / improvements.
    55  
    56  
    57  
  • doc/rt_default.conf.sample

    r1197 r1336  
    22#
    33# This extension provides configurable routing properties for freeDiameter.
     4
     5# This extension supports configuration reload at runtime. Send
     6# signal SIGUSR1 to the process to cause the process to reload its
     7# config.
    48
    59# Lines starting with a # are comments and ignored.
  • doc/rt_ereg.conf.sample

    r525 r1338  
    44# The rt_ereg extension allows creation of routing rules based on AVP value matching regular expressions.
    55
     6# This extension supports configuration reload at runtime. Send
     7# signal SIGUSR1 to the process to cause the process to reload its
     8# config.
     9
    610# First, one must indicate which AVP should be used for matching.
    711# At the moment, only AVP with OCTETSTRING types are valid.
    812#  AVP = "User-Name";
     13# It is possible to specify AVPs below GROUPED AVPs with the by separating AVPs with a colon (':'):
     14#  AVP = "Grouped-AVP1" : "Grouped-AVP2" : "Octetstring-AVP";
    915# This parameter is mandatory. There is no default value.
    1016
     
    2026#    (reminder: the server with the peer with the highest score gets the message)
    2127# Note that all rules are tested for each message that contain the AVP, not only the first match.
     28
     29# There can be multiple blocks of AVPs and rules; just start the next one with another AVP line:
     30#  AVP = "Other-AVP";
     31# and continue with rules as above.
  • extensions/CMakeLists.txt

    r1278 r1348  
    1313ENDMACRO(FD_ADD_EXTENSION)
    1414
    15 # Use the macro FD_EXTENSION_SUBDIR(extmacroname subdir descr default) to 
     15# Use the macro FD_EXTENSION_SUBDIR(extmacroname subdir descr default) to
    1616# add a new extension subdirectory.
    1717MACRO(FD_EXTENSION_SUBDIR EXTSUBDIR EXTDESCR EXTDEFAULT)
     
    4040FD_EXTENSION_SUBDIR(dict_eap    "Diameter EAP (RFC4072) Dictionary definitions" ON)
    4141
    42 FD_EXTENSION_SUBDIR(dict_dcca   "Diameter CC (RFC4006) Dictionary definitions [incomplete]" ON)
    43 FD_EXTENSION_SUBDIR(dict_dcca_3gpp   "Diameter CC 3GPP Dictionary definitions [incomplete]" ON)
    44 FD_EXTENSION_SUBDIR(dict_dcca_starent   "Diameter CC Starent Dictionary definitions" ON)
     42FD_EXTENSION_SUBDIR(dict_dcca         "Diameter CC (RFC4006) Dictionary definitions [incomplete]" ON)
     43FD_EXTENSION_SUBDIR(dict_dcca_3gpp    "Diameter CC 3GPP Dictionary definitions [incomplete]" ON)
     44FD_EXTENSION_SUBDIR(dict_dcca_starent "Diameter CC Starent Dictionary definitions" ON)
    4545
    4646FD_EXTENSION_SUBDIR(dict_sip    "Diameter SIP (RFC4740) Dictionary definitions" ON)
     
    5151FD_EXTENSION_SUBDIR(dict_rfc5777   "Classification and QoS (RFC 5777) Dictionary definitions" ON)
    5252
     53FD_EXTENSION_SUBDIR(dict_json       "Load Diameter dictionary definitions from JSON files."   OFF)
    5354FD_EXTENSION_SUBDIR(dict_legacy_xml "Load Diameter dictionary definitions from XML files."    OFF)
    5455
     
    6869# Routing extensions
    6970
    70 FD_EXTENSION_SUBDIR(rt_busypeers "Handling of Diameter TOO_BUSY messages and relay timeouts"    ON)
    71 FD_EXTENSION_SUBDIR(rt_default   "Configurable routing rules for freeDiameter"                  ON)
    72 FD_EXTENSION_SUBDIR(rt_ereg      "Configurable routing based on regexp matching of AVP values" OFF)
    73 FD_EXTENSION_SUBDIR(rt_ignore_dh "Stow Destination-Host in Proxy-Info, restore to Origin-Host for answers"      ON)
     71FD_EXTENSION_SUBDIR(rt_busypeers    "Handling of Diameter TOO_BUSY messages and relay timeouts" ON)
     72FD_EXTENSION_SUBDIR(rt_default      "Configurable routing rules for freeDiameter"                       ON)
     73FD_EXTENSION_SUBDIR(rt_deny_by_size "Deny messages that are larger than a configured size"                      ON)
     74FD_EXTENSION_SUBDIR(rt_ereg         "Configurable routing based on regexp matching of AVP values" OFF)
     75FD_EXTENSION_SUBDIR(rt_ignore_dh    "Stow Destination-Host in Proxy-Info, restore to Origin-Host for answers"   ON)
    7476FD_EXTENSION_SUBDIR(rt_load_balance "Balance load over multiple equal hosts, based on outstanding requests"     ON)
    75 FD_EXTENSION_SUBDIR(rt_randomize "Randomly choose one of the highest scored hosts and increase its score by one"        ON)
    76 FD_EXTENSION_SUBDIR(rt_redirect  "Handling of Diameter Redirect messages"                       ON)
     77FD_EXTENSION_SUBDIR(rt_randomize    "Randomly choose one of the highest scored hosts and increase its score by one"     ON)
     78FD_EXTENSION_SUBDIR(rt_redirect     "Handling of Diameter Redirect messages"                    ON)
     79FD_EXTENSION_SUBDIR(rt_rewrite      "Convert/remove AVP data in messages"                       ON)
    7780
    7881
     
    8689# Debug & test extensions
    8790
    88 FD_EXTENSION_SUBDIR(dbg_monitor "Outputs periodical status information"              ON)
     91FD_EXTENSION_SUBDIR(dbg_loglevel "Read loglevel from file -- allows runtime change"  ON)
     92FD_EXTENSION_SUBDIR(dbg_monitor     "Outputs periodical status information"              ON)
    8993FD_EXTENSION_SUBDIR(dbg_msg_timings "Show some timing information for messages"      ON)
    90 FD_EXTENSION_SUBDIR(dbg_msg_dumps "Show human-readable content of the received & sent messages"      ON)
    91 FD_EXTENSION_SUBDIR(dbg_rt      "Routing extension for debugging the routing module" ON)
    92 FD_EXTENSION_SUBDIR(test_app    "Testing application to send dummy message to another peer, like a Diameter 'ping'" OFF)
    93 FD_EXTENSION_SUBDIR(test_sip    "Testing application to simulate Diameter-SIP client (RFC4740)" OFF)
     94FD_EXTENSION_SUBDIR(dbg_msg_dumps   "Show human-readable content of the received & sent messages"      ON)
     95FD_EXTENSION_SUBDIR(dbg_rt          "Routing extension for debugging the routing module" ON)
     96FD_EXTENSION_SUBDIR(test_app        "Testing application to send dummy message to another peer, like a Diameter 'ping'" OFF)
     97FD_EXTENSION_SUBDIR(test_as     "Receive Abort-Session-Requests and display the data" OFF)
     98FD_EXTENSION_SUBDIR(test_cc     "Receive Credit-Control-Requests and display the data" OFF)
     99FD_EXTENSION_SUBDIR(test_sip        "Testing application to simulate Diameter-SIP client (RFC4740)" OFF)
    94100FD_EXTENSION_SUBDIR(dbg_interactive "Python-interpreter based module"                OFF)
    95 FD_EXTENSION_SUBDIR(test_netemul "Simple Diameter network emulator proxy extension (latency, PDV, duplicates)" OFF)
     101FD_EXTENSION_SUBDIR(test_netemul    "Simple Diameter network emulator proxy extension (latency, PDV, duplicates)" OFF)
    96102
    97103
  • extensions/dict_dcca_3gpp/dict_dcca_3gpp.c

    r1324 r1337  
    1058010580                                { { .avp_vendor = 10415, .avp_name = "Interface-Port" }, RULE_OPTIONAL, -1, 1 },
    1058110581                                { { .avp_vendor = 10415, .avp_name = "Interface-Type" }, RULE_OPTIONAL, -1, 1 },
     10582                        };
     10583                        PARSE_loc_rules(rules, rule_avp);
     10584        }
     10585
     10586        {
     10587                struct dict_object *rule_avp;
     10588                struct dict_avp_request vpa;
     10589                vpa.avp_vendor = 10415;
     10590                vpa.avp_name = "Originator-Received-Address";
     10591                CHECK_dict_search(DICT_AVP, AVP_BY_NAME_AND_VENDOR, &vpa, &rule_avp);
     10592                struct local_rules_definition rules[] =
     10593                        {
     10594                                { { .avp_vendor = 10415, .avp_name = "Address-Type" }, RULE_OPTIONAL, -1, 1 },
     10595                                { { .avp_vendor = 10415, .avp_name = "Address-Data" }, RULE_OPTIONAL, -1, 1 },
     10596                                { { .avp_vendor = 10415, .avp_name = "Address-Domain" }, RULE_OPTIONAL, -1, 1 },
    1058210597                        };
    1058310598                        PARSE_loc_rules(rules, rule_avp);
  • extensions/rt_default/rt_default.c

    r1235 r1336  
    3838 */
    3939
     40#include <signal.h>
     41
    4042#include "rt_default.h"
     43
     44#define MODULE_NAME "rt_default"
     45
     46#include <pthread.h>
     47
     48static pthread_rwlock_t rtd_lock;
     49
     50static char *rtd_config_file;
    4151
    4252/* The callback called on new messages */
     
    4555        struct msg * msg = *pmsg;
    4656        TRACE_ENTRY("%p %p %p", cbdata, msg, candidates);
     57        int ret;
    4758       
    4859        CHECK_PARAMS(msg && candidates);
    49        
     60
     61        if (pthread_rwlock_rdlock(&rtd_lock) != 0) {
     62                fd_log_notice("%s: read-lock failed, skipping handler", MODULE_NAME);
     63                return 0;
     64        }
    5065        /* Simply pass it to the appropriate function */
    5166        if (FD_IS_LIST_EMPTY(candidates)) {
    52                 return 0;
     67                ret = 0;
    5368        } else {
    54                 return rtd_process( msg, candidates );
     69                ret = rtd_process( msg, candidates );
    5570        }
     71        if (pthread_rwlock_unlock(&rtd_lock) != 0) {
     72                fd_log_notice("%s: read-unlock failed after rtd_out, exiting", MODULE_NAME);
     73                exit(1);
     74        }
     75        return ret;
    5676}
    5777
     
    5979static struct fd_rt_out_hdl * rtd_hdl = NULL;
    6080
     81static volatile int in_signal_handler = 0;
     82
     83/* signal handler */
     84static void sig_hdlr(void)
     85{
     86        if (in_signal_handler) {
     87                fd_log_error("%s: already handling a signal, ignoring new one", MODULE_NAME);
     88                return;
     89        }
     90        in_signal_handler = 1;
     91
     92        if (pthread_rwlock_wrlock(&rtd_lock) != 0) {
     93                fd_log_error("%s: locking failed, aborting config reload", MODULE_NAME);
     94                return;
     95        }
     96        rtd_conf_reload(rtd_config_file);
     97        if (pthread_rwlock_unlock(&rtd_lock) != 0) {
     98                fd_log_error("%s: unlocking failed after config reload, exiting", MODULE_NAME);
     99                exit(1);
     100        }               
     101
     102        fd_log_notice("%s: reloaded configuration", MODULE_NAME);
     103
     104        in_signal_handler = 0;
     105}
     106
     107
    61108/* entry point */
    62109static int rtd_entry(char * conffile)
    63110{
    64111        TRACE_ENTRY("%p", conffile);
    65        
     112
     113        rtd_config_file = conffile;
     114        pthread_rwlock_init(&rtd_lock, NULL);
     115
     116        if (pthread_rwlock_wrlock(&rtd_lock) != 0) {
     117                fd_log_notice("%s: write-lock failed, aborting", MODULE_NAME);
     118                return EDEADLK;
     119        }
     120
    66121        /* Initialize the repo */
    67122        CHECK_FCT( rtd_init() );
     
    69124        /* Parse the configuration file */
    70125        CHECK_FCT( rtd_conf_handle(conffile) );
    71        
     126
     127        if (pthread_rwlock_unlock(&rtd_lock) != 0) {
     128                fd_log_notice("%s: write-unlock failed, aborting", MODULE_NAME);
     129                return EDEADLK;
     130        }
     131
     132        /* Register reload callback */
     133        CHECK_FCT(fd_event_trig_regcb(SIGUSR1, MODULE_NAME, sig_hdlr));
     134
    72135#if 0
    73136        /* Dump the rules */
     
    92155        /* Destroy the data */
    93156        rtd_fini();
    94        
     157
     158        pthread_rwlock_destroy(&rtd_lock);
     159
    95160        /* Done */
    96161        return ;
    97162}
    98163
    99 EXTENSION_ENTRY("rt_default", rtd_entry);
     164EXTENSION_ENTRY(MODULE_NAME, rtd_entry);
  • extensions/rt_default/rt_default.h

    r741 r1336  
    8383int rtd_process( struct msg * msg, struct fd_list * candidates );
    8484
     85/* Reload the config file */
     86void rtd_conf_reload(char *config_file);
     87
    8588/* For debug: dump the rule repository */
    8689void rtd_dump(void);
  • extensions/rt_default/rtd_conf.y

    r1127 r1336  
    5555/* Forward declaration */
    5656int yyparse(char * conffile);
     57void rtd_confrestart(FILE *input_file);
    5758
    5859static int rules_added = 0;
     
    6667        TRACE_ENTRY("%p", conffile);
    6768       
    68         TRACE_DEBUG (FULL, "Parsing configuration file: %s...", conffile);
    69        
     69        TRACE_DEBUG (FULL, "rt_default: Parsing configuration file: %s...", conffile);
     70
     71        rules_added = 0;
    7072        rtd_confin = fopen(conffile, "r");
    7173        if (rtd_confin == NULL) {
    7274                ret = errno;
    7375                fd_log_debug("Unable to open extension configuration file %s for reading: %s", conffile, strerror(ret));
    74                 TRACE_DEBUG (INFO, "Error occurred, message logged -- configuration file.");
     76                TRACE_DEBUG (INFO, "rt_default: Error occurred, message logged -- configuration file.");
    7577                return ret;
    7678        }
    7779
     80        rtd_confrestart(rtd_confin);
    7881        ret = yyparse(conffile);
    7982
     
    8184
    8285        if (ret != 0) {
    83                 TRACE_DEBUG (INFO, "Unable to parse the configuration file.");
     86                TRACE_DEBUG (INFO, "rt_default: Unable to parse the configuration file.");
    8487                return EINVAL;
    8588        } else {
    86                 TRACE_DEBUG(FULL, "Added %d RULES routing entries successfully.", rules_added);
     89                TRACE_DEBUG(INFO, "rt_default: Added %d RULES routing entries successfully.", rules_added);
    8790        }
    8891       
     
    9699void yyerror (YYLTYPE *ploc, char * conffile, char const *s)
    97100{
    98         TRACE_DEBUG(INFO, "Error in configuration parsing");
     101        TRACE_DEBUG(INFO, "rt_default: Error in configuration parsing");
    99102       
    100103        if (ploc->first_line != ploc->last_line)
  • extensions/rt_default/rtd_rules.c

    r1179 r1336  
    4747 *  Under each TARGET element, we have the list of RULES that are defined for this target, ordered by CRITERIA type, then is_regex, then string value.
    4848 *
    49  * Note: Except during configuration parsing and module termination, the lists are only ever accessed read-only, so we do not need a lock.
     49 * Note: Access these only when holding rtd_lock; config reload may change the underlying data.
    5050 */
    5151
     
    390390}
    391391
    392 /* Destroy the module's data */
    393 void rtd_fini(void)
     392static void free_targets(void)
    394393{
    395394        int i;
    396        
    397         TRACE_ENTRY();
    398395
    399396        for (i = 0; i < RTD_TAR_MAX; i++) {
     
    402399                }
    403400        }
    404        
     401}
     402
     403/* Destroy the module's data */
     404void rtd_fini(void)
     405{
     406        TRACE_ENTRY();
     407
     408        free_targets();
    405409}
    406410
     
    493497       
    494498        return 0;
     499}
     500
     501void rtd_conf_reload(char *config_file)
     502{
     503        /* save old config in case reload goes wrong */
     504        struct fd_list old_config[RTD_TAR_MAX];
     505        int i;
     506
     507        for (i = 0; i < RTD_TAR_MAX; i++) {
     508                old_config[i] = TARGETS[i];
     509        }
     510        memset(TARGETS, 0, sizeof(*TARGETS) * RTD_TAR_MAX);
     511        for (i = 0; i < RTD_TAR_MAX; i++) {
     512                fd_list_init(&TARGETS[i], NULL);
     513        }
     514
     515        if (rtd_conf_handle(config_file) != 0) {
     516                fd_log_notice("rt_default: error reloading configuration, restoring previous configuration");
     517                free_targets();
     518                for (i = 0; i < RTD_TAR_MAX; i++) {
     519                        TARGETS[i] = old_config[i];
     520                }
     521        } else {
     522                /* this has to be done in this weird way because the items contain back pointers referencing TARGETS */
     523                struct fd_list save_config[RTD_TAR_MAX];
     524                for (i = 0; i < RTD_TAR_MAX; i++) {
     525                        save_config[i] = TARGETS[i];
     526                        TARGETS[i] = old_config[i];
     527                }
     528                free_targets();
     529                for (i = 0; i < RTD_TAR_MAX; i++) {
     530                        TARGETS[i] = save_config[i];
     531                }
     532        }
    495533}
    496534
  • extensions/rt_ereg/rtereg.c

    r1216 r1338  
    3434*********************************************************************************************************/
    3535
    36 /* 
     36/*
    3737 * This extension allows to perform some pattern-matching on an AVP
    3838 * and send the message to a server accordingly.
     
    4040 */
    4141
     42#include <pthread.h>
     43#include <signal.h>
     44
    4245#include "rtereg.h"
    4346
     47static pthread_rwlock_t rte_lock;
     48
     49#define MODULE_NAME "rt_ereg"
     50
     51static char *rt_ereg_config_file;
     52
    4453/* The configuration structure */
    45 struct rtereg_conf rtereg_conf;
     54struct rtereg_conf *rtereg_conf;
     55int rtereg_conf_size;
    4656
    4757#ifndef HAVE_REG_STARTEND
     
    5161#endif /* HAVE_REG_STARTEND */
    5262
    53 static int proceed(char * value, size_t len, struct fd_list * candidates)
     63static int rtereg_init(void);
     64static int rtereg_init_config(void);
     65static void rtereg_fini(void);
     66
     67void rtereg_conf_free(struct rtereg_conf *config_struct, int config_size)
     68{
     69        int i, j;
     70
     71        /* Destroy the data */
     72        for (j=0; j<config_size; j++) {
     73                if (config_struct[j].rules) {
     74                        for (i = 0; i < config_struct[j].rules_nb; i++) {
     75                                free(config_struct[j].rules[i].pattern);
     76                                free(config_struct[j].rules[i].server);
     77                                regfree(&config_struct[j].rules[i].preg);
     78                        }
     79                }
     80                free(config_struct[j].avps);
     81                free(config_struct[j].rules);
     82        }
     83        free(config_struct);
     84}
     85
     86static int proceed(char * value, size_t len, struct fd_list * candidates, int conf)
    5487{
    5588        int i;
    56        
    57         for (i = 0; i < rtereg_conf.rules_nb; i++) {
     89
     90        for (i = 0; i < rtereg_conf[conf].rules_nb; i++) {
    5891                /* Does this pattern match the value? */
    59                 struct rtereg_rule * r = &rtereg_conf.rules[i];
     92                struct rtereg_rule * r = &rtereg_conf[conf].rules[i];
    6093                int err = 0;
    6194                struct fd_list * c;
    62                
     95
    6396                TRACE_DEBUG(ANNOYING, "Attempt pattern matching of '%.*s' with rule '%s'", (int)len, value, r->pattern);
    64                
     97
    6598                #ifdef HAVE_REG_STARTEND
    6699                {
     
    77110                }
    78111                #endif /* HAVE_REG_STARTEND */
    79                
     112
    80113                if (err == REG_NOMATCH)
    81114                        continue;
    82                        
     115
    83116                if (err != 0) {
    84117                        char * errstr;
     
    100133                        /* Free the buffer, return the error */
    101134                        free(errstr);
    102                        
     135
    103136                        return (err == REG_ESPACE) ? ENOMEM : EINVAL;
    104137                }
    105                
     138
    106139                /* From this point, the expression matched the AVP value */
    107140                TRACE_DEBUG(FULL, "[rt_ereg] Match: '%s' to value '%.*s' => '%s' += %d",
     
    111144                                        r->server,
    112145                                        r->score);
    113                
     146
    114147                for (c = candidates->next; c != candidates; c = c->next) {
    115148                        struct rtd_candidate * cand = (struct rtd_candidate *)c;
     
    121154                }
    122155        };
    123        
     156
     157        return 0;
     158}
     159
     160static int find_avp(msg_or_avp *where, int conf_index, int level, struct fd_list * candidates)
     161{
     162        struct dict_object *what;
     163        struct dict_avp_data dictdata;
     164        struct avp *nextavp = NULL;
     165        struct avp_hdr *avp_hdr = NULL;
     166
     167        /* iterate over all AVPs and try to find a match */
     168//      for (i = 0; i<rtereg_conf[j].level; i++) {
     169        if (level > rtereg_conf[conf_index].level) {
     170                TRACE_DEBUG(INFO, "internal error, dug too deep");
     171                return 1;
     172        }
     173        what = rtereg_conf[conf_index].avps[level];
     174
     175        CHECK_FCT(fd_dict_getval(what, &dictdata));
     176        CHECK_FCT(fd_msg_browse(where, MSG_BRW_FIRST_CHILD, (void *)&nextavp, NULL));
     177        while (nextavp) {
     178                CHECK_FCT(fd_msg_avp_hdr(nextavp, &avp_hdr));
     179                if ((avp_hdr->avp_code == dictdata.avp_code) && (avp_hdr->avp_vendor == dictdata.avp_vendor)) {
     180                        if (level != rtereg_conf[conf_index].level - 1) {
     181                                TRACE_DEBUG(INFO, "[rt_ereg] found grouped AVP %d (vendor %d), digging deeper", avp_hdr->avp_code, avp_hdr->avp_vendor);
     182                                CHECK_FCT(find_avp(nextavp, conf_index, level+1, candidates));
     183                        } else {
     184                                TRACE_DEBUG(INFO, "[rt_ereg] found AVP %d (vendor %d)", avp_hdr->avp_code, avp_hdr->avp_vendor);
     185                                if (avp_hdr->avp_value != NULL) {
     186#ifndef HAVE_REG_STARTEND
     187                                        int ret;
     188
     189                                        /* Lock the buffer */
     190                                        CHECK_POSIX( pthread_mutex_lock(&mtx) );
     191
     192                                        /* Augment the buffer if needed */
     193                                        if (avp_hdr->avp_value->os.len >= bufsz) {
     194                                                CHECK_MALLOC_DO( buf = realloc(buf, avp_hdr->avp_value->os.len + 1),
     195                                                        { pthread_mutex_unlock(&mtx); return ENOMEM; } );
     196                                        }
     197
     198                                        /* Copy the AVP value */
     199                                        memcpy(buf, avp_hdr->avp_value->os.data, avp_hdr->avp_value->os.len);
     200                                        buf[avp_hdr->avp_value->os.len] = '\0';
     201
     202                                        /* Now apply the rules */
     203                                        ret = proceed(buf, avp_hdr->avp_value->os.len, candidates, conf_index);
     204
     205                                        CHECK_POSIX(pthread_mutex_unlock(&mtx));
     206
     207                                        CHECK_FCT(ret);
     208#else /* HAVE_REG_STARTEND */
     209                                        CHECK_FCT( proceed((char *) avp_hdr->avp_value->os.data, avp_hdr->avp_value->os.len, candidates, conf_index) );
     210#endif /* HAVE_REG_STARTEND */
     211                                }
     212                        }
     213                }
     214                CHECK_FCT(fd_msg_browse(nextavp, MSG_BRW_NEXT, (void *)&nextavp, NULL));
     215        }
     216
    124217        return 0;
    125218}
     
    128221static int rtereg_out(void * cbdata, struct msg ** pmsg, struct fd_list * candidates)
    129222{
    130         struct msg * msg = *pmsg;
    131         struct avp * avp = NULL;
    132        
    133         TRACE_ENTRY("%p %p %p", cbdata, msg, candidates);
    134        
    135         CHECK_PARAMS(msg && candidates);
    136        
     223        msg_or_avp *where;
     224        int j, ret;
     225
     226        TRACE_ENTRY("%p %p %p", cbdata, *pmsg, candidates);
     227
     228        CHECK_PARAMS(pmsg && *pmsg && candidates);
     229
     230        if (pthread_rwlock_rdlock(&rte_lock) != 0) {
     231                fd_log_notice("%s: read-lock failed, skipping handler", MODULE_NAME);
     232                return 0;
     233        }
     234        ret = 0;
    137235        /* Check if it is worth processing the message */
    138         if (FD_IS_LIST_EMPTY(candidates)) {
    139                 return 0;
    140         }
    141        
    142         /* Now search the AVP in the message */
    143         CHECK_FCT( fd_msg_search_avp ( msg, rtereg_conf.avp, &avp ) );
    144         if (avp != NULL) {
    145                 struct avp_hdr * ahdr = NULL;
    146                 CHECK_FCT( fd_msg_avp_hdr ( avp, &ahdr ) );
    147                 if (ahdr->avp_value != NULL) {
    148 #ifndef HAVE_REG_STARTEND
    149                         int ret;
    150                
    151                         /* Lock the buffer */
    152                         CHECK_POSIX( pthread_mutex_lock(&mtx) );
    153                        
    154                         /* Augment the buffer if needed */
    155                         if (ahdr->avp_value->os.len >= bufsz) {
    156                                 CHECK_MALLOC_DO( buf = realloc(buf, ahdr->avp_value->os.len + 1),
    157                                         { pthread_mutex_unlock(&mtx); return ENOMEM; } );
     236        if (!FD_IS_LIST_EMPTY(candidates)) {
     237                /* Now search the AVPs in the message */
     238
     239                for (j=0; j<rtereg_conf_size; j++) {
     240                        where = *pmsg;
     241                        TRACE_DEBUG(INFO, "[rt_ereg] iterating over AVP group %d", j);
     242                        if ((ret=find_avp(where, j, 0, candidates)) != 0) {
     243                                break;
    158244                        }
    159                        
    160                         /* Copy the AVP value */
    161                         memcpy(buf, ahdr->avp_value->os.data, ahdr->avp_value->os.len);
    162                         buf[ahdr->avp_value->os.len] = '\0';
    163                        
    164                         /* Now apply the rules */
    165                         ret = proceed(buf, ahdr->avp_value->os.len, candidates);
    166                        
    167                         CHECK_POSIX(pthread_mutex_unlock(&mtx));
    168                        
    169                         CHECK_FCT(ret);
    170 #else /* HAVE_REG_STARTEND */
    171                         CHECK_FCT( proceed((char *) ahdr->avp_value->os.data, ahdr->avp_value->os.len, candidates) );
    172 #endif /* HAVE_REG_STARTEND */
    173                 }
    174         }
    175        
    176         return 0;
     245                }
     246        }
     247        if (pthread_rwlock_unlock(&rte_lock) != 0) {
     248                fd_log_notice("%s: read-unlock failed after rtereg_out, exiting", MODULE_NAME);
     249                exit(1);
     250        }
     251
     252        return ret;
    177253}
    178254
     
    180256static struct fd_rt_out_hdl * rtereg_hdl = NULL;
    181257
     258static volatile int in_signal_handler = 0;
     259
     260/* signal handler */
     261static void sig_hdlr(void)
     262{
     263        struct rtereg_conf *old_config;
     264        int old_config_size;
     265
     266        if (in_signal_handler) {
     267                fd_log_error("%s: already handling a signal, ignoring new one", MODULE_NAME);
     268                return;
     269        }
     270        in_signal_handler = 1;
     271
     272        if (pthread_rwlock_wrlock(&rte_lock) != 0) {
     273                fd_log_error("%s: locking failed, aborting config reload", MODULE_NAME);
     274                return;
     275        }
     276
     277        /* save old config in case reload goes wrong */
     278        old_config = rtereg_conf;
     279        old_config_size = rtereg_conf_size;
     280        rtereg_conf = NULL;
     281        rtereg_conf_size = 0;
     282
     283        if (rtereg_init_config() != 0) {
     284                fd_log_notice("%s: error reloading configuration, restoring previous configuration", MODULE_NAME);
     285                rtereg_conf = old_config;
     286                rtereg_conf_size = old_config_size;
     287        } else {
     288                rtereg_conf_free(old_config, old_config_size);
     289        }
     290
     291        if (pthread_rwlock_unlock(&rte_lock) != 0) {
     292                fd_log_error("%s: unlocking failed after config reload, exiting", MODULE_NAME);
     293                exit(1);
     294        }
     295
     296        fd_log_notice("%s: reloaded configuration, %d AVP group%s defined", MODULE_NAME, rtereg_conf_size, rtereg_conf_size != 1 ? "s" : "");
     297
     298        in_signal_handler = 0;
     299}
     300
    182301/* entry point */
    183302static int rtereg_entry(char * conffile)
    184303{
    185304        TRACE_ENTRY("%p", conffile);
    186        
     305
     306        rt_ereg_config_file = conffile;
     307
     308        if (rtereg_init() != 0) {
     309            return 1;
     310        }
     311
     312        /* Register reload callback */
     313        CHECK_FCT(fd_event_trig_regcb(SIGUSR1, MODULE_NAME, sig_hdlr));
     314
     315        fd_log_notice("%s: configured, %d AVP group%s defined", MODULE_NAME, rtereg_conf_size, rtereg_conf_size != 1 ? "s" : "");
     316
     317        return 0;
     318}
     319
     320static int rtereg_init_config(void)
     321{
    187322        /* Initialize the configuration */
    188         memset(&rtereg_conf, 0, sizeof(rtereg_conf));
    189        
     323        if ((rtereg_conf=malloc(sizeof(*rtereg_conf))) == NULL) {
     324            TRACE_DEBUG(INFO, "malloc failured");
     325            return 1;
     326        }
     327        rtereg_conf_size = 1;
     328        memset(rtereg_conf, 0, sizeof(*rtereg_conf));
     329
    190330        /* Parse the configuration file */
    191         CHECK_FCT( rtereg_conf_handle(conffile) );
    192        
     331        CHECK_FCT( rtereg_conf_handle(rt_ereg_config_file) );
     332
     333        return 0;
     334}
     335
     336
     337/* Load */
     338static int rtereg_init(void)
     339{
     340        int ret;
     341
     342        pthread_rwlock_init(&rte_lock, NULL);
     343
     344        if (pthread_rwlock_wrlock(&rte_lock) != 0) {
     345                fd_log_notice("%s: write-lock failed, aborting", MODULE_NAME);
     346                return EDEADLK;
     347        }
     348
     349        if ((ret=rtereg_init_config()) != 0) {
     350                pthread_rwlock_unlock(&rte_lock);
     351                return ret;
     352        }
     353
     354        if (pthread_rwlock_unlock(&rte_lock) != 0) {
     355                fd_log_notice("%s: write-unlock failed, aborting", MODULE_NAME);
     356                return EDEADLK;
     357        }
     358
    193359        /* Register the callback */
    194360        CHECK_FCT( fd_rt_out_register( rtereg_out, NULL, 1, &rtereg_hdl ) );
    195        
     361
    196362        /* We're done */
    197363        return 0;
     
    199365
    200366/* Unload */
    201 void fd_ext_fini(void)
    202 {
    203         int i;
     367static void rtereg_fini(void)
     368{
    204369        TRACE_ENTRY();
    205        
     370
    206371        /* Unregister the cb */
    207372        CHECK_FCT_DO( fd_rt_out_unregister ( rtereg_hdl, NULL ), /* continue */ );
    208        
     373
    209374        /* Destroy the data */
    210         if (rtereg_conf.rules)
    211                 for (i = 0; i < rtereg_conf.rules_nb; i++) {
    212                         free(rtereg_conf.rules[i].pattern);
    213                         free(rtereg_conf.rules[i].server);
    214                         regfree(&rtereg_conf.rules[i].preg);
    215                 }
    216         free(rtereg_conf.rules);
     375        rtereg_conf_free(rtereg_conf, rtereg_conf_size);
     376        rtereg_conf = NULL;
     377        rtereg_conf_size = 0;
    217378#ifndef HAVE_REG_STARTEND
    218379        free(buf);
     380        buf = NULL;
    219381#endif /* HAVE_REG_STARTEND */
    220        
     382
    221383        /* Done */
    222384        return ;
    223385}
    224386
    225 EXTENSION_ENTRY("rt_ereg", rtereg_entry);
     387void fd_ext_fini(void)
     388{
     389        rtereg_fini();
     390}
     391
     392EXTENSION_ENTRY(MODULE_NAME, rtereg_entry);
  • extensions/rt_ereg/rtereg.h

    r741 r1338  
    5858        int                     rules_nb; /* Number of rules in the configuration */
    5959        struct rtereg_rule      *rules;   /* The array of rules */
     60
     61        int                     level;    /* how many levels of AVPs we have to dig down into */
     62        int                     finished; /* AVP fully configured, for configuration file reading */
     63        struct dict_object      **avps;   /* cache the dictionary objects that we are searching */
    6064       
    61         struct dict_object * avp; /* cache the dictionary object that we are searching */
    62        
    63 } rtereg_conf;
     65} *rtereg_conf;
    6466
     67extern int rtereg_conf_size;
  • extensions/rt_ereg/rtereg_conf.y

    r1127 r1342  
    3838
    3939/* For development only : */
    40 %debug 
     40%debug
    4141%error-verbose
    4242
     
    4545
    4646/* Keep track of location */
    47 %locations 
     47%locations
    4848%pure-parser
    4949
     
    5454/* Forward declaration */
    5555int yyparse(char * conffile);
     56void rtereg_confrestart(FILE *input_file);
    5657
    5758/* Parse the configuration file */
     
    6061        extern FILE * rtereg_confin;
    6162        int ret;
    62        
     63
    6364        TRACE_ENTRY("%p", conffile);
    64        
     65
    6566        TRACE_DEBUG (FULL, "Parsing configuration file: %s...", conffile);
    66        
     67
    6768        rtereg_confin = fopen(conffile, "r");
    6869        if (rtereg_confin == NULL) {
    6970                ret = errno;
    7071                fd_log_debug("Unable to open extension configuration file %s for reading: %s", conffile, strerror(ret));
    71                 TRACE_DEBUG (INFO, "Error occurred, message logged -- configuration file.");
     72                TRACE_DEBUG (INFO, "rt_ereg: error occurred, message logged -- configuration file.");
    7273                return ret;
    7374        }
    7475
     76        rtereg_confrestart(rtereg_confin);
    7577        ret = yyparse(conffile);
    7678
    7779        fclose(rtereg_confin);
    7880
     81        if (rtereg_conf[rtereg_conf_size-1].finished == 0) {
     82                TRACE_DEBUG(INFO, "rt_ereg: configuration invalid, AVP ended without OCTETSTRING AVP");
     83                return EINVAL;
     84        }
     85
    7986        if (ret != 0) {
    80                 TRACE_DEBUG (INFO, "Unable to parse the configuration file.");
     87                TRACE_DEBUG(INFO, "rt_ereg: unable to parse the configuration file.");
    8188                return EINVAL;
    8289        } else {
    83                 TRACE_DEBUG(FULL, "[rt-ereg] Added %d rules successfully.", rtereg_conf.rules_nb);
    84         }
    85        
     90                int i, sum = 0;
     91                for (i=0; i<rtereg_conf_size; i++) {
     92                        sum += rtereg_conf[i].rules_nb;
     93                }
     94                TRACE_DEBUG(FULL, "[rt-ereg] Added %d rules successfully.", sum);
     95        }
     96
     97        return 0;
     98}
     99
     100int avp_add(const char *name)
     101{
     102        void *ret;
     103        int level;
     104
     105        if (rtereg_conf[rtereg_conf_size-1].finished) {
     106                if ((ret = realloc(rtereg_conf, sizeof(*rtereg_conf)*(rtereg_conf_size+1))) == NULL) {
     107                        TRACE_DEBUG(INFO, "rt_ereg: realloc failed");
     108                        return -1;
     109                }
     110                rtereg_conf_size++;
     111                rtereg_conf = ret;
     112                memset(&rtereg_conf[rtereg_conf_size-1], 0, sizeof(*rtereg_conf));
     113                TRACE_DEBUG(INFO, "rt_ereg: New AVP group found starting with %s", name);
     114        }
     115        level = rtereg_conf[rtereg_conf_size-1].level + 1;
     116
     117        if ((ret = realloc(rtereg_conf[rtereg_conf_size-1].avps, sizeof(*rtereg_conf[rtereg_conf_size-1].avps)*level)) == NULL) {
     118                TRACE_DEBUG(INFO, "rt_ereg: realloc failed");
     119                return -1;
     120        }
     121        rtereg_conf[rtereg_conf_size-1].avps = ret;
     122
     123        CHECK_FCT_DO( fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME_ALL_VENDORS, name, &rtereg_conf[rtereg_conf_size-1].avps[level-1], ENOENT ),
     124                      {
     125                              TRACE_DEBUG(INFO, "rt_ereg: Unable to find '%s' AVP in the loaded dictionaries.", name);
     126                              return -1;
     127                      } );
     128
     129        /* Now check the type */
     130        {
     131                struct dict_avp_data data;
     132                CHECK_FCT( fd_dict_getval( rtereg_conf[rtereg_conf_size-1].avps[level-1], &data) );
     133                if (data.avp_basetype == AVP_TYPE_OCTETSTRING) {
     134                        rtereg_conf[rtereg_conf_size-1].finished = 1;
     135                } else if (data.avp_basetype != AVP_TYPE_GROUPED) {
     136                        TRACE_DEBUG(INFO, "rt_ereg: '%s' AVP is not an OCTETSTRING nor GROUPED AVP (%d).", name, data.avp_basetype);
     137                        return -1;
     138                }
     139        }
     140        rtereg_conf[rtereg_conf_size-1].level = level;
    86141        return 0;
    87142}
     
    93148void yyerror (YYLTYPE *ploc, char * conffile, char const *s)
    94149{
    95         TRACE_DEBUG(INFO, "Error in configuration parsing");
    96        
     150        TRACE_DEBUG(INFO, "rt_ereg: error in configuration parsing");
     151
    97152        if (ploc->first_line != ploc->last_line)
    98153                fd_log_debug("%s:%d.%d-%d.%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_line, ploc->last_column, s);
     
    126181
    127182        /* The grammar definition */
    128 conffile:               rules avp rules
    129                         ;
    130                        
     183conffile:               avp rules
     184                        | conffile avp rules
     185                        ;
     186
    131187        /* a server entry */
    132 avp:                    AVP '=' QSTRING ';'
    133                         {
    134                                 if (rtereg_conf.avp != NULL) {
    135                                         yyerror(&yylloc, conffile, "Only one AVP can be specified");
    136                                         YYERROR;
    137                                 }
    138                                
    139                                 CHECK_FCT_DO( fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, $3, &rtereg_conf.avp, ENOENT ),
    140                                         {
    141                                                 TRACE_DEBUG(INFO, "Unable to find '%s' AVP in the loaded dictionaries.", $3);
    142                                                 yyerror (&yylloc, conffile, "Invalid AVP value.");
    143                                                 YYERROR;
    144                                         } );
    145                                
    146                                 /* Now check the type */
    147                                 {
    148                                         struct dict_avp_data data;
    149                                         CHECK_FCT( fd_dict_getval( rtereg_conf.avp, &data) );
    150                                         CHECK_PARAMS_DO (data.avp_basetype == AVP_TYPE_OCTETSTRING,
    151                                                 {
    152                                                         TRACE_DEBUG(INFO, "'%s' AVP in not an OCTETSTRING AVP (%d).", $3, data.avp_basetype);
    153                                                         yyerror (&yylloc, conffile, "AVP in not an OCTETSTRING type.");
    154                                                         YYERROR;
    155                                                 } );
    156                                 }
    157                         }
    158                         ;
    159                        
     188avp:                    AVP '=' avp_part ';'
     189                        ;
     190
     191avp_part:               avp_part ':' QSTRING { if (avp_add($3) < 0) { YYERROR; } }
     192                        | QSTRING { if (avp_add($1) < 0) { YYERROR; } }
     193                        ;
     194
    160195rules:                  /* empty OK */
    161196                        | rules rule
    162197                        ;
    163                        
     198
    164199rule:                   QSTRING ':' QSTRING '+' '=' INTEGER ';'
    165200                        {
    166201                                struct rtereg_rule * new;
    167202                                int err;
    168                                
     203
    169204                                /* Add new rule in the array */
    170                                 rtereg_conf.rules_nb += 1;
    171                                 CHECK_MALLOC_DO(rtereg_conf.rules = realloc(rtereg_conf.rules, rtereg_conf.rules_nb * sizeof(struct rtereg_rule)),
     205                                rtereg_conf[rtereg_conf_size-1].rules_nb += 1;
     206                                CHECK_MALLOC_DO(rtereg_conf[rtereg_conf_size-1].rules = realloc(rtereg_conf[rtereg_conf_size-1].rules, rtereg_conf[rtereg_conf_size-1].rules_nb * sizeof(struct rtereg_rule)),
    172207                                        {
    173208                                                yyerror (&yylloc, conffile, "Not enough memory to store the configuration...");
    174209                                                YYERROR;
    175210                                        } );
    176                                
    177                                 new = &rtereg_conf.rules[rtereg_conf.rules_nb - 1];
    178                                
     211
     212                                new = &rtereg_conf[rtereg_conf_size-1].rules[rtereg_conf[rtereg_conf_size-1].rules_nb - 1];
     213
    179214                                new->pattern = $1;
    180215                                new->server  = $3;
    181216                                new->score   = $6;
    182                                
     217
    183218                                /* Attempt to compile the regex */
    184219                                CHECK_FCT_DO( err=regcomp(&new->preg, new->pattern, REG_EXTENDED | REG_NOSUB),
     
    188223
    189224                                                /* Error while compiling the regex */
    190                                                 TRACE_DEBUG(INFO, "Error while compiling the regular expression '%s':", new->pattern);
     225                                                TRACE_DEBUG(INFO, "rt_ereg: error while compiling the regular expression '%s':", new->pattern);
    191226
    192227                                                /* Get the error message size */
     
    199234                                                regerror(err, &new->preg, buf, bl);
    200235                                                TRACE_DEBUG(INFO, "\t%s", buf);
    201                                                
     236
    202237                                                /* Free the buffer, return the error */
    203238                                                free(buf);
    204                                                
     239
    205240                                                yyerror (&yylloc, conffile, "Invalid regular expression.");
    206241                                                YYERROR;
  • freeDiameterd/main.c

    r1305 r1339  
    3434*********************************************************************************************************/
    3535
     36#if defined(__GLIBC__)
     37#define _BSD_SOURCE /* for vsyslog */
     38#endif
     39
    3640#include <freeDiameter/freeDiameter-host.h>
    3741#include <freeDiameter/libfdcore.h>
     
    4044#include <getopt.h>
    4145#include <locale.h>
    42 
     46#include <syslog.h>
     47#include <stdarg.h>
    4348
    4449/* forward declarations */
     
    5661
    5762
     63static void syslog_logger(int loglevel, const char * format, va_list args)
     64{
     65        int level;
     66
     67        switch (loglevel) {
     68        case FD_LOG_NOTICE:
     69                level = LOG_NOTICE;
     70                break;
     71        case FD_LOG_ERROR:
     72                level = LOG_ERR;
     73                break;
     74        case FD_LOG_FATAL:
     75                level = LOG_CRIT;
     76                break;
     77        default:
     78                /* fallthrough */
     79        case FD_LOG_DEBUG:
     80                /* some systems log LOG_DEBUG to a file; but
     81                 * freeDiameter debug output is too verbose */
     82                return;
     83#if 0
     84                level = LOG_DEBUG;
     85                break;
     86#endif
     87        }
     88
     89        vsyslog(level, format, args);
     90}
     91
     92
    5893/* freeDiameter starting point */
    5994int main(int argc, char * argv[])
     
    6196        int ret;
    6297        sigset_t sig_all;
    63        
     98
    6499        /* Block all signals from the current thread and all its future children -- we will catch everything in catch_signals */
    65100        sigfillset(&sig_all);
    66101        ret = pthread_sigmask(SIG_BLOCK, &sig_all, NULL);
    67102        ASSERT(ret == 0);
    68        
     103
    69104        /* Parse the command-line */
    70105        ret = main_cmdline(argc, argv);
     
    72107                return ret;
    73108        }
    74        
     109
    75110        /* Initialize the core library */
    76111        ret = fd_core_initialize();
     
    79114                return ret;
    80115        }
    81        
     116
    82117        /* Set gnutls debug level ? */
    83118        if (gnutls_debug) {
     
    86121                TRACE_DEBUG(INFO, "Enabled GNUTLS debug at level %d", gnutls_debug);
    87122        }
    88        
     123
    89124        /* Parse the configuration file */
    90125        CHECK_FCT_DO( fd_core_parseconf(conffile), goto error );
    91        
     126
    92127        /* Start the servers */
    93128        CHECK_FCT_DO( fd_core_start(), goto error );
    94        
     129
    95130        /* Allow SIGINT and SIGTERM from this point to terminate the application */
    96131        CHECK_POSIX_DO( pthread_create(&signals_thr, NULL, catch_signals, NULL), goto error );
    97        
     132
    98133        TRACE_DEBUG(INFO, FD_PROJECT_BINARY " daemon initialized.");
    99134
    100135        /* Now, just wait for termination */
    101136        CHECK_FCT( fd_core_wait_shutdown_complete() );
    102        
     137
    103138        /* Just in case it was not the result of a signal, we cancel signals_thr */
    104139        fd_thr_term(&signals_thr);
    105        
     140
    106141        return 0;
    107 error: 
     142error:
    108143        CHECK_FCT_DO( fd_core_shutdown(),  );
    109144        CHECK_FCT( fd_core_wait_shutdown_complete() );
     
    138173                "  -V, --version          Print version and exit\n"
    139174                "  -c, --config=filename  Read configuration from this file instead of the \n"
    140                 "                           default location (" DEFAULT_CONF_PATH "/" FD_DEFAULT_CONF_FILENAME ").\n");
     175                "                           default location (" DEFAULT_CONF_PATH "/" FD_DEFAULT_CONF_FILENAME ").\n"
     176                "  -s, --syslog            Write log output to syslog (instead of stdout)\n");
    141177        printf( "\nDebug:\n"
    142178                "  These options are mostly useful for developers\n"
     
    156192        int option_index = 0;
    157193        char * locale;
    158        
     194
    159195        struct option long_options[] = {
    160196                { "help",       no_argument,            NULL, 'h' },
    161197                { "version",    no_argument,            NULL, 'V' },
    162198                { "config",     required_argument,      NULL, 'c' },
     199                { "syslog",     no_argument,            NULL, 's' },
    163200                { "debug",      no_argument,            NULL, 'd' },
    164201                { "quiet",      no_argument,            NULL, 'q' },
     
    169206                { NULL,         0,                      NULL, 0 }
    170207        };
    171        
     208
    172209        /* Loop on arguments */
    173210        while (1) {
    174                 c = getopt_long (argc, argv, "hVc:dql:f:F:g:", long_options, &option_index);
    175                 if (c == -1) 
     211                c = getopt_long (argc, argv, "hVc:dql:f:F:g:s", long_options, &option_index);
     212                if (c == -1)
    176213                        break;  /* Exit from the loop.  */
    177                
     214
    178215                switch (c) {
    179216                        case 'h':       /* Print help and exit.  */
     
    200237                                }
    201238                                break;
    202                                
     239
    203240                        case 'd':       /* Increase verbosity of debug messages.  */
    204241                                fd_g_debug_lvl--;
    205242                                break;
    206                                
     243
    207244                        case 'f':       /* Full debug for the function with this name.  */
    208245                                #ifdef DEBUG
     
    214251                                #endif /* DEBUG */
    215252                                break;
    216                                
     253
    217254                        case 'F':       /* Full debug for the file with this name.  */
    218255                                #ifdef DEBUG
     
    224261                                #endif /* DEBUG */
    225262                                break;
    226                                
     263
    227264                        case 'g':       /* Set a debug level and function for GNU TLS calls.  */
    228265                                gnutls_debug = (int)atoi(optarg);
    229266                                break;
    230                                
     267
    231268                        case 'q':       /* Decrease verbosity then remove debug messages.  */
    232269                                fd_g_debug_lvl++;
     270                                break;
     271
     272                        case 's':       /* Write log data using syslog(3) */
     273                                if (fd_log_handler_register(syslog_logger) != 0) {
     274                                        fprintf(stderr, "Cannot initialize syslog logger\n");
     275                                        return EINVAL;
     276                                }
    233277                                break;
    234278
     
    244288                }
    245289        }
    246                
     290
    247291        return 0;
    248292}
     
    253297        sigset_t ss;
    254298        fd_log_threadname ( "signals catcher" );
    255        
     299
    256300        sigemptyset(&ss);
    257        
     301
    258302        /* Signals that terminate the daemon */
    259303        sigaddset(&ss, SIGTERM);
    260304        sigaddset(&ss, SIGINT);
    261        
     305
    262306        /* Signals that send an event */
    263307        sigaddset(&ss, SIGUSR1);
    264308        sigaddset(&ss, SIGUSR2);
    265        
     309
    266310        /* We unblock all other signals, so that their default handler is used (such as SIGTSTP) */
    267311        CHECK_SYS_DO( pthread_sigmask( SIG_SETMASK, &ss, NULL ), goto out );
    268        
     312
    269313        /* Now loop on the reception of the signal */
    270314        while (1) {
    271315                int sig, *ps;
    272                
     316
    273317                /* Wait to receive the next signal */
    274318                CHECK_POSIX_DO( sigwait(&ss, &sig), break );
    275                
     319
    276320                TRACE_DEBUG(FULL, "Signal %d caught", sig);
    277                
     321
    278322                switch (sig) {
    279323                        case SIGUSR1:
     
    283327                                CHECK_FCT_DO( fd_event_send(fd_g_config->cnf_main_ev, FDEV_TRIGGER, sizeof(int), ps), goto out );
    284328                                break;
    285                                
     329
    286330                        case SIGINT:
    287331                        case SIGTERM:
     
    290334                }
    291335        }
    292 out:   
     336out:
    293337        /* Better way to handle this ? */
    294338        ASSERT(0);
  • include/freeDiameter/CMakeLists.txt

    r1295 r1333  
    1818# In DEBUG mode, each log can contain pid, calling function and file for easy debug. Set to ON to display this information.
    1919OPTION(DEBUG_WITH_META "Show calling location in logs?" OFF)
    20        
     20
    2121# Create the absolute path for searching extensions
    2222SET(DEFAULT_EXTENSIONS_PATH ${CMAKE_INSTALL_PREFIX}/${INSTALL_EXTENSIONS_SUFFIX})
     
    3232OPTION(DISABLE_PEER_EXPIRY "Disable RFC3539 Peers Connections Expiration after inactivity?" OFF)
    3333
    34 # The following workaround increases compatibility with some implementations without breaking anything in freeDiameter, 
    35 # so it can be enabled without risk. We keep it disabled by default anyway for those people who use freeDiameter to check the 
     34# The following workaround increases compatibility with some implementations without breaking anything in freeDiameter,
     35# so it can be enabled without risk. We keep it disabled by default anyway for those people who use freeDiameter to check the
    3636# compliancy of their implementation with the Diameter RFC...
    3737OPTION(WORKAROUND_ACCEPT_INVALID_VSAI "Do not reject a CER/CEA with a Vendor-Specific-Application-Id AVP containing both Auth- and Acct- application AVPs?" OFF)
     
    4545INCLUDE (CheckFunctionExists)
    4646INCLUDE (CheckIncludeFiles)
    47 INCLUDE (CheckSymbolExists) 
     47INCLUDE (CheckSymbolExists)
    4848INCLUDE (CheckCSourceCompiles)
    4949INCLUDE (TestBigEndian)
     
    134134
    135135# IDNA process: we use libidn from GNU (unless the function & header files are included in libc)
    136 IF(NOT DIAMID_IDNA_IGNORE  AND NOT DIAMID_IDNA_REJECT)
     136IF(NOT DIAMID_IDNA_IGNORE AND NOT DIAMID_IDNA_REJECT)
    137137        FIND_PACKAGE(IDNA)
    138138        SET(CHECK_IDNA_SOURCE_CODE "
     
    160160SET(GNUTLS_LIBRARIES ${GNUTLS_LIBRARIES} PARENT_SCOPE)
    161161
    162 find_path(GCRYPT_INCLUDE_DIR NAMES gcrypt.h)
    163 If ( NOT GCRYPT_INCLUDE_DIR )
     162FIND_PATH(GCRYPT_INCLUDE_DIR NAMES gcrypt.h)
     163IF(NOT GCRYPT_INCLUDE_DIR)
    164164        MESSAGE(SEND_ERROR "Unable to find gcrypt.h, please install libgcrypt-dev or equivalent")
    165 Endif ( NOT GCRYPT_INCLUDE_DIR )
     165ENDIF(NOT GCRYPT_INCLUDE_DIR)
    166166MARK_AS_ADVANCED(GCRYPT_INCLUDE_DIR)
    167167SET(GCRYPT_INCLUDE_DIR ${GCRYPT_INCLUDE_DIR} PARENT_SCOPE)
    168168
    169169# Also we need libgcrypt to... display its version :(
    170 find_library(GCRYPT_LIBRARY
     170FIND_LIBRARY(GCRYPT_LIBRARY
    171171  NAMES gcrypt
    172172)
    173 If ( NOT GCRYPT_LIBRARY )
     173IF(NOT GCRYPT_LIBRARY)
    174174        MESSAGE(SEND_ERROR "Unable to find libgcrypt, please install libgcrypt or equivalent")
    175 Endif ( NOT GCRYPT_LIBRARY )
     175ENDIF(NOT GCRYPT_LIBRARY)
    176176SET(GCRYPT_LIBRARY ${GCRYPT_LIBRARY} PARENT_SCOPE)
    177177
     
    229229SET(LFDCORE_INCLUDES ${SCTP_INCLUDE_DIR} ${GNUTLS_INCLUDE_DIR} ${GCRYPT_INCLUDE_DIR} PARENT_SCOPE)
    230230# And dependencies
    231 SET(LFDCORE_LINK_INTERFACES "" PARENT_SCOPE) 
     231SET(LFDCORE_LINK_INTERFACES "" PARENT_SCOPE)
    232232                # We don't force other libraries, the programs will link with what it needs
    233233                # (such as libgnutls if it uses GNUTLS_DEBUG() macro
  • libfdcore/sctp.c

    r1268 r1332  
    401401                        fd_log_debug( "              sctp_shutdown_event         : %hhu", event.sctp_shutdown_event);
    402402                        fd_log_debug( "              sctp_partial_delivery_event : %hhu", event.sctp_partial_delivery_event);
    403                         fd_log_debug( "              sctp_adaptation_layer_event : %hhu", event.sctp_adaptation_layer_event);
     403                        // fd_log_debug( "                   sctp_adaptation_layer_event : %hhu", event.sctp_adaptation_layer_event);
    404404                        // fd_log_debug( "             sctp_authentication_event    : %hhu", event.sctp_authentication_event);
    405405                }
  • libfdcore/sctp3436.c

    r1190 r1344  
    5151 - the push function sends the data on a certain stream.
    5252 We also have a demux thread that reads the socket and store received data in the appropriate fifo
    53  
     53
    5454 We have one gnutls_session per stream pair, and as many threads that read the gnutls records and save incoming data to the target queue.
    55  
     55
    5656This complexity is required because we cannot read a socket for a given stream only; we can only get the next message and find its stream.
    5757*/
     
    7171        int       event;
    7272        uint16_t  strid;
    73        
     73
    7474        TRACE_ENTRY("%p", arg);
    7575        CHECK_PARAMS_DO(conn && (conn->cc_socket > 0), goto out);
    76        
     76
    7777        /* Set the thread name */
    7878        {
    79                 char buf[48];
     79                char buf[100];
    8080                snprintf(buf, sizeof(buf), "Demuxer (%d:%s)", conn->cc_socket, conn->cc_remid);
    8181                fd_log_threadname ( buf );
    8282        }
    83        
     83
    8484        ASSERT( conn->cc_proto == IPPROTO_SCTP );
    8585        ASSERT( fd_cnx_target_queue(conn) );
    8686        ASSERT( conn->cc_sctp3436_data.array );
    87        
     87
    8888        do {
    8989                CHECK_FCT_DO( fd_sctp_recvmeta(conn, &strid, &buf, &bufsz, &event), goto fatal );
     
    9898                                }
    9999                                break;
    100                                
     100
    101101                        case FDEVP_CNX_EP_CHANGE:
    102102                                /* Send this event to the target queue */
    103103                                CHECK_FCT_DO( fd_event_send( fd_cnx_target_queue(conn), event, bufsz, buf), goto fatal );
    104104                                break;
    105                        
     105
    106106                        case FDEVP_CNX_ERROR:
    107107                                goto out;
    108                                
     108
    109109                        case FDEVP_CNX_SHUTDOWN:
    110110                                /* Just ignore the notification for now, we will get another error later anyway */
    111111                                continue;
    112                                
     112
    113113                        default:
    114114                                goto fatal;
    115115                }
    116                
     116
    117117        } while (conn->cc_loop);
    118        
     118
    119119out:
    120120        /* Signal termination of the connection to all decipher threads */
     
    125125        }
    126126        fd_cnx_markerror(conn);
    127         TRACE_DEBUG(FULL, "Thread terminated"); 
     127        TRACE_DEBUG(FULL, "Thread terminated");
    128128        return NULL;
    129        
     129
    130130fatal:
    131131        /* An unrecoverable error occurred, stop the daemon */
     
    139139        struct sctp3436_ctx * ctx = arg;
    140140        struct cnxctx    *cnx;
    141        
     141
    142142        TRACE_ENTRY("%p", arg);
    143143        CHECK_PARAMS_DO(ctx && ctx->raw_recv && ctx->parent, goto error);
    144144        cnx = ctx->parent;
    145145        ASSERT( fd_cnx_target_queue(cnx) );
    146        
     146
    147147        /* Set the thread name */
    148148        {
    149                 char buf[48];
     149                char buf[100];
    150150                snprintf(buf, sizeof(buf), "Decipher (%hu@%d:%s)", ctx->strid, cnx->cc_socket, cnx->cc_remid);
    151151                fd_log_threadname ( buf );
    152152        }
    153        
     153
    154154        /* The next function loops while there is no error */
    155155        CHECK_FCT_DO(fd_tls_rcvthr_core(cnx, ctx->strid ? ctx->session : cnx->cc_tls_para.session), /* continue */);
    156156error:
    157157        fd_cnx_markerror(cnx);
    158         TRACE_DEBUG(FULL, "Thread terminated"); 
     158        TRACE_DEBUG(FULL, "Thread terminated");
    159159        return NULL;
    160160}
     
    171171        struct timespec tsstore, *ts = NULL;
    172172        int ret;
    173        
     173
    174174        TRACE_ENTRY("%p %d", tr, ms);
    175        
     175
    176176        if (ctx->partial.buf)
    177177                return 1; /* data is already available for pull */
    178        
     178
    179179        if (ms) {
    180180                CHECK_SYS_DO(  clock_gettime(CLOCK_REALTIME, &tsstore),  return -1  );
     
    184184                ts = &tsstore;
    185185        }
    186        
     186
    187187        ret = fd_fifo_select ( ctx->raw_recv, ts );
    188188        if (ret < 0) {
     
    190190                ret = -1;
    191191        }
    192                
     192
    193193        return ret;
    194194}
     
    201201        struct sctp3436_ctx * ctx = (struct sctp3436_ctx *) tr;
    202202        struct iovec iov;
    203        
     203
    204204        TRACE_ENTRY("%p %p %zd", tr, data, len);
    205205        CHECK_PARAMS_DO( tr && data, { errno = EINVAL; return -1; } );
    206        
     206
    207207        iov.iov_base = (void *)data;
    208208        iov.iov_len  = len;
    209        
     209
    210210        return fd_sctp_sendstrv(ctx->parent, ctx->strid, &iov, 1);
    211211}
     
    214214{
    215215        struct sctp3436_ctx * ctx = (struct sctp3436_ctx *) tr;
    216        
     216
    217217        TRACE_ENTRY("%p %p %d", tr, iov, iovcnt);
    218218        CHECK_PARAMS_DO( tr && iov, { errno = EINVAL; return -1; } );
    219        
     219
    220220        return fd_sctp_sendstrv(ctx->parent, ctx->strid, (const struct iovec *)iov, iovcnt);
    221221}
     
    228228        size_t pulled = 0;
    229229        int emptied;
    230        
     230
    231231        TRACE_ENTRY("%p %p %zd", tr, buf, len);
    232232        CHECK_PARAMS_DO( tr && buf, { errno = EINVAL; goto error; } );
    233        
     233
    234234        /* If we don't have data available now, pull new message from the fifo -- this is blocking (until the queue is destroyed) */
    235235        if (!ctx->partial.buf) {
     
    241241                }
    242242        }
    243                
     243
    244244        pulled = ctx->partial.bufsz - ctx->partial.offset;
    245245        if (pulled <= len) {
     
    264264        /* We are done */
    265265        return pulled;
    266        
     266
    267267error:
    268268        gnutls_transport_set_errno (ctx->session, errno);
     
    278278        /* Set the transport pointer passed to push & pull callbacks */
    279279        GNUTLS_TRACE( gnutls_transport_set_ptr( session, (gnutls_transport_ptr_t) ctx ) );
    280        
     280
    281281        /* Reset the low water value, since we don't use sockets */
    282282#ifndef GNUTLS_VERSION_300
     
    287287        GNUTLS_TRACE( gnutls_transport_set_pull_timeout_function( session, sctp3436_pull_timeout ) );
    288288#endif /* GNUTLS_VERSION_300 */
    289        
     289
    290290        /* Set the push and pull callbacks */
    291291        GNUTLS_TRACE( gnutls_transport_set_pull_function(session, sctp3436_pull) );
     
    325325        TRACE_ENTRY("%p", conn);
    326326        CHECK_PARAMS( conn && !conn->cc_sctp3436_data.sess_store );
    327        
     327
    328328        CHECK_MALLOC( conn->cc_sctp3436_data.sess_store = malloc(sizeof(struct sr_store)) );
    329329        memset(conn->cc_sctp3436_data.sess_store, 0, sizeof(struct sr_store));
    330        
     330
    331331        fd_list_init(&conn->cc_sctp3436_data.sess_store->list, NULL);
    332332        CHECK_POSIX( pthread_rwlock_init(&conn->cc_sctp3436_data.sess_store->lock, NULL) );
    333333        conn->cc_sctp3436_data.sess_store->parent = conn;
    334        
     334
    335335        return 0;
    336336}
     
    342342        TRACE_ENTRY("%p", conn);
    343343        CHECK_PARAMS_DO( conn, return );
    344        
     344
    345345        if (!conn->cc_sctp3436_data.sess_store)
    346346                return;
    347        
     347
    348348        CHECK_POSIX_DO( pthread_rwlock_destroy(&conn->cc_sctp3436_data.sess_store->lock), /* continue */ );
    349        
     349
    350350        while (!FD_IS_LIST_EMPTY(&conn->cc_sctp3436_data.sess_store->list)) {
    351351                struct sr_data * sr = (struct sr_data *) conn->cc_sctp3436_data.sess_store->list.next;
     
    355355                free(sr);
    356356        }
    357        
     357
    358358        free(conn->cc_sctp3436_data.sess_store);
    359359        conn->cc_sctp3436_data.sess_store = NULL;
     
    366366        struct fd_list * ret;
    367367        *match = 0;
    368        
     368
    369369        for (ret = sto->list.next; ret != &sto->list; ret = ret->next) {
    370370                int cmp = 0;
    371371                struct sr_data * sr = (struct sr_data *)ret;
    372                
     372
    373373                cmp = fd_os_cmp(key.data, key.size, sr->key.data, sr->key.size);
    374374                if (cmp > 0)
    375375                        continue;
    376                
     376
    377377                if (cmp == 0)
    378378                        *match = 1;
    379                
     379
    380380                break;
    381381        }
    382        
     382
    383383        return ret;
    384384}
     
    392392        int match = 0;
    393393        int ret = 0;
    394        
     394
    395395        TRACE_DEBUG( GNUTLS_DBG_LEVEL, "GNUTLS Callback: %s", __PRETTY_FUNCTION__ );
    396396        CHECK_PARAMS_DO( sto && key.data && data.data, return -1 );
    397        
     397
    398398        CHECK_POSIX_DO( pthread_rwlock_wrlock(&sto->lock), return -1 );
    399399        TRACE_BUFFER(FD_LOG_DEBUG, GNUTLS_DBG_LEVEL, "Session store [key ", key.data, key.size, "]");
    400        
     400
    401401        li = find_or_next(sto, key, &match);
    402402        if (match) {
    403403                sr = (struct sr_data *)li;
    404                
     404
    405405                /* Check the data is the same */
    406406                if ((data.size != sr->data.size) || memcmp(data.data, sr->data.data, data.size)) {
     
    409409                        TRACE_BUFFER(FD_LOG_DEBUG, INFO, "  -- old data [", sr->data.data, sr->data.size, "]");
    410410                        TRACE_BUFFER(FD_LOG_DEBUG, INFO, "  -- new data [", data.data, data.size, "]");
    411                        
     411
    412412                        ret = -1;
    413413                } else {
     
    416416                goto out;
    417417        }
    418        
     418
    419419        /* Create a new entry */
    420420        CHECK_MALLOC_DO( sr = malloc(sizeof(struct sr_data)), { ret = -1; goto out; } );
     
    430430        sr->data.size = data.size;
    431431        memcpy(sr->data.data, data.data, data.size);
    432        
     432
    433433        /* Save this new entry in the list, we are done */
    434434        fd_list_insert_before(li, &sr->chain);
    435435
    436 out:   
     436out:
    437437        CHECK_POSIX_DO( pthread_rwlock_unlock(&sto->lock), return -1 );
    438438        return ret;
     
    446446        int match = 0;
    447447        int ret = 0;
    448        
     448
    449449        TRACE_DEBUG( GNUTLS_DBG_LEVEL, "GNUTLS Callback: %s", __PRETTY_FUNCTION__ );
    450450        CHECK_PARAMS_DO( sto && key.data, return -1 );
    451        
     451
    452452        CHECK_POSIX_DO( pthread_rwlock_wrlock(&sto->lock), return -1 );
    453453        TRACE_BUFFER(FD_LOG_DEBUG, GNUTLS_DBG_LEVEL, "Session delete [key ", key.data, key.size, "]");
    454        
     454
    455455        li = find_or_next(sto, key, &match);
    456456        if (match) {
    457457                sr = (struct sr_data *)li;
    458                
     458
    459459                /* Destroy this data */
    460460                fd_list_unlink(li);
     
    466466                ret = -1;
    467467        }
    468        
     468
    469469        CHECK_POSIX_DO( pthread_rwlock_unlock(&sto->lock), return -1 );
    470470        return ret;
     
    485485        CHECK_POSIX_DO( pthread_rwlock_rdlock(&sto->lock), return error );
    486486        TRACE_BUFFER(FD_LOG_DEBUG, GNUTLS_DBG_LEVEL, "Session fetch [key ", key.data, key.size, "]");
    487        
     487
    488488        li = find_or_next(sto, key, &match);
    489489        if (match) {
     
    493493                memcpy(res.data, sr->data.data, res.size);
    494494        }
    495 out:   
     495out:
    496496        TRACE_DEBUG(GNUTLS_DBG_LEVEL, "Fetched (%p, %d) from store %p", res.data, res.size, sto);
    497497        CHECK_POSIX_DO( pthread_rwlock_unlock(&sto->lock), return error);
     
    503503{
    504504        TRACE_ENTRY("%p", conn);
    505        
     505
    506506        GNUTLS_TRACE( gnutls_db_set_retrieve_function(session, sr_fetch));
    507507        GNUTLS_TRACE( gnutls_db_set_remove_function  (session, sr_remove));
    508508        GNUTLS_TRACE( gnutls_db_set_store_function   (session, sr_store));
    509509        GNUTLS_TRACE( gnutls_db_set_ptr              (session, conn->cc_sctp3436_data.sess_store));
    510        
     510
    511511        return;
    512512}
     
    517517        struct sctp3436_ctx * ctx = (struct sctp3436_ctx *) arg;
    518518        int resumed;
    519        
     519
    520520        TRACE_ENTRY("%p", arg);
    521        
     521
    522522        /* Set the thread name */
    523523        {
     
    526526                fd_log_threadname ( buf );
    527527        }
    528        
     528
    529529        TRACE_DEBUG(FULL, "Starting TLS resumed handshake on stream %hu", ctx->strid);
    530530
    531531        CHECK_GNUTLS_DO( gnutls_handshake( ctx->session ), return NULL);
    532                        
     532
    533533        GNUTLS_TRACE( resumed = gnutls_session_is_resumed(ctx->session) );
    534534        #ifndef GNUTLS_VERSION_300
     
    545545                }
    546546        }
    547                        
     547
    548548        /* Finished, OK */
    549549        return arg;
     
    559559{
    560560        uint16_t i;
    561        
     561
    562562        TRACE_ENTRY("%p", conn);
    563563        CHECK_PARAMS( conn && (conn->cc_sctp_para.pairs > 1) && (!conn->cc_sctp3436_data.array) );
    564        
     564
    565565        /* First, alloc the array and initialize the non-TLS data */
    566566        CHECK_MALLOC( conn->cc_sctp3436_data.array = calloc(conn->cc_sctp_para.pairs, sizeof(struct sctp3436_ctx))  );
     
    570570                CHECK_FCT( fd_fifo_new(&conn->cc_sctp3436_data.array[i].raw_recv, 10) );
    571571        }
    572        
     572
    573573        /* Set push/pull functions in the master session, using fifo in array[0] */
    574574        set_sess_transport(conn->cc_tls_para.session, &conn->cc_sctp3436_data.array[0]);
    575        
     575
    576576        /* For server side, we also initialize the resuming capabilities */
    577577        if (conn->cc_tls_para.mode == GNUTLS_SERVER) {
    578                
     578
    579579                /* Prepare the store for sessions data */
    580580                CHECK_FCT( store_init(conn) );
    581                
     581
    582582                /* Set the callbacks for resuming in the master session */
    583583                set_resume_callbacks(conn->cc_tls_para.session, conn);
     
    586586        /* Start the demux thread */
    587587        CHECK_POSIX( pthread_create( &conn->cc_rcvthr, NULL, demuxer, conn ) );
    588        
     588
    589589        return 0;
    590590}
     
    596596        int errors = 0;
    597597        gnutls_datum_t  master_data;
    598        
     598
    599599        TRACE_ENTRY("%p %p", conn, priority);
    600600        CHECK_PARAMS( conn && (conn->cc_sctp_para.pairs > 1) && conn->cc_sctp3436_data.array );
     
    602602        /* Server side: we set all the parameters, the resume callback will take care of resuming the session */
    603603        /* Client side: we duplicate the parameters of the master session, then set the transport pointer */
    604        
     604
    605605        /* For client side, retrieve the master session parameters */
    606606        if (conn->cc_tls_para.mode == GNUTLS_CLIENT) {
     
    614614                }
    615615        }
    616        
     616
    617617        /* Initialize the session objects and start the handshake in a separate thread */
    618618        for (i = 1; i < conn->cc_sctp_para.pairs; i++) {
    619619                /* Set credentials and priority */
    620620                CHECK_FCT( fd_tls_prepare(&conn->cc_sctp3436_data.array[i].session, conn->cc_tls_para.mode, 0, priority, alt_creds) );
    621                
     621
    622622                /* additional initialization for gnutls 3.x */
    623623                #ifdef GNUTLS_VERSION_300
     
    644644                        set_resume_callbacks(conn->cc_sctp3436_data.array[i].session, conn);
    645645                }
    646                
     646
    647647                /* Set transport parameters */
    648648                set_sess_transport(conn->cc_sctp3436_data.array[i].session, &conn->cc_sctp3436_data.array[i]);
    649                
     649
    650650                /* Start the handshake thread */
    651651                CHECK_POSIX( pthread_create( &conn->cc_sctp3436_data.array[i].thr, NULL, handshake_resume_th, &conn->cc_sctp3436_data.array[i] ) );
    652652        }
    653        
     653
    654654        /* We can now release the memory of master session data if any */
    655655        if (conn->cc_tls_para.mode == GNUTLS_CLIENT) {
    656656                GNUTLS_TRACE( gnutls_free(master_data.data) );
    657657        }
    658        
     658
    659659        /* Now wait for all handshakes to finish */
    660660        for (i = 1; i < conn->cc_sctp_para.pairs; i++) {
     
    666666                }
    667667        }
    668        
     668
    669669        if (errors) {
    670670                TRACE_DEBUG(INFO, "Handshake failed on %d/%hd stream pairs", errors, conn->cc_sctp_para.pairs);
     
    672672                return ENOTCONN;
    673673        }
    674        
     674
    675675        return 0;
    676676}
     
    680680{
    681681        uint16_t i;
    682        
     682
    683683        TRACE_ENTRY("%p", conn);
    684684        CHECK_PARAMS( conn && conn->cc_sctp3436_data.array );
    685        
     685
    686686        if (others) {
    687687                for (i = 1; i < conn->cc_sctp_para.pairs; i++) {
     
    700700{
    701701        uint16_t i;
    702        
     702
    703703        CHECK_PARAMS_DO( conn && conn->cc_sctp3436_data.array, return );
    704        
     704
    705705        /* End all TLS sessions, in series (not as efficient as paralel, but simpler) */
    706706        for (i = 1; i < conn->cc_sctp_para.pairs; i++) {
     
    715715{
    716716        uint16_t i;
    717        
     717
    718718        TRACE_ENTRY("%p", conn);
    719719        CHECK_PARAMS_DO( conn && conn->cc_sctp3436_data.array, return );
    720        
     720
    721721        for (i = 0; i < conn->cc_sctp_para.pairs; i++) {
    722722                if (conn->cc_sctp3436_data.array[i].thr != (pthread_t)NULL) {
     
    732732{
    733733        uint16_t i;
    734        
     734
    735735        TRACE_ENTRY("%p", conn);
    736736        CHECK_PARAMS_DO( conn && conn->cc_sctp3436_data.array, return );
    737        
     737
    738738        for (i = 1; i < conn->cc_sctp_para.pairs; i++) {
    739739                if (conn->cc_sctp3436_data.array[i].session) {
     
    749749{
    750750        uint16_t i;
    751        
     751
    752752        TRACE_ENTRY("%p", conn);
    753753        CHECK_PARAMS_DO( conn && conn->cc_sctp3436_data.array, return );
    754        
     754
    755755        for (i = 0; i < conn->cc_sctp_para.pairs; i++) {
    756756                CHECK_FCT_DO( fd_thr_term(&conn->cc_sctp3436_data.array[i].thr), /* continue */ );
     
    763763{
    764764        uint16_t i;
    765        
     765
    766766        CHECK_PARAMS_DO( conn && conn->cc_sctp3436_data.array, return );
    767        
     767
    768768        /* Terminate all receiving threads in case we did not do it yet */
    769769        fd_sctp3436_stopthreads(conn);
    770        
     770
    771771        /* Now, stop the demux thread */
    772772        CHECK_FCT_DO( fd_thr_term(&conn->cc_rcvthr), /* continue */ );
    773        
     773
    774774        /* Free remaining data in the array */
    775775        for (i = 0; i < conn->cc_sctp_para.pairs; i++) {
     
    782782                }
    783783        }
    784        
     784
    785785        /* Free the array itself now */
    786786        free(conn->cc_sctp3436_data.array);
    787787        conn->cc_sctp3436_data.array = NULL;
    788        
     788
    789789        /* Delete the store of sessions */
    790790        store_destroy(conn);
    791        
     791
    792792        return ;
    793793}
Note: See TracChangeset for help on using the changeset viewer.