Coverage Report

Created: 2026-04-12 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/dnsmasq/src/rfc1035.c
Line
Count
Source
1
/* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 dated June, 1991, or
6
   (at your option) version 3 dated 29 June, 2007.
7
 
8
   This program is distributed in the hope that it will be useful,
9
   but WITHOUT ANY WARRANTY; without even the implied warranty of
10
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
   GNU General Public License for more details.
12
     
13
   You should have received a copy of the GNU General Public License
14
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
*/
16
17
#include "dnsmasq.h"
18
19
/* EXTR_NAME_EXTRACT -> extract name
20
   EXTR_NAME_COMPARE -> compare name, case insensitive
21
   EXTR_NAME_NOCASE -> compare name, case sensitive
22
   EXTR_NAME_FLIP -> flip 0x20 bits in packet.
23
24
   For flip, name is  an array of ints, whose size
25
   is given in parm, which forms the bitmap. Bits beyond the size
26
   are assumed to be zero.
27
   
28
   return = 0 -> error
29
   return = 1 -> extract OK, compare OK, flip OK
30
   return = 2 -> extract OK, compare failed.
31
   return = 3 -> extract OK, compare failed but only on case.
32
33
   If pp == NULL, operate on the query name in the packet.
34
*/
35
int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, 
36
     char *name, int func, unsigned int parm)
37
0
{
38
0
  unsigned char *cp = (unsigned char *)name, *p1 = NULL;
39
0
  unsigned int j, l, namelen = 0, hops = 0;
40
0
  unsigned int bigmap_counter = 0, bigmap_posn = 0, bigmap_size = parm, bitmap = 0;
41
0
  int retvalue = 1, case_insens = 1, isExtract = 0, flip = 0, extrabytes = (int)parm;
42
0
  unsigned int *bigmap = (unsigned int *)name;
43
0
  unsigned char *p = pp ? *pp : (unsigned char *)(header+1);
44
  
45
0
  if (func == EXTR_NAME_EXTRACT)
46
0
    isExtract = 1, *cp = 0;
47
0
  else if (func == EXTR_NAME_NOCASE)
48
0
    case_insens = 0;
49
0
  else if (func == EXTR_NAME_FLIP)
50
0
    {
51
0
      flip = 1, extrabytes = 0;
52
0
      name = NULL;
53
0
    }
54
  
55
0
  while (1)
56
0
    { 
57
0
      unsigned int label_type;
58
59
0
      if (!CHECK_LEN(header, p, plen, 1))
60
0
  return 0;
61
      
62
0
      if ((l = *p++) == 0) 
63
  /* end marker */
64
0
  {
65
    /* check that there are the correct no. of bytes after the name */
66
0
    if (!CHECK_LEN(header, p1 ? p1 : p, plen, extrabytes))
67
0
      return 0;
68
    
69
0
    if (isExtract)
70
0
      {
71
0
        if (cp != (unsigned char *)name)
72
0
    cp--;
73
0
        *cp = 0; /* terminate: lose final period */
74
0
      }
75
0
    else if (!flip && *cp != 0)
76
0
      retvalue = 2;
77
78
0
    if (pp)
79
0
      {
80
0
        if (p1) /* we jumped via compression */
81
0
    *pp = p1;
82
0
        else
83
0
    *pp = p;
84
0
      }
85
    
86
0
    return retvalue;
87
0
  }
88
89
0
      label_type = l & 0xc0;
90
      
91
0
      if (label_type == 0xc0) /* pointer */
92
0
  { 
93
0
    if (!CHECK_LEN(header, p, plen, 1))
94
0
      return 0;
95
        
96
    /* get offset */
97
0
    l = (l&0x3f) << 8;
98
0
    l |= *p++;
99
    
100
0
    if (!p1) /* first jump, save location to go back to */
101
0
      p1 = p;
102
        
103
0
    hops++; /* break malicious infinite loops */
104
0
    if (hops > 255)
105
0
      return 0;
106
    
107
0
    p = l + (unsigned char *)header;
108
0
  }
109
0
      else if (label_type == 0x00)
110
0
  { /* label_type = 0 -> label. */
111
0
    namelen += l + 1; /* include period */
112
0
    if (namelen >= MAXDNAME)
113
0
      return 0;
114
0
    if (!CHECK_LEN(header, p, plen, l))
115
0
      return 0;
116
    
117
0
    for (j=0; j<l; j++, p++)
118
0
      if (isExtract)
119
0
        {
120
0
    unsigned char c = *p;
121
122
0
    if (c == 0 || c == '.' || c == NAME_ESCAPE)
123
0
      {
124
0
        *cp++ = NAME_ESCAPE;
125
0
        *cp++ = c+1;
126
0
      }
127
0
    else
128
0
      *cp++ = c; 
129
0
        }
130
0
      else if (flip)
131
0
        {
132
0
    unsigned char c = *p;
133
134
0
    if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
135
0
      {
136
        /* Get the next int of the bitmap */
137
0
        if (bigmap_posn < bigmap_size && bigmap_counter-- == 0)
138
0
          {
139
0
      bitmap = bigmap[bigmap_posn++];
140
0
      bigmap_counter = (sizeof(unsigned int) * 8) - 1;
141
0
          }
142
        
143
0
        if (bitmap & 1)
144
0
          *p ^= 0x20;
145
0
        bitmap >>= 1;
146
0
      }
147
0
        }
148
0
      else 
149
0
        {
150
0
    unsigned char c1 = *cp, c2 = *p;
151
    
152
0
    if (c1 == 0)
153
0
      retvalue = 2;
154
0
    else 
155
0
      {
156
0
        cp++;
157
158
0
        if (c1 == NAME_ESCAPE)
159
0
          c1 = (*cp++)-1;
160
0
        else if (case_insens && c1 >= 'A' && c1 <= 'Z')
161
0
          c1 += 'a' - 'A';
162
        
163
0
        if (case_insens && c2 >= 'A' && c2 <= 'Z')
164
0
          c2 += 'a' - 'A';
165
166
0
        if (!case_insens && retvalue != 2 && c1 != c2)
167
0
          {
168
0
      if (c1 >= 'A' && c1 <= 'Z')
169
0
        c1 += 'a' - 'A';
170
      
171
0
      if (c2 >= 'A' && c2 <= 'Z')
172
0
        c2 += 'a' - 'A';
173
      
174
0
      if (c1 == c2)
175
0
        retvalue = 3;
176
0
          }
177
        
178
0
        if (c1 != c2)
179
0
          retvalue = 2;
180
0
      }
181
0
        }
182
      
183
0
    if (isExtract)
184
0
      *cp++ = '.';
185
0
    else if (!flip && *cp != 0 && *cp++ != '.')
186
0
      retvalue = 2;
187
0
  }
188
0
      else
189
0
  return 0; /* label types 0x40 and 0x80 not supported */
190
0
    }
191
0
}
192
 
193
/* Max size of input string (for IPv6) is 75 chars.) */
194
0
#define MAXARPANAME 75
195
int in_arpa_name_2_addr(char *namein, union all_addr *addrp)
196
0
{
197
0
  int j;
198
0
  char name[MAXARPANAME+1], *cp1;
199
0
  unsigned char *addr = (unsigned char *)addrp;
200
0
  char *lastchunk = NULL, *penchunk = NULL;
201
  
202
0
  if (strlen(namein) > MAXARPANAME)
203
0
    return 0;
204
205
0
  memset(addrp, 0, sizeof(union all_addr));
206
207
  /* turn name into a series of asciiz strings */
208
  /* j counts no. of labels */
209
0
  for(j = 1,cp1 = name; *namein; cp1++, namein++)
210
0
    if (*namein == '.')
211
0
      {
212
0
  penchunk = lastchunk;
213
0
        lastchunk = cp1 + 1;
214
0
  *cp1 = 0;
215
0
  j++;
216
0
      }
217
0
    else
218
0
      *cp1 = *namein;
219
  
220
0
  *cp1 = 0;
221
222
0
  if (j<3)
223
0
    return 0;
224
225
0
  if (hostname_isequal(lastchunk, "arpa") && hostname_isequal(penchunk, "in-addr"))
226
0
    {
227
      /* IP v4 */
228
      /* address arrives as a name of the form
229
   www.xxx.yyy.zzz.in-addr.arpa
230
   some of the low order address octets might be missing
231
   and should be set to zero. */
232
0
      for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1)+1)
233
0
  {
234
    /* check for digits only (weeds out things like
235
       50.0/24.67.28.64.in-addr.arpa which are used 
236
       as CNAME targets according to RFC 2317 */
237
0
    char *cp;
238
0
    for (cp = cp1; *cp; cp++)
239
0
      if (!isdigit((unsigned char)*cp))
240
0
        return 0;
241
    
242
0
    addr[3] = addr[2];
243
0
    addr[2] = addr[1];
244
0
    addr[1] = addr[0];
245
0
    addr[0] = atoi(cp1);
246
0
  }
247
248
0
      return F_IPV4;
249
0
    }
250
0
  else if (hostname_isequal(penchunk, "ip6") && 
251
0
     (hostname_isequal(lastchunk, "int") || hostname_isequal(lastchunk, "arpa")))
252
0
    {
253
      /* IP v6:
254
         Address arrives as 0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.ip6.[int|arpa]
255
       or \[xfedcba9876543210fedcba9876543210/128].ip6.[int|arpa]
256
      
257
   Note that most of these the various representations are obsolete and 
258
   left-over from the many DNS-for-IPv6 wars. We support all the formats
259
   that we can since there is no reason not to.
260
      */
261
262
0
      if (*name == '\\' && *(name+1) == '[' && 
263
0
    (*(name+2) == 'x' || *(name+2) == 'X'))
264
0
  {   
265
0
    for (j = 0, cp1 = name+3; *cp1 && isxdigit((unsigned char) *cp1) && j < 32; cp1++, j++)
266
0
      {
267
0
        char xdig[2];
268
0
        xdig[0] = *cp1;
269
0
        xdig[1] = 0;
270
0
        if (j%2)
271
0
    addr[j/2] |= strtol(xdig, NULL, 16);
272
0
        else
273
0
    addr[j/2] = strtol(xdig, NULL, 16) << 4;
274
0
      }
275
    
276
0
    if (*cp1 == '/' && j == 32)
277
0
      return F_IPV6;
278
0
  }
279
0
      else
280
0
  {
281
0
    for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1)+1)
282
0
      {
283
0
        if (*(cp1+1) || !isxdigit((unsigned char)*cp1))
284
0
    return 0;
285
        
286
0
        for (j = sizeof(struct in6_addr)-1; j>0; j--)
287
0
    addr[j] = (addr[j] >> 4) | (addr[j-1] << 4);
288
0
        addr[0] = (addr[0] >> 4) | (strtol(cp1, NULL, 16) << 4);
289
0
      }
290
    
291
0
    return F_IPV6;
292
0
  }
293
0
    }
294
  
295
0
  return 0;
