Changing the HTTP's analyzers internals to use 64-bit integers.

(Gregor Maier).

This is the patch from #326, plus some cleanup.
This commit is contained in:
Robin Sommer 2011-04-27 21:25:51 -07:00
parent 80376653c2
commit 714289bd13
13 changed files with 56 additions and 62 deletions

View file

@ -140,7 +140,7 @@ bool ChunkedIOFd::Write(Chunk* chunk)
{ {
#ifdef DEBUG #ifdef DEBUG
DBG_LOG(DBG_CHUNKEDIO, "write of size %d [%s]", DBG_LOG(DBG_CHUNKEDIO, "write of size %d [%s]",
chunk->len, fmt_bytes(chunk->data, min(20, chunk->len))); chunk->len, fmt_bytes(chunk->data, min((uint32)20, chunk->len)));
#endif #endif
// Reject if our queue of pending chunks is way too large. Otherwise, // Reject if our queue of pending chunks is way too large. Otherwise,
@ -427,7 +427,7 @@ bool ChunkedIOFd::Read(Chunk** chunk, bool may_block)
(*chunk)->len & ~FLAG_PARTIAL, (*chunk)->len & ~FLAG_PARTIAL,
(*chunk)->len & FLAG_PARTIAL ? "(P) " : "", (*chunk)->len & FLAG_PARTIAL ? "(P) " : "",
fmt_bytes((*chunk)->data, fmt_bytes((*chunk)->data,
min(20, (*chunk)->len))); min((uint32)20, (*chunk)->len)));
#endif #endif
if ( ! ((*chunk)->len & FLAG_PARTIAL) ) if ( ! ((*chunk)->len & FLAG_PARTIAL) )

View file

