Navigation


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


Ignore:
Files:
33 deleted
17 edited

Legend:

Unmodified
Added
Removed
  • INSTALL.pkgsrc

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

    r1349 r1331  
    33Software License Agreement (BSD License)
    44
    5 Copyright (c) 2008-2019, WIDE Project and NICT
     5Copyright (c) 2008-2018, 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

    r1336 r1197  
    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.
    84
    95# Lines starting with a # are comments and ignored.
  • doc/rt_ereg.conf.sample

    r1338 r525  
    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 
    106# First, one must indicate which AVP should be used for matching.
    117# At the moment, only AVP with OCTETSTRING types are valid.
    128#  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";
    159# This parameter is mandatory. There is no default value.
    1610
     
    2620#    (reminder: the server with the peer with the highest score gets the message)
    2721# 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

    r1348 r1278  
    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
    53 FD_EXTENSION_SUBDIR(dict_json       "Load Diameter dictionary definitions from JSON files."   OFF)
    5453FD_EXTENSION_SUBDIR(dict_legacy_xml "Load Diameter dictionary definitions from XML files."    OFF)
    5554
     
    6968# Routing extensions
    7069
    71 FD_EXTENSION_SUBDIR(rt_busypeers    "Handling of Diameter TOO_BUSY messages and relay timeouts" ON)
    72 FD_EXTENSION_SUBDIR(rt_default      "Configurable routing rules for freeDiameter"                       ON)
    73 FD_EXTENSION_SUBDIR(rt_deny_by_size "Deny messages that are larger than a configured size"                      ON)
    74 FD_EXTENSION_SUBDIR(rt_ereg         "Configurable routing based on regexp matching of AVP values" OFF)
    75 FD_EXTENSION_SUBDIR(rt_ignore_dh    "Stow Destination-Host in Proxy-Info, restore to Origin-Host for answers"   ON)
     70FD_EXTENSION_SUBDIR(rt_busypeers "Handling of Diameter TOO_BUSY messages and relay timeouts"    ON)
     71FD_EXTENSION_SUBDIR(rt_default   "Configurable routing rules for freeDiameter"                  ON)
     72FD_EXTENSION_SUBDIR(rt_ereg      "Configurable routing based on regexp matching of AVP values" OFF)
     73FD_EXTENSION_SUBDIR(rt_ignore_dh "Stow Destination-Host in Proxy-Info, restore to Origin-Host for answers"      ON)
    7674FD_EXTENSION_SUBDIR(rt_load_balance "Balance load over multiple equal hosts, based on outstanding requests"     ON)
    77 FD_EXTENSION_SUBDIR(rt_randomize    "Randomly choose one of the highest scored hosts and increase its score by one"     ON)
    78 FD_EXTENSION_SUBDIR(rt_redirect     "Handling of Diameter Redirect messages"                    ON)
    79 FD_EXTENSION_SUBDIR(rt_rewrite      "Convert/remove AVP data in messages"                       ON)
     75FD_EXTENSION_SUBDIR(rt_randomize "Randomly choose one of the highest scored hosts and increase its score by one"        ON)
     76FD_EXTENSION_SUBDIR(rt_redirect  "Handling of Diameter Redirect messages"                       ON)
    8077
    8178
     
    8986# Debug & test extensions
    9087
    91 FD_EXTENSION_SUBDIR(dbg_loglevel "Read loglevel from file -- allows runtime change"  ON)
    92 FD_EXTENSION_SUBDIR(dbg_monitor     "Outputs periodical status information"              ON)
     88FD_EXTENSION_SUBDIR(dbg_monitor "Outputs periodical status information"              ON)
    9389FD_EXTENSION_SUBDIR(dbg_msg_timings "Show some timing information for messages"      ON)
    94 FD_EXTENSION_SUBDIR(dbg_msg_dumps   "Show human-readable content of the received & sent messages"      ON)
    95 FD_EXTENSION_SUBDIR(dbg_rt          "Routing extension for debugging the routing module" ON)
    96 FD_EXTENSION_SUBDIR(test_app        "Testing application to send dummy message to another peer, like a Diameter 'ping'" OFF)
    97 FD_EXTENSION_SUBDIR(test_as     "Receive Abort-Session-Requests and display the data" OFF)
    98 FD_EXTENSION_SUBDIR(test_cc     "Receive Credit-Control-Requests and display the data" OFF)
    99 FD_EXTENSION_SUBDIR(test_sip        "Testing application to simulate Diameter-SIP client (RFC4740)" OFF)
     90FD_EXTENSION_SUBDIR(dbg_msg_dumps "Show human-readable content of the received & sent messages"      ON)
     91FD_EXTENSION_SUBDIR(dbg_rt      "Routing extension for debugging the routing module" ON)
     92FD_EXTENSION_SUBDIR(test_app    "Testing application to send dummy message to another peer, like a Diameter 'ping'" OFF)
     93FD_EXTENSION_SUBDIR(test_sip    "Testing application to simulate Diameter-SIP client (RFC4740)" OFF)
    10094FD_EXTENSION_SUBDIR(dbg_interactive "Python-interpreter based module"                OFF)
    101 FD_EXTENSION_SUBDIR(test_netemul    "Simple Diameter network emulator proxy extension (latency, PDV, duplicates)" OFF)
     95FD_EXTENSION_SUBDIR(test_netemul "Simple Diameter network emulator proxy extension (latency, PDV, duplicates)" OFF)
    10296
    10397
  • extensions/dict_dcca_3gpp/dict_dcca_3gpp.c

    r1337 r1324  
    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 },
    1059710582                        };
    1059810583                        PARSE_loc_rules(rules, rule_avp);
  • extensions/rt_default/rt_default.c

    r1336 r1235  
    3838 */
    3939
    40 #include <signal.h>
    41 
    4240#include "rt_default.h"
    43 
    44 #define MODULE_NAME "rt_default"
    45 
    46 #include <pthread.h>
    47 
    48 static pthread_rwlock_t rtd_lock;
    49 
    50 static char *rtd_config_file;
    5141
    5242/* The callback called on new messages */
     
    5545        struct msg * msg = *pmsg;
    5646        TRACE_ENTRY("%p %p %p", cbdata, msg, candidates);
    57         int ret;
    5847       
    5948        CHECK_PARAMS(msg && candidates);
    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         }
     49       
    6550        /* Simply pass it to the appropriate function */
    6651        if (FD_IS_LIST_EMPTY(candidates)) {
    67                 ret = 0;
     52                return 0;
    6853        } else {
    69                 ret = rtd_process( msg, candidates );
     54                return rtd_process( msg, candidates );
    7055        }
    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;
    7656}
    7757
     
    7959static struct fd_rt_out_hdl * rtd_hdl = NULL;
    8060
    81 static volatile int in_signal_handler = 0;
    82 
    83 /* signal handler */
    84 static 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 
    10861/* entry point */
    10962static int rtd_entry(char * conffile)
    11063{
    11164        TRACE_ENTRY("%p", conffile);
    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 
     65       
    12166        /* Initialize the repo */
    12267        CHECK_FCT( rtd_init() );
     
    12469        /* Parse the configuration file */
    12570        CHECK_FCT( rtd_conf_handle(conffile) );
    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 
     71       
    13572#if 0
    13673        /* Dump the rules */
     
    15592        /* Destroy the data */
    15693        rtd_fini();
    157 
    158         pthread_rwlock_destroy(&rtd_lock);
    159 
     94       
    16095        /* Done */
    16196        return ;
    16297}
    16398
    164 EXTENSION_ENTRY(MODULE_NAME, rtd_entry);
     99EXTENSION_ENTRY("rt_default", rtd_entry);
  • extensions/rt_default/rt_default.h

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

    r1336 r1127  
    5555/* Forward declaration */
    5656int yyparse(char * conffile);
    57 void rtd_confrestart(FILE *input_file);
    5857
    5958static int rules_added = 0;
     
    6766        TRACE_ENTRY("%p", conffile);
    6867       
    69         TRACE_DEBUG (FULL, "rt_default: Parsing configuration file: %s...", conffile);
    70 
    71         rules_added = 0;
     68        TRACE_DEBUG (FULL, "Parsing configuration file: %s...", conffile);
     69       
    7270        rtd_confin = fopen(conffile, "r");
    7371        if (rtd_confin == NULL) {
    7472                ret = errno;
    7573                fd_log_debug("Unable to open extension configuration file %s for reading: %s", conffile, strerror(ret));
    76                 TRACE_DEBUG (INFO, "rt_default: Error occurred, message logged -- configuration file.");
     74                TRACE_DEBUG (INFO, "Error occurred, message logged -- configuration file.");
    7775                return ret;
    7876        }
    7977
    80         rtd_confrestart(rtd_confin);
    8178        ret = yyparse(conffile);
    8279
     
    8481
    8582        if (ret != 0) {
    86                 TRACE_DEBUG (INFO, "rt_default: Unable to parse the configuration file.");
     83                TRACE_DEBUG (INFO, "Unable to parse the configuration file.");
    8784                return EINVAL;
    8885        } else {
    89                 TRACE_DEBUG(INFO, "rt_default: Added %d RULES routing entries successfully.", rules_added);
     86                TRACE_DEBUG(FULL, "Added %d RULES routing entries successfully.", rules_added);
    9087        }
    9188       
     
    9996void yyerror (YYLTYPE *ploc, char * conffile, char const *s)
    10097{
    101         TRACE_DEBUG(INFO, "rt_default: Error in configuration parsing");
     98        TRACE_DEBUG(INFO, "Error in configuration parsing");
    10299       
    103100        if (ploc->first_line != ploc->last_line)
  • extensions/rt_default/rtd_rules.c

    r1336 r1179  
    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: Access these only when holding rtd_lock; config reload may change the underlying data.
     49 * Note: Except during configuration parsing and module termination, the lists are only ever accessed read-only, so we do not need a lock.
    5050 */
    5151
     
    390390}
    391391
    392 static void free_targets(void)
     392/* Destroy the module's data */
     393void rtd_fini(void)
    393394{
    394395        int i;
     396       
     397        TRACE_ENTRY();
    395398
    396399        for (i = 0; i < RTD_TAR_MAX; i++) {
     
    399402                }
    400403        }
    401 }
    402 
    403 /* Destroy the module's data */
    404 void rtd_fini(void)
    405 {
    406         TRACE_ENTRY();
    407 
    408         free_targets();
     404       
    409405}
    410406
     
    497493       
    498494        return 0;
    499 }
    500 
    501 void 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         }
    533495}
    534496
  • extensions/rt_ereg/rtereg.c

    r1338 r1216  
    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 
    4542#include "rtereg.h"
    4643
    47 static pthread_rwlock_t rte_lock;
    48 
    49 #define MODULE_NAME "rt_ereg"
    50 
    51 static char *rt_ereg_config_file;
    52 
    5344/* The configuration structure */
    54 struct rtereg_conf *rtereg_conf;
    55 int rtereg_conf_size;
     45struct rtereg_conf rtereg_conf;
    5646
    5747#ifndef HAVE_REG_STARTEND
     
    6151#endif /* HAVE_REG_STARTEND */
    6252
    63 static int rtereg_init(void);
    64 static int rtereg_init_config(void);
    65 static void rtereg_fini(void);
    66 
    67 void 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 
    86 static int proceed(char * value, size_t len, struct fd_list * candidates, int conf)
     53static int proceed(char * value, size_t len, struct fd_list * candidates)
    8754{
    8855        int i;
    89 
    90         for (i = 0; i < rtereg_conf[conf].rules_nb; i++) {
     56       
     57        for (i = 0; i < rtereg_conf.rules_nb; i++) {
    9158                /* Does this pattern match the value? */
    92                 struct rtereg_rule * r = &rtereg_conf[conf].rules[i];
     59                struct rtereg_rule * r = &rtereg_conf.rules[i];
    9360                int err = 0;
    9461                struct fd_list * c;
    95 
     62               
    9663                TRACE_DEBUG(ANNOYING, "Attempt pattern matching of '%.*s' with rule '%s'", (int)len, value, r->pattern);
    97 
     64               
    9865                #ifdef HAVE_REG_STARTEND
    9966                {
     
    11077                }
    11178                #endif /* HAVE_REG_STARTEND */
    112 
     79               
    11380                if (err == REG_NOMATCH)
    11481                        continue;
    115 
     82                       
    11683                if (err != 0) {
    11784                        char * errstr;
     
    133100                        /* Free the buffer, return the error */
    134101                        free(errstr);
    135 
     102                       
    136103                        return (err == REG_ESPACE) ? ENOMEM : EINVAL;
    137104                }
    138 
     105               
    139106                /* From this point, the expression matched the AVP value */
    140107                TRACE_DEBUG(FULL, "[rt_ereg] Match: '%s' to value '%.*s' => '%s' += %d",
     
    144111                                        r->server,
    145112                                        r->score);
    146 
     113               
    147114                for (c = candidates->next; c != candidates; c = c->next) {
    148115                        struct rtd_candidate * cand = (struct rtd_candidate *)c;
     
    154121                }
    155122        };
    156 
    157         return 0;
    158 }
    159 
    160 static 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 
     123       
    217124        return 0;
    218125}
     
    221128static int rtereg_out(void * cbdata, struct msg ** pmsg, struct fd_list * candidates)
    222129{
    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);
     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       
     137        /* Check if it is worth processing the message */
     138        if (FD_IS_LIST_EMPTY(candidates)) {
    232139                return 0;
    233140        }
    234         ret = 0;
    235         /* Check if it is worth processing the message */
    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;
     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; } );
    244158                        }
     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 */
    245173                }
    246174        }
    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;
     175       
     176        return 0;
    253177}
    254178
     
    256180static struct fd_rt_out_hdl * rtereg_hdl = NULL;
    257181
    258 static volatile int in_signal_handler = 0;
    259 
    260 /* signal handler */
    261 static 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 
    301182/* entry point */
    302183static int rtereg_entry(char * conffile)
    303184{
    304185        TRACE_ENTRY("%p", conffile);
    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 
    320 static int rtereg_init_config(void)
    321 {
     186       
    322187        /* Initialize the configuration */
    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 
     188        memset(&rtereg_conf, 0, sizeof(rtereg_conf));
     189       
    330190        /* Parse the configuration file */
    331         CHECK_FCT( rtereg_conf_handle(rt_ereg_config_file) );
    332 
    333         return 0;
    334 }
    335 
    336 
    337 /* Load */
    338 static 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 
     191        CHECK_FCT( rtereg_conf_handle(conffile) );
     192       
    359193        /* Register the callback */
    360194        CHECK_FCT( fd_rt_out_register( rtereg_out, NULL, 1, &rtereg_hdl ) );
    361 
     195       
    362196        /* We're done */
    363197        return 0;
     
    365199
    366200/* Unload */
    367 static void rtereg_fini(void)
    368 {
     201void fd_ext_fini(void)
     202{
     203        int i;
    369204        TRACE_ENTRY();
    370 
     205       
    371206        /* Unregister the cb */
    372207        CHECK_FCT_DO( fd_rt_out_unregister ( rtereg_hdl, NULL ), /* continue */ );
    373 
     208       
    374209        /* Destroy the data */
    375         rtereg_conf_free(rtereg_conf, rtereg_conf_size);
    376         rtereg_conf = NULL;
    377         rtereg_conf_size = 0;
     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);
    378217#ifndef HAVE_REG_STARTEND
    379218        free(buf);
    380         buf = NULL;
    381219#endif /* HAVE_REG_STARTEND */
    382 
     220       
    383221        /* Done */
    384222        return ;
    385223}
    386224
    387 void fd_ext_fini(void)
    388 {
    389         rtereg_fini();
    390 }
    391 
    392 EXTENSION_ENTRY(MODULE_NAME, rtereg_entry);
     225EXTENSION_ENTRY("rt_ereg", rtereg_entry);
  • extensions/rt_ereg/rtereg.h

    r1338 r741  
    5858        int                     rules_nb; /* Number of rules in the configuration */
    5959        struct rtereg_rule      *rules;   /* The array of rules */
     60       
     61        struct dict_object * avp; /* cache the dictionary object that we are searching */
     62       
     63} rtereg_conf;
    6064
    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 */
    64        
    65 } *rtereg_conf;
    66 
    67 extern int rtereg_conf_size;
  • extensions/rt_ereg/rtereg_conf.y

    r1342 r1127  
    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);
    56 void rtereg_confrestart(FILE *input_file);
    5756
    5857/* Parse the configuration file */
     
    6160        extern FILE * rtereg_confin;
    6261        int ret;
    63 
     62       
    6463        TRACE_ENTRY("%p", conffile);
    65 
     64       
    6665        TRACE_DEBUG (FULL, "Parsing configuration file: %s...", conffile);
    67 
     66       
    6867        rtereg_confin = fopen(conffile, "r");
    6968        if (rtereg_confin == NULL) {
    7069                ret = errno;
    7170                fd_log_debug("Unable to open extension configuration file %s for reading: %s", conffile, strerror(ret));
    72                 TRACE_DEBUG (INFO, "rt_ereg: error occurred, message logged -- configuration file.");
     71                TRACE_DEBUG (INFO, "Error occurred, message logged -- configuration file.");
    7372                return ret;
    7473        }
    7574
    76         rtereg_confrestart(rtereg_confin);
    7775        ret = yyparse(conffile);
    7876
    7977        fclose(rtereg_confin);
    8078
    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 
    8679        if (ret != 0) {
    87                 TRACE_DEBUG(INFO, "rt_ereg: unable to parse the configuration file.");
     80                TRACE_DEBUG (INFO, "Unable to parse the configuration file.");
    8881                return EINVAL;
    8982        } else {
    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);
     83                TRACE_DEBUG(FULL, "[rt-ereg] Added %d rules successfully.", rtereg_conf.rules_nb);
    9584        }
    96 
    97         return 0;
    98 }
    99 
    100 int 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;
     85       
    14186        return 0;
    14287}
     
    14893void yyerror (YYLTYPE *ploc, char * conffile, char const *s)
    14994{
    150         TRACE_DEBUG(INFO, "rt_ereg: error in configuration parsing");
    151 
     95        TRACE_DEBUG(INFO, "Error in configuration parsing");
     96       
    15297        if (ploc->first_line != ploc->last_line)
    15398                fd_log_debug("%s:%d.%d-%d.%d : %s", conffile, ploc->first_line, ploc->first_column, ploc->last_line, ploc->last_column, s);
     
    181126
    182127        /* The grammar definition */
    183 conffile:               avp rules
    184                         | conffile avp rules
    185                         ;
    186 
     128conffile:               rules avp rules
     129                        ;
     130                       
    187131        /* a server entry */
    188 avp:                    AVP '=' avp_part ';'
    189                         ;
    190 
    191 avp_part:               avp_part ':' QSTRING { if (avp_add($3) < 0) { YYERROR; } }
    192                         | QSTRING { if (avp_add($1) < 0) { YYERROR; } }
    193                         ;
    194 
     132avp:                    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                       
    195160rules:                  /* empty OK */
    196161                        | rules rule
    197162                        ;
    198 
     163                       
    199164rule:                   QSTRING ':' QSTRING '+' '=' INTEGER ';'
    200165                        {
    201166                                struct rtereg_rule * new;
    202167                                int err;
    203 
     168                               
    204169                                /* Add new rule in the array */
    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)),
     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)),
    207172                                        {
    208173                                                yyerror (&yylloc, conffile, "Not enough memory to store the configuration...");
    209174                                                YYERROR;
    210175                                        } );
    211 
    212                                 new = &rtereg_conf[rtereg_conf_size-1].rules[rtereg_conf[rtereg_conf_size-1].rules_nb - 1];
    213 
     176                               
     177                                new = &rtereg_conf.rules[rtereg_conf.rules_nb - 1];
     178                               
    214179                                new->pattern = $1;
    215180                                new->server  = $3;
    216181                                new->score   = $6;
    217 
     182                               
    218183                                /* Attempt to compile the regex */
    219184                                CHECK_FCT_DO( err=regcomp(&new->preg, new->pattern, REG_EXTENDED | REG_NOSUB),
     
    223188
    224189                                                /* Error while compiling the regex */
    225                                                 TRACE_DEBUG(INFO, "rt_ereg: error while compiling the regular expression '%s':", new->pattern);
     190                                                TRACE_DEBUG(INFO, "Error while compiling the regular expression '%s':", new->pattern);
    226191
    227192                                                /* Get the error message size */
     
    234199                                                regerror(err, &new->preg, buf, bl);
    235200                                                TRACE_DEBUG(INFO, "\t%s", buf);
    236 
     201                                               
    237202                                                /* Free the buffer, return the error */
    238203                                                free(buf);
    239 
     204                                               
    240205                                                yyerror (&yylloc, conffile, "Invalid regular expression.");
    241206                                                YYERROR;
  • freeDiameterd/main.c

    r1339 r1305  
    3434*********************************************************************************************************/
    3535
    36 #if defined(__GLIBC__)
    37 #define _BSD_SOURCE /* for vsyslog */
    38 #endif
    39 
    4036#include <freeDiameter/freeDiameter-host.h>
    4137#include <freeDiameter/libfdcore.h>
     
    4440#include <getopt.h>
    4541#include <locale.h>
    46 #include <syslog.h>
    47 #include <stdarg.h>
     42
    4843
    4944/* forward declarations */
     
    6156
    6257
    63 static 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 
    9358/* freeDiameter starting point */
    9459int main(int argc, char * argv[])
     
    9661        int ret;
    9762        sigset_t sig_all;
    98 
     63       
    9964        /* Block all signals from the current thread and all its future children -- we will catch everything in catch_signals */
    10065        sigfillset(&sig_all);
    10166        ret = pthread_sigmask(SIG_BLOCK, &sig_all, NULL);
    10267        ASSERT(ret == 0);
    103 
     68       
    10469        /* Parse the command-line */
    10570        ret = main_cmdline(argc, argv);
     
    10772                return ret;
    10873        }
    109 
     74       
    11075        /* Initialize the core library */
    11176        ret = fd_core_initialize();
     
    11479                return ret;
    11580        }
    116 
     81       
    11782        /* Set gnutls debug level ? */
    11883        if (gnutls_debug) {
     
    12186                TRACE_DEBUG(INFO, "Enabled GNUTLS debug at level %d", gnutls_debug);
    12287        }
    123 
     88       
    12489        /* Parse the configuration file */
    12590        CHECK_FCT_DO( fd_core_parseconf(conffile), goto error );
    126 
     91       
    12792        /* Start the servers */
    12893        CHECK_FCT_DO( fd_core_start(), goto error );
    129 
     94       
    13095        /* Allow SIGINT and SIGTERM from this point to terminate the application */
    13196        CHECK_POSIX_DO( pthread_create(&signals_thr, NULL, catch_signals, NULL), goto error );
    132 
     97       
    13398        TRACE_DEBUG(INFO, FD_PROJECT_BINARY " daemon initialized.");
    13499
    135100        /* Now, just wait for termination */
    136101        CHECK_FCT( fd_core_wait_shutdown_complete() );
    137 
     102       
    138103        /* Just in case it was not the result of a signal, we cancel signals_thr */
    139104        fd_thr_term(&signals_thr);
    140 
     105       
    141106        return 0;
    142 error:
     107error: 
    143108        CHECK_FCT_DO( fd_core_shutdown(),  );
    144109        CHECK_FCT( fd_core_wait_shutdown_complete() );
     
    173138                "  -V, --version          Print version and exit\n"
    174139                "  -c, --config=filename  Read configuration from this file instead of the \n"
    175                 "                           default location (" DEFAULT_CONF_PATH "/" FD_DEFAULT_CONF_FILENAME ").\n"
    176                 "  -s, --syslog            Write log output to syslog (instead of stdout)\n");
     140                "                           default location (" DEFAULT_CONF_PATH "/" FD_DEFAULT_CONF_FILENAME ").\n");
    177141        printf( "\nDebug:\n"
    178142                "  These options are mostly useful for developers\n"
     
    192156        int option_index = 0;
    193157        char * locale;
    194 
     158       
    195159        struct option long_options[] = {
    196160                { "help",       no_argument,            NULL, 'h' },
    197161                { "version",    no_argument,            NULL, 'V' },
    198162                { "config",     required_argument,      NULL, 'c' },
    199                 { "syslog",     no_argument,            NULL, 's' },
    200163                { "debug",      no_argument,            NULL, 'd' },
    201164                { "quiet",      no_argument,            NULL, 'q' },
     
    206169                { NULL,         0,                      NULL, 0 }
    207170        };
    208 
     171       
    209172        /* Loop on arguments */
    210173        while (1) {
    211                 c = getopt_long (argc, argv, "hVc:dql:f:F:g:s", long_options, &option_index);
    212                 if (c == -1)
     174                c = getopt_long (argc, argv, "hVc:dql:f:F:g:", long_options, &option_index);
     175                if (c == -1) 
    213176                        break;  /* Exit from the loop.  */
    214 
     177               
    215178                switch (c) {
    216179                        case 'h':       /* Print help and exit.  */
     
    237200                                }
    238201                                break;
    239 
     202                               
    240203                        case 'd':       /* Increase verbosity of debug messages.  */
    241204                                fd_g_debug_lvl--;
    242205                                break;
    243 
     206                               
    244207                        case 'f':       /* Full debug for the function with this name.  */
    245208                                #ifdef DEBUG
     
    251214                                #endif /* DEBUG */
    252215                                break;
    253 
     216                               
    254217                        case 'F':       /* Full debug for the file with this name.  */
    255218                                #ifdef DEBUG
     
    261224                                #endif /* DEBUG */
    262225                                break;
    263 
     226                               
    264227                        case 'g':       /* Set a debug level and function for GNU TLS calls.  */
    265228                                gnutls_debug = (int)atoi(optarg);
    266229                                break;
    267 
     230                               
    268231                        case 'q':       /* Decrease verbosity then remove debug messages.  */
    269232                                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                                 }
    277233                                break;
    278234
     
    288244                }
    289245        }
    290 
     246               
    291247        return 0;
    292248}
     
    297253        sigset_t ss;
    298254        fd_log_threadname ( "signals catcher" );
    299 
     255       
    300256        sigemptyset(&ss);
    301 
     257       
    302258        /* Signals that terminate the daemon */
    303259        sigaddset(&ss, SIGTERM);
    304260        sigaddset(&ss, SIGINT);
    305 
     261       
    306262        /* Signals that send an event */
    307263        sigaddset(&ss, SIGUSR1);
    308264        sigaddset(&ss, SIGUSR2);
    309 
     265       
    310266        /* We unblock all other signals, so that their default handler is used (such as SIGTSTP) */
    311267        CHECK_SYS_DO( pthread_sigmask( SIG_SETMASK, &ss, NULL ), goto out );
    312 
     268       
    313269        /* Now loop on the reception of the signal */
    314270        while (1) {
    315271                int sig, *ps;
    316 
     272               
    317273                /* Wait to receive the next signal */
    318274                CHECK_POSIX_DO( sigwait(&ss, &sig), break );
    319 
     275               
    320276                TRACE_DEBUG(FULL, "Signal %d caught", sig);
    321 
     277               
    322278                switch (sig) {
    323279                        case SIGUSR1:
     
    327283                                CHECK_FCT_DO( fd_event_send(fd_g_config->cnf_main_ev, FDEV_TRIGGER, sizeof(int), ps), goto out );
    328284                                break;
    329 
     285                               
    330286                        case SIGINT:
    331287                        case SIGTERM:
     
    334290                }
    335291        }
    336 out:
     292out:   
    337293        /* Better way to handle this ? */
    338294        ASSERT(0);
  • include/freeDiameter/CMakeLists.txt

    r1333 r1295  
    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

    r1332 r1268  
    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

    r1344 r1190  
    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[100];
     79                char buf[48];
    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[100];
     149                char buf[48];
    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.