2013-02-26 19:02:50 +00:00
/*
2016-01-22 00:06:05 +00:00
* Copyright © 2012 - 2016 Naim A .
2013-02-26 19:02:50 +00:00
*
* This file is part of UDPT .
*
* UDPT is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* UDPT is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with UDPT . If not , see < http : //www.gnu.org/licenses/>.
*/
2016-01-23 18:39:03 +00:00
# include "udpTracker.hpp"
2013-08-10 20:12:08 +01:00
2013-03-07 15:37:31 +00:00
2013-03-03 22:54:48 +00:00
using namespace UDPT : : Data ;
2013-02-26 19:02:50 +00:00
# define UDP_BUFFER_SIZE 2048
namespace UDPT
{
2016-02-05 01:56:49 +00:00
UDPTracker : : UDPTracker ( const boost : : program_options : : variables_map & conf ) : m_conf ( conf ) , m_logger ( boost : : log : : keywords : : channel = " UDPTracker " )
2013-02-26 19:02:50 +00:00
{
2016-01-23 18:39:03 +00:00
this - > m_allowRemotes = conf [ " tracker.allow_remotes " ] . as < bool > ( ) ;
this - > m_allowIANA_IPs = conf [ " tracker.allow_iana_ips " ] . as < bool > ( ) ;
this - > m_isDynamic = conf [ " tracker.is_dynamic " ] . as < bool > ( ) ;
2013-02-26 19:02:50 +00:00
2016-01-23 18:39:03 +00:00
this - > m_announceInterval = conf [ " tracker.announce_interval " ] . as < unsigned > ( ) ;
this - > m_cleanupInterval = conf [ " tracker.cleanup_interval " ] . as < unsigned > ( ) ;
this - > m_port = conf [ " tracker.port " ] . as < unsigned short > ( ) ;
this - > m_threadCount = conf [ " tracker.threads " ] . as < unsigned > ( ) + 1 ;
2013-02-26 19:02:50 +00:00
2016-01-23 18:39:03 +00:00
std : : list < SOCKADDR_IN > addrs ;
2013-08-16 00:09:29 +01:00
if ( addrs . empty ( ) )
{
SOCKADDR_IN sa ;
2016-01-23 18:39:03 +00:00
sa . sin_port = m_hton16 ( m_port ) ;
2013-08-16 00:09:29 +01:00
sa . sin_addr . s_addr = 0L ;
addrs . push_back ( sa ) ;
}
2016-01-23 18:39:03 +00:00
this - > m_localEndpoint = addrs . front ( ) ;
2016-01-31 22:10:49 +00:00
this - > m_conn = std : : shared_ptr < DatabaseDriver > ( new Data : : SQLite3Driver ( m_conf , this - > m_isDynamic ) ) ;
2013-02-26 19:02:50 +00:00
}
2016-01-23 18:39:03 +00:00
UDPTracker : : ~ UDPTracker ( )
2013-02-26 19:02:50 +00:00
{
2016-01-29 03:08:43 +00:00
stop ( ) ;
2013-08-16 16:56:27 +01:00
}
2016-01-23 18:39:03 +00:00
void UDPTracker : : start ( )
2013-02-26 19:02:50 +00:00
{
SOCKET sock ;
int r , // saves results
i , // loop index
yup ; // just to set TRUE
2016-01-23 18:39:03 +00:00
std : : string dbname ; // saves the Database name.
2013-02-26 19:02:50 +00:00
2016-01-23 16:11:51 +00:00
sock = : : socket ( AF_INET , SOCK_DGRAM , IPPROTO_UDP ) ;
2013-02-26 19:02:50 +00:00
if ( sock = = INVALID_SOCKET )
2016-01-23 18:39:03 +00:00
{
throw UDPT : : UDPTException ( " Failed to create socket " ) ;
}
2013-02-26 19:02:50 +00:00
yup = 1 ;
2016-01-23 16:11:51 +00:00
: : setsockopt ( sock , SOL_SOCKET , SO_REUSEADDR , ( const char * ) & yup , 1 ) ;
2013-02-26 19:02:50 +00:00
2016-01-29 02:32:47 +00:00
{
// don't block recvfrom for too long.
# if defined(linux)
timeval timeout = { 0 } ;
timeout . tv_sec = 5 ;
# elif defined(WIN32)
DWORD timeout = 5000 ;
# else
# error Unsupported OS.
# endif
: : setsockopt ( sock , SOL_SOCKET , SO_RCVTIMEO , reinterpret_cast < const char * > ( & timeout ) , sizeof ( timeout ) ) ;
}
2016-01-23 18:39:03 +00:00
this - > m_localEndpoint . sin_family = AF_INET ;
r = : : bind ( sock , reinterpret_cast < SOCKADDR * > ( & this - > m_localEndpoint ) , sizeof ( SOCKADDR_IN ) ) ;
2013-02-26 19:02:50 +00:00
if ( r = = SOCKET_ERROR )
{
# ifdef WIN32
2016-01-23 18:39:03 +00:00
: : closesocket ( sock ) ;
2013-02-26 19:02:50 +00:00
# elif defined (linux)
2016-01-23 18:39:03 +00:00
: : close ( sock ) ;
2016-02-05 01:56:49 +00:00
# endif
2016-01-23 18:39:03 +00:00
throw UDPT : : UDPTException ( " Failed to bind socket. " ) ;
2013-02-26 19:02:50 +00:00
}
2016-02-05 14:36:44 +00:00
{
char buff [ INET_ADDRSTRLEN ] ;
2016-10-04 22:20:08 +01:00
BOOST_LOG_SEV ( m_logger , boost : : log : : trivial : : info ) < < " UDP tracker bound on " < < : : inet_ntop ( AF_INET , reinterpret_cast < LPVOID > ( & m_localEndpoint . sin_addr ) , buff , sizeof ( buff ) ) < < " : " < < htons ( m_localEndpoint . sin_port ) ;
2016-02-05 14:36:44 +00:00
}
2016-01-23 18:39:03 +00:00
this - > m_sock = sock ;
2013-02-26 19:02:50 +00:00
// create maintainer thread.
2016-01-29 02:32:47 +00:00
m_threads . push_back ( boost : : thread ( UDPTracker : : _maintainance_start , this ) ) ;
2013-02-26 19:02:50 +00:00
2016-01-23 18:39:03 +00:00
for ( i = 1 ; i < this - > m_threadCount ; i + + )
2013-02-26 19:02:50 +00:00
{
2016-01-29 02:32:47 +00:00
m_threads . push_back ( boost : : thread ( UDPTracker : : _thread_start , this ) ) ;
2013-02-26 19:02:50 +00:00
}
}
2016-01-29 02:32:47 +00:00
void UDPTracker : : stop ( )
{
# ifdef linux
: : close ( m_sock ) ;
# elif defined (WIN32)
: : closesocket ( m_sock ) ;
# endif
2016-02-05 01:56:49 +00:00
BOOST_LOG_SEV ( m_logger , boost : : log : : trivial : : warning ) < < " Interrupting workers... " ;
2016-01-29 02:32:47 +00:00
for ( std : : vector < boost : : thread > : : iterator it = m_threads . begin ( ) ; it ! = m_threads . end ( ) ; + + it )
{
it - > interrupt ( ) ;
}
2016-01-29 03:08:43 +00:00
wait ( ) ;
}
void UDPTracker : : wait ( )
{
2016-02-05 01:56:49 +00:00
BOOST_LOG_SEV ( m_logger , boost : : log : : trivial : : warning ) < < " Waiting for threads to terminate... " ;
2016-01-29 02:32:47 +00:00
for ( std : : vector < boost : : thread > : : iterator it = m_threads . begin ( ) ; it ! = m_threads . end ( ) ; + + it )
{
it - > join ( ) ;
}
}
2016-01-23 18:39:03 +00:00
int UDPTracker : : sendError ( UDPTracker * usi , SOCKADDR_IN * remote , uint32_t transactionID , const std : : string & msg )
2013-02-26 19:02:50 +00:00
{
struct udp_error_response error ;
int msg_sz , // message size to send.
i ; // copy loop
char buff [ 1024 ] ; // more than reasonable message size...
error . action = m_hton32 ( 3 ) ;
error . transaction_id = transactionID ;
error . message = ( char * ) msg . c_str ( ) ;
msg_sz = 4 + 4 + 1 + msg . length ( ) ;
2013-07-11 22:09:47 +01:00
// test against overflow message. resolves issue 4.
if ( msg_sz > 1024 )
return - 1 ;
2016-01-23 18:39:03 +00:00
: : memcpy ( buff , & error , 8 ) ;
2013-02-26 19:02:50 +00:00
for ( i = 8 ; i < = msg_sz ; i + + )
{
buff [ i ] = msg [ i - 8 ] ;
}
2016-01-23 18:39:03 +00:00
: : sendto ( usi - > m_sock , buff , msg_sz , 0 , reinterpret_cast < SOCKADDR * > ( remote ) , sizeof ( * remote ) ) ;
2013-02-26 19:02:50 +00:00
return 0 ;
}
2016-01-23 18:39:03 +00:00
int UDPTracker : : handleConnection ( UDPTracker * usi , SOCKADDR_IN * remote , char * data )
2013-02-26 19:02:50 +00:00
{
2016-01-23 18:39:03 +00:00
ConnectionRequest * req = reinterpret_cast < ConnectionRequest * > ( data ) ;
2013-02-26 19:02:50 +00:00
ConnectionResponse resp ;
resp . action = m_hton32 ( 0 ) ;
resp . transaction_id = req - > transaction_id ;
2013-03-03 22:54:48 +00:00
2016-01-29 02:32:47 +00:00
if ( ! usi - > m_conn - > genConnectionId ( & resp . connection_id ,
2013-03-03 22:54:48 +00:00
m_hton32 ( remote - > sin_addr . s_addr ) ,
m_hton16 ( remote - > sin_port ) ) )
{
return 1 ;
}
2013-02-26 19:02:50 +00:00
2016-01-23 18:39:03 +00:00
: : sendto ( usi - > m_sock , ( char * ) & resp , sizeof ( ConnectionResponse ) , 0 , ( SOCKADDR * ) remote , sizeof ( SOCKADDR_IN ) ) ;
2013-02-26 19:02:50 +00:00
2016-02-05 01:56:49 +00:00
{
char buffer [ INET_ADDRSTRLEN ] ;
BOOST_LOG_SEV ( usi - > m_logger , boost : : log : : trivial : : debug ) < < " Connection Request from " < < : : inet_ntop ( AF_INET , & remote - > sin_addr , buffer , sizeof ( buffer ) ) < < " ; cId= " < < resp . connection_id < < " ; tId= " < < resp . transaction_id ;
}
2013-02-26 19:02:50 +00:00
return 0 ;
}
2016-02-05 01:56:49 +00:00
int UDPTracker : : handleAnnounce ( UDPTracker * usi , SOCKADDR_IN * remote , char * data )
2013-02-26 19:02:50 +00:00
{
AnnounceRequest * req ;
AnnounceResponse * resp ;
int q , // peer counts
bSize , // message size
i ; // loop index
2013-03-03 22:54:48 +00:00
DatabaseDriver : : TorrentEntry tE ;
2016-02-05 01:56:49 +00:00
uint8_t buff [ 1028 ] ; // Reasonable buffer size. (header+168 peers)
2013-02-26 19:02:50 +00:00
req = ( AnnounceRequest * ) data ;
2016-01-29 02:32:47 +00:00
if ( ! usi - > m_conn - > verifyConnectionId ( req - > connection_id ,
2016-02-05 01:56:49 +00:00
m_hton32 ( remote - > sin_addr . s_addr ) ,
m_hton16 ( remote - > sin_port ) ) )
2013-02-26 19:02:50 +00:00
{
return 1 ;
}
// change byte order:
2016-02-05 01:56:49 +00:00
req - > port = m_hton16 ( req - > port ) ;
req - > ip_address = m_hton32 ( req - > ip_address ) ;
req - > downloaded = m_hton64 ( req - > downloaded ) ;
req - > event = m_hton32 ( req - > event ) ; // doesn't really matter for this tracker
req - > uploaded = m_hton64 ( req - > uploaded ) ;
req - > num_want = m_hton32 ( req - > num_want ) ;
req - > left = m_hton64 ( req - > left ) ;
2013-02-26 19:02:50 +00:00
2016-01-23 18:39:03 +00:00
if ( ! usi - > m_allowRemotes & & req - > ip_address ! = 0 )
2013-02-26 19:02:50 +00:00
{
2016-01-23 23:08:30 +00:00
UDPTracker : : sendError ( usi , remote , req - > transaction_id , " Tracker doesn't allow remote IP's; Request ignored. " ) ;
2013-02-26 19:02:50 +00:00
return 0 ;
}
2016-01-29 02:32:47 +00:00
if ( ! usi - > m_conn - > isTorrentAllowed ( req - > info_hash ) )
2013-03-03 22:54:48 +00:00
{
UDPTracker : : sendError ( usi , remote , req - > transaction_id , " info_hash not registered. " ) ;
return 0 ;
}
2013-02-26 19:02:50 +00:00
// load peers
q = 30 ;
if ( req - > num_want > = 1 )
2016-01-29 02:32:47 +00:00
q = std : : min < int > ( q , req - > num_want ) ;
2013-02-26 19:02:50 +00:00
2013-03-03 22:54:48 +00:00
DatabaseDriver : : TrackerEvents event ;
2016-02-05 01:56:49 +00:00
2013-03-03 22:54:48 +00:00
{
2016-02-05 01:56:49 +00:00
std : : shared_ptr < DatabaseDriver : : PeerEntry > peersSptr = std : : shared_ptr < DatabaseDriver : : PeerEntry > ( new DatabaseDriver : : PeerEntry [ q ] ) ;
DatabaseDriver : : PeerEntry * peers = peersSptr . get ( ) ;
2013-03-03 22:54:48 +00:00
2016-02-05 01:56:49 +00:00
switch ( req - > event )
{
case 1 :
event = DatabaseDriver : : EVENT_COMPLETE ;
break ;
case 2 :
event = DatabaseDriver : : EVENT_START ;
break ;
case 3 :
event = DatabaseDriver : : EVENT_STOP ;
break ;
default :
event = DatabaseDriver : : EVENT_UNSPEC ;
break ;
}
2013-03-03 22:54:48 +00:00
2016-02-05 01:56:49 +00:00
if ( event = = DatabaseDriver : : EVENT_STOP )
q = 0 ; // no need for peers when stopping.
2013-02-26 19:02:50 +00:00
2016-02-05 01:56:49 +00:00
if ( q > 0 )
usi - > m_conn - > getPeers ( req - > info_hash , & q , peers ) ;
2013-02-26 19:02:50 +00:00
2016-02-05 01:56:49 +00:00
bSize = 20 ; // header is 20 bytes
bSize + = ( 6 * q ) ; // + 6 bytes per peer.
2013-02-26 19:02:50 +00:00
2016-02-05 01:56:49 +00:00
tE . info_hash = req - > info_hash ;
usi - > m_conn - > getTorrentInfo ( & tE ) ;
2013-02-26 19:02:50 +00:00
2016-02-05 01:56:49 +00:00
resp = ( AnnounceResponse * ) buff ;
resp - > action = m_hton32 ( 1 ) ;
resp - > interval = m_hton32 ( usi - > m_announceInterval ) ;
resp - > leechers = m_hton32 ( tE . leechers ) ;
resp - > seeders = m_hton32 ( tE . seeders ) ;
resp - > transaction_id = req - > transaction_id ;
2013-02-26 19:02:50 +00:00
2016-02-05 01:56:49 +00:00
for ( i = 0 ; i < q ; i + + )
{
int x = i * 6 ;
// network byte order!!!
// IP
buff [ 20 + x ] = ( ( peers [ i ] . ip & ( 0xff < < 24 ) ) > > 24 ) ;
buff [ 21 + x ] = ( ( peers [ i ] . ip & ( 0xff < < 16 ) ) > > 16 ) ;
buff [ 22 + x ] = ( ( peers [ i ] . ip & ( 0xff < < 8 ) ) > > 8 ) ;
buff [ 23 + x ] = ( peers [ i ] . ip & 0xff ) ;
2013-02-26 19:02:50 +00:00
2016-02-05 01:56:49 +00:00
// port
buff [ 24 + x ] = ( ( peers [ i ] . port & ( 0xff < < 8 ) ) > > 8 ) ;
buff [ 25 + x ] = ( peers [ i ] . port & 0xff ) ;
2013-02-26 19:02:50 +00:00
2016-02-05 01:56:49 +00:00
}
2013-02-26 19:02:50 +00:00
}
2016-01-23 18:39:03 +00:00
: : sendto ( usi - > m_sock , ( char * ) buff , bSize , 0 , ( SOCKADDR * ) remote , sizeof ( SOCKADDR_IN ) ) ;
2013-02-26 19:02:50 +00:00
2013-03-03 22:54:48 +00:00
// update DB.
uint32_t ip ;
2013-02-26 19:02:50 +00:00
if ( req - > ip_address = = 0 ) // default
2013-03-03 22:54:48 +00:00
ip = m_hton32 ( remote - > sin_addr . s_addr ) ;
2013-02-26 19:02:50 +00:00
else
2013-03-03 22:54:48 +00:00
ip = req - > ip_address ;
2016-01-29 02:32:47 +00:00
usi - > m_conn - > updatePeer ( req - > peer_id , req - > info_hash , ip , req - > port ,
2013-03-03 22:54:48 +00:00
req - > downloaded , req - > left , req - > uploaded , event ) ;
2013-02-26 19:02:50 +00:00
return 0 ;
}
2016-01-23 18:39:03 +00:00
int UDPTracker : : handleScrape ( UDPTracker * usi , SOCKADDR_IN * remote , char * data , int len )
2013-02-26 19:02:50 +00:00
{
2016-01-23 18:39:03 +00:00
ScrapeRequest * sR = reinterpret_cast < ScrapeRequest * > ( data ) ;
2013-02-26 19:02:50 +00:00
int v , // validation helper
c , // torrent counter
i , // loop counter
j ; // loop counter
uint8_t hash [ 20 ] ;
ScrapeResponse * resp ;
uint8_t buffer [ 1024 ] ; // up to 74 torrents can be scraped at once (17*74+8) < 1024
// validate request length:
v = len - 16 ;
if ( v < 0 | | v % 20 ! = 0 )
{
2016-01-23 18:39:03 +00:00
UDPTracker : : sendError ( usi , remote , sR - > transaction_id , " Bad scrape request. " ) ;
2013-02-26 19:02:50 +00:00
return 0 ;
}
2016-01-29 02:32:47 +00:00
if ( ! usi - > m_conn - > verifyConnectionId ( sR - > connection_id ,
2013-03-03 22:54:48 +00:00
m_hton32 ( remote - > sin_addr . s_addr ) ,
m_hton16 ( remote - > sin_port ) ) )
{
return 1 ;
}
2013-02-26 19:02:50 +00:00
// get torrent count.
c = v / 20 ;
2016-01-23 18:39:03 +00:00
resp = reinterpret_cast < ScrapeResponse * > ( buffer ) ;
resp - > action = m_hton32 ( 2 ) ;
2013-02-26 19:02:50 +00:00
resp - > transaction_id = sR - > transaction_id ;
for ( i = 0 ; i < c ; i + + )
{
int32_t * seeders ,
* completed ,
* leechers ;
for ( j = 0 ; j < 20 ; j + + )
hash [ j ] = data [ j + ( i * 20 ) + 16 ] ;
seeders = ( int32_t * ) & buffer [ i * 12 + 8 ] ;
completed = ( int32_t * ) & buffer [ i * 12 + 12 ] ;
leechers = ( int32_t * ) & buffer [ i * 12 + 16 ] ;
2013-03-03 22:54:48 +00:00
DatabaseDriver : : TorrentEntry tE ;
tE . info_hash = hash ;
2016-01-29 02:32:47 +00:00
if ( ! usi - > m_conn - > getTorrentInfo ( & tE ) )
2013-03-03 22:54:48 +00:00
{
sendError ( usi , remote , sR - > transaction_id , " Scrape Failed: couldn't retrieve torrent data " ) ;
return 0 ;
}
2013-02-26 19:02:50 +00:00
2016-01-23 18:39:03 +00:00
* seeders = m_hton32 ( tE . seeders ) ;
* completed = m_hton32 ( tE . completed ) ;
* leechers = m_hton32 ( tE . leechers ) ;
2013-02-26 19:02:50 +00:00
}
2016-01-23 18:39:03 +00:00
: : sendto ( usi - > m_sock , reinterpret_cast < const char * > ( buffer ) , sizeof ( buffer ) , 0 , reinterpret_cast < SOCKADDR * > ( remote ) , sizeof ( SOCKADDR_IN ) ) ;
2013-02-26 19:02:50 +00:00
return 0 ;
}
2016-01-29 02:32:47 +00:00
int UDPTracker : : isIANAIP ( uint32_t ip )
{
uint8_t x = ( ip % 256 ) ;
if ( x = = 0 | | x = = 10 | | x = = 127 | | x > = 224 )
return 1 ;
return 0 ;
}
2013-02-26 19:02:50 +00:00
2016-01-29 02:32:47 +00:00
int UDPTracker : : resolveRequest ( UDPTracker * usi , SOCKADDR_IN * remote , char * data , int r )
2013-02-26 19:02:50 +00:00
{
2016-01-23 18:39:03 +00:00
ConnectionRequest * cR = reinterpret_cast < ConnectionRequest * > ( data ) ;
2013-02-26 19:02:50 +00:00
uint32_t action ;
action = m_hton32 ( cR - > action ) ;
2016-01-23 18:39:03 +00:00
if ( ! usi - > m_allowIANA_IPs )
2013-02-26 19:02:50 +00:00
{
2016-01-29 02:32:47 +00:00
if ( isIANAIP ( remote - > sin_addr . s_addr ) )
2013-02-26 19:02:50 +00:00
{
2016-02-05 01:56:49 +00:00
char buffer [ INET_ADDRSTRLEN ] ;
BOOST_LOG_SEV ( usi - > m_logger , boost : : log : : trivial : : warning ) < < " Client ignored (IANA IP): " < < : : inet_ntop ( AF_INET , & remote - > sin_addr , buffer , sizeof ( buffer ) ) ;
2013-02-26 19:02:50 +00:00
return 0 ; // Access Denied: IANA reserved IP.
}
}
2016-02-05 01:56:49 +00:00
{
char buffer [ INET_ADDRSTRLEN ] ;
BOOST_LOG_SEV ( usi - > m_logger , boost : : log : : trivial : : debug ) < < " Client request from " < < : : inet_ntop ( AF_INET , & remote - > sin_addr , buffer , sizeof ( buffer ) ) ;
}
2013-02-26 19:02:50 +00:00
if ( action = = 0 & & r > = 16 )
2016-01-23 18:39:03 +00:00
return UDPTracker : : handleConnection ( usi , remote , data ) ;
2013-02-26 19:02:50 +00:00
else if ( action = = 1 & & r > = 98 )
2016-01-23 18:39:03 +00:00
return UDPTracker : : handleAnnounce ( usi , remote , data ) ;
2013-02-26 19:02:50 +00:00
else if ( action = = 2 )
2016-01-23 18:39:03 +00:00
return UDPTracker : : handleScrape ( usi , remote , data , r ) ;
2013-02-26 19:02:50 +00:00
else
{
2016-01-23 18:39:03 +00:00
UDPTracker : : sendError ( usi , remote , cR - > transaction_id , " Tracker couldn't understand Client's request. " ) ;
2013-02-26 19:02:50 +00:00
return - 1 ;
}
return 0 ;
}
2016-01-29 02:32:47 +00:00
void UDPTracker : : _thread_start ( UDPTracker * usi )
2013-02-26 19:02:50 +00:00
{
2016-02-05 01:56:49 +00:00
BOOST_LOG_SEV ( usi - > m_logger , boost : : log : : trivial : : info ) < < " Worker thread started with PID= " < < boost : : this_thread : : get_id ( ) < < " . " ;
2013-02-26 19:02:50 +00:00
SOCKADDR_IN remoteAddr ;
2016-01-29 02:32:47 +00:00
char tmpBuff [ UDP_BUFFER_SIZE ] ;
2013-03-07 15:37:31 +00:00
# ifdef linux
socklen_t addrSz ;
# else
int addrSz ;
# endif
2016-01-23 18:39:03 +00:00
addrSz = sizeof ( SOCKADDR_IN ) ;
2013-02-26 19:02:50 +00:00
2016-01-29 02:32:47 +00:00
while ( true )
2013-02-26 19:02:50 +00:00
{
// peek into the first 12 bytes of data; determine if connection request or announce request.
2016-01-29 02:32:47 +00:00
int r = : : recvfrom ( usi - > m_sock , ( char * ) tmpBuff , UDP_BUFFER_SIZE , 0 , ( SOCKADDR * ) & remoteAddr , & addrSz ) ;
2013-02-26 19:02:50 +00:00
if ( r < = 0 )
2016-01-29 02:32:47 +00:00
{
boost : : this_thread : : sleep_for ( boost : : chrono : : milliseconds ( 100 ) ) ;
continue ;
}
2013-02-26 19:02:50 +00:00
2016-01-29 02:32:47 +00:00
{
boost : : this_thread : : disable_interruption di ;
2016-02-05 01:56:49 +00:00
UDPTracker : : resolveRequest ( usi , & remoteAddr , tmpBuff , r ) ;
2016-01-29 02:32:47 +00:00
}
}
2013-02-26 19:02:50 +00:00
}
2016-01-29 02:32:47 +00:00
void UDPTracker : : _maintainance_start ( UDPTracker * usi )
2013-02-26 19:02:50 +00:00
{
2016-02-05 01:56:49 +00:00
BOOST_LOG_SEV ( usi - > m_logger , boost : : log : : trivial : : info ) < < " Maintenance thread started with PID= " < < boost : : this_thread : : get_id ( ) < < " . " ;
2016-01-29 02:32:47 +00:00
while ( true )
2013-02-26 19:02:50 +00:00
{
2016-01-29 02:32:47 +00:00
{
boost : : this_thread : : disable_interruption di ;
2016-02-05 01:56:49 +00:00
BOOST_LOG_SEV ( usi - > m_logger , boost : : log : : trivial : : info ) < < " Running cleanup... " ;
2016-01-29 02:32:47 +00:00
usi - > m_conn - > cleanup ( ) ;
}
2013-02-26 19:02:50 +00:00
2016-01-29 02:32:47 +00:00
boost : : this_thread : : sleep_for ( boost : : chrono : : seconds ( usi - > m_cleanupInterval ) ) ;
2013-02-26 19:02:50 +00:00
}
}
} ;