LCOV - code coverage report
Current view: top level - vnsw/agent/controller - controller_dns.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 0 101 0.0 %
Date: 2026-06-18 01:51:13 Functions: 0 16 0.0 %
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/util.h"
       6             : #include "base/logging.h"
       7             : #include "base/connection_info.h"
       8             : #include "base/address_util.h"
       9             : #include "cmn/agent_cmn.h"
      10             : #include "controller/controller_dns.h"
      11             : #include "controller/controller_init.h"
      12             : #include "xmpp/xmpp_channel.h"
      13             : #include "pugixml/pugixml.hpp"
      14             : #include "xml/xml_pugi.h"
      15             : #include "bind/xmpp_dns_agent.h"
      16             : 
      17             : using process::ConnectionState;
      18             : using process::ConnectionType;
      19             : using process::ConnectionStatus;
      20             : 
      21             : AgentDnsXmppChannel::DnsMessageHandler AgentDnsXmppChannel::dns_message_handler_cb_;
      22             : AgentDnsXmppChannel::DnsXmppEventHandler AgentDnsXmppChannel::dns_xmpp_event_handler_cb_;
      23             : 
      24           0 : AgentDnsXmppChannel::AgentDnsXmppChannel(Agent *agent,
      25           0 :       std::string xmpp_server, uint8_t xs_idx)
      26           0 :     : channel_(NULL), xmpp_server_(xmpp_server), xs_idx_(xs_idx),
      27           0 :     agent_(agent) {
      28           0 : }
      29             : 
      30           0 : AgentDnsXmppChannel::~AgentDnsXmppChannel() {
      31           0 :     if (channel_) {
      32           0 :         channel_->UnRegisterWriteReady(xmps::DNS);
      33           0 :         channel_->UnRegisterReceive(xmps::DNS);
      34             :     }
      35           0 : }
      36             : 
      37           0 : void AgentDnsXmppChannel::RegisterXmppChannel(XmppChannel *channel) {
      38           0 :     if (channel == NULL)
      39           0 :         return;
      40             : 
      41           0 :     channel_ = channel;
      42           0 :     channel->RegisterReceive(xmps::DNS,
      43             :             boost::bind(&AgentDnsXmppChannel::ReceiveInternal, this, _1));
      44             : }
      45             : 
      46           0 : bool AgentDnsXmppChannel::SendMsg(uint8_t *msg, std::size_t len) {
      47           0 :     if (!channel_ || channel_->GetPeerState() != xmps::READY)
      48           0 :         return false;
      49             : 
      50           0 :     return channel_->Send((const uint8_t *)msg, len, xmps::DNS,
      51           0 :             boost::bind(&AgentDnsXmppChannel::WriteReadyCb, this, _1));
      52             : }
      53             : 
      54           0 : void AgentDnsXmppChannel::ReceiveMsg(const XmppStanza::XmppMessage *msg) {
      55           0 :     if (msg && msg->type == XmppStanza::IQ_STANZA) {
      56           0 :         std::unique_ptr<XmlBase> impl(XmppXmlImplFactory::Instance()->GetXmlImpl());
      57           0 :         XmlPugi *pugi = reinterpret_cast<XmlPugi *>(impl.get());
      58           0 :         XmlPugi *msg_pugi = reinterpret_cast<XmlPugi *>(msg->dom.get());
      59           0 :         pugi->LoadXmlDoc(msg_pugi->doc()); //Verify Xmpp message format
      60             :         boost::shared_ptr<ControllerXmppData> data(new ControllerXmppData(xmps::DNS,
      61             :                                                                           xmps::UNKNOWN,
      62           0 :                                                                           xs_idx_,
      63           0 :                                                                           std::move(impl),
      64           0 :                                                                           true));
      65           0 :         agent_->controller()->Enqueue(data);
      66           0 :     }
      67           0 : }
      68             : 
      69           0 : void AgentDnsXmppChannel::ReceiveInternal(const XmppStanza::XmppMessage *msg) {
      70           0 :     ReceiveMsg(msg);
      71           0 : }
      72             : 
      73           0 : void AgentDnsXmppChannel::ReceiveDnsMessage(std::unique_ptr<XmlBase> impl) {
      74           0 :     XmlPugi *pugi = reinterpret_cast<XmlPugi *>(impl.get());
      75           0 :     pugi::xml_node node = pugi->FindNode("dns");
      76             :     DnsAgentXmpp::XmppType xmpp_type;
      77             :     uint32_t xid;
      78             :     uint16_t code;
      79           0 :     std::unique_ptr<DnsUpdateData> xmpp_data(new DnsUpdateData);
      80           0 :     if (DnsAgentXmpp::DnsAgentXmppDecode(node, xmpp_type, xid,
      81             :                                          code, xmpp_data.get())) {
      82           0 :         if (!dns_message_handler_cb_.empty())
      83           0 :             dns_message_handler_cb_(xmpp_data.release(), xmpp_type,
      84             :                                     NULL, false);
      85             :     }
      86           0 : }
      87             : 
      88           0 : std::string AgentDnsXmppChannel::ToString() const {
      89           0 :     return channel_->ToString();
      90             : }
      91             : 
      92           0 : void AgentDnsXmppChannel::WriteReadyCb(const boost::system::error_code &ec) {
      93           0 : }
      94             : 
      95           0 : void AgentDnsXmppChannel::XmppClientChannelEvent(AgentDnsXmppChannel *peer,
      96             :                                                  xmps::PeerState state) {
      97           0 :     std::unique_ptr<XmlBase> dummy_dom;
      98             :     boost::shared_ptr<ControllerXmppData> data(new ControllerXmppData(xmps::DNS,
      99             :                                                                       state,
     100           0 :                                                                       peer->GetXmppServerIdx(),
     101           0 :                                                                       std::move(dummy_dom),
     102           0 :                                                                       false));
     103           0 :     peer->agent()->controller()->Enqueue(data);
     104           0 : }
     105             : 
     106             : /*
     107             :  * AgentDnsXmppChannel state TimedOut
     108             :  *
     109             :  * If there are more than two channels available in config, then try picking
     110             :  * other channel to replace this timed out channel. And push this channel at the
     111             :  * end of the channel list so that it is picked only in worst case.
     112             :  *
     113             :  * If there are only two channels configured, no action to be taken.
     114             :  */
     115           0 : void AgentDnsXmppChannel::TimedOut() {
     116           0 :     bool update_list = false;
     117           0 :     std::vector<string>::iterator iter = agent_->GetDnslist().begin();
     118           0 :     std::vector<string>::iterator end = agent_->GetDnslist().end();
     119           0 :     for (; iter != end; iter++) {
     120           0 :         std::vector<string> server;
     121           0 :         boost::split(server, *iter, boost::is_any_of(":"));
     122           0 :         if (GetXmppServer().compare(server[0]) == 0) {
     123             :             // Add the TIMEDOUT server to the end.
     124           0 :             if (iter + 1 == end) break;
     125           0 :             std::rotate(iter, iter + 1, end);
     126           0 :             update_list = true;
     127           0 :             break;
     128             :         }
     129           0 :     }
     130           0 :     if (update_list) {
     131           0 :         agent_->controller()->ReConnectDnsServer();
     132             :     }
     133           0 : }
     134             : 
     135           0 : void AgentDnsXmppChannel::HandleXmppClientChannelEvent(AgentDnsXmppChannel *peer,
     136             :                                                        xmps::PeerState state) {
     137           0 :     peer->UpdateConnectionInfo(state);
     138           0 :     if (state == xmps::READY) {
     139           0 :         if (!peer->dns_xmpp_event_handler_cb_.empty())
     140           0 :             peer->dns_xmpp_event_handler_cb_(peer);
     141           0 :     } else if (state == xmps::TIMEDOUT) {
     142           0 :         peer->TimedOut();
     143             :     }
     144           0 : }
     145             : 
     146           0 : void AgentDnsXmppChannel::set_dns_message_handler_cb(DnsMessageHandler cb) {
     147           0 :     dns_message_handler_cb_ = cb;
     148           0 : }
     149             : 
     150           0 : void AgentDnsXmppChannel::set_dns_xmpp_event_handler_cb(DnsXmppEventHandler cb){
     151           0 :     dns_xmpp_event_handler_cb_ = cb;
     152           0 : }
     153             : 
     154           0 : void AgentDnsXmppChannel::UpdateConnectionInfo(xmps::PeerState state) {
     155           0 :     if (agent_->connection_state() == NULL)
     156           0 :         return;
     157             : 
     158           0 :     boost::asio::ip::tcp::endpoint ep;
     159           0 :     boost::system::error_code ec;
     160           0 :     std::string last_state_name;
     161           0 :     ep.address(AddressFromString(agent_->dns_server(xs_idx_), &ec));
     162           0 :     ep.port(agent_->dns_server_port(xs_idx_));
     163           0 :     const std::string name = agent_->xmpp_dns_server_prefix() +
     164           0 :                              ep.address().to_string();
     165           0 :     XmppChannel *xc = GetXmppChannel();
     166           0 :     if (xc) {
     167           0 :         last_state_name = xc->LastStateName();
     168             :     }
     169           0 :     if (state == xmps::READY) {
     170           0 :         agent_->connection_state()->Update(ConnectionType::XMPP, name,
     171             :                                            ConnectionStatus::UP, ep,
     172             :                                            last_state_name);
     173             :     } else {
     174           0 :         agent_->connection_state()->Update(ConnectionType::XMPP, name,
     175             :                                            ConnectionStatus::DOWN, ep,
     176             :                                            last_state_name);
     177             :     }
     178           0 : }

Generated by: LCOV version 1.14