1 /** 2 * Copyright © 2016 IBM Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <assert.h> 18 #include <err.h> 19 #include <errno.h> 20 #include <limits.h> 21 #include <stdbool.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> 25 #include <termios.h> 26 #include <unistd.h> 27 #include <endian.h> 28 29 #include <sys/socket.h> 30 #include <sys/un.h> 31 #include <systemd/sd-daemon.h> 32 33 #include "console-server.h" 34 35 #define SOCKET_HANDLER_PKT_SIZE 512 36 /* Set poll() timeout to 4000 uS, or 4 mS */ 37 #define SOCKET_HANDLER_PKT_US_TIMEOUT 4000 38 39 struct client { 40 struct socket_handler *sh; 41 struct poller *poller; 42 struct ringbuffer_consumer *rbc; 43 int fd; 44 bool blocked; 45 }; 46 47 struct socket_handler { 48 struct handler handler; 49 struct console *console; 50 struct poller *poller; 51 int sd; 52 53 struct client **clients; 54 int n_clients; 55 }; 56 57 static struct timeval const socket_handler_timeout = { 58 .tv_sec = 0, 59 .tv_usec = SOCKET_HANDLER_PKT_US_TIMEOUT 60 }; 61 62 static struct socket_handler *to_socket_handler(struct handler *handler) 63 { 64 return container_of(handler, struct socket_handler, handler); 65 } 66 67 static void client_close(struct client *client) 68 { 69 struct socket_handler *sh = client->sh; 70 int idx; 71 72 close(client->fd); 73 if (client->poller) { 74 console_poller_unregister(sh->console, client->poller); 75 } 76 77 if (client->rbc) { 78 ringbuffer_consumer_unregister(client->rbc); 79 } 80 81 for (idx = 0; idx < sh->n_clients; idx++) { 82 if (sh->clients[idx] == client) { 83 break; 84 } 85 } 86 87 assert(idx < sh->n_clients); 88 89 free(client); 90 client = NULL; 91 92 sh->n_clients--; 93 /* 94 * We're managing an array of pointers to aggregates, so don't warn about sizeof() on a 95 * pointer type. 96 */ 97 /* NOLINTBEGIN(bugprone-sizeof-expression) */ 98 memmove(&sh->clients[idx], &sh->clients[idx + 1], 99 sizeof(*sh->clients) * (sh->n_clients - idx)); 100 sh->clients = 101 reallocarray(sh->clients, sh->n_clients, sizeof(*sh->clients)); 102 /* NOLINTEND(bugprone-sizeof-expression) */ 103 } 104 105 static void client_set_blocked(struct client *client, bool blocked) 106 { 107 int events; 108 109 if (client->blocked == blocked) { 110 return; 111 } 112 113 client->blocked = blocked; 114 115 events = POLLIN; 116 if (client->blocked) { 117 events |= POLLOUT; 118 } 119 120 console_poller_set_events(client->sh->console, client->poller, events); 121 } 122 123 static ssize_t send_all(struct client *client, void *buf, size_t len, 124 bool block) 125 { 126 int fd, flags; 127 ssize_t rc; 128 size_t pos; 129 130 if (len > SSIZE_MAX) { 131 return -EINVAL; 132 } 133 134 fd = client->fd; 135 136 flags = MSG_NOSIGNAL; 137 if (!block) { 138 flags |= MSG_DONTWAIT; 139 } 140 141 for (pos = 0; pos < len; pos += rc) { 142 rc = send(fd, (char *)buf + pos, len - pos, flags); 143 if (rc < 0) { 144 if (!block && 145 (errno == EAGAIN || errno == EWOULDBLOCK)) { 146 client_set_blocked(client, true); 147 break; 148 } 149 150 if (errno == EINTR) { 151 continue; 152 } 153 154 return -1; 155 } 156 if (rc == 0) { 157 return -1; 158 } 159 } 160 161 return (ssize_t)pos; 162 } 163 164 /* Drain the queue to the socket and update the queue buffer. If force_len is 165 * set, send at least that many bytes from the queue, possibly while blocking 166 */ 167 static int client_drain_queue(struct client *client, size_t force_len) 168 { 169 uint8_t *buf; 170 ssize_t wlen; 171 size_t len, total_len; 172 bool block; 173 174 total_len = 0; 175 wlen = 0; 176 block = !!force_len; 177 178 /* if we're already blocked, no need for the write */ 179 if (!block && client->blocked) { 180 return 0; 181 } 182 183 for (;;) { 184 len = ringbuffer_dequeue_peek(client->rbc, total_len, &buf); 185 if (!len) { 186 break; 187 } 188 189 wlen = send_all(client, buf, len, block); 190 if (wlen <= 0) { 191 break; 192 } 193 194 total_len += wlen; 195 196 if (force_len && total_len >= force_len) { 197 break; 198 } 199 } 200 201 if (wlen < 0) { 202 return -1; 203 } 204 205 if (force_len && total_len < force_len) { 206 return -1; 207 } 208 209 ringbuffer_dequeue_commit(client->rbc, total_len); 210 return 0; 211 } 212 213 static enum ringbuffer_poll_ret client_ringbuffer_poll(void *arg, 214 size_t force_len) 215 { 216 struct client *client = arg; 217 size_t len; 218 int rc; 219 220 len = ringbuffer_len(client->rbc); 221 if (!force_len && (len < SOCKET_HANDLER_PKT_SIZE)) { 222 /* Do nothing until many small requests have accumulated, or 223 * the UART is idle for awhile (as determined by the timeout 224 * value supplied to the poll function call in console_server.c. */ 225 console_poller_set_timeout(client->sh->console, client->poller, 226 &socket_handler_timeout); 227 return RINGBUFFER_POLL_OK; 228 } 229 230 rc = client_drain_queue(client, force_len); 231 if (rc) { 232 client->rbc = NULL; 233 client_close(client); 234 return RINGBUFFER_POLL_REMOVE; 235 } 236 237 return RINGBUFFER_POLL_OK; 238 } 239 240 static enum poller_ret 241 client_timeout(struct handler *handler __attribute__((unused)), void *data) 242 { 243 struct client *client = data; 244 int rc = 0; 245 246 if (client->blocked) { 247 /* nothing to do here, we'll call client_drain_queue when 248 * we become unblocked */ 249 return POLLER_OK; 250 } 251 252 rc = client_drain_queue(client, 0); 253 if (rc) { 254 client_close(client); 255 return POLLER_REMOVE; 256 } 257 258 return POLLER_OK; 259 } 260 261 static enum poller_ret client_poll(struct handler *handler, int events, 262 void *data) 263 { 264 struct socket_handler *sh = to_socket_handler(handler); 265 struct client *client = data; 266 uint8_t buf[4096]; 267 ssize_t rc; 268 269 if (events & POLLIN) { 270 rc = recv(client->fd, buf, sizeof(buf), MSG_DONTWAIT); 271 if (rc < 0) { 272 if (errno == EAGAIN || errno == EWOULDBLOCK) { 273 return POLLER_OK; 274 } else { 275 goto err_close; 276 } 277 } 278 if (rc == 0) { 279 goto err_close; 280 } 281 282 console_data_out(sh->console, buf, rc); 283 } 284 285 if (events & POLLOUT) { 286 client_set_blocked(client, false); 287 rc = client_drain_queue(client, 0); 288 if (rc) { 289 goto err_close; 290 } 291 } 292 293 return POLLER_OK; 294 295 err_close: 296 client->poller = NULL; 297 client_close(client); 298 return POLLER_REMOVE; 299 } 300 301 static enum poller_ret socket_poll(struct handler *handler, int events, 302 void __attribute__((unused)) * data) 303 { 304 struct socket_handler *sh = to_socket_handler(handler); 305 struct client *client; 306 int fd, n; 307 308 if (!(events & POLLIN)) { 309 return POLLER_OK; 310 } 311 312 fd = accept(sh->sd, NULL, NULL); 313 if (fd < 0) { 314 return POLLER_OK; 315 } 316 317 client = malloc(sizeof(*client)); 318 memset(client, 0, sizeof(*client)); 319 320 client->sh = sh; 321 client->fd = fd; 322 client->poller = console_poller_register(sh->console, handler, 323 client_poll, client_timeout, 324 client->fd, POLLIN, client); 325 client->rbc = console_ringbuffer_consumer_register( 326 sh->console, client_ringbuffer_poll, client); 327 328 n = sh->n_clients++; 329 /* 330 * We're managing an array of pointers to aggregates, so don't warn about sizeof() on a 331 * pointer type. 332 */ 333 /* NOLINTBEGIN(bugprone-sizeof-expression) */ 334 sh->clients = 335 reallocarray(sh->clients, sh->n_clients, sizeof(*sh->clients)); 336 /* NOLINTEND(bugprone-sizeof-expression) */ 337 sh->clients[n] = client; 338 339 return POLLER_OK; 340 } 341 342 static int socket_init(struct handler *handler, struct console *console, 343 struct config *config) 344 { 345 struct socket_handler *sh = to_socket_handler(handler); 346 struct sockaddr_un addr; 347 size_t addrlen; 348 ssize_t len; 349 int rc; 350 351 sh->console = console; 352 sh->clients = NULL; 353 sh->n_clients = 0; 354 355 memset(&addr, 0, sizeof(addr)); 356 addr.sun_family = AF_UNIX; 357 len = console_socket_path(&addr, config_get_value(config, "socket-id")); 358 if (len < 0) { 359 if (errno) { 360 warn("Failed to configure socket: %s", strerror(errno)); 361 } else { 362 warn("Socket name length exceeds buffer limits"); 363 } 364 return -1; 365 } 366 367 /* Try to take a socket from systemd first */ 368 if (sd_listen_fds(0) == 1 && 369 sd_is_socket_unix(SD_LISTEN_FDS_START, SOCK_STREAM, 1, 370 addr.sun_path, len) > 0) { 371 sh->sd = SD_LISTEN_FDS_START; 372 } else { 373 sh->sd = socket(AF_UNIX, SOCK_STREAM, 0); 374 if (sh->sd < 0) { 375 warn("Can't create socket"); 376 return -1; 377 } 378 379 addrlen = sizeof(addr) - sizeof(addr.sun_path) + len; 380 381 rc = bind(sh->sd, (struct sockaddr *)&addr, addrlen); 382 if (rc) { 383 socket_path_t name; 384 console_socket_path_readable(&addr, addrlen, name); 385 warn("Can't bind to socket path %s (terminated at first null)", 386 name); 387 goto cleanup; 388 } 389 390 rc = listen(sh->sd, 1); 391 if (rc) { 392 warn("Can't listen for incoming connections"); 393 goto cleanup; 394 } 395 } 396 397 sh->poller = console_poller_register(console, handler, socket_poll, 398 NULL, sh->sd, POLLIN, NULL); 399 400 return 0; 401 cleanup: 402 close(sh->sd); 403 return -1; 404 } 405 406 static void socket_fini(struct handler *handler) 407 { 408 struct socket_handler *sh = to_socket_handler(handler); 409 410 while (sh->n_clients) { 411 client_close(sh->clients[0]); 412 } 413 414 if (sh->poller) { 415 console_poller_unregister(sh->console, sh->poller); 416 } 417 418 close(sh->sd); 419 } 420 421 static struct socket_handler socket_handler = { 422 .handler = { 423 .name = "socket", 424 .init = socket_init, 425 .fini = socket_fini, 426 }, 427 }; 428 429 console_handler_register(&socket_handler.handler); 430