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