Kea  1.9.9-git
unix_control_client.cc
Go to the documentation of this file.
1 // Copyright (C) 2015-2019 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #include <config.h>
8 
9 #include <gtest/gtest.h>
11 #include <unistd.h>
12 #include <sys/socket.h>
13 #include <sys/un.h>
14 #include <errno.h>
15 #include <string.h>
16 
17 namespace isc {
18 namespace dhcp {
19 namespace test {
20 
22  socket_fd_ = -1;
23 }
24 
27 }
28 
31  if (socket_fd_ >= 0) {
32  static_cast<void>(close(socket_fd_));
33  socket_fd_ = -1;
34  }
35 }
36 
37 bool UnixControlClient::connectToServer(const std::string& socket_path) {
38  // Create UNIX socket
39  socket_fd_ = socket(AF_UNIX, SOCK_STREAM, 0);
40  if (socket_fd_ < 0) {
41  const char* errmsg = strerror(errno);
42  ADD_FAILURE() << "Failed to open unix stream socket: " << errmsg;
43  return (false);
44  }
45 
46  struct sockaddr_un srv_addr;
47  if (socket_path.size() > sizeof(srv_addr.sun_path) - 1) {
48  ADD_FAILURE() << "Socket path specified (" << socket_path
49  << ") is larger than " << (sizeof(srv_addr.sun_path) - 1)
50  << " allowed.";
52  return (false);
53  }
54 
55  // Prepare socket address
56  memset(&srv_addr, 0, sizeof(srv_addr));
57  srv_addr.sun_family = AF_UNIX;
58  strncpy(srv_addr.sun_path, socket_path.c_str(),
59  sizeof(srv_addr.sun_path) - 1);
60  socklen_t len = sizeof(srv_addr);
61 
62  // Connect to the specified UNIX socket
63  int status = connect(socket_fd_, (struct sockaddr*)&srv_addr, len);
64  if (status == -1) {
65  const char* errmsg = strerror(errno);
66  ADD_FAILURE() << "Failed to connect unix socket: fd=" << socket_fd_
67  << ", path=" << socket_path << " : " << errmsg;
69  return (false);
70  }
71 
72  return (true);
73 }
74 
75 bool UnixControlClient::sendCommand(const std::string& command) {
76  // Send command
77  int bytes_sent = send(socket_fd_, command.c_str(), command.length(), 0);
78  if (bytes_sent < command.length()) {
79  const char* errmsg = strerror(errno);
80  ADD_FAILURE() << "Failed to send " << command.length()
81  << " bytes, send() returned " << bytes_sent
82  << " : " << errmsg;
83  return (false);
84  }
85 
86  return (true);
87 }
88 
89 bool UnixControlClient::getResponse(std::string& response,
90  const unsigned int timeout_sec) {
91  // Receive response
92  char buf[65536];
93  memset(buf, 0, sizeof(buf));
94  switch (selectCheck(timeout_sec)) {
95  case -1: {
96  const char* errmsg = strerror(errno);
97  ADD_FAILURE() << "getResponse - select failed: " << errmsg;
98  return (false);
99  }
100  case 0:
101  return (false);
102 
103  default:
104  break;
105  }
106 
107  int bytes_rcvd = recv(socket_fd_, buf, sizeof(buf), 0);
108  if (bytes_rcvd < 0) {
109  const char* errmsg = strerror(errno);
110  ADD_FAILURE() << "Failed to receive a response. recv() returned "
111  << bytes_rcvd << " : " << errmsg;
112  return (false);
113  }
114 
115  // Convert the response to a string
116  response = std::string(buf, bytes_rcvd);
117  return (true);
118 }
119 
120 int UnixControlClient::selectCheck(const unsigned int timeout_sec) {
121  int maxfd = 0;
122 
123  fd_set read_fds;
124  FD_ZERO(&read_fds);
125 
126  // Add this socket to listening set
127  FD_SET(socket_fd_, &read_fds);
128  maxfd = socket_fd_;
129 
130  struct timeval select_timeout;
131  select_timeout.tv_sec = static_cast<time_t>(timeout_sec);
132  select_timeout.tv_usec = 0;
133 
134  return (select(maxfd + 1, &read_fds, NULL, NULL, &select_timeout));
135 }
136 
137 };
138 };
139 };
void disconnectFromServer()
Closes the Control Channel socket.
int selectCheck(const unsigned int timeout_sec)
Uses select to poll the Control Channel for data waiting.
bool connectToServer(const std::string &socket_path)
Connects to a Unix socket at the given path.
UnixControlClient()
Default constructor.
bool getResponse(std::string &response, const unsigned int timeout_sec=0)
Reads the response text from the open Control Channel.
Defines the logger used by the top-level component of kea-dhcp-ddns.
bool sendCommand(const std::string &command)
Sends the given command across the open Control Channel.
int socket_fd_
Retains the fd of the open socket.