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; } }
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; }
//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(); }
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; }
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; }
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; }
//创建新的断路条目 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; }
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; }
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; }
//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; }
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; }
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); }
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; }