Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : * Copyright Contributors to the OpenSDN project
4 : */
5 :
6 : #include <cstdio>
7 : #include <iomanip>
8 : #include <assert.h>
9 : #include <errno.h>
10 : #include <sys/types.h>
11 : #include <dirent.h>
12 : #include "base/logging.h"
13 : #include <base/contrail_ports.h>
14 : #include <bind/bind_util.h>
15 : #include <cfg/dns_config.h>
16 : #include <mgr/dns_oper.h>
17 : #include "named_config.h"
18 : #include <cmn/dns.h>
19 :
20 : using namespace std;
21 :
22 : NamedConfig *NamedConfig::singleton_;
23 : const string NamedConfig::NamedZoneFileSuffix = "zone";
24 : const string NamedConfig::NamedZoneNSPrefix = "contrail-ns";
25 : const string NamedConfig::NamedZoneMXPrefix = "contrail-mx";
26 : const char NamedConfig::pid_file_name[] = "contrail-named.pid";
27 : const char NamedConfig::sessionkey_file_name[] = "session.key";
28 :
29 0 : void NamedConfig::Init(const std::string& named_config_dir,
30 : const std::string& named_config_file,
31 : const std::string& named_log_file,
32 : const std::string& rndc_config_file,
33 : const std::string& rndc_secret,
34 : const std::string& named_max_cache_size) {
35 0 : assert(singleton_ == NULL);
36 0 : singleton_ = new NamedConfig(named_config_dir, named_config_file,
37 : named_log_file, rndc_config_file, rndc_secret,
38 0 : named_max_cache_size);
39 0 : singleton_->Reset();
40 0 : }
41 :
42 15 : void NamedConfig::Shutdown() {
43 15 : assert(singleton_);
44 15 : delete singleton_;
45 15 : }
46 :
47 : // Reset bind config
48 15 : void NamedConfig::Reset() {
49 15 : reset_flag_ = true;
50 15 : CreateRndcConf();
51 15 : UpdateNamedConf();
52 15 : DIR *dir = opendir(named_config_dir_.c_str());
53 15 : if (dir) {
54 : struct dirent *file;
55 540 : while ((file = readdir(dir)) != NULL) {
56 525 : std::string str(named_config_dir_);
57 525 : str.append(file->d_name);
58 525 : if (str.find(".zone") != std::string::npos) {
59 0 : remove(str.c_str());
60 : }
61 525 : }
62 15 : closedir(dir);
63 : }
64 15 : reset_flag_ = false;
65 15 : }
66 :
67 11 : void NamedConfig::AddView(const VirtualDnsConfig *vdns) {
68 11 : UpdateNamedConf(vdns);
69 11 : if (!vdns->IsReverseResolutionEnabled()) {
70 4 : RemoveReverseZoneFiles(vdns);
71 : }
72 11 : }
73 :
74 8 : void NamedConfig::ChangeView(const VirtualDnsConfig *vdns) {
75 8 : UpdateNamedConf(vdns);
76 8 : if (!vdns->IsReverseResolutionEnabled()) {
77 4 : RemoveReverseZoneFiles(vdns);
78 : }
79 8 : std::string old_domain = vdns->GetOldDomainName();
80 8 : if (vdns->GetDomainName() != old_domain) {
81 0 : ZoneList zones;
82 0 : zones.push_back(old_domain);
83 0 : RemoveZoneFiles(vdns, zones);
84 0 : }
85 8 : }
86 :
87 11 : void NamedConfig::DelView(const VirtualDnsConfig *vdns) {
88 11 : UpdateNamedConf(vdns);
89 11 : RemoveReverseZoneFiles(vdns);
90 11 : }
91 :
92 0 : void NamedConfig::AddAllViews() {
93 0 : all_zone_files_ = true;
94 0 : UpdateNamedConf();
95 0 : all_zone_files_ = false;
96 0 : }
97 :
98 7 : void NamedConfig::AddZone(const Subnet &subnet, const VirtualDnsConfig *vdns) {
99 7 : if (!vdns->IsReverseResolutionEnabled()) {
100 0 : return;
101 : }
102 :
103 7 : ZoneList zones;
104 7 : subnet.GetReverseZones(zones);
105 : // Ignore zone files which already exist
106 25 : for (unsigned int i = 0; i < zones.size();) {
107 36 : std::ifstream file(GetZoneFilePath(vdns->GetViewName(),
108 36 : zones[i]).c_str());
109 18 : if (file.is_open()) {
110 4 : if (file.good()) {
111 4 : zones.erase(zones.begin() + i);
112 4 : file.close();
113 4 : continue;
114 : }
115 0 : file.close();
116 : }
117 14 : i++;
118 18 : }
119 7 : AddZoneFiles(zones, vdns);
120 7 : UpdateNamedConf();
121 7 : }
122 :
123 29 : void NamedConfig::DelZone(const Subnet &subnet, const VirtualDnsConfig *vdns) {
124 29 : UpdateNamedConf();
125 29 : ZoneList vdns_zones, snet_zones;
126 29 : MakeZoneList(vdns, vdns_zones);
127 29 : subnet.GetReverseZones(snet_zones);
128 : // Ignore zones which are still in use
129 87 : for (unsigned int i = 0; i < snet_zones.size();) {
130 : unsigned int j;
131 175 : for (j = 0; j < vdns_zones.size(); j++) {
132 121 : if (snet_zones[i] == vdns_zones[j]) {
133 4 : snet_zones.erase(snet_zones.begin() + i);
134 4 : break;
135 : }
136 : }
137 58 : if (j == vdns_zones.size())
138 54 : i++;
139 : }
140 29 : RemoveZoneFiles(vdns, snet_zones);
141 29 : }
142 :
143 0 : void NamedConfig::UpdateNamedConf(const VirtualDnsConfig *updated_vdns) {
144 0 : CreateNamedConf(updated_vdns);
145 0 : sync();
146 :
147 0 : ifstream pyscript("/etc/contrail/dns/applynamedconfig.py");
148 0 : if (!pyscript.good()) {
149 0 : std::stringstream str;
150 0 : str << "/usr/bin/contrail-rndc -c " << rndc_config_file_ << " -p ";
151 0 : str << ContrailPorts::DnsRndc();
152 0 : str << " reconfig";
153 0 : int res = system(str.str().c_str());
154 0 : if (res) {
155 0 : LOG(WARN, "/usr/bin/contrail-rndc command failed");
156 : }
157 0 : } else {
158 0 : std::stringstream str;
159 : // execute the helper script to apply named config
160 0 : str << "python3 /etc/contrail/dns/applynamedconfig.py";
161 0 : int res = system(str.str().c_str());
162 0 : if (res) {
163 0 : LOG(ERROR, "Applying named configuration failed");
164 : }
165 0 : }
166 0 : }
167 :
168 81 : void NamedConfig::CreateNamedConf(const VirtualDnsConfig *updated_vdns) {
169 81 : GetDefaultForwarders();
170 81 : file_.open(named_config_file_.c_str());
171 :
172 81 : WriteOptionsConfig();
173 81 : WriteRndcConfig();
174 81 : WriteLoggingConfig();
175 81 : WriteViewConfig(updated_vdns);
176 :
177 81 : file_.flush();
178 81 : file_.close();
179 81 : }
180 :
181 15 : void NamedConfig::CreateRndcConf() {
182 15 : file_.open(rndc_config_file_.c_str());
183 :
184 15 : file_ << "key \"rndc-key\" {" << endl;
185 15 : file_ << " algorithm hmac-md5;" << endl;
186 15 : file_ << " secret \"" << rndc_secret_ << "\";" << endl;
187 15 : file_ << "};" << endl << endl;
188 :
189 15 : file_ << "options {" << endl;
190 15 : file_ << " default-key \"rndc-key\";" << endl;
191 15 : file_ << " default-server 127.0.0.1;" << endl;
192 15 : file_ << " default-port " << ContrailPorts::DnsRndc() << ";" << endl;
193 15 : file_ << "};" << endl << endl;
194 :
195 15 : file_.flush();
196 15 : file_.close();
197 15 : }
198 :
199 81 : void NamedConfig::WriteOptionsConfig() {
200 81 : file_ << "options {" << endl;
201 81 : file_ << " directory \"" << named_config_dir_ << "\";" << endl;
202 81 : file_ << " managed-keys-directory \"" << named_config_dir_ << "\";" << endl;
203 81 : file_ << " empty-zones-enable no;" << endl;
204 81 : file_ << " pid-file \"" << GetPidFilePath() << "\";" << endl;
205 81 : file_ << " session-keyfile \"" << GetSessionKeyFilePath() << "\";" << endl;
206 81 : file_ << " listen-on port " << Dns::GetDnsPort() << " { any; };" << endl;
207 81 : file_ << " allow-query { any; };" << endl;
208 81 : file_ << " allow-recursion { any; };" << endl;
209 81 : file_ << " allow-query-cache { any; };" << endl;
210 81 : if (!named_max_cache_size_.empty())
211 81 : file_ << " max-cache-size " << named_max_cache_size_ << ";" << endl;
212 81 : file_ << "};" << endl << endl;
213 81 : }
214 :
215 81 : void NamedConfig::WriteRndcConfig() {
216 81 : file_ << "key \"rndc-key\" {" << endl;
217 81 : file_ << " algorithm hmac-md5;" << endl;
218 81 : file_ << " secret \"" << rndc_secret_ << "\";" << endl;
219 81 : file_ << "};" << endl << endl;
220 :
221 :
222 81 : file_ << "controls {" << endl;
223 81 : file_ << " inet 127.0.0.1 port "<< ContrailPorts::DnsRndc() << endl;
224 81 : file_ << " allow { 127.0.0.1; } keys { \"rndc-key\"; };" << endl;
225 81 : file_ << "};" << endl << endl;
226 81 : }
227 :
228 81 : void NamedConfig::WriteLoggingConfig() {
229 81 : file_ << "logging {" << endl;
230 81 : file_ << " channel debug_log {" << endl;
231 81 : file_ << " file \"" << named_log_file_ << "\" versions 3 size 5m;" << endl;
232 81 : file_ << " severity debug;" << endl;
233 81 : file_ << " print-time yes;" << endl;
234 81 : file_ << " print-severity yes;" << endl;
235 81 : file_ << " print-category yes;" << endl;
236 81 : file_ << " };" << endl;
237 81 : file_ << " category default {" << endl;
238 81 : file_ << " debug_log;" << endl;
239 81 : file_ << " };" << endl;
240 81 : file_ << " category queries {" << endl;
241 81 : file_ << " debug_log;" << endl;
242 81 : file_ << " };" << endl;
243 81 : file_ << "};" << endl << endl;
244 81 : }
245 :
246 81 : void NamedConfig::WriteViewConfig(const VirtualDnsConfig *updated_vdns) {
247 81 : ZoneViewMap zone_view_map;
248 81 : if (reset_flag_) {
249 15 : WriteDefaultView(zone_view_map);
250 15 : return;
251 : }
252 :
253 66 : VirtualDnsConfig::DataMap vdns = VirtualDnsConfig::GetVirtualDnsMap();
254 276 : for (VirtualDnsConfig::DataMap::iterator it = vdns.begin(); it != vdns.end(); ++it) {
255 210 : VirtualDnsConfig *curr_vdns = it->second;
256 210 : ZoneList zones;
257 210 : MakeZoneList(curr_vdns, zones);
258 :
259 210 : if (curr_vdns->IsDeleted() || !curr_vdns->IsNotified()) {
260 17 : RemoveZoneFiles(curr_vdns, zones);
261 17 : continue;
262 : }
263 :
264 193 : std::string view_name = curr_vdns->GetViewName();
265 193 : file_ << "view \"" << view_name << "\" {" << endl;
266 :
267 193 : std::string order = curr_vdns->GetRecordOrder();
268 193 : if (!order.empty()) {
269 193 : if (order == "round-robin")
270 46 : order = "cyclic";
271 193 : file_ << " rrset-order {order " << order << ";};" << endl;
272 : }
273 :
274 193 : std::string next_dns = curr_vdns->GetNextDns();
275 193 : if (!next_dns.empty()) {
276 191 : boost::system::error_code ec;
277 : boost::asio::ip::address_v4
278 191 : next_addr(boost::asio::ip::address_v4::from_string(next_dns, ec));
279 191 : if (!ec.value()) {
280 0 : file_ << " forwarders {" << next_addr.to_string() << ";};" << endl;
281 : } else {
282 191 : file_ << " virtual-forwarder \"" << next_dns << "\";" << endl;
283 : }
284 2 : } else if (!default_forwarders_.empty()) {
285 0 : file_ << " forwarders {" << default_forwarders_ << "};" << endl;
286 : }
287 :
288 193 : bool reverse_resolution = curr_vdns->IsReverseResolutionEnabled();
289 620 : for (unsigned int i = 0; i < zones.size(); i++) {
290 427 : WriteZone(view_name, zones[i], true, reverse_resolution, next_dns);
291 : // update the zone view map, to be used to generate default view
292 427 : if (curr_vdns->IsExternalVisible())
293 347 : zone_view_map.insert(ZoneViewPair(zones[i], view_name));
294 :
295 : }
296 :
297 193 : file_ << "};" << endl << endl;
298 :
299 193 : if (curr_vdns == updated_vdns || all_zone_files_)
300 19 : AddZoneFiles(zones, curr_vdns);
301 210 : }
302 :
303 66 : WriteDefaultView(zone_view_map);
304 81 : }
305 :
306 81 : void NamedConfig::WriteDefaultView(ZoneViewMap &zone_view_map) {
307 : // Create a default view first for any requests which do not have
308 : // view name TXT record
309 81 : file_ << "view \"_default_view_\" {" << endl;
310 81 : file_ << " match-clients {any;};" << endl;
311 81 : file_ << " match-destinations {any;};" << endl;
312 81 : file_ << " match-recursive-only no;" << endl;
313 81 : if (!default_forwarders_.empty()) {
314 0 : file_ << " forwarders {" << default_forwarders_ << "};" << endl;
315 : }
316 81 : for (ZoneViewMap::iterator it = zone_view_map.begin();
317 428 : it != zone_view_map.end(); ++it) {
318 347 : WriteZone(it->second, it->first, false, false, "");
319 : }
320 81 : file_ << "};" << endl << endl;
321 81 : }
322 :
323 774 : void NamedConfig::WriteZone(const string &vdns, const string &name,
324 : bool is_master, bool is_rr, const string &next_dns) {
325 774 : file_ << " zone \"" << name << "\" IN {" << endl;
326 774 : if (is_master) {
327 427 : file_ << " type master;" << endl;
328 427 : file_ << " file \"" << GetZoneFilePath(vdns, name) << "\";" << endl;
329 427 : file_ << " allow-update {127.0.0.1;};" << endl;
330 427 : if (!next_dns.empty()) {
331 424 : if (!is_rr && BindUtil::IsReverseZone(name)) {
332 0 : file_ << " forwarders { };" << endl;
333 : }
334 : } else {
335 3 : file_ << " forwarders { };" << endl;
336 : }
337 : } else {
338 347 : file_ << " type static-stub;" << endl;
339 347 : file_ << " virtual-server-name \"" << vdns << "\";" << endl;
340 347 : file_ << " server-addresses {127.0.0.1;};" << endl;
341 : }
342 774 : file_ << " };" << endl;
343 774 : }
344 :
345 26 : void NamedConfig::AddZoneFiles(ZoneList &zones, const VirtualDnsConfig *vdns) {
346 89 : for (unsigned int i = 0; i < zones.size(); i++) {
347 63 : CreateZoneFile(zones[i], vdns, !BindUtil::IsReverseZone(zones[i]));
348 : }
349 26 : }
350 :
351 65 : void NamedConfig::RemoveZoneFiles(const VirtualDnsConfig *vdns,
352 : ZoneList &zones) {
353 162 : for (unsigned int i = 0; i < zones.size(); i++) {
354 97 : RemoveZoneFile(vdns, zones[i]);
355 : }
356 65 : }
357 :
358 19 : void NamedConfig::RemoveReverseZoneFiles(const VirtualDnsConfig *vdns) {
359 19 : ZoneList zones;
360 19 : MakeReverseZoneList(vdns, zones);
361 19 : RemoveZoneFiles(vdns, zones);
362 19 : }
363 :
364 97 : void NamedConfig::RemoveZoneFile(const VirtualDnsConfig *vdns, string &zone) {
365 97 : string zfile_name = GetZoneFilePath(vdns->GetViewName(), zone);
366 97 : remove(zfile_name.c_str());
367 97 : zfile_name.append(".jnl");
368 97 : remove(zfile_name.c_str());
369 97 : }
370 :
371 0 : string NamedConfig::GetZoneFileName(const string &vdns, const string &name) {
372 0 : if (name.size() && name.at(name.size() - 1) == '.')
373 0 : return (vdns + "." + name + NamedZoneFileSuffix);
374 : else
375 0 : return (vdns + "." + name + "." + NamedZoneFileSuffix);
376 : }
377 :
378 0 : string NamedConfig::GetZoneFilePath(const string &vdns, const string &name) {
379 0 : return (named_config_dir_ + GetZoneFileName(vdns, name));
380 : }
381 :
382 81 : string NamedConfig::GetPidFilePath() {
383 81 : return (named_config_dir_ + pid_file_name);
384 : }
385 :
386 81 : string NamedConfig::GetSessionKeyFilePath() {
387 81 : return (named_config_dir_ + sessionkey_file_name);
388 : }
389 :
390 126 : string NamedConfig::GetZoneNSName(const string domain_name) {
391 252 : return (NamedZoneNSPrefix + "." + domain_name);
392 : }
393 :
394 63 : string NamedConfig::GetZoneMXName(const string domain_name) {
395 126 : return (NamedZoneMXPrefix + "." + domain_name);
396 : }
397 :
398 63 : void NamedConfig::CreateZoneFile(std::string &zone_name,
399 : const VirtualDnsConfig *vdns, bool ns) {
400 63 : ofstream zfile;
401 63 : string ns_name;
402 63 : string zone_filename = GetZoneFilePath(vdns->GetViewName(), zone_name);
403 :
404 63 : zfile.open(zone_filename.c_str());
405 63 : zfile << "$ORIGIN ." << endl;
406 63 : if (vdns->GetTtl() > 0) {
407 63 : zfile << "$TTL " << vdns->GetTtl() << endl;
408 : } else {
409 0 : zfile << "$TTL " << Defaults::GlobalTTL << endl;
410 : }
411 63 : zfile << left << setw(NameWidth) << zone_name << " IN SOA " <<
412 126 : GetZoneNSName(vdns->GetDomainName()) << " " <<
413 126 : GetZoneMXName(vdns->GetDomainName()) << " (" << endl;
414 63 : zfile << setw(NameWidth + 8) << "" << setw(NumberWidth) << Defaults::Serial << endl;
415 63 : zfile << setw(NameWidth + 8) << "" << setw(NumberWidth) << Defaults::Refresh << endl;
416 63 : zfile << setw(NameWidth + 8) << "" << setw(NumberWidth) << Defaults::Retry << endl;
417 63 : zfile << setw(NameWidth + 8) << "" << setw(NumberWidth) << Defaults::Expire << endl;
418 63 : if (vdns->GetNegativeCacheTtl() > 0 ) {
419 2 : zfile << setw(NameWidth + 8) << "" << setw(NumberWidth) << vdns->GetNegativeCacheTtl() << endl;
420 : } else {
421 61 : zfile << setw(NameWidth + 8) << "" << setw(NumberWidth) << Defaults::Minimum << endl;
422 : }
423 63 : zfile << setw(NameWidth + 8) << "" << ")" << endl;
424 : /* NS records are mandatory in zone file. They are required for the following reasons
425 : 1. Name servers returns NS RR in responses to queries, in the authority section
426 : of the DNS message.
427 : 2. Name servers use the NS records to determine where to send NOTIFY messages.
428 : */
429 : zfile << setw(NameWidth + 4) << "" << setw(TypeWidth) << " NS " <<
430 63 : setw(NameWidth) << GetZoneNSName(vdns->GetDomainName()) << endl;
431 63 : zfile << "$ORIGIN " << zone_name << endl;
432 : //Write the NS record
433 63 : if (ns)
434 19 : zfile << setw(NameWidth) << NamedZoneNSPrefix << " IN A " << Dns::GetSelfIp() << endl;
435 63 : zfile.flush();
436 63 : zfile.close();
437 63 : }
438 :
439 : // Create a list of zones for the virtual DNS
440 239 : void NamedConfig::MakeZoneList(const VirtualDnsConfig *vdns_config,
441 : ZoneList &zones) {
442 : // always take domain name in lower case, to avoid differences due to case
443 478 : std::string dns_domain = boost::to_lower_copy(vdns_config->GetDomainName());
444 239 : if (dns_domain.empty()) {
445 0 : return;
446 : }
447 :
448 : // Forward Zone
449 239 : zones.push_back(dns_domain);
450 :
451 : // Reverse zones are part of a view only when reverse resolution is enabled.
452 239 : if (vdns_config->IsReverseResolutionEnabled()) {
453 140 : MakeReverseZoneList(vdns_config, zones);
454 : }
455 239 : }
456 :
457 159 : void NamedConfig::MakeReverseZoneList(const VirtualDnsConfig *vdns_config,
458 : ZoneList &zones) {
459 159 : const VirtualDnsConfig::IpamList &ipams = vdns_config->GetIpamList();
460 159 : for (VirtualDnsConfig::IpamList::const_iterator ipam_it = ipams.begin();
461 262 : ipam_it != ipams.end(); ++ipam_it) {
462 103 : if ((*ipam_it)->IsDeleted() || !(*ipam_it)->IsValid()) {
463 18 : continue;
464 : }
465 85 : const IpamConfig::VnniList &vnni_list = (*ipam_it)->GetVnniList();
466 85 : for (IpamConfig::VnniList::iterator vnni_it = vnni_list.begin();
467 215 : vnni_it != vnni_list.end(); ++vnni_it) {
468 130 : if ((*vnni_it)->IsDeleted() || !(*vnni_it)->IsValid()) {
469 12 : continue;
470 : }
471 118 : const Subnets &subnets = (*vnni_it)->GetSubnets();
472 277 : for (unsigned int i = 0; i < subnets.size(); ++i) {
473 159 : const Subnet &subnet = subnets[i];
474 159 : if (subnet.IsDeleted())
475 0 : continue;
476 159 : subnet.GetReverseZones(zones);
477 : }
478 : }
479 : }
480 :
481 : // If same subnet is used in different VNs, remove duplicates
482 159 : std::sort(zones.begin(), zones.end());
483 159 : ZoneList::iterator it = std::unique(zones.begin(), zones.end());
484 159 : zones.resize(std::distance(zones.begin(), it));
485 159 : }
486 :
487 81 : void NamedConfig::GetDefaultForwarders() {
488 81 : default_forwarders_.clear();
489 81 : std::ifstream fd;
490 81 : fd.open(GetResolveFile().c_str());
491 81 : if (!fd.is_open()) {
492 81 : return;
493 : }
494 :
495 0 : std::string line;
496 0 : while (getline(fd, line)) {
497 0 : std::size_t pos = line.find_first_of("#");
498 0 : std::stringstream ss(line.substr(0, pos));
499 0 : std::string key;
500 0 : ss >> key;
501 0 : if (key == "nameserver") {
502 0 : std::string ip;
503 0 : ss >> ip;
504 0 : boost::system::error_code ec;
505 0 : boost::asio::ip::address_v4::from_string(ip, ec);
506 0 : if (!ec.value()) {
507 0 : default_forwarders_ += ip + "; ";
508 : }
509 0 : }
510 0 : }
511 :
512 0 : fd.close();
513 81 : }
514 :
515 : ///////////////////////////////////////////////////////////////////////////////
516 :
517 15 : BindStatus::BindStatus(BindEventHandler handler)
518 15 : : named_pid_(-1), handler_(handler), change_timeout_(true) {
519 30 : status_timer_ = TimerManager::CreateTimer(
520 15 : *Dns::GetEventManager()->io_service(), "BindStatusTimer",
521 : TaskScheduler::GetInstance()->GetTaskId("dns::BindStatus"), 0);
522 15 : status_timer_->Start(kInitTimeout,
523 : boost::bind(&BindStatus::CheckBindStatus, this));
524 15 : }
525 :
526 15 : BindStatus::~BindStatus() {
527 15 : status_timer_->Cancel();
528 15 : TimerManager::DeleteTimer(status_timer_);
529 15 : }
530 :
531 : // Check if a given pid belongs to contrail-named
532 0 : bool BindStatus::IsBindPid(uint32_t pid) {
533 0 : bool ret = false;
534 0 : std::stringstream str;
535 0 : str << "/proc/" << pid << "/cmdline";
536 :
537 0 : ifstream ifile(str.str().c_str());
538 0 : if (ifile.is_open()) {
539 0 : if (ifile.good()) {
540 0 : std::string cmdline;
541 0 : cmdline.assign((istreambuf_iterator<char>(ifile)),
542 : istreambuf_iterator<char>());
543 0 : istringstream cmdstream(cmdline);
544 0 : if (cmdstream.str().find("/usr/bin/contrail-named") !=
545 : std::string::npos) {
546 0 : ret = true;
547 : }
548 0 : }
549 0 : ifile.close();
550 : }
551 :
552 0 : return ret;
553 0 : }
554 :
555 0 : bool BindStatus::CheckBindStatus() {
556 0 : uint32_t new_pid = -1;
557 0 : NamedConfig *ncfg = NamedConfig::GetNamedConfigObject();
558 0 : if (ncfg) {
559 0 : std::ifstream pid_file(ncfg->GetPidFilePath().c_str());
560 0 : if (pid_file.is_open()) {
561 0 : if (pid_file.good()) {
562 0 : pid_file >> new_pid;
563 : }
564 0 : pid_file.close();
565 : }
566 0 : }
567 :
568 0 : if (new_pid == (uint32_t) -1) {
569 0 : handler_(Down);
570 0 : } else if (!IsBindPid(new_pid)) {
571 0 : if (named_pid_ != (uint32_t) -1) {
572 0 : named_pid_ = -1;
573 0 : handler_(Down);
574 : }
575 : } else {
576 0 : if (named_pid_ != new_pid) {
577 0 : named_pid_ = new_pid;
578 0 : handler_(Up);
579 : }
580 : }
581 :
582 0 : if (change_timeout_) {
583 0 : change_timeout_ = false;
584 0 : status_timer_->Reschedule(kBindStatusTimeout);
585 : }
586 0 : return true;
587 : }
|