diff --git a/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolver.java b/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolver.java index 014bf19bbe..d2124b4442 100644 --- a/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolver.java +++ b/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolver.java @@ -378,6 +378,35 @@ public class DnsNameResolver extends InetNameResolver { int ndots, boolean decodeIdn, boolean completeOncePreferredResolved) { + this(eventLoop, channelFactory, socketChannelFactory, resolveCache, cnameCache, authoritativeDnsServerCache, + null, dnsQueryLifecycleObserverFactory, queryTimeoutMillis, resolvedAddressTypes, + recursionDesired, maxQueriesPerResolve, traceEnabled, maxPayloadSize, optResourceEnabled, + hostsFileEntriesResolver, dnsServerAddressStreamProvider, searchDomains, ndots, decodeIdn, + completeOncePreferredResolved); + } + + DnsNameResolver( + EventLoop eventLoop, + ChannelFactory channelFactory, + ChannelFactory socketChannelFactory, + final DnsCache resolveCache, + final DnsCnameCache cnameCache, + final AuthoritativeDnsServerCache authoritativeDnsServerCache, + SocketAddress localAddress, + DnsQueryLifecycleObserverFactory dnsQueryLifecycleObserverFactory, + long queryTimeoutMillis, + ResolvedAddressTypes resolvedAddressTypes, + boolean recursionDesired, + int maxQueriesPerResolve, + boolean traceEnabled, + int maxPayloadSize, + boolean optResourceEnabled, + HostsFileEntriesResolver hostsFileEntriesResolver, + DnsServerAddressStreamProvider dnsServerAddressStreamProvider, + String[] searchDomains, + int ndots, + boolean decodeIdn, + boolean completeOncePreferredResolved) { super(eventLoop); this.queryTimeoutMillis = queryTimeoutMillis > 0 ? queryTimeoutMillis @@ -444,7 +473,12 @@ public class DnsNameResolver extends InetNameResolver { }); channelFuture = responseHandler.channelActivePromise; - ChannelFuture future = b.register(); + final ChannelFuture future; + if (localAddress == null) { + future = b.register(); + } else { + future = b.bind(localAddress); + } Throwable cause = future.cause(); if (cause != null) { if (cause instanceof RuntimeException) { diff --git a/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolverBuilder.java b/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolverBuilder.java index 340541ec17..d0de0a855f 100644 --- a/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolverBuilder.java +++ b/resolver-dns/src/main/java/io/netty/resolver/dns/DnsNameResolverBuilder.java @@ -25,6 +25,7 @@ import io.netty.resolver.HostsFileEntriesResolver; import io.netty.resolver.ResolvedAddressTypes; import io.netty.util.concurrent.Future; +import java.net.SocketAddress; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -42,6 +43,7 @@ public final class DnsNameResolverBuilder { private DnsCache resolveCache; private DnsCnameCache cnameCache; private AuthoritativeDnsServerCache authoritativeDnsServerCache; + private SocketAddress localAddress; private Integer minTtl; private Integer maxTtl; private Integer negativeTtl; @@ -201,6 +203,16 @@ public final class DnsNameResolverBuilder { return this; } + /** + * Configure the address that will be used to bind too. If `null` the default will be used. + * @param localAddress the bind address + * @return {@code this} + */ + public DnsNameResolverBuilder localAddress(SocketAddress localAddress) { + this.localAddress = localAddress; + return this; + } + /** * Sets the minimum and maximum TTL of the cached DNS resource records (in seconds). If the TTL of the DNS * resource record returned by the DNS server is less than the minimum TTL or greater than the maximum TTL, @@ -465,6 +477,7 @@ public final class DnsNameResolverBuilder { resolveCache, cnameCache, authoritativeDnsServerCache, + localAddress, dnsQueryLifecycleObserverFactory, queryTimeoutMillis, resolvedAddressTypes,