Opened 10 years ago

Last modified 9 years ago

#4196 assigned Bug

Should ignore one address of peer if reachable via both IPv4 and IPv6

Reported by: avidrissman Owned by: jordan
Priority: Normal Milestone: Sometime
Component: libtransmission Version: 2.22
Severity: Minor Keywords:
Cc:

Description

Many a time the same host will appear as both IPv4 and IPv6 if it is dual-stacked.

If the IPv6 address is a Teredo address (2001:0:0:/32) or an 6to4 address (2002:0::/16) then the host's ISP doesn't natively do IPv6, and it would be better to just ignore the IPv6 address and focus on the IPv4 address. (Extracting the v4 address from the Teredo or 6to4 address is trivial.)

It would be even better if there were some sort of host identifier that could be used to de-duplicate, but I don't know the BT protocol.

If the v6 address is native, then I don't know which should be ignored. But at least some coordination should be done to avoid sending the same data twice.

Change History (4)

comment:1 Changed 10 years ago by jordan

  • Milestone changed from None Set to Sometime
  • Severity changed from Normal to Minor
  • Status changed from new to assigned

This is a good idea.

I don't want to make a low-level change like this during the 2.30 freeze... and moreover I'm not sure what we should do in the native v6 case either. (Possibly to prefer v6?) So even T wasn't frozen I don't think I'd be rushing to make a patch for this. :)

Still, I agree that libtransmission needs to handle these cases one way or the other. If someone reading this ticket has ideas on what the Right Thing is, I'm all ears...

comment:2 Changed 10 years ago by avidrissman

At least handle the Teredo/6to4 case. I see so many times a duplicate client show up with both v4 and Teredo and I'm wincing, yet don't want to turn off my v6 stack and end up sticking it to the v6-only crowd.

comment:3 Changed 10 years ago by jch

Extracting the v4 address from the Teredo or 6to4 address is trivial.

Do not do that. The v4 address embedded in a 6to4 address is the address of the 6to4 router, which is not necessarily co-located with the end host. (A single 6to4 router can be shared by many end hosts.)

I don't think there are similar cases in Teredo, but it's a rather complex protocol, I wouldn't bet on that.

It would be even better if there were some sort of host identifier that could be used to de-duplicate

There is, it's the peer-id.

and moreover I'm not sure what we should do in the native v6 case either. (Possibly to prefer v6?)

Connect to both in parallel, prefer whichever we connect to first?

I thought about that last year, but as far as I can tell it requires some major surgery to the code. The trouble is -- right now, Atoms carry just one IP address; the way I see it, we'd need an Atom structure that is able to contain both an IPv4 and IPv6 address.

For the record, here's the ways that we have to associate v4 and v6:

  • if we connect to both, and the peer-ids are identical, we can associate the two and drop one of the connexions;
  • if we connect over IPv4 to a µTorrent or Transmission peer, the "ipv6" LTEP entry gives us the corresponding v6 address, if any;
  • if we connect over IPv6 to a µTorrent (not Transmission) peer, the "ipv4" LTEP entry gives us the corresponding v4 address, if any;
  • if that's not enough, we can do some magic with DHT messages, but I rather wouldn't.

Note in the above that while µTorrent treats v4 and v6 in the same way, Transmission doesn't -- Transmission assumes that it knows its v6 address (see net.c after line 440), but it doesn't try to determine its IPv4 address.

-- jch

comment:4 Changed 9 years ago by reardon

Starting to see much more of this, in particular duplication of Teredo/6to4 peers. This does need special-case handling.

The only time it seems to happen to me is via LTEP. This is the common case that I worry about. Seems like the easiest path is adding logic within parseLtepHandshake() to screen out

Later a more robust solution can be added which manages transition more effectively.

So, the logic would be:

1) if connected over IPv6 and we get "ipv4" LTEP, and the original IPv6 is Teredo/6to4, then add IPv4 and remove the original IPv6 atom... but where in the call stack?

2) if connected over IPv4 and we get "ipv6" LTEP, and the new IPv6 is Teredo/6to4, then ignore.

The originating address comes in via msgs->peer->atom, but currently that is hidden from within peer-msgs.c. Is that on purpose?

At a minimum, (2) can be implemented immediately.

Last edited 9 years ago by reardon (previous) (diff)
Note: See TracTickets for help on using tickets.