// This file Copyright © Juliusz Chroboczek. // It may be used under the MIT (SPDX: MIT) license. // License text can be found in the licenses/ folder. #pragma once #ifndef __TRANSMISSION__ #error only libtransmission should #include this header. #endif #include // size_t #include #include #include #include #ifdef _WIN32 #include #else #include #endif #include #include "libtransmission/transmission.h" #include "libtransmission/net.h" // tr_port #include "libtransmission/tr-macros.h" struct tr_pex; namespace libtransmission { class TimerMaker; } // namespace libtransmission class tr_dht { public: // Wrapper around DHT library. // This calls `jech/dht` in production, but makes it possible for tests to inject a mock. struct API { virtual ~API() = default; virtual int get_nodes(struct sockaddr_in* sin, int* num, struct sockaddr_in6* sin6, int* num6) { return ::dht_get_nodes(sin, num, sin6, num6); } virtual int nodes(int af, int* good_return, int* dubious_return, int* cached_return, int* incoming_return) { return ::dht_nodes(af, good_return, dubious_return, cached_return, incoming_return); } virtual int periodic( void const* buf, size_t buflen, struct sockaddr const* from, int fromlen, time_t* tosleep, dht_callback_t callback, void* closure) { return ::dht_periodic(buf, buflen, from, fromlen, tosleep, callback, closure); } virtual int ping_node(struct sockaddr const* sa, int salen) { return ::dht_ping_node(sa, salen); } virtual int search(unsigned char const* id, int port, int af, dht_callback_t callback, void* closure) { return ::dht_search(id, port, af, callback, closure); } virtual int init(int s, int s6, unsigned char const* id, unsigned char const* v) { return ::dht_init(s, s6, id, v); } virtual int uninit() { return ::dht_uninit(); } }; class Mediator { public: virtual ~Mediator() = default; [[nodiscard]] virtual std::vector torrents_allowing_dht() const = 0; [[nodiscard]] virtual tr_sha1_digest_t torrent_info_hash(tr_torrent_id_t) const = 0; [[nodiscard]] virtual std::string_view config_dir() const = 0; [[nodiscard]] virtual libtransmission::TimerMaker& timer_maker() = 0; [[nodiscard]] virtual API& api() { return api_; } virtual void add_pex(tr_sha1_digest_t const&, tr_pex const* pex, size_t n_pex) = 0; private: API api_; }; [[nodiscard]] static std::unique_ptr create( Mediator& mediator, tr_port peer_port, tr_socket_t udp4_socket, tr_socket_t udp6_socket); virtual ~tr_dht() = default; virtual void maybe_add_node(tr_address const& address, tr_port port) = 0; virtual void handle_message(unsigned char const* msg, size_t msglen, struct sockaddr* from, socklen_t fromlen) = 0; };