clean up udp-tracker unit tests
This commit is contained in:
parent
63c6e495bd
commit
0a042dde8b
|
@ -61,6 +61,7 @@ lib libtorrent_test
|
|||
: # sources
|
||||
setup_transfer.cpp
|
||||
dht_server.cpp
|
||||
udp_tracker.cpp
|
||||
peer_server.cpp
|
||||
../ed25519/src/$(ED25519_SOURCES).c
|
||||
web_seed_suite.cpp
|
||||
|
|
|
@ -102,11 +102,13 @@ EXTRA_DIST = Jamfile \
|
|||
|
||||
EXTRA_PROGRAMS = $(test_programs)
|
||||
|
||||
noinst_HEADERS = test.hpp setup_transfer.hpp
|
||||
noinst_HEADERS = test.hpp setup_transfer.hpp dht_server.hpp \
|
||||
peer_server.hpp udp_tracker.hpp
|
||||
|
||||
libtest_la_SOURCES = main.cpp \
|
||||
setup_transfer.cpp \
|
||||
dht_server.cpp \
|
||||
udp_tracker.cpp \
|
||||
peer_server.cpp \
|
||||
web_seed_suite.cpp \
|
||||
../ed25519/src/add_scalar.c \
|
||||
|
|
|
@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "setup_transfer.hpp" // for tests_failure
|
||||
#include "dht_server.hpp" // for stop_dht
|
||||
#include "peer_server.hpp" // for stop_peer
|
||||
#include "udp_tracker.hpp" // for stop_udp_tracker
|
||||
|
||||
int test_main();
|
||||
|
||||
|
@ -151,7 +152,7 @@ int main()
|
|||
|
||||
// just in case of premature exits
|
||||
// make sure we try to clean up some
|
||||
stop_tracker();
|
||||
stop_udp_tracker();
|
||||
stop_all_proxies();
|
||||
stop_web_server();
|
||||
stop_peer();
|
||||
|
|
|
@ -760,177 +760,6 @@ setup_transfer(session* ses1, session* ses2, session* ses3
|
|||
return boost::make_tuple(tor1, tor2, tor3);
|
||||
}
|
||||
|
||||
boost::asio::io_service* tracker_ios = 0;
|
||||
boost::shared_ptr<libtorrent::thread> tracker_server;
|
||||
libtorrent::mutex tracker_lock;
|
||||
libtorrent::event tracker_initialized;
|
||||
|
||||
bool udp_failed = false;
|
||||
|
||||
void stop_tracker()
|
||||
{
|
||||
fprintf(stderr, "%s: stop_tracker()\n", time_now_string());
|
||||
if (tracker_ios)
|
||||
{
|
||||
tracker_ios->stop();
|
||||
}
|
||||
|
||||
if (tracker_server)
|
||||
{
|
||||
tracker_server->join();
|
||||
tracker_server.reset();
|
||||
}
|
||||
|
||||
if (tracker_ios)
|
||||
{
|
||||
delete tracker_ios;
|
||||
tracker_ios = 0;
|
||||
}
|
||||
fprintf(stderr, "%s: stop_tracker() done\n", time_now_string());
|
||||
}
|
||||
|
||||
void udp_tracker_thread(int* port);
|
||||
|
||||
int start_tracker()
|
||||
{
|
||||
stop_tracker();
|
||||
|
||||
{
|
||||
libtorrent::mutex::scoped_lock l(tracker_lock);
|
||||
tracker_initialized.clear(l);
|
||||
}
|
||||
|
||||
int port = 0;
|
||||
|
||||
delete tracker_ios;
|
||||
tracker_ios = new io_service;
|
||||
tracker_server.reset(new libtorrent::thread(boost::bind(&udp_tracker_thread, &port)));
|
||||
|
||||
{
|
||||
libtorrent::mutex::scoped_lock l(tracker_lock);
|
||||
tracker_initialized.wait(l);
|
||||
}
|
||||
// test_sleep(100);
|
||||
return port;
|
||||
}
|
||||
|
||||
boost::detail::atomic_count g_udp_tracker_requests(0);
|
||||
|
||||
void on_udp_receive(error_code const& ec, size_t bytes_transferred, udp::endpoint const* from, char* buffer, udp::socket* sock)
|
||||
{
|
||||
if (ec)
|
||||
{
|
||||
fprintf(stderr, "%s: UDP tracker, read failed: %s\n", time_now_string(), ec.message().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
udp_failed = false;
|
||||
|
||||
if (bytes_transferred < 16)
|
||||
{
|
||||
fprintf(stderr, "%s: UDP message too short (from: %s)\n", time_now_string(), print_endpoint(*from).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s: UDP message %d bytes\n", time_now_string(), int(bytes_transferred));
|
||||
|
||||
char* ptr = buffer;
|
||||
detail::read_uint64(ptr);
|
||||
boost::uint32_t action = detail::read_uint32(ptr);
|
||||
boost::uint32_t transaction_id = detail::read_uint32(ptr);
|
||||
|
||||
error_code e;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case 0: // connect
|
||||
|
||||
fprintf(stderr, "%s: UDP connect from %s\n", time_now_string(), print_endpoint(*from).c_str());
|
||||
ptr = buffer;
|
||||
detail::write_uint32(0, ptr); // action = connect
|
||||
detail::write_uint32(transaction_id, ptr); // transaction_id
|
||||
detail::write_uint64(10, ptr); // connection_id
|
||||
sock->send_to(asio::buffer(buffer, 16), *from, 0, e);
|
||||
if (e) fprintf(stderr, "%s: send_to failed. ERROR: %s\n", time_now_string(), e.message().c_str());
|
||||
break;
|
||||
|
||||
case 1: // announce
|
||||
|
||||
++g_udp_tracker_requests;
|
||||
fprintf(stderr, "%s: UDP announce [%d]\n", time_now_string(), int(g_udp_tracker_requests));
|
||||
ptr = buffer;
|
||||
detail::write_uint32(1, ptr); // action = announce
|
||||
detail::write_uint32(transaction_id, ptr); // transaction_id
|
||||
detail::write_uint32(1800, ptr); // interval
|
||||
detail::write_uint32(1, ptr); // incomplete
|
||||
detail::write_uint32(1, ptr); // complete
|
||||
// 0 peers
|
||||
sock->send_to(asio::buffer(buffer, 20), *from, 0, e);
|
||||
if (e) fprintf(stderr, "%s: send_to failed. ERROR: %s\n", time_now_string(), e.message().c_str());
|
||||
break;
|
||||
case 2:
|
||||
// ignore scrapes
|
||||
fprintf(stderr, "%s: UDP scrape\n", time_now_string());
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "%s: UDP unknown message: %d\n", time_now_string(), action);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void udp_tracker_thread(int* port)
|
||||
{
|
||||
udp::socket acceptor(*tracker_ios);
|
||||
error_code ec;
|
||||
acceptor.open(udp::v4(), ec);
|
||||
if (ec)
|
||||
{
|
||||
fprintf(stderr, "Error opening listen UDP socket: %s\n", ec.message().c_str());
|
||||
libtorrent::mutex::scoped_lock l(tracker_lock);
|
||||
tracker_initialized.signal(l);
|
||||
return;
|
||||
}
|
||||
acceptor.bind(udp::endpoint(address_v4::any(), 0), ec);
|
||||
if (ec)
|
||||
{
|
||||
fprintf(stderr, "Error binding UDP socket to port 0: %s\n", ec.message().c_str());
|
||||
libtorrent::mutex::scoped_lock l(tracker_lock);
|
||||
tracker_initialized.signal(l);
|
||||
return;
|
||||
}
|
||||
*port = acceptor.local_endpoint().port();
|
||||
|
||||
fprintf(stderr, "%s: UDP tracker initialized on port %d\n", time_now_string(), *port);
|
||||
|
||||
{
|
||||
libtorrent::mutex::scoped_lock l(tracker_lock);
|
||||
tracker_initialized.signal(l);
|
||||
}
|
||||
|
||||
char buffer[2000];
|
||||
|
||||
for (;;)
|
||||
{
|
||||
error_code ec;
|
||||
udp::endpoint from;
|
||||
udp_failed = true;
|
||||
acceptor.async_receive_from(
|
||||
asio::buffer(buffer, sizeof(buffer)), from, boost::bind(
|
||||
&on_udp_receive, _1, _2, &from, &buffer[0], &acceptor));
|
||||
tracker_ios->run_one(ec);
|
||||
if (udp_failed) return;
|
||||
|
||||
if (ec)
|
||||
{
|
||||
fprintf(stderr, "%s: Error receiving on UDP socket: %s\n", time_now_string(), ec.message().c_str());
|
||||
libtorrent::mutex::scoped_lock l(tracker_lock);
|
||||
tracker_initialized.signal(l);
|
||||
return;
|
||||
}
|
||||
tracker_ios->reset();
|
||||
}
|
||||
}
|
||||
|
||||
pid_type web_server_pid = 0;
|
||||
|
||||
int start_web_server(bool ssl, bool chunked_encoding)
|
||||
|
|
|
@ -70,8 +70,6 @@ bool EXPORT print_alerts(libtorrent::session& ses, char const* name
|
|||
void EXPORT wait_for_listen(libtorrent::session& ses, char const* name);
|
||||
void EXPORT test_sleep(int millisec);
|
||||
|
||||
extern EXPORT boost::detail::atomic_count g_udp_tracker_requests;
|
||||
|
||||
void EXPORT create_random_files(std::string const& path, const int file_sizes[], int num_files);
|
||||
|
||||
boost::intrusive_ptr<libtorrent::torrent_info> EXPORT create_torrent(std::ostream* file = 0
|
||||
|
@ -93,8 +91,5 @@ int EXPORT start_proxy(int type);
|
|||
void EXPORT stop_proxy(int port);
|
||||
void EXPORT stop_all_proxies();
|
||||
|
||||
void EXPORT stop_tracker();
|
||||
int EXPORT start_tracker();
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "test.hpp"
|
||||
#include "setup_transfer.hpp"
|
||||
#include "udp_tracker.hpp"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
|
@ -134,7 +135,7 @@ void test_transfer()
|
|||
boost::intrusive_ptr<torrent_info> t = ::create_torrent(&file, 16 * 1024, 13, false);
|
||||
file.close();
|
||||
|
||||
int udp_tracker_port = start_tracker();
|
||||
int udp_tracker_port = start_udp_tracker();
|
||||
int tracker_port = start_web_server();
|
||||
|
||||
char tracker_url[200];
|
||||
|
@ -395,7 +396,7 @@ void test_transfer()
|
|||
p1 = ses1.abort();
|
||||
p2 = ses2.abort();
|
||||
|
||||
stop_tracker();
|
||||
stop_udp_tracker();
|
||||
stop_web_server();
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "setup_transfer.hpp"
|
||||
#include "dht_server.hpp"
|
||||
#include "peer_server.hpp"
|
||||
#include "udp_tracker.hpp"
|
||||
#include "libtorrent/alert.hpp"
|
||||
#include "libtorrent/alert_types.hpp"
|
||||
|
||||
|
@ -83,11 +84,11 @@ session_proxy test_proxy(proxy_settings::proxy_type proxy_type, int flags)
|
|||
#endif
|
||||
fprintf(stderr, "\n=== TEST == proxy: %s anonymous-mode: %s\n\n", proxy_name[proxy_type], (flags & anonymous_mode) ? "yes" : "no");
|
||||
int http_port = start_web_server();
|
||||
int udp_port = start_tracker();
|
||||
int udp_port = start_udp_tracker();
|
||||
int dht_port = start_dht();
|
||||
int peer_port = start_peer();
|
||||
|
||||
int prev_udp_announces = g_udp_tracker_requests;
|
||||
int prev_udp_announces = num_udp_announces();
|
||||
|
||||
int const alert_mask = alert::all_categories
|
||||
& ~alert::progress_notification
|
||||
|
@ -159,13 +160,13 @@ session_proxy test_proxy(proxy_settings::proxy_type proxy_type, int flags)
|
|||
print_alerts(*s, "s", false, false, false, &alert_predicate);
|
||||
test_sleep(100);
|
||||
|
||||
if (g_udp_tracker_requests >= prev_udp_announces + 1
|
||||
if (num_udp_announces() >= prev_udp_announces + 1
|
||||
&& num_peer_hits() > 0)
|
||||
break;
|
||||
}
|
||||
|
||||
// we should have announced to the tracker by now
|
||||
TEST_EQUAL(g_udp_tracker_requests, prev_udp_announces + bool(flags & expect_udp_connection));
|
||||
TEST_EQUAL(num_udp_announces(), prev_udp_announces + bool(flags & expect_udp_connection));
|
||||
if (flags & expect_dht_msg)
|
||||
{
|
||||
TEST_CHECK(num_dht_hits() > 0);
|
||||
|
@ -196,7 +197,7 @@ session_proxy test_proxy(proxy_settings::proxy_type proxy_type, int flags)
|
|||
|
||||
stop_peer();
|
||||
stop_dht();
|
||||
stop_tracker();
|
||||
stop_udp_tracker();
|
||||
stop_web_server();
|
||||
return pr;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "test.hpp"
|
||||
#include "setup_transfer.hpp"
|
||||
#include "udp_tracker.hpp"
|
||||
#include "libtorrent/alert.hpp"
|
||||
#include "libtorrent/session.hpp"
|
||||
#include "libtorrent/error_code.hpp"
|
||||
|
@ -43,9 +44,9 @@ using namespace libtorrent;
|
|||
int test_main()
|
||||
{
|
||||
int http_port = start_web_server();
|
||||
int udp_port = start_tracker();
|
||||
int udp_port = start_udp_tracker();
|
||||
|
||||
int prev_udp_announces = g_udp_tracker_requests;
|
||||
int prev_udp_announces = num_udp_announces();
|
||||
|
||||
int const alert_mask = alert::all_categories
|
||||
& ~alert::progress_notification
|
||||
|
@ -83,19 +84,19 @@ int test_main()
|
|||
{
|
||||
print_alerts(*s, "s");
|
||||
test_sleep(100);
|
||||
if (g_udp_tracker_requests == prev_udp_announces + 1)
|
||||
if (num_udp_announces() == prev_udp_announces + 1)
|
||||
break;
|
||||
}
|
||||
|
||||
// we should have announced to the tracker by now
|
||||
TEST_EQUAL(g_udp_tracker_requests, prev_udp_announces + 1);
|
||||
TEST_EQUAL(num_udp_announces(), prev_udp_announces + 1);
|
||||
|
||||
fprintf(stderr, "destructing session\n");
|
||||
delete s;
|
||||
fprintf(stderr, "done\n");
|
||||
|
||||
// we should have announced the stopped event now
|
||||
TEST_EQUAL(g_udp_tracker_requests, prev_udp_announces + 2);
|
||||
TEST_EQUAL(num_udp_announces(), prev_udp_announces + 2);
|
||||
|
||||
// ========================================
|
||||
// test that we move on to try the next tier if the first one fails
|
||||
|
@ -133,7 +134,7 @@ int test_main()
|
|||
snprintf(tracker_url, sizeof(tracker_url), "http://127.0.0.1:%d/announce", http_port);
|
||||
t->add_tracker(tracker_url, 3);
|
||||
|
||||
prev_udp_announces = g_udp_tracker_requests;
|
||||
prev_udp_announces = num_udp_announces();
|
||||
|
||||
addp.flags &= ~add_torrent_params::flag_paused;
|
||||
addp.flags &= ~add_torrent_params::flag_auto_managed;
|
||||
|
@ -145,18 +146,18 @@ int test_main()
|
|||
{
|
||||
print_alerts(*s, "s");
|
||||
test_sleep(100);
|
||||
if (g_udp_tracker_requests == prev_udp_announces + 1) break;
|
||||
if (num_udp_announces() == prev_udp_announces + 1) break;
|
||||
}
|
||||
|
||||
test_sleep(1000);
|
||||
|
||||
TEST_EQUAL(g_udp_tracker_requests, prev_udp_announces + 1);
|
||||
TEST_EQUAL(num_udp_announces(), prev_udp_announces + 1);
|
||||
|
||||
fprintf(stderr, "destructing session\n");
|
||||
delete s;
|
||||
fprintf(stderr, "done\n");
|
||||
|
||||
stop_tracker();
|
||||
stop_udp_tracker();
|
||||
stop_web_server();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2014, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "libtorrent/thread.hpp"
|
||||
#include "libtorrent/bencode.hpp"
|
||||
#include "libtorrent/entry.hpp"
|
||||
#include "libtorrent/address.hpp"
|
||||
#include "libtorrent/io_service.hpp"
|
||||
#include "libtorrent/error_code.hpp"
|
||||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/socket_io.hpp"
|
||||
#include "libtorrent/io.hpp"
|
||||
#include "udp_tracker.hpp"
|
||||
|
||||
#include <boost/detail/atomic_count.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#if defined TORRENT_DEBUG && TORRENT_USE_IOSTREAM
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
using namespace libtorrent;
|
||||
|
||||
struct udp_tracker
|
||||
{
|
||||
|
||||
boost::asio::io_service m_ios;
|
||||
boost::detail::atomic_count m_udp_announces;
|
||||
udp::socket m_socket;
|
||||
int m_port;
|
||||
|
||||
boost::shared_ptr<libtorrent::thread> m_thread;
|
||||
|
||||
void on_udp_receive(error_code const& ec, size_t bytes_transferred, udp::endpoint* from, char* buffer, int size)
|
||||
{
|
||||
if (ec)
|
||||
{
|
||||
fprintf(stderr, "%s: UDP tracker, read failed: %s\n", time_now_string(), ec.message().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (bytes_transferred < 16)
|
||||
{
|
||||
fprintf(stderr, "%s: UDP message too short (from: %s)\n", time_now_string(), print_endpoint(*from).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s: UDP message %d bytes\n", time_now_string(), int(bytes_transferred));
|
||||
|
||||
char* ptr = buffer;
|
||||
detail::read_uint64(ptr);
|
||||
boost::uint32_t action = detail::read_uint32(ptr);
|
||||
boost::uint32_t transaction_id = detail::read_uint32(ptr);
|
||||
|
||||
error_code e;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case 0: // connect
|
||||
|
||||
fprintf(stderr, "%s: UDP connect from %s\n", time_now_string(), print_endpoint(*from).c_str());
|
||||
ptr = buffer;
|
||||
detail::write_uint32(0, ptr); // action = connect
|
||||
detail::write_uint32(transaction_id, ptr); // transaction_id
|
||||
detail::write_uint64(10, ptr); // connection_id
|
||||
m_socket.send_to(asio::buffer(buffer, 16), *from, 0, e);
|
||||
if (e) fprintf(stderr, "%s: send_to failed. ERROR: %s\n", time_now_string(), e.message().c_str());
|
||||
break;
|
||||
|
||||
case 1: // announce
|
||||
|
||||
++m_udp_announces;
|
||||
fprintf(stderr, "%s: UDP announce [%d]\n", time_now_string(), int(m_udp_announces));
|
||||
ptr = buffer;
|
||||
detail::write_uint32(1, ptr); // action = announce
|
||||
detail::write_uint32(transaction_id, ptr); // transaction_id
|
||||
detail::write_uint32(1800, ptr); // interval
|
||||
detail::write_uint32(1, ptr); // incomplete
|
||||
detail::write_uint32(1, ptr); // complete
|
||||
// 0 peers
|
||||
m_socket.send_to(asio::buffer(buffer, 20), *from, 0, e);
|
||||
if (e) fprintf(stderr, "%s: send_to failed. ERROR: %s\n", time_now_string(), e.message().c_str());
|
||||
break;
|
||||
case 2:
|
||||
// ignore scrapes
|
||||
fprintf(stderr, "%s: UDP scrape\n", time_now_string());
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "%s: UDP unknown message: %d\n", time_now_string(), action);
|
||||
break;
|
||||
}
|
||||
|
||||
m_socket.async_receive_from(
|
||||
asio::buffer(buffer, size), *from, 0
|
||||
, boost::bind(&udp_tracker::on_udp_receive, this, _1, _2, from, buffer, size));
|
||||
}
|
||||
|
||||
udp_tracker()
|
||||
: m_udp_announces(0)
|
||||
, m_socket(m_ios)
|
||||
, m_port(0)
|
||||
{
|
||||
error_code ec;
|
||||
m_socket.open(udp::v4(), ec);
|
||||
if (ec)
|
||||
{
|
||||
fprintf(stderr, "Error opening listen UDP tracker socket: %s\n", ec.message().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
m_socket.bind(udp::endpoint(address_v4::any(), 0), ec);
|
||||
if (ec)
|
||||
{
|
||||
fprintf(stderr, "Error binding UDP tracker socket to port 0: %s\n", ec.message().c_str());
|
||||
return;
|
||||
}
|
||||
m_port = m_socket.local_endpoint(ec).port();
|
||||
if (ec)
|
||||
{
|
||||
fprintf(stderr, "Error getting local endpoint of UDP tracker socket: %s\n", ec.message().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s: UDP tracker initialized on port %d\n", time_now_string(), m_port);
|
||||
|
||||
m_thread.reset(new thread(boost::bind(&udp_tracker::thread_fun, this)));
|
||||
}
|
||||
|
||||
~udp_tracker()
|
||||
{
|
||||
m_socket.cancel();
|
||||
m_socket.close();
|
||||
if (m_thread) m_thread->join();
|
||||
}
|
||||
|
||||
int port() const { return m_port; }
|
||||
|
||||
int num_hits() const { return m_udp_announces; }
|
||||
|
||||
static void incoming_packet(error_code const& ec, size_t bytes_transferred, size_t *ret, error_code* error, bool* done)
|
||||
{
|
||||
*ret = bytes_transferred;
|
||||
*error = ec;
|
||||
*done = true;
|
||||
}
|
||||
|
||||
void thread_fun()
|
||||
{
|
||||
char buffer[2000];
|
||||
|
||||
error_code ec;
|
||||
udp::endpoint from;
|
||||
size_t bytes_transferred;
|
||||
bool done = false;
|
||||
m_socket.async_receive_from(
|
||||
asio::buffer(buffer, sizeof(buffer)), from, 0
|
||||
, boost::bind(&udp_tracker::on_udp_receive, this, _1, _2, &from, &buffer[0], sizeof(buffer)));
|
||||
|
||||
m_ios.run(ec);
|
||||
|
||||
if (ec)
|
||||
{
|
||||
fprintf(stderr, "Error running UDP tracker service: %s\n", ec.message().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(stderr, "exiting UDP tracker thread\n");
|
||||
}
|
||||
};
|
||||
|
||||
boost::shared_ptr<udp_tracker> g_udp_tracker;
|
||||
|
||||
int start_udp_tracker()
|
||||
{
|
||||
g_udp_tracker.reset(new udp_tracker);
|
||||
return g_udp_tracker->port();
|
||||
}
|
||||
|
||||
// the number of UDP tracker announces received
|
||||
int num_udp_announces()
|
||||
{
|
||||
if (g_udp_tracker) return g_udp_tracker->num_hits();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void stop_udp_tracker()
|
||||
{
|
||||
fprintf(stderr, "%s: stop_udp_tracker()\n", time_now_string());
|
||||
g_udp_tracker.reset();
|
||||
fprintf(stderr, "%s: stop_udp_tracker() done\n", time_now_string());
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 20114 Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "test.hpp" // for EXPORT
|
||||
|
||||
// returns the port the udp tracker is running on
|
||||
int EXPORT start_udp_tracker();
|
||||
|
||||
// the number of udp tracker announces received
|
||||
int EXPORT num_udp_announces();
|
||||
|
||||
void EXPORT stop_udp_tracker();
|
||||
|
Loading…
Reference in New Issue