HTTP相关

TCP协议

TCP 与 UDP 的区别

TCP是一个面向连接的、可靠的、基于字节流的传输层协议,而UDP是一个无连接的传输层协议

  1. 面向连接 所谓的连接,指的是客户端到服务器的连接,在双发的互相通信之前,TCP需要三次握手简历连接,而UDP没有简历连接的过程。

  2. 可靠性。TCP花了很多功夫保证连接的可靠性,一个是有状态,另一个是可控制。

    • TCP会精准记录哪些数据发送了,哪些数据被接受了,哪些没有被接收到,而且保证数据包按顺序到达,不允许半点差错,这就是有状态
    • 当意识到丢包或者网络环境不佳,TCP会根据具体情况调整自己的行为,控制自己的发送速度或者重发,这是可控制

    相应的, UDP就是无状态不可控

  3. 面向字节流。UDP的数据传输时基于数据包的,这是因为仅仅继承了IP层的特性,而TCP为了维护状态,将一个个IP包变成了字节流

TCP的三次握手

tvDL5j.jpg

  1. 最开始双方都处于 CLOSED 状态。然后服务端开始监听某个端口,进入了 LISTEN 状态
  2. 客户端主动发起连接,发送 SYN,自己变成 SYN-SENT 状态
  3. 服务端收到之后返回 SYNACK (对应客户端发来的SYN),自己变成了 SYN-REVD
  4. 客户端再发送 ACK 给服务端,自己变成了 ESTABLESHED 状态;
  5. 服务端收到 ACK 之后,也变成了 ESTABLESHED 状态

令外需要注意的时,从图中可以看出,SYN 时需要消耗一个序列号的,下次发送的ACK序列号要加1,原因只需要记住一个规则

凡是需要对端确认的,一定小号TCP报文的序列号。

SYN需要对端的确认,而ACK并不需要,因此SYN消耗一个序列号而ACK不用。

TCP 四次挥手

tvrEGR.jpg

  1. 刚开始双方处于 ESTABLESHED 状态
  2. 客户端要断开了,向服务器发送 FIN 报文
  3. 发送后客户端变成了 FIN-WAIT-1 状态,这时候客户端同事也变成了 half-close(半关闭) 状态,无法向服务端发送报文,只能接收。
  4. 服务端接收后向客户端确认,变成了 CLOSED-WAIT 状态
  5. 客户端收到了服务端的确认,变成了 FIN-WAIT-2 状态
  6. 服务端向客户端发送 FIN,自己进入 LAST-ACK 状态
  7. 客户端收到服务端发来的 FIN 后,自己变成了 TIME-WAIT 状态,然后发送ACK给服务端

这个时候,客户端需要等待足够长的时间,具体来说,时2个 MSL(Maximum Segment Lifetime, 报文最大生存时间),这段时间内如果客户端没有收到服务端的重发请求,那么表示 ACK 成功到达,挥手结束,否则客户端重发ACK。

为什么要等待2个MSL?因为如果不等待,一旦服务端还要给客户端发送数据包而客户端已经关闭并且客户端的端口被其他应用占用了,就会造成数据包混乱。

  1. 1个MSL确保四次挥手中主动关闭方最后的ACK报文最终能达到对端
  2. 1个MSL确保对端没有收到ACK重传的FIN报文可以达到

为什么是四次挥手

因为服务端在接手到 FIN,往往不会立即返回 FIN,必须等到服务端所有的报文都发送完毕了,才能发 FIN。因此先发一个 ACK 表示已经收到客户端的 FIN,延迟一段时间才发 FIN。这就造成了四次挥手

半连接队列和 SYN Flood 攻击

三次我收钱,服务端的状态从 CLOSED 变为 LISTEN,同时在内部创建了两个队列:半连接队列全连接队列,即SYN队列ACCEPT队列

半连接队列

当客户端发送SYN到服务端,服务端收到以后回复ACKSYN,状态由CLOSED 变为 LISTEN,此时这个连接就被推入SYN队列,也就是半连接队列

全连接队列

低昂客户端返回ACK,服务端接收后,三次握手完成。这个时候连接等待被具体的应用取走,在被取走之前,它会被推入另外一个TCP维护的队列,也就是全连接队列(Accept Queue)

SYN Flood攻击原理

SYN flood 属于典型的 DoS/DDoS攻击。其攻击原理很简单,就是用客户端在短时间内伪造大量不存在的IP地址,并向服务端疯狂发送SYN。对于服务端而言,会产生两个危险的后果:

  1. 处理大量的 SYN 包并返回对应的ACK,势必有大量连接处于SYN_RCVD 状态,从而沾满整个半连接队列,无法处理正常的请求
  2. 由于是不存在的IP,服务端长时间收不到客户端的ACK,会导致服务端不断重发数据,直到耗尽服务端你的资源

如何应对 SYN Flood 攻击

  1. 增加 SYN 连接,也就是增加半连接队列的容量
  2. 减少 SYN + ACK 重试次数,避免大量的超时重发
  3. 利用 SYN Cookie 技术,在服务端接收到 SYN 后不立即分配连接资源,而是根据这个 SYN 计算出一个Cookie,连同第二次握手回复给客户端,客户端在回复 ACK 的时候就会带上这个 Cookie,服务端验证 Cookie 合法后才分配连接