LCOV - code coverage report
Current view: top level - root/contrail/src/contrail-common/sandesh/library/cpp - sandesh_session.h (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 36 63 57.1 %
Date: 2026-08-03 02:19:58 Functions: 15 24 62.5 %
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_session.h
       7             : //
       8             : // Sandesh Session
       9             : //
      10             : 
      11             : #ifndef __SANDESH_SESSION_H__
      12             : #define __SANDESH_SESSION_H__
      13             : 
      14             : #include <mutex>
      15             : 
      16             : #include <boost/system/error_code.hpp>
      17             : #include <boost/asio.hpp>
      18             : #include <boost/tuple/tuple.hpp>
      19             : 
      20             : #include <base/util.h>
      21             : #include <io/ssl_session.h>
      22             : #include <io/udp_server.h>
      23             : 
      24             : #include <sandesh/transport/TBufferTransports.h>
      25             : #include <sandesh/sandesh.h>
      26             : #include <sandesh/sandesh_util.h>
      27             : #include <sandesh/sandesh_uve_types.h>
      28             : #include <sandesh/stats_client.h>
      29             : 
      30             : using contrail::sandesh::transport::TMemoryBuffer;
      31             : class SandeshSession;
      32             : class Sandesh;
      33             : 
      34             : class SandeshWriter {
      35             : public:
      36             :     static const uint32_t kEncodeBufferSize = 2048;
      37             :     static const unsigned int kDefaultSendSize = 16384;
      38             : 
      39             :     SandeshWriter(SandeshSession *session);
      40             :     ~SandeshWriter();
      41             :     void SendMsg(Sandesh *sandesh, bool more);
      42           0 :     void SendBuffer(boost::shared_ptr<TMemoryBuffer> sbuffer,
      43             :             bool more = false) {
      44           0 :         SendInternal(sbuffer);
      45           0 :     }
      46             :     void WriteReady(const boost::system::error_code &ec);
      47       11298 :     bool SendReady() {
      48       11298 :         std::scoped_lock lock(send_mutex_);
      49       11298 :         return ready_to_send_;
      50       11298 :     }
      51             : 
      52             :     static const std::string sandesh_open_;
      53             :     static const std::string sandesh_open_attr_length_;
      54             :     static const std::string sandesh_close_;
      55             : 
      56             : protected:
      57             :     friend class SandeshSessionTest;
      58             : 
      59             :     // Inline routines invoked by SendMsg()
      60             :     void SendMsgMore(boost::shared_ptr<TMemoryBuffer>);
      61             :     void SendMsgAll(boost::shared_ptr<TMemoryBuffer>);
      62             : 
      63             : private:
      64             :     friend class SandeshSendMsgUnitTest;
      65             : 
      66             :     SandeshSession *session_;
      67             : 
      68             :     void SendInternal(boost::shared_ptr<TMemoryBuffer>);
      69             :     void ConnectTimerExpired(const boost::system::error_code &error);
      70       24938 :     size_t send_buf_offset() { return send_buf_offset_; }
      71       22110 :     uint8_t* send_buf() const { return send_buf_; }
      72        2234 :     void set_send_buf(uint8_t *buf, size_t len) {
      73        2234 :         assert(len && (len < kDefaultSendSize));
      74        2234 :         memcpy(send_buf(), buf, len);
      75        2234 :         send_buf_offset_ = len;
      76        2234 :     }
      77        4748 :     void append_send_buf(uint8_t *buf, size_t len) {
      78        4748 :         assert(len && ((len + send_buf_offset_) < kDefaultSendSize));
      79        4748 :         memcpy(send_buf() + send_buf_offset_, buf, len);
      80        4748 :         send_buf_offset_ += len;
      81        4748 :     }
      82        2234 :     void reset_send_buf() {
      83        2234 :         send_buf_offset_ = 0;
      84        2234 :     }
      85             : 
      86             :     std::mutex send_mutex_;
      87             :     bool ready_to_send_;
      88             :     // send_buf_ is used to store unsent data
      89             :     uint8_t *send_buf_;
      90             :     size_t send_buf_offset_;
      91             : 
      92             : #define sXML_SANDESH_OPEN_ATTR_LENGTH  "<sandesh length=\""
      93             : #define sXML_SANDESH_OPEN              "<sandesh length=\"0000000000\">"
      94             : #define sXML_SANDESH_CLOSE             "</sandesh>"
      95             : 
      96             :     DISALLOW_COPY_AND_ASSIGN(SandeshWriter);
      97             : };
      98             : 
      99             : typedef boost::function<bool(const std::string&, SandeshSession *)>
     100             :     SandeshReceiveMsgCb;
     101             : 
     102             : class SandeshReader {
     103             : public:
     104             :     typedef boost::asio::const_buffer Buffer;
     105             : 
     106             :     SandeshReader(SandeshSession *session);
     107             :     virtual ~SandeshReader();
     108             :     virtual void OnRead(Buffer buffer);
     109             :     void SetReceiveMsgCb(SandeshReceiveMsgCb cb);
     110             :     static int ExtractMsgHeader(const std::string& msg, SandeshHeader& header,
     111             :             std::string& msg_type, uint32_t& header_offset);
     112             : 
     113             : private:
     114       15102 :     bool MsgLengthKnown() { return msg_length_ != (size_t)-1; }
     115             : 
     116       38258 :     size_t msg_length() { return msg_length_; }
     117             : 
     118       24915 :     void set_msg_length(size_t length) { msg_length_ = length; }
     119             : 
     120       12458 :     void reset_msg_length() { set_msg_length(-1); }
     121             : 
     122             :     void SetBuf(const std::string &str);
     123             :     void ReplaceBuf(const std::string &str);
     124             :     bool LeftOver() const;
     125             :     int MatchString(const std::string& match, size_t &m_offset);
     126             :     bool ExtractMsgLength(size_t &msg_length, int *result);
     127             :     bool ExtractMsg(Buffer buffer, int *result, bool NewBuf);
     128             : 
     129             :     std::string buf_;
     130             :     size_t offset_;
     131             :     size_t msg_length_;
     132             :     SandeshSession *session_;
     133             :     std::mutex cb_mutex_;
     134             :     SandeshReceiveMsgCb cb_;
     135             : 
     136             :     static const int kDefaultRecvSize = SandeshWriter::kDefaultSendSize;
     137             : 
     138             :     DISALLOW_COPY_AND_ASSIGN(SandeshReader);
     139             : };
     140             : 
     141             : class SandeshConnection;
     142             : 
     143             : class SandeshSession : public SslSession {
     144             : public:
     145             :     SandeshSession(SslServer *client, SslSocket *socket, int task_instance,
     146             :         int writer_task_id, int reader_task_id);
     147             :     virtual ~SandeshSession();
     148             :     virtual void Shutdown();
     149             :     virtual void OnRead(Buffer buffer);
     150           0 :     virtual void WriteReady(const boost::system::error_code &ec) {
     151           0 :         writer_->WriteReady(ec);
     152           0 :     }
     153             :     virtual bool EnqueueBuffer(u_int8_t *buf, u_int32_t buf_len);
     154       12991 :     Sandesh::SandeshQueue *send_queue() {
     155       12991 :         return send_queue_.get();
     156             :     }
     157           0 :     Sandesh::SandeshBufferQueue *send_buffer_queue() {
     158           0 :         return send_buffer_queue_.get();
     159             :     }
     160             :     SandeshWriter* writer() {
     161             :         return writer_.get();
     162             :     }
     163           0 :     void SetConnection(SandeshConnection *connection) {
     164           0 :         std::scoped_lock lock(conn_mutex_);
     165           0 :         connection_ = connection;
     166           0 :     }
     167          37 :     SandeshConnection *connection() {
     168          37 :         std::scoped_lock lock(conn_mutex_);
     169          37 :         return connection_;
     170          37 :     }
     171           0 :     void SetReceiveMsgCb(SandeshReceiveMsgCb cb) {
     172           0 :         reader_->SetReceiveMsgCb(cb);
     173           0 :     }
     174        5753 :     virtual int GetSessionInstance() const {
     175        5753 :         return instance_;
     176             :     }
     177             :     virtual void EnqueueClose();
     178             :     virtual boost::system::error_code SetSocketOptions();
     179             :     virtual std::string ToString() const;
     180             :     void set_stats_client(StatsClient *stats_client) { stats_client_ = stats_client;}
     181             :     static Sandesh * DecodeCtrlSandesh(const std::string& msg, const SandeshHeader& header,
     182             :         const std::string& sandesh_name, const uint32_t& header_offset);
     183             :     // Session statistics
     184             :     inline void increment_recv_msg() {
     185             :         sstats_.num_recv_msg++;
     186             :     }
     187             :     inline void increment_recv_msg_fail() {
     188             :         sstats_.num_recv_msg_fail++;
     189             :     }
     190           0 :     inline void increment_recv_fail() {
     191           0 :         sstats_.num_recv_fail++;
     192           0 :     }
     193       12894 :     inline void increment_send_msg() {
     194       12894 :         sstats_.num_send_msg++;
     195       12894 :     }
     196           0 :     inline void increment_send_msg_fail() {
     197           0 :         sstats_.num_send_msg_fail++;
     198           0 :     }
     199           0 :     inline void increment_send_buffer_fail() {
     200           0 :         sstats_.num_send_buffer_fail++;
     201           0 :     }
     202             :     inline void increment_wait_msgq_enqueue() {
     203             :         sstats_.num_wait_msgq_enqueue++;
     204             :     }
     205             :     inline void increment_wait_msgq_dequeue() {
     206             :         sstats_.num_wait_msgq_dequeue++;
     207             :     }
     208           0 :     inline void increment_write_ready_cb_error() {
     209           0 :         sstats_.num_write_ready_cb_error++;
     210           0 :     }
     211             :     const SandeshSessionStats& GetStats() const {
     212             :         return sstats_;
     213             :     }
     214             :     void SetSendQueueWaterMark(Sandesh::QueueWaterMarkInfo &wm_info);
     215             :     void ResetSendQueueWaterMark();
     216             :     SandeshLevel::type SendingLevel() const;
     217             : 
     218             : protected:
     219        5716 :     virtual int reader_task_id() const {
     220        5716 :         return reader_task_id_;
     221             :     }
     222             : 
     223             : private:
     224             :     friend class SandeshSessionTest;
     225             : 
     226             :     // 60 seconds - 45s + (3*5)s
     227             :     static const int kSessionKeepaliveIdleTime = 15; // in seconds
     228             :     static const int kSessionKeepaliveInterval = 3; // in seconds
     229             :     static const int kSessionKeepaliveProbes = 5; // count
     230             :     static const int kSessionTcpUserTimeout = 30000; // ms
     231             :     static const int kQueueSize = 200 * 1024 * 1024; // 200 MB
     232             : 
     233             :     bool SendMsg(SandeshElement element);
     234             :     bool SendBuffer(boost::shared_ptr<TMemoryBuffer> sbuffer);
     235             :     bool SessionSendReady();
     236             :     void SetSendingLevel(size_t count, SandeshLevel::type level);
     237             : 
     238             :     int instance_;
     239             :     boost::scoped_ptr<SandeshWriter> writer_;
     240             :     boost::scoped_ptr<SandeshReader> reader_;
     241             :     boost::scoped_ptr<Sandesh::SandeshQueue> send_queue_;
     242             :     boost::scoped_ptr<Sandesh::SandeshBufferQueue> send_buffer_queue_;
     243             :     StatsClient *stats_client_;
     244             :     SandeshConnection *connection_;
     245             :     std::mutex conn_mutex_;
     246             :     std::mutex send_mutex_;
     247             :     int keepalive_idle_time_;
     248             :     int keepalive_interval_;
     249             :     int keepalive_probes_;
     250             :     int tcp_user_timeout_;
     251             :     int reader_task_id_;
     252             :     SandeshLevel::type sending_level_;
     253             : 
     254             :     // Session statistics
     255             :     SandeshSessionStats sstats_;
     256             : 
     257             :     DISALLOW_COPY_AND_ASSIGN(SandeshSession);
     258             : };
     259             : 
     260             : #endif // __SANDESH_SESSION_H__

Generated by: LCOV version 1.14