mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-15 14:42:30 +00:00
Added ipv6 patch.
This commit is contained in:
@@ -308,7 +308,13 @@ apply_d_add_peer(core::Download* download, const std::string& arg) {
|
||||
if (download->download()->info()->is_private())
|
||||
throw torrent::input_error("Download is private.");
|
||||
|
||||
#ifdef RAK_USE_INET6
|
||||
ret = std::sscanf(arg.c_str(), "[%64[^]]]:%i%c", host, &port, &dummy);
|
||||
if (ret < 1)
|
||||
ret = std::sscanf(arg.c_str(), "%1023[^:]:%i%c", host, &port, &dummy);
|
||||
#else
|
||||
ret = std::sscanf(arg.c_str(), "%1023[^:]:%i%c", host, &port, &dummy);
|
||||
#endif
|
||||
|
||||
if (ret == 1)
|
||||
port = 6881;
|
||||
@@ -318,7 +324,11 @@ apply_d_add_peer(core::Download* download, const std::string& arg) {
|
||||
if (port < 1 || port > 65535)
|
||||
throw torrent::input_error("Invalid port number.");
|
||||
|
||||
#ifdef RAK_USE_INET6
|
||||
torrent::connection_manager()->resolver()(host, (int)rak::socket_address::pf_unspec, SOCK_STREAM, call_add_d_peer_t(download, port));
|
||||
#else
|
||||
torrent::connection_manager()->resolver()(host, (int)rak::socket_address::pf_inet, SOCK_STREAM, call_add_d_peer_t(download, port));
|
||||
#endif
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
|
||||
@@ -170,8 +170,13 @@ apply_scgi(const std::string& arg, int type) {
|
||||
lt_log_print(torrent::LOG_RPC_EVENTS,
|
||||
"The SCGI socket has not been bound to any address and likely poses a security risk.");
|
||||
|
||||
#ifdef RAK_USE_INET6
|
||||
} 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
|
||||
#else
|
||||
} else if (std::sscanf(arg.c_str(), "%1023[^:]:%i%c", address, &port, &dummy) == 2) {
|
||||
if ((err = rak::address_info::get_address_info(address, PF_INET, SOCK_STREAM, &ai)) != 0)
|
||||
#endif
|
||||
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();
|
||||
|
||||
+7
-1
@@ -69,7 +69,13 @@ retrieve_p_id_html(torrent::Peer* peer) {
|
||||
|
||||
torrent::Object
|
||||
retrieve_p_address(torrent::Peer* peer) {
|
||||
return rak::socket_address::cast_from(peer->peer_info()->socket_address())->address_str();
|
||||
const rak::socket_address *addr = rak::socket_address::cast_from(peer->peer_info()->socket_address());
|
||||
#ifdef RAK_USE_INET6
|
||||
if (addr->family() == rak::socket_address::af_inet6)
|
||||
return "[" + addr->address_str() + "]";
|
||||
else
|
||||
#endif
|
||||
return addr->address_str();
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
|
||||
+17
-1
@@ -91,8 +91,13 @@ CurlGet::start() {
|
||||
curl_easy_setopt(m_handle, CURLOPT_NOSIGNAL, (long)1);
|
||||
curl_easy_setopt(m_handle, CURLOPT_FOLLOWLOCATION, (long)1);
|
||||
curl_easy_setopt(m_handle, CURLOPT_MAXREDIRS, (long)5);
|
||||
curl_easy_setopt(m_handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
|
||||
|
||||
curl_easy_setopt(m_handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_WHATEVER);
|
||||
|
||||
curl_easy_setopt(m_handle, CURLOPT_ENCODING, "");
|
||||
#ifdef RAK_USE_INET6
|
||||
m_ipv6 = false;
|
||||
#endif
|
||||
|
||||
m_stack->add_get(this);
|
||||
}
|
||||
@@ -110,6 +115,17 @@ CurlGet::close() {
|
||||
m_handle = NULL;
|
||||
}
|
||||
|
||||
#ifdef RAK_USE_INET6
|
||||
void
|
||||
CurlGet::retry_ipv6() {
|
||||
CURL* nhandle = curl_easy_duphandle(m_handle);
|
||||
curl_easy_setopt(nhandle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6);
|
||||
curl_easy_cleanup(m_handle);
|
||||
m_handle = nhandle;
|
||||
m_ipv6 = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
CurlGet::receive_timeout() {
|
||||
return m_stack->transfer_done(m_handle, "Timed out");
|
||||
|
||||
@@ -57,6 +57,10 @@ public:
|
||||
|
||||
void start();
|
||||
void close();
|
||||
#ifdef RAK_USE_INET6
|
||||
bool is_using_ipv6() { return m_ipv6; }
|
||||
void retry_ipv6();
|
||||
#endif
|
||||
|
||||
bool is_busy() const { return m_handle; }
|
||||
bool is_active() const { return m_active; }
|
||||
@@ -75,6 +79,9 @@ private:
|
||||
void receive_timeout();
|
||||
|
||||
bool m_active;
|
||||
#ifdef RAK_USE_INET6
|
||||
bool m_ipv6;
|
||||
#endif
|
||||
|
||||
rak::priority_item m_taskTimeout;
|
||||
|
||||
|
||||
+17
-2
@@ -132,8 +132,23 @@ CurlStack::process_done_handle() {
|
||||
if (msg->msg != CURLMSG_DONE)
|
||||
throw torrent::internal_error("CurlStack::receive_action() msg->msg != CURLMSG_DONE.");
|
||||
|
||||
transfer_done(msg->easy_handle,
|
||||
msg->data.result == CURLE_OK ? NULL : curl_easy_strerror(msg->data.result));
|
||||
if (msg->data.result == CURLE_COULDNT_RESOLVE_HOST) {
|
||||
iterator itr = std::find_if(begin(), end(), rak::equal(msg->easy_handle, std::mem_fun(&CurlGet::handle)));
|
||||
|
||||
if (itr == end())
|
||||
throw torrent::internal_error("Could not find CurlGet when calling CurlStack::receive_action.");
|
||||
|
||||
if (!(*itr)->is_using_ipv6()) {
|
||||
(*itr)->retry_ipv6();
|
||||
|
||||
if (curl_multi_add_handle((CURLM*)m_handle, (*itr)->handle()) > 0)
|
||||
throw torrent::internal_error("Error calling curl_multi_add_handle.");
|
||||
}
|
||||
|
||||
} else {
|
||||
transfer_done(msg->easy_handle,
|
||||
msg->data.result == CURLE_OK ? NULL : curl_easy_strerror(msg->data.result));
|
||||
}
|
||||
|
||||
return remaining_msgs != 0;
|
||||
}
|
||||
|
||||
@@ -228,7 +228,13 @@ Manager::set_bind_address(const std::string& addr) {
|
||||
int err;
|
||||
rak::address_info* ai;
|
||||
|
||||
|
||||
#ifdef RAK_USE_INET6
|
||||
if ((err = rak::address_info::get_address_info(addr.c_str(), PF_INET, SOCK_STREAM, &ai)) != 0 &&
|
||||
(err = rak::address_info::get_address_info(addr.c_str(), PF_INET6, SOCK_STREAM, &ai)) != 0)
|
||||
#else
|
||||
if ((err = rak::address_info::get_address_info(addr.c_str(), PF_INET, SOCK_STREAM, &ai)) != 0)
|
||||
#endif
|
||||
throw torrent::input_error("Could not set bind address: " + std::string(rak::address_info::strerror(err)) + ".");
|
||||
|
||||
try {
|
||||
@@ -262,7 +268,12 @@ Manager::set_local_address(const std::string& addr) {
|
||||
int err;
|
||||
rak::address_info* ai;
|
||||
|
||||
#ifdef RAK_USE_INET6
|
||||
if ((err = rak::address_info::get_address_info(addr.c_str(), PF_INET, SOCK_STREAM, &ai)) != 0 &&
|
||||
(err = rak::address_info::get_address_info(addr.c_str(), PF_INET6, SOCK_STREAM, &ai)) != 0)
|
||||
#else
|
||||
if ((err = rak::address_info::get_address_info(addr.c_str(), PF_INET, SOCK_STREAM, &ai)) != 0)
|
||||
#endif
|
||||
throw torrent::input_error("Could not set local address: " + std::string(rak::address_info::strerror(err)) + ".");
|
||||
|
||||
try {
|
||||
|
||||
@@ -68,7 +68,11 @@ WindowPeerList::redraw() {
|
||||
int x = 2;
|
||||
int y = 0;
|
||||
|
||||
m_canvas->print(x, y, "IP"); x += 16;
|
||||
#ifdef RAK_USE_INET6
|
||||
m_canvas->print(x, y, "IP"); x += 25;
|
||||
#else
|
||||
m_canvas->print(x, y, "IP"); x += 16;
|
||||
#endif
|
||||
m_canvas->print(x, y, "UP"); x += 7;
|
||||
m_canvas->print(x, y, "DOWN"); x += 7;
|
||||
m_canvas->print(x, y, "PEER"); x += 7;
|
||||
@@ -99,10 +103,21 @@ WindowPeerList::redraw() {
|
||||
|
||||
x = 0;
|
||||
|
||||
std::string ip_address = rak::socket_address::cast_from(p->address())->address_str();
|
||||
#ifdef RAK_USE_INET6
|
||||
if (ip_address.size() >= 24) {
|
||||
ip_address.replace(ip_address.begin() + 21, ip_address.end(), "...");
|
||||
}
|
||||
#endif
|
||||
|
||||
m_canvas->print(x, y, "%c %s",
|
||||
range.first == *m_focus ? '*' : ' ',
|
||||
rak::socket_address::cast_from(p->address())->address_str().c_str());
|
||||
ip_address.c_str());
|
||||
#ifdef RAK_USE_INET6
|
||||
x += 27;
|
||||
#else
|
||||
x += 18;
|
||||
#endif
|
||||
|
||||
m_canvas->print(x, y, "%.1f", (double)p->up_rate()->rate() / 1024); x += 7;
|
||||
m_canvas->print(x, y, "%.1f", (double)p->down_rate()->rate() / 1024); x += 7;
|
||||
|
||||
@@ -71,6 +71,11 @@ SocketFd::set_priority(priority_type p) {
|
||||
check_valid();
|
||||
int opt = p;
|
||||
|
||||
#ifdef RAK_USE_INET6
|
||||
if (m_ipv6_socket)
|
||||
return setsockopt(m_fd, IPPROTO_IPV6, IPV6_TCLASS, &opt, sizeof(opt)) == 0;
|
||||
else
|
||||
#endif
|
||||
return setsockopt(m_fd, IPPROTO_IP, IP_TOS, &opt, sizeof(opt)) == 0;
|
||||
}
|
||||
|
||||
@@ -130,12 +135,36 @@ SocketFd::get_error() const {
|
||||
|
||||
bool
|
||||
SocketFd::open_stream() {
|
||||
#ifdef RAK_USE_INET6
|
||||
m_fd = socket(rak::socket_address::pf_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;
|
||||
}
|
||||
m_ipv6_socket = true;
|
||||
|
||||
int zero = 0;
|
||||
return setsockopt(m_fd, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero)) != -1;
|
||||
#else
|
||||
return (m_fd = socket(rak::socket_address::pf_inet, SOCK_STREAM, IPPROTO_TCP)) != -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
SocketFd::open_datagram() {
|
||||
#ifdef RAK_USE_INET6
|
||||
m_fd = socket(rak::socket_address::pf_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;
|
||||
}
|
||||
m_ipv6_socket = true;
|
||||
|
||||
int zero = 0;
|
||||
return setsockopt(m_fd, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero)) != -1;
|
||||
#else
|
||||
return (m_fd = socket(rak::socket_address::pf_inet, SOCK_DGRAM, 0)) != -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -153,6 +182,12 @@ bool
|
||||
SocketFd::bind(const rak::socket_address& sa) {
|
||||
check_valid();
|
||||
|
||||
#ifdef RAK_USE_INET6
|
||||
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));
|
||||
}
|
||||
#endif
|
||||
return !::bind(m_fd, sa.c_sockaddr(), sa.length());
|
||||
}
|
||||
|
||||
@@ -160,6 +195,12 @@ bool
|
||||
SocketFd::bind(const rak::socket_address& sa, unsigned int length) {
|
||||
check_valid();
|
||||
|
||||
#ifdef RAK_USE_INET6
|
||||
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));
|
||||
}
|
||||
#endif
|
||||
return !::bind(m_fd, sa.c_sockaddr(), length);
|
||||
}
|
||||
|
||||
@@ -167,9 +208,33 @@ bool
|
||||
SocketFd::connect(const rak::socket_address& sa) {
|
||||
check_valid();
|
||||
|
||||
#ifdef RAK_USE_INET6
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
|
||||
#ifdef RAK_USE_INET6
|
||||
if (m_ipv6_socket && sa->family() == rak::socket_address::af_inet6) {
|
||||
*sa = sa->sa_inet6()->normalize_address();
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SocketFd::listen(int size) {
|
||||
check_valid();
|
||||
@@ -182,7 +247,18 @@ SocketFd::accept(rak::socket_address* sa) {
|
||||
check_valid();
|
||||
socklen_t len = sizeof(rak::socket_address);
|
||||
|
||||
#ifdef RAK_USE_INET6
|
||||
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);
|
||||
#else
|
||||
return SocketFd(::accept(m_fd, sa != NULL ? sa->c_sockaddr() : NULL, &len));
|
||||
#endif
|
||||
}
|
||||
|
||||
// unsigned int
|
||||
|
||||
@@ -80,6 +80,7 @@ public:
|
||||
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 listen(int size);
|
||||
SocketFd accept(rak::socket_address* sa);
|
||||
@@ -91,6 +92,9 @@ private:
|
||||
inline void check_valid() const;
|
||||
|
||||
int m_fd;
|
||||
#ifdef RAK_USE_INET6
|
||||
bool m_ipv6_socket;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user