예제 #1
0
파일: rudp.c 프로젝트: GanapathyRaman/RUDP
int rudp_sendto(rudp_socket_t rsocket_t, void* data, int len, struct sockaddr_in6* to) {
	struct rudp_socket *rsocket;
	struct peer * cur_peer;
	struct vsftp * vs_data;

	rsocket = (struct rudp_socket *) rsocket_t;
	vs_data = (struct vsftp *) data;
	vs_data->vs_type = ntohl(vs_data->vs_type);

	// find the corresponding peer
	cur_peer = find_peer(rsocket, to);

	// create a new peer if needed
	if (cur_peer == NULL) {
		// ignore if it's not VS_TYPE_BEGIN
		if (vs_data->vs_type != VS_TYPE_BEGIN) {
			printf("rudp_sendto: cannot find peer\n");
			return -1;
		}

		cur_peer = add_peer(rsocket, to);	
	}

	// if the peer is the first peer, store the data to the data list of the socket
	if (cur_peer == rsocket->peer_head) {
		store_data(rsocket, vs_data, len);
	}

	vs_data->vs_type = htonl(vs_data->vs_type);
	
	return 0;
}
예제 #2
0
/*
 * This routine registers all the files in the directory <dirname>
 * with the index server against the peer.
 */
int
register_files(char *localhostname, char *dirname)
{
    DIR *dirp;
    struct dirent *entp;
    bool_t ret;
    int res;

    if ((dirp = opendir(dirname)) == NULL) {
        printf("opendir(%s) failed with errno %d\n", dirname, errno);
	printf("Please check if the directory %s exists and is accessible\n",dirname);
        return (errno);
    }

    while ((entp = readdir(dirp)) != NULL) {
        /*
         * Skip "." and ".."
         */
        if (strcmp(entp->d_name, ".") == 0 || strcmp(entp->d_name, "..") == 0)
            continue;
        printf("Registering file : %s to the index-server : %s\n", entp->d_name, localhostname);

        ret = add_peer(entp->d_name, localhostname);
    }

    closedir(dirp);
    return (0);
}
예제 #3
0
파일: core.cpp 프로젝트: wonghoifung/tips
int core::handle_login(inmessage* inmsg, stream_handler* handler)
{
  if (handler->get_ud()) return -1; // already login

  const uint32_t id = inmsg->read_int();
  const std::string key = inmsg->read_cstring();
  const std::string info = inmsg->read_cstring();

  // check key, process info

  peer* p = check_reconnect_peer(id);
  if (p == NULL) {
    p = add_peer(id, handler);
    if (p == NULL) return -1;
  } else {
    p->set_stream_handler(handler);
    handler->set_ud(p);
  }

  outmessage outmsg;
  outmsg.begin(cmd_peer_login);
  // some info...
  outmsg.end();
  send_message(&outmsg, handler);

  return 0;
}
예제 #4
0
파일: peermanager.c 프로젝트: asyn/openvims
/**
 * Initializes the Peer Manager. 
 * The initial list of peers is taken from the configuration provided
 * @param config - configuration for initial peers
 * @returns 1
 */
