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