LCOV - code coverage report
Current view: top level - dns/mgr - dns_mgr.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 223 818 27.3 %
Date: 2026-06-18 01:51:13 Functions: 23 53 43.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include <base/contrail_ports.h>
       6             : #include <cmn/dns.h>
       7             : #include <bind/bind_util.h>
       8             : #include <mgr/dns_mgr.h>
       9             : #include <mgr/dns_oper.h>
      10             : #include <bind/bind_resolver.h>
      11             : #include <bind/named_config.h>
      12             : #include <agent/agent_xmpp_channel.h>
      13             : 
      14          15 : DnsManager::DnsManager()
      15          15 :     : bind_status_(boost::bind(&DnsManager::BindEventHandler, this, _1)),
      16          15 :       end_of_config_(false),
      17          15 :       record_send_count_(TaskScheduler::GetInstance()->HardwareThreadCount()),
      18          15 :       named_max_retransmissions_(kMaxRetransmitCount),
      19          15 :       named_retransmission_interval_(kPendingRecordReScheduleTime),
      20          15 :       named_lo_watermark_(kNamedLoWaterMark),
      21          15 :       named_hi_watermark_(kNamedHiWaterMark),
      22          15 :       named_send_throttled_(false),
      23          15 :       pending_done_queue_(TaskScheduler::GetInstance()->GetTaskId("dns::NamedSndRcv"), 0,
      24             :                           boost::bind(&DnsManager::PendingDone, this, _1)),
      25          45 :       idx_(kMaxIndexAllocator) {
      26          15 :     std::vector<BindResolver::DnsServer> bind_servers;
      27          15 :     bind_servers.push_back(BindResolver::DnsServer("127.0.0.1",
      28          15 :                                                    Dns::GetDnsPort()));
      29          30 :     BindResolver::Init(*Dns::GetEventManager()->io_service(), bind_servers,
      30          15 :                        ContrailPorts::ContrailDnsClientUdpPort(),
      31             :                        boost::bind(&DnsManager::HandleUpdateResponse,
      32             :                                    this, _1, _2), 0);
      33             : 
      34          15 :     Dns::SetDnsConfigManager(&config_mgr_);
      35          15 :     DnsConfigManager::Observers obs;
      36             :     obs.virtual_dns = boost::bind(&DnsManager::ProcessConfig<VirtualDnsConfig>,
      37          15 :                                   this, _1, _2, _3);
      38             :     obs.virtual_dns_record =
      39             :         boost::bind(&DnsManager::ProcessConfig<VirtualDnsRecordConfig>,
      40          15 :                     this, _1, _2, _3);
      41          15 :     obs.ipam = boost::bind(&DnsManager::ProcessConfig<IpamConfig>, this, _1, _2, _3);
      42          15 :     obs.vnni = boost::bind(&DnsManager::ProcessConfig<VnniConfig>, this, _1, _2, _3);
      43             :     obs.global_qos = boost::bind(&DnsManager::ProcessConfig<GlobalQosConfig>,
      44          15 :                                  this, _1, _2, _3);
      45          15 :     Dns::GetDnsConfigManager()->RegisterObservers(obs);
      46             : 
      47          15 :     DnsConfig::VdnsCallback = boost::bind(&DnsManager::DnsView, this, _1, _2);
      48             :     DnsConfig::VdnsRecordCallback = boost::bind(&DnsManager::DnsRecord, this,
      49          15 :                                                 _1, _2);
      50             :     DnsConfig::VdnsZoneCallback = boost::bind(&DnsManager::DnsPtrZone, this,
      51          15 :                                               _1, _2, _3);
      52          15 :     pending_timer_ =
      53          15 :         TimerManager::CreateTimer(*Dns::GetEventManager()->io_service(),
      54             :               "DnsRetransmitTimer",
      55             :               TaskScheduler::GetInstance()->GetTaskId("dns::NamedSndRcv"), 0);
      56             : 
      57          15 :     end_of_config_check_timer_ =
      58          15 :         TimerManager::CreateTimer(*Dns::GetEventManager()->io_service(),
      59             :               "Check_EndofConfig_Timer",
      60             :               TaskScheduler::GetInstance()->GetTaskId("dns::Config"), 0);
      61             : 
      62             :     // PreAllocate index 0 as it cannot be used as transaction id.
      63          15 :     idx_.AllocIndex();
      64          15 : }
      65             : 
      66           0 : void DnsManager::Initialize(DB *config_db, DBGraph *config_graph,
      67             :                             const std::string& named_config_dir,
      68             :                             const std::string& named_config_file,
      69             :                             const std::string& named_log_file,
      70             :                             const std::string& rndc_config_file,
      71             :                             const std::string& rndc_secret,
      72             :                             const std::string& named_max_cache_size,
      73             :                             const uint16_t named_max_retransmissions,
      74             :                             const uint16_t named_retranmission_interval) {
      75           0 :     NamedConfig::Init(named_config_dir, named_config_file,
      76             :                       named_log_file, rndc_config_file, rndc_secret,
      77             :                       named_max_cache_size);
      78           0 :     config_mgr_.Initialize(config_db, config_graph);
      79           0 :     named_max_retransmissions_ = named_max_retransmissions;
      80           0 :     named_retransmission_interval_ = named_retranmission_interval;
      81           0 : }
      82             : 
      83          15 : DnsManager::~DnsManager() {
      84          15 :     pending_timer_->Cancel();
      85          15 :     TimerManager::DeleteTimer(pending_timer_);
      86          15 :     end_of_config_check_timer_->Cancel();
      87          15 :     TimerManager::DeleteTimer(end_of_config_check_timer_);
      88          15 :     pending_done_queue_.Shutdown();
      89          15 : }
      90             : 
      91          15 : void DnsManager::Shutdown() {
      92          15 :     config_mgr_.Terminate();
      93          15 :     NamedConfig::Shutdown();
      94          15 :     BindResolver::Shutdown();
      95          15 : }
      96             : 
      97             : template <typename ConfigType>
      98         178 : void DnsManager::ProcessConfig(IFMapNodeProxy *proxy,
      99             :                                const std::string &name,
     100             :                                DnsConfigManager::EventType event) {
     101         178 :     IFMapNode *node = proxy->node();
     102         178 :     ConfigType *config = ConfigType::Find(name);
     103         178 :     switch (event) {
     104          58 :         case DnsConfigManager::CFG_ADD:
     105          58 :             if (!config) {
     106          50 :                 config = new ConfigType(node);
     107             :             }
     108          58 :             config->OnAdd(node);
     109          58 :             break;
     110             : 
     111          62 :         case DnsConfigManager::CFG_CHANGE:
     112          62 :             if (config)
     113          62 :                 config->OnChange(node);
     114          62 :             break;
     115             : 
     116          58 :         case DnsConfigManager::CFG_DELETE:
     117          58 :             if (config) {
     118          58 :                 config->OnDelete();
     119          58 :                 delete config;
     120             :             }
     121          58 :             break;
     122             : 
     123           0 :         default:
     124           0 :             assert(0);
     125             :     }
     126         178 : }
     127             : 
     128           2 : void DnsManager::ProcessAgentUpdate(BindUtil::Operation event,
     129             :                                     const std::string &name,
     130             :                                     const std::string &vdns_name,
     131             :                                     const DnsItem &item) {
     132           2 :     std::scoped_lock lock(mutex_);
     133           2 :     VirtualDnsRecordConfig *config = VirtualDnsRecordConfig::Find(name);
     134           2 :     switch (event) {
     135           1 :         case BindUtil::ADD_UPDATE:
     136           1 :             if (!config) {
     137           0 :                 config = new VirtualDnsRecordConfig(name, vdns_name, item);
     138             :             }
     139           1 :             config->rec_.source_name = item.source_name;
     140           1 :             config->OnAdd();
     141           1 :             break;
     142             : 
     143           0 :         case BindUtil::CHANGE_UPDATE:
     144           0 :             if (config)
     145           0 :                 config->OnChange(item);
     146           0 :             break;
     147             : 
     148           1 :         case BindUtil::DELETE_UPDATE:
     149           1 :             if (config && (config->rec_.source_name == item.source_name)) {
     150           0 :                 config->OnDelete();
     151           0 :                 delete config;
     152             :             }
     153           1 :             break;
     154             : 
     155           0 :         default:
     156           0 :             assert(0);
     157             :     }
     158           2 : }
     159             : 
     160          30 : void DnsManager::DnsView(const DnsConfig *cfg, DnsConfig::DnsConfigEvent ev) {
     161             : 
     162          30 :     if (!end_of_config_)
     163           0 :         return;
     164             : 
     165          30 :     if (!bind_status_.IsUp())
     166           0 :         return;
     167             : 
     168          30 :     const VirtualDnsConfig *config = static_cast<const VirtualDnsConfig *>(cfg);
     169          30 :     DNS_BIND_TRACE(DnsBindTrace, "Virtual DNS <" << config->GetName() <<
     170             :                    "> " << DnsConfig::ToEventString(ev));
     171          30 :     config->ClearNotified();
     172          30 :     std::string dns_domain = config->GetDomainName();
     173          30 :     if (dns_domain.empty()) {
     174           0 :         DNS_BIND_TRACE(DnsBindTrace, "Virtual DNS <" << config->GetName() <<
     175             :                        "> doesnt have domain; ignoring event : " <<
     176             :                        DnsConfig::ToEventString(ev));
     177           0 :         return;
     178             :     }
     179             : 
     180          30 :     NamedConfig *ncfg = NamedConfig::GetNamedConfigObject();
     181          30 :     if (ev == DnsConfig::CFG_ADD) {
     182          11 :         if (!CheckName(config->GetName(), dns_domain)) {
     183           0 :             return;
     184             :         }
     185          11 :         config->MarkNotified();
     186          11 :         ncfg->AddView(config);
     187          19 :     } else if (ev == DnsConfig::CFG_CHANGE) {
     188           8 :         if (CheckName(config->GetName(), dns_domain)) {
     189           8 :             config->MarkNotified();
     190             :         }
     191           8 :         ncfg->ChangeView(config);
     192           8 :         if (dns_domain != config->GetOldDomainName()) {
     193           0 :             NotifyAllDnsRecords(config, ev);
     194           8 :         } else if (config->HasReverseResolutionChanged()) {
     195           8 :             bool reverse_resolution = config->IsReverseResolutionEnabled();
     196             :             // if reverse resolution is enabled now, add the reverse records
     197             :             // if reverse resolution is disabled now, mark them as not notified
     198           8 :             NotifyReverseDnsRecords(config, ev, reverse_resolution);
     199             :         }
     200             :     } else {
     201          11 :         ncfg->DelView(config);
     202          11 :         PendingListViewDelete(config);
     203             :     }
     204          30 : }
     205             : 
     206          42 : void DnsManager::DnsPtrZone(const Subnet &subnet, const VirtualDnsConfig *vdns,
     207             :                             DnsConfig::DnsConfigEvent ev) {
     208             : 
     209          42 :     if (!end_of_config_)
     210           0 :         return;
     211             : 
     212          42 :     if (!bind_status_.IsUp())
     213           0 :         return;
     214             : 
     215          42 :     std::string dns_domain = vdns->GetDomainName();
     216          42 :     if (dns_domain.empty()) {
     217           0 :         DNS_BIND_TRACE(DnsBindTrace, "Ptr Zone <" << vdns->GetName() <<
     218             :                        "> ; ignoring event: " << DnsConfig::ToEventString(ev) <<
     219             :                        " Domain: " << dns_domain << " Reverse Resolution: " <<
     220             :                        (vdns->IsReverseResolutionEnabled()? "enabled" :
     221             :                        "disabled"));
     222           0 :         return;
     223             :     }
     224             : 
     225          42 :     NamedConfig *ncfg = NamedConfig::GetNamedConfigObject();
     226          42 :     if (ev == DnsConfig::CFG_DELETE) {
     227          29 :         ncfg->DelZone(subnet, vdns);
     228          29 :         PendingListZoneDelete(subnet, vdns);
     229             :     } else {
     230          13 :         ncfg->AddZone(subnet, vdns);
     231             :     }
     232          42 :     DNS_BIND_TRACE(DnsBindTrace, "Virtual DNS <" << vdns->GetName() << "> " <<
     233             :                    subnet.prefix.to_string() << "/" << subnet.plen << " " <<
     234             :                    DnsConfig::ToEventString(ev));
     235          42 : }
     236             : 
     237          41 : void DnsManager::DnsRecord(const DnsConfig *cfg, DnsConfig::DnsConfigEvent ev) {
     238             : 
     239          41 :     if (!end_of_config_)
     240           0 :         return;
     241             : 
     242          41 :     if (!bind_status_.IsUp())
     243           0 :         return;
     244             : 
     245          41 :     if (named_send_throttled_)
     246           0 :         return;
     247             : 
     248          41 :     const VirtualDnsRecordConfig *config =
     249             :                 static_cast<const VirtualDnsRecordConfig *>(cfg);
     250          41 :     config->ClearNotified();
     251          41 :     const DnsItem &item = config->GetRecord();
     252          41 :     if (item.name == "" || item.data == "") {
     253           0 :         DNS_BIND_TRACE(DnsBindError, "Virtual DNS Record <" <<
     254             :                        config->GetName() <<
     255             :                        "> doesnt have name / data; ignoring event : " <<
     256             :                        DnsConfig::ToEventString(ev));
     257           0 :         return;
     258             :     }
     259             : 
     260          41 :     if (config->GetViewName() == "" || !config->GetVirtualDns()->IsValid()) {
     261           0 :         return;
     262             :     }
     263             : 
     264          41 :     switch (ev) {
     265          23 :         case DnsConfig::CFG_ADD:
     266             :         case DnsConfig::CFG_CHANGE:
     267          23 :             if (SendRecordUpdate(BindUtil::ADD_UPDATE, config))
     268          23 :                 config->MarkNotified();
     269          23 :             break;
     270             : 
     271          18 :         case DnsConfig::CFG_DELETE:
     272          18 :             if (SendRecordUpdate(BindUtil::DELETE_UPDATE, config))
     273          18 :                 config->ClearNotified();
     274          18 :             break;
     275             : 
     276           0 :         default:
     277           0 :             assert(0);
     278             :     }
     279             : }
     280             : 
     281          41 : bool DnsManager::SendRecordUpdate(BindUtil::Operation op,
     282             :                                   const VirtualDnsRecordConfig *config) {
     283          41 :     DnsItem item = config->GetRecord();
     284          41 :     const autogen::VirtualDnsType vdns = config->GetVDns();
     285             : 
     286          41 :     std::string zone;
     287          41 :     if (item.type == DNS_PTR_RECORD) {
     288           2 :         if (!vdns.reverse_resolution) {
     289           0 :             DNS_BIND_TRACE(DnsBindTrace, "Virtual DNS Record <" <<
     290             :                            config->GetName() << "> PTR name " << item.name <<
     291             :                            " not added - reverse resolution is not enabled");
     292           0 :             return false;
     293             :         }
     294           2 :         IpAddress addr;
     295           2 :         if (BindUtil::IsIP(item.name, addr)) {
     296           0 :             BindUtil::GetReverseZone(addr, addr.is_v4() ? 32 : 128, item.name);
     297             :         } else {
     298           2 :             if (!BindUtil::GetAddrFromPtrName(item.name, addr)) {
     299           0 :                 DNS_BIND_TRACE(DnsBindError, "Virtual DNS Record <" <<
     300             :                                config->GetName() << "> invalid PTR name " <<
     301             :                                item.name << "; ignoring");
     302           0 :                 return false;
     303             :             }
     304             :         }
     305           2 :         if (!CheckName(config->GetName(), item.data)) {
     306           0 :             return false;
     307             :         }
     308           2 :         Subnet net;
     309           2 :         if (!config->GetVirtualDns()->GetSubnet(addr, net)) {
     310           0 :             DNS_BIND_TRACE(DnsBindError, "Virtual DNS Record <" <<
     311             :                            config->GetName() <<
     312             :                            "> doesnt belong to a known subnet; ignoring");
     313           0 :             return false;
     314             :         }
     315           2 :         BindUtil::GetReverseZone(addr, net.plen, zone);
     316           2 :         item.data = BindUtil::GetFQDN(item.data, vdns.domain_name, ".");
     317             :     } else {
     318             :         // Bind allows special chars in CNAME, NS names and in CNAME data
     319          78 :         if ((item.type == DNS_A_RECORD || item.type == DNS_AAAA_RECORD) &&
     320          78 :             !CheckName(config->GetName(), item.name)) {
     321           0 :             return false;
     322             :         }
     323          39 :         if (BindUtil::IsReverseZone(item.name)) {
     324           0 :             if (item.type != DNS_NS_RECORD) {
     325           0 :                 DNS_BIND_TRACE(DnsBindError, "Virtual DNS Record <" <<
     326             :                                config->GetName() <<
     327             :                                "> only PTR and NS records allowed in reverse zone; ignoring");
     328           0 :                 return false;
     329             :             }
     330           0 :             if (!vdns.reverse_resolution) {
     331           0 :                 DNS_BIND_TRACE(DnsBindTrace, "Virtual DNS Record <" <<
     332             :                                config->GetName() << "> NS name " << item.name <<
     333             :                                " not added - reverse resolution is not enabled");
     334           0 :                 return false;
     335             :             }
     336           0 :             IpAddress addr;
     337           0 :             if (!BindUtil::GetAddrFromPtrName(item.name, addr)) {
     338           0 :                 DNS_BIND_TRACE(DnsBindError, "Virtual DNS Record <" <<
     339             :                                config->GetName() << "> invalid reverse name " <<
     340             :                                item.name << "; ignoring");
     341           0 :                 return false;
     342             :             }
     343           0 :             Subnet net;
     344           0 :             if (!config->GetVirtualDns()->GetSubnet(addr, net)) {
     345           0 :                 DNS_BIND_TRACE(DnsBindError, "Virtual DNS Record <" <<
     346             :                                config->GetName() <<
     347             :                                "> doesnt belong to a known subnet; ignoring");
     348           0 :                 return false;
     349             :             }
     350           0 :             BindUtil::GetReverseZone(addr, net.plen, zone);
     351             :         } else {
     352          39 :             zone = config->GetVDns().domain_name;
     353          78 :             item.name = BindUtil::GetFQDN(item.name,
     354          39 :                                           vdns.domain_name, vdns.domain_name);
     355             :         }
     356          39 :         if (item.type == DNS_CNAME_RECORD || item.type == DNS_MX_RECORD)
     357           0 :             item.data = BindUtil::GetFQDN(item.data, vdns.domain_name, ".");
     358             :         // In case of NS record, ensure that there are no special characters in data.
     359             :         // When it is virtual dns name, we could have chars like ':'
     360          39 :         if (item.type == DNS_NS_RECORD)
     361           0 :             BindUtil::RemoveSpecialChars(item.data);
     362             :     }
     363             :     /* Fix for CEM-21076
     364             :      * If we have a static DNS record and a VM with the hostname same as the static DNS record
     365             :      * and we delete the VM, then we should not call SendUpdate() after deleting the VM,
     366             :      * because after calling SendUpdate(), DNS queries for the static DNS record will not be resolved
     367             :      */
     368          41 :     if (config->src_ == VirtualDnsRecordConfig::Agent && op == BindUtil::DELETE_UPDATE) {
     369           0 :         VirtualDnsConfig *virt_dns = config->GetVirtualDns();
     370           0 :         for (VirtualDnsConfig::VDnsRec::const_iterator it =
     371           0 :             virt_dns->virtual_dns_records_.begin();
     372           0 :             it != virt_dns->virtual_dns_records_.end(); ++it) {
     373           0 :             if (((*it)->rec_.name + "." + virt_dns->GetDomainName() == item.name) && (*it)->src_ == VirtualDnsRecordConfig::Config) {
     374           0 :                 return false;
     375             :             }
     376             :         }
     377             :     }
     378          41 :     DnsItems items;
     379          41 :     items.push_back(item);
     380          41 :     std::string view_name = config->GetViewName();
     381          41 :     return (SendUpdate(op, view_name, zone, items));
     382          41 : }
     383             : 
     384          41 : bool DnsManager::SendUpdate(BindUtil::Operation op, const std::string &view,
     385             :                             const std::string &zone, DnsItems &items) {
     386             : 
     387          41 :     if (pending_map_.size() >= named_hi_watermark_) {
     388           0 :         DNS_OPERATIONAL_LOG(
     389             :             g_vns_constants.CategoryNames.find(Category::DNSAGENT)->second,
     390             :             SandeshLevel::SYS_NOTICE, "Bind named Send Throttled");
     391             : 
     392           0 :         named_send_throttled_ = true;
     393           0 :         return false;
     394             :     }
     395             : 
     396          41 :     uint16_t xid = GetTransId();
     397          41 :     return (AddPendingList(xid, view, zone, items, op));
     398             : }
     399             : 
     400           0 : void DnsManager::SendRetransmit(uint16_t xid, BindUtil::Operation op,
     401             :                                 const std::string &view,
     402             :                                 const std::string &zone, DnsItems &items,
     403             :                                 uint32_t retransmit_count) {
     404             : 
     405           0 :     uint8_t *pkt = new uint8_t[BindResolver::max_pkt_size];
     406           0 :     int len = BindUtil::BuildDnsUpdate(pkt, op, xid, view, zone, items);
     407           0 :     if (BindResolver::Resolver()->DnsSend(pkt, 0, len)) {
     408           0 :         DNS_BIND_TRACE(DnsBindTrace,
     409             :             "DNS transmit sent for DNS record; xid = " <<
     410             :              xid << "; View = " << view << "; Zone = " << zone << "; " <<
     411             :              DnsItemsToString(items) << " Retry = " <<
     412             :              retransmit_count);
     413             :     }
     414           0 : }
     415             : 
     416           0 : void DnsManager::UpdateAll() {
     417             : 
     418           0 :     if (!bind_status_.IsUp()) {
     419           0 :         return;
     420             :     }
     421             : 
     422           0 :     if (!end_of_config_) {
     423           0 :         return;
     424             :     }
     425             : 
     426             :     // Start dumping records to named
     427           0 :     named_send_throttled_ = false;
     428             : 
     429           0 :     VirtualDnsConfig::DataMap vmap = VirtualDnsConfig::GetVirtualDnsMap();
     430           0 :     for (VirtualDnsConfig::DataMap::iterator it = vmap.begin();
     431           0 :          it != vmap.end(); ++it) {
     432           0 :         VirtualDnsConfig *vdns = it->second;
     433           0 :         if (!vdns->GetDomainName().empty() &&
     434           0 :             CheckName(vdns->GetName(), vdns->GetDomainName())) {
     435           0 :             vdns->MarkNotified();
     436           0 :             DNS_BIND_TRACE(DnsBindTrace, "Virtual DNS <" << vdns->GetName() <<
     437             :                            "> Add");
     438             :         } else {
     439           0 :             vdns->ClearNotified();
     440             :         }
     441             :     }
     442           0 :     NamedConfig *ncfg = NamedConfig::GetNamedConfigObject();
     443           0 :     ncfg->AddAllViews();
     444           0 :     for (VirtualDnsConfig::DataMap::iterator it = vmap.begin();
     445           0 :          it != vmap.end(); ++it) {
     446           0 :         VirtualDnsConfig *vdns = it->second;
     447           0 :         if (!vdns->IsNotified())
     448           0 :             continue;
     449           0 :         NotifyAllDnsRecords(vdns, DnsConfig::CFG_ADD);
     450             :     }
     451             : 
     452           0 :     DNS_OPERATIONAL_LOG(
     453             :         g_vns_constants.CategoryNames.find(Category::DNSAGENT)->second,
     454             :         SandeshLevel::SYS_NOTICE,
     455             :         "Bulk sync has been done (the DB has been synced with named)");
     456           0 : }
     457             : 
     458           0 : void DnsManager::HandleUpdateResponse(uint8_t *pkt, std::size_t length) {
     459             :     dns_flags flags;
     460             :     uint16_t xid;
     461           0 :     DnsItems ques, ans, auth, add;
     462           0 :     if (BindUtil::ParseDnsResponse(pkt, length, xid, flags,
     463             :                                    ques, ans, auth, add)) {
     464           0 :         if (flags.ret) {
     465           0 :             DNS_BIND_TRACE(DnsBindError, "Update failed : " <<
     466             :                            BindUtil::DnsResponseCode(flags.ret) <<
     467             :                            "; xid = " << xid);
     468             :         } else {
     469           0 :             DNS_BIND_TRACE(DnsBindTrace, "Update successful; xid = " << xid);
     470           0 :             pending_done_queue_.Enqueue(xid);
     471             :         }
     472             :     }
     473           0 :     delete [] pkt;
     474           0 : }
     475             : 
     476           0 : bool DnsManager::PendingDone(uint16_t xid) {
     477           0 :     DeletePendingList(xid);
     478           0 :     return true;
     479             : }
     480             : 
     481           0 : bool DnsManager::ResendRecordsinBatch() {
     482             :     static uint16_t start_index = 0;
     483           0 :     uint16_t sent_count = 0;
     484             : 
     485           0 :     PendingListMap::iterator it;
     486           0 :     if (start_index == 0) {
     487           0 :         it = pending_map_.upper_bound(start_index);
     488             :     } else {
     489           0 :         it = pending_map_.lower_bound(start_index);
     490             :     }
     491             : 
     492           0 :     for (; it != pending_map_.end() ; ) {
     493           0 :          if (it->second.retransmit_count > named_max_retransmissions_) {
     494           0 :              DNS_BIND_TRACE(DnsBindTrace, "DNS records max retransmits reached;"
     495             :                             << "no more retransmission; xid = " << it->first);
     496             : 
     497           0 :              dp_pending_map_.insert(PendingListPair(it->first,
     498           0 :                                     PendingList(it->first, it->second.view,
     499           0 :                                                 it->second.zone, it->second.items,
     500           0 :                                                 it->second.op,
     501           0 :                                                 it->second.retransmit_count)));
     502           0 :              ResetTransId(it->first);
     503           0 :              pending_map_.erase(it++);
     504             :          } else {
     505           0 :              sent_count++;
     506           0 :              it->second.retransmit_count++;
     507           0 :              SendRetransmit(it->first, it->second.op, it->second.view,
     508           0 :                             it->second.zone, it->second.items,
     509           0 :                             it->second.retransmit_count);
     510           0 :              it++;
     511             :          }
     512           0 :          if (sent_count >= record_send_count_) break;
     513             :     }
     514             : 
     515           0 :     if (it != pending_map_.end()) {
     516           0 :         start_index = it->first;
     517           0 :         pending_timer_->Reschedule(named_retransmission_interval_);
     518             :         /* Return true to trigger auto-restart of timer */
     519           0 :         return true;
     520             :     } else {
     521           0 :         if (pending_map_.size() == 0) {
     522           0 :             start_index = 0;
     523           0 :             return false;
     524             :         }
     525           0 :         start_index = pending_map_.begin()->first;
     526           0 :         pending_timer_->Reschedule(named_retransmission_interval_);
     527             :     }
     528             : 
     529           0 :     return true;
     530             : }
     531             : 
     532          41 : bool DnsManager::AddPendingList(uint16_t xid, const std::string &view,
     533             :                                 const std::string &zone, const DnsItems &items,
     534             :                                 BindUtil::Operation op) {
     535             :     // delete earlier entries for the same items
     536          41 :     UpdatePendingList(view, zone, items);
     537             : 
     538          41 :     std::pair<PendingListMap::iterator,bool> status;
     539          82 :     status = pending_map_.insert(PendingListPair(xid, PendingList(xid, view,
     540          41 :                                                  zone, items, op)));
     541          41 :     if (status.second == false) {
     542           0 :         dp_pending_map_.insert(PendingListPair(xid, PendingList(xid, view,
     543             :                                                zone, items, op)));
     544           0 :         return true;
     545             :     } else {
     546          41 :         StartPendingTimer(named_retransmission_interval_*3);
     547          41 :         return true;
     548             :     }
     549             : }
     550             : 
     551             : // if there is an update for an item which is already in pending list,
     552             : // remove it from the pending list
     553          41 : void DnsManager::UpdatePendingList(const std::string &view,
     554             :                                    const std::string &zone,
     555             :                                    const DnsItems &items) {
     556          41 :     for (PendingListMap::iterator it = pending_map_.begin();
     557         235 :          it != pending_map_.end(); ) {
     558         262 :         if (it->second.view == view &&
     559         262 :             it->second.zone == zone &&
     560          63 :             it->second.items == items) {
     561          18 :             ResetTransId(it->first);
     562          18 :             pending_map_.erase(it++);
     563             :         } else {
     564         176 :             it++;
     565             :         }
     566             :     }
     567          41 : }
     568             : 
     569           0 : void DnsManager::DeletePendingList(uint16_t xid) {
     570           0 :     ResetTransId(xid);
     571           0 :     pending_map_.erase(xid);
     572           0 :     if (pending_map_.size() <= named_lo_watermark_) {
     573           0 :         if (named_send_throttled_) {
     574           0 :             DNS_OPERATIONAL_LOG(
     575             :                 g_vns_constants.CategoryNames.find(Category::DNSAGENT)->second,
     576             :                 SandeshLevel::SYS_NOTICE, "BIND named Send UnThrottled");
     577             : 
     578           0 :             named_send_throttled_ = false;
     579           0 :             NotifyThrottledDnsRecords();
     580             :         }
     581             :     }
     582           0 : }
     583             : 
     584           0 : void DnsManager::ClearPendingList() {
     585           0 :     pending_map_.clear();
     586           0 : }
     587             : 
     588             : // Remove entries from pending list, upon a view delete
     589          11 : void DnsManager::PendingListViewDelete(const VirtualDnsConfig *config) {
     590          11 :     for (PendingListMap::iterator it = pending_map_.begin();
     591          48 :          it != pending_map_.end(); ) {
     592          37 :         if (it->second.view == config->GetViewName()) {
     593          23 :             ResetTransId(it->first);
     594          23 :             pending_map_.erase(it++);
     595             :         } else {
     596          14 :             it++;
     597             :         }
     598             :     }
     599          11 : }
     600             : 
     601          57 : bool DnsManager::CheckZoneDelete(ZoneList &zones, PendingList &pend) {
     602         172 :     for (uint32_t i = 0; i < zones.size(); i++) {
     603         115 :         if (zones[i] == pend.zone)
     604           0 :             return true;
     605             :     }
     606          57 :     return false;
     607             : }
     608             : 
     609             : // Remove entries from pending list, upon a zone delete
     610          29 : void DnsManager::PendingListZoneDelete(const Subnet &subnet,
     611             :                                        const VirtualDnsConfig *config) {
     612          29 :     ZoneList zones;
     613          29 :     subnet.GetReverseZones(zones);
     614             : 
     615          29 :     for (PendingListMap::iterator it = pending_map_.begin();
     616         236 :          it != pending_map_.end(); ) {
     617         264 :         if (it->second.view == config->GetViewName() &&
     618          57 :             CheckZoneDelete(zones, it->second)) {
     619           0 :             ResetTransId(it->first);
     620           0 :             pending_map_.erase(it++);
     621             :         } else {
     622         207 :             it++;
     623             :         }
     624             :     }
     625          29 : }
     626             : 
     627          41 : void DnsManager::StartPendingTimer(int msec) {
     628          41 :     if (!pending_timer_->running()) {
     629           5 :         pending_timer_->Start(msec,
     630             :             boost::bind(&DnsManager::PendingTimerExpiry, this));
     631             :     }
     632          41 : }
     633             : 
     634           0 : void DnsManager::CancelPendingTimer() {
     635           0 :     pending_timer_->Cancel();
     636           0 : }
     637             : 
     638           0 : bool DnsManager::PendingTimerExpiry() {
     639           0 :     return ResendRecordsinBatch();
     640             : }
     641             : 
     642           0 : void DnsManager::NotifyThrottledDnsRecords() {
     643             : 
     644           0 :     if (!end_of_config_)
     645           0 :         return;
     646             : 
     647           0 :     if (!bind_status_.IsUp())
     648           0 :         return;
     649             : 
     650           0 :     VirtualDnsConfig::DataMap vmap = VirtualDnsConfig::GetVirtualDnsMap();
     651           0 :     for (VirtualDnsConfig::DataMap::iterator it = vmap.begin();
     652           0 :          it != vmap.end(); ++it) {
     653           0 :         VirtualDnsConfig *vdns = it->second;
     654           0 :         if (!vdns->IsNotified())
     655           0 :             continue;
     656             : 
     657           0 :         for (VirtualDnsConfig::VDnsRec::const_iterator it =
     658           0 :             vdns->virtual_dns_records_.begin();
     659           0 :             it != vdns->virtual_dns_records_.end(); ++it) {
     660           0 :             if ((*it)->IsValid()) {
     661           0 :                 if (!((*it)->IsNotified())) {
     662           0 :                     DnsRecord(*it, DnsConfig::CFG_ADD);
     663             :                 }
     664             :             }
     665             :         }
     666             :     }
     667           0 : }
     668             : 
     669           0 : void DnsManager::NotifyAllDnsRecords(const VirtualDnsConfig *config,
     670             :                                      DnsConfig::DnsConfigEvent ev) {
     671             : 
     672           0 :     if (!end_of_config_)
     673           0 :         return;
     674             : 
     675           0 :     if (!bind_status_.IsUp())
     676           0 :         return;
     677             : 
     678           0 :     for (VirtualDnsConfig::VDnsRec::const_iterator it =
     679           0 :          config->virtual_dns_records_.begin();
     680           0 :          it != config->virtual_dns_records_.end(); ++it) {
     681             :         // ClearNotified() to all DnsRecords
     682           0 :         (*it)->ClearNotified();
     683           0 :         if ((*it)->IsValid())
     684           0 :             DnsRecord(*it, ev);
     685             :     }
     686             : }
     687             : 
     688           8 : void DnsManager::NotifyReverseDnsRecords(const VirtualDnsConfig *config,
     689             :                                          DnsConfig::DnsConfigEvent ev,
     690             :                                          bool notify) {
     691             : 
     692           8 :     if (!end_of_config_)
     693           0 :         return;
     694             : 
     695           8 :     if (!bind_status_.IsUp())
     696           0 :         return;
     697             : 
     698           8 :     for (VirtualDnsConfig::VDnsRec::const_iterator it =
     699           8 :          config->virtual_dns_records_.begin();
     700          24 :          it != config->virtual_dns_records_.end(); ++it) {
     701          16 :         DnsItem item = (*it)->GetRecord();
     702          16 :         if (item.type == DNS_PTR_RECORD) {
     703           0 :             (*it)->ClearNotified();
     704           0 :             if ((*it)->IsValid() && notify) {
     705           0 :                 DnsRecord(*it, ev);
     706             :             }
     707             :         }
     708          16 :     }
     709             : }
     710             : 
     711          41 : inline uint16_t DnsManager::GetTransId() {
     712          41 :     return (idx_.AllocIndex());
     713             : }
     714             : 
     715          41 : inline void DnsManager::ResetTransId(uint16_t xid) {
     716          41 :     idx_.FreeIndex(xid);
     717          41 : }
     718             : 
     719          60 : inline bool DnsManager::CheckName(std::string rec_name, std::string name) {
     720          60 :     if (BindUtil::HasSpecialChars(name)) {
     721           0 :         DNS_CONFIGURATION_LOG(
     722             :             g_vns_constants.CategoryNames.find(Category::DNSAGENT)->second,
     723             :             SandeshLevel::SYS_ERR,
     724             :             "Invalid DNS Name - cannot use special characters in DNS name",
     725             :             rec_name, name);
     726           0 :         return false;
     727             :     }
     728          60 :     return true;
     729             : }
     730             : 
     731           0 : void DnsManager::BindEventHandler(BindStatus::Event event) {
     732           0 :     switch (event) {
     733           0 :         case BindStatus::Up: {
     734             : 
     735           0 :             DNS_OPERATIONAL_LOG(
     736             :                 g_vns_constants.CategoryNames.find(Category::DNSAGENT)->second,
     737             :                 SandeshLevel::SYS_NOTICE, "BIND named up; DNS is operational");
     738           0 :             ClearDeportedPendingList();
     739           0 :             UpdateAll();
     740           0 :             break;
     741             :         }
     742             : 
     743           0 :         case BindStatus::Down: {
     744             : 
     745           0 :             DNS_OPERATIONAL_LOG(
     746             :                 g_vns_constants.CategoryNames.find(Category::DNSAGENT)->second,
     747             :                 SandeshLevel::SYS_NOTICE, "BIND named down; DNS is not operational");
     748           0 :             NamedConfig *ncfg = NamedConfig::GetNamedConfigObject();
     749           0 :             ncfg->Reset();
     750           0 :             ClearPendingList();
     751           0 :             break;
     752             :         }
     753             : 
     754           0 :         default:
     755           0 :             assert(0);
     756             :     }
     757           0 : }
     758             : 
     759           0 : void DnsManager::StartEndofConfigTimer() {
     760           0 :     if (!end_of_config_check_timer_->running()) {
     761           0 :         end_of_config_check_timer_->Start(kEndOfConfigCheckTime,
     762             :                               boost::bind(&DnsManager::EndofConfigTimerExpiry, this));
     763             :     }
     764           0 : }
     765             : 
     766           0 : void DnsManager::CancelEndofConfigTimer() {
     767           0 :     end_of_config_check_timer_->Cancel();
     768           0 : }
     769             : 
     770           0 : bool DnsManager::EndofConfigTimerExpiry() {
     771           0 :     bool current_config_state = IsEndOfConfig();
     772           0 :     if ((current_config_state != end_of_config_) && current_config_state) {
     773           0 :         end_of_config_ = current_config_state;
     774           0 :         UpdateAll();
     775             :     } else {
     776           0 :         end_of_config_ = current_config_state;
     777             :     }
     778           0 :     return true;
     779             : }
     780             : 
     781           0 : void SandeshError(const std::string &msg, const std::string &context) {
     782           0 :     ErrorResp *resp = new ErrorResp();
     783           0 :     resp->set_resp(msg);
     784           0 :     resp->set_context(context);
     785           0 :     resp->Response();
     786           0 : }
     787             : 
     788           0 : void ShowVirtualDnsServers::HandleRequest() const {
     789           0 :     DnsManager *dns_manager = Dns::GetDnsManager();
     790           0 :     if(dns_manager) {
     791           0 :         dns_manager->VdnsServersMsgHandler("", context());
     792             :     } else {
     793           0 :         SandeshError("Invalid Request No DnsManager Object", context());
     794             :     }
     795           0 : }
     796             : 
     797           0 : void DnsManager::MakeSandeshPageReq(PageReqData *req, VirtualDnsConfig::DataMap &vdns,
     798             :                                     VirtualDnsConfig::DataMap::iterator vdns_it,
     799             :                                     VirtualDnsConfig::DataMap::iterator vdns_iter,
     800             :                                     const std::string &key, const std::string &req_name) const {
     801             :     // Set table size
     802           0 :     req->set_table_size(vdns.size());
     803             : 
     804             :     //Next page link
     805           0 :     if(vdns_iter != vdns.end()) {
     806           0 :         req->set_next_page(vdns_iter->first + req_name);
     807             :     }
     808             : 
     809             :     // First page link
     810           0 :     if(vdns.size() != 0) {
     811           0 :         req->set_first_page((vdns.begin())->first + req_name);
     812             :     }
     813             : 
     814             :     // Set Entries
     815           0 :     uint16_t start_entry=0, end_entry=0;
     816           0 :     std::stringstream ss1, ss2;
     817           0 :     if(vdns.size() != 0) {
     818           0 :         start_entry = std::distance(vdns.begin(), vdns_it);
     819           0 :         start_entry++;
     820           0 :         if(start_entry != vdns.size()) {
     821           0 :             end_entry = std::distance(vdns.begin(), --vdns_iter);
     822           0 :             end_entry++;
     823             :         } else {
     824           0 :             end_entry = start_entry;
     825             :         }
     826             :     }
     827           0 :     ss1 << start_entry;
     828           0 :     ss2 << end_entry;
     829           0 :     req->set_entries(ss1.str() + " - " + ss2.str());
     830             : 
     831             :     // Previous page link
     832           0 :     if(vdns_it != vdns.begin()) {
     833           0 :         for (int i=0; i < (DnsManager::max_records_per_sandesh); i++) {
     834           0 :             vdns_it--;
     835           0 :             if(vdns_it == vdns.begin())
     836           0 :                 break;
     837             :         }
     838           0 :         req->set_prev_page(vdns_it->first + req_name);
     839             :     }
     840             : 
     841             :     // Set link to show all entries in a single page
     842           0 :     req->set_all("AllEntries" + req_name);
     843           0 : }
     844             : 
     845           0 : void DnsManager::VdnsServersMsgHandler(const std::string &key,
     846             :                                        const std::string &context) const {
     847             :     VirtualDnsServersResponse *resp;
     848           0 :     uint16_t count = 0;
     849           0 :     uint16_t sandesh_msg_limit = DnsManager::max_records_per_sandesh;
     850           0 :     VirtualDnsConfig::DataMap vdns = VirtualDnsConfig::GetVirtualDnsMap();
     851           0 :     VirtualDnsConfig::DataMap::iterator vdns_it, vdns_iter;
     852           0 :     std::vector<VirtualDnsServersSandesh> vdns_list_sandesh;
     853           0 :     if(key == "AllEntries") {
     854           0 :         sandesh_msg_limit = vdns.size();
     855           0 :         vdns_it = vdns.begin();
     856           0 :     } else if(key != "") {
     857           0 :         vdns_it = vdns.lower_bound(key);
     858             :     } else {
     859           0 :         vdns_it = vdns.begin();
     860             :     }
     861             : 
     862           0 :     for (vdns_iter= vdns_it; vdns_iter != vdns.end(); ++vdns_iter) {
     863             : 
     864           0 :         if (count++ == sandesh_msg_limit) {
     865           0 :             break;
     866             :         }
     867           0 :         VirtualDnsConfig *vdns_config = vdns_iter->second;
     868           0 :         VirtualDnsServersSandesh vdns_sandesh;
     869           0 :         VirtualDnsTraceData vdns_trace_data;
     870           0 :         vdns_config->VirtualDnsTrace(vdns_trace_data);
     871             : 
     872           0 :         std::vector<std::string> net_list_sandesh;
     873           0 :         for (VirtualDnsConfig::IpamList::iterator ipam_iter =
     874           0 :             vdns_config->ipams_.begin();
     875           0 :             ipam_iter != vdns_config->ipams_.end(); ++ipam_iter) {
     876           0 :             IpamConfig *ipam = *ipam_iter;
     877           0 :             const IpamConfig::VnniList &vnni = ipam->GetVnniList();
     878           0 :             for (IpamConfig::VnniList::iterator vnni_it = vnni.begin();
     879           0 :                 vnni_it != vnni.end(); ++vnni_it) {
     880           0 :                 Subnets &subnets = (*vnni_it)->GetSubnets();
     881           0 :                 for (unsigned int i = 0; i < subnets.size(); i++) {
     882           0 :                     std::stringstream str;
     883           0 :                     str << subnets[i].prefix.to_string();
     884           0 :                     str << "/";
     885           0 :                     str << subnets[i].plen;
     886           0 :                     net_list_sandesh.push_back(str.str());
     887           0 :                 }
     888             :             }
     889             :         }
     890             : 
     891           0 :         vdns_sandesh.set_virtual_dns(vdns_trace_data);
     892           0 :         vdns_sandesh.set_records(vdns_config->GetName());
     893           0 :         vdns_sandesh.set_num_records(vdns_config->virtual_dns_records_.size());
     894           0 :         vdns_sandesh.set_subnets(net_list_sandesh);
     895           0 :         vdns_list_sandesh.push_back(vdns_sandesh);
     896           0 :     }
     897             : 
     898           0 :     resp = new VirtualDnsServersResponse();
     899           0 :     resp->set_context(context);
     900           0 :     resp->set_virtual_dns_servers(vdns_list_sandesh);
     901           0 :     resp->set_more(true);
     902           0 :     resp->Response();
     903             : 
     904           0 :     Pagination *page = new Pagination();
     905           0 :     PageReqData req;
     906           0 :     MakeSandeshPageReq(&req, vdns, vdns_it, vdns_iter, key, " VdnsServersReq");
     907           0 :     page->set_context(context);
     908           0 :     page->set_req(req);
     909           0 :     page->Response();
     910             : 
     911           0 : }
     912             : 
     913           0 : void ShowDnsConfig::HandleRequest() const {
     914           0 :     DnsManager *dns_manager = Dns::GetDnsManager();
     915           0 :     if(dns_manager) {
     916           0 :         dns_manager->DnsConfigMsgHandler("", context());
     917             :     } else {
     918           0 :         SandeshError("Invalid Request No DnsManager Object", context());
     919             :     }
     920           0 : }
     921             : 
     922           0 : void DnsManager::DnsConfigMsgHandler(const std::string &key,
     923             :                                      const std::string &context) const {
     924           0 :     DnsConfigResponse *resp = new DnsConfigResponse();
     925           0 :     uint16_t count = 0;
     926           0 :     uint16_t sandesh_msg_limit = DnsManager::max_records_per_sandesh;
     927           0 :     VirtualDnsConfig::DataMap vdns = VirtualDnsConfig::GetVirtualDnsMap();
     928           0 :     VirtualDnsConfig::DataMap::iterator vdns_it, vdns_iter;
     929           0 :     std::vector<VirtualDnsSandesh> vdns_list_sandesh;
     930           0 :     if(key == "AllEntries") {
     931           0 :         sandesh_msg_limit = vdns.size();
     932           0 :         vdns_it = vdns.begin();
     933           0 :     } else if(key != "") {
     934           0 :         vdns_it = vdns.lower_bound(key);
     935             :     } else {
     936           0 :         vdns_it = vdns.begin();
     937             :     }
     938             : 
     939           0 :     for (vdns_iter = vdns_it; vdns_iter != vdns.end(); ++vdns_iter) {
     940           0 :         if (count++ == sandesh_msg_limit) {
     941           0 :             break;
     942             :         }
     943           0 :         VirtualDnsConfig *vdns_config = vdns_iter->second;
     944           0 :         VirtualDnsSandesh vdns_sandesh;
     945           0 :         VirtualDnsTraceData vdns_trace_data;
     946           0 :         vdns_config->VirtualDnsTrace(vdns_trace_data);
     947             : 
     948           0 :         std::vector<VirtualDnsRecordTraceData> rec_list_sandesh;
     949           0 :         for (VirtualDnsConfig::VDnsRec::iterator rec_it =
     950           0 :               vdns_config->virtual_dns_records_.begin();
     951           0 :             rec_it != vdns_config->virtual_dns_records_.end(); ++rec_it) {
     952           0 :             VirtualDnsRecordTraceData rec_trace_data;
     953           0 :             (*rec_it)->VirtualDnsRecordTrace(rec_trace_data);
     954           0 :             rec_list_sandesh.push_back(rec_trace_data);
     955           0 :         }
     956             : 
     957           0 :         std::vector<std::string> net_list_sandesh;
     958           0 :         for (VirtualDnsConfig::IpamList::iterator ipam_iter =
     959           0 :              vdns_config->ipams_.begin();
     960           0 :             ipam_iter != vdns_config->ipams_.end(); ++ipam_iter) {
     961           0 :             IpamConfig *ipam = *ipam_iter;
     962           0 :             const IpamConfig::VnniList &vnni = ipam->GetVnniList();
     963           0 :             for (IpamConfig::VnniList::iterator vnni_it = vnni.begin();
     964           0 :                  vnni_it != vnni.end(); ++vnni_it) {
     965           0 :                 Subnets &subnets = (*vnni_it)->GetSubnets();
     966           0 :                 for (unsigned int i = 0; i < subnets.size(); i++) {
     967           0 :                     std::stringstream str;
     968           0 :                     str << subnets[i].prefix.to_string();
     969           0 :                     str << "/";
     970           0 :                     str << subnets[i].plen;
     971           0 :                     net_list_sandesh.push_back(str.str());
     972           0 :                 }
     973             :             }
     974             :         }
     975             : 
     976           0 :         vdns_sandesh.set_virtual_dns(vdns_trace_data);
     977           0 :         vdns_sandesh.set_records(rec_list_sandesh);
     978           0 :         vdns_sandesh.set_subnets(net_list_sandesh);
     979           0 :         vdns_list_sandesh.push_back(vdns_sandesh);
     980           0 :     }
     981             : 
     982           0 :     resp->set_context(context);
     983           0 :     resp->set_virtual_dns(vdns_list_sandesh);
     984           0 :     resp->set_more(true);
     985           0 :     resp->Response();
     986             : 
     987           0 :     Pagination *page = new Pagination();
     988           0 :     PageReqData req;
     989           0 :     MakeSandeshPageReq(&req, vdns, vdns_it, vdns_iter, key, " DnsConfigReq");
     990           0 :     page->set_context(context);
     991           0 :     page->set_req(req);
     992           0 :     page->Response();
     993           0 : }
     994             : 
     995           0 : void ShowVirtualDnsRecords::HandleRequest() const {
     996           0 :     DnsManager *dns_manager = Dns::GetDnsManager();
     997           0 :     if(dns_manager) {
     998           0 :         dns_manager->VdnsRecordsMsgHandler(get_virtual_dns_server(), context());
     999             :     } else {
    1000           0 :         SandeshError("Invalid Request No DnsManager Object", context());
    1001             :     }
    1002           0 : }
    1003             : 
    1004           0 : void DnsManager::VdnsRecordsMsgHandler(const std::string &key,
    1005             :                                        const std::string &context, bool show_all) const {
    1006           0 :     VirtualDnsRecordsResponse *resp = new VirtualDnsRecordsResponse();
    1007           0 :     VirtualDnsConfig::DataMap vdns = VirtualDnsConfig::GetVirtualDnsMap();
    1008             : 
    1009           0 :     std::stringstream ss(key);
    1010           0 :     std::stringstream str;
    1011           0 :     std::string vdns_server, next_iterator;
    1012           0 :     VirtualDnsRecordConfig *next_iterator_key = NULL;
    1013           0 :     std::getline(ss, vdns_server, '@');
    1014           0 :     std::getline(ss, next_iterator);
    1015           0 :     uint16_t sandesh_msg_limit = DnsManager::max_records_per_sandesh;
    1016           0 :     if (!next_iterator.empty()) {
    1017           0 :         std::stringstream next_iter(next_iterator);
    1018           0 :         uint64_t value = 0;
    1019           0 :         next_iter >> value;
    1020           0 :         next_iterator_key = (VirtualDnsRecordConfig *) value;
    1021           0 :     }
    1022           0 :     std::vector<VirtualDnsRecordTraceData> rec_list_sandesh;
    1023           0 :     VirtualDnsConfig::VDnsRec::iterator rec_it, rec_it1;
    1024           0 :     VirtualDnsConfig::DataMap::iterator vdns_it = vdns.find(vdns_server);
    1025           0 :     if (vdns_it != vdns.end()) {
    1026           0 :         VirtualDnsConfig *vdns_config = vdns_it->second;
    1027           0 :         uint16_t count = 0;
    1028           0 :         uint16_t size = vdns_config->virtual_dns_records_.size();
    1029           0 :         if(show_all) {
    1030           0 :             rec_it1 = vdns_config->virtual_dns_records_.begin();
    1031           0 :             sandesh_msg_limit = size;
    1032             :         } else {
    1033           0 :             rec_it1 = vdns_config->virtual_dns_records_.lower_bound(next_iterator_key);
    1034             :         }
    1035           0 :         for(rec_it = rec_it1;
    1036           0 :              rec_it != vdns_config->virtual_dns_records_.end(); ++rec_it) {
    1037           0 :             VirtualDnsRecordTraceData rec_trace_data;
    1038           0 :             (*rec_it)->VirtualDnsRecordTrace(rec_trace_data);
    1039           0 :             rec_list_sandesh.push_back(rec_trace_data);
    1040           0 :             if (++count == sandesh_msg_limit) {
    1041           0 :                 if (++rec_it == vdns_config->virtual_dns_records_.end())
    1042           0 :                     break;
    1043           0 :                 uint64_t value = (uint64_t)(*rec_it);
    1044           0 :                 str << vdns_server << "@" << value;
    1045           0 :                 break;
    1046             :             }
    1047           0 :         }
    1048             : 
    1049           0 :         resp->set_context(context);
    1050           0 :         resp->set_virtual_dns_server(vdns_server);
    1051           0 :         resp->set_records(rec_list_sandesh);
    1052           0 :         resp->set_more(true);
    1053           0 :         resp->Response();
    1054             : 
    1055           0 :         Pagination *page = new Pagination();
    1056           0 :         PageReqData req;
    1057             : 
    1058             :         // Set table size
    1059           0 :         req.set_table_size(size);
    1060             : 
    1061             :         //Next page link
    1062           0 :         if(rec_it != vdns_config->virtual_dns_records_.end()) {
    1063           0 :             req.set_next_page(str.str() + " VdnsRecordsReq");
    1064             :         }
    1065             : 
    1066             :         // First page link
    1067           0 :         if(size != 0) {
    1068           0 :             std::stringstream str;
    1069           0 :             uint64_t value = (uint64_t)(*(vdns_config->virtual_dns_records_.begin()));
    1070           0 :             str << vdns_server << "@" << value;
    1071           0 :             req.set_first_page(str.str() + " VdnsRecordsReq");
    1072           0 :         }
    1073             : 
    1074             :         // Set Entries
    1075           0 :         int start_entry=0, end_entry=0;
    1076           0 :         std::stringstream ss1, ss2;
    1077           0 :         if( size != 0) {
    1078           0 :             start_entry = std::distance(vdns_config->virtual_dns_records_.begin(), rec_it1);
    1079           0 :             start_entry++;
    1080           0 :             if(start_entry != size) {
    1081           0 :                 end_entry = std::distance(vdns_config->virtual_dns_records_.begin(), --rec_it);
    1082           0 :                 end_entry++;
    1083             :             } else {
    1084           0 :                 end_entry = start_entry;
    1085             :             }
    1086             :         }
    1087             : 
    1088           0 :         ss1 << start_entry;
    1089           0 :         ss2 << end_entry;
    1090           0 :         req.set_entries(ss1.str() + " - " + ss2.str());
    1091             : 
    1092             :         // Previous page link
    1093           0 :         if(rec_it1 != vdns_config->virtual_dns_records_.begin()) {
    1094           0 :             for (int i=0; i < (sandesh_msg_limit); i++) {
    1095           0 :                 rec_it1--;
    1096           0 :                 if(rec_it1 == vdns_config->virtual_dns_records_.begin())
    1097           0 :                     break;
    1098             :             }
    1099           0 :             std::stringstream str;
    1100           0 :             uint64_t value = (uint64_t)(*rec_it1);
    1101           0 :             str << vdns_server << "@" << value;
    1102           0 :             req.set_prev_page(str.str() + " VdnsRecordsReq");
    1103           0 :         }
    1104             : 
    1105             :         // Set link to show all entries in a single page
    1106           0 :         std::stringstream str;
    1107           0 :         uint64_t value = 0;
    1108           0 :         str << vdns_server << "@" << value;
    1109           0 :         req.set_all(str.str() + " AllEntriesVdnsRecordsReq");
    1110             : 
    1111           0 :         page->set_context(context);
    1112           0 :         page->set_req(req);
    1113           0 :         page->Response();
    1114             : 
    1115           0 :     } else {
    1116           0 :         SandeshError("Invalid Request Enter Vdns Server Name", context);
    1117           0 :         delete resp;
    1118             :     }
    1119           0 : }
    1120             : 
    1121           0 : void ShowBindPendingList::HandleRequest() const {
    1122           0 :     DnsManager *dns_manager = Dns::GetDnsManager();
    1123           0 :     if(dns_manager) {
    1124           0 :         dns_manager->BindPendingMsgHandler("", context());
    1125             :     } else {
    1126           0 :         SandeshError("Invalid Request No DnsManager Object", context());
    1127             :     }
    1128           0 : }
    1129             : 
    1130           0 : void DnsManager::BindPendingMsgHandler(const std::string &key,
    1131             :                                        const std::string &context) const {
    1132           0 :     BindPendingListResponse *resp = new BindPendingListResponse();
    1133           0 :     DnsManager *dns_manager = Dns::GetDnsManager();
    1134           0 :     if (dns_manager) {
    1135           0 :         uint16_t count =0;
    1136           0 :         uint16_t index=0;
    1137           0 :         stringToInteger(key, index);
    1138           0 :         uint16_t sandesh_msg_limit = DnsManager::max_records_per_sandesh;
    1139             :         DnsManager::PendingListMap map =
    1140           0 :             dns_manager->GetDeportedPendingListMap();
    1141           0 :         uint16_t size = map.size();
    1142             :         std::vector<PendingListEntry> &pending_list =
    1143           0 :             const_cast<std::vector<PendingListEntry>&>(resp->get_data());
    1144           0 :         DnsManager::PendingListMap::iterator map_it, map_iter;
    1145           0 :         if(key == "AllEntries") {
    1146           0 :             sandesh_msg_limit = size;
    1147           0 :             map_it = map.begin();
    1148             :         }
    1149           0 :         else if(key != "") {
    1150           0 :             map_it = map.lower_bound(index);
    1151             :         }
    1152             :         else {
    1153           0 :             map_it = map.begin();
    1154             :         }
    1155             : 
    1156           0 :         for (map_iter = map_it; map_iter!= map.end(); ++map_iter) {
    1157           0 :             if (count++ == sandesh_msg_limit) {
    1158           0 :                 break;
    1159             :             }
    1160           0 :             PendingListEntry entry;
    1161           0 :             entry.set_xid(map_iter->second.xid);
    1162           0 :             entry.set_view(map_iter->second.view);
    1163           0 :             entry.set_zone(map_iter->second.zone);
    1164           0 :             entry.set_retry_count(map_iter->second.retransmit_count);
    1165           0 :             entry.set_items(DnsItemsToString(map_iter->second.items));
    1166             : 
    1167           0 :             pending_list.push_back(entry);
    1168           0 :         }
    1169             : 
    1170           0 :         resp->set_context(context);
    1171           0 :         resp->set_more(true);
    1172           0 :         resp->Response();
    1173             : 
    1174           0 :         Pagination *page = new Pagination();
    1175           0 :         PageReqData req;
    1176             : 
    1177             :         // Set table size
    1178           0 :         req.set_table_size(size);
    1179             : 
    1180             :         //Next page link
    1181           0 :         if(map_iter != map.end()) {
    1182           0 :             std::stringstream ss;
    1183           0 :             ss << map_iter->first;
    1184           0 :             req.set_next_page(ss.str() + " BindPendingListReq");
    1185           0 :         }
    1186             : 
    1187             :         // First page link
    1188           0 :         if(size != 0) {
    1189           0 :             std::stringstream ss;
    1190           0 :             ss << map.begin()->first;
    1191           0 :             req.set_first_page(ss.str()+ " BindPendingListReq");
    1192           0 :         }
    1193             : 
    1194             :         // Set Entries
    1195           0 :         int start_entry=0, end_entry=0;
    1196           0 :         std::stringstream ss1, ss2;
    1197           0 :         if(size != 0) {
    1198           0 :             start_entry = std::distance(map.begin(), map_it);
    1199           0 :             start_entry++;
    1200           0 :             if(start_entry != size) {
    1201           0 :                 end_entry = std::distance(map.begin(), --map_iter);
    1202           0 :                 end_entry++;
    1203             :             } else {
    1204           0 :                 end_entry = start_entry;
    1205             :             }
    1206             : 
    1207             :         }
    1208           0 :         ss1 << start_entry;
    1209           0 :         ss2 << end_entry;
    1210           0 :         req.set_entries(ss1.str() + " - " + ss2.str());
    1211             : 
    1212             :         // Previous page link
    1213           0 :         if(map_it != map.begin()) {
    1214           0 :             for (int i=0; i < (sandesh_msg_limit); i++) {
    1215           0 :                 map_it--;
    1216           0 :                 if(map_it == map.begin())
    1217           0 :                     break;
    1218             :             }
    1219           0 :             std::stringstream ss;
    1220           0 :             ss << map_it->first;
    1221           0 :             req.set_prev_page(ss.str() + " BindPendingListReq");
    1222           0 :         }
    1223             : 
    1224             :         // Set link to show all entries in a single page
    1225           0 :         req.set_all("AllEntries BindPendingListReq");
    1226             : 
    1227           0 :         page->set_context(context);
    1228           0 :         page->set_req(req);
    1229           0 :         page->Response();
    1230             : 
    1231           0 :     } else {
    1232           0 :         SandeshError("Invalid Request No DnsManager Object ", context);
    1233           0 :         delete resp;
    1234             :     }
    1235           0 : }
    1236             : 
    1237           0 : void PageReq::HandleRequest() const {
    1238           0 :     string req_name, search_key;
    1239           0 :     vector<string> tokens;
    1240           0 :     boost::split(tokens, get_key(), boost::is_any_of(" "));
    1241           0 :     DnsManager *dns_manager = Dns::GetDnsManager();
    1242           0 :     if(dns_manager && (tokens.size() == 2)) {
    1243           0 :         search_key = tokens[0];
    1244           0 :         req_name = tokens[1];
    1245           0 :         if(req_name == "VdnsServersReq") {
    1246           0 :             dns_manager->VdnsServersMsgHandler(search_key, context());
    1247           0 :         } else if(req_name == "DnsConfigReq") {
    1248           0 :             dns_manager->DnsConfigMsgHandler(search_key, context());
    1249           0 :         } else if(req_name == "VdnsRecordsReq") {
    1250           0 :             dns_manager->VdnsRecordsMsgHandler(search_key, context());
    1251           0 :         } else if(req_name == "AllEntriesVdnsRecordsReq") {
    1252           0 :             dns_manager->VdnsRecordsMsgHandler(search_key, context(), true);
    1253           0 :         } else if (req_name == "BindPendingListReq") {
    1254           0 :             dns_manager->BindPendingMsgHandler(search_key, context());
    1255             :         } else {
    1256           0 :             SandeshError("Invalid Request", context());
    1257             :         }
    1258             :     } else {
    1259           0 :         SandeshError("Invalid Request", context());
    1260             :     }
    1261           0 : }
    1262             : 
    1263           0 : void ShowGlobalQosConfig::HandleRequest() const {
    1264           0 :     GlobalQosConfigResponse *resp = new GlobalQosConfigResponse();
    1265           0 :     GlobalQosConfig *obj = GlobalQosConfig::Find("");
    1266           0 :     resp->set_control_dscp(obj->control_dscp_);
    1267           0 :     resp->set_analytics_dscp(obj->analytics_dscp_);
    1268           0 :     resp->set_context(context());
    1269           0 :     resp->set_more(false);
    1270           0 :     resp->Response();
    1271           0 : }

Generated by: LCOV version 1.14