int peer_manager_init(dp_config *config)
{
	int i;
	peer *p;
	LOG(L_DBG,"DBG:peer_manager_init(): Peer Manager initialization...\n");
	peer_list = shm_malloc(sizeof(peer_list_t));
	peer_list->head = 0; 
	peer_list->tail = 0;
	peer_list_lock = lock_alloc();
	peer_list_lock = lock_init(peer_list_lock);
	
	hopbyhop_id = shm_malloc(sizeof(AAAMsgIdentifier));
	endtoend_id = shm_malloc(sizeof(AAAMsgIdentifier));
	msg_id_lock = lock_alloc();
	msg_id_lock = lock_init(msg_id_lock);
	
	srand((unsigned int)time(0));
	*hopbyhop_id = rand();
	*endtoend_id = (time(0)&0xFFF)<<20;
	*endtoend_id |= rand() & 0xFFFFF;	

	for(i=0;i<config->peers_cnt;i++){
		p = new_peer(config->peers[i].fqdn,config->peers[i].realm,config->peers[i].port);
		if (!p) continue;
		p->is_dynamic = 0;
		add_peer(p);
	}
	
	add_timer(PEER_MANAGER_TIMER,0,&peer_timer,0);
	
	return 1;
}
예제 #5
0
static void
run (void *cls,
     const struct GNUNET_CONFIGURATION_Handle *cfg,
     struct GNUNET_TESTING_Peer *peer)
{
  h = GNUNET_PEERINFO_connect (cfg);
  GNUNET_assert (NULL != h);
  add_peer ();
  ic = GNUNET_PEERINFO_iterate (h, GNUNET_NO, &pid,
                                &process, cls);
}
static void
run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg,
    struct GNUNET_TESTING_Peer *peer)
{
  timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL );
  mycfg = cfg;
  pnc_w_fo = GNUNET_PEERINFO_notify (mycfg, GNUNET_YES, &process_w_fo, NULL );
  pnc_wo_fo = GNUNET_PEERINFO_notify (mycfg, GNUNET_NO, &process_wo_fo, NULL );
  h = GNUNET_PEERINFO_connect (cfg);
  GNUNET_assert(NULL != h);
  add_peer ();
}
예제 #7
0
파일: ind_server.c 프로젝트: LILIYUAN/cs550
bool_t
registry_1_svc(registry_rec *argp, int *result, struct svc_req *rqstp)
{
	bool_t retval = TRUE;

    *result = add_peer(argp->fname, argp->peer, argp->bw);
#ifdef SLEEP
    printf("Sleeping for 5 secs\n");
    sleep(5);
    printf("Woke up after sleeping for 5 secs\n");
#endif /* SLEEP */

	return retval;
}
예제 #8
0
/* Client Mode */
 void *connectToPeer(void *temp) {
    struct sockaddr_in remote_addr;
    int new_fd;
    char *buffer = malloc(MAXBUFFSIZE), *buf1 = malloc(MAXBUFFSIZE), *buf2 = malloc(MAXBUFFSIZE);
    struct peerList *peer = (struct peerList *)temp;

    if (!add_peer(peer) && (peer->net_fd)) return NULL;

  /* Create TCP Socket */
    if ((new_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("could not create socket");
        exit(1);
    }

    memset((char *)&remote_addr, 0, sizeof(remote_addr));
    remote_addr.sin_family = AF_INET;
    remote_addr.sin_port = htons(peer->listenPort);
    inet_aton((char *)inet_ntoa(peer->listenIP), &remote_addr.sin_addr);

    sprintf(buf1, "%s %d", inet_ntoa(local_info->listenIP), local_info->listenPort);
    sprintf(buf2, "%s %d", inet_ntoa(peer->listenIP), peer->listenPort);

    if (debug) printf("COMPARING %s --- %s\n", buf1, buf2);
    if (!(strcmp(buf1, buf2))) return NULL;

    puts("Client Mode:");
    printf("NEW PEER: Connecting to %s:%d\n", inet_ntoa(remote_addr.sin_addr), ntohs(remote_addr.sin_port));

  /* Connect to server */
    if ((connect(new_fd, (struct sockaddr *)&remote_addr, sizeof(remote_addr))) < 0) {
        printf("NEW PEER: Peer Removed %s:%d: Failed to connect\n", inet_ntoa(peer->listenIP), peer->listenPort);
        if (debug) printf("errno: %d\n", errno);
        remove_peer(peer);
    } else {
    /* Create single link state packet */
        strcpy(buffer, peer->tapDevice);
        peer->net_fd = new_fd;
        printf("NEW PEER: Connected to server %s:%d - %d\n", inet_ntoa(peer->listenIP), peer->listenPort, peer->net_fd);
        // sprintf(buffer, "0xabcd 2048%s blah blah", send_peerList(peer));
        // send(peer->net_fd, buffer, strlen(buffer), 0);
        send_singleLinkStatePacket(peer);
        lsPacket->neighbors = HASH_COUNT(peers);
        if (debug) print_linkStatePacket();
    }

    if (debug) puts("Leaving connectToPeer");
    return NULL;
 }
예제 #9
0
파일: peer.c 프로젝트: robertseaton/slug
void 
add_peers(struct Torrent *t, struct PeerNode *peer_list)
{
     /* possible this is called from the first announce */
     if (t->peer_list == NULL) {
          t->peer_list = init_peer_node(peer_list->cargo, NULL);
          peer_list = peer_list->next;
     }
     struct PeerNode *head = peer_list;
     /* iterate over all the peers */
     while (peer_list != NULL) {
          add_peer(&t->peer_list, peer_list->cargo);
          peer_list = peer_list->next;
     }

     t->peer_list = head;
}
예제 #10
0
/**
 * @brief register a DMQ peer
 */
dmq_peer_t *register_dmq_peer(dmq_peer_t *peer)
{
	dmq_peer_t *new_peer;
	if(!peer_list) {
		LM_ERR("peer list not initialized\n");
		return NULL;
	}
	lock_get(&peer_list->lock);
	if(search_peer_list(peer_list, peer)) {
		LM_ERR("peer already exists: %.*s %.*s\n", peer->peer_id.len,
				peer->peer_id.s, peer->description.len, peer->description.s);
		lock_release(&peer_list->lock);
		return NULL;
	}
	new_peer = add_peer(peer_list, peer);
	lock_release(&peer_list->lock);
	return new_peer;
}
예제 #11
0
static void
process (void *cls, const struct GNUNET_PeerIdentity *peer,
         const struct GNUNET_HELLO_Message *hello, const char *err_msg)
{
  unsigned int agc;

  if (err_msg != NULL)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Error in communication with PEERINFO service\n"));
  }

  if (peer == NULL)
  {
    ic = NULL;
    if ((3 == global_ret) && (retries < 50))
    {
      /* try again */
      retries++;
      add_peer ();
      ic = GNUNET_PEERINFO_iterate (h, GNUNET_NO, NULL,
                                    &process,
                                    cls);
      return;
    }
    GNUNET_assert (peer == NULL);
    GNUNET_assert (2 == global_ret);
    GNUNET_PEERINFO_disconnect (h);
    h = NULL;
    global_ret = 0;
    return;
  }
  if (hello != NULL)
  {
    GNUNET_assert (3 == global_ret);
    agc = 3;
    GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO,
                                    &check_it, &agc);
    GNUNET_assert (agc == 0);
    global_ret = 2;
  }
}
예제 #12
0
파일: peermanager.c 프로젝트: asyn/openvims
/**
 * Finds a peer based on the FQDN and Realm.
 * @param fqdn - the FQDN to look for
 * @param realm - the Realm to look for
 * @returns the peer* or NULL if not found
 */
