Skip to content

Commit

Permalink
BIO_dgram support for BIO_sendmmsg/BIO_recvmmsg
Browse files Browse the repository at this point in the history
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from openssl#18270)
  • Loading branch information
hlandau authored and sftcd committed Sep 24, 2022
1 parent 9d84240 commit 365b1f7
Show file tree
Hide file tree
Showing 12 changed files with 1,443 additions and 8 deletions.
6 changes: 6 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,12 @@ OpenSSL 3.1

*David von Oheimb*

* Add new BIO_sendmmsg() and BIO_recvmmsg() BIO methods which allow
sending and receiving multiple messages in a single call. An implementation
is provided for BIO_dgram. For further details, see BIO_sendmmsg(3).

*Hugo Landau*

OpenSSL 3.0
-----------

Expand Down
3 changes: 3 additions & 0 deletions crypto/bio/bio_err.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ static const ERR_STRING_DATA BIO_str_reasons[] = {
"no hostname or service specified"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_PORT_DEFINED), "no port defined"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_SUCH_FILE), "no such file"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_PORT_MISMATCH), "port mismatch"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TFO_DISABLED), "tfo disabled"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TFO_NO_KERNEL_SUPPORT),
"tfo no kernel support"},
Expand Down Expand Up @@ -79,6 +80,8 @@ static const ERR_STRING_DATA BIO_str_reasons[] = {
"local address not available"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NON_FATAL),
"non-fatal or transient error"},
{ERR_PACK(ERR_LIB_BIO, 0, BIO_R_PORT_MISMATCH),
"port mismatch"},
{0, NULL}
};

Expand Down
6 changes: 6 additions & 0 deletions crypto/bio/bio_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,12 @@ struct sockaddr *BIO_ADDR_sockaddr_noconst(BIO_ADDR *ap);
socklen_t BIO_ADDR_sockaddr_size(const BIO_ADDR *ap);
socklen_t BIO_ADDRINFO_sockaddr_size(const BIO_ADDRINFO *bai);
const struct sockaddr *BIO_ADDRINFO_sockaddr(const BIO_ADDRINFO *bai);

# if defined(OPENSSL_SYS_WINDOWS) && defined(WSAID_WSARECVMSG)
# define BIO_HAVE_WSAMSG
extern LPFN_WSARECVMSG bio_WSARecvMsg;
extern LPFN_WSASENDMSG bio_WSASendMsg;
# endif
#endif

extern CRYPTO_RWLOCK *bio_type_lock;
Expand Down
38 changes: 38 additions & 0 deletions crypto/bio/bio_sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ struct hostent *BIO_gethostbyname(const char *name)
}
# endif

# ifdef BIO_HAVE_WSAMSG
LPFN_WSARECVMSG bio_WSARecvMsg;
LPFN_WSASENDMSG bio_WSASendMsg;
# endif

int BIO_sock_init(void)
{
# ifdef OPENSSL_SYS_WINDOWS
Expand All @@ -150,6 +155,39 @@ int BIO_sock_init(void)
ERR_raise(ERR_LIB_BIO, BIO_R_WSASTARTUP);
return -1;
}

/*
* On Windows, some socket functions are not exposed as a prototype.
* Instead, their function pointers must be loaded via this elaborate
* process...
*/
# ifdef BIO_HAVE_WSAMSG
{
GUID id_WSARecvMsg = WSAID_WSARECVMSG;
GUID id_WSASendMsg = WSAID_WSASENDMSG;
DWORD len_out = 0;
SOCKET s;

s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s != INVALID_SOCKET) {
if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER,
&id_WSARecvMsg, sizeof(id_WSARecvMsg),
&bio_WSARecvMsg, sizeof(bio_WSARecvMsg),
&len_out, NULL, NULL) != 0
|| len_out != sizeof(bio_WSARecvMsg))
bio_WSARecvMsg = NULL;

if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER,
&id_WSASendMsg, sizeof(id_WSASendMsg),
&bio_WSASendMsg, sizeof(bio_WSASendMsg),
&len_out, NULL, NULL) != 0
|| len_out != sizeof(bio_WSASendMsg))
bio_WSASendMsg = NULL;

closesocket(s);
}
}
# endif
}
# endif /* OPENSSL_SYS_WINDOWS */
# ifdef WATT32
Expand Down
Loading

0 comments on commit 365b1f7

Please sign in to comment.