size_t mtu;
/* Capability flags. */
uint32_t cap;
+ /* The local address to use (if set) */
+ BIO_ADDR *local_addr;
/*
* This lock protects updates to our rbuf. Since writes are directed to our
* own rbuf, this means we use this lock for writes and our peer's lock for
ring_buf_destroy(&b1->rbuf);
bio1->init = 0;
+ BIO_ADDR_free(b1->local_addr);
+
/* Early return if we don't have a peer. */
if (b1->peer == NULL)
return 1;
return 1;
}
+/* BIO_dgram_set0_local_addr (BIO_CTRL_DGRAM_SET0_LOCAL_ADDR) */
+static int dgram_pair_ctrl_set0_local_addr(BIO *bio, BIO_ADDR *addr)
+{
+ struct bio_dgram_pair_st *b = bio->ptr;
+
+ BIO_ADDR_free(b->local_addr);
+ b->local_addr = addr;
+ return 1;
+}
+
/* Partially threadsafe (some commands) */
static long dgram_mem_ctrl(BIO *bio, int cmd, long num, void *ptr)
{
ret = (long)dgram_pair_ctrl_set_mtu(bio, (uint32_t)num);
break;
+ case BIO_CTRL_DGRAM_SET0_LOCAL_ADDR:
+ ret = (long)dgram_pair_ctrl_set0_local_addr(bio, (BIO_ADDR *)ptr);
+ break;
+
/*
* BIO_eof: Returns whether this half of the BIO pair is empty of data to
* read.
hdr.len = sz;
hdr.dst_addr = (peer != NULL ? *peer : zero_addr);
+ if (local == NULL)
+ local = b->local_addr;
hdr.src_addr = (local != NULL ? *local : zero_addr);
saved_idx = b->rbuf.idx[0];
# define BIO_CTRL_GET_RPOLL_DESCRIPTOR 91
# define BIO_CTRL_GET_WPOLL_DESCRIPTOR 92
# define BIO_CTRL_DGRAM_DETECT_PEER_ADDR 93
+# define BIO_CTRL_DGRAM_SET0_LOCAL_ADDR 94
# define BIO_DGRAM_CAP_NONE 0U
# define BIO_DGRAM_CAP_HANDLES_SRC_ADDR (1U << 0)
(unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU, 0, NULL)
# define BIO_dgram_set_mtu(b, mtu) \
(int)BIO_ctrl((b), BIO_CTRL_DGRAM_SET_MTU, (mtu), NULL)
+# define BIO_dgram_set0_local_addr(b, addr) \
+ (int)BIO_ctrl((b), BIO_CTRL_DGRAM_SET0_LOCAL_ADDR, 0, (addr))
/* ctrl macros for BIO_f_prefix */
# define BIO_set_prefix(b,p) BIO_ctrl((b), BIO_CTRL_SET_PREFIX, 0, (void *)(p))
goto err;
#endif
} else {
+ BIO_ADDR *localaddr = NULL;
+
if (!TEST_true(BIO_new_bio_dgram_pair(&cbio, 0, &sbio, 0)))
goto err;
|| !TEST_true(BIO_dgram_set_caps(sbio, BIO_DGRAM_CAP_HANDLES_DST_ADDR)))
goto err;
+ if (!TEST_ptr(localaddr = BIO_ADDR_new()))
+ goto err;
+ /* Dummy client local addresses */
+ if (!TEST_true(BIO_ADDR_rawmake(localaddr, AF_INET, &ina, sizeof(ina),
+ htons(0)))) {
+ BIO_ADDR_free(localaddr);
+ goto err;
+ }
+ if (!TEST_int_eq(BIO_dgram_set0_local_addr(cbio, localaddr), 1)) {
+ BIO_ADDR_free(localaddr);
+ goto err;
+ }
/* Dummy server address */
if (!TEST_true(BIO_ADDR_rawmake(peeraddr, AF_INET, &ina, sizeof(ina),
htons(0))))