Browse Source

[3880] Control channel documented (devel guide)

Tomek Mrugalski 10 years ago
parent
commit
9afab5ab23
2 changed files with 204 additions and 0 deletions
  1. 5 0
      doc/devel/mainpage.dox
  2. 199 0
      src/lib/config/command-socket.dox

+ 5 - 0
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

+ 199 - 0
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 <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). 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.
+
+*/