Diff for /embedaddon/dnsmasq/src/auth.c between versions 1.1.1.1 and 1.1.1.3

version 1.1.1.1, 2013/07/29 19:37:40 version 1.1.1.3, 2016/11/02 09:57:01
Line 1 Line 1
/* dnsmasq is Copyright (c) 2000-2013 Simon Kelley/* dnsmasq is Copyright (c) 2000-2016 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 18 Line 18
   
 #ifdef HAVE_AUTH  #ifdef HAVE_AUTH
   
static struct subnet *filter_zone(struct auth_zone *zone, int flag, struct all_addr *addr_u)static struct addrlist *find_subnet(struct auth_zone *zone, int flag, struct all_addr *addr_u)
 {  {
  struct subnet *subnet;  struct addrlist *subnet;
   
   for (subnet = zone->subnet; subnet; subnet = subnet->next)    for (subnet = zone->subnet; subnet; subnet = subnet->next)
     {      {
      if (subnet->is6 && (flag & F_IPV4))      if (!(subnet->flags & ADDRLIST_IPV6))
        continue; 
 
      if (!subnet->is6) 
         {          {
          struct in_addr addr = addr_u->addr.addr4;          struct in_addr netmask, addr = addr_u->addr.addr4;
          struct in_addr mask;
           if (!(flag & F_IPV4))
             continue;
                       
          mask.s_addr = htonl(~((1 << (32 - subnet->prefixlen)) - 1));          netmask.s_addr = htonl(~(in_addr_t)0 << (32 - subnet->prefixlen));
                       
          if  (is_same_net(addr, subnet->addr4, mask))          if  (is_same_net(addr, subnet->addr.addr.addr4, netmask))
             return subnet;              return subnet;
         }          }
 #ifdef HAVE_IPV6  #ifdef HAVE_IPV6
      else if (is_same_net6(&(addr_u->addr.addr6), &subnet->addr6, subnet->prefixlen))      else if (is_same_net6(&(addr_u->addr.addr6), &subnet->addr.addr.addr6, subnet->prefixlen))
         return subnet;          return subnet;
 #endif  #endif
   
Line 46  static struct subnet *filter_zone(struct auth_zone *zo Line 45  static struct subnet *filter_zone(struct auth_zone *zo
   return NULL;    return NULL;
 }  }
   
static int filter_constructed_dhcp(struct auth_zone *zone, int flag, struct all_addr *addr_u)static int filter_zone(struct auth_zone *zone, int flag, struct all_addr *addr_u)
 {  {
#ifdef HAVE_DHCP6  /* No zones specified, no filter */
  struct dhcp_context *context;  if (!zone->subnet)
    return 1;
  if (flag & F_IPV6) 
    for (context = daemon->dhcp6; context; context = context->next) 
      if ((context->flags & CONTEXT_CONSTRUCTED) && 
          is_same_net6(&(addr_u->addr.addr6), &context->start6, context->prefix)) 
        return 1; 
#endif 
       
  return filter_zone(zone, flag, addr_u) != NULL;  return find_subnet(zone, flag, addr_u) != NULL;
 }  }
   