296
0
}
297
298
unsigned char *skip_name(unsigned char *ansp, struct dns_header *header, size_t plen, int extrabytes)
299
0
{
300
0
  while(1)
301
0
    {
302
0
      unsigned int label_type;
303
      
304
0
      if (!CHECK_LEN(header, ansp, plen, 1))
305
0
  return NULL;
306
      
307
0
      label_type = (*ansp) & 0xc0;
308
309
0
      if (label_type == 0xc0)
310
0
  {
311
    /* pointer for compression. */
312
0
    ansp += 2;  
313
0
    break;
314
0
  }
315
0
      else if (label_type == 0x80)
316
0
  return NULL; /* reserved */
317
0
      else if (label_type == 0x40)
318
0
  {
319
    /* Extended label type */
320
0
    unsigned int count, llen;
321
    
322
0
    if (!CHECK_LEN(header, ansp, plen, 2))
323
0
      return NULL;
324
    
325
0
    if (((*ansp++) & 0x3f) != 1)
326
0
      return NULL; /* we only understand bitstrings */
327
    
328
0
    count = *(ansp++); /* Bits in bitstring */
329
    
330
0
    if (count == 0) /* count == 0 means 256 bits */
331
0
      llen = 32;
332
0
    else
333
0
      llen = ((count-1)>>3)+1;
334
335
0
    if (!ADD_RDLEN(header, ansp, plen, llen))
336
0
      return NULL;
337
0
  }
338
0
      else
339
0
  { /* label type == 0 Bottom six bits is length */
340
0
    unsigned int len = (*ansp++) & 0x3f;
341
    
342
0
    if (!ADD_RDLEN(header, ansp, plen, len))
343
0
      return NULL;
344
345
0
    if (len == 0)
346
0
      break; /* zero length label marks the end. */
347
0
  }
348
0
    }
349
350
0
  if (!CHECK_LEN(header, ansp, plen, extrabytes))
351
0
    return NULL;
352
  
353
0
  return ansp;
354
0
}
355
356
unsigned char *skip_questions(struct dns_header *header, size_t plen)
357
0
{
358
0
  int q;
359
0
  unsigned char *ansp = (unsigned char *)(header+1);
360
361
0
  for (q = ntohs(header->qdcount); q != 0; q--)
362
0
    {
363
0
      if (!(ansp = skip_name(ansp, header, plen, 4)))
364
0
  return NULL;
365
0
      ansp += 4; /* class and type */
366
0
    }
367
  
368
0
  return ansp;
369
0
}
370
371
unsigned char *skip_section(unsigned char *ansp, int count, struct dns_header *header, size_t plen)
372
0
{
373
0
  int i, rdlen;
374
  
375
0
  for (i = 0; i < count; i++)
376
0
    {
377
0
      if (!(ansp = skip_name(ansp, header, plen, 10)))
378
0
  return NULL; 
379
0
      ansp += 8; /* type, class, TTL */
380
0
      GETSHORT(rdlen, ansp);
381
0
      if (!ADD_RDLEN(header, ansp, plen, rdlen))
382
0
  return NULL;
383
0
    }
384
385
0
  return ansp;
386
0
}
387
388
size_t resize_packet(struct dns_header *header, size_t plen, unsigned char *pheader, size_t hlen)
389
0
{
390
0
  unsigned char *ansp = skip_questions(header, plen);
391
    
392
  /* if packet is malformed, just return as-is. */
393
0
  if (!ansp)
394
0
    return plen;
395
  
396
0
  if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount),
397
0
          header, plen)))
398
0
    return plen;
399
    
400
  /* restore pseudoheader */
401
0
  if (pheader && ntohs(header->arcount) == 0)
402
0
    {
403
      /* must use memmove, may overlap */
404
0
      memmove(ansp, pheader, hlen);
405
0
      header->arcount = htons(1);
406
0
      ansp += hlen;
407
0
    }
408
409
0
  return ansp - (unsigned char *)header;
410
0
}
411
412
/* is addr in the non-globally-routed IP space? */ 
413
int private_net(struct in_addr addr, int ban_localhost) 
414
0
{
415
0
  in_addr_t ip_addr = ntohl(addr.s_addr);
416
417
0
  return
418
0
    (((ip_addr & 0xFF000000) == 0x7F000000) && ban_localhost)  /* 127.0.0.0/8    (loopback) */ ||
419
0
    (((ip_addr & 0xFF000000) == 0x00000000) && ban_localhost) /* RFC 5735 section 3. "here" network */ ||
420
0
    ((ip_addr & 0xFF000000) == 0x0A000000)  /* 10.0.0.0/8     (private)  */ ||
421
0
    ((ip_addr & 0xFFC00000) == 0x64400000)  /* 100.64.0.0/10  (CG-NAT) RFC6598/RFC7793*/ ||
422
0
    ((ip_addr & 0xFFF00000) == 0xAC100000)  /* 172.16.0.0/12  (private)  */ ||
423
0
    ((ip_addr & 0xFFFF0000) == 0xC0A80000)  /* 192.168.0.0/16 (private)  */ ||
424
0
    ((ip_addr & 0xFFFF0000) == 0xA9FE0000)  /* 169.254.0.0/16 (zeroconf) */ ||
425
0
    ((ip_addr & 0xFFFFFF00) == 0xC0000200)  /* 192.0.2.0/24   (test-net) */ ||
426
0
    ((ip_addr & 0xFFFFFF00) == 0xC6336400)  /* 198.51.100.0/24(test-net) */ ||
427
0
    ((ip_addr & 0xFFFFFF00) == 0xCB007100)  /* 203.0.113.0/24 (test-net) */ ||
428
0
    ((ip_addr & 0xFFFFFFFF) == 0xFFFFFFFF)  /* 255.255.255.255/32 (broadcast)*/ ;
429
0
}
430
431
int private_net6(struct in6_addr *a, int ban_localhost)
432
0
{
433
  /* Block IPv4-mapped IPv6 addresses in private IPv4 address space */
434
0
  if (IN6_IS_ADDR_V4MAPPED(a))
435
0
    {
436
0
      struct in_addr v4;
437
0
      v4.s_addr = ((const uint32_t *) (a))[3];
438
0
      return private_net(v4, ban_localhost);
439
0
    }
440
441
0
  return
442
0
    (IN6_IS_ADDR_UNSPECIFIED(a) && ban_localhost) || /* RFC 6303 4.3 */
443
0
    (IN6_IS_ADDR_LOOPBACK(a) && ban_localhost) ||    /* RFC 6303 4.3 */
444
0
    IN6_IS_ADDR_LINKLOCAL(a) ||   /* RFC 6303 4.5 */
445
0
    IN6_IS_ADDR_SITELOCAL(a) ||
446
0
    ((unsigned char *)a)[0] == 0xfd ||   /* RFC 6303 4.4 */
447
0
    ((u32 *)a)[0] == htonl(0x20010db8); /* RFC 6303 4.6 */
448
0
}
449
450
int do_doctor(struct dns_header *header, size_t qlen, char *namebuff)
451
0
{
452
0
  unsigned char *p;
453
0
  int i, qtype, qclass, rdlen;
454
0
  int done = 0;
455
  
456
0
  if (!(p = skip_questions(header, qlen)))
457
0
    return done;
458
  
459
0
  for (i = 0; i < ntohs(header->ancount) + ntohs(header->arcount); i++)
460
0
    {
461
      /* Skip over auth section */
462
0
      if (i == ntohs(header->ancount) && !(p = skip_section(p, ntohs(header->nscount), header, qlen)))
463
0
  return done;
464
      
465
0
      if (!extract_name(header, qlen, &p, namebuff, EXTR_NAME_EXTRACT, 10))
466
0
  return done; /* bad packet */
467
      
468
0
      GETSHORT(qtype, p); 
469
0
      GETSHORT(qclass, p);
470
0
      p += 4; /* ttl */
471
0
      GETSHORT(rdlen, p);
472
      
473
0
      if (qclass == C_IN && qtype == T_A)
474
0
  {
475
0
    struct doctor *doctor;
476
0
    union all_addr addr;
477
    
478
0
    if (!CHECK_LEN(header, p, qlen, INADDRSZ))
479
0
      return done;
480
    
481
    /* alignment */
482
0
    memcpy(&addr.addr4, p, INADDRSZ);
483
    
484
0
    for (doctor = daemon->doctors; doctor; doctor = doctor->next)
485
0
      {
486
0
        if (doctor->end.s_addr == 0)
487
0
    {
488
0
      if (!is_same_net(doctor->in, addr.addr4, doctor->mask))
489
0
        continue;
490
0
    }
491
0
        else if (ntohl(doctor->in.s_addr) > ntohl(addr.addr4.s_addr) || 
492
0
           ntohl(doctor->end.s_addr) < ntohl(addr.addr4.s_addr))
493
0
    continue;
494
        
495
0
        addr.addr4.s_addr &= ~doctor->mask.s_addr;
496
0
        addr.addr4.s_addr |= (doctor->out.s_addr & doctor->mask.s_addr);
497
        /* Since we munged the data, the server it came from is no longer authoritative */
498
0
        header->hb3 &= ~HB3_AA;
499
#ifdef HAVE_DNSSEC
500
        /* remove validated flag from this RR, since we changed it! */
501
        if (option_bool(OPT_DNSSEC_VALID) && i <  ntohs(header->ancount))
502
    daemon->rr_status[i] = 0;
503
#endif
504
0
        done = 1;
505
0
        memcpy(p, &addr.addr4, INADDRSZ);
506
0
        log_query(F_FORWARD | F_CONFIG | F_IPV4, namebuff, &addr, NULL, 0);
507
0
        break;
508
0
      }
509
0
  }
510
      
511
0
      if (!ADD_RDLEN(header, p, qlen, rdlen))
512
0
   return done; /* bad packet */
513
0
    }
514
515
0
  return done;
516
0
}
517
518
/* Find SOA RR in auth section to get TTL for negative caching of name. 
519
   Cache said SOA and return the difference in length between name and the name of the 
520
   SOA RR so we can look it up again.
521
*/
522
static int find_soa(struct dns_header *header, size_t qlen, char *name, int *substring, unsigned long *ttlp, int cache, time_t now)
523
0
{
524
0
  unsigned char *p, *psave;
525
0
  int qtype, qclass, rdlen;
526
0
  unsigned long ttl, minttl;
527
0
  int i, j;
528
0
  size_t name_len, soa_len, len;
529
0
  union all_addr addr;
530
531
  /* first move to NS section and find TTL from  SOA RR */
532
0
  if (!(p = skip_questions(header, qlen)) ||
533
0
      !(p = skip_section(p, ntohs(header->ancount), header, qlen)))
534
0
    return 0;  /* bad packet */
535
536
0
  name_len = strlen(name);
537
  
538
0
  if (substring)
539
0
    *substring = name_len;
540
541
0
  for (i = 0; i < ntohs(header->nscount); i++)
542
0
    {
543
0
      if (!extract_name(header, qlen, &p, daemon->workspacename, EXTR_NAME_EXTRACT, 0))
544
0
  return 0; /* bad packet */
545
      
546
0
      GETSHORT(qtype, p); 
547
0
      GETSHORT(qclass, p);
548
0
      GETLONG(ttl, p);
549
0
      GETSHORT(rdlen, p);
550
551
0
      psave = p;
552
      
553
0
      if ((qclass == C_IN) && (qtype == T_SOA))
554
0
  {
555
0
    soa_len = strlen(daemon->workspacename);
556
557
    /* SOA must be for the name we're interested in. */
558
0
    if (soa_len <= name_len && memcmp(daemon->workspacename, name + name_len - soa_len, soa_len) == 0)
559
0
      {
560
0
        int prefix = name_len - soa_len;
561
        
562
0
        if (cache)
563
0
    {
564
0
      if (!(addr.rrblock.rrdata = blockdata_alloc(NULL, 0)))
565
0
        return 0;
566
0
      addr.rrblock.rrtype = T_SOA;
567
0
      addr.rrblock.datalen = 0;
568
0
    }
569
        
570
0
        for (j = 0; j < 2; j++) /* MNAME, RNAME */
571
0
    {
572
0
      if (!extract_name(header, qlen, &p, daemon->workspacename, EXTR_NAME_EXTRACT, 0))
573
0
        {
574
0
          if (cache)
575
0
      blockdata_free(addr.rrblock.rrdata);
576
0
          return 0;
577
0
        }
578
      
579
0
      if (cache)
580
0
        {
581
0
          len = to_wire(daemon->workspacename);
582
0
          if (!blockdata_expand(addr.rrblock.rrdata, addr.rrblock.datalen, daemon->workspacename, len))
583
0
      {
584
0
        blockdata_free(addr.rrblock.rrdata);
585
0
        return 0;
586
0
      }
587
588
0
          addr.rrblock.datalen += len;
589
0
        }
590
0
    }
591
592
0
        if (!CHECK_LEN(header, p, qlen, 20))
593
0
    {
594
0
      if (cache)
595
0
        blockdata_free(addr.rrblock.rrdata);
596
0
      return 0;
597
0
    }
598
        
599
        /* rest of RR */
600
0
        if (cache)
601
0
    {
602
0
      int secflag = 0;
603
604
0
      if (!blockdata_expand(addr.rrblock.rrdata, addr.rrblock.datalen, (char *)p, 20))
605
0
        {
606
0
          blockdata_free(addr.rrblock.rrdata);
607
0
          return 0;
608
0
        }
609
      
610
0
      addr.rrblock.datalen += 20;
611
      
612
#ifdef HAVE_DNSSEC
613
      if (option_bool(OPT_DNSSEC_VALID) && daemon->rr_status[i + ntohs(header->ancount)] != 0)
614
        {
615
          secflag = F_DNSSECOK; 
616
      
617
          /* limit TTL based on signature. */
618
          if (daemon->rr_status[i + ntohs(header->ancount)] < ttl)
619
      ttl = daemon->rr_status[i + ntohs(header->ancount)];
620
        }
621
#endif
622
      
623
0
      if (!cache_insert(name + prefix, &addr, C_IN, now, ttl, F_FORWARD | F_RR | F_KEYTAG | secflag))
624
0
        {
625
0
          blockdata_free(addr.rrblock.rrdata);
626
0
          return 0;
627
0
        }
628
0
    }
629
        
630
0
        p += 16; /* SERIAL REFRESH RETRY EXPIRE */
631
        
632
0
        GETLONG(minttl, p); /* minTTL */
633
0
        if (ttl < minttl)
634
0
    minttl = ttl;
635
636
0
        if (substring)
637
0
    *substring = prefix;
638
        
639
0
        if (ttlp)
640
0
    *ttlp = minttl;
641
642
0
        return 1;
643
0
      }
644
0
  }
645
646
0
      p = psave;
647
      
648
0
      if (!ADD_RDLEN(header, p, qlen, rdlen))
649
0
  return 0; /* bad packet */
650
0
    }
651
  
652
0
  return 0;
653
0
}
654
655
/* Print TXT reply to log */
656
static int log_txt(char *name, unsigned char *p, const int ardlen, int flag)
657
0
{
658
0
  unsigned char *p1 = p;
659
 
660
  /* Loop over TXT payload */
661
0
  while ((p1 - p) < ardlen)
662
0
    {
663
0
      unsigned int i, len = *p1;
664
0
      unsigned char *p3 = p1;
665
0
      if ((p1 + len - p) >= ardlen)
666
0
  return 0; /* bad packet */
667
668
      /* make counted string zero-term and sanitise */
669
0
      for (i = 0; i < len; i++)
670
0
  {
671
0
    if (!isprint((unsigned char)*(p3+1)))
672
0
      break;
673
0
    *p3 = *(p3+1);
674
0
    p3++;
675
0
  }
676
677
0
      *p3 = 0;
678
0
      log_query(flag, name, NULL, (char*)p1, 0);
679
      /* restore */
680
0
      memmove(p1 + 1, p1, i);
681
0
      *p1 = len;
682
0
      p1 += len+1;
683
0
    }
684
0
  return 1;
685
0
}
686
687
/* Note that the following code can create CNAME chains that don't point to a real record,
688
   either because of lack of memory, or lack of SOA records.  These are treated by the cache code as 
689
   expired and cleaned out that way. 
690
   Return 1 if we reject an address because it look like part of dns-rebinding attack. 
691
   Return 2 if the packet is malformed.
692
*/
693
int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t now, 
694
          struct ipsets *ipsets, struct ipsets *nftsets, int check_rebind,