@ -120,7 +120,7 @@ void ContentLine_Analyzer::EndpointEOF(bool is_orig)
DeliverStream(1, (const u_char*) "\n", is_orig); DeliverStream(1, (const u_char*) "\n", is_orig);
} }
void ContentLine_Analyzer::SetPlainDelivery(int length) void ContentLine_Analyzer::SetPlainDelivery(int64_t length)
{ {
if ( length < 0 ) if ( length < 0 )
internal_error("negative length for plain delivery"); internal_error("negative length for plain delivery");
@ -154,7 +154,7 @@ void ContentLine_Analyzer::DoDeliver(int len, const u_char* data)
if ( plain_delivery_length > 0 ) if ( plain_delivery_length > 0 )
{ {
int deliver_plain = min(plain_delivery_length, len); int deliver_plain = min(plain_delivery_length, (int64_t)len);
last_char = 0; // clear last_char last_char = 0; // clear last_char
plain_delivery_length -= deliver_plain; plain_delivery_length -= deliver_plain;
@ -179,7 +179,7 @@ void ContentLine_Analyzer::DoDeliver(int len, const u_char* data)
if ( seq < seq_to_skip ) if ( seq < seq_to_skip )
{ {
// Skip rest of the data and return // Skip rest of the data and return
int skip_len = seq_to_skip - seq; int64_t skip_len = seq_to_skip - seq;
if ( skip_len > len ) if ( skip_len > len )
skip_len = len; skip_len = len;
@ -310,7 +310,7 @@ void ContentLine_Analyzer::CheckNUL()
} }
} }
void ContentLine_Analyzer::SkipBytesAfterThisLine(int length) void ContentLine_Analyzer::SkipBytesAfterThisLine(int64_t length)
{ {
// This is a little complicated because Bro has to handle // This is a little complicated because Bro has to handle
// both CR and CRLF as a line break. When a line is delivered, // both CR and CRLF as a line break. When a line is delivered,
@ -326,7 +326,7 @@ void ContentLine_Analyzer::SkipBytesAfterThisLine(int length)
SkipBytes(length); SkipBytes(length);
} }
void ContentLine_Analyzer::SkipBytes(int length) void ContentLine_Analyzer::SkipBytes(int64_t length)
{ {
skip_pending = 0; skip_pending = 0;
seq_to_skip = SeqDelivered() + length; seq_to_skip = SeqDelivered() + length;

View file

@ -44,16 +44,16 @@ public:
// mode for next <length> bytes. Plain-delivery data is also passed // mode for next <length> bytes. Plain-delivery data is also passed
// via DeliverStream() and can differentiated by calling // via DeliverStream() and can differentiated by calling
// IsPlainDelivery(). // IsPlainDelivery().
void SetPlainDelivery(int length); void SetPlainDelivery(int64_t length);
int GetPlainDeliveryLength() const { return plain_delivery_length; } int64_t GetPlainDeliveryLength() const { return plain_delivery_length; }
bool IsPlainDelivery() { return is_plain; } bool IsPlainDelivery() { return is_plain; }
// Skip <length> bytes after this line. // Skip <length> bytes after this line.
// Can be used to skip HTTP data for performance considerations. // Can be used to skip HTTP data for performance considerations.
void SkipBytesAfterThisLine(int length); void SkipBytesAfterThisLine(int64_t length);
void SkipBytes(int length); void SkipBytes(int64_t length);
bool IsSkippedContents(int seq, int length) bool IsSkippedContents(int64_t seq, int64_t length)
{ return seq + length <= seq_to_skip; } { return seq + length <= seq_to_skip; }
protected: protected:
@ -71,26 +71,26 @@ protected:
void CheckNUL(); void CheckNUL();
// Returns the sequence number delivered so far. // Returns the sequence number delivered so far.
int SeqDelivered() const { return seq_delivered_in_lines; } int64_t SeqDelivered() const { return seq_delivered_in_lines; }
u_char* buf; // where we build up the body of the request u_char* buf; // where we build up the body of the request
int offset; // where we are in buf int offset; // where we are in buf
int buf_len; // how big buf is, total int buf_len; // how big buf is, total
unsigned int last_char; // last (non-option) character scanned unsigned int last_char; // last (non-option) character scanned
int seq; // last seq number int64_t seq; // last seq number
int seq_to_skip; int64_t seq_to_skip;
// Seq delivered up to through NewLine() -- it is adjusted // Seq delivered up to through NewLine() -- it is adjusted
// *before* NewLine() is called. // *before* NewLine() is called.
int seq_delivered_in_lines; int64_t seq_delivered_in_lines;
// Number of bytes to be skipped after this line. See // Number of bytes to be skipped after this line. See
// comments in SkipBytesAfterThisLine(). // comments in SkipBytesAfterThisLine().
int skip_pending; int64_t skip_pending;
// Remaining bytes to deliver plain. // Remaining bytes to deliver plain.
int plain_delivery_length; int64_t plain_delivery_length;
int is_plain; int is_plain;
// Don't deliver further data. // Don't deliver further data.

View file

@ -735,7 +735,7 @@ int BroFile::Write(const char* data, int len)
while ( len ) while ( len )
{ {
int outl; int outl;
int inl = min(MIN_BUFFER_SIZE, len); int inl = min(+MIN_BUFFER_SIZE, len);
if ( ! EVP_SealUpdate(cipher_ctx, cipher_buffer, &outl, if ( ! EVP_SealUpdate(cipher_ctx, cipher_buffer, &outl,
(unsigned char*)data, inl) ) (unsigned char*)data, inl) )

View file

@ -238,7 +238,7 @@ void Gnutella_Analyzer::SendEvents(GnutellaMsgState* p, bool is_orig)
vl->append(new StringVal(p->payload)); vl->append(new StringVal(p->payload));
vl->append(new Val(p->payload_len, TYPE_COUNT)); vl->append(new Val(p->payload_len, TYPE_COUNT));
vl->append(new Val((p->payload_len < vl->append(new Val((p->payload_len <
min(p->msg_len, GNUTELLA_MAX_PAYLOAD)), min(p->msg_len, (unsigned int)GNUTELLA_MAX_PAYLOAD)),
TYPE_BOOL)); TYPE_BOOL));
vl->append(new Val((p->payload_left == 0), TYPE_BOOL)); vl->append(new Val((p->payload_left == 0), TYPE_BOOL));

View file

@ -29,7 +29,7 @@ public:
u_char msg_type; u_char msg_type;
u_char msg_ttl; u_char msg_ttl;
char payload[GNUTELLA_MAX_PAYLOAD]; char payload[GNUTELLA_MAX_PAYLOAD];
int payload_len; unsigned int payload_len;
unsigned int payload_left; unsigned int payload_left;
}; };

View file

@ -226,7 +226,7 @@ void HTTP_Entity::DeliverBodyClear(int len, const char* data, int trailing_CRLF)
// Returns 1 if the undelivered bytes are completely within the body, // Returns 1 if the undelivered bytes are completely within the body,
// otherwise returns 0. // otherwise returns 0.
int HTTP_Entity::Undelivered(int len) int HTTP_Entity::Undelivered(int64_t len)
{ {
if ( DEBUG_http ) if ( DEBUG_http )
{ {
@ -283,7 +283,7 @@ void HTTP_Entity::SubmitData(int len, const char* buf)
MIME_Entity::SubmitData(len, buf); MIME_Entity::SubmitData(len, buf);
} }
void HTTP_Entity::SetPlainDelivery(int length) void HTTP_Entity::SetPlainDelivery(int64_t length)
{ {
ASSERT(length >= 0); ASSERT(length >= 0);
ASSERT(length == 0 || ! in_header); ASSERT(length == 0 || ! in_header);
@ -302,7 +302,7 @@ void HTTP_Entity::SubmitHeader(MIME_Header* h)
data_chunk_t vt = h->get_value_token(); data_chunk_t vt = h->get_value_token();
if ( ! is_null_data_chunk(vt) ) if ( ! is_null_data_chunk(vt) )
{ {
int n; int64_t n;
if ( atoi_n(vt.length, vt.data, 0, 10, n) ) if ( atoi_n(vt.length, vt.data, 0, 10, n) )
content_length = n; content_length = n;
else else
@ -409,7 +409,7 @@ void HTTP_Entity::SubmitAllHeaders()
HTTP_Message::HTTP_Message(HTTP_Analyzer* arg_analyzer, HTTP_Message::HTTP_Message(HTTP_Analyzer* arg_analyzer,
ContentLine_Analyzer* arg_cl, bool arg_is_orig, ContentLine_Analyzer* arg_cl, bool arg_is_orig,
int expect_body, int init_header_length) int expect_body, int64_t init_header_length)
: MIME_Message (arg_analyzer) : MIME_Message (arg_analyzer)
{ {
analyzer = arg_analyzer; analyzer = arg_analyzer;
@ -477,7 +477,7 @@ void HTTP_Message::Done(const int interrupted, const char* detail)
} }
} }
int HTTP_Message::Undelivered(int len) int HTTP_Message::Undelivered(int64_t len)
{ {
if ( ! top_level ) if ( ! top_level )
return 0; return 0;
@ -628,7 +628,7 @@ void HTTP_Message::SubmitEvent(int event_type, const char* detail)
MyHTTP_Analyzer()->HTTP_Event(category, detail); MyHTTP_Analyzer()->HTTP_Event(category, detail);
} }
void HTTP_Message::SetPlainDelivery(int length) void HTTP_Message::SetPlainDelivery(int64_t length)
{ {
content_line->SetPlainDelivery(length); content_line->SetPlainDelivery(length);
@ -701,7 +701,7 @@ void HTTP_Message::DeliverEntityData()
total_buffer_size = 0; total_buffer_size = 0;
} }
int HTTP_Message::InitBuffer(int length) int HTTP_Message::InitBuffer(int64_t length)
{ {
if ( length <= 0 ) if ( length <= 0 )
return 0; return 0;
@ -1633,7 +1633,7 @@ void HTTP_Analyzer::HTTP_MessageDone(int is_orig, HTTP_Message* /* message */)
} }
void HTTP_Analyzer::InitHTTPMessage(ContentLine_Analyzer* cl, HTTP_Message*& message, void HTTP_Analyzer::InitHTTPMessage(ContentLine_Analyzer* cl, HTTP_Message*& message,
bool is_orig, int expect_body, int init_header_length) bool is_orig, int expect_body, int64_t init_header_length)
{ {
if ( message ) if ( message )
{ {

View file

@ -39,9 +39,9 @@ public:
void EndOfData(); void EndOfData();
void Deliver(int len, const char* data, int trailing_CRLF); void Deliver(int len, const char* data, int trailing_CRLF);
int Undelivered(int len); int Undelivered(int64_t len);
int BodyLength() const { return body_length; } int64_t BodyLength() const { return body_length; }
int HeaderLength() const { return header_length; } int64_t HeaderLength() const { return header_length; }
void SkipBody() { deliver_body = 0; } void SkipBody() { deliver_body = 0; }
protected: protected:
@ -50,11 +50,11 @@ protected:
HTTP_Message* http_message; HTTP_Message* http_message;
int chunked_transfer_state; int chunked_transfer_state;
int content_length; int64_t content_length;
int expect_data_length; int64_t expect_data_length;
int expect_body; int expect_body;
int body_length; int64_t body_length;
int header_length; int64_t header_length;
int deliver_body; int deliver_body;
enum { IDENTITY, GZIP, COMPRESS, DEFLATE } encoding; enum { IDENTITY, GZIP, COMPRESS, DEFLATE } encoding;
#ifdef HAVE_LIBZ #ifdef HAVE_LIBZ
@ -68,7 +68,7 @@ protected:
void SubmitData(int len, const char* buf); void SubmitData(int len, const char* buf);
void SetPlainDelivery(int length); void SetPlainDelivery(int64_t length);
void SubmitHeader(MIME_Header* h); void SubmitHeader(MIME_Header* h);
void SubmitAllHeaders(); void SubmitAllHeaders();
@ -94,12 +94,12 @@ enum {
class HTTP_Message : public MIME_Message { class HTTP_Message : public MIME_Message {
public: public:
HTTP_Message(HTTP_Analyzer* analyzer, ContentLine_Analyzer* cl, HTTP_Message(HTTP_Analyzer* analyzer, ContentLine_Analyzer* cl,
bool is_orig, int expect_body, int init_header_length); bool is_orig, int expect_body, int64_t init_header_length);
~HTTP_Message(); ~HTTP_Message();
void Done(const int interrupted, const char* msg); void Done(const int interrupted, const char* msg);
void Done() { Done(0, "message ends normally"); } void Done() { Done(0, "message ends normally"); }
int Undelivered(int len); int Undelivered(int64_t len);
void BeginEntity(MIME_Entity* /* entity */); void BeginEntity(MIME_Entity* /* entity */);
void EndEntity(MIME_Entity* entity); void EndEntity(MIME_Entity* entity);
@ -111,7 +111,7 @@ public:
void SubmitEvent(int event_type, const char* detail); void SubmitEvent(int event_type, const char* detail);
void SubmitTrailingHeaders(MIME_HeaderList& /* hlist */); void SubmitTrailingHeaders(MIME_HeaderList& /* hlist */);
void SetPlainDelivery(int length); void SetPlainDelivery(int64_t length);
void SkipEntityData(); void SkipEntityData();
HTTP_Analyzer* MyHTTP_Analyzer() const HTTP_Analyzer* MyHTTP_Analyzer() const
@ -135,16 +135,16 @@ protected:
double start_time; double start_time;
int body_length; // total length of entity bodies int64_t body_length; // total length of entity bodies
int header_length; // total length of headers, including the request/reply line int64_t header_length; // total length of headers, including the request/reply line
// Total length of content gaps that are "successfully" skipped. // Total length of content gaps that are "successfully" skipped.
// Note: this might NOT include all content gaps! // Note: this might NOT include all content gaps!
int content_gap_length; int64_t content_gap_length;
HTTP_Entity* current_entity; HTTP_Entity* current_entity;
int InitBuffer(int length); int InitBuffer(int64_t length);
void DeliverEntityData(); void DeliverEntityData();
Val* BuildMessageStat(const int interrupted, const char* msg); Val* BuildMessageStat(const int interrupted, const char* msg);
@ -191,7 +191,7 @@ protected:
int HTTP_ReplyLine(const char* line, const char* end_of_line); int HTTP_ReplyLine(const char* line, const char* end_of_line);
void InitHTTPMessage(ContentLine_Analyzer* cl, HTTP_Message*& message, bool is_orig, void InitHTTPMessage(ContentLine_Analyzer* cl, HTTP_Message*& message, bool is_orig,
int expect_body, int init_header_length); int expect_body, int64_t init_header_length);
const char* PrefixMatch(const char* line, const char* end_of_line, const char* PrefixMatch(const char* line, const char* end_of_line,
const char* prefix); const char* prefix);

View file

@ -2394,7 +2394,7 @@ bool RemoteSerializer::SendPrintHookEvent(BroFile* f, const char* txt)
if ( ! fname ) if ( ! fname )
continue; // not a managed file. continue; // not a managed file.
int len = strlen(txt); long unsigned int len = strlen(txt);
// We cut off everything after the max buffer size. That // We cut off everything after the max buffer size. That
// makes the code a bit easier, and we shouldn't have such // makes the code a bit easier, and we shouldn't have such

View file

@ -397,7 +397,7 @@ bool XMLSerializationFormat::Write(char v, const char* tag)
bool XMLSerializationFormat::Write(uint16 v, const char* tag) bool XMLSerializationFormat::Write(uint16 v, const char* tag)
{ {
const char* tmp = fmt("%"PRIu16, v); const char* tmp = fmt("%" PRIu16, v);
return WriteElem(tag, "uint16", tmp, strlen(tmp)); return WriteElem(tag, "uint16", tmp, strlen(tmp));
} }

View file

@ -630,7 +630,7 @@ function strip%(str: string%): string
function string_fill%(len: int, source: string%): string function string_fill%(len: int, source: string%): string
%{ %{
const u_char* src = source->Bytes(); const u_char* src = source->Bytes();
int n = source->Len(); int64_t n = source->Len();
char* dst = new char[len]; char* dst = new char[len];
for ( int i = 0; i < len; i += n ) for ( int i = 0; i < len; i += n )

View file

@ -295,9 +295,9 @@ char* strcasestr(const char* s, const char* find)
} }
#endif #endif
int atoi_n(int len, const char* s, const char** end, int base, int& result) template<class T> int atoi_n(int len, const char* s, const char** end, int base, T& result)
{ {
int n = 0; T n = 0;
int neg = 0; int neg = 0;
if ( len > 0 && *s == '-' ) if ( len > 0 && *s == '-' )
@ -340,6 +340,10 @@ int atoi_n(int len, const char* s, const char** end, int base, int& result)
return 1; return 1;
} }
// Instantiate the ones we need.
template int atoi_n<int>(int len, const char* s, const char** end, int base, int& result);
template int atoi_n<int64_t>(int len, const char* s, const char** end, int base, int64_t& result);
char* uitoa_n(uint64 value, char* str, int n, int base) char* uitoa_n(uint64 value, char* str, int n, int base)
{ {
static char dig[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; static char dig[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
@ -361,6 +365,7 @@ char* uitoa_n(uint64 value, char* str, int n, int base)
return str; return str;
} }
int strstr_n(const int big_len, const u_char* big, int strstr_n(const int big_len, const u_char* big,
const int little_len, const u_char* little) const int little_len, const u_char* little)
{ {

View file

@ -110,8 +110,7 @@ extern int strcasecmp_n(int s_len, const char* s, const char* t);
extern char* strcasestr(const char* s, const char* find); extern char* strcasestr(const char* s, const char* find);
#endif #endif
extern const char* strpbrk_n(size_t len, const char* s, const char* charset); extern const char* strpbrk_n(size_t len, const char* s, const char* charset);
extern int atoi_n(int len, const char* s, const char** end, template<class T> int atoi_n(int len, const char* s, const char** end, int base, T& result);
int base, int& result);
extern char* uitoa_n(uint64 value, char* str, int n, int base); extern char* uitoa_n(uint64 value, char* str, int n, int base);
int strstr_n(const int big_len, const unsigned char* big, int strstr_n(const int big_len, const unsigned char* big,
const int little_len, const unsigned char* little); const int little_len, const unsigned char* little);
@ -234,16 +233,6 @@ extern struct timeval double_to_timeval(double t);
// Return > 0 if tv_a > tv_b, 0 if equal, < 0 if tv_a < tv_b. // Return > 0 if tv_a > tv_b, 0 if equal, < 0 if tv_a < tv_b.
extern int time_compare(struct timeval* tv_a, struct timeval* tv_b); extern int time_compare(struct timeval* tv_a, struct timeval* tv_b);
inline int min(int a, int b)
{
return a < b ? a : b;
}
inline int max(int a, int b)
{
return a > b ? a : b;
}
// For now, don't use hash_maps - they're not fully portable. // For now, don't use hash_maps - they're not fully portable.
#if 0 #if 0
// Use for hash_map's string keys. // Use for hash_map's string keys.