Browse Source

udp is working in theory, return_peers_for_torrent accepts a switch to request an udp answer. Fixed prototypes.

dynamic-accesslists
erdgeist 18 years ago
parent
commit
0a90216686
  1. 85
      opentracker.c
  2. 11
      trackerlogic.c
  3. 2
      trackerlogic.h

85
opentracker.c

@ -74,6 +74,12 @@ static void handle_timeouted( void );
static void handle_accept( const int64 serversocket ); static void handle_accept( const int64 serversocket );
static void handle_read( const int64 clientsocket ); static void handle_read( const int64 clientsocket );
static void handle_write( const int64 clientsocket ); static void handle_write( const int64 clientsocket );
static void handle_udp4( const int64 serversocket );
static void ot_try_bind_udp4( char ip[4], uint16 port );
static void ot_try_bind_tcp4( char ip[4], uint16 port );
static int ot_in_udp4_sockets( int64 fd );
static int ot_in_tcp4_sockets( int64 fd );
static void usage( char *name ); static void usage( char *name );
static void help( char *name ); static void help( char *name );
@ -381,7 +387,7 @@ ANNOUNCE_WORKAROUND:
reply_size = sprintf( static_outbuf + SUCCESS_HTTP_HEADER_LENGTH, "d8:completei0e10:incompletei0e8:intervali%ie5:peers0:e", OT_CLIENT_REQUEST_INTERVAL_RANDOM ); reply_size = sprintf( static_outbuf + SUCCESS_HTTP_HEADER_LENGTH, "d8:completei0e10:incompletei0e8:intervali%ie5:peers0:e", OT_CLIENT_REQUEST_INTERVAL_RANDOM );
} else { } else {
torrent = add_peer_to_torrent( hash, &peer ); torrent = add_peer_to_torrent( hash, &peer );
if( !torrent || !( reply_size = return_peers_for_torrent( torrent, numwant, SUCCESS_HTTP_HEADER_LENGTH + static_outbuf ) ) ) HTTPERROR_500; if( !torrent || !( reply_size = return_peers_for_torrent( torrent, numwant, SUCCESS_HTTP_HEADER_LENGTH + static_outbuf, 1 ) ) ) HTTPERROR_500;
} }
ot_overall_successfulannounces++; ot_overall_successfulannounces++;
break; break;
@ -555,17 +561,76 @@ static void handle_timeouted( void ) {
} }
} }
void handle_udp4( int64 serversocket ) { static void handle_udp4( int64 serversocket ) {
size_t r; ot_peer peer;
ot_torrent *torrent;
ot_hash *hash = NULL;
char remoteip[4]; char remoteip[4];
unsigned long *inpacket = (unsigned long*)static_inbuf;
unsigned long *outpacket = (unsigned long*)static_outbuf;
unsigned long numwant, left, event;
uint16 port; uint16 port;
size_t r;
r = socket_recv4( serversocket, static_inbuf, 8192, remoteip, &port);
/* Minimum udp tracker packet size, also catches error */
if( r < 16 )
return;
switch( ntohl( inpacket[2] ) ) {
case 0: /* This is a connect action */
outpacket[0] = 0; outpacket[1] = inpacket[3];
outpacket[2] = inpacket[0]; outpacket[3] = inpacket[1];
socket_send4( serversocket, static_outbuf, 16, remoteip, port );
break;
case 1: /* This is an announce action */
/* Minimum udp announce packet size */
if( r < 98 )
return;
numwant = 200;
left = ntohl( inpacket[64/4] );
event = ntohl( inpacket[80/4] );
port = ntohl( inpacket[96/4] );
hash = (ot_hash*)inpacket+(16/4);
r = socket_recv4(serversocket, static_inbuf, 8192, remoteip, &port); OT_SETIP( &peer, remoteip );
OT_SETPORT( &peer, &port );
OT_FLAG( &peer ) = 0;
switch( event ) {
case 1: OT_FLAG( &peer ) |= PEER_FLAG_COMPLETED; break;
case 3: OT_FLAG( &peer ) |= PEER_FLAG_STOPPED; break;
default: break;
}
if( !left )
OT_FLAG( &peer ) |= PEER_FLAG_SEEDING;
if( OT_FLAG( &peer ) & PEER_FLAG_STOPPED ) {
/* Peer is gone. */
remove_peer_from_torrent( hash, &peer );
// too lazy :) /* Create fake packet to satisfy parser on the other end */
outpacket[0] = htonl( 1 );
outpacket[1] = inpacket[12/4];
outpacket[2] = outpacket[3] = outpacket[4] = 0;
socket_send4( serversocket, static_outbuf, 20, remoteip, port );
} else {
torrent = add_peer_to_torrent( hash, &peer );
if( !torrent )
return; /* XXX maybe send error */
outpacket[0] = htonl( 1 );
outpacket[1] = inpacket[12/4];
r = 8 + return_peers_for_torrent( torrent, numwant, static_outbuf + 8, 0 );
socket_send4( serversocket, static_outbuf, r, remoteip, port );
}
break;
}
} }
int ot_in_tcp4_sockets( int64 fd ) { static int ot_in_tcp4_sockets( int64 fd ) {
int i; int i;
for( i=0; i<ot_sockets_tcp4_count; ++i) for( i=0; i<ot_sockets_tcp4_count; ++i)
if( ot_sockets_tcp4[i] == fd ) if( ot_sockets_tcp4[i] == fd )
@ -573,7 +638,7 @@ int ot_in_tcp4_sockets( int64 fd ) {
return 0; return 0;
} }
int ot_in_udp4_sockets( int64 fd ) { static int ot_in_udp4_sockets( int64 fd ) {
int i; int i;
for( i=0; i<ot_sockets_udp4_count; ++i) for( i=0; i<ot_sockets_udp4_count; ++i)
if( ot_sockets_udp4[i] == fd ) if( ot_sockets_udp4[i] == fd )
@ -614,7 +679,7 @@ static void server_mainloop( ) {
} }
} }
void ot_try_bind_tcp4( char ip[4], uint16 port ) { static void ot_try_bind_tcp4( char ip[4], uint16 port ) {
int64 s = socket_tcp4( ); int64 s = socket_tcp4( );
if( ot_sockets_tcp4_count == OT_MAXSOCKETS_TCP4 ) { if( ot_sockets_tcp4_count == OT_MAXSOCKETS_TCP4 ) {
fprintf( stderr, "Too many tcp4 sockets, increase OT_MAXSOCKETS_TCP4 and recompile.\n"); exit(1); fprintf( stderr, "Too many tcp4 sockets, increase OT_MAXSOCKETS_TCP4 and recompile.\n"); exit(1);
@ -633,7 +698,7 @@ void ot_try_bind_tcp4( char ip[4], uint16 port ) {
ot_sockets_tcp4[ ot_sockets_tcp4_count++ ] = s; ot_sockets_tcp4[ ot_sockets_tcp4_count++ ] = s;
} }
void ot_try_bind_udp4( char ip[4], uint16 port ) { static void ot_try_bind_udp4( char ip[4], uint16 port ) {
int64 s = socket_udp4( ); int64 s = socket_udp4( );
if( ot_sockets_udp4_count == OT_MAXSOCKETS_UDP4 ) { if( ot_sockets_udp4_count == OT_MAXSOCKETS_UDP4 ) {
fprintf( stderr, "Too many udp4 sockets, increase OT_MAXSOCKETS_UDP4 and recompile.\n"); exit(1); fprintf( stderr, "Too many udp4 sockets, increase OT_MAXSOCKETS_UDP4 and recompile.\n"); exit(1);
@ -655,7 +720,7 @@ int main( int argc, char **argv ) {
int scanon = 1; int scanon = 1;
while( scanon ) { while( scanon ) {
switch( getopt( argc, argv, ":i:p:d:ocbBh" ) ) { switch( getopt( argc, argv, ":i:p:P:d:ocbBh" ) ) {
case -1 : scanon = 0; break; case -1 : scanon = 0; break;
case 'i': scan_ip4( optarg, serverip ); break; case 'i': scan_ip4( optarg, serverip ); break;
case 'p': ot_try_bind_tcp4( serverip, (uint16)atol( optarg ) ); break; case 'p': ot_try_bind_tcp4( serverip, (uint16)atol( optarg ) ); break;

11
trackerlogic.c

@ -269,7 +269,7 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer ) {
* RANDOM may return huge values * RANDOM may return huge values
* does not yet check not to return self * does not yet check not to return self
*/ */
size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply ) { size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply, int is_tcp ) {
char *r = reply; char *r = reply;
size_t peer_count, seed_count, index; size_t peer_count, seed_count, index;
@ -295,7 +295,15 @@ size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply
} }
if( peer_count < amount ) amount = peer_count; if( peer_count < amount ) amount = peer_count;
if( is_tcp )
r += sprintf( r, "d8:completei%zde10:incompletei%zde8:intervali%ie5:peers%zd:", seed_count, peer_count-seed_count, OT_CLIENT_REQUEST_INTERVAL_RANDOM, 6*amount ); r += sprintf( r, "d8:completei%zde10:incompletei%zde8:intervali%ie5:peers%zd:", seed_count, peer_count-seed_count, OT_CLIENT_REQUEST_INTERVAL_RANDOM, 6*amount );
else {
*(unsigned long*)(r+0) = htonl( OT_CLIENT_REQUEST_INTERVAL_RANDOM );
*(unsigned long*)(r+4) = htonl( peer_count );
*(unsigned long*)(r+8) = htonl( seed_count );
r += 12;
}
if( amount ) { if( amount ) {
unsigned int pool_offset, pool_index = 0;; unsigned int pool_offset, pool_index = 0;;
unsigned int shifted_pc = peer_count; unsigned int shifted_pc = peer_count;
@ -327,6 +335,7 @@ size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply
r += 6; r += 6;
} }
} }
if( is_tcp )
*r++ = 'e'; *r++ = 'e';
return r - reply; return r - reply;

2
trackerlogic.h

@ -94,7 +94,7 @@ extern int g_check_blacklist;
enum { STATS_MRTG, STATS_TOP5, STATS_DMEM }; enum { STATS_MRTG, STATS_TOP5, STATS_DMEM };
ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer ); ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer );
size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply ); size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply, int is_tcp );
size_t return_fullscrape_for_tracker( char **reply ); size_t return_fullscrape_for_tracker( char **reply );
size_t return_scrape_for_torrent( ot_hash *hash, char *reply ); size_t return_scrape_for_torrent( ot_hash *hash, char *reply );
size_t return_sync_for_torrent( ot_hash *hash, char **reply ); size_t return_sync_for_torrent( ot_hash *hash, char **reply );

Loading…
Cancel
Save