qbittorrent / qBittorrent

qBittorrent BitTorrent client
https://www.qbittorrent.org
Other
27.52k stars 3.91k forks source link

Is there any way to listen at 0.0.0.0 and [::] #13052

Closed SeaHOH closed 2 years ago

SeaHOH commented 4 years ago

qBittorrent version and Operating System

qBittorrten v4.2.5 64-bit Windows 7 SP1 64-bit

If on linux, libtorrent-rasterbar and Qt version

(type here)

What is the problem

I tried every "Network interface" and "Optional IP Address to bind to" pairs in "Advanced" page, listen port only bind to the configuration, loopback and link-local IPs.

What is the expected behavior

I hope that setting "Any interface" and "All address" will bind listen port to 0.0.0.0 and [::], not 127.0.0.1, [::1] and others.

Steps to reproduce

(type here)

Extra info(if any)

If more informations is needed, please tell me.

ghost commented 4 years ago

0.0.0.0 is the default route. It includes localhost and all other IPs on your local machine.

SeaHOH commented 4 years ago

0.0.0.0 is the default route. It includes localhost and all other IPs on your local machine.

How can I bind to it, just like other bittorrent client?

SeaHOH commented 4 years ago

I tested the WebUI, it works different, can easy bind to 0.0.0.0 and [::].

FranciscoPombal commented 4 years ago

0.0.0.0 is the default route. It includes localhost and all other IPs on your local machine.

This. [::] is analogous, for IPv6.

So this expectation doesn't make sense:

I hope that setting "Any interface" and "All address" will bind listen port to 0.0.0.0 and [::], not 127.0.0.1, [::1] and others.

SeaHOH commented 4 years ago

Please reopen this issue.

My PC is under a LAN, the IPv4 not has a WAN IP configuration, it is different to IPv6 which always has a global IP, so I need listen port bind to 0.0.0.0, not the 192.168.*.*.

WebUI port can bind to 0.0.0.0:8080, how can I make the main port like this?

l

ghost commented 4 years ago

I think you’ll get better response if you post this issue in libtorrent issue tracker. As it seems like libtorrent is expanding 0.0.0.0 to include 127.0.0.1 and other instead of default route.

SeaHOH commented 4 years ago

Thanks so much, @an0n666 . Can you remove Not an issue and add upstream labels?

FranciscoPombal commented 4 years ago

@SeaHOH Ok, I understand your problem better with new info you provided. If @an0n666 is right and this is what's happening:

As it seems like libtorrent is expanding 0.0.0.0 to include 127.0.0.1 and other instead of default route.

then it would be a libtorrent issue. But it could also be a problem with how qBIttorrent passes the addresses to libtorrent. This needs further investigation. I added the libtorrent label just in case, I realize once the true cause is found I might have to remove it.

EDIT: oops, forgot to reopen, fixed now, sorry

SeaHOH commented 4 years ago

https://github.com/arvidn/libtorrent/commit/88d9c05e3c9fa7388d50554b48f5470a395bd94f

I found it, but this commit behavior does not conform to BEP 45. @arvidn

Stipulations regarding socket binding from BEP 32 apply, i.e. nodes should avoid binding sockets to the unspecified address (0.0.0.0 or ::/128).

For IPv4 autoconfiguration an implementation may choose the following strategies:

  1. if available bind to all available global unicast addresses

  2. if no global unicast address is available determine a local address which is usable to connect to a randomly chosen global unicast address and then bind to that. Then bootstrap in single-address mode.

Optionally, once bootstrapping has completed and nodes supporting BEP 42 ip fields have been found they can be used to determine the external address of other available local addresses and then switch to multi-address mode if additional external addresses are available.

Implementation Note: A routed local address can be obtained by calling connect() on an unbound UDP socket with a global unicast address as target and then reading the local bind address via getsockname().

arvidn commented 4 years ago

@SeaHOH can you be more specific about how the behaviour does not conform to BEP 45?

There is no way to make libtorrent bind to INADDR_ANY.

I don't quite understand your scenario, why can't you bind to a specific interface or IP? Does the IP change over time and you would need to re-bind?

SeaHOH commented 4 years ago

Why I can't bind to a specific IP, see https://github.com/qbittorrent/qBittorrent/issues/13052#issuecomment-647340502.

I think it fit strategies 2, use the single-address mode (0.0.0.0). The external address can used as announce, even can't bind to it.

arvidn commented 4 years ago

I read that comment, and I did not understand it. Could you be more specific?

My PC is under a LAN, the IPv4 not has a WAN IP configuration,

I imagine most home computers are on a LAN, behind a router. The unique property is that your IPv4 network isn't connected to the internet, it sounds like.

it is different to IPv6 which always has a global IP

But you have an IPv6 network that's connected to the internet. What happens if you use that interface to listen on?

, so I need listen port bind to 0.0.0.0, not the 192.168...

I don't see how that follows.

SeaHOH commented 4 years ago

IPv6 designs are different to IPv4, most machines can be allocated a global address, so IPv6 is works OK.

But my PC under LAN, so, need bind 0.0.0.0, or IPv4 peers connections can not incoming.

ghost commented 4 years ago

I think you’re facing the same issue as described in this ticket https://github.com/arvidn/libtorrent/issues/4329

It was closed assuming that it was fixed. But seems like it wasn’t.

ghost commented 4 years ago

To be precise, read this comment https://github.com/arvidn/libtorrent/issues/4329#issuecomment-596600513

arvidn commented 4 years ago

But my PC under LAN, so, need bind 0.0.0.0, or IPv4 peers connections can not incoming.

OK, so you do have IPv4 connectivity. Are you behind NAT? What I don't understand is what's preventing the incoming peer connections from being accepted. It doesn't normally follow from having a local IP on a LAN, essentially everyone has that.

I think you’re facing the same issue as described in this ticket arvidn/libtorrent#4329

It sounds a bit different. If it's specifically incoming peers, that's great progress in understanding the problem. But why wouldn't a listen socket that isn't bound to 0.0.0.0 be able to accept incoming connections?

@SeaHOH Let's say your LAN IP is 192.168.1.2, and you bind to that. Can you accept connections from the local network? You could test with nc to see if just the TCP connection is accepted. I assume you have a NAT, do you see UPnP/NAT-PMP or PCP working? There should be logs for that. It seems much more likely that it's a port forwarding issue than what IP the listen socket is bound to. If you have more information that points towards it actually having to do with the bound IP, please share!

ghost commented 4 years ago

He meant he has a LAN which is not connected to internet. So If libtorrent is binding to that LAN IP it's not getting any incoming connections. He has to bind to 0.0.0.0 to get internet and get incoming connection.

arvidn commented 4 years ago

He meant he has a LAN which is not connected to internet. So If libtorrent is binding to that LAN IP it's not getting any incoming connections. He has to bind to 0.0.0.0 to get internet and get incoming connection.

Why not bind to the IP that does have a route to the internet? Why doesn't that work?

ghost commented 4 years ago

That’s a limitation in qBt GUI. It allows you to select one specific interface to bind to. You can’t bind one specific IPv4 and then select to listen on all IPv6.

arvidn commented 4 years ago

if the IPv4 network isn't connected to the internet, the reason to listen to it would be just for peers on the local network then, right?

SeaHOH commented 4 years ago

Why not bind to the IP that does have a route to the internet? Why doesn't that work?

I make my PC as a DMZ instead of using UPnP/NAT-PMP.

That is not a real DMZ, just make my PC facing WAN directly without configure a WAN IP. So, all peers connect destination is not e.g. 192.168.1.2, it is the WAN IP.

SeaHOH commented 4 years ago

Please read BEP 45 again, the IPv4 autoconfiguration strategies 2. I think It does not mention UPnP/NAT-PMP, we can just follow it, use the single-address mode.

arvidn commented 4 years ago

That is not a real DMZ, just make my PC facing WAN directly without configure a WAN IP. So, all peers connect destination is not e.g. 192.168.1.2, it is the WAN IP.

ok, so you do have IPv4 connectivity. I would expect it to work if you bind to your WAN IP then. Have you tried that? Or does qBT not allow you to enter any IP to bind to?

arvidn commented 4 years ago

It's a pretty weird setup though, right? Normally you would still use NAT with a DMZ.

arvidn commented 4 years ago

Please read BEP 45 again, the IPv4 autoconfiguration strategies 2. I think It does not mention UPnP/NAT-PMP, we can just follow it, use the single-address mode.

Can you be more specific of what part of BEP 45 is violated? just saying "read it again" is not helpful.

It says:

if no global unicast address is available determine a local address which is usable to connect to a randomly chosen global unicast address and then bind to that. Then bootstrap in single-address mode.

That's what happens when you configure the listen IP. we bind to that.

It also says:

Implementation Note: A routed local address can be obtained by calling connect() on an unbound UDP socket with a global unicast address as target and then reading the local bind address via getsockname().

Do you think doing this would report your WAN IP? If so, do you think it could be useful for anything?

SeaHOH commented 4 years ago

It's a pretty weird setup though, right? Normally you would still use NAT with a DMZ.

The destination of incoming IP packet header will not be changed, if I don't enable UPnP/NAT-PMP.

It says:

if no global unicast address is available determine a local address which is usable to connect to a randomly chosen global unicast address and then bind to that. Then bootstrap in single-address mode.

That's what happens when you configure the listen IP. we bind to that.

It wrote is "if ... and then ..., then ...", not "if ... , then ..., then ...". So, that told we bind to single-address (unspecified address), not the local address.

Implementation Note: A routed local address can be obtained by calling connect() on an unbound UDP socket with a global unicast address as target and then reading the local bind address via getsockname().

Do you think doing this would report your WAN IP? If so, do you think it could be useful for anything?

No, it wrote "A routed local address", not "global unicast address". A routed local address can be a global unicast address, but not all.

arvidn commented 4 years ago

@SeaHOH It seems we have two separate issues we're talking about now:

  1. How to solve the problem you experience (I really think this is what we should focus on).
  2. How to interpret BEP45

Issue (1):

Did you try to bind to your WAN IP? Is that allowed by the qBT UI?

As for issue (2):

It wrote is "if ... and then ..., then ...", not "if ... , then ..., then ...". So, that told we bind to single-address (unspecified address), not the local address.

I'm having a bit of trouble parsing those sentences, so I may have misunderstood you. It sounds like you interpret "single-address" to mean INADDR_ANY (or the unspecified address/0.0.0.0). I don't think that's what it means, I think it means "single" as in "one" address. Namely, the address the socket was bound to.

SeaHOH commented 4 years ago

Issue (1):

I can't, it has not be configured to PC's address.

issue (2):

Which one we would be use, if there has more than one IP? I think "single-address mode" says the "mode", not a random IP address.

arvidn commented 4 years ago

I can't, it has not be configured to PC's address.

So it sounds like qbt's UI doesn't let you type an IP address then. I think this ticket (being against qbt) should perhaps be renamed to something like "allow manually specifying an IP address or interface to listen on". I imagine this would solve the problem.

Which one we would be use, if there has more than one IP? I think "single-address mode" says the "mode", not a random IP address.

The mode being that the DHT node only has a single address, and can only be reached at that address. Nothing there implies a random IP (and I don't think I implied a random IP either). The IP would be the one chosen. In this case the one entered in the listen_interfaces setting in libtorrent.

I suppose the term "local address" is unnecessarily restrictive in:

if no global unicast address is available determine a local address which is usable to connect to a randomly chosen global unicast address

I think "local" could be dropped.

SeaHOH commented 4 years ago

Maybe send a Email to BEP team to request them updated to more clearly describe with no misunderstanding?

SeaHOH commented 4 years ago

I can't, it has not be configured to PC's address.

So it sounds like qbt's UI doesn't let you type an IP address then. I think this ticket (being against qbt) should perhaps be renamed to something like "allow manually specifying an IP address or interface to listen on". I imagine this would solve the problem.

I means my PC not configured a WAN IP.

arvidn commented 4 years ago

Maybe send a Email to BEP team to request them updated to more clearly describe with no misunderstanding?

I might propose dropping "local" in that sentence. But I would like to have a clearer understanding of whether this solves the problem you experience first. I don't think the BEP is all that relevant for this concrete situation. Even if the BEP suggested binding to the unspecified address (which it explicitly discourages earlier in the text), it would not prevent an implementation to always use the implementation strategy where you don't do that.

arvidn commented 4 years ago

I means my PC not configured a WAN IP.

Yes, I understand that. You keep dancing around my question without actually answering it though. It is possible to call bind() on a socket with an IP address that's not assigned to any local network interface [reference]. That's what I'm suggesting you do.

Does the qBT UI let you do that?

SeaHOH commented 4 years ago

it would not prevent an implementation to always use the implementation strategy where you don't do that.

That means you will never bind to 0.0.0.0 , any condition?

arvidn commented 4 years ago

That means you will never bind to 0.0.0.0 , any condition?

I'm open to be convinced. But I haven't heard any convincing reasons yet.

SeaHOH commented 4 years ago

Yes, I understand that. You keep dancing around my question without actually answering it though. It is possible to call bind() on a socket with an IP address that's not assigned to any local network interface [reference]. That's what I'm suggesting you do.

No, I can't, I am using Windows 7.

SeaHOH commented 4 years ago

I'm open to be convinced. But I haven't heard any convincing reasons yet.

I think that not all end-users can solve this issue by them self. They don't know how, has no permission etc.

You should solve it in libtorrent, rather than told users to change their environments.

arvidn commented 4 years ago

It is possible to call bind() on a socket with an IP address that's not assigned to any local network interface [reference]. That's what I'm suggesting you do.

No, I can't, I am using Windows 7.

@ssiloti Do you have any thoughts about this. It appears that with a setup like this (where you may receiving incoming connections to a WAN IP but no WAN IP configured) your only option on windows is to bind to the unspecified address.

@SeaHOH is there any reason to have a network setup like this? The fact that windows has poor support for it suggests that it's discouraged.

arvidn commented 4 years ago

I think that not all end-users can solve this issue by them self. They don't know how, has no permission etc.

You should solve it in libtorrent, rather than told users to change their environments.

There are problems with listening on the unspecified address too, as you may end up with one DHT reachable by multiple addresses. In fact, I would suppose that that problem is more likely to happen in the wild than your setup. I don't have any data of course, and that's part of the problem. But it's not as simple as just listening to the unspecified address, it might solve your problem, but cause problems for more people.

I definitely agree and have the ambition that it should work out-of-the-box for everyone. When that can't be accomplished (or is prohibitively expensive) having it work out-of-the-box for most people has to be the next priority.

SeaHOH commented 4 years ago

@SeaHOH is there any reason to have a network setup like this? The fact that windows has poor support for it suggests that it's discouraged.

For both security and convenience I setup this.

There are problems with listening on the unspecified address too, as you may end up with one DHT reachable by multiple addresses. In fact, I would suppose that that problem is more likely to happen in the wild than your setup. I don't have any data of course, and that's part of the problem. But it's not as simple as just listening to the unspecified address, it might solve your problem, but cause problems for more people.

Ofcause, can you provide a parameter (for IPv4 unspecified address) as advanced customize?

SeaHOH commented 4 years ago

Thanks so much, everyone! You heard my sounds. :smile:

ssiloti commented 4 years ago

So I take it you've enabled promiscuous mode on the system's network interface then? Otherwise there's no way that's going to work. Even with promiscuous mode enabled I'm surprised it works, normally promiscuous mode is only used when setting up bridges or packet capturing.

SeaHOH commented 4 years ago

That's the home router DMZ host.

ssiloti commented 4 years ago

Sure, but hosts normally discard packets not addressed to them. Have you verified that:

a. Your router is not re-writing the destination address to your host's private address. b. An incoming SYN packet from the WAN interface will be accepted by a socket listening on 0.0.0.0.

I'd be very surprised of both of these held without some special configuration on the host.

SeaHOH commented 4 years ago

a. Your router is not re-writing the destination address to your host's private address.

If router is re-writing to, listen private address will be work, in fact it does not.

b. An incoming SYN packet from the WAN interface will be accepted by a socket listening on 0.0.0.0.

Ofcause, that's working. Listening unspecified address does not check the incoming destination.

ssiloti commented 4 years ago

Ofcause, that's working. Listening unspecified address does not check the incoming destination.

Have you actually tried it? I would expect the packets to be discarded by the network stack long before they reach the socket. Hosts normally don't respond to any random IP address that's sent to them.

SeaHOH commented 4 years ago

Have you actually tried it? I would expect the packets to be discarded by the network stack long before they reach the socket. Hosts normally don't respond to any random IP address that's sent to them.


ipconfig

Windows IP Configuration

Ethernet Adapter xxxx:

Connection-specific DNS suffixes . : IPv6 address . . . . . . . . . . . : 240e:xxxx:xxxx:xxxx::1 Link-local IPv6 address. . . . . . : fe80::xxxx:xxxx:xxxx:xxxx%11 IPv4 address . . . . . . . . . . . : 192.168.1.xxx Subnet Mask . . . . . . . . . . . : 255.255.255.0 Default Gateway. . . . . . . . . . : fe80::1%11 192.168.1.1


First, The gateway set to `192.168.1.1`, packet come from it (becaues DMZ host is set) will be accepted, from other network will not be. I think this happen on every operating system, not only Windows (It called Edge Traversal in Windows), this behavior can be controled in firewall.
nlzy commented 4 years ago

For the incoming data packets from WAN, NAT will rewrite the destination address into private LAN IP and then forward it. So even if qBittorrent is bound to a private LAN IP, qBittorrent should be able to receive data.

I strongly recommend you to check the firewall settings on your PC.

SeaHOH commented 4 years ago

Thanks, I have returned back to use μTorrent again.

Behind NAT, incoming destination and outgoing source will be rewritten. That all are in-side, out-side addresses will not be rewritten. If socket listening on a private IP address, packets (usual reached destination) come from global IP addresses will never be accepted, they are not in a same network. Listening on unspecified address are different, there is no "same network" limit.

Peer-to-Peer Communication Across Network Address Translators

arvidn commented 4 years ago

If socket listening on a private IP address, packets (usual reached destination) come from global IP addresses will never be accepted

Clearly this is not true. As you stated in your first sentence of the paragraph: "Behind NAT, incoming destination and outgoing source will be rewritten.". Your NAT will rewrite the destination address to be your private IP, and it will be accepted.

As has been brought up before, you seem to have a very oddly configured NAT that doesn't do that. You seem to not acknowledge this, but act as if this is normal behaviour. That's confusing.

Is it your assertion that NATs don't rewrite the destination address on incoming packets?

Listening on unspecified address are different, there is no "same network" limit.

That's not true in general. TCP/IP stacks clearly discard packets whose destination address is not one of the host's own IP addresses.

Is it your assertion that TCP/IP stacks normally accept such packets? (apart from promiscuous mode)