After upgrading, I noticed there was a (private) tracker that prevented connections to other peers, due to the internal ip on the private subnet being reported together with my external. Setting network.local_address.set to my external ip fixed this, but it seems inconvenient to have to do this, especially if you don't have a fixed ip.
Thanks for the bug report!
You can/should use this approach to prevent the bug.
If that is a regression of 0.9.7, then it should be changed to use 0.0.0.0 or something to get the old behaviour.
I believe this commit introduced the bug: https://github.com/rakshasa/libtorrent/commit/d0b7724febec620c43babf08fcb5a6f4148af01c
I'm not quite sure but I believe that should be && not || in the conditional. Otherwise the check passes even on ipv4 connections to the tracker, therefore sending whatever libtorrent determines the "local address" is as a parameter.
Even if the bug can be fixed through this change, I suggest that it's a bad idea to try guessing the local address to send as a param without the user requesting it in the config. For any computer NATed by a router, it's going to find the wrong address since the computer isn't assigned a public IPv4 address under NAT.
Hi everyone ! 7 monthes later, the bug is still present, can you merge it ? :/
+1 to please merge it :) This bug is really annoying
Having the same issue, please merge the fix. Thanks.
Any news about when this fix might be merged?
Hi all, in case it's unclear, I just wrote the patch - I'm not one of the developers and I can't merge this myself. Unfortunately they seem to have gone on indefinite hiatus again.
Does anyone know which trackers are affected by this? What is happening here is that in addition to connecting over IPv4, rtorrent is sending another address via &ipv4=x.x.x.x. What some trackers are apparently doing is throwing out the implicit good address and accepting the explicit address sent by rtorrent. IMO this is definitely buggy behavior on their part - the explicit address should never differ from the implicit one, especially if the address being sent is a reserved local one (e.g. in 192.168/16). They should just completely ignore the &ipv4 tag for IPv4 connections. If you have a way of contacting these trackers, or you know what software they're using, reporting this problem upstream may get you better results.
If that isn't an option for you, you can either rebuild rtorrent yourself, or see if one of the following in your .rtorrent.rc works for you.
network.local_address.set = ""
network.local_address.set = "0.0.0.0"
network.local_address.set = "127.0.0.1"
Does anyone know which trackers are affected by this?
EMP for me at least.
EMP for me at least.
omg ew...
(same here)
I know this might be the long way around, but since the fix mentioned by @chros73 isn't working for me, I ended up writing a short bash-script that gets my external IP and leaves that in a txt-file. Unfortunately I can't quite get rtorrent to read the file and set network.local_address.set as the contents of that file.
Any help would be appreciated, what I have so far is:
# Get public IP address without the need of having dynamic DNS service, also works from behind NAT, through tunnel
method.insert = get_public_ip_address, simple|private, "execute.capture=bash,-c,\"cat /ip_chech/ip\""
# The IP address reported to the tracker. (ip) This handles dynamic IP's as well.
schedule2 = ip_tick, 0, 1800, "network.local_address.set=(get_public_ip_address)"
I run the pingcheck-script and rtorrent in separate dockers so /ip_check/ip is a shared folder and file between them.
isn't working for me
Which part of it doesn't work? :)
You need to escape the inner quotes:
method.insert = get_public_ip_address, simple|private, "execute.capture=bash,-c,\"cat /ip_chech/ip\""
@chros73 - Hmm, I feel like I had that in my code, but it's clear I lost it when I wrote it here. I've just tried it - using your correction, but it still doesn't work.
The reason your original method isn't working is because the docker-image I'm using doesn't come with dnsutils/dig-command.
I'm not sure how I would "break up the test" to see whether the issue is with the first (method.insert) or second command (schedule2), but since "network.local_adress.set" works as a separate command in itself (IE. network.local_address.set = XXX.XXX.XXX.XXX) I feel like the issue is with the first part (method.insert), but I might be wrong :)
The whole command (cat /ip_chech/ip) needs to return back a string without a newline for execute.capture.
You can try out your get_public_ip_address method in rtorrent, hit CTRL+X then use this command:
print=$get_public_ip_address=
Okay, so, I figured out how to remove the newline in bash, using the command:
cat /ping_check/ip | tr -d '\n' - my next issue is I can't quite figure out how many escape-characters I need or how to create them. I thought I needed to do like this:
method.insert = get_public_ip_address, simple|private, "execute.capture=bash,-c,\"eval cat /ip_chech/ip | tr -d '\n' \""
But that isn't quite right, as rtorrent doesn't set the IP correctly. Testing the command in rtorrent gives the following to feedbacks:
When starting or Schedule2 ticks rtorrent says: "Scheduled command failed: ip_tick: Could not set local address: Name does not resolve."
When trying to run the command, as suggested (print=$get_public_ip_address=) it simply reads a blank line - it gives the time of the input/output, but there is nothing in the line.
I'm fairly certain that what I'm missing is a way to remove the newline and correctly escape the sequence of characters needed to do that, am I onto the right path?
I've tried it both with and without eval, and that doesn't change anything.
Okay, so I've moved past the first issue, getting "get_public_ip_address" to actually give a result. When I run that command now (print=$get_public_ip_address=) it gives me a correct IP, IE. my external IP from the VPN.
The command I've used to get the first bit to resolve is:
"execute.capture=bash,-c,\"head -n 1 /ip_check/ip \"" - this solves the first bit (getting the first line of a file read into as a variable).
However, the schedule2 still fails. The output I get from that is:
"Scheduled command failed: ip_tick: Could not set local address: Name does not resolve."
Just to reiterate, you shouldn't need any scripts - &ipv4 is an optional parameter. At least one of the following in your config should get you the old libtorrent 0.13.6 behavior:
network.local_address.set = ""
network.local_address.set = "0.0.0.0"
network.local_address.set = "127.0.0.1"
See if your tracker admins can fix this for you.
Hi @afontenot - thanks for your solution, it seems to have solved the issue of the tracker status being "Invalid IP detected" when I use network.local_address.set = 127.0.0.1 .
However, this keeps rtorrent reporting two IP's to the tracker. I've tested it with http://ipmagnet.services.cbcdn.com - where it reports two IP's to the tracker:
Timestamp | IP address(es) | User Agent
-- | -- | --
28.03.2019 08:35:19 | (MyVpnIP), 127.0.0.1 | rtorrent/0.9.7/0.13.7
So, I prefer the method of using a script to set the network.adress to only my external IP - but I might not undertand why rtorrent needs to report my internal IP too?
So, if anyone is able to help me fix the current issue where I'm getting:
"Could not set local address: Name does not resolve." as output when I run the command: network.local_address.set=(get_public_ip_address) - now the weird thing is that when I set the IP of MyVPNIP in rtorrent.rc using the following syntax:
network.local_address.set= MyVPNIP
rtorrent accepts it and runs with it - and ipmagnet only reports one IP:
Timestamp | IP address(es) | User Agent
-- | -- | --
28.03.2019 08:35:19 | (MyVpnIP) | rtorrent/0.9.7/0.13.7
So, in short - how do I fix the fact that when I set my current dynamic IP in rtorrent.rc using:
network.local_address.set= MyVPNIP it works and when I set the same using:
schedule2 = ip_tick, 0, 180, "network.local_address.set=(get_public_ip_address)" it doesn't work because rtorrent tries to resolve the hostname ("Could not set local address: Name does not resolve.") - especially given that the output of print=$get_public_ip_address= in rtorrent CLI is exactly my MyVPNIP
Update - the issue has been solved.
I reinvestigated the output I got from "execute.capture=bash,-c,"head -n 1 /ip_check/ip "". As is turns out there was a $ at the end of the file that wasn't printed until I checked using cat -A /ping_check/ip.
So, re-doing the execute.capture-command to be:
"execute.capture=bash,-c,\"head -c -1 /ip_check/ip \"" has solved the issue. I now have rtorrent only reporting one IP to the tracker, and that IP is the IP contained in the file created by my ping_check-docker.
Thank you @chros73 and @afontenot for helping out with solutions, and general understanding of rtorrent, I learned a lot by troubleshooting this with you guys!
@afontenot Wanted to say thanks! Manually inserted your commit and rebuilt libtorrent.
I do have one question:
My rtorrent is running on a dual stack connection and without your fix rtorrent reported 3 IPs to the tracker (tested this here):
External IPv4, External IPv6, Internal IPv4
After using your fix rtorrent is only reporting the External IPv4, not the External IPv6.
Is this expected behavior?
Thanks!
EDIT: Well, rakshasa just merged it lol. So I guess it's fine!
Most helpful comment
+1 to please merge it :) This bug is really annoying