1 /*
   2  * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.security.ssl;
  27 
  28 import java.io.EOFException;
  29 import java.io.IOException;
  30 import java.io.InputStream;
  31 import java.io.InterruptedIOException;
  32 import java.io.OutputStream;
  33 import java.net.InetAddress;
  34 import java.net.InetSocketAddress;
  35 import java.net.Socket;
  36 import java.net.SocketAddress;
  37 import java.net.SocketException;
  38 import java.net.UnknownHostException;
  39 import java.nio.ByteBuffer;
  40 import java.util.List;
  41 import java.util.concurrent.locks.ReentrantLock;
  42 import java.util.function.BiFunction;
  43 import javax.net.ssl.HandshakeCompletedListener;
  44 import javax.net.ssl.SSLException;
  45 import javax.net.ssl.SSLHandshakeException;
  46 import javax.net.ssl.SSLParameters;
  47 import javax.net.ssl.SSLProtocolException;
  48 import javax.net.ssl.SSLServerSocket;
  49 import javax.net.ssl.SSLSession;
  50 import javax.net.ssl.SSLSocket;
  51 import jdk.internal.access.JavaNetInetAddressAccess;
  52 import jdk.internal.access.SharedSecrets;
  53 
  54 /**
  55  * Implementation of an SSL socket.
  56  * <P>
  57  * This is a normal connection type socket, implementing SSL over some lower
  58  * level socket, such as TCP.  Because it is layered over some lower level
  59  * socket, it MUST override all default socket methods.
  60  * <P>
  61  * This API offers a non-traditional option for establishing SSL
  62  * connections.  You may first establish the connection directly, then pass
  63  * that connection to the SSL socket constructor with a flag saying which
  64  * role should be taken in the handshake protocol.  (The two ends of the
  65  * connection must not choose the same role!)  This allows setup of SSL
  66  * proxying or tunneling, and also allows the kind of "role reversal"
  67  * that is required for most FTP data transfers.
  68  *
  69  * @see javax.net.ssl.SSLSocket
  70  * @see SSLServerSocket
  71  *
  72  * @author David Brownell
  73  */
  74 public final class SSLSocketImpl
  75         extends BaseSSLSocketImpl implements SSLTransport {
  76 
  77     final SSLContextImpl            sslContext;
  78     final TransportContext          conContext;
  79 
  80     private final AppInputStream    appInput = new AppInputStream();
  81     private final AppOutputStream   appOutput = new AppOutputStream();
  82 
  83     private String                  peerHost;
  84     private boolean                 autoClose;
  85     private boolean                 isConnected = false;
  86     private volatile boolean        tlsIsClosed = false;
  87 
  88     private final ReentrantLock     socketLock = new ReentrantLock();
  89     private final ReentrantLock     handshakeLock = new ReentrantLock();
  90 
  91     /*
  92      * Is the local name service trustworthy?
  93      *
  94      * If the local name service is not trustworthy, reverse host name
  95      * resolution should not be performed for endpoint identification.
  96      */
  97     private static final boolean trustNameService =
  98             Utilities.getBooleanProperty("jdk.tls.trustNameService", false);
  99 
 100     /**
 101      * Package-private constructor used to instantiate an unconnected
 102      * socket.
 103      *
 104      * This instance is meant to set handshake state to use "client mode".
 105      */
 106     SSLSocketImpl(SSLContextImpl sslContext) {
 107         super();
 108         this.sslContext = sslContext;
 109         HandshakeHash handshakeHash = new HandshakeHash();
 110         this.conContext = new TransportContext(sslContext, this,
 111                 new SSLSocketInputRecord(handshakeHash),
 112                 new SSLSocketOutputRecord(handshakeHash), true);
 113     }
 114 
 115     /**
 116      * Package-private constructor used to instantiate a server socket.
 117      *
 118      * This instance is meant to set handshake state to use "server mode".
 119      */
 120     SSLSocketImpl(SSLContextImpl sslContext, SSLConfiguration sslConfig) {
 121         super();
 122         this.sslContext = sslContext;
 123         HandshakeHash handshakeHash = new HandshakeHash();
 124         this.conContext = new TransportContext(sslContext, this, sslConfig,
 125                 new SSLSocketInputRecord(handshakeHash),
 126                 new SSLSocketOutputRecord(handshakeHash));
 127     }
 128 
 129     /**
 130      * Constructs an SSL connection to a named host at a specified
 131      * port, using the authentication context provided.
 132      *
 133      * This endpoint acts as the client, and may rejoin an existing SSL session
 134      * if appropriate.
 135      */
 136     SSLSocketImpl(SSLContextImpl sslContext, String peerHost,
 137             int peerPort) throws IOException, UnknownHostException {
 138         super();
 139         this.sslContext = sslContext;
 140         HandshakeHash handshakeHash = new HandshakeHash();
 141         this.conContext = new TransportContext(sslContext, this,
 142                 new SSLSocketInputRecord(handshakeHash),
 143                 new SSLSocketOutputRecord(handshakeHash), true);
 144         this.peerHost = peerHost;
 145         SocketAddress socketAddress =
 146                peerHost != null ? new InetSocketAddress(peerHost, peerPort) :
 147                new InetSocketAddress(InetAddress.getByName(null), peerPort);
 148         connect(socketAddress, 0);
 149     }
 150 
 151     /**
 152      * Constructs an SSL connection to a server at a specified
 153      * address, and TCP port, using the authentication context
 154      * provided.
 155      *
 156      * This endpoint acts as the client, and may rejoin an existing SSL
 157      * session if appropriate.
 158      */
 159     SSLSocketImpl(SSLContextImpl sslContext,
 160             InetAddress address, int peerPort) throws IOException {
 161         super();
 162         this.sslContext = sslContext;
 163         HandshakeHash handshakeHash = new HandshakeHash();
 164         this.conContext = new TransportContext(sslContext, this,
 165                 new SSLSocketInputRecord(handshakeHash),
 166                 new SSLSocketOutputRecord(handshakeHash), true);
 167 
 168         SocketAddress socketAddress = new InetSocketAddress(address, peerPort);
 169         connect(socketAddress, 0);
 170     }
 171 
 172     /**
 173      * Constructs an SSL connection to a named host at a specified
 174      * port, using the authentication context provided.
 175      *
 176      * This endpoint acts as the client, and may rejoin an existing SSL
 177      * session if appropriate.
 178      */
 179     SSLSocketImpl(SSLContextImpl sslContext,
 180             String peerHost, int peerPort, InetAddress localAddr,
 181             int localPort) throws IOException, UnknownHostException {
 182         super();
 183         this.sslContext = sslContext;
 184         HandshakeHash handshakeHash = new HandshakeHash();
 185         this.conContext = new TransportContext(sslContext, this,
 186                 new SSLSocketInputRecord(handshakeHash),
 187                 new SSLSocketOutputRecord(handshakeHash), true);
 188         this.peerHost = peerHost;
 189 
 190         bind(new InetSocketAddress(localAddr, localPort));
 191         SocketAddress socketAddress =
 192                peerHost != null ? new InetSocketAddress(peerHost, peerPort) :
 193                new InetSocketAddress(InetAddress.getByName(null), peerPort);
 194         connect(socketAddress, 0);
 195     }
 196 
 197     /**
 198      * Constructs an SSL connection to a server at a specified
 199      * address, and TCP port, using the authentication context
 200      * provided.
 201      *
 202      * This endpoint acts as the client, and may rejoin an existing SSL
 203      * session if appropriate.
 204      */
 205     SSLSocketImpl(SSLContextImpl sslContext,
 206             InetAddress peerAddr, int peerPort,
 207             InetAddress localAddr, int localPort) throws IOException {
 208         super();
 209         this.sslContext = sslContext;
 210         HandshakeHash handshakeHash = new HandshakeHash();
 211         this.conContext = new TransportContext(sslContext, this,
 212                 new SSLSocketInputRecord(handshakeHash),
 213                 new SSLSocketOutputRecord(handshakeHash), true);
 214 
 215         bind(new InetSocketAddress(localAddr, localPort));
 216         SocketAddress socketAddress = new InetSocketAddress(peerAddr, peerPort);
 217         connect(socketAddress, 0);
 218     }
 219 
 220     /**
 221      * Creates a server mode {@link Socket} layered over an
 222      * existing connected socket, and is able to read data which has
 223      * already been consumed/removed from the {@link Socket}'s
 224      * underlying {@link InputStream}.
 225      */
 226     SSLSocketImpl(SSLContextImpl sslContext, Socket sock,
 227             InputStream consumed, boolean autoClose) throws IOException {
 228         super(sock, consumed);
 229         // We always layer over a connected socket
 230         if (!sock.isConnected()) {
 231             throw new SocketException("Underlying socket is not connected");
 232         }
 233 
 234         this.sslContext = sslContext;
 235         HandshakeHash handshakeHash = new HandshakeHash();
 236         this.conContext = new TransportContext(sslContext, this,
 237                 new SSLSocketInputRecord(handshakeHash),
 238                 new SSLSocketOutputRecord(handshakeHash), false);
 239         this.autoClose = autoClose;
 240         doneConnect();
 241     }
 242 
 243     /**
 244      * Layer SSL traffic over an existing connection, rather than
 245      * creating a new connection.
 246      *
 247      * The existing connection may be used only for SSL traffic (using this
 248      * SSLSocket) until the SSLSocket.close() call returns. However, if a
 249      * protocol error is detected, that existing connection is automatically
 250      * closed.
 251      * <p>
 252      * This particular constructor always uses the socket in the
 253      * role of an SSL client. It may be useful in cases which start
 254      * using SSL after some initial data transfers, for example in some
 255      * SSL tunneling applications or as part of some kinds of application
 256      * protocols which negotiate use of a SSL based security.
 257      */
 258     SSLSocketImpl(SSLContextImpl sslContext, Socket sock,
 259             String peerHost, int port, boolean autoClose) throws IOException {
 260         super(sock);
 261         // We always layer over a connected socket
 262         if (!sock.isConnected()) {
 263             throw new SocketException("Underlying socket is not connected");
 264         }
 265 
 266         this.sslContext = sslContext;
 267         HandshakeHash handshakeHash = new HandshakeHash();
 268         this.conContext = new TransportContext(sslContext, this,
 269                 new SSLSocketInputRecord(handshakeHash),
 270                 new SSLSocketOutputRecord(handshakeHash), true);
 271         this.peerHost = peerHost;
 272         this.autoClose = autoClose;
 273         doneConnect();
 274     }
 275 
 276     @Override
 277     public void connect(SocketAddress endpoint,
 278             int timeout) throws IOException {
 279 
 280         if (isLayered()) {
 281             throw new SocketException("Already connected");
 282         }
 283 
 284         if (!(endpoint instanceof InetSocketAddress)) {
 285             throw new SocketException(
 286                     "Cannot handle non-Inet socket addresses.");
 287         }
 288 
 289         super.connect(endpoint, timeout);
 290         doneConnect();
 291     }
 292 
 293     @Override
 294     public String[] getSupportedCipherSuites() {
 295         return CipherSuite.namesOf(sslContext.getSupportedCipherSuites());
 296     }
 297 
 298     @Override
 299     public String[] getEnabledCipherSuites() {
 300         socketLock.lock();
 301         try {
 302             return CipherSuite.namesOf(
 303                     conContext.sslConfig.enabledCipherSuites);
 304         } finally {
 305             socketLock.unlock();
 306         }
 307     }
 308 
 309     @Override
 310     public void setEnabledCipherSuites(String[] suites) {
 311         socketLock.lock();
 312         try {
 313             conContext.sslConfig.enabledCipherSuites =
 314                     CipherSuite.validValuesOf(suites);
 315         } finally {
 316             socketLock.unlock();
 317         }
 318     }
 319 
 320     @Override
 321     public String[] getSupportedProtocols() {
 322         return ProtocolVersion.toStringArray(
 323                 sslContext.getSupportedProtocolVersions());
 324     }
 325 
 326     @Override
 327     public String[] getEnabledProtocols() {
 328         socketLock.lock();
 329         try {
 330             return ProtocolVersion.toStringArray(
 331                     conContext.sslConfig.enabledProtocols);
 332         } finally {
 333             socketLock.unlock();
 334         }
 335     }
 336 
 337     @Override
 338     public void setEnabledProtocols(String[] protocols) {
 339         if (protocols == null) {
 340             throw new IllegalArgumentException("Protocols cannot be null");
 341         }
 342 
 343         socketLock.lock();
 344         try {
 345             conContext.sslConfig.enabledProtocols =
 346                     ProtocolVersion.namesOf(protocols);
 347         } finally {
 348             socketLock.unlock();
 349         }
 350     }
 351 
 352     @Override
 353     public SSLSession getSession() {
 354         try {
 355             // start handshaking, if failed, the connection will be closed.
 356             ensureNegotiated();
 357         } catch (IOException ioe) {
 358             if (SSLLogger.isOn && SSLLogger.isOn("handshake")) {
 359                 SSLLogger.severe("handshake failed", ioe);
 360             }
 361 
 362             return SSLSessionImpl.nullSession;
 363         }
 364 
 365         return conContext.conSession;
 366     }
 367 
 368     @Override
 369     public SSLSession getHandshakeSession() {
 370         socketLock.lock();
 371         try {
 372             return conContext.handshakeContext == null ?
 373                     null : conContext.handshakeContext.handshakeSession;
 374         } finally {
 375             socketLock.unlock();
 376         }
 377     }
 378 
 379     @Override
 380     public void addHandshakeCompletedListener(
 381             HandshakeCompletedListener listener) {
 382         if (listener == null) {
 383             throw new IllegalArgumentException("listener is null");
 384         }
 385 
 386         socketLock.lock();
 387         try {
 388             conContext.sslConfig.addHandshakeCompletedListener(listener);
 389         } finally {
 390             socketLock.unlock();
 391         }
 392     }
 393 
 394     @Override
 395     public void removeHandshakeCompletedListener(
 396             HandshakeCompletedListener listener) {
 397         if (listener == null) {
 398             throw new IllegalArgumentException("listener is null");
 399         }
 400 
 401         socketLock.lock();
 402         try {
 403             conContext.sslConfig.removeHandshakeCompletedListener(listener);
 404         } finally {
 405             socketLock.unlock();
 406         }
 407     }
 408 
 409     @Override
 410     public void startHandshake() throws IOException {
 411         if (!isConnected) {
 412             throw new SocketException("Socket is not connected");
 413         }
 414 
 415         if (conContext.isBroken || conContext.isInboundClosed() ||
 416                 conContext.isOutboundClosed()) {
 417             throw new SocketException("Socket has been closed or broken");
 418         }
 419 
 420         handshakeLock.lock();
 421         try {
 422             // double check the context status
 423             if (conContext.isBroken || conContext.isInboundClosed() ||
 424                     conContext.isOutboundClosed()) {
 425                 throw new SocketException("Socket has been closed or broken");
 426             }
 427 
 428             try {
 429                 conContext.kickstart();
 430 
 431                 // All initial handshaking goes through this operation until we
 432                 // have a valid SSL connection.
 433                 //
 434                 // Handle handshake messages only, need no application data.
 435                 if (!conContext.isNegotiated) {
 436                     readHandshakeRecord();
 437                 }
 438             } catch (IOException ioe) {
 439                 throw conContext.fatal(Alert.HANDSHAKE_FAILURE,
 440                     "Couldn't kickstart handshaking", ioe);
 441             } catch (Exception oe) {    // including RuntimeException
 442                 handleException(oe);
 443             }
 444         } finally {
 445             handshakeLock.unlock();
 446         }
 447     }
 448 
 449     @Override
 450     public void setUseClientMode(boolean mode) {
 451         socketLock.lock();
 452         try {
 453             conContext.setUseClientMode(mode);
 454         } finally {
 455             socketLock.unlock();
 456         }
 457     }
 458 
 459     @Override
 460     public boolean getUseClientMode() {
 461         socketLock.lock();
 462         try {
 463             return conContext.sslConfig.isClientMode;
 464         } finally {
 465             socketLock.unlock();
 466         }
 467     }
 468 
 469     @Override
 470     public void setNeedClientAuth(boolean need) {
 471         socketLock.lock();
 472         try {
 473             conContext.sslConfig.clientAuthType =
 474                     (need ? ClientAuthType.CLIENT_AUTH_REQUIRED :
 475                             ClientAuthType.CLIENT_AUTH_NONE);
 476         } finally {
 477             socketLock.unlock();
 478         }
 479     }
 480 
 481     @Override
 482     public boolean getNeedClientAuth() {
 483         socketLock.lock();
 484         try {
 485             return (conContext.sslConfig.clientAuthType ==
 486                         ClientAuthType.CLIENT_AUTH_REQUIRED);
 487         } finally {
 488             socketLock.unlock();
 489         }
 490     }
 491 
 492     @Override
 493     public void setWantClientAuth(boolean want) {
 494         socketLock.lock();
 495         try {
 496             conContext.sslConfig.clientAuthType =
 497                     (want ? ClientAuthType.CLIENT_AUTH_REQUESTED :
 498                             ClientAuthType.CLIENT_AUTH_NONE);
 499         } finally {
 500             socketLock.unlock();
 501         }
 502     }
 503 
 504     @Override
 505     public boolean getWantClientAuth() {
 506         socketLock.lock();
 507         try {
 508             return (conContext.sslConfig.clientAuthType ==
 509                         ClientAuthType.CLIENT_AUTH_REQUESTED);
 510         } finally {
 511             socketLock.unlock();
 512         }
 513     }
 514 
 515     @Override
 516     public void setEnableSessionCreation(boolean flag) {
 517         socketLock.lock();
 518         try {
 519             conContext.sslConfig.enableSessionCreation = flag;
 520         } finally {
 521             socketLock.unlock();
 522         }
 523     }
 524 
 525     @Override
 526     public boolean getEnableSessionCreation() {
 527         socketLock.lock();
 528         try {
 529             return conContext.sslConfig.enableSessionCreation;
 530         } finally {
 531             socketLock.unlock();
 532         }
 533     }
 534 
 535     @Override
 536     public boolean isClosed() {
 537         return tlsIsClosed;
 538     }
 539 
 540     // Please don't synchronized this method.  Otherwise, the read and close
 541     // locks may be deadlocked.
 542     @Override
 543     public void close() throws IOException {
 544         if (tlsIsClosed) {
 545             return;
 546         }
 547 
 548         if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
 549             SSLLogger.fine("duplex close of SSLSocket");
 550         }
 551 
 552         try {
 553             // shutdown output bound, which may have been closed previously.
 554             if (!isOutputShutdown()) {
 555                 duplexCloseOutput();
 556             }
 557 
 558             // shutdown input bound, which may have been closed previously.
 559             if (!isInputShutdown()) {
 560                 duplexCloseInput();
 561             }
 562 
 563             if (!isClosed()) {
 564                 // close the connection directly
 565                 closeSocket(false);
 566             }
 567         } catch (IOException ioe) {
 568             // ignore the exception
 569             if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
 570                 SSLLogger.warning("SSLSocket duplex close failed", ioe);
 571             }
 572         } finally {
 573             tlsIsClosed = true;
 574         }
 575     }
 576 
 577     /**
 578      * Duplex close, start from closing outbound.
 579      *
 580      * For TLS 1.2 [RFC 5246], unless some other fatal alert has been
 581      * transmitted, each party is required to send a close_notify alert
 582      * before closing the write side of the connection.  The other party
 583      * MUST respond with a close_notify alert of its own and close down
 584      * the connection immediately, discarding any pending writes.  It is
 585      * not required for the initiator of the close to wait for the responding
 586      * close_notify alert before closing the read side of the connection.
 587      *
 588      * For TLS 1.3, Each party MUST send a close_notify alert before
 589      * closing its write side of the connection, unless it has already sent
 590      * some error alert.  This does not have any effect on its read side of
 591      * the connection.  Both parties need not wait to receive a close_notify
 592      * alert before closing their read side of the connection, though doing
 593      * so would introduce the possibility of truncation.
 594      *
 595      * In order to support user initiated duplex-close for TLS 1.3 connections,
 596      * the user_canceled alert is used together with the close_notify alert.
 597      */
 598     private void duplexCloseOutput() throws IOException {
 599         boolean useUserCanceled = false;
 600         boolean hasCloseReceipt = false;
 601         if (conContext.isNegotiated) {
 602             if (!conContext.protocolVersion.useTLS13PlusSpec()) {
 603                 hasCloseReceipt = true;
 604             } else {
 605                 // Use a user_canceled alert for TLS 1.3 duplex close.
 606                 useUserCanceled = true;
 607             }
 608         } else if (conContext.handshakeContext != null) {   // initial handshake
 609             // Use user_canceled alert regardless the protocol versions.
 610             useUserCanceled = true;
 611 
 612             // The protocol version may have been negotiated.
 613             ProtocolVersion pv = conContext.handshakeContext.negotiatedProtocol;
 614             if (pv == null || (!pv.useTLS13PlusSpec())) {
 615                 hasCloseReceipt = true;
 616             }
 617         }
 618 
 619         // Need a lock here so that the user_canceled alert and the
 620         // close_notify alert can be delivered together.
 621         conContext.outputRecord.recordLock.lock();
 622         try {
 623             try {
 624                 // send a user_canceled alert if needed.
 625                 if (useUserCanceled) {
 626                     conContext.warning(Alert.USER_CANCELED);
 627                 }
 628 
 629                 // send a close_notify alert
 630                 conContext.warning(Alert.CLOSE_NOTIFY);
 631             } finally {
 632                 if (!conContext.isOutboundClosed()) {
 633                     conContext.outputRecord.close();
 634                 }
 635 
 636                 if ((autoClose || !isLayered()) && !super.isOutputShutdown()) {
 637                     super.shutdownOutput();
 638                 }
 639             }
 640         } finally {
 641             conContext.outputRecord.recordLock.unlock();
 642         }
 643 
 644         if (!isInputShutdown()) {
 645             bruteForceCloseInput(hasCloseReceipt);
 646         }
 647     }
 648 
 649     /**
 650      * Duplex close, start from closing inbound.
 651      *
 652      * This method should only be called when the outbound has been closed,
 653      * but the inbound is still open.
 654      */
 655     private void duplexCloseInput() throws IOException {
 656         boolean hasCloseReceipt = false;
 657         if (conContext.isNegotiated &&
 658                 !conContext.protocolVersion.useTLS13PlusSpec()) {
 659             hasCloseReceipt = true;
 660         }   // No close receipt if handshake has no completed.
 661 
 662         bruteForceCloseInput(hasCloseReceipt);
 663     }
 664 
 665     /**
 666      * Brute force close the input bound.
 667      *
 668      * This method should only be called when the outbound has been closed,
 669      * but the inbound is still open.
 670      */
 671     private void bruteForceCloseInput(
 672             boolean hasCloseReceipt) throws IOException {
 673         if (hasCloseReceipt) {
 674             // It is not required for the initiator of the close to wait for
 675             // the responding close_notify alert before closing the read side
 676             // of the connection.  However, if the application protocol using
 677             // TLS provides that any data may be carried over the underlying
 678             // transport after the TLS connection is closed, the TLS
 679             // implementation MUST receive a "close_notify" alert before
 680             // indicating end-of-data to the application-layer.
 681             try {
 682                 this.shutdown();
 683             } finally {
 684                 if (!isInputShutdown()) {
 685                     shutdownInput(false);
 686                 }
 687             }
 688         } else {
 689             if (!conContext.isInboundClosed()) {
 690                 try (conContext.inputRecord) {
 691                     // Try the best to use up the input records and close the
 692                     // socket gracefully, without impact the performance too
 693                     // much.
 694                     appInput.deplete();
 695                 }
 696             }
 697 
 698             if ((autoClose || !isLayered()) && !super.isInputShutdown()) {
 699                 super.shutdownInput();
 700             }
 701         }
 702     }
 703 
 704     // Please don't synchronized this method.  Otherwise, the read and close
 705     // locks may be deadlocked.
 706     @Override
 707     public void shutdownInput() throws IOException {
 708         shutdownInput(true);
 709     }
 710 
 711     // It is not required to check the close_notify receipt unless an
 712     // application call shutdownInput() explicitly.
 713     private void shutdownInput(
 714             boolean checkCloseNotify) throws IOException {
 715         if (isInputShutdown()) {
 716             return;
 717         }
 718 
 719         if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
 720             SSLLogger.fine("close inbound of SSLSocket");
 721         }
 722 
 723         // Is it ready to close inbound?
 724         //
 725         // No need to throw exception if the initial handshake is not started.
 726         if (checkCloseNotify && !conContext.isInputCloseNotified &&
 727             (conContext.isNegotiated || conContext.handshakeContext != null)) {
 728 
 729             throw conContext.fatal(Alert.INTERNAL_ERROR,
 730                     "closing inbound before receiving peer's close_notify");
 731         }
 732 
 733         conContext.closeInbound();
 734         if ((autoClose || !isLayered()) && !super.isInputShutdown()) {
 735             super.shutdownInput();
 736         }
 737     }
 738 
 739     @Override
 740     public boolean isInputShutdown() {
 741         return conContext.isInboundClosed() &&
 742                 ((autoClose || !isLayered()) ? super.isInputShutdown(): true);
 743     }
 744 
 745     // Please don't synchronized this method.  Otherwise, the read and close
 746     // locks may be deadlocked.
 747     @Override
 748     public void shutdownOutput() throws IOException {
 749         if (isOutputShutdown()) {
 750             return;
 751         }
 752 
 753         if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
 754             SSLLogger.fine("close outbound of SSLSocket");
 755         }
 756         conContext.closeOutbound();
 757 
 758         if ((autoClose || !isLayered()) && !super.isOutputShutdown()) {
 759             super.shutdownOutput();
 760         }
 761     }
 762 
 763     @Override
 764     public boolean isOutputShutdown() {
 765         return conContext.isOutboundClosed() &&
 766                 ((autoClose || !isLayered()) ? super.isOutputShutdown(): true);
 767     }
 768 
 769     @Override
 770     public InputStream getInputStream() throws IOException {
 771         socketLock.lock();
 772         try {
 773             if (isClosed()) {
 774                 throw new SocketException("Socket is closed");
 775             }
 776 
 777             if (!isConnected) {
 778                 throw new SocketException("Socket is not connected");
 779             }
 780 
 781             if (conContext.isInboundClosed() || isInputShutdown()) {
 782                 throw new SocketException("Socket input is already shutdown");
 783             }
 784 
 785             return appInput;
 786         } finally {
 787             socketLock.unlock();
 788         }
 789     }
 790 
 791     private void ensureNegotiated() throws IOException {
 792         if (conContext.isNegotiated || conContext.isBroken ||
 793                 conContext.isInboundClosed() || conContext.isOutboundClosed()) {
 794             return;
 795         }
 796 
 797         handshakeLock.lock();
 798         try {
 799             // double check the context status
 800             if (conContext.isNegotiated || conContext.isBroken ||
 801                     conContext.isInboundClosed() ||
 802                     conContext.isOutboundClosed()) {
 803                 return;
 804             }
 805 
 806             startHandshake();
 807         } finally {
 808             handshakeLock.unlock();
 809         }
 810     }
 811 
 812     /**
 813      * InputStream for application data as returned by
 814      * SSLSocket.getInputStream().
 815      */
 816     private class AppInputStream extends InputStream {
 817         // One element array used to implement the single byte read() method
 818         private final byte[] oneByte = new byte[1];
 819 
 820         // the temporary buffer used to read network
 821         private ByteBuffer buffer;
 822 
 823         // Is application data available in the stream?
 824         private volatile boolean appDataIsAvailable;
 825 
 826         // reading lock
 827         private final ReentrantLock readLock = new ReentrantLock();
 828 
 829         // closing status
 830         private volatile boolean isClosing;
 831         private volatile boolean hasDepleted;
 832 
 833         AppInputStream() {
 834             this.appDataIsAvailable = false;
 835             this.buffer = ByteBuffer.allocate(4096);
 836         }
 837 
 838         /**
 839          * Return the minimum number of bytes that can be read
 840          * without blocking.
 841          */
 842         @Override
 843         public int available() throws IOException {
 844             // Currently not synchronized.
 845             if ((!appDataIsAvailable) || checkEOF()) {
 846                 return 0;
 847             }
 848 
 849             return buffer.remaining();
 850         }
 851 
 852         /**
 853          * Read a single byte, returning -1 on non-fault EOF status.
 854          */
 855         @Override
 856         public int read() throws IOException {
 857             int n = read(oneByte, 0, 1);
 858             if (n <= 0) {   // EOF
 859                 return -1;
 860             }
 861 
 862             return oneByte[0] & 0xFF;
 863         }
 864 
 865         /**
 866          * Reads up to {@code len} bytes of data from the input stream
 867          * into an array of bytes.
 868          *
 869          * An attempt is made to read as many as {@code len} bytes, but a
 870          * smaller number may be read. The number of bytes actually read
 871          * is returned as an integer.
 872          *
 873          * If the layer above needs more data, it asks for more, so we
 874          * are responsible only for blocking to fill at most one buffer,
 875          * and returning "-1" on non-fault EOF status.
 876          */
 877         @Override
 878         public int read(byte[] b, int off, int len) throws IOException {
 879             if (b == null) {
 880                 throw new NullPointerException("the target buffer is null");
 881             } else if (off < 0 || len < 0 || len > b.length - off) {
 882                 throw new IndexOutOfBoundsException(
 883                         "buffer length: " + b.length + ", offset; " + off +
 884                         ", bytes to read:" + len);
 885             } else if (len == 0) {
 886                 return 0;
 887             }
 888 
 889             if (checkEOF()) {
 890                 return -1;
 891             }
 892 
 893             // start handshaking if the connection has not been negotiated.
 894             if (!conContext.isNegotiated && !conContext.isBroken &&
 895                     !conContext.isInboundClosed() &&
 896                     !conContext.isOutboundClosed()) {
 897                 ensureNegotiated();
 898             }
 899 
 900             // Check if the Socket is invalid (error or closed).
 901             if (!conContext.isNegotiated ||
 902                     conContext.isBroken || conContext.isInboundClosed()) {
 903                 throw new SocketException("Connection or inbound has closed");
 904             }
 905 
 906             // Check if the input stream has been depleted.
 907             //
 908             // Note that the "hasDepleted" rather than the isClosing
 909             // filed is checked here, in case the closing process is
 910             // still in progress.
 911             if (hasDepleted) {
 912                 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
 913                     SSLLogger.fine("The input stream has been depleted");
 914                 }
 915 
 916                 return -1;
 917             }
 918 
 919             // Read the available bytes at first.
 920             //
 921             // Note that the receiving and processing of post-handshake message
 922             // are also synchronized with the read lock.
 923             readLock.lock();
 924             try {
 925                 // Double check if the Socket is invalid (error or closed).
 926                 if (conContext.isBroken || conContext.isInboundClosed()) {
 927                     throw new SocketException(
 928                             "Connection or inbound has closed");
 929                 }
 930 
 931                 // Double check if the input stream has been depleted.
 932                 if (hasDepleted) {
 933                     if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
 934                         SSLLogger.fine("The input stream is closing");
 935                     }
 936 
 937                     return -1;
 938                 }
 939 
 940                 int remains = available();
 941                 if (remains > 0) {
 942                     int howmany = Math.min(remains, len);
 943                     buffer.get(b, off, howmany);
 944 
 945                     return howmany;
 946                 }
 947 
 948                 appDataIsAvailable = false;
 949                 try {
 950                     ByteBuffer bb = readApplicationRecord(buffer);
 951                     if (bb == null) {   // EOF
 952                         return -1;
 953                     } else {
 954                         // The buffer may be reallocated for bigger capacity.
 955                         buffer = bb;
 956                     }
 957 
 958                     bb.flip();
 959                     int volume = Math.min(len, bb.remaining());
 960                     buffer.get(b, off, volume);
 961                     appDataIsAvailable = true;
 962 
 963                     return volume;
 964                 } catch (Exception e) {   // including RuntimeException
 965                     // shutdown and rethrow (wrapped) exception as appropriate
 966                     handleException(e);
 967 
 968                     // dummy for compiler
 969                     return -1;
 970                 }
 971             } finally {
 972                 // Check if the input stream is closing.
 973                 //
 974                 // If the deplete() did not hold the lock, clean up the
 975                 // input stream here.
 976                 try {
 977                     if (isClosing) {
 978                         readLockedDeplete();
 979                     }
 980                 } finally {
 981                     readLock.unlock();
 982                 }
 983             }
 984         }
 985 
 986         /**
 987          * Skip n bytes.
 988          *
 989          * This implementation is somewhat less efficient than possible, but
 990          * not badly so (redundant copy).  We reuse the read() code to keep
 991          * things simpler.
 992          */
 993         @Override
 994         public long skip(long n) throws IOException {
 995             // dummy array used to implement skip()
 996             byte[] skipArray = new byte[256];
 997             long skipped = 0;
 998 
 999             readLock.lock();
1000             try {
1001                 while (n > 0) {
1002                     int len = (int)Math.min(n, skipArray.length);
1003                     int r = read(skipArray, 0, len);
1004                     if (r <= 0) {
1005                         break;
1006                     }
1007                     n -= r;
1008                     skipped += r;
1009                 }
1010             } finally {
1011                 readLock.unlock();
1012             }
1013 
1014             return skipped;
1015         }
1016 
1017         @Override
1018         public void close() throws IOException {
1019             if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1020                 SSLLogger.finest("Closing input stream");
1021             }
1022 
1023             try {
1024                 SSLSocketImpl.this.close();
1025             } catch (IOException ioe) {
1026                 // ignore the exception
1027                 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1028                     SSLLogger.warning("input stream close failed", ioe);
1029                 }
1030             }
1031         }
1032 
1033         /**
1034          * Return whether we have reached end-of-file.
1035          *
1036          * If the socket is not connected, has been shutdown because of an error
1037          * or has been closed, throw an Exception.
1038          */
1039         private boolean checkEOF() throws IOException {
1040             if (conContext.isInboundClosed()) {
1041                 return true;
1042             } else if (conContext.isInputCloseNotified || conContext.isBroken) {
1043                 if (conContext.closeReason == null) {
1044                     return true;
1045                 } else {
1046                     throw new SSLException(
1047                         "Connection has closed: " + conContext.closeReason,
1048                         conContext.closeReason);
1049                 }
1050             }
1051 
1052             return false;
1053         }
1054 
1055         /**
1056          * Try the best to use up the input records so as to close the
1057          * socket gracefully, without impact the performance too much.
1058          */
1059         private void deplete() {
1060             if (conContext.isInboundClosed() || isClosing) {
1061                 return;
1062             }
1063 
1064             isClosing = true;
1065             if (readLock.tryLock()) {
1066                 try {
1067                     readLockedDeplete();
1068                 } finally {
1069                     readLock.unlock();
1070                 }
1071             }
1072         }
1073 
1074         /**
1075          * Try to use up the input records.
1076          *
1077          * Please don't call this method unless the readLock is held by
1078          * the current thread.
1079          */
1080         private void readLockedDeplete() {
1081             // double check
1082             if (hasDepleted || conContext.isInboundClosed()) {
1083                 return;
1084             }
1085 
1086             if (!(conContext.inputRecord instanceof SSLSocketInputRecord)) {
1087                 return;
1088             }
1089 
1090             SSLSocketInputRecord socketInputRecord =
1091                     (SSLSocketInputRecord)conContext.inputRecord;
1092             try {
1093                 socketInputRecord.deplete(
1094                     conContext.isNegotiated && (getSoTimeout() > 0));
1095             } catch (Exception ex) {
1096                 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1097                     SSLLogger.warning(
1098                         "input stream close depletion failed", ex);
1099                 }
1100             } finally {
1101                 hasDepleted = true;
1102             }
1103         }
1104     }
1105 
1106     @Override
1107     public OutputStream getOutputStream() throws IOException {
1108         socketLock.lock();
1109         try {
1110             if (isClosed()) {
1111                 throw new SocketException("Socket is closed");
1112             }
1113 
1114             if (!isConnected) {
1115                 throw new SocketException("Socket is not connected");
1116             }
1117 
1118             if (conContext.isOutboundDone() || isOutputShutdown()) {
1119                 throw new SocketException("Socket output is already shutdown");
1120             }
1121 
1122             return appOutput;
1123         } finally {
1124             socketLock.unlock();
1125         }
1126     }
1127 
1128 
1129     /**
1130      * OutputStream for application data as returned by
1131      * SSLSocket.getOutputStream().
1132      */
1133     private class AppOutputStream extends OutputStream {
1134         // One element array used to implement the write(byte) method
1135         private final byte[] oneByte = new byte[1];
1136 
1137         @Override
1138         public void write(int i) throws IOException {
1139             oneByte[0] = (byte)i;
1140             write(oneByte, 0, 1);
1141         }
1142 
1143         @Override
1144         public void write(byte[] b,
1145                 int off, int len) throws IOException {
1146             if (b == null) {
1147                 throw new NullPointerException("the source buffer is null");
1148             } else if (off < 0 || len < 0 || len > b.length - off) {
1149                 throw new IndexOutOfBoundsException(
1150                         "buffer length: " + b.length + ", offset; " + off +
1151                         ", bytes to read:" + len);
1152             } else if (len == 0) {
1153                 //
1154                 // Don't bother to really write empty records.  We went this
1155                 // far to drive the handshake machinery, for correctness; not
1156                 // writing empty records improves performance by cutting CPU
1157                 // time and network resource usage.  However, some protocol
1158                 // implementations are fragile and don't like to see empty
1159                 // records, so this also increases robustness.
1160                 //
1161                 return;
1162             }
1163 
1164             // Start handshaking if the connection has not been negotiated.
1165             if (!conContext.isNegotiated && !conContext.isBroken &&
1166                     !conContext.isInboundClosed() &&
1167                     !conContext.isOutboundClosed()) {
1168                 ensureNegotiated();
1169             }
1170 
1171             // Check if the Socket is invalid (error or closed).
1172             if (!conContext.isNegotiated ||
1173                     conContext.isBroken || conContext.isOutboundClosed()) {
1174                 throw new SocketException("Connection or outbound has closed");
1175             }
1176 
1177             //
1178 
1179             // Delegate the writing to the underlying socket.
1180             try {
1181                 conContext.outputRecord.deliver(b, off, len);
1182             } catch (SSLHandshakeException she) {
1183                 // may be record sequence number overflow
1184                 throw conContext.fatal(Alert.HANDSHAKE_FAILURE, she);
1185             } catch (IOException e) {
1186                 throw conContext.fatal(Alert.UNEXPECTED_MESSAGE, e);
1187             }
1188 
1189             // Is the sequence number is nearly overflow, or has the key usage
1190             // limit been reached?
1191             if (conContext.outputRecord.seqNumIsHuge() ||
1192                     conContext.outputRecord.writeCipher.atKeyLimit()) {
1193                 tryKeyUpdate();
1194             }
1195         }
1196 
1197         @Override
1198         public void close() throws IOException {
1199             if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1200                 SSLLogger.finest("Closing output stream");
1201             }
1202 
1203             try {
1204                 SSLSocketImpl.this.close();
1205             } catch (IOException ioe) {
1206                 // ignore the exception
1207                 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1208                     SSLLogger.warning("output stream close failed", ioe);
1209                 }
1210             }
1211         }
1212     }
1213 
1214     @Override
1215     public SSLParameters getSSLParameters() {
1216         socketLock.lock();
1217         try {
1218             return conContext.sslConfig.getSSLParameters();
1219         } finally {
1220             socketLock.unlock();
1221         }
1222     }
1223 
1224     @Override
1225     public void setSSLParameters(SSLParameters params) {
1226         socketLock.lock();
1227         try {
1228             conContext.sslConfig.setSSLParameters(params);
1229 
1230             if (conContext.sslConfig.maximumPacketSize != 0) {
1231                 conContext.outputRecord.changePacketSize(
1232                         conContext.sslConfig.maximumPacketSize);
1233             }
1234         } finally {
1235             socketLock.unlock();
1236         }
1237     }
1238 
1239     @Override
1240     public String getApplicationProtocol() {
1241         socketLock.lock();
1242         try {
1243             return conContext.applicationProtocol;
1244         } finally {
1245             socketLock.unlock();
1246         }
1247     }
1248 
1249     @Override
1250     public String getHandshakeApplicationProtocol() {
1251         socketLock.lock();
1252         try {
1253             if (conContext.handshakeContext != null) {
1254                 return conContext.handshakeContext.applicationProtocol;
1255             }
1256         } finally {
1257             socketLock.unlock();
1258         }
1259 
1260         return null;
1261     }
1262 
1263     @Override
1264     public void setHandshakeApplicationProtocolSelector(
1265             BiFunction<SSLSocket, List<String>, String> selector) {
1266         socketLock.lock();
1267         try {
1268             conContext.sslConfig.socketAPSelector = selector;
1269         } finally {
1270             socketLock.unlock();
1271         }
1272     }
1273 
1274     @Override
1275     public BiFunction<SSLSocket, List<String>, String>
1276             getHandshakeApplicationProtocolSelector() {
1277         socketLock.lock();
1278         try {
1279             return conContext.sslConfig.socketAPSelector;
1280         } finally {
1281             socketLock.unlock();
1282         }
1283     }
1284 
1285     /**
1286      * Read the initial handshake records.
1287      */
1288     private int readHandshakeRecord() throws IOException {
1289         while (!conContext.isInboundClosed()) {
1290             try {
1291                 Plaintext plainText = decode(null);
1292                 if ((plainText.contentType == ContentType.HANDSHAKE.id) &&
1293                         conContext.isNegotiated) {
1294                     return 0;
1295                 }
1296             } catch (SSLException ssle) {
1297                 throw ssle;
1298             } catch (IOException ioe) {
1299                 if (!(ioe instanceof SSLException)) {
1300                     throw new SSLException("readHandshakeRecord", ioe);
1301                 } else {
1302                     throw ioe;
1303                 }
1304             }
1305         }
1306 
1307         return -1;
1308     }
1309 
1310     /**
1311      * Read application data record. Used by AppInputStream only, but defined
1312      * here so as to use the socket level synchronization.
1313      *
1314      * Note that the connection guarantees that handshake, alert, and change
1315      * cipher spec data streams are handled as they arrive, so we never see
1316      * them here.
1317      *
1318      * Note: Please be careful about the synchronization, and don't use this
1319      * method other than in the AppInputStream class!
1320      */
1321     private ByteBuffer readApplicationRecord(
1322             ByteBuffer buffer) throws IOException {
1323         while (!conContext.isInboundClosed()) {
1324             /*
1325              * clean the buffer and check if it is too small, e.g. because
1326              * the AppInputStream did not have the chance to see the
1327              * current packet length but rather something like that of the
1328              * handshake before. In that case we return 0 at this point to
1329              * give the caller the chance to adjust the buffer.
1330              */
1331             buffer.clear();
1332             int inLen = conContext.inputRecord.bytesInCompletePacket();
1333             if (inLen < 0) {    // EOF
1334                 handleEOF(null);
1335 
1336                 // if no exception thrown
1337                 return null;
1338             }
1339 
1340             // Is this packet bigger than SSL/TLS normally allows?
1341             if (inLen > SSLRecord.maxLargeRecordSize) {
1342                 throw new SSLProtocolException(
1343                         "Illegal packet size: " + inLen);
1344             }
1345 
1346             if (inLen > buffer.remaining()) {
1347                 buffer = ByteBuffer.allocate(inLen);
1348             }
1349 
1350             try {
1351                 Plaintext plainText;
1352                 socketLock.lock();
1353                 try {
1354                     plainText = decode(buffer);
1355                 } finally {
1356                     socketLock.unlock();
1357                 }
1358                 if (plainText.contentType == ContentType.APPLICATION_DATA.id &&
1359                         buffer.position() > 0) {
1360                     return buffer;
1361                 }
1362             } catch (SSLException ssle) {
1363                 throw ssle;
1364             } catch (IOException ioe) {
1365                 if (!(ioe instanceof SSLException)) {
1366                     throw new SSLException("readApplicationRecord", ioe);
1367                 } else {
1368                     throw ioe;
1369                 }
1370             }
1371         }
1372 
1373         //
1374         // couldn't read, due to some kind of error
1375         //
1376         return null;
1377     }
1378 
1379     private Plaintext decode(ByteBuffer destination) throws IOException {
1380         Plaintext plainText;
1381         try {
1382             if (destination == null) {
1383                 plainText = SSLTransport.decode(conContext,
1384                         null, 0, 0, null, 0, 0);
1385             } else {
1386                 plainText = SSLTransport.decode(conContext,
1387                         null, 0, 0, new ByteBuffer[]{destination}, 0, 1);
1388             }
1389         } catch (EOFException eofe) {
1390             // EOFException is special as it is related to close_notify.
1391             plainText = handleEOF(eofe);
1392         }
1393 
1394         // Is the sequence number is nearly overflow?
1395         if (plainText != Plaintext.PLAINTEXT_NULL &&
1396                 (conContext.inputRecord.seqNumIsHuge() ||
1397                 conContext.inputRecord.readCipher.atKeyLimit())) {
1398             tryKeyUpdate();
1399         }
1400 
1401         return plainText;
1402     }
1403 
1404     /**
1405      * Try key update for sequence number wrap or key usage limit.
1406      *
1407      * Note that in order to maintain the handshake status properly, we check
1408      * the sequence number and key usage limit after the last record
1409      * reading/writing process.
1410      *
1411      * As we request renegotiation or close the connection for wrapped sequence
1412      * number when there is enough sequence number space left to handle a few
1413      * more records, so the sequence number of the last record cannot be
1414      * wrapped.
1415      */
1416     private void tryKeyUpdate() throws IOException {
1417         // Don't bother to kickstart if handshaking is in progress, or if the
1418         // connection is not duplex-open.
1419         if ((conContext.handshakeContext == null) &&
1420                 !conContext.isOutboundClosed() &&
1421                 !conContext.isInboundClosed() &&
1422                 !conContext.isBroken) {
1423             if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1424                 SSLLogger.finest("trigger key update");
1425             }
1426             startHandshake();
1427         }
1428     }
1429 
1430     /**
1431      * Initialize the handshaker and socket streams.
1432      *
1433      * Called by connect, the layered constructor, and SSLServerSocket.
1434      */
1435     void doneConnect() throws IOException {
1436         socketLock.lock();
1437         try {
1438             // In server mode, it is not necessary to set host and serverNames.
1439             // Otherwise, would require a reverse DNS lookup to get
1440             // the hostname.
1441             if (peerHost == null || peerHost.isEmpty()) {
1442                 boolean useNameService =
1443                         trustNameService && conContext.sslConfig.isClientMode;
1444                 useImplicitHost(useNameService);
1445             } else {
1446                 conContext.sslConfig.serverNames =
1447                         Utilities.addToSNIServerNameList(
1448                                 conContext.sslConfig.serverNames, peerHost);
1449             }
1450 
1451             InputStream sockInput = super.getInputStream();
1452             conContext.inputRecord.setReceiverStream(sockInput);
1453 
1454             OutputStream sockOutput = super.getOutputStream();
1455             conContext.inputRecord.setDeliverStream(sockOutput);
1456             conContext.outputRecord.setDeliverStream(sockOutput);
1457 
1458             this.isConnected = true;
1459         } finally {
1460             socketLock.unlock();
1461         }
1462     }
1463 
1464     private void useImplicitHost(boolean useNameService) {
1465         // Note: If the local name service is not trustworthy, reverse
1466         // host name resolution should not be performed for endpoint
1467         // identification.  Use the application original specified
1468         // hostname or IP address instead.
1469 
1470         // Get the original hostname via jdk.internal.access.SharedSecrets
1471         InetAddress inetAddress = getInetAddress();
1472         if (inetAddress == null) {      // not connected
1473             return;
1474         }
1475 
1476         JavaNetInetAddressAccess jna =
1477                 SharedSecrets.getJavaNetInetAddressAccess();
1478         String originalHostname = jna.getOriginalHostName(inetAddress);
1479         if (originalHostname != null && !originalHostname.isEmpty()) {
1480 
1481             this.peerHost = originalHostname;
1482             if (conContext.sslConfig.serverNames.isEmpty() &&
1483                     !conContext.sslConfig.noSniExtension) {
1484                 conContext.sslConfig.serverNames =
1485                         Utilities.addToSNIServerNameList(
1486                                 conContext.sslConfig.serverNames, peerHost);
1487             }
1488 
1489             return;
1490         }
1491 
1492         // No explicitly specified hostname, no server name indication.
1493         if (!useNameService) {
1494             // The local name service is not trustworthy, use IP address.
1495             this.peerHost = inetAddress.getHostAddress();
1496         } else {
1497             // Use the underlying reverse host name resolution service.
1498             this.peerHost = getInetAddress().getHostName();
1499         }
1500     }
1501 
1502     // ONLY used by HttpsClient to setup the URI specified hostname
1503     //
1504     // Please NOTE that this method MUST be called before calling to
1505     // SSLSocket.setSSLParameters(). Otherwise, the {@code host} parameter
1506     // may override SNIHostName in the customized server name indication.
1507     public void setHost(String host) {
1508         socketLock.lock();
1509         try {
1510             this.peerHost = host;
1511             this.conContext.sslConfig.serverNames =
1512                     Utilities.addToSNIServerNameList(
1513                             conContext.sslConfig.serverNames, host);
1514         } finally {
1515             socketLock.unlock();
1516         }
1517     }
1518 
1519     /**
1520      * Handle an exception.
1521      *
1522      * This method is called by top level exception handlers (in read(),
1523      * write()) to make sure we always shutdown the connection correctly
1524      * and do not pass runtime exception to the application.
1525      *
1526      * This method never returns normally, it always throws an IOException.
1527      */
1528     private void handleException(Exception cause) throws IOException {
1529         if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1530             SSLLogger.warning("handling exception", cause);
1531         }
1532 
1533         // Don't close the Socket in case of timeouts or interrupts.
1534         if (cause instanceof InterruptedIOException) {
1535             throw (IOException)cause;
1536         }
1537 
1538         // need to perform error shutdown
1539         boolean isSSLException = (cause instanceof SSLException);
1540         Alert alert;
1541         if (isSSLException) {
1542             if (cause instanceof SSLHandshakeException) {
1543                 alert = Alert.HANDSHAKE_FAILURE;
1544             } else {
1545                 alert = Alert.UNEXPECTED_MESSAGE;
1546             }
1547         } else {
1548             if (cause instanceof IOException) {
1549                 alert = Alert.UNEXPECTED_MESSAGE;
1550             } else {
1551                 // RuntimeException
1552                 alert = Alert.INTERNAL_ERROR;
1553             }
1554         }
1555 
1556         throw conContext.fatal(alert, cause);
1557     }
1558 
1559     private Plaintext handleEOF(EOFException eofe) throws IOException {
1560         if (requireCloseNotify || conContext.handshakeContext != null) {
1561             SSLException ssle;
1562             if (conContext.handshakeContext != null) {
1563                 ssle = new SSLHandshakeException(
1564                         "Remote host terminated the handshake");
1565             } else {
1566                 ssle = new SSLProtocolException(
1567                         "Remote host terminated the connection");
1568             }
1569 
1570             if (eofe != null) {
1571                 ssle.initCause(eofe);
1572             }
1573             throw ssle;
1574         } else {
1575             // treat as if we had received a close_notify
1576             conContext.isInputCloseNotified = true;
1577             shutdownInput();
1578 
1579             return Plaintext.PLAINTEXT_NULL;
1580         }
1581     }
1582 
1583 
1584     @Override
1585     public String getPeerHost() {
1586         return peerHost;
1587     }
1588 
1589     @Override
1590     public int getPeerPort() {
1591         return getPort();
1592     }
1593 
1594     @Override
1595     public boolean useDelegatedTask() {
1596         return false;
1597     }
1598 
1599     @Override
1600     public void shutdown() throws IOException {
1601         if (!isClosed()) {
1602             if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1603                 SSLLogger.fine("close the underlying socket");
1604             }
1605 
1606             try {
1607                 if (conContext.isInputCloseNotified) {
1608                     // Close the connection, no wait for more peer response.
1609                     closeSocket(false);
1610                 } else {
1611                     // Close the connection, may wait for peer close_notify.
1612                     closeSocket(true);
1613                 }
1614             } finally {
1615                 tlsIsClosed = true;
1616             }
1617         }
1618     }
1619 
1620     private void closeSocket(boolean selfInitiated) throws IOException {
1621         if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1622             SSLLogger.fine("close the SSL connection " +
1623                 (selfInitiated ? "(initiative)" : "(passive)"));
1624         }
1625 
1626         if (autoClose || !isLayered()) {
1627             super.close();
1628         } else if (selfInitiated) {
1629             if (!conContext.isInboundClosed() && !isInputShutdown()) {
1630                 // wait for close_notify alert to clear input stream.
1631                 waitForClose();
1632             }
1633         }
1634     }
1635 
1636    /**
1637     * Wait for close_notify alert for a graceful closure.
1638     *
1639     * [RFC 5246] If the application protocol using TLS provides that any
1640     * data may be carried over the underlying transport after the TLS
1641     * connection is closed, the TLS implementation must receive the responding
1642     * close_notify alert before indicating to the application layer that
1643     * the TLS connection has ended.  If the application protocol will not
1644     * transfer any additional data, but will only close the underlying
1645     * transport connection, then the implementation MAY choose to close the
1646     * transport without waiting for the responding close_notify.
1647     */
1648     private void waitForClose() throws IOException {
1649         if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1650             SSLLogger.fine("wait for close_notify or alert");
1651         }
1652 
1653         while (!conContext.isInboundClosed()) {
1654             try {
1655                 Plaintext plainText = decode(null);
1656                 // discard and continue
1657                 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
1658                     SSLLogger.finest(
1659                         "discard plaintext while waiting for close", plainText);
1660                 }
1661             } catch (Exception e) {   // including RuntimeException
1662                 handleException(e);
1663             }
1664         }
1665     }
1666 }