예제 #1
0
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;

}
예제 #2
0
파일: rrep.c 프로젝트: mcatalancid/fb-aodv
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;
}