diff --git a/Transmission.xcodeproj/project.pbxproj b/Transmission.xcodeproj/project.pbxproj index 2b1a0aae9..e98bb0a71 100644 --- a/Transmission.xcodeproj/project.pbxproj +++ b/Transmission.xcodeproj/project.pbxproj @@ -11,8 +11,6 @@ 0A6169A80FE5C9A200C66CE6 /* bitfield.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A6169A60FE5C9A200C66CE6 /* bitfield.h */; }; 0A89346B736DBCF81F3A4850 /* torrent-metainfo.cc in Sources */ = {isa = PBXBuildFile; fileRef = 0A89346B736DBCF81F3A4851 /* torrent-metainfo.cc */; }; 0A89346B736DBCF81F3A4852 /* torrent-metainfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A89346B736DBCF81F3A4853 /* torrent-metainfo.h */; }; - 11524394C75E57E52CD9ADF0 /* dns.h in Headers */ = {isa = PBXBuildFile; fileRef = 11524394C75E57E52CD9ADF1 /* dns.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 11524394C75E57E52CD9ADF2 /* dns-ev.h in Headers */ = {isa = PBXBuildFile; fileRef = 11524394C75E57E52CD9ADF3 /* dns-ev.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1BB44E07B1B52E28291B4E32 /* file-piece-map.cc in Sources */ = {isa = PBXBuildFile; fileRef = 1BB44E07B1B52E28291B4E30 /* file-piece-map.cc */; }; 1BB44E07B1B52E28291B4E33 /* file-piece-map.h in Headers */ = {isa = PBXBuildFile; fileRef = 1BB44E07B1B52E28291B4E31 /* file-piece-map.h */; }; 2856E0656A49F2665D69E760 /* benc.h in Headers */ = {isa = PBXBuildFile; fileRef = 2856E0656A49F2665D69E761 /* benc.h */; }; @@ -602,8 +600,6 @@ 0A89346B736DBCF81F3A4851 /* torrent-metainfo.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = "torrent-metainfo.cc"; sourceTree = ""; }; 0A89346B736DBCF81F3A4853 /* torrent-metainfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "torrent-metainfo.h"; sourceTree = ""; }; 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; - 11524394C75E57E52CD9ADF1 /* dns.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = dns.h; sourceTree = ""; }; - 11524394C75E57E52CD9ADF3 /* dns-ev.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = "dns-ev.h"; sourceTree = ""; }; 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 1BB44E07B1B52E28291B4E30 /* file-piece-map.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = "file-piece-map.cc"; sourceTree = ""; }; 1BB44E07B1B52E28291B4E31 /* file-piece-map.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "file-piece-map.h"; sourceTree = ""; }; @@ -1706,8 +1702,6 @@ C11DEA151FCD31C0009E22B9 /* subprocess.h */, E975121263DD973CAF4AEBA5 /* timer-ev.cc */, E975121263DD973CAF4AEBA3 /* timer-ev.h */, - 11524394C75E57E52CD9ADF1 /* dns.h */, - 11524394C75E57E52CD9ADF3 /* dns-ev.h */, E975121263DD973CAF4AEBA1 /* timer.h */, A20152790D1C26EB0081714F /* torrent-ctor.cc */, A47A7C87B8B57BE50DF0D411 /* torrent-files.cc */, @@ -2220,8 +2214,6 @@ 2856E0656A49F2665D69E760 /* benc.h in Headers */, E975121263DD973CAF4AEBA0 /* timer.h in Headers */, E975121263DD973CAF4AEBA2 /* timer-ev.h in Headers */, - 11524394C75E57E52CD9ADF0 /* dns.h in Headers */, - 11524394C75E57E52CD9ADF2 /* dns-ev.h in Headers */, C1077A4F183EB29600634C22 /* error.h in Headers */, A2679295130E00A000CB7464 /* tr-utp.h in Headers */, A263C6B1F6718E2486DB20E0 /* tr-buffer.h in Headers */, diff --git a/libtransmission/CMakeLists.txt b/libtransmission/CMakeLists.txt index 52240ab4f..315de36b7 100644 --- a/libtransmission/CMakeLists.txt +++ b/libtransmission/CMakeLists.txt @@ -136,8 +136,6 @@ endif() set(${PROJECT_NAME}_PUBLIC_HEADERS ${PROJECT_BINARY_DIR}/version.h - dns-ev.h - dns.h error-types.h error.h file.h diff --git a/libtransmission/announcer-udp.cc b/libtransmission/announcer-udp.cc index b9c54b3a5..79118c16d 100644 --- a/libtransmission/announcer-udp.cc +++ b/libtransmission/announcer-udp.cc @@ -5,13 +5,17 @@ #include // for std::find_if() #include // for errno, EAFNOSUPPORT -#include // for memset() +#include // for memcpy() #include #include #include #include #include +#ifdef _WIN32 +#include +#endif + #include #include @@ -23,6 +27,7 @@ #include "announcer-common.h" #include "crypto-utils.h" /* tr_rand_buffer() */ #include "log.h" +#include "error.h" #include "peer-io.h" #include "peer-mgr.h" // for tr_pex::fromCompact4() #include "session.h" @@ -31,6 +36,11 @@ #include "utils.h" #include "web-utils.h" +#ifdef _WIN32 +#undef gai_strerror +#define gai_strerror gai_strerrorA +#endif + #define logwarn(interned, msg) tr_logAddWarn(msg, (interned).sv()) #define logdbg(interned, msg) tr_logAddDebug(msg, (interned).sv()) #define logtrace(interned, msg) tr_logAddTrace(msg, (interned).sv()) @@ -331,9 +341,19 @@ struct tau_tracker { } + tau_tracker(tau_tracker&&) = delete; + tau_tracker(tau_tracker const&) = delete; + tau_tracker& operator=(tau_tracker&&) = delete; + tau_tracker& operator=(tau_tracker const&) = delete; + + ~tau_tracker() + { + tr_error_clear(&addr_error_); + } + [[nodiscard]] auto isIdle() const noexcept { - return std::empty(announces) && std::empty(scrapes) && (dns_request_ == 0U); + return std::empty(announces) && std::empty(scrapes); } void failAll(bool did_connect, bool did_timeout, std::string_view errmsg) @@ -374,7 +394,7 @@ struct tau_tracker tr_interned_string const host; tr_port const port; - libtransmission::Dns::Tag dns_request_ = {}; + tr_error* addr_error_ = nullptr; std::optional> addr_; time_t addr_expires_at_ = 0; @@ -391,30 +411,43 @@ struct tau_tracker std::list scrapes; }; -static void tau_tracker_upkeep(struct tau_tracker* /*tracker*/); - -static void tau_tracker_on_dns(tau_tracker* const tracker, sockaddr const* sa, socklen_t salen, time_t expires_at) +static std::optional> host2sockaddr( + std::string_view host, + tr_port port, + tr_error** error) { - tracker->dns_request_ = {}; + auto const szhost = tr_urlbuf{ host }; - if (sa == nullptr) + auto szport = std::array{}; + *fmt::format_to(std::data(szport), FMT_STRING("{:d}"), port.host()) = '\0'; + + auto hints = addrinfo{}; + hints.ai_family = AF_UNSPEC; + hints.ai_protocol = IPPROTO_UDP; + hints.ai_socktype = SOCK_DGRAM; + + addrinfo* info = nullptr; + if (int const rc = getaddrinfo(szhost, std::data(szport), &hints, &info); rc != 0) { - auto const errmsg = fmt::format(_("Couldn't find address of tracker '{host}'"), fmt::arg("host", tracker->host)); - logwarn(tracker->key, errmsg); - tracker->failAll(false, false, errmsg.c_str()); - tracker->addr_expires_at_ = tr_time() + tau_tracker::DnsRetryIntervalSecs; - } - else - { - logdbg(tracker->key, "DNS lookup succeeded"); - auto ss = sockaddr_storage{}; - memcpy(&ss, sa, salen); - tracker->addr_.emplace(ss, salen); - tracker->addr_expires_at_ = expires_at; - tau_tracker_upkeep(tracker); + tr_logAddWarn(fmt::format( + _("Couldn't look up '{address}:{port}': {error} ({error_code})"), + fmt::arg("address", host), + fmt::arg("port", port.host()), + fmt::arg("error", gai_strerror(rc)), + fmt::arg("error_code", rc))); + tr_error_set(error, rc, gai_strerror(rc)); + return {}; } + + auto ss = sockaddr_storage{}; + auto const len = info->ai_addrlen; + memcpy(&ss, info->ai_addr, len); + freeaddrinfo(info); + return std::make_pair(ss, len); } +static void tau_tracker_upkeep(struct tau_tracker* /*tracker*/); + static void tau_tracker_send_request(struct tau_tracker* tracker, void const* payload, size_t payload_len) { logdbg(tracker->key, fmt::format("sending request w/connection id {}", tracker->connection_id)); @@ -459,7 +492,6 @@ static void tau_tracker_send_requests(tau_tracker* tracker, std::list& reqs) static void tau_tracker_send_reqs(tau_tracker* tracker) { - TR_ASSERT(!tracker->dns_request_); TR_ASSERT(tracker->addr_); TR_ASSERT(tracker->connecting_at == 0); TR_ASSERT(tracker->connection_expiration_time > tr_time()); @@ -562,20 +594,20 @@ static void tau_tracker_upkeep_ex(struct tau_tracker* tracker, bool timeout_reqs return; } - /* if we don't have an address yet, try & get one now. */ - if (!closing && !tracker->addr_ && (tracker->dns_request_ == 0U)) + // if we don't have an address yet, try & get one now + if (!closing && !tracker->addr_) { - auto hints = libtransmission::Dns::Hints{}; - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_DGRAM; - hints.ai_protocol = IPPROTO_UDP; - logtrace(tracker->host, "Trying a new DNS lookup"); - tracker->dns_request_ = tracker->mediator_.dns().lookup( - tracker->host.sv(), - [tracker](sockaddr const* sa, socklen_t len, time_t expires_at) - { tau_tracker_on_dns(tracker, sa, len, expires_at); }, - hints); - return; + if (tracker->addr_expires_at_ <= now) + { + tr_error_clear(&tracker->addr_error_); + tracker->addr_ = host2sockaddr(tracker->host, tracker->port, &tracker->addr_error_); + tracker->addr_expires_at_ = now + tau_tracker::DnsRetryIntervalSecs; + } + if (tracker->addr_error_ != nullptr) + { + tracker->failAll(false, false, tracker->addr_error_->message); + return; + } } logtrace( @@ -684,12 +716,6 @@ public: for (auto& tracker : trackers_) { - // if there's a pending DNS request, cancel it - if (tracker.dns_request_ != 0U) - { - mediator_.dns().cancel(tracker.dns_request_); - } - tracker.close_at = now + 3; tau_tracker_upkeep(&tracker); } diff --git a/libtransmission/announcer.h b/libtransmission/announcer.h index 889d19e0c..97fe88bf1 100644 --- a/libtransmission/announcer.h +++ b/libtransmission/announcer.h @@ -301,7 +301,6 @@ public: public: virtual ~Mediator() noexcept = default; virtual void sendto(void const* buf, size_t buflen, sockaddr const* addr, socklen_t addrlen) = 0; - [[nodiscard]] virtual libtransmission::Dns& dns() = 0; [[nodiscard]] virtual std::optional announceIP() const = 0; }; diff --git a/libtransmission/dns-ev.h b/libtransmission/dns-ev.h deleted file mode 100644 index 1750513bf..000000000 --- a/libtransmission/dns-ev.h +++ /dev/null @@ -1,210 +0,0 @@ -// This file Copyright 2022 Mnemosyne LLC. -// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only), -// or any future license endorsed by Mnemosyne LLC. -// License text can be found in the licenses/ folder. - -#pragma once - -#ifndef __TRANSMISSION__ -#error only libtransmission should #include this header. -#endif - -#include // for std::memcpy() -#include -#include -#include -#include -#include - -#include -#include - -#include "dns.h" -#include "utils.h" // for tr_strlower() - -namespace libtransmission -{ - -class EvDns final : public Dns -{ -private: - using Key = std::pair; - - struct CacheEntry - { - sockaddr_storage ss_ = {}; - socklen_t sslen_ = {}; - time_t expires_at_ = {}; - }; - - struct CallbackArg - { - Key key; - EvDns* self; - }; - - struct Request - { - evdns_getaddrinfo_request* request; - - struct CallbackInfo - { - CallbackInfo(Tag tag, Callback callback) - : tag_{ tag } - , callback_{ std::move(callback) } - { - } - - Tag tag_; - Callback callback_; - }; - - std::list callbacks; - }; - -public: - using TimeFunc = time_t (*)(); - - EvDns(struct event_base* event_base, TimeFunc time_func) - : time_func_{ time_func } - , evdns_base_{ evdns_base_new(event_base, EVDNS_BASE_INITIALIZE_NAMESERVERS), - [](evdns_base* dns) - { - // if zero, active requests will be aborted - evdns_base_free(dns, 0); - } } - { - } - - ~EvDns() override - { - for (auto& [key, request] : requests_) - { - evdns_getaddrinfo_cancel(request.request); - } - } - - std::optional> cached(std::string_view address, Hints hints = {}) const override - { - if (auto const* entry = cached(makeKey(address, hints)); entry != nullptr) - { - return std::make_pair(reinterpret_cast(&entry->ss_), entry->sslen_); - } - - return {}; - } - - Tag lookup(std::string_view address, Callback&& callback, Hints hints = {}) override - { - auto const key = makeKey(address, hints); - - if (auto const* entry = cached(key); entry) - { - callback(reinterpret_cast(&entry->ss_), entry->sslen_, entry->expires_at_); - return {}; - } - - auto& request = requests_[key]; - auto const tag = next_tag_; - ++next_tag_; - request.callbacks.emplace_back(tag, std::move(callback)); - if (request.request == nullptr) - { - auto evhints = evutil_addrinfo{}; - evhints.ai_family = hints.ai_family; - evhints.ai_socktype = hints.ai_socktype; - evhints.ai_protocol = hints.ai_protocol; - void* const arg = new CallbackArg{ key, this }; - request.request = evdns_getaddrinfo(evdns_base_.get(), key.first.c_str(), nullptr, &evhints, evcallback, arg); - } - - return tag; - } - - void cancel(Tag tag) override - { - for (auto& [key, request] : requests_) - { - for (auto iter = std::begin(request.callbacks), end = std::end(request.callbacks); iter != end; ++iter) - { - if (iter->tag_ != tag) - { - continue; - } - - iter->callback_(nullptr, 0, 0); - - request.callbacks.erase(iter); - - // if this was the last pending request for `key`, cancel the evdns request - if (std::empty(request.callbacks)) - { - evdns_getaddrinfo_cancel(request.request); - requests_.erase(key); - } - - return; - } - } - } - -private: - [[nodiscard]] static Key makeKey(std::string_view address, Hints hints) - { - return Key{ tr_strlower(address), hints }; - } - - [[nodiscard]] CacheEntry const* cached(Key const& key) const - { - if (auto iter = cache_.find(key); iter != std::end(cache_)) - { - auto const& entry = iter->second; - - if (auto const now = time_func_(); entry.expires_at_ > now) - { - return &entry; - } - - cache_.erase(iter); // expired - } - - return nullptr; - } - - static void evcallback(int /*result*/, struct evutil_addrinfo* res, void* varg) - { - auto* const arg = static_cast(varg); - auto [key, self] = *arg; - delete arg; - - auto& cache_entry = self->cache_[key]; - - if (res != nullptr) - { - cache_entry.expires_at_ = self->time_func_() + CacheTtlSecs; - cache_entry.sslen_ = res->ai_addrlen; - std::memcpy(&cache_entry.ss_, res->ai_addr, res->ai_addrlen); - evutil_freeaddrinfo(res); - } - - if (auto request_entry = self->requests_.extract(key); request_entry) - { - for (auto& callback : request_entry.mapped().callbacks) - { - callback.callback_( - reinterpret_cast(&cache_entry.ss_), - cache_entry.sslen_, - cache_entry.expires_at_); - } - } - } - - TimeFunc const time_func_; - static time_t constexpr CacheTtlSecs = 3600U; - std::unique_ptr const evdns_base_; - mutable std::map cache_; - std::map requests_; - unsigned int next_tag_ = 1; -}; - -} // namespace libtransmission diff --git a/libtransmission/dns.h b/libtransmission/dns.h deleted file mode 100644 index 5398025c0..000000000 --- a/libtransmission/dns.h +++ /dev/null @@ -1,72 +0,0 @@ -// This file Copyright 2022 Mnemosyne LLC. -// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only), -// or any future license endorsed by Mnemosyne LLC. -// License text can be found in the licenses/ folder. - -#pragma once - -#include -#include - -#include "transmission.h" - -#include "net.h" - -namespace libtransmission -{ - -class Dns -{ -public: - virtual ~Dns() = default; - - using Callback = std::function; - using Tag = unsigned int; - - class Hints - { - public: - Hints() - { - } - - int ai_family = AF_UNSPEC; - int ai_socktype = SOCK_DGRAM; - int ai_protocol = IPPROTO_UDP; - - [[nodiscard]] constexpr int compare(Hints const& that) const noexcept // <=> - { - if (ai_family != that.ai_family) - { - return ai_family < that.ai_family ? -1 : 1; - } - - if (ai_socktype != that.ai_socktype) - { - return ai_socktype < that.ai_socktype ? -1 : 1; - } - - if (ai_protocol != that.ai_protocol) - { - return ai_protocol < that.ai_protocol ? -1 : 1; - } - - return 0; - } - - [[nodiscard]] constexpr bool operator<(Hints const& that) const noexcept - { - return compare(that) < 0; - } - }; - - [[nodiscard]] virtual std::optional> cached( - std::string_view address, - Hints hints = {}) const = 0; - - virtual Tag lookup(std::string_view address, Callback&& callback, Hints hints = {}) = 0; - - virtual void cancel(Tag) = 0; -}; - -} // namespace libtransmission diff --git a/libtransmission/session.cc b/libtransmission/session.cc index 73ef7df02..1ebf89af3 100644 --- a/libtransmission/session.cc +++ b/libtransmission/session.cc @@ -25,7 +25,6 @@ #include /* umask() */ #endif -#include #include #include @@ -39,7 +38,6 @@ #include "blocklist.h" #include "cache.h" #include "crypto-utils.h" -#include "dns-ev.h" #include "error-types.h" #include "error.h" #include "file.h" @@ -2237,7 +2235,6 @@ tr_session::tr_session(std::string_view config_dir, tr_variant* settings_dict) , blocklist_dir_{ makeBlocklistDir(config_dir) } , event_base_{ makeEventBase() } , timer_maker_{ std::make_unique(eventBase()) } - , dns_{ std::make_unique(eventBase(), tr_time) } , settings_{ settings_dict } , session_id_{ tr_time } , peer_mgr_{ tr_peerMgrNew(this), tr_peerMgrFree } diff --git a/libtransmission/session.h b/libtransmission/session.h index 64bde4586..cf9012856 100644 --- a/libtransmission/session.h +++ b/libtransmission/session.h @@ -30,7 +30,6 @@ #include "bandwidth.h" #include "bitfield.h" #include "cache.h" -#include "dns.h" #include "interned-string.h" #include "net.h" // tr_socket_t #include "open-files.h" @@ -140,11 +139,6 @@ private: return tr_address::fromString(session_.announceIP()); } - [[nodiscard]] libtransmission::Dns& dns() override - { - return *session_.dns_.get(); - } - private: tr_session& session_; }; @@ -987,9 +981,6 @@ private: // depends-on: event_base_ std::unique_ptr const timer_maker_; - // depends-on: event_base_ - std::unique_ptr const dns_; - /// static fields static std::recursive_mutex session_mutex_; @@ -1092,7 +1083,7 @@ private: // depends-on: lpd_mediator_ std::unique_ptr lpd_; - // depends-on: dns_, udp_core_ + // depends-on: udp_core_ AnnouncerUdpMediator announcer_udp_mediator_{ *this }; public: diff --git a/libtransmission/torrent.cc b/libtransmission/torrent.cc index 8d07e01dc..22bb03e52 100644 --- a/libtransmission/torrent.cc +++ b/libtransmission/torrent.cc @@ -2348,7 +2348,7 @@ void tr_torrentSetQueuePosition(tr_torrent* tor, size_t queue_position) size_t current = 0; auto const old_pos = tor->queuePosition; - tor->queuePosition = -1; + tor->queuePosition = static_cast(-1); for (auto* const walk : tor->session->torrents()) { diff --git a/tests/libtransmission/CMakeLists.txt b/tests/libtransmission/CMakeLists.txt index 167a1ad49..981ffc96f 100644 --- a/tests/libtransmission/CMakeLists.txt +++ b/tests/libtransmission/CMakeLists.txt @@ -13,7 +13,6 @@ add_executable(libtransmission-test crypto-test-ref.h crypto-test.cc error-test.cc - dns-test.cc file-piece-map-test.cc file-test.cc getopt-test.cc diff --git a/tests/libtransmission/announcer-udp-test.cc b/tests/libtransmission/announcer-udp-test.cc index aa306f9e8..294c8ebbf 100644 --- a/tests/libtransmission/announcer-udp-test.cc +++ b/tests/libtransmission/announcer-udp-test.cc @@ -14,9 +14,9 @@ #include "announcer.h" #include "crypto-utils.h" -#include "dns.h" #include "peer-mgr.h" // for tr_pex #include "tr-buffer.h" +#include "utils.h" // for tr_net_init() #include "test-fixtures.h" @@ -28,45 +28,15 @@ private: void SetUp() override { ::testing::Test::SetUp(); + + tr_net_init(); tr_timeUpdate(time(nullptr)); } protected: - class MockDns final : public libtransmission::Dns - { - public: - ~MockDns() override = default; - - [[nodiscard]] std::optional> cached( - std::string_view /*address*/, - Hints /*hints*/ = {}) const override - { - return {}; - } - - Tag lookup(std::string_view address, Callback&& callback, Hints /*hints*/) override - { - auto const addr = tr_address::fromString(address); // mock has no actual DNS, just parsing e.g. inet_pton - auto [ss, sslen] = addr->toSockaddr(Port); - callback(reinterpret_cast(&ss), sslen, tr_time() + 3600); // 1hr ttl - return {}; - } - - void cancel(Tag /*tag*/) override - { - } - - static auto constexpr Port = tr_port::fromHost(443); - }; - class MockMediator final : public tr_announcer_udp::Mediator { public: - MockMediator() - : event_base_{ event_base_new(), event_base_free } - { - } - void sendto(void const* buf, size_t buflen, sockaddr const* sa, socklen_t salen) override { auto target = tr_address::fromSockaddr(sa); @@ -74,16 +44,6 @@ protected: sent_.emplace_back(static_cast(buf), buflen, sa, salen); } - [[nodiscard]] auto* eventBase() - { - return event_base_.get(); - } - - [[nodiscard]] libtransmission::Dns& dns() override - { - return dns_; - } - [[nodiscard]] std::optional announceIP() const override { return {}; @@ -106,10 +66,6 @@ protected: }; std::deque sent_; - - std::unique_ptr const event_base_; - - MockDns dns_; }; static void expectEqual(tr_scrape_response const& expected, tr_scrape_response const& actual) @@ -202,7 +158,7 @@ protected: [[nodiscard]] static auto waitForAnnouncerToSendMessage(MockMediator& mediator) { EXPECT_FALSE(std::empty(mediator.sent_)); - libtransmission::test::waitFor(mediator.eventBase(), [&mediator]() { return !std::empty(mediator.sent_); }); + libtransmission::test::waitFor([&mediator]() { return !std::empty(mediator.sent_); }, 5s); auto buf = libtransmission::Buffer(mediator.sent_.back().buf_); mediator.sent_.pop_back(); return buf; @@ -265,8 +221,8 @@ protected: EXPECT_EQ(expected.up, actual.uploaded); // EXPECT_EQ(foo, actual.event); ; // 0: none; 1: completed; 2: started; 3: stopped // FIXME // EXPECT_EQ(foo, actual.ip_address); // FIXME - EXPECT_EQ(expected.key, actual.key); - EXPECT_EQ(expected.numwant, actual.num_want); + EXPECT_EQ(expected.key, static_cast(actual.key)); + EXPECT_EQ(expected.numwant, static_cast(actual.num_want)); EXPECT_EQ(expected.port.host(), actual.port); } @@ -412,7 +368,7 @@ TEST_F(AnnouncerUdpTest, canDestructCleanlyEvenWhenBusy) // Inspect that request for validity. auto sent = waitForAnnouncerToSendMessage(mediator); auto const connect_transaction_id = parseConnectionRequest(sent); - EXPECT_NE(0, connect_transaction_id); + EXPECT_NE(0U, connect_transaction_id); // now just end the test before responding to the request. // the announcer and mediator will go out-of-scope & be destroyed. diff --git a/tests/libtransmission/dns-test.cc b/tests/libtransmission/dns-test.cc deleted file mode 100644 index a07e951c1..000000000 --- a/tests/libtransmission/dns-test.cc +++ /dev/null @@ -1,175 +0,0 @@ -// This file Copyright (C) 2022 Mnemosyne LLC. -// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only), -// or any future license endorsed by Mnemosyne LLC. -// License text can be found in the licenses/ folder. - -#include -#include - -#include - -#include "transmission.h" - -#include "dns-ev.h" -#include "dns.h" -#include "trevent.h" // for tr_evthread_init(); - -#include "gtest/gtest.h" -#include "test-fixtures.h" - -using namespace std::literals; - -namespace libtransmission::test -{ - -class EvDnsTest : public ::testing::Test -{ -protected: - void SetUp() override - { - ::testing::Test::SetUp(); - - tr_evthread_init(); - event_base_ = event_base_new(); - } - - void TearDown() override - { - event_base_free(event_base_); - event_base_ = nullptr; - - ::testing::Test::TearDown(); - } - - struct event_base* event_base_ = nullptr; -}; - -TEST_F(EvDnsTest, canLookup) -{ - auto dns = EvDns{ event_base_, tr_time }; - auto done = false; - - dns.lookup( - "example.com", - [&done](struct sockaddr const* ai, socklen_t ailen, time_t expires_at) - { - EXPECT_NE(nullptr, ai); - EXPECT_GT(ailen, 0); - EXPECT_GT(expires_at, tr_time()); - done = true; - }); - - waitFor(event_base_, [&done]() { return done; }); - EXPECT_TRUE(done); -} - -TEST_F(EvDnsTest, canRequestWhilePending) -{ - auto dns = EvDns{ event_base_, tr_time }; - auto n_done = size_t{ 0 }; - - dns.lookup( - "example.com", - [&n_done](struct sockaddr const* ai, socklen_t ailen, time_t expires_at) - { - EXPECT_NE(nullptr, ai); - EXPECT_GT(ailen, 0); - EXPECT_GT(expires_at, tr_time()); - ++n_done; - }); - - dns.lookup( - "example.com", - [&n_done](struct sockaddr const* ai, socklen_t ailen, time_t expires_at) - { - EXPECT_NE(nullptr, ai); - EXPECT_GT(ailen, 0); - EXPECT_GT(expires_at, tr_time()); - ++n_done; - }); - - // wait for both callbacks to be called - waitFor(event_base_, [&n_done]() { return n_done >= 2U; }); - EXPECT_EQ(2U, n_done); -} - -TEST_F(EvDnsTest, canCancel) -{ - auto dns = EvDns{ event_base_, tr_time }; - auto n_done = size_t{ 0 }; - static auto constexpr Name = "example.com"sv; - - auto tag = dns.lookup( - Name, - [&n_done](struct sockaddr const* ai, socklen_t ailen, time_t expires_at) - { - ++n_done; - // we cancelled this req, so `ai` and `ailen` should be zeroed out - EXPECT_EQ(nullptr, ai); - EXPECT_EQ(0, ailen); - EXPECT_EQ(0, expires_at); - }); - - dns.lookup( - Name, - [&n_done](struct sockaddr const* ai, socklen_t ailen, time_t expires_at) - { - ++n_done; - - // this one did _not_ get cancelled so it should be OK - EXPECT_NE(nullptr, ai); - EXPECT_GT(ailen, 0); - EXPECT_GT(expires_at, tr_time()); - }); - - dns.cancel(tag); - - // wait for both callbacks to be called - waitFor(event_base_, [&n_done]() { return n_done >= 2U; }); - EXPECT_EQ(2U, n_done); -} - -TEST_F(EvDnsTest, doesCacheEntries) -{ - auto dns = EvDns{ event_base_, tr_time }; - static auto constexpr Name = "example.com"sv; - - struct sockaddr const* ai_addr = nullptr; - - dns.lookup( - Name, - [&ai_addr](struct sockaddr const* ai, socklen_t ailen, time_t expires_at) - { - EXPECT_NE(nullptr, ai); - EXPECT_GT(ailen, 0); - EXPECT_GT(expires_at, tr_time()); - ai_addr = ai; - }); - - // wait for the lookup - waitFor(event_base_, [&ai_addr]() { return ai_addr != nullptr; }); - ASSERT_NE(nullptr, ai_addr); - - auto second_callback_called = false; - dns.lookup( - Name, - [&ai_addr, &second_callback_called](struct sockaddr const* ai, socklen_t ailen, time_t expires_at) - { - EXPECT_NE(nullptr, ai); - EXPECT_GT(ailen, 0); - EXPECT_EQ(ai_addr, ai); - EXPECT_GT(expires_at, tr_time()); - second_callback_called = true; - }); - // since it's cached, the callback should have been invoked - // without waiting for the event loop - EXPECT_TRUE(second_callback_called); - - // confirm that `cached()` returns the cached value immediately - auto res = dns.cached(Name); - EXPECT_TRUE(res); - EXPECT_EQ(ai_addr, res->first); - EXPECT_GT(res->second, 0); -} - -} // namespace libtransmission::test diff --git a/tests/libtransmission/net-test.cc b/tests/libtransmission/net-test.cc index 0cfe0dcbf..32d78e1e0 100644 --- a/tests/libtransmission/net-test.cc +++ b/tests/libtransmission/net-test.cc @@ -55,7 +55,7 @@ TEST_F(NetTest, compact4) auto compact4 = std::array{}; auto out = std::data(compact4); out = addr.toCompact4(out, port); - EXPECT_EQ(std::size(Compact4), out - std::data(compact4)); + EXPECT_EQ(std::size(Compact4), static_cast(out - std::data(compact4))); EXPECT_EQ(Compact4, compact4); /// sockaddr --> compact diff --git a/tests/libtransmission/settings-test.cc b/tests/libtransmission/settings-test.cc index 0ac8ab9cd..b514cd7b6 100644 --- a/tests/libtransmission/settings-test.cc +++ b/tests/libtransmission/settings-test.cc @@ -327,7 +327,7 @@ TEST_F(SettingsTest, canSaveSizeT) settings.save(&dict); auto val = int64_t{}; EXPECT_TRUE(tr_variantDictFindInt(&dict, Key, &val)); - EXPECT_EQ(expected_value, val); + EXPECT_EQ(expected_value, static_cast(val)); tr_variantClear(&dict); }