Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/ssl/BaseSSLSocketImpl.java
38830 views
/*1* Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.ssl;2627import java.io.*;28import java.net.*;29import java.nio.channels.SocketChannel;30import java.util.Set;31import javax.net.ssl.*;3233/**34* Abstract base class for SSLSocketImpl.35*36* Its purpose is to house code with no SSL related logic (or no logic at all).37* This makes SSLSocketImpl shorter and easier to read. It contains a few38* constants and static methods plus overridden java.net.Socket methods.39*40* Methods are defined final to ensure that they are not accidentally41* overridden in SSLSocketImpl.42*43* @see javax.net.ssl.SSLSocket44* @see SSLSocketImpl45*/46abstract class BaseSSLSocketImpl extends SSLSocket {4748/*49* Normally "self" is "this" ... but not when this connection is50* layered over a preexisting socket. If we're using an existing51* socket, we delegate some actions to it. Else, we delegate52* instead to "super". This is important to ensure that we don't53* recurse infinitely ... e.g. close() calling itself, or doing54* I/O in terms of our own streams.55*/56private final Socket self;57private final InputStream consumedInput;5859BaseSSLSocketImpl() {60super();61this.self = this;62this.consumedInput = null;63}6465BaseSSLSocketImpl(Socket socket) {66super();67this.self = socket;68this.consumedInput = null;69}7071BaseSSLSocketImpl(Socket socket, InputStream consumed) {72super();73this.self = socket;74this.consumedInput = consumed;75}7677//78// CONSTANTS AND STATIC METHODS79//8081/**82* TLS requires that a close_notify warning alert is sent before the83* connection is closed in order to avoid truncation attacks. Some84* implementations (MS IIS and others) don't do that. The property85* below controls whether we accept that or treat it as an error.86*87* The default is "false", i.e. tolerate the broken behavior.88*/89private static final String PROP_NAME =90"com.sun.net.ssl.requireCloseNotify";9192static final boolean requireCloseNotify =93Utilities.getBooleanProperty(PROP_NAME, false);9495//96// MISC SOCKET METHODS97//9899/**100* Returns the unique {@link java.nio.SocketChannel SocketChannel} object101* associated with this socket, if any.102* @see java.net.Socket#getChannel103*/104@Override105public final SocketChannel getChannel() {106if (self == this) {107return super.getChannel();108} else {109return self.getChannel();110}111}112113/**114* Binds the address to the socket.115* @see java.net.Socket#bind116*/117@Override118public void bind(SocketAddress bindpoint) throws IOException {119/*120* Bind to this socket121*/122if (self == this) {123super.bind(bindpoint);124} else {125// If we're binding on a layered socket...126throw new IOException(127"Underlying socket should already be connected");128}129}130131/**132* Returns the address of the endpoint this socket is connected to133* @see java.net.Socket#getLocalSocketAddress134*/135@Override136public SocketAddress getLocalSocketAddress() {137if (self == this) {138return super.getLocalSocketAddress();139} else {140return self.getLocalSocketAddress();141}142}143144/**145* Returns the address of the endpoint this socket is connected to146* @see java.net.Socket#getRemoteSocketAddress147*/148@Override149public SocketAddress getRemoteSocketAddress() {150if (self == this) {151return super.getRemoteSocketAddress();152} else {153return self.getRemoteSocketAddress();154}155}156157/**158* Connects this socket to the server.159*160* This method is either called on an unconnected SSLSocketImpl by the161* application, or it is called in the constructor of a regular162* SSLSocketImpl. If we are layering on top on another socket, then163* this method should not be called, because we assume that the164* underlying socket is already connected by the time it is passed to165* us.166*167* @param endpoint the <code>SocketAddress</code>168* @throws IOException if an error occurs during the connection169*/170@Override171public final void connect(SocketAddress endpoint) throws IOException {172connect(endpoint, 0);173}174175/**176* Returns the connection state of the socket.177* @see java.net.Socket#isConnected178*/179@Override180public final boolean isConnected() {181if (self == this) {182return super.isConnected();183} else {184return self.isConnected();185}186}187188/**189* Returns the binding state of the socket.190* @see java.net.Socket#isBound191*/192@Override193public final boolean isBound() {194if (self == this) {195return super.isBound();196} else {197return self.isBound();198}199}200201//202// CLOSE RELATED METHODS203//204205/**206* Places the input stream for this socket at "end of stream". Any data207* sent to the input stream side of the socket is acknowledged and then208* silently discarded.209*210* @see java.net.Socket#shutdownInput211*/212@Override213public void shutdownInput() throws IOException {214if (self == this) {215super.shutdownInput();216} else {217self.shutdownInput();218}219}220221/**222* Disables the output stream for this socket. For a TCP socket, any223* previously written data will be sent followed by TCP's normal224* connection termination sequence.225*226* @see java.net.Socket#shutdownOutput227*/228@Override229public void shutdownOutput() throws IOException {230if (self == this) {231super.shutdownOutput();232} else {233self.shutdownOutput();234}235}236237/**238* Returns the input state of the socket239* @see java.net.Socket#isInputShutdown240*/241@Override242public boolean isInputShutdown() {243if (self == this) {244return super.isInputShutdown();245} else {246return self.isInputShutdown();247}248}249250/**251* Returns the output state of the socket252* @see java.net.Socket#isOutputShutdown253*/254@Override255public boolean isOutputShutdown() {256if (self == this) {257return super.isOutputShutdown();258} else {259return self.isOutputShutdown();260}261}262263/**264* Ensures that the SSL connection is closed down as cleanly265* as possible, in case the application forgets to do so.266* This allows SSL connections to be implicitly reclaimed,267* rather than forcing them to be explicitly reclaimed at268* the penalty of prematurly killing SSL sessions.269*/270@Override271@SuppressWarnings("deprecation")272protected final void finalize() throws Throwable {273try {274close();275} catch (IOException e1) {276try {277if (self == this) {278super.close();279}280} catch (IOException e2) {281// ignore282}283} finally {284// We called close on the underlying socket above to285// make doubly sure all resources got released. We286// don't finalize self in the case of overlain sockets,287// that's a different object which the GC will finalize288// separately.289290super.finalize();291}292}293294//295// GET ADDRESS METHODS296//297298/**299* Returns the address of the remote peer for this connection.300*/301@Override302public final InetAddress getInetAddress() {303if (self == this) {304return super.getInetAddress();305} else {306return self.getInetAddress();307}308}309310/**311* Gets the local address to which the socket is bound.312*313* @return the local address to which the socket is bound.314* @since 1.1315*/316@Override317public final InetAddress getLocalAddress() {318if (self == this) {319return super.getLocalAddress();320} else {321return self.getLocalAddress();322}323}324325/**326* Returns the number of the remote port that this connection uses.327*/328@Override329public final int getPort() {330if (self == this) {331return super.getPort();332} else {333return self.getPort();334}335}336337/**338* Returns the number of the local port that this connection uses.339*/340@Override341public final int getLocalPort() {342if (self == this) {343return super.getLocalPort();344} else {345return self.getLocalPort();346}347}348349//350// SOCKET OPTION METHODS351//352353/**354* Enables or disables the Nagle optimization.355* @see java.net.Socket#setTcpNoDelay356*/357@Override358public final void setTcpNoDelay(boolean value) throws SocketException {359if (self == this) {360super.setTcpNoDelay(value);361} else {362self.setTcpNoDelay(value);363}364}365366/**367* Returns true if the Nagle optimization is disabled. This368* relates to low-level buffering of TCP traffic, delaying the369* traffic to promote better throughput.370*371* @see java.net.Socket#getTcpNoDelay372*/373@Override374public final boolean getTcpNoDelay() throws SocketException {375if (self == this) {376return super.getTcpNoDelay();377} else {378return self.getTcpNoDelay();379}380}381382/**383* Assigns the socket's linger timeout.384* @see java.net.Socket#setSoLinger385*/386@Override387public final void setSoLinger(boolean flag, int linger)388throws SocketException {389if (self == this) {390super.setSoLinger(flag, linger);391} else {392self.setSoLinger(flag, linger);393}394}395396/**397* Returns the socket's linger timeout.398* @see java.net.Socket#getSoLinger399*/400@Override401public final int getSoLinger() throws SocketException {402if (self == this) {403return super.getSoLinger();404} else {405return self.getSoLinger();406}407}408409/**410* Send one byte of urgent data on the socket.411* @see java.net.Socket#sendUrgentData412* At this point, there seems to be no specific requirement to support413* this for an SSLSocket. An implementation can be provided if a need414* arises in future.415*/416@Override417public final void sendUrgentData(int data) throws SocketException {418throw new SocketException("This method is not supported "419+ "by SSLSockets");420}421422/**423* Enable/disable OOBINLINE (receipt of TCP urgent data) By default, this424* option is disabled and TCP urgent data received on a socket is silently425* discarded.426* @see java.net.Socket#setOOBInline427* Setting OOBInline does not have any effect on SSLSocket,428* since currently we don't support sending urgent data.429*/430@Override431public final void setOOBInline(boolean on) throws SocketException {432throw new SocketException("This method is ineffective, since"433+ " sending urgent data is not supported by SSLSockets");434}435436/**437* Tests if OOBINLINE is enabled.438* @see java.net.Socket#getOOBInline439*/440@Override441public final boolean getOOBInline() throws SocketException {442throw new SocketException("This method is ineffective, since"443+ " sending urgent data is not supported by SSLSockets");444}445446/**447* Returns the socket timeout.448* @see java.net.Socket#getSoTimeout449*/450@Override451public final int getSoTimeout() throws SocketException {452if (self == this) {453return super.getSoTimeout();454} else {455return self.getSoTimeout();456}457}458459@Override460public final void setSendBufferSize(int size) throws SocketException {461if (self == this) {462super.setSendBufferSize(size);463} else {464self.setSendBufferSize(size);465}466}467468@Override469public final int getSendBufferSize() throws SocketException {470if (self == this) {471return super.getSendBufferSize();472} else {473return self.getSendBufferSize();474}475}476477@Override478public final void setReceiveBufferSize(int size) throws SocketException {479if (self == this) {480super.setReceiveBufferSize(size);481} else {482self.setReceiveBufferSize(size);483}484}485486@Override487public final int getReceiveBufferSize() throws SocketException {488if (self == this) {489return super.getReceiveBufferSize();490} else {491return self.getReceiveBufferSize();492}493}494495/**496* Enable/disable SO_KEEPALIVE.497* @see java.net.Socket#setKeepAlive498*/499@Override500public final void setKeepAlive(boolean on) throws SocketException {501if (self == this) {502super.setKeepAlive(on);503} else {504self.setKeepAlive(on);505}506}507508/**509* Tests if SO_KEEPALIVE is enabled.510* @see java.net.Socket#getKeepAlive511*/512@Override513public final boolean getKeepAlive() throws SocketException {514if (self == this) {515return super.getKeepAlive();516} else {517return self.getKeepAlive();518}519}520521/**522* Sets traffic class or type-of-service octet in the IP header for523* packets sent from this Socket.524* @see java.net.Socket#setTrafficClass525*/526@Override527public final void setTrafficClass(int tc) throws SocketException {528if (self == this) {529super.setTrafficClass(tc);530} else {531self.setTrafficClass(tc);532}533}534535/**536* Gets traffic class or type-of-service in the IP header for packets537* sent from this Socket.538* @see java.net.Socket#getTrafficClass539*/540@Override541public final int getTrafficClass() throws SocketException {542if (self == this) {543return super.getTrafficClass();544} else {545return self.getTrafficClass();546}547}548549/**550* Enable/disable SO_REUSEADDR.551* @see java.net.Socket#setReuseAddress552*/553@Override554public final void setReuseAddress(boolean on) throws SocketException {555if (self == this) {556super.setReuseAddress(on);557} else {558self.setReuseAddress(on);559}560}561562/**563* Tests if SO_REUSEADDR is enabled.564* @see java.net.Socket#getReuseAddress565*/566@Override567public final boolean getReuseAddress() throws SocketException {568if (self == this) {569return super.getReuseAddress();570} else {571return self.getReuseAddress();572}573}574575/**576* Sets performance preferences for this socket.577*578* @see java.net.Socket#setPerformancePreferences(int, int, int)579*/580@Override581public void setPerformancePreferences(int connectionTime,582int latency, int bandwidth) {583if (self == this) {584super.setPerformancePreferences(585connectionTime, latency, bandwidth);586} else {587self.setPerformancePreferences(588connectionTime, latency, bandwidth);589}590}591592@Override593public String toString() {594if (self == this) {595return super.toString();596}597598return self.toString();599}600601@Override602public InputStream getInputStream() throws IOException {603if (self == this) {604return super.getInputStream();605}606607if (consumedInput != null) {608return new SequenceInputStream(consumedInput,609self.getInputStream());610}611612return self.getInputStream();613}614615@Override616public OutputStream getOutputStream() throws IOException {617if (self == this) {618return super.getOutputStream();619}620621return self.getOutputStream();622}623624@Override625public void close() throws IOException {626if (self == this) {627super.close();628} else {629self.close();630}631}632633@Override634public synchronized void setSoTimeout(int timeout) throws SocketException {635if (self == this) {636super.setSoTimeout(timeout);637} else {638self.setSoTimeout(timeout);639}640}641642boolean isLayered() {643return (self != this);644}645}646647648