checkpoint: complete test_wolfSSL_BIO_datagram(); fix some WOLFSSL_HAVE_BIO_ADDR gates to also gate on WOLFSSL_DTLS and OPENSSL_EXTRA; use DTLS_RECVFROM_FUNCTION, DTLS_SENDTO_FUNCTION, SOCKET_T, SOCKADDR, SOCKADDR_IN, and SOCKADDR_IN6 macros and types, and add SOCKADDR_UN type.

This commit is contained in:
Daniel Pouzzner
2024-06-05 00:24:21 -05:00
parent bd7f7c8bdf
commit 7216a543dd
5 changed files with 150 additions and 31 deletions

View File

@@ -851,6 +851,11 @@ long wolfSSL_BIO_ctrl(WOLFSSL_BIO *bio, int cmd, long larg, void *parg)
bio->peer_addr = (WOLFSSL_BIO_ADDR *)parg; bio->peer_addr = (WOLFSSL_BIO_ADDR *)parg;
ret = WOLFSSL_SUCCESS; ret = WOLFSSL_SUCCESS;
break; break;
case BIO_CTRL_DGRAM_QUERY_MTU:
return 0; /* not implemented */
break;
#endif /* WOLFSSL_HAVE_BIO_ADDR */ #endif /* WOLFSSL_HAVE_BIO_ADDR */
default: default:

View File

