int recv_rerr(task * tmp_packet) { aodv_route *tmp_route; rerr *tmp_rerr; int num_hops; int expired_routes = 0; tmp_rerr = (rerr *) tmp_packet->data; num_hops = tmp_rerr->num_hops+1; #ifdef CaiDebug printk("Recieved a route error from %s\n", inet_ntoa(tmp_packet->src_ip)); #endif #ifdef DTN extern int dtn_register; int first_dtn=0; #include <linux/sched.h> //JL: Added kernel threads interface: #include <linux/kthread.h> u_int32_t para[4]; para[0] = tmp_rerr->src_ip; para[1] = tmp_rerr->dst_ip; para[2] = tmp_rerr->last_avail_ip; para[3] = (u_int32_t)tmp_rerr->type; if( dtn_register==1 ){ //����ע��DTN����lastavailΪ�ջ��߽��յ���tmp_rerr��СС�ڶ�����DTN��rerr if( para[2]==NULL )//current node is the nearest DTN node to brk link { para[2] = g_mesh_ip; first_dtn = 1; } // kthread_run(&send2dtn, (void*)para, "send2dtn"); send2dtn((void*)para,DTNPORT);//tmp_rerr->dst_ip, tmp_rerr->last_avail_ip); } #endif tmp_route = find_aodv_route_by_id(tmp_rerr->dst_ip, ntohl(tmp_rerr->dst_id)); if (tmp_route && tmp_route->next_hop == tmp_packet->src_ip) { //if there is any hop before me if (!reply_to_rrer(tmp_route->src_ip, tmp_route->dst_ip)) { if (tmp_route->state != INVALID) { //route with active traffic tmp_rerr->type = RERR_MESSAGE; tmp_rerr->dst_count = 0; //unused tmp_rerr->reserved = 0; tmp_rerr->n = 0; tmp_rerr->num_hops = num_hops; tmp_rerr->dst_ip = tmp_route->dst_ip; tmp_rerr->dst_id = htonl(tmp_route->dst_id); #ifdef DTN tmp_rerr->src_ip = tmp_route->src_ip; if(dtn_register==1 && first_dtn==1) { tmp_rerr->last_avail_ip = g_mesh_ip; } #endif send_message(tmp_route->last_hop, NET_DIAMETER, tmp_rerr, sizeof(rerr)); #ifdef RECOVERYPATH /**************************************************** ������·��������ÿ������һ���µ�rerr��ʱ��Ҳ �½�һ��brk_list����Ŀ *****************************************************/ brk_link *tmp_link; tmp_link = find_brk_link(tmp_route->src_ip,tmp_route->dst_ip); if(tmp_link != NULL){//�Ѵ��ڣ������������ڣ������������ٳ��� //Update brk_link timelife������Ҫ��ʱ���Ĵ��� tmp_link->lifetime = getcurrtime() + BRK_LINK_TIMEOUT; flush_brk_list(); } else{ tmp_link = create_brk_link(tmp_route->src_ip,tmp_route->dst_ip, tmp_route->last_hop,tmp_rerr->last_avail_ip);//����������,ע���˴���ast_avail_ipӦ���Զ�·�� if(tmp_link==NULL) printk("Creat new brk link failed!\n"); #ifdef CaiDebug char s[20]; char d[20]; char l[20]; char la[20]; strcpy(s,inet_ntoa(tmp_route->src_ip)); strcpy(d,inet_ntoa(tmp_route->dst_ip)); strcpy(l,inet_ntoa(tmp_route->last_hop)); strcpy(la,inet_ntoa(tmp_rerr->last_avail_ip)); printk("new brk link %s:%s:%s:%s\n",s,d,l,la); #endif flush_brk_list(); } /******************************************************************/ #endif } }//not the source #ifdef RECOVERYPATH else{ /**************************************************** ������·��������ÿ������һ���µ�rerr��ʱ��Ҳ �½�һ��brk_list����Ŀ *****************************************************/ #ifdef DTN u_int32_t last_avail; last_avail = NULL; if(dtn_register==1 && first_dtn==1) { last_avail = g_mesh_ip; } #endif brk_link *tmp_link; tmp_link = find_brk_link(tmp_route->src_ip,tmp_route->dst_ip); if(tmp_link != NULL){//�Ѵ��ڣ������������ڣ������������ٳ��� //Update brk_link timelife������Ҫ��ʱ���Ĵ��� tmp_link->lifetime = getcurrtime() + BRK_LINK_TIMEOUT; flush_brk_list(); } else{ tmp_link = create_brk_link(tmp_route->src_ip,tmp_route->dst_ip, NULL,last_avail);//notice the last hop is NULL if(tmp_link==NULL) printk("Creat new brk link failed!\n"); #ifdef CaiDebug char s[20]; char d[20]; char l[20]; char la[20]; strcpy(s,inet_ntoa(tmp_route->src_ip)); strcpy(d,inet_ntoa(tmp_route->dst_ip)); strcpy(l,"0.0.0.0"); strcpy(la,inet_ntoa(last_avail)); printk("new brk link %s:%s:%s:%s\n",s,d,l,la); #endif flush_brk_list(); } /******************************************************************/ }//the source #endif if (tmp_route->state != INVALID) { expire_aodv_route(tmp_route); expired_routes++; } } if (g_routing_metric == WCIM && expired_routes != 0) update_my_load(); return 0; }
int recv_rrep(task * tmp_packet) { aodv_route *send_route; aodv_route *recv_route; aodv_neigh *tmp_neigh = NULL; rrep *tmp_rrep; u_int32_t path_metric; int iam_destination = 0; #ifdef DEBUG char dst_ip[16]; char src_ip[16]; #endif tmp_rrep = tmp_packet->data; convert_rrep_to_host(tmp_rrep); tmp_neigh = find_aodv_neigh(tmp_packet->src_ip); if (tmp_neigh == NULL) { #ifdef DEBUG printk("Ignoring RREP received from unknown neighbor\n"); #endif return 1; } //Update neighbor timelife delete_timer(tmp_neigh->ip, tmp_neigh->ip, NO_TOS, TASK_NEIGHBOR); insert_timer_simple(TASK_NEIGHBOR, HELLO_INTERVAL * (1 + ALLOWED_HELLO_LOSS) + 100, tmp_neigh->ip); update_timer_queue(); tmp_neigh->lifetime = HELLO_INTERVAL * (1 + ALLOWED_HELLO_LOSS) + 20 + getcurrtime(); tmp_rrep->num_hops++; #ifdef DEBUG strcpy(src_ip, inet_ntoa(tmp_rrep->src_ip)); strcpy(dst_ip, inet_ntoa(tmp_rrep->dst_ip)); printk("received new rrep from %s to %s with ToS: %u - last hop: %s\n", dst_ip, src_ip, tmp_rrep->tos, inet_ntoa(tmp_packet->src_ip)); #endif if (tmp_rrep->src_ip == g_mesh_ip || (tmp_rrep->src_ip == g_null_ip && tmp_rrep->gateway == g_mesh_ip)) iam_destination = 1; if (iam_destination) { //I'm the source of the flow (the destination of the RREP) delete_timer(tmp_rrep->src_ip, tmp_rrep->dst_ip, tmp_rrep->tos, TASK_RESEND_RREQ); update_timer_queue(); path_metric = tmp_rrep->path_metric; //Create (or update) the first hop of the route rreq_aodv_route(tmp_rrep->src_ip, tmp_rrep->dst_ip, tmp_rrep->tos, tmp_neigh, tmp_rrep->num_hops, tmp_rrep->dst_id, tmp_packet->dev, path_metric); send_route = find_aodv_route_by_id(tmp_rrep->dst_ip, tmp_rrep->dst_id); if (!send_route) { #ifdef DEBUG printk("No reverse-route for RREP from: %s to: %s with TOS %u\n", dst_ip, src_ip, tmp_rrep->tos); #endif return 0; } rrep_aodv_route(send_route); send_route->last_hop = g_mesh_ip; } else { recv_route = find_aodv_route_by_id(tmp_rrep->src_ip, tmp_rrep->src_id); //the route created by the RREQ if (!recv_route) { #ifdef DEBUG printk("Reverse Route has timed out! - RREP is not forwarded!\n"); #endif return 1; } path_metric = tmp_rrep->path_metric - recv_route->path_metric; //Create (or update) the route from source to destination rreq_aodv_route(tmp_rrep->src_ip, tmp_rrep->dst_ip, tmp_rrep->tos, tmp_neigh, tmp_rrep->num_hops, tmp_rrep->dst_id, tmp_packet->dev, path_metric); send_route = find_aodv_route_by_id(tmp_rrep->dst_ip, tmp_rrep->dst_id); if (!send_route) { #ifdef DEBUG printk("No reverse-route for RREP from: %s to: %s with TOS %u\n", dst_ip, src_ip, tmp_rrep->tos); printk("Not Forwarding RREP!\n"); #endif return 0; } rrep_aodv_route(recv_route); rrep_aodv_route(send_route); send_route->last_hop = recv_route->next_hop; recv_route->last_hop = send_route->next_hop; convert_rrep_to_network(tmp_rrep); send_message(recv_route->next_hop, NET_DIAMETER, tmp_rrep, sizeof(rrep)); } return 0; }