1.路由
2.路由选择算法
3.Link State
1.路由
csharp
复制代码
路由表示按照某种指标(传输延迟, 所经过的站点数目等)找到从源节点到目标节点的较好路径
注: "节点表示源子网所在的路由器"
a.较好路径: 按照某种指标较小的路径
b.指标: 站数, 延迟, 费用, 队列长度等
c.采用什么样的指标表示网络使用者希望网络在什么方面表现突出, 什么指标网络使用者比较重视
csharp
复制代码
a.以网络为单位进行路由, 以网络到网络的路由等价于网络对应的路由器到其他网络对应的路由器之间的路由(到了这个路由
器就是到了这个网络)
b.路由选择算法是网络层软件的一部分, 完成路由功能
c.分析"到了这个路由器就是到了这个网络"? 路由器是连接不同网络的设备, "路由器定义了一个网络的逻辑边界"; 在IP路
由层面, 数据包只要被交付给了目标网络所关联的路由器, 就等于进入了该网络
- 将网络比作一个小区
- 路由器就相当于小区的门卫/大门
2.路由选择算法
csharp
复制代码
1).网络的图抽象
csharp
复制代码
a.c(x, x') = 链路的代价 (x, x'), 比如: c(w, z) = 5
b.Cost of path (x1 , x2 , x3 ,..., xp ) = c(x1 ,x2 ) + c(x2 ,x3 ) + ... + c(xp-1 ,xp )
c.路由的输入: "拓扑, 边的代价, 源节点"; 输出: "源节点的汇集树"
csharp
复制代码
2).汇集树(sink tree): 对于同一个目的节点, 网络中的所有节点到该目的节点的最优路径构成了一棵树
路由选择算法的目标是"确定从源节点到目的节点的最佳路径"
csharp
复制代码
3).路由选择算法的原则
a.正确性(correctness)
- 算法必须是正确的和完整的, 使分组一站一站接力, 正确发向目标站
- 完整: 目标所有的站地址, 在路由表中都能找到相应的表项; 没有处理不了的目标站地址
b.简单性(simplicity)
- 算法在计算机上应简单最优但复杂的算法, 时间上延迟很大, 不实用, 不应为了获取路由信息增加很多的通信量
c.健壮性(robustness)
- 算法应能适应通信量和网络拓扑的变化, 通信量变化, 网络拓扑的变化算法能很快适应; 不向很拥挤的链路发数据, 不向
断了的链路发送数据
d.稳定性(stability)
产生的路由不应该摇摆
e.公平性(fairness)
对每一个站点都公平
f.最优性(optimality)
某一个指标的最优, 比如: 时间, 费用等指标
csharp
复制代码
4).路由算法分类
a.按运行方式分类
- 静态: 路由随时间变化缓慢
- 动态: 路由变化很快, 周期性更新; 根据链路代价的变化而变化
非自适应算法(non-adaptive algorithm): 不能适应网络拓扑和通信量的变化, 路由表是事先计算好的
自适应路由算法(adaptive algorithm): 能适应网络拓扑和通信量的变化
b.按计算方式分类: 全局和分布式算法
3.Link State
csharp
复制代码
Link State是全局式路由算法, 核心思想:
"每个路由器都知晓整个网络的拓扑结构和链路费用, 然后独立地计算出到达所有目的地的最短路径"
csharp
复制代码
1).发现相邻节点, 获知对方网络地址
a.一个路由器上电之后, 向所有线路发送HELLO分组
b.其它路由器收到HELLO分组, 回送应答, 在应答分组中, 告知自己的名字(全局唯一)
c.在LAN中, 通过广播HELLO分组, 获得其它路由器的信息
csharp
复制代码
2).测量到相邻节点的代价(延迟, 开销)
a.实测法, 发送一个分组要求对方立即响应
b.回送一个ECHO分组
c.通过测量时间可以估算出延迟情况
3).组装一个LS分组, 描述它到相邻节点的代价
a.发送者名称
b.序号, 年龄
c.列表: 给出它相邻节点, 和它到相邻节点的延迟
csharp
复制代码
4).将分组通过扩散("泛洪")的方法发到所有其它路由器
a.泛洪是一种网络数据包传输技术, 当一个路由器收到一个数据包后, 它会将这个数据包从除了接收这个数据包的那个接口之
外的所有其它接口都发送出去
b.扩散分组的数据结构
- Source: 从哪个节点收到LS分组
- Seq, Age: 序号,年龄
- Send flags: 发送标记, 必须向指定的哪些相邻站点转发LS分组
- ACK flags: 本站点必须向哪些相邻站点发送应答
- DATA: 来自source站点的LS分组
5).通过Dijkstra("迪杰斯特拉")算法找出最短路径
a.路由器获得各站点LS分组和整个网络的拓扑
b.通过Dijkstra算法计算出到其它各路由器的最短路径
c.将计算结果安装到路由表中
csharp
复制代码
序号用于解决重复接收和循环泛洪
a.问题描述: 一个路由器可能会从不同的接口, 多次收到同一个LSA
b.发生原因: 泛洪的规则是"从所有接口转发, 除了收到该LSA的那个接口"; 在一个网状网络中, 这很容易形成临时的环路,
导致同一个LSA在路由器之间来回传递
c.例子: 路由器A发出一个LSA, 发给B和C; B收到后转发给C和D, C收到后也转发给B和D; 于是, B和C都会从对方那里再次收
到这个自己已经处理过的LSA
d.解决方案: "序列号"
每个LSA都带有一个唯一的、不断递增的序列号; 当路由器收到一个LSA时, 它会检查序列号; 如果这个序列号小于或等于
自己数据库中已有的该LSA的序列号, 它就丢弃这个LSA, 并不再转发; 这从根本上避免了循环和重复处理
csharp
复制代码
问题一: 如何清理"僵尸"LSA?
a.场景: 假设路由器A发出了一个LSA, 然后突然断电崩溃了; 它发出的这个LSA还存在于其他所有路由器的数据库中, 由于A
已经崩溃, 它无法再发出一个新的LSA来声明"我之前发的作废了"; 这个"已死"的LSA就会一直留在大家的数据库里, 成为一个
僵尸LSA, 可能导致错误的路由
b.解决方案: 年龄到期
任何一个持有这个LSA的路由器, 都会不断地在泛洪过程中增加它的Age值; 最终, 当这个LSA的Age达到MaxAge(3600秒)时,
路由器会执行一次特殊的"泛洪"; 这次泛洪不是为了传播信息, 而是为了"通知所有人, 这个LSA过期了, 请立即删除"; 收到
Age = MaxAge的LSA后, 所有路由器都会将它从自己的数据库中清除
这就相当于一个自动的"垃圾回收"机制, 确保了任何LSA都不会在网络中永久存在
问题二: 如何让重启的路由器快速同步?
a.场景: 路由器A重启了, 它不记得自己崩溃前使用的序列号是多少了; 如果它从一个很低的序列号(比如0)开始发送LSA, 其
他路由器会因为拥有序列号更高的"旧"LSA而认为A发来的是过时信息, 从而忽略它, A就被"孤立"了
b.解决方案: 提前让旧LSA过期
- 在A重启后, 它不会立刻发出自己的LSA, 它会先等待, 听一下邻居的信息
- 同时, 在A重启的瞬间, 网络中原本属于A的那些旧LSA还在, 并且它们的Age还在不断增长
- 当A的邻居发现与A的连接恢复后, 它们会主动将自己数据库中属于A的且Age已经很大的LSA, 以Age = MaxAge的形式泛洪
回来, 目的是"询问A, 这个信息现在还有效吗?"
- A收到这个"过期"的LSA后, 就能意识到: "哦,这是关于我自己的旧信息,网络正在问我最新情况"; 于是, A就可以用一个
全新的序列号发出最新的LSA来回应
这样, A就顺利地重新加入了网络, 而不会因为序列号混淆而被孤立
csharp
复制代码
- 任何一个路由器, 只要它的链路状态数据库里存储着一份LSA, 这份LSA的Age字段就会随着系统时钟的滴答声而每秒自动增
加1
- 当路由器需要转发一个LSA时(即执行泛洪操作), 在将LSA放入发出去的数据包之前, 它会先把这个LSA的Age值增加一个特
定的量
csharp
复制代码
LS路由选择算法(迪杰斯特拉算法)的工作原理:
a.节点标记: 每一个节点使用(D(v), p(v)) 如:(3, B)标记
- D(v)从源节点到达本节点的最优距离
- P(v)前序节点来标注
b.2类节点
- 临时节点(tentative node): 还没有找到从源节点到此节点的最优路径的节点
- 永久节点(permanent node)N': 已经找到了从源节点到此节点的最优路径的节点
c.初始化
- 除了源节点外, 所有节点都为临时节点
- 节点代价除了与源节点代价相邻的节点外, 都为∞
d.从所有临时节点中找到一个节点代价最小的临时节点, 将之变成永久节点(当前节点)
e.对此节点的所有在临时节点集合中的邻节点(V)
- 如D(v) > D(w) + c(w,v), 则重新标注此点, (D(W) + C(W,V), W)
- 否则, 不重新标注
f.开始一个新的循环
csharp
复制代码
a.当前节点更新完毕邻近的代价值后, 从队列中寻找代价最小的节点
b."直到待处理节点集合为空, 才会停止"