001/* 002 * Copyright 2007-2020 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2007-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) 2008-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.ldap.sdk; 037 038 039 040import java.lang.reflect.Method; 041import java.net.InetAddress; 042import java.util.Arrays; 043import java.util.Collections; 044import java.util.EnumMap; 045import java.util.HashMap; 046import java.util.Map; 047import java.util.logging.Level; 048 049import com.unboundid.ldap.sdk.extensions.PasswordModifyExtendedRequest; 050import com.unboundid.ldap.sdk.extensions.StartTLSExtendedRequest; 051import com.unboundid.ldap.sdk.extensions.WhoAmIExtendedRequest; 052import com.unboundid.ldap.sdk.unboundidds.extensions. 053 DeregisterYubiKeyOTPDeviceExtendedRequest; 054import com.unboundid.ldap.sdk.unboundidds.extensions. 055 EndAdministrativeSessionExtendedRequest; 056import com.unboundid.ldap.sdk.unboundidds.extensions. 057 GenerateTOTPSharedSecretExtendedRequest; 058import com.unboundid.ldap.sdk.unboundidds.extensions. 059 GetConnectionIDExtendedRequest; 060import com.unboundid.ldap.sdk.unboundidds.extensions. 061 GetPasswordQualityRequirementsExtendedRequest; 062import com.unboundid.ldap.sdk.unboundidds.extensions. 063 PasswordPolicyStateExtendedRequest; 064import com.unboundid.ldap.sdk.unboundidds.extensions. 065 RegisterYubiKeyOTPDeviceExtendedRequest; 066import com.unboundid.ldap.sdk.unboundidds.extensions. 067 RevokeTOTPSharedSecretExtendedRequest; 068import com.unboundid.ldap.sdk.unboundidds.extensions. 069 StartAdministrativeSessionExtendedRequest; 070import com.unboundid.ldap.sdk.unboundidds.extensions. 071 ValidateTOTPPasswordExtendedRequest; 072import com.unboundid.util.Debug; 073import com.unboundid.util.DebugType; 074import com.unboundid.util.Mutable; 075import com.unboundid.util.StaticUtils; 076import com.unboundid.util.ThreadSafety; 077import com.unboundid.util.ThreadSafetyLevel; 078import com.unboundid.util.Validator; 079import com.unboundid.util.ssl.SSLSocketVerifier; 080import com.unboundid.util.ssl.TrustAllSSLSocketVerifier; 081 082 083 084/** 085 * This class provides a data structure that may be used to configure a number 086 * of connection-related properties. Elements included in the set of connection 087 * options include: 088 * <UL> 089 * <LI>A flag that indicates whether the SDK should attempt to automatically 090 * re-establish a connection if it is unexpectedly closed. By default, 091 * it will not attempt to do so.</LI> 092 * <LI>A flag that indicates whether simple bind attempts that contain a 093 * non-empty DN will be required to have a non-empty password. By 094 * default, a password will be required in such cases.</LI> 095 * <LI>A flag that indicates whether to automatically attempt to follow any 096 * referrals that may be returned by the server. By default, it will not 097 * automatically attempt to follow referrals.</LI> 098 * <LI>A referral hop limit, which indicates the maximum number of hops that 099 * the connection may take when trying to follow a referral. The default 100 * referral hop limit is five.</LI> 101 * <LI>The referral connector that should be used to create and optionally 102 * authenticate connections used to follow referrals encountered during 103 * processing. By default, referral connections will use the same socket 104 * factory and bind request as the client connection on which the referral 105 * was received.</LI> 106 * <LI>A flag that indicates whether to use the SO_KEEPALIVE socket option to 107 * attempt to more quickly detect when idle TCP connections have been lost 108 * or to prevent them from being unexpectedly closed by intermediate 109 * network hardware. By default, the SO_KEEPALIVE socket option will be 110 * used.</LI> 111 * <LI>A flag that indicates whether to use the SO_LINGER socket option to 112 * indicate how long a connection should linger after it has been closed, 113 * and a value that specifies the length of time that it should linger. 114 * By default, the SO_LINGER option will be used with a timeout of 5 115 * seconds.</LI> 116 * <LI>A flag that indicates whether to use the SO_REUSEADDR socket option to 117 * indicate that a socket in a TIME_WAIT state may be reused. By default, 118 * the SO_REUSEADDR socket option will be used.</LI> 119 * <LI>A flag that indicates whether to operate in synchronous mode, in which 120 * connections may exhibit better performance and will not require a 121 * separate reader thread, but will not allow multiple concurrent 122 * operations to be used on the same connection.</LI> 123 * <LI>A flag that indicates whether to use the TCP_NODELAY socket option to 124 * indicate that any data written to the socket will be sent immediately 125 * rather than delaying for a short amount of time to see if any more data 126 * is to be sent that could potentially be included in the same packet. 127 * By default, the TCP_NODELAY socket option will be used.</LI> 128 * <LI>A value that specifies the maximum length of time in milliseconds that 129 * an attempt to establish a connection should be allowed to block before 130 * failing. By default, a timeout of 10,000 milliseconds (10 seconds) 131 * will be used.</LI> 132 * <LI>A value that specifies the default timeout in milliseconds that the SDK 133 * should wait for a response from the server before failing. This can be 134 * defined on a per-operation-type basis, with a default of 300,000 135 * milliseconds (5 minutes) for search and extended operations, and a 136 * default timeout of 30,000 milliseconds (30 seconds) for all other types 137 * of operations. Further, the extended operation timeout can be 138 * customized on a per-operation-type basis, and a number of extended 139 * operation types have been configured with a 30,000 millisecond timeout 140 * by default. Individual requests can also be configured with their own 141 * response timeouts, and if provided, that timeout will override the 142 * default timeout from the connection options.</LI> 143 * <LI>A flag that indicates whether to attempt to abandon any request for 144 * which no response is received after waiting for the maximum response 145 * timeout. By default, no abandon request will be sent.</LI> 146 * <LI>A value which specifies the largest LDAP message size that the SDK will 147 * be willing to read from the directory server. By default, the SDK will 148 * not allow responses larger than 20,971,520 bytes (20MB). If it 149 * encounters a message that may be larger than the maximum allowed 150 * message size, then the SDK will terminate the connection to the 151 * server.</LI> 152 * <LI>The {@link LDAPConnectionLogger} that should be used to record 153 * information about requests sent and responses received over 154 * connections with this set of options. By default, no 155 * {@code LDAPConnectionLogger} will be used.</LI> 156 * <LI>The {@link DisconnectHandler} that should be used to receive 157 * notification if connection is disconnected for any reason. By default, 158 * no {@code DisconnectHandler} will be used.</LI> 159 * <LI>The {@link UnsolicitedNotificationHandler} that should be used to 160 * receive notification about any unsolicited notifications returned by 161 * the server. By default, no {@code UnsolicitedNotificationHandler} will 162 * be used.</LI> 163 * <LI>A flag that indicates whether to capture a thread stack trace whenever 164 * a new connection is established. Capturing a thread stack trace when 165 * establishing a connection may be marginally expensive, but can be 166 * useful for debugging certain kinds of problems like leaked connections 167 * (connections that are established but never explicitly closed). By 168 * default, connect stack traces will not be captured.</LI> 169 * <LI>A flag that indicates whether connections should try to retrieve schema 170 * information from the server, which may be used to better determine 171 * which matching rules should be used when comparing attribute values. 172 * By default, server schema information will not be retrieved.</LI> 173 * <LI>The size of the socket receive buffer, which may be used for 174 * temporarily holding data received from the directory server until it 175 * can be read and processed by the LDAP SDK. By default, the receive 176 * buffer size will be automatically determined by the JVM based on the 177 * underlying system settings.</LI> 178 * <LI>The size of the socket send buffer, which may be used for temporarily 179 * holding data to be sent to the directory server until it can actually 180 * be transmitted over the network. By default, the send buffer size will 181 * be automatically determined by the JVM based on the underlying system 182 * settings.</LI> 183 * <LI>A flag which indicates whether to allow a single socket factory instance 184 * (which may be shared across multiple connections) to be used to create 185 * multiple concurrent connections. This offers better and more 186 * predictable performance on some JVM implementations (especially when 187 * connection attempts fail as a result of a connection timeout), but some 188 * JVMs are known to use non-threadsafe socket factory implementations and 189 * may fail from concurrent use (for example, at least some IBM JVMs 190 * exhibit this behavior). By default, Sun/Oracle JVMs will allow 191 * concurrent socket factory use, but JVMs from other vendors will use 192 * synchronization to ensure that a socket factory will only be allowed to 193 * create one connection at a time.</LI> 194 * <LI>A class that may be used to perform additional verification (e.g., 195 * hostname validation) for any {@code SSLSocket} instances created. By 196 * default, no special verification will be performed.</LI> 197 * </UL> 198 */ 199@Mutable() 200@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE) 201public final class LDAPConnectionOptions 202{ 203 /** 204 * The prefix that will be used in conjunction with all system properties. 205 */ 206 private static final String PROPERTY_PREFIX = 207 LDAPConnectionOptions.class.getName() + '.'; 208 209 210 211 /** 212 * The name of a system property that can be used to specify the initial 213 * default value for the "abandon on timeout" behavior. If this property is 214 * set at the time that this class is loaded, then its value must be either 215 * "true" or "false". If this property is not set, then a default value of 216 * "false" will be assumed. 217 * <BR><BR> 218 * The full name for this system property is 219 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultAbandonTimeout". 220 */ 221 public static final String PROPERTY_DEFAULT_ABANDON_ON_TIMEOUT = 222 PROPERTY_PREFIX + "defaultAbandonOnTimeout"; 223 224 225 226 /** 227 * The default value for the setting that controls whether to automatically 228 * attempt to abandon any request for which no response is received within the 229 * maximum response timeout. If the 230 * {@link #PROPERTY_DEFAULT_ABANDON_ON_TIMEOUT} system property is set at the 231 * time this class is loaded, then its value will be used. Otherwise, a 232 * default of {@code false} will be used. 233 */ 234 private static final boolean DEFAULT_ABANDON_ON_TIMEOUT = 235 getSystemProperty(PROPERTY_DEFAULT_ABANDON_ON_TIMEOUT, false); 236 237 238 239 /** 240 * The default value ({@code false}) for the setting that controls whether to 241 * automatically attempt to reconnect if a connection is unexpectedly lost. 242 */ 243 private static final boolean DEFAULT_AUTO_RECONNECT = false; 244 245 246 247 /** 248 * The name of a system property that can be used to specify the initial 249 * default value for the "bind with DN requires password" behavior. If this 250 * property is set at the time that this class is loaded, then its value must 251 * be either "true" or "false". If this property is not set, then a default 252 * value of "true" will be assumed. 253 * <BR><BR> 254 * The full name for this system property is 255 * "com.unboundid.ldap.sdk.LDAPConnectionOptions. 256 * defaultBindWithDNRequiresPassword". 257 */ 258 public static final String PROPERTY_DEFAULT_BIND_WITH_DN_REQUIRES_PASSWORD = 259 PROPERTY_PREFIX + "defaultBindWithDNRequiresPassword"; 260 261 262 263 /** 264 * The default value for the setting that controls whether simple bind 265 * requests with a DN will also be required to contain a password. If the 266 * {@link #PROPERTY_DEFAULT_BIND_WITH_DN_REQUIRES_PASSWORD} system property is 267 * set at the time this class is loaded, then its value will be used. 268 * Otherwise, a default of {@code true} will be used. 269 */ 270 private static final boolean DEFAULT_BIND_WITH_DN_REQUIRES_PASSWORD = 271 getSystemProperty(PROPERTY_DEFAULT_BIND_WITH_DN_REQUIRES_PASSWORD, true); 272 273 274 275 /** 276 * The name of a system property that can be used to specify the initial 277 * default value for the "capture connect stack trace" behavior. If this 278 * property is set at the time that this class is loaded, then its value must 279 * be either "true" or "false". If this property is not set, then a default 280 * value of "false" will be assumed. 281 * <BR><BR> 282 * The full name for this system property is "com.unboundid.ldap.sdk. 283 * LDAPConnectionOptions.defaultCaptureConnectStackTrace". 284 */ 285 public static final String PROPERTY_DEFAULT_CAPTURE_CONNECT_STACK_TRACE = 286 PROPERTY_PREFIX + "defaultCaptureConnectStackTrace"; 287 288 289 290 /** 291 * The default value for the setting that controls whether to capture a thread 292 * stack trace whenever an attempt is made to establish a connection. If the 293 * {@link #PROPERTY_DEFAULT_CAPTURE_CONNECT_STACK_TRACE} system property is 294 * set at the time this class is loaded, then its value will be used. 295 * Otherwise, a default of {@code false} will be used. 296 */ 297 private static final boolean DEFAULT_CAPTURE_CONNECT_STACK_TRACE = 298 getSystemProperty(PROPERTY_DEFAULT_CAPTURE_CONNECT_STACK_TRACE, false); 299 300 301 302 /** 303 * The name of a system property that can be used to specify the initial 304 * default value for the "follow referrals" behavior. If this property is set 305 * at the time that this class is loaded, then its value must be either 306 * "true" or "false". If this property is not set, then a default value of 307 * "false" will be assumed. 308 * <BR><BR> 309 * The full name for this system property is 310 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultFollowReferrals". 311 */ 312 public static final String PROPERTY_DEFAULT_FOLLOW_REFERRALS = 313 PROPERTY_PREFIX + "defaultFollowReferrals"; 314 315 316 317 /** 318 * The default value for the setting that controls whether to attempt to 319 * automatically follow referrals. If the 320 * {@link #PROPERTY_DEFAULT_FOLLOW_REFERRALS} system property is set at the 321 * time this class is loaded, then its value will be used. Otherwise, a 322 * default of {@code false} will be used. 323 */ 324 private static final boolean DEFAULT_FOLLOW_REFERRALS = 325 getSystemProperty(PROPERTY_DEFAULT_FOLLOW_REFERRALS, false); 326 327 328 329 /** 330 * The name of a system property that can be used to specify the maximum 331 * number of hops to make when following a referral. If this property is set 332 * at the time that this class is loaded, then its value must be parseable as 333 * an integer. If this property is not set, then a default value of "5" will 334 * be assumed. 335 * <BR><BR> 336 * The full name for this system property is 337 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultReferralHopLimit". 338 */ 339 public static final String PROPERTY_DEFAULT_REFERRAL_HOP_LIMIT = 340 PROPERTY_PREFIX + "defaultReferralHopLimit"; 341 342 343 344 /** 345 * The default value for the setting that controls the referral hop limit. If 346 * the {@link #PROPERTY_DEFAULT_REFERRAL_HOP_LIMIT} system property is set at 347 * the time this class is loaded, then its value will be used. Otherwise, a 348 * default value of 5 will be used. 349 */ 350 private static final int DEFAULT_REFERRAL_HOP_LIMIT = 351 getSystemProperty(PROPERTY_DEFAULT_REFERRAL_HOP_LIMIT, 5); 352 353 354 355 /** 356 * The name of a system property that can be used to specify the initial 357 * default value for the "use schema" behavior. If this property is set at 358 * the time that this class is loaded, then its value must be either "true" or 359 * "false". If this property is not set, then a default value of "false" will 360 * be assumed. 361 * <BR><BR> 362 * The full name for this system property is 363 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultUseSchema". 364 */ 365 public static final String PROPERTY_DEFAULT_USE_SCHEMA = 366 PROPERTY_PREFIX + "defaultUseSchema"; 367 368 369 370 /** 371 * The default value for the setting that controls whether to use schema when 372 * reading data from the server. If the {@link #PROPERTY_DEFAULT_USE_SCHEMA} 373 * system property is set at the time this class is loaded, then its value 374 * will be used. Otherwise, a default value of {@code false} will be used. 375 */ 376 private static final boolean DEFAULT_USE_SCHEMA = 377 getSystemProperty(PROPERTY_DEFAULT_USE_SCHEMA, false); 378 379 380 381 /** 382 * The name of a system property that can be used to specify the initial 383 * default value for the "use pooled schema" behavior. If this property is 384 * set at the time that this class is loaded, then its value must be either 385 * "true" or "false". If this property is not set, then a default value of 386 * "false" will be assumed. 387 * <BR><BR> 388 * The full name for this system property is 389 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultUsePooledSchema". 390 */ 391 public static final String PROPERTY_DEFAULT_USE_POOLED_SCHEMA = 392 PROPERTY_PREFIX + "defaultUsePooledSchema"; 393 394 395 396 /** 397 * The default value for the setting that controls whether all connections in 398 * a connection pool should use the same cached schema object. If the 399 * {@link #PROPERTY_DEFAULT_USE_POOLED_SCHEMA} system property is set at the 400 * time this class is loaded, then its value will be used. Otherwise, a 401 * default of {@code false} will be used. 402 */ 403 private static final boolean DEFAULT_USE_POOLED_SCHEMA = 404 getSystemProperty(PROPERTY_DEFAULT_USE_POOLED_SCHEMA, false); 405 406 407 408 /** 409 * The name of a system property that can be used to specify the initial 410 * default value for the pooled schema timeout, in milliseconds. If this 411 * property is set at the time that this class is loaded, then its value must 412 * be parseable as an integer. If this property is not set, then a default 413 * value of "3600000" (3,600,000 milliseconds, or 1 hour) will be assumed. 414 * <BR><BR> 415 * The full name for this system property is "com.unboundid.ldap.sdk. 416 * LDAPConnectionOptions.defaultPooledSchemaTimeoutMillis". 417 */ 418 public static final String PROPERTY_DEFAULT_POOLED_SCHEMA_TIMEOUT_MILLIS = 419 PROPERTY_PREFIX + "defaultPooledSchemaTimeoutMillis"; 420 421 422 423 /** 424 * The default value for the setting that controls the default pooled schema 425 * timeout. If the {@link #PROPERTY_DEFAULT_POOLED_SCHEMA_TIMEOUT_MILLIS} 426 * system property is set at the time this class is loaded, then its value 427 * will be used. Otherwise, a default of 3,600,000 milliseconds (1 hour) will 428 * be used. 429 */ 430 private static final long DEFAULT_POOLED_SCHEMA_TIMEOUT_MILLIS = 3_600_000L; 431 432 433 434 /** 435 * The name of a system property that can be used to specify the initial 436 * default value for the "use keepalive" behavior. If this property is set at 437 * the time that this class is loaded, then its value must be either "true" or 438 * "false". If this property is not set, then a default value of "true" will 439 * be assumed. 440 * <BR><BR> 441 * The full name for this system property is 442 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultUseKeepalive". 443 */ 444 public static final String PROPERTY_DEFAULT_USE_KEEPALIVE = 445 PROPERTY_PREFIX + "defaultUseKeepalive"; 446 447 448 449 /** 450 * The default value for the setting that controls whether to use the 451 * {@code SO_KEEPALIVE} socket option. If the 452 * {@link #PROPERTY_DEFAULT_USE_KEEPALIVE} system property is set at the time 453 * this class is loaded, then its value will be used. Otherwise, a default of 454 * {@code true} will be used. 455 */ 456 private static final boolean DEFAULT_USE_KEEPALIVE = 457 getSystemProperty(PROPERTY_DEFAULT_USE_KEEPALIVE, true); 458 459 460 461 /** 462 * The name of a system property that can be used to specify the initial 463 * default value for the "use linger" behavior. If this property is set at 464 * the time that this class is loaded, then its value must be either "true" or 465 * "false". If this property is not set, then a default value of "true" will 466 * be assumed. 467 * <BR><BR> 468 * The full name for this system property is 469 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultUseLinger". 470 */ 471 public static final String PROPERTY_DEFAULT_USE_LINGER = 472 PROPERTY_PREFIX + "defaultUseLinger"; 473 474 475 476 /** 477 * The default value for the setting that controls whether to use the 478 * {@code SO_LINGER} socket option. If the 479 * {@link #PROPERTY_DEFAULT_USE_LINGER} system property is set at the time 480 * this class is loaded, then its value will be used. Otherwise, a default of 481 * {@code true} will be used. 482 */ 483 private static final boolean DEFAULT_USE_LINGER = 484 getSystemProperty(PROPERTY_DEFAULT_USE_LINGER, true); 485 486 487 488 /** 489 * The name of a system property that can be used to specify the initial 490 * default value for the linger timeout, in seconds. If this property is set 491 * at the time that this class is loaded, then its value must be parseable as 492 * an integer. If this property is not set, then a default value of "5" (5 493 * seconds) will be assumed. 494 * <BR><BR> 495 * The full name for this system property is 496 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultLingerTimeoutSeconds". 497 */ 498 public static final String PROPERTY_DEFAULT_LINGER_TIMEOUT_SECONDS = 499 PROPERTY_PREFIX + "defaultLingerTimeoutSeconds"; 500 501 502 503 /** 504 * The default value for the setting that controls the timeout in seconds that 505 * will be used with the {@code SO_LINGER} socket option. If the 506 * {@link #PROPERTY_DEFAULT_LINGER_TIMEOUT_SECONDS} property is set at the 507 * time this class is loaded, then its value will be used. Otherwise, a 508 * default linger timeout of 5 seconds will be used. 509 */ 510 private static final int DEFAULT_LINGER_TIMEOUT_SECONDS = 511 getSystemProperty(PROPERTY_DEFAULT_LINGER_TIMEOUT_SECONDS, 5); 512 513 514 515 /** 516 * The name of a system property that can be used to specify the initial 517 * default value for the "use reuse address" behavior. If this property is 518 * set at the time that this class is loaded, then its value must be either 519 * "true" or "false". If this property is not set, then a default value of 520 * "true" will be assumed. 521 * <BR><BR> 522 * The full name for this system property is 523 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultUseReuseAddress". 524 */ 525 public static final String PROPERTY_DEFAULT_USE_REUSE_ADDRESS = 526 PROPERTY_PREFIX + "defaultUseReuseAddress"; 527 528 529 530 /** 531 * The default value for the setting that controls whether to use the 532 * {@code SO_REUSEADDR} socket option. If the 533 * {@link #PROPERTY_DEFAULT_USE_REUSE_ADDRESS} system property is set at the 534 * time this class is loaded, then its value will be used. Otherwise, a 535 * default value of {@code true} will be used. 536 */ 537 private static final boolean DEFAULT_USE_REUSE_ADDRESS = 538 getSystemProperty(PROPERTY_DEFAULT_USE_REUSE_ADDRESS, true); 539 540 541 542 /** 543 * The name of a system property that can be used to specify the initial 544 * default value for the "use synchronous mode" behavior. If this property is 545 * set at the time that this class is loaded, then its value must be either 546 * "true" or "false". If this property is not set, then a default value of 547 * "false" will be assumed. 548 * <BR><BR> 549 * The full name for this system property is 550 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultUseSynchronousMode". 551 */ 552 public static final String PROPERTY_DEFAULT_USE_SYNCHRONOUS_MODE = 553 PROPERTY_PREFIX + "defaultUseSynchronousMode"; 554 555 556 557 /** 558 * The default value for the setting that controls whether to operate in 559 * synchronous mode, in which only a single outstanding operation may be in 560 * progress on an associated connection at any given time. If the 561 * {@link #PROPERTY_DEFAULT_USE_SYNCHRONOUS_MODE} system property is set at 562 * the time this class is loaded, then its value will be used. Otherwise, a 563 * default value of {@code false} will be used. 564 */ 565 private static final boolean DEFAULT_USE_SYNCHRONOUS_MODE = 566 getSystemProperty(PROPERTY_DEFAULT_USE_SYNCHRONOUS_MODE, false); 567 568 569 570 /** 571 * The name of a system property that can be used to specify the initial 572 * default value for the "use TCP nodelay" behavior. If this property is set 573 * at the time that this class is loaded, then its value must be either "true" 574 * or "false". If this property is not set, then a default value of "true" 575 * will be assumed. 576 * <BR><BR> 577 * The full name for this system property is 578 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultUseTCPNoDelay". 579 */ 580 public static final String PROPERTY_DEFAULT_USE_TCP_NODELAY = 581 PROPERTY_PREFIX + "defaultUseTCPNoDelay"; 582 583 584 585 /** 586 * The default value for the setting that controls whether to use the 587 * {@code TCP_NODELAY} socket option. If the 588 * {@link #PROPERTY_DEFAULT_USE_TCP_NODELAY} system property is set at the 589 * time this class is loaded, then its value will be used. Otherwise, a 590 * default value of {@code true} will be used. 591 */ 592 private static final boolean DEFAULT_USE_TCP_NODELAY = 593 getSystemProperty(PROPERTY_DEFAULT_USE_TCP_NODELAY, true); 594 595 596 597 /** 598 * The name of a system property that can be used to specify the initial 599 * default connect timeout, in milliseconds. If this property is set at the 600 * time that this class is loaded, then its value must be parseable as an 601 * integer. If this property is not set then a default value of "10000" 602 * (10,000 milliseconds, or ten seconds) will be assumed. 603 * <BR><BR> 604 * The full name for this system property is 605 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultConnectTimeoutMillis". 606 */ 607 public static final String PROPERTY_DEFAULT_CONNECT_TIMEOUT_MILLIS = 608 PROPERTY_PREFIX + "defaultConnectTimeoutMillis"; 609 610 611 612 /** 613 * The default value for the setting that controls the timeout in milliseconds 614 * when trying to establish a new connection. If the 615 * {@link #PROPERTY_DEFAULT_CONNECT_TIMEOUT_MILLIS} system property is set at 616 * the time this class is loaded, then its value will be used. Otherwise, a 617 * default of 10,000 milliseconds (10 seconds) will be used. 618 */ 619 private static final int DEFAULT_CONNECT_TIMEOUT_MILLIS = 620 getSystemProperty(PROPERTY_DEFAULT_CONNECT_TIMEOUT_MILLIS, 10_000); 621 622 623 624 /** 625 * The name of a system property that can be used to specify the initial 626 * default value for the maximum message size, in bytes. If this property is 627 * set at the time that this class is loaded, then its value must be parseable 628 * as an integer. If this property is not set, then a default value of 629 * "20971520" (20 megabytes) will be assumed. 630 * <BR><BR> 631 * The full name for this system property is 632 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultMaxMessageSizeBytes". 633 */ 634 public static final String PROPERTY_DEFAULT_MAX_MESSAGE_SIZE_BYTES = 635 PROPERTY_PREFIX + "defaultMaxMessageSizeBytes"; 636 637 638 639 /** 640 * The default value for the setting that controls the maximum LDAP message 641 * size in bytes that will be allowed when reading data from a directory 642 * server. If the {@link #PROPERTY_DEFAULT_MAX_MESSAGE_SIZE_BYTES} system 643 * property is set at the time this class is loaded, then its value will be 644 * used. Otherwise, a default value of 20,971,520 bytes (20 megabytes) will 645 * be used. 646 */ 647 private static final int DEFAULT_MAX_MESSAGE_SIZE_BYTES = 648 getSystemProperty(PROPERTY_DEFAULT_MAX_MESSAGE_SIZE_BYTES, 20_971_520); 649 650 651 652 /** 653 * The name of a system property that can be used to specify the initial 654 * default value for the receive buffer size, in bytes. If this property is 655 * set at the time that this class is loaded, then its value must be parseable 656 * as an integer. If this property is not set, then a default value of "0" 657 * (indicating that the JVM's default receive buffer size) will be assumed. 658 * <BR><BR> 659 * The full name for this system property is "com.unboundid.ldap.sdk. 660 * LDAPConnectionOptions.defaultReceiveBufferSizeBytes". 661 */ 662 public static final String PROPERTY_DEFAULT_RECEIVE_BUFFER_SIZE_BYTES = 663 PROPERTY_PREFIX + "defaultReceiveBufferSizeBytes"; 664 665 666 667 /** 668 * The default size, in bytes, to use for the receive buffer. If the 669 * {@link #PROPERTY_DEFAULT_RECEIVE_BUFFER_SIZE_BYTES} system property is set 670 * at the time this class is loaded, then its value will be used. Otherwise, 671 * a default value of 0 will be used to indicate that the JVM's default 672 * receive buffer size should be used. 673 */ 674 private static final int DEFAULT_RECEIVE_BUFFER_SIZE_BYTES = 675 getSystemProperty(PROPERTY_DEFAULT_RECEIVE_BUFFER_SIZE_BYTES, 0); 676 677 678 679 /** 680 * The name of a system property that can be used to specify the initial 681 * default value for the send buffer size, in bytes. If this property is set 682 * at the time that this class is loaded, then its value must be parseable as 683 * an integer. If this property is not set, then a default value of "0" 684 * (indicating that the JVM's default send buffer size) will be assumed. 685 * <BR><BR> 686 * The full name for this system property is 687 * "com.unboundid.ldap.sdk.LDAPConnectionOptions.defaultSendBufferSizeBytes". 688 */ 689 public static final String PROPERTY_DEFAULT_SEND_BUFFER_SIZE_BYTES = 690 PROPERTY_PREFIX + "defaultSendBufferSizeBytes"; 691 692 693 694 /** 695 * The default size, in bytes, to use for the send buffer. If the 696 * {@link #PROPERTY_DEFAULT_SEND_BUFFER_SIZE_BYTES} system property is set at 697 * the time this class is loaded, then its value will be used. Otherwise, a 698 * default value of 0 will be used to indicate that the JVM's default send 699 * buffer size should be used. 700 */ 701 private static final int DEFAULT_SEND_BUFFER_SIZE_BYTES = 702 getSystemProperty(PROPERTY_DEFAULT_SEND_BUFFER_SIZE_BYTES, 0); 703 704 705 706 /** 707 * The name of a system property that can be used to specify the initial 708 * default value for response timeouts, in milliseconds, for all types of 709 * operations. If this property is set at the time that this class is loaded, 710 * then its value must be parseable as an integer, and that value will 711 * override the values of any operation-specific properties. If this property 712 * is not set, then a default value of "300000" (300,000 milliseconds, or 713 * 5 minutes) will be assumed, but that may be overridden by 714 * operation-specific properties. 715 * <BR><BR> 716 * The full name for this system property is "com.unboundid.ldap.sdk. 717 * LDAPConnectionOptions.defaultResponseTimeoutMillis". 718 */ 719 public static final String PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS = 720 PROPERTY_PREFIX + "defaultResponseTimeoutMillis"; 721 722 723 724 /** 725 * The name of a system property that can be used to specify the initial 726 * default value for response timeouts, in milliseconds, for add operations. 727 * If this property is set at the time that this class is loaded, then 728 * its value must be parseable as an integer. It will only be used if the 729 * {@link #PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS} system property is not 730 * set, as that property will override this one. If neither of those 731 * properties is set, then a default value of "30000" (30,000 milliseconds, or 732 * 30 seconds) will be assumed. 733 * <BR><BR> 734 * The full name for this system property is "com.unboundid.ldap.sdk. 735 * LDAPConnectionOptions.defaultAddResponseTimeoutMillis". 736 */ 737 public static final String PROPERTY_DEFAULT_ADD_RESPONSE_TIMEOUT_MILLIS = 738 PROPERTY_PREFIX + "defaultAddResponseTimeoutMillis"; 739 740 741 742 /** 743 * The name of a system property that can be used to specify the initial 744 * default value for response timeouts, in milliseconds, for bind operations. 745 * If this property is set at the time that this class is loaded, then 746 * its value must be parseable as an integer. It will only be used if the 747 * {@link #PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS} system property is not 748 * set, as that property will override this one. If neither of those 749 * properties is set, then a default value of "30000" (30,000 milliseconds, or 750 * 30 seconds) will be assumed. 751 * <BR><BR> 752 * The full name for this system property is "com.unboundid.ldap.sdk. 753 * LDAPConnectionOptions.defaultBindResponseTimeoutMillis". 754 */ 755 public static final String PROPERTY_DEFAULT_BIND_RESPONSE_TIMEOUT_MILLIS = 756 PROPERTY_PREFIX + "defaultBindResponseTimeoutMillis"; 757 758 759 760 /** 761 * The name of a system property that can be used to specify the initial 762 * default value for response timeouts, in milliseconds, for compare 763 * operations. If this property is set at the time that this class is 764 * loaded, then its value must be parseable as an integer. It will only be 765 * used if the {@link #PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS} system 766 * property is not set, as that property will override this one. If neither 767 * of those properties is set, then a default value of "30000" (30,000 768 * milliseconds, or 30 seconds) will be assumed. 769 * <BR><BR> 770 * The full name for this system property is "com.unboundid.ldap.sdk. 771 * LDAPConnectionOptions.defaultCompareResponseTimeoutMillis". 772 */ 773 public static final String PROPERTY_DEFAULT_COMPARE_RESPONSE_TIMEOUT_MILLIS = 774 PROPERTY_PREFIX + "defaultCompareResponseTimeoutMillis"; 775 776 777 778 /** 779 * The name of a system property that can be used to specify the initial 780 * default value for response timeouts, in milliseconds, for delete 781 * operations. If this property is set at the time that this class is 782 * loaded, then its value must be parseable as an integer. It will only be 783 * used if the {@link #PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS} system 784 * property is not set, as that property will override this one. If neither 785 * of those properties is set, then a default value of "30000" (30,000 786 * milliseconds, or 30 seconds) will be assumed. 787 * <BR><BR> 788 * The full name for this system property is "com.unboundid.ldap.sdk. 789 * LDAPConnectionOptions.defaultDeleteResponseTimeoutMillis". 790 */ 791 public static final String PROPERTY_DEFAULT_DELETE_RESPONSE_TIMEOUT_MILLIS = 792 PROPERTY_PREFIX + "defaultDeleteResponseTimeoutMillis"; 793 794 795 796 /** 797 * The name of a system property that can be used to specify the initial 798 * default value for response timeouts, in milliseconds, for extended 799 * operations. If this property is set at the time that this class is 800 * loaded, then its value must be parseable as an integer. It will only be 801 * used if the {@link #PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS} system 802 * property is not set, as that property will override this one. If neither 803 * of those properties is set, then a default value of "300000" (300,000 804 * milliseconds, or 5 minutes) will be assumed. 805 * <BR><BR> 806 * The full name for this system property is "com.unboundid.ldap.sdk. 807 * LDAPConnectionOptions.defaultExtendedResponseTimeoutMillis". 808 * <BR><BR> 809 * Note that different timeouts may be set for specific types using a system 810 * property with this name immediately followed by a period and the request 811 * OID for the desired extended operation type. For example, the system 812 * property named "com.unboundid.ldap.sdk.LDAPConnectionOptions. 813 * defaultExtendedResponseTimeoutMillis.1.3.6.1.4.1.1466.20037" can be used to 814 * set a default response timeout for StartTLS extended operations. 815 * <BR><BR> 816 * If neither the {@link #PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS} nor the 817 * {@code PROPERTY_DEFAULT_EXTENDED_RESPONSE_TIMEOUT_MILLIS} property is set, 818 * then the following standard extended operation types will have a default 819 * timeout of 30,000 milliseconds (30 seconds) instead of 300,000 milliseconds 820 * (5 minutes), unless a property is defined to override the timeout for that 821 * specific type of extended operation: 822 * <BR> 823 * <UL> 824 * <LI>Password Modify (1.3.6.1.4.1.4203.1.11.1)</LI> 825 * <LI>StartTLS (1.3.6.1.4.1.1466.20037)</LI> 826 * <LI>Who Am I? (1.3.6.1.4.1.4203.1.11.3)</LI> 827 * </UL> 828 * <BR> 829 * The same will also be true for the following extended operations specific 830 * to the UnboundID/Ping Identity Directory Server: 831 * <BR> 832 * <UL> 833 * <LI>Deregister YubiKey OTP Device (1.3.6.1.4.1.30221.2.6.55)</LI> 834 * <LI>End Administrative Session (1.3.6.1.4.1.30221.2.6.14)</LI> 835 * <LI>Generate TOTP Shared Secret (1.3.6.1.4.1.30221.2.6.56)</LI> 836 * <LI>Get Connection ID (1.3.6.1.4.1.30221.1.6.2)</LI> 837 * <LI>Get Password Quality Requirements (1.3.6.1.4.1.30221.2.6.43)</LI> 838 * <LI>Password Policy State (1.3.6.1.4.1.30221.1.6.1)</LI> 839 * <LI>Register YubiKey OTP Device (1.3.6.1.4.1.30221.2.6.54)</LI> 840 * <LI>Revoke TOTP Shared Secret (1.3.6.1.4.1.30221.2.6.58)</LI> 841 * <LI>Start Administrative Session (1.3.6.1.4.1.30221.2.6.13)</LI> 842 * <LI>Validate TOTP Password (1.3.6.1.4.1.30221.2.6.15)</LI> 843 * </UL> 844 */ 845 public static final String PROPERTY_DEFAULT_EXTENDED_RESPONSE_TIMEOUT_MILLIS = 846 PROPERTY_PREFIX + "defaultExtendedResponseTimeoutMillis"; 847 848 849 850 /** 851 * The name of a system property that can be used to specify the initial 852 * default value for response timeouts, in milliseconds, for modify 853 * operations. If this property is set at the time that this class is 854 * loaded, then its value must be parseable as an integer. It will only be 855 * used if the {@link #PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS} system 856 * property is not set, as that property will override this one. If neither 857 * of those properties is set, then a default value of "30000" (30,000 858 * milliseconds, or 30 seconds) will be assumed. 859 * <BR><BR> 860 * The full name for this system property is "com.unboundid.ldap.sdk. 861 * LDAPConnectionOptions.defaultModifyResponseTimeoutMillis". 862 */ 863 public static final String PROPERTY_DEFAULT_MODIFY_RESPONSE_TIMEOUT_MILLIS = 864 PROPERTY_PREFIX + "defaultModifyResponseTimeoutMillis"; 865 866 867 868 /** 869 * The name of a system property that can be used to specify the initial 870 * default value for response timeouts, in milliseconds, for modify DN 871 * operations. If this property is set at the time that this class is 872 * loaded, then its value must be parseable as an integer. It will only be 873 * used if the {@link #PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS} system 874 * property is not set, as that property will override this one. If neither 875 * of those properties is set, then a default value of "30000" (30,000 876 * milliseconds, or 30 seconds) will be assumed. 877 * <BR><BR> 878 * The full name for this system property is "com.unboundid.ldap.sdk. 879 * LDAPConnectionOptions.defaultModifyDNResponseTimeoutMillis". 880 */ 881 public static final String 882 PROPERTY_DEFAULT_MODIFY_DN_RESPONSE_TIMEOUT_MILLIS = 883 PROPERTY_PREFIX + "defaultModifyDNResponseTimeoutMillis"; 884 885 886 887 /** 888 * The name of a system property that can be used to specify the initial 889 * default value for response timeouts, in milliseconds, for search 890 * operations. If this property is set at the time that this class is 891 * loaded, then its value must be parseable as an integer. It will only be 892 * used if the {@link #PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS} system 893 * property is not set, as that property will override this one. If neither 894 * of those properties is set, then a default value of "300000" (300,000 895 * milliseconds, or 5 minutes) will be assumed. 896 * <BR><BR> 897 * The full name for this system property is "com.unboundid.ldap.sdk. 898 * LDAPConnectionOptions.defaultSearchResponseTimeoutMillis". 899 */ 900 public static final String PROPERTY_DEFAULT_SEARCH_RESPONSE_TIMEOUT_MILLIS = 901 PROPERTY_PREFIX + "defaultSearchResponseTimeoutMillis"; 902 903 904 905 /** 906 * The default value for the setting that controls the default response 907 * timeout, in milliseconds, for all types of operations. 908 */ 909 private static final long DEFAULT_RESPONSE_TIMEOUT_MILLIS; 910 911 912 913 /** 914 * A map that holds the default values for the settings that control the 915 * default response timeouts, in milliseconds, for each type of operation. 916 */ 917 private static final Map<OperationType,Long> 918 DEFAULT_RESPONSE_TIMEOUT_MILLIS_BY_OPERATION_TYPE; 919 920 921 922 /** 923 * A map that holds the default values for the settings that control the 924 * default response timeouts, in milliseconds, for specific types of extended 925 * operations. 926 */ 927 private static final Map<String,Long> 928 DEFAULT_RESPONSE_TIMEOUT_MILLIS_BY_EXTENDED_OPERATION_TYPE; 929 930 931 932 /** 933 * The default name resolver that will be used to resolve host names to IP 934 * addresses. 935 */ 936 public static final NameResolver DEFAULT_NAME_RESOLVER; 937 938 939 940 static 941 { 942 // Get the default response timeout for all types of operations. 943 Long allOpsTimeout = null; 944 final EnumMap<OperationType,Long> timeoutsByOpType = 945 new EnumMap<>(OperationType.class); 946 final HashMap<String,Long> timeoutsByExtOpType = 947 new HashMap<>(StaticUtils.computeMapCapacity(10)); 948 949 final String allOpsPropertyValue = StaticUtils.getSystemProperty( 950 PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS); 951 if (allOpsPropertyValue != null) 952 { 953 try 954 { 955 allOpsTimeout = Math.max(0L, Long.parseLong(allOpsPropertyValue)); 956 for (final OperationType ot : OperationType.values()) 957 { 958 timeoutsByOpType.put(ot, allOpsTimeout); 959 } 960 961 if (Debug.debugEnabled()) 962 { 963 Debug.debug(Level.INFO, DebugType.OTHER, 964 "Using value " + allOpsTimeout + " set for system property '" + 965 PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS + "'. This " + 966 "timeout will be used for all operation types."); 967 } 968 } 969 catch (final Exception e) 970 { 971 if (Debug.debugEnabled()) 972 { 973 Debug.debugException(e); 974 Debug.debug(Level.WARNING, DebugType.OTHER, 975 "Invalid value '" + allOpsPropertyValue + "' set for system " + 976 "property '" + PROPERTY_DEFAULT_RESPONSE_TIMEOUT_MILLIS + 977 "'. The value was expected to be a long. Ignoring " + 978 "this property and proceeding as if it had not been set."); 979 } 980 } 981 } 982 983 984 // Get the default response timeout for each type of operation. 985 if (allOpsTimeout == null) 986 { 987 allOpsTimeout = 300_000L; 988 989 // Use hard-coded response timeouts of 10 seconds for abandon and unbind 990 // operations. There is no response for these operations, but the timeout 991 // is also used for sending the request. 992 timeoutsByOpType.put(OperationType.ABANDON, 10_000L); 993 timeoutsByOpType.put(OperationType.UNBIND, 10_000L); 994 995 timeoutsByOpType.put(OperationType.ADD, 996 getSystemProperty(PROPERTY_DEFAULT_ADD_RESPONSE_TIMEOUT_MILLIS, 997 30_000L)); 998 timeoutsByOpType.put(OperationType.BIND, 999 getSystemProperty(PROPERTY_DEFAULT_BIND_RESPONSE_TIMEOUT_MILLIS, 1000 30_000L)); 1001 timeoutsByOpType.put(OperationType.COMPARE, 1002 getSystemProperty(PROPERTY_DEFAULT_COMPARE_RESPONSE_TIMEOUT_MILLIS, 1003 30_000L)); 1004 timeoutsByOpType.put(OperationType.DELETE, 1005 getSystemProperty(PROPERTY_DEFAULT_DELETE_RESPONSE_TIMEOUT_MILLIS, 1006 30_000L)); 1007 timeoutsByOpType.put(OperationType.MODIFY, 1008 getSystemProperty(PROPERTY_DEFAULT_MODIFY_RESPONSE_TIMEOUT_MILLIS, 1009 30_000L)); 1010 timeoutsByOpType.put(OperationType.MODIFY_DN, 1011 getSystemProperty(PROPERTY_DEFAULT_MODIFY_DN_RESPONSE_TIMEOUT_MILLIS, 1012 30_000L)); 1013 timeoutsByOpType.put(OperationType.SEARCH, 1014 getSystemProperty(PROPERTY_DEFAULT_SEARCH_RESPONSE_TIMEOUT_MILLIS, 1015 300_000L)); 1016 1017 final String extendedOperationTypePrefix = 1018 PROPERTY_DEFAULT_EXTENDED_RESPONSE_TIMEOUT_MILLIS + '.'; 1019 for (final String propertyName : 1020 StaticUtils.getSystemProperties().stringPropertyNames()) 1021 { 1022 if (propertyName.startsWith(extendedOperationTypePrefix)) 1023 { 1024 final Long value = getSystemProperty(propertyName, null); 1025 if (value != null) 1026 { 1027 final String oid = propertyName.substring( 1028 extendedOperationTypePrefix.length()); 1029 timeoutsByExtOpType.put(oid, value); 1030 } 1031 } 1032 } 1033 1034 1035 // Get the default response timeout for different types of extended 1036 // operations. 1037 final Long extendedOpTimeout = getSystemProperty( 1038 PROPERTY_DEFAULT_EXTENDED_RESPONSE_TIMEOUT_MILLIS, null); 1039 if (extendedOpTimeout == null) 1040 { 1041 timeoutsByOpType.put(OperationType.EXTENDED, 300_000L); 1042 1043 for (final String oid : 1044 Arrays.asList( 1045 PasswordModifyExtendedRequest.PASSWORD_MODIFY_REQUEST_OID, 1046 StartTLSExtendedRequest.STARTTLS_REQUEST_OID, 1047 WhoAmIExtendedRequest.WHO_AM_I_REQUEST_OID, 1048 DeregisterYubiKeyOTPDeviceExtendedRequest. 1049 DEREGISTER_YUBIKEY_OTP_DEVICE_REQUEST_OID, 1050 EndAdministrativeSessionExtendedRequest. 1051 END_ADMIN_SESSION_REQUEST_OID, 1052 GenerateTOTPSharedSecretExtendedRequest. 1053 GENERATE_TOTP_SHARED_SECRET_REQUEST_OID, 1054 GetConnectionIDExtendedRequest.GET_CONNECTION_ID_REQUEST_OID, 1055 GetPasswordQualityRequirementsExtendedRequest. 1056 OID_GET_PASSWORD_QUALITY_REQUIREMENTS_REQUEST, 1057 PasswordPolicyStateExtendedRequest. 1058 PASSWORD_POLICY_STATE_REQUEST_OID, 1059 RegisterYubiKeyOTPDeviceExtendedRequest. 1060 REGISTER_YUBIKEY_OTP_DEVICE_REQUEST_OID, 1061 RevokeTOTPSharedSecretExtendedRequest. 1062 REVOKE_TOTP_SHARED_SECRET_REQUEST_OID, 1063 StartAdministrativeSessionExtendedRequest. 1064 START_ADMIN_SESSION_REQUEST_OID, 1065 ValidateTOTPPasswordExtendedRequest. 1066 VALIDATE_TOTP_PASSWORD_REQUEST_OID)) 1067 { 1068 if (! timeoutsByExtOpType.containsKey(oid)) 1069 { 1070 timeoutsByExtOpType.put(oid, 30_000L); 1071 } 1072 } 1073 } 1074 else 1075 { 1076 timeoutsByOpType.put(OperationType.EXTENDED, extendedOpTimeout); 1077 } 1078 } 1079 1080 1081 // Get the default name resolver to use. If the LDAP SDK is running with 1082 // access to the Ping Identity Directory Server's codebase, then we'll use 1083 // the server's default name resolver instead of the LDAP SDK's. 1084 NameResolver defaultNameResolver = DefaultNameResolver.getInstance(); 1085 try 1086 { 1087 if ((StaticUtils.getSystemProperty( 1088 "com.unboundid.directory.server.ServerRoot") != null) || 1089 (StaticUtils.getEnvironmentVariable("INSTANCE_ROOT") != null)) 1090 { 1091 final Class<?> nrClass = Class.forName( 1092 "com.unboundid.directory.server.util.OutageSafeDnsCache"); 1093 final Method getNameResolverMethod = 1094 nrClass.getMethod("getNameResolver"); 1095 final NameResolver nameResolver = 1096 (NameResolver) getNameResolverMethod.invoke(null); 1097 1098 final InetAddress localHostAddress = nameResolver.getLocalHost(); 1099 if (localHostAddress != null) 1100 { 1101 if (nameResolver.getByName(localHostAddress.getHostAddress()) != null) 1102 { 1103 defaultNameResolver = nameResolver; 1104 } 1105 } 1106 } 1107 } 1108 catch (final Throwable t) 1109 { 1110 // This is probably fine. It just means that we're not running with 1111 // access to the server codebase (or a version of the server codebase that 1112 // supports the LDAP SDK's name resolver API), or without the appropriate 1113 // setup in place (e.g., knowledge of the server root). In this case, 1114 // we'll just use the LDAP SDK's default resolver. 1115 // 1116 // Note that we intentionally catch Throwable in this case rather than 1117 // just Exception because even if the server code is available, there 1118 // may be an unexpected Error thrown (e.g., NoClassDefFound or 1119 // ExceptionInInitializerError) under certain circumstances, like if the 1120 // server's name resolver code cannot identify the server root. 1121 Debug.debugException(Level.FINEST, t); 1122 } 1123 1124 1125 DEFAULT_RESPONSE_TIMEOUT_MILLIS = allOpsTimeout; 1126 DEFAULT_RESPONSE_TIMEOUT_MILLIS_BY_OPERATION_TYPE = 1127 Collections.unmodifiableMap(timeoutsByOpType); 1128 DEFAULT_RESPONSE_TIMEOUT_MILLIS_BY_EXTENDED_OPERATION_TYPE = 1129 Collections.unmodifiableMap(timeoutsByExtOpType); 1130 DEFAULT_NAME_RESOLVER = defaultNameResolver; 1131 } 1132 1133 1134 1135 /** 1136 * The name of a system property that can be used to specify the default value 1137 * for the "allow concurrent socket factory use" behavior. If this property 1138 * is set at the time that this class is loaded, then its value must be 1139 * either "true" or "false". If this property is not set, then a default 1140 * value of "true" will be assumed. 1141 * <BR><BR> 1142 * The full name for this system property is "com.unboundid.ldap.sdk. 1143 * LDAPConnectionOptions.defaultAllowConcurrentSocketFactoryUse". 1144 */ 1145 public static final String 1146 PROPERTY_DEFAULT_ALLOW_CONCURRENT_SOCKET_FACTORY_USE = 1147 PROPERTY_PREFIX + "defaultAllowConcurrentSocketFactoryUse"; 1148 1149 1150 1151 /** 1152 * The default value for the setting that controls the default behavior with 1153 * regard to whether to allow concurrent use of a socket factory to create 1154 * client connections. 1155 */ 1156 private static final boolean DEFAULT_ALLOW_CONCURRENT_SOCKET_FACTORY_USE = 1157 getSystemProperty(PROPERTY_DEFAULT_ALLOW_CONCURRENT_SOCKET_FACTORY_USE, 1158 true); 1159 1160 1161 1162 /** 1163 * The default {@code SSLSocketVerifier} instance that will be used for 1164 * performing extra validation for {@code SSLSocket} instances. 1165 */ 1166 private static final SSLSocketVerifier DEFAULT_SSL_SOCKET_VERIFIER = 1167 TrustAllSSLSocketVerifier.getInstance(); 1168 1169 1170 1171 // Indicates whether to send an abandon request for any operation for which no 1172 // response is received in the maximum response timeout. 1173 private boolean abandonOnTimeout; 1174 1175 // Indicates whether to use synchronization prevent concurrent use of the 1176 // socket factory instance associated with a connection or set of connections. 1177 private boolean allowConcurrentSocketFactoryUse; 1178 1179 // Indicates whether the connection should attempt to automatically reconnect 1180 // if the connection to the server is lost. 1181 private boolean autoReconnect; 1182 1183 // Indicates whether to allow simple binds that contain a DN but no password. 1184 private boolean bindWithDNRequiresPassword; 1185 1186 // Indicates whether to capture a thread stack trace whenever an attempt is 1187 // made to establish a connection; 1188 private boolean captureConnectStackTrace; 1189 1190 // Indicates whether to attempt to follow any referrals that are encountered. 1191 private boolean followReferrals; 1192 1193 // Indicates whether to use SO_KEEPALIVE for the underlying sockets. 1194 private boolean useKeepAlive; 1195 1196 // Indicates whether to use SO_LINGER for the underlying sockets. 1197 private boolean useLinger; 1198 1199 // Indicates whether to use SO_REUSEADDR for the underlying sockets. 1200 private boolean useReuseAddress; 1201 1202 // Indicates whether all connections in a connection pool should reference 1203 // the same schema. 1204 private boolean usePooledSchema; 1205 1206 // Indicates whether to try to use schema information when reading data from 1207 // the server. 1208 private boolean useSchema; 1209 1210 // Indicates whether to use synchronous mode in which only a single operation 1211 // may be in progress on associated connections at any given time. 1212 private boolean useSynchronousMode; 1213 1214 // Indicates whether to use TCP_NODELAY for the underlying sockets. 1215 private boolean useTCPNoDelay; 1216 1217 // The disconnect handler for associated connections. 1218 private DisconnectHandler disconnectHandler; 1219 1220 // The connect timeout, in milliseconds. 1221 private int connectTimeoutMillis; 1222 1223 // The linger timeout to use if SO_LINGER is to be used. 1224 private int lingerTimeoutSeconds; 1225 1226 // The maximum message size in bytes that will be allowed when reading data 1227 // from a directory server. 1228 private int maxMessageSizeBytes; 1229 1230 // The socket receive buffer size to request. 1231 private int receiveBufferSizeBytes; 1232 1233 // The referral hop limit to use if referral following is enabled. 1234 private int referralHopLimit; 1235 1236 // The socket send buffer size to request. 1237 private int sendBufferSizeBytes; 1238 1239 // The connection logger that should be used to record information about 1240 // requests sent and responses received over connections with this set of 1241 // options. 1242 private LDAPConnectionLogger connectionLogger; 1243 1244 // The pooled schema timeout, in milliseconds. 1245 private long pooledSchemaTimeoutMillis; 1246 1247 // The response timeout, in milliseconds. 1248 private long responseTimeoutMillis; 1249 1250 private Map<OperationType,Long> responseTimeoutMillisByOperationType; 1251 1252 private Map<String,Long> responseTimeoutMillisByExtendedOperationType; 1253 1254 // The name resolver that will be used to resolve host names to IP addresses. 1255 private NameResolver nameResolver; 1256 1257 // Tne default referral connector that should be used for associated 1258 // connections. 1259 private ReferralConnector referralConnector; 1260 1261 // The SSLSocketVerifier instance to use to perform extra validation on 1262 // newly-established SSLSocket instances. 1263 private SSLSocketVerifier sslSocketVerifier; 1264 1265 // The unsolicited notification handler for associated connections. 1266 private UnsolicitedNotificationHandler unsolicitedNotificationHandler; 1267 1268 1269 1270 /** 1271 * Creates a new set of LDAP connection options with the default settings. 1272 */ 1273 public LDAPConnectionOptions() 1274 { 1275 abandonOnTimeout = DEFAULT_ABANDON_ON_TIMEOUT; 1276 autoReconnect = DEFAULT_AUTO_RECONNECT; 1277 bindWithDNRequiresPassword = DEFAULT_BIND_WITH_DN_REQUIRES_PASSWORD; 1278 captureConnectStackTrace = DEFAULT_CAPTURE_CONNECT_STACK_TRACE; 1279 followReferrals = DEFAULT_FOLLOW_REFERRALS; 1280 nameResolver = DEFAULT_NAME_RESOLVER; 1281 useKeepAlive = DEFAULT_USE_KEEPALIVE; 1282 useLinger = DEFAULT_USE_LINGER; 1283 useReuseAddress = DEFAULT_USE_REUSE_ADDRESS; 1284 usePooledSchema = DEFAULT_USE_POOLED_SCHEMA; 1285 useSchema = DEFAULT_USE_SCHEMA; 1286 useSynchronousMode = DEFAULT_USE_SYNCHRONOUS_MODE; 1287 useTCPNoDelay = DEFAULT_USE_TCP_NODELAY; 1288 connectTimeoutMillis = DEFAULT_CONNECT_TIMEOUT_MILLIS; 1289 lingerTimeoutSeconds = DEFAULT_LINGER_TIMEOUT_SECONDS; 1290 maxMessageSizeBytes = DEFAULT_MAX_MESSAGE_SIZE_BYTES; 1291 referralHopLimit = DEFAULT_REFERRAL_HOP_LIMIT; 1292 pooledSchemaTimeoutMillis = DEFAULT_POOLED_SCHEMA_TIMEOUT_MILLIS; 1293 responseTimeoutMillis = DEFAULT_RESPONSE_TIMEOUT_MILLIS; 1294 receiveBufferSizeBytes = DEFAULT_RECEIVE_BUFFER_SIZE_BYTES; 1295 sendBufferSizeBytes = DEFAULT_SEND_BUFFER_SIZE_BYTES; 1296 connectionLogger = null; 1297 disconnectHandler = null; 1298 referralConnector = null; 1299 sslSocketVerifier = DEFAULT_SSL_SOCKET_VERIFIER; 1300 unsolicitedNotificationHandler = null; 1301 1302 responseTimeoutMillisByOperationType = 1303 DEFAULT_RESPONSE_TIMEOUT_MILLIS_BY_OPERATION_TYPE; 1304 responseTimeoutMillisByExtendedOperationType = 1305 DEFAULT_RESPONSE_TIMEOUT_MILLIS_BY_EXTENDED_OPERATION_TYPE; 1306 allowConcurrentSocketFactoryUse = 1307 DEFAULT_ALLOW_CONCURRENT_SOCKET_FACTORY_USE; 1308 } 1309 1310 1311 1312 /** 1313 * Returns a duplicate of this LDAP connection options object that may be 1314 * modified without impacting this instance. 1315 * 1316 * @return A duplicate of this LDAP connection options object that may be 1317 * modified without impacting this instance. 1318 */ 1319 public LDAPConnectionOptions duplicate() 1320 { 1321 final LDAPConnectionOptions o = new LDAPConnectionOptions(); 1322 1323 o.abandonOnTimeout = abandonOnTimeout; 1324 o.allowConcurrentSocketFactoryUse = allowConcurrentSocketFactoryUse; 1325 o.autoReconnect = autoReconnect; 1326 o.bindWithDNRequiresPassword = bindWithDNRequiresPassword; 1327 o.captureConnectStackTrace = captureConnectStackTrace; 1328 o.followReferrals = followReferrals; 1329 o.nameResolver = nameResolver; 1330 o.useKeepAlive = useKeepAlive; 1331 o.useLinger = useLinger; 1332 o.useReuseAddress = useReuseAddress; 1333 o.usePooledSchema = usePooledSchema; 1334 o.useSchema = useSchema; 1335 o.useSynchronousMode = useSynchronousMode; 1336 o.useTCPNoDelay = useTCPNoDelay; 1337 o.connectTimeoutMillis = connectTimeoutMillis; 1338 o.lingerTimeoutSeconds = lingerTimeoutSeconds; 1339 o.maxMessageSizeBytes = maxMessageSizeBytes; 1340 o.pooledSchemaTimeoutMillis = pooledSchemaTimeoutMillis; 1341 o.responseTimeoutMillis = responseTimeoutMillis; 1342 o.referralConnector = referralConnector; 1343 o.referralHopLimit = referralHopLimit; 1344 o.connectionLogger = connectionLogger; 1345 o.disconnectHandler = disconnectHandler; 1346 o.unsolicitedNotificationHandler = unsolicitedNotificationHandler; 1347 o.receiveBufferSizeBytes = receiveBufferSizeBytes; 1348 o.sendBufferSizeBytes = sendBufferSizeBytes; 1349 o.sslSocketVerifier = sslSocketVerifier; 1350 1351 o.responseTimeoutMillisByOperationType = 1352 responseTimeoutMillisByOperationType; 1353 o.responseTimeoutMillisByExtendedOperationType = 1354 responseTimeoutMillisByExtendedOperationType; 1355 1356 return o; 1357 } 1358 1359 1360 1361 /** 1362 * Indicates whether associated connections should attempt to automatically 1363 * reconnect to the target server if the connection is lost. Note that this 1364 * option will not have any effect on pooled connections because defunct 1365 * pooled connections will be replaced by newly-created connections rather 1366 * than attempting to re-establish the existing connection. 1367 * <BR><BR> 1368 * NOTE: The use of auto-reconnect is strongly discouraged because it is 1369 * inherently fragile and can only work under very limited circumstances. It 1370 * is strongly recommended that a connection pool be used instead of the 1371 * auto-reconnect option, even in cases where only a single connection is 1372 * desired. 1373 * 1374 * @return {@code true} if associated connections should attempt to 1375 * automatically reconnect to the target server if the connection is 1376 * lost, or {@code false} if not. 1377 * 1378 * @deprecated The use of auto-reconnect is strongly discouraged because it 1379 * is inherently fragile and can only work under very limited 1380 * circumstances. It is strongly recommended that a connection 1381 * pool be used instead of the auto-reconnect option, even in 1382 * cases where only a single connection is desired. 1383 */ 1384 @Deprecated() 1385 public boolean autoReconnect() 1386 { 1387 return autoReconnect; 1388 } 1389 1390 1391 1392 /** 1393 * Specifies whether associated connections should attempt to automatically 1394 * reconnect to the target server if the connection is lost. Note that 1395 * automatic reconnection will only be available for authenticated clients if 1396 * the authentication mechanism used provides support for re-binding on a new 1397 * connection. Also note that this option will not have any effect on pooled 1398 * connections because defunct pooled connections will be replaced by 1399 * newly-created connections rather than attempting to re-establish the 1400 * existing connection. Further, auto-reconnect should not be used with 1401 * connections that use StartTLS or some other mechanism to alter the state 1402 * of the connection beyond authentication. 1403 * <BR><BR> 1404 * NOTE: The use of auto-reconnect is strongly discouraged because it is 1405 * inherently fragile and can only work under very limited circumstances. It 1406 * is strongly recommended that a connection pool be used instead of the 1407 * auto-reconnect option, even in cases where only a single connection is 1408 * desired. 1409 * 1410 * @param autoReconnect Specifies whether associated connections should 1411 * attempt to automatically reconnect to the target 1412 * server if the connection is lost. 1413 * 1414 * @deprecated The use of auto-reconnect is strongly discouraged because it 1415 * is inherently fragile and can only work under very limited 1416 * circumstances. It is strongly recommended that a connection 1417 * pool be used instead of the auto-reconnect option, even in 1418 * cases where only a single connection is desired. 1419 */ 1420 @Deprecated() 1421 public void setAutoReconnect(final boolean autoReconnect) 1422 { 1423 this.autoReconnect = autoReconnect; 1424 } 1425 1426 1427 1428 /** 1429 * Retrieves the name resolver that should be used to resolve host names to IP 1430 * addresses. 1431 * 1432 * @return The name resolver that should be used to resolve host names to IP 1433 * addresses. 1434 */ 1435 public NameResolver getNameResolver() 1436 { 1437 return nameResolver; 1438 } 1439 1440 1441 1442 /** 1443 * Sets the name resolver that should be used to resolve host names to IP 1444 * addresses. 1445 * 1446 * @param nameResolver The name resolver that should be used to resolve host 1447 * names to IP addresses. 1448 */ 1449 public void setNameResolver(final NameResolver nameResolver) 1450 { 1451 if (nameResolver == null) 1452 { 1453 this.nameResolver = DEFAULT_NAME_RESOLVER; 1454 } 1455 else 1456 { 1457 this.nameResolver = nameResolver; 1458 } 1459 } 1460 1461 1462 1463 /** 1464 * Indicates whether the SDK should allow simple bind operations that contain 1465 * a bind DN but no password. Binds of this type may represent a security 1466 * vulnerability in client applications because they may cause the client to 1467 * believe that the user is properly authenticated when the server considers 1468 * it to be an unauthenticated connection. 1469 * 1470 * @return {@code true} if the SDK should allow simple bind operations that 1471 * contain a bind DN but no password, or {@code false} if not. 1472 */ 1473 public boolean bindWithDNRequiresPassword() 1474 { 1475 return bindWithDNRequiresPassword; 1476 } 1477 1478 1479 1480 /** 1481 * Specifies whether the SDK should allow simple bind operations that contain 1482 * a bind DN but no password. 1483 * 1484 * @param bindWithDNRequiresPassword Indicates whether the SDK should allow 1485 * simple bind operations that contain a 1486 * bind DN but no password. 1487 */ 1488 public void setBindWithDNRequiresPassword( 1489 final boolean bindWithDNRequiresPassword) 1490 { 1491 this.bindWithDNRequiresPassword = bindWithDNRequiresPassword; 1492 } 1493 1494 1495 1496 /** 1497 * Indicates whether the LDAP SDK should capture a thread stack trace for each 1498 * attempt made to establish a connection. If this is enabled, then the 1499 * {@link LDAPConnection#getConnectStackTrace()} method may be used to 1500 * retrieve the stack trace. 1501 * 1502 * @return {@code true} if a thread stack trace should be captured whenever a 1503 * connection is established, or {@code false} if not. 1504 */ 1505 public boolean captureConnectStackTrace() 1506 { 1507 return captureConnectStackTrace; 1508 } 1509 1510 1511 1512 /** 1513 * Specifies whether the LDAP SDK should capture a thread stack trace for each 1514 * attempt made to establish a connection. 1515 * 1516 * @param captureConnectStackTrace Indicates whether to capture a thread 1517 * stack trace for each attempt made to 1518 * establish a connection. 1519 */ 1520 public void setCaptureConnectStackTrace( 1521 final boolean captureConnectStackTrace) 1522 { 1523 this.captureConnectStackTrace = captureConnectStackTrace; 1524 } 1525 1526 1527 1528 /** 1529 * Retrieves the maximum length of time in milliseconds that a connection 1530 * attempt should be allowed to continue before giving up. 1531 * 1532 * @return The maximum length of time in milliseconds that a connection 1533 * attempt should be allowed to continue before giving up, or zero 1534 * to indicate that there should be no connect timeout. 1535 */ 1536 public int getConnectTimeoutMillis() 1537 { 1538 return connectTimeoutMillis; 1539 } 1540 1541 1542 1543 /** 1544 * Specifies the maximum length of time in milliseconds that a connection 1545 * attempt should be allowed to continue before giving up. A value of zero 1546 * indicates that there should be no connect timeout. 1547 * 1548 * @param connectTimeoutMillis The maximum length of time in milliseconds 1549 * that a connection attempt should be allowed 1550 * to continue before giving up. 1551 */ 1552 public void setConnectTimeoutMillis(final int connectTimeoutMillis) 1553 { 1554 this.connectTimeoutMillis = connectTimeoutMillis; 1555 } 1556 1557 1558 1559 /** 1560 * Retrieves the maximum length of time in milliseconds that an operation 1561 * should be allowed to block while waiting for a response from the server. 1562 * This may be overridden on a per-operation type basis, so the 1563 * {@link #getResponseTimeoutMillis(OperationType)} method should be used 1564 * instead of this one. 1565 * 1566 * @return The maximum length of time in milliseconds that an operation 1567 * should be allowed to block while waiting for a response from the 1568 * server, or zero if there should not be any default timeout. 1569 */ 1570 public long getResponseTimeoutMillis() 1571 { 1572 return responseTimeoutMillis; 1573 } 1574 1575 1576 1577 /** 1578 * Specifies the maximum length of time in milliseconds that an operation 1579 * should be allowed to block while waiting for a response from the server. A 1580 * value of zero indicates that there should be no timeout. Note that this 1581 * will override any per-operation type and per-extended operation type 1582 * timeouts that had previously been set. 1583 * 1584 * @param responseTimeoutMillis The maximum length of time in milliseconds 1585 * that an operation should be allowed to block 1586 * while waiting for a response from the 1587 * server. 1588 */ 1589 public void setResponseTimeoutMillis(final long responseTimeoutMillis) 1590 { 1591 this.responseTimeoutMillis = Math.max(0L, responseTimeoutMillis); 1592 responseTimeoutMillisByExtendedOperationType = Collections.emptyMap(); 1593 1594 final EnumMap<OperationType,Long> newOperationTimeouts = 1595 new EnumMap<>(OperationType.class); 1596 for (final OperationType t : OperationType.values()) 1597 { 1598 newOperationTimeouts.put(t, this.responseTimeoutMillis); 1599 } 1600 responseTimeoutMillisByOperationType = 1601 Collections.unmodifiableMap(newOperationTimeouts); 1602 } 1603 1604 1605 1606 /** 1607 * Retrieves the maximum length of time in milliseconds that an operation 1608 * of the specified type should be allowed to block while waiting for a 1609 * response from the server. Note that for extended operations, the response 1610 * timeout may be overridden on a per-request OID basis, so the 1611 * {@link #getExtendedOperationResponseTimeoutMillis(String)} method should be 1612 * used instead of this one for extended operations. 1613 * 1614 * @param operationType The operation type for which to make the 1615 * determination. It must not be {@code null}. 1616 * 1617 * @return The maximum length of time in milliseconds that an operation of 1618 * the specified type should be allowed to block while waiting for a 1619 * response from the server, or zero if there should not be any 1620 * default timeout. 1621 */ 1622 public long getResponseTimeoutMillis(final OperationType operationType) 1623 { 1624 return responseTimeoutMillisByOperationType.get(operationType); 1625 } 1626 1627 1628 1629 /** 1630 * Specifies the maximum length of time in milliseconds that an operation of 1631 * the specified type should be allowed to block while waiting for a response 1632 * from the server. A value of zero indicates that there should be no 1633 * timeout. 1634 * 1635 * @param operationType The operation type for which to set the 1636 * response timeout. It must not be 1637 * {@code null}. 1638 * @param responseTimeoutMillis The maximum length of time in milliseconds 1639 * that an operation should be allowed to block 1640 * while waiting for a response from the 1641 * server. 1642 */ 1643 public void setResponseTimeoutMillis(final OperationType operationType, 1644 final long responseTimeoutMillis) 1645 { 1646 final EnumMap<OperationType,Long> newOperationTimeouts = 1647 new EnumMap<>(OperationType.class); 1648 newOperationTimeouts.putAll(responseTimeoutMillisByOperationType); 1649 newOperationTimeouts.put(operationType, 1650 Math.max(0L, responseTimeoutMillis)); 1651 1652 responseTimeoutMillisByOperationType = Collections.unmodifiableMap( 1653 newOperationTimeouts); 1654 } 1655 1656 1657 1658 /** 1659 * Retrieves the maximum length of time in milliseconds that an extended 1660 * operation with the specified request OID should be allowed to block while 1661 * waiting for a response from the server. 1662 * 1663 * @param requestOID The request OID for the extended operation for which to 1664 * make the determination. It must not be {@code null}. 1665 * 1666 * @return The maximum length of time in milliseconds that the specified type 1667 * of extended operation should be allowed to block while waiting for 1668 * a response from the server, or zero if there should not be any 1669 * default timeout. 1670 */ 1671 public long getExtendedOperationResponseTimeoutMillis(final String requestOID) 1672 { 1673 final Long timeout = 1674 responseTimeoutMillisByExtendedOperationType.get(requestOID); 1675 if (timeout == null) 1676 { 1677 return responseTimeoutMillisByOperationType.get(OperationType.EXTENDED); 1678 } 1679 else 1680 { 1681 return timeout; 1682 } 1683 } 1684 1685 1686 1687 /** 1688 * Specifies the maximum length of time in milliseconds that an extended 1689 * operation with the specified request OID should be allowed to block while 1690 * waiting for a response from the server. A value of zero indicates that 1691 * there should be no timeout. 1692 * 1693 * @param requestOID The request OID for the extended operation 1694 * type for which to set the response timeout. 1695 * It must not be {@code null}. 1696 * @param responseTimeoutMillis The maximum length of time in milliseconds 1697 * that an operation should be allowed to block 1698 * while waiting for a response from the 1699 * server. 1700 */ 1701 public void setExtendedOperationResponseTimeoutMillis(final String requestOID, 1702 final long responseTimeoutMillis) 1703 { 1704 final HashMap<String,Long> newExtOpTimeouts = 1705 new HashMap<>(responseTimeoutMillisByExtendedOperationType); 1706 newExtOpTimeouts.put(requestOID, responseTimeoutMillis); 1707 responseTimeoutMillisByExtendedOperationType = 1708 Collections.unmodifiableMap(newExtOpTimeouts); 1709 } 1710 1711 1712 1713 /** 1714 * Indicates whether the LDAP SDK should attempt to abandon any request for 1715 * which no response is received in the maximum response timeout period. 1716 * 1717 * @return {@code true} if the LDAP SDK should attempt to abandon any request 1718 * for which no response is received in the maximum response timeout 1719 * period, or {@code false} if no abandon attempt should be made in 1720 * this circumstance. 1721 */ 1722 public boolean abandonOnTimeout() 1723 { 1724 return abandonOnTimeout; 1725 } 1726 1727 1728 1729 /** 1730 * Specifies whether the LDAP SDK should attempt to abandon any request for 1731 * which no response is received in the maximum response timeout period. 1732 * 1733 * @param abandonOnTimeout Indicates whether the LDAP SDK should attempt to 1734 * abandon any request for which no response is 1735 * received in the maximum response timeout period. 1736 */ 1737 public void setAbandonOnTimeout(final boolean abandonOnTimeout) 1738 { 1739 this.abandonOnTimeout = abandonOnTimeout; 1740 } 1741 1742 1743 1744 /** 1745 * Indicates whether to use the SO_KEEPALIVE option for the underlying sockets 1746 * used by associated connections. 1747 * 1748 * @return {@code true} if the SO_KEEPALIVE option should be used for the 1749 * underlying sockets, or {@code false} if not. 1750 */ 1751 public boolean useKeepAlive() 1752 { 1753 return useKeepAlive; 1754 } 1755 1756 1757 1758 /** 1759 * Specifies whether to use the SO_KEEPALIVE option for the underlying sockets 1760 * used by associated connections. Changes to this setting will take effect 1761 * only for new sockets, and not for existing sockets. 1762 * 1763 * @param useKeepAlive Indicates whether to use the SO_KEEPALIVE option for 1764 * the underlying sockets used by associated 1765 * connections. 1766 */ 1767 public void setUseKeepAlive(final boolean useKeepAlive) 1768 { 1769 this.useKeepAlive = useKeepAlive; 1770 } 1771 1772 1773 1774 /** 1775 * Indicates whether to use the SO_LINGER option for the underlying sockets 1776 * used by associated connections. 1777 * 1778 * @return {@code true} if the SO_LINGER option should be used for the 1779 * underlying sockets, or {@code false} if not. 1780 */ 1781 public boolean useLinger() 1782 { 1783 return useLinger; 1784 } 1785 1786 1787 1788 /** 1789 * Retrieves the linger timeout in seconds that will be used if the SO_LINGER 1790 * socket option is enabled. 1791 * 1792 * @return The linger timeout in seconds that will be used if the SO_LINGER 1793 * socket option is enabled. 1794 */ 1795 public int getLingerTimeoutSeconds() 1796 { 1797 return lingerTimeoutSeconds; 1798 } 1799 1800 1801 1802 /** 1803 * Specifies whether to use the SO_LINGER option for the underlying sockets 1804 * used by associated connections. Changes to this setting will take effect 1805 * only for new sockets, and not for existing sockets. 1806 * 1807 * @param useLinger Indicates whether to use the SO_LINGER option 1808 * for the underlying sockets used by associated 1809 * connections. 1810 * @param lingerTimeoutSeconds The linger timeout in seconds that should be 1811 * used if this capability is enabled. 1812 */ 1813 public void setUseLinger(final boolean useLinger, 1814 final int lingerTimeoutSeconds) 1815 { 1816 this.useLinger = useLinger; 1817 this.lingerTimeoutSeconds = lingerTimeoutSeconds; 1818 } 1819 1820 1821 1822 /** 1823 * Indicates whether to use the SO_REUSEADDR option for the underlying sockets 1824 * used by associated connections. 1825 * 1826 * @return {@code true} if the SO_REUSEADDR option should be used for the 1827 * underlying sockets, or {@code false} if not. 1828 */ 1829 public boolean useReuseAddress() 1830 { 1831 return useReuseAddress; 1832 } 1833 1834 1835 1836 /** 1837 * Specifies whether to use the SO_REUSEADDR option for the underlying sockets 1838 * used by associated connections. Changes to this setting will take effect 1839 * only for new sockets, and not for existing sockets. 1840 * 1841 * @param useReuseAddress Indicates whether to use the SO_REUSEADDR option 1842 * for the underlying sockets used by associated 1843 * connections. 1844 */ 1845 public void setUseReuseAddress(final boolean useReuseAddress) 1846 { 1847 this.useReuseAddress = useReuseAddress; 1848 } 1849 1850 1851 1852 /** 1853 * Indicates whether to try to use schema information when reading data from 1854 * the server (e.g., to select the appropriate matching rules for the 1855 * attributes included in a search result entry). 1856 * <BR><BR> 1857 * If the LDAP SDK is configured to make use of schema, then it may be able 1858 * to more accurately perform client-side matching, including methods like 1859 * {@link Filter#matchesEntry(Entry)} or {@link Attribute#hasValue(String)}. 1860 * If both {@code useSchema} and {@code useSPooledSchema} are {@code false}, 1861 * then all client-side matching for attribute values will treat them as 1862 * directory string values with a caseIgnoreMatch equality matching rule. If 1863 * either {@code useSchema} or {@code usePooledSchema} is {@code true}, then 1864 * the LDAP SDK may be able to use the attribute type definitions from that 1865 * schema to determine the appropriate syntax and matching rules to use for 1866 * client-side matching operations involving those attributes. Any attribute 1867 * types that are not defined in the schema will still be treated as 1868 * case-insensitive directory string values. 1869 * 1870 * @return {@code true} if schema should be used when reading data from the 1871 * server, or {@code false} if not. 1872 */ 1873 public boolean useSchema() 1874 { 1875 return useSchema; 1876 } 1877 1878 1879 1880 /** 1881 * Specifies whether to try to use schema information when reading data from 1882 * the server (e.g., to select the appropriate matching rules for the 1883 * attributes included in a search result entry). 1884 * <BR><BR> 1885 * If the LDAP SDK is configured to make use of schema, then it may be able 1886 * to more accurately perform client-side matching, including methods like 1887 * {@link Filter#matchesEntry(Entry)} or {@link Attribute#hasValue(String)}. 1888 * If both {@code useSchema} and {@code useSPooledSchema} are {@code false}, 1889 * then all client-side matching for attribute values will treat them as 1890 * directory string values with a caseIgnoreMatch equality matching rule. If 1891 * either {@code useSchema} or {@code usePooledSchema} is {@code true}, then 1892 * the LDAP SDK may be able to use the attribute type definitions from that 1893 * schema to determine the appropriate syntax and matching rules to use for 1894 * client-side matching operations involving those attributes. Any attribute 1895 * types that are not defined in the schema will still be treated as 1896 * case-insensitive directory string values. 1897 * <BR><BR> 1898 * Note that calling this method with a value of {@code true} will also cause 1899 * the {@code usePooledSchema} setting to be given a value of false, since 1900 * the two values should not both be {@code true} at the same time. 1901 * 1902 * @param useSchema Indicates whether to try to use schema information when 1903 * reading data from the server. 1904 */ 1905 public void setUseSchema(final boolean useSchema) 1906 { 1907 this.useSchema = useSchema; 1908 if (useSchema) 1909 { 1910 usePooledSchema = false; 1911 } 1912 } 1913 1914 1915 1916 /** 1917 * Indicates whether to have connections that are part of a pool try to use 1918 * shared schema information when reading data from the server (e.g., to 1919 * select the appropriate matching rules for the attributes included in a 1920 * search result entry). If this is {@code true}, then connections in a 1921 * connection pool will share the same cached schema information in a way that 1922 * attempts to reduce network bandwidth and connection establishment time (by 1923 * avoiding the need for each connection to retrieve its own copy of the 1924 * schema). 1925 * <BR><BR> 1926 * If the LDAP SDK is configured to make use of schema, then it may be able 1927 * to more accurately perform client-side matching, including methods like 1928 * {@link Filter#matchesEntry(Entry)} or {@link Attribute#hasValue(String)}. 1929 * If both {@code useSchema} and {@code useSPooledSchema} are {@code false}, 1930 * then all client-side matching for attribute values will treat them as 1931 * directory string values with a caseIgnoreMatch equality matching rule. If 1932 * either {@code useSchema} or {@code usePooledSchema} is {@code true}, then 1933 * the LDAP SDK may be able to use the attribute type definitions from that 1934 * schema to determine the appropriate syntax and matching rules to use for 1935 * client-side matching operations involving those attributes. Any attribute 1936 * types that are not defined in the schema will still be treated as 1937 * case-insensitive directory string values. 1938 * <BR><BR> 1939 * If pooled schema is to be used, then it may be configured to expire so that 1940 * the schema may be periodically re-retrieved for new connections to allow 1941 * schema updates to be incorporated. This behavior is controlled by the 1942 * value returned by the {@link #getPooledSchemaTimeoutMillis} method. 1943 * 1944 * @return {@code true} if all connections in a connection pool should 1945 * reference the same schema object, or {@code false} if each 1946 * connection should retrieve its own copy of the schema. 1947 */ 1948 public boolean usePooledSchema() 1949 { 1950 return usePooledSchema; 1951 } 1952 1953 1954 1955 /** 1956 * Indicates whether to have connections that are part of a pool try to use 1957 * shared schema information when reading data from the server (e.g., to 1958 * select the appropriate matching rules for the attributes included in a 1959 * search result entry). 1960 * <BR><BR> 1961 * If the LDAP SDK is configured to make use of schema, then it may be able 1962 * to more accurately perform client-side matching, including methods like 1963 * {@link Filter#matchesEntry(Entry)} or {@link Attribute#hasValue(String)}. 1964 * If both {@code useSchema} and {@code useSPooledSchema} are {@code false}, 1965 * then all client-side matching for attribute values will treat them as 1966 * directory string values with a caseIgnoreMatch equality matching rule. If 1967 * either {@code useSchema} or {@code usePooledSchema} is {@code true}, then 1968 * the LDAP SDK may be able to use the attribute type definitions from that 1969 * schema to determine the appropriate syntax and matching rules to use for 1970 * client-side matching operations involving those attributes. Any attribute 1971 * types that are not defined in the schema will still be treated as 1972 * case-insensitive directory string values. 1973 * <BR><BR> 1974 * Note that calling this method with a value of {@code true} will also cause 1975 * the {@code useSchema} setting to be given a value of false, since the two 1976 * values should not both be {@code true} at the same time. 1977 * 1978 * @param usePooledSchema Indicates whether all connections in a connection 1979 * pool should reference the same schema object 1980 * rather than attempting to retrieve their own copy 1981 * of the schema. 1982 */ 1983 public void setUsePooledSchema(final boolean usePooledSchema) 1984 { 1985 this.usePooledSchema = usePooledSchema; 1986 if (usePooledSchema) 1987 { 1988 useSchema = false; 1989 } 1990 } 1991 1992 1993 1994 /** 1995 * Retrieves the maximum length of time in milliseconds that a pooled schema 1996 * object should be considered fresh. If the schema referenced by a 1997 * connection pool is at least this old, then the next connection attempt may 1998 * cause a new version of the schema to be retrieved. 1999 * <BR><BR> 2000 * This will only be used if the {@link #usePooledSchema} method returns 2001 * {@code true}. A value of zero indicates that the pooled schema will never 2002 * expire. 2003 * 2004 * @return The maximum length of time, in milliseconds, that a pooled schema 2005 * object should be considered fresh, or zero if pooled schema 2006 * objects should never expire. 2007 */ 2008 public long getPooledSchemaTimeoutMillis() 2009 { 2010 return pooledSchemaTimeoutMillis; 2011 } 2012 2013 2014 2015 /** 2016 * Specifies the maximum length of time in milliseconds that a pooled schema 2017 * object should be considered fresh. 2018 * 2019 * @param pooledSchemaTimeoutMillis The maximum length of time in 2020 * milliseconds that a pooled schema object 2021 * should be considered fresh. A value 2022 * less than or equal to zero will indicate 2023 * that pooled schema should never expire. 2024 */ 2025 public void setPooledSchemaTimeoutMillis(final long pooledSchemaTimeoutMillis) 2026 { 2027 this.pooledSchemaTimeoutMillis = Math.max(0L, pooledSchemaTimeoutMillis); 2028 } 2029 2030 2031 2032 /** 2033 * Indicates whether to operate in synchronous mode, in which at most one 2034 * operation may be in progress at any time on a given connection, which may 2035 * allow it to operate more efficiently and without requiring a separate 2036 * reader thread per connection. The LDAP SDK will not absolutely enforce 2037 * this restriction, but when operating in this mode correct behavior 2038 * cannot be guaranteed when multiple attempts are made to use a connection 2039 * for multiple concurrent operations. 2040 * <BR><BR> 2041 * Note that if synchronous mode is to be used, then this connection option 2042 * must be set on the connection before any attempt is made to establish the 2043 * connection. Once the connection has been established, then it will 2044 * continue to operate in synchronous or asynchronous mode based on the 2045 * options in place at the time it was connected. 2046 * 2047 * @return {@code true} if associated connections should operate in 2048 * synchronous mode, or {@code false} if not. 2049 */ 2050 public boolean useSynchronousMode() 2051 { 2052 return useSynchronousMode; 2053 } 2054 2055 2056 2057 /** 2058 * Specifies whether to operate in synchronous mode, in which at most one 2059 * operation may be in progress at any time on a given connection. 2060 * <BR><BR> 2061 * Note that if synchronous mode is to be used, then this connection option 2062 * must be set on the connection before any attempt is made to establish the 2063 * connection. Once the connection has been established, then it will 2064 * continue to operate in synchronous or asynchronous mode based on the 2065 * options in place at the time it was connected. 2066 * 2067 * @param useSynchronousMode Indicates whether to operate in synchronous 2068 * mode. 2069 */ 2070 public void setUseSynchronousMode(final boolean useSynchronousMode) 2071 { 2072 this.useSynchronousMode = useSynchronousMode; 2073 } 2074 2075 2076 2077 /** 2078 * Indicates whether to use the TCP_NODELAY option for the underlying sockets 2079 * used by associated connections. 2080 * 2081 * @return {@code true} if the TCP_NODELAY option should be used for the 2082 * underlying sockets, or {@code false} if not. 2083 */ 2084 public boolean useTCPNoDelay() 2085 { 2086 return useTCPNoDelay; 2087 } 2088 2089 2090 2091 /** 2092 * Specifies whether to use the TCP_NODELAY option for the underlying sockets 2093 * used by associated connections. Changes to this setting will take effect 2094 * only for new sockets, and not for existing sockets. 2095 * 2096 * @param useTCPNoDelay Indicates whether to use the TCP_NODELAY option for 2097 * the underlying sockets used by associated 2098 * connections. 2099 */ 2100 public void setUseTCPNoDelay(final boolean useTCPNoDelay) 2101 { 2102 this.useTCPNoDelay = useTCPNoDelay; 2103 } 2104 2105 2106 2107 /** 2108 * Indicates whether associated connections should attempt to follow any 2109 * referrals that they encounter. 2110 * 2111 * @return {@code true} if associated connections should attempt to follow 2112 * any referrals that they encounter, or {@code false} if not. 2113 */ 2114 public boolean followReferrals() 2115 { 2116 return followReferrals; 2117 } 2118 2119 2120 2121 /** 2122 * Specifies whether associated connections should attempt to follow any 2123 * referrals that they encounter, using the referral connector for the 2124 * associated connection. 2125 * 2126 * @param followReferrals Specifies whether associated connections should 2127 * attempt to follow any referrals that they 2128 * encounter. 2129 */ 2130 public void setFollowReferrals(final boolean followReferrals) 2131 { 2132 this.followReferrals = followReferrals; 2133 } 2134 2135 2136 2137 /** 2138 * Retrieves the maximum number of hops that a connection should take when 2139 * trying to follow a referral. 2140 * 2141 * @return The maximum number of hops that a connection should take when 2142 * trying to follow a referral. 2143 */ 2144 public int getReferralHopLimit() 2145 { 2146 return referralHopLimit; 2147 } 2148 2149 2150 2151 /** 2152 * Specifies the maximum number of hops that a connection should take when 2153 * trying to follow a referral. 2154 * 2155 * @param referralHopLimit The maximum number of hops that a connection 2156 * should take when trying to follow a referral. It 2157 * must be greater than zero. 2158 */ 2159 public void setReferralHopLimit(final int referralHopLimit) 2160 { 2161 Validator.ensureTrue(referralHopLimit > 0, 2162 "LDAPConnectionOptions.referralHopLimit must be greater than 0."); 2163 2164 this.referralHopLimit = referralHopLimit; 2165 } 2166 2167 2168 2169 /** 2170 * Retrieves the referral connector that will be used to establish and 2171 * optionally authenticate connections to servers when attempting to follow 2172 * referrals, if defined. 2173 * 2174 * @return The referral connector that will be used to establish and 2175 * optionally authenticate connections to servers when attempting to 2176 * follow referrals, or {@code null} if no specific referral 2177 * connector has been configured and referral connections should be 2178 * created using the same socket factory and bind request as the 2179 * connection on which the referral was received. 2180 */ 2181 public ReferralConnector getReferralConnector() 2182 { 2183 return referralConnector; 2184 } 2185 2186 2187 2188 /** 2189 * Specifies the referral connector that should be used to establish and 2190 * optionally authenticate connections to servers when attempting to follow 2191 * referrals. 2192 * 2193 * @param referralConnector The referral connector that will be used to 2194 * establish and optionally authenticate 2195 * connections to servers when attempting to follow 2196 * referrals. It may be {@code null} to indicate 2197 * that the same socket factory and bind request 2198 * as the connection on which the referral was 2199 * received should be used to establish and 2200 * authenticate connections for following 2201 * referrals. 2202 */ 2203 public void setReferralConnector(final ReferralConnector referralConnector) 2204 { 2205 this.referralConnector = referralConnector; 2206 } 2207 2208 2209 2210 /** 2211 * Retrieves the maximum size in bytes for an LDAP message that a connection 2212 * will attempt to read from the directory server. If it encounters an LDAP 2213 * message that is larger than this size, then the connection will be 2214 * terminated. 2215 * 2216 * @return The maximum size in bytes for an LDAP message that a connection 2217 * will attempt to read from the directory server, or 0 if no limit 2218 * will be enforced. 2219 */ 2220 public int getMaxMessageSize() 2221 { 2222 return maxMessageSizeBytes; 2223 } 2224 2225 2226 2227 /** 2228 * Specifies the maximum size in bytes for an LDAP message that a connection 2229 * will attempt to read from the directory server. If it encounters an LDAP 2230 * message that is larger than this size, then the connection will be 2231 * terminated. 2232 * 2233 * @param maxMessageSizeBytes The maximum size in bytes for an LDAP message 2234 * that a connection will attempt to read from 2235 * the directory server. A value less than or 2236 * equal to zero indicates that no limit should 2237 * be enforced. 2238 */ 2239 public void setMaxMessageSize(final int maxMessageSizeBytes) 2240 { 2241 this.maxMessageSizeBytes = Math.max(0, maxMessageSizeBytes); 2242 } 2243 2244 2245 2246 /** 2247 * Retrieves the logger that should be used to record information about 2248 * requests sent and responses received over connections with this set of 2249 * connection options. 2250 * 2251 * @return The logger that should be used to record information about the 2252 * requests sent and responses received over connection with this set 2253 * of options, or {@code null} if no logging should be performed. 2254 */ 2255 public LDAPConnectionLogger getConnectionLogger() 2256 { 2257 return connectionLogger; 2258 } 2259 2260 2261 2262 /** 2263 * Specifies the logger that should be used to record information about 2264 * requests sent and responses received over connections with this set of 2265 * connection options. 2266 * 2267 * @param connectionLogger The logger that should be used to record 2268 * information about the requests sent and 2269 * responses received over connection with this set 2270 * of options. It may be {@code null} if no logging 2271 * should be performed. 2272 */ 2273 public void setConnectionLogger(final LDAPConnectionLogger connectionLogger) 2274 { 2275 this.connectionLogger = connectionLogger; 2276 } 2277 2278 2279 2280 /** 2281 * Retrieves the disconnect handler to use for associated connections. 2282 * 2283 * @return the disconnect handler to use for associated connections, or 2284 * {@code null} if none is defined. 2285 */ 2286 public DisconnectHandler getDisconnectHandler() 2287 { 2288 return disconnectHandler; 2289 } 2290 2291 2292 2293 /** 2294 * Specifies the disconnect handler to use for associated connections. 2295 * 2296 * @param handler The disconnect handler to use for associated connections. 2297 */ 2298 public void setDisconnectHandler(final DisconnectHandler handler) 2299 { 2300 disconnectHandler = handler; 2301 } 2302 2303 2304 2305 /** 2306 * Retrieves the unsolicited notification handler to use for associated 2307 * connections. 2308 * 2309 * @return The unsolicited notification handler to use for associated 2310 * connections, or {@code null} if none is defined. 2311 */ 2312 public UnsolicitedNotificationHandler getUnsolicitedNotificationHandler() 2313 { 2314 return unsolicitedNotificationHandler; 2315 } 2316 2317 2318 2319 /** 2320 * Specifies the unsolicited notification handler to use for associated 2321 * connections. 2322 * 2323 * @param handler The unsolicited notification handler to use for associated 2324 * connections. 2325 */ 2326 public void setUnsolicitedNotificationHandler( 2327 final UnsolicitedNotificationHandler handler) 2328 { 2329 unsolicitedNotificationHandler = handler; 2330 } 2331 2332 2333 2334 /** 2335 * Retrieves the socket receive buffer size, in bytes, that should be 2336 * requested when establishing a connection. 2337 * 2338 * @return The socket receive buffer size, in bytes, that should be requested 2339 * when establishing a connection, or zero if the JVM's default size 2340 * should be used. 2341 */ 2342 public int getReceiveBufferSize() 2343 { 2344 return receiveBufferSizeBytes; 2345 } 2346 2347 2348 2349 /** 2350 * Specifies the socket receive buffer size, in bytes, that should be 2351 * requested when establishing a connection. 2352 * 2353 * @param receiveBufferSizeBytes The socket receive buffer size, in bytes, 2354 * that should be requested when establishing 2355 * a connection, or zero if the JVM's default 2356 * size should be used. 2357 */ 2358 public void setReceiveBufferSize(final int receiveBufferSizeBytes) 2359 { 2360 this.receiveBufferSizeBytes = Math.max(0, receiveBufferSizeBytes); 2361 } 2362 2363 2364 2365 /** 2366 * Retrieves the socket send buffer size, in bytes, that should be requested 2367 * when establishing a connection. 2368 * 2369 * @return The socket send buffer size, in bytes, that should be requested 2370 * when establishing a connection, or zero if the JVM's default size 2371 * should be used. 2372 */ 2373 public int getSendBufferSize() 2374 { 2375 return sendBufferSizeBytes; 2376 } 2377 2378 2379 2380 /** 2381 * Specifies the socket send buffer size, in bytes, that should be requested 2382 * when establishing a connection. 2383 * 2384 * @param sendBufferSizeBytes The socket send buffer size, in bytes, that 2385 * should be requested when establishing a 2386 * connection, or zero if the JVM's default size 2387 * should be used. 2388 */ 2389 public void setSendBufferSize(final int sendBufferSizeBytes) 2390 { 2391 this.sendBufferSizeBytes = Math.max(0, sendBufferSizeBytes); 2392 } 2393 2394 2395 2396 /** 2397 * Indicates whether to allow a socket factory instance (which may be shared 2398 * across multiple connections) to be used create multiple sockets 2399 * concurrently. In general, socket factory implementations are threadsafe 2400 * and can be to create multiple connections simultaneously across separate 2401 * threads, but this is known to not be the case in some VM implementations 2402 * (e.g., SSL socket factories in IBM JVMs). This setting may be used to 2403 * indicate whether concurrent socket creation attempts should be allowed 2404 * (which may allow for better and more consistent performance, especially in 2405 * cases where a connection attempt fails due to a timeout) or prevented 2406 * (which may be necessary for non-threadsafe socket factory implementations). 2407 * 2408 * @return {@code true} if multiple threads should be able to concurrently 2409 * use the same socket factory instance, or {@code false} if Java 2410 * synchronization should be used to ensure that no more than one 2411 * thread is allowed to use a socket factory at any given time. 2412 */ 2413 public boolean allowConcurrentSocketFactoryUse() 2414 { 2415 return allowConcurrentSocketFactoryUse; 2416 } 2417 2418 2419 2420 /** 2421 * Specifies whether to allow a socket factory instance (which may be shared 2422 * across multiple connections) to be used create multiple sockets 2423 * concurrently. In general, socket factory implementations are threadsafe 2424 * and can be to create multiple connections simultaneously across separate 2425 * threads, but this is known to not be the case in some VM implementations 2426 * (e.g., SSL socket factories in IBM JVMs). This setting may be used to 2427 * indicate whether concurrent socket creation attempts should be allowed 2428 * (which may allow for better and more consistent performance, especially in 2429 * cases where a connection attempt fails due to a timeout) or prevented 2430 * (which may be necessary for non-threadsafe socket factory implementations). 2431 * 2432 * @param allowConcurrentSocketFactoryUse Indicates whether to allow a 2433 * socket factory instance to be used 2434 * to create multiple sockets 2435 * concurrently. 2436 */ 2437 public void setAllowConcurrentSocketFactoryUse( 2438 final boolean allowConcurrentSocketFactoryUse) 2439 { 2440 this.allowConcurrentSocketFactoryUse = allowConcurrentSocketFactoryUse; 2441 } 2442 2443 2444 2445 /** 2446 * Retrieves the {@link SSLSocketVerifier} that will be used to perform 2447 * additional validation for any newly-created {@code SSLSocket} instances. 2448 * 2449 * @return The {@code SSLSocketVerifier} that will be used to perform 2450 * additional validation for any newly-created {@code SSLSocket} 2451 * instances. 2452 */ 2453 public SSLSocketVerifier getSSLSocketVerifier() 2454 { 2455 return sslSocketVerifier; 2456 } 2457 2458 2459 2460 /** 2461 * Specifies the {@link SSLSocketVerifier} that will be used to perform 2462 * additional validation for any newly-created {@code SSLSocket} instances. 2463 * 2464 * @param sslSocketVerifier The {@code SSLSocketVerifier} that will be used 2465 * to perform additional validation for any 2466 * newly-created {@code SSLSocket} instances. 2467 */ 2468 public void setSSLSocketVerifier(final SSLSocketVerifier sslSocketVerifier) 2469 { 2470 if (sslSocketVerifier == null) 2471 { 2472 this.sslSocketVerifier = DEFAULT_SSL_SOCKET_VERIFIER; 2473 } 2474 else 2475 { 2476 this.sslSocketVerifier = sslSocketVerifier; 2477 } 2478 } 2479 2480 2481 2482 /** 2483 * Retrieves the value of the specified system property as a boolean. 2484 * 2485 * @param propertyName The name of the system property whose value should be 2486 * retrieved. 2487 * @param defaultValue The default value that will be returned if the system 2488 * property is not defined or if its value cannot be 2489 * parsed as a boolean. 2490 * 2491 * @return The value of the specified system property as an boolean, or the 2492 * default value if the system property is not set with a valid 2493 * value. 2494 */ 2495 static boolean getSystemProperty(final String propertyName, 2496 final boolean defaultValue) 2497 { 2498 final String propertyValue = StaticUtils.getSystemProperty(propertyName); 2499 if (propertyValue == null) 2500 { 2501 if (Debug.debugEnabled()) 2502 { 2503 Debug.debug(Level.FINE, DebugType.OTHER, 2504 "Using the default value of " + defaultValue + " for system " + 2505 "property '" + propertyName + "' that is not set."); 2506 } 2507 2508 return defaultValue; 2509 } 2510 2511 if (propertyValue.equalsIgnoreCase("true")) 2512 { 2513 if (Debug.debugEnabled()) 2514 { 2515 Debug.debug(Level.INFO, DebugType.OTHER, 2516 "Using value '" + propertyValue + "' set for system property '" + 2517 propertyName + "'."); 2518 } 2519 2520 return true; 2521 } 2522 else if (propertyValue.equalsIgnoreCase("false")) 2523 { 2524 if (Debug.debugEnabled()) 2525 { 2526 Debug.debug(Level.INFO, DebugType.OTHER, 2527 "Using value '" + propertyValue + "' set for system property '" + 2528 propertyName + "'."); 2529 } 2530 2531 return false; 2532 } 2533 else 2534 { 2535 if (Debug.debugEnabled()) 2536 { 2537 Debug.debug(Level.WARNING, DebugType.OTHER, 2538 "Invalid value '" + propertyValue + "' set for system property '" + 2539 propertyName + "'. The value was expected to be either " + 2540 "'true' or 'false'. The default value of " + defaultValue + 2541 " will be used instead of the configured value."); 2542 } 2543 2544 return defaultValue; 2545 } 2546 } 2547 2548 2549 2550 /** 2551 * Retrieves the value of the specified system property as an integer. 2552 * 2553 * @param propertyName The name of the system property whose value should be 2554 * retrieved. 2555 * @param defaultValue The default value that will be returned if the system 2556 * property is not defined or if its value cannot be 2557 * parsed as an integer. 2558 * 2559 * @return The value of the specified system property as an integer, or the 2560 * default value if the system property is not set with a valid 2561 * value. 2562 */ 2563 static int getSystemProperty(final String propertyName, 2564 final int defaultValue) 2565 { 2566 final String propertyValueString = 2567 StaticUtils.getSystemProperty(propertyName); 2568 if (propertyValueString == null) 2569 { 2570 if (Debug.debugEnabled()) 2571 { 2572 Debug.debug(Level.FINE, DebugType.OTHER, 2573 "Using the default value of " + defaultValue + " for system " + 2574 "property '" + propertyName + "' that is not set."); 2575 } 2576 2577 return defaultValue; 2578 } 2579 2580 try 2581 { 2582 final int propertyValueInt = Integer.parseInt(propertyValueString); 2583 if (Debug.debugEnabled()) 2584 { 2585 Debug.debug(Level.INFO, DebugType.OTHER, 2586 "Using value " + propertyValueInt + " set for system property '" + 2587 propertyName + "'."); 2588 } 2589 2590 return propertyValueInt; 2591 } 2592 catch (final Exception e) 2593 { 2594 if (Debug.debugEnabled()) 2595 { 2596 Debug.debugException(e); 2597 Debug.debug(Level.WARNING, DebugType.OTHER, 2598 "Invalid value '" + propertyValueString + "' set for system " + 2599 "property '" + propertyName + "'. The value was expected " + 2600 "to be an integer. The default value of " + defaultValue + 2601 "will be used instead of the configured value.", 2602 e); 2603 } 2604 2605 return defaultValue; 2606 } 2607 } 2608 2609 2610 2611 /** 2612 * Retrieves the value of the specified system property as a long. 2613 * 2614 * @param propertyName The name of the system property whose value should be 2615 * retrieved. 2616 * @param defaultValue The default value that will be returned if the system 2617 * property is not defined or if its value cannot be 2618 * parsed as a long. 2619 * 2620 * @return The value of the specified system property as a long, or the 2621 * default value if the system property is not set with a valid 2622 * value. 2623 */ 2624 static Long getSystemProperty(final String propertyName, 2625 final Long defaultValue) 2626 { 2627 final String propertyValueString = 2628 StaticUtils.getSystemProperty(propertyName); 2629 if (propertyValueString == null) 2630 { 2631 if (Debug.debugEnabled()) 2632 { 2633 Debug.debug(Level.FINE, DebugType.OTHER, 2634 "Using the default value of " + defaultValue + " for system " + 2635 "property '" + propertyName + "' that is not set."); 2636 } 2637 2638 return defaultValue; 2639 } 2640 2641 try 2642 { 2643 final long propertyValueLong = Long.parseLong(propertyValueString); 2644 if (Debug.debugEnabled()) 2645 { 2646 Debug.debug(Level.INFO, DebugType.OTHER, 2647 "Using value " + propertyValueLong + " set for system property '" + 2648 propertyName + "'."); 2649 } 2650 2651 return propertyValueLong; 2652 } 2653 catch (final Exception e) 2654 { 2655 if (Debug.debugEnabled()) 2656 { 2657 Debug.debugException(e); 2658 Debug.debug(Level.WARNING, DebugType.OTHER, 2659 "Invalid value '" + propertyValueString + "' set for system " + 2660 "property '" + propertyName + "'. The value was expected " + 2661 "to be a long. The default value of " + defaultValue + 2662 "will be used instead of the configured value.", 2663 e); 2664 } 2665 2666 return defaultValue; 2667 } 2668 } 2669 2670 2671 2672 /** 2673 * Retrieves a string representation of this LDAP connection. 2674 * 2675 * @return A string representation of this LDAP connection. 2676 */ 2677 @Override() 2678 public String toString() 2679 { 2680 final StringBuilder buffer = new StringBuilder(); 2681 toString(buffer); 2682 return buffer.toString(); 2683 } 2684 2685 2686 2687 /** 2688 * Appends a string representation of this LDAP connection to the provided 2689 * buffer. 2690 * 2691 * @param buffer The buffer to which to append a string representation of 2692 * this LDAP connection. 2693 */ 2694 public void toString(final StringBuilder buffer) 2695 { 2696 buffer.append("LDAPConnectionOptions(autoReconnect="); 2697 buffer.append(autoReconnect); 2698 buffer.append(", nameResolver="); 2699 nameResolver.toString(buffer); 2700 buffer.append(", bindWithDNRequiresPassword="); 2701 buffer.append(bindWithDNRequiresPassword); 2702 buffer.append(", followReferrals="); 2703 buffer.append(followReferrals); 2704 if (followReferrals) 2705 { 2706 buffer.append(", referralHopLimit="); 2707 buffer.append(referralHopLimit); 2708 } 2709 if (referralConnector != null) 2710 { 2711 buffer.append(", referralConnectorClass="); 2712 buffer.append(referralConnector.getClass().getName()); 2713 } 2714 buffer.append(", useKeepAlive="); 2715 buffer.append(useKeepAlive); 2716 buffer.append(", useLinger="); 2717 if (useLinger) 2718 { 2719 buffer.append("true, lingerTimeoutSeconds="); 2720 buffer.append(lingerTimeoutSeconds); 2721 } 2722 else 2723 { 2724 buffer.append("false"); 2725 } 2726 buffer.append(", useReuseAddress="); 2727 buffer.append(useReuseAddress); 2728 buffer.append(", useSchema="); 2729 buffer.append(useSchema); 2730 buffer.append(", usePooledSchema="); 2731 buffer.append(usePooledSchema); 2732 buffer.append(", pooledSchemaTimeoutMillis="); 2733 buffer.append(pooledSchemaTimeoutMillis); 2734 buffer.append(", useSynchronousMode="); 2735 buffer.append(useSynchronousMode); 2736 buffer.append(", useTCPNoDelay="); 2737 buffer.append(useTCPNoDelay); 2738 buffer.append(", captureConnectStackTrace="); 2739 buffer.append(captureConnectStackTrace); 2740 buffer.append(", connectTimeoutMillis="); 2741 buffer.append(connectTimeoutMillis); 2742 buffer.append(", responseTimeoutMillis="); 2743 buffer.append(responseTimeoutMillis); 2744 2745 for (final Map.Entry<OperationType,Long> e : 2746 responseTimeoutMillisByOperationType.entrySet()) 2747 { 2748 buffer.append(", responseTimeoutMillis."); 2749 buffer.append(e.getKey().name()); 2750 buffer.append('='); 2751 buffer.append(e.getValue()); 2752 } 2753 2754 for (final Map.Entry<String,Long> e : 2755 responseTimeoutMillisByExtendedOperationType.entrySet()) 2756 { 2757 buffer.append(", responseTimeoutMillis.EXTENDED."); 2758 buffer.append(e.getKey()); 2759 buffer.append('='); 2760 buffer.append(e.getValue()); 2761 } 2762 2763 buffer.append(", abandonOnTimeout="); 2764 buffer.append(abandonOnTimeout); 2765 buffer.append(", maxMessageSizeBytes="); 2766 buffer.append(maxMessageSizeBytes); 2767 buffer.append(", receiveBufferSizeBytes="); 2768 buffer.append(receiveBufferSizeBytes); 2769 buffer.append(", sendBufferSizeBytes="); 2770 buffer.append(sendBufferSizeBytes); 2771 buffer.append(", allowConcurrentSocketFactoryUse="); 2772 buffer.append(allowConcurrentSocketFactoryUse); 2773 2774 if (connectionLogger != null) 2775 { 2776 buffer.append(", connectionLoggerClass="); 2777 buffer.append(connectionLogger.getClass().getName()); 2778 } 2779 2780 if (disconnectHandler != null) 2781 { 2782 buffer.append(", disconnectHandlerClass="); 2783 buffer.append(disconnectHandler.getClass().getName()); 2784 } 2785 2786 if (unsolicitedNotificationHandler != null) 2787 { 2788 buffer.append(", unsolicitedNotificationHandlerClass="); 2789 buffer.append(unsolicitedNotificationHandler.getClass().getName()); 2790 } 2791 2792 buffer.append(", sslSocketVerifierClass='"); 2793 buffer.append(sslSocketVerifier.getClass().getName()); 2794 buffer.append('\''); 2795 2796 buffer.append(')'); 2797 } 2798}