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     assert(singleton_ == NULL);
 
   35     singleton_ = 
new NamedConfig(named_config_dir, named_config_file,
 
   36                                  named_log_file, rndc_config_file, rndc_secret,
 
   37                                  named_max_cache_size);
 
   51     DIR *dir = opendir(named_config_dir_.c_str());
 
   54         while ((file = readdir(dir)) != NULL) {
 
   55             std::string str(named_config_dir_);
 
   56             str.append(file->d_name);
 
   57             if (str.find(
".zone") != std::string::npos) {
 
   67     UpdateNamedConf(vdns);
 
   71     UpdateNamedConf(vdns);
 
   75         zones.push_back(old_domain);
 
   76         RemoveZoneFiles(vdns, zones);
 
   81     UpdateNamedConf(vdns);
 
   85     all_zone_files_ = 
true;
 
   87     all_zone_files_ = 
false;
 
   94     for (
unsigned int i = 0; i < zones.size();) {
 
   95         std::ifstream file(zones[i].c_str());
 
   98                 zones.erase(zones.begin() + i);
 
  106     AddZoneFiles(zones, vdns);
 
  113     MakeZoneList(vdns, vdns_zones);
 
  116     for (
unsigned int i = 0; i < snet_zones.size();) {
 
  118         for (j = 0; j < vdns_zones.size(); j++) {
 
  119             if (snet_zones[i] == vdns_zones[j]) {
 
  120                 snet_zones.erase(snet_zones.begin() + i);
 
  124         if (j == vdns_zones.size())
 
  127     RemoveZoneFiles(vdns, snet_zones);
 
  131     CreateNamedConf(updated_vdns);
 
  134     ifstream pyscript(
"/etc/contrail/dns/applynamedconfig.py");
 
  135     if (!pyscript.good()) {
 
  136         std::stringstream str;
 
  137         str << 
"/usr/bin/contrail-rndc -c " << rndc_config_file_ << 
" -p ";
 
  140         int res = system(str.str().c_str());
 
  142             LOG(WARN, 
"/usr/bin/contrail-rndc command failed");
 
  145         std::stringstream str;
 
  147         str << 
"python3 /etc/contrail/dns/applynamedconfig.py";
 
  148         int res = system(str.str().c_str());
 
  150             LOG(ERROR, 
"Applying named configuration failed");
 
  156      GetDefaultForwarders();
 
  157      file_.open(named_config_file_.c_str());
 
  159      WriteOptionsConfig();
 
  161      WriteLoggingConfig();
 
  162      WriteViewConfig(updated_vdns);
 
  169      file_.open(rndc_config_file_.c_str());
 
  171      file_ << 
"key \"rndc-key\" {" << endl;
 
  172      file_ << 
"    algorithm hmac-md5;" << endl;
 
  173      file_ << 
"    secret \"" << rndc_secret_ << 
"\";" << endl;
 
  174      file_ << 
"};" << endl << endl;
 
  176      file_ << 
"options {" << endl;
 
  177      file_ << 
"    default-key \"rndc-key\";" << endl;
 
  178      file_ << 
"    default-server 127.0.0.1;" << endl;
 
  180      file_ << 
"};" << endl << endl;
 
  187     file_ << 
"options {" << endl;
 
  188     file_ << 
"    directory \"" << named_config_dir_ << 
"\";" << endl;
 
  189     file_ << 
"    managed-keys-directory \"" << named_config_dir_ << 
"\";" << endl;
 
  190     file_ << 
"    empty-zones-enable no;" << endl;
 
  191     file_ << 
"    pid-file \"" << GetPidFilePath() << 
"\";" << endl;
 
  192     file_ << 
"    session-keyfile \"" << GetSessionKeyFilePath() << 
"\";" << endl;
 
  193     file_ << 
"    listen-on port " << 
Dns::GetDnsPort() << 
" { any; };" << endl;
 
  194     file_ << 
"    allow-query { any; };" << endl;
 
  195     file_ << 
"    allow-recursion { any; };" << endl;
 
  196     file_ << 
"    allow-query-cache { any; };" << endl;
 
  197     if (!named_max_cache_size_.empty())
 
  198         file_ << 
"    max-cache-size " << named_max_cache_size_ << 
";" << endl;
 
  199     file_ << 
"};" << endl << endl;
 
  203     file_ << 
"key \"rndc-key\" {" << endl;
 
  204     file_ << 
"    algorithm hmac-md5;" << endl;
 
  205     file_ << 
"    secret \"" << rndc_secret_ << 
"\";" << endl;
 
  206     file_ << 
"};" << endl << endl;
 
  209     file_ << 
"controls {" << endl;
 
  211     file_ << 
"    allow { 127.0.0.1; }  keys { \"rndc-key\"; };" << endl;
 
  212     file_ << 
"};" << endl << endl;
 
  216     file_ << 
"logging {" << endl;
 
  217     file_ << 
"    channel debug_log {" << endl;
 
  218     file_ << 
"        file \"" << named_log_file_ << 
"\" versions 3 size 5m;" << endl;
 
  219     file_ << 
"        severity debug;" << endl;
 
  220     file_ << 
"        print-time yes;" << endl;
 
  221     file_ << 
"        print-severity yes;" << endl;
 
  222     file_ << 
"        print-category yes;" << endl;
 
  223     file_ << 
"    };" << endl;
 
  224     file_ << 
"    category default {" << endl;
 
  225     file_ << 
"        debug_log;" << endl;
 
  226     file_ << 
"    };" << endl;
 
  227     file_ << 
"    category queries {" << endl;
 
  228     file_ << 
"        debug_log;" << endl;
 
  229     file_ << 
"    };" << endl;
 
  230     file_ << 
"};" << endl << endl;
 
  236         WriteDefaultView(zone_view_map);
 
  241     for (VirtualDnsConfig::DataMap::iterator it = vdns.begin(); it != vdns.end(); ++it) {
 
  244         MakeZoneList(curr_vdns, zones);
 
  247             RemoveZoneFiles(curr_vdns, zones);
 
  252         file_ << 
"view \"" << view_name << 
"\" {" << endl;
 
  255         if (!order.empty()) {
 
  256             if (order == 
"round-robin")
 
  258             file_ << 
"    rrset-order {order " << order << 
";};" << endl;
 
  261         std::string next_dns = curr_vdns->
GetNextDns();
 
  262         if (!next_dns.empty()) {
 
  263             boost::system::error_code ec;
 
  264             boost::asio::ip::address_v4
 
  265                 next_addr(boost::asio::ip::address_v4::from_string(next_dns, ec));
 
  267                 file_ << 
"    forwarders {" << next_addr.to_string() << 
";};" << endl;
 
  269                 file_ << 
"    virtual-forwarder \"" << next_dns << 
"\";" << endl;
 
  271         } 
else if (!default_forwarders_.empty()) {
 
  272             file_ << 
"    forwarders {" << default_forwarders_ << 
"};" << endl;
 
  276         for (
unsigned int i = 0; i < zones.size(); i++) {
 
  277             WriteZone(view_name, zones[i], 
true, reverse_resolution, next_dns);
 
  280                 zone_view_map.insert(
ZoneViewPair(zones[i], view_name));
 
  284         file_ << 
"};" << endl << endl;
 
  286         if (curr_vdns == updated_vdns || all_zone_files_)
 
  287             AddZoneFiles(zones, curr_vdns);
 
  290     WriteDefaultView(zone_view_map);
 
  296     file_ << 
"view \"_default_view_\" {" << endl;
 
  297     file_ << 
"    match-clients {any;};" << endl;
 
  298     file_ << 
"    match-destinations {any;};" << endl;
 
  299     file_ << 
"    match-recursive-only no;" << endl;
 
  300     if (!default_forwarders_.empty()) {
 
  301         file_ << 
"    forwarders {" << default_forwarders_ << 
"};" << endl;
 
  303     for (ZoneViewMap::iterator it = zone_view_map.begin();
 
  304          it != zone_view_map.end(); ++it) {
 
  305         WriteZone(it->second, it->first, 
false, 
false, 
"");
 
  307     file_ << 
"};" << endl << endl;
 
  311                             bool is_master, 
bool is_rr, 
const string &next_dns) {
 
  312     file_ << 
"    zone \"" << name << 
"\" IN {" << endl;
 
  314         file_ << 
"        type master;" << endl;
 
  315         file_ << 
"        file \"" << GetZoneFilePath(vdns, name) << 
"\";" << endl;
 
  316         file_ << 
"        allow-update {127.0.0.1;};" << endl;
 
  317         if (!next_dns.empty()) {
 
  319                 file_ << 
"        forwarders { };" << endl;
 
  322             file_ << 
"        forwarders { };" << endl;
 
  325         file_ << 
"        type static-stub;" << endl;
 
  326         file_ << 
"        virtual-server-name \"" << vdns << 
"\";" << endl;
 
  327         file_ << 
"        server-addresses {127.0.0.1;};" << endl;
 
  329     file_ << 
"    };" << endl;
 
  333     for (
unsigned int i = 0; i < zones.size(); i++) {
 
  340     for (
unsigned int i = 0; i < zones.size(); i++) {
 
  341         RemoveZoneFile(vdns, zones[i]);
 
  346     string zfile_name = GetZoneFilePath(vdns->
GetViewName(), zone);
 
  347     remove(zfile_name.c_str());
 
  348     zfile_name.append(
".jnl");
 
  349     remove(zfile_name.c_str());
 
  353     if (name.size() && name.at(name.size() - 1) == 
'.')
 
  354         return (vdns + 
"." + name + NamedZoneFileSuffix);
 
  356         return (vdns + 
"." + name + 
"." + NamedZoneFileSuffix);
 
  360     return (named_config_dir_ + GetZoneFileName(vdns, name));
 
  364     return (named_config_dir_ + pid_file_name);
 
  368     return (named_config_dir_ + sessionkey_file_name);
 
  372     return (NamedZoneNSPrefix + 
"." + domain_name);
 
  376     return (NamedZoneMXPrefix + 
"." + domain_name);
 
  383     string zone_filename = GetZoneFilePath(vdns->
GetViewName(), zone_name);
 
  385     zfile.open(zone_filename.c_str());
 
  386     zfile << 
"$ORIGIN ." << endl;
 
  388         zfile << 
"$TTL " << vdns->
GetTtl() << endl;
 
  390         zfile << 
"$TTL " << Defaults::GlobalTTL << endl;
 
  392     zfile << left << setw(NameWidth) << zone_name << 
" IN  SOA " <<
 
  395     zfile << setw(NameWidth + 8) << 
"" << setw(NumberWidth) << Defaults::Serial << endl;
 
  396     zfile << setw(NameWidth + 8) << 
"" << setw(NumberWidth) << Defaults::Refresh << endl;
 
  397     zfile << setw(NameWidth + 8) << 
"" << setw(NumberWidth) << Defaults::Retry << endl;
 
  398     zfile << setw(NameWidth + 8) << 
"" << setw(NumberWidth) << Defaults::Expire << endl;
 
  400         zfile << setw(NameWidth + 8) << 
"" << setw(NumberWidth) << vdns->
GetNegativeCacheTtl() << endl;
 
  402         zfile << setw(NameWidth + 8) << 
"" << setw(NumberWidth) << Defaults::Minimum << endl;
 
  404     zfile << setw(NameWidth + 8) << 
"" << 
")" << endl;
 
  410     zfile << setw(NameWidth + 4) << 
"" << setw(TypeWidth) << 
" NS " <<
 
  411                 setw(NameWidth) << GetZoneNSName(vdns->
GetDomainName()) << endl;
 
  412     zfile << 
"$ORIGIN " << zone_name << endl;
 
  415         zfile << setw(NameWidth) << NamedZoneNSPrefix << 
" IN  A   " << 
Dns::GetSelfIp() << endl;
 
  424     std::string dns_domain = boost::to_lower_copy(vdns_config->
GetDomainName());
 
  425     if (dns_domain.empty()) {
 
  430     zones.push_back(dns_domain);
 
  433     MakeReverseZoneList(vdns_config, zones);
 
  439     for (VirtualDnsConfig::IpamList::const_iterator ipam_it = ipams.begin();
 
  440          ipam_it != ipams.end(); ++ipam_it) {
 
  441         if ((*ipam_it)->IsDeleted() || !(*ipam_it)->IsValid()) {
 
  445         for (IpamConfig::VnniList::iterator vnni_it = vnni_list.begin();
 
  446              vnni_it != vnni_list.end(); ++vnni_it) {
 
  447             if ((*vnni_it)->IsDeleted() || !(*vnni_it)->IsValid()) {
 
  450             const Subnets &subnets = (*vnni_it)->GetSubnets();
 
  451             for (
unsigned int i = 0; i < subnets.size(); ++i) {
 
  452                 const Subnet &subnet = subnets[i];
 
  461     std::sort(zones.begin(), zones.end());
 
  462     ZoneList::iterator it = std::unique(zones.begin(), zones.end());
 
  463     zones.resize(std::distance(zones.begin(), it));
 
  467     default_forwarders_.clear();
 
  469     fd.open(GetResolveFile().c_str());
 
  475     while (getline(fd, line)) {
 
  476         std::size_t pos = line.find_first_of(
"#");
 
  477         std::stringstream ss(line.substr(0, pos));
 
  480         if (key == 
"nameserver") {
 
  483             boost::system::error_code ec;
 
  484             boost::asio::ip::address_v4::from_string(ip, ec);
 
  486                 default_forwarders_ += ip + 
"; ";
 
  497     : named_pid_(-1), handler_(handler), change_timeout_(true) {
 
  513     std::stringstream str;
 
  514     str << 
"/proc/" << pid << 
"/cmdline";
 
  516     ifstream ifile(str.str().c_str());
 
  517     if (ifile.is_open()) {
 
  520             cmdline.assign((istreambuf_iterator<char>(ifile)),
 
  521                             istreambuf_iterator<char>());
 
  522             istringstream cmdstream(cmdline);
 
  523             if (cmdstream.str().find(
"/usr/bin/contrail-named") !=
 
  535     uint32_t new_pid = -1;
 
  539         if (pid_file.is_open()) {
 
  540             if (pid_file.good()) {
 
  547     if (new_pid == (uint32_t) -1) {
 
std::vector< Subnet > Subnets
 
std::vector< std::string > ZoneList
 
bool IsBindPid(uint32_t pid)
 
boost::function< void(Event)> BindEventHandler
 
BindStatus(BindEventHandler handler)
 
static const uint32_t kInitTimeout
 
static const uint32_t kBindStatusTimeout
 
BindEventHandler handler_
 
static bool IsReverseZone(const std::string &name)
 
static const uint16_t DnsRndc()
 
static std::string GetSelfIp()
 
static EventManager * GetEventManager()
 
static const uint32_t GetDnsPort()
 
std::pair< std::string, std::string > ZoneViewPair
 
virtual std::string GetZoneFilePath(const std::string &vdns, const std::string &name)
 
virtual void UpdateNamedConf(const VirtualDnsConfig *updated_vdns=NULL)
 
void GetDefaultForwarders()
 
static const std::string NamedZoneFileSuffix
 
static const std::string NamedZoneMXPrefix
 
static NamedConfig * singleton_
 
static const std::string NamedZoneNSPrefix
 
std::string GetZoneNSName(const std::string domain_name)
 
void WriteViewConfig(const VirtualDnsConfig *updated_vdns)
 
virtual void DelZone(const Subnet &subnet, const VirtualDnsConfig *vdns)
 
void MakeZoneList(const VirtualDnsConfig *vdns_config, ZoneList &zones)
 
static const char sessionkey_file_name[]
 
void WriteDefaultView(ZoneViewMap &zone_view_map)
 
virtual std::string GetZoneFileName(const std::string &vdns, const std::string &name)
 
static void Init(const std::string &named_config_dir, const std::string &named_config_file, const std::string &named_log_file, const std::string &rndc_config_file, const std::string &rndc_secret, const std::string &named_max_cache_size)
 
static NamedConfig * GetNamedConfigObject()
 
void WriteOptionsConfig()
 
std::map< std::string, std::string > ZoneViewMap
 
std::string GetPidFilePath()
 
virtual void AddZone(const Subnet &subnet, const VirtualDnsConfig *vdns)
 
virtual void AddView(const VirtualDnsConfig *vdns)
 
std::string GetSessionKeyFilePath()
 
static const char pid_file_name[]
 
void RemoveZoneFile(const VirtualDnsConfig *vdns, std::string &zone)
 
void WriteZone(const std::string &vdns, const std::string &name, bool is_master, bool is_rr, const std::string &next_dns)
 
void MakeReverseZoneList(const VirtualDnsConfig *vdns_config, ZoneList &zones)
 
virtual void AddAllViews()
 
void AddZoneFiles(ZoneList &zones, const VirtualDnsConfig *vdns)
 
std::string GetZoneMXName(const std::string domain_name)
 
void CreateZoneFile(std::string &zone_name, const VirtualDnsConfig *vdns, bool ns)
 
void RemoveZoneFiles(const VirtualDnsConfig *vdns, ZoneList &zones)
 
virtual void DelView(const VirtualDnsConfig *vdns)
 
void WriteLoggingConfig()
 
void CreateNamedConf(const VirtualDnsConfig *updated_vdns)
 
virtual void ChangeView(const VirtualDnsConfig *vdns)
 
static TaskScheduler * GetInstance()
 
static bool DeleteTimer(Timer *Timer)
 
static Timer * CreateTimer(boost::asio::io_context &service, const std::string &name, int task_id=Timer::GetTimerTaskId(), int task_instance=Timer::GetTimerInstanceId(), bool delete_on_completion=false)
 
bool Start(int time, Handler handler, ErrorHandler error_handler=NULL)
 
bool Reschedule(int time)
 
#define LOG(_Level, _Msg)
 
std::set< VnniConfig * > VnniList
 
void GetReverseZones(ZoneList &zones) const
 
static DataMap & GetVirtualDnsMap()
 
std::string GetNextDns() const
 
std::string GetOldDomainName() const
 
std::string GetRecordOrder() const
 
int GetNegativeCacheTtl() const
 
bool IsExternalVisible() const
 
std::map< std::string, VirtualDnsConfig * > DataMap
 
bool IsReverseResolutionEnabled() const
 
std::string GetDomainName() const
 
std::string GetViewName() const
 
const IpamList & GetIpamList() const
 
std::set< IpamConfig * > IpamList