// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/base/dns_reloader.h"

#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) && \
    !defined(OS_ANDROID) && !defined(__LB_SHELL__)

#include <resolv.h>

#include "base/basictypes.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_local_storage.h"
#include "net/base/network_change_notifier.h"

namespace {

// On Linux/BSD, changes to /etc/resolv.conf can go unnoticed thus resulting
// in DNS queries failing either because nameservers are unknown on startup
// or because nameserver info has changed as a result of e.g. connecting to
// a new network. Some distributions patch glibc to stat /etc/resolv.conf
// to try to automatically detect such changes but these patches are not
// universal and even patched systems such as Jaunty appear to need calls
// to res_ninit to reload the nameserver information in different threads.
//
// To fix this, on systems with FilePathWatcher support, we use
// NetworkChangeNotifier::DNSObserver to monitor /etc/resolv.conf to
// enable us to respond to DNS changes and reload the resolver state.
//
// OpenBSD does not have thread-safe res_ninit/res_nclose so we can't do
// the same trick there and most *BSD's don't yet have support for
// FilePathWatcher (but perhaps the new kqueue mac code just needs to be
// ported to *BSD to support that).
//
// Android does not have /etc/resolv.conf. The system takes care of nameserver
// changes, so none of this is needed.

class DnsReloader : public net::NetworkChangeNotifier::DNSObserver {
 public:
  struct ReloadState {
    int resolver_generation;
  };

  // NetworkChangeNotifier::DNSObserver:
  virtual void OnDNSChanged() override {
    DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_IO);
    base::AutoLock l(lock_);
    resolver_generation_++;
  }

  void MaybeReload() {
    ReloadState* reload_state = static_cast<ReloadState*>(tls_index_.Get());
    base::AutoLock l(lock_);

    if (!reload_state) {
      reload_state = new ReloadState();
      reload_state->resolver_generation = resolver_generation_;
      res_ninit(&_res);
      tls_index_.Set(reload_state);
    } else if (reload_state->resolver_generation != resolver_generation_) {
      reload_state->resolver_generation = resolver_generation_;
      // It is safe to call res_nclose here since we know res_ninit will have
      // been called above.
      res_nclose(&_res);
      res_ninit(&_res);
    }
  }

  // Free the allocated state.
  static void SlotReturnFunction(void* data) {
    ReloadState* reload_state = static_cast<ReloadState*>(data);
    if (reload_state)
      res_nclose(&_res);
    delete reload_state;
  }

 private:
  DnsReloader() : resolver_generation_(0) {
    tls_index_.Initialize(SlotReturnFunction);
    net::NetworkChangeNotifier::AddDNSObserver(this);
  }

  virtual ~DnsReloader() {
    NOTREACHED();  // LeakyLazyInstance is not destructed.
  }

  base::Lock lock_;  // Protects resolver_generation_.
  int resolver_generation_;
  friend struct base::DefaultLazyInstanceTraits<DnsReloader>;

  // We use thread local storage to identify which ReloadState to interact with.
  static base::ThreadLocalStorage::StaticSlot tls_index_;

  DISALLOW_COPY_AND_ASSIGN(DnsReloader);
};

// A TLS slot to the ReloadState for the current thread.
// static
base::ThreadLocalStorage::StaticSlot DnsReloader::tls_index_ = TLS_INITIALIZER;

base::LazyInstance<DnsReloader>::Leaky
    g_dns_reloader = LAZY_INSTANCE_INITIALIZER;

}  // namespace

namespace net {

void EnsureDnsReloaderInit() {
  DnsReloader* t ALLOW_UNUSED = g_dns_reloader.Pointer();
}

void DnsReloaderMaybeReload() {
  // This routine can be called by any of the DNS worker threads.
  DnsReloader* dns_reloader = g_dns_reloader.Pointer();
  dns_reloader->MaybeReload();
}

}  // namespace net

#endif  // defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) &&
        // !defined(OS_ANDROID) && !defined(__LB_SHELL__)
