Diff for /embedaddon/dnsmasq/src/cache.c between versions 1.1.1.4 and 1.1.1.5

version 1.1.1.4, 2021/03/17 00:56:46 version 1.1.1.5, 2023/09/27 11:02:07
Line 1 Line 1
/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley/* dnsmasq is Copyright (c) 2000-2022 Simon Kelley
   
    This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
Line 28  static int bignames_left, hash_size; Line 28  static int bignames_left, hash_size;
 static void make_non_terminals(struct crec *source);  static void make_non_terminals(struct crec *source);
 static struct crec *really_insert(char *name, union all_addr *addr, unsigned short class,  static struct crec *really_insert(char *name, union all_addr *addr, unsigned short class,
                                   time_t now,  unsigned long ttl, unsigned int flags);                                    time_t now,  unsigned long ttl, unsigned int flags);
   static void dump_cache_entry(struct crec *cache, time_t now);
   
 /* type->string mapping: this is also used by the name-hash function as a mixing table. */  /* type->string mapping: this is also used by the name-hash function as a mixing table. */
   /* taken from https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml */
 static const struct {  static const struct {
   unsigned int type;    unsigned int type;
   const char * const name;    const char * const name;
 } typestr[] = {  } typestr[] = {
  { 1,   "A" },  { 1,   "A" }, /* a host address [RFC1035] */
  { 2,   "NS" },  { 2,   "NS" }, /* an authoritative name server [RFC1035] */
  { 5,   "CNAME" },  { 3,   "MD" }, /* a mail destination (OBSOLETE - use MX) [RFC1035] */
  { 6,   "SOA" },  { 4,   "MF" }, /* a mail forwarder (OBSOLETE - use MX) [RFC1035] */
  { 10,  "NULL" },  { 5,   "CNAME" }, /* the canonical name for an alias [RFC1035] */
  { 11,  "WKS" },  { 6,   "SOA" }, /* marks the start of a zone of authority [RFC1035] */
  { 12,  "PTR" },  { 7,   "MB" }, /* a mailbox domain name (EXPERIMENTAL) [RFC1035] */
  { 13,  "HINFO" },         { 8,   "MG" }, /* a mail group member (EXPERIMENTAL) [RFC1035] */
  { 15,  "MX" },  { 9,   "MR" }, /* a mail rename domain name (EXPERIMENTAL) [RFC1035] */
  { 16,  "TXT" },  { 10,  "NULL" }, /* a null RR (EXPERIMENTAL) [RFC1035] */
  { 22,  "NSAP" },  { 11,  "WKS" }, /* a well known service description [RFC1035] */
  { 23,  "NSAP_PTR" },  { 12,  "PTR" }, /* a domain name pointer [RFC1035] */
  { 24,  "SIG" },  { 13,  "HINFO" }, /* host information [RFC1035] */
  { 25,  "KEY" },  { 14,  "MINFO" }, /* mailbox or mail list information [RFC1035] */
  { 28,  "AAAA" },  { 15,  "MX" }, /* mail exchange [RFC1035] */
  { 29,  "LOC" },  { 16,  "TXT" }, /* text strings [RFC1035] */
  { 33,  "SRV" },  { 17,  "RP" }, /* for Responsible Person [RFC1183] */
  { 35,  "NAPTR" },  { 18,  "AFSDB" }, /* for AFS Data Base location [RFC1183][RFC5864] */
  { 36,  "KX" },  { 19,  "X25" }, /* for X.25 PSDN address [RFC1183] */
  { 37,  "CERT" },  { 20,  "ISDN" }, /* for ISDN address [RFC1183] */
  { 38,  "A6" },  { 21,  "RT" }, /* for Route Through [RFC1183] */
  { 39,  "DNAME" },  { 22,  "NSAP" }, /* for NSAP address, NSAP style A record [RFC1706] */
  { 41,  "OPT" },  { 23,  "NSAP_PTR" }, /* for domain name pointer, NSAP style [RFC1348][RFC1637][RFC1706] */
  { 43,  "DS" },  { 24,  "SIG" }, /* for security signature [RFC2535][RFC2536][RFC2537][RFC2931][RFC3008][RFC3110][RFC3755][RFC4034] */
  { 46,  "RRSIG" },  { 25,  "KEY" }, /* for security key [RFC2535][RFC2536][RFC2537][RFC2539][RFC3008][RFC3110][RFC3755][RFC4034] */
  { 47,  "NSEC" },  { 26,  "PX" }, /* X.400 mail mapping information [RFC2163] */
  { 48,  "DNSKEY" },  { 27,  "GPOS" }, /* Geographical Position [RFC1712] */
  { 50,  "NSEC3" },  { 28,  "AAAA" }, /* IP6 Address [RFC3596] */
  { 51,  "NSEC3PARAM" },  { 29,  "LOC" }, /* Location Information [RFC1876] */
  { 52,  "TLSA" },  { 30,  "NXT" }, /* Next Domain (OBSOLETE) [RFC2535][RFC3755] */
  { 53,  "SMIMEA" },  { 31,  "EID" }, /* Endpoint Identifier [Michael_Patton][http://ana-3.lcs.mit.edu/~jnc/nimrod/dns.txt] 1995-06*/
  { 55,  "HIP" },  { 32,  "NIMLOC" }, /* Nimrod Locator [1][Michael_Patton][http://ana-3.lcs.mit.edu/~jnc/nimrod/dns.txt] 1995-06*/
  { 249, "TKEY" },  { 33,  "SRV" }, /* Server Selection [1][RFC2782] */
  { 250, "TSIG" },  { 34,  "ATMA" }, /* ATM Address [ ATM Forum Technical Committee, "ATM Name System, V2.0", Doc ID: AF-DANS-0152.000, July 2000. Available from and held in escrow by IANA.] */
  { 251, "IXFR" },  { 35,  "NAPTR" }, /* Naming Authority Pointer [RFC2168][RFC2915][RFC3403] */
  { 252, "AXFR" },  { 36,  "KX" }, /* Key Exchanger [RFC2230] */
  { 253, "MAILB" },  { 37,  "CERT" }, /* CERT [RFC4398] */
  { 254, "MAILA" },  { 38,  "A6" }, /* A6 (OBSOLETE - use AAAA) [RFC2874][RFC3226][RFC6563] */
  { 255, "ANY" },  { 39,  "DNAME" }, /* DNAME [RFC6672] */
  { 257, "CAA" }  { 40,  "SINK" }, /* SINK [Donald_E_Eastlake][http://tools.ietf.org/html/draft-eastlake-kitchen-sink] 1997-11*/
   { 41,  "OPT" }, /* OPT [RFC3225][RFC6891] */
   { 42,  "APL" }, /* APL [RFC3123] */
   { 43,  "DS" }, /* Delegation Signer [RFC3658][RFC4034] */
   { 44,  "SSHFP" }, /* SSH Key Fingerprint [RFC4255] */
   { 45,  "IPSECKEY" }, /* IPSECKEY [RFC4025] */
   { 46,  "RRSIG" }, /* RRSIG [RFC3755][RFC4034] */
   { 47,  "NSEC" }, /* NSEC [RFC3755][RFC4034][RFC9077] */
   { 48,  "DNSKEY" }, /* DNSKEY [RFC3755][RFC4034] */
   { 49,  "DHCID" }, /* DHCID [RFC4701] */
   { 50,  "NSEC3" }, /* NSEC3 [RFC5155][RFC9077] */
   { 51,  "NSEC3PARAM" }, /* NSEC3PARAM [RFC5155] */
   { 52,  "TLSA" }, /* TLSA [RFC6698] */
   { 53,  "SMIMEA" }, /* S/MIME cert association [RFC8162] SMIMEA/smimea-completed-template 2015-12-01*/
   { 55,  "HIP" }, /* Host Identity Protocol [RFC8005] */
   { 56,  "NINFO" }, /* NINFO [Jim_Reid] NINFO/ninfo-completed-template 2008-01-21*/
   { 57,  "RKEY" }, /* RKEY [Jim_Reid] RKEY/rkey-completed-template 2008-01-21*/
   { 58,  "TALINK" }, /* Trust Anchor LINK [Wouter_Wijngaards] TALINK/talink-completed-template 2010-02-17*/
   { 59,  "CDS" }, /* Child DS [RFC7344] CDS/cds-completed-template 2011-06-06*/
   { 60,  "CDNSKEY" }, /* DNSKEY(s) the Child wants reflected in DS [RFC7344] 2014-06-16*/
   { 61,  "OPENPGPKEY" }, /* OpenPGP Key [RFC7929] OPENPGPKEY/openpgpkey-completed-template 2014-08-12*/
   { 62,  "CSYNC" }, /* Child-To-Parent Synchronization [RFC7477] 2015-01-27*/
   { 63,  "ZONEMD" }, /* Message Digest Over Zone Data [RFC8976] ZONEMD/zonemd-completed-template 2018-12-12*/
   { 64,  "SVCB" }, /* Service Binding [draft-ietf-dnsop-svcb-https-00] SVCB/svcb-completed-template 2020-06-30*/
   { 65,  "HTTPS" }, /* HTTPS Binding [draft-ietf-dnsop-svcb-https-00] HTTPS/https-completed-template 2020-06-30*/
   { 99,  "SPF" }, /* [RFC7208] */
   { 100, "UINFO" }, /* [IANA-Reserved] */
   { 101, "UID" }, /* [IANA-Reserved] */
   { 102, "GID" }, /* [IANA-Reserved] */
   { 103, "UNSPEC" }, /* [IANA-Reserved] */
   { 104, "NID" }, /* [RFC6742] ILNP/nid-completed-template */
   { 105, "L32" }, /* [RFC6742] ILNP/l32-completed-template */
   { 106, "L64" }, /* [RFC6742] ILNP/l64-completed-template */
   { 107, "LP" }, /* [RFC6742] ILNP/lp-completed-template */
   { 108, "EUI48" }, /* an EUI-48 address [RFC7043] EUI48/eui48-completed-template 2013-03-27*/
   { 109, "EUI64" }, /* an EUI-64 address [RFC7043] EUI64/eui64-completed-template 2013-03-27*/
   { 249, "TKEY" }, /* Transaction Key [RFC2930] */
   { 250, "TSIG" }, /* Transaction Signature [RFC8945] */
   { 251, "IXFR" }, /* incremental transfer [RFC1995] */
   { 252, "AXFR" }, /* transfer of an entire zone [RFC1035][RFC5936] */
   { 253, "MAILB" }, /* mailbox-related RRs (MB, MG or MR) [RFC1035] */
   { 254, "MAILA" }, /* mail agent RRs (OBSOLETE - see MX) [RFC1035] */
   { 255, "ANY" }, /* A request for some or all records the server has available [RFC1035][RFC6895][RFC8482] */
   { 256, "URI" }, /* URI [RFC7553] URI/uri-completed-template 2011-02-22*/
   { 257, "CAA" }, /* Certification Authority Restriction [RFC8659] CAA/caa-completed-template 2011-04-07*/
   { 258, "AVC" }, /* Application Visibility and Control [Wolfgang_Riedel] AVC/avc-completed-template 2016-02-26*/
   { 259, "DOA" }, /* Digital Object Architecture [draft-durand-doa-over-dns] DOA/doa-completed-template 2017-08-30*/
   { 260, "AMTRELAY" }, /* Automatic Multicast Tunneling Relay [RFC8777] AMTRELAY/amtrelay-completed-template 2019-02-06*/
   { 32768,  "TA" }, /* DNSSEC Trust Authorities [Sam_Weiler][http://cameo.library.cmu.edu/][ Deploying DNSSEC Without a Signed Root. Technical Report 1999-19, Information Networking Institute, Carnegie Mellon University, April 2004.] 2005-12-13*/
   { 32769,  "DLV" }, /* DNSSEC Lookaside Validation (OBSOLETE) [RFC8749][RFC4431] */
 };  };
   
 static void cache_free(struct crec *crecp);  static void cache_free(struct crec *crecp);
