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