695
          int no_cache_dnssec, int secure)
696
0
{
697
0
  unsigned char *p, *p1, *endrr, *namep;
698
0
  int j, qtype, qclass, aqtype, aqclass, ardlen, res;
699
0
  unsigned long ttl;
700
0
  union all_addr addr;
701
0
#ifdef HAVE_IPSET
702
0
  char **ipsets_cur;
703
#else
704
  (void)ipsets; /* unused */
705
#endif
706
#ifdef HAVE_NFTSET
707
  char **nftsets_cur;
708
#else
709
0
  (void)nftsets; /* unused */
710
0
#endif
711
0
  int name_encoding, found = 0, ptr = 0;
712
0
  int flags = RCODE(header) == NXDOMAIN ? F_NXDOMAIN : 0;
713
714
0
  cache_start_insert();
715
716
0
  namep = p = (unsigned char *)(header+1);
717
  
718
0
  if (ntohs(header->qdcount) != 1 || !extract_name(header, qlen, &p, name, EXTR_NAME_EXTRACT, 4))
719
0
    return 2; /* bad packet */
720
  
721
0
  GETSHORT(qtype, p); 
722
0
  GETSHORT(qclass, p);
723
  
724
0
  if (qclass != C_IN)
725
0
    return 0;
726
727
  /* If the PTR record encodes an address, store using a name/address record with F_REVERSE set.
728
     Otherwise, it gets stored as an arbitrary RR below. If the query is answerable with
729
     a CNAME, also take the arbitrary-RR route, since the cache can't represent a CNAME
730
     whose target is stored in a F_REVERSE record. */
731
0
  if (qtype == T_PTR && !(flags & F_NXDOMAIN) && (name_encoding = in_arpa_name_2_addr(name, &addr)))
732
0
    { 
733
0
      ptr = 1;
734
      
735
0
      if (!(p1 = skip_questions(header, qlen)))
736
0
  return 2;
737
      
738
0
      for (j = 0; j < ntohs(header->ancount); j++) 
739
0
  {
740
0
    int secflag = 0;
741
0
    if (!(res = extract_name(header, qlen, &p1, name, EXTR_NAME_COMPARE, 10)))
742
0
      return 2; /* bad packet */
743
    
744
0
    GETSHORT(aqtype, p1); 
745
0
    GETSHORT(aqclass, p1);
746
0
    p = p1;
747
0
    GETLONG(ttl, p1);
748
0
    GETSHORT(ardlen, p1);
749
0
    endrr = p1+ardlen;
750
    
751
0
    if (aqclass == C_IN && res == 1 && aqtype == T_PTR)
752
0
      {
753
0
        found = 1;
754
755
0
        if ((daemon->max_ttl != 0) && (ttl > daemon->max_ttl))
756
0
    ttl = daemon->max_ttl;
757
        
758
#ifdef HAVE_DNSSEC
759
        if (option_bool(OPT_DNSSEC_VALID) && j < daemon->rr_status_sz && daemon->rr_status[j] != 0)
760
    {
761
      secflag = F_DNSSECOK;
762
      /* limit TTL based on signature. */
763
      if (daemon->rr_status[j] < ttl)
764
        ttl = daemon->rr_status[j];
765
    }
766
#endif
767
        
768
0
        PUTLONG(ttl, p);
769
770
0
        if (!extract_name(header, qlen, &p1, name, EXTR_NAME_EXTRACT, 0))
771
0
    return 2;
772
0
        log_query(name_encoding | secflag | F_REVERSE | F_UPSTREAM, name, &addr, NULL, 0);
773
0
        cache_insert(name, &addr, C_IN, now, ttl, name_encoding | secflag | F_REVERSE);
774
        
775
        /* restore query into name */
776
0
        p1 = namep;
777
0
        if (!extract_name(header, qlen, &p1, name, EXTR_NAME_EXTRACT, 0))
778
0
    return 2;
779
0
      }
780
    
781
0
    p1 = endrr;
782
0
    if (!CHECK_LEN(header, p1, qlen, 0))
783
0
      return 2; /* bad packet */
784
0
  }
785
0
    }
786
787
0
  if (!ptr || !found)
788
0
    {
789
      /* everything other than PTR */
790
0
      struct crec *newc, *cpp = NULL;
791
0
      int cname_count = CNAME_CHAIN, addrlen = 0, insert = 1;
792
            
793
0
      if (qtype == T_A)
794
0
  {
795
0
    addrlen = INADDRSZ;
796
0
    flags |= F_IPV4;
797
0
  }
798
0
      else if (qtype == T_AAAA)
799
0
  {
800
0
    addrlen = IN6ADDRSZ;
801
0
    flags |= F_IPV6;
802
0
  }
803
0
      else if (qtype != T_CNAME &&
804
0
         (qtype == T_SRV || qtype == T_PTR || rr_on_list(daemon->cache_rr, qtype) || rr_on_list(daemon->cache_rr, T_ANY)))
805
0
  flags |= F_RR;
806
0
      else
807
0
  insert = 0; /* NOTE: do not cache data from CNAME queries. */
808
      
809
0
    cname_loop:
810
0
      if (!(p1 = skip_questions(header, qlen)))
811
0
  return 2;
812
      
813
0
      for (j = 0; j < ntohs(header->ancount); j++) 
814
0
  {
815
0
    int secflag = 0;
816
    
817
0
    if (!(res = extract_name(header, qlen, &p1, name, EXTR_NAME_COMPARE, 10)))
818
0
      return 2; /* bad packet */
819
    
820
0
    GETSHORT(aqtype, p1); 
821
0
    GETSHORT(aqclass, p1);
822
0
    p = p1;
823
0
    GETLONG(ttl, p1);
824
0
    GETSHORT(ardlen, p1);
825
0
    endrr = p1+ardlen;
826
827
0
    if (!CHECK_LEN(header, endrr, qlen, 0))
828
0
      return 2; /* bad packet */
829
    
830
    /* Not what we're looking for? */
831
0
    if (aqclass != C_IN || res == 2)
832
0
      {
833
0
        p1 = endrr;
834
0
        continue;
835
0
      }
836
837
0
    if ((daemon->max_ttl != 0) && (ttl > daemon->max_ttl))
838
0
      ttl = daemon->max_ttl;
839
    
840
#ifdef HAVE_DNSSEC
841
    if (option_bool(OPT_DNSSEC_VALID) && j < daemon->rr_status_sz && daemon->rr_status[j] != 0)
842
      {
843
        secflag = F_DNSSECOK;
844
        
845
        /* limit TTl based on sig. */
846
        if (daemon->rr_status[j] < ttl)
847
    ttl = daemon->rr_status[j];
848
      }
849
#endif    
850
851
0
    PUTLONG(ttl, p);
852
    
853
0
    if (aqtype == T_CNAME)
854
0
      {
855
0
        if (!cname_count--)
856
0
    return 0; /* looped CNAMES */
857
        
858
0
        log_query(secflag | F_CNAME | F_FORWARD | F_UPSTREAM, name, NULL, NULL, 0);
859
        
860
0
        if (insert)
861
0
    {
862
0
      if ((newc = cache_insert(name, NULL, C_IN, now, ttl, F_CNAME | F_FORWARD | secflag)))
863
0
        {
864
0
          newc->addr.cname.target.cache = NULL;
865
0
          newc->addr.cname.is_name_ptr = 0; 
866
0
          if (cpp)
867
0
      {
868
0
        next_uid(newc);
869
0
        cpp->addr.cname.target.cache = newc;
870
0
        cpp->addr.cname.uid = newc->uid;
871
0
      }
872
0
        }
873
      
874
0
      cpp = newc;
875
0
    }
876
        
877
        /* Set the query to the CNAME target and go again unless the query was just for a CNAME. */
878
0
        namep = p1;
879
0
        if (!extract_name(header, qlen, &p1, name, EXTR_NAME_EXTRACT, 0))
880
0
    return 2;
881
        
882
0
        if (qtype != T_CNAME)
883
0
    goto cname_loop;
884
885
0
        found = 1;
886
0
      }
887
0
    else if (qtype == T_ANY || aqtype != qtype)
888
0
      {
889
#ifdef HAVE_DNSSEC
890
        if (!option_bool(OPT_DNSSEC_VALID) || aqtype != T_RRSIG)
891
#endif
892
0
    log_query(secflag | F_FORWARD | F_UPSTREAM | F_RRNAME, name, NULL, NULL, aqtype);
893
0
      }
894
0
    else if (!(flags & F_NXDOMAIN))
895
0
      {
896
0
        found = 1;
897
        
898
0
        if (flags & F_RR)
899
0
    {
900
0
      short desc, *rrdesc = rrfilter_desc(aqtype);
901
0
      unsigned char *tmp = namep;
902
      
903
0
      if (!CHECK_LEN(header, p1, qlen, ardlen))
904
0
        return 2; /* bad packet */
905
      
906
      /* If the data has no names and is small enough, store it in
907
         the crec address field rather than allocate a block. */
908
0
      if (*rrdesc == -1 && ardlen <= (int)RR_IMDATALEN)
909
0
        {
910
0
           addr.rrdata.rrtype = aqtype;
911
0
           addr.rrdata.datalen = (char)ardlen;
912
0
           flags &= ~F_KEYTAG; /* in case of >1 answer, not all the same. */ 
913
0
           if (ardlen != 0)
914
0
       memcpy(addr.rrdata.data, p1, ardlen);
915
0
        }
916
0
      else
917
0
        {
918
0
          addr.rrblock.rrtype = aqtype;
919
0
          addr.rrblock.datalen = 0;
920
0
          flags |= F_KEYTAG; /* discriminates between rrdata and rrblock */
921
          
922
          /* The RR data may include names, and those names may include
923
       compression, which will be rendered meaningless when
924
       copied into another packet. 
925
       Here we go through a description of the packet type to
926
       find the names, and extract them to a c-string and then
927
       re-encode them to standalone DNS format without compression. */
928
0
          if (!(addr.rrblock.rrdata = blockdata_alloc(NULL, 0)))
929
0
      return 0;
930
0
          do
931
0
      {
932
0
        desc = *rrdesc++;
933
        
934
0
        if (desc == -1)
935
0
          {
936
            /* Copy the rest of the RR and end. */
937
0
            if (!blockdata_expand(addr.rrblock.rrdata, addr.rrblock.datalen, (char *)p1, endrr - p1))
938
0
        {
939
0
          blockdata_free(addr.rrblock.rrdata);
940
0
          return 0;
941
0
        }
942
0
            addr.rrblock.datalen += endrr - p1;
943
0
          }
944
0
        else if (desc == 0)
945
0
          {
946
            /* Name, extract it then re-encode. */
947
0
            int len;
948
            
949
0
            if (!extract_name(header, qlen, &p1, name, EXTR_NAME_EXTRACT, 0))
950
0
        {
951
0
          blockdata_free(addr.rrblock.rrdata);
952
0
          return 2;
953
0
        }
954
            
955
0
            len = to_wire(name);
956
0
            if (!blockdata_expand(addr.rrblock.rrdata, addr.rrblock.datalen, name, len))
957
0
        {
958
0
          blockdata_free(addr.rrblock.rrdata);
959
0
          return 0;
960
0
        }
961
            
962
0
            addr.rrblock.datalen += len;
963
0
          }
964
0
        else
965
0
          {
966
            /* desc is length of a block of data to be used as-is */
967
0
            if (desc > endrr - p1)
968
0
        desc = endrr - p1;
969
970
0
            if (!blockdata_expand(addr.rrblock.rrdata, addr.rrblock.datalen, (char *)p1, desc))
971
0
        {
972
0
          blockdata_free(addr.rrblock.rrdata);
973
0
          return 0;
974
0
        }
975
976
0
            addr.rrblock.datalen += desc;
977
0
            p1 += desc;
978
0
          }
979
0
      } while (desc != -1);
980
          
981
          /* we overwrote the original name, so get it back here. */
982
0
          if (!extract_name(header, qlen, &tmp, name, EXTR_NAME_EXTRACT, 0))
983
0
      {
984
0
        blockdata_free(addr.rrblock.rrdata);
985
0
        return 2;
986
0
      }
987
0
        }
988
0
    } 
989
0
        else if (flags & (F_IPV4 | F_IPV6))
990
0
    {
991
      /* copy address into aligned storage */
992
0
      if (!CHECK_LEN(header, p1, qlen, addrlen))
993
0
        return 2; /* bad packet */
994
0
      memcpy(&addr, p1, addrlen);
995
      
996
      /* check for returned address in private space */
997
0
      if (check_rebind)
998
0
        {
999
0
          if ((flags & F_IPV4) &&
1000
0
        private_net(addr.addr4, !option_bool(OPT_LOCAL_REBIND)))
1001
0
      return 1;
1002
          
1003
0
          if ((flags & F_IPV6) &&
1004
0
        private_net6(&addr.addr6, !option_bool(OPT_LOCAL_REBIND)))
1005
0
      return 1;
1006
0
        }
1007
1008
0
      if (flags & (F_IPV4 | F_IPV6))
1009
0
        {
1010
          /* If we're a child process, send this to the parent,
1011
       since the ipset and nfset access is not re-entrant. */
1012
0
#ifdef HAVE_IPSET
1013
0
          if (ipsets)
1014
0
      {
1015
0
        if (daemon->pipe_to_parent != -1)
1016
0
          cache_send_ipset(PIPE_OP_IPSET, ipsets, flags, &addr);
1017
0
        else
1018
0
          for (ipsets_cur = ipsets->sets; *ipsets_cur; ipsets_cur++)
1019
0
            if (add_to_ipset(*ipsets_cur, &addr, flags, 0) == 0)
1020
0
        log_query((flags & (F_IPV4 | F_IPV6)) | F_IPSET, ipsets->domain, &addr, *ipsets_cur, 1);
1021
0
      }
1022
0
#endif
1023
#ifdef HAVE_NFTSET
1024
          if (nftsets)
1025
      {
1026
        if (daemon->pipe_to_parent != -1)
1027
          cache_send_ipset(PIPE_OP_NFTSET, nftsets, flags, &addr);
1028
        else
1029
          for (nftsets_cur = nftsets->sets; *nftsets_cur; nftsets_cur++)
1030
            if (add_to_nftset(*nftsets_cur, &addr, flags, 0) == 0)
1031
        log_query((flags & (F_IPV4 | F_IPV6)) | F_IPSET, nftsets->domain, &addr, *nftsets_cur, 0);
1032
      }
1033
#endif
1034
0
        }
1035
0
    }
1036
        
1037
0
        if (insert)
1038
0
    {
1039
0
      newc = cache_insert(name, &addr, C_IN, now, ttl, flags | F_FORWARD | secflag);
1040
0
      if (newc && cpp)
1041
0
        {
1042
0
          next_uid(newc);
1043
0
          cpp->addr.cname.target.cache = newc;
1044
0
          cpp->addr.cname.uid = newc->uid;
1045
0
        }
1046
0
      cpp = NULL;
1047
      
1048
      /* cache insert failed, don't leak blockdata. */
1049
0
      if (!newc && (flags & F_RR) && (flags & F_KEYTAG))
1050
0
        blockdata_free(addr.rrblock.rrdata);  
1051
0
    }
1052
        
1053
        /* We're filtering this RRtype. It will be removed from the 
1054
     returned packet in process_reply() but gets cached here anyway
1055
     and will be filtered again on the way out of the cache. Here,
1056
     we just need to alter the logging. */
1057
0
        if (qtype != T_ANY && rr_on_list(daemon->filter_rr, qtype))
1058
0
    secflag = F_NEG | F_CONFIG;
1059
        
1060
0
        if (aqtype == T_TXT)
1061
0
    log_txt(name, p1, ardlen, flags | F_FORWARD | F_UPSTREAM | secflag);
1062
0
        else
1063
0
    log_query(flags | F_FORWARD | F_UPSTREAM | secflag, name, &addr, NULL, aqtype);
1064
0
      }
1065
    
1066
0
    p1 = endrr;
1067
0
    if (!CHECK_LEN(header, p1, qlen, 0))
1068
0
      return 2; /* bad packet */
1069
0
  }
1070
      
1071
0
      if (!found && (qtype != T_ANY || (flags & F_NXDOMAIN)))
1072
0
  {
1073
0
    if (flags & F_NXDOMAIN)
1074
0
      {
1075
0
        flags &= ~(F_IPV4 | F_IPV6 | F_RR);
1076
        
1077
        /* Can store NXDOMAIN reply for any qtype. */
1078
0
        insert = 1;
1079
0
      }
1080
    
1081
0
    log_query(F_UPSTREAM | F_FORWARD | F_NEG | flags | (secure ? F_DNSSECOK : 0), name, NULL, NULL, 0);
1082
    
1083
0
    if (insert && !option_bool(OPT_NO_NEG))
1084
0
      {
1085
        /* The order of records going into the cache matters (see  cache_recv_insert()).
1086
     The target of a CNAME must immediately follow the CNAME.
1087
     (CNAME has already gone into the cache at this point)
1088
     Here we call find_soa to get the ttl and substring, but
1089
     we DON'T LET IT INSERT the SOA into the cache if our negative record is a CNAME target
1090
     so that the SOA doesn't come before the CNAME target.
1091
1092
     We call find_soa() again after inserting the CNAME target to insert the SOA
1093
     if necessary. */
1094
1095
0
        int substring, have_soa = find_soa(header, qlen, name, &substring, &ttl, cpp == NULL, now);
1096
        
1097
0
        if (have_soa || daemon->neg_ttl)
1098
0
    {     
1099
0
      if (have_soa)
1100
0
        {
1101
0
          addr.rrdata.datalen = substring;
1102
0
          addr.rrdata.rrtype = qtype;
1103
0
        }
1104
0
      else
1105
0
        {
1106
          /* If daemon->neg_ttl is set, we can cache even without an SOA. */
1107
0
          ttl = daemon->neg_ttl;
1108
0
          flags |= F_NO_RR; /* Marks no SOA found. */
1109
0
        }
1110
            
1111
0
      newc = cache_insert(name, &addr, C_IN, now, ttl, F_FORWARD | F_NEG | flags | (secure ? F_DNSSECOK : 0)); 
1112
0
      if (newc && cpp)
1113
0
        {
1114
0
          next_uid(newc);
1115
0
          cpp->addr.cname.target.cache = newc;
1116
0
          cpp->addr.cname.uid = newc->uid;
1117
        
1118
          /* we didn't insert the SOA before a CNAME target above, do it now. */
1119
0
          if (have_soa)
1120
0
      find_soa(header, qlen, name, NULL, NULL, 1, now);
1121
0
        }
1122
0
    }
1123
0
      }
1124
0
  }
1125
0
    }
1126
1127
  /* Don't cache replies from non-recursive nameservers, since we may get a 
1128
     reply containing a CNAME but not its target, even though the target 
1129
     does exist. */
1130
0
  if (!(header->hb4 & HB4_CD) &&
1131
0
      (header->hb4 & HB4_RA) &&
1132
0
      !no_cache_dnssec)
1133
0
    cache_end_insert();
1134
1135
0
  return 0;
1136
0
}
1137
1138
#if defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)
1139
/* Don't pass control chars and weird escapes to UBus. */
1140
static int safe_name(char *name)
1141
{
1142
  unsigned char *r;
1143
  
1144
  for (r = (unsigned char *)name; *r; r++)
1145
    if (!isprint((int)*r))
1146
      return 0;
1147
  
1148
  return 1;
1149
}
1150
1151
void report_addresses(struct dns_header *header, size_t len, u32 mark)
1152
{
1153
  unsigned char *p, *endrr;
1154
  int i;
1155
  unsigned long attl;
1156
  struct allowlist *allowlists;
1157
  char **pattern_pos;
1158
  
1159
  if (RCODE(header) != NOERROR)
1160
    return;
1161
  
1162
  for (allowlists = daemon->allowlists; allowlists; allowlists = allowlists->next)
1163
    if (allowlists->mark == (mark & daemon->allowlist_mask & allowlists->mask))
1164
      for (pattern_pos = allowlists->patterns; *pattern_pos; pattern_pos++)
1165
  if (!strcmp(*pattern_pos, "*"))
1166
    return;
1167
  
1168
  if (!(p = skip_questions(header, len)))
1169
    return;
1170
  for (i = ntohs(header->ancount); i != 0; i--)
1171
    {
1172
      int aqtype, aqclass, ardlen;
1173
      
1174
      if (!extract_name(header, len, &p, daemon->namebuff, EXTR_NAME_EXTRACT, 10))
1175
  return;
1176
      
1177
      if (!CHECK_LEN(header, p, len, 10))
1178
  return;
1179
      GETSHORT(aqtype, p);
1180
      GETSHORT(aqclass, p);
1181
      GETLONG(attl, p);
1182
      GETSHORT(ardlen, p);
1183
      
1184
      if (!CHECK_LEN(header, p, len, ardlen))
1185
  return;
1186
      endrr = p+ardlen;
1187
      
1188
      if (aqclass == C_IN)
1189
  {
1190
    if (aqtype == T_CNAME)
1191
      {
1192
        if (!extract_name(header, len, &p, daemon->workspacename, EXTR_NAME_EXTRACT, 0))
1193
    return;
1194
        if (safe_name(daemon->namebuff) && safe_name(daemon->workspacename))
1195
    ubus_event_bcast_connmark_allowlist_resolved(mark, daemon->namebuff, daemon->workspacename, attl);
1196
      }
1197
    if (aqtype == T_A)
1198
      {
1199
        struct in_addr addr;
1200
        char ip[INET_ADDRSTRLEN];
1201
        if (ardlen != INADDRSZ)
1202
    return;
1203
        memcpy(&addr, p, ardlen);
1204
        if (inet_ntop(AF_INET, &addr, ip, sizeof ip) && safe_name(daemon->namebuff))
1205
    ubus_event_bcast_connmark_allowlist_resolved(mark, daemon->namebuff, ip, attl);
1206
      }
1207
    else if (aqtype == T_AAAA)
1208
      {
1209
        struct in6_addr addr;
1210
        char ip[INET6_ADDRSTRLEN];
1211
        if (ardlen != IN6ADDRSZ)
1212
    return;
1213
        memcpy(&addr, p, ardlen);
1214
        if (inet_ntop(AF_INET6, &addr, ip, sizeof ip) && safe_name(daemon->namebuff))
1215
    ubus_event_bcast_connmark_allowlist_resolved(mark, daemon->namebuff, ip, attl);
1216
      }
1217
  }
1218
      
1219
      p = endrr;
1220
    }
1221
}
1222
#endif
1223
1224
/* If the packet holds exactly one query
1225
   return F_IPV4 or F_IPV6  and leave the name from the query in name */
