refactor: add a tr_port safety class (#2952)
This commit is contained in:
parent
bdac708762
commit
32f854a7cf
|
@ -19,6 +19,7 @@
|
|||
#include "transmission.h"
|
||||
|
||||
#include "interned-string.h"
|
||||
#include "net.h"
|
||||
#include "peer-mgr.h" // tr_pex
|
||||
#include "web-utils.h"
|
||||
|
||||
|
@ -134,7 +135,7 @@ struct tr_announce_request
|
|||
bool partial_seed = false;
|
||||
|
||||
/* the port we listen for incoming peers on */
|
||||
int port = 0;
|
||||
tr_port port;
|
||||
|
||||
/* per-session key */
|
||||
int key = 0;
|
||||
|
|
|
@ -71,7 +71,7 @@ static tr_urlbuf announce_url_new(tr_session const* session, tr_announce_request
|
|||
fmt::arg("sep", tr_strvContains(req->announce_url.sv(), '?') ? '&' : '?'),
|
||||
fmt::arg("info_hash", std::data(escaped_info_hash)),
|
||||
fmt::arg("peer_id", std::string_view{ std::data(req->peer_id), std::size(req->peer_id) }),
|
||||
fmt::arg("port", req->port),
|
||||
fmt::arg("port", req->port.host()),
|
||||
fmt::arg("uploaded", req->up),
|
||||
fmt::arg("downloaded", req->down),
|
||||
fmt::arg("left", req->leftUntilComplete),
|
||||
|
@ -211,7 +211,7 @@ void tr_announcerParseHttpAnnounceResponse(tr_announce_response& response, std::
|
|||
}
|
||||
else if (key == "port"sv)
|
||||
{
|
||||
pex_.port = htons(uint16_t(value));
|
||||
pex_.port.setHost(static_cast<uint16_t>(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -47,11 +47,11 @@ static void tau_sockaddr_setport(struct sockaddr* sa, tr_port port)
|
|||
{
|
||||
if (sa->sa_family == AF_INET)
|
||||
{
|
||||
TR_DISCARD_ALIGN(sa, struct sockaddr_in*)->sin_port = htons(port);
|
||||
TR_DISCARD_ALIGN(sa, struct sockaddr_in*)->sin_port = port.network();
|
||||
}
|
||||
else if (sa->sa_family == AF_INET6)
|
||||
{
|
||||
TR_DISCARD_ALIGN(sa, struct sockaddr_in6*)->sin6_port = htons(port);
|
||||
TR_DISCARD_ALIGN(sa, struct sockaddr_in6*)->sin6_port = port.network();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -370,7 +370,7 @@ static tau_announce_request make_tau_announce_request(
|
|||
evbuffer_add_hton_32(buf, 0);
|
||||
evbuffer_add_hton_32(buf, in->key);
|
||||
evbuffer_add_hton_32(buf, in->numwant);
|
||||
evbuffer_add_hton_16(buf, in->port);
|
||||
evbuffer_add_hton_16(buf, in->port.host());
|
||||
auto const* const payload_begin = evbuffer_pullup(buf, -1);
|
||||
auto const* const payload_end = payload_begin + evbuffer_get_length(buf);
|
||||
|
||||
|
@ -423,7 +423,7 @@ struct tau_tracker
|
|||
|
||||
tr_interned_string const key;
|
||||
tr_interned_string const host;
|
||||
int const port;
|
||||
tr_port const port;
|
||||
|
||||
evdns_getaddrinfo_request* dns_request = nullptr;
|
||||
std::shared_ptr<evutil_addrinfo> addr;
|
||||
|
@ -439,7 +439,7 @@ struct tau_tracker
|
|||
std::list<tau_announce_request> announces;
|
||||
std::list<tau_scrape_request> scrapes;
|
||||
|
||||
tau_tracker(tr_session* session_in, tr_interned_string key_in, tr_interned_string host_in, int port_in)
|
||||
tau_tracker(tr_session* session_in, tr_interned_string key_in, tr_interned_string host_in, tr_port port_in)
|
||||
: session{ session_in }
|
||||
, key{ key_in }
|
||||
, host{ host_in }
|
||||
|
@ -744,7 +744,7 @@ static tau_tracker* tau_session_get_tracker(tr_announcer_udp* tau, tr_interned_s
|
|||
}
|
||||
|
||||
// we don't have it -- build a new one
|
||||
tau->trackers.emplace_back(tau->session, key, tr_interned_string(parsed->host), parsed->port);
|
||||
tau->trackers.emplace_back(tau->session, key, tr_interned_string(parsed->host), tr_port::fromHost(parsed->port));
|
||||
auto* const tracker = &tau->trackers.back();
|
||||
logtrace(tracker->key, "New tau_tracker created");
|
||||
return tracker;
|
||||
|
|
|
@ -877,7 +877,7 @@ static tr_announce_request* announce_request_new(
|
|||
TR_ASSERT(current_tracker != nullptr);
|
||||
|
||||
auto* const req = new tr_announce_request();
|
||||
req->port = tr_sessionGetPublicPeerPort(announcer->session);
|
||||
req->port = announcer->session->peerPort();
|
||||
req->announce_url = current_tracker->announce_url;
|
||||
req->tracker_id = current_tracker->tracker_id;
|
||||
req->info_hash = tor->infoHash();
|
||||
|
|
|
@ -55,8 +55,8 @@ struct tr_natpmp* tr_natpmpInit()
|
|||
{
|
||||
auto* const nat = tr_new0(struct tr_natpmp, 1);
|
||||
nat->state = TR_NATPMP_DISCOVER;
|
||||
nat->public_port = 0;
|
||||
nat->private_port = 0;
|
||||
nat->public_port.clear();
|
||||
nat->private_port.clear();
|
||||
nat->natpmp.s = TR_BAD_SOCKET; /* socket */
|
||||
return nat;
|
||||
}
|
||||
|
@ -125,7 +125,12 @@ tr_port_forwarding tr_natpmpPulse(
|
|||
|
||||
if (nat->state == TR_NATPMP_SEND_UNMAP && canSendCommand(nat))
|
||||
{
|
||||
int const val = sendnewportmappingrequest(&nat->natpmp, NATPMP_PROTOCOL_TCP, nat->private_port, nat->public_port, 0);
|
||||
int const val = sendnewportmappingrequest(
|
||||
&nat->natpmp,
|
||||
NATPMP_PROTOCOL_TCP,
|
||||
nat->private_port.host(),
|
||||
nat->public_port.host(),
|
||||
0);
|
||||
logVal("sendnewportmappingrequest", val);
|
||||
nat->state = val < 0 ? TR_NATPMP_ERR : TR_NATPMP_RECV_UNMAP;
|
||||
setCommandTime(nat);
|
||||
|
@ -139,14 +144,14 @@ tr_port_forwarding tr_natpmpPulse(
|
|||
|
||||
if (val >= 0)
|
||||
{
|
||||
int const unmapped_port = resp.pnu.newportmapping.privateport;
|
||||
auto const unmapped_port = tr_port::fromHost(resp.pnu.newportmapping.privateport);
|
||||
|
||||
tr_logAddInfo(fmt::format(_("Port {port} is no longer forwarded"), fmt::arg("port", unmapped_port)));
|
||||
tr_logAddInfo(fmt::format(_("Port {port} is no longer forwarded"), fmt::arg("port", unmapped_port.host())));
|
||||
|
||||
if (nat->private_port == unmapped_port)
|
||||
{
|
||||
nat->private_port = 0;
|
||||
nat->public_port = 0;
|
||||
nat->private_port.clear();
|
||||
nat->public_port.clear();
|
||||
nat->state = TR_NATPMP_IDLE;
|
||||
nat->is_mapped = false;
|
||||
}
|
||||
|
@ -171,7 +176,12 @@ tr_port_forwarding tr_natpmpPulse(
|
|||
|
||||
if (nat->state == TR_NATPMP_SEND_MAP && canSendCommand(nat))
|
||||
{
|
||||
int const val = sendnewportmappingrequest(&nat->natpmp, NATPMP_PROTOCOL_TCP, private_port, private_port, LifetimeSecs);
|
||||
int const val = sendnewportmappingrequest(
|
||||
&nat->natpmp,
|
||||
NATPMP_PROTOCOL_TCP,
|
||||
private_port.host(),
|
||||
private_port.host(),
|
||||
LifetimeSecs);
|
||||
logVal("sendnewportmappingrequest", val);
|
||||
nat->state = val < 0 ? TR_NATPMP_ERR : TR_NATPMP_RECV_MAP;
|
||||
setCommandTime(nat);
|
||||
|
@ -188,9 +198,9 @@ tr_port_forwarding tr_natpmpPulse(
|
|||
nat->state = TR_NATPMP_IDLE;
|
||||
nat->is_mapped = true;
|
||||
nat->renew_time = tr_time() + (resp.pnu.newportmapping.lifetime / 2);
|
||||
nat->private_port = resp.pnu.newportmapping.privateport;
|
||||
nat->public_port = resp.pnu.newportmapping.mappedpublicport;
|
||||
tr_logAddInfo(fmt::format(_("Port {port} forwarded successfully"), fmt::arg("port", nat->private_port)));
|
||||
nat->private_port = tr_port::fromHost(resp.pnu.newportmapping.privateport);
|
||||
nat->public_port = tr_port::fromHost(resp.pnu.newportmapping.mappedpublicport);
|
||||
tr_logAddInfo(fmt::format(_("Port {port} forwarded successfully"), fmt::arg("port", nat->private_port.host())));
|
||||
}
|
||||
else if (val != NATPMP_TRYAGAIN)
|
||||
{
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
|
||||
#include "natpmp.h"
|
||||
#include "net.h" // tr_port
|
||||
|
||||
enum tr_natpmp_state
|
||||
{
|
||||
|
|
|
@ -65,7 +65,7 @@ char const* tr_address_and_port_to_string(char* buf, size_t buflen, tr_address c
|
|||
{
|
||||
char addr_buf[INET6_ADDRSTRLEN];
|
||||
tr_address_to_string_with_buf(addr, addr_buf, sizeof(addr_buf));
|
||||
*fmt::format_to_n(buf, buflen - 1, FMT_STRING("[{:s}]:{:d}"), addr_buf, ntohs(port)).out = '\0';
|
||||
*fmt::format_to_n(buf, buflen - 1, FMT_STRING("[{:s}]:{:d}"), addr_buf, port.host()).out = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
@ -145,7 +145,7 @@ std::string tr_address::to_string(tr_port port) const
|
|||
{
|
||||
auto addrbuf = std::array<char, TR_ADDRSTRLEN>{};
|
||||
tr_address_to_string_with_buf(this, std::data(addrbuf), std::size(addrbuf));
|
||||
return fmt::format("[{}]:{}", std::data(addrbuf), ntohs(port));
|
||||
return fmt::format(FMT_STRING("[{:s}]:{:d}"), std::data(addrbuf), port.host());
|
||||
}
|
||||
|
||||
tr_address tr_address::from_4byte_ipv4(std::string_view in)
|
||||
|
@ -290,7 +290,7 @@ bool tr_address_from_sockaddr_storage(tr_address* setme_addr, tr_port* setme_por
|
|||
auto const* const sin = (struct sockaddr_in const*)from;
|
||||
setme_addr->type = TR_AF_INET;
|
||||
setme_addr->addr.addr4.s_addr = sin->sin_addr.s_addr;
|
||||
*setme_port = sin->sin_port;
|
||||
*setme_port = tr_port::fromNetwork(sin->sin_port);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -299,7 +299,7 @@ bool tr_address_from_sockaddr_storage(tr_address* setme_addr, tr_port* setme_por
|
|||
auto const* const sin6 = (struct sockaddr_in6 const*)from;
|
||||
setme_addr->type = TR_AF_INET6;
|
||||
setme_addr->addr.addr6 = sin6->sin6_addr;
|
||||
*setme_port = sin6->sin6_port;
|
||||
*setme_port = tr_port::fromNetwork(sin6->sin6_port);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -315,14 +315,14 @@ static socklen_t setup_sockaddr(tr_address const* addr, tr_port port, struct soc
|
|||
sockaddr_in sock4 = {};
|
||||
sock4.sin_family = AF_INET;
|
||||
sock4.sin_addr.s_addr = addr->addr.addr4.s_addr;
|
||||
sock4.sin_port = port;
|
||||
sock4.sin_port = port.network();
|
||||
memcpy(sockaddr, &sock4, sizeof(sock4));
|
||||
return sizeof(struct sockaddr_in);
|
||||
}
|
||||
|
||||
sockaddr_in6 sock6 = {};
|
||||
sock6.sin6_family = AF_INET6;
|
||||
sock6.sin6_port = port;
|
||||
sock6.sin6_port = port.network();
|
||||
sock6.sin6_flowinfo = 0;
|
||||
sock6.sin6_addr = addr->addr.addr6;
|
||||
memcpy(sockaddr, &sock6, sizeof(sock6));
|
||||
|
@ -372,7 +372,7 @@ struct tr_peer_socket tr_netOpenPeerSocket(tr_session* session, tr_address const
|
|||
/* set source address */
|
||||
tr_address const* const source_addr = tr_sessionGetPublicAddress(session, addr->type, nullptr);
|
||||
TR_ASSERT(source_addr != nullptr);
|
||||
socklen_t const sourcelen = setup_sockaddr(source_addr, 0, &source_sock);
|
||||
socklen_t const sourcelen = setup_sockaddr(source_addr, {}, &source_sock);
|
||||
|
||||
if (bind(s, (struct sockaddr*)&source_sock, sourcelen) == -1)
|
||||
{
|
||||
|
@ -400,7 +400,7 @@ struct tr_peer_socket tr_netOpenPeerSocket(tr_session* session, tr_address const
|
|||
_("Couldn't connect socket {socket} to {address}:{port}: {error} ({error_code})"),
|
||||
fmt::arg("socket", s),
|
||||
fmt::arg("address", addr->to_string()),
|
||||
fmt::arg("port", ntohs(port)),
|
||||
fmt::arg("port", port.host()),
|
||||
fmt::arg("error", tr_net_strerror(tmperrno)),
|
||||
fmt::arg("error_code", tmperrno)));
|
||||
}
|
||||
|
@ -498,7 +498,7 @@ static tr_socket_t tr_netBindTCPImpl(tr_address const* addr, tr_port port, bool
|
|||
|
||||
#endif
|
||||
|
||||
int const addrlen = setup_sockaddr(addr, htons(port), &sock);
|
||||
int const addrlen = setup_sockaddr(addr, port, &sock);
|
||||
|
||||
if (bind(fd, (struct sockaddr*)&sock, addrlen) == -1)
|
||||
{
|
||||
|
@ -511,7 +511,7 @@ static tr_socket_t tr_netBindTCPImpl(tr_address const* addr, tr_port port, bool
|
|||
_("Couldn't bind port {port} on {address}: {error} ({error_code}) -- Is another copy of Transmission already running?") :
|
||||
_("Couldn't bind port {port} on {address}: {error} ({error_code})"),
|
||||
fmt::arg("address", addr->to_string()),
|
||||
fmt::arg("port", port),
|
||||
fmt::arg("port", port.host()),
|
||||
fmt::arg("error", tr_net_strerror(err)),
|
||||
fmt::arg("error_code", err)));
|
||||
}
|
||||
|
@ -523,7 +523,7 @@ static tr_socket_t tr_netBindTCPImpl(tr_address const* addr, tr_port port, bool
|
|||
|
||||
if (!suppressMsgs)
|
||||
{
|
||||
tr_logAddDebug(fmt::format("Bound socket {} to port {} on {}", fd, port, addr->to_string()));
|
||||
tr_logAddDebug(fmt::format(FMT_STRING("Bound socket {:d} to port {:d} on {:s}"), fd, port.host(), addr->to_string()));
|
||||
}
|
||||
|
||||
#ifdef TCP_FASTOPEN
|
||||
|
@ -823,7 +823,7 @@ static bool isMartianAddr(struct tr_address const* a)
|
|||
|
||||
bool tr_address_is_valid_for_peers(tr_address const* addr, tr_port port)
|
||||
{
|
||||
return port != 0 && tr_address_is_valid(addr) && !isIPv6LinkLocalAddress(addr) && !isIPv4MappedAddress(addr) &&
|
||||
return !std::empty(port) && tr_address_is_valid(addr) && !isIPv6LinkLocalAddress(addr) && !isIPv4MappedAddress(addr) &&
|
||||
!isMartianAddr(addr);
|
||||
}
|
||||
|
||||
|
@ -842,3 +842,16 @@ struct tr_peer_socket tr_peer_socket_utp_create(struct UTPSocket* const handle)
|
|||
ret.handle.utp = handle;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// tr_port
|
||||
|
||||
static auto constexpr PortLen = size_t{ 2 };
|
||||
|
||||
std::pair<tr_port, uint8_t const*> tr_port::fromCompact(uint8_t const* compact) noexcept
|
||||
{
|
||||
static_assert(PortLen == sizeof(uint16_t));
|
||||
auto nport = uint16_t{};
|
||||
std::copy_n(compact, PortLen, reinterpret_cast<uint8_t*>(&nport));
|
||||
compact += PortLen;
|
||||
return std::make_pair(tr_port::fromNetwork(nport), compact);
|
||||
}
|
||||
|
|
|
@ -9,9 +9,11 @@
|
|||
#endif
|
||||
|
||||
#include <cstddef> // size_t
|
||||
#include <cstdint> // uint8_t
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility> // std::pair
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <ws2tcpip.h>
|
||||
|
@ -71,6 +73,82 @@ struct tr_address;
|
|||
|
||||
[[nodiscard]] int tr_address_compare(tr_address const* a, tr_address const* b) noexcept;
|
||||
|
||||
/**
|
||||
* Literally just a port number.
|
||||
*
|
||||
* Exists so that you never have to wonder what byte order a port variable is in.
|
||||
*/
|
||||
class tr_port
|
||||
{
|
||||
public:
|
||||
tr_port() noexcept = default;
|
||||
|
||||
[[nodiscard]] constexpr static tr_port fromHost(uint16_t hport) noexcept
|
||||
{
|
||||
return tr_port{ hport };
|
||||
}
|
||||
|
||||
[[nodiscard]] static tr_port fromNetwork(uint16_t nport) noexcept
|
||||
{
|
||||
return tr_port{ ntohs(nport) };
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr uint16_t host() const noexcept
|
||||
{
|
||||
return hport_;
|
||||
}
|
||||
|
||||
[[nodiscard]] uint16_t network() const noexcept
|
||||
{
|
||||
return htons(hport_);
|
||||
}
|
||||
|
||||
constexpr void setHost(uint16_t hport) noexcept
|
||||
{
|
||||
hport_ = hport;
|
||||
}
|
||||
|
||||
void setNetwork(uint16_t nport) noexcept
|
||||
{
|
||||
hport_ = ntohs(nport);
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::pair<tr_port, uint8_t const*> fromCompact(uint8_t const* compact) noexcept;
|
||||
|
||||
[[nodiscard]] constexpr auto operator<(tr_port const& that) const noexcept
|
||||
{
|
||||
return hport_ < that.hport_;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto operator==(tr_port const& that) const noexcept
|
||||
{
|
||||
return hport_ == that.hport_;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto operator!=(tr_port const& that) const noexcept
|
||||
{
|
||||
return hport_ != that.hport_;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto empty() const noexcept
|
||||
{
|
||||
return hport_ == 0;
|
||||
}
|
||||
|
||||
constexpr void clear() noexcept
|
||||
{
|
||||
hport_ = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
constexpr tr_port(uint16_t hport) noexcept
|
||||
: hport_{ hport }
|
||||
{
|
||||
}
|
||||
|
||||
uint16_t hport_ = 0;
|
||||
};
|
||||
|
||||
struct tr_address
|
||||
{
|
||||
static tr_address from_4byte_ipv4(std::string_view in);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "bitfield.h"
|
||||
#include "history.h"
|
||||
#include "interned-string.h"
|
||||
#include "net.h" // tr_port
|
||||
|
||||
/**
|
||||
* @addtogroup peers Peers
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <cstdint>
|
||||
#include <cstdlib> /* qsort */
|
||||
#include <ctime> // time_t
|
||||
#include <tuple> // std::tie
|
||||
#include <iterator> // std::back_inserter
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
@ -1122,16 +1123,15 @@ size_t tr_peerMgrAddPex(tr_torrent* tor, uint8_t from, tr_pex const* pex, size_t
|
|||
std::vector<tr_pex> tr_peerMgrCompactToPex(void const* compact, size_t compactLen, uint8_t const* added_f, size_t added_f_len)
|
||||
{
|
||||
size_t n = compactLen / 6;
|
||||
auto const* walk = static_cast<std::byte const*>(compact);
|
||||
auto const* walk = static_cast<uint8_t const*>(compact);
|
||||
auto pex = std::vector<tr_pex>(n);
|
||||
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
{
|
||||
pex[i].addr.type = TR_AF_INET;
|
||||
std::copy_n(walk, 4, reinterpret_cast<std::byte*>(&pex[i].addr.addr));
|
||||
std::copy_n(walk, 4, reinterpret_cast<uint8_t*>(&pex[i].addr.addr));
|
||||
walk += 4;
|
||||
std::copy_n(walk, 2, reinterpret_cast<std::byte*>(&pex[i].port));
|
||||
walk += 2;
|
||||
std::tie(pex[i].port, walk) = tr_port::fromCompact(walk);
|
||||
|
||||
if (added_f != nullptr && n == added_f_len)
|
||||
{
|
||||
|
@ -1145,16 +1145,15 @@ std::vector<tr_pex> tr_peerMgrCompactToPex(void const* compact, size_t compactLe
|
|||
std::vector<tr_pex> tr_peerMgrCompact6ToPex(void const* compact, size_t compactLen, uint8_t const* added_f, size_t added_f_len)
|
||||
{
|
||||
size_t n = compactLen / 18;
|
||||
auto const* walk = static_cast<std::byte const*>(compact);
|
||||
auto const* walk = static_cast<uint8_t const*>(compact);
|
||||
auto pex = std::vector<tr_pex>(n);
|
||||
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
{
|
||||
pex[i].addr.type = TR_AF_INET6;
|
||||
std::copy_n(walk, 16, reinterpret_cast<std::byte*>(&pex[i].addr.addr.addr6.s6_addr));
|
||||
std::copy_n(walk, 16, reinterpret_cast<uint8_t*>(&pex[i].addr.addr.addr6.s6_addr));
|
||||
walk += 16;
|
||||
std::copy_n(walk, 2, reinterpret_cast<std::byte*>(&pex[i].port));
|
||||
walk += 2;
|
||||
std::tie(pex[i].port, walk) = tr_port::fromCompact(walk);
|
||||
|
||||
if (added_f != nullptr && n == added_f_len)
|
||||
{
|
||||
|
@ -1311,7 +1310,10 @@ int tr_peerMgrGetPeers(tr_torrent const* tor, tr_pex** setme_pex, uint8_t af, ui
|
|||
}
|
||||
}
|
||||
|
||||
qsort(atoms, atomCount, sizeof(struct peer_atom*), compareAtomsByUsefulness);
|
||||
if (atoms != nullptr)
|
||||
{
|
||||
qsort(atoms, atomCount, sizeof(struct peer_atom*), compareAtomsByUsefulness);
|
||||
}
|
||||
|
||||
/**
|
||||
*** add the first N of them into our return list
|
||||
|
@ -1338,7 +1340,10 @@ int tr_peerMgrGetPeers(tr_torrent const* tor, tr_pex** setme_pex, uint8_t af, ui
|
|||
}
|
||||
}
|
||||
|
||||
qsort(pex, count, sizeof(tr_pex), tr_pexCompare);
|
||||
if (pex != nullptr)
|
||||
{
|
||||
qsort(pex, count, sizeof(tr_pex), tr_pexCompare);
|
||||
}
|
||||
|
||||
TR_ASSERT(walk - pex == count);
|
||||
*setme_pex = pex;
|
||||
|
@ -1647,7 +1652,7 @@ static auto getPeerStats(tr_peerMsgs const* peer, time_t now, uint64_t now_msec)
|
|||
|
||||
tr_address_to_string_with_buf(&atom->addr, stats.addr, sizeof(stats.addr));
|
||||
stats.client = peer->client.c_str();
|
||||
stats.port = ntohs(peer->atom->port);
|
||||
stats.port = peer->atom->port.host();
|
||||
stats.from = atom->fromFirst;
|
||||
stats.progress = peer->progress;
|
||||
stats.isUTP = peer->is_utp_connection();
|
||||
|
|
|
@ -59,6 +59,8 @@ auto constexpr Bitfield = uint8_t{ 5 };
|
|||
auto constexpr Request = uint8_t{ 6 };
|
||||
auto constexpr Piece = uint8_t{ 7 };
|
||||
auto constexpr Cancel = uint8_t{ 8 };
|
||||
|
||||
// http://bittorrent.org/beps/bep_0005.html
|
||||
auto constexpr Port = uint8_t{ 9 };
|
||||
|
||||
// https://www.bittorrent.org/beps/bep_0006.html
|
||||
|
@ -197,7 +199,7 @@ static void pexPulse(evutil_socket_t fd, short what, void* vmsgs);
|
|||
static void protocolSendCancel(tr_peerMsgsImpl* msgs, struct peer_request const& req);
|
||||
static void protocolSendChoke(tr_peerMsgsImpl* msgs, bool choke);
|
||||
static void protocolSendHave(tr_peerMsgsImpl* msgs, tr_piece_index_t index);
|
||||
static void protocolSendPort(tr_peerMsgsImpl* msgs, uint16_t port);
|
||||
static void protocolSendPort(tr_peerMsgsImpl* msgs, tr_port port);
|
||||
static void sendInterest(tr_peerMsgsImpl* msgs, bool b);
|
||||
static void sendLtepHandshake(tr_peerMsgsImpl* msgs);
|
||||
static void tellPeerWhatWeHave(tr_peerMsgsImpl* msgs);
|
||||
|
@ -600,7 +602,7 @@ public:
|
|||
uint16_t pexCount = 0;
|
||||
uint16_t pexCount6 = 0;
|
||||
|
||||
tr_port dht_port = 0;
|
||||
tr_port dht_port;
|
||||
|
||||
EncryptionPreference encryption_preference = EncryptionPreference::Unknown;
|
||||
|
||||
|
@ -738,14 +740,14 @@ static void protocolSendCancel(tr_peerMsgsImpl* msgs, peer_request const& req)
|
|||
pokeBatchPeriod(msgs, ImmediatePriorityIntervalSecs);
|
||||
}
|
||||
|
||||
static void protocolSendPort(tr_peerMsgsImpl* msgs, uint16_t port)
|
||||
static void protocolSendPort(tr_peerMsgsImpl* msgs, tr_port port)
|
||||
{
|
||||
struct evbuffer* out = msgs->outMessages;
|
||||
|
||||
logtrace(msgs, fmt::format(FMT_STRING("sending Port {:d}"), port));
|
||||
logtrace(msgs, fmt::format(FMT_STRING("sending Port {:d}"), port.host()));
|
||||
evbuffer_add_uint32(out, 3);
|
||||
evbuffer_add_uint8(out, BtPeerMsgs::Port);
|
||||
evbuffer_add_uint16(out, port);
|
||||
evbuffer_add_uint16(out, port.network());
|
||||
}
|
||||
|
||||
static void protocolSendHave(tr_peerMsgsImpl* msgs, tr_piece_index_t index)
|
||||
|
@ -1045,7 +1047,7 @@ static void sendLtepHandshake(tr_peerMsgsImpl* msgs)
|
|||
// port number of the other side. Note that there is no need for the
|
||||
// receiving side of the connection to send this extension message,
|
||||
// since its port number is already known.
|
||||
tr_variantDictAddInt(&val, TR_KEY_p, tr_sessionGetPublicPeerPort(msgs->session));
|
||||
tr_variantDictAddInt(&val, TR_KEY_p, msgs->session->peerPort().host());
|
||||
|
||||
// http://bittorrent.org/beps/bep_0010.html
|
||||
// An integer, the number of outstanding request messages this
|
||||
|
@ -1171,7 +1173,7 @@ static void parseLtepHandshake(tr_peerMsgsImpl* msgs, uint32_t len, struct evbuf
|
|||
/* get peer's listening port */
|
||||
if (tr_variantDictFindInt(&val, TR_KEY_p, &i))
|
||||
{
|
||||
pex.port = htons((uint16_t)i);
|
||||
pex.port.setHost(i);
|
||||
msgs->publishClientGotPort(pex.port);
|
||||
logtrace(msgs, fmt::format(FMT_STRING("peer's port is now {:d}"), i));
|
||||
}
|
||||
|
@ -1747,14 +1749,23 @@ static ReadState readBtMessage(tr_peerMsgsImpl* msgs, struct evbuffer* inbuf, si
|
|||
break;
|
||||
|
||||
case BtPeerMsgs::Port:
|
||||
logtrace(msgs, "Got a BtPeerMsgs::Port");
|
||||
tr_peerIoReadUint16(msgs->io, inbuf, &msgs->dht_port);
|
||||
|
||||
if (msgs->dht_port > 0)
|
||||
// http://bittorrent.org/beps/bep_0005.html
|
||||
// Peers supporting the DHT set the last bit of the 8-byte reserved flags
|
||||
// exchanged in the BitTorrent protocol handshake. Peer receiving a handshake
|
||||
// indicating the remote peer supports the DHT should send a PORT message.
|
||||
// It begins with byte 0x09 and has a two byte payload containing the UDP
|
||||
// port of the DHT node in network byte order.
|
||||
{
|
||||
tr_dhtAddNode(msgs->session, tr_peerAddress(msgs), msgs->dht_port, false);
|
||||
}
|
||||
logtrace(msgs, "Got a BtPeerMsgs::Port");
|
||||
|
||||
auto nport = uint16_t{};
|
||||
tr_peerIoReadUint16(msgs->io, inbuf, &nport);
|
||||
if (auto const dht_port = tr_port::fromNetwork(nport); !std::empty(dht_port))
|
||||
{
|
||||
msgs->dht_port = dht_port;
|
||||
tr_dhtAddNode(msgs->session, tr_peerAddress(msgs), msgs->dht_port, false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case BtPeerMsgs::FextSuggest:
|
||||
|
|
|
@ -92,8 +92,8 @@ static void natPulse(tr_shared* s, bool do_check)
|
|||
session->private_peer_port = received_private_port;
|
||||
tr_logAddInfo(fmt::format(
|
||||
_("Mapped private port {private_port} to public port {public_port}"),
|
||||
fmt::arg("public_port", session->public_peer_port),
|
||||
fmt::arg("private_port", session->private_peer_port)));
|
||||
fmt::arg("public_port", session->public_peer_port.host()),
|
||||
fmt::arg("private_port", session->private_peer_port.host())));
|
||||
}
|
||||
|
||||
s->upnpStatus = tr_upnpPulse(
|
||||
|
|
|
@ -9,15 +9,10 @@
|
|||
#error only libtransmission should #include this header.
|
||||
#endif
|
||||
|
||||
#include "transmission.h"
|
||||
|
||||
/**
|
||||
* @addtogroup port_forwarding Port Forwarding
|
||||
* @{
|
||||
*/
|
||||
#include "net.h" // tr_port
|
||||
|
||||
struct tr_bindsockets;
|
||||
|
||||
struct tr_session;
|
||||
struct tr_shared;
|
||||
|
||||
tr_shared* tr_sharedInit(tr_session*);
|
||||
|
@ -33,5 +28,3 @@ tr_port tr_sharedGetPeerPort(tr_shared const* s);
|
|||
bool tr_sharedTraversalIsEnabled(tr_shared const* s);
|
||||
|
||||
int tr_sharedTraversalStatus(tr_shared const*);
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -605,14 +605,13 @@ static char const* tr_rpc_address_to_string(tr_rpc_address const& addr, char* bu
|
|||
|
||||
static std::string tr_rpc_address_with_port(tr_rpc_server const* server)
|
||||
{
|
||||
|
||||
char addr_buf[TrUnixAddrStrLen];
|
||||
tr_rpc_address_to_string(*server->bindAddress, addr_buf, sizeof(addr_buf));
|
||||
|
||||
std::string addr_port_str{ addr_buf };
|
||||
if (server->bindAddress->type != TR_RPC_AF_UNIX)
|
||||
{
|
||||
addr_port_str.append(":" + std::to_string(tr_rpcGetPort(server)));
|
||||
addr_port_str.append(":" + std::to_string(server->port().host()));
|
||||
}
|
||||
return addr_port_str;
|
||||
}
|
||||
|
@ -740,11 +739,11 @@ static void startServer(tr_rpc_server* server)
|
|||
|
||||
char const* address = tr_rpcGetBindAddress(server);
|
||||
|
||||
tr_port const port = server->port;
|
||||
auto const port = server->port();
|
||||
|
||||
bool const success = server->bindAddress->type == TR_RPC_AF_UNIX ?
|
||||
bindUnixSocket(base, httpd, address, server->rpc_socket_mode) :
|
||||
(evhttp_bind_socket(httpd, address, port) != -1);
|
||||
(evhttp_bind_socket(httpd, address, port.host()) != -1);
|
||||
|
||||
auto const addr_port_str = tr_rpc_address_with_port(server);
|
||||
|
||||
|
@ -840,24 +839,19 @@ static void restartServer(tr_rpc_server* const server)
|
|||
}
|
||||
}
|
||||
|
||||
void tr_rpcSetPort(tr_rpc_server* server, tr_port port)
|
||||
void tr_rpc_server::setPort(tr_port port) noexcept
|
||||
{
|
||||
TR_ASSERT(server != nullptr);
|
||||
|
||||
if (server->port != port)
|
||||
if (port_ == port)
|
||||
{
|
||||
server->port = port;
|
||||
|
||||
if (server->isEnabled)
|
||||
{
|
||||
tr_runInEventThread(server->session, restartServer, server);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
tr_port tr_rpcGetPort(tr_rpc_server const* server)
|
||||
{
|
||||
return server->port;
|
||||
port_ = port;
|
||||
|
||||
if (isEnabled)
|
||||
{
|
||||
tr_runInEventThread(session, restartServer, this);
|
||||
}
|
||||
}
|
||||
|
||||
void tr_rpcSetUrl(tr_rpc_server* server, std::string_view url)
|
||||
|
@ -1048,7 +1042,7 @@ tr_rpc_server::tr_rpc_server(tr_session* session_in, tr_variant* settings)
|
|||
}
|
||||
else
|
||||
{
|
||||
this->port = (tr_port)i;
|
||||
this->port_.setHost(i);
|
||||
}
|
||||
|
||||
key = TR_KEY_rpc_url;
|
||||
|
|
|
@ -35,6 +35,13 @@ public:
|
|||
tr_rpc_server& operator=(tr_rpc_server&) = delete;
|
||||
tr_rpc_server& operator=(tr_rpc_server&&) = delete;
|
||||
|
||||
[[nodiscard]] constexpr tr_port port() const noexcept
|
||||
{
|
||||
return port_;
|
||||
}
|
||||
|
||||
void setPort(tr_port) noexcept;
|
||||
|
||||
std::shared_ptr<libdeflate_compressor> compressor;
|
||||
|
||||
std::list<std::string> hostWhitelist;
|
||||
|
@ -56,7 +63,7 @@ public:
|
|||
static int constexpr DefaultRpcSocketMode = 0750;
|
||||
int rpc_socket_mode = DefaultRpcSocketMode;
|
||||
|
||||
tr_port port = 0;
|
||||
tr_port port_;
|
||||
|
||||
bool isAntiBruteForceEnabled = false;
|
||||
bool isEnabled = false;
|
||||
|
@ -69,10 +76,6 @@ void tr_rpcSetEnabled(tr_rpc_server* server, bool isEnabled);
|
|||
|
||||
bool tr_rpcIsEnabled(tr_rpc_server const* server);
|
||||
|
||||
void tr_rpcSetPort(tr_rpc_server* server, tr_port port);
|
||||
|
||||
tr_port tr_rpcGetPort(tr_rpc_server const* server);
|
||||
|
||||
void tr_rpcSetUrl(tr_rpc_server* server, std::string_view url);
|
||||
|
||||
std::string const& tr_rpcGetUrl(tr_rpc_server const* server);
|
||||
|
|
|
@ -1381,8 +1381,8 @@ static char const* portTest(
|
|||
tr_variant* /*args_out*/,
|
||||
struct tr_rpc_idle_data* idle_data)
|
||||
{
|
||||
auto const port = tr_sessionGetPeerPort(session);
|
||||
auto const url = fmt::format(FMT_STRING("https://portcheck.transmissionbt.com/{:d}"), port);
|
||||
auto const port = session->peerPort();
|
||||
auto const url = fmt::format(FMT_STRING("https://portcheck.transmissionbt.com/{:d}"), port.host());
|
||||
session->web->fetch({ url, onPortTested, idle_data });
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -1943,7 +1943,7 @@ static char const* sessionSet(
|
|||
|
||||
if (tr_variantDictFindInt(args_in, TR_KEY_peer_port, &i))
|
||||
{
|
||||
tr_sessionSetPeerPort(session, i);
|
||||
session->setPeerPort(tr_port::fromHost(i));
|
||||
}
|
||||
|
||||
if (tr_variantDictFindBool(args_in, TR_KEY_port_forwarding_enabled, &boolVal))
|
||||
|
@ -2222,7 +2222,7 @@ static void addSessionField(tr_session* s, tr_variant* d, tr_quark key)
|
|||
break;
|
||||
|
||||
case TR_KEY_peer_port:
|
||||
tr_variantDictAddInt(d, key, tr_sessionGetPeerPort(s));
|
||||
tr_variantDictAddInt(d, key, s->peerPort().host());
|
||||
break;
|
||||
|
||||
case TR_KEY_peer_port_random_on_start:
|
||||
|
|
|
@ -86,7 +86,10 @@ static auto constexpr BandwidthGroupsFilename = "bandwidth-groups.json"sv;
|
|||
|
||||
static tr_port getRandomPort(tr_session const* s)
|
||||
{
|
||||
return tr_port(tr_rand_int_weak(s->randomPortHigh - s->randomPortLow + 1) + s->randomPortLow);
|
||||
auto const lower = std::min(s->randomPortLow.host(), s->randomPortHigh.host());
|
||||
auto const upper = std::max(s->randomPortLow.host(), s->randomPortHigh.host());
|
||||
auto const range = upper - lower;
|
||||
return tr_port::fromHost(lower + tr_rand_int_weak(range + 1));
|
||||
}
|
||||
|
||||
/* Generate a peer id : "-TRxyzb-" + 12 random alphanumeric
|
||||
|
@ -421,10 +424,10 @@ void tr_sessionGetSettings(tr_session const* s, tr_variant* d)
|
|||
tr_variantDictAddInt(d, TR_KEY_message_level, tr_logGetLevel());
|
||||
tr_variantDictAddInt(d, TR_KEY_peer_limit_global, s->peerLimit);
|
||||
tr_variantDictAddInt(d, TR_KEY_peer_limit_per_torrent, s->peerLimitPerTorrent);
|
||||
tr_variantDictAddInt(d, TR_KEY_peer_port, tr_sessionGetPeerPort(s));
|
||||
tr_variantDictAddInt(d, TR_KEY_peer_port, s->peerPort().host());
|
||||
tr_variantDictAddBool(d, TR_KEY_peer_port_random_on_start, s->isPortRandom);
|
||||
tr_variantDictAddInt(d, TR_KEY_peer_port_random_low, s->randomPortLow);
|
||||
tr_variantDictAddInt(d, TR_KEY_peer_port_random_high, s->randomPortHigh);
|
||||
tr_variantDictAddInt(d, TR_KEY_peer_port_random_low, s->randomPortLow.host());
|
||||
tr_variantDictAddInt(d, TR_KEY_peer_port_random_high, s->randomPortHigh.host());
|
||||
tr_variantDictAddStr(d, TR_KEY_peer_socket_tos, tr_netTosToName(s->peer_socket_tos_));
|
||||
tr_variantDictAddStr(d, TR_KEY_peer_congestion_algorithm, s->peerCongestionAlgorithm());
|
||||
tr_variantDictAddBool(d, TR_KEY_pex_enabled, s->isPexEnabled);
|
||||
|
@ -975,12 +978,12 @@ static void sessionSetImpl(struct init_data* const data)
|
|||
/* incoming peer port */
|
||||
if (tr_variantDictFindInt(settings, TR_KEY_peer_port_random_low, &i))
|
||||
{
|
||||
session->randomPortLow = i;
|
||||
session->randomPortLow.setHost(i);
|
||||
}
|
||||
|
||||
if (tr_variantDictFindInt(settings, TR_KEY_peer_port_random_high, &i))
|
||||
{
|
||||
session->randomPortHigh = i;
|
||||
session->randomPortHigh.setHost(i);
|
||||
}
|
||||
|
||||
if (tr_variantDictFindBool(settings, TR_KEY_peer_port_random_on_start, &boolVal))
|
||||
|
@ -988,12 +991,16 @@ static void sessionSetImpl(struct init_data* const data)
|
|||
tr_sessionSetPeerPortRandomOnStart(session, boolVal);
|
||||
}
|
||||
|
||||
if (!tr_variantDictFindInt(settings, TR_KEY_peer_port, &i))
|
||||
{
|
||||
i = session->private_peer_port;
|
||||
}
|
||||
auto peer_port = session->private_peer_port;
|
||||
|
||||
setPeerPort(session, boolVal ? getRandomPort(session) : i);
|
||||
if (auto port = int64_t{}; tr_variantDictFindInt(settings, TR_KEY_peer_port, &port))
|
||||
{
|
||||
peer_port.setHost(static_cast<uint16_t>(port));
|
||||
}
|
||||
|
||||
setPeerPort(session, boolVal ? getRandomPort(session) : peer_port);
|
||||
}
|
||||
|
||||
if (tr_variantDictFindBool(settings, TR_KEY_port_forwarding_enabled, &boolVal))
|
||||
{
|
||||
|
@ -1244,25 +1251,25 @@ static void setPeerPort(tr_session* session, tr_port port)
|
|||
tr_runInEventThread(session, peerPortChanged, session);
|
||||
}
|
||||
|
||||
void tr_sessionSetPeerPort(tr_session* session, tr_port port)
|
||||
void tr_sessionSetPeerPort(tr_session* session, uint16_t hport)
|
||||
{
|
||||
if (tr_isSession(session) && session->private_peer_port != port)
|
||||
if (auto const port = tr_port::fromHost(hport); tr_isSession(session) && session->private_peer_port != port)
|
||||
{
|
||||
setPeerPort(session, port);
|
||||
}
|
||||
}
|
||||
|
||||
tr_port tr_sessionGetPeerPort(tr_session const* session)
|
||||
uint16_t tr_sessionGetPeerPort(tr_session const* session)
|
||||
{
|
||||
return tr_isSession(session) ? session->public_peer_port : 0;
|
||||
return tr_isSession(session) ? session->public_peer_port.host() : 0U;
|
||||
}
|
||||
|
||||
tr_port tr_sessionSetPeerPortRandom(tr_session* session)
|
||||
uint16_t tr_sessionSetPeerPortRandom(tr_session* session)
|
||||
{
|
||||
TR_ASSERT(tr_isSession(session));
|
||||
|
||||
tr_sessionSetPeerPort(session, getRandomPort(session));
|
||||
return session->private_peer_port;
|
||||
session->setPeerPort(getRandomPort(session));
|
||||
return session->private_peer_port.host();
|
||||
}
|
||||
|
||||
void tr_sessionSetPeerPortRandomOnStart(tr_session* session, bool random)
|
||||
|
@ -2555,18 +2562,21 @@ bool tr_sessionIsRPCEnabled(tr_session const* session)
|
|||
return tr_rpcIsEnabled(session->rpc_server_.get());
|
||||
}
|
||||
|
||||
void tr_sessionSetRPCPort(tr_session* session, tr_port port)
|
||||
void tr_sessionSetRPCPort(tr_session* session, uint16_t hport)
|
||||
{
|
||||
TR_ASSERT(tr_isSession(session));
|
||||
|
||||
tr_rpcSetPort(session->rpc_server_.get(), port);
|
||||
if (session->rpc_server_)
|
||||
{
|
||||
session->rpc_server_->setPort(tr_port::fromHost(hport));
|
||||
}
|
||||
}
|
||||
|
||||
tr_port tr_sessionGetRPCPort(tr_session const* session)
|
||||
uint16_t tr_sessionGetRPCPort(tr_session const* session)
|
||||
{
|
||||
TR_ASSERT(tr_isSession(session));
|
||||
|
||||
return tr_rpcGetPort(session->rpc_server_.get());
|
||||
return session->rpc_server_ ? session->rpc_server_->port().host() : uint16_t{};
|
||||
}
|
||||
|
||||
void tr_sessionSetRPCUrl(tr_session* session, char const* url)
|
||||
|
|
|
@ -337,6 +337,16 @@ public:
|
|||
*/
|
||||
tr_port public_peer_port;
|
||||
|
||||
[[nodiscard]] constexpr auto peerPort() const noexcept
|
||||
{
|
||||
return public_peer_port;
|
||||
}
|
||||
|
||||
constexpr auto setPeerPort(tr_port port) noexcept
|
||||
{
|
||||
public_peer_port = port;
|
||||
}
|
||||
|
||||
tr_port randomPortLow;
|
||||
tr_port randomPortHigh;
|
||||
|
||||
|
@ -426,11 +436,6 @@ private:
|
|||
bool incomplete_dir_enabled_ = false;
|
||||
};
|
||||
|
||||
constexpr tr_port tr_sessionGetPublicPeerPort(tr_session const* session)
|
||||
{
|
||||
return session->public_peer_port;
|
||||
}
|
||||
|
||||
bool tr_sessionAllowsDHT(tr_session const* session);
|
||||
|
||||
bool tr_sessionAllowsLPD(tr_session const* session);
|
||||
|
|
|
@ -687,12 +687,12 @@ static bool isNewTorrentASeed(tr_torrent* tor)
|
|||
|
||||
static void torrentInit(tr_torrent* tor, tr_ctor const* ctor)
|
||||
{
|
||||
auto const lock = tor->unique_lock();
|
||||
|
||||
tr_session* session = tr_ctorGetSession(ctor);
|
||||
TR_ASSERT(session != nullptr);
|
||||
|
||||
tor->session = session;
|
||||
|
||||
auto const lock = tor->unique_lock();
|
||||
|
||||
tor->queuePosition = tr_sessionCountTorrents(session);
|
||||
|
||||
torrentInitFromInfoDict(tor);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <cstring> /* memcpy(), memset(), memchr(), strlen() */
|
||||
#include <ctime>
|
||||
#include <fstream>
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
@ -106,7 +107,7 @@ static void bootstrap_from_name(char const* name, tr_port port, int af)
|
|||
hints.ai_family = af;
|
||||
|
||||
auto port_str = std::array<char, 16>{};
|
||||
*fmt::format_to(std::data(port_str), FMT_STRING("{:d}"), port) = '\0';
|
||||
*fmt::format_to(std::data(port_str), FMT_STRING("{:d}"), port.host()) = '\0';
|
||||
|
||||
addrinfo* info = nullptr;
|
||||
if (int const rc = getaddrinfo(name, std::data(port_str), &hints, &info); rc != 0)
|
||||
|
@ -114,7 +115,7 @@ static void bootstrap_from_name(char const* name, tr_port port, int af)
|
|||
tr_logAddWarn(fmt::format(
|
||||
_("Couldn't look up '{address}:{port}': {error} ({error_code})"),
|
||||
fmt::arg("address", name),
|
||||
fmt::arg("port", port),
|
||||
fmt::arg("port", port.host()),
|
||||
fmt::arg("error", gai_strerror(rc)),
|
||||
fmt::arg("error_code", rc)));
|
||||
return;
|
||||
|
@ -160,16 +161,16 @@ static void dht_boostrap_from_file(tr_session* session)
|
|||
{
|
||||
auto line_stream = std::istringstream{ line };
|
||||
auto addrstr = std::string{};
|
||||
auto port = tr_port{};
|
||||
line_stream >> addrstr >> port;
|
||||
auto hport = uint16_t{};
|
||||
line_stream >> addrstr >> hport;
|
||||
|
||||
if (line_stream.bad() || std::empty(addrstr) || port <= 0)
|
||||
if (line_stream.bad() || std::empty(addrstr))
|
||||
{
|
||||
tr_logAddWarn(fmt::format(_("Couldn't parse line: '{line}'"), fmt::arg("line", line)));
|
||||
}
|
||||
else
|
||||
{
|
||||
bootstrap_from_name(addrstr.c_str(), port, bootstrap_af(session_));
|
||||
bootstrap_from_name(addrstr.c_str(), tr_port::fromHost(hport), bootstrap_af(session_));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -199,27 +200,21 @@ static void dht_bootstrap(void* closure)
|
|||
{
|
||||
if (i < num && !bootstrap_done(cl->session, AF_INET))
|
||||
{
|
||||
auto port = tr_port{};
|
||||
auto addr = tr_address{};
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.type = TR_AF_INET;
|
||||
memcpy(&addr.addr.addr4, &cl->nodes[i * 6], 4);
|
||||
memcpy(&port, &cl->nodes[i * 6 + 4], 2);
|
||||
port = ntohs(port);
|
||||
auto const [port, out] = tr_port::fromCompact(&cl->nodes[i * 6 + 4]);
|
||||
tr_dhtAddNode(cl->session, &addr, port, true);
|
||||
}
|
||||
|
||||
if (i < num6 && !bootstrap_done(cl->session, AF_INET6))
|
||||
{
|
||||
auto port = tr_port{};
|
||||
auto addr = tr_address{};
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.type = TR_AF_INET6;
|
||||
memcpy(&addr.addr.addr6, &cl->nodes6[i * 18], 16);
|
||||
memcpy(&port, &cl->nodes6[i * 18 + 16], 2);
|
||||
port = ntohs(port);
|
||||
auto const [port, out] = tr_port::fromCompact(&cl->nodes6[i * 18 + 16]);
|
||||
tr_dhtAddNode(cl->session, &addr, port, true);
|
||||
}
|
||||
|
||||
|
@ -266,7 +261,7 @@ static void dht_bootstrap(void* closure)
|
|||
tr_logAddDebug("Attempting bootstrap from dht.transmissionbt.com");
|
||||
}
|
||||
|
||||
bootstrap_from_name("dht.transmissionbt.com", 6881, bootstrap_af(session_));
|
||||
bootstrap_from_name("dht.transmissionbt.com", tr_port::fromHost(6881), bootstrap_af(session_));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -532,7 +527,7 @@ int tr_dhtStatus(tr_session* session, int af, int* nodes_return)
|
|||
|
||||
tr_port tr_dhtPort(tr_session* ss)
|
||||
{
|
||||
return tr_dhtEnabled(ss) ? ss->udp_port : 0;
|
||||
return tr_dhtEnabled(ss) ? ss->udp_port : tr_port{};
|
||||
}
|
||||
|
||||
bool tr_dhtAddNode(tr_session* ss, tr_address const* address, tr_port port, bool bootstrap)
|
||||
|
@ -558,7 +553,7 @@ bool tr_dhtAddNode(tr_session* ss, tr_address const* address, tr_port port, bool
|
|||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
memcpy(&sin.sin_addr, &address->addr.addr4, 4);
|
||||
sin.sin_port = htons(port);
|
||||
sin.sin_port = port.network();
|
||||
dht_ping_node((struct sockaddr*)&sin, sizeof(sin));
|
||||
return true;
|
||||
}
|
||||
|
@ -569,7 +564,7 @@ bool tr_dhtAddNode(tr_session* ss, tr_address const* address, tr_port port, bool
|
|||
memset(&sin6, 0, sizeof(sin6));
|
||||
sin6.sin6_family = AF_INET6;
|
||||
memcpy(&sin6.sin6_addr, &address->addr.addr6, 16);
|
||||
sin6.sin6_port = htons(port);
|
||||
sin6.sin6_port = port.network();
|
||||
dht_ping_node((struct sockaddr*)&sin6, sizeof(sin6));
|
||||
return true;
|
||||
}
|
||||
|
@ -673,7 +668,8 @@ static AnnounceResult tr_dhtAnnounce(tr_torrent* tor, int af, bool announce)
|
|||
}
|
||||
|
||||
auto const* dht_hash = reinterpret_cast<unsigned char const*>(std::data(tor->infoHash()));
|
||||
int const rc = dht_search(dht_hash, announce ? tr_sessionGetPeerPort(session_) : 0, af, callback, nullptr);
|
||||
auto const hport = announce ? session_->peerPort().host() : 0;
|
||||
int const rc = dht_search(dht_hash, hport, af, callback, nullptr);
|
||||
if (rc < 0)
|
||||
{
|
||||
auto const error_code = errno;
|
||||
|
|
|
@ -23,7 +23,7 @@ using in_port_t = uint16_t; /* all missing */
|
|||
#include <event2/event.h>
|
||||
#include <event2/util.h>
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "transmission.h"
|
||||
|
||||
|
@ -263,9 +263,8 @@ int tr_lpdInit(tr_session* ss, tr_address* /*tr_addr*/)
|
|||
TR_ASSERT(lpd_announceInterval > 0);
|
||||
TR_ASSERT(lpd_announceScope > 0);
|
||||
|
||||
lpd_port = tr_sessionGetPeerPort(ss);
|
||||
|
||||
if (lpd_port <= 0)
|
||||
lpd_port = ss->peerPort();
|
||||
if (std::empty(lpd_port))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
@ -438,7 +437,7 @@ bool tr_lpdSendAnnounce(tr_torrent const* t)
|
|||
1,
|
||||
lpd_mcastGroup,
|
||||
lpd_mcastPort,
|
||||
lpd_port,
|
||||
lpd_port.host(),
|
||||
tr_strupper(t->infoHashString()));
|
||||
|
||||
// send the query out using [lpd_socket2]
|
||||
|
@ -484,7 +483,6 @@ static int tr_lpdConsiderAnnounce(tr_pex* peer, char const* const msg)
|
|||
char value[MaxValueLen] = { 0 };
|
||||
char hashString[MaxHashLen] = { 0 };
|
||||
int res = 0;
|
||||
int peerPort = 0;
|
||||
|
||||
if (peer != nullptr && msg != nullptr)
|
||||
{
|
||||
|
@ -505,12 +503,13 @@ static int tr_lpdConsiderAnnounce(tr_pex* peer, char const* const msg)
|
|||
}
|
||||
|
||||
/* determine announced peer port, refuse if value too large */
|
||||
if (sscanf(value, "%d", &peerPort) != 1 || peerPort > (in_port_t)-1)
|
||||
int peer_port = 0;
|
||||
if (sscanf(value, "%d", &peer_port) != 1 || peer_port > (in_port_t)-1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
peer->port = htons(peerPort);
|
||||
peer->port.setHost(peer_port);
|
||||
res = -1; /* signal caller side-effect to peer->port via return != 0 */
|
||||
|
||||
if (!lpd_extractParam(params, "Infohash", MaxHashLen, hashString))
|
||||
|
@ -524,14 +523,16 @@ static int tr_lpdConsiderAnnounce(tr_pex* peer, char const* const msg)
|
|||
{
|
||||
/* we found a suitable peer, add it to the torrent */
|
||||
tr_peerMgrAddPex(tor, TR_PEER_FROM_LPD, peer, 1);
|
||||
tr_logAddDebugTor(tor, fmt::format("Found a local peer from LPD ({})", peer->addr.to_string(peerPort)));
|
||||
tr_logAddDebugTor(
|
||||
tor,
|
||||
fmt::format(FMT_STRING("Found a local peer from LPD ({:s})"), peer->addr.to_string(peer->port)));
|
||||
|
||||
/* periodic reconnectPulse() deals with the rest... */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
tr_logAddDebug(fmt::format("Cannot serve torrent #{}", hashString));
|
||||
tr_logAddDebug(fmt::format(FMT_STRING("Cannot serve torrent #{:s}"), hashString));
|
||||
}
|
||||
|
||||
return res;
|
||||
|
|
|
@ -161,7 +161,7 @@ static void rebind_ipv6(tr_session* ss, bool force)
|
|||
memcpy(&sin6.sin6_addr, ipv6, 16);
|
||||
}
|
||||
|
||||
sin6.sin6_port = htons(ss->udp_port);
|
||||
sin6.sin6_port = ss->udp_port.network();
|
||||
|
||||
rc = bind(s, (struct sockaddr*)&sin6, sizeof(sin6));
|
||||
|
||||
|
@ -277,9 +277,8 @@ void tr_udpInit(tr_session* ss)
|
|||
TR_ASSERT(ss->udp_socket == TR_BAD_SOCKET);
|
||||
TR_ASSERT(ss->udp6_socket == TR_BAD_SOCKET);
|
||||
|
||||
ss->udp_port = tr_sessionGetPeerPort(ss);
|
||||
|
||||
if (ss->udp_port <= 0)
|
||||
ss->udp_port = ss->peerPort();
|
||||
if (std::empty(ss->udp_port))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -302,7 +301,7 @@ void tr_udpInit(tr_session* ss)
|
|||
memcpy(&sin.sin_addr, &public_addr->addr.addr4, sizeof(struct in_addr));
|
||||
}
|
||||
|
||||
sin.sin_port = htons(ss->udp_port);
|
||||
sin.sin_port = ss->udp_port.network();
|
||||
int const rc = bind(ss->udp_socket, (struct sockaddr*)&sin, sizeof(sin));
|
||||
|
||||
if (rc == -1)
|
||||
|
|
|
@ -85,7 +85,7 @@ static void incoming(void* vsession, struct UTPSocket* s)
|
|||
auto* const from = (struct sockaddr*)&from_storage;
|
||||
socklen_t fromlen = sizeof(from_storage);
|
||||
tr_address addr;
|
||||
tr_port port = 0;
|
||||
tr_port port;
|
||||
|
||||
if (!tr_sessionIsUTPEnabled(session))
|
||||
{
|
||||
|
|
|
@ -32,7 +32,6 @@ using tr_piece_index_t = uint32_t;
|
|||
/* Assuming a 16 KiB block (tr_block_info::BlockSize), a 32-bit block index gives us a maximum torrent size of 64 TiB.
|
||||
* When we ever need to grow past that, change tr_block_index_t and tr_piece_index_t to uint64_t. */
|
||||
using tr_block_index_t = uint32_t;
|
||||
using tr_port = uint16_t;
|
||||
using tr_tracker_tier_t = uint32_t;
|
||||
using tr_tracker_id_t = uint32_t;
|
||||
using tr_byte_index_t = uint64_t;
|
||||
|
@ -329,12 +328,12 @@ bool tr_sessionIsRPCEnabled(tr_session const* session);
|
|||
/** @brief Specify which port to listen for RPC requests on.
|
||||
@see tr_sessionInit()
|
||||
@see tr_sessionGetRPCPort */
|
||||
void tr_sessionSetRPCPort(tr_session* session, tr_port port);
|
||||
void tr_sessionSetRPCPort(tr_session* session, uint16_t port);
|
||||
|
||||
/** @brief Get which port to listen for RPC requests on.
|
||||
@see tr_sessionInit()
|
||||
@see tr_sessionSetRPCPort */
|
||||
tr_port tr_sessionGetRPCPort(tr_session const* session);
|
||||
uint16_t tr_sessionGetRPCPort(tr_session const* session);
|
||||
|
||||
/**
|
||||
* @brief Specify which base URL to use.
|
||||
|
@ -491,11 +490,11 @@ void tr_sessionSetPortForwardingEnabled(tr_session* session, bool enabled);
|
|||
|
||||
bool tr_sessionIsPortForwardingEnabled(tr_session const* session);
|
||||
|
||||
void tr_sessionSetPeerPort(tr_session* session, tr_port port);
|
||||
void tr_sessionSetPeerPort(tr_session* session, uint16_t port);
|
||||
|
||||
tr_port tr_sessionGetPeerPort(tr_session const* session);
|
||||
uint16_t tr_sessionGetPeerPort(tr_session const* session);
|
||||
|
||||
tr_port tr_sessionSetPeerPortRandom(tr_session* session);
|
||||
uint16_t tr_sessionSetPeerPortRandom(tr_session* session);
|
||||
|
||||
void tr_sessionSetPeerPortRandomOnStart(tr_session* session, bool random);
|
||||
|
||||
|
@ -1262,7 +1261,7 @@ struct tr_peer_stat
|
|||
bool isIncoming;
|
||||
|
||||
uint8_t from;
|
||||
tr_port port;
|
||||
uint16_t port;
|
||||
|
||||
char addr[TR_INET6_ADDRSTRLEN];
|
||||
char flagStr[32];
|
||||
|
|
|
@ -79,7 +79,7 @@ struct tr_upnp
|
|||
bool hasDiscovered = false;
|
||||
UPNPUrls urls = {};
|
||||
IGDdatas data = {};
|
||||
int port = -1;
|
||||
tr_port port;
|
||||
char lanaddr[16] = {};
|
||||
bool isMapped = false;
|
||||
UpnpState state = UpnpState::WILL_DISCOVER;
|
||||
|
@ -144,7 +144,7 @@ static int tr_upnpGetSpecificPortMappingEntry(tr_upnp* handle, char const* proto
|
|||
*intClient = '\0';
|
||||
*intPort = '\0';
|
||||
|
||||
auto const port_str = fmt::format(FMT_STRING("{:d}"), handle->port);
|
||||
auto const port_str = fmt::format(FMT_STRING("{:d}"), handle->port.host());
|
||||
|
||||
#if (MINIUPNPC_API_VERSION >= 10) /* adds remoteHost arg */
|
||||
int const err = UPNP_GetSpecificPortMappingEntry(
|
||||
|
@ -187,7 +187,7 @@ static int tr_upnpAddPortMapping(tr_upnp const* handle, char const* proto, tr_po
|
|||
int const old_errno = errno;
|
||||
errno = 0;
|
||||
|
||||
auto const port_str = fmt::format(FMT_STRING("{:d}"), port);
|
||||
auto const port_str = fmt::format(FMT_STRING("{:d}"), port.host());
|
||||
|
||||
#if (MINIUPNPC_API_VERSION >= 8)
|
||||
int err = UPNP_AddPortMapping(
|
||||
|
@ -223,7 +223,7 @@ static int tr_upnpAddPortMapping(tr_upnp const* handle, char const* proto, tr_po
|
|||
|
||||
static void tr_upnpDeletePortMapping(tr_upnp const* handle, char const* proto, tr_port port)
|
||||
{
|
||||
auto const port_str = fmt::format(FMT_STRING("{:d}"), port);
|
||||
auto const port_str = fmt::format(FMT_STRING("{:d}"), port.host());
|
||||
|
||||
UPNP_DeletePortMapping(handle->urls.controlURL, handle->data.first.servicetype, port_str.c_str(), proto, nullptr);
|
||||
}
|
||||
|
@ -300,7 +300,7 @@ tr_port_forwarding tr_upnpPulse(tr_upnp* handle, tr_port port, bool isEnabled, b
|
|||
((tr_upnpGetSpecificPortMappingEntry(handle, "TCP") != UPNPCOMMAND_SUCCESS) ||
|
||||
(tr_upnpGetSpecificPortMappingEntry(handle, "UDP") != UPNPCOMMAND_SUCCESS)))
|
||||
{
|
||||
tr_logAddInfo(fmt::format(_("Port {port} is not forwarded"), fmt::arg("port", handle->port)));
|
||||
tr_logAddInfo(fmt::format(_("Port {port} is not forwarded"), fmt::arg("port", handle->port.host())));
|
||||
handle->isMapped = false;
|
||||
}
|
||||
|
||||
|
@ -316,7 +316,7 @@ tr_port_forwarding tr_upnpPulse(tr_upnp* handle, tr_port port, bool isEnabled, b
|
|||
|
||||
handle->isMapped = false;
|
||||
handle->state = UpnpState::IDLE;
|
||||
handle->port = -1;
|
||||
handle->port = {};
|
||||
}
|
||||
|
||||
if ((handle->state == UpnpState::IDLE) && isEnabled && !handle->isMapped)
|
||||
|
@ -334,7 +334,7 @@ tr_port_forwarding tr_upnpPulse(tr_upnp* handle, tr_port port, bool isEnabled, b
|
|||
}
|
||||
else
|
||||
{
|
||||
auto const desc = fmt::format(FMT_STRING("{:s} at {:d}"), TR_NAME, port);
|
||||
auto const desc = fmt::format(FMT_STRING("{:s} at {:d}"), TR_NAME, port.host());
|
||||
int const err_tcp = tr_upnpAddPortMapping(handle, "TCP", port, desc.c_str());
|
||||
int const err_udp = tr_upnpAddPortMapping(handle, "UDP", port, desc.c_str());
|
||||
|
||||
|
@ -346,18 +346,18 @@ tr_port_forwarding tr_upnpPulse(tr_upnp* handle, tr_port port, bool isEnabled, b
|
|||
fmt::arg("url", handle->urls.controlURL),
|
||||
fmt::arg("type", handle->data.first.servicetype),
|
||||
fmt::arg("address", handle->lanaddr),
|
||||
fmt::arg("port", port)));
|
||||
fmt::arg("port", port.host())));
|
||||
|
||||
if (handle->isMapped)
|
||||
{
|
||||
tr_logAddInfo(fmt::format(_("Port {port} is forwarded"), fmt::arg("port", port)));
|
||||
tr_logAddInfo(fmt::format(_("Port {port} is forwarded"), fmt::arg("port", port.host())));
|
||||
handle->port = port;
|
||||
handle->state = UpnpState::IDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
tr_logAddInfo(_("If your router supports UPnP, please make sure UPnP is enabled!"));
|
||||
handle->port = -1;
|
||||
handle->port = {};
|
||||
handle->state = UpnpState::FAILED;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -203,7 +203,8 @@ auto parsePort(std::string_view port_sv)
|
|||
{
|
||||
auto const port = tr_parseNum<int>(port_sv);
|
||||
|
||||
return port && *port >= std::numeric_limits<tr_port>::min() && *port <= std::numeric_limits<tr_port>::max() ? *port : -1;
|
||||
using PortLimits = std::numeric_limits<uint16_t>;
|
||||
return port && PortLimits::min() <= *port && *port <= PortLimits::max() ? *port : -1;
|
||||
}
|
||||
|
||||
constexpr std::string_view getPortForScheme(std::string_view scheme)
|
||||
|
|
|
@ -450,7 +450,7 @@
|
|||
|
||||
- (void)setPort:(id)sender
|
||||
{
|
||||
tr_port const port = [sender intValue];
|
||||
uint16_t const port = [sender intValue];
|
||||
[self.fDefaults setInteger:port forKey:@"BindPort"];
|
||||
tr_sessionSetPeerPort(self.fHandle, port);
|
||||
|
||||
|
@ -460,7 +460,7 @@
|
|||
|
||||
- (void)randomPort:(id)sender
|
||||
{
|
||||
tr_port const port = tr_sessionSetPeerPortRandom(self.fHandle);
|
||||
auto const port = tr_sessionSetPeerPortRandom(self.fHandle);
|
||||
[self.fDefaults setInteger:port forKey:@"BindPort"];
|
||||
self.fPortField.intValue = port;
|
||||
|
||||
|
@ -1392,7 +1392,7 @@
|
|||
[self.fDefaults setBool:autoStart forKey:@"AutoStartDownload"];
|
||||
|
||||
//port
|
||||
tr_port const port = tr_sessionGetPeerPort(self.fHandle);
|
||||
auto const port = tr_sessionGetPeerPort(self.fHandle);
|
||||
[self.fDefaults setInteger:port forKey:@"BindPort"];
|
||||
|
||||
BOOL const nat = tr_sessionIsPortForwardingEnabled(self.fHandle);
|
||||
|
|
|
@ -244,7 +244,7 @@ void Session::updatePref(int key)
|
|||
case Prefs::RPC_PORT:
|
||||
if (session_ != nullptr)
|
||||
{
|
||||
tr_sessionSetRPCPort(session_, static_cast<tr_port>(prefs_.getInt(key)));
|
||||
tr_sessionSetRPCPort(session_, static_cast<uint16_t>(prefs_.getInt(key)));
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue