refactor: simplify tr_udp_core::sendto() (#4510)

This commit is contained in:
Charles Kerr 2023-01-01 17:16:13 -06:00 committed by GitHub
parent 47ebb3f63a
commit d338eb3bdc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 42 additions and 86 deletions

View File

@ -91,13 +91,13 @@ static void event_callback(evutil_socket_t s, [[maybe_unused]] short type, void*
auto buf = std::array<unsigned char, 8192>{};
auto from = sockaddr_storage{};
auto fromlen = socklen_t{ sizeof(from) };
auto const rc = recvfrom(
s,
reinterpret_cast<char*>(std::data(buf)),
std::size(buf) - 1,
0,
reinterpret_cast<sockaddr*>(&from),
&fromlen);
auto* const from_sa = reinterpret_cast<sockaddr*>(&from);
auto const rc = recvfrom(s, reinterpret_cast<char*>(std::data(buf)), std::size(buf) - 1, 0, from_sa, &fromlen);
if (rc <= 0)
{
return;
}
/* Since most packets we receive here are µTP, make quick inline
checks for the other protocols. The logic is as follows:
@ -106,33 +106,27 @@ static void event_callback(evutil_socket_t s, [[maybe_unused]] short type, void*
is between 0 and 3
- the above cannot be µTP packets, since these start with a 4-bit
version number (1). */
auto* session = static_cast<tr_session*>(vsession);
if (rc > 0)
auto* const session = static_cast<tr_session*>(vsession);
if (buf[0] == 'd')
{
if (buf[0] == 'd')
if (session->dht_)
{
if (session->dht_)
{
buf[rc] = '\0'; // libdht requires zero-terminated messages
session->dht_->handleMessage(std::data(buf), rc, reinterpret_cast<sockaddr*>(&from), fromlen);
}
buf[rc] = '\0'; // libdht requires zero-terminated messages
session->dht_->handleMessage(std::data(buf), rc, from_sa, fromlen);
}
else if (rc >= 8 && buf[0] == 0 && buf[1] == 0 && buf[2] == 0 && buf[3] <= 3)
}
else if (rc >= 8 && buf[0] == 0 && buf[1] == 0 && buf[2] == 0 && buf[3] <= 3)
{
if (!session->announcer_udp_->handleMessage(std::data(buf), rc))
{
if (!session->announcer_udp_->handleMessage(std::data(buf), rc))
{
tr_logAddTrace("Couldn't parse UDP tracker packet.");
}
tr_logAddTrace("Couldn't parse UDP tracker packet.");
}
else
}
else if (session->allowsUTP() && (session->utp_context != nullptr))
{
if (!tr_utpPacket(std::data(buf), rc, from_sa, fromlen, session))
{
if (session->allowsUTP() && (session->utp_context != nullptr))
{
if (!tr_utpPacket(std::data(buf), rc, (struct sockaddr*)&from, fromlen, session))
{
tr_logAddTrace("Unexpected UDP packet");
}
}
tr_logAddTrace("Unexpected UDP packet");
}
}
}
@ -231,67 +225,29 @@ tr_session::tr_udp_core::~tr_udp_core()
void tr_session::tr_udp_core::sendto(void const* buf, size_t buflen, struct sockaddr const* to, socklen_t const tolen) const
{
int error = 0;
std::array<char, std::max(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) + 1> peer = {};
if (to->sa_family == AF_INET)
if (to->sa_family != AF_INET && to->sa_family != AF_INET6)
{
if (udp4_socket_ != TR_BAD_SOCKET)
{
if (::sendto(udp4_socket_, static_cast<char const*>(buf), buflen, 0, to, tolen) == -1)
{
error = -1;
}
}
else
{
error = -1;
errno = EBADF;
}
if (error == -1)
{
evutil_inet_ntop(
AF_INET,
&((reinterpret_cast<struct sockaddr_in const*>(to))->sin_addr),
std::data(peer),
std::size(peer));
}
}
else if (to->sa_family == AF_INET6)
{
if (udp6_socket_ != TR_BAD_SOCKET)
{
if (::sendto(udp6_socket_, static_cast<char const*>(buf), buflen, 0, to, tolen) == -1)
{
error = -1;
}
}
else
{
error = -1;
errno = EBADF;
}
if (error == -1)
{
evutil_inet_ntop(
AF_INET6,
&((reinterpret_cast<struct sockaddr_in6 const*>(to))->sin6_addr),
std::data(peer),
std::size(peer));
}
}
else
{
error = -1;
errno = EAFNOSUPPORT;
}
if (error == -1)
else if (auto const sock = to->sa_family == AF_INET ? udp4_socket_ : udp6_socket_; sock == TR_BAD_SOCKET)
{
tr_logAddWarn(fmt::format(
"Couldn't send to {address}: {errno} ({error})",
fmt::arg("address", std::data(peer)),
fmt::arg("errno", errno),
fmt::arg("error", tr_strerror(errno))));
errno = EBADF;
}
else if (::sendto(sock, static_cast<char const*>(buf), buflen, 0, to, tolen) != -1)
{
return;
}
auto display_name = std::string{};
if (auto const addrport = tr_address::from_sockaddr(to); addrport)
{
auto const& [addr, port] = *addrport;
display_name = addr.display_name(port);
}
tr_logAddWarn(fmt::format(
"Couldn't send to {address}: {errno} ({error})",
fmt::arg("address", display_name),
fmt::arg("errno", errno),
fmt::arg("error", tr_strerror(errno))));
}