Skip to content

Ensure single IPv6 record per subdomain in Cloudflare provider - #301

Merged
TimothyYe merged 4 commits into
masterfrom
claude/ensure-single-ipv6-per-subdomain
Jul 26, 2026
Merged

Ensure single IPv6 record per subdomain in Cloudflare provider#301
TimothyYe merged 4 commits into
masterfrom
claude/ensure-single-ipv6-per-subdomain

Conversation

@Claude

@Claude Claude AI commented Mar 8, 2026

Copy link
Copy Markdown
Contributor

During network restarts with rapid IPv6 address changes, multiple AAAA records accumulate for the same subdomain in Cloudflare, leaving both valid and stale IP addresses that cause connectivity issues.

Changes

  • Added deleteRecord method: Implements DNS record deletion via Cloudflare API DELETE endpoint

  • Refactored UpdateIP logic:

    • Changed from strings.Contains() to exact domain name matching (rec.Name == fullDomainName)
    • Collects all matching records for a subdomain before processing
    • Updates the first record with correct IP or keeps it if already correct
    • Deletes all duplicate records in a cleanup pass

Behavior

Before: Multiple AAAA records could exist for the same subdomain

service.example.com -> 2001:db8::a34d:163a:dc1c
service.example.com -> 2001:db8::c8ab:790:5b7  (stale)

After: Only one record remains per subdomain

service.example.com -> 2001:db8::a34d:163a:dc1c

Duplicate deletion failures are logged but don't prevent successful IP updates.

Original prompt

This section details on the original issue you should resolve

<issue_title>Cloudflare 确保每个子域名仅有一个 IPv6 地址</issue_title>
<issue_description>有时主机网络在重启过程中出现 IP 反复横跳的问题:

Mar 20 21:46:18 godns[991]: time="2025-03-20T21:46:18+08:00" level=info msg="Checking IP for domain ***1.example.com"
Mar 20 21:46:19 godns[991]: time="2025-03-20T21:46:19+08:00" level=info msg="Querying records with type: AAAA"
Mar 20 21:46:29 godns[991]: time="2025-03-20T21:46:29+08:00" level=error msg="Request error:Get \"https://api.cloudflare.com/client/v4/zones/****/dns_records?type=AAAA&page=1&per_page=500\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)"
Mar 20 21:46:30 godns[991]: time="2025-03-20T21:46:30+08:00" level=info msg="Record [service] created with IP address: ****:a34d:163a:dc1c"
Mar 20 21:46:31 godns[991]: time="2025-03-20T21:46:31+08:00" level=info msg="Checking IP for domain ***2.example.com"
Mar 20 21:46:32 godns[991]: time="2025-03-20T21:46:32+08:00" level=info msg="Querying records with type: AAAA"
Mar 20 21:46:32 godns[991]: time="2025-03-20T21:46:32+08:00" level=info msg="IP mismatch: Current(****:a34d:163a:dc1c) vs Cloudflare(****:c8ab:790:5b7)"
Mar 20 21:46:33 godns[991]: time="2025-03-20T21:46:33+08:00" level=info msg="Record updated: ***2.example.com - ****:a34d:163a:dc1c"
Mar 20 21:56:54 godns[991]: time="2025-03-20T21:56:54+08:00" level=info msg="Checking IP for domain ***1.example.com"
Mar 20 21:56:54 godns[991]: time="2025-03-20T21:56:54+08:00" level=info msg="Querying records with type: AAAA"
Mar 20 21:56:55 godns[991]: time="2025-03-20T21:56:55+08:00" level=info msg="IP mismatch: Current(****:c8ab:790:5b7) vs Cloudflare(****:a34d:163a:dc1c)"
Mar 20 21:56:56 godns[991]: time="2025-03-20T21:56:56+08:00" level=info msg="Record updated: ***2.example.com - ****:c8ab:790:5b7"
Mar 20 21:56:56 godns[991]: time="2025-03-20T21:56:56+08:00" level=info msg="IP mismatch: Current(****:c8ab:790:5b7) vs Cloudflare(****:a34d:163a:dc1c)"
Mar 20 21:56:57 godns[991]: time="2025-03-20T21:56:57+08:00" level=info msg="Response failed: "
Mar 20 21:56:57 godns[991]: time="2025-03-20T21:56:57+08:00" level=info msg="Record OK: ***1.example.com - ****:c8ab:790:5b7"
Mar 20 21:56:57 godns[991]: time="2025-03-20T21:56:57+08:00" level=info msg="Checking IP for domain ***2.example.com"
Mar 20 21:56:58 godns[991]: time="2025-03-20T21:56:58+08:00" level=info msg="Querying records with type: AAAA"
Mar 20 21:56:59 godns[991]: time="2025-03-20T21:56:59+08:00" level=info msg="Record OK: ***2.example.com - ****:c8ab:790:5b7"

最终,两个 IP 都在 Cloudflare 中留下了,但实际只有一个能用,访问的时候就会访问到已失效的地址。
如何在每次更新时确保子域名只有一个 IP?</issue_description>

Comments on the Issue (you are @claude[agent] in this section)

@TimothyYe 运营商给你分配了不止一个IPv6地址吗?

Co-authored-by: TimothyYe <860685+TimothyYe@users.noreply.github.com>
@Claude Claude AI changed the title [WIP] Fix issue with multiple IPv6 addresses per subdomain Ensure single IPv6 record per subdomain in Cloudflare provider Mar 8, 2026
@TimothyYe
TimothyYe marked this pull request as ready for review March 8, 2026 14:40
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@TimothyYe

Copy link
Copy Markdown
Owner

Updated the branch:

  • Merged latest master (branch was 42 commits behind).
  • Adapted the new deleteRecord to the updated newRequest signature from 048e04d (it now returns an error) — the textual merge was clean but the result didn't compile without this.
  • Added behavior tests (cloudflare_verify_test.go, httptest mock of the Cloudflare API) covering: dedup of multiple stale AAAA records (the Cloudflare 确保每个子域名仅有一个 IPv6 地址 #268 scenario), root-domain @ dedup, no-op when the single record is already up to date, record creation when missing, and exact-name matching (the old strings.Contains false-match is gone). All tests pass.

🤖 Generated with Claude Code

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@TimothyYe
TimothyYe merged commit 2c905cb into master Jul 26, 2026
6 checks passed
@TimothyYe
TimothyYe deleted the claude/ensure-single-ipv6-per-subdomain branch July 26, 2026 02:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cloudflare 确保每个子域名仅有一个 IPv6 地址

2 participants