X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=src%2Fddns%2Fsystem.py;h=c268ba5cbae57dbbdd3aa1e1023ab96ca0cf41b1;hb=12dc74a8f9722a4fea2e5c23e46218006ef7dafd;hp=396a339b363529ea4fd769fd45e8fcf4439f6fdb;hpb=a96ab398dde79b50d3729858fac413a23ce7b417;p=ddns.git diff --git a/src/ddns/system.py b/src/ddns/system.py index 396a339..c268ba5 100644 --- a/src/ddns/system.py +++ b/src/ddns/system.py @@ -21,6 +21,7 @@ import base64 import re +import ssl import socket import urllib import urllib2 @@ -65,6 +66,13 @@ class DDNSSystem(object): return proxy def get_local_ip_address(self, proto): + ip_address = self._get_local_ip_address(proto) + + # Check if the IP address is usable and only return it then + if self._is_usable_ip_address(proto, ip_address): + return ip_address + + def _get_local_ip_address(self, proto): # Legacy code for IPFire 2. if self.distro == "ipfire-2" and proto == "ipv4": try: @@ -166,6 +174,11 @@ class DDNSSystem(object): return resp except urllib2.HTTPError, e: + # Log response header. + logger.debug(_("Response header (Status Code %s):") % e.code) + for k, v in e.hdrs.items(): + logger.debug(" %s: %s" % (k, v)) + # 400 - Bad request if e.code == 400: raise DDNSRequestError(e.reason) @@ -175,6 +188,12 @@ class DDNSSystem(object): elif e.code in (401, 403): raise DDNSAuthenticationError(e.reason) + # 404 - Not found + # Either the provider has changed the API, or + # there is an error on the server + elif e.code == 404: + raise DDNSNotFound(e.reason) + # 500 - Internal Server Error elif e.code == 500: raise DDNSInternalServerError(e.reason) @@ -188,6 +207,20 @@ class DDNSSystem(object): except urllib2.URLError, e: if e.reason: + # Handle SSL errors + if isinstance(e.reason, ssl.SSLError): + e = e.reason + + if e.reason == "CERTIFICATE_VERIFY_FAILED": + raise DDNSCertificateError + + # Raise all other SSL errors + raise DDNSSSLError(e.reason) + + # Name or service not known + if e.reason.errno == -2: + raise DDNSResolveError + # Network Unreachable (e.g. no IPv6 access) if e.reason.errno == 101: raise DDNSNetworkUnreachableError @@ -196,6 +229,10 @@ class DDNSSystem(object): elif e.reason.errno == 111: raise DDNSConnectionRefusedError + # No route to host + elif e.reason.errno == 113: + raise DDNSNoRouteToHostError(req.host) + # Raise all other unhandled exceptions. raise @@ -251,16 +288,18 @@ class DDNSSystem(object): guess_ip = self.core.settings.get("guess_external_ip", "true") guess_ip = guess_ip in ("true", "yes", "1") - # If the external IP address should be used, we just do that. - if guess_ip: - return self.guess_external_ip_address(proto) - # Get the local IP address. - local_ip_address = self.get_local_ip_address(proto) + local_ip_address = None - # If the local IP address is not usable, we must guess - # the correct IP address... - if not self._is_usable_ip_address(proto, local_ip_address): + if not guess_ip: + try: + local_ip_address = self.get_local_ip_address(proto) + except NotImplementedError: + logger.warning(_("Falling back to check the IP address with help of a public server")) + + # If no local IP address could be determined, we will fall back to the guess + # it with help of an external server... + if not local_ip_address: local_ip_address = self.guess_external_ip_address(proto) return local_ip_address @@ -282,7 +321,7 @@ class DDNSSystem(object): r"^172\.(1[6-9]|2[0-9]|31)\.\d+\.\d+$", # Dual Stack Lite address space - r"^100\.(6[4-9]|[7-9][0-9]|1[01][0-9]|12[0-7])\.\d+\.\d+", + r"^100\.(6[4-9]|[7-9][0-9]|1[01][0-9]|12[0-7])\.\d+\.\d+$", ) for match in matches: @@ -316,6 +355,10 @@ class DDNSSystem(object): if e.errno == -2: return [] + # Temporary failure in name resolution + elif e.errno == -3: + raise DDNSResolveError(hostname) + # No record for requested family available (e.g. no AAAA) elif e.errno == -5: return []