示例#1
0
// 这个函数连接到节点ID比自己小的所有邻居.
// 在所有外出连接都建立后, 返回1, 否则返回-1.
int connectNbrs() {
	int mynode= topology_getMyNodeID();
	int mynbrnum = topology_getNbrNum();
	int *nbrlist = topology_getNbrArray();
	int i=0;
	for(i=0; i<mynbrnum; i++) {
		if(nbrlist[i] < mynode) {
			int sockfd;
			struct sockaddr_in serv_addr;
			if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) <0) {
				perror("Error create socket!\n");
				return -1;
			}
			memset(&serv_addr, 0, sizeof(serv_addr));
			serv_addr.sin_family = AF_INET;
            serv_addr.sin_addr.s_addr = topology_getfromIDtoIP(nbrlist[i]);
            serv_addr.sin_port = htons(CONNECTION_PORT);
            if(connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr))<0) {
				perror("Error connect\n");
				return -1;
			}
			nt_addconn(nt, nbrlist[i], sockfd);
		}
	}
	return 1;
}
示例#2
0
//This function creates a routing table dynamically.
//All the entries in the table are initialized to NULL pointers.
//Then for all the neighbors with a direct link, create a routing entry using the neighbor itself as the 
//next hop node, and insert this routing entry into the routing table. 
//The dynamically created routing table structure is returned.
routingtable_t* routingtable_create()
{
	routingtable_t *routingTable = malloc(sizeof(routingtable_entry_t *)*MAX_ROUTINGTABLE_SLOTS);
	memset(routingTable, 0, sizeof(routingtable_entry_t *)*MAX_ROUTINGTABLE_SLOTS);

	//initialize all hash entries to NULL
	for (int i = 0; i < MAX_ROUTINGTABLE_SLOTS; i++) {
		routingTable->hash[i] = NULL;
	}
 	
 	//initialize neighbors
	int* nbrArray = topology_getNbrArray();
	int numNbrs = topology_getNbrNum();
	for (int j = 0; j < numNbrs; j++){
		routingtable_entry_t *temp = malloc(sizeof(routingtable_entry_t));
		temp->destNodeID = nbrArray[j];
		temp->nextNodeID = nbrArray[j];
		temp->next = NULL;
		int tempHash = makehash(nbrArray[j]);
		if (routingTable->hash[tempHash] == NULL) {
			routingTable->hash[tempHash] = temp;
		} else {
			routingtable_entry_t *tempEntry = routingTable->hash[tempHash];
			while (tempEntry->next != NULL) {
				tempEntry = tempEntry->next;
			}
			tempEntry->next = temp;
		}
	}

	//routingtable_print(routingTable);
	free(nbrArray);
 	return routingTable;
}
示例#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;
}
示例#4
0
//这个函数首先动态创建一个邻居表. 然后解析文件topology/topology.dat, 填充所有条目中的nodeID和nodeIP字段, 将conn字段初始化为-1.
//返回创建的邻居表.
nbr_entry_t* nt_create()
{
    int i;
    int num_nbr = topology_getNbrNum();//获取邻居节点数
    nbr_entry_t* nt = (nbr_entry_t*)malloc(num_nbr * sizeof(struct neighborentry));//创建邻居表空间
    int* temp = topology_getNbrArray();//获取邻居节点ID数组
    for (i = 0; i < num_nbr; i++) {
        nt[i].nodeID = temp[i];/////////////////
        nt[i].nodeIP = (0x72D4BE << 8) + temp[i];
        nt[i].conn = -1;
    }
    return nt;
}
示例#5
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;
}
示例#6
0
//这个函数动态创建路由表.表中的所有条目都被初始化为NULL指针.
//然后对有直接链路的邻居,使用邻居本身作为下一跳节点创建路由条目,并插入到路由表中.
//该函数返回动态创建的路由表结构.
routingtable_t* routingtable_create()
{
	routingtable_t * my_route = (routingtable_t *)malloc(sizeof(routingtable_t));
	int i = 0;
	for(i=0; i<MAX_ROUTINGTABLE_SLOTS; i++) {
		my_route->hash[i] = NULL;
	}
	int nbrnum = topology_getNbrNum();
	int *nbrlist = topology_getNbrArray();
	int j;
	for( j=0; j<nbrnum; j++) {
		routingtable_setnextnode(my_route, nbrlist[j], nbrlist[j]);
	}
	return my_route;
}
示例#7
0
//这个函数动态创建邻居代价表并使用邻居节点ID和直接链路代价初始化该表.
//邻居的节点ID和直接链路代价提取自文件topology.dat. 
nbr_cost_entry_t* nbrcosttable_create()
{
	int nbrnum = topology_getNbrNum();
	nbr_cost_entry_t *nbr_table = (nbr_cost_entry_t*)malloc(sizeof(nbr_cost_entry_t));
	int* nbrlist = topology_getNbrArray();
	int mynode  = topology_getMyNodeID();
	int i = 0;
	for(i = 0; i<nbrnum; i++) {
		nbr_table[i].nodeID = nbrlist[i];
		nbr_table[i].cost = topology_getCost(mynode, nbrlist[i]);
		nbr_table[i].flag = 0;
		pthread_mutex_init(&nbr_table[i].flag_mutex, NULL);
	}
	return nbr_table;
}
示例#8
0
//这个函数首先动态创建一个邻居表. 然后解析文件topology/topology.dat, 填充所有条目中的nodeID和nodeIP字段, 将conn字段初始化为-1.
//返回创建的邻居表.
nbr_entry_t* nt_create()
{
  	int entry_num = topology_getNbrNum();
	nbr_entry_t *neighbor_table = (nbr_entry_t *)malloc(sizeof(nbr_entry_t) * nbr_entry_num);
	nbr_entry_t *neighbor_entry = neighbor_table;
	
	int *node_id_array = topology_getNbrArray();
	
	int i;
	for (i = 0; i < entry_num; i++) {
		neighbor_entry -> nodeID = node_id_array[i];
		neighbor_entry -> nodeIP = htonl(topology_getLocalIP() | node_id_array[i]);
		neighbor_entry -> conn = -1;
		neighbor_entry ++;
	}
	neighbor_entry = NULL;
	free(node_id_array);
	return neighbor_table;
}
示例#9
0
//这个函数动态创建路由表.表中的所有条目都被初始化为NULL指针.
//然后对有直接链路的邻居,使用邻居本身作为下一跳节点创建路由条目,并插入到路由表中.
//该函数返回动态创建的路由表结构.
routingtable_t* routingtable_create()
{
	routingtable_t *route_table = (routingtable_t *)malloc(sizeof (routingtable_t));
	int i = 0;
	for(i = 0; i < MAX_ROUTINGTABLE_SLOTS; i++)
		route_table->hash[i] = NULL;
	int nbrnum = topology_getNbrNum();
	int *nbrArray = topology_getNbrArray();
	for(i = 0; i < nbrnum; i++){
		int nextNodeID = nbrArray[i];
		int index = makehash(nextNodeID);
		routingtable_entry_t *temp = route_table->hash[index];
		routingtable_entry_t *new_entry = (routingtable_entry_t *)malloc(sizeof(routingtable_entry_t));
		new_entry->destNodeID = nextNodeID;
		new_entry->nextNodeID = nextNodeID;
		new_entry->next = temp;
		route_table->hash[index] = new_entry;
	}
	return route_table;
}
示例#10
0
//这个函数首先动态创建一个邻居表. 然后解析文件topology/topology.dat, 填充所有条目中的nodeID和nodeIP字段, 将conn字段初始化为-1.
//返回创建的邻居表.
nbr_entry_t *nt_create()
{
    int this_id = topology_getMyNodeID();
    in_addr_t this_ip = topology_getIP();
    int nr_nbrs = topology_getNbrNum();
    int *nbrs = topology_getNbrArray();

    log("%d has %d neighbors", this_id, nr_nbrs);

    nbr_entry_t *table = calloc((size_t)nbrs, sizeof(*table));
    for (int i = 0; i < nr_nbrs; i++) {
        log("create nbr table entry for %d", nbrs[i]);
        table[i].conn = -1;
        table[i].nodeID = nbrs[i];
        table[i].nodeIP = (this_ip & (~0xFF)) | nbrs[i];
    }

    free(nbrs);
    return table;
}
示例#11
0
// 这个线程打开TCP端口CONNECTION_PORT, 等待节点ID比自己大的所有邻居的进入连接,
// 在所有进入连接都建立后, 这个线程终止.
void* waitNbrs(void* arg) {
	int connfd;
	int mynode= topology_getMyNodeID();
	int mynbrnum = topology_getNbrNum();
	int *nbrlist = topology_getNbrArray();
	int listenq=0;
	int i = 0;
	for(i=0; i<mynbrnum; i++) {
		if(nbrlist[i]>mynode)
			listenq++;
	}
	socklen_t clilen;
	struct sockaddr_in cli_addr, serv_addr;
	if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		 perror("Error create socket\n");
		 exit(-1);
	}
	const int one = 1;	//port可以立即重新使用
	setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one) );
	memset(&serv_addr,0,sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = INADDR_ANY;
	serv_addr.sin_port = htons(CONNECTION_PORT);
	if(bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr))<0) {
		perror("Error bind\n");
		exit(-1);
	}
	listen(listenfd, MAX_NODE_NUM);
	clilen = sizeof(cli_addr);
	for(i=0; i<listenq; i++) {
		connfd = accept(listenfd, (struct sockaddr *)&cli_addr, &clilen);
		int node = topology_getNodeIDfromip(&cli_addr.sin_addr);
		if(nt_addconn(nt, node, connfd) == -1) {
			printf("Error add!\n");
		}
		printf("Add Node: %d\n", node);
	}
	return 0;
}
示例#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);
}
示例#13
0
void* waitNbrs(void* arg) {
	//你需要编写这里的代码.
	int connfd, listenfd;
	socklen_t clilen;
	struct sockaddr_in cliaddr, servaddr;

	clilen = sizeof(cliaddr);
	memset(&cliaddr, 0, sizeof(cliaddr));
	memset(&servaddr, 0, sizeof(servaddr));

	listenfd = socket(AF_INET, SOCK_STREAM, 0);
	
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(CONNECTION_PORT);

	print_pos();
	printf("\tMSG: son listen son at %s:%d\n", inet_ntoa(servaddr.sin_addr), CONNECTION_PORT);
	const int on = 1;
	int res;
	res = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(const int));
	if (res != 0) {
		print_pos();
		printf("SON ERROR: setsockopt failed\n");
	}
	res = bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
	if (res != 0) {
		print_pos();
		printf("SON ERROR: bind failed\n");
	}
	res = listen(listenfd, 10);
	if (res != 0) {
		print_pos();
		printf("SON ERROR: listen failed\n");
	}

	// get my node id
	int myNodeID = topology_getMyNodeID();
