int ProcessTcp(Stream5LWSession *lwssn,Packet *p, TcpDataBlock *tdb,
Stream5TcpPolicy *s5TcpPolicy)
lwssn : 当前的流
p :当前的包
tdb :包含 seq ack end_seq win ts
s5TcpPolicy :流的规则参数,如最大字节数,段数,超时时间
{
tcpssn= (TcpSession *)lwssn->proto_specific_data->data;
如果tcpssn== NULL
{
判断该包是否需要处理,不需要处理则返回;
如果(SYN , ! ACK)
如果(SYN 或者ACK)
如果(ACK, !RST, STREAM5_STATE_SYN_ACK)
如果(p->dsize > 0)&& (!require3Way || midstream_allowed)
如果(p->dsize == 0)
}
else //tcpssn!=NULL
{
如果流的状态不为STREAM5_STATE_ESTABLISHED
那么 :
如果1:(TH_SYN|TH_ACK),状态为STREAM5_STATE_NONE,那么进入,|= STREAM5_STATE_SYN_ACK;
如果2:TH_ACK,状态为STREAM5_STATE_SYN_ACK,那么进入|= STREAM5_STATE_ACK |STREAM5_STATE_ESTABLISHED;
}
判断并设置包来自于客户端还是服务端;
包来自于服务端,设定流的状态;
包来自于客户端,设定流的状态;
流的状态为RESET,并且收到SYN,对已收到的数据包检测,释放原来的空间,对新的包,1.如果为RST, 则不做处理,直接丢弃该包;2.如果为SYN, !ACK, 建流;3.如果为SYN, ACK,建流;
talker或者listener的flags置位TF_FORCE_FLUSH,则该流被检测;
如果该流被忽略,则该包不被检测;
如果包带数据,又有SYN标志,则判断该包是否来自操作系统MACOS,其他的不做处理;
如果到此处tcpssn 为空,则退出该函数,不做处理;
处理没有进入established状态的流,收到ACT, RST,SYN, ECE等包的情况的处理,进入该流程,执行完后都退出该函数,没有进一步的检测;
处理wscale
处理timestamp;
//执行到此处,流已经是进入established状态下的了;
收到的包是RST,则该流进行检测,退出;如果不是RST,则判断包的序号,如果乱序包,则丢弃;
更新流的最后一个包的时间戳;
如果在已经是established流上又收到SYN,则处理重复的SYN;
检测流的窗口(tdb->win > listener->tcp_policy->max_window)是否在限制的范围内,超出范围则丢弃;
处理ACK包,在各个状态下调用UpdateSsn(),更新tdb:包含 seq ack end_seq wints
如果包带的数据大于0,1.(TCP_STATE_FIN_WAIT_2 == talker->s_mgr.state ||
TCP_STATE_TIME_WAIT == talker->s_mgr.state),丢弃该包; 2. (TCP_STATE_CLOSED == talker->s_mgr.state),丢弃该包;3. (p->tcph->th_flags != 0) || (s5TcpPolicy->policy ==STREAM_POLICY_LINUX),处理该包进行检测,否则丢弃该包;
处理FIN包,在各个状态下更新流的状态(更新流状态另外一个地方是收到ACK包后的处理);
dupfin:状态下,流的状态为(talker->s_mgr.state== TCP_STATE_TIME_WAIT && listener->s_mgr.state == TCP_STATE_CLOSED)||
(listener->s_mgr.state == TCP_STATE_TIME_WAIT &&talker->s_mgr.state == TCP_STATE_CLOSED) ||
(listener->s_mgr.state == TCP_STATE_TIME_WAIT &&talker->s_mgr.state == TCP_STATE_TIME_WAIT)
以上的状态为三种,主动关闭,被动关闭,同时关闭, 处理服务端流的检测,处理客户端流的检测。
}