Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
cmake_minimum_required(VERSION 2.8)
project(bootstrap-dht)

set(CMAKE_MODULE_PATH
${CMAKE_MODULE_PATH}
${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/
)

set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Werror ${CMAKE_CXX_FLAGS}")

find_package(Boost REQUIRED COMPONENTS system)
find_package(Threads REQUIRED)

include_directories(
${CMAKE_BINARY_DIR}/include
${Boost_INCLUDE_DIRS}
)

add_executable(bootstrap-dht
src/main.cpp
src/bdecode.cpp
src/city.cc
src/ip_set.cpp
)

target_link_libraries(bootstrap-dht
${Boost_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
)

add_executable(dht-torture
src/dht-torture.cpp
src/bdecode.cpp
)

target_link_libraries(bootstrap-dht
${Boost_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
)

install(TARGETS
bootstrap-dht
dht-torture
RUNTIME DESTINATION bin
)
2 changes: 1 addition & 1 deletion src/bencode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ struct bencoder

m_buf += std::snprintf(m_buf, m_end - m_buf, "%zu:", len);

if (m_end - m_buf < len) return;
if (m_end - m_buf < (int) len) return;

for (auto const& r : ranges) {
if (r.empty()) continue;
Expand Down
1 change: 0 additions & 1 deletion src/city.cc
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,6 @@ uint128 CityHash128(const char *s, size_t len) {
}

#ifdef __SSE4_2__
#include <citycrc.h>
#include <nmmintrin.h>

// Requires len >= 240.
Expand Down
71 changes: 59 additions & 12 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <cinttypes> // for PRId64
#include <array>

#if BOOST_VERSION < 106600
#include <boost/uuid/sha1.hpp>
#else
#include <boost/uuid/detail/sha1.hpp>
#endif
#include <boost/crc.hpp>
#include <boost/system/error_code.hpp>
#include <boost/circular_buffer.hpp>
Expand All @@ -62,6 +66,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

using boost::asio::signal_set;
using boost::asio::io_service;
using boost::asio::ip::tcp;
using boost::asio::ip::udp;
using boost::asio::ip::address_v4;
using boost::asio::ip::address_v6;
Expand All @@ -81,7 +86,7 @@ using time_point = steady_clock::time_point;

using node_id_type = std::array<char, 20>;

const int print_stats_interval = 60;
int print_stats_interval = 60;
const int rotate_secrets_interval = 600;
int nodes_in_response = 16;
int node_buffer_size = 10000000;
Expand Down Expand Up @@ -324,13 +329,21 @@ void generate_id_sha1(address const& ip_, boost::uint32_t r, char* id)
sha1 ctx;
ctx.process_bytes(ip, 4);
ctx.process_byte(rand);
#if BOOST_VERSION >= 108600
boost::uuids::detail::sha1::digest_type d;
ctx.get_digest(d);
id[0] = d[0];
id[1] = d[1];
id[2] = d[2];
id[3] = d[3];
#else
uint32_t d[5];
ctx.get_digest(d);

id[0] = (d[0] >> 24) & 0xff;
id[1] = (d[0] >> 16) & 0xff;
id[2] = (d[0] >> 8) & 0xff;
id[3] = d[0] & 0xff;
#endif

for (int i = 4; i < 19; ++i) id[i] = std::rand();
id[19] = r;
Expand Down Expand Up @@ -407,6 +420,16 @@ std::array<char, 4> compute_tid(uint8_t const* secret, char const* remote_ip
sha1 ctx;
ctx.process_bytes(secret, 20);
ctx.process_bytes(remote_ip, ip_len);
#if BOOST_VERSION >= 108600
boost::uuids::detail::sha1::digest_type d;
ctx.get_digest(d);
return {{
char(d[0]),
char(d[1]),
char(d[2]),
char(d[3])
}};
#else
std::uint32_t d[5];
ctx.get_digest(d);
return {{
Expand All @@ -415,6 +438,7 @@ std::array<char, 4> compute_tid(uint8_t const* secret, char const* remote_ip
char((d[0] >> 8) & 0xff),
char(d[0] & 0xff)
}};
#endif
}

bool verify_tid(span<char> tid, uint8_t const* secret1, uint8_t const* secret2
Expand Down Expand Up @@ -1166,9 +1190,11 @@ void print_usage()
" defaults to 6881\n"
"--response-size <n> Specifies the number of DHT nodes to return in\n"
" response to a query. Defaults to 16\n"
"--x-pollinate <ip> <port>\n"
"--x-pollinate <host> <port>\n"
" if the ping queue becomes too small, request more\n"
" nodes from this DHT node.\n"
"--print-stats-interval <n>\n"
" print stats every <n> seconds.\n"
"\n"
"\n"
);
Expand Down Expand Up @@ -1231,7 +1257,7 @@ int main(int argc, char* argv[])
return 1;
}
num_threads = atoi(argv[i]);
if (num_threads > std::thread::hardware_concurrency())
if (num_threads > (int) std::thread::hardware_concurrency())
{
fprintf(stderr, "WARNING: using more threads (%d) than cores (%d)\n"
, num_threads, std::thread::hardware_concurrency());
Expand Down Expand Up @@ -1305,29 +1331,50 @@ int main(int argc, char* argv[])
return 1;
}
}
else if (argv[i] == "--x-pollinate"_s)
else if (argv[i] == "--print-stats-interval"_s)
{
++i;
if (i >= argc)
{
fprintf(stderr, "--x-pollinate expects an IP argument\n");
fprintf(stderr, "--print-stats-interval expects a number argument\n");
return 1;
}
error_code ec;
bootstrap_node.address(address::from_string(argv[i], ec));
if (ec)
print_stats_interval = atoi(argv[i]);
if (nodes_in_response <= 0)
{
fprintf(stderr, "invalid IP argument \"%s\": %s\n"
, argv[i], ec.message().c_str());
fprintf(stderr, "invalid print-stats-interval: %d\n", nodes_in_response);
return 1;
}
}
else if (argv[i] == "--x-pollinate"_s)
{
++i;
if (i >= argc)
{
fprintf(stderr, "--x-pollinate expects an IP or hostname argument\n");
return 1;
}
std::string host = argv[i];
++i;
if (i >= argc)
{
fprintf(stderr, "--x-pollinate expects a port argument\n");
return 1;
}
bootstrap_node.port(atoi(argv[i]));
unsigned short port = static_cast<unsigned short>(atoi(argv[i]));
// Resolve host (IP or hostname) to an address
boost::asio::io_context io_context;
tcp::resolver resolver(io_context);
error_code ec;
auto endpoints = resolver.resolve(host, std::to_string(port), ec);
if (ec)
{
fprintf(stderr, "failed to resolve hostname \"%s\": %s\n", host.c_str(), ec.message().c_str());
return 1;
}
// Take the first resolved IP
bootstrap_node.address(endpoints->endpoint().address());
bootstrap_node.port(endpoints->endpoint().port());
cross_pollinate = true;
}
else if (argv[i] == "--no-verify-id"_s)
Expand Down
4 changes: 2 additions & 2 deletions src/mapped_file.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,14 @@ struct mapped_vector

T& operator[](int const idx)
{
assert(idx < m_size);
assert(idx < (int) m_size);
assert(idx >= 0);
return m_array[idx];
}

T const& operator[](int const idx) const
{
assert(idx < m_size);
assert(idx < (int) m_size);
assert(idx >= 0);
return m_array[idx];
}
Expand Down
16 changes: 8 additions & 8 deletions src/node_buffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ struct node_buffer
m_ips.insert(address_type(e.ip));
}
m_write_cursor = m_buffer.size();
if (m_current_max_size < m_buffer.size()) {
if (m_current_max_size < (int) m_buffer.size()) {
m_current_max_size = m_buffer.size();
}
if (m_write_cursor >= m_current_max_size) {
if ((int) m_write_cursor >= m_current_max_size) {
m_write_cursor = 0;
}
}
Expand All @@ -81,7 +81,7 @@ struct node_buffer
std::array<span<char const>, 2>
get_nodes(int const num_nodes)
{
if (m_buffer.size() <= num_nodes)
if ((int) m_buffer.size() <= num_nodes)
{
// this is the case where we have fewer nodes in the node_buffer than
// we want to send in a single response
Expand All @@ -106,15 +106,15 @@ struct node_buffer
}

size_t const slice1 = m_buffer.size() - m_read_cursor;
assert(slice1 < num_nodes);
assert((int) slice1 < num_nodes);
size_t const slice2 = num_nodes - slice1;

std::array<span<char const>, 2> const ret{{
{reinterpret_cast<char const*>(&m_buffer[m_read_cursor]), slice1 * sizeof(node_entry_t)}
, {reinterpret_cast<char const*>(&m_buffer[0]), slice2 * sizeof(node_entry_t)}
}};
m_read_cursor = slice2;
assert(slice1 + slice2 == num_nodes);
assert((int) (slice1 + slice2) == num_nodes);
return ret;
}

Expand All @@ -135,7 +135,7 @@ struct node_buffer
if (m_ips.count(address_type(e.ip))) return false;

auto const now = steady_clock::now();
if (m_write_cursor == m_current_max_size
if ((int) m_write_cursor == m_current_max_size
&& m_last_write_loop + minutes(15) > now)
{
// we're about to wrap the write cursor, but it's been less
Expand All @@ -148,7 +148,7 @@ struct node_buffer
// in the above if-statement. If we try to grow the buffer
// size, we may still be stuck at the upper limit, in which
// case we still need to wrap
if (m_write_cursor == m_current_max_size)
if ((int) m_write_cursor == m_current_max_size)
{
#ifdef DEBUG_STATS
printf("write cursor wrapping. %d minutes\n"
Expand All @@ -158,7 +158,7 @@ struct node_buffer
m_last_write_loop = now;
}

if (m_buffer.size() < m_current_max_size)
if ((int) m_buffer.size() < m_current_max_size)
{
m_buffer.emplace_back(e);
m_ips.insert(address_type(e.ip));
Expand Down
2 changes: 1 addition & 1 deletion src/ping_queue.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ struct ping_queue
int const time_out = duration_cast<std::chrono::seconds>(
now - m_created).count();

if (m_queue.front().expire > time_out) return false;
if ((int) m_queue.front().expire > time_out) return false;
auto ent = m_queue.front();
m_queue.pop_front();
m_ips.erase(Address(ent.addr));
Expand Down