//	print_pos();
//	printf("\tMSG: MyNodeID = %d\n", myNodeID);
	if (myNodeID == -1){
		print_pos();
		printf("ERROR: get my node id failed\n");
		exit(1);
	}
	// get my neighbor number
	int nbrNum = topology_getNbrNum();
	int *nbr = topology_getNbrArray();

	// count connect nbr
	int t = 0, i = 0;
	for (; t < nbrNum; t++) if (nbr[t] > myNodeID) i++;

//	print_pos();
//	printf("MSG: I should accept %d connects\n", i);
	for (; i > 0; i --){
//		print_pos();
//		printf("MSG: wait son connect...\n");
		connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);
		if (connfd == -1){
			print_pos();
			printf("MSG: accept failed, retry, errno=%s\n", strerror(errno));
			i++;
			continue;
		}
		// get neighbor node id
		int nbrNodeID = topology_getNodeIDfromip(&cliaddr.sin_addr);

//		print_pos();
//		printf("MSG: accept %s\n", inet_ntoa(cliaddr.sin_addr));
		//		if (nbrNodeID > myNodeID){
//		print_pos();
//		printf("\tMSG: setup connection from %d to %d\n", nbrNodeID, myNodeID);
		int res = nt_addconn(nt, nbrNodeID, connfd);
		if (res == -1) {
			printf("ERROR: nt_addconn error\n");
			pthread_exit(NULL);
		}
