Commit 6cc1b0c1 authored by Kenny Root's avatar Kenny Root Committed by The Android Automerger
Browse files

Try to get peer hostname from SocketAddress

Java 7 added a new method to InetSocketAddress called getHostString()
which returns the unresolved host for a given address. This should be
suitable for use with SNI as long as it isn't an IP address.

This also helps with testing because we can use serialization tricks to
rewrite the "hostname" field of an already-serialized loopback address.

(cherry picked from commit bc8a290f)

Bug: 27271561
Change-Id: I9845e57d505712cdfee87d18246a1a3b021deea3
parent ec57e448
......@@ -26,6 +26,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.security.InvalidKeyException;
......@@ -536,4 +537,22 @@ public class Platform {
return new OpenSSLExtendedSessionImpl(sslSession);
}
}
/*
* Pre-Java-7 backward compatibility.
*/
public static String getHostStringFromInetSocketAddress(InetSocketAddress addr) {
if (Build.VERSION.SDK_INT > 23) {
try {
Method m_getHostString = InetSocketAddress.class
.getDeclaredMethod("getHostString");
return (String) m_getHostString.invoke(addr);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (Exception ignored) {
}
}
return null;
}
}
......@@ -26,7 +26,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.security.InvalidKeyException;
import java.security.PrivateKey;
......@@ -133,7 +135,9 @@ public class OpenSSLSocketImpl
private final boolean autoClose;
/**
* The peer's DNS hostname if it was supplied during creation.
* The peer's DNS hostname if it was supplied during creation. Note that
* this may be a raw IP address, so it should be checked before use with
* extensions that don't use it like Server Name Indication (SNI).
*/
private String peerHostname;
......@@ -243,6 +247,24 @@ public class OpenSSLSocketImpl
// to wrapped socket
}
@Override
public void connect(SocketAddress endpoint) throws IOException {
connect(endpoint, 0);
}
/**
* Try to extract the peer's hostname if it's available from the endpoint address.
*/
@Override
public void connect(SocketAddress endpoint, int timeout) throws IOException {
if (peerHostname == null && endpoint instanceof InetSocketAddress) {
peerHostname = Platform.getHostStringFromInetSocketAddress(
(InetSocketAddress) endpoint);
}
super.connect(endpoint, timeout);
}
private void checkOpen() throws SocketException {
if (isClosed()) {
throw new SocketException("Socket is closed");
......
......@@ -20,6 +20,7 @@ import java.io.FileDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.security.InvalidKeyException;
......@@ -277,10 +278,18 @@ public class Platform {
}
/*
* Pre-Java 8 backward compatibility.
* Pre-Java-8 backward compatibility.
*/
public static SSLSession wrapSSLSession(OpenSSLSessionImpl sslSession) {
return new OpenSSLExtendedSessionImpl(sslSession);
}
/*
* Pre-Java-7 backward compatibility.
*/
public static String getHostStringFromInetSocketAddress(InetSocketAddress addr) {
return addr.getHostString();
}
}
......@@ -29,6 +29,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketImpl;
......@@ -317,4 +318,12 @@ class Platform {
public static SSLSession wrapSSLSession(OpenSSLSessionImpl sslSession) {
return new OpenSSLExtendedSessionImpl(sslSession);
}
/*
* Pre-Java-7 backward compatibility.
*/
public static String getHostStringFromInetSocketAddress(InetSocketAddress addr) {
return addr.getHostString();
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment