Diff for /embedaddon/dnsmasq/src/rrfilter.c between versions 1.1 and 1.1.1.3

version 1.1, 2016/11/02 09:57:01 version 1.1.1.3, 2023/09/27 11:02:07
Line 1 Line 1
/* dnsmasq is Copyright (c) 2000-2016 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 14 Line 14
    along with this program.  If not, see <http://www.gnu.org/licenses/>.     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */  */
   
/* Code to safely remove RRs from an DNS answer */ /* Code to safely remove RRs from a DNS answer */ 
   
 #include "dnsmasq.h"  #include "dnsmasq.h"
   
Line 156  static int check_rrs(unsigned char *p, struct dns_head Line 156  static int check_rrs(unsigned char *p, struct dns_head
 }  }
                   
   
/* mode is 0 to remove EDNS0, 1 to filter DNSSEC RRs *//* mode may be remove EDNS0 or DNSSEC RRs or remove A or AAAA from answer section. */
 size_t rrfilter(struct dns_header *header, size_t plen, int mode)  size_t rrfilter(struct dns_header *header, size_t plen, int mode)
 {  {
  static unsigned char **rrs;  static unsigned char **rrs = NULL;
   static int rr_sz = 0;    static int rr_sz = 0;
   
   unsigned char *p = (unsigned char *)(header+1);    unsigned char *p = (unsigned char *)(header+1);
Line 173  size_t rrfilter(struct dns_header *header, size_t plen Line 173  size_t rrfilter(struct dns_header *header, size_t plen
   GETSHORT(qclass, p);    GETSHORT(qclass, p);
   
   /* First pass, find pointers to start and end of all the records we wish to elide:    /* First pass, find pointers to start and end of all the records we wish to elide:
     records added for DNSSEC, unless explicity queried for */     records added for DNSSEC, unless explicitly queried for */
   for (rr_found = 0, chop_ns = 0, chop_an = 0, chop_ar = 0, i = 0;     for (rr_found = 0, chop_ns = 0, chop_an = 0, chop_ar = 0, i = 0; 
        i < ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount);         i < ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount);
        i++)         i++)
Line 192  size_t rrfilter(struct dns_header *header, size_t plen Line 192  size_t rrfilter(struct dns_header *header, size_t plen
       if (!ADD_RDLEN(header, p, plen, rdlen))        if (!ADD_RDLEN(header, p, plen, rdlen))
         return plen;          return plen;
   
      /* Don't remove the answer. */      if (mode == RRFILTER_EDNS0) /* EDNS */
      if (i < ntohs(header->ancount) && type == qtype && class == qclass) 
        continue; 
       
      if (mode == 0) /* EDNS */ 
         {          {
           /* EDNS mode, remove T_OPT from additional section only */            /* EDNS mode, remove T_OPT from additional section only */
           if (i < (ntohs(header->nscount) + ntohs(header->ancount)) || type != T_OPT)            if (i < (ntohs(header->nscount) + ntohs(header->ancount)) || type != T_OPT)
             continue;              continue;
         }          }
      else if (type != T_NSEC && type != T_NSEC3 && type != T_RRSIG)      else if (mode == RRFILTER_DNSSEC)
        /* DNSSEC mode, remove SIGs and NSECs from all three sections. */        {
        continue;          if (type != T_NSEC && type != T_NSEC3 && type != T_RRSIG)
             /* DNSSEC mode, remove SIGs and NSECs from all three sections. */
             continue;
 
           /* Don't remove the answer. */
           if (i < ntohs(header->ancount) && type == qtype && class == qclass)
             continue;
         }
       else
         {
           /* Only looking at answer section now. */
           if (i >= ntohs(header->ancount))
             break;
 
           if (class != C_IN)
             continue;
           
           if (mode == RRFILTER_A && type != T_A)
             continue;
 
           if (mode == RRFILTER_AAAA && type != T_AAAA)
             continue;
         }
               
         
       if (!expand_workspace(&rrs, &rr_sz, rr_found + 1))        if (!expand_workspace(&rrs, &rr_sz, rr_found + 1))
         return plen;           return plen; 
               
Line 239  size_t rrfilter(struct dns_header *header, size_t plen Line 256  size_t rrfilter(struct dns_header *header, size_t plen
   if (!check_rrs(p, header, plen, 0, rrs, rr_found))    if (!check_rrs(p, header, plen, 0, rrs, rr_found))
     return plen;      return plen;
       
  /* Third pass, elide records */  /* Third pass, actually fix up pointers in the records */
   p = (unsigned char *)(header+1);
   
   check_name(&p, header, plen, 1, rrs, rr_found);
   p += 4; /* qclass, qtype */
   
   check_rrs(p, header, plen, 1, rrs, rr_found);
 
   /* Fourth pass, elide records */
   for (p = rrs[0], i = 1; i < rr_found; i += 2)    for (p = rrs[0], i = 1; i < rr_found; i += 2)
     {      {
       unsigned char *start = rrs[i];        unsigned char *start = rrs[i];
Line 254  size_t rrfilter(struct dns_header *header, size_t plen Line 279  size_t rrfilter(struct dns_header *header, size_t plen
   header->nscount = htons(ntohs(header->nscount) - chop_ns);    header->nscount = htons(ntohs(header->nscount) - chop_ns);
   header->arcount = htons(ntohs(header->arcount) - chop_ar);    header->arcount = htons(ntohs(header->arcount) - chop_ar);
   
   /* Fourth pass, fix up pointers in the remaining records */  
   p = (unsigned char *)(header+1);  
     
   check_name(&p, header, plen, 1, rrs, rr_found);  
   p += 4; /* qclass, qtype */  
     
   check_rrs(p, header, plen, 1, rrs, rr_found);  
     
   return plen;    return plen;
 }  }
   
Line 270  u16 *rrfilter_desc(int type) Line 287  u16 *rrfilter_desc(int type)
 {  {
   /* List of RRtypes which include domains in the data.    /* List of RRtypes which include domains in the data.
      0 -> domain       0 -> domain
     integer -> no of plain bytes     integer -> no. of plain bytes
      -1 -> end       -1 -> end
   
      zero is not a valid RRtype, so the final entry is returned for       zero is not a valid RRtype, so the final entry is returned for
Line 322  int expand_workspace(unsigned char ***wkspc, int *szp, Line 339  int expand_workspace(unsigned char ***wkspc, int *szp,
     return 0;      return 0;
   
   new += 5;    new += 5;
  
  if (!(p = whine_malloc(new * sizeof(unsigned char *))))  if (!(p = whine_realloc(*wkspc, new * sizeof(unsigned char *))))
    return 0;      return 0;
  
  if (old != 0 && *wkspc)  memset(p+old, 0, new-old);
    { 
      memcpy(p, *wkspc, old * sizeof(unsigned char *)); 
      free(*wkspc); 
    } 
       
   *wkspc = p;    *wkspc = p;
   *szp = new;    *szp = new;

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


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