arvidn / libtorrent

an efficient feature complete C++ bittorrent implementation
http://libtorrent.org
Other
5.26k stars 997 forks source link

improve route selection for uTP sockets #4850

Open arvidn opened 4 years ago

arvidn commented 4 years ago

libtorrent version (or branch): RC_1_2

This issue was posted here: https://github.com/qbittorrent/qBittorrent/issues/13094

The logic that picks which UDP socket to use for a uTP connection is simple and does not pick the correct one in some circumstances. At least make it take into account:

The code is here:

std::vector<std::shared_ptr<listen_socket_t>> with_gateways;
std::shared_ptr<listen_socket_t> match;
for (auto& ls : m_listen_sockets)
{
    if (is_v4(ls->local_endpoint) != remote_address.is_v4()) continue;
    if (ls->ssl != ssl) continue;
    if (!(ls->flags & listen_socket_t::local_network))
        with_gateways.push_back(ls);

    if (match_addr_mask(ls->local_endpoint.address(), remote_address, ls->netmask))
    {
        // is this better than the previous match?
        match = ls;
    }
}
if (!match && !with_gateways.empty())
    match = with_gateways[random(std::uint32_t(with_gateways.size() - 1))];

if (match)
{
    utp_init_socket(impl, match);
    return match->local_endpoint;
}
ec.assign(boost::system::errc::not_supported, generic_category());
return {};

For both UDP and TCP connections, it seems interfaces that are DOWN are still considered.

toasta commented 4 years ago

with "outgoing interface" set to tun0 and the defaultroute over tun0, it is still trying to announce over all interfaces. Some torrents somehow get stuck in "Announce sent", stopping and starting doesnt help.

Errors seem to cycle trough.. So some torrents (on the same tracker) are ok, some are in "Connection timed out", some in "no route to host" and some hard-stuck in "Announce sent".

clientconnections seem to work.

toasta commented 4 years ago

I don't think it's a big deal to try to announce that internal network to the tracker. If it can't reach it, no harm done.

dunno. seems a bit dirty or at least "not pretty". As privacy concerns arose with failing vpns i'd avoid any announcements if they are not "configured" (as in 'use that interface only') or are doomed to fail anyway, like using wrong src-ips or something.

I know you do sort of "if this tracker is in the same subnet, then announce to it", but there might be more intermediate networks necessary to reach it.

As far as I understand, if there are other intermediate networks you must have a gateway configured, or it must be a point-to-point interface. Is that right?

there should be a route to it, but as far as i understood the "do i announce to that tracker over that interface"-logic, it'll only look for the netmask of the interface, not the actual routingtable.

[ Host-libtorrent 10.10.10.1/24] => [ 10.10.10.2/24 host1 10.20.20.2/24 ] <=> [10.20.20.1/24 host3 ]

host-libtorrent has a routes like

6.7.8.8/31 dev eth0
10.10.10.1/24 dev eth1
default via 6.7.8.9
10.20.20.0/24 via 10.10.10.2

if the tracker is 10.20.20.1 (host3), libtorrent will only see the defaultroute and not announce over eth1? I'm still voting for real routingtable queries :)

toasta commented 4 years ago

with interface set to the ip of an interface and ~60k routes set, most of the torrents are stuck in "Announce sent" and some get trough. No Client-Traffic possible.

with all routes removed and one defaultroute via the ip of the interface configured in deluge, client-traffic possible but most of the tracker announcements go over the wrong interface or with the wrong srcaddress.

lots of torrents stuck in "Announce sent".

arvidn commented 4 years ago

with "outgoing interface" set to tun0 and the defaultroute over tun0, it is still trying to announce over all interfaces. Some torrents somehow get stuck in "Announce sent", stopping and starting doesnt help.

outgoing_interface is only for peer connections, not incoming connections. So in order to still accept incoming connections, the IP has to be announced to the tracker.

arvidn commented 4 years ago

dunno. seems a bit dirty or at least "not pretty". As privacy concerns arose with failing vpns i'd avoid any announcements if they are not "configured" (as in 'use that interface only') or are doomed to fail anyway, like using wrong src-ips or something.

Sure, it's not obvious to me that pinging google is any less dirty though.

toasta commented 4 years ago

with "outgoing interface" set to tun0 and the defaultroute over tun0, it is still trying to announce over all interfaces. Some torrents somehow get stuck in "Announce sent", stopping and starting doesnt help.

outgoing_interface is only for peer connections, not incoming connections. So in order to still accept incoming connections, the IP has to be announced to the tracker.

