LTP GCOV extension - code coverage report
Current view: directory - and-httpd/src - opt_policy.c
Test: And-httpd coverage
Date: 2006-09-11 Instrumented lines: 215
Code covered: 69.3 % Executed lines: 149

       1                 : #define EX_UTILS_NO_FUNCS 1
       2                 : #include "ex_utils.h"
       3                 : 
       4                 : #include "opt_policy.h"
       5                 : 
       6                 : #include "mk.h"
       7                 : 
       8                 : #include <stddef.h> /* offsetof */
       9                 : 
      10                 : void opt_policy_exit(Opt_serv_policy_opts *opts)
      11             144 : {
      12              72 :   ASSERT(opts);
      13                 :   
      14             144 :   vstr_free_base(opts->policy_name); opts->policy_name = NULL;
      15             144 :   opts->beg = NULL;
      16                 :   
      17              72 :   ASSERT( opts->ref_io_limit);
      18             144 :   vstr_ref_del(opts->ref_io_limit);
      19              72 :   ASSERT(!opts->ref_io_limit);
      20             144 : }
      21                 : 
      22                 : static void opt_policy__io_lim_ref_cb(struct Vstr_ref *ref)
      23             144 : {
      24             144 :   Opt_serv_policy_opts *opts = NULL;
      25             144 :   struct Evnt_limit *lim = NULL;
      26                 : 
      27             144 :   if (!ref)
      28               0 :     return;
      29                 :   
      30             144 :   lim = ref->ptr;
      31              72 :   ASSERT(lim);
      32                 : 
      33                 :   /* ISO C magic, converts a ptr to io_limit into a pointer to policy_opts */
      34             144 :   opts = (Opt_serv_policy_opts *)(((char *)lim) -
      35                 :                                   offsetof(Opt_serv_policy_opts, io_limit));
      36             144 :   opts->ref_io_limit = NULL; /* more magic */
      37                 : }
      38                 : 
      39                 : int opt_policy_init(Opt_serv_opts *beg_opts, Opt_serv_policy_opts *opts)
      40             162 : {
      41              81 :   ASSERT(beg_opts);
      42                 : 
      43             162 :   opts->ref_io_limit = NULL;
      44                 :   
      45             162 :   opts->policy_name  = vstr_make_base(NULL);
      46             162 :   opts->ref_io_limit = vstr_ref_make_ptr(&opts->io_limit,
      47                 :                                          opt_policy__io_lim_ref_cb);
      48             162 :   if (!opts->policy_name  ||
      49                 :       !opts->ref_io_limit ||
      50                 :       FALSE)
      51                 :     goto fail;
      52                 : 
      53             162 :   opts->io_limit.io_r_cur         = 0;
      54             162 :   opts->io_limit.io_r_max         = 0;
      55             162 :   opts->io_limit.io_r_tm.tv_sec   = 0;
      56             162 :   opts->io_limit.io_w_cur         = 0;
      57             162 :   opts->io_limit.io_w_max         = 0;
      58             162 :   opts->io_limit.io_w_tm.tv_sec   = 0;
      59                 :   
      60             162 :   opts->io_nslimit.io_r_cur       = 0;
      61             162 :   opts->io_nslimit.io_r_max       = 0;
      62             162 :   opts->io_nslimit.io_r_tm.tv_sec = 0;
      63             162 :   opts->io_nslimit.io_w_cur       = 0;
      64             162 :   opts->io_nslimit.io_w_max       = 0;
      65             162 :   opts->io_nslimit.io_w_tm.tv_sec = 0;
      66                 :   
      67             162 :   opts->idle_timeout    = OPT_SERV_CONF_DEF_IDLE_TIMEOUT;
      68             162 :   opts->max_timeout     = OPT_SERV_CONF_DEF_MAX_TIMEOUT;
      69                 :   
      70             162 :   opts->max_connections = OPT_SERV_CONF_DEF_MAX_CONNECTIONS;
      71                 :   
      72             162 :   opts->use_insta_close = OPT_SERV_CONF_USE_INSTA_CLOSE;
      73                 :   
      74             162 :   opts->beg  = beg_opts;
      75             162 :   opts->next = NULL;
      76                 :   
      77             162 :   return (TRUE);
      78                 :   
      79               0 :  fail:
      80               0 :   opt_policy_exit(opts);
      81               0 :   return (FALSE);
      82                 : }
      83                 : 
      84                 : static void opt_policy_free(Vstr_ref *ref)
      85               0 : {
      86               0 :   Opt_serv_policy_opts *opts = NULL;
      87                 :   
      88               0 :   if (!ref)
      89               0 :     return;
      90                 : 
      91               0 :   if ((opts = ref->ptr))
      92               0 :     opt_policy_exit(opts);
      93               0 :   F(opts);
      94               0 :   free(ref);
      95                 : }
      96                 : 
      97                 : Opt_serv_policy_opts *opt_policy_make(Opt_serv_opts *beg)
      98               0 : {
      99               0 :   Opt_serv_policy_opts *opts = MK(sizeof(Opt_serv_policy_opts));
     100               0 :   Vstr_ref *ref = NULL;
     101                 :   
     102               0 :   if (!opts)
     103               0 :     goto mk_opts_fail;
     104                 : 
     105               0 :   if (!(ref = vstr_ref_make_ptr(opts, opt_policy_free)))
     106               0 :     goto mk_ref_fail;
     107               0 :   opts->ref = ref;
     108                 :   
     109               0 :   if (!opt_policy_init(beg, opts))
     110               0 :     goto policy_init_fail;
     111                 :   
     112               0 :   return (opts);
     113                 : 
     114               0 :  policy_init_fail:
     115               0 :   ref->ptr = NULL;
     116               0 :   vstr_ref_del(ref);
     117               0 :  mk_ref_fail:
     118               0 :   F(opts);
     119               0 :  mk_opts_fail:
     120               0 :   return (NULL);
     121                 : }
     122                 : 
     123                 : void opt_policy_add(Opt_serv_opts *beg, Opt_serv_policy_opts *opts)
     124              98 : {
     125              98 :   Opt_serv_policy_opts **ins = NULL;
     126                 :   
     127              98 :   opts->next = beg->def_policy;
     128              98 :   ins = &opts->next; /* hacky, fix when def_policy is a real pointer */
     129              49 :   ASSERT(*ins);
     130                 :   
     131             709 :   while ((ins = &(*ins)->next) && *ins)
     132                 :   {
     133             570 :     Vstr_base *s1 = opts->policy_name;
     134             570 :     Vstr_base *s2 = (*ins)->policy_name;
     135                 : 
     136             285 :     ASSERT(!(*ins)->next ||
     137                 :            ((*ins)->policy_name->len < (*ins)->next->policy_name->len) ||
     138                 :            (((*ins)->policy_name->len == (*ins)->next->policy_name->len) &&
     139                 :             vstr_cmp((*ins)->policy_name, 1, (*ins)->policy_name->len,
     140                 :                      (*ins)->next->policy_name, 1,
     141                 :                      (*ins)->next->policy_name->len) < 0));
     142                 :     
     143             570 :     if (s1->len > s2->len)
     144             274 :       continue;
     145             296 :     if (s1->len < s2->len)
     146               8 :       break;
     147             288 :     if (vstr_cmp(s1, 1, s1->len, s2, 1, s2->len) <= 0)
     148               0 :       break;
     149                 :   }
     150              49 :   ASSERT(ins != &opts->next);
     151              98 :   opts->next = *ins;
     152              98 :   *ins = opts;
     153              98 : }
     154                 : 
     155                 : int opt_policy_ipv4_make(Conf_parse *conf, Conf_token *token,
     156                 :                          unsigned int type, struct sockaddr *sa, int *matches)
     157             350 : {
     158             350 :   Conf_token save = *token;
     159             350 :   Vstr_ref *ref = NULL;
     160             350 :   Opt_policy_ipv4 *data = NULL;
     161             350 :   int ret = FALSE;
     162                 :   
     163             350 :   CONF_SC_PARSE_TOP_TOKEN_RET(conf, token, FALSE);
     164                 :   
     165             350 :   if (!(ref = vstr_ref_make_malloc(sizeof(Opt_policy_ipv4))))
     166               0 :     return (FALSE);
     167             350 :   data = ref->ptr;
     168                 :   
     169             350 :   ret = vstr_parse_ipv4(conf->data, token->u.node->pos, token->u.node->len,
     170                 :                         data->ipv4, &data->cidr,
     171                 :                         VSTR_FLAG05(PARSE_IPV4, CIDR, CIDR_FULL,
     172                 :                                     NETMASK, NETMASK_FULL, ONLY), NULL, NULL);
     173                 : 
     174             350 :   if (ret)
     175                 :   {
     176             350 :     *matches = opt_policy_ipv4_cidr_eq(data, sa);
     177                 :     
     178             350 :     ret = conf_token_set_user_value(conf, &save, type, ref, token->num);
     179                 :   }
     180                 :   
     181             350 :   vstr_ref_del(ref);
     182                 : 
     183             350 :   return (!!ret);
     184                 : }
     185                 : 
     186                 : int opt_policy_ipv4_cidr_eq(Opt_policy_ipv4 *data, struct sockaddr *sa)
     187           40836 : {
     188           40836 :   struct sockaddr_in *sa_in = NULL;
     189                 :   uint32_t tst_addr_ipv4;
     190                 :   unsigned char tst_ipv4[4];
     191           40836 :   unsigned int scan = 0;
     192           40836 :   unsigned int cidr = data->cidr;
     193                 :   
     194           20418 :   ASSERT(cidr <= 32);
     195                 : 
     196           40836 :   if (!sa || (sa->sa_family != AF_INET))
     197               0 :     return (FALSE);
     198           40836 :   sa_in = (struct sockaddr_in *)sa;
     199                 :     
     200           40836 :   tst_addr_ipv4 = ntohl(sa_in->sin_addr.s_addr);
     201                 :     
     202           40836 :   tst_ipv4[3] = (tst_addr_ipv4 >>  0) & 0xFF;
     203           40836 :   tst_ipv4[2] = (tst_addr_ipv4 >>  8) & 0xFF;
     204           40836 :   tst_ipv4[1] = (tst_addr_ipv4 >> 16) & 0xFF;
     205           40836 :   tst_ipv4[0] = (tst_addr_ipv4 >> 24) & 0xFF;
     206                 : 
     207           40836 :   scan = 0;
     208          189344 :   while (cidr >= 8)
     209                 :   {
     210          139828 :     if (tst_ipv4[scan] != data->ipv4[scan])
     211           32156 :       return (FALSE);
     212                 :     
     213          107672 :     ++scan;
     214          107672 :     cidr -= 8;
     215                 :   }
     216            4340 :   ASSERT(!cidr || (scan < 4));
     217                 :   
     218            8680 :   if (cidr)
     219                 :   { /* x/7 == (1 << 7) - 1 == 0b0111_1111 */
     220               0 :     unsigned int mask = ((1 << cidr) - 1) << (8 - cidr);
     221               0 :     if ((tst_ipv4[scan] & mask) != (data->ipv4[scan] & mask))
     222               0 :       return (FALSE);
     223                 :   }
     224                 : 
     225            8680 :   return (TRUE);
     226                 : }
     227                 : 
     228                 : Opt_serv_policy_opts *opt_policy_sc_conf_make(Opt_serv_opts *opts,
     229                 :                                               const Conf_parse *conf,
     230                 :                                               const Conf_token *token,
     231                 :                                               const Vstr_sect_node *pv)
     232              98 : {
     233              98 :   Opt_serv_policy_opts *popts = opts->make_policy(opts);
     234              98 :   Vstr_base *name = NULL;
     235                 : 
     236              49 :   ASSERT(conf && token && pv);
     237                 :   
     238              98 :   if (!popts)
     239               0 :     goto init_failure;
     240                 : 
     241              98 :   if (!(*opts->copy_policy)(popts, opts->def_policy))
     242               0 :     goto copy_failure;
     243                 : 
     244              49 :   ASSERT(pv);
     245                 : 
     246              98 :   name = popts->policy_name;
     247              98 :   if (!vstr_sub_vstr(name, 1, name->len, conf->data, pv->pos, pv->len,
     248                 :                      VSTR_TYPE_SUB_BUF_REF))
     249               0 :     goto name_failure;
     250              98 :   if ((token->type == CONF_TOKEN_TYPE_QUOTE_ESC_D) ||
     251                 :       (token->type == CONF_TOKEN_TYPE_QUOTE_ESC_DDD) ||
     252                 :       (token->type == CONF_TOKEN_TYPE_QUOTE_ESC_S) ||
     253                 :       (token->type == CONF_TOKEN_TYPE_QUOTE_ESC_SSS) ||
     254                 :       FALSE)
     255               0 :     if (!conf_sc_conv_unesc(name, 1, pv->len, NULL))
     256               0 :       goto name_failure;
     257                 :   
     258              98 :   opt_policy_add(opts, popts);
     259                 :   
     260              98 :   return (popts);
     261                 :   
     262               0 :  name_failure:
     263               0 :  copy_failure:
     264               0 :   vstr_ref_del(popts->ref);
     265               0 :  init_failure:
     266               0 :   return (NULL);
     267                 : }
     268                 : 
     269                 : unsigned int opt_policy_sc_conf_parse(Opt_serv_opts *opts,
     270                 :                                       const Conf_parse *conf, Conf_token *token,
     271                 :                                       Opt_serv_policy_opts **ret_popts,
     272                 :                                       Conf_token **ntoken)
     273             174 : {
     274             174 :   Opt_serv_policy_opts *popts = NULL;
     275             174 :   unsigned int cur_depth = token->depth_num;
     276                 :   Conf_token save;
     277             174 :   const Vstr_sect_node *pv = NULL;
     278             174 :   int created_now = FALSE;
     279                 :   static Conf_token policy_list_save;
     280                 :   
     281              87 :   ASSERT(opts && opts->def_policy && ret_popts && ntoken);
     282                 : 
     283             174 :   *ret_popts = NULL;
     284                 : 
     285             174 :   if (*ntoken)
     286                 :   { /* comming back for the next name... */
     287               0 :     ASSERT(*ntoken == &policy_list_save);
     288                 : 
     289               0 :     *token = **ntoken;
     290                 :   }
     291                 :   else
     292                 :   {
     293             174 :     CONF_SC_PARSE_TOP_TOKEN_RET(conf, token, 0);
     294                 : 
     295             174 :     if (token->type == CONF_TOKEN_TYPE_CLIST)
     296                 :     { /* have a list of policy names... */
     297               0 :       CONF_SC_PARSE_TOP_TOKEN_RET(conf, token, 0);
     298                 : 
     299               0 :       *ntoken  = &policy_list_save;
     300               0 :       **ntoken = *token;
     301                 :     }
     302                 :   }
     303                 :     
     304             174 :   if (!(pv = conf_token_value(token)))
     305               0 :     return (0);
     306                 :   
     307             174 :   if (!(popts = opt_policy_conf_find(opts, conf, token)))
     308                 :   {
     309              98 :     if (!(popts = opt_policy_sc_conf_make(opts, conf, token, pv)))
     310               0 :       return (0);
     311              98 :     created_now = TRUE;
     312                 :   }
     313                 :   
     314             174 :   if (*ntoken)
     315                 :   {
     316               0 :     unsigned int depth = (*ntoken)->depth_num;
     317               0 :     if (!conf_parse_token(conf, *ntoken) || (depth != (*ntoken)->depth_num))
     318               0 :       *ntoken = NULL;
     319               0 :     if (!conf_parse_end_token(conf, token, token->depth_num))
     320               0 :       return (0);
     321                 :   }
     322                 :   
     323             174 :   save = *token;
     324             174 :   if (!conf_parse_token(conf, token) || (token->depth_num < cur_depth))
     325               0 :     return (cur_depth);
     326             174 :   if (token->type != CONF_TOKEN_TYPE_SLIST)
     327             130 :     *token = save; /* restore ... */
     328                 :   else
     329                 :   { /* allow set of attributes */
     330              44 :     int clist = FALSE;
     331                 :     
     332             132 :     CONF_SC_MAKE_CLIST_BEG(policy, clist);
     333                 : 
     334              44 :     else if (OPT_SERV_SYM_EQ("inherit"))
     335                 :     {
     336              40 :       const Opt_serv_policy_opts *frm_opts = NULL;
     337              40 :       CONF_SC_PARSE_TOP_TOKEN_RET(conf, token, 0);
     338              40 :       if (!(frm_opts = opt_policy_conf_find(opts, conf, token)))
     339               0 :         return (0);
     340              40 :       if (frm_opts == popts)
     341               0 :         return (0);
     342              40 :       if (created_now && !(*opts->copy_policy)(popts, frm_opts))
     343               0 :         return (0);
     344                 :     }
     345               4 :     else if (OPT_SERV_SYM_EQ("copy"))
     346                 :     {
     347               4 :       const Opt_serv_policy_opts *frm_opts = NULL;
     348               4 :       CONF_SC_PARSE_TOP_TOKEN_RET(conf, token, 0);
     349               4 :       if (!(frm_opts = opt_policy_conf_find(opts, conf, token)))
     350               0 :         return (0);
     351               4 :       if (frm_opts == popts)
     352               0 :         return (0);
     353               4 :       if (!(*opts->copy_policy)(popts, frm_opts))
     354               0 :         return (0);
     355                 :     }
     356                 :     
     357               0 :     CONF_SC_MAKE_CLIST_END();
     358                 :   }
     359                 : 
     360             174 :   *ret_popts = popts;
     361             174 :   return (cur_depth);
     362                 : }
     363                 : 
     364                 : void opt_policy_sc_all_ref_del(Opt_serv_opts *opts)
     365              44 : {
     366              44 :   Opt_serv_policy_opts *scan = opts->def_policy;
     367                 : 
     368              44 :   opts->def_policy = NULL;
     369             232 :   while (scan)
     370                 :   {
     371             144 :     Opt_serv_policy_opts *scan_next = scan->next;
     372                 :     
     373             144 :     vstr_ref_del(scan->ref);
     374                 :     
     375             144 :     scan = scan_next;
     376                 :   }
     377              44 : }
     378                 : 

Generated by: LTP GCOV extension version 1.4