29 import java.io.BufferedOutputStream; |
29 import java.io.BufferedOutputStream; |
30 import java.io.InterruptedIOException; |
30 import java.io.InterruptedIOException; |
31 import java.io.IOException; |
31 import java.io.IOException; |
32 import java.io.OutputStream; |
32 import java.io.OutputStream; |
33 import java.io.InputStream; |
33 import java.io.InputStream; |
|
34 import java.net.InetSocketAddress; |
34 import java.net.Socket; |
35 import java.net.Socket; |
35 import javax.net.ssl.SSLSocket; |
36 import javax.net.ssl.SSLSocket; |
36 |
37 |
37 import javax.naming.CommunicationException; |
38 import javax.naming.CommunicationException; |
38 import javax.naming.ServiceUnavailableException; |
39 import javax.naming.ServiceUnavailableException; |
40 import javax.naming.InterruptedNamingException; |
41 import javax.naming.InterruptedNamingException; |
41 |
42 |
42 import javax.naming.ldap.Control; |
43 import javax.naming.ldap.Control; |
43 |
44 |
44 import java.lang.reflect.Method; |
45 import java.lang.reflect.Method; |
45 import java.lang.reflect.Constructor; |
|
46 import java.lang.reflect.InvocationTargetException; |
46 import java.lang.reflect.InvocationTargetException; |
47 import java.util.Arrays; |
47 import java.util.Arrays; |
48 import sun.misc.IOUtils; |
48 import sun.misc.IOUtils; |
49 //import javax.net.SocketFactory; |
49 import javax.net.SocketFactory; |
50 |
50 |
51 /** |
51 /** |
52 * A thread that creates a connection to an LDAP server. |
52 * A thread that creates a connection to an LDAP server. |
53 * After the connection, the thread reads from the connection. |
53 * After the connection, the thread reads from the connection. |
54 * A caller can invoke methods on the instance to read LDAP responses |
54 * A caller can invoke methods on the instance to read LDAP responses |
217 CommunicationException ce = |
217 CommunicationException ce = |
218 new CommunicationException(host + ":" + port); |
218 new CommunicationException(host + ":" + port); |
219 ce.setRootCause(realException); |
219 ce.setRootCause(realException); |
220 throw ce; |
220 throw ce; |
221 } catch (Exception e) { |
221 } catch (Exception e) { |
222 // Class.forName() seems to do more error checking |
222 // We need to have a catch all here and |
223 // and will throw IllegalArgumentException and such. |
|
224 // That's why we need to have a catch all here and |
|
225 // ignore generic exceptions. |
223 // ignore generic exceptions. |
226 // Also catches all IO errors generated by socket creation. |
224 // Also catches all IO errors generated by socket creation. |
227 CommunicationException ce = |
225 CommunicationException ce = |
228 new CommunicationException(host + ":" + port); |
226 new CommunicationException(host + ":" + port); |
229 ce.setRootCause(e); |
227 ce.setRootCause(e); |
236 } |
234 } |
237 |
235 |
238 /* |
236 /* |
239 * Create an InetSocketAddress using the specified hostname and port number. |
237 * Create an InetSocketAddress using the specified hostname and port number. |
240 */ |
238 */ |
241 private Object createInetSocketAddress(String host, int port) |
239 private InetSocketAddress createInetSocketAddress(String host, int port) { |
242 throws NoSuchMethodException { |
240 return new InetSocketAddress(host, port); |
243 |
|
244 try { |
|
245 Class<?> inetSocketAddressClass = |
|
246 Class.forName("java.net.InetSocketAddress"); |
|
247 |
|
248 Constructor<?> inetSocketAddressCons = |
|
249 inetSocketAddressClass.getConstructor(new Class<?>[]{ |
|
250 String.class, int.class}); |
|
251 |
|
252 return inetSocketAddressCons.newInstance(new Object[]{ |
|
253 host, new Integer(port)}); |
|
254 |
|
255 } catch (ClassNotFoundException | |
|
256 InstantiationException | |
|
257 InvocationTargetException | |
|
258 IllegalAccessException e) { |
|
259 throw new NoSuchMethodException(); |
|
260 |
|
261 } |
|
262 } |
241 } |
263 |
242 |
264 /* |
243 /* |
265 * Create a Socket object using the specified socket factory and time limit. |
244 * Create a Socket object using the specified socket factory and time limit. |
266 * |
245 * |
277 |
256 |
278 if (socketFactory != null) { |
257 if (socketFactory != null) { |
279 |
258 |
280 // create the factory |
259 // create the factory |
281 |
260 |
282 Class<?> socketFactoryClass = Obj.helper.loadClass(socketFactory); |
261 Class<? extends SocketFactory> socketFactoryClass = |
|
262 (Class<? extends SocketFactory>) Obj.helper.loadClass |
|
263 (socketFactory); |
283 Method getDefault = |
264 Method getDefault = |
284 socketFactoryClass.getMethod("getDefault", new Class<?>[]{}); |
265 socketFactoryClass.getMethod("getDefault", new Class<?>[]{}); |
285 Object factory = getDefault.invoke(null, new Object[]{}); |
266 SocketFactory factory = (SocketFactory) getDefault.invoke(null, new Object[]{}); |
286 |
267 |
287 // create the socket |
268 // create the socket |
288 |
269 |
289 Method createSocket = null; |
|
290 |
|
291 if (connectTimeout > 0) { |
270 if (connectTimeout > 0) { |
292 |
271 |
293 try { |
272 InetSocketAddress endpoint = |
294 createSocket = socketFactoryClass.getMethod("createSocket", |
273 createInetSocketAddress(host, port); |
295 new Class<?>[]{}); |
274 |
296 |
275 // unconnected socket |
297 Method connect = Socket.class.getMethod("connect", |
276 socket = factory.createSocket(); |
298 new Class<?>[]{Class.forName("java.net.SocketAddress"), |
277 |
299 int.class}); |
278 if (debug) { |
300 Object endpoint = createInetSocketAddress(host, port); |
279 System.err.println("Connection: creating socket with " + |
301 |
|
302 // unconnected socket |
|
303 socket = |
|
304 (Socket)createSocket.invoke(factory, new Object[]{}); |
|
305 |
|
306 if (debug) { |
|
307 System.err.println("Connection: creating socket with " + |
|
308 "a timeout using supplied socket factory"); |
280 "a timeout using supplied socket factory"); |
309 } |
281 } |
310 |
282 |
311 // connected socket |
283 // connected socket |
312 connect.invoke(socket, new Object[]{ |
284 socket.connect(endpoint, connectTimeout); |
313 endpoint, new Integer(connectTimeout)}); |
285 } |
314 |
286 |
315 } catch (NoSuchMethodException e) { |
287 // continue (but ignore connectTimeout) |
316 // continue (but ignore connectTimeout) |
|
317 } |
|
318 } |
|
319 |
|
320 if (socket == null) { |
288 if (socket == null) { |
321 createSocket = socketFactoryClass.getMethod("createSocket", |
|
322 new Class<?>[]{String.class, int.class}); |
|
323 |
|
324 if (debug) { |
289 if (debug) { |
325 System.err.println("Connection: creating socket using " + |
290 System.err.println("Connection: creating socket using " + |
326 "supplied socket factory"); |
291 "supplied socket factory"); |
327 } |
292 } |
328 // connected socket |
293 // connected socket |
329 socket = (Socket) createSocket.invoke(factory, |
294 socket = factory.createSocket(host, port); |
330 new Object[]{host, new Integer(port)}); |
|
331 } |
295 } |
332 } else { |
296 } else { |
333 |
297 |
334 if (connectTimeout > 0) { |
298 if (connectTimeout > 0) { |
335 |
299 |
336 try { |
300 InetSocketAddress endpoint = createInetSocketAddress(host, port); |
337 Constructor<Socket> socketCons = |
301 |
338 Socket.class.getConstructor(new Class<?>[]{}); |
302 socket = new Socket(); |
339 |
|
340 Method connect = Socket.class.getMethod("connect", |
|
341 new Class<?>[]{Class.forName("java.net.SocketAddress"), |
|
342 int.class}); |
|
343 Object endpoint = createInetSocketAddress(host, port); |
|
344 |
|
345 socket = socketCons.newInstance(new Object[]{}); |
|
346 |
303 |
347 if (debug) { |
304 if (debug) { |
348 System.err.println("Connection: creating socket with " + |
305 System.err.println("Connection: creating socket with " + |
349 "a timeout"); |
306 "a timeout"); |
350 } |
307 } |
351 connect.invoke(socket, new Object[]{ |
308 socket.connect(endpoint, connectTimeout); |
352 endpoint, new Integer(connectTimeout)}); |
309 } |
353 |
310 |
354 } catch (NoSuchMethodException e) { |
311 // continue (but ignore connectTimeout) |
355 // continue (but ignore connectTimeout) |
|
356 } |
|
357 } |
|
358 |
312 |
359 if (socket == null) { |
313 if (socket == null) { |
360 if (debug) { |
314 if (debug) { |
361 System.err.println("Connection: creating socket"); |
315 System.err.println("Connection: creating socket"); |
362 } |
316 } |