1226
unsigned int extract_request(struct dns_header *header, size_t qlen, char *name,
1227
           unsigned short *typep, unsigned short *classp)
1228
0
{
1229
0
  unsigned char *p = (unsigned char *)(header+1);
1230
0
  int qtype, qclass;
1231
1232
0
  if (typep)
1233
0
    *typep = 0;
1234
1235
0
  *name = 0; /* return empty name if no query found. */
1236
  
1237
0
  if (ntohs(header->qdcount) != 1 || OPCODE(header) != QUERY)
1238
0
    return 0; /* must be exactly one query. */
1239
1240
0
  if (!(header->hb3 & HB3_QR) && (ntohs(header->ancount) != 0 || ntohs(header->nscount) != 0))
1241
0
    return 0; /* non-standard query. */
1242
  
1243
0
  if (!extract_name(header, qlen, &p, name, EXTR_NAME_EXTRACT, 4))
1244
0
    return 0; /* bad packet */
1245
   
1246
0
  GETSHORT(qtype, p); 
1247
0
  GETSHORT(qclass, p);
1248
1249
0
  if (typep)
1250
0
    *typep = qtype;
1251
1252
0
  if (classp)
1253
0
    *classp = qclass;
1254
1255
0
  if (qclass == C_IN)
1256
0
    {
1257
0
      if (qtype == T_A)
1258
0
  return F_IPV4;
1259
0
      if (qtype == T_AAAA)
1260
0
  return F_IPV6;
1261
0
      if (qtype == T_ANY)
1262
0
  return  F_IPV4 | F_IPV6;
1263
0
    }
1264
1265
  /* Make the behaviour for DS and DNSKEY queries we forward the same
1266
     as for DS and DNSKEY queries we originate. */
1267
0
  if (qtype == T_DS || qtype == T_DNSKEY)
1268
0
    return F_DNSSECOK | (qtype == T_DS ? F_DS : 0);
1269
  
1270
0
  return F_QUERY;
1271
0
}
1272
1273
void setup_reply(struct dns_header *header, unsigned int flags, int ede)
1274
0
{
1275
  /* clear authoritative and truncated flags, set QR flag */
1276
0
  header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC )) | HB3_QR;
