LCOV - code coverage report
Current view: top level - root/contrail/src/contrail-common/sandesh/library/cpp - sandesh_connection.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 86 122 70.5 %
Date: 2026-08-03 02:19:58 Functions: 21 27 77.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : //
       6             : // sandesh_connection.cc
       7             : //
       8             : // Sandesh connection management implementation
       9             : //
      10             : 
      11             : #include <io/tcp_session.h>
      12             : #include <io/tcp_server.h>
      13             : #include <base/logging.h>
      14             : #include <sandesh/protocol/TXMLProtocol.h>
      15             : 
      16             : #include <sandesh/sandesh_types.h>
      17             : #include <sandesh/sandesh.h>
      18             : #include <sandesh/sandesh_ctrl_types.h>
      19             : #include <sandesh/common/vns_types.h>
      20             : #include <sandesh/common/vns_constants.h>
      21             : #include "sandesh_uve.h"
      22             : #include "sandesh_session.h"
      23             : #include "sandesh_client.h"
      24             : #include "sandesh_server.h"
      25             : #include "sandesh_connection.h"
      26             : 
      27             : using namespace std;
      28             : using boost::system::error_code;
      29             : 
      30             : #define CONNECTION_LOG(_Level, _Msg)                                           \
      31             :     do {                                                                       \
      32             :         if (LoggingDisabled()) break;                                          \
      33             :         log4cplus::Logger _Xlogger = Sandesh::logger();                        \
      34             :         if (_Xlogger.isEnabledFor(log4cplus::_Level##_LOG_LEVEL)) {            \
      35             :             log4cplus::tostringstream _Xbuf;                                   \
      36             :             if (!state_machine()->generator_key().empty()) {                   \
      37             :                 _Xbuf << state_machine()->generator_key() << " (" <<           \
      38             :                     GetTaskInstance() << ") ";                                 \
      39             :             }                                                                  \
      40             :             if (session()) {                                                   \
      41             :                 _Xbuf << session()->ToString() << " ";                         \
      42             :             }                                                                  \
      43             :             _Xbuf << _Msg;                                                     \
      44             :             _Xlogger.forcedLog(log4cplus::_Level##_LOG_LEVEL,                  \
      45             :                                _Xbuf.str());                                   \
      46             :         }                                                                      \
      47             :     } while (false)
      48             : 
      49          37 : SandeshConnection::SandeshConnection(const char *prefix, TcpServer *server,
      50          37 :         Endpoint endpoint, int task_instance, int task_id)
      51          37 :     : is_deleted_(false),
      52          37 :       server_(server),
      53          37 :       endpoint_(endpoint),
      54          37 :       admin_down_(false),
      55          37 :       session_(NULL),
      56          37 :       task_instance_(task_instance),
      57          37 :       task_id_(task_id),
      58          37 :       state_machine_(new SandeshStateMachine(prefix, this)) {
      59          37 : }
      60             : 
      61          37 : SandeshConnection::~SandeshConnection() {
      62          37 : }
      63             : 
      64          74 : void SandeshConnection::set_session(SandeshSession *session) {
      65          74 :     session_ = session;
      66          74 : }
      67             : 
      68       12410 : SandeshSession *SandeshConnection::session() const {
      69       12410 :     return session_;
      70             : }
      71             : 
      72       12373 : bool SandeshConnection::ReceiveMsg(const std::string &msg, SandeshSession *session) {
      73       12373 :     return state_machine_->OnSandeshMessage(session, msg);
      74             : }
      75             : 
      76          37 : bool SandeshConnection::SendSandesh(Sandesh *snh) {
      77          37 :     if (!session_) {
      78           0 :         snh->Release();
      79           0 :         return false;
      80             :     }
      81          37 :     ssm::SsmState state = state_machine_->get_state();
      82          37 :     if (state != ssm::SERVER_INIT && state != ssm::ESTABLISHED) {
      83           0 :         snh->Release();
      84           0 :         return false;
      85             :     }
      86             :     // XXX No bounded work queue
      87          37 :     SandeshElement element(snh);
      88          37 :     session_->send_queue()->Enqueue(element);
      89          37 :     return true;
      90             : }
      91             : 
      92          37 : void SandeshConnection::AcceptSession(SandeshSession *session) {
      93          37 :     session->SetReceiveMsgCb(boost::bind(&SandeshConnection::ReceiveMsg, this, _1, _2));
      94          37 :     session->SetConnection(this);
      95          37 :     state_machine_->PassiveOpen(session);
      96          37 : }
      97             : 
      98         148 : SandeshStateMachine *SandeshConnection::state_machine() const {
      99         148 :     return state_machine_.get();
     100             : }
     101             : 
     102           0 : void SandeshConnection::SetAdminState(bool down) {
     103           0 :     if (admin_down_ != down) {
     104           0 :         admin_down_ = down;
     105           0 :         state_machine_->SetAdminState(down);
     106             :     }
     107           0 : }
     108             : 
     109           0 : void SandeshConnection::Shutdown() {
     110           0 :     is_deleted_ = true;
     111           0 :     deleter()->Delete();
     112           0 : }
     113             : 
     114          37 : bool SandeshConnection::MayDelete() const {
     115             :     // XXX Do we have any dependencies?
     116          37 :     return true;
     117             : }
     118             : 
     119             : class SandeshServerConnection::DeleteActor : public LifetimeActor {
     120             : public:
     121          37 :     DeleteActor(SandeshServer *server, SandeshServerConnection *parent)
     122          37 :         : LifetimeActor(server->lifetime_manager()),
     123          37 :           server_(server), parent_(parent) {
     124          37 :     }
     125          37 :     virtual bool MayDelete() const {
     126          37 :         return parent_->MayDelete();
     127             :     }
     128          37 :     virtual void Shutdown() {
     129          37 :         SandeshSession *session = NULL;
     130          37 :         if (parent_->state_machine()) {
     131          37 :             session = parent_->state_machine()->session();
     132          37 :             parent_->state_machine()->clear_session();
     133             :         }
     134          37 :         if (session) {
     135           0 :             server_->DeleteSession(session);
     136             :         }
     137          37 :         parent_->is_deleted_ = true;
     138          37 :     }
     139          37 :     virtual void Destroy() {
     140          37 :         parent_->Destroy();
     141          37 :     }
     142             : 
     143             : private:
     144             :     SandeshServer *server_;
     145             :     SandeshServerConnection *parent_;
     146             : };
     147             : 
     148          37 : SandeshServerConnection::SandeshServerConnection(
     149          37 :         TcpServer *server, Endpoint endpoint, int task_instance, int task_id)
     150             :     : SandeshConnection("SandeshServer: ", server, endpoint, task_instance, task_id),
     151          37 :       deleter_(new DeleteActor(dynamic_cast<SandeshServer *>(server), this)),
     152          74 :       server_delete_ref_(this, dynamic_cast<SandeshServer *>(server)->deleter()) {
     153          37 : }
     154             : 
     155          74 : SandeshServerConnection::~SandeshServerConnection() {
     156          74 : }
     157             : 
     158          37 : void SandeshServerConnection::ManagedDelete() {
     159          37 :     deleter_->Delete();
     160          37 : }
     161             : 
     162          37 : bool SandeshServerConnection::ProcessSandeshCtrlMessage(const std::string &msg,
     163             :         const SandeshHeader &header, const std::string sandesh_name,
     164             :         const uint32_t header_offset) {
     165          37 :     SandeshServer *sserver = dynamic_cast<SandeshServer *>(server());
     166          37 :     if (!sserver) {
     167           0 :         CONNECTION_LOG(ERROR, __func__ << " No Server");
     168           0 :         return false;
     169             :     }
     170          37 :     Sandesh *ctrl_snh = SandeshSession::DecodeCtrlSandesh(msg, header, sandesh_name,
     171             :                                                           header_offset);
     172          37 :     bool ret = sserver->ReceiveSandeshCtrlMsg(state_machine(), session(), ctrl_snh);
     173          37 :     ctrl_snh->Release();
     174          37 :     return ret;
     175             : }
     176             : 
     177           0 : bool SandeshServerConnection::ProcessResourceUpdate(bool rsc) {
     178           0 :     SandeshServer *sserver = dynamic_cast<SandeshServer *>(server());
     179           0 :     if (!sserver) {
     180           0 :         CONNECTION_LOG(ERROR, __func__ << " No Server");
     181           0 :         return false;
     182             :     }
     183           0 :     return sserver->ReceiveResourceUpdate(session(), rsc);
     184             : }
     185             : 
     186       12336 : bool SandeshServerConnection::ProcessSandeshMessage(
     187             :         const SandeshMessage *msg, bool resource) {
     188       12336 :     SandeshServer *sserver = dynamic_cast<SandeshServer *>(server());
     189       12336 :     if (!sserver) {
     190           0 :         CONNECTION_LOG(ERROR, __func__ << " No Server");
     191           0 :         return false;
     192             :     }
     193       12336 :     sserver->ReceiveSandeshMsg(session(), msg, resource);
     194       12336 :     return true;
     195             : }
     196             : 
     197          37 : void SandeshServerConnection::ProcessDisconnect(SandeshSession * sess) {
     198          37 :     SandeshServer *sserver = dynamic_cast<SandeshServer *>(server());
     199          37 :     if (!sserver) {
     200           0 :         CONNECTION_LOG(ERROR, __func__ << " No Server");
     201           0 :         return;
     202             :     }
     203          37 :     sserver->DisconnectSession(sess);
     204             : }
     205             : 
     206           0 : LifetimeManager *SandeshServerConnection::lifetime_manager() {
     207           0 :     SandeshServer *sserver = dynamic_cast<SandeshServer *>(server());
     208           0 :     if (!sserver) {
     209           0 :         CONNECTION_LOG(ERROR, __func__ << " No Server");
     210           0 :         return NULL;
     211             :     }
     212           0 :     return sserver->lifetime_manager();
     213             : }
     214             : 
     215          37 : void SandeshServerConnection::Destroy() {
     216          37 :     SandeshServer *sserver = dynamic_cast<SandeshServer *>(server());
     217          37 :     if (!sserver) {
     218           0 :         CONNECTION_LOG(ERROR, __func__ << " No Server");
     219           0 :         return;
     220             :     }
     221          37 :     int index = GetTaskInstance();
     222          37 :     if (index != -1) {
     223          37 :         sserver->FreeConnectionIndex(index);
     224             :     }
     225             :     // Deletes self - should always be the last 
     226          37 :     sserver->RemoveConnection(this);
     227             : };
     228             : 
     229           0 : LifetimeActor *SandeshServerConnection::deleter() {
     230           0 :     return deleter_.get();
     231             : }

Generated by: LCOV version 1.14