bss_dgram_pair.c 35 KB

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