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: 291 397 73.3 %
Date: 2026-11-09 02:10:49 Functions: 29 37 78.4 %
Legend: Lines: hit not hit

          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             : }

Generated by: LCOV version 1.14