@@ -1113,14 +1113,14 @@ int wolfIO_Send(SOCKET_T sd, char *buf, int sz, int wrFlags)
return sent; return sent;
} }
#ifdef WOLFSSL_HAVE_BIO_ADDR #if defined(WOLFSSL_HAVE_BIO_ADDR) && defined(WOLFSSL_DTLS) && defined(OPENSSL_EXTRA)
int wolfIO_RecvFrom(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, int sz, int rdFlags) int wolfIO_RecvFrom(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, int sz, int rdFlags)
{ {
int recvd; int recvd;
socklen_t addr_len = (socklen_t)sizeof(*addr); socklen_t addr_len = (socklen_t)sizeof(*addr);
recvd = (int)recvfrom(sd, buf, (size_t)sz, rdFlags, addr ? &addr->sa : NULL, addr ? &addr_len : 0); recvd = (int)DTLS_RECVFROM_FUNCTION(sd, buf, (size_t)sz, rdFlags, addr ? &addr->sa : NULL, addr ? &addr_len : 0);
recvd = TranslateReturnCode(recvd, (int)sd); recvd = TranslateReturnCode(recvd, (int)sd);
return recvd; return recvd;
@@ -1130,13 +1130,13 @@ int wolfIO_SendTo(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, int sz, int wr
{ {
int sent; int sent;
sent = (int)sendto(sd, buf, (size_t)sz, wrFlags, addr ? &addr->sa : NULL, addr ? wolfSSL_BIO_ADDR_size(addr) : 0); sent = (int)DTLS_SENDTO_FUNCTION(sd, buf, (size_t)sz, wrFlags, addr ? &addr->sa : NULL, addr ? wolfSSL_BIO_ADDR_size(addr) : 0);
sent = TranslateReturnCode(sent, (int)sd); sent = TranslateReturnCode(sent, (int)sd);
return sent; return sent;
} }
#endif /* WOLFSSL_HAVE_BIO_ADDR */ #endif /* WOLFSSL_HAVE_BIO_ADDR && WOLFSSL_DTLS && OPENSSL_EXTRA */
#endif /* USE_WOLFSSL_IO */ #endif /* USE_WOLFSSL_IO */

View File

@@ -56968,25 +56968,35 @@ static int test_wolfSSL_BIO_tls(void)
} }
static int test_wolfSSL_BIO_datagram(void) static int test_wolfSSL_BIO_datagram(void)
{ {
EXPECT_DECLS; EXPECT_DECLS;
#if !defined(NO_BIO) && defined(WOLFSSL_HAVE_BIO_ADDR) #if !defined(NO_BIO) && defined(WOLFSSL_DTLS) && defined(WOLFSSL_HAVE_BIO_ADDR) && defined(OPENSSL_EXTRA)
int ret; int ret;
int fd1 = -1, fd2 = -1; SOCKET_T fd1 = 0, fd2 = 0; /* SOCKET_T is unsigned on Windows */
WOLFSSL_BIO *bio1 = NULL, *bio2 = NULL; WOLFSSL_BIO *bio1 = NULL, *bio2 = NULL;
WOLFSSL_BIO_ADDR *bio_addr1, *bio_addr2; WOLFSSL_BIO_ADDR *bio_addr1 = NULL, *bio_addr2 = NULL;
struct sockaddr_in sin1, sin2; SOCKADDR_IN sin1, sin2;
socklen_t slen; socklen_t slen;
static const char test_msg[] = "I am a datagram, short and stout.";
char test_msg_recvd[sizeof(test_msg) + 10];
#ifdef USE_WINDOWS_API
static const DWORD timeout = 250; /* ms */
#else
static const struct timeval timeout = { 0, 250000 };
#endif
#ifdef USE_WINDOWS_API
WSAStartup();
#endif
if (EXPECT_SUCCESS()) { if (EXPECT_SUCCESS()) {
fd1 = socket(AF_INET, SOCK_DGRAM, 17 /* UDP */); fd1 = socket(AF_INET, SOCK_DGRAM, 17 /* UDP */);
ExpectIntGE(fd1, 0); ExpectIntGT(fd1, 0);
} }
if (EXPECT_SUCCESS()) { if (EXPECT_SUCCESS()) {
fd2 = socket(AF_INET, SOCK_DGRAM, 17 /* UDP */); fd2 = socket(AF_INET, SOCK_DGRAM, 17 /* UDP */);
ExpectIntGE(fd2, 0); ExpectIntGT(fd2, 0);
} }
if (EXPECT_SUCCESS()) { if (EXPECT_SUCCESS()) {
@@ -57005,7 +57015,7 @@ static int test_wolfSSL_BIO_datagram(void)
sin1.sin_port = 0; sin1.sin_port = 0;
slen = (socklen_t)sizeof(sin1); slen = (socklen_t)sizeof(sin1);
ExpectIntEQ(bind(fd1, (const struct sockaddr *)&sin1, slen), 0); ExpectIntEQ(bind(fd1, (const struct sockaddr *)&sin1, slen), 0);
perror("bind"); ExpectIntEQ(setsockopt(fd1, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)), 0);
ExpectIntEQ(getsockname(fd1, (struct sockaddr *)&sin1, &slen), 0); ExpectIntEQ(getsockname(fd1, (struct sockaddr *)&sin1, &slen), 0);
} }
@@ -57015,9 +57025,53 @@ static int test_wolfSSL_BIO_datagram(void)
sin2.sin_port = 0; sin2.sin_port = 0;
slen = (socklen_t)sizeof(sin2); slen = (socklen_t)sizeof(sin2);
ExpectIntEQ(bind(fd2, (const struct sockaddr *)&sin2, slen), 0); ExpectIntEQ(bind(fd2, (const struct sockaddr *)&sin2, slen), 0);
ExpectIntEQ(setsockopt(fd2, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)), 0);
ExpectIntEQ(getsockname(fd2, (struct sockaddr *)&sin2, &slen), 0); ExpectIntEQ(getsockname(fd2, (struct sockaddr *)&sin2, &slen), 0);
} }
if (EXPECT_SUCCESS()) {
bio_addr2 = wolfSSL_BIO_ADDR_new();
ExpectNotNull(bio_addr2);
}
if (EXPECT_SUCCESS()) {
XMEMCPY(&bio_addr2->sa_in, &sin2, sizeof(sin2));
ExpectIntEQ((int)wolfSSL_BIO_ctrl(bio1, BIO_CTRL_DGRAM_SET_PEER, 0, bio_addr2), WOLFSSL_SUCCESS);
if (EXPECT_SUCCESS())
bio_addr2 = NULL;
}
test_msg_recvd[0] = 0;
ExpectIntEQ(wolfSSL_BIO_write(bio1, test_msg, sizeof(test_msg)), (int)sizeof(test_msg));
ExpectIntEQ(wolfSSL_BIO_read(bio2, test_msg_recvd, sizeof(test_msg_recvd)), (int)sizeof(test_msg));
ExpectIntEQ(XMEMCMP(test_msg_recvd, test_msg, sizeof(test_msg)), 0);
/* bio2 should now have bio1's addr stored as its peer_addr, because the
* BIOs aren't "connected" yet. use it to send a reply.
*/
test_msg_recvd[0] = 0;
ExpectIntEQ(wolfSSL_BIO_write(bio2, test_msg, sizeof(test_msg)), (int)sizeof(test_msg));
ExpectIntEQ(wolfSSL_BIO_read(bio1, test_msg_recvd, sizeof(test_msg_recvd)), (int)sizeof(test_msg));
ExpectIntEQ(XMEMCMP(test_msg_recvd, test_msg, sizeof(test_msg)), 0);
ExpectIntEQ(wolfSSL_BIO_read(bio1, test_msg_recvd, sizeof(test_msg_recvd)), WOLFSSL_BIO_ERROR);
#ifdef USE_WINDOWS_API
ExpectIntEQ(WSAGetLastError(), WSAEWOULDBLOCK);
#else
ExpectIntEQ(errno, EAGAIN);
#endif
ExpectIntEQ(wolfSSL_BIO_read(bio2, test_msg_recvd, sizeof(test_msg_recvd)), WOLFSSL_BIO_ERROR);
#ifdef USE_WINDOWS_API
ExpectIntEQ(WSAGetLastError(), WSAEWOULDBLOCK);
#else
ExpectIntEQ(errno, EAGAIN);
#endif
/* now "connect" the sockets. */
if (EXPECT_SUCCESS()) { if (EXPECT_SUCCESS()) {
bio_addr1 = wolfSSL_BIO_ADDR_new(); bio_addr1 = wolfSSL_BIO_ADDR_new();
ExpectNotNull(bio_addr1); ExpectNotNull(bio_addr1);
@@ -57025,36 +57079,89 @@ static int test_wolfSSL_BIO_datagram(void)
if (EXPECT_SUCCESS()) { if (EXPECT_SUCCESS()) {
bio_addr2 = wolfSSL_BIO_ADDR_new(); bio_addr2 = wolfSSL_BIO_ADDR_new();
ExpectNotNull(bio_addr1); ExpectNotNull(bio_addr2);
} }
ExpectIntEQ(connect(fd1, (const struct sockaddr *)&sin2, (socklen_t)sizeof(sin2)), 0);
ExpectIntEQ(connect(fd2, (const struct sockaddr *)&sin1, (socklen_t)sizeof(sin1)), 0);
if (EXPECT_SUCCESS()) { if (EXPECT_SUCCESS()) {
XMEMCPY(&bio_addr2->sa_in, &sin2, sizeof(sin2)); XMEMCPY(&bio_addr2->sa_in, &sin2, sizeof(sin2));
ret = (int)wolfSSL_BIO_ctrl(bio1, BIO_CTRL_DGRAM_SET_PEER, 1, bio_addr2); ExpectIntEQ((int)wolfSSL_BIO_ctrl(bio1, BIO_CTRL_DGRAM_SET_CONNECTED, 0, bio_addr2), WOLFSSL_SUCCESS);
ExpectIntEQ(ret, WOLFSSL_SUCCESS); if (EXPECT_SUCCESS())
bio_addr2 = NULL;
} }
if (EXPECT_SUCCESS()) { if (EXPECT_SUCCESS()) {
XMEMCPY(&bio_addr1->sa_in, &sin1, sizeof(sin1)); XMEMCPY(&bio_addr1->sa_in, &sin1, sizeof(sin1));
ret = (int)wolfSSL_BIO_ctrl(bio2, BIO_CTRL_DGRAM_SET_PEER, 1, bio_addr1); ExpectIntEQ((int)wolfSSL_BIO_ctrl(bio2, BIO_CTRL_DGRAM_SET_CONNECTED, 0, bio_addr1), WOLFSSL_SUCCESS);
ExpectIntEQ(ret, WOLFSSL_SUCCESS); if (EXPECT_SUCCESS())
bio_addr1 = NULL;
} }
test_msg_recvd[0] = 0;
ExpectIntEQ(wolfSSL_BIO_write(bio2, test_msg, sizeof(test_msg)), (int)sizeof(test_msg));
ExpectIntEQ(wolfSSL_BIO_read(bio1, test_msg_recvd, sizeof(test_msg_recvd)), (int)sizeof(test_msg));
ExpectIntEQ(XMEMCMP(test_msg_recvd, test_msg, sizeof(test_msg)), 0);
test_msg_recvd[0] = 0;
ExpectIntEQ(wolfSSL_BIO_write(bio1, test_msg, sizeof(test_msg)), (int)sizeof(test_msg));
ExpectIntEQ(wolfSSL_BIO_read(bio2, test_msg_recvd, sizeof(test_msg_recvd)), (int)sizeof(test_msg));
ExpectIntEQ(XMEMCMP(test_msg_recvd, test_msg, sizeof(test_msg)), 0);
#ifdef __linux__
/* now "disconnect" the sockets and attempt transmits expected to fail. */
sin1.sin_family = AF_UNSPEC;
ExpectIntEQ(connect(fd1, (const struct sockaddr *)&sin1, (socklen_t)sizeof(sin1)), 0);
ExpectIntEQ(connect(fd2, (const struct sockaddr *)&sin1, (socklen_t)sizeof(sin1)), 0);
sin1.sin_family = AF_INET;
ExpectIntEQ((int)wolfSSL_BIO_ctrl(bio1, BIO_CTRL_DGRAM_SET_CONNECTED, 0, NULL), WOLFSSL_SUCCESS);
ExpectIntEQ((int)wolfSSL_BIO_ctrl(bio2, BIO_CTRL_DGRAM_SET_CONNECTED, 0, NULL), WOLFSSL_SUCCESS);
if (EXPECT_SUCCESS()) {
bio_addr2 = wolfSSL_BIO_ADDR_new();
ExpectNotNull(bio_addr2);
}
if (EXPECT_SUCCESS()) {
sin2.sin_addr.s_addr = htonl(0xc0a8c0a8); /* 192.168.192.168 -- invalid for loopback interface. */
XMEMCPY(&bio_addr2->sa_in, &sin2, sizeof(sin2));
ExpectIntEQ((int)wolfSSL_BIO_ctrl(bio1, BIO_CTRL_DGRAM_SET_PEER, 0, bio_addr2), WOLFSSL_SUCCESS);
if (EXPECT_SUCCESS())
bio_addr2 = NULL;
}
test_msg_recvd[0] = 0;
errno = 0;
ExpectIntEQ(wolfSSL_BIO_write(bio1, test_msg, sizeof(test_msg)), -1);
ExpectIntEQ(errno, EINVAL);
#endif /* __linux__ */
if (bio1) { if (bio1) {
ret = wolfSSL_BIO_free(bio1); ret = wolfSSL_BIO_free(bio1);
ExpectIntEQ(ret, WOLFSSL_SUCCESS); ExpectIntEQ(ret, WOLFSSL_SUCCESS);
} } else if (fd1 > 0)
CloseSocket(fd1);
if (bio2) { if (bio2) {
ret = wolfSSL_BIO_free(bio2); ret = wolfSSL_BIO_free(bio2);
ExpectIntEQ(ret, WOLFSSL_SUCCESS); ExpectIntEQ(ret, WOLFSSL_SUCCESS);
} } else if (fd2 > 0)
#endif CloseSocket(fd2);
if (bio_addr1)
wolfSSL_BIO_ADDR_free(bio_addr1);
if (bio_addr2)
wolfSSL_BIO_ADDR_free(bio_addr2);
#endif /* !NO_BIO && WOLFSSL_DTLS && WOLFSSL_HAVE_BIO_ADDR && OPENSSL_EXTRA */
return EXPECT_RESULT(); return EXPECT_RESULT();
} }
#if defined(OPENSSL_ALL) && defined(HAVE_IO_TESTS_DEPENDENCIES) && \ #if defined(OPENSSL_ALL) && defined(HAVE_IO_TESTS_DEPENDENCIES) && \
defined(HAVE_HTTP_CLIENT) defined(HAVE_HTTP_CLIENT)
static THREAD_RETURN WOLFSSL_THREAD test_wolfSSL_BIO_accept_client(void* args) static THREAD_RETURN WOLFSSL_THREAD test_wolfSSL_BIO_accept_client(void* args)

