Skip to content

Commit

Permalink
P2PServer: prefer DNS TXT records to load seed nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
SChernykh committed May 10, 2023
1 parent 689fa14 commit db9e5ba
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 6 deletions.
63 changes: 59 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ if (WITH_UPNP)
endif()

if (WIN32)
set(LIBS ${LIBS} ws2_32 iphlpapi userenv psapi)
set(LIBS ${LIBS} ws2_32 iphlpapi userenv psapi dnsapi)
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
set(LIBS ${LIBS} bcrypt)
endif()
Expand Down Expand Up @@ -193,14 +193,60 @@ endif()

add_definitions(/DZMQ_STATIC)

set(CMAKE_REQUIRED_FLAGS "${GENERAL_FLAGS}")

include(CheckCXXSourceCompiles)

check_cxx_source_compiles("int main(){ return __builtin_clzll(1);}" HAVE_BUILTIN_CLZLL)
check_cxx_source_compiles("#include <intrin.h>\n#pragma intrinsic(_BitScanReverse64)\nint main(){unsigned long r;_BitScanReverse64(&r,1);return r;}" HAVE_BITSCANREVERSE64)
check_cxx_source_compiles("#include <sched.h>\nint main(){sched_param param;return sched_setscheduler(0, SCHED_IDLE, &param);}" HAVE_SCHED)

include(CheckCSourceCompiles)

set(CMAKE_REQUIRED_LIBRARIES "resolv")

check_c_source_compiles("
#include <arpa/nameser.h>
#include <resolv.h>
#include <stdio.h>
#include <memory.h>
int main(int argc, char* argv[])
{
if (argc < 2) {
return 1;
}
res_init();
uint8_t answer[4096];
const int anslen = res_query(argv[1], ns_c_in, ns_t_txt, answer, sizeof(answer));
if (anslen > (int) sizeof(answer)) {
return 1;
}
ns_msg handle;
ns_initparse(answer, anslen, &handle);
for (int rrnum = 0, n = ns_msg_count(handle, ns_s_an); rrnum < n; ++rrnum) {
ns_rr rr;
if ((ns_parserr(&handle, ns_s_an, rrnum, &rr) == 0) && (ns_rr_type(rr) == ns_t_txt)) {
const uint8_t* data = ns_rr_rdata(rr);
int len = ns_rr_rdlen(rr) - 1;
if (len > data[0]) len = data[0];
char buf[256];
memcpy(buf, data + 1, len);
buf[len] = 0;
puts(buf);
}
}
return 0;
}" HAVE_RES_QUERY)

set(CMAKE_REQUIRED_LIBRARIES)

if (HAVE_BUILTIN_CLZLL)
add_definitions(/DHAVE_BUILTIN_CLZLL)
endif()
Expand All @@ -213,6 +259,11 @@ if (HAVE_SCHED)
add_definitions(/DHAVE_SCHED)
endif()

if (HAVE_RES_QUERY)
add_definitions(/DHAVE_RES_QUERY)
set(LIBS ${LIBS} resolv)
endif()

add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES})

if (STATIC_BINARY OR STATIC_LIBS)
Expand All @@ -231,7 +282,7 @@ if (STATIC_BINARY OR STATIC_LIBS)
endif()

if (WIN32)
set(STATIC_LIBS ${STATIC_LIBS} ws2_32 iphlpapi userenv psapi wldap32)
set(STATIC_LIBS ${STATIC_LIBS} ws2_32 iphlpapi userenv psapi dnsapi)
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
set(STATIC_LIBS ${STATIC_LIBS} bcrypt)
endif()
Expand All @@ -246,6 +297,10 @@ if (STATIC_BINARY OR STATIC_LIBS)
set(STATIC_LIBS ${STATIC_LIBS} pthread)
endif()

if (HAVE_RES_QUERY)
set(STATIC_LIBS ${STATIC_LIBS} resolv)
endif()

