adding DTLS retry timeout, added CYASSL pointer to recv/send callbacks
This commit is contained in:
parent
3361f7b7fe
commit
407397e8be
@ -649,9 +649,9 @@ int SetCipherList(Suites*, const char* list);
|
|||||||
#ifndef CYASSL_USER_IO
|
#ifndef CYASSL_USER_IO
|
||||||
/* default IO callbacks */
|
/* default IO callbacks */
|
||||||
CYASSL_LOCAL
|
CYASSL_LOCAL
|
||||||
int EmbedReceive(char *buf, int sz, void *ctx);
|
int EmbedReceive(CYASSL *ssl, char *buf, int sz, void *ctx);
|
||||||
CYASSL_LOCAL
|
CYASSL_LOCAL
|
||||||
int EmbedSend(char *buf, int sz, void *ctx);
|
int EmbedSend(CYASSL *ssl, char *buf, int sz, void *ctx);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CYASSL_DTLS
|
#ifdef CYASSL_DTLS
|
||||||
@ -1132,6 +1132,7 @@ typedef struct Options {
|
|||||||
byte quietShutdown; /* don't send close notify */
|
byte quietShutdown; /* don't send close notify */
|
||||||
byte certOnly; /* stop once we get cert */
|
byte certOnly; /* stop once we get cert */
|
||||||
byte groupMessages; /* group handshake messages */
|
byte groupMessages; /* group handshake messages */
|
||||||
|
byte usingNonblock; /* set when using nonblocking socket */
|
||||||
#ifndef NO_PSK
|
#ifndef NO_PSK
|
||||||
byte havePSK; /* psk key set by user */
|
byte havePSK; /* psk key set by user */
|
||||||
psk_client_callback client_psk_cb;
|
psk_client_callback client_psk_cb;
|
||||||
@ -1258,6 +1259,9 @@ struct CYASSL {
|
|||||||
z_stream d_stream; /* decompression stream */
|
z_stream d_stream; /* decompression stream */
|
||||||
byte didStreamInit; /* for stream init and end */
|
byte didStreamInit; /* for stream init and end */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CYASSL_DTLS
|
||||||
|
int dtls_timeout;
|
||||||
|
#endif
|
||||||
#ifdef CYASSL_CALLBACKS
|
#ifdef CYASSL_CALLBACKS
|
||||||
HandShakeInfo handShakeInfo; /* info saved during handshake */
|
HandShakeInfo handShakeInfo; /* info saved during handshake */
|
||||||
TimeoutInfo timeoutInfo; /* info saved during handshake */
|
TimeoutInfo timeoutInfo; /* info saved during handshake */
|
||||||
@ -1396,7 +1400,8 @@ enum IOerrors {
|
|||||||
IO_ERR_WANT_WRITE = -2, /* need to call write again */
|
IO_ERR_WANT_WRITE = -2, /* need to call write again */
|
||||||
IO_ERR_CONN_RST = -3, /* connection reset */
|
IO_ERR_CONN_RST = -3, /* connection reset */
|
||||||
IO_ERR_ISR = -4, /* interrupt */
|
IO_ERR_ISR = -4, /* interrupt */
|
||||||
IO_ERR_CONN_CLOSE = -5 /* connection closed or epipe */
|
IO_ERR_CONN_CLOSE = -5, /* connection closed or epipe */
|
||||||
|
IO_ERR_TIMEOUT = -6 /* socket timeout */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -179,6 +179,7 @@ CYASSL_API CYASSL_CTX* CyaSSL_CTX_new(CYASSL_METHOD*);
|
|||||||
CYASSL_API CYASSL* CyaSSL_new(CYASSL_CTX*);
|
CYASSL_API CYASSL* CyaSSL_new(CYASSL_CTX*);
|
||||||
CYASSL_API int CyaSSL_set_fd (CYASSL*, int);
|
CYASSL_API int CyaSSL_set_fd (CYASSL*, int);
|
||||||
CYASSL_API int CyaSSL_get_fd(const CYASSL*);
|
CYASSL_API int CyaSSL_get_fd(const CYASSL*);
|
||||||
|
CYASSL_API void CyaSSL_using_nonblock(CYASSL*);
|
||||||
CYASSL_API int CyaSSL_connect(CYASSL*); /* please see note at top of README
|
CYASSL_API int CyaSSL_connect(CYASSL*); /* please see note at top of README
|
||||||
if you get an error from connect */
|
if you get an error from connect */
|
||||||
CYASSL_API int CyaSSL_write(CYASSL*, const void*, int);
|
CYASSL_API int CyaSSL_write(CYASSL*, const void*, int);
|
||||||
@ -760,8 +761,8 @@ CYASSL_API int CyaSSL_use_certificate_chain_buffer(CYASSL*,
|
|||||||
CYASSL_API int CyaSSL_set_group_messages(CYASSL*);
|
CYASSL_API int CyaSSL_set_group_messages(CYASSL*);
|
||||||
|
|
||||||
/* I/O callbacks */
|
/* I/O callbacks */
|
||||||
typedef int (*CallbackIORecv)(char *buf, int sz, void *ctx);
|
typedef int (*CallbackIORecv)(CYASSL *ssl, char *buf, int sz, void *ctx);
|
||||||
typedef int (*CallbackIOSend)(char *buf, int sz, void *ctx);
|
typedef int (*CallbackIOSend)(CYASSL *ssl, char *buf, int sz, void *ctx);
|
||||||
|
|
||||||
CYASSL_API void CyaSSL_SetIORecv(CYASSL_CTX*, CallbackIORecv);
|
CYASSL_API void CyaSSL_SetIORecv(CYASSL_CTX*, CallbackIORecv);
|
||||||
CYASSL_API void CyaSSL_SetIOSend(CYASSL_CTX*, CallbackIOSend);
|
CYASSL_API void CyaSSL_SetIOSend(CYASSL_CTX*, CallbackIOSend);
|
||||||
|
@ -337,6 +337,7 @@ void client_test(void* args)
|
|||||||
if (matchName && doPeerCheck)
|
if (matchName && doPeerCheck)
|
||||||
CyaSSL_check_domain_name(ssl, domain);
|
CyaSSL_check_domain_name(ssl, domain);
|
||||||
#ifdef NON_BLOCKING
|
#ifdef NON_BLOCKING
|
||||||
|
CyaSSL_using_nonblock(ssl);
|
||||||
tcp_set_nonblocking(&sockfd);
|
tcp_set_nonblocking(&sockfd);
|
||||||
NonBlockingSSL_Connect(ssl);
|
NonBlockingSSL_Connect(ssl);
|
||||||
#else
|
#else
|
||||||
@ -411,6 +412,7 @@ void client_test(void* args)
|
|||||||
|
|
||||||
showPeer(sslResume);
|
showPeer(sslResume);
|
||||||
#ifdef NON_BLOCKING
|
#ifdef NON_BLOCKING
|
||||||
|
CyaSSL_using_nonblock(sslResume);
|
||||||
tcp_set_nonblocking(&sockfd);
|
tcp_set_nonblocking(&sockfd);
|
||||||
NonBlockingSSL_Connect(sslResume);
|
NonBlockingSSL_Connect(sslResume);
|
||||||
#else
|
#else
|
||||||
|
@ -923,6 +923,7 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
|
|||||||
ssl->keys.dtls_peer_epoch = 0;
|
ssl->keys.dtls_peer_epoch = 0;
|
||||||
ssl->keys.dtls_expected_peer_epoch = 0;
|
ssl->keys.dtls_expected_peer_epoch = 0;
|
||||||
ssl->arrays.cookieSz = 0;
|
ssl->arrays.cookieSz = 0;
|
||||||
|
ssl->dtls_timeout = 2;
|
||||||
#endif
|
#endif
|
||||||
ssl->keys.encryptionOn = 0; /* initially off */
|
ssl->keys.encryptionOn = 0; /* initially off */
|
||||||
ssl->options.sessionCacheOff = ctx->sessionCacheOff;
|
ssl->options.sessionCacheOff = ctx->sessionCacheOff;
|
||||||
@ -944,6 +945,7 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
|
|||||||
ssl->options.quietShutdown = ctx->quietShutdown;
|
ssl->options.quietShutdown = ctx->quietShutdown;
|
||||||
ssl->options.certOnly = 0;
|
ssl->options.certOnly = 0;
|
||||||
ssl->options.groupMessages = ctx->groupMessages;
|
ssl->options.groupMessages = ctx->groupMessages;
|
||||||
|
ssl->options.usingNonblock = 0;
|
||||||
|
|
||||||
/* ctx still owns certificate, certChain, key, dh, and cm */
|
/* ctx still owns certificate, certChain, key, dh, and cm */
|
||||||
ssl->buffers.certificate = ctx->certificate;
|
ssl->buffers.certificate = ctx->certificate;
|
||||||
@ -1305,7 +1307,7 @@ static int Receive(CYASSL* ssl, byte* buf, word32 sz)
|
|||||||
int recvd;
|
int recvd;
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
recvd = ssl->ctx->CBIORecv((char *)buf, (int)sz, ssl->IOCB_ReadCtx);
|
recvd = ssl->ctx->CBIORecv(ssl, (char *)buf, (int)sz, ssl->IOCB_ReadCtx);
|
||||||
if (recvd < 0)
|
if (recvd < 0)
|
||||||
switch (recvd) {
|
switch (recvd) {
|
||||||
case IO_ERR_GENERAL: /* general/unknown error */
|
case IO_ERR_GENERAL: /* general/unknown error */
|
||||||
@ -1339,6 +1341,10 @@ retry:
|
|||||||
ssl->options.isClosed = 1;
|
ssl->options.isClosed = 1;
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
case IO_ERR_TIMEOUT:
|
||||||
|
/* XXX More than retry. Need to resend. */
|
||||||
|
goto retry;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return recvd;
|
return recvd;
|
||||||
}
|
}
|
||||||
@ -1386,7 +1392,8 @@ void ShrinkInputBuffer(CYASSL* ssl, int forcedFree)
|
|||||||
int SendBuffered(CYASSL* ssl)
|
int SendBuffered(CYASSL* ssl)
|
||||||
{
|
{
|
||||||
while (ssl->buffers.outputBuffer.length > 0) {
|
while (ssl->buffers.outputBuffer.length > 0) {
|
||||||
int sent = ssl->ctx->CBIOSend((char*)ssl->buffers.outputBuffer.buffer +
|
int sent = ssl->ctx->CBIOSend(ssl,
|
||||||
|
(char*)ssl->buffers.outputBuffer.buffer +
|
||||||
ssl->buffers.outputBuffer.idx,
|
ssl->buffers.outputBuffer.idx,
|
||||||
(int)ssl->buffers.outputBuffer.length,
|
(int)ssl->buffers.outputBuffer.length,
|
||||||
ssl->IOCB_WriteCtx);
|
ssl->IOCB_WriteCtx);
|
||||||
|
28
src/io.c
28
src/io.c
@ -134,12 +134,24 @@ static INLINE int LastError(void)
|
|||||||
/* The receive embedded callback
|
/* The receive embedded callback
|
||||||
* return : nb bytes read, or error
|
* return : nb bytes read, or error
|
||||||
*/
|
*/
|
||||||
int EmbedReceive(char *buf, int sz, void *ctx)
|
int EmbedReceive(CYASSL *ssl, char *buf, int sz, void *ctx)
|
||||||
{
|
{
|
||||||
int recvd;
|
int recvd;
|
||||||
int err;
|
int err;
|
||||||
int sd = *(int*)ctx;
|
int sd = *(int*)ctx;
|
||||||
|
|
||||||
|
#ifdef CYASSL_DTLS
|
||||||
|
if (ssl->options.dtls
|
||||||
|
&& !ssl->options.usingNonblock && ssl->dtls_timeout != 0) {
|
||||||
|
#if USE_WINDOWS_API
|
||||||
|
DWORD timeout = ssl->dtls_timeout;
|
||||||
|
#else
|
||||||
|
struct timeval timeout = {ssl->dtls_timeout, 0};
|
||||||
|
#endif
|
||||||
|
setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
recvd = RECV_FUNCTION(sd, (char *)buf, sz, 0);
|
recvd = RECV_FUNCTION(sd, (char *)buf, sz, 0);
|
||||||
|
|
||||||
if (recvd < 0) {
|
if (recvd < 0) {
|
||||||
@ -147,8 +159,14 @@ int EmbedReceive(char *buf, int sz, void *ctx)
|
|||||||
CYASSL_MSG("Embed Receive error");
|
CYASSL_MSG("Embed Receive error");
|
||||||
|
|
||||||
if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
|
if (err == SOCKET_EWOULDBLOCK || err == SOCKET_EAGAIN) {
|
||||||
CYASSL_MSG(" Would block");
|
if (ssl->options.usingNonblock) {
|
||||||
return IO_ERR_WANT_READ;
|
CYASSL_MSG(" Would block");
|
||||||
|
return IO_ERR_WANT_READ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CYASSL_MSG(" Socket timeout");
|
||||||
|
return IO_ERR_TIMEOUT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (err == SOCKET_ECONNRESET) {
|
else if (err == SOCKET_ECONNRESET) {
|
||||||
CYASSL_MSG(" Connection reset");
|
CYASSL_MSG(" Connection reset");
|
||||||
@ -174,13 +192,15 @@ int EmbedReceive(char *buf, int sz, void *ctx)
|
|||||||
/* The send embedded callback
|
/* The send embedded callback
|
||||||
* return : nb bytes sent, or error
|
* return : nb bytes sent, or error
|
||||||
*/
|
*/
|
||||||
int EmbedSend(char *buf, int sz, void *ctx)
|
int EmbedSend(CYASSL* ssl, char *buf, int sz, void *ctx)
|
||||||
{
|
{
|
||||||
int sd = *(int*)ctx;
|
int sd = *(int*)ctx;
|
||||||
int sent;
|
int sent;
|
||||||
int len = sz;
|
int len = sz;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
(void)ssl;
|
||||||
|
|
||||||
sent = SEND_FUNCTION(sd, &buf[sz - len], len, 0);
|
sent = SEND_FUNCTION(sd, &buf[sz - len], len, 0);
|
||||||
|
|
||||||
if (sent < 0) {
|
if (sent < 0) {
|
||||||
|
30
src/ssl.c
30
src/ssl.c
@ -185,6 +185,13 @@ int CyaSSL_get_fd(const CYASSL* ssl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CyaSSL_using_nonblock(CYASSL* ssl)
|
||||||
|
{
|
||||||
|
CYASSL_ENTER("CyaSSL_using_nonblock");
|
||||||
|
ssl->options.usingNonblock = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int CyaSSL_negotiate(CYASSL* ssl)
|
int CyaSSL_negotiate(CYASSL* ssl)
|
||||||
{
|
{
|
||||||
int err = SSL_FATAL_ERROR;
|
int err = SSL_FATAL_ERROR;
|
||||||
@ -2175,6 +2182,29 @@ int CyaSSL_set_cipher_list(CYASSL* ssl, const char* list)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int CyaSSL_dtls_get_current_timeout(CYASSL* ssl)
|
||||||
|
{
|
||||||
|
(void)ssl;
|
||||||
|
|
||||||
|
#ifdef CYASSL_DTLS
|
||||||
|
return ssl->dtls_timeout;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CyaSSL_dtls_got_timeout(CYASSL* ssl)
|
||||||
|
{
|
||||||
|
(void)ssl;
|
||||||
|
|
||||||
|
#ifdef CYASSL_DTLS
|
||||||
|
if (ssl->dtls_timeout < 64)
|
||||||
|
ssl->dtls_timeout *= 2;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* client only parts */
|
/* client only parts */
|
||||||
#ifndef NO_CYASSL_CLIENT
|
#ifndef NO_CYASSL_CLIENT
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user