static int in_zone(struct auth_zone *zone, char *name, char **cut)int in_zone(struct auth_zone *zone, char *name, char **cut)
 {  {
   size_t namelen = strlen(name);    size_t namelen = strlen(name);
   size_t domainlen = strlen(zone->domain);    size_t domainlen = strlen(zone->domain);
Line 88  static int in_zone(struct auth_zone *zone, char *name, Line 81  static int in_zone(struct auth_zone *zone, char *name,
 }  }
   
   
size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t now, union mysockaddr *peer_addrsize_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t now, union mysockaddr *peer_addr
                    int local_query, int do_bit, int have_pseudoheader) 
 {  {
   char *name = daemon->namebuff;    char *name = daemon->namebuff;
   unsigned char *p, *ansp;    unsigned char *p, *ansp;
Line 96  size_t answer_auth(struct dns_header *header, char *li Line 90  size_t answer_auth(struct dns_header *header, char *li
   int nameoffset, axfroffset = 0;    int nameoffset, axfroffset = 0;
   int q, anscount = 0, authcount = 0;    int q, anscount = 0, authcount = 0;
   struct crec *crecp;    struct crec *crecp;
  int  auth = 1, trunc = 0, nxdomain = 1, soa = 0, ns = 0, axfr = 0;  int  auth = !local_query, trunc = 0, nxdomain = 1, soa = 0, ns = 0, axfr = 0;
   struct auth_zone *zone = NULL;    struct auth_zone *zone = NULL;
  struct subnet *subnet = NULL;  struct addrlist *subnet = NULL;
   char *cut;    char *cut;
   struct mx_srv_record *rec, *move, **up;    struct mx_srv_record *rec, *move, **up;
   struct txt_record *txt;    struct txt_record *txt;
Line 109  size_t answer_auth(struct dns_header *header, char *li Line 103  size_t answer_auth(struct dns_header *header, char *li
       
   if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY )    if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY )
     return 0;      return 0;
  
   /* determine end of question section (we put answers there) */    /* determine end of question section (we put answers there) */
   if (!(ansp = skip_questions(header, qlen)))    if (!(ansp = skip_questions(header, qlen)))
     return 0; /* bad packet */      return 0; /* bad packet */
Line 138  size_t answer_auth(struct dns_header *header, char *li Line 132  size_t answer_auth(struct dns_header *header, char *li
           continue;            continue;
         }          }
   
      if (qtype == T_PTR)      if ((qtype == T_PTR || qtype == T_SOA || qtype == T_NS) &&
           (flag = in_arpa_name_2_addr(name, &addr)) &&
           !local_query)
         {          {
           if (!(flag = in_arpa_name_2_addr(name, &addr)))  
             continue;  
   
           for (zone = daemon->auth_zones; zone; zone = zone->next)            for (zone = daemon->auth_zones; zone; zone = zone->next)
            if ((subnet = filter_zone(zone, flag, &addr)))            if ((subnet = find_subnet(zone, flag, &addr)))
               break;                break;
          
           if (!zone)            if (!zone)
             {              {
               auth = 0;                auth = 0;
               continue;                continue;
             }              }
                    else if (qtype == T_SOA)
             soa = 1, found = 1;
           else if (qtype == T_NS)
             ns = 1, found = 1;
         }
 
       if (qtype == T_PTR && flag)
         {
           intr = NULL;
 
           if (flag == F_IPV4)            if (flag == F_IPV4)
            {            for (intr = daemon->int_names; intr; intr = intr->next)
              for (intr = daemon->int_names; intr; intr = intr->next)              {
                {                struct addrlist *addrlist;
                  if (addr.addr.addr4.s_addr == get_ifaddr(intr->intr).s_addr)                
                 for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
                   if (!(addrlist->flags & ADDRLIST_IPV6) && addr.addr.addr4.s_addr == addrlist->addr.addr.addr4.s_addr)
                     break;                      break;
                  else                
                    while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)                if (addrlist)
                      intr = intr->next;                  break;
                 else
                   while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
                     intr = intr->next;
               }
 #ifdef HAVE_IPV6
           else if (flag == F_IPV6)
             for (intr = daemon->int_names; intr; intr = intr->next)
               {
                 struct addrlist *addrlist;
                 
                 for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
                   if ((addrlist->flags & ADDRLIST_IPV6) && IN6_ARE_ADDR_EQUAL(&addr.addr.addr6, &addrlist->addr.addr.addr6))
                     break;
                 
                 if (addrlist)
                   break;
                 else
                   while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
                     intr = intr->next;
               }
 #endif
           
           if (intr)
             {
               if (local_query || in_zone(zone, intr->name, NULL))
                 {       
                   found = 1;
                   log_query(flag | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
                   if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
                                           daemon->auth_ttl, NULL,
                                           T_PTR, C_IN, "d", intr->name))
                     anscount++;
                 }                  }
   
               if (intr)  
                 {  
                   if (in_zone(zone, intr->name, NULL))  
                     {     
                       found = 1;  
                       log_query(F_IPV4 | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);  
                       if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,   
                                               daemon->auth_ttl, NULL,  
                                               T_PTR, C_IN, "d", intr->name))  
                         anscount++;  
                     }  
                 }  
             }              }
          
           if ((crecp = cache_find_by_addr(NULL, &addr, now, flag)))            if ((crecp = cache_find_by_addr(NULL, &addr, now, flag)))
             do {               do { 
               strcpy(name, cache_get_name(crecp));                strcpy(name, cache_get_name(crecp));
Line 189  size_t answer_auth(struct dns_header *header, char *li Line 212  size_t answer_auth(struct dns_header *header, char *li
                     *p = 0; /* must be bare name */                      *p = 0; /* must be bare name */
                                       
                   /* add  external domain */                    /* add  external domain */
                  strcat(name, ".");                  if (zone)
                  strcat(name, zone->domain);                    {
                       strcat(name, ".");
                       strcat(name, zone->domain);
                     }
                   log_query(flag | F_DHCP | F_REVERSE, name, &addr, record_source(crecp->uid));                    log_query(flag | F_DHCP | F_REVERSE, name, &addr, record_source(crecp->uid));
                   found = 1;                    found = 1;
                   if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,                     if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
Line 198  size_t answer_auth(struct dns_header *header, char *li Line 224  size_t answer_auth(struct dns_header *header, char *li
                                           T_PTR, C_IN, "d", name))                                            T_PTR, C_IN, "d", name))
                     anscount++;                      anscount++;
                 }                  }
              else if (crecp->flags & (F_DHCP | F_HOSTS) && in_zone(zone, name, NULL))              else if (crecp->flags & (F_DHCP | F_HOSTS) && (local_query || in_zone(zone, name, NULL)))
                 {                  {
                   log_query(crecp->flags & ~F_FORWARD, name, &addr, record_source(crecp->uid));                    log_query(crecp->flags & ~F_FORWARD, name, &addr, record_source(crecp->uid));
                   found = 1;                    found = 1;
Line 212  size_t answer_auth(struct dns_header *header, char *li Line 238  size_t answer_auth(struct dns_header *header, char *li
                                           
             } while ((crecp = cache_find_by_addr(crecp, &addr, now, flag)));              } while ((crecp = cache_find_by_addr(crecp, &addr, now, flag)));
   
          if (!found)          if (found)
            log_query(flag | F_NEG | F_NXDOMAIN | F_REVERSE | F_AUTH, NULL, &addr, NULL);            nxdomain = 0;
           else
             log_query(flag | F_NEG | F_NXDOMAIN | F_REVERSE | (auth ? F_AUTH : 0), NULL, &addr, NULL);
   
           continue;            continue;
         }          }
               
     cname_restart:      cname_restart:
      for (zone = daemon->auth_zones; zone; zone = zone->next)      if (found)
        if (in_zone(zone, name, &cut))        /* NS and SOA .arpa requests have set found above. */
          break;        cut = NULL;
            else
      if (!zone) 
         {          {
          auth = 0;          for (zone = daemon->auth_zones; zone; zone = zone->next)
          continue;            if (in_zone(zone, name, &cut))
               break;
           
           if (!zone)
             {
               auth = 0;
               continue;
             }
         }          }
   
       for (rec = daemon->mxnames; rec; rec = rec->next)        for (rec = daemon->mxnames; rec; rec = rec->next)
Line 321  size_t answer_auth(struct dns_header *header, char *li Line 355  size_t answer_auth(struct dns_header *header, char *li
                           anscount++;                            anscount++;
                }                 }
            }             }
    
       if (qtype == T_A)
          flag = F_IPV4;
        
 #ifdef HAVE_IPV6
        if (qtype == T_AAAA)
          flag = F_IPV6;
 #endif
        
        for (intr = daemon->int_names; intr; intr = intr->next)         for (intr = daemon->int_names; intr; intr = intr->next)
          if (hostname_isequal(name, intr->name))           if (hostname_isequal(name, intr->name))
            {             {
                struct addrlist *addrlist;
                
              nxdomain = 0;               nxdomain = 0;
             if (qtype == T_A && (addr.addr.addr4 = get_ifaddr(intr->intr)).s_addr != (in_addr_t) -1)             
               {             if (flag)
                 found = 1;               for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)  
                 log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);                 if (((addrlist->flags & ADDRLIST_IPV6)  ? T_AAAA : T_A) == qtype &&
                 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,                      (local_query || filter_zone(zone, flag, &addrlist->addr)))
                                         daemon->auth_ttl, NULL, T_A, C_IN, "4", &addr))                   {
                   anscount++;#ifdef HAVE_IPV6
               }                     if (addrlist->flags & ADDRLIST_REVONLY)
           }                       continue;
 #endif
                      found = 1;
                      log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL);
                      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
                                              daemon->auth_ttl, NULL, qtype, C_IN, 
                                              qtype == T_A ? "4" : "6", &addrlist->addr))
                        anscount++;
                    }
              }
                 
        for (a = daemon->cnames; a; a = a->next)         for (a = daemon->cnames; a; a = a->next)
          if (hostname_isequal(name, a->alias) )           if (hostname_isequal(name, a->alias) )
Line 349  size_t answer_auth(struct dns_header *header, char *li Line 401  size_t answer_auth(struct dns_header *header, char *li
                }                 }
              found = 1;               found = 1;
              if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,                if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
                                     daemon->auth_ttl, NULL,                                     daemon->auth_ttl, &nameoffset,
                                      T_CNAME, C_IN, "d", name))                                       T_CNAME, C_IN, "d", name))
                anscount++;                 anscount++;
                             
              goto cname_restart;               goto cname_restart;
            }             }
   
       if (qtype == T_A)  
         flag = F_IPV4;  
   
 #ifdef HAVE_IPV6  
       if (qtype == T_AAAA)  
         flag = F_IPV6;  
 #endif  
   
       if (!cut)        if (!cut)
         {          {
           nxdomain = 0;            nxdomain = 0;
                       
           if (qtype == T_SOA)            if (qtype == T_SOA)
             {              {
              soa = 1; /* inhibits auth section */              auth = soa = 1; /* inhibits auth section */
               found = 1;                found = 1;
               log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<SOA>");                log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<SOA>");
             }              }
Line 382  size_t answer_auth(struct dns_header *header, char *li Line 426  size_t answer_auth(struct dns_header *header, char *li
                 peer_addr->in.sin_port = 0;                  peer_addr->in.sin_port = 0;
 #ifdef HAVE_IPV6  #ifdef HAVE_IPV6
               else                else
                peer_addr->in6.sin6_port = 0;                 {
                   peer_addr->in6.sin6_port = 0; 
                   peer_addr->in6.sin6_scope_id = 0;
                 }
 #endif  #endif
                               
               for (peers = daemon->auth_peers; peers; peers = peers->next)                for (peers = daemon->auth_peers; peers; peers = peers->next)
Line 403  size_t answer_auth(struct dns_header *header, char *li Line 450  size_t answer_auth(struct dns_header *header, char *li
                   return 0;                    return 0;
                 }                  }
                                               
                 auth = 1;
               soa = 1; /* inhibits auth section */                soa = 1; /* inhibits auth section */
               ns = 1; /* ensure we include NS records! */                ns = 1; /* ensure we include NS records! */
               axfr = 1;                axfr = 1;
Line 412  size_t answer_auth(struct dns_header *header, char *li Line 460  size_t answer_auth(struct dns_header *header, char *li
             }              }
           else if (qtype == T_NS)            else if (qtype == T_NS)
             {              {
                 auth = 1;
               ns = 1; /* inhibits auth section */                ns = 1; /* inhibits auth section */
               found = 1;                found = 1;
               log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<NS>");                 log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<NS>"); 
Line 429  size_t answer_auth(struct dns_header *header, char *li Line 478  size_t answer_auth(struct dns_header *header, char *li
                   {                     { 
                     nxdomain = 0;                      nxdomain = 0;
                     if ((crecp->flags & flag) &&                       if ((crecp->flags & flag) && 
                        (filter_constructed_dhcp(zone, flag, &(crecp->addr.addr))))                        (local_query || filter_zone(zone, flag, &(crecp->addr.addr))))
                       {                        {
                         *cut = '.'; /* restore domain part */                          *cut = '.'; /* restore domain part */
                         log_query(crecp->flags, name, &crecp->addr.addr, record_source(crecp->uid));                          log_query(crecp->flags, name, &crecp->addr.addr, record_source(crecp->uid));
Line 452  size_t answer_auth(struct dns_header *header, char *li Line 501  size_t answer_auth(struct dns_header *header, char *li
             do              do
               {                 { 
                  nxdomain = 0;                   nxdomain = 0;
                 if ((crecp->flags & flag) && filter_constructed_dhcp(zone, flag, &(crecp->addr.addr)))                 if ((crecp->flags & flag) && (local_query || filter_zone(zone, flag, &(crecp->addr.addr))))
                    {                     {
                      log_query(crecp->flags, name, &crecp->addr.addr, record_source(crecp->uid));                       log_query(crecp->flags, name, &crecp->addr.addr, record_source(crecp->uid));
                      found = 1;                       found = 1;
Line 483  size_t answer_auth(struct dns_header *header, char *li Line 532  size_t answer_auth(struct dns_header *header, char *li
                       
           authname = name;            authname = name;
   
          if (!subnet->is6)          if (!(subnet->flags & ADDRLIST_IPV6))
             {              {
              in_addr_t a = ntohl(subnet->addr4.s_addr) >> 8;              in_addr_t a = ntohl(subnet->addr.addr.addr4.s_addr) >> 8;
               char *p = name;                char *p = name;
                               
              if (subnet->prefixlen == 24)              if (subnet->prefixlen >= 24)
                 p += sprintf(p, "%d.", a & 0xff);                  p += sprintf(p, "%d.", a & 0xff);
               a = a >> 8;                a = a >> 8;
              if (subnet->prefixlen != 8)              if (subnet->prefixlen >= 16 )
                 p += sprintf(p, "%d.", a & 0xff);                  p += sprintf(p, "%d.", a & 0xff);
               a = a >> 8;                a = a >> 8;
               p += sprintf(p, "%d.in-addr.arpa", a & 0xff);                p += sprintf(p, "%d.in-addr.arpa", a & 0xff);
Line 505  size_t answer_auth(struct dns_header *header, char *li Line 554  size_t answer_auth(struct dns_header *header, char *li
                               
               for (i = subnet->prefixlen-1; i >= 0; i -= 4)                for (i = subnet->prefixlen-1; i >= 0; i -= 4)
                 {                   { 
                  int dig = ((unsigned char *)&subnet->addr6)[i>>3];                  int dig = ((unsigned char *)&subnet->addr.addr.addr6)[i>>3];
                   p += sprintf(p, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);                    p += sprintf(p, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
                 }                  }
               p += sprintf(p, "ip6.arpa");                p += sprintf(p, "ip6.arpa");
Line 634  size_t answer_auth(struct dns_header *header, char *li Line 683  size_t answer_auth(struct dns_header *header, char *li
               }                }
                       
           for (intr = daemon->int_names; intr; intr = intr->next)            for (intr = daemon->int_names; intr; intr = intr->next)
            if (in_zone(zone, intr->name, &cut) && (addr.addr.addr4 = get_ifaddr(intr->intr)).s_addr != (in_addr_t) -1)            if (in_zone(zone, intr->name, &cut))
               {                {
                   struct addrlist *addrlist;
                   
                 if (cut)                  if (cut)
                   *cut = 0;                    *cut = 0;
                                   
                if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp,                 for (addrlist = intr->addr; addrlist; addrlist = addrlist->next) 
                                        daemon->auth_ttl, NULL, T_A, C_IN, "4", cut ? intr->name : NULL, &addr))                  if (!(addrlist->flags & ADDRLIST_IPV6) &&
                  anscount++;                      (local_query || filter_zone(zone, F_IPV4, &addrlist->addr)) && 
                       add_resource_record(header, limit, &trunc, -axfroffset, &ansp, 
                                           daemon->auth_ttl, NULL, T_A, C_IN, "4", cut ? intr->name : NULL, &addrlist->addr))
                     anscount++;
                                   
   #ifdef HAVE_IPV6
                   for (addrlist = intr->addr; addrlist; addrlist = addrlist->next) 
                     if ((addrlist->flags & ADDRLIST_IPV6) && 
                         (local_query || filter_zone(zone, F_IPV6, &addrlist->addr)) &&
                         add_resource_record(header, limit, &trunc, -axfroffset, &ansp, 
                                             daemon->auth_ttl, NULL, T_AAAA, C_IN, "6", cut ? intr->name : NULL, &addrlist->addr))
                       anscount++;
   #endif              
                   
                 /* restore config data */                  /* restore config data */
                 if (cut)                  if (cut)
                   *cut = '.';                     *cut = '.'; 
               }                }
                       
           for (a = daemon->cnames; a; a = a->next)            for (a = daemon->cnames; a; a = a->next)
             if (in_zone(zone, a->alias, &cut))              if (in_zone(zone, a->alias, &cut))
               {                {
Line 677  size_t answer_auth(struct dns_header *header, char *li Line 740  size_t answer_auth(struct dns_header *header, char *li
                   if ((crecp->flags & F_DHCP) && !option_bool(OPT_DHCP_FQDN))                    if ((crecp->flags & F_DHCP) && !option_bool(OPT_DHCP_FQDN))
                     {                      {
                       char *cache_name = cache_get_name(crecp);                        char *cache_name = cache_get_name(crecp);
                      if (!strchr(cache_name, '.') && filter_constructed_dhcp(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr.addr)))                      if (!strchr(cache_name, '.') && 
                           (local_query || filter_zone(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr.addr))))
                         {                          {
                           qtype = T_A;                            qtype = T_A;
 #ifdef HAVE_IPV6  #ifdef HAVE_IPV6
Line 694  size_t answer_auth(struct dns_header *header, char *li Line 758  size_t answer_auth(struct dns_header *header, char *li
                   if ((crecp->flags & F_HOSTS) || (((crecp->flags & F_DHCP) && option_bool(OPT_DHCP_FQDN))))                    if ((crecp->flags & F_HOSTS) || (((crecp->flags & F_DHCP) && option_bool(OPT_DHCP_FQDN))))
                     {                      {
                       strcpy(name, cache_get_name(crecp));                        strcpy(name, cache_get_name(crecp));
                      if (in_zone(zone, name, &cut) && filter_constructed_dhcp(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr.addr)))                      if (in_zone(zone, name, &cut) && 
                           (local_query || filter_zone(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr.addr))))
                         {                          {
                           qtype = T_A;                            qtype = T_A;
 #ifdef HAVE_IPV6  #ifdef HAVE_IPV6
Line 729  size_t answer_auth(struct dns_header *header, char *li Line 794  size_t answer_auth(struct dns_header *header, char *li
   /* done all questions, set up header and return length of result */    /* done all questions, set up header and return length of result */
   /* clear authoritative and truncated flags, set QR flag */    /* clear authoritative and truncated flags, set QR flag */
   header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR;    header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR;
   /* clear RA flag */  
   header->hb4 &= ~HB4_RA;  
   
     if (local_query)
       {
         /* set RA flag */
         header->hb4 |= HB4_RA;
       }
     else
       {
         /* clear RA flag */
         header->hb4 &= ~HB4_RA;
       }
   
   /* authoritive */    /* authoritive */
   if (auth)    if (auth)
     header->hb3 |= HB3_AA;      header->hb3 |= HB3_AA;
Line 740  size_t answer_auth(struct dns_header *header, char *li Line 814  size_t answer_auth(struct dns_header *header, char *li
   if (trunc)    if (trunc)
     header->hb3 |= HB3_TC;      header->hb3 |= HB3_TC;
       
  if (anscount == 0 && auth && nxdomain)  if ((auth || local_query) && nxdomain)
     SET_RCODE(header, NXDOMAIN);      SET_RCODE(header, NXDOMAIN);
   else    else
     SET_RCODE(header, NOERROR); /* no error */      SET_RCODE(header, NOERROR); /* no error */
   header->ancount = htons(anscount);    header->ancount = htons(anscount);
   header->nscount = htons(authcount);    header->nscount = htons(authcount);
   header->arcount = htons(0);    header->arcount = htons(0);
   
     /* Advertise our packet size limit in our reply */
     if (have_pseudoheader)
       return add_pseudoheader(header,  ansp - (unsigned char *)header, (unsigned char *)limit, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0);
   
   return ansp - (unsigned char *)header;    return ansp - (unsigned char *)header;
 }  }
       

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.3


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