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_listen.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_listen.h"
00027
00028 #include "tcp_normalizer.h"
00029 #include "tcp_session.h"
00030
00031 TcpStateListen::TcpStateListen(TcpStateMachine& tsm) :
00032 TcpStateHandler(TcpStreamTracker::TCP_LISTEN, tsm)
00033 {
00034 }
00035
00036
00037 bool TcpStateListen::syn_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00038 {
00039 if ( trk.session->config->require_3whs() || tsd.has_wscale() || ( tsd.get_seg_len() > 0 ) )
00040 {
00041 // FIXIT-L do we need this check? only server goes into Listen state...
00042 if ( tsd.get_pkt()->is_from_server() )
00043 trk.session->tel.set_tcp_event(EVENT_4WHS);
00044 }
00045
00046 return default_state_action(tsd, trk);
00047 }
00048
00049 bool TcpStateListen::syn_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00050 {
00051 trk.init_on_syn_recv(tsd);
00052 trk.normalizer->ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs() );
00053 trk.session->set_pkt_action_flag(trk.normalizer->handle_paws(tsd) );
00054 if ( tsd.get_seg_len() > 0 )
00055 trk.session->handle_data_on_syn(tsd);
00056
00057 return default_state_action(tsd, trk);
00058 }
00059
00060 bool TcpStateListen::syn_ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00061 {
00062 Flow* flow = tsd.get_flow();
00063
00064 flow->session_state |= ( STREAM_STATE_SYN | STREAM_STATE_SYN_ACK );
00065
00066 if ( trk.session->config->midstream_allowed(tsd.get_pkt() ) )
00067 {
00068 trk.init_on_synack_sent(tsd);
00069 trk.normalizer->ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs() );
00070 trk.session->init_new_tcp_session(tsd);
00071 }
00072 else if ( trk.session->config->require_3whs() )
00073 {
00074 trk.session->generate_no_3whs_event();
00075 return false;
00076 }
00077
00078 return default_state_action(tsd, trk);
00079 }
00080
00081 bool TcpStateListen::syn_ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00082 {
00083 if ( !trk.session->config->require_3whs() || trk.session->config->midstream_allowed(tsd.get_pkt() ) )
00084 {
00085 trk.init_on_synack_recv(tsd);
00086 if ( tsd.get_seg_len() > 0 )
00087 trk.session->handle_data_segment(tsd);
00088 }
00089 else if ( trk.session->config->require_3whs() )
00090 {
00091 trk.session->generate_no_3whs_event();
00092 return false;
00093 }
00094
00095 return default_state_action(tsd, trk);
00096 }
00097
00098 bool TcpStateListen::ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00099 {
00100 if ( trk.session->config->midstream_allowed(tsd.get_pkt() )
00101 && ( tsd.has_wscale() || ( tsd.get_seg_len() > 0 ) ) )
00102 {
00103 Flow* flow = tsd.get_flow();
00104
00105 // FIXIT-H do we need to verify the ACK field is >= the seq of the SYN-ACK?
00106 // 3-way Handshake complete, create TCP session
00107 flow->session_state |= ( STREAM_STATE_ACK | STREAM_STATE_SYN_ACK |
00108 STREAM_STATE_ESTABLISHED );
00109 trk.init_on_3whs_ack_sent(tsd);
00110 trk.session->init_new_tcp_session(tsd);
00111 trk.session->update_perf_base_state(TcpStreamTracker::TCP_ESTABLISHED);
00112 }
00113 else if ( trk.session->config->require_3whs() )
00114 {
00115 trk.session->generate_no_3whs_event();
00116 return false;
00117 }
00118
00119 return default_state_action(tsd, trk);
00120 }
00121
00122 bool TcpStateListen::ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00123 {
00124 if ( trk.session->config->midstream_allowed(tsd.get_pkt() )
00125 && ( tsd.has_wscale() || ( tsd.get_seg_len() > 0 ) ) )
00126 {
00127 Flow* flow = tsd.get_flow();
00128
00129 if ( !tsd.get_tcph()->is_rst() && ( flow->session_state & STREAM_STATE_SYN_ACK ) )
00130 {
00131 trk.init_on_3whs_ack_recv(tsd);
00132 trk.normalizer->ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs() );
00133 }
00134 }
00135 else if ( trk.session->config->require_3whs() )
00136 {
00137 trk.session->generate_no_3whs_event();
00138 return false;
00139 }
00140
00141 return default_state_action(tsd, trk);
00142 }
00143
00144 bool TcpStateListen::data_seg_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00145 {
00146 if ( trk.session->config->midstream_allowed(tsd.get_pkt() ) )
00147 {
00148 Flow* flow = tsd.get_flow();
00149
00150 flow->session_state |= STREAM_STATE_MIDSTREAM;
00151 flow->set_session_flags(SSNFLAG_MIDSTREAM);
00152
00153 trk.init_on_data_seg_sent(tsd);
00154 trk.session->init_new_tcp_session(tsd);
00155
00156 if ( flow->session_state & STREAM_STATE_ESTABLISHED )
00157 trk.session->update_perf_base_state(TcpStreamTracker::TCP_ESTABLISHED);
00158 }
00159 else if ( trk.session->config->require_3whs() )
00160 {
00161 trk.session->generate_no_3whs_event();
00162 return false;
00163 }
00164
00165 return default_state_action(tsd, trk);
00166 }
00167
00168 bool TcpStateListen::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00169 {
00170 if ( trk.session->config->midstream_allowed(tsd.get_pkt() ) )
00171 {
00172 Flow* flow = tsd.get_flow();
00173
00174 flow->session_state |= STREAM_STATE_MIDSTREAM;
00175 flow->set_session_flags(SSNFLAG_MIDSTREAM);
00176 trk.init_on_data_seg_recv(tsd);
00177 trk.normalizer->ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs() );
00178 trk.session->handle_data_segment(tsd);
00179 }
00180 else if ( trk.session->config->require_3whs() )
00181 {
00182 trk.session->generate_no_3whs_event();
00183 return false;
00184 }
00185
00186 return default_state_action(tsd, trk);
00187 }
00188
00189 bool TcpStateListen::fin_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00190 {
00191 if ( trk.session->config->midstream_allowed(tsd.get_pkt() ) )
00192 {
00193 }
00194 else if ( trk.session->config->require_3whs() )
00195 {
00196 trk.session->generate_no_3whs_event();
00197 return false;
00198 }
00199
00200 return default_state_action(tsd, trk);
00201 }
00202
00203 bool TcpStateListen::fin_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00204 {
00205 if ( trk.session->config->midstream_allowed(tsd.get_pkt() ) )
00206 {
00207 // FIXIT-L handle FIN on midstream
00208 }
00209 else if ( trk.session->config->require_3whs() )
00210 {
00211 trk.session->generate_no_3whs_event();
00212 return false;
00213 }
00214
00215 return default_state_action(tsd, trk);
00216 }
00217
00218 bool TcpStateListen::rst_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00219 {
00220 if ( trk.session->config->midstream_allowed(tsd.get_pkt() ) )
00221 {
00222 }
00223
00224 return default_state_action(tsd, trk);
00225 }
00226
00227 bool TcpStateListen::rst_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00228 {
00229 trk.normalizer->trim_rst_payload(tsd);
00230
00231 return default_state_action(tsd, trk);
00232 }
00233
END OF CODE