📄 aodv-uu.cc
字号:
/***************************************************************************** * * Copyright (C) 2002 Uppsala University. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Authors: Bj鰎n Wiberg <bjorn.wiberg@home.se> * Erik Nordstr鰉 <erik.nordstrom@it.uu.se> * *****************************************************************************/#include <string.h>#include <assert.h>#include "../common/encap.h"#include "aodv-uu.h"/* Method for determining the size of the AODVUU packet header type */int AODV_msg::size(){ return AODV_MSG_MAX_SIZE;}/* Tcl hooks for enabling the AODVUU packet header type */int hdr_aodvuu::offset_;static class AODVUUHeaderClass:public PacketHeaderClass { public: AODVUUHeaderClass():PacketHeaderClass("PacketHeader/AODVUU", AODV_MSG_MAX_SIZE) { bind_offset(&hdr_aodvuu::offset_);}} class_rtProtoAODVUU_hdr;/* Tcl hooks for the AODVUU routing agent */static class AODVUUclass:public TclClass { public: AODVUUclass():TclClass("Agent/AODVUU") { } TclObject *create(int argc, const char *const *argv) { /* argv[4] and up are arguments to the constructor */ assert(argc == 5); return (new AODVUU((nsaddr_t) atoi(argv[4]))); }}class_rtProtoAODVUU;/* Handler for investigating the queue of timers */void TimerQueueTimer::expire(Event *e){ struct timeval *timeout; timeout = agent_->timer_age_queue(); if (timeout) resched((double) timeout->tv_sec + (double) timeout->tv_usec / (double) 1000000);}/* Constructor for the AODVUU routing agent */NS_CLASS AODVUU(nsaddr_t id) : Agent(PT_AODVUU), initialized(0), tqtimer(this), ifqueue(0){ /* Enable usage of some of the configuration variables from Tcl. Note: Do NOT change the values of these variables in the constructor after binding them! The desired default values should be set in ~ns/tcl/lib/ns-default.tcl instead. */ bind("unidir_hack_", &unidir_hack); bind("rreq_gratuitous_", &rreq_gratuitous); bind("expanding_ring_search_", &expanding_ring_search); bind("local_repair_", &local_repair); bind("receive_n_hellos_", &receive_n_hellos); bind("hello_jittering_", &hello_jittering); bind("wait_on_reboot_", &wait_on_reboot); bind("debug_", &debug); bind("rt_log_interval_", &rt_log_interval); // Note: in milliseconds! bind("log_to_file_", &log_to_file); bind("optimized_hellos_", &optimized_hellos); bind("ratelimit_", &ratelimit); bind("llfeedback_", &llfeedback); bind("internet_gw_mode_", &internet_gw_mode); /* Other initializations follow */ /* From main.c */ progname = strdup("AODV-UU"); /* From debug.c */ /* Note: log_nmsgs was never used anywhere */ log_nmsgs = 0; log_file_fd = -1; log_rt_fd = -1; /* Set host parameters */ memset(&this_host, 0, sizeof(struct host_info)); memset(dev_indices, 0, sizeof(unsigned int) * MAX_NR_INTERFACES); this_host.seqno = 1; this_host.rreq_id = 0; /* Set network interface parameters */ DEV_NR(NS_DEV_NR).enabled = 1; DEV_NR(NS_DEV_NR).sock = -1; DEV_NR(NS_DEV_NR).ifindex = NS_IFINDEX; dev_indices[NS_DEV_NR] = NS_IFINDEX; const char faked_ifname[] = "nsif"; strncpy(DEV_NR(NS_DEV_NR).ifname, faked_ifname, IFNAMSIZ - 1); DEV_NR(NS_DEV_NR).ifname[IFNAMSIZ - 1] = '\0'; // Netmask not used in simulations DEV_NR(NS_DEV_NR).netmask.s_addr = (in_addr_t) 0; DEV_NR(NS_DEV_NR).broadcast.s_addr = AODV_BROADCAST; // One enabled network interface (in total) this_host.nif = 1; node_id = id; /* Set agent parameters */ addr() = id; port() = RT_PORT; dport() = RT_PORT; INIT_LIST_HEAD(&rreq_records); INIT_LIST_HEAD(&rreq_blacklist); INIT_LIST_HEAD(&seekhead); INIT_LIST_HEAD(&TQ); /* Initialize data structures */ worb_timer.data = NULL; worb_timer.used = 0; hello_timer.data = NULL; hello_timer.used = 0; rt_log_timer.data = NULL; rt_log_timer.used = 0; aodv_socket_init(); rt_table_init(); packet_queue_init(); packet_input_init();}/* Destructor for the AODV-UU routing agent */NS_CLASS ~ AODVUU(){ rt_table_destroy(); packet_input_cleanup(); log_cleanup();}/* Link layer callback function. Used when link layer packet delivery fails.*/static void link_layer_callback(Packet *p, void *arg){ ((AODVUU *) arg)->packetFailed(p);}/* A small function used as filter to remove packets by destination from the interface queue.*/int ifqueue_filter_on_dest(Packet *p, void *data){ struct hdr_ip *ih = HDR_IP(p); u_int32_t *addr = (u_int32_t *) data; u_int32_t dest_addr = (u_int32_t) ih->daddr(); return (dest_addr == *addr);}/* Moves pending packets with a certain next hop from the interface queue to the packet buffer or simply drops it.*/void NS_CLASS interfaceQueue(nsaddr_t addr, int action){ Packet *q_pkt = NULL; struct hdr_ip *ih = NULL; struct in_addr dest_addr; /* Check that interface queue reference is valid */ if (ifqueue == NULL || ifqueue == 0) { DEBUG(LOG_DEBUG, 0, "ifqueue is NULL!!!"); return; } dest_addr.s_addr = addr; /* Move packets from interface queue to packet buffer */ switch (action) { case IFQ_DROP: while ((q_pkt = ifqueue->filter(addr))) { struct hdr_cmn *ch = HDR_CMN(q_pkt); DEBUG(LOG_DEBUG, 0, "Dropping pkt for %s uid=%d", ip_to_str(dest_addr), ch->uid()); drop(q_pkt, DROP_RTR_NO_ROUTE); } break; case IFQ_DROP_BY_DEST: dest_addr.s_addr = addr; DEBUG(LOG_DEBUG, 0, "Dropping pkts by dest for %s queue_len=%d", ip_to_str(dest_addr), ifqueue->length()); ifqueue->filter(ifqueue_filter_on_dest, (void *) &addr); break; case IFQ_BUFFER: while ((q_pkt = ifqueue->filter(addr))) { ih = HDR_IP(q_pkt); packet_queue_add(q_pkt, dest_addr); DEBUG(LOG_DEBUG, 0, "Rebuffered IFQ packet"); } break; default: DEBUG(LOG_DEBUG, 0, "Unspecified action. Don't know what to do."); }}/* Called for packets whose delivery fails at the link layer */void NS_CLASS packetFailed(Packet *p){ struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); rt_table_t *rt_next_hop, *rt; struct in_addr dest_addr, src_addr, next_hop; packet_t pt = ch->ptype(); dest_addr.s_addr = ih->daddr(); src_addr.s_addr = ih->saddr(); next_hop.s_addr = ch->next_hop(); DEBUG(LOG_DEBUG, 0, "Got failure callback"); /* We don't care about link failures for broadcast or non-data packets */ if (!(DATA_PACKET(pt) || (pt == PT_PING) || (pt == PT_ENCAPSULATED)) || dest_addr.s_addr == IP_BROADCAST || dest_addr.s_addr == AODV_BROADCAST) { drop(p, DROP_RTR_MAC_CALLBACK); DEBUG(LOG_DEBUG, 0, "Ignoring callback"); goto end; } DEBUG(LOG_DEBUG, 0, "LINK FAILURE for next_hop=%s dest=%s uid=%d", ip_to_str(next_hop), ip_to_str(dest_addr), ch->uid()); if (seek_list_find(dest_addr)) { DEBUG(LOG_DEBUG, 0, "Ongoing route discovery, buffering packet..."); packet_queue_add(p, dest_addr); goto end; } rt_next_hop = rt_table_find(next_hop); rt = rt_table_find(dest_addr); if (!rt_next_hop || rt_next_hop->state == INVALID) goto drop; if (!rt || rt->state == INVALID) goto drop; if (rt->next_hop.s_addr != next_hop.s_addr) { DEBUG(LOG_DEBUG, 0, "next hop mismatch - DROPPING pkt"); drop(p, DROP_RTR_MAC_CALLBACK); goto end; } /* Do local repair? */ if (local_repair && rt->hcnt <= MAX_REPAIR_TTL /* && ch->num_forwards() > rt->hcnt */ ) { /* Buffer the current packet */ packet_queue_add(p, dest_addr); /* Buffer pending packets from interface queue */ interfaceQueue((nsaddr_t) next_hop.s_addr, IFQ_BUFFER); /* Mark the route to be repaired */ rt_next_hop->flags |= RT_REPAIR; neighbor_link_break(rt_next_hop); rreq_local_repair(rt, src_addr, NULL); } else { /* No local repair - just force timeout of link and drop packets */ neighbor_link_break(rt_next_hop); drop: drop(p, DROP_RTR_MAC_CALLBACK); interfaceQueue((nsaddr_t) next_hop.s_addr, IFQ_DROP); } end: /* The link layer event might have changed the timer queue, so we'd better reschedule the timer queue timer...
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -