Beispiel #1
0
int insert_timer_directional(u_int8_t task_type, u_int64_t delay,
		u_int8_t retries, u_int32_t src_ip, u_int32_t dst_ip, unsigned char tos) {
	task *new_timer = NULL;

	new_timer = create_task(task_type);

	// get memory
	if (!(new_timer)) {
		printk("Error allocating timer!\n");
		return -ENOMEM;
	}

	new_timer->src_ip = src_ip;
	new_timer->dst_ip = dst_ip;
	new_timer->tos = tos;

	if (delay != 0)
		new_timer->time = getcurrtime() + delay;

	else if (task_type == TASK_RESEND_RREQ) {
		new_timer->retries = retries;
		new_timer->ttl = 30;
		new_timer->time = getcurrtime() + ((2 ^ (RREQ_RETRIES - retries))
				* NET_TRAVERSAL_TIME);
	} else
		new_timer->time = getcurrtime() + delay;
	queue_timer(new_timer);
	//update_timer_queue();
	return 0;
}
/*
Print out to file dbg.log, along with address of node.
*/
void LOG(address *addr, char * str, ...){

	static FILE *fp;
	static FILE *fp2;
	va_list vararglist;
	static char buffer[30000];
	static int numwrites;
	static char stdstring[30];
	static char stdstring2[40];
	static char stdstring3[40]; 
	static int dbg_opened=0;

	if(dbg_opened != 639){
		numwrites=0;

		stdstring2[0]=0;

		strcpy(stdstring3, stdstring2);

		strcat(stdstring2, "dbg.log");
		strcat(stdstring3, "stats.log");

		fp = fopen(stdstring2, "a+");
		fp2 = fopen(stdstring3, "a+");

		dbg_opened=639;
	}
	else 

	sprintf(stdstring, "%d.%d.%d.%d:%d ", addr->addr[0], addr->addr[1], addr->addr[2], addr->addr[3], *(short *)&addr->addr[4]);

	va_start(vararglist, str);
	vsprintf(buffer, str, vararglist);
	va_end(vararglist);

	if(memcmp(buffer, "#STATSLOG#", 10)==0){
		fprintf(fp2, "\n %s", stdstring);
		fprintf(fp2, "[%ld] ", getcurrtime());

		fprintf(fp2, buffer);
	}
	else{
		fprintf(fp, "\n %s", stdstring);
		fprintf(fp, "[%ld] ", getcurrtime());
		fprintf(fp, buffer);

	}

	if(++numwrites >= MAXWRITES){
		fflush(fp);
		fflush(fp2);
		numwrites=0;
	}

}
Beispiel #3
0
int flush_brk_list(void) {
	u_int64_t currtime = getcurrtime();
	brk_link *dead_link, *tmp_link, *prev_link=NULL;

	tmp_link = brk_list;

	while (tmp_link!=NULL) {
		prev_link = tmp_link;

		if (time_before((unsigned long) tmp_link->lifetime,
				(unsigned long) currtime)) {//生命周期在当前时间之前

			if (tmp_link->state != INVALID) {//未过期则使其过期
				expire_brk_link(tmp_link);
				tmp_link = tmp_link->next;
			}
			else {//已标志过期,则删除。

				}

				dead_link = tmp_link;
				prev_link = tmp_link->prev;
				tmp_link = tmp_link->next;
				remove_brk_link(dead_link);
			}

			tmp_link = tmp_link->next;
		} 
			
	//insert_timer_simple(TASK_CLEANUP, HELLO_INTERVAL, g_mesh_ip);
	//update_timer_queue();
	return 1;
}
Beispiel #4
0
//expire some brk link -- 使某个断路条目过期
void expire_brk_link(brk_link * tmp_link) {

	brk_list_write_lock();
	tmp_link->lifetime = (getcurrtime() + DELETE_PERIOD);
	tmp_link->state = INVALID;
	brk_list_write_unlock();
}
Beispiel #5
0
void update_timer_queue() {
	struct timeval delay_time;
	u_int64_t currtime;
	u_int64_t remainder, numerator;

	delay_time.tv_sec = 0;
	delay_time.tv_usec = 0;

	/* lock Read */
	timer_read_lock();

	if (timer_queue == NULL) {
		// No event to set timer for
		//delay_time.tv_sec = 0;
		//delay_time.tv_usec = 0;
		//del_timer(&aodv_timer);
		timer_read_unlock();
		return;
	}
		//* Get the first time value

		currtime = getcurrtime();

		if (time_before((unsigned long) timer_queue->time,
				(unsigned long) currtime)) {
			// If the event has allready happend, set the timeout to              1 microsecond :-)

			delay_time.tv_sec = 0;
			delay_time.tv_usec = 1;
		} else {
			// Set the timer to the actual seconds / microseconds from now

			//This is a fix for an error that occurs on ARM Linux Kernels because they do 64bits differently
			//Thanks to S. Peter Li for coming up with this fix!

			numerator = (timer_queue->time - currtime);
			remainder = (u_int64_t)do_div(numerator, 1000);

			delay_time.tv_sec = numerator;
			delay_time.tv_usec = remainder * 1000;

		}


		mod_timer(&aodv_timer, jiffies + tvtojiffies(&delay_time));


	/* lock Read */
	timer_read_unlock();

	// Set the timer (in real time)
	return;
}
/* 
Introduce self to group. 
*/
int introduceselftogroup(member *node, address *joinaddr){
    
    messagehdr *msg;
#ifdef DEBUGLOG
    static char s[1024];
#endif

    if(memcmp(&node->addr, joinaddr, 4*sizeof(char)) == 0){
        /* I am the group booter (first process to join the group). Boot up the group. */
#ifdef DEBUGLOG
        LOG(&node->addr, "Starting up group...");
#endif

        node->ingroup = 1;
		node->nodenumber = 0;
		// adding the membership data of node0 
		node->memtable[node->nodenumber].lastupdatetime=getcurrtime();
		memcpy(&node->memtable[node->nodenumber].maddr,&node->addr,sizeof(address));
		node->memtable[node->nodenumber].tocleanup=0;
		node->memtable[node->nodenumber].heartbeatCounter++;
		node->memcount=1;


		logNodeAdd(&node->addr,&node->addr);
		printf("log node added ");
		
    }
    else{
        size_t msgsize = sizeof(messagehdr) + sizeof(address);
        msg=malloc(msgsize);

    /* create JOINREQ message: format of data is {struct address myaddr} */
        msg->msgtype=JOINREQ;
        memcpy((char *)(msg+1), &node->addr, sizeof(address));

#ifdef DEBUGLOG
        sprintf(s, "Trying to join...");
        LOG(&node->addr, s);
#endif

    /* send JOINREQ message to introducer member. */
        MPp2psend(&node->addr, joinaddr, (char *)msg, msgsize);
        // to increment unique node number count and assign to the newly formed node.
		MEMCOUNT++;
		node->nodenumber=MEMCOUNT;
		
        free(msg);
    }

    return 1;

}
Beispiel #7
0
aodv_neigh_2h *create_aodv_neigh_2h(u_int32_t ip) {
	aodv_neigh_2h *new_neigh_2h;
	aodv_neigh_2h *prev_neigh_2h = NULL;
	aodv_neigh_2h *tmp_neigh_2h = NULL;

	if ((new_neigh_2h = kmalloc(sizeof(aodv_neigh_2h), GFP_ATOMIC)) == NULL) {
#ifdef DEBUG
		printk("NEIGHBOR_LIST_2H: Can't allocate new entry\n");
#endif
		return NULL;
	}

	tmp_neigh_2h = aodv_neigh_list_2h;
	while ((tmp_neigh_2h != NULL) && (tmp_neigh_2h->ip < ip)) {
		prev_neigh_2h = tmp_neigh_2h;
		tmp_neigh_2h = tmp_neigh_2h->next;
	}

	if (tmp_neigh_2h && (tmp_neigh_2h->ip == ip)) {
#ifdef DEBUG
		printk("NEIGHBOR_LIST_2H: Creating a duplicate 2h neighbor entry\n");
#endif
		kfree(new_neigh_2h);
		return NULL;
	}

	neigh_write_lock(); //to avoid conflicts with read_neigh_proc (uncontrolled interruption)

	printk("NEW NEIGHBOR_2HOPS DETECTED: %s\n", inet_ntoa(ip));

	new_neigh_2h->ip = ip;
	new_neigh_2h->lifetime = getcurrtime() + NEIGHBOR_2H_TIMEOUT;
	new_neigh_2h->next = NULL;
	new_neigh_2h->load = 0;
	new_neigh_2h->load_seq = 0;
	
	if (prev_neigh_2h == NULL) {
		new_neigh_2h->next = aodv_neigh_list_2h;
		aodv_neigh_list_2h = new_neigh_2h;
	} else {
		new_neigh_2h->next = prev_neigh_2h->next;
		prev_neigh_2h->next = new_neigh_2h;
	}

	neigh_write_unlock();

	insert_timer_simple(TASK_NEIGHBOR_2H, NEIGHBOR_2H_TIMEOUT + 100, ip);
	update_timer_queue();

	return new_neigh_2h;
}
Beispiel #8
0
void recv_ett_info(task * tmp_packet) {

	aodv_neigh *tmp_neigh;
	ett_info *tmp_ett_info;

	tmp_neigh = find_aodv_neigh(tmp_packet->src_ip);
	if (tmp_neigh == NULL) {
#ifdef DEBUG
		printk ("Error: Source %s of an incoming ett_info message belongs to any neighbour\n", inet_ntoa(tmp_packet->src_ip));
#endif
		return;
	}

	//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_ett_info =tmp_packet->data;

	tmp_neigh->recv_rate = ntohs(tmp_ett_info->my_rate);
	
	if (tmp_ett_info->fixed_rate==TRUE){
		tmp_neigh->ett.fixed_rate = TRUE;
		delete_timer(tmp_neigh->ip, tmp_neigh->ip, NO_TOS, TASK_ETT_CLEANUP);
					insert_timer_simple(TASK_ETT_CLEANUP, ETT_INTERVAL * (1 + ALLOWED_ETT_LOSS)
							+ 100, tmp_neigh->ip);
					update_timer_queue();
				delay_vector_add(tmp_neigh, ntohl(tmp_ett_info->last_meas_delay));
	

	if (g_fixed_rate == 0) { //this neigh does not send pair-packets - Lets use the estimation in ETT_INFO
		//NEW ETT-PAIR received - Timer is reloaded
			
#ifdef DEBUG
		printk("Received Delay to %s: %d Usecs\n",inet_ntoa(tmp_neigh->ip) ,ntohl(tmp_ett_info->last_meas_delay));
#endif
		compute_estimation(tmp_neigh);
	}
	}
	
	if ((tmp_neigh->recv_rate == 0) || (tmp_neigh->send_rate == 0))
		tmp_neigh->ett.interval = ETT_FAST_INTERVAL;
	else
		tmp_neigh->ett.interval = ETT_INTERVAL;

	return;
}
/* 
Received a JOINREP (joinreply) message. 
*/
void Process_joinrep(void *env, char *data, int size)
{

	// reading the data received
	// This is called when the node receives membership table information from the initiator

    member *node = (member *) env;
    membershiplist *memdata = (membershiplist *)data; // typecast to membership table structure type


	int selfPresent=0;
	printf("\n ***************** JOINREP for %d *********************************",node->addr.addr[0]);
	// for each struct array element loop and print
	int tablecount=size/sizeof(membershiplist);
	printf("\nnumber of tables %d",tablecount);
	int i=0;
	int n=-1;
	for(i=0;i<tablecount;i++){

		memcpy(&node->memtable[i].maddr,&memdata->maddr,sizeof(address));
		//;
		node->memtable[i].tocleanup=memdata->tocleanup;
		node->memtable[i].lastupdatetime=memdata->lastupdatetime;
		node->memtable[i].heartbeatCounter=memdata->heartbeatCounter;

		printf("\nAdding node %d into %d s table",memdata->maddr.addr[0],node->addr.addr[0]);
		logNodeAdd(&node->addr,&memdata->maddr);
		n = memcmp (&memdata->maddr, &node->addr,sizeof(address));
			if ( n == 0 ) {
				selfPresent=1;
		}
		memdata++;
	}

	if ( selfPresent == 0 )  { 
		//indicates the node's mem list table does not contain its information
		// add to the table
		printf("SELF PRESEN MISSING \n");
		memcpy(&node->memtable[i].maddr,&node->addr,sizeof(address));
		node->memtable[i].lastupdatetime=getcurrtime();
		node->memtable[i].tocleanup=0;
		node->memtable[i].heartbeatCounter++;
		node->memcount++;
		logNodeAdd(&node->addr,&node->addr);
	}
	node->memcount=tablecount;
	// after copying the membership table , we set its ingroup to 1.
	node->ingroup = 1;
    return;
}
Beispiel #10
0
//创建新的断路条目
brk_link *create_brk_link(u_int32_t src_ip, u_int32_t dst_ip,
                          u_int32_t lasthop,u_int32_t lastavail) {

    brk_link *tmp_entry;
#ifdef CaiDebug
	char src[20];
	char dst[20];
	char lhop[20];
	char lavail[20];
	strcpy(src, inet_ntoa(src_ip));
	strcpy(dst, inet_ntoa(dst_ip));
    strcpy(lhop, inet_ntoa(lasthop));
	strcpy(lavail, inet_ntoa(lastavail));

	printk ("create_brk_link: Creating %s to %s via %s,last DTN is %s\n", src,dst,lhop,lavail);
#endif

	/* Allocate memory for new entry */

	if ((tmp_entry = (brk_link *) kmalloc(sizeof(brk_link), GFP_ATOMIC)) == NULL) {

		printk("Error getting memory for new brk link\n");
		return NULL;
	}

	tmp_entry->dst_ip = dst_ip;
	tmp_entry->dst_id = htonl(dst_ip);
	tmp_entry->src_ip = src_ip;
	tmp_entry->last_hop = lasthop;
	tmp_entry->state = ACTIVE;
	//tmp_entry->last_avail_ip = NULL;

//#ifdef DTN
    tmp_entry->last_avail_ip = lastavail;//若没有则为空,该字段不能缺少
//#endif

	tmp_entry->prev = NULL;
	tmp_entry->next = NULL;

	tmp_entry->lifetime = getcurrtime() + BRK_LINK_TIMEOUT;//该删除时间是否应该调整到稍微大一点???

	insert_brk_link(tmp_entry);
#ifdef CaiDebug
	if (brk_list == NULL) // if the brk_list is empty
	{
		printk ("brk list still NULL after insert!! ");
	}
#endif
	return tmp_entry;
}
Beispiel #11
0
void timer_queue_signal() {
	task *tmp_task;
	u_int64_t currtime;

	// Get the first due entry in the queue /
	currtime = getcurrtime();
	tmp_task = first_timer_due(currtime);

	// While there is still events that has timed out
	while (tmp_task != NULL) {
		insert_task_from_timer(tmp_task);
		tmp_task = first_timer_due(currtime);
	}
	update_timer_queue();
}
/* 
Received a JOINREQ (joinrequest) message.
*/
void Process_joinreq(void *env, char *data, int size)
{

	
   	// This function is only called by the initiator for messages sent from different other nodes in the network.
	// copy message into the membership list and send joinrep message type to the node from where it received the message
	// env is the node on which it is called 
	// data only contains the address of the sender


    member *node = (member *) env;
    address *destaddr= (address *)data; // typecast to address to directly get the dest address
	NODECOUNT++;


	// update the membership table

	node->memtable[node->memcount].lastupdatetime=getcurrtime();
	node->memtable[node->memcount].heartbeatCounter++;
	memcpy(&node->memtable[node->memcount].maddr,destaddr,sizeof(address));
	node->memcount++;

	logNodeAdd(&node->addr,destaddr);


	//create the message containing membership table and send to the sender's node
	messagehdr *msg;
    size_t msgsize = sizeof(messagehdr) + ((NODECOUNT+1) * sizeof(membershiplist));
    msg=malloc(msgsize);
	msg->msgtype=JOINREP;
	messagehdr *src=msg;
	src=src+1;
	//src=msg+1;
	// do a for loop to copy each membership array struct into message 
	int i;

	for(i=0;i<node->memcount;i++){
		//printf("\n COPYING for  %d",node->memtable[i].maddr.addr[0] );

    	memcpy((membershiplist *)(src)+i, &node->memtable[i], sizeof(membershiplist));

	}

   	MPp2psend(&node->addr, destaddr, (char *)msg, msgsize);

    return;
}
Beispiel #13
0
int insert_timer_simple(u_int8_t task_type, u_int64_t delay, u_int32_t ip) {
	task *new_entry;

	new_entry = create_task(task_type);

	// get memory
	if (new_entry == NULL) {
		printk("Error allocating timer!\n");
		return -ENOMEM;
	}
	new_entry->src_ip = ip;
	new_entry->dst_ip = ip;
	new_entry->tos = NO_TOS;
	new_entry->time = getcurrtime() + delay;
	queue_timer(new_entry);
	//update_timer_queue();
	return 0;
}
Beispiel #14
0
//brk_dst_ipΪ�ѶϿ���·��Ŀ��ip
int gen_rerr(u_int32_t brk_dst_ip) {
	aodv_route *tmp_route;
	rerr *tmp_rerr;
	int expired_routes = 0;

	//�ҵ���һ��aodv·��
	tmp_route = first_aodv_route();

	//go through list
	//����������һ��Ϊbrk_dst_ip��·����Ŀ�������ýڵ㷢��rerr����Ч����·��
	while (tmp_route != NULL) {

		//printk("tmp_route->next_hop is %s\n",inet_ntoa(tmp_route->next_hop));
		if ((tmp_route->next_hop == brk_dst_ip) && (!tmp_route->self_route)&& (!tmp_route->neigh_route)){

			if (!reply_to_rrer(tmp_route->src_ip, tmp_route->dst_ip)) { //i'm source of the route, don't send the rerr
				if (tmp_route->state != INVALID) {

					if ((tmp_rerr = (rerr *) kmalloc(sizeof(rerr), GFP_ATOMIC))
							== NULL) {
#ifdef DEBUG
						printk("Can't allocate new rrep\n");
#endif
						return 0;
					}

					tmp_rerr->type = RERR_MESSAGE;
					tmp_rerr->dst_count = 0; //unused
					tmp_rerr->reserved = 0;
					tmp_rerr->n = 0;
					tmp_rerr->num_hops = 0;
					tmp_rerr->dst_ip = tmp_route->dst_ip;
					tmp_rerr->dst_id = htonl(tmp_route->dst_id);

#ifdef DTN
					//if there is DTN register,current node will be the
					//last DTN hop near the brk node
					extern int dtn_register;
					tmp_rerr->last_avail_ip = NULL;

					tmp_rerr->src_ip = tmp_route->src_ip;
					if(dtn_register==1)
					{
						tmp_rerr->last_avail_ip = g_mesh_ip;
			        //printk("last_avail_ip:%s\n",inet_ntoa(tmp_rerr->last_avail_ip));
						//notice DTN layer
#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;
						//
						send2dtn((void*)para,DTNPORT);

					}
					else tmp_rerr->last_avail_ip = NULL;
#endif

#ifdef CaiDebug
					//cai:test gen rerr
	char local[20];
 	strcpy(local,inet_ntoa(g_mesh_ip));
	char brk[20];
strcpy(brk,inet_ntoa(brk_dst_ip));
	char last[20];
strcpy(last,inet_ntoa(tmp_route->last_hop));

	printk("rerr src is %s,brk_dst_ip is %s,the last hop is %s\n",local,brk,last);
	
#endif
                    		send_message(tmp_route->last_hop, NET_DIAMETER, tmp_rerr,sizeof(rerr));
                     kfree(tmp_rerr);

#ifdef RECOVERYPATH
                    /****************************************************
                        ������·��������ÿ������һ���µ�rerr��ʱ��Ҳ
                        �½�һ��brk_list����Ŀ
                    *****************************************************/

                    brk_link *tmp_link;
                    u_int32_t lastavail=NULL;
#ifdef DTN
                    if(dtn_register==1)
                    {
                            lastavail = g_mesh_ip;
                    }
#endif
                    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,lastavail);//����������
                        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(lastavail));
                        printk("new brk link %s:%s:%s:%s\n",s,d,l,la);
#endif
                        flush_brk_list();
                    }
                    /******************************************************************/
#endif


				}//route is not invalid


			}//not the source of the route
