]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/bio/bss_bio.c
mark all block comments that need format preserving so that
[thirdparty/openssl.git] / crypto / bio / bss_bio.c
CommitLineData
9e06f6f6 1/* crypto/bio/bss_bio.c -*- Mode: C; c-file-style: "eay" -*- */
3aa8d3a7
BM
2/* ====================================================================
3 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@openssl.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
9e06f6f6 55
9e06f6f6 56/* Special method for a BIO where the other endpoint is also a BIO
95d29597
BM
57 * of this kind, handled by the same thread (i.e. the "peer" is actually
58 * ourselves, wearing a different hat).
9e06f6f6 59 * Such "BIO pairs" are mainly for using the SSL library with I/O interfaces
95d29597
BM
60 * for which no specific BIO method is available.
61 * See ssl/ssltest.c for some hints on how this can be used. */
9e06f6f6 62
60e5f36d
BM
63/* BIO_DEBUG implies BIO_PAIR_DEBUG */
64#ifdef BIO_DEBUG
65# ifndef BIO_PAIR_DEBUG
66# define BIO_PAIR_DEBUG
67# endif
68#endif
69
70/* disable assert() unless BIO_PAIR_DEBUG has been defined */
e334d78b 71#ifndef BIO_PAIR_DEBUG
60e5f36d
BM
72# ifndef NDEBUG
73# define NDEBUG
74# endif
e334d78b
BM
75#endif
76
9e06f6f6 77#include <assert.h>
c1082a90 78#include <limits.h>
9e06f6f6 79#include <stdlib.h>
d58d092b 80#include <string.h>
9e06f6f6
BM
81
82#include <openssl/bio.h>
83#include <openssl/err.h>
84#include <openssl/crypto.h>
85
41d2a336 86#include "e_os.h"
3e83e686
RL
87
88/* VxWorks defines SSIZE_MAX with an empty value causing compile errors */
6a89a25c 89#if defined(OPENSSL_SYS_VXWORKS)
3e83e686
RL
90# undef SSIZE_MAX
91#endif
4991d07c
BM
92#ifndef SSIZE_MAX
93# define SSIZE_MAX INT_MAX
94#endif
95
9e06f6f6
BM
96static int bio_new(BIO *bio);
97static int bio_free(BIO *bio);
98static int bio_read(BIO *bio, char *buf, int size);
0e1c0612 99static int bio_write(BIO *bio, const char *buf, int num);
95d29597 100static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr);
0e1c0612 101static int bio_puts(BIO *bio, const char *str);
9e06f6f6
BM
102
103static int bio_make_pair(BIO *bio1, BIO *bio2);
104static void bio_destroy_pair(BIO *bio);
105
106static BIO_METHOD methods_biop =
107{
108 BIO_TYPE_BIO,
109 "BIO pair",
110 bio_write,
111 bio_read,
112 bio_puts,
113 NULL /* no bio_gets */,
114 bio_ctrl,
115 bio_new,
d3442bc7
RL
116 bio_free,
117 NULL /* no bio_callback_ctrl */
9e06f6f6
BM
118};
119
120BIO_METHOD *BIO_s_bio(void)
121 {
122 return &methods_biop;
123 }
124
125struct bio_bio_st
126{
127 BIO *peer; /* NULL if buf == NULL.
c035b0c3
BM
128 * If peer != NULL, then peer->ptr is also a bio_bio_st,
129 * and its "peer" member points back to us.
130 * peer != NULL iff init != 0 in the BIO. */
9e06f6f6
BM
131
132 /* This is for what we write (i.e. reading uses peer's struct): */
c035b0c3
BM
133 int closed; /* valid iff peer != NULL */
134 size_t len; /* valid iff buf != NULL; 0 if peer == NULL */
135 size_t offset; /* valid iff buf != NULL; 0 if len == 0 */
9e06f6f6 136 size_t size;
c035b0c3
BM
137 char *buf; /* "size" elements (if != NULL) */
138
316d5cdc 139 size_t request; /* valid iff peer != NULL; 0 if len != 0,
c035b0c3 140 * otherwise set by peer to number of bytes
657e60fa 141 * it (unsuccessfully) tried to read,
316d5cdc 142 * never more than buffer space (size-len) warrants. */
9e06f6f6
BM
143};
144
145static int bio_new(BIO *bio)
146 {
147 struct bio_bio_st *b;
148
26a3a48d 149 b = OPENSSL_malloc(sizeof *b);
9e06f6f6
BM
150 if (b == NULL)
151 return 0;
152
153 b->peer = NULL;
154 b->size = 17*1024; /* enough for one TLS record (just a default) */
155 b->buf = NULL;
156
95d29597 157 bio->ptr = b;
9e06f6f6
BM
158 return 1;
159 }
160
161
162static int bio_free(BIO *bio)
163 {
164 struct bio_bio_st *b;
165
166 if (bio == NULL)
167 return 0;
168 b = bio->ptr;
169
170 assert(b != NULL);
171
172 if (b->peer)
173 bio_destroy_pair(bio);
174
175 if (b->buf != NULL)
176 {
26a3a48d 177 OPENSSL_free(b->buf);
9e06f6f6
BM
178 }
179
26a3a48d 180 OPENSSL_free(b);
9e06f6f6
BM
181
182 return 1;
183 }
184
185
186
95d29597 187static int bio_read(BIO *bio, char *buf, int size_)
9e06f6f6 188 {
95d29597
BM
189 size_t size = size_;
190 size_t rest;
191 struct bio_bio_st *b, *peer_b;
192
193 BIO_clear_retry_flags(bio);
194
195 if (!bio->init)
196 return 0;
197
198 b = bio->ptr;
199 assert(b != NULL);
200 assert(b->peer != NULL);
201 peer_b = b->peer->ptr;
202 assert(peer_b != NULL);
203 assert(peer_b->buf != NULL);
204
205 peer_b->request = 0; /* will be set in "retry_read" situation */
206
207 if (buf == NULL || size == 0)
208 return 0;
209
210 if (peer_b->len == 0)
211 {
212 if (peer_b->closed)
213 return 0; /* writer has closed, and no data is left */
214 else
215 {
216 BIO_set_retry_read(bio); /* buffer is empty */
217 if (size <= peer_b->size)
218 peer_b->request = size;
219 else
99187624
BM
220 /* don't ask for more than the peer can
221 * deliver in one write */
222 peer_b->request = peer_b->size;
95d29597
BM
223 return -1;
224 }
225 }
226
227 /* we can read */
228 if (peer_b->len < size)
229 size = peer_b->len;
230
231 /* now read "size" bytes */
232
233 rest = size;
234
235 assert(rest > 0);
236 do /* one or two iterations */
237 {
238 size_t chunk;
239
240 assert(rest <= peer_b->len);
241 if (peer_b->offset + rest <= peer_b->size)
242 chunk = rest;
243 else
244 /* wrap around ring buffer */
245 chunk = peer_b->size - peer_b->offset;
246 assert(peer_b->offset + chunk <= peer_b->size);
247
248 memcpy(buf, peer_b->buf + peer_b->offset, chunk);
249
250 peer_b->len -= chunk;
251 if (peer_b->len)
252 {
253 peer_b->offset += chunk;
254 assert(peer_b->offset <= peer_b->size);
255 if (peer_b->offset == peer_b->size)
256 peer_b->offset = 0;
257 buf += chunk;
258 }
259 else
260 {
261 /* buffer now empty, no need to advance "buf" */
262 assert(chunk == rest);
263 peer_b->offset = 0;
264 }
265 rest -= chunk;
266 }
267 while (rest);
268
95d29597 269 return size;
9e06f6f6
BM
270 }
271
3e9a08ec
TH
272/*-
273 * non-copying interface: provide pointer to available data in buffer
c1082a90
BM
274 * bio_nread0: return number of available bytes
275 * bio_nread: also advance index
276 * (example usage: bio_nread0(), read from buffer, bio_nread()
277 * or just bio_nread(), read from buffer)
278 */
6f7af152
BM
279/* WARNING: The non-copying interface is largely untested as of yet
280 * and may contain bugs. */
cb70355d 281static ossl_ssize_t bio_nread0(BIO *bio, char **buf)
c1082a90
BM
282 {
283 struct bio_bio_st *b, *peer_b;
cb70355d 284 ossl_ssize_t num;
c1082a90
BM
285
286 BIO_clear_retry_flags(bio);
287
288 if (!bio->init)
289 return 0;
290
291 b = bio->ptr;
292 assert(b != NULL);
293 assert(b->peer != NULL);
294 peer_b = b->peer->ptr;
295 assert(peer_b != NULL);
296 assert(peer_b->buf != NULL);
297
298 peer_b->request = 0;
299
300 if (peer_b->len == 0)
301 {
302 char dummy;
303
304 /* avoid code duplication -- nothing available for reading */
d680ba86 305 return bio_read(bio, &dummy, 1); /* returns 0 or -1 */
c1082a90
BM
306 }
307
308 num = peer_b->len;
309 if (peer_b->size < peer_b->offset + num)
310 /* no ring buffer wrap-around for non-copying interface */
311 num = peer_b->size - peer_b->offset;
312 assert(num > 0);
313
314 if (buf != NULL)
315 *buf = peer_b->buf + peer_b->offset;
316 return num;
317 }
318
cb70355d 319static ossl_ssize_t bio_nread(BIO *bio, char **buf, size_t num_)
c1082a90
BM
320 {
321 struct bio_bio_st *b, *peer_b;
cb70355d 322 ossl_ssize_t num, available;
4991d07c
BM
323
324 if (num_ > SSIZE_MAX)
e65991f9 325 num = SSIZE_MAX;
4991d07c 326 else
cb70355d 327 num = (ossl_ssize_t)num_;
c1082a90
BM
328
329 available = bio_nread0(bio, buf);
330 if (num > available)
331 num = available;
4991d07c 332 if (num <= 0)
c1082a90
BM
333 return num;
334
335 b = bio->ptr;
336 peer_b = b->peer->ptr;
337
338 peer_b->len -= num;
339 if (peer_b->len)
340 {
341 peer_b->offset += num;
342 assert(peer_b->offset <= peer_b->size);
343 if (peer_b->offset == peer_b->size)
344 peer_b->offset = 0;
345 }
346 else
347 peer_b->offset = 0;
348
349 return num;
350 }
351
352
0e1c0612 353static int bio_write(BIO *bio, const char *buf, int num_)
9e06f6f6 354 {
95d29597
BM
355 size_t num = num_;
356 size_t rest;
357 struct bio_bio_st *b;
358
359 BIO_clear_retry_flags(bio);
360
361 if (!bio->init || buf == NULL || num == 0)
362 return 0;
363
364 b = bio->ptr;
365 assert(b != NULL);
366 assert(b->peer != NULL);
367 assert(b->buf != NULL);
368
369 b->request = 0;
370 if (b->closed)
371 {
372 /* we already closed */
373 BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE);
374 return -1;
375 }
376
377 assert(b->len <= b->size);
378
379 if (b->len == b->size)
380 {
381 BIO_set_retry_write(bio); /* buffer is full */
382 return -1;
383 }
384
385 /* we can write */
386 if (num > b->size - b->len)
387 num = b->size - b->len;
388
389 /* now write "num" bytes */
390
391 rest = num;
9e06f6f6 392
95d29597
BM
393 assert(rest > 0);
394 do /* one or two iterations */
395 {
396 size_t write_offset;
397 size_t chunk;
398
399 assert(b->len + rest <= b->size);
400
401 write_offset = b->offset + b->len;
402 if (write_offset >= b->size)
403 write_offset -= b->size;
404 /* b->buf[write_offset] is the first byte we can write to. */
405
406 if (write_offset + rest <= b->size)
407 chunk = rest;
408 else
409 /* wrap around ring buffer */
410 chunk = b->size - write_offset;
411
412 memcpy(b->buf + write_offset, buf, chunk);
413
414 b->len += chunk;
415
416 assert(b->len <= b->size);
417
418 rest -= chunk;
419 buf += chunk;
420 }
421 while (rest);
422
423 return num;
424 }
425
3e9a08ec
TH
426/*-
427 * non-copying interface: provide pointer to region to write to
c1082a90
BM
428 * bio_nwrite0: check how much space is available
429 * bio_nwrite: also increase length
430 * (example usage: bio_nwrite0(), write to buffer, bio_nwrite()
431 * or just bio_nwrite(), write to buffer)
432 */
cb70355d 433static ossl_ssize_t bio_nwrite0(BIO *bio, char **buf)
c1082a90
BM
434 {
435 struct bio_bio_st *b;
436 size_t num;
437 size_t write_offset;
438
439 BIO_clear_retry_flags(bio);
440
441 if (!bio->init)
442 return 0;
443
444 b = bio->ptr;
445 assert(b != NULL);
446 assert(b->peer != NULL);
447 assert(b->buf != NULL);
448
449 b->request = 0;
450 if (b->closed)
451 {
452 BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE);
453 return -1;
454 }
455
456 assert(b->len <= b->size);
457
458 if (b->len == b->size)
459 {
460 BIO_set_retry_write(bio);
461 return -1;
462 }
463
464 num = b->size - b->len;
465 write_offset = b->offset + b->len;
466 if (write_offset >= b->size)
467 write_offset -= b->size;
468 if (write_offset + num > b->size)
469 /* no ring buffer wrap-around for non-copying interface
f50c0497 470 * (to fulfil the promise by BIO_ctrl_get_write_guarantee,
c1082a90
BM
471 * BIO_nwrite may have to be called twice) */
472 num = b->size - write_offset;
473
474 if (buf != NULL)
475 *buf = b->buf + write_offset;
476 assert(write_offset + num <= b->size);
477
478 return num;
479 }
480
cb70355d 481static ossl_ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_)
c1082a90 482 {
5671876d 483 struct bio_bio_st *b;
cb70355d 484 ossl_ssize_t num, space;
4991d07c
BM
485
486 if (num_ > SSIZE_MAX)
487 num = SSIZE_MAX;
488 else
cb70355d 489 num = (ossl_ssize_t)num_;
c1082a90
BM
490
491 space = bio_nwrite0(bio, buf);
492 if (num > space)
493 num = space;
4991d07c 494 if (num <= 0)
c1082a90 495 return num;
5671876d
BM
496 b = bio->ptr;
497 assert(b != NULL);
c1082a90
BM
498 b->len += num;
499 assert(b->len <= b->size);
500
501 return num;
502 }
503
95d29597
BM
504
505static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
9e06f6f6
BM
506 {
507 long ret;
508 struct bio_bio_st *b = bio->ptr;
509
510 assert(b != NULL);
511
512 switch (cmd)
513 {
95d29597
BM
514 /* specific CTRL codes */
515
516 case BIO_C_SET_WRITE_BUF_SIZE:
517 if (b->peer)
518 {
519 BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE);
520 ret = 0;
521 }
6c82fda2
BM
522 else if (num == 0)
523 {
524 BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT);
525 ret = 0;
526 }
95d29597
BM
527 else
528 {
529 size_t new_size = num;
530
531 if (b->size != new_size)
532 {
533 if (b->buf)
534 {
26a3a48d 535 OPENSSL_free(b->buf);
95d29597
BM
536 b->buf = NULL;
537 }
538 b->size = new_size;
539 }
540 ret = 1;
541 }
542 break;
543
544 case BIO_C_GET_WRITE_BUF_SIZE:
54fbc77d
LJ
545 ret = (long) b->size;
546 break;
95d29597
BM
547
548 case BIO_C_MAKE_BIO_PAIR:
549 {
550 BIO *other_bio = ptr;
551
552 if (bio_make_pair(bio, other_bio))
553 ret = 1;
554 else
555 ret = 0;
556 }
557 break;
558
559 case BIO_C_DESTROY_BIO_PAIR:
3aa8d3a7 560 /* Affects both BIOs in the pair -- call just once!
95d29597
BM
561 * Or let BIO_free(bio1); BIO_free(bio2); do the job. */
562 bio_destroy_pair(bio);
563 ret = 1;
564 break;
565
566 case BIO_C_GET_WRITE_GUARANTEE:
567 /* How many bytes can the caller feed to the next write
657e60fa 568 * without having to keep any? */
95d29597
BM
569 if (b->peer == NULL || b->closed)
570 ret = 0;
571 else
572 ret = (long) b->size - b->len;
573 break;
574
575 case BIO_C_GET_READ_REQUEST:
657e60fa 576 /* If the peer unsuccessfully tried to read, how many bytes
95d29597
BM
577 * were requested? (As with BIO_CTRL_PENDING, that number
578 * can usually be treated as boolean.) */
579 ret = (long) b->request;
580 break;
581
e405b8d1
BM
582 case BIO_C_RESET_READ_REQUEST:
583 /* Reset request. (Can be useful after read attempts
584 * at the other side that are meant to be non-blocking,
585 * e.g. when probing SSL_read to see if any data is
586 * available.) */
587 b->request = 0;
588 ret = 1;
589 break;
590
95d29597
BM
591 case BIO_C_SHUTDOWN_WR:
592 /* similar to shutdown(..., SHUT_WR) */
593 b->closed = 1;
594 ret = 1;
595 break;
596
4991d07c
BM
597 case BIO_C_NREAD0:
598 /* prepare for non-copying read */
599 ret = (long) bio_nread0(bio, ptr);
600 break;
601
c1082a90
BM
602 case BIO_C_NREAD:
603 /* non-copying read */
604 ret = (long) bio_nread(bio, ptr, (size_t) num);
605 break;
606
607 case BIO_C_NWRITE0:
608 /* prepare for non-copying write */
609 ret = (long) bio_nwrite0(bio, ptr);
610 break;
611
612 case BIO_C_NWRITE:
613 /* non-copying write */
614 ret = (long) bio_nwrite(bio, ptr, (size_t) num);
615 break;
616
95d29597
BM
617
618 /* standard CTRL codes follow */
9e06f6f6
BM
619
620 case BIO_CTRL_RESET:
621 if (b->buf != NULL)
622 {
623 b->len = 0;
624 b->offset = 0;
625 }
626 ret = 0;
627 break;
628
629 case BIO_CTRL_GET_CLOSE:
630 ret = bio->shutdown;
631 break;
632
633 case BIO_CTRL_SET_CLOSE:
634 bio->shutdown = (int) num;
635 ret = 1;
636 break;
637
638 case BIO_CTRL_PENDING:
639 if (b->peer != NULL)
640 {
7eea36bb 641 struct bio_bio_st *peer_b = b->peer->ptr;
9e06f6f6
BM
642
643 ret = (long) peer_b->len;
644 }
645 else
646 ret = 0;
647 break;
648
649 case BIO_CTRL_WPENDING:
650 if (b->buf != NULL)
651 ret = (long) b->len;
652 else
653 ret = 0;
654 break;
655
656 case BIO_CTRL_DUP:
95d29597
BM
657 /* See BIO_dup_chain for circumstances we have to expect. */
658 {
659 BIO *other_bio = ptr;
660 struct bio_bio_st *other_b;
661
662 assert(other_bio != NULL);
663 other_b = other_bio->ptr;
664 assert(other_b != NULL);
665
666 assert(other_b->buf == NULL); /* other_bio is always fresh */
667
668 other_b->size = b->size;
669 }
670
c035b0c3
BM
671 ret = 1;
672 break;
9e06f6f6
BM
673
674 case BIO_CTRL_FLUSH:
675 ret = 1;
676 break;
677
95d29597
BM
678 case BIO_CTRL_EOF:
679 {
680 BIO *other_bio = ptr;
681
682 if (other_bio)
683 {
684 struct bio_bio_st *other_b = other_bio->ptr;
685
686 assert(other_b != NULL);
687 ret = other_b->len == 0 && other_b->closed;
688 }
689 else
690 ret = 1;
691 }
692 break;
693
9e06f6f6
BM
694 default:
695 ret = 0;
696 }
697 return ret;
698 }
699
0e1c0612 700static int bio_puts(BIO *bio, const char *str)
9e06f6f6
BM
701 {
702 return bio_write(bio, str, strlen(str));
703 }
704
9e06f6f6
BM
705
706static int bio_make_pair(BIO *bio1, BIO *bio2)
707 {
708 struct bio_bio_st *b1, *b2;
709
710 assert(bio1 != NULL);
711 assert(bio2 != NULL);
712
713 b1 = bio1->ptr;
714 b2 = bio2->ptr;
715
716 if (b1->peer != NULL || b2->peer != NULL)
717 {
718 BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE);
719 return 0;
720 }
721
1aad3392 722 if (b1->buf == NULL)
9e06f6f6 723 {
26a3a48d 724 b1->buf = OPENSSL_malloc(b1->size);
9e06f6f6
BM
725 if (b1->buf == NULL)
726 {
727 BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
728 return 0;
729 }
730 b1->len = 0;
731 b1->offset = 0;
732 }
733
1aad3392 734 if (b2->buf == NULL)
9e06f6f6 735 {
26a3a48d 736 b2->buf = OPENSSL_malloc(b2->size);
9e06f6f6
BM
737 if (b2->buf == NULL)
738 {
739 BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
740 return 0;
741 }
742 b2->len = 0;
743 b2->offset = 0;
744 }
745
746 b1->peer = bio2;
c035b0c3
BM
747 b1->closed = 0;
748 b1->request = 0;
9e06f6f6 749 b2->peer = bio1;
c035b0c3
BM
750 b2->closed = 0;
751 b2->request = 0;
9e06f6f6 752
3928b6bf
BM
753 bio1->init = 1;
754 bio2->init = 1;
755
9e06f6f6
BM
756 return 1;
757 }
758
759static void bio_destroy_pair(BIO *bio)
760 {
761 struct bio_bio_st *b = bio->ptr;
762
763 if (b != NULL)
764 {
765 BIO *peer_bio = b->peer;
766
767 if (peer_bio != NULL)
768 {
769 struct bio_bio_st *peer_b = peer_bio->ptr;
770
771 assert(peer_b != NULL);
772 assert(peer_b->peer == bio);
773
774 peer_b->peer = NULL;
775 peer_bio->init = 0;
776 assert(peer_b->buf != NULL);
777 peer_b->len = 0;
778 peer_b->offset = 0;
779
780 b->peer = NULL;
781 bio->init = 0;
782 assert(b->buf != NULL);
783 b->len = 0;
784 b->offset = 0;
785 }
786 }
787 }
95d29597
BM
788
789
790/* Exported convenience functions */
791int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1,
792 BIO **bio2_p, size_t writebuf2)
793 {
794 BIO *bio1 = NULL, *bio2 = NULL;
795 long r;
796 int ret = 0;
797
798 bio1 = BIO_new(BIO_s_bio());
799 if (bio1 == NULL)
800 goto err;
801 bio2 = BIO_new(BIO_s_bio());
802 if (bio2 == NULL)
803 goto err;
804
805 if (writebuf1)
806 {
807 r = BIO_set_write_buf_size(bio1, writebuf1);
808 if (!r)
809 goto err;
810 }
811 if (writebuf2)
812 {
813 r = BIO_set_write_buf_size(bio2, writebuf2);
814 if (!r)
815 goto err;
816 }
817
818 r = BIO_make_bio_pair(bio1, bio2);
819 if (!r)
820 goto err;
821 ret = 1;
822
823 err:
824 if (ret == 0)
825 {
826 if (bio1)
827 {
828 BIO_free(bio1);
829 bio1 = NULL;
830 }
831 if (bio2)
832 {
833 BIO_free(bio2);
834 bio2 = NULL;
835 }
836 }
837
838 *bio1_p = bio1;
839 *bio2_p = bio2;
840 return ret;
841 }
842
843size_t BIO_ctrl_get_write_guarantee(BIO *bio)
99187624 844 {
95d29597
BM
845 return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
846 }
847
2de62540 848size_t BIO_ctrl_get_read_request(BIO *bio)
99187624 849 {
95d29597
BM
850 return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
851 }
c1082a90 852
e405b8d1
BM
853int BIO_ctrl_reset_read_request(BIO *bio)
854 {
855 return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0);
856 }
857
c1082a90 858
657e60fa 859/* BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now
c1082a90
BM
860 * (conceivably some other BIOs could allow non-copying reads and writes too.)
861 */
862int BIO_nread0(BIO *bio, char **buf)
863 {
864 long ret;
865
866 if (!bio->init)
867 {
868 BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED);
869 return -2;
870 }
871
872 ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf);
873 if (ret > INT_MAX)
874 return INT_MAX;
875 else
876 return (int) ret;
877 }
878
879int BIO_nread(BIO *bio, char **buf, int num)
880 {
881 int ret;
882
883 if (!bio->init)
884 {
885 BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED);
886 return -2;
887 }
888
889 ret = (int) BIO_ctrl(bio, BIO_C_NREAD, num, buf);
890 if (ret > 0)
891 bio->num_read += ret;
892 return ret;
893 }
894
895int BIO_nwrite0(BIO *bio, char **buf)
896 {
897 long ret;
898
899 if (!bio->init)
900 {
901 BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED);
902 return -2;
903 }
904
905 ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf);
906 if (ret > INT_MAX)
907 return INT_MAX;
908 else
909 return (int) ret;
910 }
911
912int BIO_nwrite(BIO *bio, char **buf, int num)
913 {
914 int ret;
915
916 if (!bio->init)
917 {
918 BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED);
919 return -2;
920 }
921
922 ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf);
923 if (ret > 0)
44390fad 924 bio->num_write += ret;
c1082a90
BM
925 return ret;
926 }