1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/base/dnsrr_resolver.h"
6
7#if defined(OS_POSIX)
8#include <resolv.h>
9#endif
10
11#if defined(OS_WIN)
12#include <windns.h>
13#endif
14
15#include "base/memory/scoped_ptr.h"
16#include "base/memory/singleton.h"
17#include "base/message_loop.h"
18#include "base/stl_util-inl.h"
19#include "base/string_piece.h"
20#include "base/synchronization/lock.h"
21#include "base/task.h"
22#include "base/threading/worker_pool.h"
23#include "net/base/dns_reload_timer.h"
24#include "net/base/dns_util.h"
25#include "net/base/net_errors.h"
26
27// Life of a query:
28//
29// DnsRRResolver RRResolverJob RRResolverWorker       ...         Handle
30//      |                       (origin loop)    (worker loop)
31//      |
32//   Resolve()
33//      |---->-------------------<creates>
34//      |
35//      |---->----<creates>
36//      |
37//      |---->---------------------------------------------------<creates>
38//      |
39//      |---->--------------------Start
40//      |                           |
41//      |                        PostTask
42//      |
43//      |                                     <starts resolving>
44//      |---->-----AddHandle                          |
45//                                                    |
46//                                                    |
47//                                                    |
48//                                                  Finish
49//                                                    |
50//                                                 PostTask
51//
52//                                   |
53//                                DoReply
54//      |----<-----------------------|
55//  HandleResult
56//      |
57//      |---->-----HandleResult
58//                      |
59//                      |------>-----------------------------------Post
60//
61//
62//
63// A cache hit:
64//
65// DnsRRResolver                       Handle
66//      |
67//   Resolve()
68//      |---->------------------------<creates>
69//      |
70//      |
71//   PostTask
72//
73// (MessageLoop cycles)
74//
75//                                      Post
76
77namespace net {
78
79#if defined(OS_WIN)
80// DnsRRIsParsedByWindows returns true if Windows knows how to parse the given
81// RR type. RR data is returned in a DNS_RECORD structure which may be raw (if
82// Windows doesn't parse it) or may be a parse result. It's unclear how this
83// API is intended to evolve in the future. If Windows adds support for new RR
84// types in a future version a client which expected raw data will break.
85// See http://msdn.microsoft.com/en-us/library/ms682082(v=vs.85).aspx
86static bool DnsRRIsParsedByWindows(uint16 rrtype) {
87  // We only cover the types which are defined in dns_util.h
88  switch (rrtype) {
89    case kDNS_CNAME:
90    case kDNS_TXT:
91    case kDNS_DS:
92    case kDNS_RRSIG:
93    case kDNS_DNSKEY:
94      return true;
95    default:
96      return false;
97  }
98}
99#endif
100
101static const uint16 kClassIN = 1;
102// kMaxCacheEntries is the number of RRResponse objects that we'll cache.
103static const unsigned kMaxCacheEntries = 32;
104// kNegativeTTLSecs is the number of seconds for which we'll cache a negative
105// cache entry.
106static const unsigned kNegativeTTLSecs = 60;
107
108RRResponse::RRResponse()
109    : ttl(0), dnssec(false), negative(false) {
110}
111
112RRResponse::~RRResponse() {}
113
114class RRResolverHandle {
115 public:
116  RRResolverHandle(CompletionCallback* callback, RRResponse* response)
117      : callback_(callback),
118        response_(response) {
119  }
120
121  // Cancel ensures that the result callback will never be made.
122  void Cancel() {
123    callback_ = NULL;
124    response_ = NULL;
125  }
126
127  // Post copies the contents of |response| to the caller's RRResponse and
128  // calls the callback.
129  void Post(int rv, const RRResponse* response) {
130    if (callback_) {
131      if (response_ && response)
132        *response_ = *response;
133      callback_->Run(rv);
134    }
135    delete this;
136  }
137
138 private:
139  CompletionCallback* callback_;
140  RRResponse* response_;
141};
142
143
144// RRResolverWorker runs on a worker thread and takes care of the blocking
145// process of performing the DNS resolution.
146class RRResolverWorker {
147 public:
148  RRResolverWorker(const std::string& name, uint16 rrtype, uint16 flags,
149                   DnsRRResolver* dnsrr_resolver)
150      : name_(name),
151        rrtype_(rrtype),
152        flags_(flags),
153        origin_loop_(MessageLoop::current()),
154        dnsrr_resolver_(dnsrr_resolver),
155        canceled_(false),
156        result_(ERR_UNEXPECTED) {
157  }
158
159  bool Start() {
160    DCHECK_EQ(MessageLoop::current(), origin_loop_);
161
162    return base::WorkerPool::PostTask(
163        FROM_HERE, NewRunnableMethod(this, &RRResolverWorker::Run),
164        true /* task is slow */);
165  }
166
167  // Cancel is called from the origin loop when the DnsRRResolver is getting
168  // deleted.
169  void Cancel() {
170    DCHECK_EQ(MessageLoop::current(), origin_loop_);
171    base::AutoLock locked(lock_);
172    canceled_ = true;
173  }
174
175 private:
176
177#if defined(OS_POSIX) && !defined(ANDROID)
178
179  void Run() {
180    // Runs on a worker thread.
181
182    if (HandleTestCases()) {
183      Finish();
184      return;
185    }
186
187    bool r = true;
188    if ((_res.options & RES_INIT) == 0) {
189      if (res_ninit(&_res) != 0)
190        r = false;
191    }
192
193    if (r) {
194      unsigned long saved_options = _res.options;
195      r = Do();
196
197#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD)
198      if (!r && DnsReloadTimerHasExpired()) {
199        // When there's no network connection, _res may not be initialized by
200        // getaddrinfo. Therefore, we call res_nclose only when there are ns
201        // entries.
202        if (_res.nscount > 0)
203          res_nclose(&_res);
204        if (res_ninit(&_res) == 0)
205          r = Do();
206      }
207#endif
208      _res.options = saved_options;
209    }
210
211    response_.fetch_time = base::Time::Now();
212
213    if (r) {
214      result_ = OK;
215    } else {
216      result_ = ERR_NAME_NOT_RESOLVED;
217      response_.negative = true;
218      response_.ttl = kNegativeTTLSecs;
219    }
220
221    Finish();
222  }
223
224  bool Do() {
225    // For DNSSEC, a 4K buffer is suggested
226    static const unsigned kMaxDNSPayload = 4096;
227
228#ifndef RES_USE_DNSSEC
229    // Some versions of libresolv don't have support for the DO bit. In this
230    // case, we proceed without it.
231    static const int RES_USE_DNSSEC = 0;
232#endif
233
234#ifndef RES_USE_EDNS0
235    // Some versions of glibc are so old that they don't support EDNS0 either.
236    // http://code.google.com/p/chromium/issues/detail?id=51676
237    static const int RES_USE_EDNS0 = 0;
238#endif
239
240    // We set the options explicitly. Note that this removes several default
241    // options: RES_DEFNAMES and RES_DNSRCH (see res_init(3)).
242    _res.options = RES_INIT | RES_RECURSE | RES_USE_EDNS0 | RES_USE_DNSSEC;
243    uint8 answer[kMaxDNSPayload];
244    int len = res_search(name_.c_str(), kClassIN, rrtype_, answer,
245                         sizeof(answer));
246    if (len == -1)
247      return false;
248
249    return response_.ParseFromResponse(answer, len, rrtype_);
250  }
251
252#elif defined(ANDROID)
253
254  void Run() {
255    if (HandleTestCases()) {
256      Finish();
257      return;
258    }
259
260    response_.fetch_time = base::Time::Now();
261    response_.negative = true;
262    result_ = ERR_NAME_NOT_RESOLVED;
263    Finish();
264  }
265
266#else  // OS_WIN
267
268  void Run() {
269    if (HandleTestCases()) {
270      Finish();
271      return;
272    }
273
274    // See http://msdn.microsoft.com/en-us/library/ms682016(v=vs.85).aspx
275    PDNS_RECORD record = NULL;
276    DNS_STATUS status =
277        DnsQuery_A(name_.c_str(), rrtype_, DNS_QUERY_STANDARD,
278                   NULL /* pExtra (reserved) */, &record, NULL /* pReserved */);
279    response_.fetch_time = base::Time::Now();
280    response_.name = name_;
281    response_.dnssec = false;
282    response_.ttl = 0;
283
284    if (status != 0) {
285      response_.negative = true;
286      result_ = ERR_NAME_NOT_RESOLVED;
287    } else {
288      response_.negative = false;
289      result_ = OK;
290      for (DNS_RECORD* cur = record; cur; cur = cur->pNext) {
291        if (cur->wType == rrtype_) {
292          response_.ttl = record->dwTtl;
293          // Windows will parse some types of resource records. If we want one
294          // of these types then we have to reserialise the record.
295          switch (rrtype_) {
296            case kDNS_TXT: {
297              // http://msdn.microsoft.com/en-us/library/ms682109(v=vs.85).aspx
298              const DNS_TXT_DATA* txt = &cur->Data.TXT;
299              std::string rrdata;
300
301              for (DWORD i = 0; i < txt->dwStringCount; i++) {
302                // Although the string is typed as a PWSTR, it's actually just
303                // an ASCII byte-string.  Also, the string must be < 256
304                // elements because the length in the DNS packet is a single
305                // byte.
306                const char* s = reinterpret_cast<char*>(txt->pStringArray[i]);
307                size_t len = strlen(s);
308                DCHECK_LT(len, 256u);
309                char len8 = static_cast<char>(len);
310                rrdata.push_back(len8);
311                rrdata += s;
312              }
313              response_.rrdatas.push_back(rrdata);
314              break;
315            }
316            default:
317              if (DnsRRIsParsedByWindows(rrtype_)) {
318                // Windows parses this type, but we don't have code to unparse
319                // it.
320                NOTREACHED() << "you need to add code for the RR type here";
321                response_.negative = true;
322                result_ = ERR_INVALID_ARGUMENT;
323              } else {
324                // This type is given to us raw.
325                response_.rrdatas.push_back(
326                    std::string(reinterpret_cast<char*>(&cur->Data),
327                                cur->wDataLength));
328              }
329          }
330        }
331      }
332    }
333
334    DnsRecordListFree(record, DnsFreeRecordList);
335    Finish();
336  }
337
338#endif  // OS_WIN
339
340  // HandleTestCases stuffs in magic test values in the event that the query is
341  // from a unittest.
342  bool HandleTestCases() {
343    if (rrtype_ == kDNS_TESTING) {
344      response_.fetch_time = base::Time::Now();
345
346      if (name_ == "www.testing.notatld") {
347        response_.ttl = 86400;
348        response_.negative = false;
349        response_.rrdatas.push_back("goats!");
350        result_ = OK;
351        return true;
352      } else if (name_ == "nx.testing.notatld") {
353        response_.negative = true;
354        result_ = ERR_NAME_NOT_RESOLVED;
355        return true;
356      }
357    }
358
359    return false;
360  }
361
362  // DoReply runs on the origin thread.
363  void DoReply() {
364    DCHECK_EQ(MessageLoop::current(), origin_loop_);
365    {
366      // We lock here because the worker thread could still be in Finished,
367      // after the PostTask, but before unlocking |lock_|. If we do not lock in
368      // this case, we will end up deleting a locked Lock, which can lead to
369      // memory leaks or worse errors.
370      base::AutoLock locked(lock_);
371      if (!canceled_)
372        dnsrr_resolver_->HandleResult(name_, rrtype_, result_, response_);
373    }
374    delete this;
375  }
376
377  void Finish() {
378    // Runs on the worker thread.
379    // We assume that the origin loop outlives the DnsRRResolver. If the
380    // DnsRRResolver is deleted, it will call Cancel on us. If it does so
381    // before the Acquire, we'll delete ourselves and return. If it's trying to
382    // do so concurrently, then it'll block on the lock and we'll call PostTask
383    // while the DnsRRResolver (and therefore the MessageLoop) is still alive.
384    // If it does so after this function, we assume that the MessageLoop will
385    // process pending tasks. In which case we'll notice the |canceled_| flag
386    // in DoReply.
387
388    bool canceled;
389    {
390      base::AutoLock locked(lock_);
391      canceled = canceled_;
392      if (!canceled) {
393        origin_loop_->PostTask(
394            FROM_HERE, NewRunnableMethod(this, &RRResolverWorker::DoReply));
395      }
396    }
397
398    if (canceled)
399      delete this;
400  }
401
402  const std::string name_;
403  const uint16 rrtype_;
404  const uint16 flags_;
405  MessageLoop* const origin_loop_;
406  DnsRRResolver* const dnsrr_resolver_;
407
408  base::Lock lock_;
409  bool canceled_;
410
411  int result_;
412  RRResponse response_;
413
414  DISALLOW_COPY_AND_ASSIGN(RRResolverWorker);
415};
416
417
418// A Buffer is used for walking over a DNS packet.
419class Buffer {
420 public:
421  Buffer(const uint8* p, unsigned len)
422      : p_(p),
423        packet_(p),
424        len_(len),
425        packet_len_(len) {
426  }
427
428  bool U8(uint8* v) {
429    if (len_ < 1)
430      return false;
431    *v = *p_;
432    p_++;
433    len_--;
434    return true;
435  }
436
437  bool U16(uint16* v) {
438    if (len_ < 2)
439      return false;
440    *v = static_cast<uint16>(p_[0]) << 8 |
441         static_cast<uint16>(p_[1]);
442    p_ += 2;
443    len_ -= 2;
444    return true;
445  }
446
447  bool U32(uint32* v) {
448    if (len_ < 4)
449      return false;
450    *v = static_cast<uint32>(p_[0]) << 24 |
451         static_cast<uint32>(p_[1]) << 16 |
452         static_cast<uint32>(p_[2]) << 8 |
453         static_cast<uint32>(p_[3]);
454    p_ += 4;
455    len_ -= 4;
456    return true;
457  }
458
459  bool Skip(unsigned n) {
460    if (len_ < n)
461      return false;
462    p_ += n;
463    len_ -= n;
464    return true;
465  }
466
467  bool Block(base::StringPiece* out, unsigned len) {
468    if (len_ < len)
469      return false;
470    *out = base::StringPiece(reinterpret_cast<const char*>(p_), len);
471    p_ += len;
472    len_ -= len;
473    return true;
474  }
475
476  // DNSName parses a (possibly compressed) DNS name from the packet. If |name|
477  // is not NULL, then the name is written into it. See RFC 1035 section 4.1.4.
478  bool DNSName(std::string* name) {
479    unsigned jumps = 0;
480    const uint8* p = p_;
481    unsigned len = len_;
482
483    if (name)
484      name->clear();
485
486    for (;;) {
487      if (len < 1)
488        return false;
489      uint8 d = *p;
490      p++;
491      len--;
492
493      // The two couple of bits of the length give the type of the length. It's
494      // either a direct length or a pointer to the remainder of the name.
495      if ((d & 0xc0) == 0xc0) {
496        // This limit matches the depth limit in djbdns.
497        if (jumps > 100)
498          return false;
499        if (len < 1)
500          return false;
501        uint16 offset = static_cast<uint16>(d) << 8 |
502                        static_cast<uint16>(p[0]);
503        offset &= 0x3ff;
504        p++;
505        len--;
506
507        if (jumps == 0) {
508          p_ = p;
509          len_ = len;
510        }
511        jumps++;
512
513        if (offset >= packet_len_)
514          return false;
515        p = &packet_[offset];
516        len = packet_len_ - offset;
517      } else if ((d & 0xc0) == 0) {
518        uint8 label_len = d;
519        if (len < label_len)
520          return false;
521        if (name && label_len) {
522          if (!name->empty())
523            name->append(".");
524          name->append(reinterpret_cast<const char*>(p), label_len);
525        }
526        p += label_len;
527        len -= label_len;
528
529        if (jumps == 0) {
530          p_ = p;
531          len_ = len;
532        }
533
534        if (label_len == 0)
535          break;
536      } else {
537        return false;
538      }
539    }
540
541    return true;
542  }
543
544 private:
545  const uint8* p_;
546  const uint8* const packet_;
547  unsigned len_;
548  const unsigned packet_len_;
549
550  DISALLOW_COPY_AND_ASSIGN(Buffer);
551};
552
553bool RRResponse::HasExpired(const base::Time current_time) const {
554  const base::TimeDelta delta(base::TimeDelta::FromSeconds(ttl));
555  const base::Time expiry = fetch_time + delta;
556  return current_time >= expiry;
557}
558
559bool RRResponse::ParseFromResponse(const uint8* p, unsigned len,
560                                   uint16 rrtype_requested) {
561#if defined(OS_POSIX) && !defined(ANDROID)
562  name.clear();
563  ttl = 0;
564  dnssec = false;
565  negative = false;
566  rrdatas.clear();
567  signatures.clear();
568
569  // RFC 1035 section 4.4.1
570  uint8 flags2;
571  Buffer buf(p, len);
572  if (!buf.Skip(2) ||  // skip id
573      !buf.Skip(1) ||  // skip first flags byte
574      !buf.U8(&flags2)) {
575    return false;
576  }
577
578  // Bit 5 is the Authenticated Data (AD) bit. See
579  // http://tools.ietf.org/html/rfc2535#section-6.1
580  if (flags2 & 32) {
581    // AD flag is set. We'll trust it if it came from a local nameserver.
582    // Currently the resolv structure is IPv4 only, so we can't test for IPv6
583    // loopback addresses.
584    if (_res.nscount == 1 &&
585        memcmp(&_res.nsaddr_list[0].sin_addr,
586               "\x7f\x00\x00\x01" /* 127.0.0.1 */, 4) == 0) {
587      dnssec = true;
588    }
589  }
590
591  uint16 query_count, answer_count, authority_count, additional_count;
592  if (!buf.U16(&query_count) ||
593      !buf.U16(&answer_count) ||
594      !buf.U16(&authority_count) ||
595      !buf.U16(&additional_count)) {
596    return false;
597  }
598
599  if (query_count != 1)
600    return false;
601
602  uint16 type, klass;
603  if (!buf.DNSName(NULL) ||
604      !buf.U16(&type) ||
605      !buf.U16(&klass) ||
606      type != rrtype_requested ||
607      klass != kClassIN) {
608    return false;
609  }
610
611  if (answer_count < 1)
612    return false;
613
614  for (uint32 i = 0; i < answer_count; i++) {
615    std::string* name = NULL;
616    if (i == 0)
617      name = &this->name;
618    uint32 ttl;
619    uint16 rrdata_len;
620    if (!buf.DNSName(name) ||
621        !buf.U16(&type) ||
622        !buf.U16(&klass) ||
623        !buf.U32(&ttl) ||
624        !buf.U16(&rrdata_len)) {
625      return false;
626    }
627
628    base::StringPiece rrdata;
629    if (!buf.Block(&rrdata, rrdata_len))
630      return false;
631
632    if (klass == kClassIN && type == rrtype_requested) {
633      if (i == 0)
634        this->ttl = ttl;
635      rrdatas.push_back(std::string(rrdata.data(), rrdata.size()));
636    } else if (klass == kClassIN && type == kDNS_RRSIG) {
637      signatures.push_back(std::string(rrdata.data(), rrdata.size()));
638    }
639  }
640#endif  // defined(OS_POSIX)
641
642  return true;
643}
644
645
646// An RRResolverJob is a one-to-one counterpart of an RRResolverWorker. It
647// lives only on the DnsRRResolver's origin message loop.
648class RRResolverJob {
649 public:
650  explicit RRResolverJob(RRResolverWorker* worker)
651      : worker_(worker) {
652  }
653
654  ~RRResolverJob() {
655    if (worker_) {
656      worker_->Cancel();
657      worker_ = NULL;
658      PostAll(ERR_ABORTED, NULL);
659    }
660  }
661
662  void AddHandle(RRResolverHandle* handle) {
663    handles_.push_back(handle);
664  }
665
666  void HandleResult(int result, const RRResponse& response) {
667    worker_ = NULL;
668    PostAll(result, &response);
669  }
670
671 private:
672  void PostAll(int result, const RRResponse* response) {
673    std::vector<RRResolverHandle*> handles;
674    handles_.swap(handles);
675
676    for (std::vector<RRResolverHandle*>::iterator
677         i = handles.begin(); i != handles.end(); i++) {
678      (*i)->Post(result, response);
679      // Post() causes the RRResolverHandle to delete itself.
680    }
681  }
682
683  std::vector<RRResolverHandle*> handles_;
684  RRResolverWorker* worker_;
685};
686
687
688DnsRRResolver::DnsRRResolver()
689    : requests_(0),
690      cache_hits_(0),
691      inflight_joins_(0),
692      in_destructor_(false) {
693}
694
695DnsRRResolver::~DnsRRResolver() {
696  DCHECK(!in_destructor_);
697  in_destructor_ = true;
698  STLDeleteValues(&inflight_);
699}
700
701intptr_t DnsRRResolver::Resolve(const std::string& name, uint16 rrtype,
702                                uint16 flags, CompletionCallback* callback,
703                                RRResponse* response,
704                                int priority /* ignored */,
705                                const BoundNetLog& netlog /* ignored */) {
706  DCHECK(CalledOnValidThread());
707  DCHECK(!in_destructor_);
708
709  if (!callback || !response || name.empty())
710    return kInvalidHandle;
711
712  // Don't allow queries of type ANY
713  if (rrtype == kDNS_ANY)
714    return kInvalidHandle;
715
716  requests_++;
717
718  const std::pair<std::string, uint16> key(make_pair(name, rrtype));
719  // First check the cache.
720  std::map<std::pair<std::string, uint16>, RRResponse>::iterator i;
721  i = cache_.find(key);
722  if (i != cache_.end()) {
723    if (!i->second.HasExpired(base::Time::Now())) {
724      int error;
725      if (i->second.negative) {
726        error = ERR_NAME_NOT_RESOLVED;
727      } else {
728        error = OK;
729        *response = i->second;
730      }
731      RRResolverHandle* handle = new RRResolverHandle(
732          callback, NULL /* no response pointer because we've already filled */
733                         /* it in */);
734      cache_hits_++;
735      // We need a typed NULL pointer in order to make the templates work out.
736      static const RRResponse* kNoResponse = NULL;
737      MessageLoop::current()->PostTask(
738          FROM_HERE, NewRunnableMethod(handle, &RRResolverHandle::Post, error,
739                                       kNoResponse));
740      return reinterpret_cast<intptr_t>(handle);
741    } else {
742      // entry has expired.
743      cache_.erase(i);
744    }
745  }
746
747  // No cache hit. See if a request is currently in flight.
748  RRResolverJob* job;
749  std::map<std::pair<std::string, uint16>, RRResolverJob*>::const_iterator j;
750  j = inflight_.find(key);
751  if (j != inflight_.end()) {
752    // The request is in flight already. We'll just attach our callback.
753    inflight_joins_++;
754    job = j->second;
755  } else {
756    // Need to make a new request.
757    RRResolverWorker* worker = new RRResolverWorker(name, rrtype, flags, this);
758    job = new RRResolverJob(worker);
759    inflight_.insert(make_pair(key, job));
760    if (!worker->Start()) {
761      inflight_.erase(key);
762      delete job;
763      delete worker;
764      return kInvalidHandle;
765    }
766  }
767
768  RRResolverHandle* handle = new RRResolverHandle(callback, response);
769  job->AddHandle(handle);
770  return reinterpret_cast<intptr_t>(handle);
771}
772
773void DnsRRResolver::CancelResolve(intptr_t h) {
774  DCHECK(CalledOnValidThread());
775  RRResolverHandle* handle = reinterpret_cast<RRResolverHandle*>(h);
776  handle->Cancel();
777}
778
779void DnsRRResolver::OnIPAddressChanged() {
780  DCHECK(CalledOnValidThread());
781  DCHECK(!in_destructor_);
782
783  std::map<std::pair<std::string, uint16>, RRResolverJob*> inflight;
784  inflight.swap(inflight_);
785  cache_.clear();
786
787  STLDeleteValues(&inflight);
788}
789
790// HandleResult is called on the origin message loop.
791void DnsRRResolver::HandleResult(const std::string& name, uint16 rrtype,
792                                 int result, const RRResponse& response) {
793  DCHECK(CalledOnValidThread());
794
795  const std::pair<std::string, uint16> key(std::make_pair(name, rrtype));
796
797  DCHECK_GE(kMaxCacheEntries, 1u);
798  DCHECK_LE(cache_.size(), kMaxCacheEntries);
799  if (cache_.size() == kMaxCacheEntries) {
800    // need to remove an element of the cache.
801    const base::Time current_time(base::Time::Now());
802    std::map<std::pair<std::string, uint16>, RRResponse>::iterator i, cur;
803    for (i = cache_.begin(); i != cache_.end(); ) {
804      cur = i++;
805      if (cur->second.HasExpired(current_time))
806        cache_.erase(cur);
807    }
808  }
809  if (cache_.size() == kMaxCacheEntries) {
810    // if we didn't clear out any expired entries, we just remove the first
811    // element. Crummy but simple.
812    cache_.erase(cache_.begin());
813  }
814
815  cache_.insert(std::make_pair(key, response));
816
817  std::map<std::pair<std::string, uint16>, RRResolverJob*>::iterator j;
818  j = inflight_.find(key);
819  if (j == inflight_.end()) {
820    NOTREACHED();
821    return;
822  }
823  RRResolverJob* job = j->second;
824  inflight_.erase(j);
825
826  job->HandleResult(result, response);
827  delete job;
828}
829
830}  // namespace net
831
832DISABLE_RUNNABLE_METHOD_REFCOUNT(net::RRResolverHandle);
833DISABLE_RUNNABLE_METHOD_REFCOUNT(net::RRResolverWorker);
834