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