//这个线程处理来自SON进程的进入报文. 它通过调用son_recvpkt()接收来自SON进程的报文. //如果报文是SIP报文,并且目的节点就是本节点,就转发报文给STCP进程. 如果目的节点不是本节点, //就根据路由表转发报文给下一跳.如果报文是路由更新报文,就更新距离矢量表和路由表. void* pkthandler(void* arg) { sip_pkt_t pkt; while(son_conn != -1 && son_recvpkt(&pkt,son_conn) > 0) { //printf("Routing: received a packet from neighbor %d\n",pkt.header.src_nodeID); //printf("sip[INFO] dest:%d length:%d type:%d\n",pkt.header.dest_nodeID, pkt.header.length, pkt.header.type); if(pkt.header.type == ROUTE_UPDATE) { // broadcast update pkt_routeupdate_t *route_update = (pkt_routeupdate_t*)pkt.data; //preparations int entry_num = route_update->entryNum; routeupdate_entry_t *rupentry = route_update->entry; int src_nodeID = pkt.header.src_nodeID; int local_nodeID = topology_getMyNodeID(); int nbr_num = topology_getNbrNum(); int node_num = topology_getNodeNum(); //int *nbr_array = topology_getNbrArray(); dv_entry_t *local_dv = NULL; int i = 0; int j = 0; int cost1 = 0; int cost2 = 0; printf("SIP got ROUTE_UPDATE pkt from node(%d)\n",src_nodeID); for(i = 0;i < node_num;i++) printf("【Recv】update entry %d: nodeID %d \tcost %d\n",i,rupentry[i].nodeID,rupentry[i].cost); pthread_mutex_lock(dv_mutex); pthread_mutex_lock(routingtable_mutex); for(i = 0;i < entry_num;i++) dvtable_setcost(dv,src_nodeID,rupentry[i].nodeID,rupentry[i].cost); for(j = 0;j < nbr_num + 1;j++) if(local_nodeID == dv[j].nodeID) { local_dv = dv[j].dvEntry; break; } for(i = 0;i < node_num;i++) { int dest_nodeID = local_dv[i].nodeID; int old_cost = local_dv[i].cost; //for(j = 0;j < nbr_num;j++) //{ int medi_nodeID = src_nodeID; cost1 = nbrcosttable_getcost(nct,medi_nodeID); cost2 = dvtable_getcost(dv,medi_nodeID,dest_nodeID); if(cost1 + cost2 < old_cost) { printf("update dvtable and routingtable\n"); dvtable_setcost(dv,local_nodeID,dest_nodeID,cost1+cost2); routingtable_setnextnode(routingtable,dest_nodeID,medi_nodeID); } //} } pthread_mutex_unlock(dv_mutex); pthread_mutex_unlock(routingtable_mutex); } else if(pkt.header.type == SIP) { int local_nodeID = topology_getMyNodeID(); if(pkt.header.dest_nodeID == local_nodeID) { //forward pkt to stcp printf("SIP forward pkt to STCP\n"); forwardsegToSTCP(stcp_conn,pkt.header.src_nodeID,(seg_t*)pkt.data); } else { //forward pkt to son int next_nodeID = routingtable_getnextnode(routingtable,pkt.header.dest_nodeID); son_sendpkt(next_nodeID,&pkt,son_conn); printf("SIP forward pkt to SON to node %d\n",next_nodeID); } } } close(son_conn); son_conn = -1; pthread_exit(NULL); }
//这个线程处理来自SON进程的进入报文. 它通过调用son_recvpkt()接收来自SON进程的报文. //如果报文是SIP报文,并且目的节点就是本节点,就转发报文给STCP进程. 如果目的节点不是本节点, //就根据路由表转发报文给下一跳.如果报文是路由更新报文,就更新距离矢量表和路由表. void* pkthandler(void* arg) { sip_pkt_t pkt; int myNodeID = topology_getMyNodeID(); int nbr_num = topology_getNbrNum(); int node_num = topology_getNodeNum(); while(son_recvpkt(&pkt,son_conn)>0) { // printf("Routing: received a packet from neighbor %d\n",pkt.header.src_nodeID); switch(pkt.header.type){ case ROUTE_UPDATE: pthread_mutex_lock(dv_mutex); pthread_mutex_lock(routingtable_mutex); pkt_routeupdate_t *routemsg = (pkt_routeupdate_t *)pkt.data; int i, j, srcNode = pkt.header.src_nodeID; printf("receive ROUTE UPDATE MESSAGE FROM NODE %d\n", srcNode); for(j = 0; j < routemsg->entryNum; j ++) dvtable_setcost(dv, srcNode, routemsg->entry[j].nodeID, routemsg->entry[j].cost); for(i = 0;i < nbr_num + 1;i ++) { if(myNodeID == dv[i].nodeID) break; } dv_entry_t *myEntry = dv[i].dvEntry; int *nbr = topology_getNbrArray(); for(i = 0; i < node_num; i ++) { int destNode = myEntry[i].nodeID; for(j = 0;j < nbr_num;j ++) { int viaNode = nbr[j]; int firstCost = nbrcosttable_getcost(nct, viaNode); int lastCost = dvtable_getcost(dv, viaNode, destNode); if(firstCost + lastCost < dvtable_getcost(dv, myNodeID, destNode)) { printf("now update routing table\n"); printf("to destNode %d via nextNode %d \n", destNode, viaNode); dvtable_setcost(dv, myNodeID, destNode, firstCost + lastCost); routingtable_setnextnode(routingtable, destNode, viaNode); } } } pthread_mutex_unlock(routingtable_mutex); pthread_mutex_unlock(dv_mutex); break; case SIP: if(pkt.header.dest_nodeID == topology_getMyNodeID()){ seg_t seg_data; memcpy(&seg_data, pkt.data, sizeof(seg_t)); printf("RECEIVE PKT, destNode is me "); if(forwardsegToSTCP(stcp_conn, pkt.header.src_nodeID, &seg_data) == -1) printf("failed forwarding the seg to local STCP \n"); else printf("FORWARD the seg to local STCP \n"); } else{ pthread_mutex_lock(routingtable_mutex); int nextNodeID = routingtable_getnextnode(routingtable, pkt.header.dest_nodeID); pthread_mutex_unlock(routingtable_mutex); if(son_sendpkt(nextNodeID, &pkt, son_conn) == -1) printf("can't send pkt to son \n"); else printf("RECEIVE PKT but DESTNODE is %d SO TRANSMIT it to nextNodeID %d\n", pkt.header.dest_nodeID, nextNodeID); } break; } } pthread_exit(NULL); }
//这个线程处理来自SON进程的进入报文. 它通过调用son_recvpkt()接收来自SON进程的报文. //如果报文是SIP报文,并且目的节点就是本节点,就转发报文给STCP进程. 如果目的节点不是本节点, //就根据路由表转发报文给下一跳.如果报文是路由更新报文,就更新距离矢量表和路由表. void* pkthandler(void* arg) { //你需要编写这里的代码. printf("we are now in pkthandler in sip!\n"); sip_pkt_t pkt; int slot_num; routingtable_entry_t *ptr; int myID = topology_getMyNodeID(); while(son_recvpkt(&pkt,son_conn) > 0) { if (pkt.header.type == SIP) { printf("Routing: received a packet from neighbor %d\n",pkt.header.src_nodeID); //printf("---the received dest_nodeID is %d\n", pkt.header.dest_nodeID); //printf("---the received length is %d\n", pkt.header.length); //printf("---the received type is SIP\n"); if (pkt.header.dest_nodeID == myID) { forwardsegToSTCP(stcp_conn, pkt.header.src_nodeID, (seg_t*)pkt.data); switch(((seg_t*)(pkt.data))->header.type) { case 0: printf("SIP forward up the seg --SYN-- to the STCP!\n"); break; case 1: printf("SIP forward up the seg --SYNACK-- to the STCP!\n"); break; case 2: printf("SIP forward up the seg --FIN-- to the STCP!\n"); break; case 3: printf("SIP forward up the seg --FINACK-- to the STCP!\n"); break; case 4: printf("SIP forward up the seg --DATA-- to the STCP! and the service is %d the message is %s\n", ((struct packet_IM*)(((seg_t*)(pkt.data))->data))->service, ((struct packet_IM*)(((seg_t*)(pkt.data))->data))->message); break; case 5: printf("SIP forward up the seg --DAYAACK-- to the STCP!\n"); break; } } else { slot_num = makehash(pkt.header.dest_nodeID); ptr = routingtable->hash[slot_num]; while (ptr != NULL) {//寻找是否存在给定目的节点的路由条目 if (pkt.header.dest_nodeID == ptr->destNodeID) break; ptr = ptr->next; } if (ptr != NULL) {//根据路由表转发报文给下一跳 son_sendpkt(ptr->nextNodeID, &pkt, son_conn); printf("SIP forward down the seg to the SON, the nextnode%d!\n", ptr->nextNodeID); } } } else if (pkt.header.type == ROUTE_UPDATE) { /*================本实验精华所在================*/ //printf("---the received type is ROUTE_UPDATE\n"); pkt_routeupdate_t *routeUp = (pkt_routeupdate_t *)pkt.data; pthread_mutex_lock(dv_mutex); pthread_mutex_lock(routingtable_mutex); int i, j, srcNode = pkt.header.src_nodeID; int entryNum = topology_getNodeNum(), nbrNum = topology_getNbrNum(); for(j = 0;j < entryNum;j ++) dvtable_setcost(dv, srcNode,routeUp->entry[j].nodeID, routeUp->entry[j].cost); for(i = 0;i < entryNum;i ++) { if(topology_getMyNodeID() == (dv + i)->nodeID) break; } dv_entry_t *myEntry = (dv + i)->dvEntry; int *nbr = topology_getNbrArray(); for(i = 0;i < entryNum;i ++) { srcNode = topology_getMyNodeID(); int destNode = (myEntry + i)->nodeID; for(j = 0;j < nbrNum;j ++) { int midNode = *(nbr + j); int firstCost = nbrcosttable_getcost(nct, midNode); int lastCost = dvtable_getcost(dv, midNode, destNode); if(firstCost + lastCost < dvtable_getcost(dv, srcNode, destNode)) { dvtable_setcost(dv, srcNode, destNode, firstCost + lastCost); routingtable_setnextnode(routingtable, destNode, midNode); } } } pthread_mutex_unlock(routingtable_mutex); pthread_mutex_unlock(dv_mutex); } else { printf("error type\n"); //exit(0); } } close(son_conn); son_conn = -1; printf("we are now off pkthandler!\n"); pthread_exit(NULL); }