summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/bio/bss_conn.c1
-rw-r--r--crypto/bio/bss_dgram.c22
-rw-r--r--include/openssl/bio.h.in3
3 files changed, 26 insertions, 0 deletions
diff --git a/crypto/bio/bss_conn.c b/crypto/bio/bss_conn.c
index 0f9cba06da..8d29f94bd1 100644
--- a/crypto/bio/bss_conn.c
+++ b/crypto/bio/bss_conn.c
@@ -571,6 +571,7 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
}
break;
case BIO_CTRL_DGRAM_GET_PEER:
+ case BIO_CTRL_DGRAM_DETECT_PEER_ADDR:
if (data->state != BIO_CONN_S_OK)
conn_state(b, data); /* best effort */
diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c
index 49cf56ad19..eb6897a3fd 100644
--- a/crypto/bio/bss_dgram.c
+++ b/crypto/bio/bss_dgram.c
@@ -722,6 +722,28 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
case BIO_CTRL_DGRAM_SET_PEER:
BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
break;
+ case BIO_CTRL_DGRAM_DETECT_PEER_ADDR:
+ {
+ BIO_ADDR xaddr, *p = &data->peer;
+ socklen_t xaddr_len = sizeof(xaddr.sa);
+
+ if (BIO_ADDR_family(p) == AF_UNSPEC) {
+ if (getpeername(b->num, (void *)&xaddr.sa, &xaddr_len) == 0
+ && BIO_ADDR_family(&xaddr) != AF_UNSPEC) {
+ p = &xaddr;
+ } else {
+ ret = 0;
+ break;
+ }
+ }
+
+ ret = BIO_ADDR_sockaddr_size(p);
+ if (num == 0 || num > ret)
+ num = ret;
+
+ memcpy(ptr, p, (ret = num));
+ }
+ break;
case BIO_C_SET_NBIO:
if (!BIO_socket_nbio(b->num, num != 0))
ret = 0;
diff --git a/include/openssl/bio.h.in b/include/openssl/bio.h.in
index 9d196c7ae5..e797769909 100644
--- a/include/openssl/bio.h.in
+++ b/include/openssl/bio.h.in
@@ -190,6 +190,7 @@ extern "C" {
# define BIO_CTRL_GET_RPOLL_DESCRIPTOR 90
# define BIO_CTRL_GET_WPOLL_DESCRIPTOR 91
+# define BIO_CTRL_DGRAM_DETECT_PEER_ADDR 92
# define BIO_DGRAM_CAP_NONE 0U
# define BIO_DGRAM_CAP_HANDLES_SRC_ADDR (1U << 0)
@@ -639,6 +640,8 @@ int BIO_ctrl_reset_read_request(BIO *b);
(int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)(peer))
# define BIO_dgram_set_peer(b,peer) \
(int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)(peer))
+# define BIO_dgram_detect_peer_addr(b,peer) \
+ (int)BIO_ctrl(b, BIO_CTRL_DGRAM_DETECT_PEER_ADDR, 0, (char *)(peer))
# define BIO_dgram_get_mtu_overhead(b) \
(unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU_OVERHEAD, 0, NULL)
# define BIO_dgram_get_local_addr_cap(b) \