diff --git a/src/ddns_service/dns.py b/src/ddns_service/dns.py index 2a79f93..137e584 100644 --- a/src/ddns_service/dns.py +++ b/src/ddns_service/dns.py @@ -15,6 +15,10 @@ import dns.tsigkeyring import dns.update +# DNS name length limits (RFC 1035) +MAX_HOSTNAME_LENGTH = 253 +MAX_LABEL_LENGTH = 63 + # Valid hostname label pattern (after punycode encoding) LABEL_PATTERN = re.compile( r'^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$', re.IGNORECASE @@ -54,8 +58,9 @@ def encode_dnsname(hostname): if hostname.endswith('.'): hostname = hostname[:-1] - if len(hostname) > 253: - raise EncodingError("Hostname too long (max 253 characters)") + if len(hostname) > MAX_HOSTNAME_LENGTH: + raise EncodingError( + f"Hostname too long (max {MAX_HOSTNAME_LENGTH} characters)") try: # Encode each label using IDNA @@ -72,9 +77,9 @@ def encode_dnsname(hostname): except UnicodeError as e: raise EncodingError(f"Invalid label '{label}': {e}") - if len(encoded) > 63: + if len(encoded) > MAX_LABEL_LENGTH: raise EncodingError( - f"Label '{label}' too long (max 63 characters)" + f"Label '{label}' too long (max {MAX_LABEL_LENGTH} characters)" ) if not LABEL_PATTERN.match(encoded): @@ -209,7 +214,7 @@ def parse_bind_key_file(path): except DNSError: raise except Exception as e: - raise DNSError(f"Failed to parse key file {path}: {e}") + raise DNSError(f"Failed to parse key file {path}: {e}") from e class DNSService: