1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// Copyright (C) 2021-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef CMD_HTTP_LISTENER_H
#define CMD_HTTP_LISTENER_H

#include <asiolink/io_address.h>
#include <asiolink/io_service.h>
#include <asiolink/io_service_thread_pool.h>
#include <http/listener.h>
#include <thread><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <vector><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.

namespace isc {
namespace config {

/// @brief A multi-threaded HTTP listener that can process API commands
/// requests.
///
/// This class will listen for Command API client requests on a given
/// IP address and port.  It uses its own IOService instance to drive
/// a thread-pool which can service multiple connections concurrently.
/// The number of concurrent connections is currently limited to the
/// configured thread pool size.
///
/// @note This class is NOT compatible with Kea core single-threading.
/// It is incumbent upon the owner to ensure the Kea core multi-threading
/// is (or will be) enabled when creating instances of this class.
class CmdHttpListener {
public:
    /// @brief Constructor
    CmdHttpListener(const asiolink::IOAddress& address, const uint16_t port,
                    const uint16_t thread_pool_size = 1,
                    asiolink::TlsContextPtr context = asiolink::TlsContextPtr());

    /// @brief Destructor
    virtual ~CmdHttpListener();

    /// @brief Check if the current thread can perform thread pool state
    /// transition.
    ///
    /// @throw MultiThreadingInvalidOperation if the state transition is done on
    /// any of the worker threads.
    void checkPermissions();

    /// @brief Starts running the listener's thread pool.
    void start();

    /// @brief Pauses the listener's thread pool.
    ///
    /// Suspends thread pool event processing.
    void pause();

    /// @brief Resumes running the listener's thread pool.
    ///
    /// Resumes thread pool event processing.
    void resume();

    /// @brief Stops the listener's thread pool.
    void stop();

    /// @brief Indicates if the thread pool is running.
    ///
    /// @return True if the thread pool exists and it is in the RUNNING state,
    /// false otherwise.
    bool isRunning();

    /// @brief Indicates if the thread pool is stopped.
    ///
    /// @return True if the thread pool does not exist or it is in the STOPPED
    /// state, false otherwise.
    bool isStopped();

    /// @brief Indicates if the thread pool is paused.
    ///
    /// @return True if the thread pool exists and it is in the PAUSED state,
    /// false otherwise.
    bool isPaused();

    /// @brief Fetches the IP address on which to listen.
    ///
    /// @return IOAddress containing the address on which to listen.
    isc::asiolink::IOAddress getAddress() const {
        return (address_);
    }

    /// @brief Fetches the port number on which to listen.
    ///
    /// @return uint16_t containing the port number on which to listen.
    uint16_t getPort() const {
        return (port_);
    }

    /// @brief Fetches the maximum size of the thread pool.
    ///
    /// @return uint16_t containing the maximum size of the thread pool.
    uint16_t getThreadPoolSize() const {
        return (thread_pool_size_);
    }

    /// @brief Fetches the TLS context.
    ///
    /// @return TLS context.
    asiolink::TlsContextPtr getTlsContext() const {
        return (tls_context_);
    }

    /// @brief Fetches the number of threads in the pool.
    ///
    /// @return uint16_t containing the number of running threads.
    uint16_t getThreadCount() const {
        if (!thread_pool_) {
            return (0);
        }

        return (thread_pool_->getThreadCount());
    }

    /// @brief Fetches a pointer to the internal IOService used to
    /// drive the thread-pool in multi-threaded mode.
    ///
    /// @return pointer to the IOService instance, or an empty pointer
    /// in single-threaded mode.
    asiolink::IOServicePtr getThreadIOService() const {
        return (thread_io_service_);
    }

private:
    /// @brief IP address on which to listen.
    isc::asiolink::IOAddress address_;

    /// @brief Port on which to listen.
    uint16_t port_;

    /// @brief IOService instance that drives our IO.
    isc::asiolink::IOServicePtr thread_io_service_;

    /// @brief The HttpListener instance
    http::HttpListenerPtr http_listener_;

    /// @brief The number of threads that will call IOService_context::run().
    std::size_t thread_pool_size_;

    /// @brief The pool of threads that do IO work.
    asiolink::IoServiceThreadPoolPtr thread_pool_;

    /// @brief The TLS context.
    asiolink::TlsContextPtr tls_context_;
};

/// @brief Defines a shared pointer to CmdHttpListener.
typedef boost::shared_ptr<CmdHttpListener> CmdHttpListenerPtr;

} // namespace isc::config
} // namespace isc

#endif // CMD_HTTP_LISTENER_H