123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- // Copyright (C) 2015-2017 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/.
- /**
- @page ctrlSocket Control Channel
- @section ctrlSocketOverview Control Channel Overview
- In many cases it is useful to manage certain aspects of the DHCP servers
- while they are running. In Kea, this may be done via the Control Channel.
- Control Channel allows an external entity (e.g. a tool run by a sysadmin
- or a script) to issue commands to the server which can influence its
- behavior or retreive information from it. Several notable examples
- envisioned are: reconfiguration, statistics retrieval and manipulation,
- and shutdown.
- Communication over Control Channel is conducted using JSON structures.
- As of Kea 0.9.2, the only supported communication channel is UNIX stream
- socket, but additional types may be added in the future.
- If configured, Kea will open a socket and will listen for any incoming
- connections. A process connecting to this socket is expected to send JSON
- commands structured as follows:
- @code
- {
- "command": "foo",
- "arguments": {
- "param_foo": "value1",
- "param_bar": "value2",
- ...
- }
- }
- @endcode
- - command - is the name of command to execute and is mandatory.
- - arguments - contain a single parameter or a map or parameters
- required to carry out the given command. The exact content and format is command specific.
- The server will process the incoming command and then send a response of the form:
- @code
- {
- "result": 0|1,
- "text": "textual description",
- "arguments": {
- "argument1": "value1",
- "argument2": "value2",
- ...
- }
- }
- @endcode
- - result - indicates the outcome of the command. A value of 0 means a success while
- any non-zero value designates an error. Currently 1 is used as a generic error, but additional
- error codes may be added in the future.
- - text field - typically appears when result is non-zero and contains description of the error
- encountered.
- - arguments - is a map of additional data values returned by the server, specific to the
- command issue. The map is always present, even if it contains no data values.
- @section ctrlSocketClient Using Control Channel
- Here are two examples of how to access the Control Channel:
- 1. Use socat tool, which is available in many Linux and BSD distributions.
- See http://www.dest-unreach.org/socat/ for details. To use it:
- @code
- socat UNIX:/var/run/kea/kea4.sock -
- @endcode
- You then can type JSON commands and get responses (also in JSON format).
- 2. Here's an example C code that connects and gets a list of supported commands:
- @code
- // Copyright (C) 2015 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/.
- #include <sys/socket.h>
- #include <sys/un.h>
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- int main(int argc, const char* argv[]) {
- if (argc != 2) {
- printf("Usage: %s socket_path\n", argv[0]);
- return (1);
- }
- // Create UNIX stream socket.
- int socket_fd;
- if ((socket_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
- {
- perror("Failed to create UNIX stream");
- return (1);
- }
- // Specify the address to connect to (unix path)
- struct sockaddr_un srv_addr;
- memset(&srv_addr, 0, sizeof(struct sockaddr_un));
- srv_addr.sun_family = AF_UNIX;
- strcpy(srv_addr.sun_path, argv[1]);
- socklen_t len = sizeof(srv_addr);
- // Try to connect.
- if (connect(socket_fd, (struct sockaddr*) &srv_addr, len) == -1) {
- perror("Failed to connect");
- return (1);
- }
- // Send a command to list all available commands.
- char buf[1024];
- sprintf(buf, "{ \"command\": \"list-commands\" }");
- int bytes_sent = send(socket_fd, buf, strlen(buf), 0);
- printf("%d bytes sent\n", bytes_sent);
- // Receive a response (should be JSON formatted list of commands)
- int bytes_rcvd = recv(socket_fd, buf, sizeof(buf), 0);
- printf("%d bytes received: [%s]\n", bytes_rcvd, buf);
- // Close the socket
- close(socket_fd);
- return 0;
- }
- @endcode
- @section ctrlSocketImpl Control Channel Implementation
- Control Channel is implemented in @ref isc::config::CommandMgr. It is a signleton
- class that allows registration of callbacks that handle specific commands.
- It internally supports a single command: @c list-commands that returns a list
- of supported commands. This component is expected to be shared among all daemons.
- There are 3 main methods that are expected to be used by developers:
- - @ref isc::config::CommandMgr::registerCommand, which allows registration of
- additional commands.
- - @ref isc::config::CommandMgr::deregisterCommand, which allows removing previously
- registered command.
- - @ref isc::config::CommandMgr::processCommand, which allows handling specified
- command.
- There are also two methods for managing control sockets. They are not expected
- to be used directly, unless someone implements a new Control Channel (e.g. TCP
- or HTTPS connection):
- - @ref isc::config::CommandMgr::openCommandSocket that passes structure defined
- in the configuration file. Currently only two parameters are supported: socket-type
- (which must contain value 'unix') and socket-name (which contains unix path for
- the named socket to be created).
- - @ref isc::config::CommandMgr::closeCommandSocket() - it is used to close the
- socket.
- @section ctrlSocketConnections Accepting connections
- The @ref isc::config::CommandMgr is implemented using boost ASIO and uses
- asynchronous calls to accept new connections and receive commands from the
- controlling clients. ASIO uses IO service object to run asynchronous calls.
- Thus, before the server can use the @ref isc::config::CommandMgr it must
- provide it with a common instance of the @ref isc::asiolink::IOService
- object using @ref isc::config::CommandMgr::setIOService. The server's
- main loop must contain calls to @ref isc::asiolink::IOService::run or
- @ref isc::asiolink::IOService::poll or their variants to invoke Command
- Manager's handlers as required for processing control requests.
- */
|