コード例 #1
0
ファイル: p2p.c プロジェクト: ITanCh/netlab-NJU
/*发送请求函数,一次一般发送5个请求*/
void sendRequest(peer_t *peer,ReqState* state)
{
	int i=0;
	int r;
	char sendbuf[MAXLINE];
	//pthread_mutex_lock(&g_isSeed_lock);		//做种后不需要再存分片
	//i=g_isSeed;
	//pthread_mutex_unlock(&g_isSeed_lock);
	//if(i==2)return;

	//int size=0;
	while(i<1)
	{
		memset(sendbuf,0,MAXLINE);
		if(state->index<0)		//还未分配给该连接需要发送分片
		{
			state->index=getIndex(peer);		//选择分片,该连接负责该分片,直到该分片完成
			if(state->index<0)
			{
				//printf("没有请求可以发送\n");
				break;			//没有需要发送请求的分片
			}
			if(state->index==g_num_pieces-1)	//最后一片,需要特殊处理
				state->len=g_filelen-(g_num_pieces-1)*g_torrentmeta->piece_len;
			else
				state->len=g_torrentmeta->piece_len;
			state->offset=0;
			printf("请求分片:index:%d len:%d\n",state->index,state->len);
		}

		Head* h=(Head*)sendbuf;
		h->len=reverse_byte_orderi(13);
		h->id=0x06;
		Request * req=(Request*)(sendbuf+HEAD_SIZE);
		req->index=reverse_byte_orderi(state->index);
		req->offset=reverse_byte_orderi(state->offset);
		req->len=16384;		//16k
		if(state->offset+req->len>g_piece_state[state->index].len)	//最后一片
			req->len=g_piece_state[state->index].len-state->offset;
		printf("send request sock:%d :index: %d  offset: %d  len:%d\n",peer->sockfd,state->index,state->offset,req->len);
		state->offset+=req->len;
		req->len=reverse_byte_orderi(req->len);
		//printf("%d\n",req->len);
		r=sendme(peer->sockfd,sendbuf,17);
		if(r<=0)
			printf("req send error\n");
		if(state->offset>=g_piece_state[state->index].len)	//该分片请求已经发完
			state->index=-1;
		i++;
	}
}
コード例 #2
0
ファイル: p2p.c プロジェクト: ITanCh/netlab-NJU
/*告诉所有人我有了某个分片*/
void showPiece(int index)
{
	char temp[9];
	int len=reverse_byte_orderi(5);
	char id=0x04;
	int ind=reverse_byte_orderi(index);
	memcpy(temp,&len,sizeof(int));
	memcpy(temp+sizeof(int),&id,1);
	memcpy(temp+sizeof(int)+1,&ind,sizeof(int));
	pthread_mutex_lock(&all_peer_lock);
	int i;
	for(i=0;i<MAXPEER;i++)
	{
		if(myPeer[i].sockfd>=0)
			sendme(myPeer[i].sockfd,temp,9);
	}
	pthread_mutex_unlock(&all_peer_lock);
}
コード例 #3
0
ファイル: p2p.c プロジェクト: ITanCh/netlab-NJU
/*向所有人发送某个分片的cancel*/
void publicCancel(int index){
	char temp[17];
	int len = reverse_byte_orderi(13);
	char id = 0x08;
	int ind = reverse_byte_orderi(index);
	int begin = reverse_byte_orderi(0);
	int length = reverse_byte_orderi(0);
	memcpy(temp,&len,4);
	memcpy(temp+4,&id,1);
	memcpy(temp+5,&ind,4);
	memcpy(temp+9,&begin,4);
	memcpy(temp+13,&length,4);
	pthread_mutex_lock(&all_peer_lock);
	peer_t *p = all_peer;
	while(p != NULL)
	{
		sendme(p->sockfd,temp,17);
		p = p->next;
	}
	pthread_mutex_unlock(&all_peer_lock);
}
コード例 #4
0
ファイル: p2p.c プロジェクト: ITanCh/netlab-NJU
void sendPiece(int sockfd,int index,int offset,int len)
{
	int i=reverse_byte_orderi(index);
	int o=reverse_byte_orderi(offset);
	int l=reverse_byte_orderi(len);
	int size=l+HEAD_SIZE+2*sizeof(int);
	char sendline[MAXLINE];	
	Head *head=(Head*)sendline;
	head->len=reverse_byte_orderi(size-sizeof(int));
	head->id=0x07;
	Request *req=(Request*)(sendline+HEAD_SIZE);
	req->index=index;
	req->offset=offset;
	pthread_mutex_lock(&g_f_lock);
	fseek(g_f,i*g_torrentmeta->piece_len+o,SEEK_SET);
	fread(sendline+HEAD_SIZE+2*sizeof(int),l,1,g_f);
	pthread_mutex_unlock(&g_f_lock);
	//memcpy(sendline+HEAD_SIZE+2*sizeof(int),g_filedata+i*g_torrentmeta->piece_len+o,l);
	printf("send piece:sock:%d  index %d  offset %d len %d\n",sockfd,i,o,l);
	int r=sendme(sockfd,sendline,size);
	g_uploaded+=l;
	if(r<=0)return;
}
コード例 #5
0
void sendshkhdmsg(int sockfd)
{
    printf("\033[34m""I will send shkhdmsg to somebody\n""\033[m");
    unsigned char *shkhdmsg1;
    unsigned char *current;
    int msglen = 0;
    shkhdmsg1 = (unsigned char* )malloc(HANDSHAKE_LEN);
    current = shkhdmsg1;
    int pstrlen = strlen(BT_PROTOCOL);
    memcpy(current, (unsigned char*)&pstrlen, sizeof(int));
    current += sizeof(int);
    strncpy(current, BT_PROTOCOL, pstrlen);
    current += pstrlen;

    memset(current, 0, 8);
    current += 8;

    int i = 0;
    for(; i < 5; i ++)
    {
        int j = 0;
        int part = reverse_byte_orderi(g_infohash[i]);
        unsigned char *p = (unsigned char*)&part;
        for(; j < 4; j ++)
        {
            *current++ = p[j];
        }
    }
    for(i = 0; i < 20; i ++)
    {
        *current = g_my_id[i];
        current ++;
    }

    msglen = current - shkhdmsg1;
    send(sockfd, shkhdmsg1, msglen, 0);
    free(shkhdmsg1);
    shkhdmsg1 = NULL;
    current = NULL;
}
コード例 #6
0
// 制作一个发送给Tracker的HTTP请求. 使用一些全局变量来填充请求中的参数,  
// 如info_hash, peer_id以及有多少字节已上传和下载, 等等. 
//
// 事件: 0 - started, 1 - stopped, 2 - completed
// 这些宏的定义见头文件btdata.h
// 这个函数返回HTTP请求消息, 消息的长度写入mlen
char* make_tracker_request(int event, int* mlen)
{ 
  // 分配一个很大的空间给MESG, 并填充它
  char *MESG;
  char* cur;
  int i;

  MESG = (char*)malloc(4096*sizeof(char));
  cur = MESG;
  strcpy(cur,"GET /announce?");
  cur += strlen("GET /announce?");
  
  // 填入info_hash
  //char hexdigs[16] = {'0', '1', '2', '3', '4', '5', '6', '7', 
  //                    '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
  strcpy(cur,"info_hash=");
  cur += strlen("info_hash=");
  for(i=0; i<5; i++)
  {
    int j;
    int part = reverse_byte_orderi(g_infohash[i]);
    unsigned char* p = (unsigned char*)&part;
    for(j=0; j<4; j++)
    {
      if((p[j] > 0x2F && p[j] < 0x3A) || (p[j] > 0x41 && p[j] < 0x5B) || 
         (p[j] > 0x60 && p[j] < 0x7B))
      {
        *cur++ = p[j];
      }
      else
      {
        *cur++ = '%';
        cur += sprintf(cur,"%02X",p[j]);
      }
    }
  }

  // Peer id
  strcpy(cur,"&peer_id=");
  cur += strlen("&peer_id=");
  for(i=0; i<20; i++)
  {
    *cur++ = '%';
    cur += sprintf(cur,"%02X",(unsigned char)g_my_id[i]);
  }

  // port
  strcpy(cur,"&port=");
  cur += strlen("&port=");
  cur += sprintf(cur,"%d",g_peerport);
  
  // ip
  strcpy(cur,"&ip=");
  cur += strlen("&ip=");
  strcpy(cur,g_my_ip);
  cur += strlen(g_my_ip);

  // uploaded
  strcpy(cur,"&uploaded=");
  cur += strlen("&uploaded=");
  cur += sprintf(cur,"%d",g_uploaded);
  
  // downloaded
  strcpy(cur,"&downloaded=");
  cur += strlen("&downloaded=");
  cur += sprintf(cur,"%d",g_downloaded);
  
  // left
  strcpy(cur,"&left=");
  cur += strlen("&left=");
  cur += sprintf(cur,"%d",g_left);

  switch(event) {
  case BT_STARTED:
    strcpy(cur,"&event=");
    cur += strlen("&event=");
    strcpy(cur,"started");
    cur += strlen("started");
    break;
  case BT_STOPPED:
    strcpy(cur,"&event=");
    cur += strlen("&event=");
    strcpy(cur,"stopped");
    cur += strlen("stopped");
    break;
  case BT_COMPLETED:
    strcpy(cur,"&event=");
    cur += strlen("&event=");
    strcpy(cur,"completed");
    cur += strlen("completed");
    break;
  
  // 除了上述情况以外, 不发送event参数
  }
  
  strcpy(cur," HTTP/1.1\r\n\r\n");
  cur += strlen(" HTTP/1.1\r\n\r\n");

  *cur = '\0';

  *mlen = cur - MESG;
  
  return MESG;
}
コード例 #7
0
ファイル: p2p.c プロジェクト: ITanCh/netlab-NJU
void *PToP(void *arg)
{
	Head* head;
	peer_t * peer=(peer_t *)arg;
	peer->bitmap=malloc(mapcount);		//记录该peer的bitfield
	memset(peer->bitmap,0,mapcount);

	int sockfd=peer->sockfd;
	int i;
	char rcvline[MAXLINE];
	char sendline[MAXLINE];
	char templine[MAXLINE];
	char c;
	memset(rcvline,0,MAXLINE);
	memset(sendline,0,MAXLINE);

	//啥话不说,先来一发
	Hand* hk=(Hand*)sendline;
	hk->len=0x13;
	strcpy(hk->name,"BitTorrent protocol");
	memset(hk->reserve,0,8);
	int hash[5];
	for(i=0;i<5;i++)
		hash[i]=reverse_byte_orderi(g_infohash[i]);
	memcpy(hk->sha,hash,20);
	memcpy(hk->id,g_my_id,20);
	sendme(sockfd,sendline,sizeof(Hand));

	if(recvme(sockfd,rcvline,sizeof(Hand))<=0)
	{
		printf("握手失败\n");
		{
			shutdown(sockfd,SHUT_RDWR);
			close(sockfd);
			peer->sockfd=-1;
			return NULL;
		}
	}
	hk=(Hand*)rcvline;
	/*if(memcmp(hash,hk->sha,20)!=0){
		printf("hash 不匹配\n");
		shutdown(sockfd,SHUT_RDWR);
		close(sockfd);
		peer->sockfd=-1;
		return NULL;
	}*/
	memcpy(peer->name,hk->id,20);		

	//bitfield
	pthread_mutex_lock(&g_isSeed_lock);
	i=g_isSeed;
	pthread_mutex_unlock(&g_isSeed_lock);
	if(i==2)
	{
		memset(sendline,0,MAXLINE);
		head=(Head*)sendline;
		head->len=reverse_byte_orderi(mapcount+1);
		head->id=0x05;
		pthread_mutex_lock(&g_bitmap_lock);
		memcpy(&sendline[HEAD_SIZE],g_bitmap,mapcount);
		pthread_mutex_unlock(&g_bitmap_lock);
		sendme(sockfd,sendline,HEAD_SIZE+mapcount);
	}

	Request* req;
	int temp;
	ReqState reqState;
	reqState.index=-1;
	reqState.offset=-1;
	reqState.len=-1;
	SaveState saveState;
	saveState.index=-1;
	saveState.offset=0;

	int cancel=-1;
	int errcount=0;
	while(!g_done)
	{
		req=NULL;
		memset(rcvline,0,MAXLINE);
		memset(sendline,0,MAXLINE);
		memset(templine,0,MAXLINE);
		head=NULL;
		i=recvme(sockfd,rcvline,sizeof(int));
		if(peer->state||i<=0)
		{
			errcount++;
			if(errcount>1)
			{
				printf("接受信息错误%d\n",peer->state);
				shutdown(sockfd,SHUT_RDWR);
				close(sockfd);
				peer->sockfd=-1;
				return NULL;
			}
			continue;
		}
		errcount=0;
		head=(Head*)rcvline;
		if(reverse_byte_orderi(head->len)<=0)continue;	//keep alive	
		if(recvme(sockfd,rcvline+sizeof(int),1)<0)continue;
		int load_len=reverse_byte_orderi(head->len)-1;
		//printf("状态:%02X\n",head->id);
		switch(head->id)
		{
			case 0x00:			//choke
				printf("被阻塞!\n");
				head=(Head*)sendline;
				head->len=reverse_byte_orderi(1);
				head->id=0x02;
				peer->have_interest=1;
				sendme(sockfd,sendline,HEAD_SIZE);
				break;
			case 0x01:			//unchoke
				if(!peer->have_interest)break;
				peer->choked=0;
				sendRequest(peer,&reqState);	//send request
				break;
			case 0x02:		//interest
				if(peer->choking)break;
				cancel=-1;
				peer->interested=1;
				head=(Head*)sendline;
				head->len=reverse_byte_orderi(1);
				head->id=0x01;		//unchoke
				sendme(sockfd,sendline,HEAD_SIZE);
				//等待对方的request
				break;
			case 0x03:		//not interested
				cancel=-1;
				break;
			case 0x04:		//have
				if(recvme(sockfd,templine,load_len)<=0)
					continue;
				memcpy(&temp,templine,sizeof(int));
				temp=reverse_byte_orderi(temp);
				pthread_mutex_lock(&g_bitmap_lock);
				c=g_bitmap[temp/8];
				pthread_mutex_unlock(&g_bitmap_lock);
				if(isSet(c,8-temp%8))continue;
				head=(Head*)sendline;
				head->len=reverse_byte_orderi(1);
				head->id=0x02;
				sendme(sockfd,sendline,HEAD_SIZE);
				break;
			case 0x05:		//bitfield
				if(recvme(sockfd,templine,load_len)<=0)
					continue;
				if(load_len!=mapcount)
				{
					shutdown(sockfd,SHUT_RDWR);
					close(sockfd);
					peer->sockfd=-1;
					return NULL;
				}
				memcpy(peer->bitmap,templine,mapcount);
				i=needThis(peer->bitmap);	//判断是否有需要该用户,需要记录该用户提供了那些分片
				//printf("是否需要该用户%d\n",i);
				if(i==0)
				{
					shutdown(sockfd,SHUT_RDWR);
					close(sockfd);
					peer->sockfd=-1;
					return NULL;
				}
				else if(i==1)break;		//不感兴趣
				//send interest
				head=(Head*)sendline;
				head->len=reverse_byte_orderi(1);
				head->id=0x02;
				peer->have_interest=1;
				sendme(sockfd,sendline,HEAD_SIZE);
				break;
			case 0x06:		//request
				if(recvme(sockfd,templine,load_len)<=0)
					continue;
				req=(Request *)templine;
				if(reverse_byte_orderi(req->len)>131072)	//2^17
				{
					shutdown(sockfd,SHUT_RDWR);
					close(sockfd);
					peer->sockfd=-1;
					return NULL;
				}
				if(cancel==reverse_byte_orderi(req->index)){
					cancel=-1;
					continue;
				}
				sendPiece(sockfd,req->index,req->offset,req->len);	//发送子分片
				break;
			case 0x07:		//piece
				if(recvme(sockfd,templine,load_len)<=0)
					continue;
				//printf("load len :%d\n",i);
				req=(Request *)templine;
				/*for(i=0;i<8;i++)
				  {
				  for(temp=0;temp<8;temp++)
				  printf("%02X ",templine[i*8+temp]);
				  printf("\n");
				  }*/
				savePiece(reverse_byte_orderi(req->index),reverse_byte_orderi(req->offset),templine+2*sizeof(int),load_len-2*sizeof(int),&saveState);	//存储分片:w
				sendRequest(peer,&reqState);
				break;
			case 0x08:		//cancel
				if(recvme(sockfd,templine,load_len)<=0)continue;
				req=(Request*)templine;
				cancel=reverse_byte_orderi(req->index);
				break;
			default:
				;//printf("没有该状态%02X\n",head->id);return NULL;

		}
	}
	shutdown(sockfd,SHUT_RDWR);
	close(sockfd);
	peer->sockfd=-1;
	return NULL;
}
コード例 #8
0
void *peer_deal(void *i)
{
    struct param_list *my_param = (struct param_list *)i;
    int sockfd = my_param->sockfd;
    int close_bit = 1;
    printf("Child created for dealing with client request\n");
    char *buf = (char *)malloc(HANDSHAKE_LEN);
    memset(buf,0,HANDSHAKE_LEN);
    int n;
    while(n=recv(sockfd,buf,HANDSHAKE_LEN,0) > 0)
    {
        struct handshake_packet *my_packet = (struct handshake_packet *)buf;
        if(my_packet->len != strlen(BT_PROTOCOL))
        {
            printf("len is not match\n");
            break;
        }
        if(strncmp(my_packet->name,BT_PROTOCOL,strlen(BT_PROTOCOL)) != 0)
        {
            printf("BT_PROTOCOL is not match\n");
            break;
        }
        int i = 0,flag = 1;
        unsigned char *buf_info = my_packet->info_hash;
        for(; i<5; i++)
        {
            int j = 0;
            int part = reverse_byte_orderi(g_infohash[i]);
            unsigned char *p = (unsigned char *)&part;
            for(; j<4; j++)
            {
                if(*buf_info != p[j])
                {
                    printf("buf_info is %x and p[j] is %x\n",*buf_info,p[j]);
                    flag = 0;
                    goto END;
                }
                buf_info ++;
            }
        }
END:
        if(flag != 1)
        {
            printf("\033[33m buf_info is not match\n \033[m");
            break;
        }
        printf("waiting client get info\n");
        //sleep(10);    //这里是为了等客户端向tracker服务器发送更新请求报文
        //这里需要上锁
        pthread_mutex_lock(&g_mutex);
        for(i=0; i<MAXPEERS; i++)
        {
            //printf("peers_pool[i].id is %s and my_packet->peer_id is %s\n",peers_pool[i].id,my_packet->peer_id);
            if(peers_pool[i].used == 1 && strncmp(peers_pool[i].ip,my_param->ip,strlen(my_param->ip)) == 0)
            {
                printf("find you\n");
                break;
            }
        }
        pthread_mutex_unlock(&g_mutex);
        if(i == MAXPEERS || peers_pool[i].sockfd > 0)
        {
            printf("not you\n");
            break;
        }
        printf("i is %d\n",i);
        pthread_mutex_lock(&peers_pool[i].sock_mutex);
        if(peers_pool[i].status == 1)
        {
            pthread_mutex_unlock(&peers_pool[i].sock_mutex);
            printf("I already some shake hand to peer\n");
            break;
        }
        peers_pool[i].status = 2;
        peers_pool[i].sockfd = sockfd;
        memcpy(peers_pool[i].id,my_packet->peer_id,20);
        printf("peers_pool 0 status is %d in listen_peers\n",peers_pool[0].status);
        pthread_mutex_unlock(&peers_pool[i].sock_mutex);
        //这里开始向对方返回握手信息
        printf("send handshake packet return \n");
        memcpy(my_packet->peer_id,g_my_id,20);
        send(sockfd,buf,HANDSHAKE_LEN,0);
        close_bit = 0;
        pthread_t thread;
        int rc = pthread_create(&thread, NULL, recv_from_peer, (void *)i);
        if(rc)
        {
            printf("Error, return code from pthread_create() is %d\n", rc);
            exit(-1);
        }
        printf("shake hands succeed\n");
        //sleep(10);           //等一会
        sendBitField(sockfd);
        pthread_t thread_1;
        pthread_create(&thread_1, NULL, check_and_keepalive, (void*)i);
        break;
    }
    if(n<0)
    {
        printf("%s\n",strerror(errno));
    }
    if(close_bit)
        close(sockfd);
    free(buf);
}