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