LCOV - code coverage report
Current view: top level - dns/agent - agent_xmpp_channel.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 0 209 0.0 %
Date: 2026-11-09 02:10:49 Functions: 0 22 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : #include "base/logging.h"
       7             : #include "base/task_trigger.h"
       8             : #include <pugixml/pugixml.hpp>
       9             : #include "agent/agent_xmpp_channel.h"
      10             : 
      11             : #include "xml/xml_pugi.h"
      12             : #include "xmpp/xmpp_connection.h"
      13             : #include "xmpp/xmpp_server.h"
      14             : #include "cmn/dns.h"
      15             : #include "mgr/dns_mgr.h"
      16             : #include "mgr/dns_oper.h"
      17             : #include "bind/bind_util.h"
      18             : #include "bind/bind_resolver.h"
      19             : #include "bind/named_config.h"
      20             : #include "bind/xmpp_dns_agent.h"
      21             : #include "sandesh/sandesh_trace.h"
      22             : #include "cmn/dns_types.h"
      23             : 
      24           0 : DnsAgentXmppChannel:: DnsAgentXmppChannel(XmppChannel *channel,
      25           0 :                                           DnsAgentXmppChannelManager *mgr)
      26           0 :                                         : channel_(channel), mgr_(mgr) {
      27           0 :     channel_->RegisterReceive(xmps::DNS,
      28             :                      boost::bind(&DnsAgentXmppChannel::ReceiveReq, this, _1));
      29             : 
      30           0 : }
      31             : 
      32           0 : DnsAgentXmppChannel::~DnsAgentXmppChannel() {
      33           0 :     channel_->UnRegisterWriteReady(xmps::DNS);
      34           0 :     channel_->UnRegisterReceive(xmps::DNS);
      35           0 : }
      36             : 
      37           0 : void DnsAgentXmppChannel::Close() {
      38           0 :     UpdateDnsRecords(BindUtil::DELETE_UPDATE);
      39           0 :     if (mgr_)
      40           0 :         mgr_->RemoveChannel(channel_);
      41           0 : }
      42             : 
      43           0 : void DnsAgentXmppChannel::ReceiveReq(const XmppStanza::XmppMessage *msg) {
      44           0 :     if (msg && msg->type == XmppStanza::IQ_STANZA) {
      45           0 :         XmlBase *impl = msg->dom.get();
      46           0 :         XmlPugi *pugi = reinterpret_cast<XmlPugi *>(impl);
      47           0 :         pugi::xml_node node = pugi->FindNode("dns");
      48             :         DnsAgentXmpp::XmppType type;
      49           0 :         std::string source_name = msg->from;
      50             :         uint32_t xid;
      51             :         uint16_t code;
      52           0 :         std::unique_ptr<DnsUpdateData> rcv_data(new DnsUpdateData());
      53           0 :         DnsUpdateData *data = rcv_data.get();
      54           0 :         if (DnsAgentXmpp::DnsAgentXmppDecode(node, type, xid, code, data, source_name)) {
      55           0 :             if (type == DnsAgentXmpp::Update) {
      56           0 :                 HandleAgentUpdate(std::move(rcv_data));
      57             :             }
      58             :         }
      59           0 :     }
      60           0 : }
      61             : 
      62           0 : void DnsAgentXmppChannel::HandleAgentUpdate(
      63             :     std::unique_ptr<DnsUpdateData> rcv_data) {
      64           0 :     DnsUpdateData *data = rcv_data.get();
      65           0 :     if (data->virtual_dns.empty() || data->zone.empty()) {
      66             :         // if key is not present, ignore the update
      67           0 :         return;
      68             :     }
      69           0 :     DataSet::iterator it = update_data_.find(data);
      70           0 :     if (it != update_data_.end()) {
      71           0 :         DnsUpdateData *xmpp_data = *it;
      72           0 :         for (DnsItems::iterator iter = data->items.begin();
      73           0 :              iter != data->items.end();) {
      74             :             bool change;
      75           0 :             BindUtil::Operation op = BindUtil::ADD_UPDATE;
      76           0 :             if ((*iter).IsDelete()) {
      77           0 :                 change = xmpp_data->DelItem(*iter);
      78           0 :                 op = BindUtil::DELETE_UPDATE;
      79             :             } else {
      80           0 :                 change = xmpp_data->AddItem(*iter, true);
      81           0 :                 if (!change) {
      82           0 :                     op = BindUtil::CHANGE_UPDATE;
      83           0 :                     change = true;
      84             :                 }
      85             :             }
      86             : 
      87           0 :             if (!change) {
      88           0 :                 data->items.erase(iter++);
      89             :             } else {
      90             :                 boost::shared_ptr<DnsAgentXmppChannelManager::RecordRequest>
      91             :                     req(new DnsAgentXmppChannelManager::RecordRequest(
      92           0 :                             op, GetDnsRecordName(data->virtual_dns, *iter),
      93           0 :                             data->virtual_dns, *iter));
      94           0 :                 mgr_->EnqueueRecord(req);
      95           0 :                 ++iter;
      96           0 :             }
      97             :         }
      98           0 :         if (!xmpp_data->items.size()) {
      99           0 :             update_data_.erase(xmpp_data);
     100           0 :             delete xmpp_data;
     101             :         }
     102             :     } else {
     103           0 :         for (DnsItems::iterator iter = data->items.begin();
     104           0 :              iter != data->items.end();) {
     105           0 :             if ((*iter).IsDelete())
     106           0 :                 data->items.erase(iter++);
     107             :             else {
     108             :                 boost::shared_ptr<DnsAgentXmppChannelManager::RecordRequest>
     109             :                     req(new DnsAgentXmppChannelManager::RecordRequest(
     110             :                             BindUtil::ADD_UPDATE,
     111           0 :                             GetDnsRecordName(data->virtual_dns, *iter),
     112           0 :                             data->virtual_dns, *iter));
     113           0 :                 mgr_->EnqueueRecord(req);
     114           0 :                 ++iter;
     115           0 :             }
     116             :         }
     117           0 :         update_data_.insert(data);
     118           0 :         rcv_data.release();
     119             :     }
     120             : }
     121             : 
     122           0 : void DnsAgentXmppChannel::UpdateDnsRecords(BindUtil::Operation op) {
     123           0 :     for (DataSet::iterator it = update_data_.begin();
     124           0 :          it != update_data_.end(); ++it) {
     125           0 :         for (DnsItems::const_iterator item = (*it)->items.begin();
     126           0 :              item != (*it)->items.end(); ++item) {
     127             :             boost::shared_ptr<DnsAgentXmppChannelManager::RecordRequest>
     128             :                 req(new DnsAgentXmppChannelManager::RecordRequest(
     129           0 :                         op, GetDnsRecordName((*it)->virtual_dns, *item),
     130           0 :                         (*it)->virtual_dns, *item));
     131           0 :             mgr_->EnqueueRecord(req);
     132           0 :         }
     133             :     }
     134           0 : }
     135             : 
     136           0 : std::string DnsAgentXmppChannel::GetDnsRecordName(std::string &vdns_name,
     137             :                                                   const DnsItem &item) {
     138           0 :     std::stringstream str;
     139           0 :     str << vdns_name << ":" << item.type << ":" << item.name << ":" << item.data;
     140           0 :     return str.str();
     141           0 : }
     142             : 
     143           0 : void DnsAgentXmppChannel::GetAgentDnsData(AgentDnsData &data) {
     144           0 :     data.set_agent(channel_->connection()->endpoint().address().to_string());
     145           0 :     std::vector<AgentDnsDataItem> items;
     146           0 :     for (DataSet::iterator it = update_data_.begin();
     147           0 :          it != update_data_.end(); ++it) {
     148           0 :         AgentDnsDataItem item;
     149           0 :         item.set_virtual_dns((*it)->virtual_dns);
     150           0 :         item.set_zone((*it)->zone);
     151           0 :         std::vector<VirtualDnsRecordTraceData> records;
     152           0 :         for (DnsItems::iterator iter = (*it)->items.begin();
     153           0 :              iter != (*it)->items.end(); ++iter) {
     154           0 :             VirtualDnsRecordTraceData record;
     155           0 :             record.rec_name = (*iter).name;
     156           0 :             record.rec_type = BindUtil::DnsType((*iter).type);
     157           0 :             record.rec_class = "IN";
     158           0 :             record.rec_data = (*iter).data;
     159           0 :             record.rec_ttl = (*iter).ttl;
     160           0 :             record.source = "Agent";
     161           0 :             record.installed = "yes";
     162           0 :             record.rec_source_name = (*iter).source_name;
     163           0 :             record.rec_vm_uuid = (*iter).vm_uuid;
     164           0 :             records.push_back(record);
     165           0 :         }
     166           0 :         item.set_records(records);
     167           0 :         items.push_back(item);
     168           0 :     }
     169           0 :     data.set_agent_data(items);
     170           0 : }
     171             : 
     172           0 : DnsAgentXmppChannelManager::DnsAgentXmppChannelManager(
     173           0 :                             XmppServer *server)
     174           0 :     : server_(server),
     175           0 :       work_queue_(TaskScheduler::GetInstance()->GetTaskId("dns::Config"), 0,
     176             :                   boost::bind(&DnsAgentXmppChannelManager::ProcessRecord,
     177           0 :                               this, _1)) {
     178           0 :     if (server_) {
     179           0 :         server_->RegisterConnectionEvent(xmps::DNS,
     180             :         boost::bind(&DnsAgentXmppChannelManager::HandleXmppChannelEvent,
     181             :                     this, _1, _2));
     182             :     }
     183           0 : }
     184             : 
     185           0 : DnsAgentXmppChannelManager::~DnsAgentXmppChannelManager() {
     186           0 :     if (server_)
     187           0 :         server_->UnRegisterConnectionEvent(xmps::DNS);
     188           0 :     channel_map_.clear();
     189           0 :     work_queue_.Shutdown();
     190           0 : }
     191             : 
     192           0 : bool DnsAgentXmppChannelManager::ProcessRecord(
     193             :                                  boost::shared_ptr<RecordRequest> req) {
     194           0 :     Dns::GetDnsManager()->ProcessAgentUpdate(req->op, req->record_name,
     195           0 :                                              req->vdns_name, req->item);
     196           0 :     return true;
     197             : }
     198             : 
     199           0 : void DnsAgentXmppChannelManager::EnqueueRecord(
     200             :                                  boost::shared_ptr<RecordRequest> req) {
     201           0 :     work_queue_.Enqueue(req);
     202           0 : }
     203             : 
     204           0 : void DnsAgentXmppChannelManager::RemoveChannel(XmppChannel *ch) {
     205           0 :     channel_map_.erase(ch);
     206           0 : }
     207             : 
     208             : DnsAgentXmppChannel *
     209           0 : DnsAgentXmppChannelManager::DnsAgentXmppChannelManager::FindChannel(
     210             :     const XmppChannel *ch) {
     211           0 :     std::scoped_lock lock(mutex_);
     212           0 :     ChannelMap::iterator it = channel_map_.find(ch);
     213           0 :     if (it == channel_map_.end())
     214           0 :         return NULL;
     215           0 :     return it->second;
     216           0 : }
     217             : 
     218             : void
     219           0 : DnsAgentXmppChannelManager::HandleXmppChannelEvent(XmppChannel *channel,
     220             :                                                    xmps::PeerState state) {
     221           0 :     std::scoped_lock lock(mutex_);
     222           0 :     ChannelMap::iterator it = channel_map_.find(channel);
     223             : 
     224           0 :     if (state == xmps::READY) {
     225           0 :         if (it == channel_map_.end()) {
     226             :             DnsAgentXmppChannel *agent_xmpp_channel =
     227           0 :                             new DnsAgentXmppChannel(channel, this);
     228           0 :             channel_map_.insert(std::make_pair(channel, agent_xmpp_channel));
     229             :             ConfigClientManager *config_manager =
     230           0 :                 Dns::GetDnsManager()->get_config_manager();
     231           0 :             if (config_manager && !config_manager->GetEndOfRibComputed()) {
     232           0 :                 DNS_XMPP_TRACE(DnsXmppTrace, "Peer:" + channel->PeerAddress() +
     233             :                                " Close due to EndofRib not computed");
     234           0 :                 channel->Close();
     235             :             }
     236             :         }
     237           0 :     } else if (state == xmps::NOT_READY) {
     238           0 :         if (it != channel_map_.end()) {
     239           0 :             DnsAgentXmppChannel *agent_xmpp_channel = (*it).second;
     240           0 :             agent_xmpp_channel->Close();
     241           0 :             delete agent_xmpp_channel;
     242             :         } else {
     243           0 :             DNS_XMPP_TRACE(DnsXmppTrace,
     244             :                            "Peer not found on channel not ready event");
     245             :         }
     246             :     }
     247           0 : }
     248             : 
     249           0 : uint8_t DnsAgentXmppChannelManager::ChannelToDscp(const XmppChannel *xc) const {
     250           0 :     const XmppConnection *conn = xc->connection();
     251           0 :     if (conn) {
     252           0 :         const XmppSession *sess = conn->session();
     253           0 :         if (sess) {
     254           0 :             return sess->GetDscpValue();
     255             :         }
     256             :     }
     257           0 :     return 0;
     258             : }
     259             : 
     260           0 : void DnsAgentXmppChannelManager::GetAgentData(std::vector<AgentData> &list) {
     261           0 :     std::scoped_lock lock(mutex_);
     262           0 :     for (ChannelMap::iterator iter = channel_map_.begin();
     263           0 :          iter != channel_map_.end(); ++iter) {
     264           0 :         const XmppChannel *channel = iter->first;
     265           0 :         AgentData agent_data;
     266           0 :         agent_data.set_peer(channel->ToString());
     267           0 :         agent_data.set_peer_address(
     268           0 :             channel->connection()->endpoint().address().to_string());
     269           0 :         agent_data.set_local_address(
     270           0 :             channel->connection()->local_endpoint().address().to_string());
     271           0 :         agent_data.set_state(channel->StateName());
     272           0 :         agent_data.set_last_event(channel->LastEvent());
     273           0 :         agent_data.set_last_state(channel->LastStateName());
     274           0 :         agent_data.set_last_state_at(channel->LastStateChangeAt());
     275           0 :         agent_data.set_dscp(ChannelToDscp(channel));
     276           0 :         list.push_back(agent_data);
     277           0 :     }
     278           0 : }
     279             : 
     280           0 : void DnsAgentXmppChannelManager::GetAgentDnsData(std::vector<AgentDnsData> &dt) {
     281           0 :     std::scoped_lock lock(mutex_);
     282           0 :     for (ChannelMap::iterator iter = channel_map_.begin();
     283           0 :          iter != channel_map_.end(); ++iter) {
     284           0 :         DnsAgentXmppChannel *ch = iter->second;
     285           0 :         AgentDnsData data;
     286           0 :         ch->GetAgentDnsData(data);
     287           0 :         dt.push_back(data);
     288           0 :     }
     289           0 : }
     290             : 
     291           0 : void ShowAgentList::HandleRequest() const {
     292           0 :     DnsAgentListResponse *resp = new DnsAgentListResponse();
     293           0 :     resp->set_context(context());
     294             : 
     295           0 :     std::vector<AgentData> agent_list_sandesh;
     296           0 :     Dns::GetAgentXmppChannelManager()->GetAgentData(agent_list_sandesh);
     297             : 
     298           0 :     resp->set_agent(agent_list_sandesh);
     299           0 :     resp->Response();
     300           0 : }
     301             : 
     302           0 : void ShowAgentXmppDnsData::HandleRequest() const {
     303           0 :     AgentXmppDnsDataResponse *resp = new AgentXmppDnsDataResponse();
     304           0 :     resp->set_context(context());
     305             : 
     306           0 :     std::vector<AgentDnsData> agent_data;
     307           0 :     Dns::GetAgentXmppChannelManager()->GetAgentDnsData(agent_data);
     308             : 
     309           0 :     resp->set_data(agent_data);
     310           0 :     resp->Response();
     311           0 : }

Generated by: LCOV version 1.14