示例#1
0
文件: sip.c 项目: ITanCh/netlab-NJU
//这个线程处理来自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);
}
示例#2
0
//这个线程处理来自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);
}
示例#3
0
//这个线程处理来自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);
}