#ifdef RECOVERYPATH
			else{		    
				/****************************************************         					*****************************************************/
#ifdef DTN
					//if there is DTN register,current node will be the
					//last DTN hop near the brk node
					extern int dtn_register;
					u_int32_t last_avail;//put them out of #ifdef DTN or in is a Q 
					last_avail = NULL;
					if(dtn_register==1)
					{
						last_avail = g_mesh_ip;
						//notice DTN layer
#include <linux/sched.h>
//JL: Added kernel threads interface:
#include <linux/kthread.h>
						u_int32_t para[4];
						para[0] = tmp_route->src_ip;
						para[1] = tmp_route->dst_ip;
						para[2] = last_avail;

						//���ʹ���
						para[3] = (u_int32_t)RERR_MESSAGE;
						//
						send2dtn((void*)para,DTNPORT);

					}
#endif
				brk_link *tmp_link;
				tmp_link = find_brk_link(tmp_route->src_ip,tmp_route->dst_ip);
				if(tmp_link != NULL){
					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++;
#ifdef CaiDebug
	char local[20];
 	strcpy(local,inet_ntoa(g_mesh_ip));
	char last[20];
	strcpy(last,inet_ntoa(tmp_route->last_hop));
	printk("invalidate tmp_route %s to %s,expored_route is %d\n",local,last,expired_routes);
#endif
			}
		}
		//move on to the next entry
		tmp_route = tmp_route->next;

	}
	if (g_routing_metric == WCIM && expired_routes != 0)

	update_my_load();


	return 0;
}
Beispiel #15
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;

}
Beispiel #16
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;
}
Beispiel #17
0
int read_timer_queue_proc(char *buffer, char **buffer_location, off_t offset,
		int buffer_length, int *eof, void *data) {
	task *tmp_task;
	u_int64_t remainder, numerator;
	u_int64_t tmp_time;
	u_int64_t currtime = getcurrtime();
	int len;
	char tmp_buffer[200];

	/* lock Read */
	 timer_read_lock();

	sprintf(
			buffer,
			"\nTimer Queue\n-----------------------------------------------------------------------------\n");
	strcat(buffer,
			"       ID         |           Type           |   sec/msec   |   Retries\n");
	strcat(
			buffer,
			"-----------------------------------------------------------------------------\n");
	tmp_task = timer_queue;

	while (tmp_task != NULL) {

		//This is a fix for an error that occurs on ARM Linux Kernels because they do 64bits differently
		//Thanks printk(" timer has %d left on it\n", timer_queue->time - currtime);
		// to S. Peter Li for coming up with this fix!
		sprintf(tmp_buffer, "    %-16s  ", inet_ntoa(tmp_task->src_ip));
		strcat(buffer, tmp_buffer);

		switch (tmp_task->type) {

		case TASK_CLEANUP:
			strcat(buffer, "Route Table Cleanup     ");
			break;

		case TASK_HELLO:
			strcat(buffer, "Next Hello           ");
			break;

		case TASK_NEIGHBOR:
			strcat(buffer, "Neighbour Validity   ");
			break;

		case TASK_SEND_ETT:
			strcat(buffer, "Next ETT-Pair        ");
			break;

		case TASK_GW_CLEANUP:
			strcat(buffer, "Gateway Validity     ");
			break;

		case TASK_ST:
			strcat(buffer, "Next ST-RREQ         ");
			break;

		case TASK_ETT_CLEANUP:
			strcat(buffer, "ETT Validity         ");
			break;

		case TASK_NEIGHBOR_2H:
			strcat(buffer, "Neighbour 2H Validity");
			break;

		case TASK_RESEND_RREQ:
			strcat(buffer, "Next RREQ      ");
			break;
			
		case TASK_SEND_RREP:
			strcat(buffer, "Sending a RREP       ");
			break;

		default:
			strcat(buffer, "Undefined Task       ");
			break;
		}

		tmp_time=tmp_task->time - currtime;

		numerator = (tmp_time);
		remainder = (u_int64_t)do_div(numerator, 1000);
		sprintf(tmp_buffer, "        %3llu/%3llu           %u\n", numerator,
				remainder, tmp_task->retries);
		strcat(buffer, tmp_buffer);
		tmp_task = tmp_task->next;
	}

	strcat(
			buffer,
			"----------------------------------------------------------------------------\n");

	/* unlock Read */
	timer_read_unlock();

	len = strlen(buffer);
	if (len <= offset+buffer_length)
		*eof = 1;
	*buffer_location = buffer + offset;
	len -= offset;
	if (len>buffer_length)
		len = buffer_length;
	if (len<0)
		len = 0;
	return len;
}
/*
 *
 * Main function.
 *
 */
int main(int argc, char *argv[]){

 int i,removed;
 srand (time(NULL));
 
 if (argc < 1)
 {
	printf("Config File Required\n");
	return 1;
 }

 setparams(argv[1]);
 srand(time(NULL));

 MPinit=ENinit,MPp2psend=ENp2psend,MPrecv=ENrecv,MPcleanup=ENcleanup;
 group = malloc(MAX_NNB*sizeof(member)); 
 

 /* 
 Create an array of processes, 
 Call nodestart() on each of them, 
 Periodically call nodeloop() on each of them (once per time unit)
 Finally call finishup_thisnode() on each one of them
 */

 for(i=0;i<=EN_GPSZ-1;i++)
	 group[i].inited=0;
 
 for(globaltime=0; globaltime<500; ++globaltime) {
	 
	 /* call recvloop for all nodes currently in the system */
	 for(i=0;i<=EN_GPSZ-1;i++)
		 if(getcurrtime()>(int)(STEP_RATE*i) && group[i].bfailed==0)
			 recvloop(&group[i]);

	for(i=EN_GPSZ-1;i>=0;i--) {
		 if(getcurrtime() == (int)(STEP_RATE*i)) {
			 /* introduce the ith node into the system at time STEPRATE*i */
			 nodestart(&group[i], JOINADDR, PORTNUM); /* last two params not used here */
		 	printf("%d-th introduced node is assigned with the address: ", i);
             
		 }
		 else if(getcurrtime()>(int)(STEP_RATE*i) && group[i].bfailed==0) {
			nodeloop(&group[i]);
			 
#ifdef DEBUGLOG
			 if(i==0&&globaltime%500==0)
				 LOG(&group[0].addr, "@@time=%d", getcurrtime());
#endif
		 }
	 }

	/* fail half the members at time t=400 */
	if(DROP_MSG && getcurrtime()==50)
		dropmsg = 1;

	if(SINGLE_FAILURE && getcurrtime()==100)
	{
		removed = rand() % EN_GPSZ;

#ifdef DEBUGLOG
		LOG(&group[removed].addr, "Node failed at time=%d", getcurrtime());
#endif
		group[removed].bfailed=1;
	}
	else if(getcurrtime() == 100)
	{
		removed = rand() % EN_GPSZ/2;
		for (i = removed; i < removed + EN_GPSZ/2; i++)
		{
#ifdef DEBUGLOG
			LOG(&group[i].addr, "Node failed at time=%d", getcurrtime());
#endif
			group[i].bfailed = 1;
		}
	}

	if(DROP_MSG && getcurrtime()==300)
		dropmsg=0;

 }

 MPcleanup();
 
 for(i=0;i<=EN_GPSZ-1;i++)
	 finishup_thisnode(&group[i]);

 return 0;
}
void network_send(){
	if(queue_nitems(msg_queue) == 0){
		CNET_start_timer(EV_TIMER0, 100000, 0);
                return; // do nothing	
	}
	//Fragment each message into a small unit and send along the link designated by the routing table
	size_t len = 0;
	next = queue_peek(msg_queue, &len);
	CnetAddr dest = next->dest;
	int dest_number = find_nodenumber(dest);
	//get link to send from the routing table
	int currLink = find_link(dest);
	//printf("Link to send is : %d\n", currLink);	
	if(queue_nitems(links[currLink].sender) > 0){
		//free(next);
		//printf("Some items in SENDER queue!\n");
		CNET_start_timer(EV_TIMER0, 100000, 0);
		return; // do nothing
	}
	//Remove the topmost message from the queue
	next = queue_remove(msg_queue, &len);
	links[currLink].msg_in_sender_Q = node_buffer[dest_number].mesg_seq_no_to_generate;
	//printf("Message is to be processed! To be sent to %d from %d and size %d and message number is %d\n", dest, nodeinfo.address, len, mesg_seq_no);
	//printf("Creating frames for message #%d\n", mesg_seq_no);	
	int int_len = len - MESSAGE_HEADER_SIZE;	
	char *data_ptr;
	data_ptr = &next->data[0];
	//printf("Message is to be processed! To be sent to %d from %d and size %d and message is %s.\n", dest, nodeinfo.address, len, data);
	//Enable application is message queue grows too small
	if(queue_nitems(msg_queue) < MAX_MSG_QUEUE_SIZE/2){
		application_enabled = true;
		CNET_enable_application(ALLNODES);
	}
	
	size_t frame_len = table[dest_number].min_mtu - FRAME_HEADER_SIZE;
	// removing the length occupied by the destination address in the MESSAGE	
	//printf("Min mtu - FRAME_HEADER_SIZE is  : %d Initial message size was %d, after removing dest part it is %d\n", frame_len, len, int_len);
	//queue packets up
	int seqno;
	for(seqno = 0; int_len > 0; seqno++){
		FRAME f;
		memset(&f.payload.data[0], '\0', MAX_MESSAGE_SIZE);
		f.payload.kind = DL_DATA;
		f.payload.source = nodeinfo.address;
		f.payload.dest = dest;
		f.payload.mesg_seq_no = node_buffer[dest_number].mesg_seq_no_to_generate;
		f.payload.len = (int_len < frame_len) ? int_len : frame_len;
		f.payload.flag_offset = (int_len <= frame_len) ? 1 : 0;
		getcurrtime(&f.payload.timestamp);
		f.payload.A = seqno;
		memcpy(&f.payload.data[0], data_ptr, f.payload.len);
	//printf("Length of frame to send is : %d and the payload is %s (before adding to queue)\n", strlen(f.payload.data) + FRAME_HEADER_SIZE, f.payload.data);	
		f.checksum = 0;
		f.checksum = CNET_ccitt((unsigned char *)&f, (int)(f.payload.len) + FRAME_HEADER_SIZE);
		len = f.payload.len + FRAME_HEADER_SIZE;
		queue_add(links[currLink].sender, &f, len);
		int_len = int_len - frame_len;
		data_ptr = data_ptr + frame_len;
	}
	printf("Message read from application layer destined for address %d | size %d | msg #%d | # frames %d \n", 
			dest, len - MESSAGE_HEADER_SIZE, node_buffer[dest_number].mesg_seq_no_to_generate, seqno);
	//printf("Created %d frames\n", seqno);
	node_buffer[dest_number].mesg_seq_no_to_generate++;
	for(int i = 0; i < seqno; i++)
		links[currLink].ack_received[i] = false;		
	schedule_and_send(currLink);
	CNET_start_timer(EV_TIMER0, 100000, 0);
}
Beispiel #20
0
void recv_lprobe(task * tmp_packet) {
	aodv_neigh *tmp_neigh;
	l_probe *tmp_lprobe;
	u_int32_t res_sec, res_usec, sec, usec;

	tmp_lprobe = tmp_packet->data;

	tmp_neigh = find_aodv_neigh(tmp_packet->src_ip);
	if (tmp_neigh == NULL) {
#ifdef DEBUG
		printk ("Error: Source %s of an incoming large probe-packet belongs to any neighbour\n", inet_ntoa(tmp_packet->src_ip));
#endif
		return;
	}

	
	//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();

	if (tmp_lprobe->n_probe != tmp_neigh->ett.last_count) //if not equal, the don't belong to the same pair.
	{
#ifdef DEBUG
		printk("Error: Invalid pair of probe-packets from %s\n",inet_ntoa(tmp_packet->src_ip) );
#endif
		return;
	}

	//NEW ETT-PAIR received - Timer is reloaded
	delete_timer(tmp_neigh->ip, tmp_neigh->ip, NO_TOS, TASK_ETT_CLEANUP);
	insert_timer_simple(TASK_ETT_CLEANUP, ETT_INTERVAL * (1 + ALLOWED_ETT_LOSS)
			+ 100, tmp_neigh->ip);
	update_timer_queue();

	sec = tmp_lprobe->sec;
	usec = tmp_lprobe->usec;
	res_sec = sec - tmp_neigh->ett.sec;
	if (res_sec == 0)
		//large packet still received  on same the second-value to the small one, only usec was incremented
		res_usec = usec - tmp_neigh->ett.usec;
	else if (res_sec == 1) //large packet received in a new second-value
		res_usec=1000000 + usec - tmp_neigh->ett.sec;
	else {
#ifdef DEBUG
		printk ("Too high delay between the probe-packets, difference in seconds of %d\n", res_sec);
#endif
		res_usec = DEFAULT_ETT_METRIC;
	}
	tmp_neigh->ett.meas_delay = res_usec;
	tmp_neigh->recv_rate = ntohs(tmp_lprobe->my_rate);

	if (g_fixed_rate == 0) {
		delay_vector_add(tmp_neigh, ntohl(tmp_lprobe->last_meas_delay));
#ifdef DEBUG
		printk("Received Delay to %s: %d Usecs\n",inet_ntoa(tmp_neigh->ip) ,ntohl(tmp_lprobe->last_meas_delay));
#endif
		compute_estimation(tmp_neigh);
	}

	if (tmp_neigh->recv_rate == 0 || tmp_neigh->send_rate == 0) //Estimation is still undone! Fast_interval!
		tmp_neigh->ett.interval = ETT_FAST_INTERVAL;
	else
		tmp_neigh->ett.interval = ETT_INTERVAL;

	return;

}
void Process_gossipmsg(void *env, char *data, int size)
{
	// This process is called for every node when it receives a message of type GOSSIP
	// once received, update the current time for its own entry in the member ship table
	// Check for the data received ( a list of membership tables ) and then update its own node's membership table if the current time stamp is more for that specific node

	member *node = (member *) env;
	address *sourceAddr = (address *) data; // typecast to address to get address from data ( 6 bytes )
	membershiplist *memdata=(membershiplist *) ( sourceAddr + 1 ); // memdata pointer to array of structs

	printf("\n GOSSIP for node %d",node->addr.addr[0]);
	int tablecount=(size - sizeof(address)) / sizeof(membershiplist);
	printf("\nnumber of records received  : %d",tablecount);
	printf("\nnumber of records in its mem table : %d",node->memcount);
	int i=0;

	int j;
	int nodepresentindata=-1;

	for(i=0;i<tablecount;i++){
		printf("\nCHECKING FOR %d",memdata->maddr.addr[0]);
		nodepresentindata=0;
		for(j=0;j<node->memcount;j++){
			printf("\n : FOR %d",node->memtable[j].maddr.addr[0]);

			if(memcmp(&node->memtable[j].maddr,&memdata->maddr,sizeof(address)) == 0 ){

	     		//check if the node's memtable contains the sender's address
				nodepresentindata=1;
				//check if latest update time for this member
				if ( (getcurrtime() - node->memtable[j].lastupdatetime ) < T_CLEANUP /*node->memtable[j].lastupdatetime < memdata->lastupdatetime*/){
					printf("\n UPDATING TIME FOR %d",memdata->maddr.addr[0]);
					//if less check if ur heartbeat is less or more if more modify
					//if ( node->memtable[j].heartbeatCounter < )
					if ( node->memtable[j].heartbeatCounter < memdata->heartbeatCounter ){
						node->memtable[j].heartbeatCounter=memdata->heartbeatCounter;
						node->memtable[j].lastupdatetime = getcurrtime();
					}
				}

				if (  (getcurrtime() - node->memtable[j].lastupdatetime ) > T_CLEANUP   /*(getcurrtime()-node->memtable[j].lastupdatetime) > T_CLEANUP*/ ){
					if ( (getcurrtime() - node->memtable[j].lastupdatetime )  < T_FAIL /*getcurrtime() - memdata->lastupdatetime < T_FAIL */ ){
						node->memtable[j].tocleanup=1;
					} else {
						if ( node->memtable[j].tocleanup != 2){
							node->memtable[j].tocleanup=2;
							printf("\n REMOVING NODE %d",memdata->maddr.addr[0]);
							logNodeRemove(&node->addr,&node->memtable[j].maddr);
						}
					}
				}

			}
		}

		if ( nodepresentindata == 0  ){


			 memcpy(&node->memtable[node->memcount].maddr,&memdata->maddr,sizeof(address));
			 node->memtable[node->memcount].lastupdatetime=memdata->lastupdatetime;
			 node->memtable[node->memcount].tocleanup=memdata->tocleanup;
			 node->memtable[node->memcount].heartbeatCounter=memdata->heartbeatCounter;
			 printf("\nADDING NODE %d",memdata->maddr.addr[0]);
			 logNodeAdd(&node->addr,&memdata->maddr);
			 printf("\nADDING into mem table  node %d",memdata->maddr.addr[0]);
			 node->memcount++;
		}

		memdata++;
	}

	printf("\n\n***** GOSSIP OVER ****\n\n ");

	return;
}
/* 
Received a GOSSIP message. 
*/
void nodeloopops(member *node){

	printf("\n ** INSIDE NODELOOPOPS %d",node->addr.addr[0]);

	if ( getcurrtime() % T_GOSSIP == 0 && node->memcount !=0 ){

		// sending a gossip message by selecting a random node which is not its own
		int n=-1;
		int randomNode=-1;

		// to select random node to send the gossip message
		while(1){
			randomNode = rand() % EN_GPSZ ;
			if ( randomNode == node->nodenumber)
				continue;
			else if ( randomNode > node->memcount)
				continue;
			else if (memcmp(&node->addr,&node->memtable[randomNode].maddr,sizeof(address))==0)
				continue;
			else if (node->memtable[randomNode].tocleanup!=0)
				continue;
			else
				break;

		}

		// when you found the node to send , loop through the  memberlisttable and update your lastupdatetime.
		int i=0;

		for(i=0;i<node->memcount;i++){
			printf("\n check time for %d",node->memtable[i].maddr.addr[0]);
				// check if the mem table contains the node's address
				n = memcmp ( &node->memtable[i].maddr, &node->addr,sizeof(address));
				if ( n == 0 ){
					// update current time for ur node
					printf("\nupdating the getcurrent time");
					// check ur heartbeat and update
					//if ( node->memtable[i].heartbeatCounter < node-)
					node->memtable[i].lastupdatetime=getcurrtime();
					node->memtable[i].heartbeatCounter++;

				}else{
					if ( (getcurrtime() - node->memtable[i].heartbeatCounter) > T_CLEANUP  /*getcurrtime() - node->memtable[i].lastupdatetime > T_CLEANUP  */){
						if ( ( getcurrtime() - node->memtable[i].heartbeatCounter ) < T_FAIL /* getcurrtime() - node->memtable[i].lastupdatetime < T_FAIL */ ) {
							printf("\nTime to set del bit for node %d",node->memtable[i].maddr.addr[0]);
							node->memtable[i].tocleanup=1;
						} else {
							if ( node->memtable[i].tocleanup != 2 ){
								printf("\nTime to mark the node deleted %d",node->memtable[i].maddr.addr[0]);
								node->memtable[i].tocleanup=2;

								logNodeRemove(&node->addr,&node->memtable[i].maddr);
							}
						}
					}

				}
		}

		//create the message containing membership table and send to the sender's node
		messagehdr *msg;
		size_t msgsize = sizeof(messagehdr) + sizeof(address) +(node->memcount) * sizeof(membershiplist);
		msg=malloc(msgsize);
		msg->msgtype=GOSSIPMSG;

		membershiplist *src;
		struct address *temp;
		temp=(struct address*) (msg+1);
		memcpy(temp, &node->addr,sizeof(address));
		src=(membershiplist *)(temp + 1);

		for(i=0;i<node->memcount;i++){
			memcpy(src, &node->memtable[i],sizeof(membershiplist));
			src=src + 1;
		}
    	MPp2psend(&node->addr, &node->memtable[randomNode].maddr, (char *)msg, msgsize);


		// constructing the message to send to random node with message type GOSSIP
		printf("\n Number of records in %d mem table is %d ",node->addr.addr[0],--i);
	}

	printf("\n *** NODELOOP DONE *** ");

    return;
}