00001 //--------------------------------------------------------------------------
00002 // Copyright (C) 2015-2017 Cisco and/or its affiliates. All rights reserved.
00003 //
00004 // This program is free software; you can redistribute it and/or modify it
00005 // under the terms of the GNU General Public License Version 2 as published
00006 // by the Free Software Foundation. You may not use, modify or distribute
00007 // this program under any other version of the GNU General Public License.
00008 //
00009 // This program is distributed in the hope that it will be useful, but
00010 // WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License along
00015 // with this program; if not, write to the Free Software Foundation, Inc.,
00016 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017 //--------------------------------------------------------------------------
00018
00019 // tcp_state_established.cc author davis mcpherson <davmcphe@@cisco.com>
00020 // Created on: Jul 30, 2015
00021
00022 #ifdef HAVE_CONFIG_H
00023 #include "config.h"
00024 #endif
00025
00026 #include "tcp_state_established.h"
00027
00028 #include "tcp_normalizer.h"
00029 #include "tcp_session.h"
00030
00031 TcpStateEstablished::TcpStateEstablished(TcpStateMachine& tsm) :
00032 TcpStateHandler(TcpStreamTracker::TCP_ESTABLISHED, tsm)
00033 {
00034 }
00035
00036
00037 bool TcpStateEstablished::syn_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00038 {
00039 trk.session->check_for_repeated_syn(tsd);
00040
00041 return default_state_action(tsd, trk);
00042 }
00043
00044 bool TcpStateEstablished::syn_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00045 {
00046 trk.session->check_for_repeated_syn(tsd);
00047
00048 trk.normalizer->ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs() );
00049
00050 return default_state_action(tsd, trk);
00051 }
00052
00053 bool TcpStateEstablished::syn_ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00054 {
00055 if ( trk.session->config->midstream_allowed(tsd.get_pkt()) )
00056 {
00057 // FIXIT-M there may be an issue when syn/ack from server is seen
00058 // after ack from client which causes some tracker state variables to
00059 // not be initialized... update_tracker_ack_sent may fix that but needs
00060 // more testing
00061 //trk.update_tracker_ack_sent( tsd );
00062 trk.session->update_session_on_syn_ack();
00063 }
00064
00065 if ( trk.is_server_tracker() )
00066 trk.normalizer->ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs() );
00067
00068 return default_state_action(tsd, trk);
00069 }
00070
00071 bool TcpStateEstablished::syn_ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00072 {
00073 return default_state_action(tsd, trk);
00074 }
00075
00076 bool TcpStateEstablished::ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00077 {
00078 trk.update_tracker_ack_sent(tsd);
00079
00080 return default_state_action(tsd, trk);
00081 }
00082
00083 bool TcpStateEstablished::ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00084 {
00085 trk.update_tracker_ack_recv(tsd);
00086
00087 return default_state_action(tsd, trk);
00088 }
00089
00090 bool TcpStateEstablished::data_seg_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00091 {
00092 trk.update_tracker_ack_sent(tsd);
00093
00094 return default_state_action(tsd, trk);
00095 }
00096
00097 bool TcpStateEstablished::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00098 {
00099 trk.update_tracker_ack_recv(tsd);
00100 trk.session->handle_data_segment(tsd);
00101
00102 return default_state_action(tsd, trk);
00103 }
00104
00105 bool TcpStateEstablished::fin_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00106 {
00107 TcpStreamTracker* listener = nullptr;
00108
00109 if ( tsd.get_pkt()->is_from_client() )
00110 listener = trk.session->server;
00111 else
00112 listener = trk.session->client;
00113 trk.update_on_fin_sent(tsd);
00114
00115 if ( SEQ_EQ(tsd.get_end_seq(), (listener->r_nxt_ack + tsd.get_seg_len())) ||
00116 listener->process_inorder_fin() || !listener->is_segment_seq_valid(tsd) )
00117 {
00118 trk.session->eof_handle(tsd.get_pkt());
00119 trk.set_tcp_state(TcpStreamTracker::TCP_FIN_WAIT1);
00120 }
00121
00122 return default_state_action(tsd, trk);
00123 }
00124
00125 bool TcpStateEstablished::fin_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00126 {
00127 trk.update_tracker_ack_recv(tsd);
00128 if ( tsd.get_seg_len() > 0 )
00129 {
00130 trk.session->handle_data_segment(tsd);
00131 trk.flush_data_on_fin_recv(tsd);
00132 }
00133 if( (tsd.get_end_seq() == trk.r_nxt_ack) || !trk.is_segment_seq_valid(tsd) )
00134 {
00135 if ( trk.update_on_fin_recv(tsd) )
00136 {
00137 trk.session->update_perf_base_state(TcpStreamTracker::TCP_CLOSING);
00138 trk.set_tcp_state(TcpStreamTracker::TCP_CLOSE_WAIT);
00139 }
00140 }
00141 else
00142 {
00143 //Out of Order FIN received
00144 if ( !trk.is_fin_seq_set() )
00145 trk.set_fin_final_seq( tsd.get_seg_seq() );
00146 }
00147
00148 return default_state_action(tsd, trk);
00149 }
00150
00151 bool TcpStateEstablished::rst_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00152 {
00153 return default_state_action(tsd, trk);
00154 }
00155
00156 bool TcpStateEstablished::rst_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00157 {
00158 if ( trk.update_on_rst_recv(tsd) )
00159 {
00160 trk.session->update_session_on_rst(tsd, false);
00161 trk.session->update_perf_base_state(TcpStreamTracker::TCP_CLOSING);
00162 trk.session->set_pkt_action_flag(ACTION_RST);
00163 }
00164 else
00165 {
00166 trk.session->tel.set_tcp_event(EVENT_BAD_RST);
00167 }
00168
00169 // FIXIT-L might be good to create alert specific to RST with data
00170 if ( tsd.get_seg_len() > 0 )
00171 trk.session->tel.set_tcp_event(EVENT_DATA_AFTER_RST_RCVD);
00172
00173 return default_state_action(tsd, trk);
00174 }
00175
00176 bool TcpStateEstablished::do_pre_sm_packet_actions(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00177 {
00178 return trk.session->validate_packet_established_session(tsd);
00179 }
00180
00181 bool TcpStateEstablished::do_post_sm_packet_actions(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00182 {
00183 trk.session->update_paws_timestamps(tsd);
00184 trk.session->check_for_window_slam(tsd);
00185
00186 return true;
00187 }
00188
END OF CODE