?? dsdv.cc
字號:
/* * User Space DSDV Implementation * * Binita Gupta * University of Illinois at Urbana Champaign * * Email: binita@uiuc.edu * * * This software is Open Source under the GNU General Public License * * ******************************************* * * General Description: * ---------------------- * * This file defines all the functions of dsdv class. This is the main file * which implements most of the dadv logic. * * * * * Internal Procedures: * * * * * External Procedures: * * ********************************************* * */#include "common.h"#include "externDec.h"void process_dsdv_handler();void rebootHandler_stub(void *data);void updateHandler_stub(void *data);void periodicHandler_stub(void *data);void global_handler(int type);void sigint_timer_handler(int type);void traffic_handler();/* main dsdv initailize function */void dsdv::dsdv_init(char *interface){ struct sockaddr_in my_addr; if(check_root() == -1) { cout<< "You must be root to run this program" << endl; exit(1); } dsdvSock.createSock(interface, &my_addr); register_handler_function(dsdvSock.getSock(),process_dsdv_handler ); if (get_interface_ip(dsdvSock.getSock(), interface, &my_addr) == -1) { cout << "Error getting Interface IP" << endl; exit(1); } /* open socket for communication with kernel routing table */ ksock = init_krtsocket(); if(ksock == -1) { cout << "Error Initializing kernel socket" << endl; exit(1); } rTableForward.init_KRT(); rTableBroadcast.init_RT(); lastFullDumpTime = 0; is_broadcast = false; /* TRAFFIC */ traffic_sock = open_and_bind_sock(); if(traffic_sock < 0) { cout <<"Error opening traffic socket " << endl; exit(1); } register_handler_function(traffic_sock, traffic_handler ); sprintf(logfile_name,"%s%s%s",LOGFILE_NAME,"_",getDotIP(g_my_ip)); return; }/* TRAFFIC */void traffic_handler(){ dsdvOb.process_traffic_data();}void dsdv::process_traffic_data(){ if(read(traffic_sock,&traffic_data,sizeof(traffic_data)) < 0) { perror("Error in reading from traffic"); } #ifdef DEBUG cout << "dsdv:process_traffic_data: data read is " << traffic_data << endl;#endif if(traffic_data == START_SIMULATION) { /* start counting the routing overhead */ } else if (traffic_data == STOP_SIMULATION) { if((dsdv_log_file = fopen(logfile_name,"a")) == NULL) { perror("Error opening log file"); exit(1); } fprintf(dsdv_log_file,"Routing Overhead is %d\n",routing_overhead_in_bytes); routing_overhead_in_bytes=0; traffic_data = NO_SIMULATION; fclose(dsdv_log_file); } }void dsdv::register_handler_function(int fd, hfunc_t fun){ handlers[handler_cnt].fd = fd; handlers[handler_cnt].func = fun; handler_cnt++; return;}void process_dsdv_handler(){ dsdvOb.process_dsdv();}void dsdv::process_dsdv(){ int length; u_int32_t src; length = dsdvSock.readFromSock(&src); processRecvMsg(src);}void dsdv::processRecvMsg(u_int32_t src){ DSDV_Msg *dsdv_msg; dsdv_msg = (DSDV_Msg*)recvBuffer;#ifdef DEBUG cout << "dsdv:processRecvMsg: entered " << endl;#endif if(src == g_my_ip) {#ifdef DEBUG cout << "dsdv: processREcvMsg: ignore message from the local node " << endl;#endif return; } switch(dsdv_msg->type){ case DSDV_PERIODIC_UPDATE: processPeriodicUpdate(src); break; default:#ifdef DEBUG cout << "dsdv: processRecvMsg: default case" << endl;#endif break; } return;}void dsdv::processPeriodicUpdate(u_int32_t src){#ifdef DEBUG cout << "dsdv:processPeriodicUpdate: not during reboot " << endl;#endif updateMessage umsg; umsg.createMessage(recvBuffer);#ifdef DEBUG umsg.printUpdate();#endif umsg.applyUpdates(src); if( (!duringReboot) && is_broadcast) { is_broadcast=false; broadcastRTable(); }}/* main dsdv daemon function - takes interface name as the input parameter*/int dsdv::dsdv_daemon(char *interface){#ifdef DEBUG cout << "Entered Dsdv_Daemon" << endl;#endif registerSignal(); /* start all relevant timers here */ setRebootTimer(); setPeriodicTimer(); /* do initialization */ dsdv_init(interface); mainDaemonLoop(); return 0;}void dsdv::setRebootTimer(){ struct timerData tData; tData.type = REBOOT_TIMER; tData.data = 0; timer_Q.set_timer_first(DELETE_PERIOD, rebootHandler_stub, (void *)&tData); return;}void rebootHandler_stub(void *data){ dsdvOb.rebootHandler();}void dsdv::rebootHandler(){#ifdef DEBUG cout << "rebootHandler: entered" << endl;#endif duringReboot = false; /* do the first broadcast */ /* check if the local seq num is odd, make it the next even value */ if((localSeqNum%2)==1) { localSeqNum++; rTableForward.setLocalSeqNum(); rTableBroadcast.setLocalSeqNum(); } broadcastRTable(); startUpdateTimer();}void dsdv::startUpdateTimer(){ struct timerData tData; tData.type = PERIODIC_UPDATE_TIMER; tData.data = 0; timer_Q.set_timer(PERIODIC_UPDATE_INTERVAL, updateHandler_stub, (void *)&tData); return;}void updateHandler_stub(void *data){ dsdvOb.updateHandler();}void dsdv::updateHandler(){ /* do a broadcast here */ /* since this is a periodic update, increment the seq num */ rTableForward.incrementLocalSeqNum(); rTableBroadcast.incrementLocalSeqNum(); broadcastRTable(); /*reset the update timer */ struct timerData tData; tData.type = PERIODIC_UPDATE_TIMER; tData.data = 0; timer_Q.set_timer(PERIODIC_UPDATE_INTERVAL, updateHandler_stub, (void *)&tData); return;} void dsdv::setPeriodicTimer(){ struct timerData tData; tData.type = BROKEN_LINK_TIMER; tData.data = 0; timer_Q.set_timer(BROKEN_LINK_TIMER_INTERVAL, periodicHandler_stub, (void *)&tData); return;}void periodicHandler_stub(void *data){ dsdvOb.periodicHandler(); return;}void dsdv::periodicHandler(){ bool doBroadcast=false;#ifdef DEBUG cout << "periodicHandler: add a periodic timer " << endl;#endif /* insert new periodic timer entry */ struct timerData tData; tData.type = BROKEN_LINK_TIMER; tData.data = 0; timer_Q.timer_add(BROKEN_LINK_TIMER_INTERVAL, periodicHandler_stub, (void *)&tData); /* this timer acts as periodic timer for refreshing route table entries */ doBroadcast = rTableForward.refreshEntries(); if(doBroadcast && (!duringReboot)) { /* this is a triggered broadcast .. * don't need to sync routing tables here */ broadcastRTable(); } return;}void dsdv::mainDaemonLoop(){ int nfds=0, ret; fd_set rbits, rfds;#ifdef DEBUG cout << "mainDaemonLoop Entered " << endl;#endif FD_ZERO(&rbits); for(int i=0; i< handler_cnt; i++) { FD_SET(handlers[i].fd,&rbits); if(handlers[i].fd >= nfds) nfds = handlers[i].fd +1; } while(1) { memcpy((char *)&rfds, (char *)&rbits, sizeof(rbits)); if( (ret = select(nfds, &rfds, NULL, NULL, NULL)) < 0) {#ifdef DEBUG cout << "Error in select " << endl;#endif } else { for(int i=0;i<handler_cnt;i++) { if(FD_ISSET(handlers[i].fd, &rfds)) { (*handlers[i].func)(); } } } } return;}int dsdv::registerSignal(){ signal(SIGALRM,global_handler); signal(SIGINT,sigint_timer_handler); return 0;}void global_handler(int type){ dsdvOb.handler(type);}void dsdv::handler(int type){ timer_Q.scheduleTimer();}void sigint_timer_handler(int type){ dsdvOb.sigint_handler(type);}void dsdv::sigint_handler(int type){ free(recvBuffer); free(sendBuffer); exit(1);}void dsdv::settling_time_handler(void *data){ struct timerData *tData; u_int32_t dst; tData = (struct timerData *)data; dst=tData->data; /* since this is an update after settling time period.. * sync both the routing tables */ rTableForward.syncRTables(dst); broadcastRTable(); return;}/* this takes care of broadcast routing updates */void dsdv::broadcastRTable(){ bool full_dump=false; u_int32_t len;#ifdef DEBUG cout << "broadcastRtable: Entered" << endl;#endif full_dump = isFullDumpNeeded(); updateMessage umsg; rTableBroadcast.generateUpdateMessage(&umsg,full_dump); len = 4*(1+3*umsg.getEntriesCnt()); umsg.copyIntoBuf(sendBuffer);#ifdef DEBUG cout << "dsdv:broadcast message is" << endl; umsg.printUpdate();#endif /* send the broadcast list to the network */ send_datagram(sendBuffer,len); return;}bool dsdv::isFullDumpNeeded(){ u_int8_t num_changed_entries=0; u_int64_t currtime=getcurrtime(); if(lastFullDumpTime == 0) { lastFullDumpTime=currtime;#ifdef DEBUG cout << "dsdv:isFullDumpneeded: do full dump " << endl;#endif return true; } else { num_changed_entries = rTableBroadcast.getChangedEntriesCnt(); if((num_changed_entries > (FULL_DUMP_FACTOR * rTableBroadcast.getSize())) || ((currtime - lastFullDumpTime) > MAX_FULL_DUMP_TIMEOUT)) { lastFullDumpTime=currtime;#ifdef DEBUG cout << "dsdv:isFullDumpneeded: do full dump " << endl;#endif return true; } } return false;} /* This function actually writes the periodic update packets out to the wire... * it calls above function to generate the sending buffer*/void dsdv::send_datagram(void *data_buf, int data_len){ struct sockaddr_in their_addr; int len;#ifdef DEBUG cout << "send_datagram: Entered" << endl;#endif bzero((void *)&their_addr,sizeof(struct sockaddr_in)); /* send it out to the broadcast address */ their_addr.sin_family = AF_INET; their_addr.sin_port = htons(DSDVPORT); their_addr.sin_addr.s_addr = BROADCAST_ADDR; bzero(&(their_addr.sin_zero), 8); if(traffic_data == START_SIMULATION) routing_overhead_in_bytes +=data_len; if ( (len = sendto(dsdvSock.getSock(),data_buf,data_len,0,(sockaddr *) &their_addr, sizeof(struct sockaddr)) ) < 0) { perror("Error in sendto"); }#ifdef DEBUG cout<< "send_datagram: num of bytes sent is " << len << endl;#endif return;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -