TCP连接建立
TCP使用了三次握手法来建立连接,如下图所示
TCP三次握手详细过程:
- 客户机器A上的一个应用程序发出连接请求,本地的TCP实体创建一条连接记录,并将它标记为SYN SENT状态,然后发送一个SYN段,此SYN段中包含了主机A选择的序号x
- 服务器执行监听,当收到一个SYN时,服务器就确认该段发出SYN+ACK并且进入到SYN RCVD状态。其中ACK段是作为对x的确认,同时宣告自己的初始序号y
- 最后,主机1对服务器选择的序号进行确认,当主机A发出最后一个ACK段后,主机A切换到ESTABLISHED状态,服务器收到ACK段后也切换到ESTACLISHED状态
三次握手的漏洞
- SYN泛洪
当监听进程接受一个连接请求,并立即以SYN段作为响应时,它必须记住该SYN段的序号。这意味着一个恶意的发送端很容易地占据一个主机资源。具体的做法是这样的:恶意用户绵绵不断地发送SYN段请求服务器连接,但又故意不完成连接建立的后续过程,由此可消耗掉一台主机的资源。这种攻击称为SYN泛洪。
抵御这种攻击的一种方法是使用SYN“小甜饼”(SYN Cookie)。主机不去记忆序号,而是选择一个加密生成的序号,将它放在出境段中,并且忘记它。如果三次握手完成后,该序号(加1)将返回主机。主机运行相同的加密函数进行解密,重新生成正确的序号。这个过程允许主机检查确认号是否正确,而不必记住单独的序号。这里存在一些注意事项,比如无法处理TCP选项,所以只有当主机容易受到SYN泛洪时,才可以使用SYN Cookie。
- 其他
如伪造连接,可使用伪随机的初始序号,保证在一个时间间隔内初始序号不能重复,防止序号回绕(PAWS)
TCP连接释放
TCP使用四次挥手来释放连接,如图所示
TCP挥手详细过程:
- 主机中的应用程序执行CLOSE原语,从而使本地的TCP实体发送一个FIN段,并切换到FIN WAIT 1状态
- 当服务器收到FIN段后,向主机发送ACK段,当ACK到达主机时,它的状态会切换到FIN WAIT 2,连接的一个方向被关闭
- 服务器发送完所有数据包后,它也会执行CLOSE,TCP实体给客户发送一个FIN段
- 主机确认了服务器发来的FIN,发送给服务器ACK段,服务器收到确认返回后便释放该连接并删除响应的连接记录,客户主机的TCP等待一段长度为最大数据包生存期两倍的时间,当计时器超时后,TCP删除该连接记录
特殊情况
第一个ACK和第二个FIN有可能被组合在同一段中,从而将所需段总数降低到三个。如下图所示:
非对称释放
连接的两端在发送完自己的数据之后都用一个FIN段和ACK来释放连接的方式叫做对称释放方式,但许多Web服务器给客户端发送一个RST包,导致突然关闭连接,这种方式就是非对称方式释放连接。或者在超时的时候,也会有非对称释放方式(这种方式往往由心跳机制实现)。