Update DNS server only if IP has changed.
authorAndré Frimberger <github@frimberger.de>
Sat, 18 Oct 2014 17:55:02 +0000 (19:55 +0200)
committerAndré Frimberger <github@frimberger.de>
Sat, 18 Oct 2014 17:55:02 +0000 (19:55 +0200)
src/Dyndns/Helper.php
src/Dyndns/Hosts.php

index 8c2b316..07f53ce 100755 (executable)
@@ -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
index d06dcc7..4d98cf7 100755 (executable)
@@ -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");
         }