You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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