void
AODV::recvError(Packet *p) {
struct hdr_ip *ih = HDR_IP(p);
struct hdr_aodv_error *re = HDR_AODV_ERROR(p);
aodv_rt_entry *rt;
u_int8_t i;
Packet *rerr = Packet::alloc();
struct hdr_aodv_error *nre = HDR_AODV_ERROR(rerr);
nre->DestCount = 0;
//收到RERR,查看有哪些路径受到中断链路的影响,更新RERR内容,并向受影响的节点发送该RERR
for (i=0; i<re->DestCount; i++) {
// For each unreachable destination
rt = rtable.rt_lookup(re->unreachable_dst[i]);
if ( rt && (rt->rt_hops != INFINITY2) &&
(rt->rt_nexthop == ih->saddr()) &&
(rt->rt_seqno <= re->unreachable_dst_seqno[i]) ) {
assert(rt->rt_flags == RTF_UP);
assert((rt->rt_seqno%2) == 0); // is the seqno even?
#ifdef DEBUG
fprintf(stderr, "%s(%f): %d\t(%d\t%u\t%d)\t(%d\t%u\t%d)\n", __FUNCTION__,CURRENT_TIME,
index, rt->rt_dst, rt->rt_seqno, rt->rt_nexthop,
re->unreachable_dst[i],re->unreachable_dst_seqno[i],
ih->saddr());
#endif // DEBUG
rt->rt_seqno = re->unreachable_dst_seqno[i];
rt_down(rt);
// Not sure whether this is the right thing to do
Packet *pkt;
while((pkt = ifqueue->filter(ih->saddr()))) {
drop(pkt, DROP_RTR_MAC_CALLBACK);
}
// if precursor list non-empty add to RERR and delete the precursor list
if (!rt->pc_empty()) {
nre->unreachable_dst[nre->DestCount] = rt->rt_dst;
nre->unreachable_dst_seqno[nre->DestCount] = rt->rt_seqno;
nre->DestCount += 1;
rt->pc_delete();
}
}
}
if (nre->DestCount > 0) {
#ifdef DEBUG
fprintf(stderr, "%s(%f): %d\t sending RERR...\n", __FUNCTION__, CURRENT_TIME, index);
#endif // DEBUG
sendError(rerr);
}
else {
Packet::free(rerr);
}
Packet::free(p);
}
/*
Packet Transmission Routines
*/
AODV::recvError(Packet *p) {
struct hdr_ip *ih = HDR_IP(p);
struct hdr_aodv_error *re = HDR_AODV_ERROR(p);
aodv_rt_entry *rt;
u_int8_t i;
Packet *rerr = Packet::alloc();
struct hdr_aodv_error *nre = HDR_AODV_ERROR(rerr);
nre->DestCount = 0;
//收到RERR,查看有哪些路径受到中断链路的影响,更新RERR内容,并向受影响的节点发送该RERR
for (i=0; i<re->DestCount; i++) {
// For each unreachable destination
rt = rtable.rt_lookup(re->unreachable_dst[i]);
if ( rt && (rt->rt_hops != INFINITY2) &&
(rt->rt_nexthop == ih->saddr()) &&
(rt->rt_seqno <= re->unreachable_dst_seqno[i]) ) {
assert(rt->rt_flags == RTF_UP);
assert((rt->rt_seqno%2) == 0); // is the seqno even?
#ifdef DEBUG
fprintf(stderr, "%s(%f): %d\t(%d\t%u\t%d)\t(%d\t%u\t%d)\n", __FUNCTION__,CURRENT_TIME,
index, rt->rt_dst, rt->rt_seqno, rt->rt_nexthop,
re->unreachable_dst[i],re->unreachable_dst_seqno[i],
ih->saddr());
#endif // DEBUG
rt->rt_seqno = re->unreachable_dst_seqno[i];
rt_down(rt);
// Not sure whether this is the right thing to do
Packet *pkt;
while((pkt = ifqueue->filter(ih->saddr()))) {
drop(pkt, DROP_RTR_MAC_CALLBACK);
}
// if precursor list non-empty add to RERR and delete the precursor list
if (!rt->pc_empty()) {
nre->unreachable_dst[nre->DestCount] = rt->rt_dst;
nre->unreachable_dst_seqno[nre->DestCount] = rt->rt_seqno;
nre->DestCount += 1;
rt->pc_delete();
}
}
}
if (nre->DestCount > 0) {
#ifdef DEBUG
fprintf(stderr, "%s(%f): %d\t sending RERR...\n", __FUNCTION__, CURRENT_TIME, index);
#endif // DEBUG
sendError(rerr);
}
else {
Packet::free(rerr);
}
Packet::free(p);
}
/*
Packet Transmission Routines
*/