if sniffer sees ACK for missing packet(s) set to error, can't recover

This commit is contained in:
toddouska
2012-10-24 13:33:11 -07:00
parent bb5280d0e4
commit f969bc3645
3 changed files with 44 additions and 1 deletions

View File

@@ -100,6 +100,7 @@
#define BAD_FINISHED_MSG 66 #define BAD_FINISHED_MSG 66
#define BAD_COMPRESSION_STR 67 #define BAD_COMPRESSION_STR 67
#define BAD_DERIVE_STR 68 #define BAD_DERIVE_STR 68
#define ACK_MISSED_STR 69
/* !!!! also add to msgTable in sniffer.c and .rc file !!!! */ /* !!!! also add to msgTable in sniffer.c and .rc file !!!! */

View File

@@ -82,5 +82,6 @@ STRINGTABLE
66, "Bad Finished Message Processing" 66, "Bad Finished Message Processing"
67, "Bad Compression Type" 67, "Bad Compression Type"
68, "Bad DeriveKeys Error" 68, "Bad DeriveKeys Error"
69, "Saw ACK for Missing Packet Error"
} }

View File

@@ -218,7 +218,8 @@ static const char* const msgTable[] =
/* 66 */ /* 66 */
"Bad Finished Message Processing", "Bad Finished Message Processing",
"Bad Compression Type", "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 dstPort; /* source port */
int length; /* length of this header */ int length; /* length of this header */
word32 sequence; /* sequence number */ word32 sequence; /* sequence number */
word32 ackNumber; /* ack number */
byte fin; /* FIN set */ byte fin; /* FIN set */
byte rst; /* RST set */ byte rst; /* RST set */
byte syn; /* SYN 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 */ /* Show relative expected and relative received sequences */
static void TraceRelativeSequence(word32 expected, word32 got) 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->rst = tcphdr->flags & TCP_RST;
info->syn = tcphdr->flags & TCP_SYN; info->syn = tcphdr->flags & TCP_SYN;
info->ack = tcphdr->flags & TCP_ACK; info->ack = tcphdr->flags & TCP_ACK;
if (info->ack)
info->ackNumber = ntohl(tcphdr->ack);
if (!IsPortRegistered(info->srcPort) && !IsPortRegistered(info->dstPort)) { if (!IsPortRegistered(info->srcPort) && !IsPortRegistered(info->dstPort)) {
SetError(SERVER_PORT_NOT_REG_STR, error, NULL, 0); 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 */ /* Check TCP Sequence status */
/* returns 0 on success (continue), -1 on error, 1 on success (end) */ /* returns 0 on success (continue), -1 on error, 1 on success (end) */
static int CheckSequence(IpInfo* ipInfo, TcpInfo* tcpInfo, static int CheckSequence(IpInfo* ipInfo, TcpInfo* tcpInfo,
@@ -2093,6 +2130,10 @@ static int CheckSequence(IpInfo* ipInfo, TcpInfo* tcpInfo,
} }
TraceSequence(tcpInfo->sequence, *sslBytes); 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); return AdjustSequence(tcpInfo, session, sslBytes, sslFrame, error);
} }