Beispiel #1
0
//read topology.dat
void getTopoData()
{
	FILE *pFile;
	pFile = fopen("../topology/topology.dat","r");
	if(pFile == NULL)
	{
		printf("open file error\n");
		exit(-1);
	}
	char buf[128];
	int lineCount=0;
	while (fgets(buf,sizeof(buf),pFile)!= NULL) {
		lineCount++;
	}
	if(lineCount<=0)
	{
		printf("no topology in file\n");
		exit(-1);
	}

	//init topo data list
	allIdList=malloc(lineCount*2*sizeof(int));
	nbIdList=malloc(lineCount*sizeof(int));
	nbIpList=malloc(lineCount*sizeof(in_addr_t));
	costList=malloc(lineCount*sizeof(int));

	//get data from file
	char host1[32],host2[32];
	int cost;
	int myId=topology_getMyNodeID();
	nbCount=0;
	fseek(pFile,0,SEEK_SET);
	while(fscanf(pFile,"%s %s %d", host1, host2, &cost) > 0)	
	{
		int id1=topology_getNodeIDfromname(host1);
		int id2=topology_getNodeIDfromname(host2);
		int i=0;
		for(;i<allCount;i++)
		{
			if(allIdList[i]==id1)break;
		}
		if(i==allCount)allIdList[allCount++]=id1;

		i=0;
		for(;i<allCount;i++)
		{
			if(allIdList[i]==id2)break;
		}
		if(i==allCount)allIdList[allCount++]=id2;
		
		//neighbor 
		if(id1==myId)
		{
			nbIdList[nbCount]=id2;
			nbIpList[nbCount]=topology_getNodeIPfromname(host2);
			costList[nbCount]=cost;
			if(id2>id1)bigCount++;
			else if(id1>id2)smallCount++;
			nbCount++;
		}
		else if(id2==myId)
		{
			nbIdList[nbCount]=id1;
			nbIpList[nbCount]=topology_getNodeIPfromname(host1);
			costList[nbCount]=cost;
			if(id2>id1)smallCount++;
			else if(id1>id2)bigCount++;
			nbCount++;
		}
	}

}
Beispiel #2
0
//这个函数首先动态创建一个邻居表. 然后解析文件topology/topology.dat, 填充所有条目中的nodeID和nodeIP字段, 将conn字段初始化为-1.
//返回创建的邻居表.
nbr_entry_t* nt_create()
{
	//printf("-------------nt_create------------\n");
	nbr_entry_t *result = (nbr_entry_t *)malloc(sizeof(nbr_entry_t) * 3);
	int myNode = topology_getMyNodeID();
	FILE *fp;
	fp = fopen("/home/b101220023/lab13/topology/topology.dat", "r");
	if (fp == NULL)
	{
		printf("Cann't open file topology.dat\n");
		return 0;
	}
	char buffer[100];
	int count = 0;
	while (fgets(buffer, 99, fp) != NULL)
	{
		//printf("count is %d\n",count);
		char *node1 = (char *)malloc(11);
		char *node2 = (char *)malloc(11);
		memcpy(node1, buffer, 10);
		memcpy(node2, buffer + 11, 10);
		node1[10] = 0;
		node2[10] = 0;
		//printf("node1 is %s, node2 is %s\n", node1, node2);
		int node1ID = topology_getNodeIDfromname(node1);
		int node2ID = topology_getNodeIDfromname(node2);
		//printf("node1Id is %d, node2ID is %d\n", node1ID, node2ID);
		if (node1ID == myNode )	// 添加邻居节点信息
		{
			result[count].nodeID = node2ID;
			if (node2ID == 185)
			{
				result[count].nodeIP = inet_addr("114.212.190.185");
			}
			else if (node2ID == 186)
			{
				result[count].nodeIP = inet_addr("114.212.190.186");
			}
			else if (node2ID == 187)
			{
				result[count].nodeIP = inet_addr("114.212.190.187");
			}
			else if (node2ID == 188)
			{
				result[count].nodeIP = inet_addr("114.212.190.188");
			}
			result[count].conn = -1;
			count ++;
		}
		else if (node2ID == myNode)
		{
			result[count].nodeID = node1ID;
			if (node1ID == 185)
			{
				result[count].nodeIP = inet_addr("114.212.190.185");
			}
			else if (node1ID == 186)
			{
				result[count].nodeIP = inet_addr("114.212.190.186");
			}
			else if (node1ID == 187)
			{
				result[count].nodeIP = inet_addr("114.212.190.187");
			}
			else if (node1ID == 188)
			{
				result[count].nodeIP = inet_addr("114.212.190.188");
			}
			result[count].conn = -1;
			count ++;
		}
	}
	fclose(fp);
	//printf("count is %d\n", count);
	return result;
}
Beispiel #3
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);
}
Beispiel #4
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;
}
Beispiel #5
0
// 这个线程打开TCP端口CONNECTION_PORT, 等待节点ID比自己大的所有邻居的进入连接,
// 在所有进入连接都建立后, 这个线程终止.
void* waitNbrs(void* arg) {
	//你需要编写这里的代码.
    int myid = topology_getMyNodeID();
    pid_t pid;
    socklen_t clilen;
    int listenfd;
    //char buf[MAXLINE];
		int j = 0;
		int full = 0;
		for(j = 0;j<topology_getNbrNum();j++)
        {
            if(nt[j].nodeID > topology_getMyNodeID())
			{
                full ++;
				//printf("nt num :%d   %d\n",j,topology_getMyNodeID());
			}
        }   
    struct sockaddr_in cliaddr,servaddr;
    listenfd = socket(AF_INET,SOCK_STREAM,0);
    memset(&servaddr, 0, sizeof(struct sockaddr_in));
    servaddr.sin_family=AF_INET;
    servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
    servaddr.sin_port=htons(CONNECTION_PORT);
    bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
    listen(listenfd,MAX_NODE_NUM);//开始监听


	int temp = 0;
	printf("full:%d",full);
    for(temp = 0;temp < full;temp++)
    {
	
    clilen = sizeof(cliaddr);
    int connfd = accept(listenfd,(struct sockaddr *)&cliaddr,&clilen);
	//close(listenfd);
   // if((pid = fork()) == 0)
    //{
     //   close(listenfd);
        int neberid = topology_getNodeIDfromip((struct in_addr*)&(cliaddr.sin_addr));
        printf("neberid : %d\n",neberid);
        /*int i = 0;
        for(i = 0; i < topology_getNbrNum();i++)
        {
            if(nt[i].nodeID == neberid)
            {
                nt[i].conn = connfd;
                break;
            }
        }
        if(i == topology_getNbrNum())
        {
            printf("error node !\n");
            return 0;
        }*/
        int t = nt_addconn(nt, neberid, connfd);
        if(t!=1&&t!=0)
        {
            printf("error neberid!\n");
        }
        else if(t == 0)
		{
			temp--;
		}else
        {
            //return 1;
			printf("neberid : %d link sucess\n",neberid);
        }
		
		    int j= 0;
        //int full = 1;
         
    }

  return 0;
}
Beispiel #6
0
void waitSTCP() {
	//你需要编写这里的代码.
	//Create a socket for the socket
	//If sockfd<0 there was an error in the creation of the socket
	printf("we are now in waitSTCP!\n");
	int slot_num;
	sip_pkt_t* pkt;
	int myID = topology_getMyNodeID();
	int listenfd, connfd;
	socklen_t clilen;
	struct sockaddr_in cliaddr, servaddr;

	if ((listenfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
		perror("Problem in creating the socket");
		exit(2);
	}
	
	//preparation of the socket address
	memset(&servaddr,0, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(SIP_PORT);
	
	//bind the socket
	bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
	
	//listen to the socket by creating a connection queue, then wait for clients
	listen(listenfd, MAX_NODE_NUM);
	printf("Server running...waiting for connections.\n");

	//accept a connection
	while(1) {
		clilen = sizeof(cliaddr);
		connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen);
		stcp_conn = connfd;
		printf("Received request...\n");

		seg_t* segPtr = (seg_t*)malloc(sizeof(seg_t));
		int* dest_nodeID = (int*)malloc(sizeof(int));
		while (getsegToSend(stcp_conn, dest_nodeID, segPtr) > 0) {
			switch(segPtr->header.type) {
				case 0:
					printf("SIP get some seg --SYN-- from STCP %d!\n", stcp_conn);
					break;
				case 1:
					printf("SIP get some seg --SYNACK-- from STCP %d!\n", stcp_conn);
					break;
				case 2:
					printf("SIP get some seg --FIN-- from STCP %d!\n", stcp_conn);
					break;
				case 3:
					printf("SIP get some seg --FINACK-- from STCP %d!\n", stcp_conn);
					break;
				case 4:
					printf("SIP get some seg --DATA-- from STCP to send! and the service is %d, and the message is %s\n", ((struct packet_IM*)(segPtr->data))->service, ((struct packet_IM*)(segPtr->data))->message);
					break;
				case 5:
					printf("SIP get some seg --DAYAACK-- from STCP to send!\n");
					break;
			}
			slot_num = makehash(*dest_nodeID);
			routingtable_entry_t* ptr = routingtable->hash[slot_num];
			while (ptr != NULL) {//寻找是否存在给定目的节点的路由条目
				if (*dest_nodeID == ptr->destNodeID)
					break;
				ptr = ptr->next;
			}
			if (ptr != NULL) {//根据路由表转发报文给下一跳
				pkt = (sip_pkt_t*)malloc(sizeof(sip_pkt_t));
				pkt->header.src_nodeID = myID;
				pkt->header.dest_nodeID = *dest_nodeID;
				pkt->header.length = 24 + segPtr->header.length;
				pkt->header.type = SIP;//包含在报文中的数据是一个STCP段(包括段首部和数据)——Hobo
				memcpy(pkt->data, segPtr, pkt->header.length);
				son_sendpkt(ptr->nextNodeID, pkt, son_conn);
				printf("sip has send pkt to the son %d %d and the service is %d\n", ptr->nextNodeID, son_conn, ((struct packet_IM*)(segPtr->data))->service);
			}
			else {
				printf("can not get the destnodeID!\n");
				//exit(0);
			}
		}
	}
	printf("we are now off waitSTCP!\n");
	return;
}
Beispiel #7
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);
}