001/*
002 * Copyright 2012-2020 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2012-2020 Ping Identity Corporation
007 *
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *    http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 */
020/*
021 * Copyright (C) 2012-2020 Ping Identity Corporation
022 *
023 * This program is free software; you can redistribute it and/or modify
024 * it under the terms of the GNU General Public License (GPLv2 only)
025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
026 * as published by the Free Software Foundation.
027 *
028 * This program is distributed in the hope that it will be useful,
029 * but WITHOUT ANY WARRANTY; without even the implied warranty of
030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
031 * GNU General Public License for more details.
032 *
033 * You should have received a copy of the GNU General Public License
034 * along with this program; if not, see <http://www.gnu.org/licenses>.
035 */
036package com.unboundid.util;
037
038
039
040import java.io.IOException;
041import java.net.InetAddress;
042import java.net.Socket;
043import javax.net.ssl.SSLSocketFactory;
044
045
046
047/**
048 * This class provides an implementation of a Java socket factory that will
049 * wrap a provided socket factory but will synchronize on each use of that
050 * factory to ensure that only a single thread may use that factory to create
051 * a socket at any given time.
052 */
053@NotMutable()
054@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
055public final class SynchronizedSSLSocketFactory
056       extends SSLSocketFactory
057{
058  // The wrapped SSL socket factory.
059  private final SSLSocketFactory factory;
060
061
062
063  /**
064   * Creates a new synchronous socket factory instance that will wrap the
065   * provided socket factory.
066   *
067   * @param  factory  The socket factory to be wrapped.
068   */
069  public SynchronizedSSLSocketFactory(final SSLSocketFactory factory)
070  {
071    this.factory = factory;
072  }
073
074
075
076  /**
077   * Retrieves the {@code SSLSocketFactory} instance wrapped by this
078   * synchronized SSL socket factory.
079   *
080   * @return  The {@code SSLSocketFactory} instance wrapped by this synchronized
081   *          SSL socket factory.
082   */
083  public SSLSocketFactory getWrappedSocketFactory()
084  {
085    return factory;
086  }
087
088
089
090  /**
091   * Creates a new SSL socket to the specified server.
092   *
093   * @param  host  The host to which the connection should be established.
094   * @param  port  The port to which the connection should be established.
095   *
096   * @return  The SSL socket that was created.
097   *
098   * @throws  IOException  If a problem occurs while creating the socket.
099   */
100  @Override()
101  public Socket createSocket(final String host, final int port)
102         throws IOException
103  {
104    synchronized (factory)
105    {
106      return factory.createSocket(host, port);
107    }
108  }
109
110
111
112  /**
113   * Creates a new SSL socket to the specified server.
114   *
115   * @param  host          The host to which the connection should be
116   *                       established.
117   * @param  port          The port to which the connection should be
118   *                       established.
119   * @param  localAddress  The local address to use for the connection.  This
120   *                       will be ignored.
121   * @param  localPort     The local port to use for the connection.  This will
122   *                       be ignored.
123   *
124   * @return  The SSL socket that was created.
125   *
126   * @throws  IOException  If a problem occurs while creating the socket.
127   */
128  @Override()
129  public Socket createSocket(final String host, final int port,
130                             final InetAddress localAddress,
131                             final int localPort)
132         throws IOException
133  {
134    synchronized (factory)
135    {
136      return factory.createSocket(host, port, localAddress, localPort);
137    }
138  }
139
140
141
142  /**
143   * Creates a new SSL socket to the specified server.
144   *
145   * @param  address  The address to which the connection should be established.
146   * @param  port     The port to which the connection should be established.
147   *
148   * @return  The SSL socket that was created.
149   *
150   * @throws  IOException  If a problem occurs while creating the socket.
151   */
152  @Override()
153  public Socket createSocket(final InetAddress address, final int port)
154         throws IOException
155  {
156    synchronized (factory)
157    {
158      return factory.createSocket(address, port);
159    }
160  }
161
162
163
164  /**
165   * Creates a new SSL socket to the specified server.
166   *
167   * @param  address       The address to which the connection should be
168   *                       established.
169   * @param  port          The port to which the connection should be
170   *                       established.
171   * @param  localAddress  The local address to use for the connection.  This
172   *                       will be ignored.
173   * @param  localPort     The local port to use for the connection.  This will
174   *                       be ignored.
175   *
176   * @return  The SSL socket that was created.
177   *
178   * @throws  IOException  If a problem occurs while creating the socket.
179   */
180  @Override()
181  public Socket createSocket(final InetAddress address, final int port,
182                             final InetAddress localAddress,
183                             final int localPort)
184         throws IOException
185  {
186    synchronized (factory)
187    {
188      return factory.createSocket(address, port, localAddress, localPort);
189    }
190  }
191
192
193
194  /**
195   * Creates a new SSL socket that wraps the provided socket.
196   *
197   * @param  s          The existing socket to be wrapped to create an SSL
198   *                    socket.
199   * @param  host       The host to which the connection is established.
200   * @param  port       The port to which the connection is established.
201   * @param  autoClose  Indicates whether the provided socket should be closed
202   *                    when the created SSL socket is closed.
203   *
204   * @return  The SSL socket that was created.
205   *
206   * @throws  IOException  If a problem occurs while creating the socket.
207   */
208  @Override()
209  public Socket createSocket(final Socket s, final String host, final int port,
210                             final boolean autoClose)
211         throws IOException
212  {
213    synchronized (factory)
214    {
215      return factory.createSocket(s, host, port, autoClose);
216    }
217  }
218
219
220
221  /**
222   * Retrieves the set of cipher suites which are enabled by default.
223   *
224   * @return  The set of cipher suites which are enabled by default.
225   */
226  @Override()
227  public String[] getDefaultCipherSuites()
228  {
229    synchronized (factory)
230    {
231      return factory.getDefaultCipherSuites();
232    }
233  }
234
235
236
237  /**
238   * Retrieves the entire set of cipher suites that could be used.
239   *
240   * @return  The entire set of cipher suites that could be used.
241   */
242  @Override()
243  public String[] getSupportedCipherSuites()
244  {
245    synchronized (factory)
246    {
247      return factory.getSupportedCipherSuites();
248    }
249  }
250}