eustasy / Phoenix

A lightweight BitTorrent Tracker written in PHP with an SQL backend.
MIT License
18 stars 6 forks source link

FEATURE: Add IPv6 support. [$100 awarded] #3

Closed lewisgoddard closed 9 years ago

lewisgoddard commented 9 years ago

We have IPv6 on the server, but major changes need to be made for it to work.

--- The **[$100 bounty](https://www.bountysource.com/issues/7299608-feature-add-ipv6-support?utm_campaign=plugin&utm_content=tracker%2F10163092&utm_medium=issues&utm_source=github)** on this issue has been claimed at [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F10163092&utm_medium=issues&utm_source=github).
lewisgoddard commented 9 years ago

This will require changes to both announce and scrape, as well as the installation script for the database layout. All in all a major change to the current system, and many people do not get IPv6 in their homes yet. We should check both compatibility and the Bittorrent standards first.

lewisgoddard commented 9 years ago

While this is a nice idea, and one I quite like, the official Bittorrent Protocol Specification IPv6 Tracker Extension is in a draft state. http://www.bittorrent.org/beps/bep_0007.html

That said, many Spec. Extensions are in a draft state, including DHT, which is widely deployed. This spec seems to work much like HTML, where something is written and used, and if it is widely used a year or two later it becomes official.

lewisgoddard commented 9 years ago

I can't recall why I listed "Add Peers6 to Scrape" as "Optional".

NCommander commented 9 years ago

I've got phoenix setup on an IPv6 capable host, and got Transmission sending IPv6 requests to it. I've got the IPv6 column added to the database. Need to add handling specific support for the ipv4= argument.

lewisgoddard commented 9 years ago

It also seems like there's the option for ipv6= when requesting over IPv4 as well, which I think would be within the scope of this bug.

NCommander commented 9 years ago

I'm handling that case as well. Just finding PHP's tools for dealing with IP addresses sadly sucking :(

NCommander commented 9 years ago

So, digging deeper into this, I think the external_ip switch won't work properly with IPv6 due to privacy extensions:

https://en.wikipedia.org/wiki/IPv6#Privacy https://tools.ietf.org/html/rfc4941

The short version is the IPv6 address a client connects may not be its real IPv6 address; it can generate a new one for each outbound connection when a client is using SLAAC which is a very common setup. I realize this allows clients to put garbage in the tracker, but there's no good way of handling this; BT clients will see it as a dead client and ignore it so its not the end of the world.

enebe-nb commented 9 years ago

I can't get any IPv6 address to test this correctly (modem have incompatibility with tunneling). Can you test this branch? https://github.com/enebe-nb/phoenix/tree/ipv6-support Tell any problem you find.

There is database changes on branch.

NCommander commented 9 years ago

I'll test it, but the regexs look suspect to me. Praising IPv6 by regex is always a bad idea.

NCommander commented 9 years ago

@enebe-nb Tested it on my IPv6 host. IPv6 addresses are ignored and not logged. From the database:

mysql> select * from peers\G *** 1. row *** info_hash: eb2aecc27eb203e43b824a2b9fb54007265b0889 peer_id: 2d5452323832302d65786b756f65773669797974 compact: 4a4b80d1c8d5 ip: 74.75.128.209 port: 51413 compactv6: NULL ipv6: NULL portv6: NULL left: 0 state: 1 updated: 1439834334 1 row in set (0.00 sec)

Here's the access request:

2604:6000:9fc0:6b:4ddd:9289:51d0:b412 - - [17/Aug/2015:13:59:20 -0400] "GET /phoenix/announce.php?info_hash=%eb%2a%ec%c2~%b2%03%e4%3b%82J%2b%9f%b5%40%07%26%5b%08%89&peer_id=-TR2820-jtyitmn7mjm8&port=51413&uploaded=0&downloaded=0&left=0&numwant=80&key=2359891c&compact=1&supportcrypto=1&event=started&ipv6=2604%3A6000%3A9fc0%3A6b%3A4ddd%3A9289%3A51d0%3Ab412 HTTP/1.1" 200 284 "-" "Transmission/2.82"

NCommander commented 9 years ago

@enebe-nb I made a mistake, and my test torrent was pointed at the wrong announce address, its properly logged IPv6 announces:

*** 1. row *** info_hash: eb2aecc27eb203e43b824a2b9fb54007265b0889 peer_id: 2d5452323832302d307a6969363461743038786a compact: NULL ip: NULL port: NULL compactv6: 260460009fc0006b4ddd928951d0b412c8d5 ipv6: 2604:6000:9fc0:6b:4ddd:9289:51d0:b412 portv6: 51413 left: 0 state: 1 updated: 1439835731

I'm testing torrenting to a second v6 host now

NCommander commented 9 years ago

@enebe-nb: appears to work fine. I'm successfully torrenting a linux src ball via IPv6 from my laptop to my desktop. Congrats on getting the bounty, but please, next time, mark that you're working on it on BountySource so people don't duplicate effort.

enebe-nb commented 9 years ago

@NCommander You can take the bounty, i got another. Just thought you are using it, anyway, i couldn't make without you testing.

NCommander commented 9 years ago

@enebe-nb Wow, thanks. I'll make sure to play that forward next time I run into this situation with bounties :). I'm doing some more testing, and writing a simple test suite to make sure there aren't any missing edge cases with the patch.

NCommander commented 9 years ago

Caught a bug, I'll fix it. IPv4 parameter is ignored (always uses "real" adddress), and the regex for port doesn't properly get handled. I'll post a fixed branch in a bit.

NCommander commented 9 years ago

Ok, after an extensive round of testing, I figured out the following:

@enebe-nb's branch doesn't properly handle IP detection. BT-007 requires specific handling based if the connection is made via IPv4/IPv6. I ended up taking the announce.php work from my branch and replacing it. I reused enebe's code determining compact since I hadn't gotten that far on writing it

I'm not sure if this is a bug that existed but I was ending up with duplicated hosts in peers. I believe the reason for this is that Transmission seems to recycle the download_id for each time it takes a torrent. I added an explicate delete -> new when we do an update which solved the issue and will work around buggy clients.

There's a potential security hole since Phoenix regards X-Forwarded-For/X-HTTP-IP as valid in all cases. This allows for trivial IP spoofing. I've added a specific switch to settings.*.php to turn this on and off.

IPv6 support on hosts that support privacy extensions will almost certainty break if the tracker doesn't honor the client's IP, so we always honor it when dealing with IPv6 hosts.

The current branch I have is 90% my code, 10% from @enebe-nb. I'll post it after I finish coding up a final edge case for review. I can confirm this branch handles torrenting via IPv6 properly. Need to test IPv4 seeding when a seeder has both. Scrape doesn't appear to require any specific IPv6 changes.

NCommander commented 9 years ago

Pull request in place in #13. Ive tested this to the best of my ability; the only edge case I haven't tried is IPv6-only to IPv6-only, but I can't test that situation easily.

NCommander commented 9 years ago

Revised pull request posted.