CernVM-FS  2.12.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
resolv_conf_event_handler.cc
Go to the documentation of this file.
1 
6 
7 #include <string>
8 #include <vector>
9 
10 #include "backoff.h"
11 #include "util/logging.h"
12 #include "util/string.h"
13 
14 namespace {
15 
24  const ResolvConfEventHandler::AddressList& address_list,
25  int address_type, std::string* address) {
26  bool found = false;
27 
28  for (size_t i = 0u; i < address_list.size(); ++i) {
29  if (address_list[i].first == address_type) {
30  *address = address_list[i].second;
31  found = true;
32  break;
33  }
34  }
35  return found;
36 }
37 
38 } // namespace
39 
41  download::DownloadManager* download_manager,
42  download::DownloadManager* external_download_manager)
43  : download_manager_(download_manager),
44  external_download_manager_(external_download_manager) {}
45 
47 
48 bool ResolvConfEventHandler::Handle(const std::string& file_path,
49  file_watcher::Event /*event*/,
50  bool* clear_handler) {
51  AddressList addresses;
52  GetDnsAddresses(file_path, &addresses);
53  if (!addresses.empty()) {
54  SetDnsAddress(download_manager_, addresses);
56  }
57  *clear_handler = false;
58  return true;
59 }
60 
68  const std::string& resolv_file, AddressList* addresses) {
69  bool done = false;
70  BackoffThrottle throttle(100, 1000, 5000);
71  while (!done) {
72  FILE* f = std::fopen(resolv_file.c_str(), "r");
73  if (!f) {
75  "ResolvConfEventHandler - Could not open: %s",
76  resolv_file.c_str());
77  throttle.Throttle();
78  continue;
79  }
80  std::string line;
81  while (GetLineFile(f, &line)) {
82  std::vector<std::string> key_val = SplitString(line, ' ');
83  if (key_val.size() == 2 && key_val[0] == "nameserver") {
84  // We have found a nameserver line
85  if (SplitString(key_val[1], '.').size() == 4) {
86  // This looks like an IPv4 address
87  addresses->push_back(std::make_pair(4, key_val[1]));
88  } else if (SplitString(key_val[1], ':').size() == 8) {
89  // This looks like an IPv6 address
90  addresses->push_back(std::make_pair(6, key_val[1]));
91  }
92  }
93  }
94  std::fclose(f);
95  done = true;
96  }
97 }
98 
100  download::DownloadManager* download_manager,
101  const AddressList& addresses) {
102  // Default to IPv4 addresses unless kIpPreferV6 is specified
103  const int address_type =
104  download_manager->opt_ip_preference() == dns::kIpPreferV6 ? 6 : 4;
105 
106  std::string new_address;
107  if (GetFirstAddress(addresses, address_type, &new_address)) {
109  "ResolvConfEventhandler - resolv.conf file changed. "
110  "Setting new DNS address: %s",
111  new_address.c_str());
112  download_manager->SetDnsServer(new_address);
113  }
114 }
115 
ResolvConfEventHandler(download::DownloadManager *download_manager, download::DownloadManager *external_download_manager)
static void SetDnsAddress(download::DownloadManager *download_manager, const AddressList &addresses)
download::DownloadManager * external_download_manager_
download::DownloadManager * download_manager_
void SetDnsServer(const std::string &address)
Definition: download.cc:1985
void Throttle()
Definition: backoff.cc:50
bool GetLineFile(FILE *f, std::string *line)
Definition: string.cc:386
vector< string > SplitString(const string &str, char delim)
Definition: string.cc:290
dns::IpPreference opt_ip_preference() const
Definition: download.h:226
bool GetFirstAddress(const ResolvConfEventHandler::AddressList &address_list, int address_type, std::string *address)
static void GetDnsAddresses(const std::string &resolv_file, AddressList *addresses)
std::vector< std::pair< int, std::string > > AddressList
virtual bool Handle(const std::string &file_path, file_watcher::Event event, bool *clear_handler)
static void size_t size
Definition: smalloc.h:54
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)
Definition: logging.cc:528