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-mux.h" 34 #include "console-server.h" 35 36 #define SOCKET_HANDLER_PKT_SIZE 512 37 /* Set poll() timeout to 4000 uS, or 4 mS */ 38 #define SOCKET_HANDLER_PKT_US_TIMEOUT 4000 39 40 struct client { 41 struct socket_handler *sh; 42 struct poller *poller; 43 struct ringbuffer_consumer *rbc; 44 int fd; 45 bool blocked; 46 }; 47 48 struct socket_handler { 49 struct handler handler; 50 struct console *console; 51 struct poller *poller; 52 int sd; 53 54 struct client **clients; 55 int n_clients; 56 }; 57 58 static struct timeval const socket_handler_timeout = { 59 .tv_sec = 0, 60 .tv_usec = SOCKET_HANDLER_PKT_US_TIMEOUT 61 }; 62 63 static struct socket_handler *to_socket_handler(struct handler *handler) 64 { 65 return container_of(handler, struct socket_handler, handler); 66 } 67 68 static void client_close(struct client *client) 69 { 70 struct socket_handler *sh = client->sh; 71 int idx; 72 73 close(client->fd); 74 if (client->poller) { 75 console_poller_unregister(sh->console, client->poller); 76 } 77 78 if (client->rbc) { 79 ringbuffer_consumer_unregister(client->rbc); 80 } 81 82 for (idx = 0; idx < sh->n_clients; idx++) { 83 if (sh->clients[idx] == client) { 84 break; 85 } 86 } 87 88 assert(idx < sh->n_clients); 89 90 free(client); 91 client = NULL; 92 93 sh->n_clients--; 94 /* 95 * We're managing an array of pointers to aggregates, so don't warn about sizeof() on a 96 * pointer type. 97 */ 98 /* NOLINTBEGIN(bugprone-sizeof-expression) */ 99 memmove(&sh->clients[idx], &sh->clients[idx + 1], 100 sizeof(*sh->clients) * (sh->n_clients - idx)); 101 if (sh->n_clients == 0) { 102 free(sh->clients); 103 sh->clients = NULL; 104 } else { 105 sh->clients = reallocarray(sh->clients, sh->n_clients, 106 sizeof(*sh->clients)); 107 } 108 /* NOLINTEND(bugprone-sizeof-expression) */ 109 } 110 111 static void client_set_blocked(struct client *client, bool blocked) 112 { 113 int events; 114 115 if (client->blocked == blocked) { 116 return; 117 } 118 119 client->blocked = blocked; 120 121 events = POLLIN; 122 if (client->blocked) { 123 events |= POLLOUT; 124 } 125 126 console_poller_set_events(client->sh->console, client->poller, events); 127 } 128 129 static ssize_t send_all(struct client *client, void *buf, size_t len, 130 bool block) 131 { 132 int fd; 133 int flags; 134 ssize_t rc; 135 size_t pos; 136 137 if (len > SSIZE_MAX) { 138 return -EINVAL; 139 } 140 141 fd = client->fd; 142 143 flags = MSG_NOSIGNAL; 144 if (!block) { 145 flags |= MSG_DONTWAIT; 146 } 147 148 for (pos = 0; pos < len; pos += rc) { 149 rc = send(fd, (char *)buf + pos, len - pos, flags); 150 if (rc < 0) { 151 if (!block && 152 (errno == EAGAIN || errno == EWOULDBLOCK)) { 153 client_set_blocked(client, true); 154 break; 155 } 156 157 if (errno == EINTR) { 158 continue; 159 } 160 161 return -1; 162 } 163 if (rc == 0) { 164 return -1; 165 } 166 } 167 168 return (ssize_t)pos; 169 } 170 171 /* Drain the queue to the socket and update the queue buffer. If force_len is 172 * set, send at least that many bytes from the queue, possibly while blocking 173 */ 174 static int client_drain_queue(struct client *client, size_t force_len) 175 { 176 uint8_t *buf; 177 ssize_t wlen; 178 size_t len; 179 size_t total_len; 180 bool block; 181 182 total_len = 0; 183 wlen = 0; 184 block = !!force_len; 185 186 /* if we're already blocked, no need for the write */ 187 if (!block && client->blocked) { 188 return 0; 189 } 190 191 for (;;) { 192 len = ringbuffer_dequeue_peek(client->rbc, total_len, &buf); 193 if (!len) { 194 break; 195 } 196 197 wlen = send_all(client, buf, len, block); 198 if (wlen <= 0) { 199 break; 200 } 201 202 total_len += wlen; 203 204 if (force_len && total_len >= force_len) { 205 break; 206 } 207 } 208 209 if (wlen < 0) { 210 return -1; 211 } 212 213 if (force_len && total_len < force_len) { 214 return -1; 215 } 216 217 ringbuffer_dequeue_commit(client->rbc, total_len); 218 return 0; 219 } 220 221 static enum ringbuffer_poll_ret client_ringbuffer_poll(void *arg, 222 size_t force_len) 223 { 224 struct client *client = arg; 225 size_t len; 226 int rc; 227 228 len = ringbuffer_len(client->rbc); 229 if (!force_len && (len < SOCKET_HANDLER_PKT_SIZE)) { 230 /* Do nothing until many small requests have accumulated, or 231 * the UART is idle for awhile (as determined by the timeout 232 * value supplied to the poll function call in console_server.c. */ 233 console_poller_set_timeout(client->sh->console, client->poller, 234 &socket_handler_timeout); 235 return RINGBUFFER_POLL_OK; 236 } 237 238 rc = client_drain_queue(client, force_len); 239 if (rc) { 240 client->rbc = NULL; 241 client_close(client); 242 return RINGBUFFER_POLL_REMOVE; 243 } 244 245 return RINGBUFFER_POLL_OK; 246 } 247 248 static enum poller_ret 249 client_timeout(struct handler *handler __attribute__((unused)), void *data) 250 { 251 struct client *client = data; 252 int rc = 0; 253 254 if (client->blocked) { 255 /* nothing to do here, we'll call client_drain_queue when 256 * we become unblocked */ 257 return POLLER_OK; 258 } 259 260 rc = client_drain_queue(client, 0); 261 if (rc) { 262 client_close(client); 263 return POLLER_REMOVE; 264 } 265 266 return POLLER_OK; 267 } 268 269 static enum poller_ret client_poll(struct handler *handler, int events, 270 void *data) 271 { 272 struct socket_handler *sh = to_socket_handler(handler); 273 struct client *client = data; 274 uint8_t buf[4096]; 275 ssize_t rc; 276 277 if (events & POLLIN) { 278 rc = recv(client->fd, buf, sizeof(buf), MSG_DONTWAIT); 279 if (rc < 0) { 280 if (errno == EAGAIN || errno == EWOULDBLOCK) { 281 return POLLER_OK; 282 } 283 goto err_close; 284 } 285 if (rc == 0) { 286 goto err_close; 287 } 288 289 console_data_out(sh->console, buf, rc); 290 } 291 292 if (events & POLLOUT) { 293 client_set_blocked(client, false); 294 rc = client_drain_queue(client, 0); 295 if (rc) { 296 goto err_close; 297 } 298 } 299 300 return POLLER_OK; 301 302 err_close: 303 client->poller = NULL; 304 client_close(client); 305 return POLLER_REMOVE; 306 } 307 308 static enum poller_ret socket_poll(struct handler *handler, int events, 309 void __attribute__((unused)) * data) 310 { 311 struct socket_handler *sh = to_socket_handler(handler); 312 struct client *client; 313 int fd; 314 int n; 315 316 if (!(events & POLLIN)) { 317 return POLLER_OK; 318 } 319 320 fd = accept(sh->sd, NULL, NULL); 321 if (fd < 0) { 322 return POLLER_OK; 323 } 324 325 console_mux_activate(sh->console); 326 327 client = malloc(sizeof(*client)); 328 memset(client, 0, sizeof(*client)); 329 330 client->sh = sh; 331 client->fd = fd; 332 client->poller = console_poller_register(sh->console, handler, 333 client_poll, client_timeout, 334 client->fd, POLLIN, client); 335 client->rbc = console_ringbuffer_consumer_register( 336 sh->console, client_ringbuffer_poll, client); 337 338 n = sh->n_clients++; 339 /* 340 * We're managing an array of pointers to aggregates, so don't warn about sizeof() on a 341 * pointer type. 342 */ 343 /* NOLINTBEGIN(bugprone-sizeof-expression) */ 344 sh->clients = 345 reallocarray(sh->clients, sh->n_clients, sizeof(*sh->clients)); 346 /* NOLINTEND(bugprone-sizeof-expression) */ 347 sh->clients[n] = client; 348 349 return POLLER_OK; 350 } 351 352 /* Create socket pair and register one end as poller/consumer and return 353 * the other end to the caller. 354 * Return file descriptor on success and negative value on error. 355 */ 356 int dbus_create_socket_consumer(struct console *console) 357 { 358 struct socket_handler *sh = NULL; 359 struct client *client; 360 int fds[2]; 361 int i; 362 int rc = -1; 363 int n; 364 365 for (i = 0; i < console->n_handlers; i++) { 366 if (strcmp(console->handlers[i]->type->name, "socket") == 0) { 367 sh = to_socket_handler(console->handlers[i]); 368 break; 369 } 370 } 371 372 if (!sh) { 373 return -ENOSYS; 374 } 375 376 /* Create a socketpair */ 377 rc = socketpair(AF_UNIX, SOCK_STREAM, 0, fds); 378 if (rc < 0) { 379 warn("Failed to create socket pair"); 380 return -errno; 381 } 382 383 client = malloc(sizeof(*client)); 384 if (client == NULL) { 385 warnx("Failed to allocate client structure."); 386 rc = -ENOMEM; 387 goto close_fds; 388 } 389 memset(client, 0, sizeof(*client)); 390 391 client->sh = sh; 392 client->fd = fds[0]; 393 client->poller = console_poller_register(sh->console, &sh->handler, 394 client_poll, client_timeout, 395 client->fd, POLLIN, client); 396 client->rbc = console_ringbuffer_consumer_register( 397 sh->console, client_ringbuffer_poll, client); 398 if (client->rbc == NULL) { 399 warnx("Failed to register a consumer.\n"); 400 rc = -ENOMEM; 401 goto free_client; 402 } 403 404 n = sh->n_clients++; 405 406 /* 407 * We're managing an array of pointers to aggregates, so don't warn about 408 * sizeof() on a pointer type. 409 */ 410 /* NOLINTBEGIN(bugprone-sizeof-expression) */ 411 sh->clients = 412 reallocarray(sh->clients, sh->n_clients, sizeof(*sh->clients)); 413 /* NOLINTEND(bugprone-sizeof-expression) */ 414 sh->clients[n] = client; 415 416 /* Return the second FD to caller. */ 417 return fds[1]; 418 419 free_client: 420 free(client); 421 close_fds: 422 close(fds[0]); 423 close(fds[1]); 424 return rc; 425 } 426 427 static struct handler *socket_init(const struct handler_type *type 428 __attribute__((unused)), 429 struct console *console, 430 struct config *config 431 __attribute__((unused))) 432 { 433 struct socket_handler *sh; 434 struct sockaddr_un addr; 435 size_t addrlen; 436 ssize_t len; 437 int rc; 438 439 sh = malloc(sizeof(*sh)); 440 if (!sh) { 441 return NULL; 442 } 443 444 sh->console = console; 445 sh->clients = NULL; 446 sh->n_clients = 0; 447 448 memset(&addr, 0, sizeof(addr)); 449 addr.sun_family = AF_UNIX; 450 len = console_socket_path(addr.sun_path, console->console_id); 451 if (len < 0) { 452 if (errno) { 453 warn("Failed to configure socket: %s", strerror(errno)); 454 } else { 455 warn("Socket name length exceeds buffer limits"); 456 } 457 goto err_free; 458 } 459 460 /* Try to take a socket from systemd first */ 461 if (sd_listen_fds(0) == 1 && 462 sd_is_socket_unix(SD_LISTEN_FDS_START, SOCK_STREAM, 1, 463 addr.sun_path, len) > 0) { 464 sh->sd = SD_LISTEN_FDS_START; 465 } else { 466 sh->sd = socket(AF_UNIX, SOCK_STREAM, 0); 467 if (sh->sd < 0) { 468 warn("Can't create socket"); 469 goto err_free; 470 } 471 472 addrlen = sizeof(addr) - sizeof(addr.sun_path) + len; 473 474 rc = bind(sh->sd, (struct sockaddr *)&addr, addrlen); 475 if (rc) { 476 socket_path_t name; 477 console_socket_path_readable(&addr, addrlen, name); 478 warn("Can't bind to socket path %s (terminated at first null)", 479 name); 480 goto err_close; 481 } 482 483 rc = listen(sh->sd, 1); 484 if (rc) { 485 warn("Can't listen for incoming connections"); 486 goto err_close; 487 } 488 } 489 490 sh->poller = console_poller_register(console, &sh->handler, socket_poll, 491 NULL, sh->sd, POLLIN, NULL); 492 493 return &sh->handler; 494 495 err_close: 496 close(sh->sd); 497 err_free: 498 free(sh); 499 return NULL; 500 } 501 502 static void socket_deselect(struct handler *handler) 503 { 504 struct socket_handler *sh = to_socket_handler(handler); 505 506 while (sh->n_clients) { 507 struct client *c = sh->clients[0]; 508 client_drain_queue(c, 0); 509 client_close(c); 510 } 511 } 512 513 static void socket_fini(struct handler *handler) 514 { 515 struct socket_handler *sh = to_socket_handler(handler); 516 517 while (sh->n_clients) { 518 client_close(sh->clients[0]); 519 } 520 521 if (sh->poller) { 522 console_poller_unregister(sh->console, sh->poller); 523 } 524 525 close(sh->sd); 526 free(sh); 527 } 528 529 static const struct handler_type socket_handler = { 530 .name = "socket", 531 .init = socket_init, 532 .deselect = socket_deselect, 533 .fini = socket_fini, 534 }; 535 536 console_handler_register(&socket_handler); 537