Giter Site home page Giter Site logo

Comments (8)

Tachi107 avatar Tachi107 commented on August 26, 2024

Hi, thanks for your report!

Unfortunately I though that AAAA records were supported, but I have no way to test it as my ISP only gives me IPv4 addresses.

I'll try to see if I can spot the issue.

Do you have any suggestions regarding IPv6 testing?

from cloudflare-ddns.

stephanlachnit avatar stephanlachnit commented on August 26, 2024

Thanks for the fast reply. In case I can help you debug, let me know how. Maybe I have time to dig a bit in the code on the weekend as well.

One suggestion would be to have a "debug" or "verbose" mode where the json from the request would be printed, but I suspect this would either require an env var or a larger rewrite or the cli arg parsing.

Wrt to the testing: maybe you can just point a AAAA record to a random IP v6 (e.g. from google.com), and fake the icanhazip function with to give you some other IP v6.

from cloudflare-ddns.

Tachi107 avatar Tachi107 commented on August 26, 2024

from cloudflare-ddns.

stephanlachnit avatar stephanlachnit commented on August 26, 2024

As for the "cli arg parsing", I took what you could call a minimalist approach. Instead of properly parsing the arguments [...]

So I check for the number of arguments and if it is zero I use the config in /etc, if it's two I load the second argument as the config file, and if it's three I use the three args as the config data. No command line parser libraries required. I know, it's an ugly hack, it's not extensible, but it's the first thing that came to my mind and it works!

Yeah, I've looked a bit into that part to find out if there is any verbose option.

So yes, a verbose mode would definitely be necessary if cloudflare-ddns had a couple of extra features, but for the time being only logging the json on error should be enough to figure out what went wrong.

If you want a lightweight parser, you could go e.g. with https://github.com/jarro2783/cxxopts (https://tracker.debian.org/pkg/cxxopts, https://wrapdb.mesonbuild.com/v2/cxxopts_3.0.0-1/cxxopts.wrap). I can understand if you don't want to add this to keep it as minimal as possible, but proper error reporting would be nice :)

trying to edit a nonexistent record (could be report it, but come on, you're supposed to at least insert valid data ;)

FYI, I took me quite a while to find the "Zone ID" :)

Mhh, I could even set up a small server like icanhazip that simply returns a fake IPv6 address so that cloudflare-ddns sends that as the new IP address to Cloudflare, to see what happens. Thanks for the suggestion!

Setting a server up for this is maybe it much :D I would just replace this:

const std::string_view response_sv {response.buffer, response.size};

with this

const std::string_view response_sv {"ip=2345:0425:2CA1:0000:0000:0567:5673:23b5\n"};
// example IP v6 for testing from https://ipcisco.com/lesson/ipv6-address/

Send that to a test AAAA entry on Cloudflare and see what is happening.

from cloudflare-ddns.

Tachi107 avatar Tachi107 commented on August 26, 2024

I can understand if you don't want to add this to keep it as minimal as possible, but proper error reporting would be nice :)

I don't necessarily need to embed a proper CLI parser to add a --verbose option though (but I probably should). I generally don't like having options when a better default behaviour could solve the problem instead, and in this case proper error reporting should be enough. I should've done that earlier, I know :)

FYI, I took me quite a while to find the "Zone ID" :)

Yeah it took me a lot too of time too. Maybe a screenshot could help.

Setting a server up for this is maybe it much :D

Yep, sorry but I was quite tired yesterday and that clearly didn't make sense..

Anyway, I tried reproducing your issue, but cloudflare-ddns worked just fine.

Here's what I did:

  • Created a DNS record called dbgtemp.domain.tld with value 2620:fe::fe
  • Replaced the occurrences of local_ip.data() with 2345:0425:2CA1:0000:0000:0567:5673:23b5 so that the tool thinks that it has to update the DNS record
  • Ran the tool

Everything worked as expected, and the record was correctly updated.

This makes me think that the issue might not be in the functions that talk to the API, but in the get_local_ip() function, i.e. the one that figures out what's the IP address of the device running cloudflare-ddns, and unfortunately I can't easily fake that. To find the IP address it makes a request to https://one.one.one.one/cdn-cgi/trace and parses the response. The parsing is done with the IPv4 response in mind, as I don't even know how the response looks when querying the page with an IPv6 address. For example, here's what I get if I curl it:

fl=270f68
h=one.one.one.one
ip=128.116.201.23
ts=1651600677.626
visit_scheme=https
uag=curl/7.82.0
colo=MXP
http=http/2
loc=IT
tls=TLSv1.3
sni=plaintext
warp=off
gateway=off

Based on this format, the current parsing is done searching for ip= and reading from there until the newline character, and considering that as the local IP address.

Could you please send me the body of that page when queried from an IPv6 address? I could then use that as a mock response. Thanks!

As I ran this in a debugger I was able to get the API responses, to make sure that nothing strange was happening behind the scenes; here there are, for completeness:

get_record_raw call (gets info about a DNS record from Cloudflare)

{
	"result": [
		{
			"id": "something",
			"zone_id": "something_else",
			"zone_name": "domain.tld",
			"name": "dbgtemp.domain.tld",
			"type": "AAAA",
			"content": "2620:fe::fe",
			"proxiable": true,
			"proxied": false,
			"ttl": 60,
			"locked": false,
			"meta": {
				"auto_added": false,
				"managed_by_apps": false,
				"managed_by_argo_tunnel": false,
				"source": "primary"
			},
			"created_on": "2022-05-03T16:14:46.906459Z",
			"modified_on": "2022-05-03T16:14:46.906459Z"
		}
	],
	"success": true,
	"errors": [],
	"messages": [],
	"result_info": {
		"page": 1,
		"per_page": 100,
		"count": 1,
		"total_count": 1,
		"total_pages": 1
	}
}

