]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1806 in SNORT/snort3 from ~STECHEW/snort3:handle_invalid_acks_v2...
authorRuss Combs (rucombs) <rucombs@cisco.com>
Tue, 22 Oct 2019 13:54:56 +0000 (09:54 -0400)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Tue, 22 Oct 2019 13:54:56 +0000 (09:54 -0400)
Squashed commit of the following:

commit a8ff46342ba2547b7bef27e529013a047aff6f22
Author: Steve Chew <stechew@cisco.com>
Date:   Thu Oct 17 14:47:10 2019 -0400

    stream_tcp: If no-ack is on, rewrite ACK value to be the expected ACK.

src/stream/libtcp/tcp_segment_descriptor.h
src/stream/libtcp/tcp_stream_tracker.cc
src/stream/tcp/tcp_session.cc

index 7e2fe2035a605849eb62ceb99c2af2e5160b9f76..33cd334a59fdc3355c2d642ecc84671f2541f0ce 100644 (file)
@@ -72,6 +72,11 @@ public:
         return seg_ack;
     }
 
+    void set_seg_ack(uint32_t ack)
+    {
+        this->seg_ack = ack;
+    }
+
     void set_end_seq(uint32_t end_seq)
     {
         this->end_seq = end_seq;
@@ -155,7 +160,7 @@ private:
     const uint16_t src_port;
     const uint16_t dst_port;
     uint32_t seg_seq;
-    const uint32_t seg_ack;
+    uint32_t seg_ack;
     uint32_t seg_wnd;
     uint32_t end_seq;
     uint32_t ts = 0;
index 13c1f05f786868b2cac7bc63282bda6bea8812f4..7de202e1b3a7d4bc38cccd812decfdad10cefff2 100644 (file)
@@ -477,27 +477,11 @@ void TcpStreamTracker::update_tracker_ack_recv(TcpSegmentDescriptor& tsd)
 // In no-ack policy, data is implicitly acked immediately.
 void TcpStreamTracker::update_tracker_no_ack_recv(TcpSegmentDescriptor& tsd)
 {
-    // No_ack mode requires that segments be provided in order. If we see
-    // a gap, don't advance the seq and turn off no-ack mode.
-    if(tsd.get_seg_len() != (tsd.get_end_seq() - snd_una))
-    {
-        Stream::set_no_ack_mode(tsd.get_flow(), false);
-        return;
-    }
-
     snd_una = snd_nxt = tsd.get_end_seq();
 }
 
 void TcpStreamTracker::update_tracker_no_ack_sent(TcpSegmentDescriptor& tsd)
 {
-    // No_ack mode requires that segments be provided in order. If we see
-    // a gap, don't advance the seq and turn off no-ack mode.
-    if(tsd.get_seg_len() != (tsd.get_end_seq() - r_win_base))
-    {
-        Stream::set_no_ack_mode(tsd.get_flow(), false);
-        return;
-    }
-
     r_win_base = tsd.get_end_seq();
     reassembler.flush_on_ack_policy(tsd.get_pkt());
 }
index b232a07bafab72ac01ef590553be9807278c5cef..e2679aab73ded597e98fe0eeceb5e993f6dcb6a7 100644 (file)
@@ -993,13 +993,24 @@ bool TcpSession::do_packet_analysis_pre_checks(Packet* p, TcpSegmentDescriptor&
     pkt_action_mask = ACTION_NOTHING;
     tel.clear_tcp_events();
     // process thru state machine...talker first
-    if (p->is_from_client())
+    // When in no-ack mode, don't trust ACK numbers. Set the ACK value
+    // as if the last packet in the other direction was ACK'd.
+    // FIXIT-M: The snd_nxt and snd_una checks are only needed because
+    // the snd_nxt value isn't valid for SYN/ACK packet. Can remove those
+    // checks if that is fixed.
+    if ( p->is_from_client() )
     {
         update_session_on_client_packet(tsd);
+
+        if ( no_ack_mode_enabled() and (server.get_snd_nxt() or server.get_snd_una()) )
+            tsd.set_seg_ack(server.get_snd_nxt());
     }
     else
     {
         update_session_on_server_packet(tsd);
+
+        if ( no_ack_mode_enabled() and (client.get_snd_nxt() or client.get_snd_una()) )
+            tsd.set_seg_ack(client.get_snd_nxt());
     }
 
     update_ignored_session(tsd);