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 #define _GNU_SOURCE 18 19 #include <assert.h> 20 #include <err.h> 21 #include <errno.h> 22 #include <stdbool.h> 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <string.h> 26 #include <termios.h> 27 #include <unistd.h> 28 #include <endian.h> 29 30 #include <sys/socket.h> 31 #include <sys/un.h> 32 33 #include "console-server.h" 34 35 const size_t buffer_size = 128 * 1024; 36 37 struct client { 38 struct socket_handler *sh; 39 struct poller *poller; 40 struct ringbuffer_consumer *rbc; 41 int fd; 42 }; 43 44 struct socket_handler { 45 struct handler handler; 46 struct console *console; 47 struct poller *poller; 48 struct ringbuffer *ringbuffer; 49 int sd; 50 51 struct client **clients; 52 int n_clients; 53 }; 54 55 static struct socket_handler *to_socket_handler(struct handler *handler) 56 { 57 return container_of(handler, struct socket_handler, handler); 58 } 59 60 static void client_close(struct client *client) 61 { 62 struct socket_handler *sh = client->sh; 63 int idx; 64 65 close(client->fd); 66 if (client->poller) 67 console_poller_unregister(sh->console, client->poller); 68 69 if (client->rbc) 70 ringbuffer_consumer_unregister(client->rbc); 71 72 for (idx = 0; idx < sh->n_clients; idx++) 73 if (sh->clients[idx] == client) 74 break; 75 76 assert(idx < sh->n_clients); 77 78 free(client); 79 client = NULL; 80 81 sh->n_clients--; 82 memmove(&sh->clients[idx], &sh->clients[idx+1], 83 sizeof(*sh->clients) * (sh->n_clients - idx)); 84 sh->clients = realloc(sh->clients, 85 sizeof(*sh->clients) * sh->n_clients); 86 } 87 88 static ssize_t send_all(int fd, void *buf, size_t len, bool block) 89 { 90 int rc, flags; 91 size_t pos; 92 93 flags = MSG_NOSIGNAL; 94 if (!block) 95 flags |= MSG_DONTWAIT; 96 97 for (pos = 0; pos < len; pos += rc) { 98 rc = send(fd, buf + pos, len - pos, flags); 99 if (rc < 0) { 100 if (!block && (errno == EAGAIN || errno == EWOULDBLOCK)) 101 break; 102 103 if (errno == EINTR) 104 continue; 105 106 return -1; 107 } 108 if (rc == 0) 109 return -1; 110 } 111 112 return pos; 113 } 114 115 /* Drain the queue to the socket and update the queue buffer. If force_len is 116 * set, send at least that many bytes from the queue, possibly while blocking 117 */ 118 static int client_drain_queue(struct client *client, size_t force_len) 119 { 120 uint8_t *buf; 121 ssize_t wlen; 122 size_t len, total_len; 123 bool block; 124 125 total_len = 0; 126 wlen = 0; 127 block = !!force_len; 128 129 for (;;) { 130 len = ringbuffer_dequeue_peek(client->rbc, total_len, &buf); 131 if (!len) 132 break; 133 134 wlen = send_all(client->fd, buf, len, block); 135 if (wlen <= 0) 136 break; 137 138 total_len += wlen; 139 140 if (force_len && total_len >= force_len) 141 break; 142 } 143 144 if (wlen < 0) 145 return -1; 146 147 if (force_len && total_len < force_len) 148 return -1; 149 150 ringbuffer_dequeue_commit(client->rbc, total_len); 151 return 0; 152 } 153 154 static enum ringbuffer_poll_ret client_ringbuffer_poll(void *arg, 155 size_t force_len) 156 { 157 struct client *client = arg; 158 int rc; 159 160 rc = client_drain_queue(client, force_len); 161 if (rc) { 162 client->rbc = NULL; 163 client_close(client); 164 return RINGBUFFER_POLL_REMOVE; 165 } 166 167 return RINGBUFFER_POLL_OK; 168 } 169 170 static enum poller_ret client_poll(struct handler *handler, 171 int events, void *data) 172 { 173 struct socket_handler *sh = to_socket_handler(handler); 174 struct client *client = data; 175 uint8_t buf[4096]; 176 int rc; 177 178 if (events & POLLIN) { 179 rc = recv(client->fd, buf, sizeof(buf), MSG_DONTWAIT); 180 if (rc < 0) { 181 if (errno == EAGAIN || errno == EWOULDBLOCK) 182 return POLLER_OK; 183 else 184 goto err_close; 185 } 186 if (rc == 0) 187 goto err_close; 188 189 console_data_out(sh->console, buf, rc); 190 } 191 192 if (events & POLLOUT) { 193 rc = client_drain_queue(client, 0); 194 if (rc) 195 goto err_close; 196 } 197 198 return POLLER_OK; 199 200 err_close: 201 client->poller = NULL; 202 client_close(client); 203 return POLLER_REMOVE; 204 } 205 206 static enum poller_ret socket_poll(struct handler *handler, 207 int events, void __attribute__((unused)) *data) 208 { 209 struct socket_handler *sh = to_socket_handler(handler); 210 struct client *client; 211 int fd, n; 212 213 if (!(events & POLLIN)) 214 return POLLER_OK; 215 216 fd = accept(sh->sd, NULL, NULL); 217 if (fd < 0) 218 return POLLER_OK; 219 220 client = malloc(sizeof(*client)); 221 memset(client, 0, sizeof(*client)); 222 223 client->sh = sh; 224 client->fd = fd; 225 client->poller = console_poller_register(sh->console, handler, 226 client_poll, client->fd, POLLIN, client); 227 client->rbc = ringbuffer_consumer_register(sh->ringbuffer, 228 client_ringbuffer_poll, client); 229 230 n = sh->n_clients++; 231 sh->clients = realloc(sh->clients, 232 sizeof(*sh->clients) * sh->n_clients); 233 sh->clients[n] = client; 234 235 return POLLER_OK; 236 237 } 238 239 static int socket_init(struct handler *handler, struct console *console, 240 struct config *config __attribute__((unused))) 241 { 242 struct socket_handler *sh = to_socket_handler(handler); 243 struct sockaddr_un addr; 244 int rc; 245 246 sh->console = console; 247 sh->clients = NULL; 248 sh->n_clients = 0; 249 250 sh->ringbuffer = ringbuffer_init(buffer_size); 251 if (!sh->ringbuffer) { 252 warn("Can't allocate backlog ring buffer"); 253 return -1; 254 } 255 256 sh->sd = socket(AF_UNIX, SOCK_STREAM, 0); 257 if(sh->sd < 0) { 258 warn("Can't create socket"); 259 return -1; 260 } 261 262 memset(&addr, 0, sizeof(addr)); 263 addr.sun_family = AF_UNIX; 264 memcpy(&addr.sun_path, &console_socket_path, console_socket_path_len); 265 266 rc = bind(sh->sd, (struct sockaddr *)&addr, sizeof(addr)); 267 if (rc) { 268 warn("Can't bind to socket path %s", 269 console_socket_path_readable); 270 return -1; 271 } 272 273 rc = listen(sh->sd, 1); 274 if (rc) { 275 warn("Can't listen for incoming connections"); 276 return -1; 277 } 278 279 sh->poller = console_poller_register(console, handler, socket_poll, 280 sh->sd, POLLIN, NULL); 281 282 return 0; 283 } 284 285 static int socket_data(struct handler *handler, uint8_t *buf, size_t len) 286 { 287 struct socket_handler *sh = to_socket_handler(handler); 288 ringbuffer_queue(sh->ringbuffer, buf, len); 289 return 0; 290 } 291 292 static void socket_fini(struct handler *handler) 293 { 294 struct socket_handler *sh = to_socket_handler(handler); 295 296 while (sh->n_clients) 297 client_close(sh->clients[0]); 298 299 if (sh->poller) 300 console_poller_unregister(sh->console, sh->poller); 301 302 if (sh->ringbuffer) 303 ringbuffer_fini(sh->ringbuffer); 304 305 close(sh->sd); 306 } 307 308 static struct socket_handler socket_handler = { 309 .handler = { 310 .name = "socket", 311 .init = socket_init, 312 .data_in = socket_data, 313 .fini = socket_fini, 314 }, 315 }; 316 317 console_handler_register(&socket_handler.handler); 318 319