bss_dgram_pair.c 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328
  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. #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 grows_on_write : 1; /* Set for 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->mtu = 1472; /* conservative default MTU */
  242. /* default buffer size */
  243. b->req_buf_len = 9 * (sizeof(struct dgram_hdr) + b->mtu);
  244. b->lock = CRYPTO_THREAD_lock_new();
  245. if (b->lock == NULL) {
  246. OPENSSL_free(b);
  247. return 0;
  248. }
  249. bio->ptr = b;
  250. return 1;
  251. }
  252. static int dgram_mem_init(BIO *bio)
  253. {
  254. struct bio_dgram_pair_st *b;
  255. if (!dgram_pair_init(bio))
  256. return 0;
  257. b = bio->ptr;
  258. if (ring_buf_init(&b->rbuf, b->req_buf_len) == 0) {
  259. ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB);
  260. return 0;
  261. }
  262. b->grows_on_write = 1;
  263. bio->init = 1;
  264. return 1;
  265. }
  266. static int dgram_pair_free(BIO *bio)
  267. {
  268. struct bio_dgram_pair_st *b;
  269. if (bio == NULL)
  270. return 0;
  271. b = bio->ptr;
  272. if (!ossl_assert(b != NULL))
  273. return 0;
  274. /* We are being freed. Disconnect any peer and destroy buffers. */
  275. dgram_pair_ctrl_destroy_bio_pair(bio);
  276. CRYPTO_THREAD_lock_free(b->lock);
  277. OPENSSL_free(b);
  278. return 1;
  279. }
  280. /* BIO_make_bio_pair (BIO_C_MAKE_BIO_PAIR) */
  281. static int dgram_pair_ctrl_make_bio_pair(BIO *bio1, BIO *bio2)
  282. {
  283. struct bio_dgram_pair_st *b1, *b2;
  284. /* peer must be non-NULL. */
  285. if (bio1 == NULL || bio2 == NULL) {
  286. ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT);
  287. return 0;
  288. }
  289. /* Ensure the BIO we have been passed is actually a dgram pair BIO. */
  290. if (bio1->method != &dgram_pair_method || bio2->method != &dgram_pair_method) {
  291. ERR_raise_data(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT,
  292. "both BIOs must be BIO_dgram_pair");
  293. return 0;
  294. }
  295. b1 = bio1->ptr;
  296. b2 = bio2->ptr;
  297. if (!ossl_assert(b1 != NULL && b2 != NULL)) {
  298. ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
  299. return 0;
  300. }
  301. /*
  302. * This ctrl cannot be used to associate a BIO pair half which is already
  303. * associated.
  304. */
  305. if (b1->peer != NULL || b2->peer != NULL) {
  306. ERR_raise_data(ERR_LIB_BIO, BIO_R_IN_USE,
  307. "cannot associate a BIO_dgram_pair which is already in use");
  308. return 0;
  309. }
  310. if (!ossl_assert(b1->req_buf_len >= MIN_BUF_LEN
  311. && b2->req_buf_len >= MIN_BUF_LEN)) {
  312. ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED);
  313. return 0;
  314. }
  315. if (b1->rbuf.len != b1->req_buf_len)
  316. if (ring_buf_init(&b1->rbuf, b1->req_buf_len) == 0) {
  317. ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB);
  318. return 0;
  319. }
  320. if (b2->rbuf.len != b2->req_buf_len)
  321. if (ring_buf_init(&b2->rbuf, b2->req_buf_len) == 0) {
  322. ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB);
  323. ring_buf_destroy(&b1->rbuf);
  324. return 0;
  325. }
  326. b1->peer = bio2;
  327. b2->peer = bio1;
  328. b1->role = 0;
  329. b2->role = 1;
  330. bio1->init = 1;
  331. bio2->init = 1;
  332. return 1;
  333. }
  334. /* BIO_destroy_bio_pair (BIO_C_DESTROY_BIO_PAIR) */
  335. static int dgram_pair_ctrl_destroy_bio_pair(BIO *bio1)
  336. {
  337. BIO *bio2;
  338. struct bio_dgram_pair_st *b1 = bio1->ptr, *b2;
  339. ring_buf_destroy(&b1->rbuf);
  340. bio1->init = 0;
  341. /* Early return if we don't have a peer. */
  342. if (b1->peer == NULL)
  343. return 1;
  344. bio2 = b1->peer;
  345. b2 = bio2->ptr;
  346. /* Invariant. */
  347. if (!ossl_assert(b2->peer == bio1))
  348. return 0;
  349. /* Free buffers. */
  350. ring_buf_destroy(&b2->rbuf);
  351. bio2->init = 0;
  352. b1->peer = NULL;
  353. b2->peer = NULL;
  354. return 1;
  355. }
  356. /* BIO_eof (BIO_CTRL_EOF) */
  357. static int dgram_pair_ctrl_eof(BIO *bio)
  358. {
  359. struct bio_dgram_pair_st *b = bio->ptr, *peerb;
  360. if (!ossl_assert(b != NULL))
  361. return -1;
  362. /* If we aren't initialized, we can never read anything */
  363. if (!bio->init)
  364. return 1;
  365. if (!is_dgram_pair(b))
  366. return 0;
  367. peerb = b->peer->ptr;
  368. if (!ossl_assert(peerb != NULL))
  369. return -1;
  370. /*
  371. * Since we are emulating datagram semantics, never indicate EOF so long as
  372. * we have a peer.
  373. */
  374. return 0;
  375. }
  376. /* BIO_set_write_buf_size (BIO_C_SET_WRITE_BUF_SIZE) */
  377. static int dgram_pair_ctrl_set_write_buf_size(BIO *bio, size_t len)
  378. {
  379. struct bio_dgram_pair_st *b = bio->ptr;
  380. /* Changing buffer sizes is not permitted while a peer is connected. */
  381. if (b->peer != NULL) {
  382. ERR_raise(ERR_LIB_BIO, BIO_R_IN_USE);
  383. return 0;
  384. }
  385. /* Enforce minimum size. */
  386. if (len < MIN_BUF_LEN)
  387. len = MIN_BUF_LEN;
  388. if (b->rbuf.start != NULL) {
  389. if (!ring_buf_resize(&b->rbuf, len))
  390. return 0;
  391. }
  392. b->req_buf_len = len;
  393. b->grows_on_write = 0;
  394. return 1;
  395. }
  396. /* BIO_reset (BIO_CTRL_RESET) */
  397. static int dgram_pair_ctrl_reset(BIO *bio)
  398. {
  399. struct bio_dgram_pair_st *b = bio->ptr;
  400. ring_buf_clear(&b->rbuf);
  401. return 1;
  402. }
  403. /* BIO_pending (BIO_CTRL_PENDING) (Threadsafe) */
  404. static size_t dgram_pair_ctrl_pending(BIO *bio)
  405. {
  406. size_t saved_idx, saved_count;
  407. struct bio_dgram_pair_st *b = bio->ptr, *readb;
  408. struct dgram_hdr hdr;
  409. size_t l;
  410. /* Safe to check; init may not change during this call */
  411. if (!bio->init)
  412. return 0;
  413. if (is_dgram_pair(b))
  414. readb = b->peer->ptr;
  415. else
  416. readb = b;
  417. if (CRYPTO_THREAD_write_lock(readb->lock) == 0)
  418. return 0;
  419. saved_idx = readb->rbuf.idx[1];
  420. saved_count = readb->rbuf.count;
  421. l = dgram_pair_read_inner(readb, (uint8_t *)&hdr, sizeof(hdr));
  422. readb->rbuf.idx[1] = saved_idx;
  423. readb->rbuf.count = saved_count;
  424. CRYPTO_THREAD_unlock(readb->lock);
  425. if (!ossl_assert(l == 0 || l == sizeof(hdr)))
  426. return 0;
  427. return l > 0 ? hdr.len : 0;
  428. }
  429. /* BIO_get_write_guarantee (BIO_C_GET_WRITE_GUARANTEE) (Threadsafe) */
  430. static size_t dgram_pair_ctrl_get_write_guarantee(BIO *bio)
  431. {
  432. size_t l;
  433. struct bio_dgram_pair_st *b = bio->ptr;
  434. if (CRYPTO_THREAD_read_lock(b->lock) == 0)
  435. return 0;
  436. l = b->rbuf.len - b->rbuf.count;
  437. if (l >= sizeof(struct dgram_hdr))
  438. l -= sizeof(struct dgram_hdr);
  439. /*
  440. * If the amount of buffer space would not be enough to accommodate the
  441. * worst-case size of a datagram, report no space available.
  442. */
  443. if (l < b->mtu)
  444. l = 0;
  445. CRYPTO_THREAD_unlock(b->lock);
  446. return l;
  447. }
  448. /* BIO_dgram_get_local_addr_cap (BIO_CTRL_DGRAM_GET_LOCAL_ADDR_CAP) */
  449. static int dgram_pair_ctrl_get_local_addr_cap(BIO *bio)
  450. {
  451. struct bio_dgram_pair_st *b = bio->ptr, *readb;
  452. if (!bio->init)
  453. return 0;
  454. if (is_dgram_pair(b))
  455. readb = b->peer->ptr;
  456. else
  457. readb = b;
  458. return (~readb->cap & (BIO_DGRAM_CAP_HANDLES_SRC_ADDR
  459. | BIO_DGRAM_CAP_PROVIDES_DST_ADDR)) == 0;
  460. }
  461. /* BIO_dgram_get_effective_caps (BIO_CTRL_DGRAM_GET_EFFECTIVE_CAPS) */
  462. static int dgram_pair_ctrl_get_effective_caps(BIO *bio)
  463. {
  464. struct bio_dgram_pair_st *b = bio->ptr, *peerb;
  465. if (b->peer == NULL)
  466. return 0;
  467. peerb = b->peer->ptr;
  468. return peerb->cap;
  469. }
  470. /* BIO_dgram_get_caps (BIO_CTRL_DGRAM_GET_CAPS) */
  471. static uint32_t dgram_pair_ctrl_get_caps(BIO *bio)
  472. {
  473. struct bio_dgram_pair_st *b = bio->ptr;
  474. return b->cap;
  475. }
  476. /* BIO_dgram_set_caps (BIO_CTRL_DGRAM_SET_CAPS) */
  477. static int dgram_pair_ctrl_set_caps(BIO *bio, uint32_t caps)
  478. {
  479. struct bio_dgram_pair_st *b = bio->ptr;
  480. b->cap = caps;
  481. return 1;
  482. }
  483. /* BIO_dgram_get_local_addr_enable (BIO_CTRL_DGRAM_GET_LOCAL_ADDR_ENABLE) */
  484. static int dgram_pair_ctrl_get_local_addr_enable(BIO *bio)
  485. {
  486. struct bio_dgram_pair_st *b = bio->ptr;
  487. return b->local_addr_enable;
  488. }
  489. /* BIO_dgram_set_local_addr_enable (BIO_CTRL_DGRAM_SET_LOCAL_ADDR_ENABLE) */
  490. static int dgram_pair_ctrl_set_local_addr_enable(BIO *bio, int enable)
  491. {
  492. struct bio_dgram_pair_st *b = bio->ptr;
  493. if (dgram_pair_ctrl_get_local_addr_cap(bio) == 0)
  494. return 0;
  495. b->local_addr_enable = (enable != 0 ? 1 : 0);
  496. return 1;
  497. }
  498. /* BIO_dgram_get_mtu (BIO_CTRL_DGRAM_GET_MTU) */
  499. static int dgram_pair_ctrl_get_mtu(BIO *bio)
  500. {
  501. struct bio_dgram_pair_st *b = bio->ptr;
  502. return b->mtu;
  503. }
  504. /* BIO_dgram_set_mtu (BIO_CTRL_DGRAM_SET_MTU) */
  505. static int dgram_pair_ctrl_set_mtu(BIO *bio, size_t mtu)
  506. {
  507. struct bio_dgram_pair_st *b = bio->ptr, *peerb;
  508. b->mtu = mtu;
  509. if (b->peer != NULL) {
  510. peerb = b->peer->ptr;
  511. peerb->mtu = mtu;
  512. }
  513. return 1;
  514. }
  515. /* Partially threadsafe (some commands) */
  516. static long dgram_mem_ctrl(BIO *bio, int cmd, long num, void *ptr)
  517. {
  518. long ret = 1;
  519. struct bio_dgram_pair_st *b = bio->ptr;
  520. if (!ossl_assert(b != NULL))
  521. return 0;
  522. switch (cmd) {
  523. /*
  524. * BIO_set_write_buf_size: Set the size of the ring buffer used for storing
  525. * datagrams. No more writes can be performed once the buffer is filled up,
  526. * until reads are performed. This cannot be used after a peer is connected.
  527. */
  528. case BIO_C_SET_WRITE_BUF_SIZE: /* Non-threadsafe */
  529. ret = (long)dgram_pair_ctrl_set_write_buf_size(bio, (size_t)num);
  530. break;
  531. /*
  532. * BIO_get_write_buf_size: Get ring buffer size.
  533. */
  534. case BIO_C_GET_WRITE_BUF_SIZE: /* Non-threadsafe */
  535. ret = (long)b->req_buf_len;
  536. break;
  537. /*
  538. * BIO_reset: Clear all data which was written to this side of the pair.
  539. */
  540. case BIO_CTRL_RESET: /* Non-threadsafe */
  541. dgram_pair_ctrl_reset(bio);
  542. break;
  543. /*
  544. * BIO_get_write_guarantee: Any BIO_write providing a buffer less than or
  545. * equal to this value is guaranteed to succeed.
  546. */
  547. case BIO_C_GET_WRITE_GUARANTEE: /* Threadsafe */
  548. ret = (long)dgram_pair_ctrl_get_write_guarantee(bio);
  549. break;
  550. /* BIO_pending: Bytes available to read. */
  551. case BIO_CTRL_PENDING: /* Threadsafe */
  552. ret = (long)dgram_pair_ctrl_pending(bio);
  553. break;
  554. /* BIO_flush: No-op. */
  555. case BIO_CTRL_FLUSH: /* Threadsafe */
  556. break;
  557. /* BIO_dgram_get_no_trunc */
  558. case BIO_CTRL_DGRAM_GET_NO_TRUNC: /* Non-threadsafe */
  559. ret = (long)b->no_trunc;
  560. break;
  561. /* BIO_dgram_set_no_trunc */
  562. case BIO_CTRL_DGRAM_SET_NO_TRUNC: /* Non-threadsafe */
  563. b->no_trunc = (num > 0);
  564. break;
  565. /* BIO_dgram_get_local_addr_enable */
  566. case BIO_CTRL_DGRAM_GET_LOCAL_ADDR_ENABLE: /* Non-threadsafe */
  567. *(int *)ptr = (int)dgram_pair_ctrl_get_local_addr_enable(bio);
  568. break;
  569. /* BIO_dgram_set_local_addr_enable */
  570. case BIO_CTRL_DGRAM_SET_LOCAL_ADDR_ENABLE: /* Non-threadsafe */
  571. ret = (long)dgram_pair_ctrl_set_local_addr_enable(bio, num);
  572. break;
  573. /* BIO_dgram_get_local_addr_cap: Can local addresses be supported? */
  574. case BIO_CTRL_DGRAM_GET_LOCAL_ADDR_CAP: /* Non-threadsafe */
  575. ret = (long)dgram_pair_ctrl_get_local_addr_cap(bio);
  576. break;
  577. /* BIO_dgram_get_effective_caps */
  578. case BIO_CTRL_DGRAM_GET_EFFECTIVE_CAPS: /* Non-threadsafe */
  579. /* BIO_dgram_get_caps */
  580. case BIO_CTRL_DGRAM_GET_CAPS: /* Non-threadsafe */
  581. ret = (long)dgram_pair_ctrl_get_caps(bio);
  582. break;
  583. /* BIO_dgram_set_caps */
  584. case BIO_CTRL_DGRAM_SET_CAPS: /* Non-threadsafe */
  585. ret = (long)dgram_pair_ctrl_set_caps(bio, (uint32_t)num);
  586. break;
  587. /* BIO_dgram_get_mtu */
  588. case BIO_CTRL_DGRAM_GET_MTU: /* Non-threadsafe */
  589. ret = (long)dgram_pair_ctrl_get_mtu(bio);
  590. break;
  591. /* BIO_dgram_set_mtu */
  592. case BIO_CTRL_DGRAM_SET_MTU: /* Non-threadsafe */
  593. ret = (long)dgram_pair_ctrl_set_mtu(bio, (uint32_t)num);
  594. break;
  595. /*
  596. * BIO_eof: Returns whether this half of the BIO pair is empty of data to
  597. * read.
  598. */
  599. case BIO_CTRL_EOF: /* Non-threadsafe */
  600. ret = (long)dgram_pair_ctrl_eof(bio);
  601. break;
  602. default:
  603. ret = 0;
  604. break;
  605. }
  606. return ret;
  607. }
  608. static long dgram_pair_ctrl(BIO *bio, int cmd, long num, void *ptr)
  609. {
  610. long ret = 1;
  611. switch (cmd) {
  612. /*
  613. * BIO_make_bio_pair: this is usually used by BIO_new_dgram_pair, though it
  614. * may be used manually after manually creating each half of a BIO pair
  615. * using BIO_new. This only needs to be called on one of the BIOs.
  616. */
  617. case BIO_C_MAKE_BIO_PAIR: /* Non-threadsafe */
  618. ret = (long)dgram_pair_ctrl_make_bio_pair(bio, (BIO *)ptr);
  619. break;
  620. /*
  621. * BIO_destroy_bio_pair: Manually disconnect two halves of a BIO pair so
  622. * that they are no longer peers.
  623. */
  624. case BIO_C_DESTROY_BIO_PAIR: /* Non-threadsafe */
  625. dgram_pair_ctrl_destroy_bio_pair(bio);
  626. break;
  627. /* BIO_dgram_get_effective_caps */
  628. case BIO_CTRL_DGRAM_GET_EFFECTIVE_CAPS: /* Non-threadsafe */
  629. ret = (long)dgram_pair_ctrl_get_effective_caps(bio);
  630. break;
  631. default:
  632. ret = dgram_mem_ctrl(bio, cmd, num, ptr);
  633. break;
  634. }
  635. return ret;
  636. }
  637. int BIO_new_bio_dgram_pair(BIO **pbio1, size_t writebuf1,
  638. BIO **pbio2, size_t writebuf2)
  639. {
  640. int ret = 0;
  641. long r;
  642. BIO *bio1 = NULL, *bio2 = NULL;
  643. bio1 = BIO_new(BIO_s_dgram_pair());
  644. if (bio1 == NULL)
  645. goto err;
  646. bio2 = BIO_new(BIO_s_dgram_pair());
  647. if (bio2 == NULL)
  648. goto err;
  649. if (writebuf1 > 0) {
  650. r = BIO_set_write_buf_size(bio1, writebuf1);
  651. if (r == 0)
  652. goto err;
  653. }
  654. if (writebuf2 > 0) {
  655. r = BIO_set_write_buf_size(bio2, writebuf2);
  656. if (r == 0)
  657. goto err;
  658. }
  659. r = BIO_make_bio_pair(bio1, bio2);
  660. if (r == 0)
  661. goto err;
  662. ret = 1;
  663. err:
  664. if (ret == 0) {
  665. BIO_free(bio1);
  666. bio1 = NULL;
  667. BIO_free(bio2);
  668. bio2 = NULL;
  669. }
  670. *pbio1 = bio1;
  671. *pbio2 = bio2;
  672. return ret;
  673. }
  674. /* Must hold peer write lock */
  675. static size_t dgram_pair_read_inner(struct bio_dgram_pair_st *b, uint8_t *buf, size_t sz)
  676. {
  677. size_t total_read = 0;
  678. /*
  679. * We repeat pops from the ring buffer for as long as we have more
  680. * application *buffer to fill until we fail. We may not be able to pop
  681. * enough data to fill the buffer in one operation if the ring buffer wraps
  682. * around, but there may still be more data available.
  683. */
  684. while (sz > 0) {
  685. uint8_t *src_buf = NULL;
  686. size_t src_len = 0;
  687. /*
  688. * There are two BIO instances, each with a ringbuf. We read from the
  689. * peer ringbuf and write to our own ringbuf.
  690. */
  691. ring_buf_tail(&b->rbuf, &src_buf, &src_len);
  692. if (src_len == 0)
  693. break;
  694. if (src_len > sz)
  695. src_len = sz;
  696. if (buf != NULL)
  697. memcpy(buf, src_buf, src_len);
  698. ring_buf_pop(&b->rbuf, src_len);
  699. if (buf != NULL)
  700. buf += src_len;
  701. total_read += src_len;
  702. sz -= src_len;
  703. }
  704. return total_read;
  705. }
  706. /*
  707. * Must hold peer write lock. Returns number of bytes processed or negated BIO
  708. * response code.
  709. */
  710. static ossl_ssize_t dgram_pair_read_actual(BIO *bio, char *buf, size_t sz,
  711. BIO_ADDR *local, BIO_ADDR *peer,
  712. int is_multi)
  713. {
  714. size_t l, trunc = 0, saved_idx, saved_count;
  715. struct bio_dgram_pair_st *b = bio->ptr, *readb;
  716. struct dgram_hdr hdr;
  717. if (!is_multi)
  718. BIO_clear_retry_flags(bio);
  719. if (!bio->init)
  720. return -BIO_R_UNINITIALIZED;
  721. if (!ossl_assert(b != NULL))
  722. return -BIO_R_TRANSFER_ERROR;
  723. if (is_dgram_pair(b))
  724. readb = b->peer->ptr;
  725. else
  726. readb = b;
  727. if (!ossl_assert(readb != NULL && readb->rbuf.start != NULL))
  728. return -BIO_R_TRANSFER_ERROR;
  729. if (sz > 0 && buf == NULL)
  730. return -BIO_R_INVALID_ARGUMENT;
  731. /* If the caller wants to know the local address, it must be enabled */
  732. if (local != NULL && b->local_addr_enable == 0)
  733. return -BIO_R_LOCAL_ADDR_NOT_AVAILABLE;
  734. /* Read the header. */
  735. saved_idx = readb->rbuf.idx[1];
  736. saved_count = readb->rbuf.count;
  737. l = dgram_pair_read_inner(readb, (uint8_t *)&hdr, sizeof(hdr));
  738. if (l == 0) {
  739. /* Buffer was empty. */
  740. if (!is_multi)
  741. BIO_set_retry_read(bio);
  742. return -BIO_R_NON_FATAL;
  743. }
  744. if (!ossl_assert(l == sizeof(hdr)))
  745. /*
  746. * This should not be possible as headers (and their following payloads)
  747. * should always be written atomically.
  748. */
  749. return -BIO_R_BROKEN_PIPE;
  750. if (sz > hdr.len) {
  751. sz = hdr.len;
  752. } else if (sz < hdr.len) {
  753. /* Truncation is occurring. */
  754. trunc = hdr.len - sz;
  755. if (b->no_trunc) {
  756. /* Restore original state. */
  757. readb->rbuf.idx[1] = saved_idx;
  758. readb->rbuf.count = saved_count;
  759. return -BIO_R_NON_FATAL;
  760. }
  761. }
  762. l = dgram_pair_read_inner(readb, (uint8_t *)buf, sz);
  763. if (!ossl_assert(l == sz))
  764. /* We were somehow not able to read the entire datagram. */
  765. return -BIO_R_TRANSFER_ERROR;
  766. /*
  767. * If the datagram was truncated due to an inadequate buffer, discard the
  768. * remainder.
  769. */
  770. if (trunc > 0 && !ossl_assert(dgram_pair_read_inner(readb, NULL, trunc) == trunc))
  771. /* We were somehow not able to read/skip the entire datagram. */
  772. return -BIO_R_TRANSFER_ERROR;
  773. if (local != NULL)
  774. *local = hdr.dst_addr;
  775. if (peer != NULL)
  776. *peer = hdr.src_addr;
  777. return (ossl_ssize_t)l;
  778. }
  779. /* Threadsafe */
  780. static int dgram_pair_lock_both_write(struct bio_dgram_pair_st *a,
  781. struct bio_dgram_pair_st *b)
  782. {
  783. struct bio_dgram_pair_st *x, *y;
  784. x = (a->role == 1) ? a : b;
  785. y = (a->role == 1) ? b : a;
  786. if (!ossl_assert(a->role != b->role))
  787. return 0;
  788. if (!ossl_assert(a != b && x != y))
  789. return 0;
  790. if (CRYPTO_THREAD_write_lock(x->lock) == 0)
  791. return 0;
  792. if (CRYPTO_THREAD_write_lock(y->lock) == 0) {
  793. CRYPTO_THREAD_unlock(x->lock);
  794. return 0;
  795. }
  796. return 1;
  797. }
  798. static void dgram_pair_unlock_both(struct bio_dgram_pair_st *a,
  799. struct bio_dgram_pair_st *b)
  800. {
  801. CRYPTO_THREAD_unlock(a->lock);
  802. CRYPTO_THREAD_unlock(b->lock);
  803. }
  804. /* Threadsafe */
  805. static int dgram_pair_read(BIO *bio, char *buf, int sz_)
  806. {
  807. int ret;
  808. ossl_ssize_t l;
  809. struct bio_dgram_pair_st *b = bio->ptr, *peerb;
  810. if (sz_ < 0) {
  811. ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT);
  812. return -1;
  813. }
  814. if (b->peer == NULL) {
  815. ERR_raise(ERR_LIB_BIO, BIO_R_BROKEN_PIPE);
  816. return -1;
  817. }
  818. peerb = b->peer->ptr;
  819. /*
  820. * For BIO_read we have to acquire both locks because we touch the retry
  821. * flags on the local bio. (This is avoided in the recvmmsg case as it does
  822. * not touch the retry flags.)
  823. */
  824. if (dgram_pair_lock_both_write(peerb, b) == 0) {
  825. ERR_raise(ERR_LIB_BIO, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
  826. return -1;
  827. }
  828. l = dgram_pair_read_actual(bio, buf, (size_t)sz_, NULL, NULL, 0);
  829. if (l < 0) {
  830. if (l != -BIO_R_NON_FATAL)
  831. ERR_raise(ERR_LIB_BIO, -l);
  832. ret = -1;
  833. } else {
  834. ret = (int)l;
  835. }
  836. dgram_pair_unlock_both(peerb, b);
  837. return ret;
  838. }
  839. /* Threadsafe */
  840. static int dgram_pair_recvmmsg(BIO *bio, BIO_MSG *msg,
  841. size_t stride, size_t num_msg,
  842. uint64_t flags,
  843. size_t *num_processed)
  844. {
  845. int ret;
  846. ossl_ssize_t l;
  847. BIO_MSG *m;
  848. size_t i;
  849. struct bio_dgram_pair_st *b = bio->ptr, *readb;
  850. if (num_msg == 0) {
  851. *num_processed = 0;
  852. return 1;
  853. }
  854. if (!bio->init) {
  855. ERR_raise(ERR_LIB_BIO, BIO_R_BROKEN_PIPE);
  856. *num_processed = 0;
  857. return 0;
  858. }
  859. if (is_dgram_pair(b))
  860. readb = b->peer->ptr;
  861. else
  862. readb = b;
  863. if (CRYPTO_THREAD_write_lock(readb->lock) == 0) {
  864. ERR_raise(ERR_LIB_BIO, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
  865. *num_processed = 0;
  866. return 0;
  867. }
  868. for (i = 0; i < num_msg; ++i) {
  869. m = &BIO_MSG_N(msg, i);
  870. l = dgram_pair_read_actual(bio, m->data, m->data_len,
  871. m->local, m->peer, 1);
  872. if (l < 0) {
  873. *num_processed = i;
  874. if (i > 0) {
  875. ret = 1;
  876. } else {
  877. ERR_raise(ERR_LIB_BIO, -l);
  878. ret = 0;
  879. }
  880. goto out;
  881. }
  882. m->data_len = l;
  883. m->flags = 0;
  884. }
  885. *num_processed = i;
  886. ret = 1;
  887. out:
  888. CRYPTO_THREAD_unlock(readb->lock);
  889. return ret;
  890. }
  891. /* Threadsafe */
  892. static int dgram_mem_read(BIO *bio, char *buf, int sz_)
  893. {
  894. int ret;
  895. ossl_ssize_t l;
  896. struct bio_dgram_pair_st *b = bio->ptr;
  897. if (sz_ < 0) {
  898. ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT);
  899. return -1;
  900. }
  901. if (CRYPTO_THREAD_write_lock(b->lock) == 0) {
  902. ERR_raise(ERR_LIB_BIO, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
  903. return -1;
  904. }
  905. l = dgram_pair_read_actual(bio, buf, (size_t)sz_, NULL, NULL, 0);
  906. if (l < 0) {
  907. if (l != -BIO_R_NON_FATAL)
  908. ERR_raise(ERR_LIB_BIO, -l);
  909. ret = -1;
  910. } else {
  911. ret = (int)l;
  912. }
  913. CRYPTO_THREAD_unlock(b->lock);
  914. return ret;
  915. }
  916. /*
  917. * Calculate the array growth based on the target size.
  918. *
  919. * The growth factor is a rational number and is defined by a numerator
  920. * and a denominator. According to Andrew Koenig in his paper "Why Are
  921. * Vectors Efficient?" from JOOP 11(5) 1998, this factor should be less
  922. * than the golden ratio (1.618...).
  923. *
  924. * We use an expansion factor of 8 / 5 = 1.6
  925. */
  926. static const size_t max_rbuf_size = SIZE_MAX / 2; /* unlimited in practice */
  927. static ossl_inline size_t compute_rbuf_growth(size_t target, size_t current)
  928. {
  929. int err = 0;
  930. while (current < target) {
  931. if (current >= max_rbuf_size)
  932. return 0;
  933. current = safe_muldiv_size_t(current, 8, 5, &err);
  934. if (err)
  935. return 0;
  936. if (current >= max_rbuf_size)
  937. current = max_rbuf_size;
  938. }
  939. return current;
  940. }
  941. /* Must hold local write lock */
  942. static size_t dgram_pair_write_inner(struct bio_dgram_pair_st *b,
  943. const uint8_t *buf, size_t sz)
  944. {
  945. size_t total_written = 0;
  946. /*
  947. * We repeat pushes to the ring buffer for as long as we have data until we
  948. * fail. We may not be able to push in one operation if the ring buffer
  949. * wraps around, but there may still be more room for data.
  950. */
  951. while (sz > 0) {
  952. size_t dst_len;
  953. uint8_t *dst_buf;
  954. /*
  955. * There are two BIO instances, each with a ringbuf. We write to our own
  956. * ringbuf and read from the peer ringbuf.
  957. */
  958. ring_buf_head(&b->rbuf, &dst_buf, &dst_len);
  959. if (dst_len == 0) {
  960. size_t new_len;
  961. if (!b->grows_on_write) /* resize only if size not set explicitly */
  962. break;
  963. /* increase the size */
  964. new_len = compute_rbuf_growth(b->req_buf_len + sz, b->req_buf_len);
  965. if (new_len == 0 || !ring_buf_resize(&b->rbuf, new_len))
  966. break;
  967. b->req_buf_len = new_len;
  968. }
  969. if (dst_len > sz)
  970. dst_len = sz;
  971. memcpy(dst_buf, buf, dst_len);
  972. ring_buf_push(&b->rbuf, dst_len);
  973. buf += dst_len;
  974. sz -= dst_len;
  975. total_written += dst_len;
  976. }
  977. return total_written;
  978. }
  979. /*
  980. * Must hold local write lock. Returns number of bytes processed or negated BIO
  981. * response code.
  982. */
  983. static ossl_ssize_t dgram_pair_write_actual(BIO *bio, const char *buf, size_t sz,
  984. const BIO_ADDR *local, const BIO_ADDR *peer,
  985. int is_multi)
  986. {
  987. static const BIO_ADDR zero_addr;
  988. size_t saved_idx, saved_count;
  989. struct bio_dgram_pair_st *b = bio->ptr, *readb;
  990. struct dgram_hdr hdr = {0};
  991. if (!is_multi)
  992. BIO_clear_retry_flags(bio);
  993. if (!bio->init)
  994. return -BIO_R_UNINITIALIZED;
  995. if (!ossl_assert(b != NULL && b->rbuf.start != NULL))
  996. return -BIO_R_TRANSFER_ERROR;
  997. if (sz > 0 && buf == NULL)
  998. return -BIO_R_INVALID_ARGUMENT;
  999. if (local != NULL && b->local_addr_enable == 0)
  1000. return -BIO_R_LOCAL_ADDR_NOT_AVAILABLE;
  1001. if (is_dgram_pair(b))
  1002. readb = b->peer->ptr;
  1003. else
  1004. readb = b;
  1005. if (peer != NULL && (readb->cap & BIO_DGRAM_CAP_HANDLES_DST_ADDR) == 0)
  1006. return -BIO_R_PEER_ADDR_NOT_AVAILABLE;
  1007. hdr.len = sz;
  1008. hdr.dst_addr = (peer != NULL ? *peer : zero_addr);
  1009. hdr.src_addr = (local != NULL ? *local : zero_addr);
  1010. saved_idx = b->rbuf.idx[0];
  1011. saved_count = b->rbuf.count;
  1012. if (dgram_pair_write_inner(b, (const uint8_t *)&hdr, sizeof(hdr)) != sizeof(hdr)
  1013. || dgram_pair_write_inner(b, (const uint8_t *)buf, sz) != sz) {
  1014. /*
  1015. * We were not able to push the header and the entirety of the payload
  1016. * onto the ring buffer, so abort and roll back the ring buffer state.
  1017. */
  1018. b->rbuf.idx[0] = saved_idx;
  1019. b->rbuf.count = saved_count;
  1020. if (!is_multi)
  1021. BIO_set_retry_write(bio);
  1022. return -BIO_R_NON_FATAL;
  1023. }
  1024. return sz;
  1025. }
  1026. /* Threadsafe */
  1027. static int dgram_pair_write(BIO *bio, const char *buf, int sz_)
  1028. {
  1029. int ret;
  1030. ossl_ssize_t l;
  1031. struct bio_dgram_pair_st *b = bio->ptr;
  1032. if (sz_ < 0) {
  1033. ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT);
  1034. return -1;
  1035. }
  1036. if (CRYPTO_THREAD_write_lock(b->lock) == 0) {
  1037. ERR_raise(ERR_LIB_BIO, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
  1038. return -1;
  1039. }
  1040. l = dgram_pair_write_actual(bio, buf, (size_t)sz_, NULL, NULL, 0);
  1041. if (l < 0) {
  1042. ERR_raise(ERR_LIB_BIO, -l);
  1043. ret = -1;
  1044. } else {
  1045. ret = (int)l;
  1046. }
  1047. CRYPTO_THREAD_unlock(b->lock);
  1048. return ret;
  1049. }
  1050. /* Threadsafe */
  1051. static int dgram_pair_sendmmsg(BIO *bio, BIO_MSG *msg,
  1052. size_t stride, size_t num_msg,
  1053. uint64_t flags, size_t *num_processed)
  1054. {
  1055. ossl_ssize_t ret, l;
  1056. BIO_MSG *m;
  1057. size_t i;
  1058. struct bio_dgram_pair_st *b = bio->ptr;
  1059. if (num_msg == 0) {
  1060. *num_processed = 0;
  1061. return 1;
  1062. }
  1063. if (CRYPTO_THREAD_write_lock(b->lock) == 0) {
  1064. ERR_raise(ERR_LIB_BIO, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
  1065. *num_processed = 0;
  1066. return 0;
  1067. }
  1068. for (i = 0; i < num_msg; ++i) {
  1069. m = &BIO_MSG_N(msg, i);
  1070. l = dgram_pair_write_actual(bio, m->data, m->data_len,
  1071. m->local, m->peer, 1);
  1072. if (l < 0) {
  1073. *num_processed = i;
  1074. if (i > 0) {
  1075. ret = 1;
  1076. } else {
  1077. ERR_raise(ERR_LIB_BIO, -l);
  1078. ret = 0;
  1079. }
  1080. goto out;
  1081. }
  1082. m->flags = 0;
  1083. }
  1084. *num_processed = i;
  1085. ret = 1;
  1086. out:
  1087. CRYPTO_THREAD_unlock(b->lock);
  1088. return ret;
  1089. }
  1090. #endif