return 0;
}
-int TcpSessionPacketSsnReuse(const Packet *p, void *tcp_ssn);
+int TcpSessionPacketSsnReuse(const Packet *p, const Flow *f, void *tcp_ssn);
static inline int FlowCompare(Flow *f, const Packet *p)
{
if (f->flags & FLOW_TCP_REUSED)
return 0;
- /* lets see if we need to consider the existing session for
- * reuse: only considering SYN packets. */
- int syn = (p->tcph && ((p->tcph->th_flags & TH_SYN) == TH_SYN));
- int has_protoctx = ((f->protoctx != NULL));
-
- /* syn on existing state, need to see if we need to 'reuse' */
- if (unlikely(syn && has_protoctx && FlowGetPacketDirection(f,p) == TOSERVER)) {
- if (unlikely(TcpSessionPacketSsnReuse(p, f->protoctx) == 1)) {
- /* okay, we need to setup a new flow for this packet.
- * Flag the flow that it's been replaced by a new one */
- f->flags |= FLOW_TCP_REUSED;
- SCLogDebug("flow obsolete: TCP reuse will use a new flow");
- return 0;
- }
+ /* lets see if we need to consider the existing session reuse */
+ if (unlikely(TcpSessionPacketSsnReuse(p, f, f->protoctx) == 1)) {
+ /* okay, we need to setup a new flow for this packet.
+ * Flag the flow that it's been replaced by a new one */
+ f->flags |= FLOW_TCP_REUSED;
+ SCLogDebug("flow obsolete: TCP reuse will use a new flow");
+ return 0;
}
return 1;
} else {
* \retval 0 to_server
* \retval 1 to_client
*/
-int FlowGetPacketDirection(Flow *f, const Packet *p)
+int FlowGetPacketDirection(const Flow *f, const Packet *p)
{
if (p->proto == IPPROTO_TCP || p->proto == IPPROTO_UDP || p->proto == IPPROTO_SCTP) {
if (!(CMP_PORT(p->sp,p->dp))) {
static inline void FlowSetNoPayloadInspectionFlag(Flow *);
static inline void FlowSetSessionNoApplayerInspectionFlag(Flow *);
-int FlowGetPacketDirection(Flow *, const Packet *);
+int FlowGetPacketDirection(const Flow *, const Packet *);
void FlowCleanupAppLayer(Flow *);
return 0;
}
-int TcpSessionPacketSsnReuse(const Packet *p, void *tcp_ssn)
-{
- TcpSession *ssn = tcp_ssn;
- if (ssn->state == TCP_CLOSED) {
- if(!(SEQ_EQ(ssn->client.isn, TCP_GET_SEQ(p))))
- {
- return 1;
- }
- }
- return 0;
-}
-
/* flow is and stays locked */
int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt,
PacketQueue *pq)
/** \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(Packet *p, const TcpSession *ssn)
+int TcpSessionReuseDoneEnough(const Packet *p, const Flow *f, const TcpSession *ssn)
{
- if (FlowGetPacketDirection(p->flow, p) == TOSERVER) {
+ if (FlowGetPacketDirection(f, p) == TOSERVER) {
if (ssn == NULL) {
SCLogDebug("steam starter packet %"PRIu64", ssn %p null. No reuse.", p->pcap_cnt, ssn);
return 0;
}
}
-
SCLogDebug("default: how did we get here?");
return 0;
}
+int TcpSessionPacketSsnReuse(const Packet *p, const Flow *f, const void *tcp_ssn)
+{
+ if (p->proto == IPPROTO_TCP && p->tcph != NULL) {
+ if (TcpSessionPacketIsStreamStarter(p) == 1) {
+ if (TcpSessionReuseDoneEnough(p, f, tcp_ssn) == 1) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
/** \brief Handle TCP reuse of tuple
*
* Logic:
int reuse = 0;
FLOWLOCK_RDLOCK(p->flow);
- reuse = TcpSessionReuseDoneEnough(p, p->flow->protoctx);
+ reuse = TcpSessionReuseDoneEnough(p, p->flow, p->flow->protoctx);
if (!reuse) {
SCLogDebug("steam starter packet %"PRIu64", but state not "
"ready to be reused", p->pcap_cnt);