size_t add_peer_to_torrent_proxy( ot_hash hash, ot_peer *peer ) { int exactmatch; ot_torrent *torrent; ot_peer *peer_dest; ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash ); torrent = vector_find_or_insert( torrents_list, (void*)hash, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); if( !torrent ) return -1; if( !exactmatch ) { /* Create a new torrent entry, then */ memcpy( torrent->hash, hash, sizeof(ot_hash) ); if( !( torrent->peer_list = malloc( sizeof (ot_peerlist) ) ) ) { vector_remove_torrent( torrents_list, torrent ); mutex_bucket_unlock_by_hash( hash, 0 ); return -1; } byte_zero( torrent->peer_list, sizeof( ot_peerlist ) ); } /* Check for peer in torrent */ peer_dest = vector_find_or_insert_peer( &(torrent->peer_list->peers), peer, &exactmatch ); if( !peer_dest ) { mutex_bucket_unlock_by_hash( hash, 0 ); return -1; } /* Tell peer that it's fresh */ OT_PEERTIME( peer ) = 0; /* If we hadn't had a match create peer there */ if( !exactmatch ) { torrent->peer_list->peer_count++; if( OT_PEERFLAG(peer) & PEER_FLAG_SEEDING ) torrent->peer_list->seed_count++; } memcpy( peer_dest, peer, sizeof(ot_peer) ); mutex_bucket_unlock_by_hash( hash, 0 ); return 0; }
size_t remove_peer_from_torrent_proxy( ot_hash hash, ot_peer *peer ) { int exactmatch; ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash ); ot_torrent *torrent = binary_search( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); if( exactmatch ) { ot_peerlist *peer_list = torrent->peer_list; switch( vector_remove_peer( &peer_list->peers, peer ) ) { case 2: peer_list->seed_count--; /* Fall throughs intended */ case 1: peer_list->peer_count--; /* Fall throughs intended */ default: break; } } mutex_bucket_unlock_by_hash( hash, 0 ); return 0; }
static int persist_add_peer(ot_hash *hash, ot_peerlist *peer_list, ot_peer *peer) { int exactmatch, delta_torrentcount = 0; ot_torrent *torrent; ot_peer *peer_dest; /* eliminate compiler warnings */ (void)peer_list; ot_vector *torrents_list = mutex_bucket_lock_by_hash(*hash); if( !accesslist_hashisvalid( hash ) ) { mutex_bucket_unlock_by_hash( *hash, 0 ); return 0; } torrent = vector_find_or_insert( torrents_list, (void*)hash, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); if( !torrent ) { mutex_bucket_unlock_by_hash( *hash, 0 ); return 0; } if( !exactmatch ) { /* Create a new torrent entry, then */ memcpy( torrent->hash, hash, sizeof(ot_hash) ); if( !( torrent->peer_list = malloc( sizeof (ot_peerlist) ) ) ) { vector_remove_torrent( torrents_list, torrent ); mutex_bucket_unlock_by_hash( *hash, 0 ); return 0; } byte_zero( torrent->peer_list, sizeof( ot_peerlist ) ); delta_torrentcount = 1; } /* Ignore torrent base in odb file, just use current clock. */ torrent->peer_list->base = g_now_minutes; /* Check for peer in torrent */ peer_dest = vector_find_or_insert_peer( &(torrent->peer_list->peers), peer, &exactmatch ); if( !peer_dest ) { mutex_bucket_unlock_by_hash( *hash, delta_torrentcount ); return 0; } /* If we hadn't had a match, create peer there */ if( !exactmatch ) { torrent->peer_list->peer_count++; if( OT_PEERFLAG(peer) & PEER_FLAG_COMPLETED ) torrent->peer_list->down_count++; if( OT_PEERFLAG(peer) & PEER_FLAG_SEEDING ) torrent->peer_list->seed_count++; } else { LOG_ERR("Repeat peer in a same torrent\n"); assert(0); } memcpy( peer_dest, peer, sizeof(ot_peer) ); mutex_bucket_unlock_by_hash( *hash, delta_torrentcount ); return 0; }