diff --git a/libtransmission/tr-udp.cc b/libtransmission/tr-udp.cc index 929d283ed..869f9b224 100644 --- a/libtransmission/tr-udp.cc +++ b/libtransmission/tr-udp.cc @@ -91,13 +91,13 @@ static void event_callback(evutil_socket_t s, [[maybe_unused]] short type, void* auto buf = std::array{}; auto from = sockaddr_storage{}; auto fromlen = socklen_t{ sizeof(from) }; - auto const rc = recvfrom( - s, - reinterpret_cast(std::data(buf)), - std::size(buf) - 1, - 0, - reinterpret_cast(&from), - &fromlen); + auto* const from_sa = reinterpret_cast(&from); + + auto const rc = recvfrom(s, reinterpret_cast(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(vsession); - if (rc > 0) + auto* const session = static_cast(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(&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 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(buf), buflen, 0, to, tolen) == -1) - { - error = -1; - } - } - else - { - error = -1; - errno = EBADF; - } - if (error == -1) - { - evutil_inet_ntop( - AF_INET, - &((reinterpret_cast(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(buf), buflen, 0, to, tolen) == -1) - { - error = -1; - } - } - else - { - error = -1; - errno = EBADF; - } - if (error == -1) - { - evutil_inet_ntop( - AF_INET6, - &((reinterpret_cast(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(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)))); }