Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 246400 Details for
Bug 336386
net-p2p/rtorrent and net-libs/libtorrent : added ipv6 support
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
patch that adds ipv6 support
rtorrent-0.8.6-ipv6-07.patch (text/plain), 18.37 KB, created by
Maik Nijhuis
on 2010-09-07 21:01:35 UTC
(
hide
)
Description:
patch that adds ipv6 support
Filename:
MIME Type:
Creator:
Maik Nijhuis
Created:
2010-09-07 21:01:35 UTC
Size:
18.37 KB
patch
obsolete
>diff -ur rtorrent-0.8.6.orig/rak/socket_address.h rtorrent-0.8.6/rak/socket_address.h >--- rtorrent-0.8.6.orig/rak/socket_address.h 2009-11-12 09:03:48.000000000 +0100 >+++ rtorrent-0.8.6/rak/socket_address.h 2010-07-23 14:45:07.000000000 +0200 >@@ -145,7 +145,7 @@ > }; > }; > >-// Remeber to set the AF_INET. >+// Remember to set the AF_INET. > > class socket_address_inet { > public: >@@ -184,6 +184,10 @@ > > const sockaddr* c_sockaddr() const { return reinterpret_cast<const sockaddr*>(&m_sockaddr); } > const sockaddr_in* c_sockaddr_inet() const { return &m_sockaddr; } >+ >+#ifdef RAK_USE_INET6 >+ socket_address_inet6 to_mapped_address() const; >+#endif > > bool operator == (const socket_address_inet& rhs) const; > bool operator < (const socket_address_inet& rhs) const; >@@ -192,6 +196,52 @@ > struct sockaddr_in m_sockaddr; > }; > >+#ifdef RAK_USE_INET6 >+// Remember to set the AF_INET6. >+ >+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; } >+ 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); } >+ >+ 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<sockaddr*>(&m_sockaddr); } >+ sockaddr_in6* c_sockaddr_inet6() { return &m_sockaddr; } >+ >+ const sockaddr* c_sockaddr() const { return reinterpret_cast<const sockaddr*>(&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; >+}; >+#endif >+ > // Unique key for the address, excluding port numbers etc. > class socket_address_key { > public: >@@ -241,8 +291,10 @@ > switch (family()) { > case af_inet: > return sa_inet()->is_valid(); >-// case af_inet6: >-// return sa_inet6().is_valid(); >+#ifdef RAK_USE_INET6 >+ case af_inet6: >+ return sa_inet6()->is_valid(); >+#endif > default: > return false; > } >@@ -253,6 +305,10 @@ > switch (family()) { > case af_inet: > return !sa_inet()->is_address_any(); >+#ifdef RAK_USE_INET6 >+ case af_inet6: >+ return !sa_inet6()->is_address_any(); >+#endif > default: > return false; > } >@@ -263,6 +319,10 @@ > switch (family()) { > case af_inet: > return sa_inet()->is_address_any(); >+#ifdef RAK_USE_INET6 >+ case af_inet6: >+ return sa_inet6()->is_address_any(); >+#endif > default: > return true; > } >@@ -273,6 +333,10 @@ > switch (family()) { > case af_inet: > return sa_inet()->port(); >+#ifdef RAK_USE_INET6 >+ case af_inet6: >+ return sa_inet6()->port(); >+#endif > default: > return 0; > } >@@ -283,6 +347,10 @@ > switch (family()) { > case af_inet: > return sa_inet()->set_port(p); >+#ifdef RAK_USE_INET6 >+ case af_inet6: >+ return sa_inet6()->set_port(p); >+#endif > default: > break; > } >@@ -293,6 +361,10 @@ > switch (family()) { > case af_inet: > return sa_inet()->address_str(); >+#ifdef RAK_USE_INET6 >+ case af_inet6: >+ return sa_inet6()->address_str(); >+#endif > default: > return std::string(); > } >@@ -303,6 +375,10 @@ > switch (family()) { > case af_inet: > return sa_inet()->address_c_str(buf, size); >+#ifdef RAK_USE_INET6 >+ case af_inet6: >+ return sa_inet6()->address_c_str(buf, size); >+#endif > default: > return false; > } >@@ -314,6 +390,12 @@ > sa_inet()->set_family(); > return true; > >+#ifdef RAK_USE_INET6 >+ } else if (sa_inet6()->set_address_c_str(a)) { >+ sa_inet6()->set_family(); >+ return true; >+#endif >+ > } else { > return false; > } >@@ -325,6 +407,10 @@ > switch(family()) { > case af_inet: > return sizeof(sockaddr_in); >+#ifdef RAK_USE_INET6 >+ case af_inet6: >+ return sizeof(sockaddr_in6); >+#endif > default: > return 0; > } >@@ -349,8 +435,10 @@ > switch (family()) { > case af_inet: > return *sa_inet() == *rhs.sa_inet(); >-// case af_inet6: >-// return *sa_inet6() == *rhs.sa_inet6(); >+#ifdef RAK_USE_INET6 >+ case af_inet6: >+ return *sa_inet6() == *rhs.sa_inet6(); >+#endif > default: > throw std::logic_error("socket_address::operator == (rhs) invalid type comparison."); > } >@@ -364,8 +452,10 @@ > switch (family()) { > case af_inet: > return *sa_inet() < *rhs.sa_inet(); >-// case af_inet6: >-// return *sa_inet6() < *rhs.sa_inet6(); >+#ifdef RAK_USE_INET6 >+ case af_inet6: >+ return *sa_inet6() < *rhs.sa_inet6(); >+#endif > default: > throw std::logic_error("socket_address::operator < (rhs) invalid type comparison."); > } >@@ -391,6 +481,23 @@ > return inet_pton(AF_INET, a, &m_sockaddr.sin_addr); > } > >+#ifdef RAK_USE_INET6 >+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<in6_addr *>(addr32)); >+ sa.set_port_n(m_sockaddr.sin_port); >+ return sa; >+} >+#endif >+ > inline bool > socket_address_inet::operator == (const socket_address_inet& rhs) const { > return >@@ -406,6 +513,59 @@ > m_sockaddr.sin_port < rhs.m_sockaddr.sin_port); > } > >+#ifdef RAK_USE_INET6 >+ >+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 socket_address >+socket_address_inet6::normalize_address() const { >+ const uint32_t *addr32 = reinterpret_cast<const uint32_t *>(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<const socket_address*>(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 >+ > } > > #endif >diff -ur rtorrent-0.8.6.orig/src/command_peer.cc rtorrent-0.8.6/src/command_peer.cc >--- rtorrent-0.8.6.orig/src/command_peer.cc 2009-11-12 09:03:48.000000000 +0100 >+++ rtorrent-0.8.6/src/command_peer.cc 2010-07-23 14:45:07.000000000 +0200 >@@ -68,7 +68,13 @@ > > 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 >diff -ur rtorrent-0.8.6.orig/src/core/curl_get.cc rtorrent-0.8.6/src/core/curl_get.cc >--- rtorrent-0.8.6.orig/src/core/curl_get.cc 2009-11-12 09:03:44.000000000 +0100 >+++ rtorrent-0.8.6/src/core/curl_get.cc 2010-07-23 14:45:07.000000000 +0200 >@@ -88,8 +88,20 @@ > 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); >+ >+ // Even when IPv6-enabled, we don't want to use CURL_IPRESOLVE_WHATEVER, >+ // since that will usually prefer connecting over IPv6 to the tracker. >+ // Since it's usually a lot easier to find our global IPv6 address >+ // (if we have one) than our global IPv4 address, we prefer connecting >+ // over IPv4 if we can, so that the tracker will get our IPv4 address >+ // that way. If the resolve fails, CurlStack will call retry_ipv6() >+ // on us and we'll make a second attempt with CURL_IPRESOLVE_V6. > curl_easy_setopt(m_handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); >+ > curl_easy_setopt(m_handle, CURLOPT_ENCODING, ""); >+#ifdef RAK_USE_INET6 >+ m_ipv6 = false; >+#endif > > m_stack->add_get(this); > } >@@ -107,6 +119,17 @@ > 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"); >diff -ur rtorrent-0.8.6.orig/src/core/curl_get.h rtorrent-0.8.6/src/core/curl_get.h >--- rtorrent-0.8.6.orig/src/core/curl_get.h 2009-11-12 09:03:44.000000000 +0100 >+++ rtorrent-0.8.6/src/core/curl_get.h 2010-07-23 14:45:07.000000000 +0200 >@@ -56,6 +56,10 @@ > > 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; } >@@ -74,6 +78,9 @@ > void receive_timeout(); > > bool m_active; >+#ifdef RAK_USE_INET6 >+ bool m_ipv6; >+#endif > > rak::priority_item m_taskTimeout; > >diff -ur rtorrent-0.8.6.orig/src/core/curl_stack.cc rtorrent-0.8.6/src/core/curl_stack.cc >--- rtorrent-0.8.6.orig/src/core/curl_stack.cc 2009-11-12 09:03:44.000000000 +0100 >+++ rtorrent-0.8.6/src/core/curl_stack.cc 2010-07-23 14:45:07.000000000 +0200 >@@ -111,6 +111,21 @@ > if (msg->msg != CURLMSG_DONE) > throw torrent::internal_error("CurlStack::receive_action() msg->msg != CURLMSG_DONE."); > >+#ifdef RAK_USE_INET6 >+ 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."); >+ continue; >+ } >+ } else >+#endif > transfer_done(msg->easy_handle, msg->data.result == CURLE_OK ? NULL : curl_easy_strerror(msg->data.result)); > } > >diff -ur rtorrent-0.8.6.orig/src/display/window_peer_list.cc rtorrent-0.8.6/src/display/window_peer_list.cc >--- rtorrent-0.8.6.orig/src/display/window_peer_list.cc 2009-11-12 09:03:47.000000000 +0100 >+++ rtorrent-0.8.6/src/display/window_peer_list.cc 2010-07-23 14:45:07.000000000 +0200 >@@ -68,7 +68,11 @@ > 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 @@ > > 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; >diff -ur rtorrent-0.8.6.orig/src/utils/socket_fd.cc rtorrent-0.8.6/src/utils/socket_fd.cc >--- rtorrent-0.8.6.orig/src/utils/socket_fd.cc 2009-11-12 09:03:46.000000000 +0100 >+++ rtorrent-0.8.6/src/utils/socket_fd.cc 2010-07-23 23:11:07.000000000 +0200 >@@ -71,6 +71,11 @@ > 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 @@ > > 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 @@ > 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 @@ > 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,10 +208,34 @@ > 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 @@ > 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 >diff -ur rtorrent-0.8.6.orig/src/utils/socket_fd.h rtorrent-0.8.6/src/utils/socket_fd.h >--- rtorrent-0.8.6.orig/src/utils/socket_fd.h 2009-11-12 09:03:46.000000000 +0100 >+++ rtorrent-0.8.6/src/utils/socket_fd.h 2010-07-23 14:45:07.000000000 +0200 >@@ -80,6 +80,7 @@ > 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 @@ > inline void check_valid() const; > > int m_fd; >+#ifdef RAK_USE_INET6 >+ bool m_ipv6_socket; >+#endif > }; > > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 336386
:
246399
| 246400 |
246402
|
246404