command-socket.dox 6.23 KB
Newer Older
1
// Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC")
2
//
3
4
5
// 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/.
6
7
8
9
10
11

/**
 @page ctrlSocket Control Channel

@section ctrlSocketOverview Control Channel Overview

12
13
14
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
15
or a script) to issue commands to the server which can influence its
Josh Soref's avatar
Josh Soref committed
16
behavior or retrieve information from it. Several notable examples
17
envisioned are: reconfiguration, statistics retrieval and manipulation,
Tomek Mrugalski's avatar
Tomek Mrugalski committed
18
and shutdown.
19
20

Communication over Control Channel is conducted using JSON structures.
21
22
As of Kea 0.9.2, the only supported communication channel is UNIX stream
socket, but additional types may be added in the future.
23
24
25

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
26
commands structured as follows:
27
28
29

@code
{
30
    "command": "foo",
31
32
33
34
35
36
37
38
    "arguments": {
        "param_foo": "value1",
        "param_bar": "value2",
        ...
    }
}
@endcode

Tomek Mrugalski's avatar
Tomek Mrugalski committed
39
- command - is the name of command to execute and is mandatory.
40
- arguments - contain a single parameter or a map or parameters
41
42
43
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:
44
45
46
47
48
49
50
51
52
53
54
55
56

@code
{
    "result": 0|1,
    "text": "textual description",
    "arguments": {
        "argument1": "value1",
        "argument2": "value2",
        ...
    }
}
@endcode

57
58
59
60
61
- 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.
Tomek Mrugalski's avatar
Tomek Mrugalski committed
62
- arguments - is a map of additional data values returned by the server, specific to the
63
command issue. The map is always present, even if it contains no data values.
64

65
@section ctrlSocketClient Using Control Channel
66

67
Here are two examples of how to access the Control Channel:
68
69
70
71
72
73

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
74
You then can type JSON commands and get responses (also in JSON format).
75
76
77
78
79

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")
//
80
81
82
// 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/.
83
84
85
86
87
88
89

#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

90
int main(int argc, const char* argv[]) {
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

    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)
106
    struct sockaddr_un srv_addr;
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
    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
151
to be used directly, unless someone implements a new Control Channel (e.g. TCP
152
153
154
155
156
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
157
  the named socket to be created).
158
- @ref isc::config::CommandMgr::closeCommandSocket() - it is used to close the
159
  socket.
160
161
162

@section ctrlSocketConnections Accepting connections

163
164
165
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.
166
Thus, before the server can use the @ref isc::config::CommandMgr it must
167
provide it with a common instance of the @ref isc::asiolink::IOService
168
object using @ref isc::config::CommandMgr::setIOService. The server's
169
170
171
172
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.

173
174

*/