📄 aodv_rreq.c
字号:
this_host.seqno, rev_rt->dest_addr, MY_ROUTE_TIMEOUT); rrep_send(rrep, rev_rt, NULL, RREP_SIZE); } else { /* We are an INTERMEDIATE node. - check if we have an active * route entry */ fwd_rt = rt_table_find(rreq_dest); if (fwd_rt && fwd_rt->state == VALID && !rreq->d) { struct timeval now; u_int32_t lifetime; /* GENERATE RREP, i.e we have an ACTIVE route entry that is fresh enough (our destination sequence number for that route is larger than the one in the RREQ). */ gettimeofday(&now, NULL);#ifdef CONFIG_GATEWAY_DISABLED if (fwd_rt->flags & RT_INET_DEST) { rt_table_t *gw_rt; /* This node knows that this is a rreq for an Internet * destination and it has a valid route to the gateway */ goto forward; // DISABLED gw_rt = rt_table_find(fwd_rt->next_hop); if (!gw_rt || gw_rt->state == INVALID) goto forward; lifetime = timeval_diff(&gw_rt->rt_timer.timeout, &now); rrep = rrep_create(0, 0, gw_rt->hcnt, gw_rt->dest_addr, gw_rt->dest_seqno, rev_rt->dest_addr, lifetime); ext = rrep_add_ext(rrep, RREP_INET_DEST_EXT, rrep_size, sizeof(struct in_addr), (char *) &rreq_dest); rrep_size += AODV_EXT_SIZE(ext); DEBUG(LOG_DEBUG, 0, "Intermediate node response for INTERNET dest: %s rrep_size=%d", ip_to_str(rreq_dest), rrep_size); rrep_send(rrep, rev_rt, gw_rt, rrep_size); return; }#endif /* CONFIG_GATEWAY_DISABLED */ /* Respond only if the sequence number is fresh enough... */ if (fwd_rt->dest_seqno != 0 && (int32_t) fwd_rt->dest_seqno >= (int32_t) rreq_dest_seqno) { lifetime = timeval_diff(&fwd_rt->rt_timer.timeout, &now); rrep = rrep_create(0, 0, fwd_rt->hcnt, fwd_rt->dest_addr, fwd_rt->dest_seqno, rev_rt->dest_addr, lifetime); rrep_send(rrep, rev_rt, fwd_rt, rrep_size); } else { goto forward; } /* If the GRATUITOUS flag is set, we must also unicast a gratuitous RREP to the destination. */ if (rreq->g) { rrep = rrep_create(0, 0, rev_rt->hcnt, rev_rt->dest_addr, rev_rt->dest_seqno, fwd_rt->dest_addr, lifetime); rrep_send(rrep, fwd_rt, rev_rt, RREP_SIZE); DEBUG(LOG_INFO, 0, "Sending G-RREP to %s with rte to %s", ip_to_str(rreq_dest), ip_to_str(rreq_orig)); } return; } forward: if (ip_ttl > 1) { /* Update the sequence number in case the maintained one is * larger */ if (fwd_rt && !(fwd_rt->flags & RT_INET_DEST) && (int32_t) fwd_rt->dest_seqno > (int32_t) rreq_dest_seqno) rreq->dest_seqno = htonl(fwd_rt->dest_seqno); rreq_forward(rreq, rreqlen, --ip_ttl); } else { DEBUG(LOG_DEBUG, 0, "RREQ not forwarded - ttl=0"); } }}/* Perform route discovery for a unicast destination */void NS_CLASS rreq_route_discovery(struct in_addr dest_addr, u_int8_t flags, struct ip_data *ipd){ struct timeval now; rt_table_t *rt; seek_list_t *seek_entry; u_int32_t dest_seqno; int ttl;#define TTL_VALUE ttl gettimeofday(&now, NULL); if (seek_list_find(dest_addr)) return; /* If we already have a route entry, we use information from it. */ rt = rt_table_find(dest_addr); ttl = NET_DIAMETER; /* This is the TTL if we don't use expanding ring search */ if (!rt) { dest_seqno = 0; if (expanding_ring_search) ttl = TTL_START; } else { dest_seqno = rt->dest_seqno; if (expanding_ring_search) { ttl = rt->hcnt + TTL_INCREMENT; }/* if (rt->flags & RT_INET_DEST) *//* flags |= RREQ_DEST_ONLY; */ /* A routing table entry waiting for a RREP should not be expunged before 2 * NET_TRAVERSAL_TIME... */ if (timeval_diff(&rt->rt_timer.timeout, &now) < (2 * NET_TRAVERSAL_TIME)) rt_table_update_timeout(rt, 2 * NET_TRAVERSAL_TIME); } rreq_send(dest_addr, dest_seqno, ttl, flags); /* Remember that we are seeking this destination */ seek_entry = seek_list_insert(dest_addr, dest_seqno, ttl, flags, ipd); /* Set a timer for this RREQ */ if (expanding_ring_search) timer_set_timeout(&seek_entry->seek_timer, RING_TRAVERSAL_TIME); else timer_set_timeout(&seek_entry->seek_timer, NET_TRAVERSAL_TIME); DEBUG(LOG_DEBUG, 0, "Seeking %s ttl=%d", ip_to_str(dest_addr), ttl); return;}/* Local repair is very similar to route discovery... */void NS_CLASS rreq_local_repair(rt_table_t * rt, struct in_addr src_addr, struct ip_data *ipd){ struct timeval now; seek_list_t *seek_entry; rt_table_t *src_entry; int ttl; u_int8_t flags = 0; if (!rt) return; if (seek_list_find(rt->dest_addr)) return; if (!(rt->flags & RT_REPAIR)) return; gettimeofday(&now, NULL); DEBUG(LOG_DEBUG, 0, "REPAIRING route to %s", ip_to_str(rt->dest_addr)); /* Caclulate the initial ttl to use for the RREQ. MIN_REPAIR_TTL mentioned in the draft is the last known hop count to the destination. */ src_entry = rt_table_find(src_addr); if (src_entry) ttl = (int) (max(rt->hcnt, 0.5 * src_entry->hcnt) + LOCAL_ADD_TTL); else ttl = rt->hcnt + LOCAL_ADD_TTL; DEBUG(LOG_DEBUG, 0, "%s, rreq ttl=%d, dest_hcnt=%d", ip_to_str(rt->dest_addr), ttl, rt->hcnt); /* Reset the timeout handler, was probably previously local_repair_timeout */ rt->rt_timer.handler = &NS_CLASS route_expire_timeout; if (timeval_diff(&rt->rt_timer.timeout, &now) < (2 * NET_TRAVERSAL_TIME)) rt_table_update_timeout(rt, 2 * NET_TRAVERSAL_TIME); rreq_send(rt->dest_addr, rt->dest_seqno, ttl, flags); /* Remember that we are seeking this destination and setup the timers */ seek_entry = seek_list_insert(rt->dest_addr, rt->dest_seqno, ttl, flags, ipd); if (expanding_ring_search) timer_set_timeout(&seek_entry->seek_timer, 2 * ttl * NODE_TRAVERSAL_TIME); else timer_set_timeout(&seek_entry->seek_timer, NET_TRAVERSAL_TIME); DEBUG(LOG_DEBUG, 0, "Seeking %s ttl=%d", ip_to_str(rt->dest_addr), ttl); return;}NS_STATIC struct rreq_record *NS_CLASS rreq_record_insert(struct in_addr orig_addr, u_int32_t rreq_id){ struct rreq_record *rec; /* First check if this rreq packet is already buffered */ rec = rreq_record_find(orig_addr, rreq_id); /* If already buffered, should we update the timer??? */ if (rec) return rec; if ((rec = (struct rreq_record *) malloc(sizeof(struct rreq_record))) == NULL) { fprintf(stderr, "Malloc failed!!!\n"); exit(-1); } rec->orig_addr = orig_addr; rec->rreq_id = rreq_id; timer_init(&rec->rec_timer, &NS_CLASS rreq_record_timeout, rec); list_add(&rreq_records, &rec->l); DEBUG(LOG_INFO, 0, "Buffering RREQ %s rreq_id=%lu time=%u", ip_to_str(orig_addr), rreq_id, PATH_DISCOVERY_TIME); timer_set_timeout(&rec->rec_timer, PATH_DISCOVERY_TIME); return rec;}NS_STATIC struct rreq_record *NS_CLASS rreq_record_find(struct in_addr orig_addr, u_int32_t rreq_id){ list_t *pos; list_foreach(pos, &rreq_records) { struct rreq_record *rec = (struct rreq_record *) pos; if (rec->orig_addr.s_addr == orig_addr.s_addr && (rec->rreq_id == rreq_id)) return rec; } return NULL;}void NS_CLASS rreq_record_timeout(void *arg){ struct rreq_record *rec = (struct rreq_record *) arg; list_detach(&rec->l); free(rec);}struct blacklist *NS_CLASS rreq_blacklist_insert(struct in_addr dest_addr){ struct blacklist *bl; /* First check if this rreq packet is already buffered */ bl = rreq_blacklist_find(dest_addr); /* If already buffered, should we update the timer??? */ if (bl) return bl; if ((bl = (struct blacklist *) malloc(sizeof(struct blacklist))) == NULL) { fprintf(stderr, "Malloc failed!!!\n"); exit(-1); } bl->dest_addr.s_addr = dest_addr.s_addr; timer_init(&bl->bl_timer, &NS_CLASS rreq_blacklist_timeout, bl); list_add(&rreq_blacklist, &bl->l); timer_set_timeout(&bl->bl_timer, BLACKLIST_TIMEOUT); return bl;}struct blacklist *NS_CLASS rreq_blacklist_find(struct in_addr dest_addr){ list_t *pos; list_foreach(pos, &rreq_blacklist) { struct blacklist *bl = (struct blacklist *) pos; if (bl->dest_addr.s_addr == dest_addr.s_addr) return bl; } return NULL;}void NS_CLASS rreq_blacklist_timeout(void *arg){ struct blacklist *bl = (struct blacklist *) arg; list_detach(&bl->l); free(bl);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -