diff --git a/doc/devel/mainpage.dox b/doc/devel/mainpage.dox index 7ee81a8d51..7c1ec42b48 100644 --- a/doc/devel/mainpage.dox +++ b/doc/devel/mainpage.dox @@ -81,6 +81,11 @@ * - @subpage lfc * - @subpage lfcProcessing * - @subpage lfcFiles + * - @subpage ctrlSocket + * - @subpage ctrlSocketOverview + * - @subpage ctrlSocketClient + * - @subpage ctrlSocketImpl + * - @subpage ctrlSocketConnections * - @subpage libdhcp * - @subpage libdhcpIntro * - @subpage libdhcpRelay diff --git a/src/lib/config/command-socket.dox b/src/lib/config/command-socket.dox new file mode 100644 index 0000000000..207873f094 --- /dev/null +++ b/src/lib/config/command-socket.dox @@ -0,0 +1,199 @@ +// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC") +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +/** + @page ctrlSocket Control Channel + +@section ctrlSocketOverview Control Channel Overview + +In many cases it is useful to manage certain aspects of the DHCP servers. +DHCPv4 component in Kea supports control channel. It allows external entity +(e.g. a tool run by a sysadmin or a script) to influence the server and extract +certain information out from it. Several notable examples envisaged are: +reconfiguration, statistics retrival and manipulation and shutdown. + +@todo: Update this text once control channel support in DHCPv6 is added. + +Communication over control channel is conducted using JSON structures. +Currently (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 +structure in the following format: + +@code +{ + "command": "foo", + "arguments": { + "param_foo": "value1", + "param_bar": "value2", + ... + } +} +@endcode + +command field is mandatory. Depending on the actual command, the arguments field +may be absent, it may contain a single parameter or a map or parameters. The +exact format is command specific. The server will process incoming command and +send a response: + +@code +{ + "result": 0|1, + "text": "textual description", + "arguments": { + "argument1": "value1", + "argument2": "value2", + ... + } +} +@endcode + +Result designates outcome of the command. 0 means a success and 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 map always appears, even if there are no parameters. + +@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 an 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") +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include +#include +#include +#include +#include + +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). This method calls @ref + isc::config::CommandSocketFactory::create method, which in turn calls type specific + creation method. Again, currently only UNIX type is supported, but the factory + class is expected to be extended to cover additional types. +- @ref isc::config::CommandMgr::closeCommandSocket() - it is used to close the + socket. It calls @ref isc::config::CommandSocketFactory::close method that may + do type specific closure operations. In particular, for UNIX socket, it also + deletes the file after socket was closed. + +@section ctrlSocketConnections Accepting connections + +Command channel is connection oriented communication. In that sense it is +different than all other communications supported so far in Kea. To facilitate +connections, several mechanisms were implemented. Once control socket is opened, +a special callback (@ref isc::config::CommandMgr::connectionAcceptor) is +installed to process incoming connections. When select called in +@ref isc::dhcp::IfaceMgr::receive4 indicates that there is some data to be +processed, this callback calls accept, which creates a new socket for handling +this particular incoming connection. Also, it install another callback +(@ref isc::config::CommandMgr::commandReader) that will process incoming +data or will close the socket when necessary. CommandReader reads data from +incoming socket and attempts to parse it as JSON structures. If successful, +it calls isc::config::CommandMgr::processCommand(), serializes the structure +returned and attempts to send it back. + +@todo Currently commands and responses up to 64KB are supported. It was deemed +sufficient for the current needs, but in the future we may need to extend +it to handle bigger structures. + +*/