113 lines
3.1 KiB
C++
113 lines
3.1 KiB
C++
// This file Copyright © 2009-2023 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 <cstddef> // size_t
|
|
#include <ctime>
|
|
#include <memory>
|
|
#include <string_view>
|
|
#include <vector>
|
|
|
|
#include <dht/dht.h>
|
|
|
|
#include "transmission.h"
|
|
|
|
#include "net.h" // tr_port
|
|
|
|
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 const char* id, unsigned const char* v)
|
|
{
|
|
return ::dht_init(s, s6, id, v);
|
|
}
|
|
|
|
virtual int uninit()
|
|
{
|
|
return ::dht_uninit();
|
|
}
|
|
};
|
|
|
|
class Mediator
|
|
{
|
|
public:
|
|
virtual ~Mediator() = default;
|
|
|
|
[[nodiscard]] virtual std::vector<tr_torrent_id_t> 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<tr_dht> create(
|
|
Mediator& mediator,
|
|
tr_port peer_port,
|
|
tr_socket_t udp4_socket,
|
|
tr_socket_t udp6_socket);
|
|
virtual ~tr_dht() = default;
|
|
|
|
virtual void 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;
|
|
};
|