peer *get_peer_from_fqdn(str fqdn,str realm)
{
	peer *i;
	lock_get(peer_list_lock);
	i = peer_list->head;
	while(i){
		if (fqdn.len == i->fqdn.len && strncasecmp(fqdn.s,i->fqdn.s,fqdn.len)==0) 
			break;
		i = i->next;
	}
	lock_release(peer_list_lock);
	if (!i&&config->accept_unknown_peers){
		i = new_peer(fqdn,realm,3868);
		if (i){
			i->is_dynamic=1;
			touch_peer(i);
			add_peer(i);
		}
	}
	return i;
}
예제 #13
0
void 
get_peers(struct Torrent *t, char *data)
{
     int64_t i = 0;
     char *j;

#define PEERS_STR "5:peers"
     j = strstr(data, PEERS_STR);
     j += strlen(PEERS_STR);
     
     freeBEncode(parseBEncode(j, &i));

     uint64_t num_peers = 0;
     while (isdigit(*j)) {
          num_peers = num_peers * 10 + ((*j) - '0');
          ++j; --i;
     }

     num_peers /= 6;
     /* skip the ':' */
     j++; i--;

     syslog(LOG_DEBUG, "ANNOUNCE: %"PRIu64" peers.\n", num_peers);

     uint32_t ip;
     uint16_t port;

     int k;
     for (k = 0; k < num_peers; k++) {
          memcpy(&ip, j, sizeof(ip));
          j += sizeof(ip);
          memcpy(&port, j, sizeof(port));
          j += sizeof(port);

          if (t->peer_list == NULL)
               t->peer_list = init_peer_node(init_peer(ip, port, t), NULL);
          else
               add_peer(&t->peer_list, init_peer(ip, port, t));
     }
}
예제 #14
0
int run_command(const std::string& cmd) {
    if (cmd == "add_peer") {
        return add_peer();
    }
    if (cmd == "remove_peer") {
        return remove_peer();
    }
    if (cmd == "change_peers") {
        return change_peers();
    }
    if (cmd == "reset_peer") {
        return reset_peer();
    }
    if (cmd == "snapshot") {
        return snapshot();
    }
    if (cmd == "transfer_leader") {
        return transfer_leader();
    }
    LOG(ERROR) << "Unknown command `" << cmd << '\'';
    return -1;
}
예제 #15
0
void
udp_get_peers(int8_t* data, int length, struct Torrent* t)
{
     uint32_t ip;
     uint16_t port;
     int num_peers;

     num_peers = length / (sizeof(ip) + sizeof(port));

     int i;
     int j = 0;
     for (i = 0; i < num_peers; i++) {
          memcpy(&ip, &data[j], sizeof(ip));
          j += sizeof(ip);
          memcpy(&port, &data[j], sizeof(port));
          j += sizeof(port);

          if (t->peer_list == NULL)
               t->peer_list = init_peer_node(init_peer(ip, port, t), NULL);
          else
               add_peer(&t->peer_list, init_peer(ip, port, t));
     }
}
예제 #16
0
/*
 * This routine registers all the files in the directory <dirname>
 * with the index server against the peer.
 */
