refactor: remove tr_address_from_string() (#3524)

use tr_address::fromString() instead

* refactor: use tr_address.isIPv4()
This commit is contained in:
Charles Kerr 2022-07-25 17:25:55 -05:00 committed by GitHub
parent b29cc8b9fa
commit d09aba0e6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 71 additions and 95 deletions

View File

@ -258,7 +258,10 @@ void tr_announcerParseHttpAnnounceResponse(tr_announce_response& response, std::
}
else if (key == "ip")
{
tr_address_from_string(&pex_.addr, value);
if (auto const addr = tr_address::fromString(value); addr)
{
pex_.addr = *addr;
}
}
else if (key == "peer id")
{

View File

@ -89,15 +89,10 @@ static uint32_t announce_ip(tr_session const* session)
return 0;
}
tr_address ta;
// Since size of IP field is only 4 bytes long we can announce
// only IPv4 addresses.
if (!tr_address_from_string(&ta, session->announceIP()) || (ta.type != TR_AF_INET))
{
return 0;
}
return ta.addr.addr4.s_addr;
auto const addr = tr_address::fromString(session->announceIP());
return addr && addr->isIPv4() ? addr->addr.addr4.s_addr : 0;
}
/****

View File

@ -112,7 +112,7 @@ bool BlocklistFile::hasAddress(tr_address const& addr)
{
TR_ASSERT(tr_address_is_valid(&addr));
if (!is_enabled_ || addr.type == TR_AF_INET6)
if (!is_enabled_ || !addr.isIPv4())
{
return false;
}
@ -155,9 +155,9 @@ bool BlocklistFile::parseLine1(std::string_view line, struct IPv4Range* range)
{
return false;
}
if (auto addr = tr_address{}; tr_address_from_string(&addr, line.substr(0, pos)))
if (auto const addr = tr_address::fromString(line.substr(0, pos)); addr)
{
range->begin_ = ntohl(addr.addr.addr4.s_addr);
range->begin_ = ntohl(addr->addr.addr4.s_addr);
}
else
{
@ -166,9 +166,9 @@ bool BlocklistFile::parseLine1(std::string_view line, struct IPv4Range* range)
line = line.substr(pos + 1);
// parse the trailing 'y.y.y.y'
if (auto addr = tr_address{}; tr_address_from_string(&addr, line))
if (auto const addr = tr_address::fromString(line); addr)
{
range->end_ = ntohl(addr.addr.addr4.s_addr);
range->end_ = ntohl(addr->addr.addr4.s_addr);
}
else
{
@ -193,9 +193,9 @@ bool BlocklistFile::parseLine2(std::string_view line, struct IPv4Range* range)
return false;
}
if (auto addr = tr_address{}; tr_address_from_string(&addr, line.substr(0, pos)))
if (auto const addr = tr_address::fromString(line.substr(0, pos)); addr)
{
range->begin_ = ntohl(addr.addr.addr4.s_addr);
range->begin_ = ntohl(addr->addr.addr4.s_addr);
}
else
{
@ -209,9 +209,9 @@ bool BlocklistFile::parseLine2(std::string_view line, struct IPv4Range* range)
return false;
}
if (auto addr = tr_address{}; tr_address_from_string(&addr, line.substr(0, pos)))
if (auto const addr = tr_address::fromString(line.substr(0, pos)); addr)
{
range->end_ = ntohl(addr.addr.addr4.s_addr);
range->end_ = ntohl(addr->addr.addr4.s_addr);
}
else
{

View File

@ -61,39 +61,6 @@ std::string tr_net_strerror(int err)
#endif
}
bool tr_address_from_string(tr_address* dst, char const* src)
{
if (evutil_inet_pton(AF_INET, src, &dst->addr) == 1)
{
dst->type = TR_AF_INET;
return true;
}
if (evutil_inet_pton(AF_INET6, src, &dst->addr) == 1)
{
dst->type = TR_AF_INET6;
return true;
}
return false;
}
bool tr_address_from_string(tr_address* dst, std::string_view src)
{
// inet_pton() requires zero-terminated strings,
// so make a zero-terminated copy here on the stack.
auto buf = std::array<char, TR_ADDRSTRLEN>{};
if (std::size(src) >= std::size(buf))
{
// shouldn't ever be that large; malformed address
return false;
}
*std::copy(std::begin(src), std::end(src), std::begin(buf)) = '\0';
return tr_address_from_string(dst, std::data(buf));
}
/*
* Compare two tr_address structures.
* Returns:
@ -106,11 +73,11 @@ int tr_address_compare(tr_address const* a, tr_address const* b) noexcept
// IPv6 addresses are always "greater than" IPv4
if (a->type != b->type)
{
return a->type == TR_AF_INET ? 1 : -1;
return a->isIPv4() ? 1 : -1;
}
return a->type == TR_AF_INET ? memcmp(&a->addr.addr4, &b->addr.addr4, sizeof(a->addr.addr4)) :
memcmp(&a->addr.addr6.s6_addr, &b->addr.addr6.s6_addr, sizeof(a->addr.addr6.s6_addr));
return a->isIPv4() ? memcmp(&a->addr.addr4, &b->addr.addr4, sizeof(a->addr.addr4)) :
memcmp(&a->addr.addr6.s6_addr, &b->addr.addr6.s6_addr, sizeof(a->addr.addr6.s6_addr));
}
/***********************************************************************
@ -246,7 +213,7 @@ static socklen_t setup_sockaddr(tr_address const* addr, tr_port port, struct soc
{
TR_ASSERT(tr_address_is_valid(addr));
if (addr->type == TR_AF_INET)
if (addr->isIPv4())
{
sockaddr_in sock4 = {};
sock4.sin_family = AF_INET;
@ -370,7 +337,7 @@ struct tr_peer_socket tr_netOpenPeerSocket(tr_session* session, tr_address const
{
int const tmperrno = sockerrno;
if ((tmperrno != ENETUNREACH && tmperrno != EHOSTUNREACH) || addr->type == TR_AF_INET)
if ((tmperrno != ENETUNREACH && tmperrno != EHOSTUNREACH) || addr->isIPv4())
{
tr_logAddWarn(fmt::format(
_("Couldn't connect socket {socket} to {address}:{port}: {error} ({error_code})"),
@ -473,7 +440,7 @@ static tr_socket_t tr_netBindTCPImpl(tr_address const* addr, tr_port port, bool
#ifdef IPV6_V6ONLY
if ((addr->type == TR_AF_INET6) &&
if (addr->isIPv6() &&
(setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<char const*>(&optval), sizeof(optval)) == -1) &&
(sockerrno != ENOPROTOOPT)) // if the kernel doesn't support it, ignore it
{
@ -788,12 +755,12 @@ unsigned char const* tr_globalIPv6(tr_session const* session)
static bool isIPv4MappedAddress(tr_address const* addr)
{
return addr->type == TR_AF_INET6 && IN6_IS_ADDR_V4MAPPED(&addr->addr.addr6);
return addr->isIPv6() && IN6_IS_ADDR_V4MAPPED(&addr->addr.addr6);
}
static bool isIPv6LinkLocalAddress(tr_address const* addr)
{
return addr->type == TR_AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&addr->addr.addr6);
return addr->isIPv6() && IN6_IS_ADDR_LINKLOCAL(&addr->addr.addr6);
}
/* isMartianAddr was written by Juliusz Chroboczek,
@ -861,16 +828,25 @@ std::pair<tr_port, uint8_t const*> tr_port::fromCompact(uint8_t const* compact)
/// tr_address
std::optional<tr_address> tr_address::fromString(std::string_view address_str)
std::optional<tr_address> tr_address::fromString(std::string_view address_sv)
{
auto const address_sz = tr_strbuf<char, TR_ADDRSTRLEN>{ address_sv };
auto addr = tr_address{};
if (!tr_address_from_string(&addr, address_str))
if (evutil_inet_pton(AF_INET, address_sz, &addr.addr) == 1)
{
return {};
addr.type = TR_AF_INET;
return addr;
}
return addr;
if (evutil_inet_pton(AF_INET6, address_sz, &addr.addr) == 1)
{
addr.type = TR_AF_INET6;
return addr;
}
return {};
}
std::string_view tr_address::readable(char* out, size_t outlen, tr_port port) const

View File

@ -201,10 +201,6 @@ struct tr_address
extern tr_address const tr_inaddr_any;
extern tr_address const tr_in6addr_any;
bool tr_address_from_string(tr_address* setme, char const* string);
bool tr_address_from_string(tr_address* dst, std::string_view src);
bool tr_address_from_sockaddr_storage(tr_address* setme, tr_port* port, struct sockaddr_storage const* src);
bool tr_address_is_valid_for_peers(tr_address const* addr, tr_port port);

View File

@ -290,7 +290,7 @@ public:
if (tr_dhtEnabled(torrent->session) && io->supportsDHT())
{
/* Only send PORT over IPv6 when the IPv6 DHT is running (BEP-32). */
if (io->address().type == TR_AF_INET || tr_globalIPv6(nullptr) != nullptr)
if (io->address().isIPv4() || tr_globalIPv6(nullptr) != nullptr)
{
protocolSendPort(this, tr_dhtPort(torrent->session));
}
@ -1005,7 +1005,7 @@ size_t tr_generateAllowedSet(tr_piece_index_t* setmePieces, size_t desiredSetSiz
size_t setSize = 0;
if (addr->type == TR_AF_INET)
if (addr->isIPv4())
{
uint8_t w[SHA_DIGEST_LENGTH + 4];
uint8_t* walk = w;

View File

@ -793,7 +793,6 @@ static void sessionSetImpl(struct init_data* const data)
TR_ASSERT(tr_variantIsDict(settings));
TR_ASSERT(tr_amInEventThread(session));
auto b = tr_bindinfo{};
auto boolVal = bool{};
auto d = double{};
auto i = int64_t{};
@ -973,23 +972,33 @@ static void sessionSetImpl(struct init_data* const data)
free_incoming_peer_port(session);
if (!tr_variantDictFindStrView(settings, TR_KEY_bind_address_ipv4, &sv) || !tr_address_from_string(&b.addr, sv) ||
b.addr.type != TR_AF_INET)
{
b.addr = tr_inaddr_any;
auto b = tr_bindinfo{ TR_BAD_SOCKET, tr_inaddr_any, nullptr };
if (tr_variantDictFindStrView(settings, TR_KEY_bind_address_ipv4, &sv))
{
if (auto const addr = tr_address::fromString(sv); addr && addr->isIPv4())
{
b.addr = *addr;
}
}
session->bind_ipv4 = static_cast<struct tr_bindinfo*>(tr_memdup(&b, sizeof(struct tr_bindinfo)));
}
b.socket = TR_BAD_SOCKET;
session->bind_ipv4 = static_cast<struct tr_bindinfo*>(tr_memdup(&b, sizeof(struct tr_bindinfo)));
if (!tr_variantDictFindStrView(settings, TR_KEY_bind_address_ipv6, &sv) || !tr_address_from_string(&b.addr, sv) ||
b.addr.type != TR_AF_INET6)
{
b.addr = tr_in6addr_any;
}
auto b = tr_bindinfo{ TR_BAD_SOCKET, tr_in6addr_any, nullptr };
b.socket = TR_BAD_SOCKET;
session->bind_ipv6 = static_cast<tr_bindinfo*>(tr_memdup(&b, sizeof(struct tr_bindinfo)));
if (tr_variantDictFindStrView(settings, TR_KEY_bind_address_ipv6, &sv))
{
if (auto const addr = tr_address::fromString(sv); addr && addr->isIPv6())
{
b.addr = *addr;
}
}
session->bind_ipv6 = static_cast<tr_bindinfo*>(tr_memdup(&b, sizeof(struct tr_bindinfo)));
}
/* incoming peer port */
if (tr_variantDictFindInt(settings, TR_KEY_peer_port_random_low, &i))

View File

@ -530,7 +530,7 @@ tr_port tr_dhtPort(tr_session* ss)
bool tr_dhtAddNode(tr_session* ss, tr_address const* address, tr_port port, bool bootstrap)
{
int af = address->type == TR_AF_INET ? AF_INET : AF_INET6;
int af = address->isIPv4() ? AF_INET : AF_INET6;
if (!tr_dhtEnabled(ss))
{
@ -545,7 +545,7 @@ bool tr_dhtAddNode(tr_session* ss, tr_address const* address, tr_port port, bool
return false;
}
if (address->type == TR_AF_INET)
if (address->isIPv4())
{
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
@ -556,7 +556,7 @@ bool tr_dhtAddNode(tr_session* ss, tr_address const* address, tr_port port, bool
return true;
}
if (address->type == TR_AF_INET6)
if (address->isIPv6())
{
struct sockaddr_in6 sin6;
memset(&sin6, 0, sizeof(sin6));

View File

@ -33,8 +33,7 @@ using namespace std::literals;
bool tr_addressIsIP(char const* str)
{
tr_address tmp;
return tr_address_from_string(&tmp, str);
return str != nullptr && tr_address::fromString(str).has_value();
}
char const* tr_webGetResponseStr(long code)
@ -271,16 +270,15 @@ std::string_view getSiteName(std::string_view host)
return host;
}
// psl needs a zero-terminated hostname
auto const szhost = tr_urlbuf{ host };
// is it an IP?
auto addr = tr_address{};
if (tr_address_from_string(&addr, std::data(szhost)))
if (auto const addr = tr_address::fromString(host); addr)
{
return host;
}
// psl needs a zero-terminated hostname
auto const szhost = tr_urlbuf{ host };
// is it a registered name?
if (isAsciiNonUpperCase(host))
{

View File

@ -59,8 +59,8 @@ protected:
bool addressIsBlocked(char const* address_str)
{
struct tr_address addr = {};
return !tr_address_from_string(&addr, address_str) || tr_sessionIsAddressBlocked(session_, &addr);
auto const addr = tr_address::fromString(address_str);
return !addr || tr_sessionIsAddressBlocked(session_, &*addr);
}
};

View File

@ -14,7 +14,6 @@ TEST(PeerMsgs, placeholder)
#if 0
auto infohash = tr_sha1_digest_t{};
struct tr_address addr;
tr_piece_index_t pieceCount = 1313;
size_t numwant;
size_t numgot;
@ -23,7 +22,7 @@ TEST(PeerMsgs, placeholder)
memset(std::data(infohash), 0xaa, std::size(infohash));
tr_address_from_string(&addr, "80.4.4.200");
auto const addr = tr_address::fromString("80.4.4.200");
numwant = 7;
numgot = tr_generateAllowedSet(buf, numwant, pieceCount, infohash, &addr);