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