Kea  2.3.6-git
mt_tcp_listener_mgr.cc
Go to the documentation of this file.
1 // Copyright (C) 2022-2023 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #include <config.h>
9 #include <asiolink/io_address.h>
10 #include <asiolink/io_error.h>
11 #include <asiolink/io_service.h>
12 #include <mt_tcp_listener_mgr.h>
13 #include <tcp_log.h>
15 
16 #include <boost/pointer_cast.hpp>
17 
18 using namespace isc::asiolink;
19 using namespace isc::tcp;
20 using namespace isc::util;
21 
22 namespace isc {
23 namespace tcp {
24 
25 MtTcpListenerMgr::MtTcpListenerMgr(TcpListenerFactory listener_factory,
26  const IOAddress& address,
27  const uint16_t port,
28  const uint16_t thread_pool_size /* = 1 */,
29  TlsContextPtr context /* = () */,
30  TcpConnectionFilterCallback connection_filter /* = 0 */)
31  : listener_factory_(listener_factory),
32  address_(address), port_(port), thread_io_service_(), tcp_listener_(),
33  thread_pool_size_(thread_pool_size), thread_pool_(),
34  tls_context_(context), connection_filter_(connection_filter),
35  idle_timeout_(TCP_IDLE_CONNECTION_TIMEOUT) {
36 }
37 
39  stop();
40 }
41 
42 void
44  // We must be in multi-threading mode.
45  if (!MultiThreadingMgr::instance().getMode()) {
46  isc_throw(InvalidOperation, "MtTcpListenerMgr cannot be started"
47  " when multi-threading is disabled");
48  }
49 
50  // Punt if we're already started.
51  if (!isStopped()) {
52  isc_throw(InvalidOperation, "MtTcpListenerMgr already started!");
53  }
54 
55  try {
56  // Create a new IOService.
57  thread_io_service_.reset(new IOService());
58 
59  // Create a new TCPListener derivation using the factory.
60  tcp_listener_ = listener_factory_(*thread_io_service_,
61  address_,
62  port_,
63  tls_context_,
64  idle_timeout_,
65  connection_filter_);
66 
67  // Instruct the HTTP listener to actually open socket, install
68  // callback and start listening.
69  tcp_listener_->start();
70 
71  // Create the thread pool with immediate start.
72  thread_pool_.reset(new IoServiceThreadPool(thread_io_service_, thread_pool_size_));
73 
74  // OK, seems like we're good to go.
76  .arg(thread_pool_size_)
77  .arg(address_)
78  .arg(port_)
79  .arg(tls_context_ ? "true" : "false");
80  } catch (const std::exception& ex) {
81  isc_throw(Unexpected, "MtTcpListenerMgr::start failed:" << ex.what());
82  }
83 }
84 
85 void
87  if (thread_pool_) {
88  thread_pool_->checkPausePermissions();
89  }
90 }
91 
92 void
94  if (thread_pool_) {
95  thread_pool_->pause();
96  }
97 }
98 
99 void
101  if (thread_pool_) {
102  thread_pool_->run();
103  }
104 }
105 
106 void
108  // Nothing to do.
109  if (!thread_io_service_) {
110  return;
111  }
112 
114  .arg(address_)
115  .arg(port_);
116 
117  // Stop the thread pool.
118  thread_pool_->stop();
119 
120  // Get rid of the listener.
121  tcp_listener_.reset();
122 
123  // Ditch the IOService.
124  thread_io_service_.reset();
125 
127  .arg(address_)
128  .arg(port_);
129 }
130 
131 bool
133  if (thread_pool_) {
134  return (thread_pool_->isRunning());
135  }
136 
137  return (false);
138 }
139 
140 bool
142  if (thread_pool_) {
143  return (thread_pool_->isStopped());
144  }
145 
146  return (true);
147 }
148 
149 bool
151  if (thread_pool_) {
152  return (thread_pool_->isPaused());
153  }
154 
155  return (false);
156 }
157 
158 } // namespace isc::config
159 } // namespace isc
const int DBGLVL_TRACE_BASIC
Trace basic operations.
Definition: log_dbglevels.h:69
std::function< bool(const boost::asio::ip::tcp::endpoint &)> TcpConnectionFilterCallback
Type of the callback for filtering new connections by ip address.
std::function< TcpListenerPtr(asiolink::IOService &io_service, const asiolink::IOAddress &server_address, const unsigned short server_port, const asiolink::TlsContextPtr &tls_context, const TcpListener::IdleTimeout &idle_timeout, const TcpConnectionFilterCallback &connection_filter) > TcpListenerFactory
Defines a factory function for creating TcpListeners.
bool isPaused()
Indicates if the thread pool is paused.
const long TCP_IDLE_CONNECTION_TIMEOUT
Default connection idle timeout in milliseconds.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition: edns.h:19
bool isRunning()
Indicates if the thread pool is running.
const isc::log::MessageID MT_TCP_LISTENER_MGR_STOPPING
Definition: tcp_messages.h:13
A generic exception that is thrown when an unexpected error condition occurs.
void resume()
Resumes running the listener&#39;s thread pool.
Defines the logger used by the top-level component of kea-lfc.
virtual ~MtTcpListenerMgr()
Destructor.
A generic exception that is thrown if a function is called in a prohibited way.
const isc::log::MessageID MT_TCP_LISTENER_MGR_STOPPED
Definition: tcp_messages.h:12
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition: macros.h:14
void stop()
Stops the listener&#39;s thread pool.
void pause()
Pauses the listener&#39;s thread pool.
isc::log::Logger tcp_logger("tcp")
Defines the logger used within libkea-tcp library.
Definition: tcp_log.h:18
const isc::log::MessageID MT_TCP_LISTENER_MGR_STARTED
Definition: tcp_messages.h:11
void start()
Starts running the listener&#39;s thread pool.
void checkPermissions()
Check if the current thread can perform thread pool state transition.
bool isStopped()
Indicates if the thread pool is stopped.