| Kea 3.0.2-git

unix_command_mgr.cc
Go to the documentation of this file.
1// Copyright (C) 2015-2025 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>
8
9#include <asiolink/asio_wrapper.h>
10#include <asiolink/interval_timer.h>
11#include <asiolink/io_service.h>
12#include <asiolink/unix_domain_socket.h>
13#include <asiolink/unix_domain_socket_acceptor.h>
14#include <asiolink/unix_domain_socket_endpoint.h>
15#include <config/command_mgr.h>
16#include <config/unix_command_config.h>
17#include <config/unix_command_mgr.h>
18#include <cc/data.h>
19#include <cc/command_interpreter.h>
20#include <cc/json_feed.h>
21#include <dhcp/iface_mgr.h>
22#include <config/config_log.h>
23#include <config/timeouts.h>
24#include <util/watch_socket.h>
25#include <boost/enable_shared_from_this.hpp>
26#include <array>
27#include <functional>
28#include <unistd.h>
29#include <sys/file.h>
30
31 using namespace isc;
32 using namespace isc::asiolink;
33 using namespace isc::config;
34 using namespace isc::data;
35 using namespace isc::dhcp;
36 namespace ph = std::placeholders;
37
38 namespace {
39
41 const size_t BUF_SIZE = 32768;
42
43 class ConnectionPool;
44
45 class Connection;
46
48 typedef boost::shared_ptr<Connection> ConnectionPtr;
49
54 class Connection : public boost::enable_shared_from_this<Connection> {
55 public:
56
75 Connection(const IOServicePtr& io_service,
76 const boost::shared_ptr<UnixDomainSocket>& socket,
77 ConnectionPool& connection_pool,
78 const long timeout,
79 bool use_external)
80 : io_service_(io_service), socket_(socket), timeout_timer_(io_service_),
81 timeout_(timeout), buf_(), response_(),
82 connection_pool_(connection_pool), feed_(), watch_socket_(),
83 use_external_(use_external), defer_shutdown_(false) {
84
85 LOG_DEBUG(command_logger, DBG_COMMAND, COMMAND_SOCKET_CONNECTION_OPENED)
86 .arg(socket_->getNative());
87
88 // Callback value of 0 is used to indicate that callback function is
89 // not installed.
90 if (use_external_) {
91 watch_socket_.reset(new util::WatchSocket());
92 IfaceMgr::instance().addExternalSocket(watch_socket_->getSelectFd(), 0);
93 IfaceMgr::instance().addExternalSocket(socket_->getNative(), 0);
94 }
95
96 // Initialize state model for receiving and preparsing commands.
97 feed_.initModel();
98
99 // Start timer for detecting timeouts.
100 scheduleTimer();
101 }
102
106 ~Connection() {
107 timeout_timer_.cancel();
108 }
109
111 void scheduleTimer() {
112 timeout_timer_.setup(std::bind(&Connection::timeoutHandler, this),
113 timeout_, IntervalTimer::ONE_SHOT);
114 }
115
122 void stop() {
123 if (defer_shutdown_) {
124 io_service_->post(std::bind([](ConnectionPtr c) { c->stop(); }, shared_from_this()));
125 return;
126 }
127
128 LOG_DEBUG(command_logger, DBG_COMMAND, COMMAND_SOCKET_CONNECTION_CLOSED)
129 .arg(socket_->getNative());
130
131 if (use_external_) {
132 IfaceMgr::instance().deleteExternalSocket(watch_socket_->getSelectFd());
133 IfaceMgr::instance().deleteExternalSocket(socket_->getNative());
134
135 // Close watch socket and log errors if occur.
136 std::string watch_error;
137 if (!watch_socket_->closeSocket(watch_error)) {
138 LOG_ERROR(command_logger, COMMAND_WATCH_SOCKET_CLOSE_ERROR)
139 .arg(watch_error);
140 }
141 }
142
143 socket_->close();
144 timeout_timer_.cancel();
145 }
146
151 void terminate();
152
158 void doReceive() {
159 socket_->asyncReceive(&buf_[0], sizeof(buf_),
160 std::bind(&Connection::receiveHandler,
161 shared_from_this(), ph::_1, ph::_2));
162 }
163
171 void doSend() {
172 size_t chunk_size = (response_.size() < BUF_SIZE) ? response_.size() : BUF_SIZE;
173 socket_->asyncSend(&response_[0], chunk_size,
174 std::bind(&Connection::sendHandler, shared_from_this(), ph::_1, ph::_2));
175
176 if (use_external_) {
177 // Asynchronous send has been scheduled and we need to indicate this
178 // to break the synchronous select(). The handler should clear this
179 // status when invoked.
180 try {
181 watch_socket_->markReady();
182 } catch (const std::exception& ex) {
183 LOG_ERROR(command_logger, COMMAND_WATCH_SOCKET_MARK_READY_ERROR)
184 .arg(ex.what());
185 }
186 }
187 }
188
197 //
201 void receiveHandler(const boost::system::error_code& ec,
202 size_t bytes_transferred);
203
212 void sendHandler(const boost::system::error_code& ec,
213 size_t bytes_transferred);
214
219 void timeoutHandler();
220
221 private:
222
224 IOServicePtr io_service_;
225
227 boost::shared_ptr<UnixDomainSocket> socket_;
228
230 IntervalTimer timeout_timer_;
231
233 long timeout_;
234
236 std::array<char, BUF_SIZE> buf_;
237
239 std::string response_;
240
242 ConnectionPool& connection_pool_;
243
246 JSONFeed feed_;
247
250 util::WatchSocketPtr watch_socket_;
251
253 bool use_external_;
254
257 bool defer_shutdown_;
258};
259
261 class ConnectionPool {
262 public:
263
267 void start(const ConnectionPtr& connection) {
268 connection->doReceive();
269 connections_.insert(connection);
270 }
271
275 void stop(const ConnectionPtr& connection) {
276 try {
277 connection->stop();
278 connections_.erase(connection);
279 } catch (const std::exception& ex) {
280 LOG_ERROR(command_logger, COMMAND_SOCKET_CONNECTION_CLOSE_FAIL)
281 .arg(ex.what());
282 }
283 }
284
286 void stopAll() {
287 for (auto const& conn : connections_) {
288 conn->stop();
289 }
290 connections_.clear();
291 }
292
293 private:
294
296 std::set<ConnectionPtr> connections_;
297
298};
299
300 void
301Connection::terminate() {
302 try {
303 socket_->shutdown();
304
305 } catch (const std::exception& ex) {
306 LOG_ERROR(command_logger, COMMAND_SOCKET_CONNECTION_SHUTDOWN_FAIL)
307 .arg(ex.what());
308 }
309}
310
311 void
312Connection::receiveHandler(const boost::system::error_code& ec,
313 size_t bytes_transferred) {
314 if (ec) {
315 if (ec.value() == boost::asio::error::eof) {
316 std::stringstream os;
317 if (feed_.getProcessedText().empty()) {
318 os << "no input data to discard";
319 } else {
320 os << "discarding partial command of "
321 << feed_.getProcessedText().size() << " bytes";
322 }
323
324 // Foreign host has closed the connection. We should remove it from the
325 // connection pool.
326 LOG_INFO(command_logger, COMMAND_SOCKET_CLOSED_BY_FOREIGN_HOST)
327 .arg(socket_->getNative()).arg(os.str());
328 } else if (ec.value() != boost::asio::error::operation_aborted) {
329 LOG_ERROR(command_logger, COMMAND_SOCKET_READ_FAIL)
330 .arg(ec.value()).arg(socket_->getNative());
331 }
332
333 connection_pool_.stop(shared_from_this());
334 return;
335
336 } else if (bytes_transferred == 0) {
337 // Nothing received. Close the connection.
338 connection_pool_.stop(shared_from_this());
339 return;
340 }
341
342 LOG_DEBUG(command_logger, DBG_COMMAND, COMMAND_SOCKET_READ)
343 .arg(bytes_transferred).arg(socket_->getNative());
344
345 // Reschedule the timer because the transaction is ongoing.
346 scheduleTimer();
347
348 ConstElementPtr cmd;
349 ConstElementPtr rsp;
350
351 try {
352 // Received some data over the socket. Append them to the JSON feed
353 // to see if we have reached the end of command.
354 feed_.postBuffer(&buf_[0], bytes_transferred);
355 feed_.poll();
356 // If we haven't yet received the full command, continue receiving.
357 if (feed_.needData()) {
358 doReceive();
359 return;
360 }
361
362 // Received entire command. Parse the command into JSON.
363 if (feed_.feedOk()) {
364 cmd = feed_.toElement();
365
366 defer_shutdown_ = true;
367
368 std::unique_ptr<Connection, void(*)(Connection*)> p(this, [](Connection* p) { p->defer_shutdown_ = false; });
369
370 // Cancel the timer to make sure that long lasting command
371 // processing doesn't cause the timeout.
372 timeout_timer_.cancel();
373
374 // If successful, then process it as a command.
375 rsp = CommandMgr::instance().processCommand(cmd);
376
377 } else {
378 // Failed to parse command as JSON or process the received command.
379 // This exception will be caught below and the error response will
380 // be sent.
381 isc_throw(BadValue, feed_.getErrorMessage());
382 }
383
384 } catch (const Exception& ex) {
385 LOG_WARN(command_logger, COMMAND_PROCESS_ERROR1).arg(ex.what());
386 rsp = createAnswer(CONTROL_RESULT_ERROR, std::string(ex.what()));
387 }
388
389 // No response generated. Connection will be closed.
390 if (!rsp) {
391 LOG_WARN(command_logger, COMMAND_RESPONSE_ERROR)
392 .arg(cmd ? cmd->str() : "unknown");
393 rsp = createAnswer(CONTROL_RESULT_ERROR,
394 "internal server error: no response generated");
395
396 } else {
397
398 // Reschedule the timer as it may be either canceled or need to be
399 // updated to not timeout before we manage to the send the reply.
400 scheduleTimer();
401
402 // Let's convert JSON response to text. Note that at this stage
403 // the rsp pointer is always set.
404 response_ = rsp->str();
405
406 doSend();
407 return;
408 }
409
410 // Close the connection if we have sent the entire response.
411 connection_pool_.stop(shared_from_this());
412}
413
414 void
415Connection::sendHandler(const boost::system::error_code& ec,
416 size_t bytes_transferred) {
417 if (use_external_) {
418 // Clear the watch socket so as the future send operation can mark it
419 // again to interrupt the synchronous select() call.
420 try {
421 watch_socket_->clearReady();
422 } catch (const std::exception& ex) {
423 LOG_ERROR(command_logger, COMMAND_WATCH_SOCKET_CLEAR_ERROR)
424 .arg(ex.what());
425 }
426 }
427
428 if (ec) {
429 // If an error occurred, log this error and stop the connection.
430 if (ec.value() != boost::asio::error::operation_aborted) {
431 LOG_ERROR(command_logger, COMMAND_SOCKET_WRITE_FAIL)
432 .arg(socket_->getNative()).arg(ec.message());
433 }
434
435 } else {
436
437 // Reschedule the timer because the transaction is ongoing.
438 scheduleTimer();
439
440 // No error. We are in a process of sending a response. Need to
441 // remove the chunk that we have managed to sent with the previous
442 // attempt.
443 response_.erase(0, bytes_transferred);
444
445 LOG_DEBUG(command_logger, DBG_COMMAND, COMMAND_SOCKET_WRITE)
446 .arg(bytes_transferred).arg(response_.size())
447 .arg(socket_->getNative());
448
449 // Check if there is any data left to be sent and sent it.
450 if (!response_.empty()) {
451 doSend();
452 return;
453 }
454
455 // Gracefully shutdown the connection and close the socket if
456 // we have sent the whole response.
457 terminate();
458 }
459
460 // All data sent or an error has occurred. Close the connection.
461 connection_pool_.stop(shared_from_this());
462}
463
464 void
465Connection::timeoutHandler() {
466 LOG_INFO(command_logger, COMMAND_SOCKET_CONNECTION_TIMEOUT)
467 .arg(socket_->getNative());
468
469 try {
470 socket_->cancel();
471
472 } catch (const std::exception& ex) {
473 LOG_ERROR(command_logger, COMMAND_SOCKET_CONNECTION_CANCEL_FAIL)
474 .arg(socket_->getNative())
475 .arg(ex.what());
476 }
477
478 std::stringstream os;
479 os << "Connection over control channel timed out";
480 if (!feed_.getProcessedText().empty()) {
481 os << ", discarded partial command of "
482 << feed_.getProcessedText().size() << " bytes";
483 }
484
485 ConstElementPtr rsp = createAnswer(CONTROL_RESULT_ERROR, os.str());
486 response_ = rsp->str();
487 doSend();
488}
489
490}
491
492 namespace isc {
493 namespace config {
494
496 class UnixCommandMgrImpl {
497 public:
498
500 UnixCommandMgrImpl()
501 : timeout_(TIMEOUT_DHCP_SERVER_RECEIVE_COMMAND), use_external_(true) {
502 }
503
509 void openCommandSockets(const isc::data::ConstElementPtr config);
510
518 void openCommandSocket(const isc::data::ConstElementPtr config);
519
523 void closeCommandSocket(UnixSocketInfoPtr info);
524
528 void closeCommandSockets(bool remove = true);
529
533 void doAccept(UnixSocketInfoPtr info);
534
542 int getControlSocketFD(UnixSocketInfoPtr info);
543
546 IOServicePtr io_service_;
547
549 ConnectionPool connection_pool_;
550
552 std::map<std::string, UnixSocketInfoPtr> sockets_;
553
555 long timeout_;
556
558 bool use_external_;
559};
560
561 void
562 UnixCommandMgrImpl::openCommandSockets(const isc::data::ConstElementPtr config) {
563 if (!config) {
564 isc_throw(BadSocketInfo, "Missing config parameters, can't create socket.");
565 }
566
567 if (config->getType() != Element::list) {
568 isc_throw(DhcpConfigError, "expected list type ("
569 << config->getPosition() << ")");
570 }
571
572 for (auto const& socket : config->listValue()) {
573 openCommandSocket(socket);
574 }
575
576 auto copy = sockets_;
577 for (auto const& data : copy) {
578 if (data.second->usable_) {
579 // If the connection can be used (just created) or reused, keep it
580 // in the list and clear the flag. It will be marked again on next
581 // configuration event if needed.
582 data.second->usable_ = false;
583 } else {
584 // If the connection can not be reused, stop it and remove it from the list.
585 closeCommandSocket(data.second);
586 }
587 }
588}
589
590 void
591 UnixCommandMgrImpl::openCommandSocket(const isc::data::ConstElementPtr config) {
592 if (!config) {
593 isc_throw(BadSocketInfo, "Missing config parameters, can't create socket.");
594 }
595
596 UnixCommandConfigPtr cmd_config(new UnixCommandConfig(config));
597
598 // Search for the specific connection and reuse the existing one if found.
599 auto it = sockets_.find(cmd_config->getSocketName());
600 if (it != sockets_.end()) {
601 // If the connection can be reused, mark it as usable.
602 it->second->usable_ = true;
603 return;
604 }
605
606 // Connection not found so it needs to be created.
607 // First let's open lock file.
608 std::string lock_name = cmd_config->getLockName();
609 int lock_fd = open(lock_name.c_str(), O_RDONLY | O_CREAT, 0600);
610 if (lock_fd == -1) {
611 std::string errmsg = strerror(errno);
612 isc_throw(SocketError, "cannot create socket lockfile, "
613 << lock_name << ", : " << errmsg);
614 }
615
616 // Try to acquire lock. If we can't somebody else is actively
617 // using it.
618 int ret = flock(lock_fd, LOCK_EX | LOCK_NB);
619 if (ret != 0) {
620 std::string errmsg = strerror(errno);
621 close(lock_fd);
622 isc_throw(SocketError, "cannot lock socket lockfile, "
623 << lock_name << ", : " << errmsg);
624 }
625
626 // We have the lock, so let's remove the pre-existing socket
627 // file if it exists.
628 static_cast<void>(::remove(cmd_config->getSocketName().c_str()));
629
630 LOG_INFO(command_logger, COMMAND_ACCEPTOR_START)
631 .arg(cmd_config->getSocketName());
632
633 UnixSocketInfoPtr socket_info(new UnixSocketInfo());
634 socket_info->config_ = cmd_config;
635 socket_info->lock_fd_ = lock_fd;
636
637 try {
638 // Start asynchronous acceptor service.
639 socket_info->acceptor_.reset(new UnixDomainSocketAcceptor(io_service_));
640 UnixDomainSocketEndpoint endpoint(cmd_config->getSocketName());
641 socket_info->acceptor_->open(endpoint);
642 socket_info->acceptor_->bind(endpoint);
643 socket_info->acceptor_->listen();
644 if (use_external_) {
645 // Install this socket in Interface Manager.
646 IfaceMgr::instance().addExternalSocket(socket_info->acceptor_->getNative(), 0);
647 }
648
649 doAccept(socket_info);
650
651 } catch (const std::exception& ex) {
652 close(lock_fd);
653 static_cast<void>(::remove(cmd_config->getLockName().c_str()));
654 isc_throw(SocketError, ex.what());
655 }
656
657 sockets_[cmd_config->getSocketName()] = socket_info;
658}
659
660 void
661 UnixCommandMgrImpl::closeCommandSocket(UnixSocketInfoPtr info) {
662 if (info) {
663 // Close acceptor if the acceptor is open.
664 if (info->acceptor_ && info->acceptor_->isOpen()) {
665 if (use_external_) {
666 IfaceMgr::instance().deleteExternalSocket(info->acceptor_->getNative());
667 }
668 info->acceptor_->close();
669 static_cast<void>(::remove(info->config_->getSocketName().c_str()));
670 static_cast<void>(::remove(info->config_->getLockName().c_str()));
671 }
672
673 // Stop all connections which can be closed. The only connection that won't
674 // be closed is the one over which we have received a request to reconfigure
675 // the server. This connection will be held until the UnixCommandMgr
676 // responds to such request.
677 connection_pool_.stopAll();
678 if (info->lock_fd_ != -1) {
679 close(info->lock_fd_);
680 info->lock_fd_ = -1;
681 }
682 auto it = sockets_.find(info->config_->getSocketName());
683 if (it != sockets_.end()) {
684 sockets_.erase(it);
685 }
686 try {
687 io_service_->pollOne();
688 } catch (...) {
689 }
690 } else {
691 closeCommandSockets(false);
692 }
693}
694
695 void
696 UnixCommandMgrImpl::closeCommandSockets(bool remove) {
697 auto copy = sockets_;
698 for (auto const& data : copy) {
699 closeCommandSocket(data.second);
700 }
701 if (remove) {
702 sockets_.clear();
703 }
704}
705
706 void
707 UnixCommandMgrImpl::doAccept(UnixSocketInfoPtr info) {
708 // Create a socket into which the acceptor will accept new connection.
709 info->socket_.reset(new UnixDomainSocket(io_service_));
710 info->acceptor_->asyncAccept(*info->socket_,
711 [this, info](const boost::system::error_code& ec) {
712 if (!ec) {
713 // New connection is arriving. Start asynchronous transmission.
714 ConnectionPtr connection(new Connection(io_service_, info->socket_,
715 connection_pool_,
716 timeout_,
717 use_external_));
718 connection_pool_.start(connection);
719
720 } else if (ec.value() != boost::asio::error::operation_aborted) {
721 LOG_ERROR(command_logger, COMMAND_SOCKET_ACCEPT_FAIL)
722 .arg(info->acceptor_->getNative()).arg(ec.message());
723 }
724
725 // Unless we're stopping the service, start accepting connections again.
726 if (ec.value() != boost::asio::error::operation_aborted) {
727 doAccept(info);
728 }
729 });
730}
731
732 int
733 UnixCommandMgrImpl::getControlSocketFD(UnixSocketInfoPtr info) {
734 // Return the most recent listener or null.
735 if (info) {
736 auto const& it = sockets_.find(info->config_->getSocketName());
737 if (it != sockets_.end()) {
738 return (it->second->acceptor_->getNative());
739 }
740 } else if (sockets_.size()) {
741 return (sockets_.begin()->second->acceptor_->getNative());
742 }
743 return (-1);
744}
745
746UnixCommandMgr::UnixCommandMgr() : impl_(new UnixCommandMgrImpl()) {
747}
748
749 void
750 UnixCommandMgr::openCommandSocket(const isc::data::ConstElementPtr config) {
751 impl_->openCommandSocket(config);
752}
753
754 void
755 UnixCommandMgr::openCommandSockets(const isc::data::ConstElementPtr config) {
756 impl_->openCommandSockets(config);
757}
758
759 void
760 UnixCommandMgr::closeCommandSocket(UnixSocketInfoPtr info) {
761 impl_->closeCommandSocket(info);
762}
763
764 void
765 UnixCommandMgr::closeCommandSockets() {
766 impl_->closeCommandSockets();
767}
768
769 int
770 UnixCommandMgr::getControlSocketFD(UnixSocketInfoPtr info) {
771 return (impl_->getControlSocketFD(info));
772}
773
774 UnixCommandMgr&
775 UnixCommandMgr::instance() {
776 static UnixCommandMgr cmd_mgr;
777 return (cmd_mgr);
778}
779
780 void
781 UnixCommandMgr::setIOService(const IOServicePtr& io_service) {
782 impl_->io_service_ = io_service;
783}
784
785 void
786 UnixCommandMgr::setConnectionTimeout(const long timeout) {
787 impl_->timeout_ = timeout;
788}
789
790 void
791 UnixCommandMgr::addExternalSockets(bool use_external) {
792 impl_->use_external_ = use_external;
793}
794
795} // end of isc::config
796} // end of isc
if
if(!(yy_init))
Definition agent_lexer.cc:1900
asio_wrapper.h
Element::list
@ list
Definition data.h:146
isc::Exception::what
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
Definition exceptions/exceptions.cc:32
isc::asiolink::IntervalTimer::ONE_SHOT
@ ONE_SHOT
Definition interval_timer.h:63
isc::asiolink::UnixDomainSocketAcceptor
Implements acceptor service for UnixDomainSocket.
Definition unix_domain_socket_acceptor.h:26
isc::asiolink::UnixDomainSocketEndpoint
Endpoint for UnixDomainSocket.
Definition unix_domain_socket_endpoint.h:24
isc::asiolink::UnixDomainSocket
Represents unix domain socket implemented in terms of boost asio.
Definition unix_domain_socket.h:30
isc::config::BadSocketInfo
An exception indicating that specified socket parameters are invalid.
Definition command_mgr.h:17
isc::config::BaseCommandMgr::processCommand
virtual isc::data::ConstElementPtr processCommand(const isc::data::ConstElementPtr &cmd)
Triggers command processing.
Definition base_command_mgr.cc:119
isc::config::CommandMgr::instance
static CommandMgr & instance()
CommandMgr is a singleton class.
Definition command_mgr.cc:18
isc::config::SocketError
An exception indicating a problem with socket operation.
Definition unix_command_mgr.h:22
isc::config::UnixCommandConfig
UNIX command config aka UNIX control socket info class.
Definition unix_command_config.h:23
isc::config::UnixCommandMgrImpl
Implementation of the UnixCommandMgr.
Definition unix_command_mgr.cc:496
isc::config::UnixCommandMgrImpl::closeCommandSocket
void closeCommandSocket(UnixSocketInfoPtr info)
Shuts down any open unix control sockets.
Definition unix_command_mgr.cc:661
isc::config::UnixCommandMgrImpl::openCommandSockets
void openCommandSockets(const isc::data::ConstElementPtr config)
Opens acceptor service allowing the control clients to connect.
Definition unix_command_mgr.cc:562
isc::config::UnixCommandMgrImpl::timeout_
long timeout_
Connection timeout.
Definition unix_command_mgr.cc:555
isc::config::UnixCommandMgrImpl::connection_pool_
ConnectionPool connection_pool_
Pool of connections.
Definition unix_command_mgr.cc:549
isc::config::UnixCommandMgrImpl::use_external_
bool use_external_
Use external sockets flag.
Definition unix_command_mgr.cc:558
isc::config::UnixCommandMgrImpl::doAccept
void doAccept(UnixSocketInfoPtr info)
Asynchronously accepts next connection.
Definition unix_command_mgr.cc:707
isc::config::UnixCommandMgrImpl::closeCommandSockets
void closeCommandSockets(bool remove=true)
Shuts down any open unix control sockets.
Definition unix_command_mgr.cc:696
isc::config::UnixCommandMgrImpl::sockets_
std::map< std::string, UnixSocketInfoPtr > sockets_
The UNIX socket data (configuration, acceptor, etc.).
Definition unix_command_mgr.cc:552
isc::config::UnixCommandMgrImpl::openCommandSocket
void openCommandSocket(const isc::data::ConstElementPtr config)
Opens acceptor service allowing the control clients to connect.
Definition unix_command_mgr.cc:591
isc::config::UnixCommandMgrImpl::UnixCommandMgrImpl
UnixCommandMgrImpl()
Constructor.
Definition unix_command_mgr.cc:500
isc::config::UnixCommandMgrImpl::io_service_
IOServicePtr io_service_
Pointer to the IO service used by the server process for running asynchronous tasks.
Definition unix_command_mgr.cc:546
isc::config::UnixCommandMgrImpl::getControlSocketFD
int getControlSocketFD(UnixSocketInfoPtr info)
Returns unix control socket descriptor.
Definition unix_command_mgr.cc:733
isc::config::UnixCommandMgr
Unix Commands Manager implementation for the Kea servers.
Definition unix_command_mgr.h:33
isc::config::UnixCommandMgr::instance
static UnixCommandMgr & instance()
UnixCommandMgr is a singleton class.
Definition unix_command_mgr.cc:775
isc::config::UnixCommandMgr::setIOService
void setIOService(const asiolink::IOServicePtr &io_service)
Sets IO service to be used by the unix command manager.
Definition unix_command_mgr.cc:781
isc::config::UnixCommandMgr::getControlSocketFD
int getControlSocketFD(UnixSocketInfoPtr info=UnixSocketInfoPtr())
Returns unix control socket descriptor.
Definition unix_command_mgr.cc:770
isc::config::UnixCommandMgr::openCommandSockets
void openCommandSockets(const isc::data::ConstElementPtr config)
Opens unix control socket with parameters specified in socket_info (required parameters: socket-type:...
Definition unix_command_mgr.cc:755
isc::config::UnixCommandMgr::closeCommandSockets
void closeCommandSockets()
Shuts down any open unix control sockets.
Definition unix_command_mgr.cc:765
isc::config::UnixCommandMgr::addExternalSockets
void addExternalSockets(bool use_external=true)
Use external sockets flag.
Definition unix_command_mgr.cc:791
isc::config::UnixCommandMgr::closeCommandSocket
void closeCommandSocket(UnixSocketInfoPtr info=UnixSocketInfoPtr())
Shuts down any open unix control sockets.
Definition unix_command_mgr.cc:760
isc::config::UnixCommandMgr::setConnectionTimeout
void setConnectionTimeout(const long timeout)
Override default connection timeout.
Definition unix_command_mgr.cc:786
isc::config::UnixCommandMgr::openCommandSocket
void openCommandSocket(const isc::data::ConstElementPtr config)
Opens unix control socket with parameters specified in socket_info (required parameters: socket-type:...
Definition unix_command_mgr.cc:750
isc::dhcp::DhcpConfigError
To be removed. Please use ConfigError instead.
Definition dhcp_config_error.h:58
isc::dhcp::IfaceMgr::deleteExternalSocket
void deleteExternalSocket(int socketfd)
Deletes external socket.
Definition iface_mgr.cc:352
isc::dhcp::IfaceMgr::instance
static IfaceMgr & instance()
IfaceMgr is a singleton class.
Definition iface_mgr.cc:54
isc::dhcp::IfaceMgr::addExternalSocket
void addExternalSocket(int socketfd, SocketCallback callback)
Adds external socket and a callback.
Definition iface_mgr.cc:329
command_interpreter.h
This file contains several functions and constants that are used for handling commands and responses ...
command_mgr.h
config_log.h
data.h
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition exceptions/exceptions.h:210
iface_mgr.h
interval_timer.h
io_service.h
json_feed.h
LOG_ERROR
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition macros.h:32
LOG_INFO
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition macros.h:20
LOG_WARN
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition macros.h:26
LOG_DEBUG
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition macros.h:14
isc::asiolink
Definition addr_utilities.cc:170
isc::asiolink::IOServicePtr
boost::shared_ptr< IOService > IOServicePtr
Defines a smart pointer to an IOService instance.
Definition io_service.h:28
isc::config
Definition command_interpreter.cc:23
isc::config::COMMAND_PROCESS_ERROR1
const isc::log::MessageID COMMAND_PROCESS_ERROR1
Definition config_messages.h:18
isc::config::UnixSocketInfoPtr
boost::shared_ptr< UnixSocketInfo > UnixSocketInfoPtr
Pointer to a UnixSocketInfo object.
Definition unix_command_config.h:152
isc::config::COMMAND_SOCKET_READ_FAIL
const isc::log::MessageID COMMAND_SOCKET_READ_FAIL
Definition config_messages.h:32
isc::config::COMMAND_SOCKET_CONNECTION_SHUTDOWN_FAIL
const isc::log::MessageID COMMAND_SOCKET_CONNECTION_SHUTDOWN_FAIL
Definition config_messages.h:29
isc::config::COMMAND_SOCKET_CONNECTION_CLOSED
const isc::log::MessageID COMMAND_SOCKET_CONNECTION_CLOSED
Definition config_messages.h:26
isc::config::UnixCommandConfigPtr
boost::shared_ptr< UnixCommandConfig > UnixCommandConfigPtr
Pointer to a UnixCommandConfig object.
Definition unix_command_config.h:123
isc::config::CONTROL_RESULT_ERROR
const int CONTROL_RESULT_ERROR
Status code indicating a general failure.
Definition command_interpreter.h:45
isc::config::COMMAND_SOCKET_CONNECTION_CANCEL_FAIL
const isc::log::MessageID COMMAND_SOCKET_CONNECTION_CANCEL_FAIL
Definition config_messages.h:25
isc::config::COMMAND_SOCKET_CONNECTION_OPENED
const isc::log::MessageID COMMAND_SOCKET_CONNECTION_OPENED
Definition config_messages.h:28
isc::config::COMMAND_SOCKET_CLOSED_BY_FOREIGN_HOST
const isc::log::MessageID COMMAND_SOCKET_CLOSED_BY_FOREIGN_HOST
Definition config_messages.h:24
isc::config::COMMAND_SOCKET_CONNECTION_TIMEOUT
const isc::log::MessageID COMMAND_SOCKET_CONNECTION_TIMEOUT
Definition config_messages.h:30
isc::config::COMMAND_ACCEPTOR_START
const isc::log::MessageID COMMAND_ACCEPTOR_START
Definition config_messages.h:11
isc::config::createAnswer
ConstElementPtr createAnswer()
Creates a standard config/command level success answer message (i.e.
Definition command_interpreter.cc:54
isc::config::COMMAND_RESPONSE_ERROR
const isc::log::MessageID COMMAND_RESPONSE_ERROR
Definition config_messages.h:22
isc::config::TIMEOUT_DHCP_SERVER_RECEIVE_COMMAND
constexpr long TIMEOUT_DHCP_SERVER_RECEIVE_COMMAND
Timeout for the DHCP server to receive command over the unix domain socket.
Definition timeouts.h:17
isc::config::COMMAND_SOCKET_WRITE_FAIL
const isc::log::MessageID COMMAND_SOCKET_WRITE_FAIL
Definition config_messages.h:34
isc::config::COMMAND_SOCKET_CONNECTION_CLOSE_FAIL
const isc::log::MessageID COMMAND_SOCKET_CONNECTION_CLOSE_FAIL
Definition config_messages.h:27
isc::config::COMMAND_WATCH_SOCKET_CLOSE_ERROR
const isc::log::MessageID COMMAND_WATCH_SOCKET_CLOSE_ERROR
Definition config_messages.h:36
isc::config::DBG_COMMAND
const int DBG_COMMAND
Definition config_log.h:24
isc::config::COMMAND_SOCKET_READ
const isc::log::MessageID COMMAND_SOCKET_READ
Definition config_messages.h:31
isc::config::command_logger
isc::log::Logger command_logger("commands")
Command processing Logger.
Definition config_log.h:21
isc::config::COMMAND_WATCH_SOCKET_MARK_READY_ERROR
const isc::log::MessageID COMMAND_WATCH_SOCKET_MARK_READY_ERROR
Definition config_messages.h:37
isc::config::COMMAND_SOCKET_WRITE
const isc::log::MessageID COMMAND_SOCKET_WRITE
Definition config_messages.h:33
isc::config::COMMAND_WATCH_SOCKET_CLEAR_ERROR
const isc::log::MessageID COMMAND_WATCH_SOCKET_CLEAR_ERROR
Definition config_messages.h:35
isc::data
Definition base_stamped_element.cc:12
isc::data::copy
ElementPtr copy(ConstElementPtr from, int level)
Copy the data up to a nesting level.
Definition data.cc:1420
isc::data::ConstElementPtr
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:29
isc::db::info
@ info
Definition db_log.h:120
isc::dhcp
Definition dhcp4/client_handler.cc:20
isc::util::WatchSocketPtr
boost::shared_ptr< WatchSocket > WatchSocketPtr
Defines a smart pointer to an instance of a WatchSocket.
Definition watch_socket.h:138
isc
Defines the logger used by the top-level component of kea-lfc.
Definition agent_parser.cc:148
isc::config::UnixSocketInfo
Structure used to store UNIX connection data.
Definition unix_command_config.h:127
timeouts.h
unix_command_config.h
unix_command_mgr.h
unix_domain_socket.h
unix_domain_socket_acceptor.h
unix_domain_socket_endpoint.h
watch_socket.h
Defines the class, WatchSocket.