// 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)

#include <resolv.h>

#include "base/basictypes.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/message_loop/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(base::MessageLoopForIO::IsCurrent());
    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)
