自顶向下方法
计算机网络与因特网
应用层
安全套接字层(SSL),位于应用层,可以对数据加密。
网络应用:Web应用,电子邮件应用
应用层协议:HTTP, SMTP
本章讨论物种应用:Web、文件传输、电子邮件、目录服务、流式视频与P2P。
DNS
递归查询
将任务交给一个DNS服务器就不管了,最终会得到查询的结果。
迭代查询
将任务交给一个DNS服务器后,DNS服务器会返回新的DNS服务器,这些需要本机自己去查。
查询通常遵 循图2-18 中的模式: 从请求主机到本地 DNS 服务器的查询是递归的、其余的查询 根DNS服务器是迭代的。1,8是递归的,其他是迭代的

运输层
UDP
- 长度 ,首部+数据
- 校验和,对所有16比特数据进行求和、回卷、反码计算。

可靠传输
基于完全可行信道传输
rdt1.0
不用担心差错随便发
基于有比特差错信道的可靠数据传输(信道上发送的包某些位可能改变,但信道不会有其他问题,比如丢包等)
rdt2.0
接收方通过ACK和NAK来确认,有NAK就会重传。
本协议基本可行,但有一个缺陷:数据发送方收到了出错的ACK和NAK包怎么办,数据发送方当然可以重发前一个包,但发了之后,接收方如何判断这个包是重传的包还是新的包。加一个分组就行了,如下
rdt2.1
发送时,增加一个一位的分组信息,接收方只需要检查序号就知道这个包是重传还是新发的包。
比如,服务器发送分组为1的包给客户端,客户端发送了ACK给服务器,但该包在传输过程中损坏了,服务器不知道这个包是什么意思,于是重发了分组为1的包给客户端,客户端收到包后,发现组号是1,刚刚也收到了相同的包,就知道这是重传的包了。(从而避免将这个包当成是新的数据)
rdt2.2
因为有了分组号,NAK也可以被冗余ACK代替了。
比如客户端收到了包1,向服务器发送ACK:1,然后收到了出错的包0,那么也向服务器发送ACK:1,这样服务器就知道包0出错需要重发了。
基于有比特差错、会丢包的信道的可靠数据传输
rdt3.0
常见的办法是:由发送方来检测和恢复丢包工作(不管是丢数据还是丢ACK,都是发送方的定时器来检测)。当发送方等待一段时间(通过定时器)没有收到ACK,则重发分组。

rdt3.0是基本完善的协议,但是效率太低。可以通过流水线操作一直发数据,但是遇到包丢失如何处理呢,两种基本方式:回退N步(G–Back-N)和选择重传(Selective Repeat,SR)
回退N步(又名滑动窗口协议)

为什么会限制窗口长度为N,是为了流量控制。
比如TCP建立连接时,客户端发送的syn报文会给出当前套接字对应的窗口大小,服务器段应该保证未被确认的报文大小小于这个窗口。
GBN发送方需要面临三种新的事件:
- 上层调用,如果窗口已满,可以直接返回,让用户待会儿再试,或者使用同步机制,待会儿再发。
- 收到一个ACK,GBN中,使用的是累计确认的方式。
- 超时事件,最早未被确认的分组有一个定时器。超时后,会重发已发送但没有被确认的分组。
GBN接收方不需要接收分组错乱的包。因为不管接收方缓不缓存这些乱序的包,最后GBN发送方都会重发。(比如接收方没有收到包0,但收到了包1、2,那么这两个包会被丢弃)
选择重传
选择重传 (SR) 协议通过让发送方仅重传那些它怀疑在接收方出错(即丢失或受损)的分组而避免了不必要的重传。 所以选择重传不会使用累计确认了,每个包都会单独确认。

SR发送方面临的事件:
- 上层调用,
- 超时,每个分组都有定时器,哪个定时器超时就重发那个分组
- 收到ACK,没有使用累计确认,根据情况移动窗口。
SR接收方面临的事件:
- 序号在窗口内的,发ACK,根据情况移动窗口。
- 序号在窗口前N个包内的,也发ACK。比如说服务器发送了一个包,客户端返回的ACK在路上丢失了,服务器会因为该包的定时器超时而重发,但是客户端的窗口已经移动到下一个位置了,所以客户端还不需要确认一下。
窗口长度必须小于或等于序号空间大小的一半。
TCP
提供了可靠数据传输、拥塞控制。
UDP是无连接的,会根据目的IP、端口号来确定发给哪个套接字。
TCP是有连接的,会根据四元组(源/目的IP、源/目的端口号)来确定发给那个套接字。(原因在于建立连接时和建立连接后,客户端都通过80端口与服务器通信,但这些信息应该被发到不同的套接字里面去,单靠目的端口IP是没法区分的)
TCP连接
最大报文段长度MSS由链路层帧长度MTU确定,以太网是1500字节,所以在其上的MSS为1460字节。
TCP报文结构

