Merge pull request #201 from cconlon/socketSelectEAGAIN
JNI/JSSE: Add support for poll(), fix for EAGAIN and select()pull/206/head
commit
bef6379273
18
README.md
18
README.md
|
@ -327,6 +327,24 @@ $ ./configure --enable-secure-renegotiation
|
|||
|
||||
Or by defining `-DHAVE_SECURE_RENEGOTIATION`.
|
||||
|
||||
### Native File Descriptor Events
|
||||
|
||||
wolfSSL JNI/JSSE internally makes several calls that operate on native
|
||||
file descriptors inside Java Socket objects. These native file descriptors
|
||||
are watched for read and write events with either `select()` or `poll()`.
|
||||
|
||||
By default `poll()` will be used, unless `WOLFJNI_USE_IO_SELECT` is defined
|
||||
or added to CFLAGS when compiling the native JNI sources (see `java.sh`).
|
||||
Windows builds will also default to using `select()` since `poll()` is not
|
||||
available there.
|
||||
|
||||
wolfSSL JNI/JSSE does not select/poll on a large number of file descriptors
|
||||
(typically just one). Although if used in applications that make lots of
|
||||
connections, when using `select()` the `FD_ISSET` and other related macros
|
||||
result in undefined behavior when the file descriptor number is larger than
|
||||
`FD_SETSIZE` (defaults to 1024 on most systems). For this reason, `poll()` is
|
||||
used as the default descriptor monitoring function.
|
||||
|
||||
## Release Notes
|
||||
|
||||
Release notes can be found in [ChangeLog.md](./ChangeLog.md).
|
||||
|
|
|
@ -9,8 +9,18 @@ extern "C" {
|
|||
#endif
|
||||
#undef com_wolfssl_WolfSSL_JNI_SESSION_UNAVAILABLE
|
||||
#define com_wolfssl_WolfSSL_JNI_SESSION_UNAVAILABLE -10001L
|
||||
#undef com_wolfssl_WolfSSL_WOLFJNI_TIMEOUT
|
||||
#define com_wolfssl_WolfSSL_WOLFJNI_TIMEOUT -11L
|
||||
#undef com_wolfssl_WolfSSL_WOLFJNI_IO_EVENT_FAIL
|
||||
#define com_wolfssl_WolfSSL_WOLFJNI_IO_EVENT_FAIL -10L
|
||||
#undef com_wolfssl_WolfSSL_WOLFJNI_IO_EVENT_TIMEOUT
|
||||
#define com_wolfssl_WolfSSL_WOLFJNI_IO_EVENT_TIMEOUT -11L
|
||||
#undef com_wolfssl_WolfSSL_WOLFJNI_IO_EVENT_ERROR
|
||||
#define com_wolfssl_WolfSSL_WOLFJNI_IO_EVENT_ERROR -14L
|
||||
#undef com_wolfssl_WolfSSL_WOLFJNI_IO_EVENT_FD_CLOSED
|
||||
#define com_wolfssl_WolfSSL_WOLFJNI_IO_EVENT_FD_CLOSED -15L
|
||||
#undef com_wolfssl_WolfSSL_WOLFJNI_IO_EVENT_POLLHUP
|
||||
#define com_wolfssl_WolfSSL_WOLFJNI_IO_EVENT_POLLHUP -16L
|
||||
#undef com_wolfssl_WolfSSL_WOLFJNI_IO_EVENT_INVALID_TIMEOUT
|
||||
#define com_wolfssl_WolfSSL_WOLFJNI_IO_EVENT_INVALID_TIMEOUT -17L
|
||||
#undef com_wolfssl_WolfSSL_SSL_ERROR_NONE
|
||||
#define com_wolfssl_WolfSSL_SSL_ERROR_NONE 0L
|
||||
#undef com_wolfssl_WolfSSL_SSL_FAILURE
|
||||
|
|
|
@ -33,6 +33,11 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <sys/errno.h>
|
||||
#endif
|
||||
#ifdef WOLFJNI_USE_IO_SELECT
|
||||
#include <sys/select.h>
|
||||
#else
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#ifndef WOLFSSL_JNI_DEFAULT_PEEK_TIMEOUT
|
||||
/* Default wolfSSL_peek() timeout for wolfSSL_get_session(), ms */
|
||||
|
@ -186,9 +191,6 @@ int NativeSSLVerifyCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store)
|
|||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/* jni functions */
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLSession_newSSL
|
||||
(JNIEnv* jenv, jobject jcl, jlong ctx)
|
||||
{
|
||||
|
@ -599,22 +601,50 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_getFd
|
|||
return wolfSSL_get_fd(ssl);
|
||||
}
|
||||
|
||||
/* enum values used in socketSelect() */
|
||||
/* enum values used in socketSelect() and socketPoll(). Some of these
|
||||
* values are also duplicated in WolfSSL.java for access from Java classes.
|
||||
* If updated here, make sure to update in WolfSSL.java too. */
|
||||
enum {
|
||||
WOLFJNI_SELECT_FAIL = -10,
|
||||
WOLFJNI_TIMEOUT = -11, /* also in WolfSSL.java */
|
||||
WOLFJNI_RECV_READY = -12,
|
||||
WOLFJNI_SEND_READY = -13,
|
||||
WOLFJNI_ERROR_READY = -14
|
||||
WOLFJNI_IO_EVENT_FAIL = -10,
|
||||
WOLFJNI_IO_EVENT_TIMEOUT = -11,
|
||||
WOLFJNI_IO_EVENT_RECV_READY = -12,
|
||||
WOLFJNI_IO_EVENT_SEND_READY = -13,
|
||||
WOLFJNI_IO_EVENT_ERROR = -14,
|
||||
WOLFJNI_IO_EVENT_FD_CLOSED = -15,
|
||||
WOLFJNI_IO_EVENT_POLLHUP = -16,
|
||||
WOLFJNI_IO_EVENT_INVALID_TIMEOUT = -17
|
||||
};
|
||||
|
||||
/* perform a select() call on underlying socket to wait for socket to be ready
|
||||
* to read/write, or timeout. Note that we explicitly set the underlying
|
||||
* socket descriptor to non-blocking so we can select() on it.
|
||||
#ifdef WOLFJNI_USE_IO_SELECT
|
||||
|
||||
/* Perform a select() call on the underlying socket to wait for socket to be
|
||||
* ready for read/write, or timeout. Note that we explicitly set the underlying
|
||||
* socket descriptor to non-blocking.
|
||||
*
|
||||
* The Java socket timeout value representing no timeout is NULL, not 0 like
|
||||
* C. We adjust for this when handling timeout_ms here. timeout_ms is in
|
||||
* milliseconds. */
|
||||
* NOTE: the FD_ISSET macro behavior is undefined if the descriptor value is
|
||||
* less than 0 or greater than or equal to FD_SETSIZE (1024 by default).
|
||||
*
|
||||
* On a Java Socket, a timeout of 0 is an infinite timeout. Greater than zero
|
||||
* is a timeout in milliseconds. Negative timeout is invalid and not supported.
|
||||
* For select(), a non-NULL timeval struct specifies maximum timeout to wait,
|
||||
* a NULL timeval struct is an infinite timeout. A zero-valued timeval struct
|
||||
* will return immediately (no timeout).
|
||||
*
|
||||
* @param sockfd socket descriptor to select()
|
||||
* @param timeout_ms timeout in milliseconds. 0 indicates infinite timeout, to
|
||||
* match Java timeout behavior. Negative timeout not
|
||||
* supported, since not supported on Java Socket.
|
||||
* @param rx set to 1 to monitor readability on socket descriptor,
|
||||
* otherwise 0 to monitor writability
|
||||
*
|
||||
* @return possible return values are:
|
||||
* WOLFJNI_IO_EVENT_FAIL
|
||||
* WOLFJNI_IO_EVENT_ERROR
|
||||
* WOLFJNI_IO_EVENT_TIMEOUT
|
||||
* WOLFJNI_IO_EVENT_RECV_READY
|
||||
* WOLFJNI_IO_EVENT_SEND_READY
|
||||
* WOLFJNI_IO_EVENT_INVALID_TIMEOUT
|
||||
*/
|
||||
static int socketSelect(int sockfd, int timeout_ms, int rx)
|
||||
{
|
||||
fd_set fds, errfds;
|
||||
|
@ -624,6 +654,11 @@ static int socketSelect(int sockfd, int timeout_ms, int rx)
|
|||
int result = 0;
|
||||
struct timeval timeout;
|
||||
|
||||
/* Java Socket does not support negative timeouts, sanitize */
|
||||
if (timeout_ms < 0) {
|
||||
return WOLFJNI_IO_EVENT_INVALID_TIMEOUT;
|
||||
}
|
||||
|
||||
#ifndef USE_WINDOWS_API
|
||||
do {
|
||||
#endif
|
||||
|
@ -648,31 +683,118 @@ static int socketSelect(int sockfd, int timeout_ms, int rx)
|
|||
}
|
||||
|
||||
if (result == 0) {
|
||||
return WOLFJNI_TIMEOUT;
|
||||
return WOLFJNI_IO_EVENT_TIMEOUT;
|
||||
} else if (result > 0) {
|
||||
if (FD_ISSET(sockfd, &fds)) {
|
||||
if (rx) {
|
||||
return WOLFJNI_RECV_READY;
|
||||
return WOLFJNI_IO_EVENT_RECV_READY;
|
||||
} else {
|
||||
return WOLFJNI_SEND_READY;
|
||||
return WOLFJNI_IO_EVENT_SEND_READY;
|
||||
}
|
||||
} else if (FD_ISSET(sockfd, &errfds)) {
|
||||
return WOLFJNI_ERROR_READY;
|
||||
return WOLFJNI_IO_EVENT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef USE_WINDOWS_API
|
||||
} while ((result == -1) && (errno == EINTR));
|
||||
} while ((result == -1) && ((errno == EINTR) || (errno == EAGAIN)));
|
||||
#endif
|
||||
|
||||
/* Return on error, unless select() was interrupted, try again above */
|
||||
return WOLFJNI_SELECT_FAIL;
|
||||
/* Return on error, unless errno EINTR or EAGAIN, try again above */
|
||||
return WOLFJNI_IO_EVENT_FAIL;
|
||||
}
|
||||
|
||||
#else /* !WOLFJNI_USE_IO_SELECT */
|
||||
|
||||
/* Perform poll() on underlying socket descriptor to wait for socket to be
|
||||
* ready for read/write, or timeout. Note that we are explicitly setting
|
||||
* the underlying descriptor to non-blocking.
|
||||
*
|
||||
* On a Java Socket, a timeout of 0 is an infinite timeout. Greater than zero
|
||||
* is a timeout in milliseconds. Negative timeout is invalid and not supported.
|
||||
* For poll(), timeout greater than 0 specifies max timeout in milliseconds,
|
||||
* zero timeout will return immediately (no timeout), and -1 will block
|
||||
* indefinitely.
|
||||
*
|
||||
* @param sockfd socket descriptor to poll()
|
||||
* @param timeout_ms timeout in milliseconds. 0 indicates infinite timeout, to
|
||||
* match Java timeout behavior. Negative timeout not
|
||||
* supported, since not supported on Java Socket.
|
||||
* @param rx set to 1 to monitor readability on socket descriptor,
|
||||
* otherwise 0 to ignore readability events
|
||||
* @param tx set to 1 to monitor writability on socket descriptor,
|
||||
* otherwise 0 to ignore writability events
|
||||
*
|
||||
* @return possible return values are:
|
||||
* WOLFJNI_IO_EVENT_FAIL
|
||||
* WOLFJNI_IO_EVENT_ERROR
|
||||
* WOLFJNI_IO_EVENT_TIMEOUT
|
||||
* WOLFJNI_IO_EVENT_RECV_READY
|
||||
* WOLFJNI_IO_EVENT_SEND_READY
|
||||
* WOLFJNI_IO_EVENT_FD_CLOSED
|
||||
* WOLFJNI_IO_EVENT_POLLHUP
|
||||
* WOLFJNI_IO_EVENT_INVALID_TIMEOUT
|
||||
*/
|
||||
static int socketPoll(int sockfd, int timeout_ms, int rx, int tx)
|
||||
{
|
||||
int ret;
|
||||
int timeout;
|
||||
struct pollfd fds[1];
|
||||
|
||||
/* Sanitize timeout and convert from Java to poll() expectations */
|
||||
timeout = timeout_ms;
|
||||
if (timeout < 0) {
|
||||
return WOLFJNI_IO_EVENT_INVALID_TIMEOUT;
|
||||
} else if (timeout == 0) {
|
||||
timeout = -1;
|
||||
}
|
||||
|
||||
fds[0].fd = sockfd;
|
||||
fds[0].events = 0;
|
||||
if (tx) {
|
||||
fds[0].events |= POLLOUT;
|
||||
}
|
||||
if (rx) {
|
||||
fds[0].events |= POLLIN;
|
||||
}
|
||||
|
||||
do {
|
||||
ret = poll(fds, 1, timeout);
|
||||
if (ret == 0) {
|
||||
return WOLFJNI_IO_EVENT_TIMEOUT;
|
||||
|
||||
} else if (ret > 0) {
|
||||
if (fds[0].revents & POLLIN ||
|
||||
fds[0].revents & POLLPRI) { /* read possible */
|
||||
return WOLFJNI_IO_EVENT_RECV_READY;
|
||||
|
||||
} else if (fds[0].revents & POLLOUT) { /* write possible */
|
||||
return WOLFJNI_IO_EVENT_SEND_READY;
|
||||
|
||||
} else if (fds[0].revents & POLLNVAL) { /* fd not open */
|
||||
return WOLFJNI_IO_EVENT_FD_CLOSED;
|
||||
|
||||
} else if (fds[0].revents & POLLERR) { /* exceptional error */
|
||||
return WOLFJNI_IO_EVENT_ERROR;
|
||||
|
||||
} else if (fds[0].revents & POLLHUP) { /* sock disconnected */
|
||||
return WOLFJNI_IO_EVENT_POLLHUP;
|
||||
}
|
||||
}
|
||||
|
||||
} while ((ret == -1) && ((errno == EINTR) || (errno == EAGAIN)));
|
||||
|
||||
return WOLFJNI_IO_EVENT_FAIL;
|
||||
}
|
||||
|
||||
#endif /* WOLFJNI_USE_IO_SELECT */
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_connect
|
||||
(JNIEnv* jenv, jobject jcl, jlong sslPtr, jint timeout)
|
||||
{
|
||||
int ret = 0, err = 0, sockfd = 0;
|
||||
int pollRx = 0;
|
||||
int pollTx = 0;
|
||||
wolfSSL_Mutex* jniSessLock = NULL;
|
||||
SSLAppData* appData = NULL;
|
||||
WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr;
|
||||
|
@ -726,12 +848,28 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_connect
|
|||
break;
|
||||
}
|
||||
|
||||
ret = socketSelect(sockfd, (int)timeout, 1);
|
||||
if (ret == WOLFJNI_RECV_READY || ret == WOLFJNI_SEND_READY) {
|
||||
if (err == SSL_ERROR_WANT_READ) {
|
||||
pollRx = 1;
|
||||
}
|
||||
else if (err == SSL_ERROR_WANT_WRITE) {
|
||||
pollTx = 1;
|
||||
}
|
||||
|
||||
#if defined(WOLFJNI_USE_IO_SELECT) || defined(USE_WINDOWS_API)
|
||||
ret = socketSelect(sockfd, (int)timeout, pollRx);
|
||||
#else
|
||||
ret = socketPoll(sockfd, (int)timeout, pollRx, pollTx);
|
||||
#endif
|
||||
if ((ret == WOLFJNI_IO_EVENT_RECV_READY) ||
|
||||
(ret == WOLFJNI_IO_EVENT_SEND_READY)) {
|
||||
/* I/O ready, continue handshake and try again */
|
||||
continue;
|
||||
} else if (ret == WOLFJNI_TIMEOUT) {
|
||||
/* Java will throw SocketTimeoutException */
|
||||
} else if (ret == WOLFJNI_IO_EVENT_TIMEOUT ||
|
||||
ret == WOLFJNI_IO_EVENT_FD_CLOSED ||
|
||||
ret == WOLFJNI_IO_EVENT_ERROR ||
|
||||
ret == WOLFJNI_IO_EVENT_POLLHUP ||
|
||||
ret == WOLFJNI_IO_EVENT_FAIL) {
|
||||
/* Java will throw SocketTimeoutException or SocketException */
|
||||
break;
|
||||
} else {
|
||||
/* error */
|
||||
|
@ -758,6 +896,8 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_write
|
|||
{
|
||||
byte* data = NULL;
|
||||
int ret = SSL_FAILURE, err, sockfd;
|
||||
int pollRx = 0;
|
||||
int pollTx = 0;
|
||||
wolfSSL_Mutex* jniSessLock = NULL;
|
||||
SSLAppData* appData = NULL;
|
||||
WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr;
|
||||
|
@ -819,12 +959,32 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_write
|
|||
break;
|
||||
}
|
||||
|
||||
ret = socketSelect(sockfd, (int)timeout, 0);
|
||||
if (ret == WOLFJNI_RECV_READY || ret == WOLFJNI_SEND_READY) {
|
||||
if (err == SSL_ERROR_WANT_READ) {
|
||||
pollRx = 1;
|
||||
}
|
||||
else if (err == SSL_ERROR_WANT_WRITE) {
|
||||
pollTx = 1;
|
||||
}
|
||||
|
||||
#if defined(WOLFJNI_USE_IO_SELECT) || defined(USE_WINDOWS_API)
|
||||
ret = socketSelect(sockfd, (int)timeout, pollRx);
|
||||
#else
|
||||
ret = socketPoll(sockfd, (int)timeout, pollRx, pollTx);
|
||||
#endif
|
||||
if ((ret == WOLFJNI_IO_EVENT_RECV_READY) ||
|
||||
(ret == WOLFJNI_IO_EVENT_SEND_READY)) {
|
||||
/* loop around and try wolfSSL_write() again */
|
||||
continue;
|
||||
} else if (ret == WOLFJNI_IO_EVENT_TIMEOUT ||
|
||||
ret == WOLFJNI_IO_EVENT_FD_CLOSED ||
|
||||
ret == WOLFJNI_IO_EVENT_ERROR ||
|
||||
ret == WOLFJNI_IO_EVENT_POLLHUP ||
|
||||
ret == WOLFJNI_IO_EVENT_FAIL) {
|
||||
/* Java will throw SocketTimeoutException or
|
||||
* SocketException */
|
||||
break;
|
||||
} else {
|
||||
/* error or timeout occurred during select */
|
||||
/* error */
|
||||
ret = WOLFSSL_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
@ -847,6 +1007,8 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read
|
|||
{
|
||||
byte* data = NULL;
|
||||
int size = 0, ret, err, sockfd;
|
||||
int pollRx = 0;
|
||||
int pollTx = 0;
|
||||
wolfSSL_Mutex* jniSessLock = NULL;
|
||||
SSLAppData* appData = NULL;
|
||||
WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr;
|
||||
|
@ -905,12 +1067,32 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read
|
|||
break;
|
||||
}
|
||||
|
||||
ret = socketSelect(sockfd, timeout, 1);
|
||||
if (ret == WOLFJNI_RECV_READY || ret == WOLFJNI_SEND_READY) {
|
||||
if (err == SSL_ERROR_WANT_READ) {
|
||||
pollRx = 1;
|
||||
}
|
||||
else if (err == SSL_ERROR_WANT_WRITE) {
|
||||
pollTx = 1;
|
||||
}
|
||||
|
||||
#if defined(WOLFJNI_USE_IO_SELECT) || defined(USE_WINDOWS_API)
|
||||
ret = socketSelect(sockfd, (int)timeout, pollRx);
|
||||
#else
|
||||
ret = socketPoll(sockfd, (int)timeout, pollRx, pollTx);
|
||||
#endif
|
||||
if ((ret == WOLFJNI_IO_EVENT_RECV_READY) ||
|
||||
(ret == WOLFJNI_IO_EVENT_SEND_READY)) {
|
||||
/* loop around and try wolfSSL_read() again */
|
||||
continue;
|
||||
} else if (ret == WOLFJNI_IO_EVENT_TIMEOUT ||
|
||||
ret == WOLFJNI_IO_EVENT_FD_CLOSED ||
|
||||
ret == WOLFJNI_IO_EVENT_ERROR ||
|
||||
ret == WOLFJNI_IO_EVENT_POLLHUP ||
|
||||
ret == WOLFJNI_IO_EVENT_FAIL) {
|
||||
/* Java will throw SocketTimeoutException or
|
||||
* SocketException */
|
||||
break;
|
||||
} else {
|
||||
/* error or timeout occurred during select */
|
||||
/* other error occurred */
|
||||
size = ret;
|
||||
break;
|
||||
}
|
||||
|
@ -930,6 +1112,8 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_accept
|
|||
(JNIEnv* jenv, jobject jcl, jlong sslPtr, jint timeout)
|
||||
{
|
||||
int ret = 0, err, sockfd;
|
||||
int pollRx = 0;
|
||||
int pollTx = 0;
|
||||
wolfSSL_Mutex* jniSessLock = NULL;
|
||||
SSLAppData* appData = NULL;
|
||||
WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr;
|
||||
|
@ -983,12 +1167,33 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_accept
|
|||
break;
|
||||
}
|
||||
|
||||
ret = socketSelect(sockfd, (int)timeout, 1);
|
||||
if (ret == WOLFJNI_RECV_READY || ret == WOLFJNI_SEND_READY) {
|
||||
/* I/O ready, continue handshake and try again */
|
||||
if (err == SSL_ERROR_WANT_READ) {
|
||||
pollRx = 1;
|
||||
}
|
||||
else if (err == SSL_ERROR_WANT_WRITE) {
|
||||
pollTx = 1;
|
||||
}
|
||||
|
||||
#if defined(WOLFJNI_USE_IO_SELECT) || defined(USE_WINDOWS_API)
|
||||
ret = socketSelect(sockfd, (int)timeout, pollRx);
|
||||
#else
|
||||
ret = socketPoll(sockfd, (int)timeout, pollRx, pollTx);
|
||||
#endif
|
||||
if ((ret == WOLFJNI_IO_EVENT_RECV_READY) ||
|
||||
(ret == WOLFJNI_IO_EVENT_SEND_READY)) {
|
||||
/* loop around and try wolfSSL_accept() again */
|
||||
continue;
|
||||
} else if (ret == WOLFJNI_IO_EVENT_TIMEOUT ||
|
||||
ret == WOLFJNI_IO_EVENT_FD_CLOSED ||
|
||||
ret == WOLFJNI_IO_EVENT_ERROR ||
|
||||
ret == WOLFJNI_IO_EVENT_POLLHUP ||
|
||||
ret == WOLFJNI_IO_EVENT_FAIL) {
|
||||
/* Java will throw SocketTimeoutException or
|
||||
* SocketException */
|
||||
break;
|
||||
} else {
|
||||
/* error or timeout */
|
||||
/* other error occurred */
|
||||
ret = SSL_FAILURE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1156,6 +1361,8 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_shutdownSSL
|
|||
(JNIEnv* jenv, jobject jcl, jlong sslPtr, jint timeout)
|
||||
{
|
||||
int ret = 0, err, sockfd;
|
||||
int pollRx = 0;
|
||||
int pollTx = 0;
|
||||
wolfSSL_Mutex* jniSessLock;
|
||||
SSLAppData* appData = NULL;
|
||||
WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr;
|
||||
|
@ -1209,12 +1416,33 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_shutdownSSL
|
|||
break;
|
||||
}
|
||||
|
||||
ret = socketSelect(sockfd, timeout, 1);
|
||||
if (ret == WOLFJNI_RECV_READY || ret == WOLFJNI_SEND_READY) {
|
||||
/* I/O ready, continue handshake and try again */
|
||||
if (err == SSL_ERROR_WANT_READ) {
|
||||
pollRx = 1;
|
||||
}
|
||||
else if (err == SSL_ERROR_WANT_WRITE) {
|
||||
pollTx = 1;
|
||||
}
|
||||
|
||||
#if defined(WOLFJNI_USE_IO_SELECT) || defined(USE_WINDOWS_API)
|
||||
ret = socketSelect(sockfd, (int)timeout, pollRx);
|
||||
#else
|
||||
ret = socketPoll(sockfd, (int)timeout, pollRx, pollTx);
|
||||
#endif
|
||||
if ((ret == WOLFJNI_IO_EVENT_RECV_READY) ||
|
||||
(ret == WOLFJNI_IO_EVENT_SEND_READY)) {
|
||||
/* loop around and try wolfSSL_shutdown() again */
|
||||
continue;
|
||||
} else if (ret == WOLFJNI_IO_EVENT_TIMEOUT ||
|
||||
ret == WOLFJNI_IO_EVENT_FD_CLOSED ||
|
||||
ret == WOLFJNI_IO_EVENT_ERROR ||
|
||||
ret == WOLFJNI_IO_EVENT_POLLHUP ||
|
||||
ret == WOLFJNI_IO_EVENT_FAIL) {
|
||||
/* Java will throw SocketTimeoutException or
|
||||
* SocketException */
|
||||
break;
|
||||
} else {
|
||||
/* error or timeout */
|
||||
/* other error occurred */
|
||||
ret = SSL_FAILURE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1401,9 +1629,16 @@ JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLSession_get1Session
|
|||
break;
|
||||
}
|
||||
|
||||
#if defined(WOLFJNI_USE_IO_SELECT) || defined(USE_WINDOWS_API)
|
||||
/* Default to select() on Windows or if WOLFJNI_USE_IO_SELECT */
|
||||
ret = socketSelect(sockfd,
|
||||
(int)WOLFSSL_JNI_DEFAULT_PEEK_TIMEOUT, 1);
|
||||
if (ret == WOLFJNI_RECV_READY || ret == WOLFJNI_SEND_READY) {
|
||||
#else
|
||||
ret = socketPoll(sockfd,
|
||||
(int)WOLFSSL_JNI_DEFAULT_PEEK_TIMEOUT, 1, 0);
|
||||
#endif
|
||||
if ((ret == WOLFJNI_IO_EVENT_RECV_READY) ||
|
||||
(ret == WOLFJNI_IO_EVENT_SEND_READY)) {
|
||||
/* I/O ready, continue handshake and try again */
|
||||
continue;
|
||||
} else {
|
||||
|
|
|
@ -54,9 +54,36 @@ public class WolfSSL {
|
|||
public static final int JNI_SESSION_UNAVAILABLE = -10001;
|
||||
|
||||
/**
|
||||
* Socket timed out, matches com_wolfssl_WolfSSLSession.c socketSelect()
|
||||
* return value */
|
||||
public static final int WOLFJNI_TIMEOUT = -11;
|
||||
* Socket select/poll() failed, matches com_wolfssl_WolfSSLSession.c
|
||||
* socketSelect() and socketPoll() return value.
|
||||
*/
|
||||
public static final int WOLFJNI_IO_EVENT_FAIL = -10;
|
||||
|
||||
/**
|
||||
* Socket timed out, matches com_wolfssl_WolfSSLSession.c
|
||||
* socketSelect() and socketPoll() return value.
|
||||
*/
|
||||
public static final int WOLFJNI_IO_EVENT_TIMEOUT = -11;
|
||||
|
||||
/**
|
||||
* Socket poll() exceptional error, matches com_wolfssl_WolfSSLSession.c
|
||||
* socketPoll() return value */
|
||||
public static final int WOLFJNI_IO_EVENT_ERROR = -14;
|
||||
|
||||
/**
|
||||
* Socket file descriptor closed, matches com_wolfssl_WolfSSLSession.c
|
||||
* socketPoll() return value */
|
||||
public static final int WOLFJNI_IO_EVENT_FD_CLOSED = -15;
|
||||
|
||||
/**
|
||||
* Socket disconnected during poll(), matches
|
||||
* com_wolfssl_WolfSSLSession.c socketPoll() return value */
|
||||
public static final int WOLFJNI_IO_EVENT_POLLHUP = -16;
|
||||
|
||||
/**
|
||||
* Socket invalid timeout during poll/select(), matches
|
||||
* com_wolfssl_WolfSSLSession.c socketPoll/socketSelect() return value */
|
||||
public static final int WOLFJNI_IO_EVENT_INVALID_TIMEOUT = -17;
|
||||
|
||||
/* ----------------------- wolfSSL codes ---------------------------- */
|
||||
|
||||
|
|
|
@ -94,11 +94,6 @@ public class WolfSSLSession {
|
|||
/* lock around native WOLFSSL pointer use */
|
||||
private final Object sslLock = new Object();
|
||||
|
||||
/* return values from naitve socketSelect(), should match
|
||||
* ones in native/com_wolfssl_WolfSSLSession.c */
|
||||
private int WOLFJNI_SELECT_FAIL = -10;
|
||||
private int WOLFJNI_TIMEOUT = -11;
|
||||
|
||||
/* SNI requested by this WolfSSLSession if client side and useSNI()
|
||||
* was called successfully. */
|
||||
private byte[] clientSNIRequested = null;
|
||||
|
@ -567,6 +562,36 @@ public class WolfSSLSession {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to throw appropriate exception based on native
|
||||
* result of poll()/select() from API that does I/O.
|
||||
*/
|
||||
private static void throwExceptionFromIOReturnValue(
|
||||
int ret, String nativeFunc)
|
||||
throws SocketTimeoutException, SocketException {
|
||||
|
||||
if (ret == WolfSSL.WOLFJNI_IO_EVENT_TIMEOUT) {
|
||||
throw new SocketTimeoutException(
|
||||
"Native socket timed out during " + nativeFunc);
|
||||
}
|
||||
else if (ret == WolfSSL.WOLFJNI_IO_EVENT_FD_CLOSED) {
|
||||
throw new SocketException("Socket fd closed during poll(), " +
|
||||
"errno = " + WolfSSL.getErrno());
|
||||
}
|
||||
else if (ret == WolfSSL.WOLFJNI_IO_EVENT_ERROR) {
|
||||
throw new SocketException("Socket fd poll() exceptional error, " +
|
||||
"errno = " + WolfSSL.getErrno());
|
||||
}
|
||||
else if (ret == WolfSSL.WOLFJNI_IO_EVENT_POLLHUP) {
|
||||
throw new SocketException("Socket disconnected during poll(), " +
|
||||
"errno = " + WolfSSL.getErrno());
|
||||
}
|
||||
else if (ret == WolfSSL.WOLFJNI_IO_EVENT_FAIL) {
|
||||
throw new SocketException("Socket select/poll() failed, " +
|
||||
"errno = " + WolfSSL.getErrno());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an SSL/TLS handshake with a server.
|
||||
* This function is called on the client side. When called, the underlying
|
||||
|
@ -602,29 +627,12 @@ public class WolfSSLSession {
|
|||
* a more detailed error code, call <code>getError()</code>.
|
||||
* @throws IllegalStateException WolfSSLContext has been freed
|
||||
* @throws SocketTimeoutException if underlying socket timed out
|
||||
* @throws SocketException Native socket select() failed
|
||||
* @throws SocketException Native socket select() or poll() failed
|
||||
*/
|
||||
public int connect()
|
||||
throws IllegalStateException, SocketTimeoutException, SocketException {
|
||||
|
||||
int ret = 0;
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
synchronized (sslLock) {
|
||||
ret = connect(this.sslPtr, 0);
|
||||
}
|
||||
|
||||
if (ret == WolfSSL.WOLFJNI_TIMEOUT) {
|
||||
throw new SocketTimeoutException(
|
||||
"Native socket timed out during SSL_connect()");
|
||||
}
|
||||
else if (ret == WOLFJNI_SELECT_FAIL) {
|
||||
throw new SocketException("Socket select() failed, errno = " +
|
||||
WolfSSL.getErrno());
|
||||
}
|
||||
|
||||
return ret;
|
||||
return connect(0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -657,14 +665,15 @@ public class WolfSSLSession {
|
|||
* <p>
|
||||
* before calling <code>newSSL()</code>, though it's not recommended.
|
||||
*
|
||||
* @param timeout read timeout, milliseconds.
|
||||
* @param timeout read timeout, milliseconds. Specify 0 to use infinite
|
||||
* timeout
|
||||
*
|
||||
* @return <code>SSL_SUCCESS</code> if successful, otherwise
|
||||
* <code>SSL_FATAL_ERROR</code> if an error occurred. To get
|
||||
* <code>SSL_FAILURE</code> if an error occurred. To get
|
||||
* a more detailed error code, call <code>getError()</code>.
|
||||
* @throws IllegalStateException WolfSSLContext has been freed
|
||||
* @throws SocketTimeoutException if socket timeout occurs
|
||||
* @throws SocketException Native socket select() failed
|
||||
* @throws SocketException Native socket select() or poll() failed
|
||||
*/
|
||||
public int connect(int timeout)
|
||||
throws IllegalStateException, SocketTimeoutException, SocketException {
|
||||
|
@ -677,13 +686,7 @@ public class WolfSSLSession {
|
|||
ret = connect(this.sslPtr, timeout);
|
||||
}
|
||||
|
||||
if (ret == WOLFJNI_TIMEOUT) {
|
||||
throw new SocketTimeoutException("Socket connect timeout");
|
||||
}
|
||||
else if (ret == WOLFJNI_SELECT_FAIL) {
|
||||
throw new SocketException("Socket select() failed, errno = " +
|
||||
WolfSSL.getErrno());
|
||||
}
|
||||
throwExceptionFromIOReturnValue(ret, "wolfSSL_connect()");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -710,7 +713,7 @@ public class WolfSSLSession {
|
|||
* @param length size, in bytes, of data to send to the peer
|
||||
* @return the number of bytes written upon success. <code>0
|
||||
* </code>or a negative value will be returned upon failure.
|
||||
* <code>SSL_FATAL_ERROR</code>return upon failure when either
|
||||
* <code>SSL_FAILURE</code>return upon failure when either
|
||||
* an error occurred or, when using non-blocking sockets,
|
||||
* the <b>SSL_ERROR_WANT_READ</b> or
|
||||
* <b>SSL_ERROR_WANT_WRITE</b> error was received and the
|
||||
|
@ -718,10 +721,11 @@ public class WolfSSLSession {
|
|||
* <code>BAD_FUNC_ARC</code> when bad arguments are used.
|
||||
* Use <code>getError</code> to get a specific error code.
|
||||
* @throws IllegalStateException WolfSSLContext has been freed
|
||||
* @throws SocketException Native socket select() failed
|
||||
* @throws SocketTimeoutException if socket timeout occurs
|
||||
* @throws SocketException Native socket select() or poll() failed
|
||||
*/
|
||||
public int write(byte[] data, int length)
|
||||
throws IllegalStateException, SocketException {
|
||||
throws IllegalStateException, SocketTimeoutException, SocketException {
|
||||
|
||||
int ret;
|
||||
long localPtr;
|
||||
|
@ -741,10 +745,7 @@ public class WolfSSLSession {
|
|||
* occur if needed */
|
||||
ret = write(localPtr, data, 0, length, 0);
|
||||
|
||||
if (ret == WOLFJNI_SELECT_FAIL) {
|
||||
throw new SocketException("Socket select() failed, errno = " +
|
||||
WolfSSL.getErrno());
|
||||
}
|
||||
throwExceptionFromIOReturnValue(ret, "wolfSSL_write()");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -782,7 +783,7 @@ public class WolfSSLSession {
|
|||
* Use <code>getError</code> to get a specific error code.
|
||||
* @throws IllegalStateException WolfSSLContext has been freed
|
||||
* @throws SocketTimeoutException if socket timeout occurs
|
||||
* @throws SocketException Native socket select() failed
|
||||
* @throws SocketException Native socket select/poll() failed
|
||||
*/
|
||||
public int write(byte[] data, int length, int timeout)
|
||||
throws IllegalStateException, SocketTimeoutException, SocketException {
|
||||
|
@ -826,7 +827,7 @@ public class WolfSSLSession {
|
|||
* Use <code>getError</code> to get a specific error code.
|
||||
* @throws IllegalStateException WolfSSLContext has been freed
|
||||
* @throws SocketTimeoutException if socket timeout occurs
|
||||
* @throws SocketException Native socket select() failed
|
||||
* @throws SocketException Native socket select/poll() failed
|
||||
*/
|
||||
public int write(byte[] data, int offset, int length, int timeout)
|
||||
throws IllegalStateException, SocketTimeoutException, SocketException {
|
||||
|
@ -849,13 +850,7 @@ public class WolfSSLSession {
|
|||
* occur if needed */
|
||||
ret = write(localPtr, data, offset, length, timeout);
|
||||
|
||||
if (ret == WOLFJNI_TIMEOUT) {
|
||||
throw new SocketTimeoutException("Socket write timeout");
|
||||
}
|
||||
else if (ret == WOLFJNI_SELECT_FAIL) {
|
||||
throw new SocketException("Socket select() failed, errno = " +
|
||||
WolfSSL.getErrno());
|
||||
}
|
||||
throwExceptionFromIOReturnValue(ret, "wolfSSL_write()");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -893,10 +888,12 @@ public class WolfSSLSession {
|
|||
* get a specific error code.
|
||||
* <code>BAD_FUNC_ARC</code> when bad arguments are used.
|
||||
* @throws IllegalStateException WolfSSLContext has been freed
|
||||
* @throws SocketException Native socket select() failed
|
||||
* @throws SocketTimeoutException if socket timeout occurs, should not
|
||||
* occur since infinite timeout is used for this call.
|
||||
* @throws SocketException Native socket select/poll() failed
|
||||
*/
|
||||
public int read(byte[] data, int sz)
|
||||
throws IllegalStateException, SocketException {
|
||||
throws IllegalStateException, SocketTimeoutException, SocketException {
|
||||
|
||||
int ret;
|
||||
long localPtr;
|
||||
|
@ -916,10 +913,7 @@ public class WolfSSLSession {
|
|||
* occur if needed */
|
||||
ret = read(localPtr, data, 0, sz, 0);
|
||||
|
||||
if (ret == WOLFJNI_SELECT_FAIL) {
|
||||
throw new SocketException("Socket select() failed, errno = " +
|
||||
WolfSSL.getErrno());
|
||||
}
|
||||
throwExceptionFromIOReturnValue(ret, "wolfSSL_read()");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -959,7 +953,7 @@ public class WolfSSLSession {
|
|||
* <code>BAD_FUNC_ARC</code> when bad arguments are used.
|
||||
* @throws IllegalStateException WolfSSLContext has been freed
|
||||
* @throws SocketTimeoutException if socket timeout occurs
|
||||
* @throws SocketException Native socket select() failed
|
||||
* @throws SocketException Native socket select/poll() failed
|
||||
*/
|
||||
public int read(byte[] data, int sz, int timeout)
|
||||
throws IllegalStateException, SocketTimeoutException, SocketException {
|
||||
|
@ -1005,7 +999,7 @@ public class WolfSSLSession {
|
|||
* <code>BAD_FUNC_ARC</code> when bad arguments are used.
|
||||
* @throws IllegalStateException WolfSSLContext has been freed
|
||||
* @throws SocketTimeoutException if socket timeout occurs
|
||||
* @throws SocketException Native socket select() failed
|
||||
* @throws SocketException Native socket select/poll() failed
|
||||
*/
|
||||
public int read(byte[] data, int offset, int sz, int timeout)
|
||||
throws IllegalStateException, SocketTimeoutException, SocketException {
|
||||
|
@ -1028,13 +1022,7 @@ public class WolfSSLSession {
|
|||
* occur if needed */
|
||||
ret = read(localPtr, data, offset, sz, timeout);
|
||||
|
||||
if (ret == WOLFJNI_TIMEOUT) {
|
||||
throw new SocketTimeoutException("Socket read timeout");
|
||||
}
|
||||
else if (ret == WOLFJNI_SELECT_FAIL) {
|
||||
throw new SocketException("Socket select() failed, errno = " +
|
||||
WolfSSL.getErrno());
|
||||
}
|
||||
throwExceptionFromIOReturnValue(ret, "wolfSSL_read()");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1063,31 +1051,14 @@ public class WolfSSLSession {
|
|||
* error code, call <code>getError()</code>.
|
||||
* @throws IllegalStateException WolfSSLContext has been freed
|
||||
* @throws SocketTimeoutException if underlying socket timed out
|
||||
* @throws SocketException Native socket select() failed
|
||||
* @throws SocketException Native socket select/accept() failed
|
||||
* @see #getError(int)
|
||||
* @see #connect()
|
||||
*/
|
||||
public int accept()
|
||||
throws IllegalStateException, SocketTimeoutException, SocketException {
|
||||
|
||||
int ret;
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
synchronized (sslLock) {
|
||||
ret = accept(this.sslPtr, 0);
|
||||
}
|
||||
|
||||
if (ret == WolfSSL.WOLFJNI_TIMEOUT) {
|
||||
throw new SocketTimeoutException(
|
||||
"Native socket timed out during SSL_accept()");
|
||||
}
|
||||
else if (ret == WOLFJNI_SELECT_FAIL) {
|
||||
throw new SocketException("Socket select() failed, errno = " +
|
||||
WolfSSL.getErrno());
|
||||
}
|
||||
|
||||
return ret;
|
||||
return accept(0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1132,14 +1103,7 @@ public class WolfSSLSession {
|
|||
ret = accept(this.sslPtr, timeout);
|
||||
}
|
||||
|
||||
if (ret == WolfSSL.WOLFJNI_TIMEOUT) {
|
||||
throw new SocketTimeoutException(
|
||||
"Native socket timed out during SSL_accept()");
|
||||
}
|
||||
else if (ret == WOLFJNI_SELECT_FAIL) {
|
||||
throw new SocketException("Socket select() failed, errno = " +
|
||||
WolfSSL.getErrno());
|
||||
}
|
||||
throwExceptionFromIOReturnValue(ret, "wolfSSL_accept()");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1199,28 +1163,17 @@ public class WolfSSLSession {
|
|||
* <code>SSL_FATAL_ERROR</code> upon failure. Call <code>
|
||||
* getError()</code> for a more specific error code.
|
||||
* @throws IllegalStateException WolfSSLContext has been freed
|
||||
* @throws SocketException Native socket select() failed
|
||||
* @throws SocketTimeoutException if socket timeout occurs, should not
|
||||
* since infinite timeout is used for this call.
|
||||
* @throws SocketException Native socket select/poll() failed
|
||||
* @see #shutdownSSL(int)
|
||||
* @see #freeSSL(long)
|
||||
* @see WolfSSLContext#free()
|
||||
*/
|
||||
public int shutdownSSL()
|
||||
throws IllegalStateException, SocketException {
|
||||
throws IllegalStateException, SocketTimeoutException, SocketException {
|
||||
|
||||
int ret;
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
synchronized (sslLock) {
|
||||
ret = shutdownSSL(this.sslPtr, 0);
|
||||
}
|
||||
|
||||
if (ret == WOLFJNI_SELECT_FAIL) {
|
||||
throw new SocketException("Socket select() failed, errno = " +
|
||||
WolfSSL.getErrno());
|
||||
}
|
||||
|
||||
return ret;
|
||||
return shutdownSSL(0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1250,8 +1203,8 @@ public class WolfSSLSession {
|
|||
* <code>SSL_FATAL_ERROR</code> upon failure. Call <code>
|
||||
* getError()</code> for a more specific error code.
|
||||
* @throws IllegalStateException WolfSSLContext has been freed
|
||||
* @throws SocketTimeoutException if read timeout occurs.
|
||||
* @throws SocketException Native socket select() failed
|
||||
* @throws SocketTimeoutException if socket timeout occurs.
|
||||
* @throws SocketException Native socket select/poll() failed
|
||||
* @see #freeSSL(long)
|
||||
* @see WolfSSLContext#free()
|
||||
*/
|
||||
|
@ -1266,13 +1219,7 @@ public class WolfSSLSession {
|
|||
ret = shutdownSSL(this.sslPtr, timeout);
|
||||
}
|
||||
|
||||
if (ret == WOLFJNI_TIMEOUT) {
|
||||
throw new SocketTimeoutException("Socket read timeout");
|
||||
}
|
||||
else if (ret == WOLFJNI_SELECT_FAIL) {
|
||||
throw new SocketException("Socket select() failed, errno = " +
|
||||
WolfSSL.getErrno());
|
||||
}
|
||||
throwExceptionFromIOReturnValue(ret, "wolfSSL_shutdown()");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -353,8 +353,11 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
*
|
||||
* @return WolfSSL.SSL_SUCCESS on success, zero or negative on error
|
||||
* @throws SocketException if ssl.shutdownSSL() encounters a socket error
|
||||
* @throws SocketTimeoutException if ssl.shutdownSSL() times out
|
||||
*/
|
||||
private synchronized int ClosingConnection() throws SocketException {
|
||||
private synchronized int ClosingConnection()
|
||||
throws SocketException, SocketTimeoutException {
|
||||
|
||||
int ret;
|
||||
|
||||
/* Save session into WolfSSLAuthStore cache, saves session
|
||||
|
@ -395,7 +398,13 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
|
||||
/**
|
||||
* Starts or continues SSL/TLS handshake.
|
||||
* Returns WolfSSL.SSL_SUCCESS or WolfSSL.SSL_FAILURE
|
||||
*
|
||||
* @return WolfSSL.SSL_SUCCESS or WolfSSL.SSL_FAILURE
|
||||
* @throws SocketException if ssl.connect() or ssl.accept() encounters
|
||||
* a socket exception.
|
||||
* @throws SocketTimeoutException if ssl.connect() or ssl.accept()
|
||||
* times out. This should not happen since infinite timeout is
|
||||
* being used for these calls.
|
||||
*/
|
||||
private synchronized int DoHandshake() throws SSLException {
|
||||
int ret = WolfSSL.SSL_SUCCESS;
|
||||
|
@ -434,10 +443,12 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
* (SSLSession.getApplicationBufferSize()).
|
||||
*
|
||||
* @throws SocketException if ssl.write() encounters a socket error
|
||||
* @throws SocketTimeoutException if ssl.write() times out. Shouldn't
|
||||
* happen since this is using an infinite timeout.
|
||||
* @return bytes sent on success, negative on error
|
||||
*/
|
||||
private synchronized int SendAppData(ByteBuffer[] in, int ofst, int len)
|
||||
throws SocketException {
|
||||
throws SocketException, SocketTimeoutException {
|
||||
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
|
@ -629,7 +640,7 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
|
||||
try {
|
||||
ClosingConnection();
|
||||
} catch (SocketException e) {
|
||||
} catch (SocketException | SocketTimeoutException e) {
|
||||
throw new SSLException(e);
|
||||
}
|
||||
produced += CopyOutPacket(out);
|
||||
|
@ -653,7 +664,7 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
if (ret > 0) {
|
||||
consumed += ret;
|
||||
}
|
||||
} catch (SocketException e) {
|
||||
} catch (SocketException | SocketTimeoutException e) {
|
||||
throw new SSLException(e);
|
||||
}
|
||||
}
|
||||
|
@ -781,7 +792,7 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
synchronized (ioLock) {
|
||||
try {
|
||||
ret = this.ssl.read(tmp, maxOutSz);
|
||||
} catch (SocketException e) {
|
||||
} catch (SocketTimeoutException | SocketException e) {
|
||||
throw new SSLException(e);
|
||||
}
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
|
@ -821,7 +832,8 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
* 0, or err */
|
||||
ret = 0;
|
||||
}
|
||||
} catch (SocketException e) {
|
||||
} catch (SocketException |
|
||||
SocketTimeoutException e) {
|
||||
throw new SSLException(e);
|
||||
}
|
||||
return ret;
|
||||
|
@ -998,7 +1010,7 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
* release, global JNI verify callback pointer */
|
||||
this.engineHelper.unsetVerifyCallback();
|
||||
}
|
||||
} catch (SocketException e) {
|
||||
} catch (SocketException | SocketTimeoutException e) {
|
||||
throw new SSLException(e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1220,7 +1220,7 @@ public class WolfSSLEngineHelper {
|
|||
/* TODO: SunJSSE sends a Handshake Failure alert instead here */
|
||||
try {
|
||||
this.ssl.shutdownSSL();
|
||||
} catch (SocketException e) {
|
||||
} catch (SocketException | SocketTimeoutException e) {
|
||||
throw new SSLException(e);
|
||||
}
|
||||
|
||||
|
@ -1336,7 +1336,8 @@ public class WolfSSLEngineHelper {
|
|||
|
||||
} catch (SocketException e) {
|
||||
/* SocketException may be thrown if native socket
|
||||
* select() fails. Propogate errno back inside exception. */
|
||||
* select/poll() fails. Propogate errno back inside new
|
||||
* SSLException. */
|
||||
throw new SSLException(e);
|
||||
}
|
||||
|
||||
|
|
|
@ -943,7 +943,7 @@ public class WolfSSLSocket extends SSLSocket {
|
|||
"Failed to set native Socket fd");
|
||||
}
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"registered SSLSocket with native wolfSSL");
|
||||
"registered SSLSocket(this) with native wolfSSL");
|
||||
|
||||
} else {
|
||||
ret = ssl.setFd(this.socket);
|
||||
|
@ -962,7 +962,7 @@ public class WolfSSLSocket extends SSLSocket {
|
|||
}
|
||||
else {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"registered Socket with native wolfSSL");
|
||||
"registered Socket(this.socket) with native wolfSSL");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1888,14 +1888,23 @@ public class WolfSSLSocket extends SSLSocket {
|
|||
}
|
||||
}
|
||||
|
||||
if (this.socket != null) {
|
||||
ret = ssl.shutdownSSL(this.socket.getSoTimeout());
|
||||
} else {
|
||||
ret = ssl.shutdownSSL(super.getSoTimeout());
|
||||
}
|
||||
try {
|
||||
if (this.socket != null) {
|
||||
ret = ssl.shutdownSSL(
|
||||
this.socket.getSoTimeout());
|
||||
} else {
|
||||
ret = ssl.shutdownSSL(
|
||||
super.getSoTimeout());
|
||||
}
|
||||
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"ssl.shutdownSSL() ret = " + ret);
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"ssl.shutdownSSL() ret = " + ret);
|
||||
|
||||
} catch (SocketException | SocketTimeoutException e) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"Exception while trying to ssl.shutdownSSL(), " +
|
||||
"ignoring to finish cleanup");
|
||||
}
|
||||
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"thread trying to get handshakeLock");
|
||||
|
@ -2052,7 +2061,8 @@ public class WolfSSLSocket extends SSLSocket {
|
|||
InetSocketAddress address = null;
|
||||
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"entered connect(SocketAddress endpoint, int timeout)");
|
||||
"entered connect(SocketAddress endpoint, int timeout / " +
|
||||
timeout + " ms)");
|
||||
|
||||
if (!(endpoint instanceof InetSocketAddress)) {
|
||||
throw new IllegalArgumentException("endpoint is not of type " +
|
||||
|
@ -2066,6 +2076,8 @@ public class WolfSSLSocket extends SSLSocket {
|
|||
}
|
||||
|
||||
address = (InetSocketAddress)endpoint;
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"Underlying Java Socket connected to peer: " + address);
|
||||
|
||||
/* register host/port for session resumption in case where
|
||||
createSocket() was called without host/port, but
|
||||
|
@ -2510,6 +2522,16 @@ public class WolfSSLSocket extends SSLSocket {
|
|||
" (error code: " + err + ")");
|
||||
}
|
||||
|
||||
} catch (SocketException e) {
|
||||
/* ssl.read() can throw SocketException from poll() if fd
|
||||
* closed or peer shut down connection */
|
||||
if (e.getMessage().contains("fd closed during poll") ||
|
||||
e.getMessage().contains("disconnected during poll")) {
|
||||
/* end of stream */
|
||||
return -1;
|
||||
}
|
||||
throw e;
|
||||
|
||||
} catch (IllegalStateException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue