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 if (client->rbc) 77 ringbuffer_consumer_unregister(client->rbc); 78 79 for (idx = 0; idx < sh->n_clients; idx++) 80 if (sh->clients[idx] == client) 81 break; 82 83 assert(idx < sh->n_clients); 84 85 free(client); 86 client = NULL; 87 88 sh->n_clients--; 89 /* 90 * We're managing an array of pointers to aggregates, so don't warn about sizeof() on a 91 * pointer type. 92 */ 93 /* NOLINTBEGIN(bugprone-sizeof-expression) */ 94 memmove(&sh->clients[idx], &sh->clients[idx + 1], 95 sizeof(*sh->clients) * (sh->n_clients - idx)); 96 sh->clients = 97 reallocarray(sh->clients, sh->n_clients, sizeof(*sh->clients)); 98 /* NOLINTEND(bugprone-sizeof-expression) */ 99 } 100 101 static void client_set_blocked(struct client *client, bool blocked) 102 { 103 int events; 104 105 if (client->blocked == blocked) 106 return; 107 108 client->blocked = blocked; 109 110 events = POLLIN; 111 if (client->blocked) 112 events |= POLLOUT; 113 114 console_poller_set_events(client->sh->console, client->poller, events); 115 } 116 117 static ssize_t send_all(struct client *client, void *buf, size_t len, 118 bool block) 119 { 120 int fd, flags; 121 ssize_t rc; 122 size_t pos; 123 124 if (len > SSIZE_MAX) 125 return -EINVAL; 126 127 fd = client->fd; 128 129 flags = MSG_NOSIGNAL; 130 if (!block) 131 flags |= MSG_DONTWAIT; 132 133 for (pos = 0; pos < len; pos += rc) { 134 rc = send(fd, (char *)buf + pos, len - pos, flags); 135 if (rc < 0) { 136 if (!block && 137 (errno == EAGAIN || errno == EWOULDBLOCK)) { 138 client_set_blocked(client, true); 139 break; 140 } 141 142 if (errno == EINTR) 143 continue; 144 145 return -1; 146 } 147 if (rc == 0) 148 return -1; 149 } 150 151 return (ssize_t)pos; 152 } 153 154 /* Drain the queue to the socket and update the queue buffer. If force_len is 155 * set, send at least that many bytes from the queue, possibly while blocking 156 */ 157 static int client_drain_queue(struct client *client, size_t force_len) 158 { 159 uint8_t *buf; 160 ssize_t wlen; 161 size_t len, total_len; 162 bool block; 163 164 total_len = 0; 165 wlen = 0; 166 block = !!force_len; 167 168 /* if we're already blocked, no need for the write */ 169 if (!block && client->blocked) 170 return 0; 171 172 for (;;) { 173 len = ringbuffer_dequeue_peek(client->rbc, total_len, &buf); 174 if (!len) 175 break; 176 177 wlen = send_all(client, buf, len, block); 178 if (wlen <= 0) 179 break; 180 181 total_len += wlen; 182 183 if (force_len && total_len >= force_len) 184 break; 185 } 186 187 if (wlen < 0) 188 return -1; 189 190 if (force_len && total_len < force_len) 191 return -1; 192 193 ringbuffer_dequeue_commit(client->rbc, total_len); 194 return 0; 195 } 196 197 static enum ringbuffer_poll_ret client_ringbuffer_poll(void *arg, 198 size_t force_len) 199 { 200 struct client *client = arg; 201 size_t len; 202 int rc; 203 204 len = ringbuffer_len(client->rbc); 205 if (!force_len && (len < SOCKET_HANDLER_PKT_SIZE)) { 206 /* Do nothing until many small requests have accumulated, or 207 * the UART is idle for awhile (as determined by the timeout 208 * value supplied to the poll function call in console_server.c. */ 209 console_poller_set_timeout(client->sh->console, client->poller, 210 &socket_handler_timeout); 211 return RINGBUFFER_POLL_OK; 212 } 213 214 rc = client_drain_queue(client, force_len); 215 if (rc) { 216 client->rbc = NULL; 217 client_close(client); 218 return RINGBUFFER_POLL_REMOVE; 219 } 220 221 return RINGBUFFER_POLL_OK; 222 } 223 224 static enum poller_ret 225 client_timeout(struct handler *handler __attribute__((unused)), void *data) 226 { 227 struct client *client = data; 228 int rc = 0; 229 230 if (client->blocked) { 231 /* nothing to do here, we'll call client_drain_queue when 232 * we become unblocked */ 233 return POLLER_OK; 234 } 235 236 rc = client_drain_queue(client, 0); 237 if (rc) { 238 client_close(client); 239 return POLLER_REMOVE; 240 } 241 242 return POLLER_OK; 243 } 244 245 static enum poller_ret client_poll(struct handler *handler, int events, 246 void *data) 247 { 248 struct socket_handler *sh = to_socket_handler(handler); 249 struct client *client = data; 250 uint8_t buf[4096]; 251 ssize_t rc; 252 253 if (events & POLLIN) { 254 rc = recv(client->fd, buf, sizeof(buf), MSG_DONTWAIT); 255 if (rc < 0) { 256 if (errno == EAGAIN || errno == EWOULDBLOCK) 257 return POLLER_OK; 258 else 259 goto err_close; 260 } 261 if (rc == 0) 262 goto err_close; 263 264 console_data_out(sh->console, buf, rc); 265 } 266 267 if (events & POLLOUT) { 268 client_set_blocked(client, false); 269 rc = client_drain_queue(client, 0); 270 if (rc) 271 goto err_close; 272 } 273 274 return POLLER_OK; 275 276 err_close: 277 client->poller = NULL; 278 client_close(client); 279 return POLLER_REMOVE; 280 } 281 282 static enum poller_ret socket_poll(struct handler *handler, int events, 283 void __attribute__((unused)) * data) 284 { 285 struct socket_handler *sh = to_socket_handler(handler); 286 struct client *client; 287 int fd, n; 288 289 if (!(events & POLLIN)) 290 return POLLER_OK; 291 292 fd = accept(sh->sd, NULL, NULL); 293 if (fd < 0) 294 return POLLER_OK; 295 296 client = malloc(sizeof(*client)); 297 memset(client, 0, sizeof(*client)); 298 299 client->sh = sh; 300 client->fd = fd; 301 client->poller = console_poller_register(sh->console, handler, 302 client_poll, client_timeout, 303 client->fd, POLLIN, client); 304 client->rbc = console_ringbuffer_consumer_register( 305 sh->console, client_ringbuffer_poll, client); 306 307 n = sh->n_clients++; 308 /* 309 * We're managing an array of pointers to aggregates, so don't warn about sizeof() on a 310 * pointer type. 311 */ 312 /* NOLINTBEGIN(bugprone-sizeof-expression) */ 313 sh->clients = 314 reallocarray(sh->clients, sh->n_clients, sizeof(*sh->clients)); 315 /* NOLINTEND(bugprone-sizeof-expression) */ 316 sh->clients[n] = client; 317 318 return POLLER_OK; 319 } 320 321 static int socket_init(struct handler *handler, struct console *console, 322 struct config *config) 323 { 324 struct socket_handler *sh = to_socket_handler(handler); 325 struct sockaddr_un addr; 326 size_t addrlen; 327 ssize_t len; 328 int rc; 329 330 sh->console = console; 331 sh->clients = NULL; 332 sh->n_clients = 0; 333 334 memset(&addr, 0, sizeof(addr)); 335 addr.sun_family = AF_UNIX; 336 len = console_socket_path(&addr, config_get_value(config, "socket-id")); 337 if (len < 0) { 338 if (errno) 339 warn("Failed to configure socket: %s", strerror(errno)); 340 else 341 warn("Socket name length exceeds buffer limits"); 342 return -1; 343 } 344 345 /* Try to take a socket from systemd first */ 346 if (sd_listen_fds(0) == 1 && 347 sd_is_socket_unix(SD_LISTEN_FDS_START, SOCK_STREAM, 1, 348 addr.sun_path, len) > 0) { 349 sh->sd = SD_LISTEN_FDS_START; 350 } else { 351 sh->sd = socket(AF_UNIX, SOCK_STREAM, 0); 352 if (sh->sd < 0) { 353 warn("Can't create socket"); 354 return -1; 355 } 356 357 addrlen = sizeof(addr) - sizeof(addr.sun_path) + len; 358 359 rc = bind(sh->sd, (struct sockaddr *)&addr, addrlen); 360 if (rc) { 361 socket_path_t name; 362 console_socket_path_readable(&addr, addrlen, name); 363 warn("Can't bind to socket path %s (terminated at first null)", 364 name); 365 goto cleanup; 366 } 367 368 rc = listen(sh->sd, 1); 369 if (rc) { 370 warn("Can't listen for incoming connections"); 371 goto cleanup; 372 } 373 } 374 375 sh->poller = console_poller_register(console, handler, socket_poll, 376 NULL, sh->sd, POLLIN, NULL); 377 378 return 0; 379 cleanup: 380 close(sh->sd); 381 return -1; 382 } 383 384 static void socket_fini(struct handler *handler) 385 { 386 struct socket_handler *sh = to_socket_handler(handler); 387 388 while (sh->n_clients) 389 client_close(sh->clients[0]); 390 391 if (sh->poller) 392 console_poller_unregister(sh->console, sh->poller); 393 394 close(sh->sd); 395 } 396 397 static struct socket_handler socket_handler = { 398 .handler = { 399 .name = "socket", 400 .init = socket_init, 401 .fini = socket_fini, 402 }, 403 }; 404 405 console_handler_register(&socket_handler.handler); 406