diff --git a/CMakeLists.txt b/CMakeLists.txt index 44776ce..b28c71d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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() @@ -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 \n#pragma intrinsic(_BitScanReverse64)\nint main(){unsigned long r;_BitScanReverse64(&r,1);return r;}" HAVE_BITSCANREVERSE64) check_cxx_source_compiles("#include \nint main(){sched_param param;return sched_setscheduler(0, SCHED_IDLE, ¶m);}" HAVE_SCHED) +include(CheckCSourceCompiles) + +set(CMAKE_REQUIRED_LIBRARIES "resolv") + +check_c_source_compiles(" +#include +#include +#include +#include + +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() @@ -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) @@ -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() @@ -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" diff --git a/src/p2p_server.cpp b/src/p2p_server.cpp index f6f7ae4..93024a9 100644 --- a/src/p2p_server.cpp +++ b/src/p2p_server.cpp @@ -31,6 +31,13 @@ #include #include +#ifdef _WIN32 +#include +#elif defined(HAVE_RES_QUERY) +#include +#include +#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", ""}; @@ -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); } @@ -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(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(ns_rr_rdlen(rr) - 1, *data); + ++data; + + if (!saved_list.empty()) { + saved_list += ','; + } + + const char* c = reinterpret_cast(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; diff --git a/src/tcp_server.cpp b/src/tcp_server.cpp index 4c09ca2..b1dfa69 100644 --- a/src/tcp_server.cpp +++ b/src/tcp_server.cpp @@ -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); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7be7a51..659cd1d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -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()