set_record_raw() call (updates a DNS record)

{
	"result": {
		"id": "something",
		"zone_id": "something_else",
		"zone_name": "domain.tld",
		"name": "dbgtemp.domain.tld",
		"type": "AAAA",
		"content": "2345:0425:2ca1:0000:0000:0567:5673:23b5",
		"proxiable": true,
		"proxied": false,
		"ttl": 60,
		"locked": false,
		"meta": {
			"auto_added": false,
			"managed_by_apps": false,
			"managed_by_argo_tunnel": false,
			"source": "primary"
		},
		"created_on": "2022-05-03T16:14:46.906459Z",
		"modified_on": "2022-05-03T17:16:15.448064Z"
	},
	"success": true,
	"errors": [],
	"messages": []
}

from cloudflare-ddns.

stephanlachnit avatar stephanlachnit commented on August 26, 2024

FYI, I took me quite a while to find the "Zone ID" :)

Yeah it took me a lot too of time too. Maybe a screenshot could help.

Good idea!

Yep, sorry but I was quite tired yesterday and that clearly didn't make sense..

No worries :)

To find the IP address it makes a request to https://one.one.one.one/cdn-cgi/trace and parses the response. The parsing is done with the IPv4 response in mind, as I don't even know how the response looks when querying the page with an IPv6 address.

Already checked that, but I don't think that's it. Looks pretty much the same:

fl=75f74
h=one.one.one.one
ip=2003:e4:2f19:8901:1fb7:fed:9b2a:ae4b
ts=1651601270.597
visit_scheme=https
uag=Mozilla/5.0 (X11; Linux x86_64; rv:99.0) Gecko/20100101 Firefox/99.0
colo=HAM
http=http/2
loc=DE
tls=TLSv1.3
sni=plaintext
warp=off
gateway=off

This makes me think that the issue might not be in the functions that talk to the API, but in the get_local_ip() function, i.e. the one that figures out what's the IP address of the device running cloudflare-ddns, and unfortunately I can't easily fake that.

One thought: do you enforce IP v4 / v6 when running curl? A quickly skimmed the code and I didn't find a difference. Maybe it tries to update an AAAA record with a v4 IP?

Just a quick idea I have is to check if result.type is an A or AAAA record in get_record and set a corresponding enum for the type (e.g. INVALID, A, AAAA, CNAME). This enum is then given to the get_local_ip function to enforce the respective IP protocol. This would require a SOVERSION bump though (which I don't think is a big issue at this stage of the project).

from cloudflare-ddns.

Tachi107 avatar Tachi107 commented on August 26, 2024

Already checked that, but I don't think that's it. Looks pretty much the same:

And in fact using your response as a mock didn't help, the record is successfully updated anyway.

One thought: do you enforce IP v4 / v6 when running curl?

Nope, I do not enforce it (I don't even know if it is possible).

Maybe it tries to update an AAAA record with a v4 IP?

Oh, that might be the issue. Until now I supposed that a given host either has an IPv4 or an IPv6 address, but not both. But clearly this is not true and creates issues because now you don't know what kind of address a call to get_local_ip() could return.

So what's probably happening in your setup is that get_local_ip() is returning the IPv4 address of your host (even if it also has an IPv6 one), while what you want to update is an AAAA record, so when cloudflare-ddns tries to set the remote IPv6 address value to the local IPv4 address it triggers an error.

To be sure that this is the case, I wrote a quick patch that logs more things in case of error, 2104e13. I've attached the corresponding .debs. Thanks again!

cloudflare-ddns-error-debs.tar.gz

from cloudflare-ddns.

stephanlachnit avatar stephanlachnit commented on August 26, 2024

One thought: do you enforce IP v4 / v6 when running curl?

Nope, I do not enforce it (I don't even know if it is possible).

At least with curl's CLI you can do so:

curl -4 icanhazip.com && curl -6 icanhazip.com

Edit: found it for libcurl: https://curl.se/libcurl/c/CURLOPT_IPRESOLVE.html

Maybe it tries to update an AAAA record with a v4 IP?

Oh, that might be the issue. Until now I supposed that a given host either has an IPv4 or an IPv6 address, but not both. But clearly this is not true and creates issues because now you don't know what kind of address a call to get_local_ip() could return.

So what's probably happening in your setup is that get_local_ip() is returning the IPv4 address of your host (even if it also has an IPv6 one), while what you want to update is an AAAA record, so when cloudflare-ddns tries to set the remote IPv6 address value to the local IPv4 address it triggers an error.

To be sure that this is the case, I wrote a quick patch that logs more things in case of error, 2104e13. I've attached the corresponding .debs. Thanks again!

Thanks for the builds!
And jup, looks like we have it:

New IP: Something went really wrong. Here's what:
	The JSON element does not have the requested type.

Here's some more info that could help:
	Local IP: 84.131.254.222
	DNS response: {"result":null,"success":false,"errors":[{"code":9006,"message":"Content for AAAA record must be a valid IPv6 address."}],"messages":[]}

from cloudflare-ddns.

Related Issues (8)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.