Line 139  static void rehash(int size) Line 190  static void rehash(int size)
   else if (new_size <= hash_size || !(new = whine_malloc(new_size * sizeof(struct crec *))))    else if (new_size <= hash_size || !(new = whine_malloc(new_size * sizeof(struct crec *))))
     return;      return;
   
  for(i = 0; i < new_size; i++)  for (i = 0; i < new_size; i++)
     new[i] = NULL;      new[i] = NULL;
   
   old = hash_table;    old = hash_table;
Line 183  static void cache_hash(struct crec *crecp) Line 234  static void cache_hash(struct crec *crecp)
      immortal entries are at the end of the hash-chain.       immortal entries are at the end of the hash-chain.
      This allows reverse searches and garbage collection to be optimised */       This allows reverse searches and garbage collection to be optimised */
   
  struct crec **up = hash_bucket(cache_get_name(crecp));  char *name = cache_get_name(crecp);
  struct crec **up = hash_bucket(name);
  if (!(crecp->flags & F_REVERSE))  unsigned int flags = crecp->flags & (F_IMMORTAL | F_REVERSE);
   
   if (!(flags & F_REVERSE))
     {      {
       while (*up && ((*up)->flags & F_REVERSE))        while (*up && ((*up)->flags & F_REVERSE))
         up = &((*up)->hash_next);           up = &((*up)->hash_next); 
               
      if (crecp->flags & F_IMMORTAL)      if (flags & F_IMMORTAL)
         while (*up && !((*up)->flags & F_IMMORTAL))          while (*up && !((*up)->flags & F_IMMORTAL))
           up = &((*up)->hash_next);            up = &((*up)->hash_next);
     }      }
   
     /* Preserve order when inserting the same name multiple times.
        Do not mess up the flag invariants. */
     while (*up &&
            hostname_isequal(cache_get_name(*up), name) &&
            flags == ((*up)->flags & (F_IMMORTAL | F_REVERSE)))
       up = &((*up)->hash_next);
     
   crecp->hash_next = *up;    crecp->hash_next = *up;
   *up = crecp;    *up = crecp;
 }  }
