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
to_socket_handler(struct handler * handler)63 static struct socket_handler *to_socket_handler(struct handler *handler)
64 {
65 return container_of(handler, struct socket_handler, handler);
66 }
67
client_close(struct client * client)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
client_set_blocked(struct client * client,bool blocked)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
send_all(struct client * client,void * buf,size_t len,bool block)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 */
client_drain_queue(struct client * client,size_t force_len)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
client_ringbuffer_poll(void * arg,size_t force_len)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
client_timeout(struct handler * handler,void * data)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
client_poll(struct handler * handler,int events,void * data)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
socket_poll(struct handler * handler,int events,void * data)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 */
dbus_create_socket_consumer(struct console * console)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
socket_init(const struct handler_type * type,struct console * console,struct config * config)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
socket_deselect(struct handler * handler)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
socket_fini(struct handler * handler)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