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

Generated by: LCOV version 1.14