From f969bc364587a416dcb850ac44ab61fc5b7dbb4b Mon Sep 17 00:00:00 2001 From: toddouska Date: Wed, 24 Oct 2012 13:33:11 -0700 Subject: [PATCH] if sniffer sees ACK for missing packet(s) set to error, can't recover --- cyassl/sniffer_error.h | 1 + cyassl/sniffer_error.rc | 1 + src/sniffer.c | 43 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/cyassl/sniffer_error.h b/cyassl/sniffer_error.h index e6883f2dd..27e56f8ee 100644 --- a/cyassl/sniffer_error.h +++ b/cyassl/sniffer_error.h @@ -100,6 +100,7 @@ #define BAD_FINISHED_MSG 66 #define BAD_COMPRESSION_STR 67 #define BAD_DERIVE_STR 68 +#define ACK_MISSED_STR 69 /* !!!! also add to msgTable in sniffer.c and .rc file !!!! */ diff --git a/cyassl/sniffer_error.rc b/cyassl/sniffer_error.rc index 307efbf29..6171f7849 100644 --- a/cyassl/sniffer_error.rc +++ b/cyassl/sniffer_error.rc @@ -82,5 +82,6 @@ STRINGTABLE 66, "Bad Finished Message Processing" 67, "Bad Compression Type" 68, "Bad DeriveKeys Error" + 69, "Saw ACK for Missing Packet Error" } diff --git a/src/sniffer.c b/src/sniffer.c index b9775254e..bf6cd26cd 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -218,7 +218,8 @@ static const char* const msgTable[] = /* 66 */ "Bad Finished Message Processing", "Bad Compression Type", - "Bad DeriveKeys Error" + "Bad DeriveKeys Error", + "Saw ACK for Missing Packet Error" }; @@ -490,6 +491,7 @@ typedef struct TcpInfo { int dstPort; /* source port */ int length; /* length of this header */ word32 sequence; /* sequence number */ + word32 ackNumber; /* ack number */ byte fin; /* FIN set */ byte rst; /* RST set */ byte syn; /* SYN set */ @@ -654,6 +656,15 @@ static void TraceSequence(word32 seq, int len) } +/* Show sequence and payload length for Trace */ +static void TraceAck(word32 ack, word32 expected) +{ + if (TraceOn) { + fprintf(TraceFile, "\tAck:%u Expected:%u\n", ack, expected); + } +} + + /* Show relative expected and relative received sequences */ static void TraceRelativeSequence(word32 expected, word32 got) { @@ -979,6 +990,8 @@ static int CheckTcpHdr(TcpHdr* tcphdr, TcpInfo* info, char* error) info->rst = tcphdr->flags & TCP_RST; info->syn = tcphdr->flags & TCP_SYN; info->ack = tcphdr->flags & TCP_ACK; + if (info->ack) + info->ackNumber = ntohl(tcphdr->ack); if (!IsPortRegistered(info->srcPort) && !IsPortRegistered(info->dstPort)) { SetError(SERVER_PORT_NOT_REG_STR, error, NULL, 0); @@ -2070,6 +2083,30 @@ static int AdjustSequence(TcpInfo* tcpInfo, SnifferSession* session, } +/* Check latest ack number for missing packets + return 0 ok, <0 on error */ +static int CheckAck(TcpInfo* tcpInfo, SnifferSession* session) +{ + if (tcpInfo->ack) { + word32 seqStart = (session->flags.side == SERVER_END) ? + session->srvSeqStart :session->cliSeqStart; + word32 real = tcpInfo->ackNumber - seqStart; + word32 expected = (session->flags.side == SERVER_END) ? + session->srvExpected : session->cliExpected; + + /* handle rollover of sequence */ + if (tcpInfo->ackNumber < seqStart) + real = 0xffffffffU - seqStart + tcpInfo->ackNumber; + + TraceAck(real, expected); + + if (real > expected) + return -1; /* we missed a packet, ACKing data we never saw */ + } + return 0; +} + + /* Check TCP Sequence status */ /* returns 0 on success (continue), -1 on error, 1 on success (end) */ static int CheckSequence(IpInfo* ipInfo, TcpInfo* tcpInfo, @@ -2093,6 +2130,10 @@ static int CheckSequence(IpInfo* ipInfo, TcpInfo* tcpInfo, } TraceSequence(tcpInfo->sequence, *sslBytes); + if (CheckAck(tcpInfo, session) < 0) { + SetError(ACK_MISSED_STR, error, session, FATAL_ERROR_STATE); + return -1; + } return AdjustSequence(tcpInfo, session, sslBytes, sslFrame, error); }