View File

@@ -2794,7 +2794,7 @@ struct WOLFSSL_BIO {
#endif #endif
}; };
#ifdef WOLFSSL_HAVE_BIO_ADDR #if defined(WOLFSSL_HAVE_BIO_ADDR) && defined(OPENSSL_EXTRA)
WOLFSSL_LOCAL socklen_t wolfSSL_BIO_ADDR_size(const WOLFSSL_BIO_ADDR *addr); WOLFSSL_LOCAL socklen_t wolfSSL_BIO_ADDR_size(const WOLFSSL_BIO_ADDR *addr);
#endif #endif

View File

@@ -439,6 +439,10 @@
#ifdef WOLFSSL_IPV6 #ifdef WOLFSSL_IPV6
typedef struct sockaddr_in6 SOCKADDR_IN6; typedef struct sockaddr_in6 SOCKADDR_IN6;
#endif #endif
#if defined(HAVE_SYS_UN_H) && !defined(WOLFSSL_NO_SOCKADDR_UN)
#include <sys/un.h>
typedef struct sockaddr_un SOCKADDR_UN;
#endif
typedef struct hostent HOSTENT; typedef struct hostent HOSTENT;
#endif /* HAVE_SOCKADDR */ #endif /* HAVE_SOCKADDR */
@@ -465,27 +469,30 @@ WOLFSSL_API int wolfIO_Recv(SOCKET_T sd, char *buf, int sz, int rdFlags);
#ifdef WOLFSSL_HAVE_BIO_ADDR #ifdef WOLFSSL_HAVE_BIO_ADDR
#ifdef WOLFSSL_NO_SOCK
#error WOLFSSL_HAVE_BIO_ADDR and WOLFSSL_NO_SOCK are mutually incompatible.
#endif
#ifndef WOLFSSL_NO_BIO_ADDR_UN #ifndef WOLFSSL_NO_BIO_ADDR_UN
#include <sys/un.h>
#endif #endif
union WOLFSSL_BIO_ADDR { union WOLFSSL_BIO_ADDR {
struct sockaddr sa; SOCKADDR sa;
#ifndef WOLFSSL_NO_BIO_ADDR_IN SOCKADDR_IN sa_in;
struct sockaddr_in sa_in;
#endif
#ifdef WOLFSSL_IPV6 #ifdef WOLFSSL_IPV6
struct sockaddr_in6 sa_in6; SOCKADDR_IN6 sa_in6;
#endif #endif
#ifndef WOLFSSL_NO_BIO_ADDR_UN #if defined(HAVE_SYS_UN_H) && !defined(WOLFSSL_NO_SOCKADDR_UN)
struct sockaddr_un sa_un; SOCKADDR_UN sa_un;
#endif #endif
}; };
typedef union WOLFSSL_BIO_ADDR WOLFSSL_BIO_ADDR; typedef union WOLFSSL_BIO_ADDR WOLFSSL_BIO_ADDR;
#if defined(WOLFSSL_DTLS) && defined(OPENSSL_EXTRA)
WOLFSSL_API int wolfIO_SendTo(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, int sz, int wrFlags); WOLFSSL_API int wolfIO_SendTo(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, int sz, int wrFlags);
WOLFSSL_API int wolfIO_RecvFrom(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, int sz, int rdFlags); WOLFSSL_API int wolfIO_RecvFrom(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, int sz, int rdFlags);
#endif
#endif /* WOLFSSL_HAVE_BIO_ADDR */ #endif /* WOLFSSL_HAVE_BIO_ADDR */