-
-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enabling listening on tcp port when proxy is used for peer connections #7726
base: RC_2_0
Are you sure you want to change the base?
Enabling listening on tcp port when proxy is used for peer connections #7726
Conversation
@Masong19hippows that link appears to be broken. Is that text posted anywhere else? |
it's not surprising the HTTP proxy specification from 1997 defines proxy as an intermediary for making requests. That was essentially the only thing you could do with HTTP. The Socks5 protocol (which is also called "proxy") does in fact support incoming connections, both over TCP and UDP. I wouldn't consider that text a compelling argument to change libtorrents behavior. I think enumerating the legitimate use cases might be. Either way, if there is a compelling argument, I think it would be best to guard it under a new setting, rather than changing behavior for everyone. |
Unfortunately, it doesn't look like it. However, it still cached on my machine via google amp. I just coped the text article and here it is. Patch qBittorrent: Listening on port while using proxy First things first, to achieve that, we need a proxy where we can set up port forwarding on it, then we modify and compile qbittorrent ourselves. A VPN can work, but that requires UPnP/PMP support of the VPN, which many lacks in. And also, use with caution, if you do not want to expose your IP address accidentally, always use a VPN. Recently, I came across a situation where I need to do some seeding, but the network I was on requires a proxy to gain access to the Internet. Naively, I set up the proxy settings in qbittorrent, quickly found out that it did not work at all. After some long nights searching and digging, it turned out that the library qbittorrent (along with several other FOSS torrenting software) depends on, libtorrent, on some recent versions, completely disables port listening while Use proxy for peer connections is enabled, to avoid network traffic leakage, rendering it impossible to do seeding at all while using a proxy. But the authors never make this clear, and I suspect that qbittorrent authors haven't even realized this behavior. The setting page on qbittorrent doesn't reflect the change in port listening section at all when you enable proxy for peers. So here come the easier parts. We find the corresponding conditional code, modify, patch, then recompile libtorrent. No changes in qbittorrent are needed, only libtorrent. Check out my patch file listen-when-proxy-on.patch based on v2.0.7 of libtorrent at end of this article. Since I'm on archlinux (and yes, BTW, I'm using arch :D), patching software is relatively convenient. Go grab the PKGBUILD script from arch offical package page https://archlinux.org/packages/extra/x86_64/libtorrent-rasterbar/ (source files link), add our patch into prepare() section like this: prepare() { Fire up qbittorrent and set a fixed listening port, say 7890; Disclaimer: qBittorrent and libtorrent are FOSS, the patch shared here is also free from restrictions. Please comply with your local regulations, use with caution and at your own risks. listen-when-proxy-on.patch: diff --git a/src/session_impl.cpp b/src/session_impl.cpp // if we don't proxy peer connections, don't apply the special logic for
@@ -5473,7 +5473,7 @@ namespace {
@@ -5611,7 +5611,7 @@ namespace { if (!s->natpmp_mapper
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one possible way to implement this would be to add a new proxy type, like http_with_local_listen
, or something like that. It would behave like http
but also accept incoming connections
src/session_impl.cpp
Outdated
// the natpmp constructor may fail and call the callbacks | ||
// into the session_impl. | ||
s->natpmp_mapper = std::make_shared<natpmp>(m_io_context, *this, listen_socket_handle(s)); | ||
ip_interface ip; | ||
ip.interface_address = s->local_endpoint.address(); | ||
ip.netmask = s->netmask; | ||
std::strncpy(ip.name, s->device.c_str(), sizeof(ip.name) - 1); | ||
ip.name[sizeof(ip.name) - 1] = '\0'; | ||
s->natpmp_mapper->start(ip); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it doesn't make any sense to disable NAT-PMP entirely. this seems unrelated to the intention of this patch
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this was just a mistake on my end. It was not my intention to disable nat-pmp entirely. Rather, it was to enable the ability to use it regardless of proxy.
It does not. The socks4 protocol specifies bind and connect commands while the socks5 protocol specifies auth and the udp communication commands. Bind in the socks4 protocol is defined as: "The client connects to the SOCKS server and sends a BIND request when and in the socks5 spec: "It is expected that the client side of an application protocol will This is not facilitating inbound connections in the traditional sense, rather it facilitates inbound connections on an already existing outbound connection. In the spec, it used ftp as an example, and I think this is perfect because ftp needs at least 2 connections to the client, one inbound and one outbound. I think this explains it better than I could. If we were to hack the bind command in order to listen and forward ports, the qbittorrent host would first need to send an outbound connect command to all potential leachers. This would require massive changes and its more hacky than it should be. There are applications that extend/break the socks protocol (like ssh) to include the support of inbound connections. However, this is not something outlined in the socks protocol itself, and so it shouldn't be treated as such in my opinion.
I was more just trying to point out that the proxy server itself should not facilitate inbound connections, because this was used in the past issues to justify libtorrent behavior. I have been using this PR with qbittorrent for awhile now and I honestly haven't noticed any issues. Before, the seeding wasn't working well. As for the use cases, I see this as removing an artificial limitation rather than adding a feature. The use case would be that the user would get full seeding/leaching potential. It honestly works so well that I had to limit the number of inbound connections because it overloaded my socks5 server and used all of the ports on my system.
That makes sense. I just did a quick and dirty thing to try and get the conversation started, but I am willing to learn and expand this. |
We can setup reserve proxy/port forwarding on the same server with http/socks proxy. |
I'm unsure what you mean. Can you please elaborate? I get the setup up a reverse proxy type thing and forwarding the port to the socks server, but what would the socks server do with it once it gets that traffic? Socks servers do not accept inbound traffic to forward to a host unless otherwise defined by the socks bind protocol. There's no way to do this with just socks. If I'm getting what you are putting down, I am actually already doing this right now. I am using the patch above to listen to the port while using a proxy, and then using socat to forward the port from the socks server to the qbittorrent host. Qbittorrent should not have anything to do with a reverse proxy though, because the socks host and the qbittorrent host might be on separate machines. Any way you look at it, you can't inheritly forward ports from the socks host to the qbittorrent host with just the socks protocol. |
Your setup is exactly what I mean.
I saw your discussions but I didn't understand why not just patch lt (keep listening with proxy set) and let other tools take care of port forwarding? (e.g. iptables/socat/frp/...)
…________________________________
From: Mason Garten ***@***.***>
Sent: Tuesday, October 8, 2024 9:45:39 PM
To: arvidn/libtorrent ***@***.***>
Cc: anonbaby ***@***.***>; Comment ***@***.***>
Subject: Re: [arvidn/libtorrent] Enabling listening on tcp port when proxy is used for peer connections (PR #7726)
We can setup reserve proxy/port forwarding on the same server with http/socks proxy.
That would be equivalent to wireguard+port forwarding setup, if port listening is not disabled.
I'm unsure what you mean. Can you please elaborate?
I get setting up a reverse proxy type thing and forwarding the port to the socks server, but what would the socks server do with it once it gets that traffic? Socks servers do not accept inbound traffic to forward to a host unless otherwise defined by the socks bind protocol.
If I'm getting what you are putting down, I am actually already doing this right now. I am using the patch above to listen to the port while using a proxy, and then using socat to forward the port from the socks server to the qbittorrent host.
Qbittorrent should not have anything to do with a reverse proxy though, because the socks host and the qbittorrent host might be on separate machines. Any way you look at it, you can't inheritly forward ports from the socks host to the qbittorrent host with just the socks protocol.
—
Reply to this email directly, view it on GitHub<#7726 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/BJ6P7JNNFKCXD6NDWKESKUDZ2POYHAVCNFSM6AAAAABMFVVMNSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGOJZHA4TIMBVGY>.
You are receiving this because you commented.Message ID: ***@***.***>
|
@arvidn can you please review again? I changed this so that there is now a new setting to enable listening while using a proxy. The default value for this is false to maintain compatibility between versions. When this value is false, it follows the original logic before the PR. I also branched and made changes to qbittorrent in order to test these changes. This can be found in the listenOnProxy branch at https://github.com/Masong19hippows/qBittorrent. There are some bugs that I need to fix and I need to figure out the translations, but it should provide a good enough platform for testing the change. The most notable issue with the qbittorrent branch is that if you change the new setting, you will need to restart qbittorrent in order for it to be applied. |
This test is ensuring some aspects of ABI stability and is failing. https://ci.appveyor.com/project/arvidn/libtorrent/builds/50811938/job/l22u63al4sr0ykyn#L1156 the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this could be simplified by using the existing listen socket flag listen_socket_t::accept_incoming
instead of tacking on additional conditions
src/session_impl.cpp
Outdated
@@ -6891,7 +6896,7 @@ namespace { | |||
// connected to the internet. The whole point is to forward ports through | |||
// the gateway | |||
if ((s->flags & listen_socket_t::local_network) | |||
|| (s->flags & listen_socket_t::proxy)) | |||
|| (s->flags & !m_settings.get_bool(settings_pack::listen_on_proxy))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not right. the &
is a bit-wise AND operation. you can mask the flags
field against flags/bits set in this field. get_bool()
returns a bool
, not a flag value. I think you meant to preserve the existing check and add this additional one.
src/session_impl.cpp
Outdated
@@ -5664,7 +5669,7 @@ namespace { | |||
|
|||
if (!s->natpmp_mapper | |||
&& !(s->flags & listen_socket_t::local_network) | |||
&& !(s->flags & listen_socket_t::proxy)) | |||
&& m_settings.get_bool(settings_pack::listen_on_proxy)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you don't configure a proxy and leave listen_on_proxy
as false
; it looks like this change would disable NAT-PMP in that case. I think what you meant to do was to add another condition to the flags & proxy
check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there might be a simpler way of doing this. Rather than checking the settings here, I think you should be able to check the listen_socket_t::accept_incoming
flag. You'd have to make sure this flag is set correctly depending on the listen_on_proxy
setting when the sockets are created though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arvidn would it be acceptable to just remove the proxy being a factor in whether the user can enable natpmp? Or is this something that is best left in another PR/Issue/Discussion?
@@ -5566,9 +5574,6 @@ namespace { | |||
return std::uint16_t(sock->tcp_external_port()); | |||
} | |||
|
|||
if (m_settings.get_int(settings_pack::proxy_type) != settings_pack::none | |||
&& m_settings.get_bool(settings_pack::proxy_peer_connections)) | |||
return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would have expected this also depend on the listen_on_proxy
setting, no?
@@ -5522,11 +5525,11 @@ namespace { | |||
if (m_listen_sockets.empty()) return 0; | |||
if (sock) | |||
{ | |||
// if we're using a proxy, we won't be able to accept any TCP | |||
// connections. Not even uTP connections via the port we know about. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to update or extend this comment, rather than removing it
qbittorrent disables the listening tcp port when the option "Use proxy for peer connections" is enabled. This is mentioned in #21134 and #8718.
I don't believe this should be the case as its a fundamental misunderstanding of what the proxy should do. Proxies are only for outbound connections and should not change behavior of incoming connections. This is outlined in the http proxy spec as defining a proxy as a service for making requests.
I think the current implementation is an artificial limitation set by libtorrent rather than the protocol itself. There are plenty of reasons to still accept incoming connections while using the proxy for outbound connections. A very reason is for networks that require a proxy for internet.
This pull request is heavily based on this article.