001/* 002 * Copyright 2012-2024 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2012-2024 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-2024 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 @NotNull 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(@NotNull 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 @NotNull() 084 public SSLSocketFactory getWrappedSocketFactory() 085 { 086 return factory; 087 } 088 089 090 091 /** 092 * Creates a new SSL socket to the specified server. 093 * 094 * @param host The host to which the connection should be established. 095 * @param port The port to which the connection should be established. 096 * 097 * @return The SSL socket that was created. 098 * 099 * @throws IOException If a problem occurs while creating the socket. 100 */ 101 @Override() 102 @NotNull() 103 public Socket createSocket(@NotNull final String host, final int port) 104 throws IOException 105 { 106 synchronized (factory) 107 { 108 return factory.createSocket(host, port); 109 } 110 } 111 112 113 114 /** 115 * Creates a new SSL socket to the specified server. 116 * 117 * @param host The host to which the connection should be 118 * established. 119 * @param port The port to which the connection should be 120 * established. 121 * @param localAddress The local address to use for the connection. 122 * @param localPort The local port to use for the connection. 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 @NotNull() 130 public Socket createSocket(@NotNull final String host, final int port, 131 @NotNull final InetAddress localAddress, 132 final int localPort) 133 throws IOException 134 { 135 synchronized (factory) 136 { 137 return factory.createSocket(host, port, localAddress, localPort); 138 } 139 } 140 141 142 143 /** 144 * Creates a new SSL socket to the specified server. 145 * 146 * @param address The address to which the connection should be established. 147 * @param port The port to which the connection should be established. 148 * 149 * @return The SSL socket that was created. 150 * 151 * @throws IOException If a problem occurs while creating the socket. 152 */ 153 @Override() 154 @NotNull() 155 public Socket createSocket(@NotNull final InetAddress address, final int port) 156 throws IOException 157 { 158 synchronized (factory) 159 { 160 return factory.createSocket(address, port); 161 } 162 } 163 164 165 166 /** 167 * Creates a new SSL socket to the specified server. 168 * 169 * @param address The address to which the connection should be 170 * established. 171 * @param port The port to which the connection should be 172 * established. 173 * @param localAddress The local address to use for the connection. 174 * @param localPort The local port to use for the connection. 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 @NotNull() 182 public Socket createSocket(@NotNull final InetAddress address, final int port, 183 @NotNull final InetAddress localAddress, 184 final int localPort) 185 throws IOException 186 { 187 synchronized (factory) 188 { 189 return factory.createSocket(address, port, localAddress, localPort); 190 } 191 } 192 193 194 195 /** 196 * Creates a new SSL socket that wraps the provided socket. 197 * 198 * @param s The existing socket to be wrapped to create an SSL 199 * socket. 200 * @param host The host to which the connection is established. 201 * @param port The port to which the connection is established. 202 * @param autoClose Indicates whether the provided socket should be closed 203 * when the created SSL socket is closed. 204 * 205 * @return The SSL socket that was created. 206 * 207 * @throws IOException If a problem occurs while creating the socket. 208 */ 209 @Override() 210 @NotNull() 211 public Socket createSocket(@NotNull final Socket s, 212 @NotNull final String host, final int port, 213 final boolean autoClose) 214 throws IOException 215 { 216 synchronized (factory) 217 { 218 return factory.createSocket(s, host, port, autoClose); 219 } 220 } 221 222 223 224 /** 225 * Retrieves the set of cipher suites which are enabled by default. 226 * 227 * @return The set of cipher suites which are enabled by default. 228 */ 229 @Override() 230 @NotNull() 231 public String[] getDefaultCipherSuites() 232 { 233 synchronized (factory) 234 { 235 return factory.getDefaultCipherSuites(); 236 } 237 } 238 239 240 241 /** 242 * Retrieves the entire set of cipher suites that could be used. 243 * 244 * @return The entire set of cipher suites that could be used. 245 */ 246 @Override() 247 @NotNull() 248 public String[] getSupportedCipherSuites() 249 { 250 synchronized (factory) 251 { 252 return factory.getSupportedCipherSuites(); 253 } 254 } 255}