- 序号与确认号,这个确认号与前面GBN和SR的ACK有点区别,这里的确认号是期望接受的下一个字节。TCP也是累计确认的。
往返时间的估计与超时
TCP 如同前面3.4节所讲的 rdt 协议一样,它采用超时/重传机制来处理报文段的丢失问 题。
EstimatedRTT = 0. 875·EstimatedRTT + 0. 125·SampleRTT
Timeoutlnterval = EstimatedRTT + 4 ·DevR’IT
TCP超时会重传,3个冗余ACK会重传。
TCP并不是单一的GBN,SR,比如TCP超时只会传第一个包,不丢弃乱序的包,这有点像SR,TCP使用累计确认,这有点像GBN。(GBN的缺点在于超时会重传所有未确认的包,SR缺点是为每一个包构建一个定时器,感觉TCP是取其精华、去其糟粕)
一个发送方能够具有的未被确认报文段的具体数量是由TCP 的流量控制和拥塞控制机制决定的。
可靠数据传输
TCP发送方简化的描述
1 | / * 假设发送方不受TCP流量和拥塞控制的限制, 来自上层数据的长度小于MSS. 且数据传送只在一个 |
超时间隔在每次重传后会呈指数型增长。 然而,每当定时器在另两个事件(即 收到上层应用的数据和收到ACK) 中的任意一个启动时, Timeoutlnterval 由最近的 Estimat edRTI 值与 DevRTI值推算得到。这种修改提供了一个形式受限的拥塞控制,更复杂的拥塞控制在3.7中介绍。
快速重传,冗余ACK,看下接收方如何发送ACK。(第二条的意思是,如果连续两个报文都是按照顺序发送的,直接发送累计ACK)
根据上面的建议,接收方会产生冗余ACK,一旦收到3个冗余ACK,TCP就执行快速重传。
选择GBN还是SR
TCP 的差错恢复机制也许最好 被分类为GBN 协议与SR协议的混合体。
流量控制
拥塞控制是避免网络IP网络拥塞。
流量控制是避免接收方缓存溢出。
发送方要保证接收方的三个变量满足如下关系:
LastByteSent - LastByteAcked <= rwnd
TCP连接管理