target_link_libraries(${CMAKE_PROJECT_NAME}
"${CMAKE_SOURCE_DIR}/external/src/libzmq/build/lib/libzmq.a"
"${CMAKE_SOURCE_DIR}/external/src/libuv/build/libuv_a.a"
Expand Down
56 changes: 56 additions & 0 deletions src/p2p_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@
#include <fstream>
#include <numeric>

#ifdef _WIN32
#include <WinDNS.h>
#elif defined(HAVE_RES_QUERY)
#include <arpa/nameser.h>
#include <resolv.h>
#endif

static constexpr char log_category_prefix[] = "P2PServer ";
static constexpr char saved_peer_list_file_name[] = "p2pool_peers.txt";
static const char* seed_nodes[] = { "seeds.p2pool.io", ""};
Expand Down Expand Up @@ -131,6 +138,10 @@ P2PServer::P2PServer(p2pool* pool)
PANIC_STOP();
}

#if !defined(_WIN32) && defined(HAVE_RES_QUERY)
res_init();
#endif

load_peer_list();
start_listening(params.m_p2pAddresses, params.m_upnp);
}
Expand Down Expand Up @@ -488,6 +499,51 @@ void P2PServer::load_peer_list()
for (size_t i = 0; nodes[i][0]; ++i) {
LOGINFO(4, "loading peers from " << nodes[i]);

// Prefer DNS TXT records
#ifdef _WIN32
PDNS_RECORD pQueryResults;
if (DnsQuery(nodes[i], DNS_TYPE_TEXT, DNS_QUERY_STANDARD, NULL, &pQueryResults, NULL) == 0) {
for (PDNS_RECORD p = pQueryResults; p; p = p->pNext) {
for (size_t j = 0; j < p->Data.TXT.dwStringCount; ++j) {
if (!saved_list.empty()) {
saved_list += ',';
}
LOGINFO(4, "added " << p->Data.TXT.pStringArray[j] << " from " << nodes[i]);
saved_list += p->Data.TXT.pStringArray[j];
}
}
DnsRecordListFree(pQueryResults, DnsFreeRecordList);
continue;
}
#elif defined(HAVE_RES_QUERY)
uint8_t answer[4096];
const int anslen = res_query(nodes[i], ns_c_in, ns_t_txt, answer, sizeof(answer));

if ((0 < anslen) && (anslen < static_cast<int>(sizeof(answer)))) {
ns_msg handle;
if (ns_initparse(answer, anslen, &handle) == 0) {
for (int rrnum = 0, n = ns_msg_count(handle, ns_s_an); rrnum < n; ++rrnum) {
ns_rr rr;
if ((ns_parserr(&handle, ns_s_an, rrnum, &rr) == 0) && (ns_rr_type(rr) == ns_t_txt)) {
const uint8_t* data = ns_rr_rdata(rr);

const int len = std::min<int>(ns_rr_rdlen(rr) - 1, *data);
++data;

if (!saved_list.empty()) {
saved_list += ',';
}

const char* c = reinterpret_cast<const char*>(data);
LOGINFO(4, "added " << log::const_buf(c, len) << " from " << nodes[i]);
saved_list.append(c, len);
}
}
continue;
}
}
#endif

addrinfo hints{};
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
Expand Down
2 changes: 1 addition & 1 deletion src/tcp_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ void TCPServer::parse_address_list_internal(const std::string& address_list, Cal
}
}

const int port = atoi(address.substr(k2 + 1).c_str());
const int port = strtol(address.substr(k2 + 1).c_str(), nullptr, 10);
if ((port > 0) && (port < 65536)) {
callback(is_v6, address, ip, port);
}
Expand Down
2 changes: 1 addition & 1 deletion tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ include_directories(src)
include_directories(googletest/googletest/include)

if (WIN32)
set(LIBS ${LIBS} ws2_32 iphlpapi userenv psapi wldap32)
set(LIBS ${LIBS} ws2_32 iphlpapi userenv psapi dnsapi)
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
set(LIBS ${LIBS} bcrypt)
endif()
Expand Down

0 comments on commit db9e5ba

Please sign in to comment.