1277
  /* clear AD flag, set RA flag */
1278
0
  header->hb4 = (header->hb4 & ~HB4_AD) | HB4_RA;
1279
1280
0
  header->nscount = htons(0);
1281
0
  header->arcount = htons(0);
1282
0
  header->ancount = htons(0); /* no answers unless changed below */
1283
0
  if (flags == F_NOERR)
1284
0
    SET_RCODE(header, NOERROR); /* empty domain */
1285
0
  else if (flags == F_NXDOMAIN)
1286
0
    SET_RCODE(header, NXDOMAIN);
1287
0
  else if (flags == F_RCODE)
1288
0
    SET_RCODE(header, NOTIMP);
1289
0
  else if (flags & ( F_IPV4 | F_IPV6))
1290
0
    {
1291
0
      SET_RCODE(header, NOERROR);
1292
0
      header->hb3 |= HB3_AA;
1293
0
    }
1294
0
  else /* nowhere to forward to */
1295
0
    {
1296
0
      union all_addr a;
1297
0
      a.log.rcode = REFUSED;
1298
0
      a.log.ede = ede;
1299
0
      log_query(F_CONFIG | F_RCODE, "error", &a, NULL, 0);
1300
0
      SET_RCODE(header, REFUSED);
1301
0
    }
1302
0
}
1303
1304
/* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */
1305
int check_for_local_domain(char *name, time_t now)
1306
0
{
1307
0
  struct mx_srv_record *mx;
1308
0
  struct txt_record *txt;
1309
0
  struct interface_name *intr;
1310
0
  struct ptr_record *ptr;
1311
0
  struct naptr *naptr;
1312
1313
0
  for (naptr = daemon->naptr; naptr; naptr = naptr->next)
1314
0
     if (hostname_issubdomain(name, naptr->name))
1315
0
      return 1;
1316
1317
0
   for (mx = daemon->mxnames; mx; mx = mx->next)
1318
0
    if (hostname_issubdomain(name, mx->name))
1319
0
      return 1;
1320
1321
0
  for (txt = daemon->txt; txt; txt = txt->next)
1322
0
    if (hostname_issubdomain(name, txt->name))
1323
0
      return 1;
1324
1325
0
  for (intr = daemon->int_names; intr; intr = intr->next)
1326
0
    if (hostname_issubdomain(name, intr->name))
1327
0
      return 1;
1328
1329
0
  for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1330
0
    if (hostname_issubdomain(name, ptr->name))
1331
0
      return 1;
1332
1333
0
  if (cache_find_non_terminal(name, now))
1334
0
    return 1;
1335
1336
0
  if (is_name_synthetic(F_IPV4, name, NULL) ||
1337
0
      is_name_synthetic(F_IPV6, name, NULL))
1338
0
    return 1;
1339
1340
0
  return 0;
1341
0
}
1342
1343
static int check_bad_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr, char *name, unsigned long *ttlp)
1344
0
{
1345
0
  unsigned char *p;
1346
0
  int i, qtype, qclass, rdlen;
1347
0
  unsigned long ttl;
1348
0
  struct bogus_addr *baddrp;
1349
  
1350
  /* skip over questions */
1351
0
  if (!(p = skip_questions(header, qlen)))
1352
0
    return 0; /* bad packet */
1353
1354
0
  for (i = ntohs(header->ancount); i != 0; i--)
1355
0
    {
1356
0
      if (name && !extract_name(header, qlen, &p, name, EXTR_NAME_EXTRACT, 10))
1357
0
  return 0; /* bad packet */
1358
1359
0
      if (!name && !(p = skip_name(p, header, qlen, 10)))
1360
0
  return 0;
1361
      
1362
0
      GETSHORT(qtype, p); 
1363
0
      GETSHORT(qclass, p);
1364
0
      GETLONG(ttl, p);
1365
0
      GETSHORT(rdlen, p);
1366
0
      if (ttlp)
1367
0
  *ttlp = ttl;
1368
      
1369
0
      if (qclass == C_IN)
1370
0
  {
1371
0
    if (qtype == T_A)
1372
0
      {
1373
0
        struct in_addr addr;
1374
        
1375
0
        if (!CHECK_LEN(header, p, qlen, INADDRSZ))
1376
0
    return 0;
1377
1378
0
        memcpy(&addr, p, INADDRSZ);
1379
1380
0
        for (baddrp = baddr; baddrp; baddrp = baddrp->next)
1381
0
    if (!baddrp->is6 && is_same_net_prefix(addr, baddrp->addr.addr4, baddrp->prefix))
1382
0
      return 1;
1383
0
      }
1384
0
    else if (qtype == T_AAAA)
1385
0
      {
1386
0
        struct in6_addr addr;
1387
        
1388
0
        if (!CHECK_LEN(header, p, qlen, IN6ADDRSZ))
1389
0
    return 0;
1390
1391
0
        memcpy(&addr, p, IN6ADDRSZ);
1392
1393
0
        for (baddrp = baddr; baddrp; baddrp = baddrp->next)
1394
0
    if (baddrp->is6 && is_same_net6(&addr, &baddrp->addr.addr6, baddrp->prefix))
1395
0
      return 1;
1396
0
      }
1397
0
  }
1398
      
1399
0
      if (!ADD_RDLEN(header, p, qlen, rdlen))
1400
0
  return 0;
1401
0
    }
1402
  
1403
0
  return 0;
1404
0
}
1405
1406
/* Is the packet a reply with the answer address equal to addr?
1407
   If so mung is into an NXDOMAIN reply and also put that information
1408
   in the cache. */
1409
int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name, time_t now)
1410
0
{
1411
0
  unsigned long ttl;
1412
1413
0
  if (check_bad_address(header, qlen, daemon->bogus_addr, name, &ttl))
1414
0
    {
1415
      /* Found a bogus address. Insert that info here, since there no SOA record
1416
   to get the ttl from in the normal processing */
1417
0
      cache_start_insert();
1418
0
      cache_insert(name, NULL, C_IN, now, ttl, F_FORWARD | F_NEG | F_NXDOMAIN);
1419
0
      cache_end_insert();
1420
0
      log_query(F_CONFIG | F_FORWARD | F_NEG | F_NXDOMAIN, name, NULL, NULL, 0);
1421
1422
0
      return 1;
1423
0
    }
1424
1425
0
  return 0;
1426
0
}
1427
1428
int check_for_ignored_address(struct dns_header *header, size_t qlen)
1429
0
{
1430
0
  return check_bad_address(header, qlen, daemon->ignore_addr, NULL, NULL);
1431
0
}
1432
1433
/* Nameoffset > 0 means that the name of the new record already exists at the given offset,
1434
   so use a "jump" to that.
1435
   Nameoffset == 0 means use the first variable argument as the name of the new record.
1436
   nameoffset < 0 means use the first variable argument as the start of the new record name,
1437
   then "jump" to -nameoffset to complete it. */
1438
int add_resource_record(struct dns_header *header, char *limit, int *truncp, int nameoffset, unsigned char **pp, 
1439
      unsigned long ttl, int *offset, unsigned short type, unsigned short class, char *format, ...)