HTTP、TCP、IP、ICMP、UDP、DNS、ARP
IP地址、MAC地址、OSI七层模型(或者 TCP/IP 五层模型)
HTTPS安全相关的:数字签名、数字证书、TLS
常见网络攻击:局域网ARP泛洪、DDoS、TCP SYN Flood、XSS等
SYN 泛洪攻击:客户端只握第一次手,不握第三次手,这会导致服务器为连接分配TCP缓存,并且保持一段时间。这是DoS攻击的一种。
防御方法:主要思想就是第一次握手之后服务器不存储任何数据就行了。但关键是第三次握手时客户端需要发送ACK, 这个值为服务器的 SYN + 1,但服务器都不存储任何值,如何得到这个 SYN 值呢。——让客户端发过来就行了,具体步骤如下:
- 服务器收到SYN报文时,将源/目的IP地址和端口以及一个秘密的数传入一个哈希函数,得到初始序列号,然后把带有这个初始序列号的SYNACK包发给客户端。
- 服务器收到ACK后,根据之前的哈希函数再次计算初始序列号,这个序列号应该等于客户端传的ACK号-1。这时才生成一个具有套接字的全开的连接。
- 如果客户没有返回一个ACK报文段,则初始的 SYN 并没有对服务 器产生危害`因为服务器没有为它分配任何资源。
nmap 可以用于端口检测
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 (pytorch_cuda) root@a40793cb857f:~# nmap -p 10080,10081,10082,10083,10084,10085,10086,10087,10088,10089,10090 202.115.17.63
Starting Nmap 7.80 ( https://nmap.org ) at 2024-11-30 21:44 CST
Nmap scan report for 202.115.17.63
Host is up (0.0012s latency).
PORT STATE SERVICE
10080/tcp filtered amanda
10081/tcp filtered famdc
10082/tcp filtered amandaidx
10083/tcp filtered amidxtape
10084/tcp filtered unknown
10085/tcp filtered unknown
10086/tcp closed unknown
10087/tcp closed unknown
10088/tcp closed unknown
10089/tcp open unknown
10090/tcp open unknown
拥塞控制原理
拥塞原因与代价
我们首先将看看出现拥塞的原因以及拥塞的代价:
- 情况1:两个发送方和一个有无穷大缓存的路由器,两个发送方的发送速率大于链路传输速率,会导致拥塞,
- 情况2:因为路由器缓存不足,或者是因为发送了不必要的重传
- 情况3,分组被丢失时,传输该分组的所有上游路由器都做无用功了。
拥塞控制方法
- 端到端拥塞控制(只靠TCP,不靠IP层),TCP协议用的这个。
- 网络辅助的拥塞控制(路由器可以发送拥塞状态的反馈信息)
TCP拥塞控制
三个问题:
如何限制发送流量的速率
发送方有一个拥塞窗口cwnd可以限制发送流量的效率,接收方有一个接收窗口rwnd(流量控制)。
1
LastByteSent - LastByteAcked <= min{cwnd, rwnd}
如何感知拥塞情况:超时,3个冗余ACK。
如何改变发送速率
- 丢包意味着阻塞,需要减少拥塞窗口
- ACK包的到达意味着网络不拥塞,可以增加拥塞窗口
TCP 拥塞控制算法
慢启动、拥塞避免、快速恢复(第三点只是推荐)
慢启动
连接开始时:cwnd为一个较小值,假设这个值为一个MSS=500字节,RTT=200ms,那么初始发送速率为MSS/RTT = 500 * 5 = 2.5kBps = 20kbps
。每当 传输的报文段首次被确认就增加 l 个 MSS,每过一个rtt,拥塞窗口就会翻倍。
这种指数增长何时停止呢:
- 如果出现超时导致的丢包事件,发送方将cwnd设置为1并重新开始慢启动,他还将第二个状态变量ssthresh(慢启动阈值)的值设置为cwnd/2.
- 当cwnd等于ssthresh时,结束慢启动并转移到拥塞避免模式。
- 如果检测到三个冗余ACK, TCP执行快速重传并进入快速恢复状态。

可以看出**
ssthresh
的值只有一种(初始的64除外),就是cwnd/2
**,他是会导致系统拥塞的窗口值cwnd
的一半,当下次的cwnd
超过ssthresh
时,为了避免上次的拥塞重现,cwnd
就不能翻倍了,必须离开慢启动状态。
TCP分岔:优化云服务器的性能
当用户向远程服务器请求内容时,并且距离服务器太远,那么RTT会很大,TCP慢启动会导致低劣的性能。如果请求的数据不是太多,那么cwnd维持在很小的值。
改善的途径是:
- 部署临近用户的前端服务器
- 在该前端服务器使用TCP分岔,该前端服务器与远程服务器之间维护一条TCP连接,可以避免低速的慢启动过程。
拥塞避免
每个RTT只将cwnd 的值增加一个MSS
快速恢复
对收到的每个冗余的 ACK, cwnd 的值增加一个 MSS。
- 当对丢失报文段的一个 ACK 到达时, TCP 在降低 cwnd 后进入拥塞避免状态。
- 如果出现超时事件,快速恢复迁移到慢启动状态:
TCP拥塞控制:回顾
对TCP吞吐量的宏观描述
假设在连接持续期间 RTT和 W几乎不变` 那么TCP的传输 速率在W/(2 x RTT) 到 W/RTT 之间变化。
公平性
比如2条TCP连接,通过一条速率为R的链路,两条连接都能使用相同的链路带宽吗?
在理想情况下:链路只有TCP, 两条连接MSS和RTT相同,忽略慢启动。如下图,原点45的直线上是公平的。假设初始时处于最不公平的A点,那么两条连接会按照加法增加,到达B,超过阈值后按照乘法减少,变为C,最终不断逼近原点45的直线。

但实际情况中,RTT小的连接会快速增长,抢到更多带宽。
明确拥塞通告:网络辅助拥塞控制

