command-socket.dox 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. // Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. /**
  15. @page ctrlSocket Control Channel
  16. @section ctrlSocketOverview Control Channel Overview
  17. In many cases it is useful to manage certain aspects of the DHCP servers
  18. while they are running. In Kea, this may be done via the Control Channel.
  19. Control Channel allows an external entity (e.g. a tool run by a sysadmin
  20. or a script) to issue commands to the server which can influence its
  21. behavior or retreive information from it. Several notable examples
  22. envisioned are: reconfiguration, statistics retrieval and manipulation,
  23. and shutdown.
  24. Communication over Control Channel is conducted using JSON structures.
  25. As of Kea 0.9.2, the only supported communication channel is UNIX stream
  26. socket, but additional types may be added in the future.
  27. If configured, Kea will open a socket and will listen for any incoming
  28. connections. A process connecting to this socket is expected to send JSON
  29. commands structured as follows:
  30. @code
  31. {
  32. "command": "foo",
  33. "arguments": {
  34. "param_foo": "value1",
  35. "param_bar": "value2",
  36. ...
  37. }
  38. }
  39. @endcode
  40. - command - is the name of command to execute and is mandatory.
  41. - arguments - contain a single parameter or a map or parameters
  42. required to carry out the given command. The exact content and format is command specific.
  43. The server will process the incoming command and then send a response of the form:
  44. @code
  45. {
  46. "result": 0|1,
  47. "text": "textual description",
  48. "arguments": {
  49. "argument1": "value1",
  50. "argument2": "value2",
  51. ...
  52. }
  53. }
  54. @endcode
  55. - result - indicates the outcome of the command. A value of 0 means a success while
  56. any non-zero value designates an error. Currently 1 is used as a generic error, but additional
  57. error codes may be added in the future.
  58. - text field - typically appears when result is non-zero and contains description of the error
  59. encountered.
  60. - arguments - is a map of additional data values returned by the server, specific to the
  61. command issue. The map is always present, even if it contains no data values.
  62. @section ctrlSocketClient Using Control Channel
  63. Here are two examples of how to access the Control Channel:
  64. 1. Use socat tool, which is available in many Linux and BSD distributions.
  65. See http://www.dest-unreach.org/socat/ for details. To use it:
  66. @code
  67. socat UNIX:/var/run/kea/kea4.sock -
  68. @endcode
  69. You then can type JSON commands and get responses (also in JSON format).
  70. 2. Here's an example C code that connects and gets a list of supported commands:
  71. @code
  72. // Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
  73. //
  74. // Permission to use, copy, modify, and/or distribute this software for any
  75. // purpose with or without fee is hereby granted, provided that the above
  76. // copyright notice and this permission notice appear in all copies.
  77. //
  78. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  79. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  80. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  81. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  82. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  83. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  84. // PERFORMANCE OF THIS SOFTWARE.
  85. #include <sys/socket.h>
  86. #include <sys/un.h>
  87. #include <stdio.h>
  88. #include <string.h>
  89. #include <unistd.h>
  90. int main(int argc, const char* argv[]) {
  91. if (argc != 2) {
  92. printf("Usage: %s socket_path\n", argv[0]);
  93. return (1);
  94. }
  95. // Create UNIX stream socket.
  96. int socket_fd;
  97. if ((socket_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
  98. {
  99. perror("Failed to create UNIX stream");
  100. return (1);
  101. }
  102. // Specify the address to connect to (unix path)
  103. struct sockaddr_un srv_addr;
  104. memset(&srv_addr, 0, sizeof(struct sockaddr_un));
  105. srv_addr.sun_family = AF_UNIX;
  106. strcpy(srv_addr.sun_path, argv[1]);
  107. socklen_t len = sizeof(srv_addr);
  108. // Try to connect.
  109. if (connect(socket_fd, (struct sockaddr*) &srv_addr, len) == -1) {
  110. perror("Failed to connect");
  111. return (1);
  112. }
  113. // Send a command to list all available commands.
  114. char buf[1024];
  115. sprintf(buf, "{ \"command\": \"list-commands\" }");
  116. int bytes_sent = send(socket_fd, buf, strlen(buf), 0);
  117. printf("%d bytes sent\n", bytes_sent);
  118. // Receive a response (should be JSON formatted list of commands)
  119. int bytes_rcvd = recv(socket_fd, buf, sizeof(buf), 0);
  120. printf("%d bytes received: [%s]\n", bytes_rcvd, buf);
  121. // Close the socket
  122. close(socket_fd);
  123. return 0;
  124. }
  125. @endcode
  126. @section ctrlSocketImpl Control Channel Implementation
  127. Control Channel is implemented in @ref isc::config::CommandMgr. It is a signleton
  128. class that allows registration of callbacks that handle specific commands.
  129. It internally supports a single command: @c list-commands that returns a list
  130. of supported commands. This component is expected to be shared among all daemons.
  131. There are 3 main methods that are expected to be used by developers:
  132. - @ref isc::config::CommandMgr::registerCommand, which allows registration of
  133. additional commands.
  134. - @ref isc::config::CommandMgr::deregisterCommand, which allows removing previously
  135. registered command.
  136. - @ref isc::config::CommandMgr::processCommand, which allows handling specified
  137. command.
  138. There are also two methods for managing control sockets. They are not expected
  139. to be used directly, unless someone implements a new Control Channel (e.g. TCP
  140. or HTTPS connection):
  141. - @ref isc::config::CommandMgr::openCommandSocket that passes structure defined
  142. in the configuration file. Currently only two parameters are supported: socket-type
  143. (which must contain value 'unix') and socket-name (which contains unix path for
  144. the named socket to be created). This method calls @ref
  145. isc::config::CommandSocketFactory::create method, which parses the parameters
  146. and instantiates one object from a class derived from @ref isc::config::CommandSocket.
  147. Again, currently only UNIX type is supported, but the factory
  148. class is expected to be extended to cover additional types.
  149. - @ref isc::config::CommandMgr::closeCommandSocket() - it is used to close the
  150. socket. It calls close method on the @ref isc::config::CommandSocket object, if
  151. one exists. In particular, for UNIX socket, it also deletes the file after socket
  152. was closed.
  153. @section ctrlSocketConnections Accepting connections
  154. Control Channel is connection oriented communication. In that sense it is
  155. different than all other communications supported so far in Kea. To facilitate
  156. connections, several mechanisms were implemented. Intially a single UNIX socket
  157. it opened (see isc::config::UnixCommandSocket). Its @ref
  158. isc::config::UnixCommandSocket::receiveHandler callback method is
  159. installed in @ref isc::dhcp::IfaceMgr to process incoming connections. When the
  160. select call in @ref isc::dhcp::IfaceMgr::receive4 indicates that there is some data to be
  161. processed, this callback calls accept, which creates a new socket for handling
  162. this particular incoming connection. Once the socket descriptor is known, a new
  163. instance of @ref isc::config::ConnectionSocket is created to represent that
  164. socket (and the whole ongoing connection). It installs another callback
  165. (@ref isc::config::ConnectionSocket::receiveHandler that calls
  166. (@ref isc::config::CommandMgr::commandReader) that will process incoming
  167. data or will close the socket when necessary. CommandReader reads data from
  168. incoming socket and attempts to parse it as JSON structures. If successful,
  169. it calls isc::config::CommandMgr::processCommand(), serializes the structure
  170. returned and attempts to send it back.
  171. @todo Currently commands and responses up to 64KB are supported. It was deemed
  172. sufficient for the current needs, but in the future we may need to extend
  173. it to handle bigger structures.
  174. */