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