Line 324  static int is_outdated_cname_pointer(struct crec *crec Line 385  static int is_outdated_cname_pointer(struct crec *crec
   
 static int is_expired(time_t now, struct crec *crecp)  static int is_expired(time_t now, struct crec *crecp)
 {  {
     /* Don't dump expired entries if they are within the accepted timeout range.
        The cache becomes approx. LRU. Never use expired DS or DNSKEY entries.
        Possible values for daemon->cache_max_expiry:
         -1  == serve cached content regardless how long ago it expired
          0  == the option is disabled, expired content isn't served
         <n> == serve cached content only if it expire less than <n> seconds
                ago (where n is a positive integer) */
     if (daemon->cache_max_expiry != 0 &&
         (daemon->cache_max_expiry == -1 ||
          difftime(now, crecp->ttd) < daemon->cache_max_expiry) &&
         !(crecp->flags & (F_DS | F_DNSKEY)))
       return 0;
   
   if (crecp->flags & F_IMMORTAL)    if (crecp->flags & F_IMMORTAL)
     return 0;      return 0;
   
Line 333  static int is_expired(time_t now, struct crec *crecp) Line 407  static int is_expired(time_t now, struct crec *crecp)
   return 1;    return 1;
 }  }
   
   /* Remove entries with a given UID from the cache */
   unsigned int cache_remove_uid(const unsigned int uid)
   {
     int i;
     unsigned int removed = 0;
     struct crec *crecp, **up;
   
     for (i = 0; i < hash_size; i++)
       for (crecp = hash_table[i], up = &hash_table[i]; crecp; crecp = crecp->hash_next)
         if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) && crecp->uid == uid)
           {
             *up = crecp->hash_next;
             free(crecp);
             removed++;
           }
         else
           up = &crecp->hash_next;
     
     return removed;
   }
   
 static struct crec *cache_scan_free(char *name, union all_addr *addr, unsigned short class, time_t now,  static struct crec *cache_scan_free(char *name, union all_addr *addr, unsigned short class, time_t now,
                                     unsigned int flags, struct crec **target_crec, unsigned int *target_uid)                                      unsigned int flags, struct crec **target_crec, unsigned int *target_uid)
 {  {
Line 363  static struct crec *cache_scan_free(char *name, union  Line 458  static struct crec *cache_scan_free(char *name, union 
           if ((crecp->flags & F_FORWARD) && hostname_isequal(cache_get_name(crecp), name))            if ((crecp->flags & F_FORWARD) && hostname_isequal(cache_get_name(crecp), name))
             {              {
               /* Don't delete DNSSEC in favour of a CNAME, they can co-exist */                /* Don't delete DNSSEC in favour of a CNAME, they can co-exist */
              if ((flags & crecp->flags & (F_IPV4 | F_IPV6 | F_SRV)) ||               if ((flags & crecp->flags & (F_IPV4 | F_IPV6 | F_SRV | F_NXDOMAIN)) || 
                   (((crecp->flags | flags) & F_CNAME) && !(crecp->flags & (F_DNSKEY | F_DS))))                    (((crecp->flags | flags) & F_CNAME) && !(crecp->flags & (F_DNSKEY | F_DS))))
                 {                  {
                   if (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))                    if (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))
Line 433  static struct crec *cache_scan_free(char *name, union  Line 528  static struct crec *cache_scan_free(char *name, union 
           else if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) &&            else if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) &&
                    (flags & crecp->flags & F_REVERSE) &&                      (flags & crecp->flags & F_REVERSE) && 
                    (flags & crecp->flags & (F_IPV4 | F_IPV6)) &&                     (flags & crecp->flags & (F_IPV4 | F_IPV6)) &&
                   memcmp(&crecp->addr, addr, addrlen) == 0)                   addr && memcmp(&crecp->addr, addr, addrlen) == 0)
             {              {
               *up = crecp->hash_next;                *up = crecp->hash_next;
               cache_unlink(crecp);                cache_unlink(crecp);
Line 488  struct crec *cache_insert(char *name, union all_addr * Line 583  struct crec *cache_insert(char *name, union all_addr *
   else    else
 #endif  #endif
     {      {
       /* Don't log DNSSEC records here, done elsewhere */  
       log_query(flags | F_UPSTREAM, name, addr, NULL);  
       if (daemon->max_cache_ttl != 0 && daemon->max_cache_ttl < ttl)        if (daemon->max_cache_ttl != 0 && daemon->max_cache_ttl < ttl)
         ttl = daemon->max_cache_ttl;          ttl = daemon->max_cache_ttl;
       if (daemon->min_cache_ttl != 0 && daemon->min_cache_ttl > ttl)        if (daemon->min_cache_ttl != 0 && daemon->min_cache_ttl > ttl)
Line 505  static struct crec *really_insert(char *name, union al Line 598  static struct crec *really_insert(char *name, union al
 {  {
   struct crec *new, *target_crec = NULL;    struct crec *new, *target_crec = NULL;
   union bigname *big_name = NULL;    union bigname *big_name = NULL;
  int freed_all = flags & F_REVERSE;  int freed_all = (flags & F_REVERSE);
  int free_avail = 0;  struct crec *free_avail = NULL;
   unsigned int target_uid;    unsigned int target_uid;
       
   /* if previous insertion failed give up now. */    /* if previous insertion failed give up now. */
Line 554  static struct crec *really_insert(char *name, union al Line 647  static struct crec *really_insert(char *name, union al
               
       /* Free entry at end of LRU list, use it. */        /* Free entry at end of LRU list, use it. */
       if (!(new->flags & (F_FORWARD | F_REVERSE)))        if (!(new->flags & (F_FORWARD | F_REVERSE)))
        break;        break; 
   
       /* End of LRU list is still in use: if we didn't scan all the hash        /* End of LRU list is still in use: if we didn't scan all the hash
          chains for expired entries do that now. If we already tried that           chains for expired entries do that now. If we already tried that
Line 566  static struct crec *really_insert(char *name, union al Line 659  static struct crec *really_insert(char *name, union al
          insert. Once in this state, all inserts will probably fail. */           insert. Once in this state, all inserts will probably fail. */
       if (free_avail)        if (free_avail)
         {          {
          static int warned = 0;          my_syslog(LOG_ERR, _("Internal error in cache."));
          if (!warned)          /* Log the entry we tried to delete. */
            {          dump_cache_entry(free_avail, now);
              my_syslog(LOG_ERR, _("Internal error in cache.")); 
              warned = 1; 
            } 
           insert_error = 1;            insert_error = 1;
           return NULL;            return NULL;
         }          }
Line 579  static struct crec *really_insert(char *name, union al Line 669  static struct crec *really_insert(char *name, union al
       if (freed_all)        if (freed_all)
         {          {
           /* For DNSSEC records, uid holds class. */            /* For DNSSEC records, uid holds class. */
          free_avail = 1; /* Must be free space now. */          free_avail = new; /* Must be free space now. */
          cache_scan_free(cache_get_name(new), &new->addr, new->uid, now, new->flags, NULL, NULL);          
          daemon->metrics[METRIC_DNS_CACHE_LIVE_FREED]++;          /* condition valid when stale-caching */
           if (difftime(now, new->ttd) < 0)
             daemon->metrics[METRIC_DNS_CACHE_LIVE_FREED]++;
           
           cache_scan_free(cache_get_name(new), &new->addr, new->uid, now, new->flags, NULL, NULL); 
         }          }
       else        else
         {          {
Line 644  static struct crec *really_insert(char *name, union al Line 738  static struct crec *really_insert(char *name, union al
   new->ttd = now + (time_t)ttl;    new->ttd = now + (time_t)ttl;
   new->next = new_chain;    new->next = new_chain;
   new_chain = new;    new_chain = new;
  
   return new;    return new;
 }  }
   
Line 822  int cache_find_non_terminal(char *name, time_t now) Line 916  int cache_find_non_terminal(char *name, time_t now)
 struct crec *cache_find_by_name(struct crec *crecp, char *name, time_t now, unsigned int prot)  struct crec *cache_find_by_name(struct crec *crecp, char *name, time_t now, unsigned int prot)
 {  {
   struct crec *ans;    struct crec *ans;
  int no_rr = prot & F_NO_RR;  int no_rr = (prot & F_NO_RR) || option_bool(OPT_NORR);
   
   prot &= ~F_NO_RR;    prot &= ~F_NO_RR;
       
Line 970  struct crec *cache_find_by_addr(struct crec *crecp, un Line 1064  struct crec *cache_find_by_addr(struct crec *crecp, un
 static void add_hosts_entry(struct crec *cache, union all_addr *addr, int addrlen,   static void add_hosts_entry(struct crec *cache, union all_addr *addr, int addrlen, 
                             unsigned int index, struct crec **rhash, int hashsz)                              unsigned int index, struct crec **rhash, int hashsz)
 {  {
   struct crec *lookup = cache_find_by_name(NULL, cache_get_name(cache), 0, cache->flags & (F_IPV4 | F_IPV6));  
   int i;    int i;
   unsigned int j;     unsigned int j; 
     struct crec *lookup = NULL;
   
   /* Remove duplicates in hosts files. */    /* Remove duplicates in hosts files. */
  if (lookup && (lookup->flags & F_HOSTS) && memcmp(&lookup->addr, addr, addrlen) == 0)  while ((lookup = cache_find_by_name(lookup, cache_get_name(cache), 0, cache->flags & (F_IPV4 | F_IPV6))))
    {    if ((lookup->flags & F_HOSTS) && memcmp(&lookup->addr, addr, addrlen) == 0)
      free(cache);      {
      return;        free(cache);
    }        return;
       }
           
   /* Ensure there is only one address -> name mapping (first one trumps)     /* Ensure there is only one address -> name mapping (first one trumps) 
      We do this by steam here, The entries are kept in hash chains, linked       We do this by steam here, The entries are kept in hash chains, linked
Line 987  static void add_hosts_entry(struct crec *cache, union  Line 1082  static void add_hosts_entry(struct crec *cache, union 
      the array rhash, hashed on address. Note that rhash and the values       the array rhash, hashed on address. Note that rhash and the values
      in ->next are only valid  whilst reading hosts files: the buckets are       in ->next are only valid  whilst reading hosts files: the buckets are
      then freed, and the ->next pointer used for other things.        then freed, and the ->next pointer used for other things. 
   
      Only insert each unique address once into this hashing structure.       Only insert each unique address once into this hashing structure.
   
      This complexity avoids O(n^2) divergent CPU use whilst reading       This complexity avoids O(n^2) divergent CPU use whilst reading
Line 1084  int read_hostsfile(char *filename, unsigned int index, Line 1178  int read_hostsfile(char *filename, unsigned int index,
 {    {  
   FILE *f = fopen(filename, "r");    FILE *f = fopen(filename, "r");
   char *token = daemon->namebuff, *domain_suffix = NULL;    char *token = daemon->namebuff, *domain_suffix = NULL;
  int addr_count = 0, name_count = cache_size, lineno = 1;  int names_done = 0, name_count = cache_size, lineno = 1;
   unsigned int flags = 0;    unsigned int flags = 0;
   union all_addr addr;    union all_addr addr;
   int atnl, addrlen = 0;    int atnl, addrlen = 0;
Line 1120  int read_hostsfile(char *filename, unsigned int index, Line 1214  int read_hostsfile(char *filename, unsigned int index,
           continue;            continue;
         }          }
               
       addr_count++;  
         
       /* rehash every 1000 names. */        /* rehash every 1000 names. */
       if (rhash && ((name_count - cache_size) > 1000))        if (rhash && ((name_count - cache_size) > 1000))
         {          {
Line 1153  int read_hostsfile(char *filename, unsigned int index, Line 1245  int read_hostsfile(char *filename, unsigned int index,
                   cache->ttd = daemon->local_ttl;                    cache->ttd = daemon->local_ttl;
                   add_hosts_entry(cache, &addr, addrlen, index, rhash, hashsz);                    add_hosts_entry(cache, &addr, addrlen, index, rhash, hashsz);
                   name_count++;                    name_count++;
                     names_done++;
                 }                  }
               if ((cache = whine_malloc(SIZEOF_BARE_CREC + strlen(canon) + 1)))                if ((cache = whine_malloc(SIZEOF_BARE_CREC + strlen(canon) + 1)))
                 {                  {
Line 1161  int read_hostsfile(char *filename, unsigned int index, Line 1254  int read_hostsfile(char *filename, unsigned int index,
                   cache->ttd = daemon->local_ttl;                    cache->ttd = daemon->local_ttl;
                   add_hosts_entry(cache, &addr, addrlen, index, rhash, hashsz);                    add_hosts_entry(cache, &addr, addrlen, index, rhash, hashsz);
                   name_count++;                    name_count++;
                     names_done++;
                 }                  }
               free(canon);                free(canon);
                               
Line 1177  int read_hostsfile(char *filename, unsigned int index, Line 1271  int read_hostsfile(char *filename, unsigned int index,
   if (rhash)    if (rhash)
     rehash(name_count);       rehash(name_count); 
       
  my_syslog(LOG_INFO, _("read %s - %d addresses"), filename, addr_count);  my_syslog(LOG_INFO, _("read %s - %d names"), filename, names_done);
       
   return name_count;    return name_count;
 }  }
Line 1351  struct in_addr a_record_from_hosts(char *name, time_t  Line 1445  struct in_addr a_record_from_hosts(char *name, time_t 
   struct crec *crecp = NULL;    struct crec *crecp = NULL;
   struct in_addr ret;    struct in_addr ret;
       
  while ((crecp = cache_find_by_name(crecp, name, now, F_IPV4)))  /* If no DNS service, cache not initialised. */
    if (crecp->flags & F_HOSTS)  if (daemon->port != 0)
      return crecp->addr.addr4;    while ((crecp = cache_find_by_name(crecp, name, now, F_IPV4)))
      if (crecp->flags & F_HOSTS)
         return crecp->addr.addr4;
   
   my_syslog(MS_DHCP | LOG_WARNING, _("No IPv4 address found for %s"), name);    my_syslog(MS_DHCP | LOG_WARNING, _("No IPv4 address found for %s"), name);
       
   ret.s_addr = 0;    ret.s_addr = 0;
Line 1549  static void make_non_terminals(struct crec *source) Line 1645  static void make_non_terminals(struct crec *source)
       if (crecp)        if (crecp)
         {          {
           crecp->flags = (source->flags | F_NAMEP) & ~(F_IPV4 | F_IPV6 | F_CNAME | F_SRV | F_DNSKEY | F_DS | F_REVERSE);            crecp->flags = (source->flags | F_NAMEP) & ~(F_IPV4 | F_IPV6 | F_CNAME | F_SRV | F_DNSKEY | F_DS | F_REVERSE);
          crecp->ttd = source->ttd;          if (!(crecp->flags & F_IMMORTAL))
             crecp->ttd = source->ttd;
           crecp->name.namep = name;            crecp->name.namep = name;
                       
           cache_hash(crecp);            cache_hash(crecp);
Line 1602  int cache_make_stat(struct txt_record *t) Line 1699  int cache_make_stat(struct txt_record *t)
     case TXT_STAT_SERVERS:      case TXT_STAT_SERVERS:
       /* sum counts from different records for same server */        /* sum counts from different records for same server */
       for (serv = daemon->servers; serv; serv = serv->next)        for (serv = daemon->servers; serv; serv = serv->next)
        serv->flags &= ~SERV_COUNTED;        serv->flags &= ~SERV_MARK;
               
       for (serv = daemon->servers; serv; serv = serv->next)        for (serv = daemon->servers; serv; serv = serv->next)
        if (!(serv->flags &         if (!(serv->flags & SERV_MARK))
              (SERV_NO_ADDR | SERV_LITERAL_ADDRESS | SERV_COUNTED | SERV_USE_RESOLV | SERV_NO_REBIND))) 
           {            {
             char *new, *lenp;              char *new, *lenp;
             int port, newlen, bytes_avail, bytes_needed;              int port, newlen, bytes_avail, bytes_needed;
             unsigned int queries = 0, failed_queries = 0;              unsigned int queries = 0, failed_queries = 0;
             for (serv1 = serv; serv1; serv1 = serv1->next)              for (serv1 = serv; serv1; serv1 = serv1->next)
              if (!(serv1->flags &               if (!(serv1->flags & SERV_MARK) && sockaddr_isequal(&serv->addr, &serv1->addr))
                    (SERV_NO_ADDR | SERV_LITERAL_ADDRESS | SERV_COUNTED | SERV_USE_RESOLV | SERV_NO_REBIND)) &&  
                  sockaddr_isequal(&serv->addr, &serv1->addr)) 
                 {                  {
                  serv1->flags |= SERV_COUNTED;                  serv1->flags |= SERV_MARK;
                   queries += serv1->queries;                    queries += serv1->queries;
                   failed_queries += serv1->failed_queries;                    failed_queries += serv1->failed_queries;
                 }                  }
Line 1628  int cache_make_stat(struct txt_record *t) Line 1722  int cache_make_stat(struct txt_record *t)
               {                {
                 /* expand buffer if necessary */                  /* expand buffer if necessary */
                 newlen = bytes_needed + 1 + bufflen - bytes_avail;                  newlen = bytes_needed + 1 + bufflen - bytes_avail;
                if (!(new = whine_malloc(newlen)))                if (!(new = whine_realloc(buff, newlen)))
                   return 0;                    return 0;
                 memcpy(new, buff, bufflen);  
                 free(buff);  
                 p = new + (p - buff);                  p = new + (p - buff);
                 lenp = p - 1;                  lenp = p - 1;
                 buff = new;                  buff = new;
Line 1644  int cache_make_stat(struct txt_record *t) Line 1736  int cache_make_stat(struct txt_record *t)
           }            }
       t->txt = (unsigned char *)buff;        t->txt = (unsigned char *)buff;
       t->len = p - buff;        t->len = p - buff;
   
       return 1;        return 1;
     }      }
       
Line 1668  static char *sanitise(char *name) Line 1761  static char *sanitise(char *name)
   return name;    return name;
 }  }
   
   static void dump_cache_entry(struct crec *cache, time_t now)
   {
     (void)now;
     static char *buff = NULL;
     
     char *p, *t = " ";
     char *a = daemon->addrbuff, *n = cache_get_name(cache);
   
     /* String length is limited below */
     if (!buff && !(buff = whine_malloc(150)))
       return;
     
     p = buff;
     
     *a = 0;
     if (strlen(n) == 0 && !(cache->flags & F_REVERSE))
       n = "<Root>";
     p += sprintf(p, "%-30.30s ", sanitise(n));
     if ((cache->flags & F_CNAME) && !is_outdated_cname_pointer(cache))
       a = sanitise(cache_get_cname_target(cache));
     else if ((cache->flags & F_SRV) && !(cache->flags & F_NEG))
       {
         int targetlen = cache->addr.srv.targetlen;
         ssize_t len = sprintf(a, "%u %u %u ", cache->addr.srv.priority,
                               cache->addr.srv.weight, cache->addr.srv.srvport);
         
         if (targetlen > (40 - len))
           targetlen = 40 - len;
         blockdata_retrieve(cache->addr.srv.target, targetlen, a + len);
         a[len + targetlen] = 0;           
       }
   #ifdef HAVE_DNSSEC
     else if (cache->flags & F_DS)
       {
         if (!(cache->flags & F_NEG))
           sprintf(a, "%5u %3u %3u", cache->addr.ds.keytag,
                   cache->addr.ds.algo, cache->addr.ds.digest);
       }
     else if (cache->flags & F_DNSKEY)
       sprintf(a, "%5u %3u %3u", cache->addr.key.keytag,
               cache->addr.key.algo, cache->addr.key.flags);
   #endif
     else if (!(cache->flags & F_NEG) || !(cache->flags & F_FORWARD))
       { 
         a = daemon->addrbuff;
         if (cache->flags & F_IPV4)
           inet_ntop(AF_INET, &cache->addr, a, ADDRSTRLEN);
         else if (cache->flags & F_IPV6)
           inet_ntop(AF_INET6, &cache->addr, a, ADDRSTRLEN);
       }
     
     if (cache->flags & F_IPV4)
       t = "4";
     else if (cache->flags & F_IPV6)
       t = "6";
     else if (cache->flags & F_CNAME)
       t = "C";
     else if (cache->flags & F_SRV)
       t = "V";
   #ifdef HAVE_DNSSEC
     else if (cache->flags & F_DS)
       t = "S";
     else if (cache->flags & F_DNSKEY)
       t = "K";
   #endif
     else if (!(cache->flags & F_NXDOMAIN)) /* non-terminal */
       t = "!";
     
     p += sprintf(p, "%-40.40s %s%s%s%s%s%s%s%s%s%s ", a, t,
                  cache->flags & F_FORWARD ? "F" : " ",
                  cache->flags & F_REVERSE ? "R" : " ",
                  cache->flags & F_IMMORTAL ? "I" : " ",
                  cache->flags & F_DHCP ? "D" : " ",
                  cache->flags & F_NEG ? "N" : " ",
                  cache->flags & F_NXDOMAIN ? "X" : " ",
                  cache->flags & F_HOSTS ? "H" : " ",
                  cache->flags & F_CONFIG ? "C" : " ",
                  cache->flags & F_DNSSECOK ? "V" : " ");
   #ifdef HAVE_BROKEN_RTC
     p += sprintf(p, "%-24lu", cache->flags & F_IMMORTAL ? 0: (unsigned long)(cache->ttd - now));
   #else
     p += sprintf(p, "%-24.24s", cache->flags & F_IMMORTAL ? "" : ctime(&(cache->ttd)));
   #endif
     if(cache->flags & (F_HOSTS | F_CONFIG) && cache->uid > 0)
       p += sprintf(p, " %-40.40s", record_source(cache->uid));
     
     my_syslog(LOG_INFO, "%s", buff);
   }
   
 void dump_cache(time_t now)  void dump_cache(time_t now)
 {  {
   struct server *serv, *serv1;    struct server *serv, *serv1;
Line 1678  void dump_cache(time_t now) Line 1859  void dump_cache(time_t now)
             daemon->cachesize, daemon->metrics[METRIC_DNS_CACHE_LIVE_FREED], daemon->metrics[METRIC_DNS_CACHE_INSERTED]);              daemon->cachesize, daemon->metrics[METRIC_DNS_CACHE_LIVE_FREED], daemon->metrics[METRIC_DNS_CACHE_INSERTED]);
   my_syslog(LOG_INFO, _("queries forwarded %u, queries answered locally %u"),     my_syslog(LOG_INFO, _("queries forwarded %u, queries answered locally %u"), 
             daemon->metrics[METRIC_DNS_QUERIES_FORWARDED], daemon->metrics[METRIC_DNS_LOCAL_ANSWERED]);              daemon->metrics[METRIC_DNS_QUERIES_FORWARDED], daemon->metrics[METRIC_DNS_LOCAL_ANSWERED]);
     if (daemon->cache_max_expiry != 0)
       my_syslog(LOG_INFO, _("queries answered from stale cache %u"), daemon->metrics[METRIC_DNS_STALE_ANSWERED]);
 #ifdef HAVE_AUTH  #ifdef HAVE_AUTH
   my_syslog(LOG_INFO, _("queries for authoritative zones %u"), daemon->metrics[METRIC_DNS_AUTH_ANSWERED]);    my_syslog(LOG_INFO, _("queries for authoritative zones %u"), daemon->metrics[METRIC_DNS_AUTH_ANSWERED]);
 #endif  #endif
Line 1686  void dump_cache(time_t now) Line 1869  void dump_cache(time_t now)
   
   /* sum counts from different records for same server */    /* sum counts from different records for same server */
   for (serv = daemon->servers; serv; serv = serv->next)    for (serv = daemon->servers; serv; serv = serv->next)
    serv->flags &= ~SERV_COUNTED;    serv->flags &= ~SERV_MARK;
       
   for (serv = daemon->servers; serv; serv = serv->next)    for (serv = daemon->servers; serv; serv = serv->next)
    if (!(serv->flags &     if (!(serv->flags & SERV_MARK))
          (SERV_NO_ADDR | SERV_LITERAL_ADDRESS | SERV_COUNTED | SERV_USE_RESOLV | SERV_NO_REBIND))) 
       {        {
         int port;          int port;
        unsigned int queries = 0, failed_queries = 0;        unsigned int queries = 0, failed_queries = 0, nxdomain_replies = 0, retrys = 0;
         unsigned int sigma_latency = 0, count_latency = 0;
 
         for (serv1 = serv; serv1; serv1 = serv1->next)          for (serv1 = serv; serv1; serv1 = serv1->next)
          if (!(serv1->flags &           if (!(serv1->flags & SERV_MARK) && sockaddr_isequal(&serv->addr, &serv1->addr))
                (SERV_NO_ADDR | SERV_LITERAL_ADDRESS | SERV_COUNTED | SERV_USE_RESOLV | SERV_NO_REBIND)) &&  
              sockaddr_isequal(&serv->addr, &serv1->addr)) 
             {              {
              serv1->flags |= SERV_COUNTED;              serv1->flags |= SERV_MARK;
               queries += serv1->queries;                queries += serv1->queries;
               failed_queries += serv1->failed_queries;                failed_queries += serv1->failed_queries;
                 nxdomain_replies += serv1->nxdomain_replies;
                 retrys += serv1->retrys;
                 sigma_latency += serv1->query_latency;
                 count_latency++;
             }              }
         port = prettyprint_addr(&serv->addr, daemon->addrbuff);          port = prettyprint_addr(&serv->addr, daemon->addrbuff);
        my_syslog(LOG_INFO, _("server %s#%d: queries sent %u, retried or failed %u"), daemon->addrbuff, port, queries, failed_queries);        my_syslog(LOG_INFO, _("server %s#%d: queries sent %u, retried %u, failed %u, nxdomain replies %u, avg. latency %ums"),
                   daemon->addrbuff, port, queries, retrys, failed_queries, nxdomain_replies, sigma_latency/count_latency);
       }        }
  
   if (option_bool(OPT_DEBUG) || option_bool(OPT_LOG))    if (option_bool(OPT_DEBUG) || option_bool(OPT_LOG))
     {      {
      struct crec *cache ;      struct crec *cache;
       int i;        int i;
      my_syslog(LOG_INFO, "Host                                     Address                        Flags      Expires");      my_syslog(LOG_INFO, "Host                           Address                                  Flags      Expires                  Source");
       my_syslog(LOG_INFO, "------------------------------ ---------------------------------------- ---------- ------------------------ ------------");
           
       for (i=0; i<hash_size; i++)        for (i=0; i<hash_size; i++)
         for (cache = hash_table[i]; cache; cache = cache->hash_next)          for (cache = hash_table[i]; cache; cache = cache->hash_next)
          {          dump_cache_entry(cache, now);
            char *t = " "; 
            char *a = daemon->addrbuff, *p = daemon->namebuff, *n = cache_get_name(cache); 
            *a = 0; 
            if (strlen(n) == 0 && !(cache->flags & F_REVERSE)) 
              n = "<Root>"; 
            p += sprintf(p, "%-30.30s ", sanitise(n)); 
            if ((cache->flags & F_CNAME) && !is_outdated_cname_pointer(cache)) 
              a = sanitise(cache_get_cname_target(cache)); 
            else if ((cache->flags & F_SRV) && !(cache->flags & F_NEG)) 
              { 
                int targetlen = cache->addr.srv.targetlen; 
                ssize_t len = sprintf(a, "%u %u %u ", cache->addr.srv.priority, 
                                      cache->addr.srv.weight, cache->addr.srv.srvport); 
 
                if (targetlen > (40 - len)) 
                  targetlen = 40 - len; 
                blockdata_retrieve(cache->addr.srv.target, targetlen, a + len); 
                a[len + targetlen] = 0;          
              } 
#ifdef HAVE_DNSSEC 
            else if (cache->flags & F_DS) 
              { 
                if (!(cache->flags & F_NEG)) 
                  sprintf(a, "%5u %3u %3u", cache->addr.ds.keytag, 
                          cache->addr.ds.algo, cache->addr.ds.digest); 
              } 
            else if (cache->flags & F_DNSKEY) 
              sprintf(a, "%5u %3u %3u", cache->addr.key.keytag, 
                      cache->addr.key.algo, cache->addr.key.flags); 
#endif 
            else if (!(cache->flags & F_NEG) || !(cache->flags & F_FORWARD)) 
              {  
                a = daemon->addrbuff; 
                if (cache->flags & F_IPV4) 
                  inet_ntop(AF_INET, &cache->addr, a, ADDRSTRLEN); 
                else if (cache->flags & F_IPV6) 
                  inet_ntop(AF_INET6, &cache->addr, a, ADDRSTRLEN); 
              } 
 
            if (cache->flags & F_IPV4) 
              t = "4"; 
            else if (cache->flags & F_IPV6) 
              t = "6"; 
            else if (cache->flags & F_CNAME) 
              t = "C"; 
            else if (cache->flags & F_SRV) 
              t = "V"; 
#ifdef HAVE_DNSSEC 
            else if (cache->flags & F_DS) 
              t = "S"; 
            else if (cache->flags & F_DNSKEY) 
              t = "K"; 
#endif 
            p += sprintf(p, "%-40.40s %s%s%s%s%s%s%s%s%s  ", a, t, 
                         cache->flags & F_FORWARD ? "F" : " ", 
                         cache->flags & F_REVERSE ? "R" : " ", 
                         cache->flags & F_IMMORTAL ? "I" : " ", 
                         cache->flags & F_DHCP ? "D" : " ", 
                         cache->flags & F_NEG ? "N" : " ", 
                         cache->flags & F_NXDOMAIN ? "X" : " ", 
                         cache->flags & F_HOSTS ? "H" : " ", 
                         cache->flags & F_DNSSECOK ? "V" : " "); 
#ifdef HAVE_BROKEN_RTC 
            p += sprintf(p, "%lu", cache->flags & F_IMMORTAL ? 0: (unsigned long)(cache->ttd - now)); 
#else 
            p += sprintf(p, "%s", cache->flags & F_IMMORTAL ? "\n" : ctime(&(cache->ttd))); 
            /* ctime includes trailing \n - eat it */ 
            *(p-1) = 0; 
#endif 
            my_syslog(LOG_INFO, "%s", daemon->namebuff); 
          } 
     }      }
 }  }
   
 char *record_source(unsigned int index)  char *record_source(unsigned int index)
 {  {
   struct hostsfile *ah;    struct hostsfile *ah;
#ifdef HAVE_INOTIFY
   struct dyndir *dd;
 #endif
   
   if (index == SRC_CONFIG)    if (index == SRC_CONFIG)
     return "config";      return "config";
   else if (index == SRC_HOSTS)    else if (index == SRC_HOSTS)
Line 1804  char *record_source(unsigned int index) Line 1924  char *record_source(unsigned int index)
       return ah->fname;        return ah->fname;
   
 #ifdef HAVE_INOTIFY  #ifdef HAVE_INOTIFY
  for (ah = daemon->dynamic_dirs; ah; ah = ah->next)  /* Dynamic directories contain multiple files */
     if (ah->index == index)  for (dd = daemon->dynamic_dirs; dd; dd = dd->next)
       return ah->fname;    for (ah = dd->files; ah; ah = ah->next)
       if (ah->index == index)
         return ah->fname;
 #endif  #endif
   
   return "<unknown>";    return "<unknown>";
 }  }
   
char *querystr(char *desc, unsigned short type)static char *querystr(char *desc, unsigned short type)
 {  {
   unsigned int i;    unsigned int i;
   int len = 10; /* strlen("type=xxxxx") */    int len = 10; /* strlen("type=xxxxx") */
Line 1860  char *querystr(char *desc, unsigned short type) Line 1982  char *querystr(char *desc, unsigned short type)
           if (types)            if (types)
             sprintf(buff, "<%s>", types);              sprintf(buff, "<%s>", types);
           else            else
            sprintf(buff, "type=%d", type);            sprintf(buff, "<type=%d>", type);
         }          }
     }      }
       
   return buff ? buff : "";    return buff ? buff : "";
 }  }
   
void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg)static char *edestr(int ede)
 {  {
  char *source, *dest = daemon->addrbuff;  switch (ede)
     {
     case EDE_OTHER:                       return "other";
     case EDE_USUPDNSKEY:                  return "unsupported DNSKEY algorithm";
     case EDE_USUPDS:                      return "unsupported DS digest";
     case EDE_STALE:                       return "stale answer";
     case EDE_FORGED:                      return "forged";
     case EDE_DNSSEC_IND:                  return "DNSSEC indeterminate";
     case EDE_DNSSEC_BOGUS:                return "DNSSEC bogus";
     case EDE_SIG_EXP:                     return "DNSSEC signature expired";
     case EDE_SIG_NYV:                     return "DNSSEC sig not yet valid";
     case EDE_NO_DNSKEY:                   return "DNSKEY missing";
     case EDE_NO_RRSIG:                    return "RRSIG missing";
     case EDE_NO_ZONEKEY:                  return "no zone key bit set";
     case EDE_NO_NSEC:                     return "NSEC(3) missing";
     case EDE_CACHED_ERR:                  return "cached error";
     case EDE_NOT_READY:                   return "not ready";
     case EDE_BLOCKED:                     return "blocked";
     case EDE_CENSORED:                    return "censored";
     case EDE_FILTERED:                    return "filtered";
     case EDE_PROHIBITED:                  return "prohibited";
     case EDE_STALE_NXD:                   return "stale NXDOMAIN";
     case EDE_NOT_AUTH:                    return "not authoritative";
     case EDE_NOT_SUP:                     return "not supported";
     case EDE_NO_AUTH:                     return "no reachable authority";
     case EDE_NETERR:                      return "network error";
     case EDE_INVALID_DATA:                return "invalid data";
     default:                              return "unknown";
     }
 }
 
 void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg, unsigned short type)
 {
   char *source, *dest = arg;
   char *verb = "is";    char *verb = "is";
     char *extra = "";
     char portstring[7]; /* space for #<portnum> */
       
   if (!option_bool(OPT_LOG))    if (!option_bool(OPT_LOG))
     return;      return;
   
     /* build query type string if requested */
     if (!(flags & (F_SERVER | F_IPSET)) && type > 0)
       arg = querystr(arg, type);
   
   #ifdef HAVE_DNSSEC
     if ((flags & F_DNSSECOK) && option_bool(OPT_EXTRALOG))
       extra = " (DNSSEC signed)";
   #endif
   
   name = sanitise(name);    name = sanitise(name);
   
   if (addr)    if (addr)
     {      {
         dest = daemon->addrbuff;
   
       if (flags & F_KEYTAG)        if (flags & F_KEYTAG)
         sprintf(daemon->addrbuff, arg, addr->log.keytag, addr->log.algo, addr->log.digest);          sprintf(daemon->addrbuff, arg, addr->log.keytag, addr->log.algo, addr->log.digest);
       else if (flags & F_RCODE)        else if (flags & F_RCODE)
         {          {
           unsigned int rcode = addr->log.rcode;            unsigned int rcode = addr->log.rcode;
   
           if (rcode == SERVFAIL)          if (rcode == SERVFAIL)
             dest = "SERVFAIL";            dest = "SERVFAIL";
           else if (rcode == REFUSED)          else if (rcode == REFUSED)
             dest = "REFUSED";            dest = "REFUSED";
           else if (rcode == NOTIMP)          else if (rcode == NOTIMP)
             dest = "not implemented";            dest = "not implemented";
           else          else
             sprintf(daemon->addrbuff, "%u", rcode);            sprintf(daemon->addrbuff, "%u", rcode);
 
           if (addr->log.ede != EDE_UNSET)
             {
               extra = daemon->addrbuff;
               sprintf(extra, " (EDE: %s)", edestr(addr->log.ede));
             }
         }          }
         else if (flags & (F_IPV4 | F_IPV6))
           {
             inet_ntop(flags & F_IPV4 ? AF_INET : AF_INET6,
                       addr, daemon->addrbuff, ADDRSTRLEN);
             if ((flags & F_SERVER) && type != NAMESERVER_PORT)
               {
                 extra = portstring;
                 sprintf(portstring, "#%u", type);
               }
           }
       else        else
        inet_ntop(flags & F_IPV4 ? AF_INET : AF_INET6,        dest = arg;
                  addr, daemon->addrbuff, ADDRSTRLEN); 
       
     }      }
   else  
     dest = arg;  
   
   if (flags & F_REVERSE)    if (flags & F_REVERSE)
     {      {
Line 1938  void log_query(unsigned int flags, char *name, union a Line 2118  void log_query(unsigned int flags, char *name, union a
   else if (flags & F_UPSTREAM)    else if (flags & F_UPSTREAM)
     source = "reply";      source = "reply";
   else if (flags & F_SECSTAT)    else if (flags & F_SECSTAT)
    source = "validation";    {
       if (addr && addr->log.ede != EDE_UNSET && option_bool(OPT_EXTRALOG))
         {
           extra = daemon->addrbuff;
           sprintf(extra, " (EDE: %s)", edestr(addr->log.ede));
         }
       source = "validation";
       dest = arg;
     }
   else if (flags & F_AUTH)    else if (flags & F_AUTH)
     source = "auth";      source = "auth";
  else if (flags & F_SERVER)   else if (flags & F_DNSSEC)
     {      {
         source = arg;
         verb = "to";
       }
      else if (flags & F_SERVER)
       {
       source = "forwarded";        source = "forwarded";
       verb = "to";        verb = "to";
     }      }
Line 1951  void log_query(unsigned int flags, char *name, union a Line 2144  void log_query(unsigned int flags, char *name, union a
       source = arg;        source = arg;
       verb = "from";        verb = "from";
     }      }
   else if (flags & F_DNSSEC)  
     {  
       source = arg;  
       verb = "to";  
     }  
   else if (flags & F_IPSET)    else if (flags & F_IPSET)
     {      {
      source = "ipset add";      source = type ? "ipset add" : "nftset add";
       dest = name;        dest = name;
       name = arg;        name = arg;
       verb = daemon->addrbuff;        verb = daemon->addrbuff;
     }      }
     else if (flags & F_STALE)
       source = "cached-stale";
   else    else
     source = "cached";      source = "cached";
       
  if (strlen(name) == 0)  if (name && !name[0])
     name = ".";      name = ".";
   
   if (option_bool(OPT_EXTRALOG))    if (option_bool(OPT_EXTRALOG))
     {      {
       int port = prettyprint_addr(daemon->log_source_addr, daemon->addrbuff2);  
       if (flags & F_NOEXTRA)        if (flags & F_NOEXTRA)
        my_syslog(LOG_INFO, "* %s/%u %s %s %s %s", daemon->addrbuff2, port, source, name, verb, dest);        my_syslog(LOG_INFO, "%u %s %s %s %s%s", daemon->log_display_id, source, name, verb, dest, extra);
       else        else
        my_syslog(LOG_INFO, "%u %s/%u %s %s %s %s", daemon->log_display_id, daemon->addrbuff2, port, source, name, verb, dest);        {
            int port = prettyprint_addr(daemon->log_source_addr, daemon->addrbuff2);
            my_syslog(LOG_INFO, "%u %s/%u %s %s %s %s%s", daemon->log_display_id, daemon->addrbuff2, port, source, name, verb, dest, extra);
         }
     }      }
   else    else
    my_syslog(LOG_INFO, "%s %s %s %s", source, name, verb, dest);    my_syslog(LOG_INFO, "%s %s %s %s%s", source, name, verb, dest, extra);
 }  }
   
    

Removed from v.1.1.1.4  
changed lines
  Added in v.1.1.1.5


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>