mobile/android/thirdparty/ch/boye/httpclientandroidlib/conn/ssl/SSLSocketFactory.java

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /*
michael@0 2 * ====================================================================
michael@0 3 * Licensed to the Apache Software Foundation (ASF) under one
michael@0 4 * or more contributor license agreements. See the NOTICE file
michael@0 5 * distributed with this work for additional information
michael@0 6 * regarding copyright ownership. The ASF licenses this file
michael@0 7 * to you under the Apache License, Version 2.0 (the
michael@0 8 * "License"); you may not use this file except in compliance
michael@0 9 * with the License. You may obtain a copy of the License at
michael@0 10 *
michael@0 11 * http://www.apache.org/licenses/LICENSE-2.0
michael@0 12 *
michael@0 13 * Unless required by applicable law or agreed to in writing,
michael@0 14 * software distributed under the License is distributed on an
michael@0 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
michael@0 16 * KIND, either express or implied. See the License for the
michael@0 17 * specific language governing permissions and limitations
michael@0 18 * under the License.
michael@0 19 * ====================================================================
michael@0 20 *
michael@0 21 * This software consists of voluntary contributions made by many
michael@0 22 * individuals on behalf of the Apache Software Foundation. For more
michael@0 23 * information on the Apache Software Foundation, please see
michael@0 24 * <http://www.apache.org/>.
michael@0 25 *
michael@0 26 */
michael@0 27
michael@0 28 package ch.boye.httpclientandroidlib.conn.ssl;
michael@0 29
michael@0 30 import ch.boye.httpclientandroidlib.annotation.ThreadSafe;
michael@0 31
michael@0 32 import ch.boye.httpclientandroidlib.conn.ConnectTimeoutException;
michael@0 33 import ch.boye.httpclientandroidlib.conn.scheme.HostNameResolver;
michael@0 34 import ch.boye.httpclientandroidlib.conn.scheme.LayeredSchemeSocketFactory;
michael@0 35 import ch.boye.httpclientandroidlib.conn.scheme.LayeredSocketFactory;
michael@0 36 import ch.boye.httpclientandroidlib.params.HttpConnectionParams;
michael@0 37 import ch.boye.httpclientandroidlib.params.HttpParams;
michael@0 38
michael@0 39 import javax.net.ssl.KeyManager;
michael@0 40 import javax.net.ssl.KeyManagerFactory;
michael@0 41 import javax.net.ssl.SSLContext;
michael@0 42 import javax.net.ssl.SSLSocket;
michael@0 43 import javax.net.ssl.TrustManager;
michael@0 44 import javax.net.ssl.TrustManagerFactory;
michael@0 45 import javax.net.ssl.X509TrustManager;
michael@0 46
michael@0 47 import java.io.IOException;
michael@0 48 import java.net.InetAddress;
michael@0 49 import java.net.InetSocketAddress;
michael@0 50 import java.net.Socket;
michael@0 51 import java.net.SocketTimeoutException;
michael@0 52 import java.net.UnknownHostException;
michael@0 53 import java.security.KeyManagementException;
michael@0 54 import java.security.KeyStore;
michael@0 55 import java.security.KeyStoreException;
michael@0 56 import java.security.NoSuchAlgorithmException;
michael@0 57 import java.security.SecureRandom;
michael@0 58 import java.security.UnrecoverableKeyException;
michael@0 59
michael@0 60 /**
michael@0 61 * Layered socket factory for TLS/SSL connections.
michael@0 62 * <p>
michael@0 63 * SSLSocketFactory can be used to validate the identity of the HTTPS server against a list of
michael@0 64 * trusted certificates and to authenticate to the HTTPS server using a private key.
michael@0 65 * <p>
michael@0 66 * SSLSocketFactory will enable server authentication when supplied with
michael@0 67 * a {@link KeyStore trust-store} file containing one or several trusted certificates. The client
michael@0 68 * secure socket will reject the connection during the SSL session handshake if the target HTTPS
michael@0 69 * server attempts to authenticate itself with a non-trusted certificate.
michael@0 70 * <p>
michael@0 71 * Use JDK keytool utility to import a trusted certificate and generate a trust-store file:
michael@0 72 * <pre>
michael@0 73 * keytool -import -alias "my server cert" -file server.crt -keystore my.truststore
michael@0 74 * </pre>
michael@0 75 * <p>
michael@0 76 * In special cases the standard trust verification process can be bypassed by using a custom
michael@0 77 * {@link TrustStrategy}. This interface is primarily intended for allowing self-signed
michael@0 78 * certificates to be accepted as trusted without having to add them to the trust-store file.
michael@0 79 * <p>
michael@0 80 * The following parameters can be used to customize the behavior of this
michael@0 81 * class:
michael@0 82 * <ul>
michael@0 83 * <li>{@link ch.boye.httpclientandroidlib.params.CoreConnectionPNames#CONNECTION_TIMEOUT}</li>
michael@0 84 * <li>{@link ch.boye.httpclientandroidlib.params.CoreConnectionPNames#SO_TIMEOUT}</li>
michael@0 85 * <li>{@link ch.boye.httpclientandroidlib.params.CoreConnectionPNames#SO_REUSEADDR}</li>
michael@0 86 * </ul>
michael@0 87 * <p>
michael@0 88 * SSLSocketFactory will enable client authentication when supplied with
michael@0 89 * a {@link KeyStore key-store} file containing a private key/public certificate
michael@0 90 * pair. The client secure socket will use the private key to authenticate
michael@0 91 * itself to the target HTTPS server during the SSL session handshake if
michael@0 92 * requested to do so by the server.
michael@0 93 * The target HTTPS server will in its turn verify the certificate presented
michael@0 94 * by the client in order to establish client's authenticity
michael@0 95 * <p>
michael@0 96 * Use the following sequence of actions to generate a key-store file
michael@0 97 * </p>
michael@0 98 * <ul>
michael@0 99 * <li>
michael@0 100 * <p>
michael@0 101 * Use JDK keytool utility to generate a new key
michael@0 102 * <pre>keytool -genkey -v -alias "my client key" -validity 365 -keystore my.keystore</pre>
michael@0 103 * For simplicity use the same password for the key as that of the key-store
michael@0 104 * </p>
michael@0 105 * </li>
michael@0 106 * <li>
michael@0 107 * <p>
michael@0 108 * Issue a certificate signing request (CSR)
michael@0 109 * <pre>keytool -certreq -alias "my client key" -file mycertreq.csr -keystore my.keystore</pre>
michael@0 110 * </p>
michael@0 111 * </li>
michael@0 112 * <li>
michael@0 113 * <p>
michael@0 114 * Send the certificate request to the trusted Certificate Authority for signature.
michael@0 115 * One may choose to act as her own CA and sign the certificate request using a PKI
michael@0 116 * tool, such as OpenSSL.
michael@0 117 * </p>
michael@0 118 * </li>
michael@0 119 * <li>
michael@0 120 * <p>
michael@0 121 * Import the trusted CA root certificate
michael@0 122 * <pre>keytool -import -alias "my trusted ca" -file caroot.crt -keystore my.keystore</pre>
michael@0 123 * </p>
michael@0 124 * </li>
michael@0 125 * <li>
michael@0 126 * <p>
michael@0 127 * Import the PKCS#7 file containg the complete certificate chain
michael@0 128 * <pre>keytool -import -alias "my client key" -file mycert.p7 -keystore my.keystore</pre>
michael@0 129 * </p>
michael@0 130 * </li>
michael@0 131 * <li>
michael@0 132 * <p>
michael@0 133 * Verify the content the resultant keystore file
michael@0 134 * <pre>keytool -list -v -keystore my.keystore</pre>
michael@0 135 * </p>
michael@0 136 * </li>
michael@0 137 * </ul>
michael@0 138 *
michael@0 139 * @since 4.0
michael@0 140 */
michael@0 141 @SuppressWarnings("deprecation")
michael@0 142 @ThreadSafe
michael@0 143 public class SSLSocketFactory implements LayeredSchemeSocketFactory, LayeredSocketFactory {
michael@0 144
michael@0 145 public static final String TLS = "TLS";
michael@0 146 public static final String SSL = "SSL";
michael@0 147 public static final String SSLV2 = "SSLv2";
michael@0 148
michael@0 149 public static final X509HostnameVerifier ALLOW_ALL_HOSTNAME_VERIFIER
michael@0 150 = new AllowAllHostnameVerifier();
michael@0 151
michael@0 152 public static final X509HostnameVerifier BROWSER_COMPATIBLE_HOSTNAME_VERIFIER
michael@0 153 = new BrowserCompatHostnameVerifier();
michael@0 154
michael@0 155 public static final X509HostnameVerifier STRICT_HOSTNAME_VERIFIER
michael@0 156 = new StrictHostnameVerifier();
michael@0 157
michael@0 158 /**
michael@0 159 * Gets the default factory, which uses the default JVM settings for secure
michael@0 160 * connections.
michael@0 161 *
michael@0 162 * @return the default factory
michael@0 163 */
michael@0 164 public static SSLSocketFactory getSocketFactory() {
michael@0 165 return new SSLSocketFactory();
michael@0 166 }
michael@0 167
michael@0 168 private final javax.net.ssl.SSLSocketFactory socketfactory;
michael@0 169 private final HostNameResolver nameResolver;
michael@0 170 // TODO: make final
michael@0 171 private volatile X509HostnameVerifier hostnameVerifier;
michael@0 172
michael@0 173 private static SSLContext createSSLContext(
michael@0 174 String algorithm,
michael@0 175 final KeyStore keystore,
michael@0 176 final String keystorePassword,
michael@0 177 final KeyStore truststore,
michael@0 178 final SecureRandom random,
michael@0 179 final TrustStrategy trustStrategy)
michael@0 180 throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException, KeyManagementException {
michael@0 181 if (algorithm == null) {
michael@0 182 algorithm = TLS;
michael@0 183 }
michael@0 184 KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(
michael@0 185 KeyManagerFactory.getDefaultAlgorithm());
michael@0 186 kmfactory.init(keystore, keystorePassword != null ? keystorePassword.toCharArray(): null);
michael@0 187 KeyManager[] keymanagers = kmfactory.getKeyManagers();
michael@0 188 TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(
michael@0 189 TrustManagerFactory.getDefaultAlgorithm());
michael@0 190 tmfactory.init(truststore);
michael@0 191 TrustManager[] trustmanagers = tmfactory.getTrustManagers();
michael@0 192 if (trustmanagers != null && trustStrategy != null) {
michael@0 193 for (int i = 0; i < trustmanagers.length; i++) {
michael@0 194 TrustManager tm = trustmanagers[i];
michael@0 195 if (tm instanceof X509TrustManager) {
michael@0 196 trustmanagers[i] = new TrustManagerDecorator(
michael@0 197 (X509TrustManager) tm, trustStrategy);
michael@0 198 }
michael@0 199 }
michael@0 200 }
michael@0 201
michael@0 202 SSLContext sslcontext = SSLContext.getInstance(algorithm);
michael@0 203 sslcontext.init(keymanagers, trustmanagers, random);
michael@0 204 return sslcontext;
michael@0 205 }
michael@0 206
michael@0 207 private static SSLContext createDefaultSSLContext() {
michael@0 208 try {
michael@0 209 return createSSLContext(TLS, null, null, null, null, null);
michael@0 210 } catch (Exception ex) {
michael@0 211 throw new IllegalStateException("Failure initializing default SSL context", ex);
michael@0 212 }
michael@0 213 }
michael@0 214
michael@0 215 /**
michael@0 216 * @deprecated Use {@link #SSLSocketFactory(String, KeyStore, String, KeyStore, SecureRandom, X509HostnameVerifier)}
michael@0 217 */
michael@0 218 @Deprecated
michael@0 219 public SSLSocketFactory(
michael@0 220 final String algorithm,
michael@0 221 final KeyStore keystore,
michael@0 222 final String keystorePassword,
michael@0 223 final KeyStore truststore,
michael@0 224 final SecureRandom random,
michael@0 225 final HostNameResolver nameResolver)
michael@0 226 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
michael@0 227 this(createSSLContext(
michael@0 228 algorithm, keystore, keystorePassword, truststore, random, null),
michael@0 229 nameResolver);
michael@0 230 }
michael@0 231
michael@0 232 /**
michael@0 233 * @since 4.1
michael@0 234 */
michael@0 235 public SSLSocketFactory(
michael@0 236 String algorithm,
michael@0 237 final KeyStore keystore,
michael@0 238 final String keystorePassword,
michael@0 239 final KeyStore truststore,
michael@0 240 final SecureRandom random,
michael@0 241 final X509HostnameVerifier hostnameVerifier)
michael@0 242 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
michael@0 243 this(createSSLContext(
michael@0 244 algorithm, keystore, keystorePassword, truststore, random, null),
michael@0 245 hostnameVerifier);
michael@0 246 }
michael@0 247
michael@0 248 /**
michael@0 249 * @since 4.1
michael@0 250 */
michael@0 251 public SSLSocketFactory(
michael@0 252 String algorithm,
michael@0 253 final KeyStore keystore,
michael@0 254 final String keystorePassword,
michael@0 255 final KeyStore truststore,
michael@0 256 final SecureRandom random,
michael@0 257 final TrustStrategy trustStrategy,
michael@0 258 final X509HostnameVerifier hostnameVerifier)
michael@0 259 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
michael@0 260 this(createSSLContext(
michael@0 261 algorithm, keystore, keystorePassword, truststore, random, trustStrategy),
michael@0 262 hostnameVerifier);
michael@0 263 }
michael@0 264
michael@0 265 public SSLSocketFactory(
michael@0 266 final KeyStore keystore,
michael@0 267 final String keystorePassword,
michael@0 268 final KeyStore truststore)
michael@0 269 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
michael@0 270 this(TLS, keystore, keystorePassword, truststore, null, null, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
michael@0 271 }
michael@0 272
michael@0 273 public SSLSocketFactory(
michael@0 274 final KeyStore keystore,
michael@0 275 final String keystorePassword)
michael@0 276 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException{
michael@0 277 this(TLS, keystore, keystorePassword, null, null, null, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
michael@0 278 }
michael@0 279
michael@0 280 public SSLSocketFactory(
michael@0 281 final KeyStore truststore)
michael@0 282 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
michael@0 283 this(TLS, null, null, truststore, null, null, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
michael@0 284 }
michael@0 285
michael@0 286 /**
michael@0 287 * @since 4.1
michael@0 288 */
michael@0 289 public SSLSocketFactory(
michael@0 290 final TrustStrategy trustStrategy,
michael@0 291 final X509HostnameVerifier hostnameVerifier)
michael@0 292 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
michael@0 293 this(TLS, null, null, null, null, trustStrategy, hostnameVerifier);
michael@0 294 }
michael@0 295
michael@0 296 /**
michael@0 297 * @since 4.1
michael@0 298 */
michael@0 299 public SSLSocketFactory(
michael@0 300 final TrustStrategy trustStrategy)
michael@0 301 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
michael@0 302 this(TLS, null, null, null, null, trustStrategy, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
michael@0 303 }
michael@0 304
michael@0 305 public SSLSocketFactory(final SSLContext sslContext) {
michael@0 306 this(sslContext, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
michael@0 307 }
michael@0 308
michael@0 309 /**
michael@0 310 * @deprecated Use {@link #SSLSocketFactory(SSLContext)}
michael@0 311 */
michael@0 312 @Deprecated
michael@0 313 public SSLSocketFactory(
michael@0 314 final SSLContext sslContext, final HostNameResolver nameResolver) {
michael@0 315 super();
michael@0 316 this.socketfactory = sslContext.getSocketFactory();
michael@0 317 this.hostnameVerifier = BROWSER_COMPATIBLE_HOSTNAME_VERIFIER;
michael@0 318 this.nameResolver = nameResolver;
michael@0 319 }
michael@0 320
michael@0 321 /**
michael@0 322 * @since 4.1
michael@0 323 */
michael@0 324 public SSLSocketFactory(
michael@0 325 final SSLContext sslContext, final X509HostnameVerifier hostnameVerifier) {
michael@0 326 super();
michael@0 327 this.socketfactory = sslContext.getSocketFactory();
michael@0 328 this.hostnameVerifier = hostnameVerifier;
michael@0 329 this.nameResolver = null;
michael@0 330 }
michael@0 331
michael@0 332 private SSLSocketFactory() {
michael@0 333 this(createDefaultSSLContext());
michael@0 334 }
michael@0 335
michael@0 336 /**
michael@0 337 * @param params Optional parameters. Parameters passed to this method will have no effect.
michael@0 338 * This method will create a unconnected instance of {@link Socket} class.
michael@0 339 * @since 4.1
michael@0 340 */
michael@0 341 public Socket createSocket(final HttpParams params) throws IOException {
michael@0 342 return this.socketfactory.createSocket();
michael@0 343 }
michael@0 344
michael@0 345 @Deprecated
michael@0 346 public Socket createSocket() throws IOException {
michael@0 347 return this.socketfactory.createSocket();
michael@0 348 }
michael@0 349
michael@0 350 /**
michael@0 351 * @since 4.1
michael@0 352 */
michael@0 353 public Socket connectSocket(
michael@0 354 final Socket socket,
michael@0 355 final InetSocketAddress remoteAddress,
michael@0 356 final InetSocketAddress localAddress,
michael@0 357 final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
michael@0 358 if (remoteAddress == null) {
michael@0 359 throw new IllegalArgumentException("Remote address may not be null");
michael@0 360 }
michael@0 361 if (params == null) {
michael@0 362 throw new IllegalArgumentException("HTTP parameters may not be null");
michael@0 363 }
michael@0 364 Socket sock = socket != null ? socket : new Socket();
michael@0 365 if (localAddress != null) {
michael@0 366 sock.setReuseAddress(HttpConnectionParams.getSoReuseaddr(params));
michael@0 367 sock.bind(localAddress);
michael@0 368 }
michael@0 369
michael@0 370 int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
michael@0 371 int soTimeout = HttpConnectionParams.getSoTimeout(params);
michael@0 372
michael@0 373 try {
michael@0 374 sock.setSoTimeout(soTimeout);
michael@0 375 sock.connect(remoteAddress, connTimeout);
michael@0 376 } catch (SocketTimeoutException ex) {
michael@0 377 throw new ConnectTimeoutException("Connect to " + remoteAddress + " timed out");
michael@0 378 }
michael@0 379
michael@0 380 // HttpInetSocketAddress#toString() returns original hostname value of the remote address
michael@0 381 String hostname = remoteAddress.toString();
michael@0 382 int port = remoteAddress.getPort();
michael@0 383 String s = ":" + port;
michael@0 384 if (hostname.endsWith(s)) {
michael@0 385 hostname = hostname.substring(0, hostname.length() - s.length());
michael@0 386 }
michael@0 387
michael@0 388 SSLSocket sslsock;
michael@0 389 // Setup SSL layering if necessary
michael@0 390 if (sock instanceof SSLSocket) {
michael@0 391 sslsock = (SSLSocket) sock;
michael@0 392 } else {
michael@0 393 sslsock = (SSLSocket) this.socketfactory.createSocket(sock, hostname, port, true);
michael@0 394 }
michael@0 395 if (this.hostnameVerifier != null) {
michael@0 396 try {
michael@0 397 this.hostnameVerifier.verify(hostname, sslsock);
michael@0 398 // verifyHostName() didn't blowup - good!
michael@0 399 } catch (IOException iox) {
michael@0 400 // close the socket before re-throwing the exception
michael@0 401 try { sslsock.close(); } catch (Exception x) { /*ignore*/ }
michael@0 402 throw iox;
michael@0 403 }
michael@0 404 }
michael@0 405 return sslsock;
michael@0 406 }
michael@0 407
michael@0 408
michael@0 409 /**
michael@0 410 * Checks whether a socket connection is secure.
michael@0 411 * This factory creates TLS/SSL socket connections
michael@0 412 * which, by default, are considered secure.
michael@0 413 * <br/>
michael@0 414 * Derived classes may override this method to perform
michael@0 415 * runtime checks, for example based on the cypher suite.
michael@0 416 *
michael@0 417 * @param sock the connected socket
michael@0 418 *
michael@0 419 * @return <code>true</code>
michael@0 420 *
michael@0 421 * @throws IllegalArgumentException if the argument is invalid
michael@0 422 */
michael@0 423 public boolean isSecure(final Socket sock) throws IllegalArgumentException {
michael@0 424 if (sock == null) {
michael@0 425 throw new IllegalArgumentException("Socket may not be null");
michael@0 426 }
michael@0 427 // This instanceof check is in line with createSocket() above.
michael@0 428 if (!(sock instanceof SSLSocket)) {
michael@0 429 throw new IllegalArgumentException("Socket not created by this factory");
michael@0 430 }
michael@0 431 // This check is performed last since it calls the argument object.
michael@0 432 if (sock.isClosed()) {
michael@0 433 throw new IllegalArgumentException("Socket is closed");
michael@0 434 }
michael@0 435 return true;
michael@0 436 }
michael@0 437
michael@0 438 /**
michael@0 439 * @since 4.1
michael@0 440 */
michael@0 441 public Socket createLayeredSocket(
michael@0 442 final Socket socket,
michael@0 443 final String host,
michael@0 444 final int port,
michael@0 445 final boolean autoClose) throws IOException, UnknownHostException {
michael@0 446 SSLSocket sslSocket = (SSLSocket) this.socketfactory.createSocket(
michael@0 447 socket,
michael@0 448 host,
michael@0 449 port,
michael@0 450 autoClose
michael@0 451 );
michael@0 452 if (this.hostnameVerifier != null) {
michael@0 453 this.hostnameVerifier.verify(host, sslSocket);
michael@0 454 }
michael@0 455 // verifyHostName() didn't blowup - good!
michael@0 456 return sslSocket;
michael@0 457 }
michael@0 458
michael@0 459 @Deprecated
michael@0 460 public void setHostnameVerifier(X509HostnameVerifier hostnameVerifier) {
michael@0 461 if ( hostnameVerifier == null ) {
michael@0 462 throw new IllegalArgumentException("Hostname verifier may not be null");
michael@0 463 }
michael@0 464 this.hostnameVerifier = hostnameVerifier;
michael@0 465 }
michael@0 466
michael@0 467 public X509HostnameVerifier getHostnameVerifier() {
michael@0 468 return this.hostnameVerifier;
michael@0 469 }
michael@0 470
michael@0 471 /**
michael@0 472 * @deprecated Use {@link #connectSocket(Socket, InetSocketAddress, InetSocketAddress, HttpParams)}
michael@0 473 */
michael@0 474 @Deprecated
michael@0 475 public Socket connectSocket(
michael@0 476 final Socket socket,
michael@0 477 final String host, int port,
michael@0 478 final InetAddress localAddress, int localPort,
michael@0 479 final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
michael@0 480 InetSocketAddress local = null;
michael@0 481 if (localAddress != null || localPort > 0) {
michael@0 482 // we need to bind explicitly
michael@0 483 if (localPort < 0) {
michael@0 484 localPort = 0; // indicates "any"
michael@0 485 }
michael@0 486 local = new InetSocketAddress(localAddress, localPort);
michael@0 487 }
michael@0 488 InetAddress remoteAddress;
michael@0 489 if (this.nameResolver != null) {
michael@0 490 remoteAddress = this.nameResolver.resolve(host);
michael@0 491 } else {
michael@0 492 remoteAddress = InetAddress.getByName(host);
michael@0 493 }
michael@0 494 InetSocketAddress remote = new InetSocketAddress(remoteAddress, port);
michael@0 495 return connectSocket(socket, remote, local, params);
michael@0 496 }
michael@0 497
michael@0 498 /**
michael@0 499 * @deprecated Use {@link #createLayeredSocket(Socket, String, int, boolean)}
michael@0 500 */
michael@0 501 @Deprecated
michael@0 502 public Socket createSocket(
michael@0 503 final Socket socket,
michael@0 504 final String host, int port,
michael@0 505 boolean autoClose) throws IOException, UnknownHostException {
michael@0 506 return createLayeredSocket(socket, host, port, autoClose);
michael@0 507 }
michael@0 508
michael@0 509 }

mercurial