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