25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

818 lines
21 KiB

  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@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@cryptsoft.com). This product includes software written by Tim
  51. * Hudson (tjh@cryptsoft.com). */
  52. #include <openssl/bio.h>
  53. #include <assert.h>
  54. #include <string.h>
  55. #include <openssl/buf.h>
  56. #include <openssl/err.h>
  57. #include <openssl/mem.h>
  58. struct bio_bio_st {
  59. BIO *peer; /* NULL if buf == NULL.
  60. * If peer != NULL, then peer->ptr is also a bio_bio_st,
  61. * and its "peer" member points back to us.
  62. * peer != NULL iff init != 0 in the BIO. */
  63. /* This is for what we write (i.e. reading uses peer's struct): */
  64. int closed; /* valid iff peer != NULL */
  65. size_t len; /* valid iff buf != NULL; 0 if peer == NULL */
  66. size_t offset; /* valid iff buf != NULL; 0 if len == 0 */
  67. size_t size;
  68. uint8_t *buf; /* "size" elements (if != NULL) */
  69. char buf_externally_allocated; /* true iff buf was externally allocated. */
  70. char zero_copy_read_lock; /* true iff a zero copy read operation
  71. * is in progress. */
  72. char zero_copy_write_lock; /* true iff a zero copy write operation
  73. * is in progress. */
  74. size_t request; /* valid iff peer != NULL; 0 if len != 0,
  75. * otherwise set by peer to number of bytes
  76. * it (unsuccessfully) tried to read,
  77. * never more than buffer space (size-len) warrants. */
  78. };
  79. static int bio_new(BIO *bio) {
  80. struct bio_bio_st *b;
  81. b = OPENSSL_malloc(sizeof *b);
  82. if (b == NULL) {
  83. return 0;
  84. }
  85. memset(b, 0, sizeof(struct bio_bio_st));
  86. b->size = 17 * 1024; /* enough for one TLS record (just a default) */
  87. bio->ptr = b;
  88. return 1;
  89. }
  90. static void bio_destroy_pair(BIO *bio) {
  91. struct bio_bio_st *b = bio->ptr;
  92. BIO *peer_bio;
  93. struct bio_bio_st *peer_b;
  94. if (b == NULL) {
  95. return;
  96. }
  97. peer_bio = b->peer;
  98. if (peer_bio == NULL) {
  99. return;
  100. }
  101. peer_b = peer_bio->ptr;
  102. assert(peer_b != NULL);
  103. assert(peer_b->peer == bio);
  104. peer_b->peer = NULL;
  105. peer_bio->init = 0;
  106. assert(peer_b->buf != NULL);
  107. peer_b->len = 0;
  108. peer_b->offset = 0;
  109. b->peer = NULL;
  110. bio->init = 0;
  111. assert(b->buf != NULL);
  112. b->len = 0;
  113. b->offset = 0;
  114. }
  115. static int bio_free(BIO *bio) {
  116. struct bio_bio_st *b;
  117. if (bio == NULL) {
  118. return 0;
  119. }
  120. b = bio->ptr;
  121. assert(b != NULL);
  122. if (b->peer) {
  123. bio_destroy_pair(bio);
  124. }
  125. if (!b->buf_externally_allocated) {
  126. OPENSSL_free(b->buf);
  127. }
  128. OPENSSL_free(b);
  129. return 1;
  130. }
  131. static size_t bio_zero_copy_get_read_buf(struct bio_bio_st* peer_b,
  132. uint8_t** out_read_buf,
  133. size_t* out_buf_offset) {
  134. size_t max_available;
  135. if (peer_b->len > peer_b->size - peer_b->offset) {
  136. /* Only the first half of the ring buffer can be read. */
  137. max_available = peer_b->size - peer_b->offset;
  138. } else {
  139. max_available = peer_b->len;
  140. }
  141. *out_read_buf = peer_b->buf;
  142. *out_buf_offset = peer_b->offset;
  143. return max_available;
  144. }
  145. int BIO_zero_copy_get_read_buf(BIO* bio, uint8_t** out_read_buf,
  146. size_t* out_buf_offset,
  147. size_t* out_available_bytes) {
  148. struct bio_bio_st* b;
  149. struct bio_bio_st* peer_b;
  150. size_t max_available;
  151. *out_available_bytes = 0;
  152. BIO_clear_retry_flags(bio);
  153. if (!bio->init) {
  154. OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf, BIO_R_UNINITIALIZED);
  155. return 0;
  156. }
  157. b = bio->ptr;
  158. if (!b || !b->peer) {
  159. OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf,
  160. BIO_R_UNSUPPORTED_METHOD);
  161. return 0;
  162. }
  163. peer_b = b->peer->ptr;
  164. if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
  165. OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf,
  166. BIO_R_UNSUPPORTED_METHOD);
  167. return 0;
  168. }
  169. if (peer_b->zero_copy_read_lock) {
  170. OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf, BIO_R_INVALID_ARGUMENT);
  171. return 0;
  172. }
  173. peer_b->request = 0; /* Is not used by zero-copy API. */
  174. max_available =
  175. bio_zero_copy_get_read_buf(peer_b, out_read_buf, out_buf_offset);
  176. assert(peer_b->buf != NULL);
  177. if (max_available > 0) {
  178. peer_b->zero_copy_read_lock = 1;
  179. }
  180. *out_available_bytes = max_available;
  181. return 1;
  182. }
  183. int BIO_zero_copy_get_read_buf_done(BIO* bio, size_t bytes_read) {
  184. struct bio_bio_st* b;
  185. struct bio_bio_st* peer_b;
  186. size_t max_available;
  187. size_t dummy_read_offset;
  188. uint8_t* dummy_read_buf;
  189. assert(BIO_get_retry_flags(bio) == 0);
  190. if (!bio->init) {
  191. OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
  192. BIO_R_UNINITIALIZED);
  193. return 0;
  194. }
  195. b = bio->ptr;
  196. if (!b || !b->peer) {
  197. OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
  198. BIO_R_UNSUPPORTED_METHOD);
  199. return 0;
  200. }
  201. peer_b = b->peer->ptr;
  202. if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
  203. OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
  204. BIO_R_UNSUPPORTED_METHOD);
  205. return 0;
  206. }
  207. if (!peer_b->zero_copy_read_lock) {
  208. OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
  209. BIO_R_INVALID_ARGUMENT);
  210. return 0;
  211. }
  212. max_available =
  213. bio_zero_copy_get_read_buf(peer_b, &dummy_read_buf, &dummy_read_offset);
  214. if (bytes_read > max_available) {
  215. OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
  216. BIO_R_INVALID_ARGUMENT);
  217. return 0;
  218. }
  219. peer_b->len -= bytes_read;
  220. assert(peer_b->len >= 0);
  221. assert(peer_b->offset + bytes_read <= peer_b->size);
  222. /* Move read offset. If zero_copy_write_lock == 1 we must advance the
  223. * offset even if buffer becomes empty, to make sure
  224. * write_offset = (offset + len) mod size does not change. */
  225. if (peer_b->offset + bytes_read == peer_b->size ||
  226. (!peer_b->zero_copy_write_lock && peer_b->len == 0)) {
  227. peer_b->offset = 0;
  228. } else {
  229. peer_b->offset += bytes_read;
  230. }
  231. bio->num_read += bytes_read;
  232. peer_b->zero_copy_read_lock = 0;
  233. return 1;
  234. }
  235. static size_t bio_zero_copy_get_write_buf(struct bio_bio_st* b,
  236. uint8_t** out_write_buf,
  237. size_t* out_buf_offset) {
  238. size_t write_offset;
  239. size_t max_available;
  240. assert(b->len <= b->size);
  241. write_offset = b->offset + b->len;
  242. if (write_offset >= b->size) {
  243. /* Only the first half of the ring buffer can be written to. */
  244. write_offset -= b->size;
  245. /* write up to the start of the ring buffer. */
  246. max_available = b->offset - write_offset;
  247. } else {
  248. /* write up to the end the buffer. */
  249. max_available = b->size - write_offset;
  250. }
  251. *out_write_buf = b->buf;
  252. *out_buf_offset = write_offset;
  253. return max_available;
  254. }
  255. int BIO_zero_copy_get_write_buf(BIO* bio, uint8_t** out_write_buf,
  256. size_t* out_buf_offset,
  257. size_t* out_available_bytes) {
  258. struct bio_bio_st* b;
  259. struct bio_bio_st* peer_b;
  260. size_t max_available;
  261. *out_available_bytes = 0;
  262. BIO_clear_retry_flags(bio);
  263. if (!bio->init) {
  264. OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf, BIO_R_UNINITIALIZED);
  265. return 0;
  266. }
  267. b = bio->ptr;
  268. if (!b || !b->buf || !b->peer) {
  269. OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf,
  270. BIO_R_UNSUPPORTED_METHOD);
  271. return 0;
  272. }
  273. peer_b = b->peer->ptr;
  274. if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
  275. OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf,
  276. BIO_R_UNSUPPORTED_METHOD);
  277. return 0;
  278. }
  279. assert(b->buf != NULL);
  280. if (b->zero_copy_write_lock) {
  281. OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf, BIO_R_INVALID_ARGUMENT);
  282. return 0;
  283. }
  284. b->request = 0;
  285. if (b->closed) {
  286. /* Bio is already closed. */
  287. OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf, BIO_R_BROKEN_PIPE);
  288. return 0;
  289. }
  290. max_available = bio_zero_copy_get_write_buf(b, out_write_buf, out_buf_offset);
  291. if (max_available > 0) {
  292. b->zero_copy_write_lock = 1;
  293. }
  294. *out_available_bytes = max_available;
  295. return 1;
  296. }
  297. int BIO_zero_copy_get_write_buf_done(BIO* bio, size_t bytes_written) {
  298. struct bio_bio_st* b;
  299. struct bio_bio_st* peer_b;
  300. size_t rest;
  301. size_t dummy_write_offset;
  302. uint8_t* dummy_write_buf;
  303. if (!bio->init) {
  304. OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
  305. BIO_R_UNINITIALIZED);
  306. return 0;
  307. }
  308. b = bio->ptr;
  309. if (!b || !b->buf || !b->peer) {
  310. OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
  311. BIO_R_UNSUPPORTED_METHOD);
  312. return 0;
  313. }
  314. peer_b = b->peer->ptr;
  315. if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
  316. OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
  317. BIO_R_UNSUPPORTED_METHOD);
  318. return 0;
  319. }
  320. b->request = 0;
  321. if (b->closed) {
  322. /* BIO is already closed. */
  323. OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done, BIO_R_BROKEN_PIPE);
  324. return 0;
  325. }
  326. if (!b->zero_copy_write_lock) {
  327. OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
  328. BIO_R_INVALID_ARGUMENT);
  329. return 0;
  330. }
  331. rest = bio_zero_copy_get_write_buf(b, &dummy_write_buf, &dummy_write_offset);
  332. if (bytes_written > rest) {
  333. OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
  334. BIO_R_INVALID_ARGUMENT);
  335. return 0;
  336. }
  337. bio->num_write += bytes_written;
  338. /* Move write offset. */
  339. b->len += bytes_written;
  340. b->zero_copy_write_lock = 0;
  341. return 1;
  342. }
  343. static int bio_read(BIO *bio, char *buf, int size_) {
  344. size_t size = size_;
  345. size_t rest;
  346. struct bio_bio_st *b, *peer_b;
  347. BIO_clear_retry_flags(bio);
  348. if (!bio->init) {
  349. return 0;
  350. }
  351. b = bio->ptr;
  352. assert(b != NULL);
  353. assert(b->peer != NULL);
  354. peer_b = b->peer->ptr;
  355. assert(peer_b != NULL);
  356. assert(peer_b->buf != NULL);
  357. peer_b->request = 0; /* will be set in "retry_read" situation */
  358. if (buf == NULL || size == 0 || peer_b->zero_copy_read_lock) {
  359. return 0;
  360. }
  361. if (peer_b->len == 0) {
  362. if (peer_b->closed) {
  363. return 0; /* writer has closed, and no data is left */
  364. } else {
  365. BIO_set_retry_read(bio); /* buffer is empty */
  366. if (size <= peer_b->size) {
  367. peer_b->request = size;
  368. } else {
  369. /* don't ask for more than the peer can
  370. * deliver in one write */
  371. peer_b->request = peer_b->size;
  372. }
  373. return -1;
  374. }
  375. }
  376. /* we can read */
  377. if (peer_b->len < size) {
  378. size = peer_b->len;
  379. }
  380. /* now read "size" bytes */
  381. rest = size;
  382. assert(rest > 0);
  383. /* one or two iterations */
  384. do {
  385. size_t chunk;
  386. assert(rest <= peer_b->len);
  387. if (peer_b->offset + rest <= peer_b->size) {
  388. chunk = rest;
  389. } else {
  390. /* wrap around ring buffer */
  391. chunk = peer_b->size - peer_b->offset;
  392. }
  393. assert(peer_b->offset + chunk <= peer_b->size);
  394. memcpy(buf, peer_b->buf + peer_b->offset, chunk);
  395. peer_b->len -= chunk;
  396. /* If zero_copy_write_lock == 1 we must advance the offset even if buffer
  397. * becomes empty, to make sure write_offset = (offset + len) % size
  398. * does not change. */
  399. if (peer_b->len || peer_b->zero_copy_write_lock) {
  400. peer_b->offset += chunk;
  401. assert(peer_b->offset <= peer_b->size);
  402. if (peer_b->offset == peer_b->size) {
  403. peer_b->offset = 0;
  404. }
  405. buf += chunk;
  406. } else {
  407. /* buffer now empty, no need to advance "buf" */
  408. assert(chunk == rest);
  409. peer_b->offset = 0;
  410. }
  411. rest -= chunk;
  412. } while (rest);
  413. return size;
  414. }
  415. static int bio_write(BIO *bio, const char *buf, int num_) {
  416. size_t num = num_;
  417. size_t rest;
  418. struct bio_bio_st *b;
  419. BIO_clear_retry_flags(bio);
  420. if (!bio->init || buf == NULL || num == 0) {
  421. return 0;
  422. }
  423. b = bio->ptr;
  424. assert(b != NULL);
  425. assert(b->peer != NULL);
  426. assert(b->buf != NULL);
  427. if (b->zero_copy_write_lock) {
  428. return 0;
  429. }
  430. b->request = 0;
  431. if (b->closed) {
  432. /* we already closed */
  433. OPENSSL_PUT_ERROR(BIO, bio_write, BIO_R_BROKEN_PIPE);
  434. return -1;
  435. }
  436. assert(b->len <= b->size);
  437. if (b->len == b->size) {
  438. BIO_set_retry_write(bio); /* buffer is full */
  439. return -1;
  440. }
  441. /* we can write */
  442. if (num > b->size - b->len) {
  443. num = b->size - b->len;
  444. }
  445. /* now write "num" bytes */
  446. rest = num;
  447. assert(rest > 0);
  448. /* one or two iterations */
  449. do {
  450. size_t write_offset;
  451. size_t chunk;
  452. assert(b->len + rest <= b->size);
  453. write_offset = b->offset + b->len;
  454. if (write_offset >= b->size) {
  455. write_offset -= b->size;
  456. }
  457. /* b->buf[write_offset] is the first byte we can write to. */
  458. if (write_offset + rest <= b->size) {
  459. chunk = rest;
  460. } else {
  461. /* wrap around ring buffer */
  462. chunk = b->size - write_offset;
  463. }
  464. memcpy(b->buf + write_offset, buf, chunk);
  465. b->len += chunk;
  466. assert(b->len <= b->size);
  467. rest -= chunk;
  468. buf += chunk;
  469. } while (rest);
  470. return num;
  471. }
  472. static int bio_make_pair(BIO* bio1, BIO* bio2,
  473. size_t writebuf1_len, uint8_t* ext_writebuf1,
  474. size_t writebuf2_len, uint8_t* ext_writebuf2) {
  475. struct bio_bio_st *b1, *b2;
  476. assert(bio1 != NULL);
  477. assert(bio2 != NULL);
  478. b1 = bio1->ptr;
  479. b2 = bio2->ptr;
  480. if (b1->peer != NULL || b2->peer != NULL) {
  481. OPENSSL_PUT_ERROR(BIO, bio_make_pair, BIO_R_IN_USE);
  482. return 0;
  483. }
  484. assert(b1->buf_externally_allocated == 0);
  485. assert(b2->buf_externally_allocated == 0);
  486. if (b1->buf == NULL) {
  487. if (writebuf1_len) {
  488. b1->size = writebuf1_len;
  489. }
  490. if (!ext_writebuf1) {
  491. b1->buf_externally_allocated = 0;
  492. b1->buf = OPENSSL_malloc(b1->size);
  493. if (b1->buf == NULL) {
  494. OPENSSL_PUT_ERROR(BIO, bio_make_pair, ERR_R_MALLOC_FAILURE);
  495. return 0;
  496. }
  497. } else {
  498. b1->buf = ext_writebuf1;
  499. b1->buf_externally_allocated = 1;
  500. }
  501. b1->len = 0;
  502. b1->offset = 0;
  503. }
  504. if (b2->buf == NULL) {
  505. if (writebuf2_len) {
  506. b2->size = writebuf2_len;
  507. }
  508. if (!ext_writebuf2) {
  509. b2->buf_externally_allocated = 0;
  510. b2->buf = OPENSSL_malloc(b2->size);
  511. if (b2->buf == NULL) {
  512. OPENSSL_PUT_ERROR(BIO, bio_make_pair, ERR_R_MALLOC_FAILURE);
  513. return 0;
  514. }
  515. } else {
  516. b2->buf = ext_writebuf2;
  517. b2->buf_externally_allocated = 1;
  518. }
  519. b2->len = 0;
  520. b2->offset = 0;
  521. }
  522. b1->peer = bio2;
  523. b1->closed = 0;
  524. b1->request = 0;
  525. b1->zero_copy_read_lock = 0;
  526. b1->zero_copy_write_lock = 0;
  527. b2->peer = bio1;
  528. b2->closed = 0;
  529. b2->request = 0;
  530. b2->zero_copy_read_lock = 0;
  531. b2->zero_copy_write_lock = 0;
  532. bio1->init = 1;
  533. bio2->init = 1;
  534. return 1;
  535. }
  536. static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) {
  537. long ret;
  538. struct bio_bio_st *b = bio->ptr;
  539. assert(b != NULL);
  540. switch (cmd) {
  541. /* specific CTRL codes */
  542. case BIO_C_GET_WRITE_BUF_SIZE:
  543. ret = (long)b->size;
  544. break;
  545. case BIO_C_GET_WRITE_GUARANTEE:
  546. /* How many bytes can the caller feed to the next write
  547. * without having to keep any? */
  548. if (b->peer == NULL || b->closed) {
  549. ret = 0;
  550. } else {
  551. ret = (long)b->size - b->len;
  552. }
  553. break;
  554. case BIO_C_GET_READ_REQUEST:
  555. /* If the peer unsuccessfully tried to read, how many bytes
  556. * were requested? (As with BIO_CTRL_PENDING, that number
  557. * can usually be treated as boolean.) */
  558. ret = (long)b->request;
  559. break;
  560. case BIO_C_RESET_READ_REQUEST:
  561. /* Reset request. (Can be useful after read attempts
  562. * at the other side that are meant to be non-blocking,
  563. * e.g. when probing SSL_read to see if any data is
  564. * available.) */
  565. b->request = 0;
  566. ret = 1;
  567. break;
  568. case BIO_C_SHUTDOWN_WR:
  569. /* similar to shutdown(..., SHUT_WR) */
  570. b->closed = 1;
  571. ret = 1;
  572. break;
  573. /* standard CTRL codes follow */
  574. case BIO_CTRL_GET_CLOSE:
  575. ret = bio->shutdown;
  576. break;
  577. case BIO_CTRL_SET_CLOSE:
  578. bio->shutdown = (int)num;
  579. ret = 1;
  580. break;
  581. case BIO_CTRL_PENDING:
  582. if (b->peer != NULL) {
  583. struct bio_bio_st *peer_b = b->peer->ptr;
  584. ret = (long)peer_b->len;
  585. } else {
  586. ret = 0;
  587. }
  588. break;
  589. case BIO_CTRL_WPENDING:
  590. ret = 0;
  591. if (b->buf != NULL) {
  592. ret = (long)b->len;
  593. }
  594. break;
  595. case BIO_CTRL_FLUSH:
  596. ret = 1;
  597. break;
  598. case BIO_CTRL_EOF: {
  599. BIO *other_bio = ptr;
  600. if (other_bio) {
  601. struct bio_bio_st *other_b = other_bio->ptr;
  602. assert(other_b != NULL);
  603. ret = other_b->len == 0 && other_b->closed;
  604. } else {
  605. ret = 1;
  606. }
  607. } break;
  608. default:
  609. ret = 0;
  610. }
  611. return ret;
  612. }
  613. static int bio_puts(BIO *bio, const char *str) {
  614. return bio_write(bio, str, strlen(str));
  615. }
  616. static const BIO_METHOD methods_biop = {
  617. BIO_TYPE_BIO, "BIO pair", bio_write, bio_read,
  618. bio_puts, NULL /* no bio_gets */, bio_ctrl, bio_new,
  619. bio_free, NULL /* no bio_callback_ctrl */
  620. };
  621. const BIO_METHOD *bio_s_bio(void) { return &methods_biop; }
  622. int BIO_new_bio_pair(BIO** bio1_p, size_t writebuf1,
  623. BIO** bio2_p, size_t writebuf2) {
  624. return BIO_new_bio_pair_external_buf(bio1_p, writebuf1, NULL, bio2_p,
  625. writebuf2, NULL);
  626. }
  627. int BIO_new_bio_pair_external_buf(BIO** bio1_p, size_t writebuf1_len,
  628. uint8_t* ext_writebuf1,
  629. BIO** bio2_p, size_t writebuf2_len,
  630. uint8_t* ext_writebuf2) {
  631. BIO *bio1 = NULL, *bio2 = NULL;
  632. int ret = 0;
  633. /* External buffers must have sizes greater than 0. */
  634. if ((ext_writebuf1 && !writebuf1_len) || (ext_writebuf2 && !writebuf2_len)) {
  635. goto err;
  636. }
  637. bio1 = BIO_new(bio_s_bio());
  638. if (bio1 == NULL) {
  639. goto err;
  640. }
  641. bio2 = BIO_new(bio_s_bio());
  642. if (bio2 == NULL) {
  643. goto err;
  644. }
  645. if (!bio_make_pair(bio1, bio2, writebuf1_len, ext_writebuf1, writebuf2_len,
  646. ext_writebuf2)) {
  647. goto err;
  648. }
  649. ret = 1;
  650. err:
  651. if (ret == 0) {
  652. BIO_free(bio1);
  653. bio1 = NULL;
  654. BIO_free(bio2);
  655. bio2 = NULL;
  656. }
  657. *bio1_p = bio1;
  658. *bio2_p = bio2;
  659. return ret;
  660. }
  661. size_t BIO_ctrl_get_read_request(BIO *bio) {
  662. return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
  663. }
  664. size_t BIO_ctrl_get_write_guarantee(BIO *bio) {
  665. return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
  666. }
  667. int BIO_shutdown_wr(BIO *bio) {
  668. return BIO_ctrl(bio, BIO_C_SHUTDOWN_WR, 0, NULL);
  669. }