adding DTLS retry timeout, added CYASSL pointer to recv/send callbacks

This commit is contained in:
John Safranek 2012-09-06 22:41:55 -07:00
parent 3361f7b7fe
commit 407397e8be
6 changed files with 76 additions and 11 deletions

View File

@ -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 */
}; };

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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) {

View File

@ -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