Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 19375 | Differences between
and this patch

Collapse All | Expand All

(-)djbdns-1.05-original/query.c (-38 / +79 lines)
Lines 91-96 Link Here
91
  }
91
  }
92
}
92
}
93
93
94
static int move_name_to_alias(struct query *z,uint32 ttl)
95
{
96
  int j ;
97
98
  if (z->alias[QUERY_MAXALIAS - 1]) return 0 ;
99
  for (j = QUERY_MAXALIAS - 1;j > 0;--j)
100
    z->alias[j] = z->alias[j - 1];
101
  for (j = QUERY_MAXALIAS - 1;j > 0;--j)
102
    z->aliasttl[j] = z->aliasttl[j - 1];
103
  z->alias[0] = z->name[0];
104
  z->aliasttl[0] = ttl;
105
  z->name[0] = 0;
106
  return 1 ;
107
}
108
94
static int rqa(struct query *z)
109
static int rqa(struct query *z)
95
{
110
{
96
  int i;
111
  int i;
Lines 123-129 Link Here
123
static char *t1 = 0;
138
static char *t1 = 0;
124
static char *t2 = 0;
139
static char *t2 = 0;
125
static char *t3 = 0;
140
static char *t3 = 0;
126
static char *cname = 0;
127
static char *referral = 0;
141
static char *referral = 0;
128
static unsigned int *records = 0;
142
static unsigned int *records = 0;
129
143
Lines 179-193 Link Here
179
  uint16 datalen;
193
  uint16 datalen;
180
  char *control;
194
  char *control;
181
  char *d;
195
  char *d;
196
  char *owner_name = 0 ;
182
  const char *dtype;
197
  const char *dtype;
183
  unsigned int dlen;
198
  unsigned int dlen;
184
  int flagout;
199
  int flagout;
185
  int flagcname;
186
  int flagreferral;
200
  int flagreferral;
187
  int flagsoa;
201
  int flagsoa;
188
  uint32 ttl;
202
  uint32 ttl;
189
  uint32 soattl;
203
  uint32 soattl;
190
  uint32 cnamettl;
191
  int i;
204
  int i;
192
  int j;
205
  int j;
193
  int k;
206
  int k;
Lines 252-258 Link Here
252
265
253
    byte_copy(key,2,DNS_T_CNAME);
266
    byte_copy(key,2,DNS_T_CNAME);
254
    cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
267
    cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
255
    if (cached) {
268
    /* A previous explicit query might have caused an empty RRSet to have been
269
    ** cached.  Take care to ignore such a thing. 
270
    */
271
    if (cached && cachedlen) {
256
      if (typematch(DNS_T_CNAME,dtype)) {
272
      if (typematch(DNS_T_CNAME,dtype)) {
257
        log_cachedanswer(d,DNS_T_CNAME);
273
        log_cachedanswer(d,DNS_T_CNAME);
258
        if (!rqa(z)) goto DIE;
274
        if (!rqa(z)) goto DIE;
Lines 261-268 Link Here
261
	return 1;
277
	return 1;
262
      }
278
      }
263
      log_cachedcname(d,cached);
279
      log_cachedcname(d,cached);
264
      if (!dns_domain_copy(&cname,cached)) goto DIE;
280
      if (!z->level) {
265
      goto CNAME;
281
	if (!move_name_to_alias(z,ttl)) goto DIE ;
282
      }
283
      if (!dns_domain_copy(&z->name[z->level],cached)) goto DIE;
284
      goto NEWNAME;
266
    }
285
    }
267
286
268
    if (typematch(DNS_T_NS,dtype)) {
287
    if (typematch(DNS_T_NS,dtype)) {
Lines 351-357 Link Here
351
      }
370
      }
352
    }
371
    }
