aodv協議尋路流程
阿新 • • 發佈:2018-11-28
當協議接收到一個分組,即recv(Packet*,Handler*)函式被呼叫,函式根據分組型別呼叫不同的處理函式進行處理。
void AODV::recv(Packet *p, Handler*) { struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); assert(initialized()); //如果分組型別是AODV型別,則交給recvAodv函式 if(ch->ptype() == PT_AODV) { ih->ttl_ -= 1; recvAODV(p);return; } /* 略 */ }
1、如果是協議分組,則將分組的ttl值減1,並呼叫recvAODV(Packet*)函式進行處理。recvAODV函式再根據分組的不同型別來呼叫不同的函式進行處理。
void AODV::recvAODV(Packet *p) { struct hdr_aodv *ah = HDR_AODV(p); assert(HDR_IP (p)->sport() == RT_PORT); assert(HDR_IP (p)->dport() == RT_PORT);View Code/* * Incoming Packets.傳入的資料包。 */ switch(ah->ah_type) {//根據包型別呼叫不同函式 case AODVTYPE_RREQ: recvRequest(p); break; case AODVTYPE_RREP: recvReply(p); break; case AODVTYPE_RERR: recvError(p); break; case AODVTYPE_HELLO: recvHello(p); break;default: fprintf(stderr, "Invalid AODV type (%x)\n", ah->ah_type); exit(1); } }
(1)如果接收到的是路由請求分組,則呼叫recvRequest(Packet*)函式進行處理。
1 void 2 AODV::recvRequest(Packet *p) { 3 struct hdr_ip *ih = HDR_IP(p); 4 struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p); 5 aodv_rt_entry *rt; 6 /*1,看該分組是否有自己產生*/ 7 if(rq->rq_src == index) { 8 Packet::free(p); 9 return; 10 } 11 12 /*2,如果已經收到了源地址和請求序列號相等的請求報文,丟棄*/ 13 if (id_lookup(rq->rq_src, rq->rq_bcast_id)) { 14 Packet::free(p); 15 return; 16 } 17 18 /*3,如果沒有收到過該分組,將收到的廣播分組存入broadcast中*/ 19 /*快取此路由請求*/ 20 id_insert(rq->rq_src, rq->rq_bcast_id); 21 /*4,建立反向路徑*/ 22 aodv_rt_entry *rt0; // rt0 is the reverse route rt0是反向路由 23 //查詢是否存在反向路由 24 rt0 = rtable.rt_lookup(rq->rq_src); 25 26 if(rt0 == 0) { 27 //如果不存在反向路由項,新建立反向路由 28 rt0 = rtable.rt_add(rq->rq_src); 29 } 30 //更新此路由條目的生存時間 31 rt0->rt_expire = max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE)); 32 // 如存在反向路由,判斷反向路由是否需要更新 33 if ( (rq->rq_src_seqno > rt0->rt_seqno ) ||//如果請求序列號大於路由序列號或者 34 ((rq->rq_src_seqno == rt0->rt_seqno) && //兩者序列號相等但是跳數比源路由跳數小,則更新 35 (rq->rq_hop_count < rt0->rt_hops)) ) { 36 /* 37 * 此處略 38 */ 39 } 40 // End for putting reverse route in rt table 在rt表中設定反向路由 41 42 43 /*5,轉發或處理該包*/ 44 45 /*在這種情況下我們有兩種選擇,一種是將RREQ繼續傳播下去,另一種是產生RREP.在這之前我們需要確定, 46 反向路由已經在路由表中存在。如果存在反向路由,在考慮是否應該向源節點發送RREP*/ 47 rt = rtable.rt_lookup(rq->rq_dst); // 判斷節點本身是否是路由請求分組的目的地址 48 49 50 if(rq->rq_dst == index) { //如果節點本身是目的節點地址,向源節點發送路由請求應答分組並且回收請求分組 51 52 seqno = max(seqno, rq->rq_dst_seqno)+1; 53 if (seqno%2) seqno++;// 如果目的節點序列號是奇數就將其變成偶數,保證目的節點序列號是偶數 54 55 56 sendReply(rq->rq_src, // IP Destination 57 1, // Hop Count 58 index, // Dest IP Address 59 seqno, // Dest Sequence Num 60 MY_ROUTE_TIMEOUT, // Lifetime 61 rq->rq_timestamp); // timestamp 62 63 Packet::free(p);//釋放RREQ ,產生RREP 64 } 65 //如果不是目的節點,但是有到目的節點的路徑,也傳送路由應答報文 66 else if (rt && (rt->rt_hops != INFINITY2) &&(rt->rt_seqno >= rq->rq_dst_seqno) ) {//保證夠新(目的節點序列號) 67 68 assert(rq->rq_dst == rt->rt_dst); 69 70 //向源節點發送路由應答分組 71 sendReply(rq->rq_src, 72 rt->rt_hops + 1, // 若是目的節點設成 1,這裡不是目的節點就在RREQ中的跳數加1 73 rq->rq_dst, //如果是目的節點這一項就是目的節點的IP地址(這個節點本身的地址)這裡是RREQ中的目的節點的IP地址 74 rt->rt_seqno, 75 (u_int32_t) (rt->rt_expire - CURRENT_TIME), 76 77 rq->rq_timestamp); 78 // Insert nexthops to RREQ source and RREQ destination in the 將nexthops插入到RREQ源和RREQ目的地 79 // precursor lists of destination and source respectively 分別位於的目的地和源的前體列表中 80 81 82 //更新正向路由和反向路由的前區列表 83 rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source 加入字首列表 84 rt0->pc_insert(rt->rt_nexthop); // nexthop to RREQ destination 加入字首列表 85 86 87 Packet::free(p); 88 } 89 //如果沒有到達目的節點足夠新的路由,繼續轉發路由請求分組 90 else { 91 ih->saddr() = index; 92 ih->daddr() = IP_BROADCAST; 93 rq->rq_hop_count += 1; 94 // Maximum sequence number seen en route 看到的最大的序列號 95 if (rt) rq->rq_dst_seqno = max(rt->rt_seqno, rq->rq_dst_seqno); 96 forward((aodv_rt_entry*) 0, p, DELAY); 97 } 98 }View Code2
2、forward
1 void 2 AODV::forward(aodv_rt_entry *rt, Packet *p, double delay) { 3 struct hdr_cmn *ch = HDR_CMN(p); 4 struct hdr_ip *ih = HDR_IP(p); 5 /*如果跳數為零,直接丟棄*/ 6 if(ih->ttl_ == 0) { //超時 7 drop(p, DROP_RTR_TTL); 8 return; 9 } 10 /*如果不是AODV型別資料包並且鏈路方向是上行並且是廣播包或者此節點就是目的地址*/ 11 if ((( ch->ptype() != PT_AODV && ch->direction() == hdr_cmn::UP ) && 12 ((u_int32_t)ih->daddr() == IP_BROADCAST)) 13 || (ih->daddr() == here_.addr_)) { 14 dmux_->recv(p,0);//交給分類器 15 return; 16 } 17 18 /*判斷是否有去忘目的地的路由,沒有那說明這是廣播*/ 19 if (rt) { //更新一些引數 20 assert(rt->rt_flags == RTF_UP); 21 rt->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT; 22 ch->next_hop_ = rt->rt_nexthop; 23 ch->addr_type() = NS_AF_INET; //代表分組需要經過單播路由到達目的地,需要呼叫arp; 24 ch->direction() = hdr_cmn::DOWN; //important: change the packet's direction 25 } 26 else { 27 28 assert(ih->daddr() == (nsaddr_t) IP_BROADCAST); 29 ch->addr_type() = NS_AF_NONE;//代表廣播報文 , NS_AF_ILINK代表不需要呼叫arp 30 ch->direction() = hdr_cmn::DOWN; // 鏈路方向下行 important: change the packet's direction 31 } 32 //如果該資料包是廣播包 33 if (ih->daddr() == (nsaddr_t) IP_BROADCAST) {//廣播報文 34 // If it is a broadcast packet 35 assert(rt == 0); 36 if (ch->ptype() == PT_AODV) { 37 /* 38 * Jitter the sending of AODV broadcast packets by 10ms 39 * Jitter傳送AODV廣播資料包10ms 40 */ 41 Scheduler::instance().schedule(target_, p, 42 0.01 * Random::uniform());//加入定時器 43 } else { //如果不是AODV型別 44 Scheduler::instance().schedule(target_, p, 0.); // No jitter 45 } 46 } 47 else { // Not a broadcast packet 非廣播報文 48 if(delay > 0.0) { 49 Scheduler::instance().schedule(target_, p, delay); 50 } 51 else { 52 // Not a broadcast packet, no delay, send immediately 立即傳送 53 Scheduler::instance().schedule(target_, p, 0.); 54 } 55 } 56 57 58 }View Code3