1 /* 2 * QEMU I/O channels driver websockets 3 * 4 * Copyright (c) 2015 Red Hat, Inc. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 * 19 */ 20 21 #include "qemu/osdep.h" 22 #include "qapi/error.h" 23 #include "qemu/bswap.h" 24 #include "io/channel-websock.h" 25 #include "crypto/hash.h" 26 #include "trace.h" 27 28 29 /* Max amount to allow in rawinput/rawoutput buffers */ 30 #define QIO_CHANNEL_WEBSOCK_MAX_BUFFER 8192 31 32 #define QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN 24 33 #define QIO_CHANNEL_WEBSOCK_GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" 34 #define QIO_CHANNEL_WEBSOCK_GUID_LEN strlen(QIO_CHANNEL_WEBSOCK_GUID) 35 36 #define QIO_CHANNEL_WEBSOCK_HEADER_PROTOCOL "sec-websocket-protocol" 37 #define QIO_CHANNEL_WEBSOCK_HEADER_VERSION "sec-websocket-version" 38 #define QIO_CHANNEL_WEBSOCK_HEADER_KEY "sec-websocket-key" 39 #define QIO_CHANNEL_WEBSOCK_HEADER_UPGRADE "upgrade" 40 #define QIO_CHANNEL_WEBSOCK_HEADER_HOST "host" 41 #define QIO_CHANNEL_WEBSOCK_HEADER_CONNECTION "connection" 42 43 #define QIO_CHANNEL_WEBSOCK_PROTOCOL_BINARY "binary" 44 #define QIO_CHANNEL_WEBSOCK_CONNECTION_UPGRADE "Upgrade" 45 #define QIO_CHANNEL_WEBSOCK_UPGRADE_WEBSOCKET "websocket" 46 47 #define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RESPONSE \ 48 "HTTP/1.1 101 Switching Protocols\r\n" \ 49 "Upgrade: websocket\r\n" \ 50 "Connection: Upgrade\r\n" \ 51 "Sec-WebSocket-Accept: %s\r\n" \ 52 "Sec-WebSocket-Protocol: binary\r\n" \ 53 "\r\n" 54 #define QIO_CHANNEL_WEBSOCK_HANDSHAKE_DELIM "\r\n" 55 #define QIO_CHANNEL_WEBSOCK_HANDSHAKE_END "\r\n\r\n" 56 #define QIO_CHANNEL_WEBSOCK_SUPPORTED_VERSION "13" 57 #define QIO_CHANNEL_WEBSOCK_HTTP_METHOD "GET" 58 #define QIO_CHANNEL_WEBSOCK_HTTP_PATH "/" 59 #define QIO_CHANNEL_WEBSOCK_HTTP_VERSION "HTTP/1.1" 60 61 /* The websockets packet header is variable length 62 * depending on the size of the payload... */ 63 64 /* ...length when using 7-bit payload length */ 65 #define QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT 6 66 /* ...length when using 16-bit payload length */ 67 #define QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT 8 68 /* ...length when using 64-bit payload length */ 69 #define QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT 14 70 71 /* Length of the optional data mask field in header */ 72 #define QIO_CHANNEL_WEBSOCK_HEADER_LEN_MASK 4 73 74 /* Maximum length that can fit in 7-bit payload size */ 75 #define QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_THRESHOLD_7_BIT 126 76 /* Maximum length that can fit in 16-bit payload size */ 77 #define QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_THRESHOLD_16_BIT 65536 78 79 /* Magic 7-bit length to indicate use of 16-bit payload length */ 80 #define QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT 126 81 /* Magic 7-bit length to indicate use of 64-bit payload length */ 82 #define QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_64_BIT 127 83 84 /* Bitmasks & shifts for accessing header fields */ 85 #define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN 0x80 86 #define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE 0x0f 87 #define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK 0x80 88 #define QIO_CHANNEL_WEBSOCK_HEADER_FIELD_PAYLOAD_LEN 0x7f 89 #define QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_FIN 7 90 #define QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_HAS_MASK 7 91 92 typedef struct QIOChannelWebsockHeader QIOChannelWebsockHeader; 93 94 struct QEMU_PACKED QIOChannelWebsockHeader { 95 unsigned char b0; 96 unsigned char b1; 97 union { 98 struct QEMU_PACKED { 99 uint16_t l16; 100 QIOChannelWebsockMask m16; 101 } s16; 102 struct QEMU_PACKED { 103 uint64_t l64; 104 QIOChannelWebsockMask m64; 105 } s64; 106 QIOChannelWebsockMask m; 107 } u; 108 }; 109 110 typedef struct QIOChannelWebsockHTTPHeader QIOChannelWebsockHTTPHeader; 111 112 struct QIOChannelWebsockHTTPHeader { 113 char *name; 114 char *value; 115 }; 116 117 enum { 118 QIO_CHANNEL_WEBSOCK_OPCODE_CONTINUATION = 0x0, 119 QIO_CHANNEL_WEBSOCK_OPCODE_TEXT_FRAME = 0x1, 120 QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME = 0x2, 121 QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE = 0x8, 122 QIO_CHANNEL_WEBSOCK_OPCODE_PING = 0x9, 123 QIO_CHANNEL_WEBSOCK_OPCODE_PONG = 0xA 124 }; 125 126 static size_t 127 qio_channel_websock_extract_headers(char *buffer, 128 QIOChannelWebsockHTTPHeader *hdrs, 129 size_t nhdrsalloc, 130 Error **errp) 131 { 132 char *nl, *sep, *tmp; 133 size_t nhdrs = 0; 134 135 /* 136 * First parse the HTTP protocol greeting of format: 137 * 138 * $METHOD $PATH $VERSION 139 * 140 * e.g. 141 * 142 * GET / HTTP/1.1 143 */ 144 145 nl = strstr(buffer, QIO_CHANNEL_WEBSOCK_HANDSHAKE_DELIM); 146 if (!nl) { 147 error_setg(errp, "Missing HTTP header delimiter"); 148 return 0; 149 } 150 *nl = '\0'; 151 152 tmp = strchr(buffer, ' '); 153 if (!tmp) { 154 error_setg(errp, "Missing HTTP path delimiter"); 155 return 0; 156 } 157 *tmp = '\0'; 158 159 if (!g_str_equal(buffer, QIO_CHANNEL_WEBSOCK_HTTP_METHOD)) { 160 error_setg(errp, "Unsupported HTTP method %s", buffer); 161 return 0; 162 } 163 164 buffer = tmp + 1; 165 tmp = strchr(buffer, ' '); 166 if (!tmp) { 167 error_setg(errp, "Missing HTTP version delimiter"); 168 return 0; 169 } 170 *tmp = '\0'; 171 172 if (!g_str_equal(buffer, QIO_CHANNEL_WEBSOCK_HTTP_PATH)) { 173 error_setg(errp, "Unexpected HTTP path %s", buffer); 174 return 0; 175 } 176 177 buffer = tmp + 1; 178 179 if (!g_str_equal(buffer, QIO_CHANNEL_WEBSOCK_HTTP_VERSION)) { 180 error_setg(errp, "Unsupported HTTP version %s", buffer); 181 return 0; 182 } 183 184 buffer = nl + strlen(QIO_CHANNEL_WEBSOCK_HANDSHAKE_DELIM); 185 186 /* 187 * Now parse all the header fields of format 188 * 189 * $NAME: $VALUE 190 * 191 * e.g. 192 * 193 * Cache-control: no-cache 194 */ 195 do { 196 QIOChannelWebsockHTTPHeader *hdr; 197 198 nl = strstr(buffer, QIO_CHANNEL_WEBSOCK_HANDSHAKE_DELIM); 199 if (nl) { 200 *nl = '\0'; 201 } 202 203 sep = strchr(buffer, ':'); 204 if (!sep) { 205 error_setg(errp, "Malformed HTTP header"); 206 return 0; 207 } 208 *sep = '\0'; 209 sep++; 210 while (*sep == ' ') { 211 sep++; 212 } 213 214 if (nhdrs >= nhdrsalloc) { 215 error_setg(errp, "Too many HTTP headers"); 216 return 0; 217 } 218 219 hdr = &hdrs[nhdrs++]; 220 hdr->name = buffer; 221 hdr->value = sep; 222 223 /* Canonicalize header name for easier identification later */ 224 for (tmp = hdr->name; *tmp; tmp++) { 225 *tmp = g_ascii_tolower(*tmp); 226 } 227 228 if (nl) { 229 buffer = nl + strlen(QIO_CHANNEL_WEBSOCK_HANDSHAKE_DELIM); 230 } 231 } while (nl != NULL); 232 233 return nhdrs; 234 } 235 236 static const char * 237 qio_channel_websock_find_header(QIOChannelWebsockHTTPHeader *hdrs, 238 size_t nhdrs, 239 const char *name) 240 { 241 size_t i; 242 243 for (i = 0; i < nhdrs; i++) { 244 if (g_str_equal(hdrs[i].name, name)) { 245 return hdrs[i].value; 246 } 247 } 248 249 return NULL; 250 } 251 252 253 static int qio_channel_websock_handshake_send_response(QIOChannelWebsock *ioc, 254 const char *key, 255 Error **errp) 256 { 257 char combined_key[QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN + 258 QIO_CHANNEL_WEBSOCK_GUID_LEN + 1]; 259 char *accept = NULL, *response = NULL; 260 size_t responselen; 261 262 g_strlcpy(combined_key, key, QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN + 1); 263 g_strlcat(combined_key, QIO_CHANNEL_WEBSOCK_GUID, 264 QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN + 265 QIO_CHANNEL_WEBSOCK_GUID_LEN + 1); 266 267 /* hash and encode it */ 268 if (qcrypto_hash_base64(QCRYPTO_HASH_ALG_SHA1, 269 combined_key, 270 QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN + 271 QIO_CHANNEL_WEBSOCK_GUID_LEN, 272 &accept, 273 errp) < 0) { 274 return -1; 275 } 276 277 response = g_strdup_printf(QIO_CHANNEL_WEBSOCK_HANDSHAKE_RESPONSE, accept); 278 responselen = strlen(response); 279 buffer_reserve(&ioc->encoutput, responselen); 280 buffer_append(&ioc->encoutput, response, responselen); 281 282 g_free(accept); 283 g_free(response); 284 285 return 0; 286 } 287 288 static int qio_channel_websock_handshake_process(QIOChannelWebsock *ioc, 289 char *buffer, 290 Error **errp) 291 { 292 QIOChannelWebsockHTTPHeader hdrs[32]; 293 size_t nhdrs = G_N_ELEMENTS(hdrs); 294 const char *protocols = NULL, *version = NULL, *key = NULL, 295 *host = NULL, *connection = NULL, *upgrade = NULL; 296 297 nhdrs = qio_channel_websock_extract_headers(buffer, hdrs, nhdrs, errp); 298 if (!nhdrs) { 299 return -1; 300 } 301 302 protocols = qio_channel_websock_find_header( 303 hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_PROTOCOL); 304 if (!protocols) { 305 error_setg(errp, "Missing websocket protocol header data"); 306 return -1; 307 } 308 309 version = qio_channel_websock_find_header( 310 hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_VERSION); 311 if (!version) { 312 error_setg(errp, "Missing websocket version header data"); 313 return -1; 314 } 315 316 key = qio_channel_websock_find_header( 317 hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_KEY); 318 if (!key) { 319 error_setg(errp, "Missing websocket key header data"); 320 return -1; 321 } 322 323 host = qio_channel_websock_find_header( 324 hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_HOST); 325 if (!host) { 326 error_setg(errp, "Missing websocket host header data"); 327 return -1; 328 } 329 330 connection = qio_channel_websock_find_header( 331 hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_CONNECTION); 332 if (!connection) { 333 error_setg(errp, "Missing websocket connection header data"); 334 return -1; 335 } 336 337 upgrade = qio_channel_websock_find_header( 338 hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_UPGRADE); 339 if (!upgrade) { 340 error_setg(errp, "Missing websocket upgrade header data"); 341 return -1; 342 } 343 344 if (!g_strrstr(protocols, QIO_CHANNEL_WEBSOCK_PROTOCOL_BINARY)) { 345 error_setg(errp, "No '%s' protocol is supported by client '%s'", 346 QIO_CHANNEL_WEBSOCK_PROTOCOL_BINARY, protocols); 347 return -1; 348 } 349 350 if (!g_str_equal(version, QIO_CHANNEL_WEBSOCK_SUPPORTED_VERSION)) { 351 error_setg(errp, "Version '%s' is not supported by client '%s'", 352 QIO_CHANNEL_WEBSOCK_SUPPORTED_VERSION, version); 353 return -1; 354 } 355 356 if (strlen(key) != QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN) { 357 error_setg(errp, "Key length '%zu' was not as expected '%d'", 358 strlen(key), QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN); 359 return -1; 360 } 361 362 if (!g_strrstr(connection, QIO_CHANNEL_WEBSOCK_CONNECTION_UPGRADE)) { 363 error_setg(errp, "No connection upgrade requested '%s'", connection); 364 return -1; 365 } 366 367 if (!g_str_equal(upgrade, QIO_CHANNEL_WEBSOCK_UPGRADE_WEBSOCKET)) { 368 error_setg(errp, "Incorrect upgrade method '%s'", upgrade); 369 return -1; 370 } 371 372 return qio_channel_websock_handshake_send_response(ioc, key, errp); 373 } 374 375 static int qio_channel_websock_handshake_read(QIOChannelWebsock *ioc, 376 Error **errp) 377 { 378 char *handshake_end; 379 ssize_t ret; 380 /* Typical HTTP headers from novnc are 512 bytes, so limiting 381 * total header size to 4096 is easily enough. */ 382 size_t want = 4096 - ioc->encinput.offset; 383 buffer_reserve(&ioc->encinput, want); 384 ret = qio_channel_read(ioc->master, 385 (char *)buffer_end(&ioc->encinput), want, errp); 386 if (ret < 0) { 387 return -1; 388 } 389 ioc->encinput.offset += ret; 390 391 handshake_end = g_strstr_len((char *)ioc->encinput.buffer, 392 ioc->encinput.offset, 393 QIO_CHANNEL_WEBSOCK_HANDSHAKE_END); 394 if (!handshake_end) { 395 if (ioc->encinput.offset >= 4096) { 396 error_setg(errp, 397 "End of headers not found in first 4096 bytes"); 398 return -1; 399 } else { 400 return 0; 401 } 402 } 403 *handshake_end = '\0'; 404 405 if (qio_channel_websock_handshake_process(ioc, 406 (char *)ioc->encinput.buffer, 407 errp) < 0) { 408 return -1; 409 } 410 411 buffer_advance(&ioc->encinput, 412 handshake_end - (char *)ioc->encinput.buffer + 413 strlen(QIO_CHANNEL_WEBSOCK_HANDSHAKE_END)); 414 return 1; 415 } 416 417 static gboolean qio_channel_websock_handshake_send(QIOChannel *ioc, 418 GIOCondition condition, 419 gpointer user_data) 420 { 421 QIOTask *task = user_data; 422 QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK( 423 qio_task_get_source(task)); 424 Error *err = NULL; 425 ssize_t ret; 426 427 ret = qio_channel_write(wioc->master, 428 (char *)wioc->encoutput.buffer, 429 wioc->encoutput.offset, 430 &err); 431 432 if (ret < 0) { 433 trace_qio_channel_websock_handshake_fail(ioc); 434 qio_task_set_error(task, err); 435 qio_task_complete(task); 436 return FALSE; 437 } 438 439 buffer_advance(&wioc->encoutput, ret); 440 if (wioc->encoutput.offset == 0) { 441 trace_qio_channel_websock_handshake_complete(ioc); 442 qio_task_complete(task); 443 return FALSE; 444 } 445 trace_qio_channel_websock_handshake_pending(ioc, G_IO_OUT); 446 return TRUE; 447 } 448 449 static gboolean qio_channel_websock_handshake_io(QIOChannel *ioc, 450 GIOCondition condition, 451 gpointer user_data) 452 { 453 QIOTask *task = user_data; 454 QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK( 455 qio_task_get_source(task)); 456 Error *err = NULL; 457 int ret; 458 459 ret = qio_channel_websock_handshake_read(wioc, &err); 460 if (ret < 0) { 461 trace_qio_channel_websock_handshake_fail(ioc); 462 qio_task_set_error(task, err); 463 qio_task_complete(task); 464 return FALSE; 465 } 466 if (ret == 0) { 467 trace_qio_channel_websock_handshake_pending(ioc, G_IO_IN); 468 /* need more data still */ 469 return TRUE; 470 } 471 472 trace_qio_channel_websock_handshake_reply(ioc); 473 qio_channel_add_watch( 474 wioc->master, 475 G_IO_OUT, 476 qio_channel_websock_handshake_send, 477 task, 478 NULL); 479 return FALSE; 480 } 481 482 483 static void qio_channel_websock_encode(QIOChannelWebsock *ioc) 484 { 485 size_t header_size; 486 union { 487 char buf[QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT]; 488 QIOChannelWebsockHeader ws; 489 } header; 490 491 if (!ioc->rawoutput.offset) { 492 return; 493 } 494 495 header.ws.b0 = (1 << QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_FIN) | 496 (QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME & 497 QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE); 498 if (ioc->rawoutput.offset < 499 QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_THRESHOLD_7_BIT) { 500 header.ws.b1 = (uint8_t)ioc->rawoutput.offset; 501 header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT; 502 } else if (ioc->rawoutput.offset < 503 QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_THRESHOLD_16_BIT) { 504 header.ws.b1 = QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT; 505 header.ws.u.s16.l16 = cpu_to_be16((uint16_t)ioc->rawoutput.offset); 506 header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT; 507 } else { 508 header.ws.b1 = QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_64_BIT; 509 header.ws.u.s64.l64 = cpu_to_be64(ioc->rawoutput.offset); 510 header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT; 511 } 512 header_size -= QIO_CHANNEL_WEBSOCK_HEADER_LEN_MASK; 513 514 buffer_reserve(&ioc->encoutput, header_size + ioc->rawoutput.offset); 515 buffer_append(&ioc->encoutput, header.buf, header_size); 516 buffer_append(&ioc->encoutput, ioc->rawoutput.buffer, 517 ioc->rawoutput.offset); 518 buffer_reset(&ioc->rawoutput); 519 } 520 521 522 static ssize_t qio_channel_websock_decode_header(QIOChannelWebsock *ioc, 523 Error **errp) 524 { 525 unsigned char opcode, fin, has_mask; 526 size_t header_size; 527 size_t payload_len; 528 QIOChannelWebsockHeader *header = 529 (QIOChannelWebsockHeader *)ioc->encinput.buffer; 530 531 if (ioc->payload_remain) { 532 error_setg(errp, 533 "Decoding header but %zu bytes of payload remain", 534 ioc->payload_remain); 535 return -1; 536 } 537 if (ioc->encinput.offset < QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT) { 538 /* header not complete */ 539 return QIO_CHANNEL_ERR_BLOCK; 540 } 541 542 fin = (header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_FIN) >> 543 QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_FIN; 544 opcode = header->b0 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_OPCODE; 545 has_mask = (header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_HAS_MASK) >> 546 QIO_CHANNEL_WEBSOCK_HEADER_SHIFT_HAS_MASK; 547 payload_len = header->b1 & QIO_CHANNEL_WEBSOCK_HEADER_FIELD_PAYLOAD_LEN; 548 549 if (opcode == QIO_CHANNEL_WEBSOCK_OPCODE_CLOSE) { 550 /* disconnect */ 551 return 0; 552 } 553 554 /* Websocket frame sanity check: 555 * * Websocket fragmentation is not supported. 556 * * All websockets frames sent by a client have to be masked. 557 * * Only binary encoding is supported. 558 */ 559 if (!fin) { 560 error_setg(errp, "websocket fragmentation is not supported"); 561 return -1; 562 } 563 if (!has_mask) { 564 error_setg(errp, "websocket frames must be masked"); 565 return -1; 566 } 567 if (opcode != QIO_CHANNEL_WEBSOCK_OPCODE_BINARY_FRAME) { 568 error_setg(errp, "only binary websocket frames are supported"); 569 return -1; 570 } 571 572 if (payload_len < QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT) { 573 ioc->payload_remain = payload_len; 574 header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_7_BIT; 575 ioc->mask = header->u.m; 576 } else if (payload_len == QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_16_BIT && 577 ioc->encinput.offset >= QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT) { 578 ioc->payload_remain = be16_to_cpu(header->u.s16.l16); 579 header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_16_BIT; 580 ioc->mask = header->u.s16.m16; 581 } else if (payload_len == QIO_CHANNEL_WEBSOCK_PAYLOAD_LEN_MAGIC_64_BIT && 582 ioc->encinput.offset >= QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT) { 583 ioc->payload_remain = be64_to_cpu(header->u.s64.l64); 584 header_size = QIO_CHANNEL_WEBSOCK_HEADER_LEN_64_BIT; 585 ioc->mask = header->u.s64.m64; 586 } else { 587 /* header not complete */ 588 return QIO_CHANNEL_ERR_BLOCK; 589 } 590 591 buffer_advance(&ioc->encinput, header_size); 592 return 1; 593 } 594 595 596 static ssize_t qio_channel_websock_decode_payload(QIOChannelWebsock *ioc, 597 Error **errp) 598 { 599 size_t i; 600 size_t payload_len; 601 uint32_t *payload32; 602 603 if (!ioc->payload_remain) { 604 error_setg(errp, 605 "Decoding payload but no bytes of payload remain"); 606 return -1; 607 } 608 609 /* If we aren't at the end of the payload, then drop 610 * off the last bytes, so we're always multiple of 4 611 * for purpose of unmasking, except at end of payload 612 */ 613 if (ioc->encinput.offset < ioc->payload_remain) { 614 payload_len = ioc->encinput.offset - (ioc->encinput.offset % 4); 615 } else { 616 payload_len = ioc->payload_remain; 617 } 618 if (payload_len == 0) { 619 return QIO_CHANNEL_ERR_BLOCK; 620 } 621 622 ioc->payload_remain -= payload_len; 623 624 /* unmask frame */ 625 /* process 1 frame (32 bit op) */ 626 payload32 = (uint32_t *)ioc->encinput.buffer; 627 for (i = 0; i < payload_len / 4; i++) { 628 payload32[i] ^= ioc->mask.u; 629 } 630 /* process the remaining bytes (if any) */ 631 for (i *= 4; i < payload_len; i++) { 632 ioc->encinput.buffer[i] ^= ioc->mask.c[i % 4]; 633 } 634 635 buffer_reserve(&ioc->rawinput, payload_len); 636 buffer_append(&ioc->rawinput, ioc->encinput.buffer, payload_len); 637 buffer_advance(&ioc->encinput, payload_len); 638 return payload_len; 639 } 640 641 642 QIOChannelWebsock * 643 qio_channel_websock_new_server(QIOChannel *master) 644 { 645 QIOChannelWebsock *wioc; 646 QIOChannel *ioc; 647 648 wioc = QIO_CHANNEL_WEBSOCK(object_new(TYPE_QIO_CHANNEL_WEBSOCK)); 649 ioc = QIO_CHANNEL(wioc); 650 651 wioc->master = master; 652 if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) { 653 qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN); 654 } 655 object_ref(OBJECT(master)); 656 657 trace_qio_channel_websock_new_server(wioc, master); 658 return wioc; 659 } 660 661 void qio_channel_websock_handshake(QIOChannelWebsock *ioc, 662 QIOTaskFunc func, 663 gpointer opaque, 664 GDestroyNotify destroy) 665 { 666 QIOTask *task; 667 668 task = qio_task_new(OBJECT(ioc), 669 func, 670 opaque, 671 destroy); 672 673 trace_qio_channel_websock_handshake_start(ioc); 674 trace_qio_channel_websock_handshake_pending(ioc, G_IO_IN); 675 qio_channel_add_watch(ioc->master, 676 G_IO_IN, 677 qio_channel_websock_handshake_io, 678 task, 679 NULL); 680 } 681 682 683 static void qio_channel_websock_finalize(Object *obj) 684 { 685 QIOChannelWebsock *ioc = QIO_CHANNEL_WEBSOCK(obj); 686 687 buffer_free(&ioc->encinput); 688 buffer_free(&ioc->encoutput); 689 buffer_free(&ioc->rawinput); 690 buffer_free(&ioc->rawoutput); 691 object_unref(OBJECT(ioc->master)); 692 if (ioc->io_tag) { 693 g_source_remove(ioc->io_tag); 694 } 695 if (ioc->io_err) { 696 error_free(ioc->io_err); 697 } 698 } 699 700 701 static ssize_t qio_channel_websock_read_wire(QIOChannelWebsock *ioc, 702 Error **errp) 703 { 704 ssize_t ret; 705 706 if (ioc->encinput.offset < 4096) { 707 size_t want = 4096 - ioc->encinput.offset; 708 709 buffer_reserve(&ioc->encinput, want); 710 ret = qio_channel_read(ioc->master, 711 (char *)ioc->encinput.buffer + 712 ioc->encinput.offset, 713 want, 714 errp); 715 if (ret < 0) { 716 return ret; 717 } 718 if (ret == 0 && 719 ioc->encinput.offset == 0) { 720 return 0; 721 } 722 ioc->encinput.offset += ret; 723 } 724 725 while (ioc->encinput.offset != 0) { 726 if (ioc->payload_remain == 0) { 727 ret = qio_channel_websock_decode_header(ioc, errp); 728 if (ret < 0) { 729 return ret; 730 } 731 if (ret == 0) { 732 ioc->io_eof = TRUE; 733 break; 734 } 735 } 736 737 ret = qio_channel_websock_decode_payload(ioc, errp); 738 if (ret < 0) { 739 return ret; 740 } 741 } 742 return 1; 743 } 744 745 746 static ssize_t qio_channel_websock_write_wire(QIOChannelWebsock *ioc, 747 Error **errp) 748 { 749 ssize_t ret; 750 ssize_t done = 0; 751 qio_channel_websock_encode(ioc); 752 753 while (ioc->encoutput.offset > 0) { 754 ret = qio_channel_write(ioc->master, 755 (char *)ioc->encoutput.buffer, 756 ioc->encoutput.offset, 757 errp); 758 if (ret < 0) { 759 if (ret == QIO_CHANNEL_ERR_BLOCK && 760 done > 0) { 761 return done; 762 } else { 763 return ret; 764 } 765 } 766 buffer_advance(&ioc->encoutput, ret); 767 done += ret; 768 } 769 return done; 770 } 771 772 773 static void qio_channel_websock_flush_free(gpointer user_data) 774 { 775 QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(user_data); 776 object_unref(OBJECT(wioc)); 777 } 778 779 static void qio_channel_websock_set_watch(QIOChannelWebsock *ioc); 780 781 static gboolean qio_channel_websock_flush(QIOChannel *ioc, 782 GIOCondition condition, 783 gpointer user_data) 784 { 785 QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(user_data); 786 ssize_t ret; 787 788 if (condition & G_IO_OUT) { 789 ret = qio_channel_websock_write_wire(wioc, &wioc->io_err); 790 if (ret < 0) { 791 goto cleanup; 792 } 793 } 794 795 if (condition & G_IO_IN) { 796 ret = qio_channel_websock_read_wire(wioc, &wioc->io_err); 797 if (ret < 0) { 798 goto cleanup; 799 } 800 } 801 802 cleanup: 803 qio_channel_websock_set_watch(wioc); 804 return FALSE; 805 } 806 807 808 static void qio_channel_websock_unset_watch(QIOChannelWebsock *ioc) 809 { 810 if (ioc->io_tag) { 811 g_source_remove(ioc->io_tag); 812 ioc->io_tag = 0; 813 } 814 } 815 816 static void qio_channel_websock_set_watch(QIOChannelWebsock *ioc) 817 { 818 GIOCondition cond = 0; 819 820 qio_channel_websock_unset_watch(ioc); 821 822 if (ioc->io_err) { 823 return; 824 } 825 826 if (ioc->encoutput.offset) { 827 cond |= G_IO_OUT; 828 } 829 if (ioc->encinput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER && 830 !ioc->io_eof) { 831 cond |= G_IO_IN; 832 } 833 834 if (cond) { 835 object_ref(OBJECT(ioc)); 836 ioc->io_tag = 837 qio_channel_add_watch(ioc->master, 838 cond, 839 qio_channel_websock_flush, 840 ioc, 841 qio_channel_websock_flush_free); 842 } 843 } 844 845 846 static ssize_t qio_channel_websock_readv(QIOChannel *ioc, 847 const struct iovec *iov, 848 size_t niov, 849 int **fds, 850 size_t *nfds, 851 Error **errp) 852 { 853 QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc); 854 size_t i; 855 ssize_t got = 0; 856 ssize_t ret; 857 858 if (wioc->io_err) { 859 error_propagate(errp, error_copy(wioc->io_err)); 860 return -1; 861 } 862 863 if (!wioc->rawinput.offset) { 864 ret = qio_channel_websock_read_wire(QIO_CHANNEL_WEBSOCK(ioc), errp); 865 if (ret < 0) { 866 return ret; 867 } 868 } 869 870 for (i = 0 ; i < niov ; i++) { 871 size_t want = iov[i].iov_len; 872 if (want > (wioc->rawinput.offset - got)) { 873 want = (wioc->rawinput.offset - got); 874 } 875 876 memcpy(iov[i].iov_base, 877 wioc->rawinput.buffer + got, 878 want); 879 got += want; 880 881 if (want < iov[i].iov_len) { 882 break; 883 } 884 } 885 886 buffer_advance(&wioc->rawinput, got); 887 qio_channel_websock_set_watch(wioc); 888 return got; 889 } 890 891 892 static ssize_t qio_channel_websock_writev(QIOChannel *ioc, 893 const struct iovec *iov, 894 size_t niov, 895 int *fds, 896 size_t nfds, 897 Error **errp) 898 { 899 QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc); 900 size_t i; 901 ssize_t done = 0; 902 ssize_t ret; 903 904 if (wioc->io_err) { 905 error_propagate(errp, error_copy(wioc->io_err)); 906 return -1; 907 } 908 909 if (wioc->io_eof) { 910 error_setg(errp, "%s", "Broken pipe"); 911 return -1; 912 } 913 914 for (i = 0; i < niov; i++) { 915 size_t want = iov[i].iov_len; 916 if ((want + wioc->rawoutput.offset) > QIO_CHANNEL_WEBSOCK_MAX_BUFFER) { 917 want = (QIO_CHANNEL_WEBSOCK_MAX_BUFFER - wioc->rawoutput.offset); 918 } 919 if (want == 0) { 920 goto done; 921 } 922 923 buffer_reserve(&wioc->rawoutput, want); 924 buffer_append(&wioc->rawoutput, iov[i].iov_base, want); 925 done += want; 926 if (want < iov[i].iov_len) { 927 break; 928 } 929 } 930 931 done: 932 ret = qio_channel_websock_write_wire(wioc, errp); 933 if (ret < 0 && 934 ret != QIO_CHANNEL_ERR_BLOCK) { 935 qio_channel_websock_unset_watch(wioc); 936 return -1; 937 } 938 939 qio_channel_websock_set_watch(wioc); 940 941 if (done == 0) { 942 return QIO_CHANNEL_ERR_BLOCK; 943 } 944 945 return done; 946 } 947 948 static int qio_channel_websock_set_blocking(QIOChannel *ioc, 949 bool enabled, 950 Error **errp) 951 { 952 QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc); 953 954 qio_channel_set_blocking(wioc->master, enabled, errp); 955 return 0; 956 } 957 958 static void qio_channel_websock_set_delay(QIOChannel *ioc, 959 bool enabled) 960 { 961 QIOChannelWebsock *tioc = QIO_CHANNEL_WEBSOCK(ioc); 962 963 qio_channel_set_delay(tioc->master, enabled); 964 } 965 966 static void qio_channel_websock_set_cork(QIOChannel *ioc, 967 bool enabled) 968 { 969 QIOChannelWebsock *tioc = QIO_CHANNEL_WEBSOCK(ioc); 970 971 qio_channel_set_cork(tioc->master, enabled); 972 } 973 974 static int qio_channel_websock_shutdown(QIOChannel *ioc, 975 QIOChannelShutdown how, 976 Error **errp) 977 { 978 QIOChannelWebsock *tioc = QIO_CHANNEL_WEBSOCK(ioc); 979 980 return qio_channel_shutdown(tioc->master, how, errp); 981 } 982 983 static int qio_channel_websock_close(QIOChannel *ioc, 984 Error **errp) 985 { 986 QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc); 987 988 return qio_channel_close(wioc->master, errp); 989 } 990 991 typedef struct QIOChannelWebsockSource QIOChannelWebsockSource; 992 struct QIOChannelWebsockSource { 993 GSource parent; 994 QIOChannelWebsock *wioc; 995 GIOCondition condition; 996 }; 997 998 static gboolean 999 qio_channel_websock_source_prepare(GSource *source, 1000 gint *timeout) 1001 { 1002 QIOChannelWebsockSource *wsource = (QIOChannelWebsockSource *)source; 1003 GIOCondition cond = 0; 1004 *timeout = -1; 1005 1006 if (wsource->wioc->rawinput.offset) { 1007 cond |= G_IO_IN; 1008 } 1009 if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) { 1010 cond |= G_IO_OUT; 1011 } 1012 1013 return cond & wsource->condition; 1014 } 1015 1016 static gboolean 1017 qio_channel_websock_source_check(GSource *source) 1018 { 1019 QIOChannelWebsockSource *wsource = (QIOChannelWebsockSource *)source; 1020 GIOCondition cond = 0; 1021 1022 if (wsource->wioc->rawinput.offset) { 1023 cond |= G_IO_IN; 1024 } 1025 if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) { 1026 cond |= G_IO_OUT; 1027 } 1028 1029 return cond & wsource->condition; 1030 } 1031 1032 static gboolean 1033 qio_channel_websock_source_dispatch(GSource *source, 1034 GSourceFunc callback, 1035 gpointer user_data) 1036 { 1037 QIOChannelFunc func = (QIOChannelFunc)callback; 1038 QIOChannelWebsockSource *wsource = (QIOChannelWebsockSource *)source; 1039 GIOCondition cond = 0; 1040 1041 if (wsource->wioc->rawinput.offset) { 1042 cond |= G_IO_IN; 1043 } 1044 if (wsource->wioc->rawoutput.offset < QIO_CHANNEL_WEBSOCK_MAX_BUFFER) { 1045 cond |= G_IO_OUT; 1046 } 1047 1048 return (*func)(QIO_CHANNEL(wsource->wioc), 1049 (cond & wsource->condition), 1050 user_data); 1051 } 1052 1053 static void 1054 qio_channel_websock_source_finalize(GSource *source) 1055 { 1056 QIOChannelWebsockSource *ssource = (QIOChannelWebsockSource *)source; 1057 1058 object_unref(OBJECT(ssource->wioc)); 1059 } 1060 1061 GSourceFuncs qio_channel_websock_source_funcs = { 1062 qio_channel_websock_source_prepare, 1063 qio_channel_websock_source_check, 1064 qio_channel_websock_source_dispatch, 1065 qio_channel_websock_source_finalize 1066 }; 1067 1068 static GSource *qio_channel_websock_create_watch(QIOChannel *ioc, 1069 GIOCondition condition) 1070 { 1071 QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc); 1072 QIOChannelWebsockSource *ssource; 1073 GSource *source; 1074 1075 source = g_source_new(&qio_channel_websock_source_funcs, 1076 sizeof(QIOChannelWebsockSource)); 1077 ssource = (QIOChannelWebsockSource *)source; 1078 1079 ssource->wioc = wioc; 1080 object_ref(OBJECT(wioc)); 1081 1082 ssource->condition = condition; 1083 1084 qio_channel_websock_set_watch(wioc); 1085 return source; 1086 } 1087 1088 static void qio_channel_websock_class_init(ObjectClass *klass, 1089 void *class_data G_GNUC_UNUSED) 1090 { 1091 QIOChannelClass *ioc_klass = QIO_CHANNEL_CLASS(klass); 1092 1093 ioc_klass->io_writev = qio_channel_websock_writev; 1094 ioc_klass->io_readv = qio_channel_websock_readv; 1095 ioc_klass->io_set_blocking = qio_channel_websock_set_blocking; 1096 ioc_klass->io_set_cork = qio_channel_websock_set_cork; 1097 ioc_klass->io_set_delay = qio_channel_websock_set_delay; 1098 ioc_klass->io_close = qio_channel_websock_close; 1099 ioc_klass->io_shutdown = qio_channel_websock_shutdown; 1100 ioc_klass->io_create_watch = qio_channel_websock_create_watch; 1101 } 1102 1103 static const TypeInfo qio_channel_websock_info = { 1104 .parent = TYPE_QIO_CHANNEL, 1105 .name = TYPE_QIO_CHANNEL_WEBSOCK, 1106 .instance_size = sizeof(QIOChannelWebsock), 1107 .instance_finalize = qio_channel_websock_finalize, 1108 .class_init = qio_channel_websock_class_init, 1109 }; 1110 1111 static void qio_channel_websock_register_types(void) 1112 { 1113 type_register_static(&qio_channel_websock_info); 1114 } 1115 1116 type_init(qio_channel_websock_register_types); 1117