卓桐 看雪学院
看雪论坛作者ID:卓桐
URL url = new URL("https://www.baidu.com");
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("192.168.2.1", 8081));
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(10000);
connection.addRequestProperty("accept-encoding", "gzip, deflate, br");
connection.setRequestMethod("GET");
InputStream is = connection.getInputStream();
Map<String, List<String>> map = connection.getHeaderFields();
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
Log.e("zhuo", entry.getKey()+"="+entry.getValue());
}
GZIPInputStream gis = new GZIPInputStream(is);
byte buf[] = new byte[1024];
gis.read(buf);
Log.e("zhuo", new String(buf));
connection.disconnect();
W/System.err: java.net.ConnectException: failed to connect to localhost/127.0.0.1 (port 8081) after 10000ms: isConnected failed: ECONNREFUSED (Connection refused)
W/System.err: at libcore.io.IoBridge.isConnected(IoBridge.java:223)
at libcore.io.IoBridge.connectErrno(IoBridge.java:161)
at libcore.io.IoBridge.connect(IoBridge.java:112)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
at java.net.Socket.connect(Socket.java:843)
at com.android.okhttp.internal.Platform.connectSocket(Platform.java:131)
at com.android.okhttp.Connection.connect(Connection.java:101)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:294)
at com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:345)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:296)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:179)
at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:246)
transient URLStreamHandler streamHandler;
public URLConnection openConnection() throws IOException {
return streamHandler.openConnection(this);
}
public URL(String spec) throws MalformedURLException {
this((URL) null, spec, null);
}
public URL(URL context, String spec, URLStreamHandler handler) throws MalformedURLException {
if (spec == null) {
throw new MalformedURLException();
}
if (handler != null) {
streamHandler = handler;
}
spec = spec.trim();
protocol = UrlUtils.getSchemePrefix(spec);
int schemeSpecificPartStart = protocol != null ? (protocol.length() + 1) : 0;
if (protocol != null && context != null && !protocol.equals(context.protocol)) {
context = null;
}
if (context != null) {
set(context.protocol, context.getHost(), context.getPort(), context.getAuthority(),
context.getUserInfo(), context.getPath(), context.getQuery(),
context.getRef());
if (streamHandler == null) {
streamHandler = context.streamHandler;
}
} else if (protocol == null) {
throw new MalformedURLException("Protocol not found: " + spec);
}
if (streamHandler == null) {
setupStreamHandler();
if (streamHandler == null) {
throw new MalformedURLException("Unknown protocol: " + protocol);
}
}
try {
streamHandler.parseURL(this, spec, schemeSpecificPartStart, spec.length());
} catch (Exception e) {
throw new MalformedURLException(e.toString());
}
}
void setupStreamHandler() {
...
else if (protocol.equals("http")) {
try {
String name = "com.android.okhttp.HttpHandler";
streamHandler = (URLStreamHandler) Class.forName(name).newInstance();
} catch (Exception e) {
throw new AssertionError(e);
}
} else if (protocol.equals("https")) {
try {
String name = "com.android.okhttp.HttpsHandler";
streamHandler = (URLStreamHandler) Class.forName(name).newInstance();
} catch (Exception e) {
throw new AssertionError(e);
}
}
...
}
public class HttpHandler extends URLStreamHandler {
@Override protected URLConnection openConnection(URL url) throws IOException {
return newOkHttpClient(null ).open(url);
}
@Override protected URLConnection openConnection(URL url, Proxy proxy) throws IOException {
if (url == null || proxy == null) {
throw new IllegalArgumentException("url == null || proxy == null");
}
return newOkHttpClient(proxy).open(url);
}
@Override protected int getDefaultPort() {
return 80;
}
protected OkHttpClient newOkHttpClient(Proxy proxy) {
OkHttpClient client = new OkHttpClient();
client.setFollowProtocolRedirects(false);
if (proxy != null) {
client.setProxy(proxy);
}
return client;
}
}
public final class HttpsHandler extends HttpHandler {
private static final List<String> ENABLED_TRANSPORTS = Arrays.asList("http/1.1");
@Override protected int getDefaultPort() {
return 443;
}
@Override
protected OkHttpClient newOkHttpClient(Proxy proxy) {
OkHttpClient client = super.newOkHttpClient(proxy);
client.setTransports(ENABLED_TRANSPORTS);
HostnameVerifier verifier = HttpsURLConnection.getDefaultHostnameVerifier();
if (!(verifier instanceof DefaultHostnameVerifier)) {
client.setHostnameVerifier(verifier);
}
return client;
}
}
HttpURLConnection open(URL url, Proxy proxy) {
String protocol = url.getProtocol();
OkHttpClient copy = copyWithDefaults();
copy.proxy = proxy;
if (protocol.equals("http")) return new HttpURLConnectionImpl(url, copy);
if (protocol.equals("https")) return new HttpsURLConnectionImpl(url, copy);
throw new IllegalArgumentException("Unexpected protocol: " + protocol);
}
private OkHttpClient copyWithDefaults() {
OkHttpClient result = new OkHttpClient(this);
result.proxy = proxy;
result.proxySelector = proxySelector != null ? proxySelector : ProxySelector.getDefault();
result.cookieHandler = cookieHandler != null ? cookieHandler : CookieHandler.getDefault();
result.responseCache = responseCache != null ? responseCache : ResponseCache.getDefault();
result.sslSocketFactory = sslSocketFactory != null
? sslSocketFactory
: HttpsURLConnection.getDefaultSSLSocketFactory();
result.hostnameVerifier = hostnameVerifier != null
? hostnameVerifier
: OkHostnameVerifier.INSTANCE;
result.authenticator = authenticator != null
? authenticator
: HttpAuthenticator.SYSTEM_DEFAULT;
result.connectionPool = connectionPool != null ? connectionPool : ConnectionPool.getDefault();
result.followProtocolRedirects = followProtocolRedirects;
result.transports = transports != null ? transports : DEFAULT_TRANSPORTS;
result.connectTimeout = connectTimeout;
result.readTimeout = readTimeout;
return result;
}
@Override public final InputStream getInputStream() throws IOException {
if (!doInput) {
throw new ProtocolException("This protocol does not support input");
}
HttpEngine response = getResponse();
if (getResponseCode() >= HTTP_BAD_REQUEST) {
throw new FileNotFoundException(url.toString());
}
InputStream result = response.getResponseBody();
if (result == null) {
throw new ProtocolException("No response body exists; responseCode=" + getResponseCode());
}
return result;
}
private HttpEngine getResponse() throws IOException {
initHttpEngine();
if (httpEngine.hasResponse()) {
return httpEngine;
}
while (true) {
if (!execute(true)) {
continue;
}
...
}
private boolean execute(boolean readResponse) throws IOException {
try {
httpEngine.sendRequest();
if (readResponse) {
httpEngine.readResponse();
}
return true;
} catch (IOException e) {
if (handleFailure(e)) {
return false;
} else {
throw e;
}
}
}
public final void sendRequest() throws IOException {
...
if (responseSource.requiresConnection()) {
sendSocketRequest();
} else if (connection != null) {
client.getConnectionPool().recycle(connection);
connection = null;
}
}
private void sendSocketRequest() throws IOException {
if (connection == null) {
connect();
}
if (transport != null) {
throw new IllegalStateException();
}
transport = (Transport) connection.newTransport(this);
if (hasRequestBody() && requestBodyOut == null) {
requestBodyOut = transport.createRequestBody();
}
}
protected final void connect() throws IOException {
if (connection != null) {
return;
}
if (routeSelector == null) {
String uriHost = uri.getHost();
if (uriHost == null) {
throw new UnknownHostException(uri.toString());
}
SSLSocketFactory sslSocketFactory = null;
HostnameVerifier hostnameVerifier = null;
if (uri.getScheme().equalsIgnoreCase("https")) {
sslSocketFactory = client.getSslSocketFactory();
hostnameVerifier = client.getHostnameVerifier();
}
Address address = new Address(uriHost, getEffectivePort(uri), sslSocketFactory,
hostnameVerifier, client.getAuthenticator(), client.getProxy(), client.getTransports());
routeSelector = new RouteSelector(address, uri, client.getProxySelector(),
client.getConnectionPool(), Dns.DEFAULT, client.getRoutesDatabase());
}
connection = routeSelector.next(method);
if (!connection.isConnected()) {
connection.connect(client.getConnectTimeout(), client.getReadTimeout(), getTunnelConfig());
client.getConnectionPool().maybeShare(connection);
client.getRoutesDatabase().connected(connection.getRoute());
} else {
connection.updateReadTimeout(client.getReadTimeout());
}
connected(connection);
if (connection.getRoute().getProxy() != client.getProxy()) {
requestHeaders.getHeaders().setRequestLine(getRequestLine());
}
}
public Connection(Route route) {
this.route = route;
}
public void connect(int connectTimeout, int readTimeout, TunnelRequest tunnelRequest)
throws IOException {
if (connected) {
throw new IllegalStateException("already connected");
}
connected = true;
socket = (route.proxy.type() != Proxy.Type.HTTP) ? new Socket(route.proxy) : new Socket();
Platform.get().connectSocket(socket, route.inetSocketAddress, connectTimeout);
socket.setSoTimeout(readTimeout);
in = socket.getInputStream();
out = socket.getOutputStream();
if (route.address.sslSocketFactory != null) {
upgradeToTls(tunnelRequest);
}
int mtu = Platform.get().getMtu(socket);
if (mtu < 1024) mtu = 1024;
if (mtu > 8192) mtu = 8192;
in = new BufferedInputStream(in, mtu);
out = new BufferedOutputStream(out, mtu);
}
connection = routeSelector.next(method);
public Connection next(String method) throws IOException {
for (Connection pooled; (pooled = pool.get(address)) != null; ) {
if (method.equals("GET") || pooled.isReadable()) return pooled;
pooled.close();
}
if (!hasNextTlsMode()) {
if (!hasNextInetSocketAddress()) {
if (!hasNextProxy()) {
if (!hasNextPostponed()) {
throw new NoSuchElementException();
}
return new Connection(nextPostponed());
}
lastProxy = nextProxy();
resetNextInetSocketAddress(lastProxy);
}
lastInetSocketAddress = nextInetSocketAddress();
resetNextTlsMode();
}
boolean modernTls = nextTlsMode() == TLS_MODE_MODERN;
Route route = new Route(address, lastProxy, lastInetSocketAddress, modernTls);
if (routeDatabase.shouldPostpone(route)) {
postponedRoutes.add(route);
return next(method);
}
return new Connection(route);
}
public Route(Address address, Proxy proxy, InetSocketAddress inetSocketAddress,
boolean modernTls) {
if (address == null) throw new NullPointerException("address == null");
if (proxy == null) throw new NullPointerException("proxy == null");
if (inetSocketAddress == null) throw new NullPointerException("inetSocketAddress == null");
this.address = address;
this.proxy = proxy;
this.inetSocketAddress = inetSocketAddress;
this.modernTls = modernTls;
}
private InetSocketAddress nextInetSocketAddress() throws UnknownHostException {
InetSocketAddress result =
new InetSocketAddress(socketAddresses[nextSocketAddressIndex++], socketPort);
if (nextSocketAddressIndex == socketAddresses.length) {
socketAddresses = null;
nextSocketAddressIndex = 0;
}
return result;
}
private void resetNextInetSocketAddress(Proxy proxy) throws UnknownHostException {
socketAddresses = null;
String socketHost;
if (proxy.type() == Proxy.Type.DIRECT) {
socketHost = uri.getHost();
socketPort = getEffectivePort(uri);
} else {
SocketAddress proxyAddress = proxy.address();
if (!(proxyAddress instanceof InetSocketAddress)) {
throw new IllegalArgumentException(
"Proxy.address() is not an " + "InetSocketAddress: " + proxyAddress.getClass());
}
InetSocketAddress proxySocketAddress = (InetSocketAddress) proxyAddress;
socketHost = proxySocketAddress.getHostName();
socketPort = proxySocketAddress.getPort();
}
socketAddresses = dns.getAllByName(socketHost);
nextSocketAddressIndex = 0;
}
routeSelector = new RouteSelector(address, uri, client.getProxySelector(),
client.getConnectionPool(), Dns.DEFAULT, client.getRoutesDatabase());
public interface Dns {
Dns DEFAULT = new Dns() {
@Override public InetAddress[] getAllByName(String host) throws UnknownHostException {
return InetAddress.getAllByName(host);
}
};
InetAddress[] getAllByName(String host) throws UnknownHostException;
}
private static InetAddress[] lookupHostByName(String host) throws UnknownHostException {
...
StructAddrinfo hints = new StructAddrinfo();
hints.ai_flags = AI_ADDRCONFIG;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
InetAddress[] addresses = Libcore.os.getaddrinfo(host, hints);
for (InetAddress address : addresses) {
address.hostName = host;
}
addressCache.put(host, addresses);
}
NATIVE_METHOD(Posix, getaddrinfo, "(Ljava/lang/String;Llibcore/io/StructAddrinfo;)[Ljava/net/InetAddress;"),
对应的c++实现为Posix_getaddrinfo
static jobjectArray Posix_getaddrinfo(JNIEnv* env, jobject, jstring javaNode, jobject javaHints) {
...
addrinfo* addressList = NULL;
errno = 0;
int rc = getaddrinfo(node.c_str(), NULL, &hints, &addressList);
UniquePtr<addrinfo, addrinfo_deleter> addressListDeleter(addressList);
if (rc != 0) {
throwGaiException(env, "getaddrinfo", rc);
return NULL;
}
...
return result;
}
int
getaddrinfo(const char *hostname, const char *servname,
const struct addrinfo *hints, struct addrinfo **res)
{
return android_getaddrinfoforiface(hostname, servname, hints, NULL, 0, res);
}
int
android_getaddrinfoforiface(const char *hostname, const char *servname,
const struct addrinfo *hints, const char *iface, int mark, struct addrinfo **res)
{
......
const char* cache_mode = getenv("ANDROID_DNS_MODE");
......
if (cache_mode == NULL || strcmp(cache_mode, "local") != 0) {
return android_getaddrinfo_proxy(hostname, servname, hints, res, iface);
}
for (ex = explore; ex->e_af >= 0; ex++) {
*pai = ai0;
if (pai->ai_family != ex->e_af)
continue;
if (!MATCH(pai->ai_socktype, ex->e_socktype,
WILD_SOCKTYPE(ex))) {
continue;
}
if (!MATCH(pai->ai_protocol, ex->e_protocol,
WILD_PROTOCOL(ex))) {
continue;
}
if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
pai->ai_socktype = ex->e_socktype;
if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
pai->ai_protocol = ex->e_protocol;
error = explore_fqdn(pai, hostname, servname,
&cur->ai_next, iface, mark);
while (cur && cur->ai_next)
cur = cur->ai_next;
}
if (sentinel.ai_next)
error = 0;
if (error)
goto free;
if (error == 0) {
if (sentinel.ai_next) {
good:
*res = sentinel.ai_next;
return SUCCESS;
} else
error = EAI_FAIL;
}
free:
bad:
if (sentinel.ai_next)
freeaddrinfo(sentinel.ai_next);
*res = NULL;
return error;
}
static int
explore_fqdn(const struct addrinfo *pai, const char *hostname,
const char *servname, struct addrinfo **res, const char *iface, int mark)
{
struct addrinfo *result;
struct addrinfo *cur;
int error = 0;
static const ns_dtab dtab[] = {
NS_FILES_CB(_files_getaddrinfo, NULL)
{ NSSRC_DNS, _dns_getaddrinfo, NULL },
NS_NIS_CB(_yp_getaddrinfo, NULL)
{ 0, 0, 0 }
};
assert(pai != NULL);
assert(res != NULL);
result = NULL;
if (get_portmatch(pai, servname) != 0)
return 0;
switch (nsdispatch(&result, dtab, NSDB_HOSTS, "getaddrinfo",
default_dns_files, hostname, pai, iface, mark)) {
case NS_TRYAGAIN:
error = EAI_AGAIN;
goto free;
case NS_UNAVAIL:
error = EAI_FAIL;
goto free;
case NS_NOTFOUND:
error = EAI_NODATA;
goto free;
case NS_SUCCESS:
error = 0;
for (cur = result; cur; cur = cur->ai_next) {
GET_PORT(cur, servname);
}
break;
}
*res = result;
return 0;
free:
if (result)
freeaddrinfo(result);
return error;
}
static nss_method
_nsmethod(const char *source, const char *database, const char *method,
const ns_dtab disp_tab[], void **cb_data)
{
int curdisp;
if (disp_tab != NULL) {
for (curdisp = 0; disp_tab[curdisp].src != NULL; curdisp++) {
if (strcasecmp(source, disp_tab[curdisp].src) == 0) {
*cb_data = disp_tab[curdisp].cb_data;
return (disp_tab[curdisp].callback);
}
}
}
*cb_data = NULL;
return (NULL);
}
int
nsdispatch(void *retval, const ns_dtab disp_tab[], const char *database,
const char *method, const ns_src defaults[], ...)
{
va_list ap;
int i, result;
const ns_src *srclist;
int srclistsize;
nss_method cb;
void *cb_data;
assert(database != NULL);
assert(method != NULL);
assert(defaults != NULL);
if (database == NULL || method == NULL || defaults == NULL)
return (NS_UNAVAIL);
srclist = defaults;
srclistsize = 0;
while (srclist[srclistsize].name != NULL)
srclistsize++;
result = 0;
for (i = 0; i < srclistsize; i++) {
cb = _nsmethod(srclist[i].name, database, method,
disp_tab, &cb_data);
result = 0;
if (cb != NULL) {
va_start(ap, defaults);
result = (*cb)(retval, cb_data, ap);
va_end(ap);
if (defaults[0].flags & NS_FORCEALL)
continue;
if (result & srclist[i].flags)
break;
}
}
result &= NS_STATUSMASK;
return (result ? result : NS_NOTFOUND);
}
#define NSSRC_FILES "files"
{ NSSRC_FILES, F, __UNCONST(C) },
static const ns_src default_dns_files[] = {
{ NSSRC_FILES, NS_SUCCESS },
{ NSSRC_DNS, NS_SUCCESS },
{ 0, 0 }
};
#define _PATH_HOSTS "/system/etc/hosts"
static void
_sethtent(FILE **hostf)
{
if (!*hostf)
*hostf = fopen(_PATH_HOSTS, "r" );
else
rewind(*hostf);
}
static int
_files_getaddrinfo(void *rv, void *cb_data, va_list ap)
{
const char *name;
const struct addrinfo *pai;
struct addrinfo sentinel, *cur;
struct addrinfo *p;
FILE *hostf = NULL;
name = va_arg(ap, char *);
pai = va_arg(ap, struct addrinfo *);
memset(&sentinel, 0, sizeof(sentinel));
cur = &sentinel;
_sethtent(&hostf);
while ((p = _gethtent(&hostf, name, pai)) != NULL) {
cur->ai_next = p;
while (cur && cur->ai_next)
cur = cur->ai_next;
}
_endhtent(&hostf);
*((struct addrinfo **)rv) = sentinel.ai_next;
if (sentinel.ai_next == NULL)
return NS_NOTFOUND;
return NS_SUCCESS;
}
static int
_dns_getaddrinfo(void *rv, void *cb_data, va_list ap)
{
struct addrinfo *ai;
querybuf *buf, *buf2;
const char *name;
const struct addrinfo *pai;
struct addrinfo sentinel, *cur;
struct res_target q, q2;
res_state res;
const char* iface;
int mark;
name = va_arg(ap, char *);
pai = va_arg(ap, const struct addrinfo *);
iface = va_arg(ap, char *);
mark = va_arg(ap, int);
memset(&q, 0, sizeof(q));
memset(&q2, 0, sizeof(q2));
memset(&sentinel, 0, sizeof(sentinel));
cur = &sentinel;
buf = malloc(sizeof(*buf));
if (buf == NULL) {
h_errno = NETDB_INTERNAL;
return NS_NOTFOUND;
}
buf2 = malloc(sizeof(*buf2));
if (buf2 == NULL) {
free(buf);
h_errno = NETDB_INTERNAL;
return NS_NOTFOUND;
}
switch (pai->ai_family) {
case AF_UNSPEC:
q.name = name;
q.qclass = C_IN;
q.answer = buf->buf;
q.anslen = sizeof(buf->buf);
int query_ipv6 = 1, query_ipv4 = 1;
if (pai->ai_flags & AI_ADDRCONFIG) {
if (_using_default_dns(iface)) {
query_ipv6 = _have_ipv6();
query_ipv4 = _have_ipv4();
}
}
if (query_ipv6) {
q.qtype = T_AAAA;
if (query_ipv4) {
q.next = &q2;
q2.name = name;
q2.qclass = C_IN;
q2.qtype = T_A;
q2.answer = buf2->buf;
q2.anslen = sizeof(buf2->buf);
}
} else if (query_ipv4) {
q.qtype = T_A;
} else {
free(buf);
free(buf2);
return NS_NOTFOUND;
}
break;
case AF_INET:
q.name = name;
q.qclass = C_IN;
q.qtype = T_A;
q.answer = buf->buf;
q.anslen = sizeof(buf->buf);
break;
case AF_INET6:
q.name = name;
q.qclass = C_IN;
q.qtype = T_AAAA;
q.answer = buf->buf;
q.anslen = sizeof(buf->buf);
break;
default:
free(buf);
free(buf2);
return NS_UNAVAIL;
}
res = __res_get_state();
if (res == NULL) {
free(buf);
free(buf2);
return NS_NOTFOUND;
}
res_setiface(res, iface);
res_setmark(res, mark);
if (res_searchN(name, &q, res) < 0) {
__res_put_state(res);
free(buf);
free(buf2);
return NS_NOTFOUND;
}
ai = getanswer(buf, q.n, q.name, q.qtype, pai);
if (ai) {
cur->ai_next = ai;
while (cur && cur->ai_next)
cur = cur->ai_next;
}
if (q.next) {
ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai);
if (ai)
cur->ai_next = ai;
}
free(buf);
free(buf2);
if (sentinel.ai_next == NULL) {
__res_put_state(res);
switch (h_errno) {
case HOST_NOT_FOUND:
return NS_NOTFOUND;
case TRY_AGAIN:
return NS_TRYAGAIN;
default:
return NS_UNAVAIL;
}
}
_rfc6724_sort(&sentinel);
__res_put_state(res);
*((struct addrinfo **)rv) = sentinel.ai_next;
return NS_SUCCESS;
}
InetAddress.getByName ->
getAllByNameImpl ->
lookupHostByName ->
Libcore.os.getaddrinfo ->
getaddrinfo ->
android_getaddrinfoforiface ->
android_getaddrinfo_proxy ->
connect
fprintf
远程系统进程netd:
new DnsProxyListener ->
dpl->startListener ->
pthread_create ->
SocketListener::threadStart ->
me->runListener ->
select
accept
onDataAvailable ->
dispatchCommand ->
runCommand ->
DnsProxyListener::GetAddrInfoCmd::runCommand ->
new DnsProxyListener::GetAddrInfoHandler
handler->start ->
DnsProxyListener::GetAddrInfoHandler::start ->
DnsProxyListener::GetAddrInfoHandler::threadStart ->
handler->run ->
DnsProxyListener::GetAddrInfoHandler::run ->
android_getaddrinfoforiface ->
explore_fqdn ->
nsdispatch ->
_files_getaddrinfo
_dns_getaddrinfo
sendLenAndData
private void resetNextInetSocketAddress(Proxy proxy) throws UnknownHostException {
socketAddresses = null;
String socketHost;
if (proxy.type() == Proxy.Type.DIRECT) {
socketHost = uri.getHost();
socketPort = getEffectivePort(uri);
} else {
SocketAddress proxyAddress = proxy.address();
if (!(proxyAddress instanceof InetSocketAddress)) {
throw new IllegalArgumentException(
"Proxy.address() is not an " + "InetSocketAddress: " + proxyAddress.getClass());
}
InetSocketAddress proxySocketAddress = (InetSocketAddress) proxyAddress;
socketHost = proxySocketAddress.getHostName();
socketPort = proxySocketAddress.getPort();
}
socketAddresses = dns.getAllByName(socketHost);
nextSocketAddressIndex = 0;
}
InetSocketAddress(String hostname, int port, boolean needResolved) {
if (hostname == null || port < 0 || port > 65535) {
throw new IllegalArgumentException("host=" + hostname + ", port=" + port);
}
InetAddress addr = null;
if (needResolved) {
try {
addr = InetAddress.getByName(hostname);
hostname = null;
} catch (UnknownHostException ignored) {
}
}
this.addr = addr;
this.hostname = hostname;
this.port = port;
}
private void resetNextInetSocketAddress(Proxy proxy) throws IOException {
inetSocketAddresses = new ArrayList<>();
String socketHost;
int socketPort;
if (proxy.type() == Proxy.Type.DIRECT || proxy.type() == Proxy.Type.SOCKS) {
socketHost = address.getUriHost();
socketPort = getEffectivePort(uri);
} else {
SocketAddress proxyAddress = proxy.address();
if (!(proxyAddress instanceof InetSocketAddress)) {
throw new IllegalArgumentException(
"Proxy.address() is not an " + "InetSocketAddress: " + proxyAddress.getClass());
}
InetSocketAddress proxySocketAddress = (InetSocketAddress) proxyAddress;
socketHost = getHostString(proxySocketAddress);
socketPort = proxySocketAddress.getPort();
}
if (socketPort < 1 || socketPort > 65535) {
throw new SocketException("No route to " + socketHost + ":" + socketPort
+ "; port is out of range");
}
for (InetAddress inetAddress : network.resolveInetAddresses(socketHost)) {
inetSocketAddresses.add(new InetSocketAddress(inetAddress, socketPort));
}
nextInetSocketAddressIndex = 0;
}
static String getHostString(InetSocketAddress socketAddress) {
InetAddress address = socketAddress.getAddress();
if (address == null) {
return socketAddress.getHostName();
}
return address.getHostAddress();
}
看雪ID:卓桐
https://bbs.pediy.com/user-670707.htm
推荐文章++++