LCOV - code coverage report
Current view: top level - dns/bind - named_config.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 275 383 71.8 %
Date: 2026-06-08 02:02:55 Functions: 28 36 77.8 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14