From f040f31ea3a2b13d15da4d75c780c6d7921d0e16 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Wed, 15 Apr 2026 19:00:23 +0800 Subject: [PATCH 1/9] support domain for seed and backup members --- common/build.gradle | 3 +- .../org/tron/common/backup/BackupManager.java | 89 +++++++++++++++---- .../java/org/tron/core/config/args/Args.java | 50 ++++++++++- gradle/verification-metadata.xml | 8 ++ 4 files changed, 130 insertions(+), 20 deletions(-) diff --git a/common/build.gradle b/common/build.gradle index 98fc3257190..b7494f1c1d4 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -21,7 +21,8 @@ dependencies { api 'org.aspectj:aspectjrt:1.9.8' api 'org.aspectj:aspectjweaver:1.9.8' api 'org.aspectj:aspectjtools:1.9.8' - api group: 'io.github.tronprotocol', name: 'libp2p', version: '2.2.7',{ + api group: 'com.github.317787106', name: 'libp2p', version: 'v0.0.9',{ + //api group: 'io.github.tronprotocol', name: 'libp2p', version: '2.2.7',{ exclude group: 'io.grpc', module: 'grpc-context' exclude group: 'io.grpc', module: 'grpc-core' exclude group: 'io.grpc', module: 'grpc-netty' diff --git a/framework/src/main/java/org/tron/common/backup/BackupManager.java b/framework/src/main/java/org/tron/common/backup/BackupManager.java index a8812a62bb4..a2fa904c5d4 100644 --- a/framework/src/main/java/org/tron/common/backup/BackupManager.java +++ b/framework/src/main/java/org/tron/common/backup/BackupManager.java @@ -8,9 +8,13 @@ import io.netty.util.internal.ConcurrentSet; import java.net.InetAddress; import java.net.InetSocketAddress; +import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import lombok.Getter; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.tron.common.backup.message.KeepAliveMessage; @@ -20,46 +24,44 @@ import org.tron.common.backup.socket.UdpEvent; import org.tron.common.es.ExecutorServiceManager; import org.tron.common.parameter.CommonParameter; +import org.tron.p2p.dns.lookup.LookUpTxt; +import org.tron.p2p.utils.NetUtil; @Slf4j(topic = "backup") @Component public class BackupManager implements EventHandler { - private CommonParameter parameter = CommonParameter.getInstance(); + private final CommonParameter parameter = CommonParameter.getInstance(); - private int priority = parameter.getBackupPriority(); + private final int priority = parameter.getBackupPriority(); - private int port = parameter.getBackupPort(); + private final int port = parameter.getBackupPort(); - private int keepAliveInterval = parameter.getKeepAliveInterval(); + private final int keepAliveInterval = parameter.getKeepAliveInterval(); - private int keepAliveTimeout = keepAliveInterval * 6; + private final int keepAliveTimeout = keepAliveInterval * 6; private String localIp = ""; - private Set members = new ConcurrentSet<>(); + private final Set members = new ConcurrentSet<>(); + + private final Map domainIpCache = new ConcurrentHashMap<>(); private final String esName = "backup-manager"; - private ScheduledExecutorService executorService = + private final ScheduledExecutorService executorService = ExecutorServiceManager.newSingleThreadScheduledExecutor(esName); + @Setter private MessageHandler messageHandler; + @Getter private BackupStatusEnum status = MASTER; private volatile long lastKeepAliveTime; private volatile boolean isInit = false; - public void setMessageHandler(MessageHandler messageHandler) { - this.messageHandler = messageHandler; - } - - public BackupStatusEnum getStatus() { - return status; - } - public void setStatus(BackupStatusEnum status) { logger.info("Change backup status to {}", status); this.status = status; @@ -78,10 +80,15 @@ public void init() { logger.warn("Failed to get local ip"); } - for (String member : parameter.getBackupMembers()) { - if (!localIp.equals(member)) { - members.add(member); + for (String raw : parameter.getBackupMembers()) { + String ip = resolveToIp(raw); + if (ip == null || localIp.equals(ip)) { + continue; + } + if (!NetUtil.validIpV4(raw) && !NetUtil.validIpV6(raw)) { + domainIpCache.put(raw, ip); } + members.add(ip); } logger.info("Backup localIp:{}, members: size= {}, {}", localIp, members.size(), members); @@ -111,6 +118,14 @@ public void init() { logger.error("Exception in send keep alive", t); } }, 1000, keepAliveInterval, TimeUnit.MILLISECONDS); + + executorService.scheduleWithFixedDelay(() -> { + try { + refreshMemberIps(); + } catch (Throwable t) { + logger.error("Exception in backup DNS refresh", t); + } + }, 60_000L, 60_000L, TimeUnit.MILLISECONDS); } @Override @@ -162,4 +177,42 @@ public enum BackupStatusEnum { MASTER } + private String resolveToIp(String raw) { + if (NetUtil.validIpV4(raw) || NetUtil.validIpV6(raw)) { + return raw; + } + InetAddress address = LookUpTxt.lookUpIp(raw, true); + if (address == null) { + address = LookUpTxt.lookUpIp(raw, false); + } + if (address == null) { + logger.warn("Failed to resolve backup member domain: {}", raw); + return null; + } + return address.getHostAddress(); + } + + /** + * Re-resolves all tracked domain entries. If an IP has changed, the old IP is + * removed from {@link #members} and the new IP is added. + */ + private void refreshMemberIps() { + for (Map.Entry entry : domainIpCache.entrySet()) { + String domain = entry.getKey(); + String oldIp = entry.getValue(); + String newIp = resolveToIp(domain); + if (newIp == null) { + logger.warn("DNS refresh: failed to re-resolve backup member domain {}, keep it", domain); + continue; + } + if (!newIp.equals(oldIp)) { + logger.info("DNS refresh: backup member {} IP changed {} -> {}", domain, oldIp, newIp); + members.remove(oldIp); + if (!localIp.equals(newIp)) { + members.add(newIp); + } + domainIpCache.put(domain, newIp); + } + } + } } diff --git a/framework/src/main/java/org/tron/core/config/args/Args.java b/framework/src/main/java/org/tron/core/config/args/Args.java index 83d7fd2c63d..f2a1a80414c 100644 --- a/framework/src/main/java/org/tron/core/config/args/Args.java +++ b/framework/src/main/java/org/tron/core/config/args/Args.java @@ -74,6 +74,7 @@ import org.tron.core.exception.TronError; import org.tron.core.store.AccountStore; import org.tron.p2p.P2pConfig; +import org.tron.p2p.dns.lookup.LookUpTxt; import org.tron.p2p.dns.update.DnsType; import org.tron.p2p.dns.update.PublishConfig; import org.tron.p2p.utils.NetUtil; @@ -1308,8 +1309,13 @@ public static List getInetSocketAddress( return ret; } List list = config.getStringList(path); + for (String configString : list) { - InetSocketAddress inetSocketAddress = NetUtil.parseInetSocketAddress(configString); + InetSocketAddress inetSocketAddress = resolveInetSocketAddress(configString); + if (inetSocketAddress == null) { + logger.warn("Failed to resolve address, skip: {}", configString); + continue; + } if (filter) { String ip = inetSocketAddress.getAddress().getHostAddress(); int port = inetSocketAddress.getPort(); @@ -1326,6 +1332,30 @@ public static List getInetSocketAddress( return ret; } + /** + * Parses an address string and, if the host part is a domain name rather than an IP literal, + * resolves it to an {@link InetAddress} via {@link LookUpTxt#lookUpIp}. Support IPv4 domain now + * + * @param configString address in {@code ip:port} or {@code [ipv6]:port} or + * {@code domain:port} format + * @return a fully resolved {@link InetSocketAddress}, or {@code null} if DNS resolution fails + */ + private static InetSocketAddress resolveInetSocketAddress(String configString) { + InetSocketAddress parsed = NetUtil.parseInetSocketAddress(configString); + String host = parsed.getHostString(); + int port = parsed.getPort(); + if (NetUtil.validIpV4(host) || NetUtil.validIpV6(host)) { + return parsed; + } + + // The host is a domain name, resolve it to an IP address, only support IPv4 now + InetAddress address = LookUpTxt.lookUpIp(host, true); + if (address == null) { + return null; + } + return new InetSocketAddress(address, port); + } + public static List getInetAddress( final com.typesafe.config.Config config, String path) { List ret = new ArrayList<>(); @@ -1660,6 +1690,24 @@ private static void initBackupProperty(Config config) { PARAMETER.backupMembers = config.hasPath(ConfigKey.NODE_BACKUP_MEMBERS) ? config.getStringList(ConfigKey.NODE_BACKUP_MEMBERS) : new ArrayList<>(); + checkBackupMembers(); + } + + private static void checkBackupMembers() { + for (String member : PARAMETER.backupMembers) { + if (NetUtil.validIpV4(member) || NetUtil.validIpV6(member)) { + continue; + } + // Determine whether a domain name can be resolved to an IP address. + InetAddress address = LookUpTxt.lookUpIp(member, true); + if (address == null) { + address = LookUpTxt.lookUpIp(member, false); + } + if (address == null) { + throw new TronError("Failed to resolve backup member domain: " + member, + TronError.ErrCode.PARAMETER_INIT); + } + } } public static void logConfig() { diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 4d0bf1013d6..db17d29e0cf 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -247,6 +247,14 @@ + + + + + + + + From cbf122257c998e06aa69b5af4e0d39a68a9183e4 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Wed, 15 Apr 2026 20:06:56 +0800 Subject: [PATCH 2/9] use isolate executor for dns lookup --- .../org/tron/common/backup/BackupManager.java | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/framework/src/main/java/org/tron/common/backup/BackupManager.java b/framework/src/main/java/org/tron/common/backup/BackupManager.java index a2fa904c5d4..10e90690f6d 100644 --- a/framework/src/main/java/org/tron/common/backup/BackupManager.java +++ b/framework/src/main/java/org/tron/common/backup/BackupManager.java @@ -48,10 +48,13 @@ public class BackupManager implements EventHandler { private final Map domainIpCache = new ConcurrentHashMap<>(); private final String esName = "backup-manager"; - private final ScheduledExecutorService executorService = ExecutorServiceManager.newSingleThreadScheduledExecutor(esName); + private final String dnsEsName = "backup-dns-refresh"; + private final ScheduledExecutorService dnsExecutorService = + ExecutorServiceManager.newSingleThreadScheduledExecutor(dnsEsName); + @Setter private MessageHandler messageHandler; @@ -119,13 +122,15 @@ public void init() { } }, 1000, keepAliveInterval, TimeUnit.MILLISECONDS); - executorService.scheduleWithFixedDelay(() -> { - try { - refreshMemberIps(); - } catch (Throwable t) { - logger.error("Exception in backup DNS refresh", t); - } - }, 60_000L, 60_000L, TimeUnit.MILLISECONDS); + if (!domainIpCache.isEmpty()) { + dnsExecutorService.scheduleWithFixedDelay(() -> { + try { + refreshMemberIps(); + } catch (Throwable t) { + logger.error("Exception in backup DNS refresh", t); + } + }, 60_000L, 60_000L, TimeUnit.MILLISECONDS); + } } @Override @@ -164,6 +169,7 @@ public void handleEvent(UdpEvent udpEvent) { public void stop() { ExecutorServiceManager.shutdownAndAwaitTermination(executorService, esName); + ExecutorServiceManager.shutdownAndAwaitTermination(dnsExecutorService, dnsEsName); } @Override From b3706efb7108cfc3a0d3be86fb0a14b27b4f4c33 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Wed, 15 Apr 2026 23:48:26 +0800 Subject: [PATCH 3/9] add one log when resolve domain success --- framework/src/main/java/org/tron/core/config/args/Args.java | 1 + 1 file changed, 1 insertion(+) diff --git a/framework/src/main/java/org/tron/core/config/args/Args.java b/framework/src/main/java/org/tron/core/config/args/Args.java index f2a1a80414c..659d0530682 100644 --- a/framework/src/main/java/org/tron/core/config/args/Args.java +++ b/framework/src/main/java/org/tron/core/config/args/Args.java @@ -1353,6 +1353,7 @@ private static InetSocketAddress resolveInetSocketAddress(String configString) { if (address == null) { return null; } + logger.info("Resolve {} to {}", host, address.getHostAddress()); return new InetSocketAddress(address, port); } From 1483681e2619c5bb6c98644bd520bc1af504d13a Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Thu, 16 Apr 2026 16:14:22 +0800 Subject: [PATCH 4/9] parallet get ip by dns --- .../org/tron/common/backup/BackupManager.java | 24 ++++--- .../java/org/tron/core/config/args/Args.java | 70 +++++++++++++++---- 2 files changed, 70 insertions(+), 24 deletions(-) diff --git a/framework/src/main/java/org/tron/common/backup/BackupManager.java b/framework/src/main/java/org/tron/common/backup/BackupManager.java index 10e90690f6d..cf66d070987 100644 --- a/framework/src/main/java/org/tron/common/backup/BackupManager.java +++ b/framework/src/main/java/org/tron/common/backup/BackupManager.java @@ -83,13 +83,13 @@ public void init() { logger.warn("Failed to get local ip"); } - for (String raw : parameter.getBackupMembers()) { - String ip = resolveToIp(raw); + for (String ipOrDomain : parameter.getBackupMembers()) { + String ip = resolveToIp(ipOrDomain); if (ip == null || localIp.equals(ip)) { continue; } - if (!NetUtil.validIpV4(raw) && !NetUtil.validIpV6(raw)) { - domainIpCache.put(raw, ip); + if (!NetUtil.validIpV4(ipOrDomain) && !NetUtil.validIpV6(ipOrDomain)) { + domainIpCache.put(ipOrDomain, ip); } members.add(ip); } @@ -183,16 +183,20 @@ public enum BackupStatusEnum { MASTER } - private String resolveToIp(String raw) { - if (NetUtil.validIpV4(raw) || NetUtil.validIpV6(raw)) { - return raw; + /** + * Resolves a hostname or IP string to a numeric IP address string. + */ + private String resolveToIp(String ipOrDomain) { + // Fast path: already a numeric address — no lookup needed. + if (NetUtil.validIpV4(ipOrDomain) || NetUtil.validIpV6(ipOrDomain)) { + return ipOrDomain; } - InetAddress address = LookUpTxt.lookUpIp(raw, true); + InetAddress address = LookUpTxt.lookUpIp(ipOrDomain, true); if (address == null) { - address = LookUpTxt.lookUpIp(raw, false); + address = LookUpTxt.lookUpIp(ipOrDomain, false); } if (address == null) { - logger.warn("Failed to resolve backup member domain: {}", raw); + logger.warn("Failed to resolve backup member domain: {}", ipOrDomain); return null; } return address.getHostAddress(); diff --git a/framework/src/main/java/org/tron/core/config/args/Args.java b/framework/src/main/java/org/tron/core/config/args/Args.java index 659d0530682..e394037636c 100644 --- a/framework/src/main/java/org/tron/core/config/args/Args.java +++ b/framework/src/main/java/org/tron/core/config/args/Args.java @@ -37,11 +37,13 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Optional; import java.util.Properties; import java.util.Set; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; import java.util.stream.Collectors; import lombok.Getter; import lombok.NoArgsConstructor; @@ -56,6 +58,7 @@ import org.tron.common.args.Witness; import org.tron.common.config.DbBackupConfig; import org.tron.common.cron.CronExpression; +import org.tron.common.es.ExecutorServiceManager; import org.tron.common.logsfilter.EventPluginConfig; import org.tron.common.logsfilter.FilterQuery; import org.tron.common.logsfilter.TriggerConfig; @@ -1309,11 +1312,57 @@ public static List getInetSocketAddress( return ret; } List list = config.getStringList(path); + if (list.isEmpty()) { + return ret; + } + // Collect entries whose host part is a domain name (not an IP literal). + List domainEntries = new ArrayList<>(); for (String configString : list) { - InetSocketAddress inetSocketAddress = resolveInetSocketAddress(configString); + String host = NetUtil.parseInetSocketAddress(configString).getHostString(); + if (!NetUtil.validIpV4(host) && !NetUtil.validIpV6(host)) { + domainEntries.add(configString); + } + } + + // Resolve domain names: spin up a thread pool only when there are multiple domains + Map domainResolved = new HashMap<>(); + if (domainEntries.size() > 1) { + String poolName = "args-dns-lookup"; + ExecutorService dnsPool = ExecutorServiceManager + .newFixedThreadPool(poolName, domainEntries.size(), true); + List> futures = new ArrayList<>(domainEntries.size()); + for (String entry : domainEntries) { + futures.add(dnsPool.submit(() -> resolveInetSocketAddress(entry))); + } + for (int i = 0; i < domainEntries.size(); i++) { + String entry = domainEntries.get(i); + try { + domainResolved.put(entry, futures.get(i).get()); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + logger.warn("DNS lookup interrupted for: {}", entry); + } catch (ExecutionException e) { + logger.warn("Failed to resolve address, skip: {}", entry); + } + } + ExecutorServiceManager.shutdownAndAwaitTermination(dnsPool, poolName); + } else if (domainEntries.size() == 1) { + String entry = domainEntries.get(0); + domainResolved.put(entry, resolveInetSocketAddress(entry)); + } + + // Build the result list preserving the original config order. + for (String configString : list) { + InetSocketAddress inetSocketAddress; + InetSocketAddress parsed = NetUtil.parseInetSocketAddress(configString); + if (NetUtil.validIpV4(parsed.getHostString()) || NetUtil.validIpV6(parsed.getHostString())) { + inetSocketAddress = parsed; + } else { + inetSocketAddress = domainResolved.get(configString); + } + if (inetSocketAddress == null) { - logger.warn("Failed to resolve address, skip: {}", configString); continue; } if (filter) { @@ -1333,23 +1382,16 @@ public static List getInetSocketAddress( } /** - * Parses an address string and, if the host part is a domain name rather than an IP literal, - * resolves it to an {@link InetAddress} via {@link LookUpTxt#lookUpIp}. Support IPv4 domain now - * - * @param configString address in {@code ip:port} or {@code [ipv6]:port} or - * {@code domain:port} format - * @return a fully resolved {@link InetSocketAddress}, or {@code null} if DNS resolution fails + * Resolves a {@code domain:port} address string to an {@link InetSocketAddress} via DNS. */ private static InetSocketAddress resolveInetSocketAddress(String configString) { InetSocketAddress parsed = NetUtil.parseInetSocketAddress(configString); String host = parsed.getHostString(); int port = parsed.getPort(); - if (NetUtil.validIpV4(host) || NetUtil.validIpV6(host)) { - return parsed; - } - - // The host is a domain name, resolve it to an IP address, only support IPv4 now InetAddress address = LookUpTxt.lookUpIp(host, true); + if (address == null) { + address = LookUpTxt.lookUpIp(host, false); + } if (address == null) { return null; } From aadffe7492393823c15da3d2a7564abe6a3e89ed Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Thu, 16 Apr 2026 17:28:22 +0800 Subject: [PATCH 5/9] add InetUtil --- .../org/tron/common/backup/BackupManager.java | 35 ++---- .../java/org/tron/core/config/args/Args.java | 90 +------------- .../org/tron/core/config/args/InetUtil.java | 115 ++++++++++++++++++ 3 files changed, 131 insertions(+), 109 deletions(-) create mode 100644 framework/src/main/java/org/tron/core/config/args/InetUtil.java diff --git a/framework/src/main/java/org/tron/common/backup/BackupManager.java b/framework/src/main/java/org/tron/common/backup/BackupManager.java index cf66d070987..c70d6df4d63 100644 --- a/framework/src/main/java/org/tron/common/backup/BackupManager.java +++ b/framework/src/main/java/org/tron/common/backup/BackupManager.java @@ -4,6 +4,7 @@ import static org.tron.common.backup.BackupManager.BackupStatusEnum.MASTER; import static org.tron.common.backup.BackupManager.BackupStatusEnum.SLAVER; import static org.tron.common.backup.message.UdpMessageTypeEnum.BACKUP_KEEP_ALIVE; +import static org.tron.core.config.args.InetUtil.resolveInetAddress; import io.netty.util.internal.ConcurrentSet; import java.net.InetAddress; @@ -24,7 +25,6 @@ import org.tron.common.backup.socket.UdpEvent; import org.tron.common.es.ExecutorServiceManager; import org.tron.common.parameter.CommonParameter; -import org.tron.p2p.dns.lookup.LookUpTxt; import org.tron.p2p.utils.NetUtil; @Slf4j(topic = "backup") @@ -84,8 +84,13 @@ public void init() { } for (String ipOrDomain : parameter.getBackupMembers()) { - String ip = resolveToIp(ipOrDomain); - if (ip == null || localIp.equals(ip)) { + InetAddress inetAddress = resolveInetAddress(ipOrDomain); + if (inetAddress == null) { + logger.warn("Failed to resolve backup member domain: {}", ipOrDomain); + continue; + } + String ip = inetAddress.getHostAddress(); + if (localIp.equals(ip)) { continue; } if (!NetUtil.validIpV4(ipOrDomain) && !NetUtil.validIpV6(ipOrDomain)) { @@ -183,25 +188,6 @@ public enum BackupStatusEnum { MASTER } - /** - * Resolves a hostname or IP string to a numeric IP address string. - */ - private String resolveToIp(String ipOrDomain) { - // Fast path: already a numeric address — no lookup needed. - if (NetUtil.validIpV4(ipOrDomain) || NetUtil.validIpV6(ipOrDomain)) { - return ipOrDomain; - } - InetAddress address = LookUpTxt.lookUpIp(ipOrDomain, true); - if (address == null) { - address = LookUpTxt.lookUpIp(ipOrDomain, false); - } - if (address == null) { - logger.warn("Failed to resolve backup member domain: {}", ipOrDomain); - return null; - } - return address.getHostAddress(); - } - /** * Re-resolves all tracked domain entries. If an IP has changed, the old IP is * removed from {@link #members} and the new IP is added. @@ -210,11 +196,12 @@ private void refreshMemberIps() { for (Map.Entry entry : domainIpCache.entrySet()) { String domain = entry.getKey(); String oldIp = entry.getValue(); - String newIp = resolveToIp(domain); - if (newIp == null) { + InetAddress inetAddress = resolveInetAddress(domain); + if (inetAddress == null) { logger.warn("DNS refresh: failed to re-resolve backup member domain {}, keep it", domain); continue; } + String newIp = inetAddress.getHostAddress(); if (!newIp.equals(oldIp)) { logger.info("DNS refresh: backup member {} IP changed {} -> {}", domain, oldIp, newIp); members.remove(oldIp); diff --git a/framework/src/main/java/org/tron/core/config/args/Args.java b/framework/src/main/java/org/tron/core/config/args/Args.java index e394037636c..4ef22624611 100644 --- a/framework/src/main/java/org/tron/core/config/args/Args.java +++ b/framework/src/main/java/org/tron/core/config/args/Args.java @@ -12,6 +12,7 @@ import static org.tron.core.Constant.MIN_PROPOSAL_EXPIRE_TIME; import static org.tron.core.config.Parameter.ChainConstant.BLOCK_PRODUCE_TIMEOUT_PERCENT; import static org.tron.core.config.Parameter.ChainConstant.MAX_ACTIVE_WITNESS_NUM; +import static org.tron.core.config.args.InetUtil.resolveInetAddress; import static org.tron.core.exception.TronError.ErrCode.PARAMETER_INIT; import com.beust.jcommander.JCommander; @@ -41,9 +42,6 @@ import java.util.Set; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; import java.util.stream.Collectors; import lombok.Getter; import lombok.NoArgsConstructor; @@ -58,7 +56,6 @@ import org.tron.common.args.Witness; import org.tron.common.config.DbBackupConfig; import org.tron.common.cron.CronExpression; -import org.tron.common.es.ExecutorServiceManager; import org.tron.common.logsfilter.EventPluginConfig; import org.tron.common.logsfilter.FilterQuery; import org.tron.common.logsfilter.TriggerConfig; @@ -1312,59 +1309,7 @@ public static List getInetSocketAddress( return ret; } List list = config.getStringList(path); - if (list.isEmpty()) { - return ret; - } - - // Collect entries whose host part is a domain name (not an IP literal). - List domainEntries = new ArrayList<>(); - for (String configString : list) { - String host = NetUtil.parseInetSocketAddress(configString).getHostString(); - if (!NetUtil.validIpV4(host) && !NetUtil.validIpV6(host)) { - domainEntries.add(configString); - } - } - - // Resolve domain names: spin up a thread pool only when there are multiple domains - Map domainResolved = new HashMap<>(); - if (domainEntries.size() > 1) { - String poolName = "args-dns-lookup"; - ExecutorService dnsPool = ExecutorServiceManager - .newFixedThreadPool(poolName, domainEntries.size(), true); - List> futures = new ArrayList<>(domainEntries.size()); - for (String entry : domainEntries) { - futures.add(dnsPool.submit(() -> resolveInetSocketAddress(entry))); - } - for (int i = 0; i < domainEntries.size(); i++) { - String entry = domainEntries.get(i); - try { - domainResolved.put(entry, futures.get(i).get()); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - logger.warn("DNS lookup interrupted for: {}", entry); - } catch (ExecutionException e) { - logger.warn("Failed to resolve address, skip: {}", entry); - } - } - ExecutorServiceManager.shutdownAndAwaitTermination(dnsPool, poolName); - } else if (domainEntries.size() == 1) { - String entry = domainEntries.get(0); - domainResolved.put(entry, resolveInetSocketAddress(entry)); - } - - // Build the result list preserving the original config order. - for (String configString : list) { - InetSocketAddress inetSocketAddress; - InetSocketAddress parsed = NetUtil.parseInetSocketAddress(configString); - if (NetUtil.validIpV4(parsed.getHostString()) || NetUtil.validIpV6(parsed.getHostString())) { - inetSocketAddress = parsed; - } else { - inetSocketAddress = domainResolved.get(configString); - } - - if (inetSocketAddress == null) { - continue; - } + for (InetSocketAddress inetSocketAddress : InetUtil.getInetSocketAddressList(list)) { if (filter) { String ip = inetSocketAddress.getAddress().getHostAddress(); int port = inetSocketAddress.getPort(); @@ -1381,24 +1326,6 @@ public static List getInetSocketAddress( return ret; } - /** - * Resolves a {@code domain:port} address string to an {@link InetSocketAddress} via DNS. - */ - private static InetSocketAddress resolveInetSocketAddress(String configString) { - InetSocketAddress parsed = NetUtil.parseInetSocketAddress(configString); - String host = parsed.getHostString(); - int port = parsed.getPort(); - InetAddress address = LookUpTxt.lookUpIp(host, true); - if (address == null) { - address = LookUpTxt.lookUpIp(host, false); - } - if (address == null) { - return null; - } - logger.info("Resolve {} to {}", host, address.getHostAddress()); - return new InetSocketAddress(address, port); - } - public static List getInetAddress( final com.typesafe.config.Config config, String path) { List ret = new ArrayList<>(); @@ -1738,16 +1665,9 @@ private static void initBackupProperty(Config config) { private static void checkBackupMembers() { for (String member : PARAMETER.backupMembers) { - if (NetUtil.validIpV4(member) || NetUtil.validIpV6(member)) { - continue; - } - // Determine whether a domain name can be resolved to an IP address. - InetAddress address = LookUpTxt.lookUpIp(member, true); - if (address == null) { - address = LookUpTxt.lookUpIp(member, false); - } - if (address == null) { - throw new TronError("Failed to resolve backup member domain: " + member, + InetAddress inetAddress = resolveInetAddress(member); + if (inetAddress == null) { + throw new TronError("Failed to resolve backup member: " + member, TronError.ErrCode.PARAMETER_INIT); } } diff --git a/framework/src/main/java/org/tron/core/config/args/InetUtil.java b/framework/src/main/java/org/tron/core/config/args/InetUtil.java new file mode 100644 index 00000000000..a38a6774e4e --- /dev/null +++ b/framework/src/main/java/org/tron/core/config/args/InetUtil.java @@ -0,0 +1,115 @@ +package org.tron.core.config.args; + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import lombok.extern.slf4j.Slf4j; +import org.tron.common.es.ExecutorServiceManager; +import org.tron.p2p.dns.lookup.LookUpTxt; +import org.tron.p2p.utils.NetUtil; + +@Slf4j(topic = "app") +public class InetUtil { + + public static List getInetSocketAddressList(List items) { + List ret = new ArrayList<>(); + if (items.isEmpty()) { + return ret; + } + // Collect entries whose host part is a domain name (not an IP literal). + List domainEntries = new ArrayList<>(); + for (String item : items) { + String host = NetUtil.parseInetSocketAddress(item).getHostString(); + if (!NetUtil.validIpV4(host) && !NetUtil.validIpV6(host)) { + domainEntries.add(item); + } + } + + // Resolve domain names: spin up a thread pool only when there are multiple domains + Map domainResolved = new HashMap<>(); + if (domainEntries.size() > 1) { + String poolName = "args-dns-lookup"; + ExecutorService dnsPool = ExecutorServiceManager + .newFixedThreadPool(poolName, domainEntries.size(), true); + List> futures = new ArrayList<>(domainEntries.size()); + for (String entry : domainEntries) { + futures.add(dnsPool.submit(() -> resolveInetSocketAddress(entry))); + } + for (int i = 0; i < domainEntries.size(); i++) { + String entry = domainEntries.get(i); + try { + domainResolved.put(entry, futures.get(i).get()); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + logger.warn("DNS lookup interrupted for: {}", entry); + } catch (ExecutionException e) { + logger.warn("Failed to resolve address, skip: {}", entry); + } + } + ExecutorServiceManager.shutdownAndAwaitTermination(dnsPool, poolName); + } else if (domainEntries.size() == 1) { + String entry = domainEntries.get(0); + domainResolved.put(entry, resolveInetSocketAddress(entry)); + } + + // Build the result list preserving the original config order. + for (String configString : items) { + InetSocketAddress inetSocketAddress; + InetSocketAddress parsed = NetUtil.parseInetSocketAddress(configString); + if (NetUtil.validIpV4(parsed.getHostString()) || NetUtil.validIpV6(parsed.getHostString())) { + inetSocketAddress = parsed; + } else { + inetSocketAddress = domainResolved.get(configString); + } + if (inetSocketAddress == null) { + continue; + } + ret.add(inetSocketAddress); + } + return ret; + } + + /** + * Resolves a {@code domain:port} address string to an {@link InetSocketAddress} via DNS. + */ + private static InetSocketAddress resolveInetSocketAddress(String configString) { + InetSocketAddress parsed = NetUtil.parseInetSocketAddress(configString); + String host = parsed.getHostString(); + int port = parsed.getPort(); + InetAddress address = LookUpTxt.lookUpIp(host, true); + if (address == null) { + address = LookUpTxt.lookUpIp(host, false); + } + if (address == null) { + return null; + } + logger.info("Resolve {} to {}", host, address.getHostAddress()); + return new InetSocketAddress(address, port); + } + + /** + * Resolves a hostname or IP string to a numeric IP address string. + */ + public static InetAddress resolveInetAddress(String ipOrDomain) { + // Fast path: already a numeric address — no lookup needed. + if (NetUtil.validIpV4(ipOrDomain) || NetUtil.validIpV6(ipOrDomain)) { + try { + return InetAddress.getByName(ipOrDomain); + } catch (UnknownHostException e) { + return null; + } + } + InetAddress address = LookUpTxt.lookUpIp(ipOrDomain, true); + if (address == null) { + address = LookUpTxt.lookUpIp(ipOrDomain, false); + } + return address; + } +} From 10e1cb422ed14bdf5b6f9f7cb91ade51299ddade Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Wed, 22 Apr 2026 16:04:14 +0800 Subject: [PATCH 6/9] add comment for InetUtil --- .../org/tron/core/config/args/InetUtil.java | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/framework/src/main/java/org/tron/core/config/args/InetUtil.java b/framework/src/main/java/org/tron/core/config/args/InetUtil.java index a38a6774e4e..8d0309fd623 100644 --- a/framework/src/main/java/org/tron/core/config/args/InetUtil.java +++ b/framework/src/main/java/org/tron/core/config/args/InetUtil.java @@ -18,6 +18,22 @@ @Slf4j(topic = "app") public class InetUtil { + /** + * Converts a list of {@code host:port} config strings into resolved {@link InetSocketAddress} + * objects, preserving the original order. + * + *

IP literals (IPv4 and IPv6) are used as-is. Domain names are resolved via DNS: when there + * are multiple domains they are resolved in parallel using a dedicated thread pool; a single + * domain is resolved inline. Entries that fail DNS resolution are silently dropped. Item is + * ipOrDomain:port, maybe like this: + *

  • 192.168.100.0:18888, + *
  • [fe80::48ff:fe00:1122]:18888, + *
  • example.com:18888, + *
  • hostname:18888 + * + * @param items list of address strings in {@code host:port} format (may mix IPs and domains) + * @return resolved addresses in the same order as {@code items}, omit unresolvable entries + */ public static List getInetSocketAddressList(List items) { List ret = new ArrayList<>(); if (items.isEmpty()) { @@ -77,7 +93,13 @@ public static List getInetSocketAddressList(List item } /** - * Resolves a {@code domain:port} address string to an {@link InetSocketAddress} via DNS. + * Resolves a {@code ipOrDomain:port} config string to an {@link InetSocketAddress} via DNS. + * + *

    The host is looked up first over IPv4, then over IPv6 as a fallback. Returns {@code null} + * if DNS resolution fails for both address families. + * + * @param configString address string in {@code ipOrDomain:port} format + * @return resolved {@link InetSocketAddress}, or {@code null} if the host cannot be resolved */ private static InetSocketAddress resolveInetSocketAddress(String configString) { InetSocketAddress parsed = NetUtil.parseInetSocketAddress(configString); @@ -95,7 +117,11 @@ private static InetSocketAddress resolveInetSocketAddress(String configString) { } /** - * Resolves a hostname or IP string to a numeric IP address string. + * Resolves {@code ipOrDomain} to an {@link InetAddress}. + * + *

    IP literals are converted directly without a DNS lookup. Domain names are first resolved + * over IPv4, then retried over IPv6 if the first attempt fails. Returns {@code null} if the + * address cannot be resolved. */ public static InetAddress resolveInetAddress(String ipOrDomain) { // Fast path: already a numeric address — no lookup needed. From 678cc893bc52f7eb2da9fff9c47f3c09db7e65ec Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Wed, 22 Apr 2026 16:38:00 +0800 Subject: [PATCH 7/9] optimize comment --- .../src/main/java/org/tron/core/config/args/InetUtil.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/framework/src/main/java/org/tron/core/config/args/InetUtil.java b/framework/src/main/java/org/tron/core/config/args/InetUtil.java index 8d0309fd623..25f90cb0b92 100644 --- a/framework/src/main/java/org/tron/core/config/args/InetUtil.java +++ b/framework/src/main/java/org/tron/core/config/args/InetUtil.java @@ -19,8 +19,8 @@ public class InetUtil { /** - * Converts a list of {@code host:port} config strings into resolved {@link InetSocketAddress} - * objects, preserving the original order. + * Converts a list of {@code ipOrDomain:port} config strings into resolved {@link + * InetSocketAddress} objects, preserving the original order. * *

    IP literals (IPv4 and IPv6) are used as-is. Domain names are resolved via DNS: when there * are multiple domains they are resolved in parallel using a dedicated thread pool; a single @@ -31,7 +31,7 @@ public class InetUtil { *

  • example.com:18888, *
  • hostname:18888 * - * @param items list of address strings in {@code host:port} format (may mix IPs and domains) + * @param items list of address strings in {@code ipOrDomain:port} format (may mix IP and domains) * @return resolved addresses in the same order as {@code items}, omit unresolvable entries */ public static List getInetSocketAddressList(List items) { From b348ac4404688dcd3c5d6bef6ca4ca1e6b61e19d Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Wed, 22 Apr 2026 18:49:40 +0800 Subject: [PATCH 8/9] extract method --- common/build.gradle | 2 +- .../java/org/tron/core/config/args/Args.java | 31 ++++++++++++------- .../org/tron/core/config/args/InetUtil.java | 25 ++++++++------- gradle/verification-metadata.xml | 10 +++--- 4 files changed, 40 insertions(+), 28 deletions(-) diff --git a/common/build.gradle b/common/build.gradle index b7494f1c1d4..afc8652e6c5 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -21,7 +21,7 @@ dependencies { api 'org.aspectj:aspectjrt:1.9.8' api 'org.aspectj:aspectjweaver:1.9.8' api 'org.aspectj:aspectjtools:1.9.8' - api group: 'com.github.317787106', name: 'libp2p', version: 'v0.0.9',{ + api group: 'com.github.317787106', name: 'libp2p', version: 'v0.10.0',{ //api group: 'io.github.tronprotocol', name: 'libp2p', version: '2.2.7',{ exclude group: 'io.grpc', module: 'grpc-context' exclude group: 'io.grpc', module: 'grpc-core' diff --git a/framework/src/main/java/org/tron/core/config/args/Args.java b/framework/src/main/java/org/tron/core/config/args/Args.java index 4ef22624611..43a3bfd141a 100644 --- a/framework/src/main/java/org/tron/core/config/args/Args.java +++ b/framework/src/main/java/org/tron/core/config/args/Args.java @@ -74,7 +74,6 @@ import org.tron.core.exception.TronError; import org.tron.core.store.AccountStore; import org.tron.p2p.P2pConfig; -import org.tron.p2p.dns.lookup.LookUpTxt; import org.tron.p2p.dns.update.DnsType; import org.tron.p2p.dns.update.PublishConfig; import org.tron.p2p.utils.NetUtil; @@ -1302,14 +1301,12 @@ private static RateLimiterInitialization getRateLimiterFromConfig( return initialization; } + public static List getInetSocketAddress( final com.typesafe.config.Config config, String path, boolean filter) { List ret = new ArrayList<>(); - if (!config.hasPath(path)) { - return ret; - } - List list = config.getStringList(path); - for (InetSocketAddress inetSocketAddress : InetUtil.getInetSocketAddressList(list)) { + List socketAddressList = getInetSockerAddress(config, path); + for (InetSocketAddress inetSocketAddress : socketAddressList) { if (filter) { String ip = inetSocketAddress.getAddress().getHostAddress(); int port = inetSocketAddress.getPort(); @@ -1326,15 +1323,27 @@ public static List getInetSocketAddress( return ret; } - public static List getInetAddress( + private static List getInetSockerAddress( final com.typesafe.config.Config config, String path) { - List ret = new ArrayList<>(); + List socketAddressList = new ArrayList<>(); if (!config.hasPath(path)) { - return ret; + return socketAddressList; } List list = config.getStringList(path); - for (String configString : list) { - InetSocketAddress inetSocketAddress = NetUtil.parseInetSocketAddress(configString); + try { + socketAddressList = InetUtil.resolveInetSocketAddressList(list); + } catch (RuntimeException e) { + throw new TronError(String.format("config %s contains %s", path, e.getMessage()), + TronError.ErrCode.PARAMETER_INIT); + } + return socketAddressList; + } + + public static List getInetAddress( + final com.typesafe.config.Config config, String path) { + List ret = new ArrayList<>(); + List socketAddressList = getInetSockerAddress(config, path); + for (InetSocketAddress inetSocketAddress : socketAddressList) { ret.add(inetSocketAddress.getAddress()); } return ret; diff --git a/framework/src/main/java/org/tron/core/config/args/InetUtil.java b/framework/src/main/java/org/tron/core/config/args/InetUtil.java index 25f90cb0b92..3c78dac4f4b 100644 --- a/framework/src/main/java/org/tron/core/config/args/InetUtil.java +++ b/framework/src/main/java/org/tron/core/config/args/InetUtil.java @@ -31,17 +31,19 @@ public class InetUtil { *
  • example.com:18888, *
  • hostname:18888 * - * @param items list of address strings in {@code ipOrDomain:port} format (may mix IP and domains) + * @param ipOrDomainWithPortList list of address strings in {@code ipOrDomain:port} format + * (may mix IPs and domains) * @return resolved addresses in the same order as {@code items}, omit unresolvable entries */ - public static List getInetSocketAddressList(List items) { + public static List resolveInetSocketAddressList( + List ipOrDomainWithPortList) { List ret = new ArrayList<>(); - if (items.isEmpty()) { + if (ipOrDomainWithPortList.isEmpty()) { return ret; } // Collect entries whose host part is a domain name (not an IP literal). List domainEntries = new ArrayList<>(); - for (String item : items) { + for (String item : ipOrDomainWithPortList) { String host = NetUtil.parseInetSocketAddress(item).getHostString(); if (!NetUtil.validIpV4(host) && !NetUtil.validIpV6(host)) { domainEntries.add(item); @@ -52,8 +54,9 @@ public static List getInetSocketAddressList(List item Map domainResolved = new HashMap<>(); if (domainEntries.size() > 1) { String poolName = "args-dns-lookup"; + int poolSize = StrictMath.min(domainEntries.size(), 10); ExecutorService dnsPool = ExecutorServiceManager - .newFixedThreadPool(poolName, domainEntries.size(), true); + .newFixedThreadPool(poolName, poolSize, true); List> futures = new ArrayList<>(domainEntries.size()); for (String entry : domainEntries) { futures.add(dnsPool.submit(() -> resolveInetSocketAddress(entry))); @@ -76,13 +79,13 @@ public static List getInetSocketAddressList(List item } // Build the result list preserving the original config order. - for (String configString : items) { + for (String item : ipOrDomainWithPortList) { InetSocketAddress inetSocketAddress; - InetSocketAddress parsed = NetUtil.parseInetSocketAddress(configString); + InetSocketAddress parsed = NetUtil.parseInetSocketAddress(item); if (NetUtil.validIpV4(parsed.getHostString()) || NetUtil.validIpV6(parsed.getHostString())) { inetSocketAddress = parsed; } else { - inetSocketAddress = domainResolved.get(configString); + inetSocketAddress = domainResolved.get(item); } if (inetSocketAddress == null) { continue; @@ -98,11 +101,11 @@ public static List getInetSocketAddressList(List item *

    The host is looked up first over IPv4, then over IPv6 as a fallback. Returns {@code null} * if DNS resolution fails for both address families. * - * @param configString address string in {@code ipOrDomain:port} format + * @param ipOrDomainWithPort address string in {@code ipOrDomain:port} format * @return resolved {@link InetSocketAddress}, or {@code null} if the host cannot be resolved */ - private static InetSocketAddress resolveInetSocketAddress(String configString) { - InetSocketAddress parsed = NetUtil.parseInetSocketAddress(configString); + private static InetSocketAddress resolveInetSocketAddress(String ipOrDomainWithPort) { + InetSocketAddress parsed = NetUtil.parseInetSocketAddress(ipOrDomainWithPort); String host = parsed.getHostString(); int port = parsed.getPort(); InetAddress address = LookUpTxt.lookUpIp(host, true); diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index db17d29e0cf..81f5997c9ec 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -247,12 +247,12 @@ - - - + + + - - + + From 634f111949db03b5739f16c9ab263c24c4a62360 Mon Sep 17 00:00:00 2001 From: jiangyuanshu <317787106@qq.com> Date: Fri, 24 Apr 2026 23:37:12 +0800 Subject: [PATCH 9/9] optimize comment --- .../org/tron/core/config/args/InetUtil.java | 77 ++++++++++--------- 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/framework/src/main/java/org/tron/core/config/args/InetUtil.java b/framework/src/main/java/org/tron/core/config/args/InetUtil.java index 3c78dac4f4b..3d5e44f9588 100644 --- a/framework/src/main/java/org/tron/core/config/args/InetUtil.java +++ b/framework/src/main/java/org/tron/core/config/args/InetUtil.java @@ -18,45 +18,50 @@ @Slf4j(topic = "app") public class InetUtil { + private static final String DNS_POOL_NAME = "args-dns-lookup"; + private static final int DNS_POOL_MAX_SIZE = 10; + /** * Converts a list of {@code ipOrDomain:port} config strings into resolved {@link * InetSocketAddress} objects, preserving the original order. * *

    IP literals (IPv4 and IPv6) are used as-is. Domain names are resolved via DNS: when there - * are multiple domains they are resolved in parallel using a dedicated thread pool; a single - * domain is resolved inline. Entries that fail DNS resolution are silently dropped. Item is - * ipOrDomain:port, maybe like this: - *

  • 192.168.100.0:18888, - *
  • [fe80::48ff:fe00:1122]:18888, - *
  • example.com:18888, - *
  • hostname:18888 + * are multiple domains, they are resolved in parallel using a dedicated thread pool; a single + * domain is resolved inline. Entries that fail DNS resolution are silently dropped. + * + *

    Supported formats: + *

      + *
    • {@code 192.168.100.0:18888} + *
    • {@code [fe80::48ff:fe00:1122]:18888} + *
    • {@code example.com:18888} + *
    • {@code hostname:18888} + *
    * - * @param ipOrDomainWithPortList list of address strings in {@code ipOrDomain:port} format - * (may mix IPs and domains) - * @return resolved addresses in the same order as {@code items}, omit unresolvable entries + * @param ipOrDomainWithPortList list of address strings in {@code ipOrDomain:port} format, + * may mix IP literals and domain names + * @return resolved addresses in the same order as the input, omitting unresolvable entries */ public static List resolveInetSocketAddressList( List ipOrDomainWithPortList) { - List ret = new ArrayList<>(); + List result = new ArrayList<>(); if (ipOrDomainWithPortList.isEmpty()) { - return ret; + return result; } + // Collect entries whose host part is a domain name (not an IP literal). List domainEntries = new ArrayList<>(); for (String item : ipOrDomainWithPortList) { - String host = NetUtil.parseInetSocketAddress(item).getHostString(); - if (!NetUtil.validIpV4(host) && !NetUtil.validIpV6(host)) { + if (!isIpLiteral(NetUtil.parseInetSocketAddress(item).getHostString())) { domainEntries.add(item); } } - // Resolve domain names: spin up a thread pool only when there are multiple domains - Map domainResolved = new HashMap<>(); + // Resolve domain names: spin up a thread pool only when there are multiple domains. + Map resolvedDomains = new HashMap<>(); if (domainEntries.size() > 1) { - String poolName = "args-dns-lookup"; - int poolSize = StrictMath.min(domainEntries.size(), 10); + int poolSize = StrictMath.min(domainEntries.size(), DNS_POOL_MAX_SIZE); ExecutorService dnsPool = ExecutorServiceManager - .newFixedThreadPool(poolName, poolSize, true); + .newFixedThreadPool(DNS_POOL_NAME, poolSize, true); List> futures = new ArrayList<>(domainEntries.size()); for (String entry : domainEntries) { futures.add(dnsPool.submit(() -> resolveInetSocketAddress(entry))); @@ -64,7 +69,7 @@ public static List resolveInetSocketAddressList( for (int i = 0; i < domainEntries.size(); i++) { String entry = domainEntries.get(i); try { - domainResolved.put(entry, futures.get(i).get()); + resolvedDomains.put(entry, futures.get(i).get()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); logger.warn("DNS lookup interrupted for: {}", entry); @@ -72,27 +77,23 @@ public static List resolveInetSocketAddressList( logger.warn("Failed to resolve address, skip: {}", entry); } } - ExecutorServiceManager.shutdownAndAwaitTermination(dnsPool, poolName); + ExecutorServiceManager.shutdownAndAwaitTermination(dnsPool, DNS_POOL_NAME); } else if (domainEntries.size() == 1) { String entry = domainEntries.get(0); - domainResolved.put(entry, resolveInetSocketAddress(entry)); + resolvedDomains.put(entry, resolveInetSocketAddress(entry)); } // Build the result list preserving the original config order. for (String item : ipOrDomainWithPortList) { - InetSocketAddress inetSocketAddress; InetSocketAddress parsed = NetUtil.parseInetSocketAddress(item); - if (NetUtil.validIpV4(parsed.getHostString()) || NetUtil.validIpV6(parsed.getHostString())) { - inetSocketAddress = parsed; - } else { - inetSocketAddress = domainResolved.get(item); - } - if (inetSocketAddress == null) { - continue; + InetSocketAddress resolved = isIpLiteral(parsed.getHostString()) + ? parsed + : resolvedDomains.get(item); + if (resolved != null) { + result.add(resolved); } - ret.add(inetSocketAddress); } - return ret; + return result; } /** @@ -123,12 +124,14 @@ private static InetSocketAddress resolveInetSocketAddress(String ipOrDomainWithP * Resolves {@code ipOrDomain} to an {@link InetAddress}. * *

    IP literals are converted directly without a DNS lookup. Domain names are first resolved - * over IPv4, then retried over IPv6 if the first attempt fails. Returns {@code null} if the - * address cannot be resolved. + * over IPv4, then retried over IPv6 if the first attempt fails. + * + * @param ipOrDomain IPv4/IPv6 literal or a domain name to resolve + * @return the resolved {@link InetAddress}, or {@code null} if resolution fails */ public static InetAddress resolveInetAddress(String ipOrDomain) { // Fast path: already a numeric address — no lookup needed. - if (NetUtil.validIpV4(ipOrDomain) || NetUtil.validIpV6(ipOrDomain)) { + if (isIpLiteral(ipOrDomain)) { try { return InetAddress.getByName(ipOrDomain); } catch (UnknownHostException e) { @@ -141,4 +144,8 @@ public static InetAddress resolveInetAddress(String ipOrDomain) { } return address; } + + private static boolean isIpLiteral(String host) { + return NetUtil.validIpV4(host) || NetUtil.validIpV6(host); + } }