网络层设备-路由器-实现
网络层的设计
路由器-有网络层,物理层,数据链路层的功能
路由算法
最优路径的每一段也是最优路径,不然我可以找到一条更短的总路径
汇聚树-从所有源头节点到一个目标节点的最优路径的集合
路由节点只要保存下一跳就可以
迪杰斯特拉算法
参见B站枫叶的视频
泛洪算法
在不知道拓扑结构的情况下
只要有一个新数据包
就立刻复制很多份
然后分发给每一个你认识的路由器
这样肯定能到目标但是非常浪费流量
优化 限制传递次数/不转发发过的数据包
动态路由算法
距离矢量算法
我只读取我邻居告诉我的距离
每个路由器维护的路由表:
目的地 | 下一跳 | 距离
-------+--------+------
A | B | 5
C | D | 3
问题是可能出现环路
比如
A --- B --- D
| |
C --- E
我们关注目的地为a
| 节点 | 到A的最佳路径 | 距离 | 下一跳 |
|---|---|---|---|
| A | 直接连接 | 0 | - |
| B | A → B | 1 | A |
| C | A → B → C | 2 | B |
| D | A → B → D | 2 | B |
| E | A → B → D → E | 3 | D |
但是假如a-b断了
b为了更新表去询问c和d,
-
C认为到A的路径是 C → B → A
-
D认为到A的路径是 D → B → A
-
但B知道到A的链路已经断了!
B心想:
-
通过C到A:代价 = B到C(1) + C到A(2) = 3
-
通过D到A:代价 = B到D(1) + D到A(2) = 3
现在路由表变成:
| 节点 | 到A的路径 | 距离 | 下一跳 |
|---|---|---|---|
| B | B → C → ?→A | 3 | C |
| C | C → B → ?→A | 2 | B |
环路出现了:
-
B认为:要到A,先发给C
-
C认为:要到A,先发给B
-
数据包就在 B ↔ C 之间来回传递!
这是因为部分节点(比如CD)不知道变化
链路状态路由算法
每个路由器都有全局网络拓扑图
每个路由器先认识直接连接的邻居路由器。
然后给邻居发送自己的链路状态
每个路由器收集所有信息,画出完整的网络连接图。找最短路由
但是容易数量爆炸
层次路由
划分成小区域,小区域内有完整路由,区域之间简单由几个路由转发就行
广播路由
为了给所有用户广播一条消息,采用接力赛的方式
树-链路状态 知道整个地图
-
广播源发出消息
-
每个路由器收到消息后:
-
查看网络地图,找到以广播源为根的"传递树"
-
如果自己在这棵树上,就继续传递给"下游"的路由器
-
如果自己不在传递路径上,就安静地听着
-
逆向路径-链路 只知道怎么到目的地
只相信正确方向来的信息
我们知道消息源,知道最短路,只相信最短路来的消息
组播路由
只发给`特定的一组人
树-链路状态 知道整个地图
对树进行剪枝
逆向路径-链路 只知道怎么到目的地
转发+剪枝
先构造树,再剪枝
网络:
源(S) --- A --- B --- C
| |
D E
组播组G的成员:C、E
-
s先广播,
-
所有路由器用逆向路径转发:
-
检查数据是否从"到S的最短路径"传来
-
如果是,就转发给所有其他邻居
-
场景:路由器B
-
直接连接的主机:没有组G成员
-
下游路由器:C说"我要组G",但E说"我不要"
-
B的行动: 不向E发送组播数据
场景:路由器D
-
直接连接的主机:没有组G成员
-
下游路由器:没有其他路由器
-
D的行动: 向上游A发送"剪枝请求":"别给我发组G的数据了!"
场景:路由器A
-
收到来自D的剪枝请求
-
检查自己:
-
直接连接的主机:没有组G成员
-
下游路由器:B还需要组G数据(因为C要)
-
-
A的行动: 继续向B转发,但停止向D转发
但是组播路由导致转发状态爆炸,核心选择困难
一般采用放射状结构,尽力生成最小代价树
这是一个np难问题
选播路由
将数据发送到一组服务器中最近的一个
迪杰斯特拉/直接拿树
移动主机路由
移动主机告诉家乡代理我在哪
家乡代理把应该给我的数据包转发给我
我直接返回自己的新ip给对方
后续直接发给我的新ip
ADHOC路由
人传人,对自己听到的消息进行扩散
泛洪成功后建立回传路径,开始通信
每台主机一移动就忘记和他相关的路
拥塞控制
可能是传输层/网络层/资源问题
1.提高网络供给
2.流量感知路由
3.分时段规划
4.准入控制
5.放弃负载
服务质量
流量整形
漏桶算法
数据包 → 漏桶 → 以恒定速率流出
特点:
-
不管输入多快,输出速度恒定
-
消除所有突发流量
-
简单但可能不够灵活
令牌桶算法
令牌以固定速率产生
数据包需要拿到"令牌"才能发送
桶里可以积累一些令牌应对突发
特点:
-
平均速率受限
-
但允许短期突发
-
更符合实际应用需求
包调度和准入控制
FFIO 优先级队列 加权公平队列
准入控制负责检测是否有足够资源
资源预留协议RSVP专门用来在路径上的所有路由器上预留资源,由接收方发动
网络互连
由于协议太复杂了,我们一般不做协议之间的转换
直接把整个数据打包进新的协议
不同协议之间数据包大小有区别,所以我们入口服务器就把数据分段,记录偏移位置和后面是否有统一个包的数据
Internet网络层
IPV4
| 字段 | 位数 | 功能说明 | 实际应用 |
|---|---|---|---|
| 版本 | 4 | 协议版本标识 | IPv4=4, IPv6=6 |
| 头长度 | 4 | 头部总长度(×4字节) | 最小值5(20字节),最大值15(60字节) |
| 区分服务 | 8 | QoS服务类型 | 前6位DSCP,后2位ECN |
| 总长度 | 16 | 整个数据包长度 | 最大65535字节 |
| 标识 | 16 | 数据包唯一标识 | 分段时所有子包继承相同ID |
分段相关字段
| 字段 | 位数 | 功能说明 |
|---|---|---|
| DF | 1 | 禁止分段(Don't Fragment) |
| MF | 1 | 更多分段(More Fragments) |
| 分段偏移 | 13 | 数据在原始包中的位置(×8字节) |
路由相关字段
| 字段 | 位数 | 功能说明 |
|---|---|---|
| TTL | 8 | 生存时间(跳数或秒) |
| 协议 | 8 | 上层协议类型(TCP=6, UDP=17) |
| 头校验和 | 16 | 头部完整性校验 |
| 字段 | 位数 | 功能说明 |
| 源地址 | 32 | 发送方的IP地址 |
| 目标地址 | 32 | 接收方的IP地址 |
| 选项 | 0~40 | 用于可选择的功能 |
|---|
不保证交付,不保证顺序,不保证不重复
IP地址
IP地址 = 网络号 + 主机号
例:192.168.1.100 = 192.168.1.0(网络) + 100(主机)
几个特殊的地址:
00000000 00000000 00000000 00000000 本机
00000000 00000000 00000000 xxxxxxxx 本地网络
11111111 11111111 11111111 11111111 本地网络广播
xxxxxxxx xxxxxxxx xxxxxxxx 11111111 向某个网络广播
01111111 xxxxxxxx xxxxxxxx xxxxxxxx 回环测试,数据包不离开本机,直接返回
子网掩码
用于声明IP地址中网络前缀的长度(前多少位为网络号)。
IP地址与子网掩码"按位与",就得到IP地址所在的网络。通常一个网络使用主机全0表示。
IP地址:192.168.1.100 11000000.10101000.00000001.01100100
子网掩码:255.255.255.0 11111111.11111111.11111111.00000000
|←---网络部分--→|←---主机部分→|
网络地址:192.168.1.0 11000000.10101000.00000001.00000000
传统:192.168.1.0 255.255.255.0
CIDR:192.168.1.0/24
解释:
/24 = 前24位是网络号
255.255.255.0 = 24个1 + 8个0
同一网络内的设备前24位必须一样,比如192.168.1,最后八位可以不同
否则依靠路由器转发
子网划分
如果一个网络内有超大量主机,则划分为小网络
举个例子
原始网络:192.168.0.0/16
需要划分:4个子网
每个子网:至少1000台主机
原始主机位:16位(65534台主机)
需要子网数:4个 → 需要2位(2²=4)
剩余主机位:14位(16382台主机/子网)✓
原始:255.255.0.0 = /16
新子网掩码:255.255.192.0 = /18
划分得到
子网1:192.168.0.0/18 范围:192.168.0.1 - 192.168.63.254
子网2:192.168.64.0/18 范围:192.168.64.1 - 192.168.127.254
子网3:192.168.128.0/18 范围:192.168.128.1 - 192.168.191.254
子网4:192.168.192.0/18 范围:192.168.192.1 - 192.168.255.254
NAT
使用私有地址内部,共享公有地址外部
端口号用于区分内部主机
比如我的电脑使用端口54321
路由器
-
内网接口IP:
192.168.1.1 -
公网接口IP:
203.0.113.5
路由器建立映射
|-----------------------|---------------------|
| 内部私有IP:端口 | 映射到的公网IP:端口 |
| 192.168.1.100:54321 | 203.0.113.5:10240 |
网站服务器收到这个包,并准备回复。它看到的请求来自 203.0.113.5:10240,所以它会向这个地址回包。
路由器收到之后,转发给54321端口
IPV6
-
Pv4地址 :32位,约43亿个。
192.168.1.1 -
IPv6地址 :128位,数量是2的128次方。这是一个天文数字,足以让地球上的每一粒沙子都分配一个IP地址。例如:
2001:0db8:85a3:0000:0000:8a2e:0370:7334 -
基础头部:固定为40字节,字段数量减少,结构规整。这使得路由器的数据包转发效率更高,实现了"简化协议"和"减少路由表大小"的目标(更清晰的路由聚合)。
IP协议族
在同一个局域网内
ARP
广播自己手里的目标ip,等待目标设备回复
DHCP
自动为设备分配IP地址、子网掩码、网关、DNS服务器等网络配置
IP层
ICMP
传递网络控制和错误消息
路由协议
OSPF-开放最短路优先
-
每个路由器都把自己连接的邻居和链路成本(带宽、延迟等)广播给AS内的所有其他路由器。
-
这样,每个路由器都有一张完整的内部网络地图。
-
然后使用Dijkstra(最短路径)算法计算出到所有目的地的最佳路径。
BGP - 边界网关协议
再不同的系统之间交换信息,用特定的策略来规划,不一定是最短路,找加权最短路
流量工程协议
MPLS-多标签交换
-
在进入MPLS网络时,给数据包打上一个标签。
-
网络中的路由器只看这个简单的标签来决定下一跳,而不用分析复杂的IP头。
-
离开MPLS网络时,标签被移除。
IP多播
源主机只发送一份 数据,网络负责将其复制并传递给所有加入该组的成员。
移动IP
IP地址原本包含位置信息 (网络部分)和身份信息(主机部分)。但当主机移动时,就产生了矛盾:
-
如果改变IP,所有现有连接都会中断
-
如果不改变IP,路由无法正确送达
移动ip包括
-
移动节点:可以改变网络连接点的主机
-
家乡代理:在移动节点家乡网络中的路由器
-
外地代理:在移动节点当前所在网络中的路由器
详见上文