353
372
354
    if (!typematch(DNS_T_ANY,dtype) && !typematch(DNS_T_AXFR,dtype) && !typematch(DNS_T_CNAME,dtype) && !typematch(DNS_T_NS,dtype) && !typematch(DNS_T_PTR,dtype) && !typematch(DNS_T_A,dtype) && !typematch(DNS_T_MX,dtype)) {
373
    if (!typematch(DNS_T_ANY,dtype) && !typematch(DNS_T_AXFR,dtype) && !typematch(DNS_T_NS,dtype) && !typematch(DNS_T_PTR,dtype) && !typematch(DNS_T_A,dtype) && !typematch(DNS_T_MX,dtype)) {
355
      byte_copy(key,2,dtype);
374
      byte_copy(key,2,dtype);
356
      cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
375
      cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
357
      if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) {
376
      if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) {
Lines 471-499 Link Here
471
  if (rcode && (rcode != 3)) goto DIE; /* impossible; see irrelevant() */
490
  if (rcode && (rcode != 3)) goto DIE; /* impossible; see irrelevant() */
472
491
473
  flagout = 0;
492
  flagout = 0;
474
  flagcname = 0;
475
  flagreferral = 0;
493
  flagreferral = 0;
476
  flagsoa = 0;
494
  flagsoa = 0;
477
  soattl = 0;
495
  soattl = 0;
478
  cnamettl = 0;
496
  if (!dns_domain_copy(&owner_name,d)) goto DIE;
497
  /* This code assumes that the CNAME chain is presented in the correct 
498
  ** order.  The example algorithm in RFC 1034 will actually result in this
499
  ** being the case, but the words do not require it to be so.
500
  */
479
  for (j = 0;j < numanswers;++j) {
501
  for (j = 0;j < numanswers;++j) {
480
    pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE;
502
    pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE;
481
    pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
503
    pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
482
504
483
    if (dns_domain_equal(t1,d))
505
    if (dns_domain_equal(t1,owner_name))
484
      if (byte_equal(header + 2,2,DNS_C_IN)) { /* should always be true */
506
      if (byte_equal(header + 2,2,DNS_C_IN)) { /* should always be true */
485
        if (typematch(header,dtype))
507
        if (typematch(header,dtype))
486
          flagout = 1;
508
          flagout = 1;
487
        else if (typematch(header,DNS_T_CNAME)) {
509
        else if (typematch(header,DNS_T_CNAME)) {
488
          if (!dns_packet_getname(buf,len,pos,&cname)) goto DIE;
510
          if (!dns_packet_getname(buf,len,pos,&owner_name)) goto DIE;
489
          flagcname = 1;
490
	  cnamettl = ttlget(header + 4);
491
        }
511
        }
492
      }
512
      }
493
  
513
  
494
    uint16_unpack_big(header + 8,&datalen);
514
    uint16_unpack_big(header + 8,&datalen);
495
    pos += datalen;
515
    pos += datalen;
496
  }
516
  }
517
  dns_domain_free(&owner_name) ;
497
  posauthority = pos;
518
  posauthority = pos;
498
519
499
  for (j = 0;j < numauthority;++j) {
520
  for (j = 0;j < numauthority;++j) {
Lines 515-529 Link Here
515
  }
536
  }
516
  posglue = pos;
537
  posglue = pos;
517
538
518
519
  if (!flagcname && !rcode && !flagout && flagreferral && !flagsoa)
520
    if (dns_domain_equal(referral,control) || !dns_domain_suffix(referral,control)) {
521
      log_lame(whichserver,control,referral);
522
      byte_zero(whichserver,4);
523
      goto HAVENS;
524
    }
525
526
527
  if (records) { alloc_free(records); records = 0; }
539
  if (records) { alloc_free(records); records = 0; }
528
540
529
  k = numanswers + numauthority + numglue;
541
  k = numanswers + numauthority + numglue;
Lines 670-693 Link Here
670
682
671
  alloc_free(records); records = 0;
683
  alloc_free(records); records = 0;
672
684
685
  if (byte_diff(DNS_T_CNAME,2,dtype)) {
686
    /* This code assumes that the CNAME chain is presented in the correct 
687
    ** order.  The example algorithm in RFC 1034 will actually result in this
688
    ** being the case, but the words do not require it to be so.
689
    */
690
    pos = posanswers;
691
    for (j = 0;j < numanswers;++j) {
692
      pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE;
693
      pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
694
695
      if (dns_domain_equal(t1,d))
696
	if (byte_equal(header + 2,2,DNS_C_IN)) { /* should always be true */
697
	  if (typematch(header,DNS_T_CNAME)) {
698
	    ttl = ttlget(header + 4);
699
	    if (z->level == 0) {
700
	      if (!move_name_to_alias(z,ttl)) goto DIE ;
701
	    }
702
	    if (!dns_packet_getname(buf,len,pos,&z->name[z->level])) goto DIE;
703
	    d = z->name[z->level];
704
	    if (!dns_domain_suffix(d,control) || !roots_same(d,control))
705
	      goto NEWNAME ;  /* Cannot trust the chain further - restart using current name */
706
	  }
707
	}
673
708
674
  if (flagcname) {
709
      uint16_unpack_big(header + 8,&datalen);
675
    ttl = cnamettl;
710
      pos += datalen;
676
    CNAME:
677
    if (!z->level) {
678
      if (z->alias[QUERY_MAXALIAS - 1]) goto DIE;
679
      for (j = QUERY_MAXALIAS - 1;j > 0;--j)
680
        z->alias[j] = z->alias[j - 1];
681
      for (j = QUERY_MAXALIAS - 1;j > 0;--j)
682
        z->aliasttl[j] = z->aliasttl[j - 1];
683
      z->alias[0] = z->name[0];
684
      z->aliasttl[0] = ttl;
685
      z->name[0] = 0;
686
    }
711
    }
687
    if (!dns_domain_copy(&z->name[z->level],cname)) goto DIE;
688
    goto NEWNAME;
689
  }
712
  }
690
713
714
  /* A "no such name" error applies to the end of any CNAME chain, not to the start. */
691
  if (rcode == 3) {
715
  if (rcode == 3) {
692
    log_nxdomain(whichserver,d,soattl);
716
    log_nxdomain(whichserver,d,soattl);
693
    cachegeneric(DNS_T_ANY,d,"",0,soattl);
717
    cachegeneric(DNS_T_ANY,d,"",0,soattl);
Lines 700-709 Link Here
700
    return 1;
724
    return 1;
701
  }
725
  }
702
726
727
  /* We check for a lame server _after_ we have cached any records that it
728
  ** might have returned to us.  This copes better with the incorrect
729
  ** behaviour of one content DNS server software that doesn't return
730
  ** complete CNAME chains but instead returns only the first link in a
731
  ** chain followed by a lame delegation to the same server.
732
  ** Also: We check for a lame server _after_ following the CNAME chain.  The
733
  ** delegation in a referral answer applies to the _end_ of the chain, not
734
  ** to the beginning.
735
  */
736
  if (!rcode && !flagout && flagreferral && !flagsoa)
737
    if (dns_domain_equal(referral,control) || !dns_domain_suffix(referral,control)) {
738
      log_lame(whichserver,control,referral);
739
      byte_zero(whichserver,4);
740
      goto HAVENS;
741
    }
742
703
  if (!flagout && flagsoa)
743
  if (!flagout && flagsoa)
744
    /* Don't save empty RRSets for those types that we use as special markers. */
704
    if (byte_diff(DNS_T_ANY,2,dtype))
745
    if (byte_diff(DNS_T_ANY,2,dtype))
705
      if (byte_diff(DNS_T_AXFR,2,dtype))
746
      if (byte_diff(DNS_T_AXFR,2,dtype)) {
706
        if (byte_diff(DNS_T_CNAME,2,dtype)) {
707
          save_start();
747
          save_start();
708
          save_finish(dtype,d,soattl);
748
          save_finish(dtype,d,soattl);
709
	  log_nodata(whichserver,d,dtype,soattl);
749
	  log_nodata(whichserver,d,dtype,soattl);
Lines 815-820 Link Here
815
  DIE:
855
  DIE:
816
  cleanup(z);
856
  cleanup(z);
817
  if (records) { alloc_free(records); records = 0; }
857
  if (records) { alloc_free(records); records = 0; }
858
  dns_domain_free(&owner_name) ;
818
  return -1;
859
  return -1;
819
}
860
}

Return to bug 19375