Skip to content

Commit c542dc9

Browse files
committed
8325579: Inconsistent behavior in com.sun.jndi.ldap.Connection::createSocket
Reviewed-by: mbaesken Backport-of: 32bf1f4169fd07291d608323c143832ad48e531e
1 parent 4202063 commit c542dc9

File tree

3 files changed

+212
-116
lines changed

3 files changed

+212
-116
lines changed

src/java.naming/share/classes/com/sun/jndi/ldap/Connection.java

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -120,17 +120,15 @@
120120
public final class Connection implements Runnable {
121121

122122
private static final boolean debug = false;
123-
private static final int dump = 0; // > 0 r, > 1 rw
124-
125123

126124
final private Thread worker; // Initialized in constructor
127125

128-
private boolean v3 = true; // Set in setV3()
126+
private boolean v3 = true; // Set in setV3()
129127

130-
final public String host; // used by LdapClient for generating exception messages
131-
// used by StartTlsResponse when creating an SSL socket
132-
final public int port; // used by LdapClient for generating exception messages
133-
// used by StartTlsResponse when creating an SSL socket
128+
public final String host; // used by LdapClient for generating exception messages
129+
// used by StartTlsResponse when creating an SSL socket
130+
public final int port; // used by LdapClient for generating exception messages
131+
// used by StartTlsResponse when creating an SSL socket
134132

135133
private boolean bound = false; // Set in setBound()
136134

@@ -319,30 +317,37 @@ private SocketFactory getSocketFactory(String socketFactoryName) throws Exceptio
319317
}
320318

321319
private Socket createConnectionSocket(String host, int port, SocketFactory factory,
322-
int connectTimeout) throws Exception {
320+
int connectTimeout) throws IOException {
323321
Socket socket = null;
324322

323+
// if timeout is supplied, try to use unconnected socket for connecting with timeout
325324
if (connectTimeout > 0) {
326-
// create unconnected socket and then connect it if timeout
327-
// is supplied
328-
InetSocketAddress endpoint =
329-
createInetSocketAddress(host, port);
330-
// unconnected socket
331-
socket = factory.createSocket();
332-
// connect socket with a timeout
333-
socket.connect(endpoint, connectTimeout);
334325
if (debug) {
335-
System.err.println("Connection: creating socket with " +
336-
"a connect timeout");
326+
System.err.println("Connection: creating socket with a connect timeout");
327+
}
328+
try {
329+
// unconnected socket
330+
socket = factory.createSocket();
331+
} catch (IOException e) {
332+
// unconnected socket is likely not supported by the SocketFactory
333+
if (debug) {
334+
System.err.println("Connection: unconnected socket not supported by SocketFactory");
335+
}
336+
}
337+
if (socket != null) {
338+
InetSocketAddress endpoint = createInetSocketAddress(host, port);
339+
// connect socket with a timeout
340+
socket.connect(endpoint, connectTimeout);
337341
}
338342
}
343+
344+
// either no timeout was supplied or unconnected socket did not work
339345
if (socket == null) {
340346
// create connected socket
341-
socket = factory.createSocket(host, port);
342347
if (debug) {
343-
System.err.println("Connection: creating connected socket with" +
344-
" no connect timeout");
348+
System.err.println("Connection: creating connected socket with no connect timeout");
345349
}
350+
socket = factory.createSocket(host, port);
346351
}
347352
return socket;
348353
}
@@ -351,7 +356,7 @@ private Socket createConnectionSocket(String host, int port, SocketFactory facto
351356
// the SSL handshake following socket connection as part of the timeout.
352357
// So explicitly set a socket read timeout, trigger the SSL handshake,
353358
// then reset the timeout.
354-
private void initialSSLHandshake(SSLSocket sslSocket , int connectTimeout) throws Exception {
359+
private void initialSSLHandshake(SSLSocket sslSocket, int connectTimeout) throws Exception {
355360

356361
if (!IS_HOSTNAME_VERIFICATION_DISABLED) {
357362
SSLParameters param = sslSocket.getSSLParameters();

src/java.naming/share/classes/module-info.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -36,21 +36,33 @@
3636
* The following implementation specific properties are supported by the
3737
* default LDAP Naming Service Provider implementation in the JDK:
3838
* <ul>
39+
* <li>{@code java.naming.ldap.factory.socket}:
40+
* <br>The value of this environment property specifies the fully
41+
* qualified class name of the socket factory used by the LDAP provider.
42+
* This class must implement the {@link javax.net.SocketFactory} abstract class
43+
* and provide an implementation of the static "getDefault()" method that
44+
* returns an instance of the socket factory. By default the environment
45+
* property is not set.
46+
* </li>
3947
* <li>{@code com.sun.jndi.ldap.connect.timeout}:
40-
* <br>The value of this property is the string representation
41-
* of an integer representing the connection timeout in
42-
* milliseconds. If the LDAP provider cannot establish a
43-
* connection within that period, it aborts the connection attempt.
48+
* <br>The value of this environment property is the string representation
49+
* of an integer specifying the connection timeout in milliseconds.
50+
* If the LDAP provider cannot establish a connection within that period,
51+
* it aborts the connection attempt.
4452
* The integer should be greater than zero. An integer less than
4553
* or equal to zero means to use the network protocol's (i.e., TCP's)
4654
* timeout value.
4755
* <br> If this property is not specified, the default is to wait
4856
* for the connection to be established or until the underlying
4957
* network times out.
58+
* <br> If a custom socket factory is provided via environment property
59+
* {@code java.naming.ldap.factory.socket} and unconnected sockets
60+
* are not supported, the specified timeout is ignored
61+
* and the provider behaves as if no connection timeout was set.
5062
* </li>
5163
* <li>{@code com.sun.jndi.ldap.read.timeout}:
5264
* <br>The value of this property is the string representation
53-
* of an integer representing the read timeout in milliseconds
65+
* of an integer specifying the read timeout in milliseconds
5466
* for LDAP operations. If the LDAP provider cannot get a LDAP
5567
* response within that period, it aborts the read attempt. The
5668
* integer should be greater than zero. An integer less than or

0 commit comments

Comments
 (0)