Skip to content

Commit 490ea1c

Browse files
committed
expose experimental settings for dns
1 parent 98e3054 commit 490ea1c

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

core/src/main/java/com/linecorp/armeria/client/AbstractDnsResolverBuilder.java

+46
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,14 @@
3838

3939
import io.micrometer.core.instrument.MeterRegistry;
4040
import io.netty.channel.EventLoopGroup;
41+
import io.netty.channel.socket.DatagramChannel;
42+
import io.netty.channel.socket.SocketChannel;
4143
import io.netty.handler.codec.dns.DnsRecord;
4244
import io.netty.resolver.HostsFileEntriesResolver;
4345
import io.netty.resolver.dns.BiDnsQueryLifecycleObserverFactory;
46+
import io.netty.resolver.dns.DnsNameResolver;
4447
import io.netty.resolver.dns.DnsNameResolverBuilder;
48+
import io.netty.resolver.dns.DnsNameResolverChannelStrategy;
4549
import io.netty.resolver.dns.DnsQueryLifecycleObserverFactory;
4650
import io.netty.resolver.dns.DnsServerAddressStream;
4751
import io.netty.resolver.dns.DnsServerAddressStreamProvider;
@@ -83,6 +87,11 @@ public abstract class AbstractDnsResolverBuilder<SELF extends AbstractDnsResolve
8387
private List<String> searchDomains = DnsUtil.defaultSearchDomains();
8488
private int ndots = DnsUtil.defaultNdots();
8589
private boolean decodeIdn = true;
90+
@Nullable
91+
private DnsNameResolverChannelStrategy datagramChannelStrategy;
92+
@Nullable
93+
private Class<? extends SocketChannel> socketChannelType;
94+
private boolean retrySocketChannelOnTimeout;
8695

8796
@Nullable
8897
private MeterRegistry meterRegistry;
@@ -487,6 +496,36 @@ protected final DnsCache maybeCreateDnsCache() {
487496
}
488497
}
489498

499+
/**
500+
* Set the strategy that is used to determine how a {@link DatagramChannel} is used by the resolver for
501+
* sending queries over UDP protocol.
502+
*/
503+
@UnstableApi
504+
public SELF datagramChannelStrategy(DnsNameResolverChannelStrategy datagramChannelStrategy) {
505+
requireNonNull(datagramChannelStrategy, "datagramChannelStrategy");
506+
this.datagramChannelStrategy = datagramChannelStrategy;
507+
return self();
508+
}
509+
510+
/**
511+
* Enables <a href="https://tools.ietf.org/html/rfc7766">TCP fallback</a> using the specified
512+
* {@link SocketChannel} type.
513+
* <p>
514+
* TCP fallback is disabled by default.
515+
* @param socketChannelType the type of {@link SocketChannel} to use for TCP fallback.
516+
* @param retrySocketChannelOnTimeout if {@code true} the {@link DnsNameResolver} will also fallback to
517+
* TCP if a timeout was detected, if {@code false} it will only try to
518+
* use TCP if the response was marked as truncated.
519+
*/
520+
@UnstableApi
521+
public SELF socketChannelType(Class<? extends SocketChannel> socketChannelType,
522+
boolean retrySocketChannelOnTimeout) {
523+
requireNonNull(socketChannelType, "channelType");
524+
this.socketChannelType = socketChannelType;
525+
this.retrySocketChannelOnTimeout = retrySocketChannelOnTimeout;
526+
return self();
527+
}
528+
490529
/**
491530
* Builds a configurator that configures a {@link DnsNameResolverBuilder} with the properties set.
492531
*/
@@ -561,6 +600,13 @@ protected final Consumer<DnsNameResolverBuilder> buildConfigurator(EventLoopGrou
561600
if (observerFactory != null) {
562601
builder.dnsQueryLifecycleObserverFactory(observerFactory);
563602
}
603+
final DnsNameResolverChannelStrategy datagramChannelStrategy = this.datagramChannelStrategy;
604+
if (datagramChannelStrategy != null) {
605+
builder.datagramChannelStrategy(datagramChannelStrategy);
606+
}
607+
final Class<? extends SocketChannel> socketChannelType = this.socketChannelType;
608+
final boolean retrySocketChannelOnTimeout = this.retrySocketChannelOnTimeout;
609+
builder.socketChannelType(socketChannelType, retrySocketChannelOnTimeout);
564610
};
565611
}
566612
}

core/src/test/java/com/linecorp/armeria/client/endpoint/dns/DnsAddressEndpointGroupTest.java

+36
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,15 @@
5050
import io.netty.buffer.Unpooled;
5151
import io.netty.channel.ChannelHandlerContext;
5252
import io.netty.channel.ChannelInboundHandlerAdapter;
53+
import io.netty.channel.socket.nio.NioSocketChannel;
5354
import io.netty.handler.codec.dns.DatagramDnsQuery;
5455
import io.netty.handler.codec.dns.DefaultDnsQuestion;
5556
import io.netty.handler.codec.dns.DefaultDnsRawRecord;
5657
import io.netty.handler.codec.dns.DefaultDnsResponse;
5758
import io.netty.handler.codec.dns.DnsRecord;
5859
import io.netty.handler.codec.dns.DnsSection;
5960
import io.netty.resolver.ResolvedAddressTypes;
61+
import io.netty.resolver.dns.DnsNameResolverChannelStrategy;
6062
import io.netty.util.NetUtil;
6163
import io.netty.util.ReferenceCountUtil;
6264

@@ -612,6 +614,40 @@ public void onFailure(List<DnsRecord> oldRecords,
612614
}
613615
}
614616

617+
@Test
618+
void experimentalSettingsYieldCorrectResults() {
619+
try (TestDnsServer server = new TestDnsServer(ImmutableMap.of(
620+
new DefaultDnsQuestion("baz.com.", A),
621+
new DefaultDnsResponse(0).addRecord(ANSWER, newAddressRecord("baz.com.", "1.1.1.1"))))) {
622+
final AtomicBoolean success = new AtomicBoolean(false);
623+
final DnsQueryListener listener = new DnsQueryListener() {
624+
@Override
625+
public void onSuccess(List<DnsRecord> oldRecords,
626+
List<DnsRecord> newRecords, String logPrefix) {
627+
success.set(true);
628+
}
629+
630+
@Override
631+
public void onFailure(List<DnsRecord> oldRecords,
632+
Throwable cause, String logPrefix, long delayMillis, int attemptsSoFar) {
633+
}
634+
};
635+
try (DnsAddressEndpointGroup group =
636+
DnsAddressEndpointGroup.builder("baz.com")
637+
.port(8080)
638+
.serverAddresses(server.addr())
639+
.dnsCache(NoopDnsCache.INSTANCE)
640+
.addDnsQueryListeners(listener)
641+
.datagramChannelStrategy(
642+
DnsNameResolverChannelStrategy.ChannelPerResolution)
643+
.socketChannelType(NioSocketChannel.class, true)
644+
.build()) {
645+
await().timeout(Duration.ofSeconds(1))
646+
.untilAsserted(() -> assertThat(success.get()).isTrue());
647+
}
648+
}
649+
}
650+
615651
private static DnsRecord newCompatibleAddressRecord(String name, String ipV4Addr) {
616652
final ByteBuf content = Unpooled.buffer();
617653
content.writeZero(12);

0 commit comments

Comments
 (0)