all: avoid DNS with GRPC_PROXY_EXP

In some environments DNS is not available and is performed by the
CONNECT proxy. Nothing "special" should need to be done for these
environments, but the previous support took shortcuts which knowingly
would not support such environments.

This change should fix both OkHttp and Netty. Netty's
Bootstrap.connect() resolved the name immediately whereas using
ChannelPipeline.connect() waits until the address reaches the end of the
pipeline. Netty uses NetUtil.toSocketAddressString() to get the name of
the address, which uses InetSocketAddress.getHostString() when
available.

OkHttp is still using InetSocketAddress.getHostName() which may issue
reverse DNS lookups. However, if the reverse DNS lookup fails, it should
convert the IP to a textual string like getHostString(). So as long as
the reverse DNS maps to the same machine as the IP, there should only be
performance concerns, not correctness issues. Since the DnsNameResolver
is creating unresolved addresses, the reverse DNS lookups shouldn't
occur in the common case.
This commit is contained in:
Eric Anderson 2017-01-24 11:05:21 -08:00
parent 23f5a6ff2a
commit 65e4d9f47a
3 changed files with 14 additions and 16 deletions

View File

@ -140,6 +140,15 @@ class DnsNameResolver extends NameResolver {
resolving = true;
}
try {
if (System.getenv("GRPC_PROXY_EXP") != null) {
ResolvedServerInfoGroup servers = ResolvedServerInfoGroup.builder()
.add(new ResolvedServerInfo(
InetSocketAddress.createUnresolved(host, port), Attributes.EMPTY))
.build();
savedListener.onUpdate(Collections.singletonList(servers), Attributes.EMPTY);
return;
}
try {
inetAddrs = getAllByName(host);
} catch (UnknownHostException e) {

View File

@ -43,9 +43,6 @@ import io.grpc.testing.TestUtils;
import io.netty.handler.ssl.SslContext;
import java.io.File;
import java.io.FileInputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import javax.net.ssl.SSLSocketFactory;
@ -304,16 +301,6 @@ public class TestServiceClient {
@Override
protected ManagedChannel createChannel() {
if (!useOkHttp) {
InetAddress address;
try {
address = InetAddress.getByName(serverHost);
if (serverHostOverride != null) {
// Force the hostname to match the cert the server uses.
address = InetAddress.getByAddress(serverHostOverride, address.getAddress());
}
} catch (UnknownHostException ex) {
throw new RuntimeException(ex);
}
SslContext sslContext = null;
if (useTestCa) {
try {
@ -323,7 +310,8 @@ public class TestServiceClient {
throw new RuntimeException(ex);
}
}
return NettyChannelBuilder.forAddress(new InetSocketAddress(address, serverPort))
return NettyChannelBuilder.forAddress(serverHost, serverPort)
.overrideAuthority(serverHostOverride)
.flowControlWindow(65 * 1024)
.negotiationType(useTls ? NegotiationType.TLS : NegotiationType.PLAINTEXT)
.sslContext(sslContext)

View File

@ -194,8 +194,9 @@ class NettyClientTransport implements ConnectionClientTransport {
* that it may begin buffering writes.
*/
b.handler(negotiationHandler);
channel = b.register().channel();
// Start the connection operation to the server.
channel = b.connect(address).addListener(new ChannelFutureListener() {
channel.connect(address).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (!future.isSuccess()) {
@ -209,7 +210,7 @@ class NettyClientTransport implements ConnectionClientTransport {
future.channel().pipeline().fireExceptionCaught(future.cause());
}
}
}).channel();
});
// Start the write queue as soon as the channel is constructed
handler.startWriteQueue(channel);
// This write will have no effect, yet it will only complete once the negotiationHandler