1440
0
{
1441
0
  va_list ap;
1442
0
  unsigned char *sav, *p = *pp;
1443
0
  int j;
1444
0
  unsigned short usval;
1445
0
  long lval;
1446
0
  char *sval;
1447
  
1448
0
#define CHECK_LIMIT(size) \
1449
0
  if (limit && p + (size) > (unsigned char*)limit) goto truncated;
1450
1451
0
  va_start(ap, format);   /* make ap point to 1st unamed argument */
1452
  
1453
0
  if (truncp && *truncp)
1454
0
    goto truncated;
1455
  
1456
0
  if (nameoffset > 0)
1457
0
    {
1458
0
      CHECK_LIMIT(2);
1459
0
      PUTSHORT(nameoffset | 0xc000, p);
1460
0
    }
1461
0
  else
1462
0
    {
1463
0
      char *name = va_arg(ap, char *);
1464
0
      if (name && !(p = do_rfc1035_name(p, name, limit)))
1465
0
  goto truncated;
1466
      
1467
0
      if (nameoffset < 0)
1468
0
  {
1469
0
    CHECK_LIMIT(2);
1470
0
    PUTSHORT(-nameoffset | 0xc000, p);
1471
0
  }
1472
0
      else
1473
0
  {
1474
0
    CHECK_LIMIT(1);
1475
0
    *p++ = 0;
1476
0
  }
1477
0
    }
1478
1479
  /* type (2) + class (2) + ttl (4) + rdlen (2) */
1480
0
  CHECK_LIMIT(10);
1481
  
1482
0
  PUTSHORT(type, p);
1483
0
  PUTSHORT(class, p);
1484
0
  PUTLONG(ttl, p);      /* TTL */
1485
1486
0
  sav = p;              /* Save pointer to RDLength field */
1487
0
  PUTSHORT(0, p);       /* Placeholder RDLength */
1488
1489
0
  for (; *format; format++)
1490
0
    switch (*format)
1491
0
      {
1492
0
      case '6':
1493
0
        CHECK_LIMIT(IN6ADDRSZ);
1494
0
  sval = va_arg(ap, char *); 
1495
0
  memcpy(p, sval, IN6ADDRSZ);
1496
0
  p += IN6ADDRSZ;
1497
0
  break;
1498
  
1499
0
      case '4':
1500
0
        CHECK_LIMIT(INADDRSZ);
1501
0
  sval = va_arg(ap, char *); 
1502
0
  memcpy(p, sval, INADDRSZ);
1503
0
  p += INADDRSZ;
1504
0
  break;
1505
  
1506
0
      case 'b':
1507
0
        CHECK_LIMIT(1);
1508
0
  usval = va_arg(ap, int);
1509
0
  *p++ = usval;
1510
0
  break;
1511
  
1512
0
      case 's':
1513
0
        CHECK_LIMIT(2);
1514
0
  usval = va_arg(ap, int);
1515
0
  PUTSHORT(usval, p);
1516
0
  break;
1517
  
1518
0
      case 'l':
1519
0
        CHECK_LIMIT(4);
1520
0
  lval = va_arg(ap, long);
1521
0
  PUTLONG(lval, p);
1522
0
  break;
1523
  
1524
0
      case 'd':
1525
        /* get domain-name answer arg and store it in RDATA field */
1526
0
        if (offset)
1527
0
          *offset = p - (unsigned char *)header;
1528
0
        if (!(p = do_rfc1035_name(p, va_arg(ap, char *), limit)))
1529
0
    goto truncated;
1530
0
  CHECK_LIMIT(1);
1531
0
        *p++ = 0;
1532
0
  break;
1533
  
1534
0
      case 't':
1535
0
  usval = va_arg(ap, int);
1536
0
        CHECK_LIMIT(usval);
1537
0
  sval = va_arg(ap, char *);
1538
0
  if (usval != 0)
1539
0
    memcpy(p, sval, usval);
1540
0
  p += usval;
1541
0
  break;
1542
1543
0
      case 'z':
1544
0
  sval = va_arg(ap, char *);
1545
0
  usval = sval ? strlen(sval) : 0;
1546
0
  if (usval > 255)
1547
0
    usval = 255;
1548
0
        CHECK_LIMIT(usval + 1);
1549
0
  *p++ = (unsigned char)usval;
1550
0
  memcpy(p, sval, usval);
1551
0
  p += usval;
1552
0
  break;
1553
0
      }
1554
1555
0
  va_end(ap); /* clean up variable argument pointer */
1556
  
1557
  /* Now, store real RDLength. sav already checked against limit. */
1558
0
  j = p - sav - 2;
1559
0
  PUTSHORT(j, sav);
1560
  
1561
0
  *pp = p;
1562
0
  return 1;
1563
  
1564
0
 truncated:
1565
0
  va_end(ap);
1566
0
  if (truncp)
1567
0
    *truncp = 1;
1568
0
  return 0;
1569
1570
0
#undef CHECK_LIMIT
1571
0
}
1572
1573
static int crec_isstale(struct crec *crecp, time_t now)
1574
0
{
1575
0
  return (!(crecp->flags & F_IMMORTAL)) && difftime(crecp->ttd, now) < 0; 
1576
0
}
1577
1578
static unsigned long crec_ttl(struct crec *crecp, time_t now)
1579
0
{
1580
0
  signed long ttl = difftime(crecp->ttd, now);
1581
1582
  /* Return 0 ttl for DHCP entries, which might change
1583
     before the lease expires, unless configured otherwise. */
1584
1585
0
  if (crecp->flags & F_DHCP)
1586
0
    {
1587
0
      int conf_ttl = daemon->use_dhcp_ttl ? daemon->dhcp_ttl : daemon->local_ttl;
1588
      
1589
      /* Apply ceiling of actual lease length to configured TTL. */
1590
0
      if (!(crecp->flags & F_IMMORTAL) && ttl < conf_ttl)
1591
0
  return ttl;
1592
      
1593
0
      return conf_ttl;
1594
0
    }   
1595
  
1596
  /* Immortal entries other than DHCP are local, and hold TTL in TTD field. */
1597
0
  if (crecp->flags & F_IMMORTAL)
1598
0
    return crecp->ttd;
1599
1600
  /* Stale cache entries. */
1601
0
  if (ttl < 0)
1602
0
    return 0;
1603
  
1604
  /* Return the Max TTL value if it is lower than the actual TTL */
1605
0
  if (daemon->max_ttl == 0 || ((unsigned)ttl < daemon->max_ttl))
1606
0
    return ttl;
1607
0
  else
1608
0
    return daemon->max_ttl;
1609
0
}
1610
1611
static int cache_not_validated(const struct crec *crecp)
1612
0
{
1613
0
  return (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK));
1614
0
}
1615
1616
/* return zero if we can't answer from cache, or packet size if we can */
1617
size_t answer_request(struct dns_header *header, char *limit, size_t qlen,  
1618
          struct in_addr local_addr, struct in_addr local_netmask, 
1619
          time_t now, int ad_reqd, int do_bit, int no_cache, int *stale, int *filtered) 
1620
0
{
1621
0
  char *name = daemon->namebuff;
1622
0
  unsigned char *p, *ansp;
1623
0
  unsigned int qtype, qclass;
1624
0
  union all_addr addr;
1625
0
  int nameoffset;
1626
0
  unsigned short flag;
1627
0
  int ans, anscount = 0, nscount = 0, addncount = 0;
1628
0
  struct crec *crecp, *soa_lookup = NULL;
1629
0
  int nxdomain = 0, notimp = 0, auth = 1, trunc = 0, sec_data = 1;
1630
0
  struct mx_srv_record *rec;
1631
0
  size_t len;
1632
0
  int rd_bit = (header->hb3 & HB3_RD);
1633
0
  int count = 255; /* catch loops */
1634
1635
  /* Suppress cached answers if no_cache set. */
1636
0
  if (no_cache)
1637
0
    rd_bit = 0;
1638
  
1639
0
  if (stale)
1640
0
    *stale = 0;
1641
1642
0
  if (filtered)
1643
0
    *filtered = 0;
1644
  
1645
0
  if (ntohs(header->qdcount) != 1 ||
1646
0
      ntohs(header->ancount) != 0 ||
1647
0
      ntohs(header->nscount) != 0 ||
1648
0
      OPCODE(header) != QUERY )
1649
0
    return 0;
1650
  
1651
  /* Don't return AD set if checking disabled. */
1652
0
  if (header->hb4 & HB4_CD)
1653
0
    sec_data = 0;
1654
  
1655
0
  for (rec = daemon->mxnames; rec; rec = rec->next)
1656
0
    rec->offset = 0;
1657
  
1658
  /* determine end of question section (we put answers there) */
1659
0
  if (!(ansp = skip_questions(header, qlen)))
1660
0
    return 0; /* bad packet */
1661
   
1662
  /* now process each question, answers go in RRs after the question */
1663
0
  p = (unsigned char *)(header+1);
1664
1665
  /* save pointer to name for copying into answers */
1666
0
  nameoffset = p - (unsigned char *)header;
1667
  
1668
  /* now extract name as .-concatenated string into name */
1669
0
  if (!extract_name(header, qlen, &p, name, EXTR_NAME_EXTRACT, 4))
1670
0
    return 0; /* bad packet */
1671
  
1672
0
  GETSHORT(qtype, p); 
1673
0
  GETSHORT(qclass, p);
1674
  
1675
0
  ans = 0; /* have we answered this question */
1676
  
1677
0
  if (qclass == C_IN)
1678
0
    while (--count != 0 && (crecp = cache_find_by_name(NULL, name, now, F_CNAME | F_NXDOMAIN)))
1679
0
      {
1680
0
  char *cname_target;
1681
0
  int stale_flag = 0;
1682
  
1683
0
  if (crec_isstale(crecp, now))
1684
0
    {
1685
0
      if (stale)
1686
0
        *stale = 1;
1687
      
1688
0
      stale_flag = F_STALE;
1689
0
    }
1690
  
1691
0
  if (crecp->flags & F_NEG)
1692
0
    soa_lookup = crecp;
1693
    
1694
0
  if (crecp->flags & F_NXDOMAIN)
1695
0
    {
1696
0
      if (qtype == T_CNAME)
1697
0
        {
1698
0
    log_query(stale_flag | crecp->flags, name, NULL, record_source(crecp->uid), 0);
1699
0
    auth = 0;
1700
0
    nxdomain = 1;
1701
0
    ans = 1;
1702
0
        }
1703
0
      break;
1704
0
    }  
1705
  
1706
0
  cname_target = cache_get_cname_target(crecp);
1707
  
1708
  /* If the client asked for DNSSEC  don't use cached data. */
1709
0
  if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
1710
0
      (rd_bit && (!do_bit || cache_not_validated(crecp))))
1711
0
    {
1712
0
      if (crecp->flags & F_CONFIG || qtype == T_CNAME)
1713
0
        ans = 1;
1714
      
1715
0
      if (!(crecp->flags & F_DNSSECOK))
1716
0
        sec_data = 0;
1717
      
1718
0
      log_query(stale_flag | crecp->flags, name, NULL, record_source(crecp->uid), 0);
1719
0
      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
1720
0
            crec_ttl(crecp, now), &nameoffset,
1721
0
            T_CNAME, C_IN, "d", cname_target))
1722
0
        anscount++;
1723
0
    }
1724
0
  else
1725
0
    return 0; /* give up if any cached CNAME in chain can't be used for DNSSEC reasons. */
1726
  
1727
0
  if (qtype == T_CNAME)
1728
0
    break;
1729
  
1730
0
  strcpy(name, cname_target);
1731
0
      }
1732
  
1733
0
  if (qtype == T_TXT || qtype == T_ANY)
1734
0
    {
1735
0
      struct txt_record *t;
1736
0
      for(t = daemon->txt; t ; t = t->next)
1737
0
  {
1738
0
    if (t->class == qclass && hostname_isequal(name, t->name))
1739
0
      {
1740
0
        unsigned long ttl = daemon->local_ttl;
1741
0
        int ok = 1;
1742
        
1743
0
        ans = 1, sec_data = 0;
1744
0
#ifndef NO_ID
1745
        /* Dynamically generate stat record */
1746
0
        if (t->stat != 0)
1747
0
    {
1748
0
      ttl = 0;
1749
0
      if (!cache_make_stat(t))
1750
0
        ok = 0;
1751
0
    }
1752
0
#endif
1753
0
        if (ok)
1754
0
    {
1755
0
      log_query(F_CONFIG | F_RRNAME, name, NULL, "<TXT>", 0);
1756
0
      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
1757
0
            ttl, NULL,
1758
0
            T_TXT, t->class, "t", t->len, t->txt))
1759
0
        anscount++;
1760
0
    }
1761
0
      }
1762
0
  }
1763
0
    }
1764
  
1765
0
  if (qclass == C_CHAOS)
1766
0
    {
1767
      /* don't forward *.bind and *.server chaos queries - always reply with NOTIMP */
1768
0
      if (hostname_issubdomain("bind", name) || hostname_issubdomain("server", name))
1769
0
  {
1770
0
    if (!ans)
1771
0
      {
1772
0
        notimp = 1, auth = 0;
1773
        
1774
0
        addr.log.rcode = NOTIMP;
1775
0
        log_query(F_CONFIG | F_RCODE, name, &addr, NULL, 0);
1776
      
1777
0
        ans = 1, sec_data = 0;
1778
0
      }
1779
0
  }
1780
0
    }
1781
  
1782
0
  if (qclass == C_IN)
1783
0
    {
1784
0
      struct txt_record *t;
1785
      
1786
0
      for (t = daemon->rr; t; t = t->next)
1787
0
  if ((t->class == qtype || qtype == T_ANY) && hostname_isequal(name, t->name))
1788
0
    {
1789
0
      ans = 1;
1790
0
      sec_data = 0;
1791
0
      log_query(F_CONFIG | F_RRNAME, name, NULL, NULL, t->class);
1792
0
      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
1793
0
            daemon->local_ttl, NULL,
1794
0
            t->class, C_IN, "t", t->len, t->txt))
1795
0
        anscount++;
1796
0
    }
1797
      
1798
0
      if (qtype == T_PTR || qtype == T_ANY)
