001/* 002 * Copyright 2015-2024 the original author or authors 003 * 004 * This software is licensed under the Apache License, Version 2.0, 005 * the GNU Lesser General Public License version 2 or later ("LGPL") 006 * and the WTFPL. 007 * You may choose either license to govern your use of this software only 008 * upon the condition that you accept all of the terms of either 009 * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 010 */ 011package org.minidns.dnslabel; 012 013/** 014 * A LDH (<b>L</b>etters, <b>D</b>igits, <b>H</b>yphen) label, which is the 015 * classical label form. 016 * <p> 017 * Note that it is a common misconception that LDH labels can not start with a 018 * digit. The origin of this misconception is likely that 019 * <a href="https://datatracker.ietf.org/doc/html/rfc1034#section-3.5">RFC 1034 020 * § 3.5</a> specified 021 * </p> 022 * <blockquote> 023 * They [i.e, DNS labels] must start with a letter, end with a letter or digit, 024 * and have as interior characters only letters, digits, and hyphen. 025 * </blockquote>. 026 * However, this was relaxed in 027 * <a href="https://datatracker.ietf.org/doc/html/rfc1123#page-13">RFC 1123 § 028 * 2.1</a> 029 * <blockquote> 030 * One aspect of host name syntax is hereby changed: the restriction on the first 031 * character is relaxed to allow either a letter or a digit. 032 * </blockquote> 033 * and later summarized in 034 * <a href="https://datatracker.ietf.org/doc/html/rfc3696#section-2">RFC 3696 § 035 * 2</a>: 036 * <blockquote> 037 * If the hyphen is used, it is not permitted to appear at either the beginning 038 * or end of a label. 039 * </blockquote> 040 * Furthermore 041 * <a href="https://datatracker.ietf.org/doc/html/rfc5890#section-2.3.1">RFC 042 * 5890 § 2.3.1</a> only mentions the requirement that hyphen must not be the 043 * first or last character of a LDH label. 044 * 045 * @see <a href="https://tools.ietf.org/html/rfc5890#section-2.3.1">RFC 5890 § 046 * 2.3.1. LDH Label</a> 047 * 048 */ 049public abstract class LdhLabel extends DnsLabel { 050 051 protected LdhLabel(String label) { 052 super(label); 053 } 054 055 public static boolean isLdhLabel(String label) { 056 if (label.isEmpty()) { 057 return false; 058 } 059 060 if (LeadingOrTrailingHyphenLabel.isLeadingOrTrailingHypenLabelInternal(label)) { 061 return false; 062 } 063 064 return consistsOnlyOfLettersDigitsAndHypen(label); 065 } 066 067 protected static LdhLabel fromInternal(String label) { 068 assert isLdhLabel(label); 069 070 if (ReservedLdhLabel.isReservedLdhLabel(label)) { 071 // Label starts with '??--'. Now let us see if it is a XN-Label, starting with 'xn--', but be aware that the 072 // 'xn' part is case insensitive. The XnLabel.isXnLabelInternal(String) method takes care of this. 073 if (XnLabel.isXnLabelInternal(label)) { 074 return XnLabel.fromInternal(label); 075 } else { 076 return new ReservedLdhLabel(label); 077 } 078 } 079 return new NonReservedLdhLabel(label); 080 } 081}