switch sniffer buffers to dynamic, reduce holding memory if large number of sessions cached

This commit is contained in:
toddouska 2012-10-24 17:37:57 -07:00
parent 3e7619c785
commit 0bbbea20be
3 changed files with 47 additions and 19 deletions

View File

@ -605,8 +605,8 @@ enum {
#define MTU_EXTRA 0
#endif
/* give user option to use 16K static buffers, sniffer needs them too */
#if defined(LARGE_STATIC_BUFFERS) || defined(CYASSL_SNIFFER)
/* give user option to use 16K static buffers */
#if defined(LARGE_STATIC_BUFFERS)
#define RECORD_SIZE MAX_RECORD_SIZE
#else
#ifdef CYASSL_DTLS
@ -635,8 +635,7 @@ enum {
The length (in bytes) of the following TLSPlaintext.fragment.
The length should not exceed 2^14.
*/
#if defined(LARGE_STATIC_BUFFERS) || defined(CYASSL_SNIFFER) || \
defined(CYASSL_DTLS)
#if defined(LARGE_STATIC_BUFFERS) || defined(CYASSL_DTLS)
#define STATIC_BUFFER_LEN RECORD_HEADER_SZ + RECORD_SIZE + COMP_EXTRA + \
MTU_EXTRA + MAX_MSG_EXTRA
#else
@ -1511,6 +1510,8 @@ CYASSL_LOCAL Signer* GetCA(void* cm, byte* hash);
CYASSL_LOCAL void BuildTlsFinished(CYASSL* ssl, Hashes* hashes,
const byte* sender);
CYASSL_LOCAL void FreeArrays(CYASSL* ssl, int keep);
CYASSL_LOCAL int CheckAvalaibleSize(CYASSL *ssl, int size);
CYASSL_LOCAL int GrowInputBuffer(CYASSL* ssl, int size, int usedLength);
#ifndef NO_TLS
CYASSL_LOCAL int MakeTlsMasterSecret(CYASSL*);

View File

@ -1809,7 +1809,7 @@ static INLINE int GrowOutputBuffer(CYASSL* ssl, int size)
/* Grow the input buffer, should only be to read cert or big app data */
static INLINE int GrowInputBuffer(CYASSL* ssl, int size, int usedLength)
int GrowInputBuffer(CYASSL* ssl, int size, int usedLength)
{
byte* tmp = (byte*) XMALLOC(size + usedLength, ssl->heap,
DYNAMIC_TYPE_IN_BUFFER);
@ -1835,7 +1835,7 @@ static INLINE int GrowInputBuffer(CYASSL* ssl, int size, int usedLength)
/* check avalaible size into output buffer, make room if needed */
static INLINE int CheckAvalaibleSize(CYASSL *ssl, int size)
int CheckAvalaibleSize(CYASSL *ssl, int size)
{
if (ssl->buffers.outputBuffer.bufferSize - ssl->buffers.outputBuffer.length
< (word32)size) {
@ -1846,6 +1846,7 @@ static INLINE int CheckAvalaibleSize(CYASSL *ssl, int size)
return 0;
}
/* do all verify and sanity checks on record header */
static int GetRecordHeader(CYASSL* ssl, const byte* input, word32* inOutIdx,
RecordLayerHeader* rh, word16 *size)

View File

@ -74,6 +74,8 @@ enum {
SNIFFER_TIMEOUT = 900, /* Cache unclosed Sessions for 15 minutes */
TICKET_HINT_LEN = 4, /* Session Ticket Hint length */
EXT_TYPE_SZ = 2, /* Extension length */
MAX_INPUT_SZ = MAX_RECORD_SIZE + COMP_EXTRA + MAX_MSG_EXTRA +
MTU_EXTRA, /* Max input sz of reassembly */
TICKET_EXT_ID = 0x23 /* Session Ticket Extension ID */
};
@ -1008,7 +1010,7 @@ static int GetRecordHeader(const byte* input, RecordLayerHeader* rh, int* size)
XMEMCPY(rh, input, RECORD_HEADER_SZ);
*size = (rh->length[0] << 8) | rh->length[1];
if (*size > (RECORD_SIZE + MAX_COMP_EXTRA + MAX_MSG_EXTRA))
if (*size > (MAX_RECORD_SIZE + COMP_EXTRA + MAX_MSG_EXTRA))
return LENGTH_ERROR;
return 0;
@ -2179,9 +2181,11 @@ static int CheckPreRecord(IpInfo* ipInfo, TcpInfo* tcpInfo,
Trace(PARTIAL_ADD_STR);
if ( (*sslBytes + length) > ssl->buffers.inputBuffer.bufferSize) {
SetError(BUFFER_ERROR_STR, error, *session, FATAL_ERROR_STATE);
if (GrowInputBuffer(ssl, *sslBytes, length) < 0) {
SetError(MEMORY_STR, error, *session, FATAL_ERROR_STATE);
return -1;
}
}
XMEMCPY(&ssl->buffers.inputBuffer.buffer[length], *sslFrame, *sslBytes);
*sslBytes += length;
ssl->buffers.inputBuffer.length = *sslBytes;
@ -2205,7 +2209,7 @@ static int CheckPreRecord(IpInfo* ipInfo, TcpInfo* tcpInfo,
/* See if input on the reassembly list is ready for consuming */
/* returns 1 for TRUE, 0 for FALSE */
static int HaveMoreInput(SnifferSession* session, const byte** sslFrame,
int* sslBytes, const byte** end)
int* sslBytes, const byte** end, char* error)
{
/* sequence and reassembly based on from, not to */
int moreInput = 0;
@ -2220,11 +2224,23 @@ static int HaveMoreInput(SnifferSession* session, const byte** sslFrame,
byte* myBuffer = (session->flags.side == SERVER_END) ?
session->sslServer->buffers.inputBuffer.buffer :
session->sslClient->buffers.inputBuffer.buffer;
word32 bufferSize = (session->flags.side == SERVER_END) ?
session->sslServer->buffers.inputBuffer.bufferSize :
session->sslClient->buffers.inputBuffer.bufferSize;
SSL* ssl = (session->flags.side == SERVER_END) ?
session->sslServer : session->sslClient;
while (*front && ((*front)->begin == *expected) ) {
word32 room = STATIC_BUFFER_LEN - *length;
word32 room = bufferSize - *length;
word32 packetLen = (*front)->end - (*front)->begin + 1;
if (packetLen > room && bufferSize < MAX_INPUT_SZ) {
if (GrowInputBuffer(ssl, packetLen, *length) < 0) {
SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
return 0;
}
}
if (packetLen <= room) {
PacketBuffer* del = *front;
@ -2283,13 +2299,15 @@ doMessage:
/* store partial if not there already or we advanced */
if (ssl->buffers.inputBuffer.length == 0 || sslBegin != sslFrame) {
if (sslBytes > (int)ssl->buffers.inputBuffer.bufferSize) {
SetError(BUFFER_ERROR_STR, error, session, FATAL_ERROR_STATE);
if (GrowInputBuffer(ssl, sslBytes, 0) < 0) {
SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
return -1;
}
}
XMEMCPY(ssl->buffers.inputBuffer.buffer, sslFrame, sslBytes);
ssl->buffers.inputBuffer.length = sslBytes;
}
if (HaveMoreInput(session, &sslFrame, &sslBytes, &end))
if (HaveMoreInput(session, &sslFrame, &sslBytes, &end, error))
goto doMessage;
return decoded;
}
@ -2298,12 +2316,15 @@ doMessage:
tmp = sslFrame + rhSize; /* may have more than one record to process */
/* decrypt if needed */
if (session->flags.side == SERVER_END && session->flags.serverCipherOn)
sslFrame = DecryptMessage(ssl, sslFrame, rhSize,
ssl->buffers.outputBuffer.buffer);
else if (session->flags.side == CLIENT_END && session->flags.clientCipherOn)
if ((session->flags.side == SERVER_END && session->flags.serverCipherOn)
|| (session->flags.side == CLIENT_END && session->flags.clientCipherOn)) {
if (CheckAvalaibleSize(ssl, rhSize) < 0) {
SetError(MEMORY_STR, error, session, FATAL_ERROR_STATE);
return -1;
}
sslFrame = DecryptMessage(ssl, sslFrame, rhSize,
ssl->buffers.outputBuffer.buffer);
}
switch ((enum ContentType)rh.type) {
case handshake:
@ -2344,6 +2365,8 @@ doMessage:
SetError(BAD_APP_DATA_STR, error,session,FATAL_ERROR_STATE);
return -1;
}
if (ssl->buffers.outputBuffer.dynamicFlag)
ShrinkOutputBuffer(ssl);
}
break;
case alert:
@ -2366,9 +2389,12 @@ doMessage:
ssl->buffers.inputBuffer.length = 0;
/* could have more input ready now */
if (HaveMoreInput(session, &sslFrame, &sslBytes, &end))
if (HaveMoreInput(session, &sslFrame, &sslBytes, &end, error))
goto doMessage;
if (ssl->buffers.inputBuffer.dynamicFlag)
ShrinkInputBuffer(ssl, NO_FORCED_FREE);
return decoded;
}