1 /*
2 * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 #include <stdio.h>
11 #include <errno.h>
12 #include "bio_local.h"
13 #include "internal/cryptlib.h"
14 #include "internal/safe_math.h"
15
16 #if !defined(OPENSSL_NO_DGRAM) && !defined(OPENSSL_NO_SOCK)
17
18 OSSL_SAFE_MATH_UNSIGNED(size_t, size_t)
19
20 /* ===========================================================================
21 * Byte-wise ring buffer which supports pushing and popping blocks of multiple
22 * bytes at a time.
23 */
24 struct ring_buf {
25 unsigned char *start; /* start of buffer */
26 size_t len; /* size of buffer allocation in bytes */
27 size_t count; /* number of bytes currently pushed */
28 /*
29 * These index into start. Where idx[0] == idx[1], the buffer is full
30 * (if count is nonzero) and empty otherwise.
31 */
32 size_t idx[2]; /* 0: head, 1: tail */
33 };
34
ring_buf_init(struct ring_buf * r,size_t nbytes)35 static int ring_buf_init(struct ring_buf *r, size_t nbytes)
36 {
37 r->start = OPENSSL_malloc(nbytes);
38 if (r->start == NULL)
39 return 0;
40
41 r->len = nbytes;
42 r->idx[0] = r->idx[1] = r->count = 0;
43 return 1;
44 }
45
ring_buf_destroy(struct ring_buf * r)46 static void ring_buf_destroy(struct ring_buf *r)
47 {
48 OPENSSL_free(r->start);
49 r->start = NULL;
50 r->len = 0;
51 r->count = 0;
52 }
53
54 /*
55 * Get a pointer to the next place to write data to be pushed to the ring buffer
56 * (idx=0), or the next data to be popped from the ring buffer (idx=1). The
57 * pointer is written to *buf and the maximum number of bytes which can be
58 * read/written are written to *len. After writing data to the buffer, call
59 * ring_buf_push/pop() with the number of bytes actually read/written, which
60 * must not exceed the returned length.
61 */
ring_buf_head_tail(struct ring_buf * r,int idx,uint8_t ** buf,size_t * len)62 static void ring_buf_head_tail(struct ring_buf *r, int idx, uint8_t **buf, size_t *len)
63 {
64 size_t max_len = r->len - r->idx[idx];
65
66 if (idx == 0 && max_len > r->len - r->count)
67 max_len = r->len - r->count;
68 if (idx == 1 && max_len > r->count)
69 max_len = r->count;
70
71 *buf = (uint8_t *)r->start + r->idx[idx];
72 *len = max_len;
73 }
74
75 #define ring_buf_head(r, buf, len) ring_buf_head_tail((r), 0, (buf), (len))
76 #define ring_buf_tail(r, buf, len) ring_buf_head_tail((r), 1, (buf), (len))
77
78 /*
79 * Commit bytes to the ring buffer previously filled after a call to
80 * ring_buf_head().
81 */
ring_buf_push_pop(struct ring_buf * r,int idx,size_t num_bytes)82 static void ring_buf_push_pop(struct ring_buf *r, int idx, size_t num_bytes)
83 {
84 size_t new_idx;
85
86 /* A single push/pop op cannot wrap around, though it can reach the end.
87 * If the caller adheres to the convention of using the length returned
88 * by ring_buf_head/tail(), this cannot happen.
89 */
90 if (!ossl_assert(num_bytes <= r->len - r->idx[idx]))
91 return;
92
93 /*
94 * Must not overfill the buffer, or pop more than is in the buffer either.
95 */
96 if (!ossl_assert(idx != 0 ? num_bytes <= r->count
97 : num_bytes + r->count <= r->len))
98 return;
99
100 /* Update the index. */
101 new_idx = r->idx[idx] + num_bytes;
102 if (new_idx == r->len)
103 new_idx = 0;
104
105 r->idx[idx] = new_idx;
106 if (idx != 0)
107 r->count -= num_bytes;
108 else
109 r->count += num_bytes;
110 }
111
112 #define ring_buf_push(r, num_bytes) ring_buf_push_pop((r), 0, (num_bytes))
113 #define ring_buf_pop(r, num_bytes) ring_buf_push_pop((r), 1, (num_bytes))
114
ring_buf_clear(struct ring_buf * r)115 static void ring_buf_clear(struct ring_buf *r)
116 {
117 r->idx[0] = r->idx[1] = r->count = 0;
118 }
119
ring_buf_resize(struct ring_buf * r,size_t nbytes)120 static int ring_buf_resize(struct ring_buf *r, size_t nbytes)
121 {
122 unsigned char *new_start;
123
124 if (r->start == NULL)
125 return ring_buf_init(r, nbytes);
126
127 if (nbytes == r->len)
128 return 1;
129
130 if (r->count > 0 && nbytes < r->len)
131 /* fail shrinking the ring buffer when there is any data in it */
132 return 0;
133
134 new_start = OPENSSL_realloc(r->start, nbytes);
135 if (new_start == NULL)
136 return 0;
137
138 /* Moving tail if it is after (or equal to) head */
139 if (r->count > 0) {
140 if (r->idx[0] <= r->idx[1]) {
141 size_t offset = nbytes - r->len;
142
143 memmove(new_start + r->idx[1] + offset, new_start + r->idx[1],
144 r->len - r->idx[1]);
145 r->idx[1] += offset;
146 }
147 } else {
148 /* just reset the head/tail because it might be pointing outside */
149 r->idx[0] = r->idx[1] = 0;
150 }
151
152 r->start = new_start;
153 r->len = nbytes;
154
155 return 1;
156 }
157
158 /* ===========================================================================
159 * BIO_s_dgram_pair is documented in BIO_s_dgram_pair(3).
160 *
161 * INTERNAL DATA STRUCTURE
162 *
163 * This is managed internally by using a bytewise ring buffer which supports
164 * pushing and popping spans of multiple bytes at once. The ring buffer stores
165 * internal packets which look like this:
166 *
167 * struct dgram_hdr hdr;
168 * uint8_t data[];
169 *
170 * The header contains the length of the data and metadata such as
171 * source/destination addresses.
172 *
173 * The datagram pair BIO is designed to support both traditional
174 * BIO_read/BIO_write (likely to be used by applications) as well as
175 * BIO_recvmmsg/BIO_sendmmsg.
176 */
177 struct bio_dgram_pair_st;
178 static int dgram_pair_write(BIO *bio, const char *buf, int sz_);
179 static int dgram_pair_read(BIO *bio, char *buf, int sz_);
180 static int dgram_mem_read(BIO *bio, char *buf, int sz_);
181 static long dgram_pair_ctrl(BIO *bio, int cmd, long num, void *ptr);
182 static long dgram_mem_ctrl(BIO *bio, int cmd, long num, void *ptr);
183 static int dgram_pair_init(BIO *bio);
184 static int dgram_mem_init(BIO *bio);
185 static int dgram_pair_free(BIO *bio);
186 static int dgram_pair_sendmmsg(BIO *b, BIO_MSG *msg, size_t stride,
187 size_t num_msg, uint64_t flags,
188 size_t *num_processed);
189 static int dgram_pair_recvmmsg(BIO *b, BIO_MSG *msg, size_t stride,
190 size_t num_msg, uint64_t flags,
191 size_t *num_processed);
192
193 static int dgram_pair_ctrl_destroy_bio_pair(BIO *bio1);
194 static size_t dgram_pair_read_inner(struct bio_dgram_pair_st *b, uint8_t *buf,
195 size_t sz);
196
197 #define BIO_MSG_N(array, n) (*(BIO_MSG *)((char *)(array) + (n)*stride))
198
199 static const BIO_METHOD dgram_pair_method = {
200 BIO_TYPE_DGRAM_PAIR,
201 "BIO dgram pair",
202 bwrite_conv,
203 dgram_pair_write,
204 bread_conv,
205 dgram_pair_read,
206 NULL, /* dgram_pair_puts */
207 NULL, /* dgram_pair_gets */
208 dgram_pair_ctrl,
209 dgram_pair_init,
210 dgram_pair_free,
211 NULL, /* dgram_pair_callback_ctrl */
212 dgram_pair_sendmmsg,
213 dgram_pair_recvmmsg,
214 };
215
216 static const BIO_METHOD dgram_mem_method = {
217 BIO_TYPE_DGRAM_MEM,
218 "BIO dgram mem",
219 bwrite_conv,
220 dgram_pair_write,
221 bread_conv,
222 dgram_mem_read,
223 NULL, /* dgram_pair_puts */
224 NULL, /* dgram_pair_gets */
225 dgram_mem_ctrl,
226 dgram_mem_init,
227 dgram_pair_free,
228 NULL, /* dgram_pair_callback_ctrl */
229 dgram_pair_sendmmsg,
230 dgram_pair_recvmmsg,
231 };
232
BIO_s_dgram_pair(void)233 const BIO_METHOD *BIO_s_dgram_pair(void)
234 {
235 return &dgram_pair_method;
236 }
237
BIO_s_dgram_mem(void)238 const BIO_METHOD *BIO_s_dgram_mem(void)
239 {
240 return &dgram_mem_method;
241 }
242
243 struct dgram_hdr {
244 size_t len; /* payload length in bytes, not including this struct */
245 BIO_ADDR src_addr, dst_addr; /* family == 0: not present */
246 };
247
248 struct bio_dgram_pair_st {
249 /* The other half of the BIO pair. NULL for dgram_mem. */
250 BIO *peer;
251 /* Writes are directed to our own ringbuf and reads to our peer. */
252 struct ring_buf rbuf;
253 /* Requested size of rbuf buffer in bytes once we initialize. */
254 size_t req_buf_len;
255 /* Largest possible datagram size */
256 size_t mtu;
257 /* Capability flags. */
258 uint32_t cap;
259 /*
260 * This lock protects updates to our rbuf. Since writes are directed to our
261 * own rbuf, this means we use this lock for writes and our peer's lock for
262 * reads.
263 */
264 CRYPTO_RWLOCK *lock;
265 unsigned int no_trunc : 1; /* Reads fail if they would truncate */
266 unsigned int local_addr_enable : 1; /* Can use BIO_MSG->local? */
267 unsigned int role : 1; /* Determines lock order */
268 unsigned int grows_on_write : 1; /* Set for BIO_s_dgram_mem only */
269 };
270
271 #define MIN_BUF_LEN (1024)
272
273 #define is_dgram_pair(b) (b->peer != NULL)
274
dgram_pair_init(BIO * bio)275 static int dgram_pair_init(BIO *bio)
276 {
277 struct bio_dgram_pair_st *b = OPENSSL_zalloc(sizeof(*b));
278
279 if (b == NULL)
280 return 0;
281
282 b->mtu = 1472; /* conservative default MTU */
283 /* default buffer size */
284 b->req_buf_len = 9 * (sizeof(struct dgram_hdr) + b->mtu);
285
286 b->lock = CRYPTO_THREAD_lock_new();
287 if (b->lock == NULL) {
288 OPENSSL_free(b);
289 return 0;
290 }
291
292 bio->ptr = b;
293 return 1;
294 }
295
dgram_mem_init(BIO * bio)296 static int dgram_mem_init(BIO *bio)
297 {
298 struct bio_dgram_pair_st *b;
299
300 if (!dgram_pair_init(bio))
301 return 0;
302
303 b = bio->ptr;
304
305 if (ring_buf_init(&b->rbuf, b->req_buf_len) == 0) {
306 ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB);
307 return 0;
308 }
309
310 b->grows_on_write = 1;
311
312 bio->init = 1;
313 return 1;
314 }
315
dgram_pair_free(BIO * bio)316 static int dgram_pair_free(BIO *bio)
317 {
318 struct bio_dgram_pair_st *b;
319
320 if (bio == NULL)
321 return 0;
322
323 b = bio->ptr;
324 if (!ossl_assert(b != NULL))
325 return 0;
326
327 /* We are being freed. Disconnect any peer and destroy buffers. */
328 dgram_pair_ctrl_destroy_bio_pair(bio);
329
330 CRYPTO_THREAD_lock_free(b->lock);
331 OPENSSL_free(b);
332 return 1;
333 }
334
335 /* BIO_make_bio_pair (BIO_C_MAKE_BIO_PAIR) */
dgram_pair_ctrl_make_bio_pair(BIO * bio1,BIO * bio2)336 static int dgram_pair_ctrl_make_bio_pair(BIO *bio1, BIO *bio2)
337 {
338 struct bio_dgram_pair_st *b1, *b2;
339
340 /* peer must be non-NULL. */
341 if (bio1 == NULL || bio2 == NULL) {
342 ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT);
343 return 0;
344 }
345
346 /* Ensure the BIO we have been passed is actually a dgram pair BIO. */
347 if (bio1->method != &dgram_pair_method || bio2->method != &dgram_pair_method) {
348 ERR_raise_data(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT,
349 "both BIOs must be BIO_dgram_pair");
350 return 0;
351 }
352
353 b1 = bio1->ptr;
354 b2 = bio2->ptr;
355
356 if (!ossl_assert(b1 != NULL && b2 != NULL)) {
357 ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
358 return 0;
359 }
360
361 /*
362 * This ctrl cannot be used to associate a BIO pair half which is already
363 * associated.
364 */
365 if (b1->peer != NULL || b2->peer != NULL) {
366 ERR_raise_data(ERR_LIB_BIO, BIO_R_IN_USE,
367 "cannot associate a BIO_dgram_pair which is already in use");
368 return 0;
369 }
370
371 if (!ossl_assert(b1->req_buf_len >= MIN_BUF_LEN
372 && b2->req_buf_len >= MIN_BUF_LEN)) {
373 ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
374 return 0;
375 }
376
377 if (b1->rbuf.len != b1->req_buf_len)
378 if (ring_buf_init(&b1->rbuf, b1->req_buf_len) == 0) {
379 ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB);
380 return 0;
381 }
382
383 if (b2->rbuf.len != b2->req_buf_len)
384 if (ring_buf_init(&b2->rbuf, b2->req_buf_len) == 0) {
385 ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB);
386 ring_buf_destroy(&b1->rbuf);
387 return 0;
388 }
389
390 b1->peer = bio2;
391 b2->peer = bio1;
392 b1->role = 0;
393 b2->role = 1;
394 bio1->init = 1;
395 bio2->init = 1;
396 return 1;
397 }
398
399 /* BIO_destroy_bio_pair (BIO_C_DESTROY_BIO_PAIR) */
dgram_pair_ctrl_destroy_bio_pair(BIO * bio1)400 static int dgram_pair_ctrl_destroy_bio_pair(BIO *bio1)
401 {
402 BIO *bio2;
403 struct bio_dgram_pair_st *b1 = bio1->ptr, *b2;
404
405 ring_buf_destroy(&b1->rbuf);
406 bio1->init = 0;
407
408 /* Early return if we don't have a peer. */
409 if (b1->peer == NULL)
410 return 1;
411
412 bio2 = b1->peer;
413 b2 = bio2->ptr;
414
415 /* Invariant. */
416 if (!ossl_assert(b2->peer == bio1))
417 return 0;
418
419 /* Free buffers. */
420 ring_buf_destroy(&b2->rbuf);
421
422 bio2->init = 0;
423 b1->peer = NULL;
424 b2->peer = NULL;
425 return 1;
426 }
427
428 /* BIO_eof (BIO_CTRL_EOF) */
dgram_pair_ctrl_eof(BIO * bio)429 static int dgram_pair_ctrl_eof(BIO *bio)
430 {
431 struct bio_dgram_pair_st *b = bio->ptr, *peerb;
432
433 if (!ossl_assert(b != NULL))
434 return -1;
435
436 /* If we aren't initialized, we can never read anything */
437 if (!bio->init)
438 return 1;
439 if (!is_dgram_pair(b))
440 return 0;
441
442
443 peerb = b->peer->ptr;
444 if (!ossl_assert(peerb != NULL))
445 return -1;
446
447 /*
448 * Since we are emulating datagram semantics, never indicate EOF so long as
449 * we have a peer.
450 */
451 return 0;
452 }
453
454 /* BIO_set_write_buf_size (BIO_C_SET_WRITE_BUF_SIZE) */
dgram_pair_ctrl_set_write_buf_size(BIO * bio,size_t len)455 static int dgram_pair_ctrl_set_write_buf_size(BIO *bio, size_t len)
456 {
457 struct bio_dgram_pair_st *b = bio->ptr;
458
459 /* Changing buffer sizes is not permitted while a peer is connected. */
460 if (b->peer != NULL) {
461 ERR_raise(ERR_LIB_BIO, BIO_R_IN_USE);
462 return 0;
463 }
464
465 /* Enforce minimum size. */
466 if (len < MIN_BUF_LEN)
467 len = MIN_BUF_LEN;
468
469 if (b->rbuf.start != NULL) {
470 if (!ring_buf_resize(&b->rbuf, len))
471 return 0;
472 }
473
474 b->req_buf_len = len;
475 b->grows_on_write = 0;
476 return 1;
477 }
478
479 /* BIO_reset (BIO_CTRL_RESET) */
dgram_pair_ctrl_reset(BIO * bio)480 static int dgram_pair_ctrl_reset(BIO *bio)
481 {
482 struct bio_dgram_pair_st *b = bio->ptr;
483
484 ring_buf_clear(&b->rbuf);
485 return 1;
486 }
487
488 /* BIO_pending (BIO_CTRL_PENDING) (Threadsafe) */
dgram_pair_ctrl_pending(BIO * bio)489 static size_t dgram_pair_ctrl_pending(BIO *bio)
490 {
491 size_t saved_idx, saved_count;
492 struct bio_dgram_pair_st *b = bio->ptr, *readb;
493 struct dgram_hdr hdr;
494 size_t l;
495
496 /* Safe to check; init may not change during this call */
497 if (!bio->init)
498 return 0;
499 if (is_dgram_pair(b))
500 readb = b->peer->ptr;
501 else
502 readb = b;
503
504 if (CRYPTO_THREAD_write_lock(readb->lock) == 0)
505 return 0;
506
507 saved_idx = readb->rbuf.idx[1];
508 saved_count = readb->rbuf.count;
509
510 l = dgram_pair_read_inner(readb, (uint8_t *)&hdr, sizeof(hdr));
511
512 readb->rbuf.idx[1] = saved_idx;
513 readb->rbuf.count = saved_count;
514
515 CRYPTO_THREAD_unlock(readb->lock);
516
517 if (!ossl_assert(l == 0 || l == sizeof(hdr)))
518 return 0;
519
520 return l > 0 ? hdr.len : 0;
521 }
522
523 /* BIO_get_write_guarantee (BIO_C_GET_WRITE_GUARANTEE) (Threadsafe) */
dgram_pair_ctrl_get_write_guarantee(BIO * bio)524 static size_t dgram_pair_ctrl_get_write_guarantee(BIO *bio)
525 {
526 size_t l;
527 struct bio_dgram_pair_st *b = bio->ptr;
528
529 if (CRYPTO_THREAD_read_lock(b->lock) == 0)
530 return 0;
531
532 l = b->rbuf.len - b->rbuf.count;
533 if (l >= sizeof(struct dgram_hdr))
534 l -= sizeof(struct dgram_hdr);
535
536 /*
537 * If the amount of buffer space would not be enough to accommodate the
538 * worst-case size of a datagram, report no space available.
539 */
540 if (l < b->mtu)
541 l = 0;
542
543 CRYPTO_THREAD_unlock(b->lock);
544 return l;
545 }
546
547 /* BIO_dgram_get_local_addr_cap (BIO_CTRL_DGRAM_GET_LOCAL_ADDR_CAP) */
dgram_pair_ctrl_get_local_addr_cap(BIO * bio)548 static int dgram_pair_ctrl_get_local_addr_cap(BIO *bio)
549 {
550 struct bio_dgram_pair_st *b = bio->ptr, *readb;
551
552 if (!bio->init)
553 return 0;
554
555 if (is_dgram_pair(b))
556 readb = b->peer->ptr;
557 else
558 readb = b;
559
560 return (~readb->cap & (BIO_DGRAM_CAP_HANDLES_SRC_ADDR
561 | BIO_DGRAM_CAP_PROVIDES_DST_ADDR)) == 0;
562 }
563
564 /* BIO_dgram_get_effective_caps (BIO_CTRL_DGRAM_GET_EFFECTIVE_CAPS) */
dgram_pair_ctrl_get_effective_caps(BIO * bio)565 static int dgram_pair_ctrl_get_effective_caps(BIO *bio)
566 {
567 struct bio_dgram_pair_st *b = bio->ptr, *peerb;
568
569 if (b->peer == NULL)
570 return 0;
571
572 peerb = b->peer->ptr;
573
574 return peerb->cap;
575 }
576
577 /* BIO_dgram_get_caps (BIO_CTRL_DGRAM_GET_CAPS) */
dgram_pair_ctrl_get_caps(BIO * bio)578 static uint32_t dgram_pair_ctrl_get_caps(BIO *bio)
579 {
580 struct bio_dgram_pair_st *b = bio->ptr;
581
582 return b->cap;
583 }
584
585 /* BIO_dgram_set_caps (BIO_CTRL_DGRAM_SET_CAPS) */
dgram_pair_ctrl_set_caps(BIO * bio,uint32_t caps)586 static int dgram_pair_ctrl_set_caps(BIO *bio, uint32_t caps)
587 {
588 struct bio_dgram_pair_st *b = bio->ptr;
589
590 b->cap = caps;
591 return 1;
592 }
593
594 /* BIO_dgram_get_local_addr_enable (BIO_CTRL_DGRAM_GET_LOCAL_ADDR_ENABLE) */
dgram_pair_ctrl_get_local_addr_enable(BIO * bio)595 static int dgram_pair_ctrl_get_local_addr_enable(BIO *bio)
596 {
597 struct bio_dgram_pair_st *b = bio->ptr;
598
599 return b->local_addr_enable;
600 }
601
602 /* BIO_dgram_set_local_addr_enable (BIO_CTRL_DGRAM_SET_LOCAL_ADDR_ENABLE) */
dgram_pair_ctrl_set_local_addr_enable(BIO * bio,int enable)603 static int dgram_pair_ctrl_set_local_addr_enable(BIO *bio, int enable)
604 {
605 struct bio_dgram_pair_st *b = bio->ptr;
606
607 if (dgram_pair_ctrl_get_local_addr_cap(bio) == 0)
608 return 0;
609
610 b->local_addr_enable = (enable != 0 ? 1 : 0);
611 return 1;
612 }
613
614 /* BIO_dgram_get_mtu (BIO_CTRL_DGRAM_GET_MTU) */
dgram_pair_ctrl_get_mtu(BIO * bio)615 static int dgram_pair_ctrl_get_mtu(BIO *bio)
616 {
617 struct bio_dgram_pair_st *b = bio->ptr;
618
619 return b->mtu;
620 }
621
622 /* BIO_dgram_set_mtu (BIO_CTRL_DGRAM_SET_MTU) */
dgram_pair_ctrl_set_mtu(BIO * bio,size_t mtu)623 static int dgram_pair_ctrl_set_mtu(BIO *bio, size_t mtu)
624 {
625 struct bio_dgram_pair_st *b = bio->ptr, *peerb;
626
627 b->mtu = mtu;
628
629 if (b->peer != NULL) {
630 peerb = b->peer->ptr;
631 peerb->mtu = mtu;
632 }
633
634 return 1;
635 }
636
637 /* Partially threadsafe (some commands) */
dgram_mem_ctrl(BIO * bio,int cmd,long num,void * ptr)638 static long dgram_mem_ctrl(BIO *bio, int cmd, long num, void *ptr)
639 {
640 long ret = 1;
641 struct bio_dgram_pair_st *b = bio->ptr;
642
643 if (!ossl_assert(b != NULL))
644 return 0;
645
646 switch (cmd) {
647 /*
648 * BIO_set_write_buf_size: Set the size of the ring buffer used for storing
649 * datagrams. No more writes can be performed once the buffer is filled up,
650 * until reads are performed. This cannot be used after a peer is connected.
651 */
652 case BIO_C_SET_WRITE_BUF_SIZE: /* Non-threadsafe */
653 ret = (long)dgram_pair_ctrl_set_write_buf_size(bio, (size_t)num);
654 break;
655
656 /*
657 * BIO_get_write_buf_size: Get ring buffer size.
658 */
659 case BIO_C_GET_WRITE_BUF_SIZE: /* Non-threadsafe */
660 ret = (long)b->req_buf_len;
661 break;
662
663 /*
664 * BIO_reset: Clear all data which was written to this side of the pair.
665 */
666 case BIO_CTRL_RESET: /* Non-threadsafe */
667 dgram_pair_ctrl_reset(bio);
668 break;
669
670 /*
671 * BIO_get_write_guarantee: Any BIO_write providing a buffer less than or
672 * equal to this value is guaranteed to succeed.
673 */
674 case BIO_C_GET_WRITE_GUARANTEE: /* Threadsafe */
675 ret = (long)dgram_pair_ctrl_get_write_guarantee(bio);
676 break;
677
678 /* BIO_pending: Bytes available to read. */
679 case BIO_CTRL_PENDING: /* Threadsafe */
680 ret = (long)dgram_pair_ctrl_pending(bio);
681 break;
682
683 /* BIO_flush: No-op. */
684 case BIO_CTRL_FLUSH: /* Threadsafe */
685 break;
686
687 /* BIO_dgram_get_no_trunc */
688 case BIO_CTRL_DGRAM_GET_NO_TRUNC: /* Non-threadsafe */
689 ret = (long)b->no_trunc;
690 break;
691
692 /* BIO_dgram_set_no_trunc */
693 case BIO_CTRL_DGRAM_SET_NO_TRUNC: /* Non-threadsafe */
694 b->no_trunc = (num > 0);
695 break;
696
697 /* BIO_dgram_get_local_addr_enable */
698 case BIO_CTRL_DGRAM_GET_LOCAL_ADDR_ENABLE: /* Non-threadsafe */
699 *(int *)ptr = (int)dgram_pair_ctrl_get_local_addr_enable(bio);
700 break;
701
702 /* BIO_dgram_set_local_addr_enable */
703 case BIO_CTRL_DGRAM_SET_LOCAL_ADDR_ENABLE: /* Non-threadsafe */
704 ret = (long)dgram_pair_ctrl_set_local_addr_enable(bio, num);
705 break;
706
707 /* BIO_dgram_get_local_addr_cap: Can local addresses be supported? */
708 case BIO_CTRL_DGRAM_GET_LOCAL_ADDR_CAP: /* Non-threadsafe */
709 ret = (long)dgram_pair_ctrl_get_local_addr_cap(bio);
710 break;
711
712 /* BIO_dgram_get_effective_caps */
713 case BIO_CTRL_DGRAM_GET_EFFECTIVE_CAPS: /* Non-threadsafe */
714 /* BIO_dgram_get_caps */
715 case BIO_CTRL_DGRAM_GET_CAPS: /* Non-threadsafe */
716 ret = (long)dgram_pair_ctrl_get_caps(bio);
717 break;
718
719 /* BIO_dgram_set_caps */
720 case BIO_CTRL_DGRAM_SET_CAPS: /* Non-threadsafe */
721 ret = (long)dgram_pair_ctrl_set_caps(bio, (uint32_t)num);
722 break;
723
724 /* BIO_dgram_get_mtu */
725 case BIO_CTRL_DGRAM_GET_MTU: /* Non-threadsafe */
726 ret = (long)dgram_pair_ctrl_get_mtu(bio);
727 break;
728
729 /* BIO_dgram_set_mtu */
730 case BIO_CTRL_DGRAM_SET_MTU: /* Non-threadsafe */
731 ret = (long)dgram_pair_ctrl_set_mtu(bio, (uint32_t)num);
732 break;
733
734 /*
735 * BIO_eof: Returns whether this half of the BIO pair is empty of data to
736 * read.
737 */
738 case BIO_CTRL_EOF: /* Non-threadsafe */
739 ret = (long)dgram_pair_ctrl_eof(bio);
740 break;
741
742 default:
743 ret = 0;
744 break;
745 }
746
747 return ret;
748 }
749
dgram_pair_ctrl(BIO * bio,int cmd,long num,void * ptr)750 static long dgram_pair_ctrl(BIO *bio, int cmd, long num, void *ptr)
751 {
752 long ret = 1;
753
754 switch (cmd) {
755 /*
756 * BIO_make_bio_pair: this is usually used by BIO_new_dgram_pair, though it
757 * may be used manually after manually creating each half of a BIO pair
758 * using BIO_new. This only needs to be called on one of the BIOs.
759 */
760 case BIO_C_MAKE_BIO_PAIR: /* Non-threadsafe */
761 ret = (long)dgram_pair_ctrl_make_bio_pair(bio, (BIO *)ptr);
762 break;
763
764 /*
765 * BIO_destroy_bio_pair: Manually disconnect two halves of a BIO pair so
766 * that they are no longer peers.
767 */
768 case BIO_C_DESTROY_BIO_PAIR: /* Non-threadsafe */
769 dgram_pair_ctrl_destroy_bio_pair(bio);
770 break;
771
772 /* BIO_dgram_get_effective_caps */
773 case BIO_CTRL_DGRAM_GET_EFFECTIVE_CAPS: /* Non-threadsafe */
774 ret = (long)dgram_pair_ctrl_get_effective_caps(bio);
775 break;
776
777 default:
778 ret = dgram_mem_ctrl(bio, cmd, num, ptr);
779 break;
780 }
781
782 return ret;
783 }
784
BIO_new_bio_dgram_pair(BIO ** pbio1,size_t writebuf1,BIO ** pbio2,size_t writebuf2)785 int BIO_new_bio_dgram_pair(BIO **pbio1, size_t writebuf1,
786 BIO **pbio2, size_t writebuf2)
787 {
788 int ret = 0;
789 long r;
790 BIO *bio1 = NULL, *bio2 = NULL;
791
792 bio1 = BIO_new(BIO_s_dgram_pair());
793 if (bio1 == NULL)
794 goto err;
795
796 bio2 = BIO_new(BIO_s_dgram_pair());
797 if (bio2 == NULL)
798 goto err;
799
800 if (writebuf1 > 0) {
801 r = BIO_set_write_buf_size(bio1, writebuf1);
802 if (r == 0)
803 goto err;
804 }
805
806 if (writebuf2 > 0) {
807 r = BIO_set_write_buf_size(bio2, writebuf2);
808 if (r == 0)
809 goto err;
810 }
811
812 r = BIO_make_bio_pair(bio1, bio2);
813 if (r == 0)
814 goto err;
815
816 ret = 1;
817 err:
818 if (ret == 0) {
819 BIO_free(bio1);
820 bio1 = NULL;
821 BIO_free(bio2);
822 bio2 = NULL;
823 }
824
825 *pbio1 = bio1;
826 *pbio2 = bio2;
827 return ret;
828 }
829
830 /* Must hold peer write lock */
dgram_pair_read_inner(struct bio_dgram_pair_st * b,uint8_t * buf,size_t sz)831 static size_t dgram_pair_read_inner(struct bio_dgram_pair_st *b, uint8_t *buf, size_t sz)
832 {
833 size_t total_read = 0;
834
835 /*
836 * We repeat pops from the ring buffer for as long as we have more
837 * application *buffer to fill until we fail. We may not be able to pop
838 * enough data to fill the buffer in one operation if the ring buffer wraps
839 * around, but there may still be more data available.
840 */
841 while (sz > 0) {
842 uint8_t *src_buf = NULL;
843 size_t src_len = 0;
844
845 /*
846 * There are two BIO instances, each with a ringbuf. We read from the
847 * peer ringbuf and write to our own ringbuf.
848 */
849 ring_buf_tail(&b->rbuf, &src_buf, &src_len);
850 if (src_len == 0)
851 break;
852
853 if (src_len > sz)
854 src_len = sz;
855
856 if (buf != NULL)
857 memcpy(buf, src_buf, src_len);
858
859 ring_buf_pop(&b->rbuf, src_len);
860
861 if (buf != NULL)
862 buf += src_len;
863 total_read += src_len;
864 sz -= src_len;
865 }
866
867 return total_read;
868 }
869
870 /*
871 * Must hold peer write lock. Returns number of bytes processed or negated BIO
872 * response code.
873 */
dgram_pair_read_actual(BIO * bio,char * buf,size_t sz,BIO_ADDR * local,BIO_ADDR * peer,int is_multi)874 static ossl_ssize_t dgram_pair_read_actual(BIO *bio, char *buf, size_t sz,
875 BIO_ADDR *local, BIO_ADDR *peer,
876 int is_multi)
877 {
878 size_t l, trunc = 0, saved_idx, saved_count;
879 struct bio_dgram_pair_st *b = bio->ptr, *readb;
880 struct dgram_hdr hdr;
881
882 if (!is_multi)
883 BIO_clear_retry_flags(bio);
884
885 if (!bio->init)
886 return -BIO_R_UNINITIALIZED;
887
888 if (!ossl_assert(b != NULL))
889 return -BIO_R_TRANSFER_ERROR;
890
891 if (is_dgram_pair(b))
892 readb = b->peer->ptr;
893 else
894 readb = b;
895 if (!ossl_assert(readb != NULL && readb->rbuf.start != NULL))
896 return -BIO_R_TRANSFER_ERROR;
897
898 if (sz > 0 && buf == NULL)
899 return -BIO_R_INVALID_ARGUMENT;
900
901 /* If the caller wants to know the local address, it must be enabled */
902 if (local != NULL && b->local_addr_enable == 0)
903 return -BIO_R_LOCAL_ADDR_NOT_AVAILABLE;
904
905 /* Read the header. */
906 saved_idx = readb->rbuf.idx[1];
907 saved_count = readb->rbuf.count;
908 l = dgram_pair_read_inner(readb, (uint8_t *)&hdr, sizeof(hdr));
909 if (l == 0) {
910 /* Buffer was empty. */
911 if (!is_multi)
912 BIO_set_retry_read(bio);
913 return -BIO_R_NON_FATAL;
914 }
915
916 if (!ossl_assert(l == sizeof(hdr)))
917 /*
918 * This should not be possible as headers (and their following payloads)
919 * should always be written atomically.
920 */
921 return -BIO_R_BROKEN_PIPE;
922
923 if (sz > hdr.len) {
924 sz = hdr.len;
925 } else if (sz < hdr.len) {
926 /* Truncation is occurring. */
927 trunc = hdr.len - sz;
928 if (b->no_trunc) {
929 /* Restore original state. */
930 readb->rbuf.idx[1] = saved_idx;
931 readb->rbuf.count = saved_count;
932 return -BIO_R_NON_FATAL;
933 }
934 }
935
936 l = dgram_pair_read_inner(readb, (uint8_t *)buf, sz);
937 if (!ossl_assert(l == sz))
938 /* We were somehow not able to read the entire datagram. */
939 return -BIO_R_TRANSFER_ERROR;
940
941 /*
942 * If the datagram was truncated due to an inadequate buffer, discard the
943 * remainder.
944 */
945 if (trunc > 0 && !ossl_assert(dgram_pair_read_inner(readb, NULL, trunc) == trunc))
946 /* We were somehow not able to read/skip the entire datagram. */
947 return -BIO_R_TRANSFER_ERROR;
948
949 if (local != NULL)
950 *local = hdr.dst_addr;
951 if (peer != NULL)
952 *peer = hdr.src_addr;
953
954 return (ossl_ssize_t)l;
955 }
956
957 /* Threadsafe */
dgram_pair_lock_both_write(struct bio_dgram_pair_st * a,struct bio_dgram_pair_st * b)958 static int dgram_pair_lock_both_write(struct bio_dgram_pair_st *a,
959 struct bio_dgram_pair_st *b)
960 {
961 struct bio_dgram_pair_st *x, *y;
962
963 x = (a->role == 1) ? a : b;
964 y = (a->role == 1) ? b : a;
965
966 if (!ossl_assert(a->role != b->role))
967 return 0;
968
969 if (!ossl_assert(a != b && x != y))
970 return 0;
971
972 if (CRYPTO_THREAD_write_lock(x->lock) == 0)
973 return 0;
974
975 if (CRYPTO_THREAD_write_lock(y->lock) == 0) {
976 CRYPTO_THREAD_unlock(x->lock);
977 return 0;
978 }
979
980 return 1;
981 }
982
dgram_pair_unlock_both(struct bio_dgram_pair_st * a,struct bio_dgram_pair_st * b)983 static void dgram_pair_unlock_both(struct bio_dgram_pair_st *a,
984 struct bio_dgram_pair_st *b)
985 {
986 CRYPTO_THREAD_unlock(a->lock);
987 CRYPTO_THREAD_unlock(b->lock);
988 }
989
990 /* Threadsafe */
dgram_pair_read(BIO * bio,char * buf,int sz_)991 static int dgram_pair_read(BIO *bio, char *buf, int sz_)
992 {
993 int ret;
994 ossl_ssize_t l;
995 struct bio_dgram_pair_st *b = bio->ptr, *peerb;
996
997 if (sz_ < 0) {
998 ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT);
999 return -1;
1000 }
1001
1002 if (b->peer == NULL) {
1003 ERR_raise(ERR_LIB_BIO, BIO_R_BROKEN_PIPE);
1004 return -1;
1005 }
1006
1007 peerb = b->peer->ptr;
1008
1009 /*
1010 * For BIO_read we have to acquire both locks because we touch the retry
1011 * flags on the local bio. (This is avoided in the recvmmsg case as it does
1012 * not touch the retry flags.)
1013 */
1014 if (dgram_pair_lock_both_write(peerb, b) == 0) {
1015 ERR_raise(ERR_LIB_BIO, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
1016 return -1;
1017 }
1018
1019 l = dgram_pair_read_actual(bio, buf, (size_t)sz_, NULL, NULL, 0);
1020 if (l < 0) {
1021 if (l != -BIO_R_NON_FATAL)
1022 ERR_raise(ERR_LIB_BIO, -l);
1023 ret = -1;
1024 } else {
1025 ret = (int)l;
1026 }
1027
1028 dgram_pair_unlock_both(peerb, b);
1029 return ret;
1030 }
1031
1032 /* Threadsafe */
dgram_pair_recvmmsg(BIO * bio,BIO_MSG * msg,size_t stride,size_t num_msg,uint64_t flags,size_t * num_processed)1033 static int dgram_pair_recvmmsg(BIO *bio, BIO_MSG *msg,
1034 size_t stride, size_t num_msg,
1035 uint64_t flags,
1036 size_t *num_processed)
1037 {
1038 int ret;
1039 ossl_ssize_t l;
1040 BIO_MSG *m;
1041 size_t i;
1042 struct bio_dgram_pair_st *b = bio->ptr, *readb;
1043
1044 if (num_msg == 0) {
1045 *num_processed = 0;
1046 return 1;
1047 }
1048
1049 if (!bio->init) {
1050 ERR_raise(ERR_LIB_BIO, BIO_R_BROKEN_PIPE);
1051 *num_processed = 0;
1052 return 0;
1053 }
1054
1055 if (is_dgram_pair(b))
1056 readb = b->peer->ptr;
1057 else
1058 readb = b;
1059
1060 if (CRYPTO_THREAD_write_lock(readb->lock) == 0) {
1061 ERR_raise(ERR_LIB_BIO, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
1062 *num_processed = 0;
1063 return 0;
1064 }
1065
1066 for (i = 0; i < num_msg; ++i) {
1067 m = &BIO_MSG_N(msg, i);
1068 l = dgram_pair_read_actual(bio, m->data, m->data_len,
1069 m->local, m->peer, 1);
1070 if (l < 0) {
1071 *num_processed = i;
1072 if (i > 0) {
1073 ret = 1;
1074 } else {
1075 ERR_raise(ERR_LIB_BIO, -l);
1076 ret = 0;
1077 }
1078 goto out;
1079 }
1080
1081 m->data_len = l;
1082 m->flags = 0;
1083 }
1084
1085 *num_processed = i;
1086 ret = 1;
1087 out:
1088 CRYPTO_THREAD_unlock(readb->lock);
1089 return ret;
1090 }
1091
1092 /* Threadsafe */
dgram_mem_read(BIO * bio,char * buf,int sz_)1093 static int dgram_mem_read(BIO *bio, char *buf, int sz_)
1094 {
1095 int ret;
1096 ossl_ssize_t l;
1097 struct bio_dgram_pair_st *b = bio->ptr;
1098
1099 if (sz_ < 0) {
1100 ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT);
1101 return -1;
1102 }
1103
1104 if (CRYPTO_THREAD_write_lock(b->lock) == 0) {
1105 ERR_raise(ERR_LIB_BIO, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
1106 return -1;
1107 }
1108
1109 l = dgram_pair_read_actual(bio, buf, (size_t)sz_, NULL, NULL, 0);
1110 if (l < 0) {
1111 if (l != -BIO_R_NON_FATAL)
1112 ERR_raise(ERR_LIB_BIO, -l);
1113 ret = -1;
1114 } else {
1115 ret = (int)l;
1116 }
1117
1118 CRYPTO_THREAD_unlock(b->lock);
1119 return ret;
1120 }
1121
1122 /*
1123 * Calculate the array growth based on the target size.
1124 *
1125 * The growth factor is a rational number and is defined by a numerator
1126 * and a denominator. According to Andrew Koenig in his paper "Why Are
1127 * Vectors Efficient?" from JOOP 11(5) 1998, this factor should be less
1128 * than the golden ratio (1.618...).
1129 *
1130 * We use an expansion factor of 8 / 5 = 1.6
1131 */
1132 static const size_t max_rbuf_size = SIZE_MAX / 2; /* unlimited in practice */
compute_rbuf_growth(size_t target,size_t current)1133 static ossl_inline size_t compute_rbuf_growth(size_t target, size_t current)
1134 {
1135 int err = 0;
1136
1137 while (current < target) {
1138 if (current >= max_rbuf_size)
1139 return 0;
1140
1141 current = safe_muldiv_size_t(current, 8, 5, &err);
1142 if (err)
1143 return 0;
1144 if (current >= max_rbuf_size)
1145 current = max_rbuf_size;
1146 }
1147 return current;
1148 }
1149
1150 /* Must hold local write lock */
dgram_pair_write_inner(struct bio_dgram_pair_st * b,const uint8_t * buf,size_t sz)1151 static size_t dgram_pair_write_inner(struct bio_dgram_pair_st *b,
1152 const uint8_t *buf, size_t sz)
1153 {
1154 size_t total_written = 0;
1155
1156 /*
1157 * We repeat pushes to the ring buffer for as long as we have data until we
1158 * fail. We may not be able to push in one operation if the ring buffer
1159 * wraps around, but there may still be more room for data.
1160 */
1161 while (sz > 0) {
1162 size_t dst_len;
1163 uint8_t *dst_buf;
1164
1165 /*
1166 * There are two BIO instances, each with a ringbuf. We write to our own
1167 * ringbuf and read from the peer ringbuf.
1168 */
1169 ring_buf_head(&b->rbuf, &dst_buf, &dst_len);
1170 if (dst_len == 0) {
1171 size_t new_len;
1172
1173 if (!b->grows_on_write) /* resize only if size not set explicitly */
1174 break;
1175 /* increase the size */
1176 new_len = compute_rbuf_growth(b->req_buf_len + sz, b->req_buf_len);
1177 if (new_len == 0 || !ring_buf_resize(&b->rbuf, new_len))
1178 break;
1179 b->req_buf_len = new_len;
1180 }
1181
1182 if (dst_len > sz)
1183 dst_len = sz;
1184
1185 memcpy(dst_buf, buf, dst_len);
1186 ring_buf_push(&b->rbuf, dst_len);
1187
1188 buf += dst_len;
1189 sz -= dst_len;
1190 total_written += dst_len;
1191 }
1192
1193 return total_written;
1194 }
1195
1196 /*
1197 * Must hold local write lock. Returns number of bytes processed or negated BIO
1198 * response code.
1199 */
dgram_pair_write_actual(BIO * bio,const char * buf,size_t sz,const BIO_ADDR * local,const BIO_ADDR * peer,int is_multi)1200 static ossl_ssize_t dgram_pair_write_actual(BIO *bio, const char *buf, size_t sz,
1201 const BIO_ADDR *local, const BIO_ADDR *peer,
1202 int is_multi)
1203 {
1204 static const BIO_ADDR zero_addr;
1205 size_t saved_idx, saved_count;
1206 struct bio_dgram_pair_st *b = bio->ptr, *readb;
1207 struct dgram_hdr hdr = {0};
1208
1209 if (!is_multi)
1210 BIO_clear_retry_flags(bio);
1211
1212 if (!bio->init)
1213 return -BIO_R_UNINITIALIZED;
1214
1215 if (!ossl_assert(b != NULL && b->rbuf.start != NULL))
1216 return -BIO_R_TRANSFER_ERROR;
1217
1218 if (sz > 0 && buf == NULL)
1219 return -BIO_R_INVALID_ARGUMENT;
1220
1221 if (local != NULL && b->local_addr_enable == 0)
1222 return -BIO_R_LOCAL_ADDR_NOT_AVAILABLE;
1223
1224 if (is_dgram_pair(b))
1225 readb = b->peer->ptr;
1226 else
1227 readb = b;
1228 if (peer != NULL && (readb->cap & BIO_DGRAM_CAP_HANDLES_DST_ADDR) == 0)
1229 return -BIO_R_PEER_ADDR_NOT_AVAILABLE;
1230
1231 hdr.len = sz;
1232 hdr.dst_addr = (peer != NULL ? *peer : zero_addr);
1233 hdr.src_addr = (local != NULL ? *local : zero_addr);
1234
1235 saved_idx = b->rbuf.idx[0];
1236 saved_count = b->rbuf.count;
1237 if (dgram_pair_write_inner(b, (const uint8_t *)&hdr, sizeof(hdr)) != sizeof(hdr)
1238 || dgram_pair_write_inner(b, (const uint8_t *)buf, sz) != sz) {
1239 /*
1240 * We were not able to push the header and the entirety of the payload
1241 * onto the ring buffer, so abort and roll back the ring buffer state.
1242 */
1243 b->rbuf.idx[0] = saved_idx;
1244 b->rbuf.count = saved_count;
1245 if (!is_multi)
1246 BIO_set_retry_write(bio);
1247 return -BIO_R_NON_FATAL;
1248 }
1249
1250 return sz;
1251 }
1252
1253 /* Threadsafe */
dgram_pair_write(BIO * bio,const char * buf,int sz_)1254 static int dgram_pair_write(BIO *bio, const char *buf, int sz_)
1255 {
1256 int ret;
1257 ossl_ssize_t l;
1258 struct bio_dgram_pair_st *b = bio->ptr;
1259
1260 if (sz_ < 0) {
1261 ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT);
1262 return -1;
1263 }
1264
1265 if (CRYPTO_THREAD_write_lock(b->lock) == 0) {
1266 ERR_raise(ERR_LIB_BIO, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
1267 return -1;
1268 }
1269
1270 l = dgram_pair_write_actual(bio, buf, (size_t)sz_, NULL, NULL, 0);
1271 if (l < 0) {
1272 ERR_raise(ERR_LIB_BIO, -l);
1273 ret = -1;
1274 } else {
1275 ret = (int)l;
1276 }
1277
1278 CRYPTO_THREAD_unlock(b->lock);
1279 return ret;
1280 }
1281
1282 /* Threadsafe */
dgram_pair_sendmmsg(BIO * bio,BIO_MSG * msg,size_t stride,size_t num_msg,uint64_t flags,size_t * num_processed)1283 static int dgram_pair_sendmmsg(BIO *bio, BIO_MSG *msg,
1284 size_t stride, size_t num_msg,
1285 uint64_t flags, size_t *num_processed)
1286 {
1287 ossl_ssize_t ret, l;
1288 BIO_MSG *m;
1289 size_t i;
1290 struct bio_dgram_pair_st *b = bio->ptr;
1291
1292 if (num_msg == 0) {
1293 *num_processed = 0;
1294 return 1;
1295 }
1296
1297 if (CRYPTO_THREAD_write_lock(b->lock) == 0) {
1298 ERR_raise(ERR_LIB_BIO, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
1299 *num_processed = 0;
1300 return 0;
1301 }
1302
1303 for (i = 0; i < num_msg; ++i) {
1304 m = &BIO_MSG_N(msg, i);
1305 l = dgram_pair_write_actual(bio, m->data, m->data_len,
1306 m->local, m->peer, 1);
1307 if (l < 0) {
1308 *num_processed = i;
1309 if (i > 0) {
1310 ret = 1;
1311 } else {
1312 ERR_raise(ERR_LIB_BIO, -l);
1313 ret = 0;
1314 }
1315 goto out;
1316 }
1317
1318 m->flags = 0;
1319 }
1320
1321 *num_processed = i;
1322 ret = 1;
1323 out:
1324 CRYPTO_THREAD_unlock(b->lock);
1325 return ret;
1326 }
1327
1328 #endif
1329