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) {
void RemoveZoneFiles(const VirtualDnsConfig *vdns, ZoneList &zones)
static const char pid_file_name[]
virtual void AddAllViews()
std::string GetZoneNSName(const std::string domain_name)
virtual void DelZone(const Subnet &subnet, const VirtualDnsConfig *vdns)
int GetNegativeCacheTtl() const
void CreateZoneFile(std::string &zone_name, const VirtualDnsConfig *vdns, bool ns)
std::pair< std::string, std::string > ZoneViewPair
const IpamList & GetIpamList() const
static const uint32_t GetDnsPort()
virtual void ChangeView(const VirtualDnsConfig *vdns)
void WriteZone(const std::string &vdns, const std::string &name, bool is_master, bool is_rr, const std::string &next_dns)
virtual void AddView(const VirtualDnsConfig *vdns)
static const uint32_t kBindStatusTimeout
std::string GetOldDomainName() const
void GetDefaultForwarders()
bool IsBindPid(uint32_t pid)
std::string GetZoneMXName(const std::string domain_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)
virtual void AddZone(const Subnet &subnet, const VirtualDnsConfig *vdns)
std::string GetPidFilePath()
void MakeZoneList(const VirtualDnsConfig *vdns_config, ZoneList &zones)
static const char sessionkey_file_name[]
std::set< VnniConfig * > VnniList
static std::string GetSelfIp()
bool IsReverseResolutionEnabled() const
void GetReverseZones(ZoneList &zones) const
void CreateNamedConf(const VirtualDnsConfig *updated_vdns)
static NamedConfig * GetNamedConfigObject()
static bool IsReverseZone(const std::string &name)
virtual std::string GetZoneFilePath(const std::string &vdns, const std::string &name)
std::string GetSessionKeyFilePath()
std::string GetRecordOrder() const
void WriteDefaultView(ZoneViewMap &zone_view_map)
bool IsExternalVisible() const
static TaskScheduler * GetInstance()
static const std::string NamedZoneNSPrefix
std::vector< Subnet > Subnets
virtual void DelView(const VirtualDnsConfig *vdns)
std::string GetDomainName() const
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)
virtual void UpdateNamedConf(const VirtualDnsConfig *updated_vdns=NULL)
std::map< std::string, std::string > ZoneViewMap
std::string GetViewName() const
void AddZoneFiles(ZoneList &zones, const VirtualDnsConfig *vdns)
static const uint16_t DnsRndc()
void WriteViewConfig(const VirtualDnsConfig *updated_vdns)
static const std::string NamedZoneMXPrefix
void RemoveZoneFile(const VirtualDnsConfig *vdns, std::string &zone)
bool Start(int time, Handler handler, ErrorHandler error_handler=NULL)
std::map< std::string, VirtualDnsConfig * > DataMap
BindEventHandler handler_
#define LOG(_Level, _Msg)
std::string GetNextDns() const
static NamedConfig * singleton_
static EventManager * GetEventManager()
bool Reschedule(int time)
static const std::string NamedZoneFileSuffix
std::set< IpamConfig * > IpamList
BindStatus(BindEventHandler handler)
void WriteLoggingConfig()
virtual std::string GetZoneFileName(const std::string &vdns, const std::string &name)
static DataMap & GetVirtualDnsMap()
static const uint32_t kInitTimeout
boost::function< void(Event)> BindEventHandler
void MakeReverseZoneList(const VirtualDnsConfig *vdns_config, ZoneList &zones)
void WriteOptionsConfig()
std::vector< std::string > ZoneList
static bool DeleteTimer(Timer *Timer)