refactor: add a tr_port safety class (#2952)

This commit is contained in:
Charles Kerr 2022-04-21 10:58:13 -05:00 committed by GitHub
parent bdac708762
commit 32f854a7cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 303 additions and 182 deletions

View File

@ -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;

View File

@ -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
{

View File

@ -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;

View File

@ -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();

View File

@ -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)
{

View File

@ -15,6 +15,7 @@
*/
#include "natpmp.h"
#include "net.h" // tr_port
enum tr_natpmp_state
{

View File

@ -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);
}

View File

@ -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);

View File

@ -16,6 +16,7 @@
#include "bitfield.h"
#include "history.h"
#include "interned-string.h"
#include "net.h" // tr_port
/**
* @addtogroup peers Peers

View File

@ -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();

View File

@ -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:

View File

@ -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(

View File

@ -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*);
/** @} */

View File

@ -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;

View File

@ -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);

View File

@ -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:

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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))
{

View File

@ -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];

View File

@ -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;
}
}

View File

@ -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)

View File

@ -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);

View File

@ -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;