Kea  2.5.3
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  thread_io_service_.reset();
82  tcp_listener_.reset();
83  thread_pool_.reset();
84  isc_throw(Unexpected, "MtTcpListenerMgr::start failed:" << ex.what());
85  }
86 }
87 
88 void
90  if (thread_pool_) {
91  thread_pool_->checkPausePermissions();
92  }
93 }
94 
95 void
97  if (thread_pool_) {
98  thread_pool_->pause();
99  }
100 }
101 
102 void
104  if (thread_pool_) {
105  thread_pool_->run();
106  }
107 }
108 
109 void
111  // Nothing to do.
112  if (!thread_io_service_) {
113  return;
114  }
115 
117  .arg(address_)
118  .arg(port_);
119 
120  // Stop the thread pool.
121  thread_pool_->stop();
122 
123  // Get rid of the listener.
124  tcp_listener_.reset();
125 
126  // Ditch the IOService.
127  thread_io_service_.reset();
128 
130  .arg(address_)
131  .arg(port_);
132 }
133 
134 bool
136  if (thread_pool_) {
137  return (thread_pool_->isRunning());
138  }
139 
140  return (false);
141 }
142 
143 bool
145  if (thread_pool_) {
146  return (thread_pool_->isStopped());
147  }
148 
149  return (true);
150 }
151 
152 bool
154  if (thread_pool_) {
155  return (thread_pool_->isPaused());
156  }
157 
158  return (false);
159 }
160 
161 } // namespace isc::config
162 } // namespace isc
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown if a function is called in a prohibited way.
A generic exception that is thrown when an unexpected error condition occurs.
void pause()
Pauses the listener's thread pool.
void start()
Starts running the listener's thread pool.
bool isPaused()
Indicates if the thread pool is paused.
void checkPermissions()
Check if the current thread can perform thread pool state transition.
bool isStopped()
Indicates if the thread pool is stopped.
void resume()
Resumes running the listener's thread pool.
void stop()
Stops the listener's thread pool.
virtual ~MtTcpListenerMgr()
Destructor.
bool isRunning()
Indicates if the thread pool is running.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition: macros.h:14
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.
const long TCP_IDLE_CONNECTION_TIMEOUT
Default connection idle timeout in milliseconds.
const isc::log::MessageID MT_TCP_LISTENER_MGR_STARTED
Definition: tcp_messages.h:11
const isc::log::MessageID MT_TCP_LISTENER_MGR_STOPPING
Definition: tcp_messages.h:13
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_STOPPED
Definition: tcp_messages.h:12
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.
Definition: edns.h:19
Defines the logger used by the top-level component of kea-lfc.