Navigation


Changeset 1338:f1b65381c1e7 in freeDiameter for extensions/rt_ereg/rtereg_conf.y


Ignore:
Timestamp:
Apr 9, 2019, 10:48:45 PM (5 years ago)
Author:
Thomas Klausner <tk@giga.or.at>
Branch:
default
Phase:
public
histedit_source:
a96776a293770a9223f9cf06945dfdcf3844398a
Message:

rt_ereg: Support config reload. Support grouped AVPs. Support multiple separate AVPs.

Written for Effortel Technologies SA, published with their consent.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • extensions/rt_ereg/rtereg_conf.y

    r1127 r1338  
    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, 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;
Note: See TracChangeset for help on using the changeset viewer.