Skip to content

Fixing TCP Listening Port with Proxy#8003

Open
Masong19hippows wants to merge 12 commits into
arvidn:RC_2_0from
Masong19hippows:ListenOnTCPWithProxy
Open

Fixing TCP Listening Port with Proxy#8003
Masong19hippows wants to merge 12 commits into
arvidn:RC_2_0from
Masong19hippows:ListenOnTCPWithProxy

Conversation

@Masong19hippows

Copy link
Copy Markdown

Hello,

I made a PR awhile back about listening on the defined TCP port whenever proxies are enabled. The current behavior is to disable listening when a proxy is set. My proposed changes would add a bool configuration option that would enable listening when a proxy is configured. Default value is false. In the same logic, I also removed the proxy check when enabling natPMP/upnp. This check was meant to disable opening up these ports if the proxy was configured. Instead of coupling this with any proxy settings, I just removed the check all together so that it's only dependent on the "Use UPnP / NAT-PMP port forwarding from my router" flag. I felt this was best because it follows the same logic as decoupling the listening TCP port with the proxy settings - user should decide with one setting.

This was in PR #7726

I felt it was best to close that PR and start anew because I messed up a rebase. During the year of inactivity, there were alot of changes that caused the PR to need a rebase. It got messy because I messed up and I felt like this was a much better option. I think I resolved all of the issues @arvidn showed as well.

Please review when you have a moment.

@Masong19hippows

Copy link
Copy Markdown
Author

I'm not sure why the build is failing on github. It doesn't look related to anything I changed. My guess is that I have to change something in the settings pack test with the other bools, but I don't know the magic number to add to the base.

image

@qBittUser

This comment was marked as resolved.

@jiang-zhexin

Copy link
Copy Markdown

I really need this feature, this is awesome.

And could add SOCKS5 BIND support? I've implemented it in Go, it might not be too hard.

@Masong19hippows

Copy link
Copy Markdown
Author

@jiang-zhexin

You might need to look back at the previous pr for more info where I explained it better. Essentialy the socks bind command is meant to be a temporary port on the server side for secondary connections to an already existing connect. Like, if I contacted a website through a socks proxy, I could then initiate the bind process for that website to send traffic back to me through an open port on the server.

It's not really a bind in the traditional sense, and because of this, I don't think it's possible to accept incoming connections through sock bind.

@Masong19hippows

Copy link
Copy Markdown
Author

I think I might've fixed it. I think that means it's good to merge on the ABI stability part then?

@qBittUser

This comment was marked as resolved.

@arvidn arvidn left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't thought this through, but it seems to be some overlap with this new setting and proxy_peer_connections. For example, if proxy_peer_connections is set and proxy_accept_incoming is set, that seems like a contradiction.

Did we already discuss the feasibility of just making proxy_peer_connections being false meaning incoming connections are allowed? Or perhaps that's already the case.

Comment thread include/libtorrent/settings_pack.hpp Outdated
// man-in-the-middle connections.
proxy_send_host_in_connect,

// if true, listening on the defined port will be enabled while using proxy

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs some elaboration. "defined" port should probably be described as local listen sockets, allowing incoming connections that are not proxied, circumventing the proxy.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just updated it. Is that better?

Comment thread include/libtorrent/settings_pack.hpp Outdated

@arvidn arvidn left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you consider only changing repoen_listen_sockets()?
I think the check right here is the only thing you would need to change: https://github.com/arvidn/libtorrent/blob/RC_2_0/src/session_impl.cpp#L2060-L2072

Right now, if we use a proxy for peers, we ignore all the listen sockets set up, and just create a single one with the proxy flag. That's the flag that causes the behavior you don't want. i.e. not accepting incoming connections directly, only via the proxy.

You could, instead, treat the proxy as addative to the listen sockets configured by listen_interfaces (rather than replacing them). I believe that would also give you the behavior you need, but with a smaller patch and without changing so much existing behavior.

Comment thread src/session_handle.cpp Outdated
Comment thread src/session_impl.cpp
if (m_settings.get_int(settings_pack::proxy_type) != settings_pack::none
&& m_settings.get_bool(settings_pack::proxy_peer_connections))
&& m_settings.get_bool(settings_pack::proxy_peer_connections)
&& !m_settings.get_bool(settings_pack::proxy_accept_incoming))

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems to be the crux. Is the point if proxy_accept_incoming to accept incoming peers on the local socket even though outgoing connections must go via the proxy?

@Masong19hippows Masong19hippows Aug 18, 2025

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that's exactly it. Essentially, the outgoing connection towards clients via the proxy or not shouldn't affect incoming connections, because qbittorrent has no way of accepting incoming connections through the proxy via any proxy protocols.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so, if proxy_peer_connections is false, then proxy_accept_incoming does not have any effect. is that right?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe so.

@Masong19hippows

Copy link
Copy Markdown
Author

I haven't thought this through, but it seems to be some overlap with this new setting and proxy_peer_connections. For example, if proxy_peer_connections is set and proxy_accept_incoming is set, that seems like a contradiction.

