void route_discovery_timeout(void *arg) { seek_list_t *seek_entry; seek_entry = (seek_list_t *)arg; /* Sanity check... */ if(seek_entry == NULL) return; #ifdef DEBUG log(LOG_DEBUG, 0, "route_discovery_timeout: %s", ip_to_str(seek_entry->dest_addr)); #endif if(seek_entry->reqs < RREQ_RETRIES) { RREQ *rreq; if(use_expanding_ring_search) { if(seek_entry->ttl < TTL_THRESHOLD) seek_entry->ttl += TTL_INCREMENT; else { seek_entry->ttl = NET_DIAMETER; seek_entry->reqs++; } /* Set a new timer for seeking this destination */ seek_entry->timer_id = timer_new(2*seek_entry->ttl*NODE_TRAVERSAL_TIME, route_discovery_timeout, seek_entry); } else { seek_entry->reqs++; seek_entry->timer_id = timer_new(NET_TRAVERSAL_TIME, route_discovery_timeout, seek_entry); } rreq = rreq_create(seek_entry->flags, seek_entry->dest_addr, seek_entry->dest_seqno); aodv_socket_send((AODV_msg *)rreq, AODV_BROADCAST, RREQ_SIZE, seek_entry->ttl); } else { packet_buff_drop(seek_entry->dest_addr); #ifdef DEBUG log(LOG_DEBUG, 0, "route_discovery_timeout: NO ROUTE FOUND!"); #endif seek_entry->timer_id = 0; /* Send an ICMP Destination Host Unreachable to the application: */ if(seek_entry->ipd) icmp_send_host_unreachable(this_host->ipaddr, seek_entry->ipd->data, seek_entry->ipd->len); seek_list_remove(seek_entry->dest_addr); } }
/* if packet->interface = NULL then the packet has been generated by the router */ void ip_forward(struct sr_packet * packet) { struct ip * ip_hdr = IP_HDR(packet); uint32_t next_hop; char thru_interface[SR_NAMELEN]; /* if the destination is to one of our ports, then just forward it there */ if(interface_list_get_interface_by_ip(INTERFACE_LIST(packet->sr), ip_hdr->ip_dst.s_addr)) { ip_handle_incoming_packet(packet); } else { if(forwarding_table_lookup_next_hop(ROUTER(packet->sr)->fwd_table, ip_hdr->ip_dst.s_addr, &next_hop, thru_interface, interface_list_inbound(packet->sr, packet->interface)) && interface_list_forward_packet(packet->sr, packet->interface, thru_interface)) { if(next_hop == 0) { next_hop = ip_hdr->ip_dst.s_addr; } ip_hdr->ip_ttl --; ip_hdr->ip_sum = checksum_ipheader(ip_hdr); ip_send(packet,next_hop,thru_interface); } else { if(forwarding_table_lookup_next_hop(ROUTER(packet->sr)->fwd_table, ip_hdr->ip_src.s_addr, 0,0, interface_list_inbound(packet->sr, packet->interface))) { icmp_send_host_unreachable(packet); } } } }
void NS_CLASS route_discovery_timeout(void *arg) { struct timeval now; seek_list_t *seek_entry; rt_table_t *rt, *repair_rt; seek_entry = (seek_list_t *) arg; #define TTL_VALUE seek_entry->ttl /* Sanity check... */ if (!seek_entry) return; gettimeofday(&now, NULL); DEBUG(LOG_DEBUG, 0, "%s", ip_to_str(seek_entry->dest_addr)); if (seek_entry->reqs < RREQ_RETRIES) { if (expanding_ring_search) { if (TTL_VALUE < TTL_THRESHOLD) TTL_VALUE += TTL_INCREMENT; else { TTL_VALUE = NET_DIAMETER; seek_entry->reqs++; } /* Set a new timer for seeking this destination */ timer_set_timeout(&seek_entry->seek_timer, RING_TRAVERSAL_TIME); } else { seek_entry->reqs++; timer_set_timeout(&seek_entry->seek_timer, seek_entry->reqs * 2 * NET_TRAVERSAL_TIME); } /* AODV should use a binary exponential backoff RREP waiting time. */ DEBUG(LOG_DEBUG, 0, "Seeking %s ttl=%d wait=%d", ip_to_str(seek_entry->dest_addr), TTL_VALUE, 2 * TTL_VALUE * NODE_TRAVERSAL_TIME); /* A routing table entry waiting for a RREP should not be expunged before 2 * NET_TRAVERSAL_TIME... */ rt = rt_table_find(seek_entry->dest_addr); if (rt && timeval_diff(&rt->rt_timer.timeout, &now) < (2 * NET_TRAVERSAL_TIME)) rt_table_update_timeout(rt, 2 * NET_TRAVERSAL_TIME); rreq_send(seek_entry->dest_addr, seek_entry->dest_seqno, TTL_VALUE, seek_entry->flags); } else { packet_queue_drop(seek_entry->dest_addr); DEBUG(LOG_DEBUG, 0, "NO ROUTE FOUND!"); #ifndef NS_PORT /* Send an ICMP Destination Host Unreachable to the application: */ if (seek_entry->ipd) icmp_send_host_unreachable(seek_entry->ipd->data, seek_entry->ipd->len); #endif repair_rt = rt_table_find(seek_entry->dest_addr); seek_list_remove(seek_entry); /* If this route has been in repair, then we should timeout the route at this point. */ if (repair_rt && (repair_rt->flags & RT_REPAIR)) { DEBUG(LOG_DEBUG, 0, "REPAIR for %s failed!", ip_to_str(repair_rt->dest_addr)); local_repair_timeout(repair_rt); } } }