I have no incoming connections, only outgoing. So "outgoing_interface" is not considered for tracker announcements?

arvidn commented 4 years ago

there should be a route to it, but as far as i understood the "do i announce to that tracker over that interface"-logic, it'll only look for the netmask of the interface, not the actual routingtable.

Right. Looking at the routing table wouldn't really help. The question isn't "If I contact this IP, will my connection go over this interface?". The question is: "Is it possible to accept incoming connections from the internet (or the tracker's network) on this interface".

The has_default_route patch makes the routing table check a bit more sophisticated, where it looks not only for a default route, but also if there's any route to that inerface, which seems like a reasonable indication.

toasta commented 4 years ago

Sure, it's not obvious to me that pinging google is any less dirty though.

it proofs there is internet behind that interface and is less likely to leak any information. Dunno how udp tracker announcements actually work, but i suspect it'll fire-and-forget send a packet with the info_hash. a three-way handshake to google leaks basically no information..

Just trying to help and think how i would do a "is there internet" check.

arvidn commented 4 years ago

I have no incoming connections, only outgoing. So "outgoing_interface" is not considered for tracker announcements?

Correct. https://libtorrent.org/reference-Settings.html#outgoing_interfaces

arvidn commented 4 years ago

with all routes removed and one defaultroute via the ip of the interface configured in deluge, client-traffic possible but most of the tracker announcements go over the wrong interface or with the wrong srcaddress.

What does that mean exactly? Does it mean the default listen interfaces (which are 0.0.0.0:6881,[::]:6881) are expanded to interfaces that you wouldn't expect it to?

I think the bulk of this issue (or at least the first part of it that I'm trying to address) is concerning how the default settings (i.e. when the user doesn't specify listen IP(s) or interface(s)). When I say "expand" I mean turn 0.0.0.0 and [::] into specific IPs and interfaces. Which ones it expands to is printed to the log as "successfully listening on ..." (or something like that, assuming it succeeded in opening a listen socket).

The patch set fixes the following issues:

  1. the issue of failing to enumerate large routing tables (and also large interface lists for that matter)
  2. the issue of expanding the unspecified listen addresses to include interfaces that are DOWN.
  3. the issue of assuming an interface is a local-only network if there is no default route to it.

I would like to know your opinion about these changes.

  1. Do you think they are an improvement to the current behavior (I suppose (1) is a no-brainer probably)
  2. If so, do you think these patches work as described above?

lots of torrents stuck in "Announce sent".

Unfortunately I don't really know exactly what that means in Deluge.

arvidn commented 4 years ago

actually, I have one more question, apart from the issue of peer connections over uTP not honoring the routing table, can the other issues you experience be solved by the "escape hatch" of explicitly specifying the listen interface you want to use?

I think it's important that there is a manual override that works.

toasta commented 4 years ago

So "outgoing_interface" is not considered for tracker announcements? Correct. https://libtorrent.org/reference-Settings.html#outgoing_interfaces

hmmk.. i read that but imho it's not clear, that tracker-announcements are completely separate.

This controls which IP address outgoing TCP connections are bound to,

there's no mentioning of "tracker" in the description of outgoing_interface, but listen_interfaces talks about outgoing (udp) trackers and that if you dont specify a port, outgoing tcp will still be possible. So i wrongly assumed, as the tracker-connection is a tcp connection, it'll adhere to that, too.

But you might consider changing that or adding another option so people having the "vpn dies and reveals my real ip" could simply put "tun0" in the outgoing_interface and never fear that any ip other than that of tun0 would be published.

arvidn commented 4 years ago

hmmk.. i read that but imho it's not clear, that tracker-announcements are completely separate.

Yeah, I agree that it's not all that clear. The mutli-homed section of the documentation should also describe some of the rationale we've talked about here, and how trackers, incoming peer connections and outgoing peer connections are treated differently (and really, only the outgoing peer connections take the routing table into account, or are meant to do that at least).

But you might consider changing that or adding another option so people having the "vpn dies and reveals my real ip" could simply put "tun0" in the outgoing_interface and never fear that any ip other than that of tun0 would be published.

If you put tun0 in both listen_interfaces and outgoing_interfaces you get that behavior (at least that's the intention).

I've been considering retiring the outgoing_interfaces in favor of a boolean setting to use the listen_interfaces as the outgoing interfaces (when enabled). Right now it's a bit weird that they can be set to separate interfaces.

toasta commented 4 years ago

But you might consider changing that or adding another option so people having the "vpn dies and reveals my real ip" could simply put "tun0" in the outgoing_interface and never fear that any ip other than that of tun0 would be published.

If you put tun0 in both listen_interfaces and outgoing_interfaces you get that behavior (at least that's the intention).

tried that, i would expect it to not use any other interface for tracker-announcements, too, but this is what it does with both set to tun0

bf@bf-spielwiese:~$ ip a show dev tun1
    inet 10.8.1.5/24 brd 10.8.1.255 scope global tun1

listening on tun1, link-type RAW (Raw IP), capture size 262144 bytes
18:34:58.638808 IP 10.8.0.21.51429 > 333.333.333.333.333: Flags [S], seq 1217798281, win 64240, options [mss 1460,sackOK,TS val 175028227 ecr 0,nop,wscale 7], length 0
18:34:58.638831 IP 10.8.0.20.49271 > 333.333.333.333.333: Flags [S], seq 2428195436, win 64240, options [mss 1460,sackOK,TS val 2581027498 ecr 0,nop,wscale 7], length 0
18:34:58.638840 IP 10.123.123.2.52483 > 333.333.333.333.333: Flags [S], seq 2517015004, win 64240, options [mss 1460,sackOK,TS val 3134451541 ecr 0,nop,wscale 7], length 0
18:35:02.046570 IP 10.8.0.20.56215 > 333.333.333.333.333: Flags [S], seq 1326238818, win 64240, options [mss 1460,sackOK,TS val 2581030906 ecr 0,nop,wscale 7], length 0
18:35:03.054780 IP 10.8.0.20.56215 > 333.333.333.333.333: Flags [S], seq 1326238818, win 64240, options [mss 1460,sackOK,TS val 2581031914 ecr 0,nop,wscale 7], length 0
18:35:05.070774 IP 10.8.0.20.56215 > 333.333.333.333.333: Flags [S], seq 1326238818, win 64240, options [mss 1460,sackOK,TS val 2581033930 ecr 0,nop,wscale 7], length 0
18:35:06.830839 IP 10.123.123.2.52483 > 333.333.333.333.333: Flags [S], seq 2517015004, win 64240, options [mss 1460,sackOK,TS val 3134459733 ecr 0,nop,wscale 7], length 0
18:35:06.830860 IP 10.8.0.20.49271 > 333.333.333.333.333: Flags [S], seq 2428195436, win 64240, options [mss 1460,sackOK,TS val 2581035690 ecr 0,nop,wscale 7], length 0
18:35:06.830871 IP 10.8.0.21.51429 > 333.333.333.333.333: Flags [S], seq 1217798281, win 64240, options [mss 1460,sackOK,TS val 175036419 ecr 0,nop,wscale 7], length 0
18:35:09.134804 IP 10.8.0.20.56215 > 333.333.333.333.333: Flags [S], seq 1326238818, win 64240, options [mss 1460,sackOK,TS val 2581037994 ecr 0,nop,wscale 7], length 0

(note that tun1 has 10.8.1.5 and with both interface entries set to tun0 i would expect to see no bt traffic on tun1 and i would never expect traffic with the wrong src ip.

But you mentioned tracker announcements are totally different and dont adhere to any restrictions one would expect from setting interfaces? I think - at least for http-announcements, they should follow the users wish to only use this one interface.

supplying all 5 tunnels as outgoing and/or listen interfaces didnt make it better.

Putting dht aside...

There might be a corner ultra special case where you want to use all available interfaces but always announce an ip from lo, but that's too special to think about right now and even if, announcing over one interface only should be enough.

and it's a little weird... since no tracker-announcements gets trough, i have no clients to connect to, altough those would use the correct interface?

arvidn commented 4 years ago

tried that, i would expect it to not use any other interface for tracker-announcements, too, but this is what it does with both set to tun0

What's the log output from libtorrent? I don't know what the log you posted means. libtorrent will print which interfaces and IPs it creates listen sockets for. I think that log would help understand what's going on.

You set listen_interfaces to tun0:<some port> and outgoing_interfaces to just tun0, is that right?

But you mentioned tracker announcements are totally different and dont adhere to any restrictions one would expect from setting interfaces?

No, I'm pretty sure I never said anything to suggest that. It's quite the opposite. tracker announces only care about the listen_interfaces setting, they don't care about your routing table (essentially).

supplying all 5 tunnels as outgoing and/or listen interfaces didnt make it better.

What did it do?

I'm getting the feeling that you may be getting error messages back from libtorrent, but you aren't seeing them because, maybe you're filtering alerts or not printing all of them.

Putting dht aside...

if interface(s) are set, i still see no reason why it should http-announce to anywhere else

neither do I

should not cycle trough the ips, especially not using routable src ips over rfc-interfaces and vice versa

Well, it still need to enumerate the IPs assigned to the specified interface, since there may be more than one. Say, one IPv4 and one IPv6 address.

if no interfaces set, not to/over any other interface the routing selects for that destination.

I would like to know more about what you mean here. There is no "destination" (at least not in deciding which IPs to "listen on", and announce to). The tracker itself is a destination, is that what you mean? do you mean that a tracker should always only be announced to once over whatever interface your routing table says it should use? (my understanding is that the routing table will always only have one best path to a destination IP).

That wouldn't work. Consider having one IPv4 and one IPv6 address, should only one be exposed to the tracker? Or having multiple internet connections, with separate global IPs, should only one be exposed to the tracker?

toasta commented 4 years ago

What's the log output from libtorrent? I don't know what the log you posted means. libtorrent will print which interfaces and IPs it creates listen sockets for. I think that log would help understand what's going on.

The tcpdump should just show that it's using almost all source ips the box has, but it always uses the same outgoing interface which will only work if one uses the correct source ip.

No, I'm pretty sure I never said anything to suggest that. It's quite the opposite. tracker announces only care about the listen_interfaces setting, they don't care about your routing table (essentially).

k. then i got

also, trackers and peer connections are different. for trackers libtorrent attempts to announce all IPs that can reach the tracker.

wrong.

should not cycle trough the ips, especially not using routable src ips over rfc-interfaces and vice versa

Well, it still need to enumerate the IPs assigned to the specified interface, since there may be more than one. Say, one IPv4 and one IPv6 address.

yep, but it does this for all interfaces, not just the one that can actually reach the tracker (that's why i was always recommending the routing table)

if no interfaces set, not to/over any other interface the routing selects for that destination.

I would like to know more about what you mean here. There is no "destination" (at least not in deciding which IPs to "listen on", and announce to). The tracker itself is a destination, is that what you mean?

yup.

do you mean that a tracker should always only be announced to once over whatever interface your routing table says it should use? (my understanding is that the routing table will always only have one best path to a destination IP).

That wouldn't work. Consider having one IPv4 and one IPv6 address, should only one be exposed to the tracker?

nope. that's different address families. It's in two stacks and therefore like two different interfaces or two different running instances. I get that you need that, but you'll only do that if the address resolved has an AAAA record anyhow.

Let's agree that if we say "interface" we both mean the tuple {interface,adressfamily}, so {eth0,v4} and {eth0,v6} are two interfaces. And all ips of that single interface that is used to reach the destination (tracker) should be announced (putting mixing rfc and routable ips aside, that's a bonus) but only the ips of this interface the route points at. So if eth0 has 192.168.123.1 and 4.5.6.7, then it's usually pointless to use both to reach a tracker 11.12.13.14 as 192.168.123.1 will usually never be able to reach 11.12.13.14, but see below.

Or having multiple internet connections, with separate global IPs, should only one be exposed to the tracker?

that's a tough one. I think this has to be left to the user. You already hinted at "there's only one best route". This is usually true, putting ecmp and med aside. So if you announce both,

What libtorrent - according to strace - does, is looping over all source addresses the box has with bind() - setting the src ip -, then with connect() to the address. The problem is that setting src doesn't make the connection stick to or select the right interface (i think you also describe that in the docs Binding an outgoing connection to a local IP does not necessarily make the connection via the associated NIC/Adapter.. So in my case, 90% of the packets sent out don't do anything and maybe delay everything for a very long time.

I think the problem is that torrents get stuck in "Announcements sent" state with this configuration. Skimming over the code i see no timer at first glance (but there is some) that puts a torrent out of this state.

force_reannounce has some ignore_min_interval reannounce_flags_t .

assuming that force_reannounce from torrent_handle.cpp is the function the application (deluge, qBitorrent) calls which queues the async call, maybe it's only qbittorent that does not set this flaq on "force reannounce" but it can't get to reannounce once it's in this state. Waiting very very long (hours) does sometimes make this state go away, Pausing and unpausing, not really.

This might also explain, why shutting down deluge/qBittorrent takes hours because it's waiting for all the "stopped" announcements to come back.

I don't know if this maybe is https://github.com/arvidn/libtorrent/blob/f4defa52b2d6bc3043e404229fdf8ec7c02db01e/src/torrent.cpp#L8994 combined with https://github.com/arvidn/libtorrent/blob/f4defa52b2d6bc3043e404229fdf8ec7c02db01e/src/torrent.cpp#L9012

and maybe the counter m_waiting_tracker (L9028)

What i also noticed in strace is that it's issuing the first n (5?) bind() calls followed by the connect() calls in sequence, then processes other stuff and then finally for the last (remaining?) src-ips (bind() and connect()) But that's only a observation, which likely does not have anything to do with the behavior.

Hope that helps...

mhertz commented 4 years ago

Sorry for butting in, and just quickly wanted to add that I get same behaviour as before when testing a fresh build of has_default_routes libtorrent branch(#4881) i.e. still both VPN and own IP are reported when checking announce-source-IPs from ipmagnet website(http-tracker) on windows 10 with two different provider's openvpn configs in deluge 2.0.3 and not binding any interfaces/ips, so default setup(config).

Unrelated, but I had never thought about if opening torrent client without any torrents in, and then starting VPN afterwards, then only the own IP is announced when adding ipmagnet link afterwards and not both, but that of-course also makes sence as having set listen/out sockets already. Qbittorrent's log states it sees the new IP and whatnot, but doesn't let libtorrent know seemingly to re-initialize. I know such behaviour is very exotic and doesn't make sence anyway lol, but just never thought about it, and saw it by chance when testing this and forgetting start VPN initially. This is both v1.2.7, v1.2.6 and has_default_routes i'm talking about here, but is torrent-client issue I understand.

Sorry again for butting in, and just added this comment because old ticket referrenced this ticket to be used instead.

Edit: Forgot to say that was thinking if the reason for the own IP isn't announced on Linux and only on windows(when not binding anything), when same profile used and same clients used both places from openvpn.net, maybe was because using tun on Linux and tap on windows, but changing to tap on Linux I couldn't get internet access, even though status from openvpn was OK, so couldn't test that scenario(I checked had nameservers in-place, but got no route to host on curl's/ping's etc.), and didn't know how use tun on windows, for additional testing neither.

arvidn commented 4 years ago

@toasta there are a few steps involved, and I realise some of the things I've said can easily be misinterpreted. I would like to clarify.

Step 1, to establish which IPs to listen on

This is determined by the listen_interfaces setting. There are 3 kinds of things it can contain:

  1. If listen_interfaces is configured to specific IPs, those IPs will be used for listen sockets to be bound to.
  2. If listen_interfaces is set to a device name, the IP addresses associated with that device are resolved and used. The name of the device is also recorded and used for SO_BINDTODEVICE. I use "device", "interface" and "adapter" interchangeably, and I don't refer it a pair of device-name + address family.
  3. If listen_interfaces is set to an unspecified address (which is the default, 0.0.0.0 and [::]) then all IP addresses associated with a local interface are enumerated and a heuristic is used to determine whether each IP can "reach the internet" or not. Basically, this is to prevent sending a tracker announce from 127.0.0.1. This is the only time the routing table is taken into account, for determining listening interfaces. The heuristics is described in detail in https://github.com/arvidn/libtorrent/pull/4881

I think option 3 here may be problematic in some cases. The set of patches in the pipeline to land attempts to improve this. For example by ignoring devices that are "down", and by not requiring a default route to an interface in order to consider it "connected to the internet" (to support two routes of 0.0.0.0/1 + 128.0.0.0/1).

Step 2, send announces to trackers

In this step, only IPs selected from step 1 are considered.

This is where the can_route() function is applied, but only to the IP addresses (also called listen_socket_t) we've already started listening on. Each such, listen_socket_t also has a netmask associated with it, pulled from the interface list. This netmask is used to determine whether the tracker is on the same network (not very likely) or if the listen_socket_t is a "local network" only. i.e. cannot reach the internet. Any interface that's explicitly configured is never considered "local".

If a listen_socket_t object is determined to be announced, there are two things that can happen.

  1. If the tracker is a UDP tracker, the UDP socket associated with the listen_socket_t is used to send the packets to the tracker. This UDP socket will have been bound (with bind() and possible with SO_BINDTODEVICE), which will determine the device that's used.

  2. If the tracker is an HTTP tracker, the TCP socket will be bound with bind() and possible SO_BINDTODEVICE before connecting.

Step 3, making peer connections

(let's assume outgoing_interfaces are not set). Outgoing TCP peer connections do not care about listen_socket_t objects at all. They are made just as normal. (if outgoing_interfaces are set, those IPs are used to bind() the outgoing sockets in a round-robin fashion, over all outgoing interfaces).

For outgoing uTP peer connections, one of the UDP sockets associated with a listen_socket_t will be used. This is because all uTP connections, UDP tracker connections and DHT messages share a UDP socket. This can lead to using the "wrong" interface for talking to a peer, relative to what the routing table says. I believe this is the other issue you are experiencing @toasta.

Let's agree that if we say "interface" we both mean the tuple {interface,adressfamily}, so {eth0,v4} and {eth0,v6} are two interfaces.

I don't think that's typically how the word "interface", "device" or "adapter" is used. I use those words to refer to a (physical or virtual) NIC. Each of which can be associated with any number of networks (i.e. address and prefix-length)

And all ips of that single interface that is used to reach the destination (tracker) should be announced (putting mixing rfc and routable ips aside, that's a bonus) but only the ips of this interface the route points at.

I'm not actually that familiar with how people would normally set up multiple networks over the same interface. But I've seen segmentations of local networks where some reach the internet, and some reach various internal services, that are fire-walled from the internet. Are you saying that it only ever makes sense to announce one network per interface?

I can imagine having multiple networks for an interface that still reach different egress points to the internet, in which case both would make sense to be announced.

Or having multiple internet connections, with separate global IPs, should only one be exposed to the tracker?

that's a tough one. I think this has to be left to the user. You already hinted at "there's only one best route". This is usually true, putting ecmp and med aside.

it is ultimately up to the user, because listen_interfaces can be configured.

What libtorrent - according to strace - does, is looping over all source addresses the box has with bind()

What do you mean by this exactly? libtorrent will enumerate the interfaces and IPs somewhat regularly. Is that what you see in strace? It's normally done via a netlink socket on linux though. I don't know what you mean by "with bind()", it's not calling bind() multiple times on the same socket with all the different local IPs, is it?

  • setting the src ip -, then with connect() to the address. The problem is that setting src doesn't make the connection stick to or select the right interface (i think you also describe that in the docs Binding an outgoing connection to a local IP does not necessarily make the connection via the associated NIC/Adapter.. So in my case, 90% of the packets sent out don't do anything and maybe delay everything for a very long time.

It sounds like the heuristic of picking which interfaces to "listen on" is mismatching your routing table, and attempts to bind to device fail (which isn't too surprising, since you need root privileges for that on linux). Hence the mismatch of source IP and interface.

Does that sound like it would explain the symptoms you see?

I would like to improve this situation and I'm open to suggestions. However, you say that even if you set listen_interfaces to the correct interface, it still doesn't work for you. Is that right? I would like to focus on that problem first, since that prevents people from getting it to work explicitly, even when circumventing the heuristic.

arvidn commented 4 years ago

@mhertz thanks for the report. Announcing both the VPN and the direct connection is a somewhat separate issue, and I think it deserves its own ticket, feel free to create a ticket for this issue (I seem to recall there is one in qbt, that probably should be linked). I'm open to suggestions for how to solve that. Maybe the default should be to only expand unspecified addresses to IPs from the "main" interface. It would require some heuristic to figure out which the main one is.

mhertz commented 4 years ago

Sorry Arvid, I guess I misunderstood your closing post in my ticket about this, like as if you had one of the commits in #4881 made for fixing this and to direct also conversation of this issue here.

I don't know enough about this to suggest if/what changes should possibly be made regarding that, and after reading your explenations previously I learned that it quite possibly was kinda unavoidable, given supporting multi-homed support, but anyway, I'll butt out again, and follow this interesting learningfull ticket from the outside :) Sorry again for the detraction.

arvidn commented 4 years ago

@toasta I believe the last issue I haven't addressed yet is the interface outgoing uTP peer connections are made over. I think the ideal solution would be to have a separate UDP socket, bound to the unspecified address to be used for peer connections.

The tricky thing with that is that SO_REUSEADDR and SO_REUSEPORT may have slightly different behavior on different platforms and incoming packets may still arrive on any socket. So for UDP trackers and the DHT nodes, they may receive packets on the "unspecified" socket, which would add some complication.

The simplest solution would probably be to take the routing table into account when picking the outgoing interface.

ghost commented 2 years ago

@arvidn was this a duplicate of https://github.com/arvidn/libtorrent/issues/6772 or they're different issues?

Zerogoki00 commented 1 year ago

Any update? 3 years have passed and it's still not fixed... The bug is very annoying and it breaks my VPN routing