POSIX API大集合
五元组
(sip, sport, dip, dport, protocol)
三次握手的过程, 内核协议栈分析
内核协议栈中是有内核数据结构的.
我们send/write数据, 都是先发送到内核协议栈中,然后由内核协议栈封装发送到物理介质中传输到对端的
对端的接收过程也是经有内核协议栈进行解包, 最终对端应用层获取数据.
三次握手的过程是由客户端的用户通过connect系统调用发起的
由内核协议栈之间完成三次握手. 建立连接的.
第一次握手的时候, 会根据五元组生成一个 node 挂载到半连接队列syn队列中.
第三次握手的时候会根据五元组的信息定位半连接队列中对应的node结点将其移动到accept queue中去.
accept函数则是根据accept中的一个结点为其分配一个fd并且return
connect调用之后客户端处于 syn-sent状态 + 服务端接收到第一次握手数据包的时候处于 syn-recv状态.
listen函数
int listen(int sockfd, int backlog);
unix系统中,backlog 是syn队列+accept队列
的最大值;
linux系统中,backlog是accept队列
的最大值。
至此我非常向提到一个东西叫做
DDOS攻击, 洪水攻击
eg : 在syn上做文章. 不断的向服务器发出syn请求, 请求和服务器建立连接, 恶意的占满服务器的syn队列. 使得正常的普通客户无法和服务器正常建立联系, 无法获取服务.
这个就算最为初级的syn洪水了
还可以利用反射机制,达到借刀杀人的效果
就是将目标服务器ip填写为源ip地址和其他机器请求建立连接.
这样其他机器误以为是服务器想要建立连接, 就会不断的向服务器发送syn + ack包, 这样服务器也会疲于处理大量的无效syn + ack包而无法正常运作
甚至还有更为牛逼的放大攻击.
利用服务器的ip地址发送DNS请求, 然后对于DNS请求而言, 一般是发送一个请求报文远远小于响应报文的, 这样就可以达到放大的效果. 放大垃圾数据攻击服务器.
DDOS 攻击的应对措施
在服务器前面放一台巨大的堡垒机. 让其拦截掉恶意请求.过滤连接请求. 达到净化的效果
数据发送
其实针对数据的send/write是从用户态拷贝到内核协议栈的内核缓冲区中的,然后由内核协议栈不断地进行层层封包, 最后放到物理介质传输到对端, 对端接收到数据报, 在根据头部信息分用, 最终将数据传到应用层
怎么保证顺序?如何保证包地顺序到达(序号 + 确认应答机制 + 重传)
延迟ack,解决包的有序的问题. 就不见ack, 会在最近序号没有收到ack位置及其之后所有的包全部重传, 这样就可以保证一定是顺序到达地. 后面地包先到也没用,还是会丢弃重传. (保证顺序)
重传费带宽, 所以有些时候需要考虑udp, 比如在弱网环境下, 也就是网络环境非常差劲地情况下.
实时性强的场景,也可以选择udp
udp使用场景:
- 游戏,利用UDP的实时性;
- 迅雷下载,使用UDP传输,抢占带宽;TCP有拥塞控制,对带宽进行控制。
TCP断开连接的过程
tcp连接的断开过程. 是由客户端发起的close。然后内核协议栈会向对端发送一个fin包, 同时主动发起方进入fin_wait1状态, 然后对端收到fin包,先回一个ack然后被动的进入close_wait状态. 为何此处的fin + ack不可以何在一起, 因为服务器端很可能还需要向客户端发送未发送完的数据. 发送完之后才会进行close.
问题1. 大量的CLOSE_WAIT + FIN_WAIT2是为啥?
服务端没有处理断开连接的逻辑, 收到客户端的fin包,关闭了读端之后没有进行close。(没有close的逻辑)
time_wait状态存在的原因?
避免最后一次ack的丢失, 如果服务器久收不到客户端发送过来的ack包,也就是被动方久收不到ack就会重新发送fin,这个时候不等,不就没了嘛。 为了让服务端正常断开这条连接, 于是等待time_wait = 2MSL。