Did we already discuss the feasibility of just making proxy_peer_connections being false meaning incoming connections are allowed? Or perhaps that's already the case.

The problem with that approach is that there is still a use case to use the proxy for peer connections and still listen on the local port. With some external forwarding tools, you can forward incoming connections from the proxy to the local port, but that doesn't work if qbittorrent isn't listening on that port.

@Masong19hippows

Copy link
Copy Markdown
Author

did you consider only changing repoen_listen_sockets()? I think the check right here is the only thing you would need to change: https://github.com/arvidn/libtorrent/blob/RC_2_0/src/session_impl.cpp#L2060-L2072

Right now, if we use a proxy for peers, we ignore all the listen sockets set up, and just create a single one with the proxy flag. That's the flag that causes the behavior you don't want. i.e. not accepting incoming connections directly, only via the proxy.

I believe I already did this here, unless I am mindreading what you are saying. My proposed solution is to add an additional check for the new proxy_accept_incoming flag.

This has 2 different permutations then. If there is a proxy configured and proxy_peer_connections is true, then we would listen on the local port if proxy_accept_incoming is true and follow original logic if false. If there is a proxy configured and proxy_peer_connections is false, then we won't listen on the local port regardless of the proxy_accept_incoming flag. We could remove the proxy_peer_connections check here, but then it would change the predefined behavior, which you said you didn't want to do in the previous pr, and instead want to guard this new behavior around this new flag.

In addition to this check, there is also a check on line 2834 that does the same thing, which I believe to be necessary.

You could, instead, treat the proxy as addative to the listen sockets configured by listen_interfaces (rather than replacing them). I believe that would also give you the behavior you need, but with a smaller patch and without changing so much existing behavior.

Can you please elaborate on what you mean here? I'm not familiar enough with the codebase to understand.

Comment thread src/session_impl.cpp Outdated
Comment thread src/session_impl.cpp
if (m_settings.get_int(settings_pack::proxy_type) != settings_pack::none
&& m_settings.get_bool(settings_pack::proxy_peer_connections))
&& m_settings.get_bool(settings_pack::proxy_peer_connections)
&& !m_settings.get_bool(settings_pack::proxy_accept_incoming))

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so, if proxy_peer_connections is false, then proxy_accept_incoming does not have any effect. is that right?

Comment thread src/session_impl.cpp Outdated
Comment on lines +5548 to +5551
if (m_settings.get_int(settings_pack::proxy_type) != settings_pack::none
&& m_settings.get_bool(settings_pack::proxy_peer_connections)
&& !m_settings.get_bool(settings_pack::proxy_accept_incoming))
return 0;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check and early exit should only be used if sock == nullptr. If sock is set, we already have this check based on whether the listen socket is using a proxy or not.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the if statement before this one guarantees that this check will only be ran if sock is null. The if block with if(sock) on line 5529 has a guaranteed return, and so the following if block will only run if sock is null. Regardless, I changed this to have a null check and this should be resolved.

Comment thread src/session_impl.cpp Outdated
Comment thread src/session_impl.cpp
Comment on lines -5573 to -5575
if (m_settings.get_int(settings_pack::proxy_type) != settings_pack::none
&& m_settings.get_bool(settings_pack::proxy_peer_connections))
return 0;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look right. This should probably mimic the session_impl::listen_port() above. I think you'd want to update the check and early exit on line 5569 as well

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I fixed this if you want to take a look @arvidn, when you get a chance.

Comment thread src/session_impl.cpp
Comment on lines -5670 to -5671
&& !(s->flags & listen_socket_t::local_network)
&& !(s->flags & listen_socket_t::proxy))

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does this need to change? I can see taking the new option into account, not just removing this condition

@Masong19hippows Masong19hippows Oct 16, 2025

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think removing the proxy check for natpmp/upnp makes intuitive sense, because there is already a flag specifically for it. I think it would be confusing for people that use a proxy to also make sure this new flag is checked if they want natpmp/upnp to work, especially when the new flag doesn't describe natpmp/upnp. Please let me know your thoughts, I can add it back in if you'd like.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default assumption of using a proxy for peer connections is that you don't accept incoming peer connections that circumvent the proxy. If you don't accept incoming connections, clearly you also should not forward the port. There's no listen socket receiving the incoming connection anyway.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for the delay, I just saw this. I believe I corrected this if you want to take a look.

Comment thread src/session_impl.cpp Outdated
// the gateway
if ((s->flags & listen_socket_t::local_network)
|| (s->flags & listen_socket_t::proxy))
if ((s->flags & listen_socket_t::local_network))

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here too. You're removing this check. I would imagine you want to take the new option into account instead

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fruworg

fruworg commented Nov 7, 2025

Copy link
Copy Markdown

LGTM

@arvidn arvidn self-assigned this Jan 4, 2026
@erns8

erns8 commented Jun 23, 2026

Copy link
Copy Markdown

Any update ? @arvidn

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants