From a27d593eac81f9c2a52440d3ed72d6083a33a52a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andr=C3=A9=20Frimberger?= Date: Sat, 18 Oct 2014 19:55:02 +0200 Subject: [PATCH] Update DNS server only if IP has changed. --- src/Dyndns/Helper.php | 101 +++++++++++++++++++++++++++++++++++++++++++++++++- src/Dyndns/Hosts.php | 11 +++--- 2 files changed, 106 insertions(+), 6 deletions(-) diff --git a/src/Dyndns/Helper.php b/src/Dyndns/Helper.php index 8c2b316..07f53ce 100755 --- a/src/Dyndns/Helper.php +++ b/src/Dyndns/Helper.php @@ -15,10 +15,109 @@ class Helper */ public static function checkValidIp($ip) { - return filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) || filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6); + return Helper::isIPv4Addr($ip) || Helper::isIPv6Addr($ip); } /** + * Is IP address a valid IPv4 address? + * + * @param string IP address + * @return boolean True if IP is a valid IPv4 address + */ + public static function isIPv4Addr($ip) + { + return filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4); + } + + /** + * Is IP address a valid IPv6 address? + * + * @param string IP address + * @return boolean True if IP is a valid IPv6 address + */ + public static function isIPv6Addr($ip) + { + return filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6); + } + + + /** + * Returns DNS record type depending on the IP version + * + * @param string IP address + * @return String record type or FALSE + */ + public static function getRecordType($ip) + { + if (Helper::isIPv4Addr($ip)) { + return "A"; + } + + if (Helper::isIPv6Addr($ip)) { + return "AAAA"; + } + + return FALSE; + } + + + /** + * Returns DNS record id depending on the IP version + * + * @param string IP address + * @return int record id or FALSE + */ + public static function getRecordId($ip) + { + if (Helper::isIPv4Addr($ip)) { + return DNS_A; + } + + if (Helper::isIPv6Addr($ip)) { + return DNS_AAAA; + } + + return FALSE; + } + + /** + * Checks if IP has changed + * + * @param string hostname + * @param string IP address + * @param string authoritative name servers + * @return boolean True if IP has changed + */ + public static function hasIPChanged($hostname, $newIp, $ns = NULL) + { + $record_id = Helper::getRecordId($newIp); + $dnsRes = dns_get_record($hostname, $record_id, $ns); + + foreach ($dnsRes as $k => $v) { + $currIp = "invalid"; + + // IPv4: + if (array_key_exists("ip", $v)) { + $currIp = $v["ip"]; + } + + // IPv6 + if (array_key_exists("ipv6", $v)) { + $currIp = $v["ipv6"]; + } + + $currIpPton = inet_pton($currIp); + $newIpPton = inet_pton($newIp); + + if (strcmp($currIpPton, $newIpPton) === 0) { + return false; + } + } + + return true; + } + + /** * Check valid hostname (FQDN) * * @param string Hostname diff --git a/src/Dyndns/Hosts.php b/src/Dyndns/Hosts.php index d06dcc7..4d98cf7 100755 --- a/src/Dyndns/Hosts.php +++ b/src/Dyndns/Hosts.php @@ -171,15 +171,16 @@ class Hosts fwrite($fh, "server $server\n"); fwrite($fh, "zone $zone\n"); foreach ($this->updates as $host => $ip) { - $recType = "unknown record type"; + $recType = Helper::getRecordType($ip); - if( filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) ){ - $recType = "A"; + if ($recType === FALSE) { + $this->debug('ERROR: unknown record type'); } - if( filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) ){ - $recType = "AAAA"; + if (! Helper::hasIPChanged($host, $ip)) { + continue; } + fwrite($fh, "update delete $host $recType\n"); fwrite($fh, "update add $host $ttl $recType $ip\n"); } -- 2.1.4