网络层:数据平面
数据平面:负责转发包,控制层面:负责控制路由方式。
DHCP
四个步骤:
- DHCP 服务器发现:DHCP客户向广播地址发DHCP发现报文
- DHCP服务器提供,DHCP服务器(可能有多个)向DHCP客户回复IP地址、有效时间等。
- DHCP请求,DHCP客户从服务器中选一个,发配置信息发给DHCP服务器进行确认
- DHCP ACK, 服务器进行响应。
为了防止向有人往局域网上发送恶意分组,可以使用两种流行的防御措施:
- 防火墙,可以禁止ICMP,UDP等。
- 入侵检测系统(IDS),不仅检查首部字段,还要检查载荷。
网络层:控制平面
路由选择算法
- 集中式路由选择算法,需要以所有节点之间的连接性以及开销为输入,又叫链路状态算法。
- 分散式路由算法,路由器仅与相邻节点进行信息交换,逐渐计算到达目的地的最低开销路径。距离向量(DV)算法是分散式路由选择算法。
链路状态路由选择算法
此处介绍Dijkstra
算法,
可以看看这个图最短路径算法之迪杰斯特拉算法
距离向量路由选择算法
dx(y) = minv{c(x,v) + dv(y)}
缺点:路由选择算法传播慢,解决方法:毒性逆转。
链路开销改变
- 某一链路开销减少,可以迅速传播
- 某一链路开销增大,需要经过很多次迭代。

毒性逆转
假如z从x,y获取信息,更新路由表,然后将表中的信息发送给附近的路由器。更加z的路由表,到达x节点需要经过y节点,那么发给y节点和非y节点的信息是不同的:
- 发给y节点的信息,会将x到z的距离设为无穷大
- 发给非y节点的信息,就是正常的路由信息
LS和DV的比较
自治系统内部的路由选择:OSPF
某些一级ISP在其整个网络中使用一个庞大的 AS(自治系统), 而其他ISP则将它们的 ISP拆分为数十 个互联的AS。 在一个自治系 统内运行的路由选择算法叫作自治系统内部路由选择协议。
开放最短路优先(OSPF)
OSPF 路由选择及其关系密切的协议 IS-IS 都被广泛用千因特网的 AS 内部路由选择。
OSPF是一种链路状态协议,它使用洪泛链路状态信息和 Dijkstra 最低开销路径算法。
ISP之间的路由选择:BGP
在因特网中,所有的AS运行相同的AS 间路由选择协议,称为边界网关协议。(还有很多内容没讲,感觉也没必要看那么细致)
ICMP:因特网控制报文协议
ICMP用来沟通网络层的信息,运行HTTP会话时,出现的“目的网络不可达”就会由路由器给源主机发这样的ICMP消息。
Traceroute 是用 ICMP报文(被网络策略禁止了也可以用UDP)来实现的,Traceroute 向目的主机发送一系列IP数据报。 这些数据报的携带了一个具有不可达UDP端口号的UDP报文段。 第一个数据报的TTL为 1,第二个的TTL为2, 第三个的 TTL 为3’依次类推。 当第n个数据报到达第n台路由器时,第n 台路由 器观察到这个数据报的’ITL正好过期。 根据IP协议规则,路由器丢弃该数据报并发送 一个ICMP告警报文给源主机(类型 11 编码0)。 该告警报文包含了路由器的名字和它 的 IP 地址。 当该ICMP报文返回源主机时,源主机从定时器得到往返时延,从ICMP报 文中得到第n台路由器的名字与IP地址。
差错检测与纠正
假设保护的数据包括上层的数据、链路帧首部的地址、序号,定义为D。然后是差错检测和纠正比特EDC。到达接收节点后,他们变成了D‘和EDC’。接收方的挑战是只根据这两个,判断D’是否与初始的D相同。

三种方法:奇偶校验、校验与方法、循环冗余校验
奇偶校验
发送一个额外的比特,使得所有数据的和为奇数或者偶数。
校验和方法
先取反后相加与先相加后取反,得到的结果是一样的。因此实现代码都是先相加,最后再取反。
- 发送方:原码相加 ,并将高位叠加到低位,取反 ,得到反码求和结果,放入校验和
- 接收方:将所有原码 相加,高位叠加, 如全为1,则正确
TCP和UDP中常用。
循环冗余校验
发送方接收方先协商一个r+1比特的多项式,然后再D后面加上r比特数字,使得整个数字能够整除协商的多项式。