1799
0
  {
1800
    /* see if it's w.z.y.z.in-addr.arpa format */
1801
0
    int is_arpa = in_arpa_name_2_addr(name, &addr);
1802
0
    struct ptr_record *ptr;
1803
0
    struct interface_name* intr = NULL;
1804
    
1805
0
    for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1806
0
      if (hostname_isequal(name, ptr->name))
1807
0
        break;
1808
    
1809
0
    if (is_arpa == F_IPV4)
1810
0
      for (intr = daemon->int_names; intr; intr = intr->next)
1811
0
        {
1812
0
    struct addrlist *addrlist;
1813
    
1814
0
    for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
1815
0
      if (!(addrlist->flags & ADDRLIST_IPV6) && addr.addr4.s_addr == addrlist->addr.addr4.s_addr)
1816
0
        break;
1817
    
1818
0
    if (addrlist)
1819
0
      break;
1820
0
    else if (!(intr->flags & INP4))
1821
0
      while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
1822
0
        intr = intr->next;
1823
0
        }
1824
0
    else if (is_arpa == F_IPV6)
1825
0
      for (intr = daemon->int_names; intr; intr = intr->next)
1826
0
        {
1827
0
    struct addrlist *addrlist;
1828
    
1829
0
    for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
1830
0
      if ((addrlist->flags & ADDRLIST_IPV6) && IN6_ARE_ADDR_EQUAL(&addr.addr6, &addrlist->addr.addr6))
1831
0
        break;
1832
    
1833
0
    if (addrlist)
1834
0
      break;
1835
0
    else if (!(intr->flags & INP6))
1836
0
      while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
1837
0
        intr = intr->next;
1838
0
        }
1839
    
1840
0
    if (intr)
1841
0
      {
1842
0
        sec_data = 0;
1843
0
        ans = 1;
1844
0
        log_query(is_arpa | F_REVERSE | F_CONFIG, intr->name, &addr, NULL, 0);
1845
0
        if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
1846
0
              daemon->local_ttl, NULL,
1847
0
              T_PTR, C_IN, "d", intr->name))
1848
0
    anscount++;
1849
0
      }
1850
0
    else if (ptr)
1851
0
      {
1852
0
        ans = 1;
1853
0
        sec_data = 0;
1854
0
        log_query(F_CONFIG | F_RRNAME, name, NULL, "<PTR>", 0);
1855
0
        for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1856
0
    if (hostname_isequal(name, ptr->name) &&
1857
0
        add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
1858
0
          daemon->local_ttl, NULL,
1859
0
          T_PTR, C_IN, "d", ptr->ptr))
1860
0
      anscount++;
1861
        
1862
0
      }
1863
0
    else if (is_arpa && (crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
1864
0
      {
1865
        /* Don't use cache when DNSSEC data required, unless we know that
1866
     the zone is unsigned, which implies that we're doing
1867
     validation. */
1868
0
        if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
1869
0
      (rd_bit && (!do_bit || cache_not_validated(crecp)) ))
1870
0
    {
1871
0
      do 
1872
0
        { 
1873
0
          int stale_flag = 0;
1874
          
1875
0
          if (crec_isstale(crecp, now))
1876
0
      {
1877
0
        if (stale)
1878
0
          *stale = 1;
1879
        
1880
0
        stale_flag = F_STALE;
1881
0
      }
1882
          
1883
          /* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
1884
0
          if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
1885
0
      continue;
1886
          
1887
0
          if (!(crecp->flags & F_DNSSECOK))
1888
0
      sec_data = 0;
1889
          
1890
0
          ans = 1;
1891
          
1892
0
          if (crecp->flags & F_NEG)
1893
0
      {
1894
0
        auth = 0;
1895
0
        if (crecp->flags & F_NXDOMAIN)
1896
0
          nxdomain = 1;
1897
0
        log_query(stale_flag | (crecp->flags & ~F_FORWARD), name, &addr, NULL, 0);
1898
0
        soa_lookup = crecp;
1899
0
      }
1900
0
          else
1901
0
      {
1902
0
        if (!(crecp->flags & (F_HOSTS | F_DHCP)))
1903
0
          auth = 0;
1904
        
1905
0
        log_query(stale_flag | (crecp->flags & ~F_FORWARD), cache_get_name(crecp), &addr, 
1906
0
            record_source(crecp->uid), 0);
1907
        
1908
0
        if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
1909
0
              crec_ttl(crecp, now), NULL,
1910
0
              T_PTR, C_IN, "d", cache_get_name(crecp)))
1911
0
          anscount++;
1912
0
      }
1913
0
        } while ((crecp = cache_find_by_addr(crecp, &addr, now, is_arpa)));
1914
0
    }
1915
0
      }
1916
0
    else if (is_rev_synth(is_arpa, &addr, name))
1917
0
      {
1918
0
        ans = 1;
1919
0
        sec_data = 0;
1920
0
        log_query(F_CONFIG | F_REVERSE | is_arpa, name, &addr, NULL, 0);
1921
        
1922
0
        if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
1923
0
              daemon->local_ttl, NULL,
1924
0
              T_PTR, C_IN, "d", name))
1925
0
    anscount++;
1926
0
      }
1927
0
    else if (option_bool(OPT_BOGUSPRIV) &&
1928
0
       ((is_arpa == F_IPV6 && private_net6(&addr.addr6, 1)) || (is_arpa == F_IPV4 && private_net(addr.addr4, 1))) &&
1929
0
       !lookup_domain(name, F_DOMAINSRV, NULL, NULL))
1930
0
      {
1931
        /* if no configured server, not in cache, enabled and private IPV4 address, return NXDOMAIN */
1932
0
        ans = 1;
1933
0
        sec_data = 0;
1934
0
        nxdomain = 1;
1935
0
        log_query(F_CONFIG | F_REVERSE | is_arpa | F_NEG | F_NXDOMAIN,
1936
0
      name, &addr, NULL, 0);
1937
0
      }
1938
0
  }
1939
      
1940
0
      for (flag = F_IPV4; flag; flag = (flag == F_IPV4) ? F_IPV6 : 0)
1941
0
  {
1942
0
    unsigned short type = (flag == F_IPV6) ? T_AAAA : T_A;
1943
0
    struct interface_name *intr;
1944
    
1945
0
    if (qtype != type && qtype != T_ANY)
1946
0
      continue;
1947
    
1948
    /* interface name stuff */
1949
0
    for (intr = daemon->int_names; intr; intr = intr->next)
1950
0
      if (hostname_isequal(name, intr->name))
1951
0
        break;
1952
    
1953
0
    if (intr)
1954
0
      {
1955
0
        struct addrlist *addrlist;
1956
0
        int gotit = 0, localise = 0;
1957
        
1958
0
        enumerate_interfaces(0);
1959
        
1960
        /* See if a putative address is on the network from which we received
1961
     the query, is so we'll filter other answers. */
1962
0
        if (local_addr.s_addr != 0 && option_bool(OPT_LOCALISE) && type == T_A)
1963
0
    for (intr = daemon->int_names; intr; intr = intr->next)
1964
0
      if (hostname_isequal(name, intr->name))
1965
0
        for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
1966
0
          if (!(addrlist->flags & ADDRLIST_IPV6) && 
1967
0
        is_same_net(addrlist->addr.addr4, local_addr, local_netmask))
1968
0
      {
1969
0
        localise = 1;
1970
0
        break;
1971
0
      }
1972
        
1973
0
        for (intr = daemon->int_names; intr; intr = intr->next)
1974
0
    if (hostname_isequal(name, intr->name))
1975
0
      {
1976
0
        for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
1977
0
          if (((addrlist->flags & ADDRLIST_IPV6) ? T_AAAA : T_A) == type)
1978
0
      {
1979
0
        if (localise && 
1980
0
            !is_same_net(addrlist->addr.addr4, local_addr, local_netmask))
1981
0
          continue;
1982
        
1983
0
        if (addrlist->flags & ADDRLIST_REVONLY)
1984
0
          continue;
1985
        
1986
0
        ans = 1;  
1987
0
        sec_data = 0;
1988
0
        gotit = 1;
1989
0
        log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL, 0);
1990
0
        if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
1991
0
              daemon->local_ttl, NULL, type, C_IN, 
1992
0
              type == T_A ? "4" : "6", &addrlist->addr))
1993
0
          anscount++;
1994
0
      }
1995
0
      }
1996
        
1997
0
        if (!gotit)
1998
0
    log_query(F_FORWARD | F_CONFIG | flag | F_NEG, name, NULL, NULL, 0);
1999
        
2000
0
        continue;
2001
0
      }
2002
    
2003
0
    if ((crecp = cache_find_by_name(NULL, name, now, flag)))
2004
0
      {
2005
0
        int localise = 0;
2006
        
2007
        /* See if a putative address is on the network from which we received
2008
     the query, is so we'll filter other answers. */
2009
0
        if (!(crecp->flags & F_NEG) && local_addr.s_addr != 0 && option_bool(OPT_LOCALISE) && flag == F_IPV4)
2010
0
    {
2011
0
      struct crec *save = crecp;
2012
0
      do {
2013
0
        if ((crecp->flags & F_HOSTS) &&
2014
0
      is_same_net(crecp->addr.addr4, local_addr, local_netmask))
2015
0
          {
2016
0
      localise = 1;
2017
0
      break;
2018
0
          } 
2019
0
      } while ((crecp = cache_find_by_name(crecp, name, now, flag)));
2020
0
      crecp = save;
2021
0
    }
2022
        
2023
        /* If the client asked for DNSSEC  don't use cached data. */
2024
0
        if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
2025
0
      (rd_bit && (!do_bit || cache_not_validated(crecp)) ))
2026
0
    do
2027
0
      { 
2028
0
        int stale_flag = 0;
2029
        
2030
0
        if (crec_isstale(crecp, now))
2031
0
          {
2032
0
      if (stale)
2033
0
        *stale = 1;
2034
      
2035
0
      stale_flag = F_STALE;
2036
0
          }
2037
        
2038
        /* don't answer wildcard queries with data not from /etc/hosts
2039
           or DHCP leases */
2040
0
        if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
2041
0
          break;
2042
        
2043
0
        if (!(crecp->flags & F_DNSSECOK))
2044
0
          sec_data = 0;
2045
        
2046
0
        if (!(crecp->flags & (F_HOSTS | F_DHCP)))
2047
0
          auth = 0;
2048
        
2049
0
        if (qtype != T_ANY && rr_on_list(daemon->filter_rr, qtype) &&
2050
0
      !(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG | F_NEG)))
2051
0
          {
2052
      /* We have a cached answer but we're filtering it. */
2053
0
      ans = 1;
2054
0
      sec_data = 0;
2055
      
2056
0
      log_query(F_NEG | F_CONFIG | flag, name, NULL, NULL, 0);
2057
      
2058
0
      if (filtered)
2059
0
        *filtered = 1;
2060
0
          }
2061
0
        else if (crecp->flags & F_NEG)
2062
0
          {
2063
0
      if (qtype != T_ANY)
2064
0
        {
2065
0
          ans = 1;
2066
0
          auth = 0;
2067
0
          soa_lookup = crecp;
2068
0
          if (crecp->flags & F_NXDOMAIN)
2069
0
            nxdomain = 1;
2070
          
2071
0
          log_query(stale_flag | crecp->flags, name, NULL, NULL, 0);
2072
0
        }
2073
0
          }
2074
0
        else 
2075
0
          {
2076
      /* If we are returning local answers depending on network,
2077
         filter here. */
2078
0
      if (localise && 
2079
0
          (crecp->flags & F_HOSTS) &&
2080
0
          !is_same_net(crecp->addr.addr4, local_addr, local_netmask))
2081
0
        continue;
2082
      
2083
0
      ans = 1;
2084
0
      log_query(stale_flag | (crecp->flags & ~F_REVERSE), name, &crecp->addr,
2085
0
          record_source(crecp->uid), 0);
2086
      
2087
0
      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
2088
0
            crec_ttl(crecp, now), NULL, type, C_IN, 
2089
0
            type == T_A ? "4" : "6", &crecp->addr))
2090
0
        anscount++;
2091
0
          }
2092
0
      } while ((crecp = cache_find_by_name(crecp, name, now, flag)));
2093
0
    }
2094
0
    else if (is_name_synthetic(flag, name, &addr))
2095
0
      {
2096
0
        ans = 1, sec_data = 0;
2097
0
        log_query(F_FORWARD | F_CONFIG | flag, name, &addr, NULL, 0);
2098
0
        if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
2099
0
              daemon->local_ttl, NULL, type, C_IN, type == T_A ? "4" : "6", &addr))
2100
0
    anscount++;
2101
0
      }
2102
0
  }
2103
      
2104
0
      if (qtype == T_MX || qtype == T_ANY)
2105
0
  {
2106
0
    int found = 0;
2107
0
    for (rec = daemon->mxnames; rec; rec = rec->next)
2108
0
      if (!rec->issrv && hostname_isequal(name, rec->name))
2109
0
        {
2110
0
    int offset;
2111
    
2112
0
    ans = found = 1;
2113
0
    sec_data = 0;
2114
    
2115
0
    log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>", 0);
2116
0
    if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
2117
0
          &offset, T_MX, C_IN, "sd", rec->weight, rec->target))
