]> git.ipfire.org Git - oddments/ddns.git/commitdiff
Merge remote-tracking branch 'stevee/dtdns.com'
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 13 Jun 2014 15:49:46 +0000 (15:49 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 13 Jun 2014 15:49:46 +0000 (15:49 +0000)
.gitignore
Makefile.am
ddns.conf.sample [moved from ddns.conf with 100% similarity]
ddns.in
src/ddns/__init__.py
src/ddns/errors.py
src/ddns/system.py

index 17f56bd5d83ac7c683d034ad20cd9ec956b5a302..dc5d2d366366b3fd9ceca0856499e0a8a6759633 100644 (file)
@@ -1,6 +1,7 @@
 /Makefile
 /build-aux
 /ddns
+/ddns.conf
 /missing
 /src/ddns/__version__.py
 /tmp
@@ -19,4 +20,7 @@ config.log
 config.status
 configure
 install-sh
+intltool-extract.in
+intltool-merge.in
+intltool-update.in
 stamp-*
index bfa5a61793f888c4b23694400e22fcb94052a316..fbf4bc1acb357565b3c6e1f7abc821b007c3ee84 100644 (file)
@@ -61,7 +61,7 @@ CLEANFILES += \
        ddns
 
 dist_configs_DATA = \
-       ddns.conf
+       ddns.conf.sample
 
 ddns_PYTHON = \
        src/ddns/__init__.py \
similarity index 100%
rename from ddns.conf
rename to ddns.conf.sample
diff --git a/ddns.in b/ddns.in
index 726eac34623927c4249f1b1d50c2a14513ce8e0e..343c396cf9ee942912f061d9f2255d2148801097 100644 (file)
--- a/ddns.in
+++ b/ddns.in
@@ -41,6 +41,10 @@ def main():
        subparsers = p.add_subparsers(help=_("Sub-command help"),
                dest="subparsers_name")
 
+       # guess-ip-addresses
+       p_guess_ip_addresses = subparsers.add_parser("guess-ip-addresses",
+               help=_("Guess the external IP addresses"))
+
        # list-providers
        p_list_providers = subparsers.add_parser("list-providers",
                help=_("List all available providers"))
@@ -66,7 +70,18 @@ def main():
                d.load_configuration(args.config)
 
        # Handle commands...
-       if args.subparsers_name == "list-providers":
+       if args.subparsers_name == "guess-ip-addresses":
+               # IPv6
+               ipv6_address = d.system.guess_external_ipv6_address()
+               if ipv6_address:
+                       print _("IPv6 Address: %s") % ipv6_address
+
+               # IPv4
+               ipv4_address = d.system.guess_external_ipv4_address()
+               if ipv4_address:
+                       print _("IPv4 Address: %s") % ipv4_address
+
+       elif args.subparsers_name == "list-providers":
                provider_names = d.get_provider_names()
                print "\n".join(provider_names)
 
index 47fe03b873dfb83e2f671c51d53e9d2dd1d86aa3..e728c3752bbdb88d559ae4b59f5ff123d92f46c5 100644 (file)
@@ -107,6 +107,8 @@ class DDNSCore(object):
                return sorted(self.providers.keys())
 
        def load_configuration(self, filename):
+               logger.debug(_("Loading configuration file %s") % filename)
+
                configs = ConfigParser.SafeConfigParser()
                configs.read([filename,])
 
index cd935d032001e65dfa25d08c82d2738f25fc9e59..f9cc3f627a7e88c7f5e8e14fc7d6256461c417ee 100644 (file)
@@ -23,6 +23,10 @@ class DDNSError(Exception):
        pass
 
 
+class DDNSNetworkError(DDNSError):
+       pass
+
+
 class DDNSAbuseError(DDNSError):
        """
                Thrown when the server reports
@@ -56,6 +60,20 @@ class DDNSConfigurationError(DDNSError):
        pass
 
 
+class DDNSConnectionRefusedError(DDNSNetworkError):
+       """
+               Thrown when a connection is refused.
+       """
+       pass
+
+
+class DDNSConnectionTimeoutError(DDNSNetworkError):
+       """
+               Thrown when a connection to a server has timed out.
+       """
+       pass
+
+
 class DDNSHostNotFoundError(DDNSError):
        """
                Thrown when a configuration entry could
@@ -72,6 +90,13 @@ class DDNSInternalServerError(DDNSError):
        pass
 
 
+class DDNSNetworkUnreachableError(DDNSNetworkError):
+       """
+               Thrown when a network is not reachable.
+       """
+       pass
+
+
 class DDNSRequestError(DDNSError):
        """
                Thrown when a request could
@@ -80,6 +105,13 @@ class DDNSRequestError(DDNSError):
        pass
 
 
+class DDNSServiceUnavailableError(DDNSNetworkError):
+       """
+               Equivalent to HTTP error code 503.
+       """
+       pass
+
+
 class DDNSUpdateError(DDNSError):
        """
                Thrown when an update could not be
index 90226b3943963771d070251fe7e9c0afefc4442b..08df26593a1f7d8db11c1a0e419ec693139fcde3 100644 (file)
@@ -26,6 +26,7 @@ import urllib
 import urllib2
 
 from __version__ import CLIENT_VERSION
+from .errors import *
 from i18n import _
 
 # Initialize the logger.
@@ -56,12 +57,17 @@ class DDNSSystem(object):
 
                return proxy
 
-       def guess_external_ipv6_address(self):
+       def _guess_external_ip_address(self, url, timeout=10):
                """
                        Sends a request to an external web server
                        to determine the current default IP address.
                """
-               response = self.send_request("http://checkip6.dns.lightningwirelabs.com")
+               try:
+                       response = self.send_request(url, timeout=timeout)
+
+               # If the server could not be reached, we will return nothing.
+               except DDNSNetworkError:
+                       return
 
                if not response.code == 200:
                        return
@@ -72,21 +78,19 @@ class DDNSSystem(object):
 
                return match.group(1)
 
-       def guess_external_ipv4_address(self):
+       def guess_external_ipv6_address(self):
                """
                        Sends a request to the internet to determine
-                       the public IP address.
-
-                       XXX does not work for IPv6.
+                       the public IPv6 address.
                """
-               response = self.send_request("http://checkip4.dns.lightningwirelabs.com")
+               return self._guess_external_ip_address("http://checkip6.dns.lightningwirelabs.com")
 
-               if response.code == 200:
-                       match = re.search(r"Your IP address is: (\d+.\d+.\d+.\d+)", response.read())
-                       if match is None:
-                               return
-
-                       return match.group(1)
+       def guess_external_ipv4_address(self):
+               """
+                       Sends a request to the internet to determine
+                       the public IPv4 address.
+               """
+               return self._guess_external_ip_address("http://checkip4.dns.lightningwirelabs.com")
 
        def send_request(self, url, method="GET", data=None, username=None, password=None, timeout=30):
                assert method in ("GET", "POST")
@@ -129,7 +133,7 @@ class DDNSSystem(object):
                        logger.debug("  %s: %s" % (k, v))
 
                try:
-                       resp = urllib2.urlopen(req)
+                       resp = urllib2.urlopen(req, timeout=timeout)
 
                        # Log response header.
                        logger.debug(_("Response header:"))
@@ -139,9 +143,30 @@ class DDNSSystem(object):
                        # Return the entire response object.
                        return resp
 
+               except urllib2.HTTPError, e:
+                       # 503 - Service Unavailable
+                       if e.code == 503:
+                               raise DDNSServiceUnavailableError
+
+                       # Raise all other unhandled exceptions.
+                       raise
+
                except urllib2.URLError, e:
+                       if e.reason:
+                               # Network Unreachable (e.g. no IPv6 access)
+                               if e.reason.errno == 101:
+                                       raise DDNSNetworkUnreachableError
+                               elif e.reason.errno == 111:
+                                       raise DDNSConnectionRefusedError
+
+                       # Raise all other unhandled exceptions.
                        raise
 
+               except socket.timeout, e:
+                       logger.debug(_("Connection timeout"))
+
+                       raise DDNSConnectionTimeoutError
+
        def _format_query_args(self, data):
                args = []