//		print_pos();
//		printf("MSG: add node=%d, conn=%d\t to nt\n", nbrNodeID, connfd);
		//		}
	}
	printf("MSG: son connect neighbors ok\n");
	pthread_exit(NULL);
}
示例#14
0
// 这个函数连接到节点ID比自己小的所有邻居.
// 在所有外出连接都建立后, 返回1, 否则返回-1.
int connectNbrs() {
	int sockfd[MAX_NODE_NUM];
	int myNodeID = topology_getMyNodeID();
	int *nbr = topology_getNbrArray();
	int t = topology_getNbrNum();
//	print_pos();
//	printf("MSG:  topology nbr num = %d\n", t);
	int i;
//	for (i = 0; i < t; i ++) printf("MSG: nbr item %d\n", nbr[i]);

	struct sockaddr_in servaddr;
	// get conn count
	int conn_ct = 0;
	for (i = 0; i < t; i ++) {
		if (nbr[i] < myNodeID) conn_ct++;
	}

	// create socket
	for (i = 0; i < conn_ct; i ++){
		sockfd[i] = socket(AF_INET, SOCK_STREAM, 0);
		if (sockfd[i] < 0){
			print_pos();
			printf("\tError: create connect Nbrs socket failed\n");
			return -1;
		}
	}

	// set up tcp connect
	int j = 0;
	for (i = 0; i < t; i ++){
		if (nbr[i] < myNodeID) {
			memset(&servaddr, 0, sizeof(struct sockaddr_in));
			servaddr.sin_family = AF_INET;
			servaddr.sin_port = htons(CONNECTION_PORT);
			servaddr.sin_addr.s_addr = getIPByNode(nbr[i]);

//			print_pos();
//			printf("MSG: prepare to connect %s:%d, node=%d\n", inet_ntoa(servaddr.sin_addr), CONNECTION_PORT, nbr[i]);
			// set up connection
			int result;
			int retry_ct = 10;
			do {
//				print_pos();
//				printf("\tMSG: try to connect %d -> %d\n", myNodeID, nbr[i]);
				result = connect(sockfd[j], (struct sockaddr *)&servaddr, sizeof(struct sockaddr));
				if (result == -1){
					print_pos();
					printf("ERROR: connect %d->%d, failed, retry, errno=%s\n", myNodeID, nbr[i], strerror(errno));
				}
//				else printf("GOOD: connect success\n");
				retry_ct --;
				if (result == -1) sleep(1);
			} while (result == -1 && retry_ct > 0);

			// store in neighbor table
			if (result != -1){
				result = nt_addconn(nt, nbr[i], sockfd[j]);
				if (result == -1){
					print_pos();
					printf("\tERROR: nt_addconn error\n");
					return -1;

				}
				printf("MSG: add nt node=%d, conn=%d\n", nbr[i], sockfd[j]);
				j ++;
			} else {
				print_pos();
				printf("ERROR: tcp conn failed, retry too many times\n");
				return -1;
			}
		}
	}
	return 1;
}
示例#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);
}