GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/resolv_conf_event_handler.cc
Date: 2024-04-28 02:33:07
Exec Total Coverage
Lines: 19 49 38.8%
Branches: 26 64 40.6%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #include "resolv_conf_event_handler.h"
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
16 /**
17 * Get the first address of type address_type from the list of addresses
18 *
19 * @param address_list List of IP addresses
20 * @param address_type Type of IP address desired; Can be either 4 or 6
21 * @param address (out) The first address found
22 */
23 bool GetFirstAddress(
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
40 ResolvConfEventHandler::ResolvConfEventHandler(
41 download::DownloadManager* download_manager,
42 download::DownloadManager* external_download_manager)
43 : download_manager_(download_manager),
44 external_download_manager_(external_download_manager) {}
45
46 ResolvConfEventHandler::~ResolvConfEventHandler() {}
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);
55 SetDnsAddress(external_download_manager_, addresses);
56 }
57 *clear_handler = false;
58 return true;
59 }
60
61 /**
62 * Returns any nameserver IP addresses from file
63 *
64 * Reads a file, line by line. Returns the IP addresses corresponding
65 * to nameservers (i.e. from lines "nameserver <IP_ADDRESS>")
66 */
67 4 void ResolvConfEventHandler::GetDnsAddresses(
68 const std::string& resolv_file, AddressList* addresses) {
69 4 bool done = false;
70
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 BackoffThrottle throttle(100, 1000, 5000);
71
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 while (!done) {
72
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 FILE* f = std::fopen(resolv_file.c_str(), "r");
73
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!f) {
74 LogCvmfs(kLogCvmfs, kLogDebug,
75 "ResolvConfEventHandler - Could not open: %s",
76 resolv_file.c_str());
77 throttle.Throttle();
78 continue;
79 }
80 4 std::string line;
81
3/4
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
✓ Branch 4 taken 4 times.
15 while (GetLineFile(f, &line)) {
82
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 std::vector<std::string> key_val = SplitString(line, ' ');
83
6/6
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 1 times.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 7 times.
✓ Branch 8 taken 4 times.
11 if (key_val.size() == 2 && key_val[0] == "nameserver") {
84 // We have found a nameserver line
85
3/4
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 4 times.
7 if (SplitString(key_val[1], '.').size() == 4) {
86 // This looks like an IPv4 address
87
2/4
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
3 addresses->push_back(std::make_pair(4, key_val[1]));
88
3/4
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 2 times.
4 } else if (SplitString(key_val[1], ':').size() == 8) {
89 // This looks like an IPv6 address
90
2/4
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
2 addresses->push_back(std::make_pair(6, key_val[1]));
91 }
92 }
93 11 }
94
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 std::fclose(f);
95 4 done = true;
96 4 }
97 4 }
98
99 void ResolvConfEventHandler::SetDnsAddress(
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)) {
108 LogCvmfs(kLogCvmfs, kLogDebug,
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
116