为什么主机和路由器除了IP地址外,还需要MAC地址。
- 保持各层独立。网络层不仅仅有IP协议,还有其他协议比如IPX。
- 灵活性:IP 地址是逻辑地址,可以动态分配和变更,而 MAC 地址是物理地址,固定在硬件中。
地址解析协议
将IP地址变为MAC地址。
原书326页给出了网络是如何连接的的详细过程
计算机网络中的安全
安全是什么:
- 两者的通话内容不能被别人看
- 不能有第三方假冒某一者进行通话
- 两者的通话内容不能被别人改
我们能够指出安全通信有如下特性:
- 机密性
- 报文完整性
- 端点鉴别
- 运行安全性
加密
RSA
报文完整和数字签名
散列函数
就是哈希函数吧,不同的输入对应不同的输入(找到不同的输入,使输出相同几乎是不可能的)。
比如MD5、SHA-1。
报文鉴别码
A生成一个报文m,计算散列H(m),生成一个拓展报文(m, H(m)), 将该包发给B,B再次计算H(m) 看它是否等于A传递过来的H(m)。但这有个很明显的缺点,散列H是公开的,任何人都可以给B发送符合的消息。
所以A、B之间还需要共享一个密钥s,计算散列时也要计算这个密钥的。H(m+s)被称为报文鉴别码(MAC)。
数字签名
数字签名也应当以可鉴别的、不可伪造的方式进行。
假如使用对称加密(加密和解密时使用相同的密钥),那么接收方必须获得发送方的密钥才能解密,但发送方如何安全的把自己的密钥发出来。
假如使用非对称加密,能达到效果。为了节约时间,可以直接对散列签名加密。

端点鉴别
安全电子邮件
为了实现机密性,可以使用对称密钥,但如何安全的分发必要给对方是个问题,可以使用非对称密钥先将对称密钥发给对方,之后的连接才开始用对称密钥。(这样可以兼顾安全和效率)

为了保证报文完整和实现发送方鉴别,需要使用数字签名和报文摘要。


完整过程:

但这里两者都需要对方的公钥,需要通过CA验证该公钥。
为什么需要使用两者的公钥私钥?因为既要证明Alice是Alice,又要证明Bob是Bob。这个邮件只能被Bob读,并且让Bob能相信Alice是Alice。(非对称加密将安全性的保证转移到了CA上)
使TCP连接安全:SSL
宏观描述
有三个阶段:握手、密钥导出、数据传输。
我们现在描述针对一个客户 (Bob) 和一个服务器 (Alice) 之间的 通信会话的这三个阶段、其中 Alice 具有私钥/公钥对和将她的身份与其公钥绑定的 证书。
握手,在握手阶段,Bob需要:①与 Alice创建一条TCP连接;②验证Alice 是真实的 Alice; ③发送给Alice 一个主密钥、 Bob 和 Alice 待用该主密钥生成 SSL 会话所需的所有对称密
密钥导出,为了更安全,使用更多的密钥:
- EB, 用于从 Bob 发送到 Alice 的数据的会话加密密钥
- MB, 用于从 Bob 发送到 Alice 的数据的会话 MAC 密钥
- EA,用于从Alice 发送到 Bob 的数据的会话加密密钥
- MA,用于从 Alice 发送到 Bob 的数据的会话MAC 密钥
两个加密密钥将用于加密数据;两个MAC 密钥将用于验证数据的完整性
数据传输:SSL将数据流 分割成记录,对每个记录附加一个MAC用于完整性检查,然后加密该“记录+MAC”。 为 了产生这个MAC, Bob将数据连同密钥MB放入一个散列函数中,如在8.3 节所讨论。 为 了加密”记录+MAC” 这个包, Bob使用他的会话加密密钥 EB 然后这个加密的包将传 递给TCP经因特网传输。
看起来很完整了,但TCP序号并没有加密,可能被中间人更改两个包的序号。所以计算散列函数时,还需要加上一个递增的序号。
更完整的描述
网络层安全性:IPsec和虚拟专用网(VPN)
匿名与隐私
如果访问一个有争议的网站,并且想该网站不泄露你的IP, 本地ISP不知道你在访问该网站,本地ISP不知道你访问的内容。
可以使用可信代理服务器+SSL的组合,SSL避免了被别人查看内容,可信代理服务器隐藏了你的IP以及你要访问的网站的IP。
多媒体网络
这本书写的挺好的,之后有空可以看看。