Ejemplo n.º 1
0
//这个线程每隔ROUTEUPDATE_INTERVAL时间发送路由更新报文.路由更新报文包含这个节点
//的距离矢量.广播是通过设置SIP报文头中的dest_nodeID为BROADCAST_NODEID,并通过son_sendpkt()发送报文来完成的.
void* routeupdate_daemon(void* arg) {
	//你需要编写这里的代码.
	printf("we are now in routeupdate_daemon\n");
	sip_pkt_t *pkt = (sip_pkt_t*)malloc(sizeof(sip_pkt_t)); 
	int entryNum = topology_getNodeNum();
	pkt->header.src_nodeID = topology_getMyNodeID();
	pkt->header.dest_nodeID = BROADCAST_NODEID;
	pkt->header.length = entryNum * sizeof(routeupdate_entry_t) + 4;
	pkt->header.type = ROUTE_UPDATE;
	pkt_routeupdate_t* routeUp = (pkt_routeupdate_t*)pkt->data;
	
	routeUp->entryNum = entryNum;
	//memcpy(routeUp->entry, dv[0].dvEntry, sizeof(dv_t));
	
	while (1) {
		pthread_mutex_lock(dv_mutex);
		memcpy(routeUp->entry, dv[0].dvEntry, sizeof(dv_entry_t) * entryNum);
		son_sendpkt(BROADCAST_NODEID, pkt, son_conn);
		printf("has broadcast to the son\n");
		/*printf("---the sent src_nodeID is %d\n", pkt->header.src_nodeID);
		printf("---the sent dest_nodeID is %d\n", pkt->header.dest_nodeID);
		printf("---the sent length is %d\n", pkt->header.length);
		printf("---the sent type is ROUTE_UPDATE\n");*/
		pthread_mutex_unlock(dv_mutex);
		sleep(ROUTEUPDATE_INTERVAL);
	}
	printf("we are now off routeupdate_daemon\n");
	pthread_exit(NULL);
}
Ejemplo n.º 2
0
//这个线程每隔ROUTEUPDATE_INTERVAL时间发送路由更新报文.路由更新报文包含这个节点
//的距离矢量.广播是通过设置SIP报文头中的dest_NodeID为BROADCAST_NODEID,并通过son_sendpkt()发送报文来完成的.
void* routeupdate_daemon(void* arg) 
{
	int node_num = topology_getNodeNum();
	int nbr_num = topology_getNbrNum();
	pkt_routeupdate_t routemsg;

	while(1){
		sleep(ROUTEUPDATE_INTERVAL);
		sip_pkt_t sendbuf;
		memset(&sendbuf, 0, sizeof sendbuf);
		sendbuf.header.type = ROUTE_UPDATE;
		sendbuf.header.dest_nodeID = BROADCAST_NODEID;
		sendbuf.header.src_nodeID = topology_getMyNodeID();
		sendbuf.header.length = sizeof(pkt_routeupdate_t);

		//add the content of route update packet	
		int i = 0;
		routemsg.entryNum = node_num;
		pthread_mutex_lock(dv_mutex);
		for(i = 0; i < node_num; i++){
			//dv[nbr_num] is the node itself's distance vector
			routemsg.entry[i].nodeID = dv[nbr_num].dvEntry[i].nodeID;
			routemsg.entry[i].cost = dv[nbr_num].dvEntry[i].cost;
		}
		pthread_mutex_unlock(dv_mutex);
		memcpy(sendbuf.data, &routemsg, sizeof routemsg);

		if(son_sendpkt(BROADCAST_NODEID, &sendbuf, son_conn) == -1){
			printf("sip:  can't send routeupdate msg\n");
		//	break;
		}
	}
	pthread_exit(NULL);
}
Ejemplo n.º 3
0
//这个函数动态创建距离矢量表.
//距离矢量表包含n+1个条目, 其中n是这个节点的邻居数,剩下1个是这个节点本身.
//距离矢量表中的每个条目是一个dv_t结构,它包含一个源节点ID和一个有N个dv_entry_t结构的数组, 其中N是重叠网络中节点总数.
//每个dv_entry_t包含一个目的节点地址和从该源节点到该目的节点的链路代价.
//距离矢量表也在这个函数中初始化.从这个节点到其邻居的链路代价使用提取自topology.dat文件中的直接链路代价初始化.
//其他链路代价被初始化为INFINITE_COST.
//该函数返回动态创建的距离矢量表.
dv_t* dvtable_create()
{
    int nbr_count = topology_getNbrNum();
    int * nbr_array = topology_getNbrArray();
    int node_count = topology_getNodeNum();
    int * node_array = topology_getNodeArray();
    dv_t * dvtable = (dv_t *)malloc( sizeof(dv_t) * (nbr_count + 1) );
    memset(dvtable, 0, sizeof(dv_t) * (nbr_count+1) );

    int i, j;
    // the first dv_t has nodeID of itself.
    dvtable[0].nodeID = topology_getMyNodeID();
    dvtable[0].dvEntry = (dv_entry_t *)malloc(sizeof(dv_entry_t)*(node_count));
    memset(dvtable[0].dvEntry, 0, sizeof(dv_entry_t)*(node_count));
    for (j = 0; j < node_count; ++j) {
        dvtable[0].dvEntry[j].nodeID = node_array[j];
        dvtable[0].dvEntry[j].cost = topology_getCost(dvtable[0].nodeID, node_array[j]);
        if (dvtable[0].nodeID == dvtable[0].dvEntry[j].nodeID)
            dvtable[0].dvEntry[j].cost = 0;

    }



    for (i = 1; i < nbr_count+1; ++i) {
        dvtable[i].nodeID = nbr_array[i-1];
        dvtable[i].dvEntry = (dv_entry_t *)malloc( sizeof(dv_entry_t)*node_count);
        memset(dvtable[i].dvEntry, 0, sizeof(dv_entry_t)*node_count);
        for (j = 0; j < node_count; ++j) {
            dvtable[i].dvEntry[j].nodeID = node_array[j];
            dvtable[i].dvEntry[j].cost = INFINITE_COST;
        }
    }
    return dvtable;
}
Ejemplo n.º 4
0
int dventry_getcost(dv_entry_t *dve, int dest_node) {
    int node_num = topology_getNodeNum();
    int i = 0;
    for (i = 0; i < node_num; ++i) {
        if (dve[i].nodeID == dest_node)
            return dve[i].cost;
    }
    return INFINITE_COST;
}
Ejemplo n.º 5
0
int debugTopology()
{
	topology_analysis();
	printf("nbr :%d node %d \n", topology_getNbrNum(), topology_getNodeNum());
	int i = 0;
	for(i = 0; i < nbrNum; i++)
		printf("%d ", nbrIDArray[i]);
	printf("\n");
	for(i = 0; i < nodeNum; i++)
		printf("%d ", nodeArray[i]);
	printf("\n");
}
Ejemplo n.º 6
0
int dventry_setcost(dv_entry_t *dve, int dest_node,  int cost) {
    int node_num = topology_getNodeNum();
    int i = 0;
    for (i = 0; i < node_num; ++i) {
        if (dve[i].nodeID == dest_node) {
            dve[i].cost = cost;
            return 1;
        }
    }
    printf("panic: %s dest_node not found.\n", __FUNCTION__);
    return -1;
}
Ejemplo n.º 7
0
//这个函数动态创建距离矢量表.
//距离矢量表包含n+1个条目, 其中n是这个节点的邻居数,剩下1个是这个节点本身.
//距离矢量表中的每个条目是一个dv_t结构,它包含一个源节点ID和一个有N个dv_entry_t结构的数组, 其中N是重叠网络中节点总数.
//每个dv_entry_t包含一个目的节点地址和从该源节点到该目的节点的链路代价.
//距离矢量表也在这个函数中初始化.从这个节点到其邻居的链路代价使用提取自topology.dat文件中的直接链路代价初始化.
//其他链路代价被初始化为INFINITE_COST.
//该函数返回动态创建的距离矢量表.
dv_t* dvtable_create()
{
	getTopoData();
	nbn=topology_getNbrNum();
	int *nbList=topology_getNbrArray();
	int *costList=topology_getNbrCost();
	alln=topology_getNodeNum();
	int *allList=topology_getNodeArray();

	dv_t *dvList=malloc((nbn+1)*sizeof(dv_t));
	if(dvList==NULL)exit(-1);
	int i=0;
	//init nerghbor 
	for(;i<nbn;i++)
	{
		dvList[i].nodeID=nbList[i];
		dvList[i].dvEntry=malloc(alln*sizeof(dv_entry_t));
		int j=0;
		for(;j<alln;j++)
		{
			dvList[i].dvEntry[j].nodeID=allList[j];
			dvList[i].dvEntry[j].cost=INFINITE_COST;
		}
	}
	
	//init this node
	dvList[nbn].nodeID=topology_getMyNodeID();
	dvList[nbn].dvEntry=malloc(alln*sizeof(dv_entry_t));
	for(i=0;i<alln;i++)
	{
		dvList[nbn].dvEntry[i].nodeID=allList[i];
		if(allList[i]==dvList[nbn].nodeID)
		{
			dvList[nbn].dvEntry[i].cost=0;
			continue;
		}
		int j=0;
		for(;j<nbn;j++)
		{
			if(allList[i]==nbList[j])
			{
				dvList[nbn].dvEntry[i].cost=costList[j];
				break;
			}
		}
		if(j==nbn)
			dvList[nbn].dvEntry[i].cost=INFINITE_COST;
	}
	return dvList;
}
Ejemplo n.º 8
0
//这个函数返回距离矢量表中2个节点之间的链路代价.
//如果这2个节点在表中发现了,就返回链路代价,否则返回INFINITE_COST.
unsigned int dvtable_getcost(dv_t* dvtable, int fromNodeID, int toNodeID)
{
    int i, j;
    int nbr_count = topology_getNbrNum();
    int node_count = topology_getNodeNum();
    for (i = 0; i < nbr_count + 1; ++i) {
        if (dvtable[i].nodeID == fromNodeID) break;
    }
    if (i == nbr_count + 1 || dvtable[i].nodeID != fromNodeID)
        return INFINITE_COST;
    for (j = 0; j < node_count; ++j) {
        if (dvtable[i].dvEntry[j].nodeID == toNodeID)
            return dvtable[i].dvEntry[j].cost;
    }
    return INFINITE_COST;
}
Ejemplo n.º 9
0
//这个函数打印距离矢量表的内容.
void dvtable_print(dv_t* dvtable)
{
    int i, j;
    int nbr_count = topology_getNbrNum();
    int node_count = topology_getNodeNum();

    for (i = 0; i < nbr_count + 1; ++i) {
        printf("from node %d:\t", dvtable[i].nodeID);
        for (j = 0; j < node_count; ++j) {
            printf("[ #%3d = %3d ]",
                   dvtable[i].dvEntry[j].nodeID, dvtable[i].dvEntry[j].cost);
        }
        putchar('\n');
    }
    return;
}
Ejemplo n.º 10
0
//这个线程每隔ROUTEUPDATE_INTERVAL时间发送路由更新报文.路由更新报文包含这个节点
//的距离矢量.广播是通过设置SIP报文头中的dest_nodeID为BROADCAST_NODEID,并通过son_sendpkt()发送报文来完成的.
void* routeupdate_daemon(void* arg) {
	sip_pkt_t *update_sip = (sip_pkt_t*)malloc(sizeof(sip_pkt_t));
	pkt_routeupdate_t *routeupdate_pkt = (pkt_routeupdate_t*)malloc(sizeof(pkt_routeupdate_t));
	int i = 0;
	//settings
	int node_num = topology_getNodeNum();
	int nbr_num = topology_getNbrNum();
	routeupdate_pkt->entryNum = node_num;
	int local_nodeID = topology_getMyNodeID();
	//find local node distance vector
	//int my_dv = 0;
	dv_entry_t *my_dv_entry = NULL;
	for(i = 0;i < nbr_num + 1;i++)
	{
		if(local_nodeID == dv[i].nodeID)
		{
			my_dv_entry = dv[i].dvEntry;
			break;
		}
	}
	update_sip->header.src_nodeID = topology_getMyNodeID();;
	update_sip->header.dest_nodeID = BROADCAST_NODEID;
	update_sip->header.length = sizeof(pkt_routeupdate_t);
	update_sip->header.type = ROUTE_UPDATE;
	while(1)
	{
		sleep(ROUTEUPDATE_INTERVAL);
		//printf("SIP: Update Broadcast\n");
		pthread_mutex_lock(dv_mutex);
		for(i = 0;i < node_num;i++)
		{
			routeupdate_pkt->entry[i].nodeID = my_dv_entry[i].nodeID;
			routeupdate_pkt->entry[i].cost = my_dv_entry[i].cost;
			printf("【Send】update entry %d: nodeID %d \tcost %d\n",i,routeupdate_pkt->entry[i].nodeID,routeupdate_pkt->entry[i].cost);
		}
		memcpy(update_sip->data,routeupdate_pkt,update_sip->header.length);
		pthread_mutex_unlock(dv_mutex);
		if(son_conn != -1 && son_sendpkt(BROADCAST_NODEID,update_sip,son_conn) > 0)
			printf("SIP send a pkt to SON\n");
		else
			son_conn = -1;
		//printf("SIP: Broadcast Done\n");
	}
	return 0;
}
Ejemplo n.º 11
0
//这个函数解析保存在文件topology.dat中的拓扑信息.
//返回一个动态分配的数组, 它包含重叠网络中所有节点的ID. 
int* topology_getNodeArray(){
	int num = topology_getNodeNum();
	int *nodeID = (int *)malloc(sizeof(int)*num);
	memset(nodeID, 0, sizeof(int)*num);
	int i = 0;
	char buf[MAX_LENGTH];
	FILE *file = fopen("../topology/ip_info.dat", "r");
	if(file == NULL)
		return NULL;
	char *p;
	while( fgets(buf, MAX_LENGTH, file) ){
		p = strtok(buf, "\t\b\n\v\r ");
		p = strtok(NULL,"\t\b\n\v\r ");
		nodeID[i++] = (ntohl((int)(inet_addr(p)))&0x0ff);
	}
	fclose(file);
	return nodeID;
}
Ejemplo n.º 12
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);
}
Ejemplo n.º 13
0
//this functions parses the topology information stored in topology.dat
//returns a dynamically allocated array which contains all the nodes' IDs in the overlay network  
int* topology_getNodeArray()
{
	int numNodes;
	if ((numNodes = topology_getNodeNum()) <= 0) {
		printf("Error getting total number of nodes from getNodeArray.\n");
		return NULL;
	}
  	int *nodeIDs = malloc(sizeof(int)*numNodes);
  	memset(nodeIDs, 0, sizeof(int)* numNodes);
  	int i;
  	for (i = 0; i < numNodes; i++) {
  		nodeIDs[i] = -1;
  	}

  	//get topology.dat
	char *fileName = "../topology/topology.dat";
	FILE *pFile = fopen(fileName, "r");
	if (pFile == NULL) {
		perror("Error getting file in getNodeArray.\n");
		return NULL;
	}

	char buffer[200];
	char host1[100];
	char host2[200];
	int h1, h2;
	unsigned int num;
	while (fgets(buffer, sizeof(buffer), pFile)){
		sscanf(buffer, "%s %s %u\n", host1, host2, &num);
		if ((h1 = topology_getNodeIDfromname(host1)) < 0 || (h2 = topology_getNodeIDfromname(host2)) < 0){
			printf("Error. host1 = %s, h1 = %d, host2 = %s, h2 = %d\n", host1, h1, host2, h2);
			return NULL;
		}

		int j = 0;
		while (nodeIDs[j] != -1) {
			if (h1 == nodeIDs[j]) {
				j = -1;
				break;
			}
			j++;
		}
		if (j != -1 && j < MAX_NODE_NUM) {
			nodeIDs[j] = h1;
		}
		j = 0;
		while (nodeIDs[j] != -1) {
			if (h2 == nodeIDs[j]) {
				j = -1;
				break;
			}
			j++;
		}
		if (j != -1 && j < MAX_NODE_NUM) {
			nodeIDs[j] = h2;
		}


		memset(buffer, 0, sizeof(char)*200);
		memset(host1, 0, sizeof(char)*100);
		memset(host2, 0, sizeof(char)*100);
	}
	//printf("Topology.c returning node array with nodes: ");
	//for (i = 0; i < numNodes; i++) {
  	//	printf("%d ", nodeIDs[i]);
  	//}
	//printf("\n");
	fclose(pFile);
	return nodeIDs;
}
Ejemplo n.º 14
0
//这个线程处理来自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);
}
Ejemplo n.º 15
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);
}