LCOV - code coverage report
Current view: top level - xmpp - xmpp_channel_mux.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 100 161 62.1 %
Date: 2026-10-05 02:12:29 Functions: 23 44 52.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include "xmpp/xmpp_channel_mux.h"
       6             : 
       7             : #include <boost/foreach.hpp>
       8             : 
       9             : #include "base/task_annotations.h"
      10             : #include "xmpp/xmpp_init.h"
      11             : #include "xmpp/xmpp_connection.h"
      12             : 
      13             : using namespace std;
      14             : using namespace xmsm;
      15             : 
      16         516 : XmppChannelMux::XmppChannelMux(XmppConnection *connection)
      17         516 :     : connection_(connection), rx_message_trace_cb_(NULL),
      18        1032 :       tx_message_trace_cb_(NULL) {
      19         516 :         last_received_ = 0;
      20         516 :         last_sent_ = 0;
      21         516 : }
      22             : 
      23         607 : XmppChannelMux::~XmppChannelMux() {
      24         516 :     assert(map_.empty());
      25         607 : }
      26             : 
      27           4 : void XmppChannelMux::Close() {
      28           4 :     connection_->Clear();
      29           4 : }
      30             : 
      31        1196 : bool XmppChannelMux::LastReceived(time_t duration) const {
      32        1196 :     return (UTCTimestamp() - last_received_) <= duration;
      33             : }
      34             : 
      35         283 : bool XmppChannelMux::LastSent(time_t duration) const {
      36         283 :     return (UTCTimestamp() - last_sent_) <= duration;
      37             : }
      38             : 
      39      488875 : xmps::PeerState XmppChannelMux::GetPeerState() const {
      40      488875 :     xmsm::XmState st = connection_->GetStateMcState();
      41      488887 :     return (st == xmsm::ESTABLISHED) ? xmps::READY :
      42      488887 :                                        xmps::NOT_READY;
      43             : }
      44             : 
      45           0 : void XmppChannelMux::WriteReady(const boost::system::error_code &ec) {
      46           0 :     std::scoped_lock lock(mutex_);
      47             : 
      48           0 :     WriteReadyCbMap::iterator iter = map_.begin();
      49           0 :     WriteReadyCbMap::iterator next = iter;
      50           0 :     for (; iter != map_.end(); iter = next) {
      51           0 :         ++next;
      52           0 :         SendReadyCb cb = iter->second;
      53           0 :         cb(ec);
      54           0 :         map_.erase(iter);
      55           0 :     }
      56           0 : }
      57             : 
      58      234416 : bool XmppChannelMux::Send(const uint8_t *msg, size_t msgsize,
      59             :                           const string *msg_str, xmps::PeerId id,
      60             :                           SendReadyCb cb) {
      61      234416 :     if (!connection_) return false;
      62             : 
      63      234416 :     std::scoped_lock lock(mutex_);
      64      234523 :     last_sent_ = UTCTimestamp();
      65      234541 :     bool res = connection_->Send(msg, msgsize, msg_str);
      66      234507 :     if (res == false) {
      67           8 :         RegisterWriteReady(id, cb);
      68             :     }
      69      234507 :     return res;
      70      234507 : }
      71             : 
      72         856 : int XmppChannelMux::GetTaskInstance() const {
      73         856 :     return connection_->GetTaskInstance();
      74             : }
      75             : 
      76         392 : void XmppChannelMux::RegisterReferer(xmps::PeerId id) {
      77         392 :     referers_.insert(id);
      78         392 : }
      79             : 
      80         392 : void XmppChannelMux::UnRegisterReferer(xmps::PeerId id) {
      81         392 :     referers_.erase(id);
      82         392 : }
      83             : 
      84         591 : void XmppChannelMux::RegisterReceive(xmps::PeerId id, ReceiveCb cb) {
      85         591 :     rxmap_.insert(make_pair(id, cb));
      86         591 : }
      87             : 
      88         615 : void XmppChannelMux::UnRegisterReceive(xmps::PeerId id) {
      89         615 :     ReceiveCbMap::iterator it = rxmap_.find(id);
      90         615 :     if (it != rxmap_.end()) {
      91         587 :         rxmap_.erase(it);
      92             :     }
      93             : 
      94         615 :     if (ReceiverCount())
      95         212 :         return;
      96             : 
      97             :     XmppServerConnection *server_connection =
      98         455 :         dynamic_cast<XmppServerConnection *>(connection_);
      99             : 
     100             :     // If GracefulRestart helper mode close process is complete, restart the
     101             :     // state machine to form new session with the client.
     102         524 :     if (!connection_->IsDeleted() && server_connection &&
     103          69 :             server_connection->server()->IsGRHelperModeEnabled()) {
     104          52 :         server_connection->state_machine()->Initialize();
     105          52 :         return;
     106             :     }
     107             : 
     108         403 :     connection_->RetryDelete();
     109             : }
     110             : 
     111         524 : size_t XmppChannelMux::RefererCount() const {
     112         524 :     return referers_.size();
     113             : }
     114             : 
     115        1398 : size_t XmppChannelMux::ReceiverCount() const {
     116        1398 :     return rxmap_.size();
     117             : }
     118             : 
     119           0 : vector<string> XmppChannelMux::GetReceiverList() const {
     120           0 :     vector<string> receivers;
     121           0 :     for (const auto& value : rxmap_) {
     122           0 :         receivers.push_back(xmps::PeerIdToName(value.first));
     123             :     }
     124           0 :     return receivers;
     125           0 : }
     126             : 
     127             : //
     128             : // To be called after acquiring mutex
     129             : //
     130           8 : void XmppChannelMux::RegisterWriteReady(xmps::PeerId id, SendReadyCb cb) {
     131           8 :     map_.insert(make_pair(id, cb));
     132           8 : }
     133             : 
     134             : //
     135             : // To be called after acquiring mutex
     136             : //
     137         571 : void XmppChannelMux::UnRegisterWriteReady(xmps::PeerId id) {
     138         571 :     map_.erase(id);
     139         571 : }
     140             : 
     141      246385 : const std::string &XmppChannelMux::ToString() const {
     142      246385 :     return connection_->ToString();
     143             : }
     144             : 
     145           0 : const std::string &XmppChannelMux::FromString() const {
     146           0 :     return connection_->FromString();
     147             : }
     148             : 
     149           0 : std::string XmppChannelMux::StateName() const {
     150           0 :     return connection_->StateName();
     151             : }
     152             : 
     153           0 : std::string XmppChannelMux::AuthType() const {
     154           0 :     return connection_->GetXmppAuthenticationType();
     155             : }
     156             : 
     157           0 : std::string XmppChannelMux::PeerAddress() const {
     158           0 :     return connection_->endpoint_string();
     159             : }
     160             : 
     161      466260 : inline bool MatchCallback(string to, xmps::PeerId peer) {
     162      466260 :     if ((to.find(XmppInit::kBgpPeer) != string::npos) &&
     163             :         (peer == xmps::BGP)) {
     164      234468 :         return true;
     165             :     }
     166      231792 :     if ((to.find(XmppInit::kConfigPeer) != string::npos) &&
     167             :         (peer == xmps::CONFIG)) {
     168           0 :         return true;
     169             :     }
     170      231792 :     if ((to.find(XmppInit::kDnsPeer) != string::npos) &&
     171             :         (peer == xmps::DNS)) {
     172           0 :         return true;
     173             :     }
     174      231792 :     if ((to.find(XmppInit::kOtherPeer) != string::npos) &&
     175             :         (peer == xmps::OTHER)) {
     176           4 :         return true;
     177             :     }
     178      231788 :     return false;
     179             : }
     180             : 
     181      234491 : void XmppChannelMux::ProcessXmppMessage(const XmppStanza::XmppMessage *msg) {
     182      234491 :     last_received_ = UTCTimestamp();
     183      234493 :     ReceiveCbMap::iterator iter = rxmap_.begin();
     184      700753 :     for (; iter != rxmap_.end(); ++iter) {
     185      466260 :         if (MatchCallback(msg->to, iter->first)) {
     186      234472 :             ReceiveCb cb = iter->second;
     187      234472 :             cb(msg, GetPeerState());
     188      234472 :         }
     189             :     }
     190      234493 : }
     191             : 
     192        1136 : void XmppChannelMux::HandleStateEvent(xmsm::XmState state) {
     193        1136 :     CHECK_CONCURRENCY("xmpp::StateMachine");
     194        1136 :     xmps::PeerState st = xmps::NOT_READY;
     195        1136 :     if (state == xmsm::ESTABLISHED) {
     196         557 :         st = xmps::READY;
     197         579 :     } else if (state == xmsm::ACTIVE) {
     198          15 :         st = xmps::TIMEDOUT;
     199             :     }
     200             : 
     201        1136 :     if (connection_->IsClient()) {
     202         560 :         XmppClient *client = static_cast<XmppClient *>(connection_->server());
     203         560 :         client->NotifyConnectionEvent(this, st);
     204             :     } else {
     205             :         // Event to create the peer on server
     206         576 :         XmppServer *server = static_cast<XmppServer *>(connection_->server());
     207         576 :         server->NotifyConnectionEvent(this, st);
     208             :     }
     209        1136 : }
     210             : 
     211           0 : std::string XmppChannelMux::LastStateName() const {
     212           0 :     return connection_->LastStateName();
     213             : }
     214           0 : std::string XmppChannelMux::LastStateChangeAt() const {
     215           0 :     return connection_->LastStateChangeAt();
     216             : }
     217           0 : std::string XmppChannelMux::LastEvent() const {
     218           0 :     return connection_->LastEvent();
     219             : }
     220           0 : uint32_t XmppChannelMux::rx_open() const {
     221           0 :     return connection_->rx_open();
     222             : }
     223           0 : uint32_t XmppChannelMux::rx_close() const {
     224           0 :     return connection_->rx_close();
     225             : }
     226           0 : uint32_t XmppChannelMux::rx_update() const {
     227           0 :     return connection_->rx_update();
     228             : }
     229           0 : uint32_t XmppChannelMux::rx_keepalive() const {
     230           0 :     return connection_->rx_keepalive();
     231             : }
     232           0 : uint32_t XmppChannelMux::tx_open() const {
     233           0 :     return connection_->tx_open();
     234             : }
     235           0 : uint32_t XmppChannelMux::tx_close() const {
     236           0 :     return connection_->tx_close();
     237             : }
     238           0 : uint32_t XmppChannelMux::tx_update() const {
     239           0 :     return connection_->tx_update();
     240             : }
     241           0 : uint32_t XmppChannelMux::tx_keepalive() const {
     242           0 :     return connection_->tx_keepalive();
     243             : }
     244           0 : uint32_t XmppChannelMux::FlapCount() const {
     245           0 :     return connection_->flap_count();
     246             : }
     247           0 : std::string XmppChannelMux::LastFlap() const {
     248           0 :     return connection_->last_flap_at();
     249             : }
     250             : 
     251           0 : void XmppChannelMux::RegisterRxMessageTraceCallback(RxMessageTraceCb cb) {
     252           0 :     rx_message_trace_cb_ = cb;
     253           0 : }
     254           0 : void XmppChannelMux::RegisterTxMessageTraceCallback(TxMessageTraceCb cb) {
     255           0 :     tx_message_trace_cb_ = cb;
     256           0 : }
     257             : 
     258      235675 : bool XmppChannelMux::RxMessageTrace(const std::string &to_address,
     259             :                                     int port,
     260             :                                     int msg_size,
     261             :                                     const std::string &msg,
     262             :                                     const XmppStanza::XmppMessage *xmpp_msg) {
     263      235675 :     if (rx_message_trace_cb_) {
     264           0 :         return rx_message_trace_cb_(to_address, port, msg_size, msg, xmpp_msg);
     265             :     }
     266      235675 :     return false;
     267             : }
     268             : 
     269      234335 : bool XmppChannelMux::TxMessageTrace(const std::string &to_address,
     270             :                                     int port,
     271             :                                     int msg_size,
     272             :                                     const std::string &msg,
     273             :                                     const XmppStanza::XmppMessage *xmpp_msg) {
     274      234335 :     if (tx_message_trace_cb_) {
     275           0 :         return tx_message_trace_cb_(to_address, port, msg_size, msg, xmpp_msg);
     276             :     }
     277      234343 :     return false;
     278             : }

Generated by: LCOV version 1.14