0N/A/*
2362N/A * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/A
0N/Apackage sun.security.ssl;
0N/A
0N/Aimport java.io.*;
0N/Aimport java.nio.channels.SocketChannel;
0N/Aimport java.net.*;
0N/A
0N/Aimport javax.net.ssl.*;
0N/A
0N/A/**
0N/A * Abstract base class for SSLSocketImpl. Its purpose is to house code with
0N/A * no SSL related logic (or no logic at all). This makes SSLSocketImpl shorter
0N/A * and easier to read. It contains a few constants and static methods plus
0N/A * overridden java.net.Socket methods.
0N/A *
0N/A * Methods are defined final to ensure that they are not accidentally
0N/A * overridden in SSLSocketImpl.
0N/A *
0N/A * @see javax.net.ssl.SSLSocket
0N/A * @see SSLSocketImpl
0N/A *
0N/A */
0N/Aabstract class BaseSSLSocketImpl extends SSLSocket {
0N/A
0N/A /*
0N/A * Normally "self" is "this" ... but not when this connection is
0N/A * layered over a preexisting socket. If we're using an existing
0N/A * socket, we delegate some actions to it. Else, we delegate
0N/A * instead to "super". This is important to ensure that we don't
0N/A * recurse infinitely ... e.g. close() calling itself, or doing
0N/A * I/O in terms of our own streams.
0N/A */
0N/A final Socket self;
0N/A
0N/A BaseSSLSocketImpl() {
0N/A super();
0N/A this.self = this;
0N/A }
0N/A
0N/A BaseSSLSocketImpl(Socket socket) {
0N/A super();
0N/A this.self = socket;
0N/A }
0N/A
0N/A //
0N/A // CONSTANTS AND STATIC METHODS
0N/A //
0N/A
0N/A /**
0N/A * TLS requires that a close_notify warning alert is sent before the
0N/A * connection is closed in order to avoid truncation attacks. Some
0N/A * implementations (MS IIS and others) don't do that. The property
0N/A * below controls whether we accept that or treat it as an error.
0N/A *
0N/A * The default is "false", i.e. tolerate the broken behavior.
0N/A */
0N/A private final static String PROP_NAME =
0N/A "com.sun.net.ssl.requireCloseNotify";
0N/A
0N/A final static boolean requireCloseNotify =
0N/A Debug.getBooleanProperty(PROP_NAME, false);
0N/A
0N/A //
0N/A // MISC SOCKET METHODS
0N/A //
0N/A
0N/A /**
0N/A * Returns the unique {@link java.nio.SocketChannel SocketChannel} object
0N/A * associated with this socket, if any.
0N/A * @see java.net.Socket#getChannel
0N/A */
0N/A public final SocketChannel getChannel() {
0N/A if (self == this) {
0N/A return super.getChannel();
0N/A } else {
0N/A return self.getChannel();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Binds the address to the socket.
0N/A * @see java.net.Socket#bind
0N/A */
0N/A public void bind(SocketAddress bindpoint) throws IOException {
0N/A /*
0N/A * Bind to this socket
0N/A */
0N/A if (self == this) {
0N/A super.bind(bindpoint);
0N/A } else {
0N/A // If we're binding on a layered socket...
0N/A throw new IOException(
0N/A "Underlying socket should already be connected");
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns the address of the endpoint this socket is connected to
0N/A * @see java.net.Socket#getLocalSocketAddress
0N/A */
0N/A public SocketAddress getLocalSocketAddress() {
0N/A if (self == this) {
0N/A return super.getLocalSocketAddress();
0N/A } else {
0N/A return self.getLocalSocketAddress();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns the address of the endpoint this socket is connected to
0N/A * @see java.net.Socket#getRemoteSocketAddress
0N/A */
0N/A public SocketAddress getRemoteSocketAddress() {
0N/A if (self == this) {
0N/A return super.getRemoteSocketAddress();
0N/A } else {
0N/A return self.getRemoteSocketAddress();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Connects this socket to the server.
0N/A *
0N/A * This method is either called on an unconnected SSLSocketImpl by the
0N/A * application, or it is called in the constructor of a regular
0N/A * SSLSocketImpl. If we are layering on top on another socket, then
0N/A * this method should not be called, because we assume that the
0N/A * underlying socket is already connected by the time it is passed to
0N/A * us.
0N/A *
0N/A * @param endpoint the <code>SocketAddress</code>
0N/A * @throws IOException if an error occurs during the connection
0N/A */
0N/A public final void connect(SocketAddress endpoint) throws IOException {
0N/A connect(endpoint, 0);
0N/A }
0N/A
0N/A /**
0N/A * Returns the connection state of the socket.
0N/A * @see java.net.Socket#isConnected
0N/A */
0N/A public final boolean isConnected() {
0N/A if (self == this) {
0N/A return super.isConnected();
0N/A } else {
0N/A return self.isConnected();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns the binding state of the socket.
0N/A * @see java.net.Socket#isBound
0N/A */
0N/A public final boolean isBound() {
0N/A if (self == this) {
0N/A return super.isBound();
0N/A } else {
0N/A return self.isBound();
0N/A }
0N/A }
0N/A
0N/A //
0N/A // CLOSE RELATED METHODS
0N/A //
0N/A
0N/A /**
0N/A * The semantics of shutdownInput is not supported in TLS 1.0
0N/A * spec. Thus when the method is called on an SSL socket, an
0N/A * UnsupportedOperationException will be thrown.
0N/A *
0N/A * @throws UnsupportedOperationException
0N/A */
0N/A public final void shutdownInput() throws IOException {
0N/A throw new UnsupportedOperationException("The method shutdownInput()" +
0N/A " is not supported in SSLSocket");
0N/A }
0N/A
0N/A /**
0N/A * The semantics of shutdownOutput is not supported in TLS 1.0
0N/A * spec. Thus when the method is called on an SSL socket, an
0N/A * UnsupportedOperationException will be thrown.
0N/A *
0N/A * @throws UnsupportedOperationException
0N/A */
0N/A public final void shutdownOutput() throws IOException {
0N/A throw new UnsupportedOperationException("The method shutdownOutput()" +
0N/A " is not supported in SSLSocket");
0N/A
0N/A }
0N/A
0N/A /**
0N/A * Returns the input state of the socket
0N/A * @see java.net.Socket#isInputShutdown
0N/A */
0N/A public final boolean isInputShutdown() {
0N/A if (self == this) {
0N/A return super.isInputShutdown();
0N/A } else {
0N/A return self.isInputShutdown();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns the output state of the socket
0N/A * @see java.net.Socket#isOutputShutdown
0N/A */
0N/A public final boolean isOutputShutdown() {
0N/A if (self == this) {
0N/A return super.isOutputShutdown();
0N/A } else {
0N/A return self.isOutputShutdown();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Ensures that the SSL connection is closed down as cleanly
0N/A * as possible, in case the application forgets to do so.
0N/A * This allows SSL connections to be implicitly reclaimed,
0N/A * rather than forcing them to be explicitly reclaimed at
0N/A * the penalty of prematurly killing SSL sessions.
0N/A */
0N/A protected final void finalize() throws Throwable {
0N/A try {
0N/A close();
0N/A } catch (IOException e1) {
0N/A try {
0N/A if (self == this) {
0N/A super.close();
0N/A }
0N/A } catch (IOException e2) {
0N/A // ignore
0N/A }
0N/A } finally {
709N/A // We called close on the underlying socket above to
709N/A // make doubly sure all resources got released. We
709N/A // don't finalize self in the case of overlain sockets,
709N/A // that's a different object which the GC will finalize
709N/A // separately.
709N/A
0N/A super.finalize();
0N/A }
0N/A }
0N/A
0N/A //
0N/A // GET ADDRESS METHODS
0N/A //
0N/A
0N/A /**
0N/A * Returns the address of the remote peer for this connection.
0N/A */
0N/A public final InetAddress getInetAddress() {
0N/A if (self == this) {
0N/A return super.getInetAddress();
0N/A } else {
0N/A return self.getInetAddress();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Gets the local address to which the socket is bound.
0N/A *
0N/A * @return the local address to which the socket is bound.
0N/A * @since JDK1.1
0N/A */
0N/A public final InetAddress getLocalAddress() {
0N/A if (self == this) {
0N/A return super.getLocalAddress();
0N/A } else {
0N/A return self.getLocalAddress();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns the number of the remote port that this connection uses.
0N/A */
0N/A public final int getPort() {
0N/A if (self == this) {
0N/A return super.getPort();
0N/A } else {
0N/A return self.getPort();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns the number of the local port that this connection uses.
0N/A */
0N/A public final int getLocalPort() {
0N/A if (self == this) {
0N/A return super.getLocalPort();
0N/A } else {
0N/A return self.getLocalPort();
0N/A }
0N/A }
0N/A
0N/A //
0N/A // SOCKET OPTION METHODS
0N/A //
0N/A
0N/A /**
0N/A * Enables or disables the Nagle optimization.
0N/A * @see java.net.Socket#setTcpNoDelay
0N/A */
0N/A public final void setTcpNoDelay(boolean value) throws SocketException {
0N/A if (self == this) {
0N/A super.setTcpNoDelay(value);
0N/A } else {
0N/A self.setTcpNoDelay(value);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns true if the Nagle optimization is disabled. This
0N/A * relates to low-level buffering of TCP traffic, delaying the
0N/A * traffic to promote better throughput.
0N/A *
0N/A * @see java.net.Socket#getTcpNoDelay
0N/A */
0N/A public final boolean getTcpNoDelay() throws SocketException {
0N/A if (self == this) {
0N/A return super.getTcpNoDelay();
0N/A } else {
0N/A return self.getTcpNoDelay();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Assigns the socket's linger timeout.
0N/A * @see java.net.Socket#setSoLinger
0N/A */
0N/A public final void setSoLinger(boolean flag, int linger)
0N/A throws SocketException {
0N/A if (self == this) {
0N/A super.setSoLinger(flag, linger);
0N/A } else {
0N/A self.setSoLinger(flag, linger);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns the socket's linger timeout.
0N/A * @see java.net.Socket#getSoLinger
0N/A */
0N/A public final int getSoLinger() throws SocketException {
0N/A if (self == this) {
0N/A return super.getSoLinger();
0N/A } else {
0N/A return self.getSoLinger();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Send one byte of urgent data on the socket.
0N/A * @see java.net.Socket#sendUrgentData
0N/A * At this point, there seems to be no specific requirement to support
0N/A * this for an SSLSocket. An implementation can be provided if a need
0N/A * arises in future.
0N/A */
0N/A public final void sendUrgentData(int data) throws SocketException {
0N/A throw new SocketException("This method is not supported "
0N/A + "by SSLSockets");
0N/A }
0N/A
0N/A /**
0N/A * Enable/disable OOBINLINE (receipt of TCP urgent data) By default, this
0N/A * option is disabled and TCP urgent data received on a socket is silently
0N/A * discarded.
0N/A * @see java.net.Socket#setOOBInline
0N/A * Setting OOBInline does not have any effect on SSLSocket,
0N/A * since currently we don't support sending urgent data.
0N/A */
0N/A public final void setOOBInline(boolean on) throws SocketException {
0N/A throw new SocketException("This method is ineffective, since"
0N/A + " sending urgent data is not supported by SSLSockets");
0N/A }
0N/A
0N/A /**
0N/A * Tests if OOBINLINE is enabled.
0N/A * @see java.net.Socket#getOOBInline
0N/A */
0N/A public final boolean getOOBInline() throws SocketException {
0N/A throw new SocketException("This method is ineffective, since"
0N/A + " sending urgent data is not supported by SSLSockets");
0N/A }
0N/A
0N/A /**
0N/A * Returns the socket timeout.
0N/A * @see java.net.Socket#getSoTimeout
0N/A */
0N/A public final int getSoTimeout() throws SocketException {
0N/A if (self == this) {
0N/A return super.getSoTimeout();
0N/A } else {
0N/A return self.getSoTimeout();
0N/A }
0N/A }
0N/A
0N/A public final void setSendBufferSize(int size) throws SocketException {
0N/A if (self == this) {
0N/A super.setSendBufferSize(size);
0N/A } else {
0N/A self.setSendBufferSize(size);
0N/A }
0N/A }
0N/A
0N/A public final int getSendBufferSize() throws SocketException {
0N/A if (self == this) {
0N/A return super.getSendBufferSize();
0N/A } else {
0N/A return self.getSendBufferSize();
0N/A }
0N/A }
0N/A
0N/A public final void setReceiveBufferSize(int size) throws SocketException {
0N/A if (self == this) {
0N/A super.setReceiveBufferSize(size);
0N/A } else {
0N/A self.setReceiveBufferSize(size);
0N/A }
0N/A }
0N/A
0N/A public final int getReceiveBufferSize() throws SocketException {
0N/A if (self == this) {
0N/A return super.getReceiveBufferSize();
0N/A } else {
0N/A return self.getReceiveBufferSize();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Enable/disable SO_KEEPALIVE.
0N/A * @see java.net.Socket#setKeepAlive
0N/A */
0N/A public final void setKeepAlive(boolean on) throws SocketException {
0N/A if (self == this) {
0N/A super.setKeepAlive(on);
0N/A } else {
0N/A self.setKeepAlive(on);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Tests if SO_KEEPALIVE is enabled.
0N/A * @see java.net.Socket#getKeepAlive
0N/A */
0N/A public final boolean getKeepAlive() throws SocketException {
0N/A if (self == this) {
0N/A return super.getKeepAlive();
0N/A } else {
0N/A return self.getKeepAlive();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Sets traffic class or type-of-service octet in the IP header for
0N/A * packets sent from this Socket.
0N/A * @see java.net.Socket#setTrafficClass
0N/A */
0N/A public final void setTrafficClass(int tc) throws SocketException {
0N/A if (self == this) {
0N/A super.setTrafficClass(tc);
0N/A } else {
0N/A self.setTrafficClass(tc);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Gets traffic class or type-of-service in the IP header for packets
0N/A * sent from this Socket.
0N/A * @see java.net.Socket#getTrafficClass
0N/A */
0N/A public final int getTrafficClass() throws SocketException {
0N/A if (self == this) {
0N/A return super.getTrafficClass();
0N/A } else {
0N/A return self.getTrafficClass();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Enable/disable SO_REUSEADDR.
0N/A * @see java.net.Socket#setReuseAddress
0N/A */
0N/A public final void setReuseAddress(boolean on) throws SocketException {
0N/A if (self == this) {
0N/A super.setReuseAddress(on);
0N/A } else {
0N/A self.setReuseAddress(on);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Tests if SO_REUSEADDR is enabled.
0N/A * @see java.net.Socket#getReuseAddress
0N/A */
0N/A public final boolean getReuseAddress() throws SocketException {
0N/A if (self == this) {
0N/A return super.getReuseAddress();
0N/A } else {
0N/A return self.getReuseAddress();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Sets performance preferences for this socket.
0N/A *
0N/A * @see java.net.Socket#setPerformancePreferences(int, int, int)
0N/A */
0N/A public void setPerformancePreferences(int connectionTime,
0N/A int latency, int bandwidth) {
0N/A if (self == this) {
0N/A super.setPerformancePreferences(
0N/A connectionTime, latency, bandwidth);
0N/A } else {
0N/A self.setPerformancePreferences(
0N/A connectionTime, latency, bandwidth);
0N/A }
0N/A }
0N/A
0N/A}