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 #define MTU_EXTRA 0
#endif #endif
/* give user option to use 16K static buffers, sniffer needs them too */ /* give user option to use 16K static buffers */
#if defined(LARGE_STATIC_BUFFERS) || defined(CYASSL_SNIFFER) #if defined(LARGE_STATIC_BUFFERS)
#define RECORD_SIZE MAX_RECORD_SIZE #define RECORD_SIZE MAX_RECORD_SIZE
#else #else
#ifdef CYASSL_DTLS #ifdef CYASSL_DTLS
@ -635,8 +635,7 @@ enum {
The length (in bytes) of the following TLSPlaintext.fragment. The length (in bytes) of the following TLSPlaintext.fragment.
The length should not exceed 2^14. The length should not exceed 2^14.
*/ */
#if defined(LARGE_STATIC_BUFFERS) || defined(CYASSL_SNIFFER) || \ #if defined(LARGE_STATIC_BUFFERS) || defined(CYASSL_DTLS)
defined(CYASSL_DTLS)
#define STATIC_BUFFER_LEN RECORD_HEADER_SZ + RECORD_SIZE + COMP_EXTRA + \ #define STATIC_BUFFER_LEN RECORD_HEADER_SZ + RECORD_SIZE + COMP_EXTRA + \
MTU_EXTRA + MAX_MSG_EXTRA MTU_EXTRA + MAX_MSG_EXTRA
#else #else
@ -1511,6 +1510,8 @@ CYASSL_LOCAL Signer* GetCA(void* cm, byte* hash);
CYASSL_LOCAL void BuildTlsFinished(CYASSL* ssl, Hashes* hashes, CYASSL_LOCAL void BuildTlsFinished(CYASSL* ssl, Hashes* hashes,
const byte* sender); const byte* sender);
CYASSL_LOCAL void FreeArrays(CYASSL* ssl, int keep); 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 #ifndef NO_TLS
CYASSL_LOCAL int MakeTlsMasterSecret(CYASSL*); 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 */ /* 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, byte* tmp = (byte*) XMALLOC(size + usedLength, ssl->heap,
DYNAMIC_TYPE_IN_BUFFER); 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 */ /* 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 if (ssl->buffers.outputBuffer.bufferSize - ssl->buffers.outputBuffer.length
< (word32)size) { < (word32)size) {
@ -1846,6 +1846,7 @@ static INLINE int CheckAvalaibleSize(CYASSL *ssl, int size)
return 0; return 0;
} }
/* do all verify and sanity checks on record header */ /* do all verify and sanity checks on record header */
static int GetRecordHeader(CYASSL* ssl, const byte* input, word32* inOutIdx, static int GetRecordHeader(CYASSL* ssl, const byte* input, word32* inOutIdx,
RecordLayerHeader* rh, word16 *size) RecordLayerHeader* rh, word16 *size)

View File

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