CernVM-FS  2.13.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  int address_type, std::string *address) {
25  bool found = false;
26 
27  for (size_t i = 0u; i < address_list.size(); ++i) {
28  if (address_list[i].first == address_type) {
29  *address = address_list[i].second;
30  found = true;
31  break;
32  }
33  }
34  return found;
35 }
36 
37 } // namespace
38 
40  download::DownloadManager *download_manager,
41  download::DownloadManager *external_download_manager)
42  : download_manager_(download_manager)
43  , external_download_manager_(external_download_manager) { }
44 
46 
47 bool ResolvConfEventHandler::Handle(const std::string &file_path,
48  file_watcher::Event /*event*/,
49  bool *clear_handler) {
50  AddressList addresses;
51  GetDnsAddresses(file_path, &addresses);
52  if (!addresses.empty()) {
53  SetDnsAddress(download_manager_, addresses);
55  }
56  *clear_handler = false;
57  return true;
58 }
59 
66 void ResolvConfEventHandler::GetDnsAddresses(const std::string &resolv_file,
67  AddressList *addresses) {
68  bool done = false;
69  BackoffThrottle throttle(100, 1000, 5000);
70  while (!done) {
71  FILE *f = std::fopen(resolv_file.c_str(), "r");
72  if (!f) {
74  "ResolvConfEventHandler - Could not open: %s",
75  resolv_file.c_str());
76  throttle.Throttle();
77  continue;
78  }
79  std::string line;
80  while (GetLineFile(f, &line)) {
81  std::vector<std::string> key_val = SplitString(line, ' ');
82  if (key_val.size() == 2 && key_val[0] == "nameserver") {
83  // We have found a nameserver line
84  if (SplitString(key_val[1], '.').size() == 4) {
85  // This looks like an IPv4 address
86  addresses->push_back(std::make_pair(4, key_val[1]));
87  } else if (SplitString(key_val[1], ':').size() == 8) {
88  // This looks like an IPv6 address
89  addresses->push_back(std::make_pair(6, key_val[1]));
90  }
91  }
92  }
93  std::fclose(f);
94  done = true;
95  }
96 }
97 
99  download::DownloadManager *download_manager, const AddressList &addresses) {
100  // Default to IPv4 addresses unless kIpPreferV6 is specified
101  const int address_type = download_manager->opt_ip_preference()
103  ? 6
104  : 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 }
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:2108
void Throttle()
Definition: backoff.cc:48
bool GetLineFile(FILE *f, std::string *line)
Definition: string.cc:422
vector< string > SplitString(const string &str, char delim)
Definition: string.cc:306
dns::IpPreference opt_ip_preference() const
Definition: download.h:258
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:545