bss_dgram_pair.c 30 KB

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