From 5d669158b1ad2983ea94ba069c822a007c0feb0c Mon Sep 17 00:00:00 2001
From: Erick Hitter <git-contrib@ethitter.com>
Date: Sat, 30 Dec 2017 15:26:49 -0800
Subject: [PATCH] Improve IPv6 Support

* Allow to be skipped if used with an ISP that doesn't provide IPv6
* Support reducing to prefix if running multiple instances; otherwise, instance portion of IPv6 address causes excessive updating

Fixes #1
---
 config-sample.json |  3 ++-
 dyndnsd-client.go  | 38 +++++++++++++++++++++++++-------------
 2 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/config-sample.json b/config-sample.json
index 98be7b1..193e51d 100644
--- a/config-sample.json
+++ b/config-sample.json
@@ -7,5 +7,6 @@
   "path": "",
   "dns_hostname": "",
   "ipv4_endpoint": "http://whatismyip.akamai.com/",
-  "ipv6_endpoint": "http://ipv6.whatismyip.akamai.com/"
+  "ipv6_endpoint": "http://ipv6.whatismyip.akamai.com/",
+  "ipv6_use_prefix": true
 }
\ No newline at end of file
diff --git a/dyndnsd-client.go b/dyndnsd-client.go
index 3d31f0d..fbb51d2 100644
--- a/dyndnsd-client.go
+++ b/dyndnsd-client.go
@@ -57,7 +57,7 @@ func main() {
 	// IPv4 is required
 	if ipv4, err := getUrl(ipv4Endpoint); err == nil {
 		if ipv4Valid := net.ParseIP(ipv4); ipv4Valid == nil {
-			logger.Println("Invalid IPv4 address")
+			logger.Println("Invalid IPv4 address returned by endpoint")
 			logger.Printf("%s", err)
 			return
 		} else {
@@ -72,20 +72,32 @@ func main() {
 	}
 
 	// IPv6 is optional
-	if ipv6, err := getUrl(ipv6Endpoint); err == nil {
-		if ipv6Valid := net.ParseIP(ipv6); ipv6Valid == nil {
-			logger.Println("Invalid IPv6 address")
-			logger.Printf("%s", err)
+	// Leave empty to skip
+	if len(ipv6Endpoint) > 0 {
+		if ipv6, err := getUrl(ipv6Endpoint); err == nil {
+			if ipv6Valid := net.ParseIP(ipv6); ipv6Valid == nil {
+				logger.Println("Invalid IPv6 address returned by endpoint")
+				logger.Printf("%s", err)
+			} else {
+				var ipv6String string
+				var usePrefix bool
+				cfg.Get("ipv6_use_prefix", &usePrefix)
+				ipMask := fmt.Sprintf("%s/%d", ipv6Valid.String(), 64)
+
+				if ipv6, network, err := net.ParseCIDR(ipMask); usePrefix && err == nil {
+					ipv6String = network.String()
+				} else {
+					ipv6String = ipv6.String()
+				}
+
+				query := endpoint.Query()
+				query.Set("myip6", ipv6String)
+				endpoint.RawQuery = query.Encode()
+			}
 		} else {
-			// TODO: parse to /64, use ::1.
-
-			query := endpoint.Query()
-			query.Set("myip6", ipv6Valid.String())
-			endpoint.RawQuery = query.Encode()
+			logger.Println("Couldn't retrieve IPv6 address")
+			logger.Printf("%s", err)
 		}
-	} else {
-		logger.Println("Couldn't retrieve IPv6 address")
-		logger.Printf("%s", err)
 	}
 
 	// Send the update
-- 
GitLab