int
register_files(char *localhostname, char *dirname)
{
    DIR *dirp;
    struct dirent *entp;
    bool_t ret;
    int res;
    char name[MAXPATHLEN];
    struct stat sbuf;

    if ((dirp = opendir(dirname)) == NULL) {
        printf("opendir(%s) failed with errno %d\n", dirname, errno);
	printf("Please check if the directory %s exists and is accessible\n",dirname);
        return (errno);
    }

    while ((entp = readdir(dirp)) != NULL) {
        /*
         * Skip "." and ".."
         */
        if (strcmp(entp->d_name, ".") == 0 || strcmp(entp->d_name, "..") == 0)
            continue;
        printf("Registering file : %s to the index-server : %s\n", entp->d_name, localhostname);

        sprintf(name, "%s/%s", dirname, entp->d_name);
        if (stat(name, &sbuf) != 0) {
            printf("register_files : stat(%s) failed. errno=%d\n", name, errno);
        }
/*-------------- start change ----------------*/
        ret = add_peer(entp->d_name, localhostname, PRIMARY, 0, ttrtime, sbuf.st_mtime);
/*-------------- end change ----------------*/
        filecount++;
    }

    closedir(dirp);
    return (0);
}
예제 #17
0
int add_peer() {
    CHECK_FLAG(conf);
    CHECK_FLAG(peer);
    CHECK_FLAG(group);
    Configuration conf;
    if (conf.parse_from(FLAGS_conf) != 0) {
        LOG(ERROR) << "Fail to parse --conf=`" << FLAGS_conf << '\'';
        return -1;
    }
    PeerId new_peer;
    if (new_peer.parse(FLAGS_peer) != 0) {
        LOG(ERROR) << "Fail to parse --peer=`" << FLAGS_peer<< '\'';
        return -1;
    }
    CliOptions opt;
    opt.timeout_ms = FLAGS_timeout_ms;
    opt.max_retry = FLAGS_max_retry;
    butil::Status st = add_peer(FLAGS_group, conf, new_peer, opt);
    if (!st.ok()) {
        LOG(ERROR) << "Fail to add_peer : " << st;
        return -1;
    }
    return 0;
}
예제 #18
0
파일: server.c 프로젝트: vatlidak/undergrad
void *serving_thread(void *argp) 
{
	char 	buffer[BUFSIZE];
	char	*clientip,*clientport;
	char 	*type,*data=NULL;
	int 	rval;
	int err;
	char 	*filename,*md5sum="xxx",*filesize="12324";
	int 	socket = *(int*)argp;
	fileptr tempnode;
	FILE 	*fp;
	char 	prints[45];
	
	printf("in thread:%d\n",socket);
	
	
	sprintf(prints,"../serverLog.%u",(unsigned int)pthread_self());
	if ( (fp = fopen(prints,"wb")) == NULL )
	{
		perror("fopen");
		return NULL;
	}
	if	(err=pthread_detach (pthread_self ()))	
	{
		// Detach thread  
		perror2("pthread_detach ",err);
		return NULL; 
	}
	////////////////////////////////////////////////////////////////


	if ((rval=myread(socket, buffer, BUFSIZE)) <= 0)
	{
		perror("read"); 
		return NULL;
	}
	if ( GetType(buffer,fp) == JOINREQUEST)
	{ 
		parse_JoinRequest(buffer,&clientip,&clientport);
		JoinResponse(buffer);
		fprintf(fp,"JoinResponse to client with ip: %s\n",clientip);
		if(mywrite(socket,buffer,BUFSIZE) <= 0 )
		{
			perror("write");
			return NULL;
		}
				
	}	
	while (runflag)
	{
	
		///Ask FileList///
		int rval;
		if ( (rval=myread(socket, buffer , BUFSIZE)) < 0)
		{	
			perror("read"); 
			break;
		}
		//an to socket exei kleisei
		else if ( rval == 0 )
		{
			close(socket);	
			break;
		}
		else if (GetType(buffer,fp) == ASKFILELIST) 
		{	
			//if (err = pthread_mutex_lock(&serverlist_mux) ){ 
			//	perror2(" pthread_mutex_lock ",err ); exit(1); }
			fprintf(fp,"upadate server's list\n");	
			initialize("./",&metadata);
			printf("initialization:\n");
			printfile(metadata);
			//chekarw ti lista me ta arxeia pou diatiro kai gia kathe komvo tha ftiaxno 2 orismata pou tou 
			//antistixoun filename kai md5 na mi ksexasw teleuteoorisma NULL
			FileList(buffer,metadata);
			fprintf(fp,"Send FileList to client with ip: %s\n",clientip);
			//if (err = pthread_mutex_unlock(&serverlist_mux) ){ 
			//	perror2(" pthread_mutex_unlock ",err ); exit(1); }
			if(mywrite(socket,buffer,BUFSIZE) <= 0 )
			{
				perror("write");
				break;
			}		
		}
		///AskFile///
		else if (GetType(buffer,fp) == ASKFILE)
		{ 
			parse_AskFile(buffer,&filename);
			fprintf(fp,"client with ip: %s asked for file:%s\n",clientip,filename);
			//lock list gia anazitisi tou arxeiou
			if (err = pthread_mutex_lock(&serverlist_mux) ){ 
				perror2(" pthread_mutex_lock ",err ); exit(1); }
			tempnode=filenode(metadata,filename,NULL);
			if (err = pthread_mutex_unlock(&serverlist_mux) ){ 
				perror2(" pthread_mutex_unlock ",err ); exit(1); }
			AskFileResponse(buffer,filename,myip,myport);
			fprintf(fp,"server is going to send the file to client \n");
			if(mywrite(socket,buffer,BUFSIZE) <= 0 )
			{	
				perror("write");
				break;
			}	
		}
		///GetFile///	
		else if (GetType(buffer,fp) == GETFILE)
		{
			parse_GetFile(buffer,&filename,&md5sum);
			//stelnei to arxeio pou tou zita kai sti lista tou oti autos o client exei pleon to arxeio
			//lock list gia na ton prosthesei sti lista
			GetFileResponse(socket,filename,md5sum);	
			if (err = pthread_mutex_lock(&serverlist_mux) ){ 
				perror2(" pthread_mutex_lock ",err ); exit(1); }
			tempnode=filenode(metadata,filename,md5sum);
			add_peer(&tempnode,clientip,clientport);
			if (err = pthread_mutex_unlock(&serverlist_mux) ){ 
				perror2(" pthread_mutex_unlock ",err ); exit(1); }
			fprintf(fp,"send  File %s to client with ip: %s\n",filename,clientip);		
		}
		///SendFile	
		else if (GetType(buffer,fp) == SENDFILE)
		{ 
			parse_SendFile(buffer,&filename,&md5sum,&filesize,socket);
			//lock list gia na prosthesei to arxeio
			if (err = pthread_mutex_lock(&serverlist_mux) ){ 
				perror2(" pthread_mutex_lock ",err ); exit(1); }
			add_file(&metadata,filename,md5sum);
			tempnode=filenode(metadata,filename,md5sum);
			add_peer(&tempnode,clientip,clientport);
			if (err = pthread_mutex_unlock(&serverlist_mux) ){ 
				perror2(" pthread_mutex_unlock ",err ); exit(1); }
			SendFileResponse(buffer,filename,md5sum);
			fprintf(fp,"new File %s from client with ip: %s\n",filename,clientip);
			if(mywrite(socket,buffer,BUFSIZE) <= 0 )
			{
				perror("write");
				break;
			}	
		
		}
		///DeleteFile	
		else if (GetType(buffer,fp) == DELETEFILE)
		{ 
			printf("DeleteFile\n");
			parse_DeleteFile(buffer,&filename,&md5sum);
			fprintf(fp,"File to delete: %s \n",filename);
			//lock list mux
			if (err = pthread_mutex_lock(&serverlist_mux) ){ 
				perror2(" pthread_mutex_lock ",err ); exit(1); }
			tempnode=filenode(metadata,filename,NULL);
			if (err = pthread_mutex_unlock(&serverlist_mux) ){ 
				perror2(" pthread_mutex_unlock ",err ); exit(1); }
			//lock file mux
			if (err = pthread_mutex_lock(&tempnode->file_mux) ){ 
				perror2(" pthread_mutex_lock ",err ); exit(1); }
			if( remove(filename) != 0 )
    				perror( "Error deleting file" );
  			else
    				printf("File  %s successfully deleted\n",filename);
			if (err = pthread_mutex_unlock(&tempnode->file_mux) ){ 
				perror2(" pthread_mutex_unlock ",err ); exit(1); }
			//lock list mux
			if (err = pthread_mutex_lock(&serverlist_mux) ){ 
				perror2(" pthread_mutex_lock ",err ); exit(1); }
			delete_file(&metadata,filename,md5sum);
			if (err = pthread_mutex_unlock(&serverlist_mux) ){ 
				perror2(" pthread_mutex_unlock ",err ); exit(1); }
			DeleteFileResponse(buffer,filename,md5sum);
			fprintf(fp,"file deleted %s\n",filename);
			if(mywrite(socket,buffer,BUFSIZE) <= 0 )
			{
				perror("write");
				break;
			}	
		}	
	}
	close(socket);
	fprintf(fp,"Closing connection.\n");
	fclose(fp);
	free(argp);
}
예제 #19
0
//there should be lock handle, such as global_stat_spin, but I just don't want to implement it now.
int update_peer_table(struct peer_profile_t** peer_table, FILE *secrets_file, int max_id)
{
    if(NULL == peer_table || NULL == secrets_file)
    {
        ERROR(0, "update_peer_table: peer_table or secrets_file is NULL");
        return -1;
    }
    
    int i;
    for(i = 0; i < max_id+1; i++)
        if(peer_table[i] != NULL)
            peer_table[i]->discard = true;

    size_t len = 1024;
    char *line = (char *)malloc(len);
    if(line == NULL)
    {
        ERROR(errno, "update_peer_table: malloc failed");
        return -1;
    }
    else
        bzero(line, len);

    while(-1 != getline(&line, &len, secrets_file))  //why line is an array of char*, not a char* ?
    {
        int id = 0;
        char *id_str = NULL;
        char *psk_str = NULL;
        char *ip_name_str = NULL;
        char *ip6_str = NULL;
        char *port_str = NULL;

        if(shrink_line(line) <= 1)
            continue;
        id_str = strtok(line, " ");
        psk_str = strtok(NULL, " ");
        ip_name_str = strtok(NULL, " ");
        ip6_str = strtok(NULL, " ");
        port_str = strtok(NULL, " ");

        if(NULL == id_str)
            continue;
        if(NULL == psk_str)
        {
            WARNING("PSK of ID %s not found, ignore this peer!", id_str);
            continue;
        }
        id = inet_ptons(id_str);
        if(0 == id || id > max_id)
        {
            WARNING("The ID of %s may be wrong, ignore this peer!", id_str);
            continue;
        }
        
        struct peer_profile_t * tmp_peer = add_peer();
        if(tmp_peer == NULL)
        {
            ERROR(errno, "update_peer_table: add_peer failed.");
            return -1;
        }
        if(peer_table[id] != NULL)
            if(copy_peer(tmp_peer, peer_table[id]) < 0)
                ERROR(0, "Copy the ID of %s failed.", id_str);

        tmp_peer->id = id;
        tmp_peer->discard = false;

        if(strlen(psk_str) > 2*AES_TEXT_LEN)
            WARNING("PSK of ID %s is longer than %d, ignore some bytes.", id_str, 2*AES_TEXT_LEN);
        strncpy((char*)tmp_peer->psk, psk_str, 2*AES_TEXT_LEN);

        if(port_str != NULL) //port_str must be parsed before ip, because servaddr.sin_port uses it.
        {
            int port = atoi(port_str);
            if(port < 1)
                WARNING("Invalid PORT of peer: %s, ingore it's port value!", id_str);
            tmp_peer->port = port;
        }

        if(ip_name_str != NULL && strcmp(ip_name_str, "none") != 0)
        {
            char ip_str[IPV4_LEN] = "\0";
            if(hostname_to_ip(ip_name_str, ip_str) < 0)
                WARNING("Invalid host of peer: %s, %s nslookup failed, ingore it's IP/Port value!", id_str, ip_name_str);
            else
            {
                inet_pton(AF_INET, ip_str, &(tmp_peer->peeraddr->sin_addr));
                tmp_peer->peeraddr->sin_family = AF_INET;
                tmp_peer->peeraddr->sin_port = htons(tmp_peer->port);
                tmp_peer->restricted = true;
            }
        }

        if(ip6_str != NULL && strcmp(ip6_str, "none") != 0)
            WARNING("IPv6 not supported now, ignore it!");

        tmp_peer->vip = htonl(id); //0.0.x.x in network byte order, used inside tunnel.
        //tmp_peer->rip = (global_tunif.addr & global_tunif.mask) | htonl(id); //in network byte order.

        if(peer_table[id] != NULL &&
            tmp_peer->peeraddr->sin_addr.s_addr == peer_table[id]->peeraddr->sin_addr.s_addr &&
            tmp_peer->peeraddr->sin_port == peer_table[id]->peeraddr->sin_port &&
            strncmp((char *)(tmp_peer->psk), (char *)(peer_table[id]->psk), 2*AES_TEXT_LEN) == 0)
        {
            //the peer does not change
            peer_table[id]->discard = false;
            delete_peer(tmp_peer);
            tmp_peer = NULL;
            continue;
        }

        if(peer_table[id] != NULL)
        {
            INFO("update the ID of %s.", id_str);
            if(copy_peer(peer_table[id], tmp_peer) < 0)
                ERROR(0, "Update the ID of %s failed", id_str);
            delete_peer(tmp_peer);
            tmp_peer = NULL;
        }
        else
        {
            INFO("Add the ID of %s.", id_str);
            peer_table[id] = tmp_peer;
        }
    }

    free(line);

    for(i = 0; i < max_id+1; i++)
        if(peer_table[i] != NULL)
            if(peer_table[i]->discard)
            {
                WARNING("Delete the ID of %d.%d.", i/256, i%256);
                delete_peer(peer_table[i]);
                peer_table[i] = NULL;
            }

    return 0;
}
예제 #20
0
int contact_tracker(bt_args_t *bt_args)
{
    printf("Please wait ...\nConnecting with tracker.\n");

    char *new_file;
    long long leng;

    new_file = read_file(bt_args->torrent_file, &leng);

    if (!new_file)
        return 1;

    char *inf = strstr(strstr(new_file, "info"), "d");
    // length on ubuntu 14.04 torrent should be 44478
    long long len = be_len(inf);

    memset(bt_args->info_hash, '\0', BT_INFO_HASH_SIZE);
    memset(bt_args->bt_peer_id, '\0', BT_INFO_HASH_SIZE);
    SHA1((unsigned char const *) inf, (size_t) len, (unsigned char *) bt_args->info_hash);

    char *request_to_send = malloc(FILE_NAME_MAX);
    request_to_send = malloc(FILE_NAME_MAX);

    memset(request_to_send, '\0', FILE_NAME_MAX);
    memcpy(bt_args->bt_peer_id, generate_peer_id(), 20);

    //Port number this peer is listening on.
    //Common behavior is for a downloader to try to listen on
    //port 6881 and if that port is taken try 6882, then 6883, etc. and give up after 6889.
    uint16_t port = INIT_PORT;
    bt_args->bt_info->num_pieces = bt_args->bt_info->length / bt_args->bt_info->piece_length;
    sprintf(request_to_send,
            "%s?info_hash=%s&peer_id=%s&port=%hu&uploaded=0"
            "&downloaded=0&left=%d&event=started&compact=1",
            bt_args->bt_info->announce, url_encode(bt_args->info_hash),
            url_encode(bt_args->bt_peer_id), port, bt_args->bt_info->length);

    // correct request to send on ubuntu torrent

    //  http://torrent.ubuntu.com:6969/announce?
    //      info_hash=%B4%15%C9%13d%3E%5F%F4%9F%E3%7D0K%BB%5En%11%ADQ%01
    //      announce?info_hash=%b4%15%c9%13d%3e_%f4%9f%e3%7d0K%bb%5en%11%adQ%01
    //      &peer_id=TueFeb32137332015RRR&port=6681&event=started&uploaded=0
    //      &downloaded=0&left=1162936320&compact=1

    if (bt_args->verbose)
        printf("Request URL for tracker: %s\n", request_to_send);

    char *result = _send_http_request(request_to_send);
    if (result)
    {
        be_node *node = be_decoden(result, (long long int) be_len);

        if (bt_args->verbose)
            be_dump(node);

        bt_peer *peer = malloc(sizeof(bt_peer));

        // parse_info(peer, node);
        _fill_peer_info(peer, node, 0, "");

        int num_peers = 0;

        char *peer_num = strstr(result, "peers");
        if (peer_num == NULL)
        {
            printf("Something went wrong in parsing received data!\n");
            free(result);
            return 1;
        }
        int i = 0;
        peer_num += 5;
        char buff[20];
        memset(buff, 0, 20);
        for (; *peer_num != ':'; peer_num++, i++)
            buff[i] = *peer_num;

        char *endptr;
        num_peers = (int) strtol(buff, &endptr, 10) / 6;

        if (num_peers == 0)
        {
            free(result);
            return 1;
        }
        int count = 0;
        pthread_t *thread = malloc(num_peers * sizeof(pthread_t));
        printf("Connecting with peers.\n");
        for (i = 0; i < num_peers; i++)
        {
            uint32_t ip = *(uint32_t *) (peer->peer_hashes + count);
            count = (int) (count + sizeof(uint32_t));
            port = *(uint16_t *) (peer->peer_hashes + count);
            count = (int) (count + sizeof(uint16_t));

            peer_t *my_peer_t = malloc(sizeof(peer_t));

            my_peer_t->interested = -1;
            my_peer_t->choked = -1;

            //IP to string
            struct in_addr ip_addr;
            ip_addr.s_addr = ip;

            char *id = malloc(21);
            memset(id, 0, 21);
            calc_id(inet_ntoa(ip_addr), port, id);
            memset(my_peer_t->id, 0, ID_SIZE);
            strcpy((char *) my_peer_t->id, id);

            init_peer(my_peer_t, id, inet_ntoa(ip_addr), htons(port));
            add_peer(my_peer_t, bt_args, inet_ntoa(ip_addr), port);

            thdata *data = malloc(sizeof(thdata));

            data->th_num = i;
            data->bt_args = bt_args;
            data->bt_peer_t = my_peer_t;

            pthread_create (&thread[i], NULL, (void *) &_connect_function, (void *) data);
        }

        for (i = 0; i < num_peers; i++);
        pthread_join(thread[i], NULL);
    }
    else
    {
        printf("Something went wrong!\n");
        return 1;
    }

    return 0;
}