Skip to content

Commit

Permalink
Merge pull request #14766 from iterate-ch/feature/GH-14286
Browse files Browse the repository at this point in the history
Return all resolved addresses.
  • Loading branch information
dkocher authored Jun 20, 2023
2 parents b837fc9 + cd1a7dc commit 431562a
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 19 deletions.
18 changes: 9 additions & 9 deletions core/dylib/src/test/java/ch/cyberduck/core/ResolverTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class ResolverTest {

@Test
public void testResolve() throws Exception {
assertEquals("52.31.8.231", new Resolver().resolve("cyberduck.io", new DisabledCancelCallback()).getHostAddress());
assertEquals("52.31.8.231", new Resolver().resolve("cyberduck.io", new DisabledCancelCallback())[0].getHostAddress());
}

@Test
Expand All @@ -30,7 +30,7 @@ public void testFailure() throws Exception {
catch(ResolveFailedException e) {
//
}
assertNotNull(resolver.resolve("cyberduck.io", new DisabledCancelCallback()).getHostAddress());
assertNotNull(resolver.resolve("cyberduck.io", new DisabledCancelCallback())[0].getHostAddress());
}

@Test
Expand All @@ -48,29 +48,29 @@ public void verify() throws ConnectionCanceledException {
catch(ResolveCanceledException e) {
//
}
assertNotNull(resolver.resolve("cyberduck.io", new DisabledCancelCallback()).getHostAddress());
assertNotNull(resolver.resolve("cyberduck.io", new DisabledCancelCallback())[0].getHostAddress());
}

@Test
public void testResolveIPv6Localhost() throws Exception {
assertEquals("localhost", new Resolver().resolve("::1", new DisabledCancelCallback()).getHostName());
assertEquals("0:0:0:0:0:0:0:1", new Resolver().resolve("::1", new DisabledCancelCallback()).getHostAddress());
assertEquals("localhost", new Resolver().resolve("::1", new DisabledCancelCallback())[0].getHostName());
assertEquals("0:0:0:0:0:0:0:1", new Resolver().resolve("::1", new DisabledCancelCallback())[0].getHostAddress());
}

@Test
@Ignore
public void testResolveLinkLocalZoneIndexInterfaceName() throws Exception {
assertEquals("andaman.local", new Resolver().resolve("andaman.local", new DisabledCancelCallback()).getHostName());
assertEquals("fe80:0:0:0:c62c:3ff:fe0b:8670%en0", new Resolver().resolve("fe80::c62c:3ff:fe0b:8670%en0", new DisabledCancelCallback()).getHostAddress());
assertEquals("andaman.local", new Resolver().resolve("andaman.local", new DisabledCancelCallback())[0].getHostName());
assertEquals("fe80:0:0:0:c62c:3ff:fe0b:8670%en0", new Resolver().resolve("fe80::c62c:3ff:fe0b:8670%en0", new DisabledCancelCallback())[0].getHostAddress());
}

@Test
public void testResolvePublicDNSIPv6Only() throws Exception {
assertEquals("2001:470:a085:999:0:0:0:21", new Resolver().resolve("ftp6.netbsd.org", new DisabledCancelCallback()).getHostAddress());
assertEquals("2001:470:a085:999:0:0:0:21", new Resolver().resolve("ftp6.netbsd.org", new DisabledCancelCallback())[0].getHostAddress());
}

@Test
public void testResolvePublicDNSIPv6ForHybrid() throws Exception {
assertEquals("2600:3c02:0:0:f03c:91ff:fe89:e8b1", new Resolver(true).resolve("intronetworks.cs.luc.edu", new DisabledCancelCallback()).getHostAddress());
assertEquals("2600:3c02:0:0:f03c:91ff:fe89:e8b1", new Resolver(true).resolve("intronetworks.cs.luc.edu", new DisabledCancelCallback())[0].getHostAddress());
}
}
17 changes: 11 additions & 6 deletions core/src/main/java/ch/cyberduck/core/Resolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@
import java.text.MessageFormat;
import java.time.Duration;
import java.util.Arrays;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import com.google.common.util.concurrent.Uninterruptibles;