2118
0
      {
2119
0
        anscount++;
2120
0
        if (rec->target)
2121
0
          rec->offset = offset;
2122
0
      }
2123
0
        }
2124
    
2125
0
    if (!found && (option_bool(OPT_SELFMX) || option_bool(OPT_LOCALMX)) &&
2126
0
        cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP | F_NO_RR))
2127
0
      { 
2128
0
        ans = 1;
2129
0
        sec_data = 0;
2130
0
        log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>", 0);
2131
0
        if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, NULL, 
2132
0
              T_MX, C_IN, "sd", 1, 
2133
0
              option_bool(OPT_SELFMX) ? name : daemon->mxtarget))
2134
0
    anscount++;
2135
0
      }
2136
0
  }
2137
      
2138
0
      if (qtype == T_SRV || qtype == T_ANY)
2139
0
  {
2140
0
    struct mx_srv_record *move = NULL, **up = &daemon->mxnames;
2141
    
2142
0
    for (rec = daemon->mxnames; rec; rec = rec->next)
2143
0
      if (rec->issrv && hostname_isequal(name, rec->name))
2144
0
        {
2145
0
    int offset;
2146
    
2147
0
    ans = 1;
2148
0
    sec_data = 0;
2149
0
    log_query(F_CONFIG | F_RRNAME, name, NULL, "<SRV>", 0);
2150
0
    if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, 
2151
0
          &offset, T_SRV, C_IN, "sssd", 
2152
0
          rec->priority, rec->weight, rec->srvport, rec->target))
2153
0
      {
2154
0
        anscount++;
2155
0
        if (rec->target)
2156
0
          rec->offset = offset;
2157
0
      }
2158
    
2159
    /* unlink first SRV record found */
2160
0
    if (!move)
2161
0
      {
2162
0
        move = rec;
2163
0
      *up = rec->next;
2164
0
      }
2165
0
    else
2166
0
      up = &rec->next;      
2167
0
        }
2168
0
      else
2169
0
        up = &rec->next;
2170
    
2171
    /* put first SRV record back at the end. */
2172
0
    if (move)
2173
0
      {
2174
0
        *up = move;
2175
0
        move->next = NULL;
2176
0
      }
2177
0
  }
2178
      
2179
0
      if (qtype == T_NAPTR || qtype == T_ANY)
2180
0
  {
2181
0
    struct naptr *na;
2182
0
    for (na = daemon->naptr; na; na = na->next)
2183
0
      if (hostname_isequal(name, na->name))
2184
0
        {
2185
0
    ans = 1;
2186
0
    sec_data = 0;
2187
0
    log_query(F_CONFIG | F_RRNAME, name, NULL, "<NAPTR>", 0);
2188
0
    if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, 
2189
0
          NULL, T_NAPTR, C_IN, "sszzzd", 
2190
0
          na->order, na->pref, na->flags, na->services, na->regexp, na->replace))
2191
0
      anscount++;
2192
0
        }
2193
0
  }
2194
      
2195
0
      if (qtype == T_MAILB)
2196
0
  ans = 1, nxdomain = 1, sec_data = 0;
2197
      
2198
0
      if (qtype == T_SOA && option_bool(OPT_FILTER))
2199
0
  {
2200
0
    ans = 1;
2201
0
    sec_data = 0;
2202
0
    log_query(F_CONFIG | F_NEG, name, &addr, NULL, 0);
2203
0
  }
2204
      
2205
0
      if (!ans)
2206
0
  {
2207
0
    if ((crecp = cache_find_by_name(NULL, name, now, F_RR | F_NXDOMAIN)) && rd_bit)
2208
0
      do
2209
0
        {
2210
0
    int flags = crecp->flags;
2211
0
    unsigned short rrtype;
2212
2213
0
    if (flags & F_KEYTAG)
2214
0
      rrtype = crecp->addr.rrblock.rrtype;
2215
0
    else
2216
0
      rrtype = crecp->addr.rrdata.rrtype;
2217
    
2218
0
    if (((flags & F_NXDOMAIN) || rrtype == qtype) &&
2219
0
        (!do_bit || cache_not_validated(crecp)))
2220
0
      {
2221
0
        char *rrdata = NULL;
2222
0
        unsigned short rrlen = 0;
2223
        
2224
0
        if (crec_isstale(crecp, now))
2225
0
          {
2226
0
      if (stale)
2227
0
        *stale = 1;
2228
      
2229
0
      flags |= F_STALE;
2230
0
          }
2231
        
2232
0
        if (!(flags & F_DNSSECOK))
2233
0
          sec_data = 0;
2234
        
2235
0
        if (flags & F_NXDOMAIN)
2236
0
          nxdomain = 1;
2237
0
        else if (qtype != T_ANY && rr_on_list(daemon->filter_rr, qtype))
2238
0
          flags |= F_NEG | F_CONFIG;
2239
        
2240
0
        auth = 0;
2241
0
        ans = 1;
2242
2243
0
        if (flags & F_NEG)
2244
0
          soa_lookup = crecp;
2245
        
2246
0
        if (!(flags & F_NEG))
2247
0
          {
2248
0
      if (flags & F_KEYTAG)
2249
0
        {
2250
0
          rrlen = crecp->addr.rrblock.datalen;
2251
0
          rrdata = blockdata_retrieve(crecp->addr.rrblock.rrdata, crecp->addr.rrblock.datalen, NULL);
2252
0
        }
2253
0
      else
2254
0
        {
2255
0
          rrlen = crecp->addr.rrdata.datalen;
2256
0
          rrdata = crecp->addr.rrdata.data;
2257
0
        }
2258
0
          }
2259
        
2260
0
        if (!(flags & F_NEG) && add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
2261
0
                crec_ttl(crecp, now), NULL, qtype, C_IN, "t",
2262
0
                rrlen, rrdata))
2263
0
          anscount++;
2264
        
2265
        /* log after cache insertion as log_txt mangles rrdata */
2266
0
        if (qtype == T_TXT && !(flags & F_NEG))
2267
0
          log_txt(name, (unsigned char *)rrdata, rrlen, flags & (F_DNSSECOK | F_STALE));
2268
0
        else
2269
0
          log_query(flags, name, &crecp->addr, NULL, 0);
2270
0
      }
2271
0
        } while ((crecp = cache_find_by_name(crecp, name, now, F_RR)));
2272
0
  }
2273
      
2274
0
      if (!ans && option_bool(OPT_FILTER) && (qtype == T_SRV || (qtype == T_ANY && strchr(name, '_'))))
2275
0
  {
2276
0
    ans = 1;
2277
0
    sec_data = 0;
2278
0
    log_query(F_CONFIG | F_NEG, name, NULL, NULL, 0);
2279
0
  }
2280
      
2281
      
2282
0
      if (qtype != T_ANY && !ans && rr_on_list(daemon->filter_rr, qtype) && !do_bit)
2283
0
  {
2284
    /* We don't have a cached answer and when we get an answer from upstream we're going to
2285
       filter it anyway. If we have a cached answer for the domain for another RRtype then
2286
       that may be enough to tell us if the answer should be NODATA and save the round trip.
2287
       Cached NXDOMAIN has already been handled, so here we look for any record for the domain,
2288
       since its existence allows us to return a NODATA answer. Note that we never set the AD flag,
2289
       since we didn't authenticate the record; this doesn't work if we want auth data, so
2290
       don't use this shortcut in that case. */
2291
    
2292
0
    if (cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6 | F_RR | F_CNAME))
2293
0
      {
2294
0
        ans = 1;
2295
0
        sec_data = auth = 0;
2296
        
2297
0
        log_query(F_NEG | F_CONFIG | flag, name, NULL, NULL, 0);
2298
        
2299
0
        if (filtered)
2300
0
    *filtered = 1;
2301
0
      }
2302
0
  }
2303
0
    }
2304
  
2305
0
  if (!ans)
2306
0
    return 0; /* failed to answer a question */
2307
2308
  /* We found a negative record. See if we have an SOA record to 
2309
     return in the AUTH section. 
2310
     
2311
     For FORWARD NEG records, the addr.rrdata.datalen field of the othewise
2312
     empty addr is used to held an offset in to the name which yields the SOA
2313
     name.
2314
     If the F_NO_RR flag is set, there was no SOA record supplied with the RR.  */
2315
0
  if (soa_lookup && !(soa_lookup->flags & F_NO_RR))
2316
0
    {
2317
0
      char *soa_name = name + soa_lookup->addr.rrdata.datalen;
2318
      
2319
0
      crecp = NULL;
2320
0
      while ((crecp = cache_find_by_name(crecp, soa_name, now, F_RR)))
2321
0
  if (crecp->addr.rrblock.rrtype == T_SOA)
2322
0
    {
2323
0
      char *rrdata;
2324
      
2325
0
      if (!(crecp->flags & F_NEG) &&
2326
0
    (rrdata = blockdata_retrieve(crecp->addr.rrblock.rrdata, crecp->addr.rrblock.datalen, NULL)) &&
2327
0
    add_resource_record(header, limit, &trunc, 0, &ansp, 
2328
0
            crec_ttl(crecp, now), NULL, T_SOA, C_IN, "t",
2329
0
            soa_name, crecp->addr.rrblock.datalen, rrdata))
2330
0
        {
2331
0
    nscount++;
2332
    
2333
0
    if (!(crecp->flags & F_DNSSECOK))
2334
0
      sec_data = 0;
2335
0
        }
2336
0
      break;
2337
0
    }
2338
0
    }
2339
      
2340
  /* create an additional data section, for stuff in SRV and MX record replies. */
2341
0
  for (rec = daemon->mxnames; rec; rec = rec->next)
2342
0
    if (rec->offset != 0)
2343
0
      {
2344
  /* squash dupes */
2345
0
  struct mx_srv_record *tmp;
2346
0
  for (tmp = rec->next; tmp; tmp = tmp->next)
2347
0
    if (tmp->offset != 0 && hostname_isequal(rec->target, tmp->target))
2348
0
      tmp->offset = 0;
2349
  
2350
0
  crecp = NULL;
2351
0
  while ((crecp = cache_find_by_name(crecp, rec->target, now, F_IPV4 | F_IPV6)))
2352
0
    {
2353
0
      int type =  crecp->flags & F_IPV4 ? T_A : T_AAAA;
2354
2355
0
      if (crecp->flags & F_NEG)
2356
0
        continue;
2357
2358
0
      if (add_resource_record(header, limit, NULL, rec->offset, &ansp, 
2359
0
            crec_ttl(crecp, now), NULL, type, C_IN, 
2360
0
            crecp->flags & F_IPV4 ? "4" : "6", &crecp->addr))
2361
0
        {
2362
0
    addncount++;
2363
0
    if (!(crecp->flags & F_DNSSECOK))
2364
0
      sec_data = 0;
2365
0
        }
2366
0
    }
2367
0
      }
2368
  
2369
  /* done all questions, set up header and return length of result */
2370
  /* clear authoritative and truncated flags, set QR flag */
2371
0
  header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR;
2372
  /* set RA flag */
2373
0
  header->hb4 |= HB4_RA;
2374
   
2375
  /* authoritative - only hosts and DHCP derived names. */
2376
0
  if (auth)
2377
0
    header->hb3 |= HB3_AA;
2378
  
2379
  /* truncation */
2380
0
  if (trunc)
2381
0
    {
2382
0
      header->hb3 |= HB3_TC;
2383
0
      if (!(ansp = skip_questions(header, qlen)))
2384
0
  return 0; /* bad packet */
2385
0
      anscount = nscount = addncount = 0;
2386
0
      log_query(0, "reply", NULL, "truncated", 0);
2387
0
    }
2388
2389
0
  if (nxdomain)
2390
0
    SET_RCODE(header, NXDOMAIN);
2391
0
  else if (notimp)
2392
0
    SET_RCODE(header, NOTIMP);
2393
0
  else
2394
0
    SET_RCODE(header, NOERROR); /* no error */
2395
2396
0
  header->ancount = htons(anscount);
2397
0
  header->nscount = htons(nscount);
2398
0
  header->arcount = htons(addncount);
2399
2400
0
  len = ansp - (unsigned char *)header;
2401
  
2402
0
  if (ad_reqd && sec_data)
2403
0
    header->hb4 |= HB4_AD;
2404
0
  else
2405
0
    header->hb4 &= ~HB4_AD;
2406
  
2407
0
  return len;
2408
0
}