"Fossies" - the Fresh Open Source Software Archive

Member "adns-1.5.1/src/check.c" (12 Aug 2016, 5875 Bytes) of package /linux/misc/dns/adns-1.5.1.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 "check.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.5.0_vs_1.5.1.

    1 /*
    2  * check.c
    3  * - consistency checks
    4  */
    5 /*
    6  *  This file is part of adns, which is
    7  *    Copyright (C) 1997-2000,2003,2006,2014-2016  Ian Jackson
    8  *    Copyright (C) 2014  Mark Wooding
    9  *    Copyright (C) 1999-2000,2003,2006  Tony Finch
   10  *    Copyright (C) 1991 Massachusetts Institute of Technology
   11  *  (See the file INSTALL for full details.)
   12  *  
   13  *  This program is free software; you can redistribute it and/or modify
   14  *  it under the terms of the GNU General Public License as published by
   15  *  the Free Software Foundation; either version 3, or (at your option)
   16  *  any later version.
   17  *  
   18  *  This program is distributed in the hope that it will be useful,
   19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   21  *  GNU General Public License for more details.
   22  *  
   23  *  You should have received a copy of the GNU General Public License
   24  *  along with this program; if not, write to the Free Software Foundation.
   25  */
   26 
   27 #include "internal.h"
   28 
   29 void adns_checkconsistency(adns_state ads, adns_query qu) {
   30   adns__consistency(ads,qu,cc_user);
   31 }
   32 
   33 #define DLIST_CHECK(list, nodevar, part, body)          \
   34   if ((list).head) {                        \
   35     assert(! (list).head->part back);               \
   36     for ((nodevar)= (list).head;                \
   37      (nodevar);                     \
   38      (nodevar)= (nodevar)->part next) {         \
   39       assert((nodevar)->part next               \
   40          ? (nodevar) == (nodevar)->part next->part back \
   41          : (nodevar) == (list).tail);           \
   42       body                          \
   43     }                               \
   44   }
   45 
   46 #define DLIST_ASSERTON(node, nodevar, list, part)   \
   47   do {                          \
   48     for ((nodevar)= (list).head;            \
   49      (nodevar) != (node);               \
   50      (nodevar)= (nodevar)->part next) {     \
   51       assert((nodevar));                \
   52     }                           \
   53   } while(0)
   54 
   55 static void checkc_query_alloc(adns_state ads, adns_query qu) {
   56   allocnode *an;
   57 
   58   DLIST_CHECK(qu->allocations, an, , {
   59   });
   60 }
   61 
   62 static void checkc_query(adns_state ads, adns_query qu) {
   63   adns_query child;
   64 
   65   assert(qu->udpnextserver < ads->nservers);
   66   assert(!(qu->udpsent & (~0UL << ads->nservers)));
   67   assert(qu->search_pos <= ads->nsearchlist);
   68   if (qu->parent) DLIST_ASSERTON(qu, child, qu->parent->children, siblings.);
   69 }
   70 
   71 static void checkc_notcpbuf(adns_state ads) {
   72   assert(!ads->tcpsend.used);
   73   assert(!ads->tcprecv.used);
   74   assert(!ads->tcprecv_skip);
   75 }
   76 
   77 static void checkc_global(adns_state ads) {
   78   const struct sortlist *sl;
   79   int i;
   80   
   81   assert(ads->udpsockets >= 0);
   82 
   83   for (i=0; i<ads->nsortlist; i++) {
   84     sl= &ads->sortlist[i];
   85     assert(adns__addr_matches(sl->base.sa.sa_family,
   86                   adns__sockaddr_addr(&sl->base.sa),
   87                   &sl->base,&sl->mask));
   88   }
   89 
   90   assert(ads->tcpserver >= 0 && ads->tcpserver < ads->nservers);
   91   
   92   switch (ads->tcpstate) {
   93   case server_connecting:
   94     assert(ads->tcpsocket >= 0);
   95     checkc_notcpbuf(ads);
   96     break;
   97   case server_disconnected:
   98   case server_broken:
   99     assert(ads->tcpsocket == -1);
  100     checkc_notcpbuf(ads);
  101     break;
  102   case server_ok:
  103     assert(ads->tcpsocket >= 0);
  104     assert(ads->tcprecv_skip <= ads->tcprecv.used);
  105     break;
  106   default:
  107     assert(!"ads->tcpstate value");
  108   }
  109 
  110   assert(ads->searchlist || !ads->nsearchlist);
  111 }
  112 
  113 static void checkc_queue_udpw(adns_state ads) {
  114   adns_query qu;
  115   
  116   DLIST_CHECK(ads->udpw, qu, , {
  117     assert(qu->state==query_tosend);
  118     assert(qu->retries <= UDPMAXRETRIES);
  119     assert(qu->udpsent);
  120     assert(!qu->children.head && !qu->children.tail);
  121     checkc_query(ads,qu);
  122     checkc_query_alloc(ads,qu);
  123   });
  124 }
  125 
  126 static void checkc_queue_tcpw(adns_state ads) {
  127   adns_query qu;
  128   
  129   DLIST_CHECK(ads->tcpw, qu, , {
  130     assert(qu->state==query_tcpw);
  131     assert(!qu->children.head && !qu->children.tail);
  132     assert(qu->retries <= ads->nservers+1);
  133     checkc_query(ads,qu);
  134     checkc_query_alloc(ads,qu);
  135   });
  136 }
  137 
  138 static void checkc_queue_childw(adns_state ads) {
  139   adns_query parent, child;
  140 
  141   DLIST_CHECK(ads->childw, parent, , {
  142     assert(parent->state == query_childw);
  143     assert(parent->children.head);
  144     DLIST_CHECK(parent->children, child, siblings., {
  145       assert(child->parent == parent);
  146       assert(child->state != query_done);
  147     });
  148     checkc_query(ads,parent);
  149     checkc_query_alloc(ads,parent);
  150   });
  151 }
  152 
  153 static void checkc_query_done(adns_state ads, adns_query qu) {
  154   assert(qu->state == query_done);
  155   assert(!qu->children.head && !qu->children.tail);
  156   checkc_query(ads,qu);
  157 }
  158 
  159 static void checkc_queue_output(adns_state ads) {
  160   adns_query qu;
  161   
  162   DLIST_CHECK(ads->output, qu, , {
  163     assert(!qu->parent);
  164     assert(!qu->allocations.head && !qu->allocations.tail);
  165     checkc_query_done(ads,qu);
  166   });
  167 }
  168 
  169 static void checkc_queue_intdone(adns_state ads) {
  170   adns_query qu;
  171   
  172   DLIST_CHECK(ads->intdone, qu, , {
  173     assert(qu->parent);
  174     assert(qu->ctx.callback);
  175     checkc_query_done(ads,qu);
  176   });
  177 }
  178 
  179 void adns__consistency(adns_state ads, adns_query qu, consistency_checks cc) {
  180   adns_query search;
  181   
  182   switch (cc) {
  183   case cc_user:
  184     break;
  185   case cc_entex:
  186     if (!(ads->iflags & adns_if_checkc_entex)) return;
  187     assert(!ads->intdone.head);
  188     break;
  189   case cc_freq:
  190     if ((ads->iflags & adns_if_checkc_freq) != adns_if_checkc_freq) return;
  191     break;
  192   default:
  193     abort();
  194   }
  195 
  196   checkc_global(ads);
  197   checkc_queue_udpw(ads);
  198   checkc_queue_tcpw(ads);
  199   checkc_queue_childw(ads);
  200   checkc_queue_output(ads);
  201   checkc_queue_intdone(ads);
  202 
  203   if (qu) {
  204     switch (qu->state) {
  205     case query_tosend:
  206       DLIST_ASSERTON(qu, search, ads->udpw, );
  207       break;
  208     case query_tcpw:
  209       DLIST_ASSERTON(qu, search, ads->tcpw, );
  210       break;
  211     case query_childw:
  212       DLIST_ASSERTON(qu, search, ads->childw, );
  213       break;
  214     case query_done:
  215       if (qu->parent)
  216     DLIST_ASSERTON(qu, search, ads->intdone, );
  217       else
  218     DLIST_ASSERTON(qu, search, ads->output, );
  219       break;
  220     default:
  221       assert(!"specific query state");
  222     }
  223   }
  224 }