|
|
@ -368,7 +368,7 @@ static void handle_read( int64 peersocket ) { |
|
|
|
|
|
|
|
|
|
|
|
/* See, if we already have a connection to that peer */ |
|
|
|
/* See, if we already have a connection to that peer */ |
|
|
|
for( i=0; i<MAX_PEERS; ++i ) |
|
|
|
for( i=0; i<MAX_PEERS; ++i ) |
|
|
|
if( ( g_connections[i].state & FLAG_MASK ) == FLAG_CONNECTED && |
|
|
|
if( ( g_connections[i].state & FLAG_MASK ) == FLAG_CONNECTED && |
|
|
|
g_connections[i].tracker_id == tracker_id ) { |
|
|
|
g_connections[i].tracker_id == tracker_id ) { |
|
|
|
fprintf( stderr, "Peer already connected. Closing connection.\n" ); |
|
|
|
fprintf( stderr, "Peer already connected. Closing connection.\n" ); |
|
|
|
goto close_socket; |
|
|
|
goto close_socket; |
|
|
@ -557,8 +557,8 @@ int main( int argc, char **argv ) { |
|
|
|
ot_try_bind( serverip, tmpport ); |
|
|
|
ot_try_bind( serverip, tmpport ); |
|
|
|
++sbound; |
|
|
|
++sbound; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 'c': |
|
|
|
case 'c': |
|
|
|
if( g_connection_count > MAX_PEERS / 2 ) exerr( "Connection limit exceeded.\n" ); |
|
|
|
if( g_connection_count > MAX_PEERS / 2 ) exerr( "Connection limit exceeded.\n" ); |
|
|
|
tmpport = 0; |
|
|
|
tmpport = 0; |
|
|
|
if( !scan_ip6_port( optarg, |
|
|
|
if( !scan_ip6_port( optarg, |
|
|
|
g_connections[g_connection_count].ip, |
|
|
|
g_connections[g_connection_count].ip, |
|
|
@ -613,46 +613,42 @@ static void * streamsync_worker( void * args ) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Maximal memory requirement: max 3 blocks, max torrents * 20 + max peers * 7 */ |
|
|
|
/* Maximal memory requirement: max 3 blocks, max torrents * 20 + max peers * 7 */ |
|
|
|
mem = 3 * ( 4 + 1 + 1 + 2 ) + ( count_one + count_two ) * 19 + count_def * 20 + |
|
|
|
mem = 3 * ( 4 + 1 + 1 + 2 ) + ( count_one + count_two ) * 19 + count_def * ( 19 + 6 ) + |
|
|
|
( count_one + 2 * count_two + count_peers ) * 7; |
|
|
|
( count_one + 2 * count_two + count_peers ) * 7; |
|
|
|
|
|
|
|
|
|
|
|
fprintf( stderr, "Mem: %zd\n", mem ); |
|
|
|
fprintf( stderr, "Mem: %zd\n", mem ); |
|
|
|
|
|
|
|
|
|
|
|
ptr = ptr_a = ptr_b = ptr_c = malloc( mem ); |
|
|
|
ptr = ptr_a = ptr_b = ptr_c = malloc( mem ); |
|
|
|
if( !ptr ) goto unlock_continue; |
|
|
|
if( !ptr ) goto unlock_continue; |
|
|
|
|
|
|
|
|
|
|
|
if( count_one > 8 ) { |
|
|
|
if( count_one > 8 || !count_def ) { |
|
|
|
mem_a = 4 + 1 + 1 + 2 + count_one * ( 19 + 7 ); |
|
|
|
mem_a = 4 + 1 + 1 + 2 + count_one * ( 19 + 7 ); |
|
|
|
ptr_b += mem_a; ptr_c += mem_a; |
|
|
|
ptr_b += mem_a; ptr_c += mem_a; |
|
|
|
memcpy( ptr_a, &g_tracker_id, sizeof(g_tracker_id)); /* Offset 0: the tracker ID */ |
|
|
|
memcpy( ptr_a, &g_tracker_id, sizeof(g_tracker_id)); /* Offset 0: the tracker ID */ |
|
|
|
ptr_a[4] = 1; /* Offset 4: packet type 1 */ |
|
|
|
ptr_a[4] = 1; /* Offset 4: packet type 1 */ |
|
|
|
ptr_a[5] = (bucket << 8) >> OT_BUCKET_COUNT_BITS; /* Offset 5: the shared prefix */ |
|
|
|
ptr_a[5] = (bucket << 8) >> OT_BUCKET_COUNT_BITS; /* Offset 5: the shared prefix */ |
|
|
|
ptr_a[6] = count_one >> 8; |
|
|
|
ptr_a[6] = count_one >> 8; |
|
|
|
ptr_a[7] = count_one & 255; |
|
|
|
ptr_a[7] = count_one & 255; |
|
|
|
ptr_a += 8; |
|
|
|
ptr_a += 8; |
|
|
|
} else { |
|
|
|
} else |
|
|
|
count_def += count_one; |
|
|
|
count_def += count_one; |
|
|
|
count_peers += count_one; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( count_two > 8 ) { |
|
|
|
if( count_two > 8 || !count_def ) { |
|
|
|
mem_b = 4 + 1 + 1 + 2 + count_two * ( 19 + 14 ); |
|
|
|
mem_b = 4 + 1 + 1 + 2 + count_two * ( 19 + 14 ); |
|
|
|
ptr_c += mem_b; |
|
|
|
ptr_c += mem_b; |
|
|
|
memcpy( ptr_b, &g_tracker_id, sizeof(g_tracker_id)); /* Offset 0: the tracker ID */ |
|
|
|
memcpy( ptr_b, &g_tracker_id, sizeof(g_tracker_id)); /* Offset 0: the tracker ID */ |
|
|
|
ptr_b[4] = 2; /* Offset 4: packet type 2 */ |
|
|
|
ptr_b[4] = 2; /* Offset 4: packet type 2 */ |
|
|
|
ptr_b[5] = (bucket << 8) >> OT_BUCKET_COUNT_BITS; /* Offset 5: the shared prefix */ |
|
|
|
ptr_b[5] = (bucket << 8) >> OT_BUCKET_COUNT_BITS; /* Offset 5: the shared prefix */ |
|
|
|
ptr_b[6] = count_two >> 8; |
|
|
|
ptr_b[6] = count_two >> 8; |
|
|
|
ptr_b[7] = count_two & 255; |
|
|
|
ptr_b[7] = count_two & 255; |
|
|
|
ptr_b += 8; |
|
|
|
ptr_b += 8; |
|
|
|
} else { |
|
|
|
} else |
|
|
|
count_def += count_two; |
|
|
|
count_def += count_two; |
|
|
|
count_peers += 2 * count_two; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( count_def ) { |
|
|
|
if( count_def ) { |
|
|
|
memcpy( ptr_c, &g_tracker_id, sizeof(g_tracker_id)); /* Offset 0: the tracker ID */ |
|
|
|
memcpy( ptr_c, &g_tracker_id, sizeof(g_tracker_id)); /* Offset 0: the tracker ID */ |
|
|
|
ptr_c[4] = 0; /* Offset 4: packet type 0 */ |
|
|
|
ptr_c[4] = 0; /* Offset 4: packet type 0 */ |
|
|
|
ptr_c[5] = (bucket << 8) >> OT_BUCKET_COUNT_BITS; /* Offset 5: the shared prefix */ |
|
|
|
ptr_c[5] = (bucket << 8) >> OT_BUCKET_COUNT_BITS; /* Offset 5: the shared prefix */ |
|
|
|
ptr_c[6] = count_def >> 8; |
|
|
|
ptr_c[6] = count_def >> 8; |
|
|
|
ptr_c[7] = count_def & 255; |
|
|
|
ptr_c[7] = count_def & 255; |
|
|
|
ptr_c += 8; |
|
|
|
ptr_c += 8; |
|
|
@ -665,26 +661,36 @@ static void * streamsync_worker( void * args ) { |
|
|
|
ot_peerlist *peer_list = torrent->peer_list; |
|
|
|
ot_peerlist *peer_list = torrent->peer_list; |
|
|
|
ot_peer *peers = (ot_peer*)(peer_list->peers.data); |
|
|
|
ot_peer *peers = (ot_peer*)(peer_list->peers.data); |
|
|
|
uint8_t **dst; |
|
|
|
uint8_t **dst; |
|
|
|
int multi = 0; |
|
|
|
|
|
|
|
switch( peer_list->peer_count ) { |
|
|
|
/* Determine destination slot */ |
|
|
|
|
|
|
|
count_peers = peer_list->peer_count; |
|
|
|
|
|
|
|
switch( count_peers ) { |
|
|
|
case 0: continue; |
|
|
|
case 0: continue; |
|
|
|
case 1: dst = mem_a ? &ptr_a : &ptr_c; break; |
|
|
|
case 1: dst = mem_a ? &ptr_a : &ptr_c; break; |
|
|
|
case 2: dst = mem_b ? &ptr_b : &ptr_c; break; |
|
|
|
case 2: dst = mem_b ? &ptr_b : &ptr_c; break; |
|
|
|
default: dst = &ptr_c; multi = 1; break; |
|
|
|
default: dst = &ptr_c; break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
do { |
|
|
|
/* Copy tail of info_hash, advance pointer */ |
|
|
|
size_t i, pc = peer_list->peer_count; |
|
|
|
memcpy( *dst, torrent->hash + 1, sizeof( ot_hash ) - 1); |
|
|
|
if( pc > 255 ) pc = 255; |
|
|
|
*dst += sizeof( ot_hash ) - 1; |
|
|
|
memcpy( *dst, torrent->hash + 1, sizeof( ot_hash ) - 1); |
|
|
|
|
|
|
|
*dst += sizeof( ot_hash ) - 1; |
|
|
|
/* Encode peer count */ |
|
|
|
if( multi ) *(*dst)++ = pc; |
|
|
|
if( dst == &ptr_c ) |
|
|
|
for( i=0; i < pc; ++i ) { |
|
|
|
while( count_peers ) { |
|
|
|
memcpy( *dst, peers++, OT_IP_SIZE + 3 ); |
|
|
|
if( count_peers <= 0x7f ) |
|
|
|
*dst += OT_IP_SIZE + 3; |
|
|
|
*(*dst)++ = count_peers; |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
*(*dst)++ = 0x80 | ( count_peers & 0x7f ); |
|
|
|
|
|
|
|
count_peers >>= 7; |
|
|
|
} |
|
|
|
} |
|
|
|
peer_list->peer_count -= pc; |
|
|
|
|
|
|
|
} while( peer_list->peer_count ); |
|
|
|
/* Copy peers */ |
|
|
|
|
|
|
|
count_peers = peer_list->peer_count; |
|
|
|
|
|
|
|
while( count_peers-- ) { |
|
|
|
|
|
|
|
memcpy( *dst, peers++, OT_IP_SIZE + 3 ); |
|
|
|
|
|
|
|
*dst += OT_IP_SIZE + 3; |
|
|
|
|
|
|
|
} |
|
|
|
free_peerlist(peer_list); |
|
|
|
free_peerlist(peer_list); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -700,7 +706,7 @@ unlock_continue: |
|
|
|
if( ptr_a > ptr_c ) ptr_c = ptr_a; |
|
|
|
if( ptr_a > ptr_c ) ptr_c = ptr_a; |
|
|
|
mem = ptr_c - ptr; |
|
|
|
mem = ptr_c - ptr; |
|
|
|
|
|
|
|
|
|
|
|
for( i=0; i<g_connection_count; ++i ) { |
|
|
|
for( i=0; i < g_connection_count; ++i ) { |
|
|
|
if( PROXYPEER_ISCONNECTED(g_connections[i].state) ) { |
|
|
|
if( PROXYPEER_ISCONNECTED(g_connections[i].state) ) { |
|
|
|
void *tmp = malloc( mem ); |
|
|
|
void *tmp = malloc( mem ); |
|
|
|
if( tmp ) { |
|
|
|
if( tmp ) { |
|
|
@ -735,18 +741,30 @@ void livesync_ticker( ) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void livesync_proxytell( uint8_t prefix, uint8_t *info_hash, uint8_t *peer ) { |
|
|
|
static void livesync_proxytell( uint8_t prefix, uint8_t *info_hash, uint8_t *peer ) { |
|
|
|
|
|
|
|
unsigned int i; |
|
|
|
|
|
|
|
|
|
|
|
*g_peerbuffer_pos = prefix; |
|
|
|
*g_peerbuffer_pos = prefix; |
|
|
|
memcpy( g_peerbuffer_pos + 1, info_hash, sizeof(ot_hash) - 1 ); |
|
|
|
memcpy( g_peerbuffer_pos + 1, info_hash, sizeof(ot_hash) - 1 ); |
|
|
|
memcpy( g_peerbuffer_pos + sizeof(ot_hash), peer, sizeof(ot_peer) - 1 ); |
|
|
|
memcpy( g_peerbuffer_pos + sizeof(ot_hash), peer, sizeof(ot_peer) - 1 ); |
|
|
|
|
|
|
|
|
|
|
|
g_peerbuffer_pos += sizeof(ot_hash) + sizeof(ot_peer); |
|
|
|
/* Dump info_hash */ |
|
|
|
|
|
|
|
for( i=0; i<sizeof(ot_hash); ++i ) |
|
|
|
|
|
|
|
printf( "%02X", g_peerbuffer_pos[i] ); |
|
|
|
|
|
|
|
putchar( ':' ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
g_peerbuffer_pos += sizeof(ot_hash); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf( "%d.%d.%d.%d:%hd (%02X %02X)\n", g_peerbuffer_pos[0], g_peerbuffer_pos[1], g_peerbuffer_pos[2], g_peerbuffer_pos[3], |
|
|
|
|
|
|
|
g_peerbuffer_pos[4] | ( g_peerbuffer_pos[5] << 8 ), g_peerbuffer_pos[6], g_peerbuffer_pos[7] ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
g_peerbuffer_pos += sizeof(ot_peer); |
|
|
|
|
|
|
|
|
|
|
|
if( g_peerbuffer_pos >= g_peerbuffer_highwater ) |
|
|
|
if( g_peerbuffer_pos >= g_peerbuffer_highwater ) |
|
|
|
livesync_issue_peersync(); |
|
|
|
livesync_issue_peersync(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void process_indata( proxy_peer * peer ) { |
|
|
|
static void process_indata( proxy_peer * peer ) { |
|
|
|
int ensuremem, consumed, peers; |
|
|
|
int consumed, peers; |
|
|
|
uint8_t *data = peer->indata, *hash; |
|
|
|
uint8_t *data = peer->indata, *hash; |
|
|
|
uint8_t *dataend = data + peer->indata_length; |
|
|
|
uint8_t *dataend = data + peer->indata_length; |
|
|
|
|
|
|
|
|
|
|
@ -760,21 +778,37 @@ static void process_indata( proxy_peer * peer ) { |
|
|
|
peer->packet_tprefix = data[5]; |
|
|
|
peer->packet_tprefix = data[5]; |
|
|
|
peer->packet_tcount = data[6] * 256 + data[7]; |
|
|
|
peer->packet_tcount = data[6] * 256 + data[7]; |
|
|
|
data += 8; |
|
|
|
data += 8; |
|
|
|
|
|
|
|
printf( "type: %d, prefix: %02X, torrentcount: %d\n", peer->packet_type, peer->packet_tprefix, peer->packet_tcount ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* ensure size for the complete torrent block */ |
|
|
|
next_torrent: |
|
|
|
if( data + 26 > dataend ) break; |
|
|
|
/* Ensure size for the complete torrent block */ |
|
|
|
peers = peer->packet_type ? peer->packet_type : data[19]; |
|
|
|
if( data + sizeof(ot_hash) + OT_IP_SIZE + 3 > dataend ) break; |
|
|
|
ensuremem = 19 + ( peer->packet_type == 0 ) + 7 * peers; |
|
|
|
|
|
|
|
if( data + ensuremem > dataend ) break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Advance pointer to peer count or peers */ |
|
|
|
hash = data; |
|
|
|
hash = data; |
|
|
|
data += 19 + ( peer->packet_type == 0 ); |
|
|
|
data += sizeof(ot_hash) - 1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Type 0 has peer count encoded before each peers */ |
|
|
|
|
|
|
|
if( peer->packet_type == 0 ) { |
|
|
|
|
|
|
|
int shift = 0; |
|
|
|
|
|
|
|
peers = 0; |
|
|
|
|
|
|
|
do peers |= ( 0x7f & *data ) << ( 7 * shift ); |
|
|
|
|
|
|
|
while ( *(data++) & 0x80 && shift++ < 6 ); |
|
|
|
|
|
|
|
} else |
|
|
|
|
|
|
|
peers = peer->packet_type; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Ensure enough data being read to hold all peers */ |
|
|
|
|
|
|
|
if( data + 7 * peers > dataend ) break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf( "peers: %d\n", peers ); |
|
|
|
|
|
|
|
|
|
|
|
while( peers-- ) { |
|
|
|
while( peers-- ) { |
|
|
|
livesync_proxytell( peer->packet_tprefix, hash, data ); |
|
|
|
livesync_proxytell( peer->packet_tprefix, hash, data ); |
|
|
|
data += 7; |
|
|
|
data += OT_IP_SIZE + 3; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if( --peer->packet_tcount ) |
|
|
|
|
|
|
|
goto next_torrent; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
consumed = data - peer->indata; |
|
|
|
consumed = data - peer->indata; |
|
|
|