tcp reuse: support reuse on syn/ack

Support TCP reuse on SYN/ACK. Only effective if midstream and/or
async-oneside options are enabled.
pull/1342/head
Victor Julien 10 years ago
parent 11e3f25de3
commit eaae008aeb

@ -4680,21 +4680,24 @@ static inline int StreamTcpValidateChecksum(Packet *p)
* \retval bool true/false */
static int TcpSessionPacketIsStreamStarter(const Packet *p)
{
uint8_t flag = TH_SYN;
//SCLogInfo("Want: %02x, have %02x", flag, p->tcph->th_flags);
if (p->tcph->th_flags == flag) {
if (p->tcph->th_flags == TH_SYN) {
SCLogDebug("packet %"PRIu64" is a stream starter: %02x", p->pcap_cnt, p->tcph->th_flags);
return 1;
}
if (stream_config.midstream == TRUE || stream_config.async_oneside == TRUE) {
if (p->tcph->th_flags == (TH_SYN|TH_ACK)) {
SCLogDebug("packet %"PRIu64" is a midstream stream starter: %02x", p->pcap_cnt, p->tcph->th_flags);
return 1;
}
}
return 0;
}
/** \internal
* \brief Check if Flow and TCP SSN allow this flow/tuple to be reused
* \retval bool true yes reuse, false no keep tracking old ssn */
int TcpSessionReuseDoneEnough(const Packet *p, const Flow *f, const TcpSession *ssn)
static int TcpSessionReuseDoneEnoughSyn(const Packet *p, const Flow *f, const TcpSession *ssn)
{
if (FlowGetPacketDirection(f, p) == TOSERVER) {
if (ssn == NULL) {
@ -4741,6 +4744,77 @@ int TcpSessionReuseDoneEnough(const Packet *p, const Flow *f, const TcpSession *
return 0;
}
/** \internal
* \brief check if ssn is done enough for reuse by syn/ack
* \note should only be called if midstream is enabled
*/
static int TcpSessionReuseDoneEnoughSynAck(const Packet *p, const Flow *f, const TcpSession *ssn)
{
if (FlowGetPacketDirection(f, p) == TOCLIENT) {
if (ssn == NULL) {
SCLogDebug("steam starter packet %"PRIu64", ssn %p null. No reuse.", p->pcap_cnt, ssn);
return 0;
}
if (SEQ_EQ(ssn->server.isn, TCP_GET_SEQ(p))) {
SCLogDebug("steam starter packet %"PRIu64", ssn %p. Packet SEQ == Stream ISN. Retransmission. Don't reuse.", p->pcap_cnt, ssn);
return 0;
}
if (ssn->state >= TCP_LAST_ACK) {
SCLogDebug("steam starter packet %"PRIu64", ssn %p state >= TCP_LAST_ACK (%u). Reuse.", p->pcap_cnt, ssn, ssn->state);
return 1;
}
if (ssn->state == TCP_NONE) {
SCLogDebug("steam starter packet %"PRIu64", ssn %p state == TCP_NONE (%u). Reuse.", p->pcap_cnt, ssn, ssn->state);
return 1;
}
if (ssn->state < TCP_LAST_ACK) {
SCLogDebug("steam starter packet %"PRIu64", ssn %p state < TCP_LAST_ACK (%u). Don't reuse.", p->pcap_cnt, ssn, ssn->state);
return 0;
}
} else {
if (ssn == NULL) {
SCLogDebug("steam starter packet %"PRIu64", ssn %p null. Reuse.", p->pcap_cnt, ssn);
return 1;
}
if (ssn->state >= TCP_LAST_ACK) {
SCLogDebug("steam starter packet %"PRIu64", ssn %p state >= TCP_LAST_ACK (%u). Reuse.", p->pcap_cnt, ssn, ssn->state);
return 1;
}
if (ssn->state == TCP_NONE) {
SCLogDebug("steam starter packet %"PRIu64", ssn %p state == TCP_NONE (%u). Reuse.", p->pcap_cnt, ssn, ssn->state);
return 1;
}
if (ssn->state < TCP_LAST_ACK) {
SCLogDebug("steam starter packet %"PRIu64", ssn %p state < TCP_LAST_ACK (%u). Don't reuse.", p->pcap_cnt, ssn, ssn->state);
return 0;
}
}
SCLogDebug("default: how did we get here?");
return 0;
}
/** \brief Check if SSN is done enough for reuse
*
* Reuse means a new TCP session reuses the tuple (flow in suri)
*
* \retval bool true if ssn can be reused, false if not */
int TcpSessionReuseDoneEnough(const Packet *p, const Flow *f, const TcpSession *ssn)
{
if (p->tcph->th_flags == TH_SYN) {
return TcpSessionReuseDoneEnoughSyn(p, f, ssn);
}
if (stream_config.midstream == TRUE || stream_config.async_oneside == TRUE) {
if (p->tcph->th_flags == (TH_SYN|TH_ACK)) {
return TcpSessionReuseDoneEnoughSynAck(p, f, ssn);
}
}
return 0;
}
int TcpSessionPacketSsnReuse(const Packet *p, const Flow *f, const void *tcp_ssn)
{
if (p->proto == IPPROTO_TCP && p->tcph != NULL) {

Loading…
Cancel
Save