1 /* ==================================================================== 2 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 16 * 3. All advertising materials mentioning features or use of this 17 * software must display the following acknowledgment: 18 * "This product includes software developed by the OpenSSL Project 19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 20 * 21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 22 * endorse or promote products derived from this software without 23 * prior written permission. For written permission, please contact 24 * openssl-core (at) openssl.org. 25 * 26 * 5. Products derived from this software may not be called "OpenSSL" 27 * nor may "OpenSSL" appear in their names without prior written 28 * permission of the OpenSSL Project. 29 * 30 * 6. Redistributions of any form whatsoever must retain the following 31 * acknowledgment: 32 * "This product includes software developed by the OpenSSL Project 33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 34 * 35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 46 * OF THE POSSIBILITY OF SUCH DAMAGE. 47 * ==================================================================== 48 * 49 * This product includes cryptographic software written by Eric Young 50 * (eay (at) cryptsoft.com). This product includes software written by Tim 51 * Hudson (tjh (at) cryptsoft.com). */ 52 53 #include <openssl/bio.h> 54 55 #include <assert.h> 56 #include <string.h> 57 58 #include <openssl/buf.h> 59 #include <openssl/err.h> 60 #include <openssl/mem.h> 61 62 63 struct bio_bio_st { 64 BIO *peer; /* NULL if buf == NULL. 65 * If peer != NULL, then peer->ptr is also a bio_bio_st, 66 * and its "peer" member points back to us. 67 * peer != NULL iff init != 0 in the BIO. */ 68 69 /* This is for what we write (i.e. reading uses peer's struct): */ 70 int closed; /* valid iff peer != NULL */ 71 size_t len; /* valid iff buf != NULL; 0 if peer == NULL */ 72 size_t offset; /* valid iff buf != NULL; 0 if len == 0 */ 73 size_t size; 74 uint8_t *buf; /* "size" elements (if != NULL) */ 75 char buf_externally_allocated; /* true iff buf was externally allocated. */ 76 77 char zero_copy_read_lock; /* true iff a zero copy read operation 78 * is in progress. */ 79 char zero_copy_write_lock; /* true iff a zero copy write operation 80 * is in progress. */ 81 82 size_t request; /* valid iff peer != NULL; 0 if len != 0, 83 * otherwise set by peer to number of bytes 84 * it (unsuccessfully) tried to read, 85 * never more than buffer space (size-len) warrants. */ 86 }; 87 88 static int bio_new(BIO *bio) { 89 struct bio_bio_st *b; 90 91 b = OPENSSL_malloc(sizeof *b); 92 if (b == NULL) { 93 return 0; 94 } 95 memset(b, 0, sizeof(struct bio_bio_st)); 96 97 b->size = 17 * 1024; /* enough for one TLS record (just a default) */ 98 bio->ptr = b; 99 return 1; 100 } 101 102 static void bio_destroy_pair(BIO *bio) { 103 struct bio_bio_st *b = bio->ptr; 104 BIO *peer_bio; 105 struct bio_bio_st *peer_b; 106 107 if (b == NULL) { 108 return; 109 } 110 111 peer_bio = b->peer; 112 if (peer_bio == NULL) { 113 return; 114 } 115 116 peer_b = peer_bio->ptr; 117 118 assert(peer_b != NULL); 119 assert(peer_b->peer == bio); 120 121 peer_b->peer = NULL; 122 peer_bio->init = 0; 123 assert(peer_b->buf != NULL); 124 peer_b->len = 0; 125 peer_b->offset = 0; 126 127 b->peer = NULL; 128 bio->init = 0; 129 assert(b->buf != NULL); 130 b->len = 0; 131 b->offset = 0; 132 } 133 134 static int bio_free(BIO *bio) { 135 struct bio_bio_st *b; 136 137 if (bio == NULL) { 138 return 0; 139 } 140 b = bio->ptr; 141 142 assert(b != NULL); 143 144 if (b->peer) { 145 bio_destroy_pair(bio); 146 } 147 148 if (!b->buf_externally_allocated) { 149 OPENSSL_free(b->buf); 150 } 151 152 OPENSSL_free(b); 153 154 return 1; 155 } 156 157 static size_t bio_zero_copy_get_read_buf(struct bio_bio_st* peer_b, 158 uint8_t** out_read_buf, 159 size_t* out_buf_offset) { 160 size_t max_available; 161 if (peer_b->len > peer_b->size - peer_b->offset) { 162 /* Only the first half of the ring buffer can be read. */ 163 max_available = peer_b->size - peer_b->offset; 164 } else { 165 max_available = peer_b->len; 166 } 167 168 *out_read_buf = peer_b->buf; 169 *out_buf_offset = peer_b->offset; 170 return max_available; 171 } 172 173 int BIO_zero_copy_get_read_buf(BIO* bio, uint8_t** out_read_buf, 174 size_t* out_buf_offset, 175 size_t* out_available_bytes) { 176 struct bio_bio_st* b; 177 struct bio_bio_st* peer_b; 178 size_t max_available; 179 *out_available_bytes = 0; 180 181 BIO_clear_retry_flags(bio); 182 183 if (!bio->init) { 184 OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf, BIO_R_UNINITIALIZED); 185 return 0; 186 } 187 188 b = bio->ptr; 189 190 if (!b || !b->peer) { 191 OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf, 192 BIO_R_UNSUPPORTED_METHOD); 193 return 0; 194 } 195 196 peer_b = b->peer->ptr; 197 if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) { 198 OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf, 199 BIO_R_UNSUPPORTED_METHOD); 200 return 0; 201 } 202 203 if (peer_b->zero_copy_read_lock) { 204 OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf, BIO_R_INVALID_ARGUMENT); 205 return 0; 206 } 207 208 peer_b->request = 0; /* Is not used by zero-copy API. */ 209 210 max_available = 211 bio_zero_copy_get_read_buf(peer_b, out_read_buf, out_buf_offset); 212 213 assert(peer_b->buf != NULL); 214 if (max_available > 0) { 215 peer_b->zero_copy_read_lock = 1; 216 } 217 218 *out_available_bytes = max_available; 219 return 1; 220 } 221 222 int BIO_zero_copy_get_read_buf_done(BIO* bio, size_t bytes_read) { 223 struct bio_bio_st* b; 224 struct bio_bio_st* peer_b; 225 size_t max_available; 226 size_t dummy_read_offset; 227 uint8_t* dummy_read_buf; 228 229 assert(BIO_get_retry_flags(bio) == 0); 230 231 if (!bio->init) { 232 OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done, 233 BIO_R_UNINITIALIZED); 234 return 0; 235 } 236 237 b = bio->ptr; 238 239 if (!b || !b->peer) { 240 OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done, 241 BIO_R_UNSUPPORTED_METHOD); 242 return 0; 243 } 244 245 peer_b = b->peer->ptr; 246 if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) { 247 OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done, 248 BIO_R_UNSUPPORTED_METHOD); 249 return 0; 250 } 251 252 if (!peer_b->zero_copy_read_lock) { 253 OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done, 254 BIO_R_INVALID_ARGUMENT); 255 return 0; 256 } 257 258 max_available = 259 bio_zero_copy_get_read_buf(peer_b, &dummy_read_buf, &dummy_read_offset); 260 if (bytes_read > max_available) { 261 OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done, 262 BIO_R_INVALID_ARGUMENT); 263 return 0; 264 } 265 266 peer_b->len -= bytes_read; 267 assert(peer_b->len >= 0); 268 assert(peer_b->offset + bytes_read <= peer_b->size); 269 270 /* Move read offset. If zero_copy_write_lock == 1 we must advance the 271 * offset even if buffer becomes empty, to make sure 272 * write_offset = (offset + len) mod size does not change. */ 273 if (peer_b->offset + bytes_read == peer_b->size || 274 (!peer_b->zero_copy_write_lock && peer_b->len == 0)) { 275 peer_b->offset = 0; 276 } else { 277 peer_b->offset += bytes_read; 278 } 279 280 bio->num_read += bytes_read; 281 peer_b->zero_copy_read_lock = 0; 282 return 1; 283 } 284 285 static size_t bio_zero_copy_get_write_buf(struct bio_bio_st* b, 286 uint8_t** out_write_buf, 287 size_t* out_buf_offset) { 288 size_t write_offset; 289 size_t max_available; 290 291 assert(b->len <= b->size); 292 293 write_offset = b->offset + b->len; 294 295 if (write_offset >= b->size) { 296 /* Only the first half of the ring buffer can be written to. */ 297 write_offset -= b->size; 298 /* write up to the start of the ring buffer. */ 299 max_available = b->offset - write_offset; 300 } else { 301 /* write up to the end the buffer. */ 302 max_available = b->size - write_offset; 303 } 304 305 *out_write_buf = b->buf; 306 *out_buf_offset = write_offset; 307 return max_available; 308 } 309 310 int BIO_zero_copy_get_write_buf(BIO* bio, uint8_t** out_write_buf, 311 size_t* out_buf_offset, 312 size_t* out_available_bytes) { 313 struct bio_bio_st* b; 314 struct bio_bio_st* peer_b; 315 size_t max_available; 316 317 *out_available_bytes = 0; 318 BIO_clear_retry_flags(bio); 319 320 if (!bio->init) { 321 OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf, BIO_R_UNINITIALIZED); 322 return 0; 323 } 324 325 b = bio->ptr; 326 327 if (!b || !b->buf || !b->peer) { 328 OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf, 329 BIO_R_UNSUPPORTED_METHOD); 330 return 0; 331 } 332 peer_b = b->peer->ptr; 333 if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) { 334 OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf, 335 BIO_R_UNSUPPORTED_METHOD); 336 return 0; 337 } 338 339 assert(b->buf != NULL); 340 341 if (b->zero_copy_write_lock) { 342 OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf, BIO_R_INVALID_ARGUMENT); 343 return 0; 344 } 345 346 b->request = 0; 347 if (b->closed) { 348 /* Bio is already closed. */ 349 OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf, BIO_R_BROKEN_PIPE); 350 return 0; 351 } 352 353 max_available = bio_zero_copy_get_write_buf(b, out_write_buf, out_buf_offset); 354 355 if (max_available > 0) { 356 b->zero_copy_write_lock = 1; 357 } 358 359 *out_available_bytes = max_available; 360 return 1; 361 } 362 363 int BIO_zero_copy_get_write_buf_done(BIO* bio, size_t bytes_written) { 364 struct bio_bio_st* b; 365 struct bio_bio_st* peer_b; 366 367 size_t rest; 368 size_t dummy_write_offset; 369 uint8_t* dummy_write_buf; 370 371 if (!bio->init) { 372 OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done, 373 BIO_R_UNINITIALIZED); 374 return 0; 375 } 376 377 b = bio->ptr; 378 379 if (!b || !b->buf || !b->peer) { 380 OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done, 381 BIO_R_UNSUPPORTED_METHOD); 382 return 0; 383 } 384 peer_b = b->peer->ptr; 385 if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) { 386 OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done, 387 BIO_R_UNSUPPORTED_METHOD); 388 return 0; 389 } 390 391 b->request = 0; 392 if (b->closed) { 393 /* BIO is already closed. */ 394 OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done, BIO_R_BROKEN_PIPE); 395 return 0; 396 } 397 398 if (!b->zero_copy_write_lock) { 399 OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done, 400 BIO_R_INVALID_ARGUMENT); 401 return 0; 402 } 403 404 rest = bio_zero_copy_get_write_buf(b, &dummy_write_buf, &dummy_write_offset); 405 406 if (bytes_written > rest) { 407 OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done, 408 BIO_R_INVALID_ARGUMENT); 409 return 0; 410 } 411 412 bio->num_write += bytes_written; 413 /* Move write offset. */ 414 b->len += bytes_written; 415 b->zero_copy_write_lock = 0; 416 return 1; 417 } 418 419 static int bio_read(BIO *bio, char *buf, int size_) { 420 size_t size = size_; 421 size_t rest; 422 struct bio_bio_st *b, *peer_b; 423 424 BIO_clear_retry_flags(bio); 425 426 if (!bio->init) { 427 return 0; 428 } 429 430 b = bio->ptr; 431 assert(b != NULL); 432 assert(b->peer != NULL); 433 peer_b = b->peer->ptr; 434 assert(peer_b != NULL); 435 assert(peer_b->buf != NULL); 436 437 peer_b->request = 0; /* will be set in "retry_read" situation */ 438 439 if (buf == NULL || size == 0 || peer_b->zero_copy_read_lock) { 440 return 0; 441 } 442 443 if (peer_b->len == 0) { 444 if (peer_b->closed) { 445 return 0; /* writer has closed, and no data is left */ 446 } else { 447 BIO_set_retry_read(bio); /* buffer is empty */ 448 if (size <= peer_b->size) { 449 peer_b->request = size; 450 } else { 451 /* don't ask for more than the peer can 452 * deliver in one write */ 453 peer_b->request = peer_b->size; 454 } 455 return -1; 456 } 457 } 458 459 /* we can read */ 460 if (peer_b->len < size) { 461 size = peer_b->len; 462 } 463 464 /* now read "size" bytes */ 465 rest = size; 466 467 assert(rest > 0); 468 /* one or two iterations */ 469 do { 470 size_t chunk; 471 472 assert(rest <= peer_b->len); 473 if (peer_b->offset + rest <= peer_b->size) { 474 chunk = rest; 475 } else { 476 /* wrap around ring buffer */ 477 chunk = peer_b->size - peer_b->offset; 478 } 479 assert(peer_b->offset + chunk <= peer_b->size); 480 481 memcpy(buf, peer_b->buf + peer_b->offset, chunk); 482 483 peer_b->len -= chunk; 484 /* If zero_copy_write_lock == 1 we must advance the offset even if buffer 485 * becomes empty, to make sure write_offset = (offset + len) % size 486 * does not change. */ 487 if (peer_b->len || peer_b->zero_copy_write_lock) { 488 peer_b->offset += chunk; 489 assert(peer_b->offset <= peer_b->size); 490 if (peer_b->offset == peer_b->size) { 491 peer_b->offset = 0; 492 } 493 buf += chunk; 494 } else { 495 /* buffer now empty, no need to advance "buf" */ 496 assert(chunk == rest); 497 peer_b->offset = 0; 498 } 499 rest -= chunk; 500 } while (rest); 501 502 return size; 503 } 504 505 static int bio_write(BIO *bio, const char *buf, int num_) { 506 size_t num = num_; 507 size_t rest; 508 struct bio_bio_st *b; 509 510 BIO_clear_retry_flags(bio); 511 512 if (!bio->init || buf == NULL || num == 0) { 513 return 0; 514 } 515 516 b = bio->ptr; 517 assert(b != NULL); 518 assert(b->peer != NULL); 519 assert(b->buf != NULL); 520 521 if (b->zero_copy_write_lock) { 522 return 0; 523 } 524 525 b->request = 0; 526 if (b->closed) { 527 /* we already closed */ 528 OPENSSL_PUT_ERROR(BIO, bio_write, BIO_R_BROKEN_PIPE); 529 return -1; 530 } 531 532 assert(b->len <= b->size); 533 534 if (b->len == b->size) { 535 BIO_set_retry_write(bio); /* buffer is full */ 536 return -1; 537 } 538 539 /* we can write */ 540 if (num > b->size - b->len) { 541 num = b->size - b->len; 542 } 543 544 /* now write "num" bytes */ 545 rest = num; 546 547 assert(rest > 0); 548 /* one or two iterations */ 549 do { 550 size_t write_offset; 551 size_t chunk; 552 553 assert(b->len + rest <= b->size); 554 555 write_offset = b->offset + b->len; 556 if (write_offset >= b->size) { 557 write_offset -= b->size; 558 } 559 /* b->buf[write_offset] is the first byte we can write to. */ 560 561 if (write_offset + rest <= b->size) { 562 chunk = rest; 563 } else { 564 /* wrap around ring buffer */ 565 chunk = b->size - write_offset; 566 } 567 568 memcpy(b->buf + write_offset, buf, chunk); 569 570 b->len += chunk; 571 572 assert(b->len <= b->size); 573 574 rest -= chunk; 575 buf += chunk; 576 } while (rest); 577 578 return num; 579 } 580 581 static int bio_make_pair(BIO* bio1, BIO* bio2, 582 size_t writebuf1_len, uint8_t* ext_writebuf1, 583 size_t writebuf2_len, uint8_t* ext_writebuf2) { 584 struct bio_bio_st *b1, *b2; 585 586 assert(bio1 != NULL); 587 assert(bio2 != NULL); 588 589 b1 = bio1->ptr; 590 b2 = bio2->ptr; 591 592 if (b1->peer != NULL || b2->peer != NULL) { 593 OPENSSL_PUT_ERROR(BIO, bio_make_pair, BIO_R_IN_USE); 594 return 0; 595 } 596 597 assert(b1->buf_externally_allocated == 0); 598 assert(b2->buf_externally_allocated == 0); 599 600 if (b1->buf == NULL) { 601 if (writebuf1_len) { 602 b1->size = writebuf1_len; 603 } 604 if (!ext_writebuf1) { 605 b1->buf_externally_allocated = 0; 606 b1->buf = OPENSSL_malloc(b1->size); 607 if (b1->buf == NULL) { 608 OPENSSL_PUT_ERROR(BIO, bio_make_pair, ERR_R_MALLOC_FAILURE); 609 return 0; 610 } 611 } else { 612 b1->buf = ext_writebuf1; 613 b1->buf_externally_allocated = 1; 614 } 615 b1->len = 0; 616 b1->offset = 0; 617 } 618 619 if (b2->buf == NULL) { 620 if (writebuf2_len) { 621 b2->size = writebuf2_len; 622 } 623 if (!ext_writebuf2) { 624 b2->buf_externally_allocated = 0; 625 b2->buf = OPENSSL_malloc(b2->size); 626 if (b2->buf == NULL) { 627 OPENSSL_PUT_ERROR(BIO, bio_make_pair, ERR_R_MALLOC_FAILURE); 628 return 0; 629 } 630 } else { 631 b2->buf = ext_writebuf2; 632 b2->buf_externally_allocated = 1; 633 } 634 b2->len = 0; 635 b2->offset = 0; 636 } 637 638 b1->peer = bio2; 639 b1->closed = 0; 640 b1->request = 0; 641 b1->zero_copy_read_lock = 0; 642 b1->zero_copy_write_lock = 0; 643 b2->peer = bio1; 644 b2->closed = 0; 645 b2->request = 0; 646 b2->zero_copy_read_lock = 0; 647 b2->zero_copy_write_lock = 0; 648 649 bio1->init = 1; 650 bio2->init = 1; 651 652 return 1; 653 } 654 655 static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) { 656 long ret; 657 struct bio_bio_st *b = bio->ptr; 658 659 assert(b != NULL); 660 661 switch (cmd) { 662 /* specific CTRL codes */ 663 664 case BIO_C_GET_WRITE_BUF_SIZE: 665 ret = (long)b->size; 666 break; 667 668 case BIO_C_GET_WRITE_GUARANTEE: 669 /* How many bytes can the caller feed to the next write 670 * without having to keep any? */ 671 if (b->peer == NULL || b->closed) { 672 ret = 0; 673 } else { 674 ret = (long)b->size - b->len; 675 } 676 break; 677 678 case BIO_C_GET_READ_REQUEST: 679 /* If the peer unsuccessfully tried to read, how many bytes 680 * were requested? (As with BIO_CTRL_PENDING, that number 681 * can usually be treated as boolean.) */ 682 ret = (long)b->request; 683 break; 684 685 case BIO_C_RESET_READ_REQUEST: 686 /* Reset request. (Can be useful after read attempts 687 * at the other side that are meant to be non-blocking, 688 * e.g. when probing SSL_read to see if any data is 689 * available.) */ 690 b->request = 0; 691 ret = 1; 692 break; 693 694 case BIO_C_SHUTDOWN_WR: 695 /* similar to shutdown(..., SHUT_WR) */ 696 b->closed = 1; 697 ret = 1; 698 break; 699 700 /* standard CTRL codes follow */ 701 702 case BIO_CTRL_GET_CLOSE: 703 ret = bio->shutdown; 704 break; 705 706 case BIO_CTRL_SET_CLOSE: 707 bio->shutdown = (int)num; 708 ret = 1; 709 break; 710 711 case BIO_CTRL_PENDING: 712 if (b->peer != NULL) { 713 struct bio_bio_st *peer_b = b->peer->ptr; 714 ret = (long)peer_b->len; 715 } else { 716 ret = 0; 717 } 718 break; 719 720 case BIO_CTRL_WPENDING: 721 ret = 0; 722 if (b->buf != NULL) { 723 ret = (long)b->len; 724 } 725 break; 726 727 case BIO_CTRL_FLUSH: 728 ret = 1; 729 break; 730 731 case BIO_CTRL_EOF: { 732 BIO *other_bio = ptr; 733 734 if (other_bio) { 735 struct bio_bio_st *other_b = other_bio->ptr; 736 assert(other_b != NULL); 737 ret = other_b->len == 0 && other_b->closed; 738 } else { 739 ret = 1; 740 } 741 } break; 742 743 default: 744 ret = 0; 745 } 746 return ret; 747 } 748 749 static int bio_puts(BIO *bio, const char *str) { 750 return bio_write(bio, str, strlen(str)); 751 } 752 753 static const BIO_METHOD methods_biop = { 754 BIO_TYPE_BIO, "BIO pair", bio_write, bio_read, 755 bio_puts, NULL /* no bio_gets */, bio_ctrl, bio_new, 756 bio_free, NULL /* no bio_callback_ctrl */ 757 }; 758 759 const BIO_METHOD *bio_s_bio(void) { return &methods_biop; } 760 761 int BIO_new_bio_pair(BIO** bio1_p, size_t writebuf1, 762 BIO** bio2_p, size_t writebuf2) { 763 return BIO_new_bio_pair_external_buf(bio1_p, writebuf1, NULL, bio2_p, 764 writebuf2, NULL); 765 } 766 767 int BIO_new_bio_pair_external_buf(BIO** bio1_p, size_t writebuf1_len, 768 uint8_t* ext_writebuf1, 769 BIO** bio2_p, size_t writebuf2_len, 770 uint8_t* ext_writebuf2) { 771 BIO *bio1 = NULL, *bio2 = NULL; 772 int ret = 0; 773 774 /* External buffers must have sizes greater than 0. */ 775 if ((ext_writebuf1 && !writebuf1_len) || (ext_writebuf2 && !writebuf2_len)) { 776 goto err; 777 } 778 779 bio1 = BIO_new(bio_s_bio()); 780 if (bio1 == NULL) { 781 goto err; 782 } 783 bio2 = BIO_new(bio_s_bio()); 784 if (bio2 == NULL) { 785 goto err; 786 } 787 788 if (!bio_make_pair(bio1, bio2, writebuf1_len, ext_writebuf1, writebuf2_len, 789 ext_writebuf2)) { 790 goto err; 791 } 792 ret = 1; 793 794 err: 795 if (ret == 0) { 796 BIO_free(bio1); 797 bio1 = NULL; 798 BIO_free(bio2); 799 bio2 = NULL; 800 } 801 802 *bio1_p = bio1; 803 *bio2_p = bio2; 804 return ret; 805 } 806 807 size_t BIO_ctrl_get_read_request(BIO *bio) { 808 return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL); 809 } 810 811 size_t BIO_ctrl_get_write_guarantee(BIO *bio) { 812 return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL); 813 } 814 815 int BIO_shutdown_wr(BIO *bio) { 816 return BIO_ctrl(bio, BIO_C_SHUTDOWN_WR, 0, NULL); 817 } 818