From e7a80c7b180bfb54e0d9ea2530f988909e8ae3ff Mon Sep 17 00:00:00 2001 From: Jari Sundell Date: Wed, 17 Sep 2025 14:44:54 +0200 Subject: [PATCH] Remove deprecated rak::socket_address. --- Makefile.am | 1 - rak/address_info.h | 43 +-- rak/socket_address.h | 557 -------------------------------- src/command_download.cc | 21 +- src/command_network.cc | 16 +- src/command_peer.cc | 51 +-- src/command_throttle.cc | 57 +--- src/core/manager.cc | 20 +- src/display/utils.cc | 13 +- src/display/window_peer_list.cc | 6 +- src/rpc/scgi.cc | 33 +- src/utils/socket_fd.cc | 136 +------- src/utils/socket_fd.h | 51 +-- 13 files changed, 100 insertions(+), 905 deletions(-) delete mode 100644 rak/socket_address.h diff --git a/Makefile.am b/Makefile.am index f41bec55..d8cfbea3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -14,7 +14,6 @@ EXTRA_DIST= \ rak/path.h \ rak/partial_queue.h \ rak/regex.h \ - rak/socket_address.h \ rak/string_manip.h \ rak/unordered_vector.h \ scripts/checks.m4 \ diff --git a/rak/address_info.h b/rak/address_info.h index 7e621ae3..ddc1f493 100644 --- a/rak/address_info.h +++ b/rak/address_info.h @@ -1,36 +1,3 @@ -// rak - Rakshasa's toolbox -// Copyright (C) 2005-2007, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell - // Wrapper for addrinfo with focus on zero-copy conversion to and from // the c-type and wrapper. // @@ -41,7 +8,7 @@ #define RAK_ADDRESS_INFO_H #include -#include +#include namespace rak { @@ -57,13 +24,11 @@ public: int socket_type() const { return m_addrinfo.ai_socktype; } void set_socket_type(int t) { m_addrinfo.ai_socktype = t; } - + int protocol() const { return m_addrinfo.ai_protocol; } void set_protocol(int p) { m_addrinfo.ai_protocol = p; } - - size_t length() const { return m_addrinfo.ai_addrlen; } - socket_address* address() { return reinterpret_cast(m_addrinfo.ai_addr); } + size_t length() const { return m_addrinfo.ai_addrlen; } addrinfo* c_addrinfo() { return &m_addrinfo; } const addrinfo* c_addrinfo() const { return &m_addrinfo; } @@ -86,7 +51,7 @@ address_info::get_address_info(const char* node, int pfamily, int stype, address hints.clear(); hints.set_family(pfamily); hints.set_socket_type(stype); - + return ::getaddrinfo(node, NULL, hints.c_addrinfo(), reinterpret_cast(ai)); } diff --git a/rak/socket_address.h b/rak/socket_address.h deleted file mode 100644 index ba105a6b..00000000 --- a/rak/socket_address.h +++ /dev/null @@ -1,557 +0,0 @@ -// rak - Rakshasa's toolbox -// Copyright (C) 2005-2007, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell - - -// Wrappers for the various sockaddr types with focus on zero-copy -// casting between the original type and the wrapper class. -// -// The default ctor does not initialize any data. -// -// _n suffixes indicate that the argument or return value is in -// network byte order, _h that they are in hardware byte order. - -// Add define for inet6 scope id? - -#ifndef RAK_SOCKET_ADDRESS_H -#define RAK_SOCKET_ADDRESS_H - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace rak { - -class socket_address_inet; -class socket_address_inet6; - -class socket_address { -public: - static const sa_family_t af_inet = AF_INET; - static const int pf_inet = PF_INET; - static const sa_family_t af_inet6 = AF_INET6; - static const int pf_inet6 = PF_INET6; - static const sa_family_t af_unspec = AF_UNSPEC; - static const int pf_unspec = PF_UNSPEC; - -#ifdef AF_LOCAL - static const sa_family_t af_local = AF_LOCAL; - static const int pf_local = PF_LOCAL; -#else - static const sa_family_t af_local = AF_UNIX; - static const int pf_local = PF_UNIX; -#endif - - bool is_any() const; - bool is_valid() const; - bool is_bindable() const; - bool is_address_any() const; - - bool is_valid_inet_class() const { return family() == af_inet || family() == af_inet6; } - - void clear() { std::memset(this, 0, sizeof(socket_address)); set_family(); } - - sa_family_t family() const { return m_sockaddr.sa_family; } - void set_family() { m_sockaddr.sa_family = af_unspec; } - - uint16_t port() const; - void set_port(uint16_t p); - - std::string address_str() const; - bool address_c_str(char* buf, socklen_t size) const; - - std::string pretty_address_str() const; - - // Attemts to set it as an inet, then an inet6 address. It will - // never set anything but net addresses, no local/unix. - bool set_address_str(const std::string& a) { return set_address_c_str(a.c_str()); } - bool set_address_c_str(const char* a); - - uint32_t length() const; - - socket_address_inet* sa_inet() { return reinterpret_cast(this); } - const socket_address_inet* sa_inet() const { return reinterpret_cast(this); } - - sockaddr* c_sockaddr() { return &m_sockaddr; } - sockaddr_in* c_sockaddr_inet() { return &m_sockaddrInet; } - - const sockaddr* c_sockaddr() const { return &m_sockaddr; } - const sockaddr_in* c_sockaddr_inet() const { return &m_sockaddrInet; } - - socket_address_inet6* sa_inet6() { return reinterpret_cast(this); } - const socket_address_inet6* sa_inet6() const { return reinterpret_cast(this); } - - sockaddr_in6* c_sockaddr_inet6() { return &m_sockaddrInet6; } - const sockaddr_in6* c_sockaddr_inet6() const { return &m_sockaddrInet6; } - - // Copy a socket address which has the length 'length. Zero out any - // extranous bytes and ensure it does not go beyond the size of this - // struct. - void copy(const socket_address& src, size_t length); - void copy_sockaddr(const sockaddr* src); - - static socket_address* cast_from(sockaddr* sa) { return reinterpret_cast(sa); } - static const socket_address* cast_from(const sockaddr* sa) { return reinterpret_cast(sa); } - - // The different families will be sorted according to the - // sa_family_t's numeric value. - bool operator == (const socket_address& rhs) const; - bool operator < (const socket_address& rhs) const; - - bool operator == (const sockaddr& rhs) const { return *this == *cast_from(&rhs); } - bool operator == (const sockaddr* rhs) const { return *this == *cast_from(rhs); } - bool operator < (const sockaddr& rhs) const { return *this == *cast_from(&rhs); } - bool operator < (const sockaddr* rhs) const { return *this == *cast_from(rhs); } - -private: - union { - sockaddr m_sockaddr; - sockaddr_in m_sockaddrInet; - sockaddr_in6 m_sockaddrInet6; - }; -}; - -// Remember to set the AF_INET. - -class socket_address_inet { -public: - bool is_any() const { return is_port_any() && is_address_any(); } - bool is_valid() const { return !is_port_any() && !is_address_any(); } - bool is_port_any() const { return port() == 0; } - bool is_address_any() const { return m_sockaddr.sin_addr.s_addr == htonl(INADDR_ANY); } - - void clear() { std::memset(this, 0, sizeof(socket_address_inet)); set_family(); } - - uint16_t port() const { return ntohs(m_sockaddr.sin_port); } - uint16_t port_n() const { return m_sockaddr.sin_port; } - void set_port(uint16_t p) { m_sockaddr.sin_port = htons(p); } - void set_port_n(uint16_t p) { m_sockaddr.sin_port = p; } - - // Should address() return the uint32_t? - in_addr address() const { return m_sockaddr.sin_addr; } - uint32_t address_h() const { return ntohl(m_sockaddr.sin_addr.s_addr); } - uint32_t address_n() const { return m_sockaddr.sin_addr.s_addr; } - std::string address_str() const; - bool address_c_str(char* buf, socklen_t size) const; - - void set_address(in_addr a) { m_sockaddr.sin_addr = a; } - void set_address_h(uint32_t a) { m_sockaddr.sin_addr.s_addr = htonl(a); } - void set_address_n(uint32_t a) { m_sockaddr.sin_addr.s_addr = a; } - bool set_address_str(const std::string& a) { return set_address_c_str(a.c_str()); } - bool set_address_c_str(const char* a); - - void set_address_any() { set_port(0); set_address_h(INADDR_ANY); } - - sa_family_t family() const { return m_sockaddr.sin_family; } - void set_family() { m_sockaddr.sin_family = AF_INET; } - - sockaddr* c_sockaddr() { return reinterpret_cast(&m_sockaddr); } - sockaddr_in* c_sockaddr_inet() { return &m_sockaddr; } - - const sockaddr* c_sockaddr() const { return reinterpret_cast(&m_sockaddr); } - const sockaddr_in* c_sockaddr_inet() const { return &m_sockaddr; } - - socket_address_inet6 to_mapped_address() const; - - bool operator == (const socket_address_inet& rhs) const; - bool operator < (const socket_address_inet& rhs) const; - -private: - struct sockaddr_in m_sockaddr; -}; - -class socket_address_inet6 { -public: - bool is_any() const { return is_port_any() && is_address_any(); } - bool is_valid() const { return !is_port_any() && !is_address_any(); } - bool is_port_any() const { return port() == 0; } - bool is_address_any() const { return std::memcmp(&m_sockaddr.sin6_addr, &in6addr_any, sizeof(in6_addr)) == 0; } - - void clear() { std::memset(this, 0, sizeof(socket_address_inet6)); set_family(); } - - uint16_t port() const { return ntohs(m_sockaddr.sin6_port); } - uint16_t port_n() const { return m_sockaddr.sin6_port; } - void set_port(uint16_t p) { m_sockaddr.sin6_port = htons(p); } - void set_port_n(uint16_t p) { m_sockaddr.sin6_port = p; } - - in6_addr address() const { return m_sockaddr.sin6_addr; } - const in6_addr* address_ptr() const { return &m_sockaddr.sin6_addr; } - std::string address_str() const; - bool address_c_str(char* buf, socklen_t size) const; - - void set_address(in6_addr a) { m_sockaddr.sin6_addr = a; } - bool set_address_str(const std::string& a) { return set_address_c_str(a.c_str()); } - bool set_address_c_str(const char* a); - - void set_address_any() { set_port(0); set_address(in6addr_any); } - - std::string pretty_address_str() const; - - sa_family_t family() const { return m_sockaddr.sin6_family; } - void set_family() { m_sockaddr.sin6_family = AF_INET6; } - - sockaddr* c_sockaddr() { return reinterpret_cast(&m_sockaddr); } - sockaddr_in6* c_sockaddr_inet6() { return &m_sockaddr; } - - const sockaddr* c_sockaddr() const { return reinterpret_cast(&m_sockaddr); } - const sockaddr_in6* c_sockaddr_inet6() const { return &m_sockaddr; } - - socket_address normalize_address() const; - - bool operator == (const socket_address_inet6& rhs) const; - bool operator < (const socket_address_inet6& rhs) const; - -private: - struct sockaddr_in6 m_sockaddr; -}; - -inline bool -socket_address::is_any() const { - switch (family()) { - case af_inet: - return sa_inet()->is_any(); - case af_inet6: - return sa_inet6()->is_any(); - default: - return false; - } -} - -inline bool -socket_address::is_valid() const { - switch (family()) { - case af_inet: - return sa_inet()->is_valid(); - case af_inet6: - return sa_inet6()->is_valid(); - default: - return false; - } -} - -inline bool -socket_address::is_bindable() const { - switch (family()) { - case af_inet: - return !sa_inet()->is_address_any(); - case af_inet6: - return !sa_inet6()->is_address_any(); - default: - return false; - } -} - -inline bool -socket_address::is_address_any() const { - switch (family()) { - case af_inet: - return sa_inet()->is_address_any(); - case af_inet6: - return sa_inet6()->is_address_any(); - default: - return true; - } -} - -inline uint16_t -socket_address::port() const { - switch (family()) { - case af_inet: - return sa_inet()->port(); - case af_inet6: - return sa_inet6()->port(); - default: - return 0; - } -} - -inline void -socket_address::set_port(uint16_t p) { - switch (family()) { - case af_inet: - return sa_inet()->set_port(p); - case af_inet6: - return sa_inet6()->set_port(p); - default: - break; - } -} - -inline std::string -socket_address::address_str() const { - switch (family()) { - case af_inet: - return sa_inet()->address_str(); - case af_inet6: - return sa_inet6()->address_str(); - default: - return std::string(); - } -} - -inline bool -socket_address::address_c_str(char* buf, socklen_t size) const { - switch (family()) { - case af_inet: - return sa_inet()->address_c_str(buf, size); - case af_inet6: - return sa_inet6()->address_c_str(buf, size); - default: - return false; - } -} - -inline std::string -socket_address::pretty_address_str() const { - switch (family()) { - case af_inet: - return sa_inet()->address_str(); - case af_inet6: - return sa_inet6()->pretty_address_str(); - case af_unspec: - return std::string("unspec"); - default: - return std::string("invalid"); - } -} - - -inline bool -socket_address::set_address_c_str(const char* a) { - if (sa_inet()->set_address_c_str(a)) { - sa_inet()->set_family(); - return true; - - } else if (sa_inet6()->set_address_c_str(a)) { - sa_inet6()->set_family(); - return true; - - } else { - return false; - } -} - -// Is the zero length really needed, should we require some length? -inline uint32_t -socket_address::length() const { - switch(family()) { - case af_inet: - return sizeof(sockaddr_in); - case af_inet6: - return sizeof(sockaddr_in6); - default: - return 0; - } -} - -inline void -socket_address::copy(const socket_address& src, size_t length) { - length = std::min(length, sizeof(socket_address)); - - std::memset(this, 0, sizeof(socket_address)); - std::memcpy(this, &src, length); -} - -inline void -socket_address::copy_sockaddr(const sockaddr* src) { - std::memset(this, 0, sizeof(socket_address)); - std::memcpy(static_cast(this), src, socket_address::cast_from(src)->length()); -} - -inline bool -socket_address::operator == (const socket_address& rhs) const { - if (family() != rhs.family()) - return false; - - switch (family()) { - case af_inet: - return *sa_inet() == *rhs.sa_inet(); - case af_inet6: - return *sa_inet6() == *rhs.sa_inet6(); - default: - throw std::logic_error("socket_address::operator == (rhs) invalid type comparison."); - } -} - -inline bool -socket_address::operator < (const socket_address& rhs) const { - if (family() != rhs.family()) - return family() < rhs.family(); - - switch (family()) { - case af_inet: - return *sa_inet() < *rhs.sa_inet(); - case af_inet6: - return *sa_inet6() < *rhs.sa_inet6(); - default: - throw std::logic_error("socket_address::operator < (rhs) invalid type comparison."); - } -} - -inline std::string -socket_address_inet::address_str() const { - char buf[INET_ADDRSTRLEN]; - - if (!address_c_str(buf, INET_ADDRSTRLEN)) - return std::string(); - - return std::string(buf); -} - -inline bool -socket_address_inet::address_c_str(char* buf, socklen_t size) const { - return inet_ntop(family(), &m_sockaddr.sin_addr, buf, size); -} - -inline bool -socket_address_inet::set_address_c_str(const char* a) { - return inet_pton(AF_INET, a, &m_sockaddr.sin_addr); -} - -inline socket_address_inet6 -socket_address_inet::to_mapped_address() const { - uint32_t addr32[4]; - addr32[0] = 0; - addr32[1] = 0; - addr32[2] = htonl(0xffff); - addr32[3] = m_sockaddr.sin_addr.s_addr; - - socket_address_inet6 sa; - sa.clear(); - sa.set_address(*reinterpret_cast(addr32)); - sa.set_port_n(m_sockaddr.sin_port); - return sa; -} - -inline bool -socket_address_inet::operator == (const socket_address_inet& rhs) const { - return - m_sockaddr.sin_addr.s_addr == rhs.m_sockaddr.sin_addr.s_addr && - m_sockaddr.sin_port == rhs.m_sockaddr.sin_port; -} - -inline bool -socket_address_inet::operator < (const socket_address_inet& rhs) const { - return - m_sockaddr.sin_addr.s_addr < rhs.m_sockaddr.sin_addr.s_addr || - (m_sockaddr.sin_addr.s_addr == rhs.m_sockaddr.sin_addr.s_addr && - m_sockaddr.sin_port < rhs.m_sockaddr.sin_port); -} - -inline std::string -socket_address_inet6::address_str() const { - char buf[INET6_ADDRSTRLEN]; - - if (!address_c_str(buf, INET6_ADDRSTRLEN)) - return std::string(); - - return std::string(buf); -} - -inline bool -socket_address_inet6::address_c_str(char* buf, socklen_t size) const { - return inet_ntop(family(), &m_sockaddr.sin6_addr, buf, size); -} - -inline bool -socket_address_inet6::set_address_c_str(const char* a) { - return inet_pton(AF_INET6, a, &m_sockaddr.sin6_addr); -} - -inline std::string -socket_address_inet6::pretty_address_str() const { - char buf[INET6_ADDRSTRLEN + 2 + 6]; - - if (inet_ntop(family(), &m_sockaddr.sin6_addr, buf + 1, INET6_ADDRSTRLEN) == NULL) - return std::string(); - - buf[0] = '['; - - char* last_char = (char*)std::memchr(buf + 1, 0, INET6_ADDRSTRLEN); - - // TODO: Throw exception here. - - if (last_char == NULL || last_char >= buf + 1 + INET6_ADDRSTRLEN) - throw std::logic_error("inet_ntop for inet6 returned bad buffer"); - - *(last_char++) = ']'; - - if (!is_port_any()) { - if (snprintf(last_char, 7, ":%" PRIu16, port()) == -1) - return std::string("error"); // TODO: Throw here. - - } else { - *last_char = '\0'; - } - - return std::string(buf); -} - -inline socket_address -socket_address_inet6::normalize_address() const { - const uint32_t *addr32 = reinterpret_cast(m_sockaddr.sin6_addr.s6_addr); - if (addr32[0] == 0 && addr32[1] == 0 && addr32[2] == htonl(0xffff)) { - socket_address addr4; - addr4.sa_inet()->set_family(); - addr4.sa_inet()->set_address_n(addr32[3]); - addr4.sa_inet()->set_port_n(m_sockaddr.sin6_port); - return addr4; - } - return *reinterpret_cast(this); -} - -inline bool -socket_address_inet6::operator == (const socket_address_inet6& rhs) const { - return - memcmp(&m_sockaddr.sin6_addr, &rhs.m_sockaddr.sin6_addr, sizeof(in6_addr)) == 0 && - m_sockaddr.sin6_port == rhs.m_sockaddr.sin6_port; -} - -inline bool -socket_address_inet6::operator < (const socket_address_inet6& rhs) const { - int addr_comp = memcmp(&m_sockaddr.sin6_addr, &rhs.m_sockaddr.sin6_addr, sizeof(in6_addr)); - return - addr_comp < 0 || - (addr_comp == 0 || - m_sockaddr.sin6_port < rhs.m_sockaddr.sin6_port); -} - -} - -#endif diff --git a/src/command_download.cc b/src/command_download.cc index 4e45f88b..f86ec38c 100644 --- a/src/command_download.cc +++ b/src/command_download.cc @@ -6,9 +6,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -104,22 +102,19 @@ apply_d_change_link(core::Download* download, const torrent::Object::list_type& switch (changeType) { case 0: - if (symlink(target.c_str(), link.c_str()) == -1){ - lt_log_print(torrent::LOG_TORRENT_WARN, "create_link failed: %s", - rak::error_number::current().c_str()); - } + if (symlink(target.c_str(), link.c_str()) == -1) + lt_log_print(torrent::LOG_TORRENT_WARN, "create_link failed: %s", std::strerror(errno)); + break; case 1: { rak::file_stat fileStat; - rak::error_number::clear_global(); + errno = 0; + + if (!fileStat.update_link(link) || !fileStat.is_link() || unlink(link.c_str()) == -1) + lt_log_print(torrent::LOG_TORRENT_WARN, "delete_link failed: %s", std::strerror(errno)); - if (!fileStat.update_link(link) || !fileStat.is_link() || - unlink(link.c_str()) == -1){ - lt_log_print(torrent::LOG_TORRENT_WARN, "delete_link failed: %s", - rak::error_number::current().c_str()); - } break; } default: @@ -137,7 +132,7 @@ apply_d_delete_tied(core::Download* download) { return torrent::Object(); if (::unlink(rak::path_expand(tie).c_str()) == -1) - control->core()->push_log_std("Could not unlink tied file: " + std::string(rak::error_number::current().c_str())); + control->core()->push_log_std("Could not unlink tied file: " + std::string(std::strerror(errno))); rpc::call_command("d.tied_to_file.set", std::string(), rpc::make_target(download)); return torrent::Object(); diff --git a/src/command_network.cc b/src/command_network.cc index e4d5fdd5..7ebbba50 100644 --- a/src/command_network.cc +++ b/src/command_network.cc @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -86,8 +87,7 @@ apply_scgi(const std::string& arg, int type) { rpc::SCgi* scgi = new rpc::SCgi; rak::address_info* ai = NULL; - rak::socket_address sa; - rak::socket_address* saPtr; + torrent::sa_unique_ptr sa; try { int port, err; @@ -98,17 +98,17 @@ apply_scgi(const std::string& arg, int type) { switch (type) { case 1: if (std::sscanf(arg.c_str(), ":%i%c", &port, &dummy) == 1) { - sa.sa_inet()->clear(); - saPtr = &sa; + sa = torrent::sa_make_inet(); lt_log_print(torrent::LOG_RPC_EVENTS, "SCGI socket is open to any address and is a security risk"); } else if (std::sscanf(arg.c_str(), "%1023[^:]:%i%c", address, &port, &dummy) == 2 || std::sscanf(arg.c_str(), "[%64[^]]]:%i%c", address, &port, &dummy) == 2) { // [xx::xx]:port format - if ((err = rak::address_info::get_address_info(address,PF_UNSPEC, SOCK_STREAM, &ai)) != 0) + + if ((err = rak::address_info::get_address_info(address, PF_UNSPEC, SOCK_STREAM, &ai)) != 0) throw torrent::input_error("Could not bind address: " + std::string(rak::address_info::strerror(err)) + "."); - saPtr = ai->address(); + sa = torrent::sa_copy(ai->c_addrinfo()->ai_addr); lt_log_print(torrent::LOG_RPC_EVENTS, "SCGI socket is bound to an address and might be a security risk"); @@ -119,8 +119,8 @@ apply_scgi(const std::string& arg, int type) { if (port <= 0 || port >= (1 << 16)) throw torrent::input_error("Invalid port number."); - saPtr->set_port(port); - scgi->open_port(saPtr, saPtr->length(), rpc::call_command_value("network.scgi.dont_route")); + torrent::sap_set_port(sa, port); + scgi->open_port(sa.get(), torrent::sap_length(sa), rpc::call_command_value("network.scgi.dont_route")); break; diff --git a/src/command_peer.cc b/src/command_peer.cc index 3f9a56d0..8a1a1658 100644 --- a/src/command_peer.cc +++ b/src/command_peer.cc @@ -1,45 +1,9 @@ -// rTorrent - BitTorrent client -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell - - #include "config.h" -#include -#include -#include #include #include #include +#include #include #include #include @@ -67,17 +31,18 @@ retrieve_p_id_html(torrent::Peer* peer) { torrent::Object retrieve_p_address(torrent::Peer* peer) { - const rak::socket_address *addr = rak::socket_address::cast_from(peer->peer_info()->socket_address()); + auto sa = peer->peer_info()->socket_address(); + auto addr_str = torrent::sa_addr_str(sa); - if (addr->family() == rak::socket_address::af_inet6) - return "[" + addr->address_str() + "]"; - else - return addr->address_str(); + if (sa->sa_family == AF_INET6) + return "[" + addr_str + "]"; + + return addr_str; } torrent::Object retrieve_p_port(torrent::Peer* peer) { - return rak::socket_address::cast_from(peer->peer_info()->socket_address())->port(); + return torrent::sa_port(peer->peer_info()->socket_address()); } torrent::Object diff --git a/src/command_throttle.cc b/src/command_throttle.cc index 40232b89..4e8e86a5 100644 --- a/src/command_throttle.cc +++ b/src/command_throttle.cc @@ -1,47 +1,14 @@ -// rTorrent - BitTorrent client -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell - - #include "config.h" #include -#include #include #include #include +#include #include "core/manager.h" #include "ui/root.h" +#include "rak/address_info.h" #include "rpc/parse.h" #include "rpc/parse_commands.h" @@ -57,13 +24,16 @@ parse_address_range(const torrent::Object::list_type& args, torrent::Object::lis rak::address_info* ai; ret = std::sscanf(itr->as_string().c_str(), "%1023[^/]/%d%c", host, &prefixWidth, &dummy); + if (ret < 1 || rak::address_info::get_address_info(host, PF_INET, SOCK_STREAM, &ai) != 0) throw torrent::input_error("Could not resolve host."); uint32_t begin, end; - rak::socket_address sa; - sa.copy(*ai->address(), ai->length()); - begin = end = sa.sa_inet()->address_h(); + auto sa = torrent::sa_copy(ai->c_addrinfo()->ai_addr); + auto sa_addr = htonl(reinterpret_cast(sa.get())->sin_addr.s_addr); + + begin = end = sa_addr; + rak::address_info::free_address_info(ai); if (ret == 2) { @@ -71,18 +41,21 @@ parse_address_range(const torrent::Object::list_type& args, torrent::Object::lis throw torrent::input_error("Cannot specify both network and range end."); uint32_t netmask = std::numeric_limits::max() << (32 - prefixWidth); - if (prefixWidth >= 32 || sa.sa_inet()->address_h() & ~netmask) + + if (prefixWidth >= 32 || sa_addr & ~netmask) throw torrent::input_error("Invalid address/prefix."); - end = sa.sa_inet()->address_h() | ~netmask; + end = sa_addr | ~netmask; } else if (++itr != args.end()) { if (rak::address_info::get_address_info(itr->as_string().c_str(), PF_INET, SOCK_STREAM, &ai) != 0) throw torrent::input_error("Could not resolve host."); - sa.copy(*ai->address(), ai->length()); + sa = torrent::sa_copy(ai->c_addrinfo()->ai_addr); + sa_addr = htonl(reinterpret_cast(sa.get())->sin_addr.s_addr); + rak::address_info::free_address_info(ai); - end = sa.sa_inet()->address_h(); + end = sa_addr; } // convert to [begin, end) making sure the end doesn't overflow diff --git a/src/core/manager.cc b/src/core/manager.cc index 81ea6f9b..583e0704 100644 --- a/src/core/manager.cc +++ b/src/core/manager.cc @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -99,7 +98,10 @@ Manager::set_address_throttle(uint32_t begin, uint32_t end, torrent::ThrottlePai torrent::ThrottlePair Manager::get_address_throttle(const sockaddr* addr) { - return m_addressThrottles.get(rak::socket_address::cast_from(addr)->sa_inet()->address_h(), torrent::ThrottlePair(nullptr, nullptr)); + if (addr->sa_family != AF_INET) + return torrent::ThrottlePair(nullptr, nullptr); + + return m_addressThrottles.get(ntohl(reinterpret_cast(addr)->sin_addr.s_addr), torrent::ThrottlePair(nullptr, nullptr)); } int64_t @@ -182,7 +184,7 @@ Manager::listen_open() { return; } - throw torrent::input_error("Could not open/bind port for listening: " + std::string(rak::error_number::current().c_str())); + throw torrent::input_error("Could not open/bind port for listening: " + std::string(std::strerror(errno))); } void @@ -198,12 +200,12 @@ Manager::set_bind_address(const std::string& addr) { if (torrent::connection_manager()->is_listen_open()) { torrent::connection_manager()->listen_close(); - torrent::config::network_config()->set_bind_address(ai->address()->c_sockaddr()); + torrent::config::network_config()->set_bind_address(ai->c_addrinfo()->ai_addr); listen_open(); } else { - torrent::config::network_config()->set_bind_address(ai->address()->c_sockaddr()); + torrent::config::network_config()->set_bind_address(ai->c_addrinfo()->ai_addr); } rak::address_info::free_address_info(ai); @@ -224,7 +226,7 @@ Manager::set_local_address(const std::string& addr) { throw torrent::input_error("Could not set local address: " + std::string(rak::address_info::strerror(err)) + "."); try { - torrent::config::network_config()->set_local_address(ai->address()->c_sockaddr()); + torrent::config::network_config()->set_local_address(ai->c_addrinfo()->ai_addr); rak::address_info::free_address_info(ai); @@ -254,8 +256,10 @@ Manager::set_proxy_address(const std::string& addr) { try { - ai->address()->set_port(port); - torrent::config::network_config()->set_proxy_address(ai->address()->c_sockaddr()); + auto sa = torrent::sa_copy(ai->c_addrinfo()->ai_addr); + torrent::sap_set_port(sa, port); + + torrent::config::network_config()->set_proxy_address(sa.get()); rak::address_info::free_address_info(ai); diff --git a/src/display/utils.cc b/src/display/utils.cc index 7547eb7c..76fc34bf 100644 --- a/src/display/utils.cc +++ b/src/display/utils.cc @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -31,7 +30,7 @@ namespace display { char* -print_string(char* first, char* last, char* str) { +print_string(char* first, char* last, const char* str) { if (first == last) return first; @@ -80,17 +79,9 @@ print_ddmmyyyy(char* first, char* last, time_t t) { return print_buffer(first, last, "%02u/%02u/%04u", u->tm_mday, (u->tm_mon + 1), (1900 + u->tm_year)); } -char* -print_address(char* first, char* last, const rak::socket_address* sa) { - if (!sa->address_c_str(first, last - first)) - return first; - - return std::find(first, last, '\0'); -} - inline char* print_address(char* first, char* last, const sockaddr* sa) { - return print_address(first, last, rak::socket_address::cast_from(sa)); + return print_string(first, last, torrent::sa_addr_str(sa).c_str()); } char* diff --git a/src/display/window_peer_list.cc b/src/display/window_peer_list.cc index 5396c020..397b5ff1 100644 --- a/src/display/window_peer_list.cc +++ b/src/display/window_peer_list.cc @@ -1,10 +1,10 @@ #include "config.h" #include -#include #include #include #include +#include #include #include @@ -63,7 +63,7 @@ WindowPeerList::redraw() { x = 0; - std::string ip_address = rak::socket_address::cast_from(p->address())->address_str(); + auto ip_address = torrent::sa_addr_str(p->address()); if (ip_address.size() >= 24) { ip_address.replace(ip_address.begin() + 21, ip_address.end(), "..."); @@ -92,7 +92,7 @@ WindowPeerList::redraw() { peerType = 'u'; else if (p->peer_info()->is_preferred()) peerType = 'p'; - else + else peerType = ' '; m_canvas->print(x, y, "%c%c/%c%c/%c%c", diff --git a/src/rpc/scgi.cc b/src/rpc/scgi.cc index 9b972585..bf24959e 100644 --- a/src/rpc/scgi.cc +++ b/src/rpc/scgi.cc @@ -1,13 +1,13 @@ #include "config.h" #include -#include -#include #include #include #include #include #include +#include +#include #include "control.h" #include "globals.h" @@ -41,7 +41,7 @@ void SCgi::open_port(void* sa, unsigned int length, bool dontRoute) { if (!get_fd().open_stream() || (dontRoute && !get_fd().set_dont_route(true))) - throw torrent::resource_error("Could not open socket for listening: " + std::string(rak::error_number::current().c_str())); + throw torrent::resource_error("Could not open socket for listening: " + std::string(std::strerror(errno))); open(sa, length); } @@ -51,8 +51,8 @@ SCgi::open_named(const std::string& filename) { if (filename.empty() || filename.size() > 4096) throw torrent::resource_error("Invalid filename length."); - char buffer[sizeof(sockaddr_un) + filename.size()]; - sockaddr_un* sa = reinterpret_cast(buffer); + auto buffer = std::make_unique(sizeof(sockaddr_un) + filename.size()); + sockaddr_un* sa = reinterpret_cast(buffer.get()); #ifdef __sun__ sa->sun_family = AF_UNIX; @@ -74,9 +74,9 @@ SCgi::open(void* sa, unsigned int length) { try { if (!get_fd().set_nonblock() || !get_fd().set_reuse_address(true) || - !get_fd().bind(*reinterpret_cast(sa), length) || + !get_fd().bind_sa(reinterpret_cast(sa), length) || !get_fd().listen(max_tasks)) - throw torrent::resource_error("Could not prepare socket for listening: " + std::string(rak::error_number::current().c_str())); + throw torrent::resource_error("Could not prepare socket for listening: " + std::string(std::strerror(errno))); torrent::connection_manager()->inc_socket_count(); @@ -108,18 +108,27 @@ SCgi::deactivate() { void SCgi::event_read() { - rak::socket_address sa; - utils::SocketFd fd; + while (true) { + int fd; + torrent::sa_unique_ptr sa; + + std::tie(fd, sa) = torrent::fd_accept(get_fd().get_fd()); + + if (fd == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK) + break; + + throw torrent::resource_error("Listener port accept() failed: " + std::string(std::strerror(errno))); + } - while ((fd = get_fd().accept(&sa)).is_valid()) { SCgiTask* task = std::find_if(m_task, m_task + max_tasks, std::mem_fn(&SCgiTask::is_available)); if (task == m_task + max_tasks) { - fd.close(); + torrent::fd_close(fd); continue; } - task->open(this, fd.get_fd()); + task->open(this, fd); } } diff --git a/src/utils/socket_fd.cc b/src/utils/socket_fd.cc index a466a3f8..515627ab 100644 --- a/src/utils/socket_fd.cc +++ b/src/utils/socket_fd.cc @@ -1,37 +1,3 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell - - #include "config.h" #include @@ -44,9 +10,9 @@ #include #include #include -#include - #include +#include + #include "socket_fd.h" namespace utils { @@ -131,11 +97,11 @@ SocketFd::get_error() const { bool SocketFd::open_stream() { - m_fd = socket(rak::socket_address::pf_inet6, SOCK_STREAM, IPPROTO_TCP); + m_fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); if (m_fd == -1) { m_ipv6_socket = false; - return (m_fd = socket(rak::socket_address::pf_inet, SOCK_STREAM, IPPROTO_TCP)) != -1; + return (m_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) != -1; } m_ipv6_socket = true; @@ -146,10 +112,10 @@ SocketFd::open_stream() { bool SocketFd::open_datagram() { - m_fd = socket(rak::socket_address::pf_inet6, SOCK_DGRAM, 0); + m_fd = socket(AF_INET6, SOCK_DGRAM, 0); if (m_fd == -1) { m_ipv6_socket = false; - return (m_fd = socket(rak::socket_address::pf_inet, SOCK_DGRAM, 0)) != -1; + return (m_fd = socket(AF_INET, SOCK_DGRAM, 0)) != -1; } m_ipv6_socket = true; @@ -159,7 +125,7 @@ SocketFd::open_datagram() { bool SocketFd::open_local() { - return (m_fd = socket(rak::socket_address::pf_local, SOCK_STREAM, 0)) != -1; + return (m_fd = socket(AF_LOCAL, SOCK_STREAM, 0)) != -1; } void @@ -169,55 +135,18 @@ SocketFd::close() { } bool -SocketFd::bind(const rak::socket_address& sa) { +SocketFd::bind_sa(const sockaddr* sa, unsigned int length) { check_valid(); - if (m_ipv6_socket && sa.family() == rak::socket_address::pf_inet) { - rak::socket_address_inet6 sa_mapped = sa.sa_inet()->to_mapped_address(); - return !::bind(m_fd, sa_mapped.c_sockaddr(), sizeof(sa_mapped)); + if (m_ipv6_socket && sa->sa_family == AF_INET) { + if (length < sizeof(sockaddr_in)) + throw torrent::input_error("SocketFd::bind_sa: invalid sockaddr length for AF_INET"); + + auto mapped_sa = torrent::sin6_to_v4mapped_in(reinterpret_cast(sa)); + return !::bind(m_fd, reinterpret_cast(mapped_sa.get()), sizeof(sockaddr_in6)); } - return !::bind(m_fd, sa.c_sockaddr(), sa.length()); -} - -bool -SocketFd::bind(const rak::socket_address& sa, unsigned int length) { - check_valid(); - - if (m_ipv6_socket && sa.family() == rak::socket_address::pf_inet) { - rak::socket_address_inet6 sa_mapped = sa.sa_inet()->to_mapped_address(); - return !::bind(m_fd, sa_mapped.c_sockaddr(), sizeof(sa_mapped)); - } - - return !::bind(m_fd, sa.c_sockaddr(), length); -} - -bool -SocketFd::connect(const rak::socket_address& sa) { - check_valid(); - - if (m_ipv6_socket && sa.family() == rak::socket_address::pf_inet) { - rak::socket_address_inet6 sa_mapped = sa.sa_inet()->to_mapped_address(); - return !::connect(m_fd, sa_mapped.c_sockaddr(), sizeof(sa_mapped)) || errno == EINPROGRESS; - } - - return !::connect(m_fd, sa.c_sockaddr(), sa.length()) || errno == EINPROGRESS; -} - -bool -SocketFd::getsockname(rak::socket_address *sa) { - check_valid(); - - socklen_t len = sizeof(rak::socket_address); - if (::getsockname(m_fd, sa->c_sockaddr(), &len)) { - return false; - } - - if (m_ipv6_socket && sa->family() == rak::socket_address::af_inet6) { - *sa = sa->sa_inet6()->normalize_address(); - } - - return true; + return !::bind(m_fd, sa, length); } bool @@ -227,39 +156,4 @@ SocketFd::listen(int size) { return !::listen(m_fd, size); } -SocketFd -SocketFd::accept(rak::socket_address* sa) { - check_valid(); - socklen_t len = sizeof(rak::socket_address); - - if (sa == NULL) { - return SocketFd(::accept(m_fd, NULL, &len)); - } - int fd = ::accept(m_fd, sa->c_sockaddr(), &len); - if (fd != -1 && m_ipv6_socket && sa->family() == rak::socket_address::af_inet6) { - *sa = sa->sa_inet6()->normalize_address(); - } - return SocketFd(fd); -} - -// unsigned int -// SocketFd::get_read_queue_size() const { -// unsigned int v; - -// if (!is_valid() || ioctl(m_fd, SIOCINQ, &v) < 0) -// throw internal_error("SocketFd::get_read_queue_size() could not be performed"); - -// return v; -// } - -// unsigned int -// SocketFd::get_write_queue_size() const { -// unsigned int v; - -// if (!is_valid() || ioctl(m_fd, SIOCOUTQ, &v) < 0) -// throw internal_error("SocketFd::get_write_queue_size() could not be performed"); - -// return v; -// } - } diff --git a/src/utils/socket_fd.h b/src/utils/socket_fd.h index e959692e..2efce097 100644 --- a/src/utils/socket_fd.h +++ b/src/utils/socket_fd.h @@ -1,45 +1,9 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell - - #ifndef RTORRENT_UTILS_SOCKET_FD_H #define RTORRENT_UTILS_SOCKET_FD_H +#include #include - -namespace rak { - class socket_address; -} +#include namespace utils { @@ -51,7 +15,7 @@ public: explicit SocketFd(int fd) : m_fd(fd) {} bool is_valid() const { return m_fd >= 0; } - + int get_fd() const { return m_fd; } void set_fd(int fd) { m_fd = fd; } @@ -75,16 +39,9 @@ public: void clear() { m_fd = -1; } - bool bind(const rak::socket_address& sa); - bool bind(const rak::socket_address& sa, unsigned int length); - bool connect(const rak::socket_address& sa); - bool getsockname(rak::socket_address* sa); + bool bind_sa(const sockaddr* sa, unsigned int length); bool listen(int size); - SocketFd accept(rak::socket_address* sa); - -// unsigned int get_read_queue_size() const; -// unsigned int get_write_queue_size() const; private: inline void check_valid() const;