TCP/UDP
如何描述网络的传输能力? 带宽--单位时间内的流量,表达是「速度」,比如常见的带宽 100 MB/s 带宽时延积 BDP--决定网络中飞行报文的大小,RTT * 带宽 发送缓冲区 tcp_wmem--决定了发送窗口 swnd 的上限/下限,不能超过带宽时延积 BDP;否则网络过载,发生丢包 接收缓冲区 tcp_rmem--决定了接收窗口 rwnd 的上限/下限 TCP 三次握手/四次挥手--https://www.cnblogs.com/xiaolincoding/p/13067971.html 三次握手 目的--全双工确认 ISN--Initial Sequence Number 是固定的吗? ISN可以看作是一个32比特的计数器,每4ms加1。 两次握手为什么不行? 防止已经失效的客户端请求长时间延迟后触达服务器,导致服务器的资源浪费。 SYN Flood 排查 netstat -s | grep "SYNs to LISTEN" 解决方案 1. 缩短 SYN Timeout 2. 增加半连接队列--增加存储处于 SYN_RCVD 状态的连接 3. 过滤网关防护--超时设置(网关超时时间比server小)、SYN网关(网关完成第三次握手,将半连接转化为全连接)、SYN署理(网关代替server完成三次握手) 4. SYN cookies 技术--服务器在收到客户端的SYN报文时,不分配资源保存半连接,而是利用ISN的随机性将SYN信息加密保存着SYN+ACK之中,在第三次握手中再校验。 tcp_syn_retries--client重试发送SYNC的次数,每次重试超时时间是上一次的 2 倍(当第五次超时重传后,会继续等待 32 秒,如果服务端仍然没有回应 ACK,客户端就会终止三次握手) tcp_synack_retries--重发 SYN+ACK 报文,默认5次 tcp_max_syn_backlog/somaxconn/backlog--增大半连接队列 min(somaxconn, backlog)--accept 队列的长度(全连接队列) 查看当前 accept 队列的长度--ss -ltn 查看由于 accept 连接队列已满,而被丢弃的连接--netstat -s | grep "overflowed" syncookies--开启 SYN cookies 技术 tcp_abort_on_overflow--当 accept 队列已满,向客户端发送 RST 复位报文 四次挥手 目的--全双工关闭 MSL--Maximum Segment Lifetime 报文段最大生存时间 TIME_WAIT 等待 2MSL 的目的? 1. 保证最后一个ACK触达对端(对端在一次MSL超时后,重传FIN+ACK,导致TIME_WAIT的2MSL重新计时) 2. 防止收到历史数据,从而导致数据错乱 tcp_max_tw_buckets--控制 TIME_WAIT 连接数 tcp_orphan_retries--控制 FIN 重发次数。 close()--直接关闭读写 孤儿连接--不属于任何进程的连接,由内核接管 FIN_WAIT2 和 TIME_WAIT 状态。 tcp_fin_timeout--控制处于 FIN_WAIT2 状态的时间 tcp_max_orphans--控制孤儿连接数量 shutdown()--分别关闭读写 TCP 可靠性 MTU:Maxitum Transmission Unit,某层网络一包数据负载的最大值 MSS:Maxitum Segment Size,TCP包能够传输的最大数据大小 重传 快速重传 不以时间为驱动,而是以数据驱动重传;发送端收到了三个相同 Ack 确认,就会在定时器过期之前,重传丢失的这个数据包。 超时重传 发送数据时,设定一个定时器,当超过指定的时间后,没有收到对方的 ACK 确认应答报文,就会重发该数据 定时器超时时间(RTO) 略大于 RTT,RTT 是经常波动变化的,RTO 也是如此; 每当遇到一次超时重传的时候,都会将下一次超时时间间隔设为先前值的两倍; 两次超时,就说明网络环境差,不宜频繁反复发送。 确认 累积确认 基于窗口,不用等ack再发送下一个数据包 选择确认(SACK)--https://blog.csdn.net/wdscq1234/article/details/52503315 解决重传策略的不足 1. 重传下一个包--丢包过多,一个一个等待 2. 重传下一个包及之后所有的包--丢包很少,流量浪费 将缓存的地图发送给发送方 SACK block 1--报告一个重复的连续片段 SACK block 2--报告一个没有确认的连续片段 滑动窗口 基于确认/重传实现的滑动窗口,提供TCP的可靠性,提供TCP的流控特性 tcp_window_scaling--控制窗口扩大因子,从 2^16=64KB 扩大到 2^30=1GB 发送窗口 swnd 已经发送但还未收到对端ACK的 未发送但对端允许发送的 接收窗口 rwnd 未接收准备接收 发送窗口与接收窗口关系 “发送窗口”则要求取决于对端通告的“接收窗口” “接收窗口”大小取决于应用、系统、硬件的限制 拥塞窗口 cwnd swnd = min(cwnd, rwnd),当 cwnd >= rwnd,拥塞控制就失效了(大多数情况下网络曲线是平滑的,不是锯齿状的) 窗口收缩导致丢包 TCP 规定是不允许同时减少缓存又收缩窗口的,而是采用先收缩窗口,过段时间再减少缓存 窗口关闭--https://www.cnblogs.com/hongdada/p/11171068.html 零窗口:如果窗口大小为 0 时,就会阻止发送方给接收方传递数据,直到窗口变为非 0 为止(潜在死锁) 死锁解决:TCP 连接方收到对方的零窗口通知,就启动持续计时器;计时器超时,就会发送窗口探测 ( Window probe ) 报文 糊涂窗口综合症 1. 接收方--当「窗口大小」小于 min( MSS,缓存空间/2 ) ,也就是小于 MSS 与 1/2 缓存大小中的最小值时,就会向发送方通告窗口为 0 2. 发送方--Nagle 算法:窗口大于 MSS 或者收到ACK回包 拥塞控制 慢启动(指数性的增长) ssthresh (slow start threshold) 当 cwnd < ssthresh,发送方每收到一个 ACK,拥塞窗口 cwnd 的大小就会加 1 拥塞避免(线性增长) 当 cwnd >= ssthresh,发送方每当收到一个 ACK 时,cwnd 增加 1/cwnd 拥塞发生 当发生了「超时重传」,ssthresh 设为 cwnd/2,cwnd 重置为 1 当发生了「快速重传」,ssthresh 设为 cwnd/2,cwnd 重置为 ssthresh + 3 * MSS KeepAlive 保活探测机制 目的 减少服务端失效的半连接 防止网关丢弃路由信息 弊端 弱网环境导致连接关闭 额外的网络流量开销 与 HTTP KeepAlive 的区别 HTTP KeepAlive 的目的是多路复用,减少 TCP 握手、挥手的开销 与心跳保活的区别 KeepAlive 保证网络层连接的存活 心跳探测两端服务的可用性 TCP状态 CLOSED: The socket is not in use. LISTEN: The socket is listening for incoming connections. Unconnected listening sockets like these are only displayed when using the -a option. SYN_SENT: The socket is actively trying to establish a connection to a remote peer. SYN_RCVD: The socket has passively received a connection request from a remote peer. ESTABLISHED: The socket has an established connection between a local application and a remote peer. CLOSE_WAIT: The socket connection has been closed by the remote peer, and the system is waiting for the local application to close its half of the connection. LAST_ACK: The socket connection has been closed by the remote peer, the local application has closed its half of the connection, and the system is waiting for the remote peer to acknowledge the close. FIN_WAIT_1: The socket connection has been closed by the local application, the remote peer has not yet acknowledged the close, and the system is waiting for it to close its half of the connection. FIN_WAIT_2: The socket connection has been closed by the local application, the remote peer has acknowledged the close, and the system is waiting for it to close its half of the connection. CLOSING: The socket connection has been closed by the local application and the remote peer simultaneously, and the remote peer has not yet acknowledged the close attempt of the local application. TIME_WAIT: The socket connection has been closed by the local application, the remote peer has closed its half of the connection, and the system is waiting to be sure that the remote peer received the last acknowledgement. 作用: 1. 可靠地实现TCP全双工连接的终止 2. 允许老的重复分节在网络中消逝 大量TIME_WAIT修复 https://blog.csdn.net/yanggd1987/article/details/39317871 状态与socket函数 原始设计 connect对应SYN_SENT状态 accept对应SYN_RCVD状态 recv返回0,对应CLOSE_WAIT 实际实现 服务器协议栈负责三次握手的交互过程,连接建立后,往listen队列中添加一个成功的连接,直到队列的最大长度 服务器调用accept从listen队列中取出一条成功的tcp连接,listen队列中的连接个数就少一个 accept与三次握手无关,这在一定程度上可以减少 SYN Flood 攻击 https://blog.csdn.net/u013782203/article/details/51767763 https://blog.csdn.net/futurewu/article/details/76674016 DNS记录类型 A记录/AAAA记录: 用于名称解析的重要记录,它将特定的主机名映射到对应主机的IP地址上 NS: 域名服务器记录,用来指定该域名由哪个DNS服务器来进行解析 CNAME记录: 用于将某个别名指向到某个A记录上,这样就不需要再为某个新名字另外创建一条新的A记录 MX记录: 用户可以将该域名下的邮件服务器指向到自己的mail server上,然后即可自行操作控制所有的邮箱设置 SRV记录: 用于定义提供特定服务的服务器的位置 NAPTR记录: 提供了正则表达式方式去映射一个域名(与SIP协议相关) DNS查询过程中遇到的服务器 ISP缓存服务器 逻辑根域名服务器 顶级域名服务器 二级域名服务器 DNS轮询 dns-server对于一个域名配置了多个解析ip,每次DNS解析请求来访问dns-server,会轮询返回这些ip DNS有关的安全风险 防火墙不会限制对DNS的访问,通过DNS绕过防火墙 泄漏内部的网络拓朴结构 域名劫持 gethostbyname的性能瓶颈 该函数不能像connect和read等函数那样通过setsockopt或者select函数那样设置超时时间,因此常常成为程序的瓶颈 不支持并发:在多线程下面,如果有一个线程的gethostbyname发生阻塞,其它线程都会在gethostbyname处发生阻塞 refs: DNS https://www.cnblogs.com/LittleHann/p/3828927.html