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

Generated by: LCOV version 1.14