added dtls message retry
This commit is contained in:
parent
97ca8439a4
commit
56ee2eaba8
@ -218,7 +218,8 @@ enum {
|
||||
DYNAMIC_TYPE_ALTNAME = 29,
|
||||
DYNAMIC_TYPE_SUITES = 30,
|
||||
DYNAMIC_TYPE_CIPHER = 31,
|
||||
DYNAMIC_TYPE_RNG = 32
|
||||
DYNAMIC_TYPE_RNG = 32,
|
||||
DYNAMIC_TYPE_DTLS_POOL = 33
|
||||
};
|
||||
|
||||
/* stack protection */
|
||||
|
@ -398,6 +398,7 @@ enum Misc {
|
||||
DTLS_RECORD_EXTRA = 8, /* diff from normal */
|
||||
DTLS_HANDSHAKE_SEQ_SZ = 2, /* handshake header sequence number */
|
||||
DTLS_HANDSHAKE_FRAG_SZ = 3, /* fragment offset and length are 24 bit */
|
||||
DTLS_POOL_SZ = 5, /* buffers to hold in the retry pool */
|
||||
|
||||
FINISHED_LABEL_SZ = 15, /* TLS finished label size */
|
||||
TLS_FINISHED_SZ = 12, /* TLS has a shorter size */
|
||||
@ -445,6 +446,7 @@ enum Misc {
|
||||
CLIENT_HELLO_FIRST = 35, /* Protocol + RAN_LEN + sizeof(id_len) */
|
||||
MAX_SUITE_NAME = 48, /* maximum length of cipher suite string */
|
||||
DEFAULT_TIMEOUT = 500, /* default resumption timeout in seconds */
|
||||
DTLS_DEFAULT_TIMEOUT = 1, /* default timeout for DTLS receive */
|
||||
|
||||
MAX_PSK_ID_LEN = 128, /* max psk identity/hint supported */
|
||||
MAX_PSK_KEY_LEN = 64, /* max psk key supported */
|
||||
@ -1210,6 +1212,13 @@ typedef struct DtlsRecordLayerHeader {
|
||||
} DtlsRecordLayerHeader;
|
||||
|
||||
|
||||
typedef struct DtlsPool {
|
||||
buffer buf[DTLS_POOL_SZ];
|
||||
int used;
|
||||
byte pool[MAX_MTU*DTLS_POOL_SZ];
|
||||
} DtlsPool;
|
||||
|
||||
|
||||
/* CyaSSL ssl type */
|
||||
struct CYASSL {
|
||||
CYASSL_CTX* ctx;
|
||||
@ -1274,6 +1283,7 @@ struct CYASSL {
|
||||
#endif
|
||||
#ifdef CYASSL_DTLS
|
||||
int dtls_timeout;
|
||||
DtlsPool* dtls_pool;
|
||||
#endif
|
||||
#ifdef CYASSL_CALLBACKS
|
||||
HandShakeInfo handShakeInfo; /* info saved during handshake */
|
||||
@ -1479,6 +1489,12 @@ CYASSL_LOCAL void BuildTlsFinished(CYASSL* ssl, Hashes* hashes,
|
||||
#endif
|
||||
#endif /* NO_CYASSL_SERVER */
|
||||
|
||||
#ifdef CYASSL_DTLS
|
||||
CYASSL_LOCAL int DtlsPoolInit(CYASSL*);
|
||||
CYASSL_LOCAL void DtlsPoolSave(CYASSL*, const byte*, int);
|
||||
CYASSL_LOCAL int DtlsPoolSend(CYASSL*);
|
||||
CYASSL_LOCAL void DtlsPoolReset(CYASSL*);
|
||||
#endif /* CYASSL_DTLS */
|
||||
|
||||
#ifndef NO_TLS
|
||||
|
||||
|
@ -216,6 +216,10 @@ CYASSL_API long CyaSSL_CTX_set_session_cache_mode(CYASSL_CTX*, long);
|
||||
CYASSL_API int CyaSSL_CTX_set_cipher_list(CYASSL_CTX*, const char*);
|
||||
CYASSL_API int CyaSSL_set_cipher_list(CYASSL*, const char*);
|
||||
|
||||
/* Nonblocking DTLS helper functions */
|
||||
CYASSL_API int CyaSSL_dtls_get_current_timeout(CYASSL* ssl);
|
||||
CYASSL_API int CyaSSL_dtls_got_timeout(CYASSL* ssl);
|
||||
|
||||
CYASSL_API int CyaSSL_ERR_GET_REASON(int err);
|
||||
CYASSL_API char* CyaSSL_ERR_error_string(unsigned long,char*);
|
||||
CYASSL_API void CyaSSL_ERR_error_string_n(unsigned long e, char* buf,
|
||||
|
@ -292,6 +292,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
|
||||
#endif
|
||||
|
||||
#ifdef NON_BLOCKING
|
||||
CyaSSL_using_nonblock(ssl);
|
||||
tcp_set_nonblocking(&clientfd);
|
||||
NonBlockingSSL_Accept(ssl);
|
||||
#else
|
||||
|
168
src/internal.c
168
src/internal.c
@ -981,7 +981,8 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
|
||||
ssl->keys.dtls_peer_epoch = 0;
|
||||
ssl->keys.dtls_expected_peer_epoch = 0;
|
||||
ssl->arrays.cookieSz = 0;
|
||||
ssl->dtls_timeout = 2;
|
||||
ssl->dtls_timeout = DTLS_DEFAULT_TIMEOUT;
|
||||
ssl->dtls_pool = NULL;
|
||||
#endif
|
||||
ssl->keys.encryptionOn = 0; /* initially off */
|
||||
ssl->keys.decryptedCur = 0; /* initially off */
|
||||
@ -1135,6 +1136,8 @@ void SSL_ResourceFree(CYASSL* ssl)
|
||||
#ifdef CYASSL_DTLS
|
||||
if (ssl->buffers.dtlsHandshake.buffer != NULL)
|
||||
XFREE(ssl->buffers.dtlsHandshake.buffer, ssl->heap, DYNAMIC_TYPE_NONE);
|
||||
if (ssl->dtls_pool != NULL)
|
||||
XFREE(ssl->dtls_pool, ssl->heap, DYNAMIC_TYPE_NONE);
|
||||
#endif
|
||||
#if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
|
||||
XFREE(ssl->peerCert.derCert.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
|
||||
@ -1172,6 +1175,14 @@ void FreeHandshakeResources(CYASSL* ssl)
|
||||
XFREE(ssl->rng, ssl->heap, DYNAMIC_TYPE_RNG);
|
||||
ssl->rng = NULL;
|
||||
}
|
||||
|
||||
#ifdef CYASSL_DTLS
|
||||
/* DTLS_POOL */
|
||||
if (ssl->options.dtls && ssl->dtls_pool != NULL) {
|
||||
XFREE(ssl->dtls_pool, ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
|
||||
ssl->dtls_pool = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -1183,6 +1194,87 @@ void FreeSSL(CYASSL* ssl)
|
||||
}
|
||||
|
||||
|
||||
#ifdef CYASSL_DTLS
|
||||
|
||||
int DtlsPoolInit(CYASSL* ssl)
|
||||
{
|
||||
if (ssl->dtls_pool == NULL) {
|
||||
DtlsPool *pool = (DtlsPool*)XMALLOC(sizeof(DtlsPool),
|
||||
ssl->heap, DYNAMIC_TYPE_DTLS_POOL);
|
||||
if (pool == NULL) {
|
||||
CYASSL_MSG("DTLS Buffer Pool Memory error");
|
||||
return MEMORY_E;
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < DTLS_POOL_SZ; i++) {
|
||||
pool->buf[i].length = 0;
|
||||
pool->buf[i].buffer = pool->pool + (MAX_MTU * i);
|
||||
}
|
||||
pool->used = 0;
|
||||
ssl->dtls_pool = pool;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void DtlsPoolSave(CYASSL* ssl, const byte *src, int sz)
|
||||
{
|
||||
DtlsPool *pool = ssl->dtls_pool;
|
||||
if (pool != NULL && pool->used < DTLS_POOL_SZ) {
|
||||
buffer *buf = &pool->buf[pool->used];
|
||||
XMEMCPY(buf->buffer, src, sz);
|
||||
buf->length = (word32)sz;
|
||||
pool->used++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DtlsPoolReset(CYASSL* ssl)
|
||||
{
|
||||
if (ssl->dtls_pool != NULL) {
|
||||
ssl->dtls_pool->used = 0;
|
||||
ssl->dtls_timeout = DTLS_DEFAULT_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int DtlsPoolSend(CYASSL* ssl)
|
||||
{
|
||||
DtlsPool *pool = ssl->dtls_pool;
|
||||
|
||||
if (pool != NULL && pool->used > 0) {
|
||||
int i;
|
||||
for (i = 0; i < pool->used; i++) {
|
||||
int sendResult;
|
||||
buffer* buf = &pool->buf[i];
|
||||
DtlsRecordLayerHeader* dtls = (DtlsRecordLayerHeader*)buf->buffer;
|
||||
|
||||
if (dtls->type == change_cipher_spec) {
|
||||
ssl->keys.dtls_epoch++;
|
||||
ssl->keys.dtls_sequence_number = 0;
|
||||
}
|
||||
c16toa(ssl->keys.dtls_epoch, dtls->epoch);
|
||||
c32to48(ssl->keys.dtls_sequence_number++, dtls->sequence_number);
|
||||
|
||||
XMEMCPY(ssl->buffers.outputBuffer.buffer, buf->buffer, buf->length);
|
||||
ssl->buffers.outputBuffer.idx = 0;
|
||||
ssl->buffers.outputBuffer.length = buf->length;
|
||||
|
||||
sendResult = SendBuffered(ssl);
|
||||
if (sendResult < 0) {
|
||||
return sendResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
ProtocolVersion MakeSSLv3(void)
|
||||
{
|
||||
ProtocolVersion pv;
|
||||
@ -1438,9 +1530,11 @@ retry:
|
||||
ssl->options.isClosed = 1;
|
||||
return -1;
|
||||
|
||||
#ifdef CYASSL_DTLS
|
||||
case IO_ERR_TIMEOUT:
|
||||
/* XXX More than retry. Need to resend. */
|
||||
DtlsPoolSend(ssl);
|
||||
goto retry;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return recvd;
|
||||
@ -3014,6 +3108,7 @@ int ProcessReply(CYASSL* ssl)
|
||||
|
||||
#ifdef CYASSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
DtlsPoolReset(ssl);
|
||||
ssl->keys.dtls_expected_peer_epoch++;
|
||||
ssl->keys.dtls_expected_peer_sequence_number = 0;
|
||||
}
|
||||
@ -3120,6 +3215,11 @@ int SendChangeCipher(CYASSL* ssl)
|
||||
|
||||
output[idx] = 1; /* turn it on */
|
||||
|
||||
#ifdef CYASSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
DtlsPoolSave(ssl, output, sendSz);
|
||||
}
|
||||
#endif
|
||||
#ifdef CYASSL_CALLBACKS
|
||||
if (ssl->hsInfoOn) AddPacketName("ChangeCipher", &ssl->handShakeInfo);
|
||||
if (ssl->toInfoOn)
|
||||
@ -3318,8 +3418,14 @@ static int BuildMessage(CYASSL* ssl, byte* output, const byte* input, int inSz,
|
||||
XMEMCPY(output + idx, input, inSz);
|
||||
idx += inSz;
|
||||
|
||||
if (type == handshake)
|
||||
if (type == handshake) {
|
||||
#ifdef CYASSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
DtlsPoolSave(ssl, output, headerSz+inSz);
|
||||
}
|
||||
#endif
|
||||
HashOutput(ssl, output, headerSz + inSz, ivSz);
|
||||
}
|
||||
if (ssl->specs.cipher_type != aead) {
|
||||
ssl->hmac(ssl, output+idx, output + headerSz + ivSz, inSz, type, 0);
|
||||
idx += digestSz;
|
||||
@ -3389,6 +3495,11 @@ int SendFinished(CYASSL* ssl)
|
||||
else
|
||||
BuildFinished(ssl, &ssl->verifyHashes, client);
|
||||
}
|
||||
#ifdef CYASSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
DtlsPoolSave(ssl, output, sendSz);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CYASSL_CALLBACKS
|
||||
if (ssl->hsInfoOn) AddPacketName("Finished", &ssl->handShakeInfo);
|
||||
@ -3467,6 +3578,11 @@ int SendCertificate(CYASSL* ssl)
|
||||
i += ssl->buffers.certChain.length; */
|
||||
}
|
||||
}
|
||||
#ifdef CYASSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
DtlsPoolSave(ssl, output, sendSz);
|
||||
}
|
||||
#endif
|
||||
HashOutput(ssl, output, sendSz, 0);
|
||||
#ifdef CYASSL_CALLBACKS
|
||||
if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
|
||||
@ -3536,6 +3652,11 @@ int SendCertificateRequest(CYASSL* ssl)
|
||||
/* if add more to output, adjust i
|
||||
i += REQ_HEADER_SZ; */
|
||||
|
||||
#ifdef CYASSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
DtlsPoolSave(ssl, output, sendSz);
|
||||
}
|
||||
#endif
|
||||
HashOutput(ssl, output, sendSz, 0);
|
||||
|
||||
#ifdef CYASSL_CALLBACKS
|
||||
@ -4797,6 +4918,11 @@ int SetCipherList(Suites* s, const char* list)
|
||||
output[idx++] = ecc_dsa_sa_algo;
|
||||
}
|
||||
|
||||
#ifdef CYASSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
DtlsPoolSave(ssl, output, sendSz);
|
||||
}
|
||||
#endif
|
||||
HashOutput(ssl, output, sendSz, 0);
|
||||
|
||||
ssl->options.clientState = CLIENT_HELLO_COMPLETE;
|
||||
@ -4824,6 +4950,11 @@ int SetCipherList(Suites* s, const char* list)
|
||||
if (ssl->hsInfoOn) AddPacketName("HelloVerifyRequest",
|
||||
&ssl->handShakeInfo);
|
||||
if (ssl->toInfoOn) AddLateName("HelloVerifyRequest", &ssl->timeoutInfo);
|
||||
#endif
|
||||
#ifdef CYASSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
DtlsPoolReset(ssl);
|
||||
}
|
||||
#endif
|
||||
XMEMCPY(&pv, input + *inOutIdx, sizeof(pv));
|
||||
*inOutIdx += sizeof(pv);
|
||||
@ -4937,7 +5068,11 @@ int SetCipherList(Suites* s, const char* list)
|
||||
ssl->options.resuming = 0; /* server denied resumption try */
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CYASSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
DtlsPoolReset(ssl);
|
||||
}
|
||||
#endif
|
||||
return SetCipherSpecs(ssl);
|
||||
}
|
||||
|
||||
@ -5391,7 +5526,11 @@ int SetCipherList(Suites* s, const char* list)
|
||||
XMEMCPY(output + idx, encSecret, encSz);
|
||||
/* if add more to output, adjust idx
|
||||
idx += encSz; */
|
||||
|
||||
#ifdef CYASSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
DtlsPoolSave(ssl, output, sendSz);
|
||||
}
|
||||
#endif
|
||||
HashOutput(ssl, output, sendSz, 0);
|
||||
|
||||
#ifdef CYASSL_CALLBACKS
|
||||
@ -5527,8 +5666,10 @@ int SetCipherList(Suites* s, const char* list)
|
||||
sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + length +
|
||||
extraSz + VERIFY_HEADER;
|
||||
#ifdef CYASSL_DTLS
|
||||
if (ssl->options.dtls)
|
||||
if (ssl->options.dtls) {
|
||||
sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
|
||||
DtlsPoolSave(ssl, output, sendSz);
|
||||
}
|
||||
#endif
|
||||
HashOutput(ssl, output, sendSz, 0);
|
||||
}
|
||||
@ -5631,6 +5772,11 @@ int SetCipherList(Suites* s, const char* list)
|
||||
output[idx++] = NO_COMPRESSION;
|
||||
|
||||
ssl->buffers.outputBuffer.length += sendSz;
|
||||
#ifdef CYASSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
DtlsPoolSave(ssl, output, sendSz);
|
||||
}
|
||||
#endif
|
||||
HashOutput(ssl, output, sendSz, 0);
|
||||
|
||||
#ifdef CYASSL_CALLBACKS
|
||||
@ -6091,6 +6237,11 @@ int SetCipherList(Suites* s, const char* list)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CYASSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
DtlsPoolSave(ssl, output, sendSz);
|
||||
}
|
||||
#endif
|
||||
HashOutput(ssl, output, sendSz, 0);
|
||||
|
||||
#ifdef CYASSL_CALLBACKS
|
||||
@ -6943,6 +7094,11 @@ int SetCipherList(Suites* s, const char* list)
|
||||
|
||||
AddHeaders(output, 0, server_hello_done, ssl);
|
||||
|
||||
#ifdef CYASSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
DtlsPoolSave(ssl, output, sendSz);
|
||||
}
|
||||
#endif
|
||||
HashOutput(ssl, output, sendSz, 0);
|
||||
#ifdef CYASSL_CALLBACKS
|
||||
if (ssl->hsInfoOn)
|
||||
|
2
src/io.c
2
src/io.c
@ -143,7 +143,7 @@ int EmbedReceive(CYASSL *ssl, char *buf, int sz, void *ctx)
|
||||
#ifdef CYASSL_DTLS
|
||||
if (ssl->options.dtls
|
||||
&& !ssl->options.usingNonblock && ssl->dtls_timeout != 0) {
|
||||
#if USE_WINDOWS_API
|
||||
#ifdef USE_WINDOWS_API
|
||||
DWORD timeout = ssl->dtls_timeout;
|
||||
#else
|
||||
struct timeval timeout = {ssl->dtls_timeout, 0};
|
||||
|
29
src/ssl.c
29
src/ssl.c
@ -2219,19 +2219,30 @@ int CyaSSL_dtls_get_current_timeout(CYASSL* ssl)
|
||||
#ifdef CYASSL_DTLS
|
||||
return ssl->dtls_timeout;
|
||||
#else
|
||||
return 0;
|
||||
return SSL_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void CyaSSL_dtls_got_timeout(CYASSL* ssl)
|
||||
int CyaSSL_dtls_got_timeout(CYASSL* ssl)
|
||||
{
|
||||
int result = SSL_NOT_IMPLEMENTED;
|
||||
(void)ssl;
|
||||
|
||||
#ifdef CYASSL_DTLS
|
||||
if (ssl->dtls_timeout < 64)
|
||||
if (ssl->dtls_timeout < 64) {
|
||||
ssl->dtls_timeout *= 2;
|
||||
if (DtlsPoolSend(ssl) < 0)
|
||||
result = SSL_FATAL_ERROR;
|
||||
else
|
||||
result = SSL_SUCCESS;
|
||||
}
|
||||
else {
|
||||
result = SSL_FATAL_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -2285,6 +2296,12 @@ void CyaSSL_dtls_got_timeout(CYASSL* ssl)
|
||||
ssl->options.dtls = 1;
|
||||
ssl->options.tls = 1;
|
||||
ssl->options.tls1_1 = 1;
|
||||
|
||||
if (DtlsPoolInit(ssl) != 0) {
|
||||
ssl->error = MEMORY_ERROR;
|
||||
CYASSL_ERROR(ssl->error);
|
||||
return SSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -2535,6 +2552,12 @@ void CyaSSL_dtls_got_timeout(CYASSL* ssl)
|
||||
ssl->options.dtls = 1;
|
||||
ssl->options.tls = 1;
|
||||
ssl->options.tls1_1 = 1;
|
||||
|
||||
if (DtlsPoolInit(ssl) != 0) {
|
||||
ssl->error = MEMORY_ERROR;
|
||||
CYASSL_ERROR(ssl->error);
|
||||
return SSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user