~ubuntu-branches/ubuntu/maverick/pdns/maverick-updates

« back to all changes in this revision

Viewing changes to pdns/dnspacket.cc

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Haas
  • Date: 2009-02-25 23:25:51 UTC
  • mfrom: (1.1.7 upstream) (12.1.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090225232551-ts3d9k9q0ti442i9
Tags: 2.9.22-1
New upstream version (closes: #513409).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
    PowerDNS Versatile Database Driven Nameserver
3
 
    Copyright (C) 2001 - 2007  PowerDNS.COM BV
 
3
    Copyright (C) 2001 - 2008  PowerDNS.COM BV
4
4
 
5
5
    This program is free software; you can redistribute it and/or modify
6
6
    it under the terms of the GNU General Public License version 2 as 
38
38
#include "arguments.hh"
39
39
#include "dnswriter.hh"
40
40
#include "dnsparser.hh"
 
41
#include "dnsrecords.hh"
41
42
 
42
43
DNSPacket::DNSPacket() 
43
44
{
44
45
  d_wrapped=false;
45
46
  d_compress=true;
46
47
  d_tcp=false;
 
48
  d_wantsnsid=false;
47
49
}
48
50
 
49
51
string DNSPacket::getString()
87
89
  qtype=orig.qtype;
88
90
  qclass=orig.qclass;
89
91
  qdomain=orig.qdomain;
90
 
 
 
92
  d_maxreplylen = orig.d_maxreplylen;
 
93
  d_ednsping = orig.d_ednsping;
 
94
  d_wantsnsid = orig.d_wantsnsid;
91
95
  rrs=orig.rrs;
92
96
 
93
97
  d_wrapped=orig.d_wrapped;
184
188
  // fill out data with some plausible defaults:
185
189
  // 10800 3600 604800 3600
186
190
  data.serial=0;
187
 
  data.refresh=arg().asNum("soa-refresh-default");
188
 
  data.retry=arg().asNum("soa-retry-default");
189
 
  data.expire=arg().asNum("soa-expire-default");
190
 
  data.default_ttl=arg().asNum("soa-minimum-ttl");
 
191
  data.refresh=::arg().asNum("soa-refresh-default");
 
192
  data.retry=::arg().asNum("soa-retry-default");
 
193
  data.expire=::arg().asNum("soa-expire-default");
 
194
  data.default_ttl=::arg().asNum("soa-minimum-ttl");
191
195
 
192
196
  vector<string>parts;
193
197
  stringtok(parts,content);
263
267
  rrs.reserve(200);
264
268
}
265
269
 
 
270
bool DNSPacket::couldBeCached()
 
271
{
 
272
  return d_ednsping.empty() && !d_wantsnsid;
 
273
}
 
274
 
266
275
/** Must be called before attempting to access getData(). This function stuffs all resource
267
276
 *  records found in rrs into the data buffer. It also frees resource records queued for us.
268
277
 */
287
296
 
288
297
  stable_sort(rrs.begin(),rrs.end(),rrcomp);
289
298
 
290
 
  if(!d_tcp && !arg().mustDo("no-shuffle")) {
 
299
  static bool mustShuffle =::arg().mustDo("no-shuffle");
 
300
 
 
301
  if(!d_tcp && !mustShuffle) {
291
302
    shuffle(rrs);
292
303
  }
293
304
  d_wrapped=true;
302
313
  pw.getHeader()->id=d.id;
303
314
  pw.getHeader()->rd=d.rd;
304
315
 
305
 
  if(!rrs.empty()) {
 
316
  DNSPacketWriter::optvect_t opts;
 
317
  if(d_wantsnsid) {
 
318
    opts.push_back(make_pair(3, ::arg()["server-id"]));
 
319
  }
 
320
 
 
321
  if(!d_ednsping.empty()) {
 
322
    opts.push_back(make_pair(4, d_ednsping));
 
323
  }
 
324
 
 
325
  if(!rrs.empty() || !opts.empty()) {
306
326
    try {
307
327
      for(pos=rrs.begin(); pos < rrs.end(); ++pos) {
308
328
        // this needs to deal with the 'prio' mismatch!
318
338
        shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(pos->qtype.getCode(), 1, pos->content)); 
319
339
        drc->toPacket(pw);
320
340
      }
 
341
      if(!opts.empty())
 
342
        pw.addOpt(2800, 0, 0, opts);
 
343
 
321
344
      pw.commit();
322
345
    }
323
 
    catch(exception& e) {
324
 
      L<<Logger::Error<<"Exception: "<<e.what()<<endl;
 
346
    catch(std::exception& e) {
 
347
      L<<Logger::Warning<<"Exception: "<<e.what()<<endl;
325
348
      throw;
326
349
    }
327
350
  }
380
403
  r->d_tcp = d_tcp;
381
404
  r->qdomain = qdomain;
382
405
  r->qtype = qtype;
 
406
  r->d_maxreplylen = d_maxreplylen;
 
407
  r->d_ednsping = d_ednsping;
 
408
  r->d_wantsnsid = d_wantsnsid;
383
409
  return r;
384
410
}
385
411
 
391
417
  d_wrapped=true; // if we do this, don't later on wrapup
392
418
}
393
419
 
 
420
int DNSPacket::noparse(const char *mesg, int length)
 
421
{
 
422
  stringbuffer.assign(mesg,length); 
 
423
  
 
424
  len=length;
 
425
  if(length < 12) { 
 
426
    L << Logger::Warning << "Ignoring packet: too short from "
 
427
      << getRemote() << endl;
 
428
    return -1;
 
429
  }
 
430
  d_wantsnsid=false;
 
431
  d_ednsping.clear();
 
432
  d_maxreplylen=512;
 
433
  memcpy((void *)&d,(const void *)stringbuffer.c_str(),12);
 
434
  return 0;
 
435
}
 
436
 
394
437
/** This function takes data from the network, possibly received with recvfrom, and parses
395
438
    it into our class. Results of calling this function multiple times on one packet are
396
439
    unknown. Returns -1 if the packet cannot be parsed.
399
442
try
400
443
{
401
444
  stringbuffer.assign(mesg,length); 
402
 
 
 
445
  
403
446
  len=length;
404
447
  if(length < 12) { 
405
448
    L << Logger::Warning << "Ignoring packet: too short from "
406
449
      << getRemote() << endl;
407
450
    return -1;
408
451
  }
409
 
  MOADNSParser mdp(string(mesg, length));
 
452
 
 
453
  MOADNSParser mdp(stringbuffer);
 
454
  EDNSOpts edo;
 
455
 
 
456
  // ANY OPTION WHICH *MIGHT* BE SET DOWN BELOW SHOULD BE CLEARED FIRST!
 
457
 
 
458
  d_wantsnsid=false;
 
459
  d_ednsping.clear();
 
460
 
 
461
  if(getEDNSOpts(mdp, &edo)) {
 
462
    d_maxreplylen=max(edo.d_packetsize, (uint16_t)1280);
 
463
 
 
464
    for(vector<pair<uint16_t, string> >::const_iterator iter = edo.d_options.begin();
 
465
        iter != edo.d_options.end(); 
 
466
        ++iter) {
 
467
      if(iter->first == 3) {// 'EDNS NSID'
 
468
        d_wantsnsid=1;
 
469
      }
 
470
      else if(iter->first == 5) {// 'EDNS PING'
 
471
        d_ednsping = iter->second;
 
472
      }
 
473
      else
 
474
        ; // cerr<<"Have an option #"<<iter->first<<endl;
 
475
    }
 
476
  }
 
477
  else  {
 
478
    d_maxreplylen=512;
 
479
  }
410
480
 
411
481
  memcpy((void *)&d,(const void *)stringbuffer.c_str(),12);
412
482
  qdomain=mdp.d_qname;
424
494
  qclass=mdp.d_qclass;
425
495
  return 0;
426
496
}
427
 
catch(exception& e) {
 
497
catch(std::exception& e) {
428
498
  return -1;
429
499
}
430
500
 
 
501
int DNSPacket::getMaxReplyLen()
 
502
{
 
503
  return d_maxreplylen;
 
504
}
 
505
 
 
506
void DNSPacket::setMaxReplyLen(int bytes)
 
507
{
 
508
  d_maxreplylen=bytes;
 
509
}
 
510
 
431
511
//! Use this to set where this packet was received from or should be sent to
432
512
void DNSPacket::setRemote(const ComboAddress *s)
433
513
{