Expand All @@ -63,21 +65,24 @@ public Resolver(final boolean preferIPv6) {
* @throws ResolveFailedException If the hostname cannot be resolved
* @throws ResolveCanceledException If the lookup has been interrupted
*/
public InetAddress resolve(final String hostname, final CancelCallback callback) throws ResolveFailedException, ResolveCanceledException {
public InetAddress[] resolve(final String hostname, final CancelCallback callback) throws ResolveFailedException, ResolveCanceledException {
final CountDownLatch signal = new CountDownLatch(1);
final AtomicReference<InetAddress> resolved = new AtomicReference<>();
final AtomicReference<Set<InetAddress>> resolved = new AtomicReference<>();
final AtomicReference<UnknownHostException> failure = new AtomicReference<>();
final Thread resolver = threadFactory.newThread(new Runnable() {
@Override
public void run() {
try {
final InetAddress[] allByName = InetAddress.getAllByName(hostname);
Arrays.stream(allByName).findFirst().ifPresent(resolved::set);
resolved.set(Arrays.stream(allByName).collect(Collectors.toSet()));
if(preferIPv6) {
Arrays.stream(allByName).filter(inetAddress -> inetAddress instanceof Inet6Address).findFirst().ifPresent(resolved::set);
final Set<InetAddress> filtered = Arrays.stream(allByName).filter(inetAddress -> inetAddress instanceof Inet6Address).collect(Collectors.toSet());
if(!filtered.isEmpty()) {
resolved.set(filtered);
}
}
if(log.isInfoEnabled()) {
log.info(String.format("Resolved %s to %s", hostname, resolved.get().getHostAddress()));
log.info(String.format("Resolved %s to %s", hostname, Arrays.toString(resolved.get().toArray())));
}
}
catch(UnknownHostException e) {
Expand Down Expand Up @@ -114,7 +119,7 @@ public void run() {
throw new ResolveFailedException(
MessageFormat.format(LocaleFactory.localizedString("DNS lookup for {0} failed", "Error"), hostname), failure.get());
}
return resolved.get();
return resolved.get().toArray(new InetAddress[resolved.get().size()]);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import ch.cyberduck.core.Resolver;
import ch.cyberduck.core.exception.ResolveCanceledException;
import ch.cyberduck.core.exception.ResolveFailedException;

import org.apache.http.conn.DnsResolver;

import java.net.InetAddress;
Expand All @@ -31,7 +32,7 @@ public class CustomDnsResolver implements DnsResolver {
@Override
public InetAddress[] resolve(String host) throws UnknownHostException {
try {
return new InetAddress[]{resolver.resolve(host, new DisabledCancelCallback())};
return resolver.resolve(host, new DisabledCancelCallback());
}
catch(ResolveFailedException | ResolveCanceledException e) {
throw new UnknownHostException(e.getDetail(false));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public CustomClientConfiguration(final Host host, final ThreadLocalHostnameDeleg
@Override
public InetAddress[] resolve(final String host) throws UnknownHostException {
try {
return new InetAddress[]{new Resolver().resolve(host, new DisabledCancelCallback())};
return new Resolver().resolve(host, new DisabledCancelCallback());
}
catch(ResolveFailedException | ResolveCanceledException e) {
throw new UnknownHostException(e.getDetail(false));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,8 +303,8 @@ private List<TransferStatus> query(final Path file, final TransferStatus status,
if(StringUtils.equals(node.getEndPoint(), host.getHostname())) {
break;
}
if(StringUtils.equals(node.getEndPoint(), new Resolver().resolve(host.getHostname(),
new DisabledCancelCallback()).getHostAddress())) {
if(StringUtils.equals(node.getEndPoint(), new Resolver().resolve(
host.getHostname(), new DisabledCancelCallback())[0].getHostAddress())) {
break;
}
log.warn(String.format("Redirect to %s for file %s", node.getEndPoint(), file));
Expand Down

0 comments on commit 431562a

Please sign in to comment.