aodv路由协议分析
1?AODV?報文格式
AODV?有三種基本的協議報文類型:RREQ?報文、RREP?報文和RRER?報文。
1.1?RREQ?報文
a.?對RREQ?的處理
接收到RREQ?的結點做如下處理:
(1)創建一個表項,先不分配有效序列號,用于記錄反向路徑。
(2)如果在“路由發現定時”內已收到一個具有相同標識的RREQ?報文,則拋棄該報文,不做任何處理;否則,對該表項進行更新如下:
I.下一跳結點=廣播RREQ?的鄰居。
II.跳數=RREQ?報文的“跳計數”字段值。
III.設置表項的“過時計時器”。
(3)如果滿足以下條件,則結點產生“路由回答報文”RREP,并發送到信源;否則更新RREQ?報文并廣播更新后的RREQ?報文。
I.該結點是信宿。
II.結點的路由表中有到信宿的活動表項,且表項的信宿序列號大于RREQ中的信宿序列號。
(4)更新RREQ?報文并廣播更新后的RREQ?報文
I.信宿序列號=本結點收到的信宿相關的最大序列號。
II.跳計數加1。
1.2?RREP?報文
(1)信宿結點產生RREP
執行如下操作:
I.如果收到相應的RREQ?的信宿序列號與信宿維護的當前序列號相等,則信宿將自己維護的序列號加1,否則不變。
II.跳計數=0。
III.定時器值。
(2)中間結點產生的RREP
執行如下操作:
I.本結點獲取的該信宿的最大序列號。
II.跳計數=本結點到信宿的跳數(查相應表項即可得到)。
III.更新本結點維護的“前向路由表項”的下一跳和“反向路由表項”的前一跳
b.?對RREP?的處理
結點對接收到的RREP?作如下處理。
(1)如果沒有與RREP?報文中的信宿相匹配的表項,則先創建一個“前向路表”空表項。
(2)否則,滿足如下條件對已有表項進行更新。
條件:
I.現有表項的信宿序列號小于RREP?報文中的序列號。
II.現有的表項沒有激活。
III.信宿序列號相同,但RREP?報文的“跳計數”值小于表項相對應的值;通過更新或創建,產生一個新的前向路由。
更新:
IV.下一跳=廣播RREP?的鄰居結點。
V.信宿序列號=RREP?中的信宿序列號。
VI.跳計數加1。
(3)按照上述的過程,任何轉發RREP?的結點,都記錄了到信宿的下一跳,當RREP到達信源時。結點地址匹配,不再轉發RREP,信源到信宿的前向路由已經建立起來了。信源可以沿這條前向路徑進行數據傳輸。
1.3?RRER?報文
鄰居間周期性的互相廣播“Hello”報文,用來保持聯系,若在一段時間內沒有收到“Hello”報文,則認定為鏈路斷。例如當結點X、Y?之間鏈路產生斷路使數據無法通過此條鏈路傳至信宿,則結點X?會產生RRER?報文向信源報告此情況。RRER?通過廣播形式傳送,維護路由表的結點收到此報文會更新路由表(將X、Y
間的路由設成無效),并轉發RRER?報文。
2?協議從接收到一個分組開始的基本流程
AODV?路由協議主要包括以下幾個組件:
1、協議實體
2、路由表
3、定時器
(1)廣播定時器
(2)周期Hello?報文廣播定時器
(3)用于鄰居管理的定時器
(4)用于路由緩存的定時器
(5)用于本地修復的定時器
(6)緩存廣播ID?的定時器
4、日志記錄器
5、路由緩存隊列
當協議接收到一個分組,即recv(Packet*,?Handler*)函數被調用,函數根據分組類型調用不同的處理函數進行處理。
1、如果是協議分組,則將分組的ttl?值減1,并調用recvAODV(Packet*)函數進行處理。recvAODV?函數再根據分組的不同類型來調用不同的函數進行處理。
(1)如果接收到的是路由請求分組,則調用recvRequest(Packet*)函數進行處理。如果該分組由節點自身產生或已經接收過的,會被節點丟棄,并結束處理。否則,節點將緩存該分組的序列號,并將該分組發送來的路徑添加到反向路由中,轉發相應分組。然后,節點根據該分組的目的地址進行判斷并調用不同函數進行
處理。如果節點自身即為目的節點,則調用sendReply(nsaddr_t,?u_int32_t,nsaddr_t,?u_int32_t,?u_int32_t,?double)函數進行響應。如果節點不是目的節點,但知道通往目的節點的路由,則調用sendReply?函數進行響應,并在源和目的前驅列表中分別插入到源和目的的下一跳節點。否則,不能直接響應該請求,
將跳數加1,并調用forward(aodv_rt_entry*,?Packet*,?double)函數轉發該分組。在sendReply?函數中,節點首先查找到達目的節點(即發送路由請求分組的節點)的路由,創建并填充分組,然后調用Scheduler::instance().schedule()函數來發送該分組。
(2)如果接收到的是路由響應分組,則調用recvReply(Packet*)函數進行處理。節點首先查詢前往分組目的節點的路由,如果不存在則新增一條路由項。然后,節點更新到該目的節點的路由項,并發送所有相關分組。如果節點為目的節點則更新路由發現延遲并發送所有相關的分組。如果節點不是目的節點,但知道通往目的節點的路由,則將跳數加1,調用forward?函數轉發該分組,并修改響應的前驅列表。如果節點不是目的節點,也不知道通往目的節點的路由,則丟棄該分組。
(3)如果接收到的是路由錯誤分組,則調用recvError(Packet*)函數進行處理。
節點首先清除所有受到影響的路由項,丟棄所有受影響的分組。然后,如果前驅節點中存在會受該路由錯誤影響的分組,則調用sendError(Packet*,?bool)函數轉發該分組。sendError?函數創建并填充分組,?然后調用Scheduler::instance().schedule()函數來發送該分組。
(4)如果接收到的是Hello?消息分組,則調用recvHello(Packet*)函數進行處理。節點會將該鄰居的信息添加到鄰居列表中(或更新該鄰居的信息)。
2、如果是數據分組,則節點丟棄已經發送過或者ttl?為0?的分組,并結束處理。如果分組是由上層協議產生的,則節點添加IP?報頭。隨后,節點根據目的路由進行不同處理。
(1)如果目的節點路由未知,則調用rt_resolve(Packet*)函數進行路由解析和轉發。如果目的節點路由在路由表中存在,則直接調用forward?函數進行轉發。如果分組是由節點自身產生的,則將分組保存到緩沖隊列中,并調用sendRequest(nsaddr_t)函數查詢目的路由。如果目的路由已知,但正在進行本地修復,則將分組保存到緩沖隊列中。否則,丟棄該分組,并調用sendError?函數報錯。
(2)如果目的節點路由已知,則調用forward?進行轉發。節點丟棄ttl?為0?的分組,并根據分組類型決定下一步操作。如果接收到的是數據分組,且自身為目的節點,則通過調用PortClassifier?對象的recv(Packet*,?Handle*)函數將分組交遞給高層協議,?并結束處理。否則,?節點設置分組屬性,?并調用
Scheduler::instance().schedule?(Handler*,?Event*,?double)函數來發送分組。其中,Handler?為基類中的屬性target_(會根據腳本中的設置指向相應的協議實體),?Event?為要發送的分組即可。以上就是在節點收到分組后的一個處理過程。
以下是各個定時器所做的工作。
1、廣播定時器BroadcastTimer?在到時后調用id_purge()函數刪除廣播項中已超時的項目,并通過調用Scheduler::?instance().schedule()函數來設置下次被調用的時間(Handler?為this?指針,Event?為類屬性intr)。
2、周期Hello?報文廣播定時器HelloTimer?在到時后調用sendHello()函數向鄰居創建并發送Hello?消息,并調用schedule()函數來設置下次被調用的時間。
3、鄰居管理定時器NeighborTimer?在到時后調用nb_purge()函數來清除鄰居列表中已超時的鄰居項,并調用schedule()來設置下次被調用的時間。nb_purge會調用nt_delete(nsaddr_t)?函數來清除超時的鄰居項,?其又會調用handle_link_failure(nsaddr_t)函數來處理由于鄰居節點被刪除而引起的路由
變化。
4、路由緩存定時器RouteCacheTimer?在到時后調用rt_purge()函數來清除路由表中已超時的路由項,并丟棄相關的分組,再調用schedule()來設置下次被調用的時間。
5、本地修復定時器LocalRepairTimer?在調用后根據傳遞的分組的目的地址關閉相應的路由項。
6、緩存廣播ID?定時器BroadcastID?用來保存廣播分組的ID。
轉載于:https://www.cnblogs.com/yue-/archive/2012/04/23/6260090.html
總結
以上是生活随笔為你收集整理的aodv路由协议分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 黑苹果使用itlwm网卡驱动提示itlw
- 下一篇: 【例题 8-13 UVA - 11093