"Fossies" - the Fresh Open Source Software Archive

Member "rbldnsd-0.998/rbldnsd_ip4tset.c" (14 Mar 2013, 3222 Bytes) of package /linux/misc/dns/rbldnsd-0.998.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "rbldnsd_ip4tset.c" see the Fossies "Dox" file reference documentation.

    1 /* ip4tset dataset type: IP4 addresses (ranges), with A and TXT
    2  * values for every individual entry.
    3  */
    4 
    5 #include <stdio.h>
    6 #include <string.h>
    7 #include <stdlib.h>
    8 #include "rbldnsd.h"
    9 
   10 struct dsdata {
   11   unsigned n;       /* count */
   12   unsigned a;       /* allocated (only for loading) */
   13   unsigned h;       /* hint: how much to allocate next time */
   14   ip4addr_t *e;     /* array of entries */
   15   const char *def_rr;   /* default A and TXT RRs */
   16 };
   17 
   18 definedstype(ip4tset, DSTF_IP4REV, "(trivial) set of ip4 addresses");
   19 
   20 static void ds_ip4tset_reset(struct dsdata *dsd, int UNUSED unused_freeall) {
   21  if (dsd->e) {
   22     free(dsd->e);
   23     dsd->e = NULL;
   24     dsd->n = dsd->a = 0;
   25   }
   26   dsd->def_rr = NULL;
   27 }
   28 
   29 static void ds_ip4tset_start(struct dataset UNUSED *unused_ds) {
   30 }
   31 
   32 static int
   33 ds_ip4tset_line(struct dataset *ds, char *s, struct dsctx *dsc) {
   34   struct dsdata *dsd = ds->ds_dsd;
   35   ip4addr_t a;
   36 
   37   if (*s == ':') {
   38     if (!dsd->def_rr) {
   39       unsigned rrl;
   40       const char *rr;
   41       if (!(rrl = parse_a_txt(s, &rr, def_rr, dsc)))
   42         return 1;
   43       if (!(dsd->def_rr = mp_dmemdup(ds->ds_mp, rr, rrl)))
   44         return 0;
   45     }
   46     return 1;
   47   }
   48 
   49   if (ip4prefix(s, &a, &s) != 32 ||
   50       (*s && !ISSPACE(*s) && !ISCOMMENT(*s) && *s != ':')) {
   51     dswarn(dsc, "invalid address");
   52     return 1;
   53   }
   54 
   55   if (dsd->n >= dsd->a) {
   56     ip4addr_t *e = dsd->e;
   57     if (!dsd->a)
   58       dsd->a = dsd->h ? dsd->h : 64;
   59     else
   60       dsd->a <<= 1;
   61     e = trealloc(ip4addr_t, e, dsd->a);
   62     if (!e)
   63       return 0;
   64     dsd->e = e;
   65   }
   66 
   67   dsd->e[dsd->n++] = a;
   68 
   69   return 1;
   70 }
   71 
   72 static void ds_ip4tset_finish(struct dataset *ds, struct dsctx *dsc) {
   73   struct dsdata *dsd = ds->ds_dsd;
   74   ip4addr_t *e = dsd->e;
   75   unsigned n = dsd->n;
   76 
   77   if (!n)
   78     dsd->h = 0;
   79   else {
   80     dsd->h = dsd->a;
   81     while((dsd->h >> 1) >= n)
   82       dsd->h >>= 1;
   83 
   84 #   define QSORT_TYPE ip4addr_t
   85 #   define QSORT_BASE e
   86 #   define QSORT_NELT n
   87 #   define QSORT_LT(a,b) *a < *b
   88 #   include "qsort.c"
   89 
   90 #define ip4tset_eeq(a,b) a == b
   91     REMOVE_DUPS(ip4addr_t, e, n, ip4tset_eeq);
   92     SHRINK_ARRAY(ip4addr_t, e, n, dsd->a);
   93     dsd->e = e;
   94     dsd->n = n;
   95   }
   96 
   97   if (!dsd->def_rr) dsd->def_rr = def_rr;
   98   dsloaded(dsc, "cnt=%u", n);
   99 }
  100 
  101 static int
  102 ds_ip4tset_find(const ip4addr_t *e, int b, ip4addr_t q) {
  103   int a = 0, m;
  104   --b;
  105   while(a <= b) {
  106     if (e[(m = (a + b) >> 1)] == q) return 1;
  107     else if (e[m] < q) a = m + 1;
  108     else b = m - 1;
  109   }
  110   return 0;
  111 }
  112 
  113 static int
  114 ds_ip4tset_query(const struct dataset *ds, const struct dnsqinfo *qi,
  115                 struct dnspacket *pkt) {
  116   const struct dsdata *dsd = ds->ds_dsd;
  117   const char *ipsubst;
  118 
  119   if (!qi->qi_ip4valid) return 0;
  120   check_query_overwrites(qi);
  121 
  122   if (!dsd->n || !ds_ip4tset_find(dsd->e, dsd->n, qi->qi_ip4))
  123     return 0;
  124 
  125   ipsubst = (qi->qi_tflag & NSQUERY_TXT) ? ip4atos(qi->qi_ip4) : NULL;
  126   addrr_a_txt(pkt, qi->qi_tflag, dsd->def_rr, ipsubst, ds);
  127 
  128   return NSQUERY_FOUND;
  129 }
  130 
  131 #ifndef NO_MASTER_DUMP
  132 
  133 static void
  134 ds_ip4tset_dump(const struct dataset *ds,
  135                const unsigned char UNUSED *unused_odn,
  136                FILE *f) {
  137   const struct dsdata *dsd = ds->ds_dsd;
  138   const ip4addr_t *e = dsd->e, *t = e + dsd->n;
  139   while(e < t)
  140     dump_ip4(*e++, dsd->def_rr, ds, f);
  141 }
  142 
  143 #endif