LCOV - code coverage report
Current view: top level - root/contrail/src/contrail-common/io - tcp_server.h (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 23 23 100.0 %
Date: 2026-08-03 02:19:58 Functions: 11 11 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #ifndef SRC_IO_TCP_SERVER_H_
       6             : #define SRC_IO_TCP_SERVER_H_
       7             : 
       8             : #include <map>
       9             : #include <condition_variable>
      10             : #include <mutex>
      11             : #include <set>
      12             : #include <string>
      13             : #include <atomic>
      14             : #include <boost/asio/ip/tcp.hpp>
      15             : #include <boost/intrusive_ptr.hpp>
      16             : #include <boost/scoped_ptr.hpp>
      17             : 
      18             : #include "base/util.h"
      19             : #include "base/address.h"
      20             : #include "io/server_manager.h"
      21             : #include "io/io_utils.h"
      22             : #include <sandesh/library/cpp/sandesh_options.h>
      23             : 
      24             : class EventManager;
      25             : class TcpSession;
      26             : class SocketIOStats;
      27             : 
      28             : class TcpServer {
      29             : public:
      30             :     typedef boost::asio::ip::tcp::endpoint Endpoint;
      31             :     typedef boost::asio::ip::tcp::socket Socket;
      32             :     typedef boost::asio::ip::tcp::socket::native_handle_type NativeSocketType;
      33             : 
      34             :     explicit TcpServer(EventManager *evm);
      35             :     virtual ~TcpServer();
      36             : 
      37             :     // Bind a listening socket and register it with the event manager.
      38             :     virtual bool Initialize(unsigned short port);
      39             :     virtual bool Initialize(unsigned short port, const IpAddress &host_ip,
      40             :         int intf_id = -1);
      41             :     bool InitializeInternal(boost::asio::ip::tcp::endpoint localaddr);
      42             : 
      43        7159 :     const std::string ToString() const { return name_; }
      44             :     void SetAcceptor();
      45             :     void ResetAcceptor();
      46             : 
      47             :     // shutdown the listening socket.
      48             :     void Shutdown();
      49             : 
      50             :     // close all existing sessions and delete them.
      51             :     void ClearSessions();
      52             :     void UpdateSessionsDscp(uint8_t dscp);
      53             : 
      54             :     // Helper function that allocates a socket and calls the virtual method
      55             :     // AllocSession. The session object is owned by the TcpServer and must
      56             :     // be deallocated via DeleteSession.
      57             :     virtual TcpSession *CreateSession();
      58             : 
      59             :     // Delete a session object.
      60             :     virtual void DeleteSession(TcpSession *session);
      61             : 
      62             :     virtual void Connect(TcpSession *session, Endpoint remote);
      63             : 
      64      109118 :     virtual bool DisableSandeshLogMessages() const { return false; }
      65             : 
      66             :     int GetPort() const;
      67             :     const io::SocketStats &GetSocketStats() const { return stats_; }
      68             : 
      69             :     //
      70             :     // Return the number of tcp sessions in the map
      71             :     //
      72           4 :     size_t GetSessionCount() const {
      73           4 :         return session_ref_.size();
      74             :     }
      75             : 
      76      396939 :     EventManager *event_manager() { return evm_; }
      77             : 
      78             :     // Returns true if any of the sessions on this server has read available
      79             :     // data.
      80             :     bool HasSessionReadAvailable() const;
      81             :     bool HasSessions() const;
      82             : 
      83             :     TcpSession *GetSession(Endpoint remote);
      84             : 
      85             :     // wait until the server has deleted all sessions.
      86             :     void WaitForEmpty();
      87             : 
      88             :     void GetRxSocketStats(SocketIOStats *socket_stats) const;
      89             :     void GetTxSocketStats(SocketIOStats *socket_stats) const;
      90             : 
      91         664 :     void GetRxSocketStats(SocketIOStats &socket_stats) const {
      92         664 :         GetRxSocketStats(&socket_stats);
      93         664 :     }
      94             : 
      95         664 :     void GetTxSocketStats(SocketIOStats &socket_stats) const {
      96         664 :         GetTxSocketStats(&socket_stats);
      97         664 :     }
      98             : 
      99             :     int SetMd5SocketOption(NativeSocketType fd, uint32_t peer_ip,
     100             :                            const std::string &md5_password);
     101             :     int SetListenSocketMd5Option(uint32_t peer_ip,
     102             :                                  const std::string &md5_password);
     103             :     int SetDscpSocketOption(NativeSocketType fd, uint8_t value);
     104             :     uint8_t GetDscpValue(NativeSocketType fd) const;
     105             :     int SetListenSocketDscp(uint8_t value);
     106             :     int SetSocketOptions(const SandeshConfig &sandesh_config);
     107             :     int SetKeepAliveSocketOption(int fd, const SandeshConfig &sandesh_config);
     108             : 
     109             : protected:
     110             :     typedef boost::intrusive_ptr<TcpServer> TcpServerPtr;
     111             :     typedef boost::intrusive_ptr<TcpSession> TcpSessionPtr;
     112             : 
     113             :     // Create a session object.
     114             :     virtual TcpSession *AllocSession(Socket *socket) = 0;
     115             : 
     116             :     // Only SslServer overrides this method, to manage server with SSL
     117             :     // socket instead of TCP socket
     118             :     virtual TcpSession *AllocSession(bool server_session);
     119             : 
     120             :     virtual Socket *accept_socket() const;
     121             :     virtual void set_accept_socket();
     122             : 
     123             :     //
     124             :     // Passively accepted a new session. Returns true if the session is
     125             :     // accepted, false otherwise.
     126             :     //
     127             :     // If the session is not accepted, tcp_server.cc deletes the newly
     128             :     // created session.
     129             :     //
     130             :     virtual bool AcceptSession(TcpSession *session);
     131             : 
     132             :     // For testing - will typically be used by derived class.
     133           8 :     void set_socket_open_failure(bool flag) { socket_open_failure_ = flag; }
     134        8003 :     bool socket_open_failure() const { return socket_open_failure_; }
     135             : 
     136             :     Endpoint LocalEndpoint() const;
     137             : 
     138             :     virtual void AcceptHandlerComplete(TcpSessionPtr session);
     139             :     virtual void ConnectHandlerComplete(TcpSessionPtr session);
     140             : 
     141             : private:
     142             :     friend class TcpSession;
     143             :     friend class SslSession;
     144             :     friend class TcpMessageWriter;
     145             :     friend class BgpServerUnitTest;
     146             :     friend void intrusive_ptr_add_ref(TcpServer *server);
     147             :     friend void intrusive_ptr_release(TcpServer *server);
     148             : 
     149             :     struct TcpSessionPtrCmp {
     150      121274 :         bool operator()(const TcpSessionPtr &lhs,
     151             :                         const TcpSessionPtr &rhs) const {
     152      121274 :             return lhs.get() < rhs.get();
     153             :         }
     154             :     };
     155             :     typedef std::set<TcpSessionPtr, TcpSessionPtrCmp> SessionSet;
     156             :     typedef std::multimap<Endpoint, TcpSession *> SessionMap;
     157             : 
     158             :     void InsertSessionToMap(Endpoint remote, TcpSession *session);
     159             :     bool RemoveSessionFromMap(Endpoint remote, TcpSession *session);
     160             : 
     161             :     // Called by the asio service.
     162             :     void AcceptHandlerInternal(TcpServerPtr server,
     163             :              const boost::system::error_code &error);
     164             : 
     165             :     void ConnectHandler(TcpServerPtr server, TcpSessionPtr session,
     166             :                         const boost::system::error_code &error);
     167             : 
     168             :     // Trigger the async accept operation.
     169             :     void AsyncAccept();
     170             : 
     171             :     void OnSessionClose(TcpSession *session);
     172             :     void SetName(Endpoint local_endpoint);
     173             : 
     174             :     io::SocketStats stats_;
     175             :     EventManager *evm_;
     176             :     // mutex protects the session maps
     177             :     mutable std::mutex mutex_;
     178             :     std::condition_variable cond_var_;
     179             :     SessionSet session_ref_;
     180             :     SessionMap session_map_;
     181             :     std::unique_ptr<Socket> so_accept_;      // socket used in async_accept
     182             :     boost::scoped_ptr<boost::asio::ip::tcp::acceptor> acceptor_;
     183             :     std::atomic<int> refcount_;
     184             :     std::string name_;
     185             :     bool socket_open_failure_;
     186             :     int intf_id_;
     187             : 
     188             :     DISALLOW_COPY_AND_ASSIGN(TcpServer);
     189             : };
     190             : 
     191             : typedef boost::intrusive_ptr<TcpServer> TcpServerPtr;
     192             : 
     193      392858 : inline void intrusive_ptr_add_ref(TcpServer *server) {
     194      392858 :     server->refcount_.fetch_add(1);
     195      392858 : }
     196             : 
     197      392834 : inline void intrusive_ptr_release(TcpServer *server) {
     198      392834 :     int prev = server->refcount_.fetch_sub(1);
     199      392834 :     if (prev == 1) {
     200       17561 :         delete server;
     201             :     }
     202      392834 : }
     203             : 
     204             : class TcpServerManager {
     205             : public:
     206             :     static void AddServer(TcpServer *server);
     207             :     static void DeleteServer(TcpServer *server);
     208             :     static size_t GetServerCount();
     209             : 
     210             : private:
     211             :     static ServerManager<TcpServer, TcpServerPtr> impl_;
     212             : };
     213             : 
     214             : #endif  // SRC_IO_TCP_SERVER_H_

Generated by: LCOV version 1.14