001    /*
002     * Copyright 2007-2016 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2008-2016 UnboundID Corp.
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     */
021    package com.unboundid.ldap.sdk;
022    
023    
024    
025    import com.unboundid.util.StaticUtils;
026    import com.unboundid.util.ssl.SSLSocketVerifier;
027    import com.unboundid.util.ssl.TrustAllSSLSocketVerifier;
028    
029    import static com.unboundid.util.Validator.*;
030    
031    
032    
033    /**
034     * This class provides a data structure that may be used to configure a number
035     * of connection-related properties.  Elements included in the set of connection
036     * options include:
037     * <UL>
038     *   <LI>A flag that indicates whether the SDK should attempt to automatically
039     *       re-establish a connection if it is unexpectedly closed.  By default,
040     *       it will not attempt to do so.</LI>
041     *   <LI>A flag that indicates whether simple bind attempts that contain a
042     *       non-empty DN will be required to have a non-empty password.  By
043     *       default, a password will be required in such cases.</LI>
044     *   <LI>A flag that indicates whether to automatically attempt to follow any
045     *       referrals that may be returned by the server.  By default, it will not
046     *       automatically attempt to follow referrals.</LI>
047     *   <LI>A referral hop limit, which indicates the maximum number of hops that
048     *       the connection may take when trying to follow a referral.  The default
049     *       referral hop limit is five.</LI>
050     *   <LI>The referral connector that should be used to create and optionally
051     *       authenticate connections used to follow referrals encountered during
052     *       processing.  By default, referral connections will use the same socket
053     *       factory and bind request as the client connection on which the referral
054     *       was received.</LI>
055     *   <LI>A flag that indicates whether to use the SO_KEEPALIVE socket option to
056     *       attempt to more quickly detect when idle TCP connections have been lost
057     *       or to prevent them from being unexpectedly closed by intermediate
058     *       network hardware.  By default, the SO_KEEPALIVE socket option will be
059     *       used.</LI>
060     *   <LI>A flag that indicates whether to use the SO_LINGER socket option to
061     *       indicate how long a connection should linger after it has been closed,
062     *       and a value that specifies the length of time that it should linger.
063     *       By default, the SO_LINGER option will be used with a timeout of 5
064     *       seconds.</LI>
065     *   <LI>A flag that indicates whether to use the SO_REUSEADDR socket option to
066     *       indicate that a socket in a TIME_WAIT state may be reused.  By default,
067     *       the SO_REUSEADDR socket option will be used.</LI>
068     *   <LI>A flag that indicates whether to operate in synchronous mode, in which
069     *       connections may exhibit better performance and will not require a
070     *       separate reader thread, but will not allow multiple concurrent
071     *       operations to be used on the same connection.</LI>
072     *   <LI>A flag that indicates whether to use the TCP_NODELAY socket option to
073     *       indicate that any data written to the socket will be sent immediately
074     *       rather than delaying for a short amount of time to see if any more data
075     *       is to be sent that could potentially be included in the same packet.
076     *       By default, the TCP_NODELAY socket option will be used.</LI>
077     *   <LI>A value which specifies the maximum length of time in milliseconds that
078     *       an attempt to establish a connection should be allowed to block before
079     *       failing.  By default, a timeout of 60,000 milliseconds (1 minute) will
080     *       be used.</LI>
081     *   <LI>A value which specifies the default timeout in milliseconds that the
082     *       SDK should wait for a response from the server before failing.  By
083     *       default, a timeout of 300,000 milliseconds (5 minutes) will be
084     *       used.</LI>
085     *   <LI>A flag that indicates whether to attempt to abandon any request for
086     *       which no response is received after waiting for the maximum response
087     *       timeout.  By default, no abandon request will be sent.</LI>
088     *   <LI>A value which specifies the largest LDAP message size that the SDK will
089     *       be willing to read from the directory server.  By default, the SDK will
090     *       not allow responses larger than 20971520 bytes (20MB).  If it
091     *       encounters a message that may be larger than the maximum allowed
092     *       message size, then the SDK will terminate the connection to the
093     *       server.</LI>
094     *   <LI>The {@code DisconnectHandler} that should be used to receive
095     *       notification if connection is disconnected for any reason.  By default,
096     *       no {@code DisconnectHandler} will be used.</LI>
097     *   <LI>The {@code UnsolicitedNotificationHandler} that should be used to
098     *       receive notification about any unsolicited notifications returned by
099     *       the server.  By default, no {@code UnsolicitedNotificationHandler} will
100     *       be used.</LI>
101     *   <LI>A flag that indicates whether to capture a thread stack trace whenever
102     *       a new connection is established.  Capturing a thread stack trace when
103     *       establishing a connection may be marginally expensive, but can be
104     *       useful for debugging certain kinds of problems like leaked connections
105     *       (connections that are established but never explicitly closed).  By
106     *       default, connect stack traces will not be captured.</LI>
107     *   <LI>A flag that indicates whether connections should try to retrieve schema
108     *       information from the server, which may be used to better determine
109     *       which matching rules should be used when comparing attribute values.
110     *       By default, server schema information will not be retrieved.</LI>
111     *   <LI>The size of the socket receive buffer, which may be used for
112     *       temporarily holding data received from the directory server until it
113     *       can be read and processed by the LDAP SDK.  By default, the receive
114     *       buffer size will be automatically determined by the JVM based on the
115     *       underlying system settings.</LI>
116     *   <LI>The size of the socket send buffer, which may be used for temporarily
117     *       holding data to be sent to the directory server until it can actually
118     *       be transmitted over the network.  By default, the send buffer size will
119     *       be automatically determined by the JVM based on the underlying system
120     *       settings.</LI>
121     *  <LI>A flag which indicates whether to allow a single socket factory instance
122     *      (which may be shared across multiple connections) to be used to create
123     *      multiple concurrent connections.  This offers better and more
124     *      predictable performance on some JVM implementations (especially when
125     *      connection attempts fail as a result of a connection timeout), but some
126     *      JVMs are known to use non-threadsafe socket factory implementations and
127     *      may fail from concurrent use (for example, at least some IBM JVMs
128     *      exhibit this behavior).  By default, Sun/Oracle JVMs will allow
129     *      concurrent socket factory use, but JVMs from other vendors will use
130     *      synchronization to ensure that a socket factory will only be allowed to
131     *      create one connection at a time.</LI>
132     *  <LI>A class that may be used to perform additional verification (e.g.,
133     *      hostname validation) for any {@code SSLSocket} instances created.  By
134     *      default, no special verification will be performed.</LI>
135     * </UL>
136     */
137    public final class LDAPConnectionOptions
138    {
139      /**
140       * The default value ({@code false}) for the setting that controls whether to
141       * attempt to abandon any request for which no response is received within the
142       * maximum response timeout.
143       */
144      static final boolean DEFAULT_ABANDON_ON_TIMEOUT = false;
145    
146    
147    
148      /**
149       * The default value ({@code false}) for the setting that controls whether to
150       * automatically attempt to reconnect if a connection is unexpectedly lost.
151       */
152      static final boolean DEFAULT_AUTO_RECONNECT = false;
153    
154    
155    
156      /**
157       * The default value ({@code true}) for the setting that controls whether
158       * simple bind requests with a DN are also required to contain a password.
159       */
160      static final boolean DEFAULT_BIND_WITH_DN_REQUIRES_PASSWORD = true;
161    
162    
163    
164      /**
165       * The default value ({@code false}) for the setting that controls whether to
166       * capture a thread stack trace whenever an attempt is made to establish a
167       * connection.
168       */
169      static final boolean DEFAULT_CAPTURE_CONNECT_STACK_TRACE = false;
170    
171    
172    
173      /**
174       * The default value ({@code false}) for the setting that controls whether to
175       * attempt to automatically follow referrals.
176       */
177      static final boolean DEFAULT_FOLLOW_REFERRALS = false;
178    
179    
180    
181      /**
182       * The default value ({@code false}) for the setting that controls whether all
183       * connections in a connection pool should use the same cached schema object.
184       */
185      static final boolean DEFAULT_USE_POOLED_SCHEMA = false;
186    
187    
188    
189      /**
190       * The default value ({@code true}) for the setting that controls whether to
191       * use the {@code SO_KEEPALIVE} socket option.
192       */
193      static final boolean DEFAULT_USE_KEEPALIVE = true;
194    
195    
196    
197      /**
198       * The default value ({@code true}) for the setting that controls whether to
199       * use the {@code SO_LINGER} socket option.
200       */
201      static final boolean DEFAULT_USE_LINGER = true;
202    
203    
204    
205      /**
206       * The default value ({@code true}) for the setting that controls whether to
207       * use the {@code SO_REUSEADDR} socket option.
208       */
209      static final boolean DEFAULT_USE_REUSE_ADDRESS = true;
210    
211    
212    
213      /**
214       * The default value ({@code false}) for the setting that controls whether to
215       * use schema when reading data from the server.
216       */
217      static final boolean DEFAULT_USE_SCHEMA = false;
218    
219    
220    
221      /**
222       * The default value ({@code false}) for the setting that controls whether to
223       * operate in synchronous mode, in which only a single outstanding operation
224       * may be in progress on an associated connection at any given time.
225       */
226      static final boolean DEFAULT_USE_SYNCHRONOUS_MODE = false;
227    
228    
229    
230      /**
231       * The default value ({@code true}) for the setting that controls whether to
232       * use the {@code TCP_NODELAY} socket option.
233       */
234      static final boolean DEFAULT_USE_TCP_NODELAY = true;
235    
236    
237    
238      /**
239       * The default value (60000) for the setting that controls the timeout in
240       * milliseconds when trying to establish a new connection.
241       */
242      static final int DEFAULT_CONNECT_TIMEOUT_MILLIS = 60000;
243    
244    
245    
246      /**
247       * The default value (5) for the setting that controls the timeout in seconds
248       * that will be used with the {@code SO_LINGER} socket option.
249       */
250      static final int DEFAULT_LINGER_TIMEOUT_SECONDS = 5;
251    
252    
253    
254      /**
255       * The default value (20971520 bytes, or 20MB) for the setting that controls
256       * the maximum LDAP message size in bytes that will be allowed when reading
257       * data from a directory server.
258       */
259      static final int DEFAULT_MAX_MESSAGE_SIZE = 20971520;
260    
261    
262    
263      /**
264       * The default size to use for the receive buffer.
265       */
266      static final int DEFAULT_RECEIVE_BUFFER_SIZE = 0;
267    
268    
269    
270      /**
271       * The default value (5) for the setting that controls the referral hop limit.
272       */
273      static final int DEFAULT_REFERRAL_HOP_LIMIT = 5;
274    
275    
276    
277      /**
278       * The default size to use for the send buffer.
279       */
280      static final int DEFAULT_SEND_BUFFER_SIZE = 0;
281    
282    
283    
284      /**
285       * The default value (3600000 milliseconds, or one hour) for the setting that
286       * controls the default pooled schema timeout.
287       */
288      static final long DEFAULT_POOLED_SCHEMA_TIMEOUT_MILLIS = 3600000L;
289    
290    
291    
292      /**
293       * The default value (300000) for the setting that controls the default
294       * response timeout in milliseconds.
295       */
296      static final long DEFAULT_RESPONSE_TIMEOUT_MILLIS = 300000L;
297    
298    
299    
300      /**
301       * The default value for the setting that controls the default behavior with
302       * regard to whether to allow concurrent use of a socket factory to create
303       * client connections.
304       */
305      static final boolean DEFAULT_ALLOW_CONCURRENT_SOCKET_FACTORY_USE;
306      static
307      {
308        final String vmVendor =
309             StaticUtils.toLowerCase(System.getProperty("java.vm.vendor"));
310        DEFAULT_ALLOW_CONCURRENT_SOCKET_FACTORY_USE = ((vmVendor != null) &&
311             (vmVendor.contains("sun microsystems") ||
312              vmVendor.contains("oracle") ||
313              vmVendor.contains("apple") ||
314              vmVendor.contains("azul systems")));
315      }
316    
317    
318    
319      /**
320       * The default {@code SSLSocketVerifier} instance that will be used for
321       * performing extra validation for {@code SSLSocket} instances.
322       */
323      static final SSLSocketVerifier DEFAULT_SSL_SOCKET_VERIFIER =
324           TrustAllSSLSocketVerifier.getInstance();
325    
326    
327    
328      // Indicates whether to send an abandon request for any operation for which no
329      // response is received in the maximum response timeout.
330      private boolean abandonOnTimeout;
331    
332      // Indicates whether to use synchronization prevent concurrent use of the
333      // socket factory instance associated with a connection or set of connections.
334      private boolean allowConcurrentSocketFactoryUse;
335    
336      // Indicates whether the connection should attempt to automatically reconnect
337      // if the connection to the server is lost.
338      private boolean autoReconnect;
339    
340      // Indicates whether to allow simple binds that contain a DN but no password.
341      private boolean bindWithDNRequiresPassword;
342    
343      // Indicates whether to capture a thread stack trace whenever an attempt is
344      // made to establish a connection;
345      private boolean captureConnectStackTrace;
346    
347      // Indicates whether to attempt to follow any referrals that are encountered.
348      private boolean followReferrals;
349    
350      // Indicates whether to use SO_KEEPALIVE for the underlying sockets.
351      private boolean useKeepAlive;
352    
353      // Indicates whether to use SO_LINGER for the underlying sockets.
354      private boolean useLinger;
355    
356      // Indicates whether to use SO_REUSEADDR for the underlying sockets.
357      private boolean useReuseAddress;
358    
359      // Indicates whether all connections in a connection pool should reference
360      // the same schema.
361      private boolean usePooledSchema;
362    
363      // Indicates whether to try to use schema information when reading data from
364      // the server.
365      private boolean useSchema;
366    
367      // Indicates whether to use synchronous mode in which only a single operation
368      // may be in progress on associated connections at any given time.
369      private boolean useSynchronousMode;
370    
371      // Indicates whether to use TCP_NODELAY for the underlying sockets.
372      private boolean useTCPNoDelay;
373    
374      // The disconnect handler for associated connections.
375      private DisconnectHandler disconnectHandler;
376    
377      // The connect timeout, in milliseconds.
378      private int connectTimeout;
379    
380      // The linger timeout to use if SO_LINGER is to be used.
381      private int lingerTimeout;
382    
383      // The maximum message size in bytes that will be allowed when reading data
384      // from a directory server.
385      private int maxMessageSize;
386    
387      // The socket receive buffer size to request.
388      private int receiveBufferSize;
389    
390      // The referral hop limit to use if referral following is enabled.
391      private int referralHopLimit;
392    
393      // The socket send buffer size to request.
394      private int sendBufferSize;
395    
396      // The pooled schema timeout, in milliseconds.
397      private long pooledSchemaTimeout;
398    
399      // The response timeout, in milliseconds.
400      private long responseTimeout;
401    
402      // Tne default referral connector that should be used for associated
403      // connections.
404      private ReferralConnector referralConnector;
405    
406      // The SSLSocketVerifier instance to use to perform extra validation on
407      // newly-established SSLSocket instances.
408      private SSLSocketVerifier sslSocketVerifier;
409    
410      // The unsolicited notification handler for associated connections.
411      private UnsolicitedNotificationHandler unsolicitedNotificationHandler;
412    
413    
414    
415      /**
416       * Creates a new set of LDAP connection options with the default settings.
417       */
418      public LDAPConnectionOptions()
419      {
420        abandonOnTimeout               = DEFAULT_ABANDON_ON_TIMEOUT;
421        autoReconnect                  = DEFAULT_AUTO_RECONNECT;
422        bindWithDNRequiresPassword     = DEFAULT_BIND_WITH_DN_REQUIRES_PASSWORD;
423        captureConnectStackTrace       = DEFAULT_CAPTURE_CONNECT_STACK_TRACE;
424        followReferrals                = DEFAULT_FOLLOW_REFERRALS;
425        useKeepAlive                   = DEFAULT_USE_KEEPALIVE;
426        useLinger                      = DEFAULT_USE_LINGER;
427        useReuseAddress                = DEFAULT_USE_REUSE_ADDRESS;
428        usePooledSchema                = DEFAULT_USE_POOLED_SCHEMA;
429        useSchema                      = DEFAULT_USE_SCHEMA;
430        useSynchronousMode             = DEFAULT_USE_SYNCHRONOUS_MODE;
431        useTCPNoDelay                  = DEFAULT_USE_TCP_NODELAY;
432        connectTimeout                 = DEFAULT_CONNECT_TIMEOUT_MILLIS;
433        lingerTimeout                  = DEFAULT_LINGER_TIMEOUT_SECONDS;
434        maxMessageSize                 = DEFAULT_MAX_MESSAGE_SIZE;
435        referralHopLimit               = DEFAULT_REFERRAL_HOP_LIMIT;
436        pooledSchemaTimeout            = DEFAULT_POOLED_SCHEMA_TIMEOUT_MILLIS;
437        responseTimeout                = DEFAULT_RESPONSE_TIMEOUT_MILLIS;
438        receiveBufferSize              = DEFAULT_RECEIVE_BUFFER_SIZE;
439        sendBufferSize                 = DEFAULT_SEND_BUFFER_SIZE;
440        disconnectHandler              = null;
441        referralConnector              = null;
442        sslSocketVerifier              = DEFAULT_SSL_SOCKET_VERIFIER;
443        unsolicitedNotificationHandler = null;
444    
445        allowConcurrentSocketFactoryUse =
446             DEFAULT_ALLOW_CONCURRENT_SOCKET_FACTORY_USE;
447      }
448    
449    
450    
451      /**
452       * Returns a duplicate of this LDAP connection options object that may be
453       * modified without impacting this instance.
454       *
455       * @return  A duplicate of this LDAP connection options object that may be
456       *          modified without impacting this instance.
457       */
458      public LDAPConnectionOptions duplicate()
459      {
460        final LDAPConnectionOptions o = new LDAPConnectionOptions();
461    
462        o.abandonOnTimeout                = abandonOnTimeout;
463        o.allowConcurrentSocketFactoryUse = allowConcurrentSocketFactoryUse;
464        o.autoReconnect                   = autoReconnect;
465        o.bindWithDNRequiresPassword      = bindWithDNRequiresPassword;
466        o.captureConnectStackTrace        = captureConnectStackTrace;
467        o.followReferrals                 = followReferrals;
468        o.useKeepAlive                    = useKeepAlive;
469        o.useLinger                       = useLinger;
470        o.useReuseAddress                 = useReuseAddress;
471        o.usePooledSchema                 = usePooledSchema;
472        o.useSchema                       = useSchema;
473        o.useSynchronousMode              = useSynchronousMode;
474        o.useTCPNoDelay                   = useTCPNoDelay;
475        o.connectTimeout                  = connectTimeout;
476        o.lingerTimeout                   = lingerTimeout;
477        o.maxMessageSize                  = maxMessageSize;
478        o.pooledSchemaTimeout             = pooledSchemaTimeout;
479        o.responseTimeout                 = responseTimeout;
480        o.referralConnector               = referralConnector;
481        o.referralHopLimit                = referralHopLimit;
482        o.disconnectHandler               = disconnectHandler;
483        o.unsolicitedNotificationHandler  = unsolicitedNotificationHandler;
484        o.receiveBufferSize               = receiveBufferSize;
485        o.sendBufferSize                  = sendBufferSize;
486        o.sslSocketVerifier               = sslSocketVerifier;
487    
488        return o;
489      }
490    
491    
492    
493      /**
494       * Indicates whether associated connections should attempt to automatically
495       * reconnect to the target server if the connection is lost.  Note that this
496       * option will not have any effect on pooled connections because defunct
497       * pooled connections will be replaced by newly-created connections rather
498       * than attempting to re-establish the existing connection.
499       * <BR><BR>
500       * NOTE:  The use of auto-reconnect is strongly discouraged because it is
501       * inherently fragile and can only work under very limited circumstances.  It
502       * is strongly recommended that a connection pool be used instead of the
503       * auto-reconnect option, even in cases where only a single connection is
504       * desired.
505       *
506       * @return  {@code true} if associated connections should attempt to
507       *          automatically reconnect to the target server if the connection is
508       *          lost, or {@code false} if not.
509       *
510       * @deprecated  The use of auto-reconnect is strongly discouraged because it
511       *              is inherently fragile and can only work under very limited
512       *              circumstances.  It is strongly recommended that a connection
513       *              pool be used instead of the auto-reconnect option, even in
514       *              cases where only a single connection is desired.
515       */
516      @Deprecated()
517      public boolean autoReconnect()
518      {
519        return autoReconnect;
520      }
521    
522    
523    
524      /**
525       * Specifies whether associated connections should attempt to automatically
526       * reconnect to the target server if the connection is lost.  Note that
527       * automatic reconnection will only be available for authenticated clients if
528       * the authentication mechanism used provides support for re-binding on a new
529       * connection.  Also note that this option will not have any effect on pooled
530       * connections because defunct pooled connections will be replaced by
531       * newly-created connections rather than attempting to re-establish the
532       * existing connection.  Further, auto-reconnect should not be used with
533       * connections that use StartTLS or some other mechanism to alter the state
534       * of the connection beyond authentication.
535       * <BR><BR>
536       * NOTE:  The use of auto-reconnect is strongly discouraged because it is
537       * inherently fragile and can only work under very limited circumstances.  It
538       * is strongly recommended that a connection pool be used instead of the
539       * auto-reconnect option, even in cases where only a single connection is
540       * desired.
541       *
542       * @param  autoReconnect  Specifies whether associated connections should
543       *                        attempt to automatically reconnect to the target
544       *                        server if the connection is lost.
545       *
546       * @deprecated  The use of auto-reconnect is strongly discouraged because it
547       *              is inherently fragile and can only work under very limited
548       *              circumstances.  It is strongly recommended that a connection
549       *              pool be used instead of the auto-reconnect option, even in
550       *              cases where only a single connection is desired.
551       */
552      @Deprecated()
553      public void setAutoReconnect(final boolean autoReconnect)
554      {
555        this.autoReconnect = autoReconnect;
556      }
557    
558    
559    
560      /**
561       * Indicates whether the SDK should allow simple bind operations that contain
562       * a bind DN but no password.  Binds of this type may represent a security
563       * vulnerability in client applications because they may cause the client to
564       * believe that the user is properly authenticated when the server considers
565       * it to be an unauthenticated connection.
566       *
567       * @return  {@code true} if the SDK should allow simple bind operations that
568       *          contain a bind DN but no password, or {@code false} if not.
569       */
570      public boolean bindWithDNRequiresPassword()
571      {
572        return bindWithDNRequiresPassword;
573      }
574    
575    
576    
577      /**
578       * Specifies whether the SDK should allow simple bind operations that contain
579       * a bind DN but no password.
580       *
581       * @param  bindWithDNRequiresPassword  Indicates whether the SDK should allow
582       *                                     simple bind operations that contain a
583       *                                     bind DN but no password.
584       */
585      public void setBindWithDNRequiresPassword(
586                       final boolean bindWithDNRequiresPassword)
587      {
588        this.bindWithDNRequiresPassword = bindWithDNRequiresPassword;
589      }
590    
591    
592    
593      /**
594       * Indicates whether the LDAP SDK should capture a thread stack trace for each
595       * attempt made to establish a connection.  If this is enabled, then the
596       * {@code LDAPConnection#getConnectStackTrace()}  method may be used to
597       * retrieve the stack trace.
598       *
599       * @return  {@code true} if a thread stack trace should be captured whenever a
600       *          connection is established, or {@code false} if not.
601       */
602      public boolean captureConnectStackTrace()
603      {
604        return captureConnectStackTrace;
605      }
606    
607    
608    
609      /**
610       * Specifies whether the LDAP SDK should capture a thread stack trace for each
611       * attempt made to establish a connection.
612       *
613       * @param  captureConnectStackTrace  Indicates whether to capture a thread
614       *                                   stack trace for each attempt made to
615       *                                   establish a connection.
616       */
617      public void setCaptureConnectStackTrace(
618                       final boolean captureConnectStackTrace)
619      {
620        this.captureConnectStackTrace = captureConnectStackTrace;
621      }
622    
623    
624    
625      /**
626       * Retrieves the maximum length of time in milliseconds that a connection
627       * attempt should be allowed to continue before giving up.
628       *
629       * @return  The maximum length of time in milliseconds that a connection
630       *          attempt should be allowed to continue before giving up, or zero
631       *          to indicate that there should be no connect timeout.
632       */
633      public int getConnectTimeoutMillis()
634      {
635        return connectTimeout;
636      }
637    
638    
639    
640      /**
641       * Specifies the maximum length of time in milliseconds that a connection
642       * attempt should be allowed to continue before giving up.  A value of zero
643       * indicates that there should be no connect timeout.
644       *
645       * @param  connectTimeout  The maximum length of time in milliseconds that a
646       *                         connection attempt should be allowed to continue
647       *                         before giving up.
648       */
649      public void setConnectTimeoutMillis(final int connectTimeout)
650      {
651        this.connectTimeout = connectTimeout;
652      }
653    
654    
655    
656      /**
657       * Retrieves the maximum length of time in milliseconds that an operation
658       * should be allowed to block while waiting for a response from the server.
659       * This may be overridden on a per-operation basis.
660       *
661       * @return  The maximum length of time in milliseconds that an operation
662       *          should be allowed to block while waiting for a response from the
663       *          server, or zero if there should not be any default timeout.
664       */
665      public long getResponseTimeoutMillis()
666      {
667        return responseTimeout;
668      }
669    
670    
671    
672      /**
673       * Specifies the maximum length of time in milliseconds that an operation
674       * should be allowed to block while waiting for a response from the server.  A
675       * value of zero indicates that there should be no timeout.
676       *
677       * @param  responseTimeout  The maximum length of time in milliseconds that an
678       *                          operation should be allowed to block while waiting
679       *                          for a response from the server.
680       *
681       */
682      public void setResponseTimeoutMillis(final long responseTimeout)
683      {
684        if (responseTimeout < 0)
685        {
686          this.responseTimeout = 0L;
687        }
688        else
689        {
690          this.responseTimeout = responseTimeout;
691        }
692      }
693    
694    
695    
696      /**
697       * Indicates whether the LDAP SDK should attempt to abandon any request for
698       * which no response is received in the maximum response timeout period.
699       *
700       * @return  {@code true} if the LDAP SDK should attempt to abandon any request
701       *          for which no response is received in the maximum response timeout
702       *          period, or {@code false} if no abandon attempt should be made in
703       *          this circumstance.
704       */
705      public boolean abandonOnTimeout()
706      {
707        return abandonOnTimeout;
708      }
709    
710    
711    
712      /**
713       * Specifies whether the LDAP SDK should attempt to abandon any request for
714       * which no response is received in the maximum response timeout period.
715       *
716       * @param  abandonOnTimeout  Indicates whether the LDAP SDK should attempt to
717       *                           abandon any request for which no response is
718       *                           received in the maximum response timeout period.
719       */
720      public void setAbandonOnTimeout(final boolean abandonOnTimeout)
721      {
722        this.abandonOnTimeout = abandonOnTimeout;
723      }
724    
725    
726    
727      /**
728       * Indicates whether to use the SO_KEEPALIVE option for the underlying sockets
729       * used by associated connections.
730       *
731       * @return  {@code true} if the SO_KEEPALIVE option should be used for the
732       *          underlying sockets, or {@code false} if not.
733       */
734      public boolean useKeepAlive()
735      {
736        return useKeepAlive;
737      }
738    
739    
740    
741      /**
742       * Specifies whether to use the SO_KEEPALIVE option for the underlying sockets
743       * used by associated connections.  Changes to this setting will take effect
744       * only for new sockets, and not for existing sockets.
745       *
746       * @param  useKeepAlive  Indicates whether to use the SO_KEEPALIVE option for
747       *                       the underlying sockets used by associated
748       *                       connections.
749       */
750      public void setUseKeepAlive(final boolean useKeepAlive)
751      {
752        this.useKeepAlive = useKeepAlive;
753      }
754    
755    
756    
757      /**
758       * Indicates whether to use the SO_LINGER option for the underlying sockets
759       * used by associated connections.
760       *
761       * @return  {@code true} if the SO_LINGER option should be used for the
762       *          underlying sockets, or {@code false} if not.
763       */
764      public boolean useLinger()
765      {
766        return useLinger;
767      }
768    
769    
770    
771      /**
772       * Retrieves the linger timeout in seconds that will be used if the SO_LINGER
773       * socket option is enabled.
774       *
775       * @return  The linger timeout in seconds that will be used if the SO_LINGER
776       *          socket option is enabled.
777       */
778      public int getLingerTimeoutSeconds()
779      {
780        return lingerTimeout;
781      }
782    
783    
784    
785      /**
786       * Specifies whether to use the SO_LINGER option for the underlying sockets
787       * used by associated connections.  Changes to this setting will take effect
788       * only for new sockets, and not for existing sockets.
789       *
790       * @param  useLinger      Indicates whether to use the SO_LINGER option for
791       *                        the underlying sockets used by associated
792       *                        connections.
793       * @param  lingerTimeout  The linger timeout in seconds that should be used if
794       *                        this capability is enabled.
795       */
796      public void setUseLinger(final boolean useLinger, final int lingerTimeout)
797      {
798        this.useLinger     = useLinger;
799        this.lingerTimeout = lingerTimeout;
800      }
801    
802    
803    
804      /**
805       * Indicates whether to use the SO_REUSEADDR option for the underlying sockets
806       * used by associated connections.
807       *
808       * @return  {@code true} if the SO_REUSEADDR option should be used for the
809       *          underlying sockets, or {@code false} if not.
810       */
811      public boolean useReuseAddress()
812      {
813        return useReuseAddress;
814      }
815    
816    
817    
818      /**
819       * Specifies whether to use the SO_REUSEADDR option for the underlying sockets
820       * used by associated connections.  Changes to this setting will take effect
821       * only for new sockets, and not for existing sockets.
822       *
823       * @param  useReuseAddress  Indicates whether to use the SO_REUSEADDR option
824       *                          for the underlying sockets used by associated
825       *                          connections.
826       */
827      public void setUseReuseAddress(final boolean useReuseAddress)
828      {
829        this.useReuseAddress = useReuseAddress;
830      }
831    
832    
833    
834      /**
835       * Indicates whether to try to use schema information when reading data from
836       * the server (e.g., to select the appropriate matching rules for the
837       * attributes included in a search result entry).
838       *
839       * @return  {@code true} if schema should be used when reading data from the
840       *          server, or {@code false} if not.
841       */
842      public boolean useSchema()
843      {
844        return useSchema;
845      }
846    
847    
848    
849      /**
850       * Specifies whether to try to use schema information when reading data from
851       * the server (e.g., to select the appropriate matching rules for the
852       * attributes included in a search result entry).
853       * <BR><BR>
854       * Note that calling this method with a value of {@code true} will also cause
855       * the {@code usePooledSchema} setting to be given a value of false, since
856       * the two values should not both be {@code true} at the same time.
857       *
858       * @param  useSchema  Indicates whether to try to use schema information when
859       *                    reading data from the server.
860       */
861      public void setUseSchema(final boolean useSchema)
862      {
863        this.useSchema = useSchema;
864        if (useSchema)
865        {
866          usePooledSchema = false;
867        }
868      }
869    
870    
871    
872      /**
873       * Indicates whether to have connections that are part of a pool try to use
874       * shared schema information when reading data from the server (e.g., to
875       * select the appropriate matching rules for the attributes included in a
876       * search result entry).  If this is {@code true}, then connections in a
877       * connection pool will share the same cached schema information in a way that
878       * attempts to reduce network bandwidth and connection establishment time (by
879       * avoiding the need for each connection to retrieve its own copy of the
880       * schema).
881       * <BR><BR>
882       * If pooled schema is to be used, then it may be configured to expire so that
883       * the schema may be periodically re-retrieved for new connections to allow
884       * schema updates to be incorporated.  This behavior is controlled by the
885       * value returned by the {@code getPooledSchemaTimeoutMillis} method.
886       *
887       * @return  {@code true} if all connections in a connection pool should
888       *          reference the same schema object, or {@code false} if each
889       *          connection should retrieve its own copy of the schema.
890       */
891      public boolean usePooledSchema()
892      {
893        return usePooledSchema;
894      }
895    
896    
897    
898      /**
899       * Indicates whether to have connections that are part of a pool try to use
900       * shared schema information when reading data from the server (e.g., to
901       * select the appropriate matching rules for the attributes included in a
902       * search result entry).
903       * <BR><BR>
904       * Note that calling this method with a value of {@code true} will also cause
905       * the {@code useSchema} setting to be given a value of false, since the two
906       * values should not both be {@code true} at the same time.
907       *
908       * @param  usePooledSchema  Indicates whether all connections in a connection
909       *                          pool should reference the same schema object
910       *                          rather than attempting to retrieve their own copy
911       *                          of the schema.
912       */
913      public void setUsePooledSchema(final boolean usePooledSchema)
914      {
915        this.usePooledSchema = usePooledSchema;
916        if (usePooledSchema)
917        {
918          useSchema = false;
919        }
920      }
921    
922    
923    
924      /**
925       * Retrieves the maximum length of time in milliseconds that a pooled schema
926       * object should be considered fresh.  If the schema referenced by a
927       * connection pool is at least this old, then the next connection attempt may
928       * cause a new version of the schema to be retrieved.
929       * <BR><BR>
930       * This will only be used if the {@code usePooledSchema} method returns
931       * {@code true}.  A value of zero indicates that the pooled schema will never
932       * expire.
933       *
934       * @return  The maximum length of time, in milliseconds, that a pooled schema
935       *          object should be considered fresh, or zero if pooled schema
936       *          objects should never expire.
937       */
938      public long getPooledSchemaTimeoutMillis()
939      {
940        return pooledSchemaTimeout;
941      }
942    
943    
944    
945      /**
946       * Specifies the maximum length of time in milliseconds that a pooled schema
947       * object should be considered fresh.
948       *
949       * @param  pooledSchemaTimeout  The maximum length of time in milliseconds
950       *                              that a pooled schema object should be
951       *                              considered fresh.  A value less than or equal
952       *                              to zero will indicate that pooled schema
953       *                              should never expire.
954       */
955      public void setPooledSchemaTimeoutMillis(final long pooledSchemaTimeout)
956      {
957        if (pooledSchemaTimeout < 0)
958        {
959          this.pooledSchemaTimeout = 0L;
960        }
961        else
962        {
963          this.pooledSchemaTimeout = pooledSchemaTimeout;
964        }
965      }
966    
967    
968    
969      /**
970       * Indicates whether to operate in synchronous mode, in which at most one
971       * operation may be in progress at any time on a given connection, which may
972       * allow it to operate more efficiently and without requiring a separate
973       * reader thread per connection.  The LDAP SDK will not absolutely enforce
974       * this restriction, but when operating in this mode correct behavior
975       * cannot be guaranteed when multiple attempts are made to use a connection
976       * for multiple concurrent operations.
977       * <BR><BR>
978       * Note that if synchronous mode is to be used, then this connection option
979       * must be set on the connection before any attempt is made to establish the
980       * connection.  Once the connection has been established, then it will
981       * continue to operate in synchronous or asynchronous mode based on the
982       * options in place at the time it was connected.
983       *
984       * @return  {@code true} if associated connections should operate in
985       *          synchronous mode, or {@code false} if not.
986       */
987      public boolean useSynchronousMode()
988      {
989        return useSynchronousMode;
990      }
991    
992    
993    
994      /**
995       * Specifies whether to operate in synchronous mode, in which at most one
996       * operation may be in progress at any time on a given connection.
997       * <BR><BR>
998       * Note that if synchronous mode is to be used, then this connection option
999       * must be set on the connection before any attempt is made to establish the
1000       * connection.  Once the connection has been established, then it will
1001       * continue to operate in synchronous or asynchronous mode based on the
1002       * options in place at the time it was connected.
1003       *
1004       * @param  useSynchronousMode  Indicates whether to operate in synchronous
1005       *                             mode.
1006       */
1007      public void setUseSynchronousMode(final boolean useSynchronousMode)
1008      {
1009        this.useSynchronousMode = useSynchronousMode;
1010      }
1011    
1012    
1013    
1014      /**
1015       * Indicates whether to use the TCP_NODELAY option for the underlying sockets
1016       * used by associated connections.
1017       *
1018       * @return  {@code true} if the TCP_NODELAY option should be used for the
1019       *          underlying sockets, or {@code false} if not.
1020       */
1021      public boolean useTCPNoDelay()
1022      {
1023        return useTCPNoDelay;
1024      }
1025    
1026    
1027    
1028      /**
1029       * Specifies whether to use the TCP_NODELAY option for the underlying sockets
1030       * used by associated connections.  Changes to this setting will take effect
1031       * only for new sockets, and not for existing sockets.
1032       *
1033       * @param  useTCPNoDelay  Indicates whether to use the TCP_NODELAY option for
1034       *                        the underlying sockets used by associated
1035       *                        connections.
1036       */
1037      public void setUseTCPNoDelay(final boolean useTCPNoDelay)
1038      {
1039        this.useTCPNoDelay = useTCPNoDelay;
1040      }
1041    
1042    
1043    
1044      /**
1045       * Indicates whether associated connections should attempt to follow any
1046       * referrals that they encounter.
1047       *
1048       * @return  {@code true} if associated connections should attempt to follow
1049       *          any referrals that they encounter, or {@code false} if not.
1050       */
1051      public boolean followReferrals()
1052      {
1053        return followReferrals;
1054      }
1055    
1056    
1057    
1058      /**
1059       * Specifies whether associated connections should attempt to follow any
1060       * referrals that they encounter, using the referral connector for the
1061       * associated connection.
1062       *
1063       * @param  followReferrals  Specifies whether associated connections should
1064       *                          attempt to follow any referrals that they
1065       *                          encounter.
1066       */
1067      public void setFollowReferrals(final boolean followReferrals)
1068      {
1069        this.followReferrals = followReferrals;
1070      }
1071    
1072    
1073    
1074      /**
1075       * Retrieves the maximum number of hops that a connection should take when
1076       * trying to follow a referral.
1077       *
1078       * @return  The maximum number of hops that a connection should take when
1079       *          trying to follow a referral.
1080       */
1081      public int getReferralHopLimit()
1082      {
1083        return referralHopLimit;
1084      }
1085    
1086    
1087    
1088      /**
1089       * Specifies the maximum number of hops that a connection should take when
1090       * trying to follow a referral.
1091       *
1092       * @param  referralHopLimit  The maximum number of hops that a connection
1093       *                           should take when trying to follow a referral.  It
1094       *                           must be greater than zero.
1095       */
1096      public void setReferralHopLimit(final int referralHopLimit)
1097      {
1098        ensureTrue(referralHopLimit > 0,
1099             "LDAPConnectionOptions.referralHopLimit must be greater than 0.");
1100    
1101        this.referralHopLimit = referralHopLimit;
1102      }
1103    
1104    
1105    
1106      /**
1107       * Retrieves the referral connector that will be used to establish and
1108       * optionally authenticate connections to servers when attempting to follow
1109       * referrals, if defined.
1110       *
1111       * @return  The referral connector that will be used to establish and
1112       *          optionally authenticate connections to servers when attempting to
1113       *          follow referrals, or {@code null} if no specific referral
1114       *          connector has been configured and referral connections should be
1115       *          created using the same socket factory and bind request as the
1116       *          connection on which the referral was received.
1117       */
1118      public ReferralConnector getReferralConnector()
1119      {
1120        return referralConnector;
1121      }
1122    
1123    
1124    
1125      /**
1126       * Specifies the referral connector that should be used to establish and
1127       * optionally authenticate connections to servers when attempting to follow
1128       * referrals.
1129       *
1130       * @param  referralConnector  The referral connector that will be used to
1131       *                            establish and optionally authenticate
1132       *                            connections to servers when attempting to follow
1133       *                            referrals.  It may be {@code null} to indicate
1134       *                            that the same socket factory and bind request
1135       *                            as the connection on which the referral was
1136       *                            received should be used to establish and
1137       *                            authenticate connections for following
1138       *                            referrals.
1139       */
1140      public void setReferralConnector(final ReferralConnector referralConnector)
1141      {
1142        this.referralConnector = referralConnector;
1143      }
1144    
1145    
1146    
1147      /**
1148       * Retrieves the maximum size in bytes for an LDAP message that a connection
1149       * will attempt to read from the directory server.  If it encounters an LDAP
1150       * message that is larger than this size, then the connection will be
1151       * terminated.
1152       *
1153       * @return  The maximum size in bytes for an LDAP message that a connection
1154       *          will attempt to read from the directory server, or 0 if no limit
1155       *          will be enforced.
1156       */
1157      public int getMaxMessageSize()
1158      {
1159        return maxMessageSize;
1160      }
1161    
1162    
1163    
1164      /**
1165       * Specifies the maximum size in bytes for an LDAP message that a connection
1166       * will attempt to read from the directory server.  If it encounters an LDAP
1167       * message that is larger than this size, then the connection will be
1168       * terminated.
1169       *
1170       * @param  maxMessageSize  The maximum size in bytes for an LDAP message that
1171       *                         a connection will attempt to read from the
1172       *                         directory server.  A value less than or equal to
1173       *                         zero indicates that no limit should be enforced.
1174       */
1175      public void setMaxMessageSize(final int maxMessageSize)
1176      {
1177        if (maxMessageSize > 0)
1178        {
1179          this.maxMessageSize = maxMessageSize;
1180        }
1181        else
1182        {
1183          this.maxMessageSize = 0;
1184        }
1185      }
1186    
1187    
1188    
1189      /**
1190       * Retrieves the disconnect handler to use for associated connections.
1191       *
1192       * @return  the disconnect handler to use for associated connections, or
1193       *          {@code null} if none is defined.
1194       */
1195      public DisconnectHandler getDisconnectHandler()
1196      {
1197        return disconnectHandler;
1198      }
1199    
1200    
1201    
1202      /**
1203       * Specifies the disconnect handler to use for associated connections.
1204       *
1205       * @param  handler  The disconnect handler to use for associated connections.
1206       */
1207      public void setDisconnectHandler(final DisconnectHandler handler)
1208      {
1209        disconnectHandler = handler;
1210      }
1211    
1212    
1213    
1214      /**
1215       * Retrieves the unsolicited notification handler to use for associated
1216       * connections.
1217       *
1218       * @return  The unsolicited notification handler to use for associated
1219       *          connections, or {@code null} if none is defined.
1220       */
1221      public UnsolicitedNotificationHandler getUnsolicitedNotificationHandler()
1222      {
1223        return unsolicitedNotificationHandler;
1224      }
1225    
1226    
1227    
1228      /**
1229       * Specifies the unsolicited notification handler to use for associated
1230       * connections.
1231       *
1232       * @param  handler  The unsolicited notification handler to use for associated
1233       *                  connections.
1234       */
1235      public void setUnsolicitedNotificationHandler(
1236                       final UnsolicitedNotificationHandler handler)
1237      {
1238        unsolicitedNotificationHandler = handler;
1239      }
1240    
1241    
1242    
1243      /**
1244       * Retrieves the socket receive buffer size that should be requested when
1245       * establishing a connection.
1246       *
1247       * @return  The socket receive buffer size that should be requested when
1248       *          establishing a connection, or zero if the default size should be
1249       *          used.
1250       */
1251      public int getReceiveBufferSize()
1252      {
1253        return receiveBufferSize;
1254      }
1255    
1256    
1257    
1258      /**
1259       * Specifies the socket receive buffer size that should be requested when
1260       * establishing a connection.
1261       *
1262       * @param  receiveBufferSize  The socket receive buffer size that should be
1263       *                            requested when establishing a connection, or
1264       *                            zero if the default size should be used.
1265       */
1266      public void setReceiveBufferSize(final int receiveBufferSize)
1267      {
1268        if (receiveBufferSize < 0)
1269        {
1270          this.receiveBufferSize = 0;
1271        }
1272        else
1273        {
1274          this.receiveBufferSize = receiveBufferSize;
1275        }
1276      }
1277    
1278    
1279    
1280      /**
1281       * Retrieves the socket send buffer size that should be requested when
1282       * establishing a connection.
1283       *
1284       * @return  The socket send buffer size that should be requested when
1285       *          establishing a connection, or zero if the default size should be
1286       *          used.
1287       */
1288      public int getSendBufferSize()
1289      {
1290        return sendBufferSize;
1291      }
1292    
1293    
1294    
1295      /**
1296       * Specifies the socket send buffer size that should be requested when
1297       * establishing a connection.
1298       *
1299       * @param  sendBufferSize  The socket send buffer size that should be
1300       *                         requested when establishing a connection, or zero
1301       *                         if the default size should be used.
1302       */
1303      public void setSendBufferSize(final int sendBufferSize)
1304      {
1305        if (sendBufferSize < 0)
1306        {
1307          this.sendBufferSize = 0;
1308        }
1309        else
1310        {
1311          this.sendBufferSize = sendBufferSize;
1312        }
1313      }
1314    
1315    
1316    
1317      /**
1318       * Indicates whether to allow a socket factory instance (which may be shared
1319       * across multiple connections) to be used create multiple sockets
1320       * concurrently.  In general, socket factory implementations are threadsafe
1321       * and can be to create multiple connections simultaneously across separate
1322       * threads, but this is known to not be the case in some VM implementations
1323       * (e.g., SSL socket factories in IBM JVMs).  This setting may be used to
1324       * indicate whether concurrent socket creation attempts should be allowed
1325       * (which may allow for better and more consistent performance, especially in
1326       * cases where a connection attempt fails due to a timeout) or prevented
1327       * (which may be necessary for non-threadsafe socket factory implementations).
1328       *
1329       * @return  {@code true} if multiple threads should be able to concurrently
1330       *          use the same socket factory instance, or {@code false} if Java
1331       *          synchronization should be used to ensure that no more than one
1332       *          thread is allowed to use a socket factory at any given time.
1333       */
1334      public boolean allowConcurrentSocketFactoryUse()
1335      {
1336        return allowConcurrentSocketFactoryUse;
1337      }
1338    
1339    
1340    
1341      /**
1342       * Specifies whether to allow a socket factory instance (which may be shared
1343       * across multiple connections) to be used create multiple sockets
1344       * concurrently.  In general, socket factory implementations are threadsafe
1345       * and can be to create multiple connections simultaneously across separate
1346       * threads, but this is known to not be the case in some VM implementations
1347       * (e.g., SSL socket factories in IBM JVMs).  This setting may be used to
1348       * indicate whether concurrent socket creation attempts should be allowed
1349       * (which may allow for better and more consistent performance, especially in
1350       * cases where a connection attempt fails due to a timeout) or prevented
1351       * (which may be necessary for non-threadsafe socket factory implementations).
1352       *
1353       * @param  allowConcurrentSocketFactoryUse  Indicates whether to allow a
1354       *                                          socket factory instance to be used
1355       *                                          to create multiple sockets
1356       *                                          concurrently.
1357       */
1358      public void setAllowConcurrentSocketFactoryUse(
1359                       final boolean allowConcurrentSocketFactoryUse)
1360      {
1361        this.allowConcurrentSocketFactoryUse = allowConcurrentSocketFactoryUse;
1362      }
1363    
1364    
1365    
1366      /**
1367       * Retrieves the {@code SSLSocketVerifier} that will be used to perform
1368       * additional validation for any newly-created {@code SSLSocket} instances.
1369       *
1370       * @return  The {@code SSLSocketVerifier} that will be used to perform
1371       *          additional validation for any newly-created {@code SSLSocket}
1372       *          instances.
1373       */
1374      public SSLSocketVerifier getSSLSocketVerifier()
1375      {
1376        return sslSocketVerifier;
1377      }
1378    
1379    
1380    
1381      /**
1382       * Specifies the {@code SSLSocketVerifier} that will be used to perform
1383       * additional validation for any newly-created {@code SSLSocket} instances.
1384       *
1385       * @param  sslSocketVerifier  The {@code SSLSocketVerifier} that will be used
1386       *                            to perform additional validation for any
1387       *                            newly-created {@code SSLSocket} instances.
1388       */
1389      public void setSSLSocketVerifier(final SSLSocketVerifier sslSocketVerifier)
1390      {
1391        if (sslSocketVerifier == null)
1392        {
1393          this.sslSocketVerifier = DEFAULT_SSL_SOCKET_VERIFIER;
1394        }
1395        else
1396        {
1397          this.sslSocketVerifier = sslSocketVerifier;
1398        }
1399      }
1400    
1401    
1402    
1403      /**
1404       * Retrieves a string representation of this LDAP connection.
1405       *
1406       * @return  A string representation of this LDAP connection.
1407       */
1408      @Override()
1409      public String toString()
1410      {
1411        final StringBuilder buffer = new StringBuilder();
1412        toString(buffer);
1413        return buffer.toString();
1414      }
1415    
1416    
1417    
1418      /**
1419       * Appends a string representation of this LDAP connection to the provided
1420       * buffer.
1421       *
1422       * @param  buffer  The buffer to which to append a string representation of
1423       *                 this LDAP connection.
1424       */
1425      public void toString(final StringBuilder buffer)
1426      {
1427        buffer.append("LDAPConnectionOptions(autoReconnect=");
1428        buffer.append(autoReconnect);
1429        buffer.append(", bindWithDNRequiresPassword=");
1430        buffer.append(bindWithDNRequiresPassword);
1431        buffer.append(", followReferrals=");
1432        buffer.append(followReferrals);
1433        if (followReferrals)
1434        {
1435          buffer.append(", referralHopLimit=");
1436          buffer.append(referralHopLimit);
1437        }
1438        if (referralConnector != null)
1439        {
1440          buffer.append(", referralConnectorClass=");
1441          buffer.append(referralConnector.getClass().getName());
1442        }
1443        buffer.append(", useKeepAlive=");
1444        buffer.append(useKeepAlive);
1445        buffer.append(", useLinger=");
1446        if (useLinger)
1447        {
1448          buffer.append("true, lingerTimeoutSeconds=");
1449          buffer.append(lingerTimeout);
1450        }
1451        else
1452        {
1453          buffer.append("false");
1454        }
1455        buffer.append(", useReuseAddress=");
1456        buffer.append(useReuseAddress);
1457        buffer.append(", useSchema=");
1458        buffer.append(useSchema);
1459        buffer.append(", usePooledSchema=");
1460        buffer.append(usePooledSchema);
1461        buffer.append(", pooledSchemaTimeoutMillis=");
1462        buffer.append(pooledSchemaTimeout);
1463        buffer.append(", useSynchronousMode=");
1464        buffer.append(useSynchronousMode);
1465        buffer.append(", useTCPNoDelay=");
1466        buffer.append(useTCPNoDelay);
1467        buffer.append(", captureConnectStackTrace=");
1468        buffer.append(captureConnectStackTrace);
1469        buffer.append(", connectTimeoutMillis=");
1470        buffer.append(connectTimeout);
1471        buffer.append(", responseTimeoutMillis=");
1472        buffer.append(responseTimeout);
1473        buffer.append(", abandonOnTimeout=");
1474        buffer.append(abandonOnTimeout);
1475        buffer.append(", maxMessageSize=");
1476        buffer.append(maxMessageSize);
1477        buffer.append(", receiveBufferSize=");
1478        buffer.append(receiveBufferSize);
1479        buffer.append(", sendBufferSize=");
1480        buffer.append(sendBufferSize);
1481        buffer.append(", allowConcurrentSocketFactoryUse=");
1482        buffer.append(allowConcurrentSocketFactoryUse);
1483        if (disconnectHandler != null)
1484        {
1485          buffer.append(", disconnectHandlerClass=");
1486          buffer.append(disconnectHandler.getClass().getName());
1487        }
1488        if (unsolicitedNotificationHandler != null)
1489        {
1490          buffer.append(", unsolicitedNotificationHandlerClass=");
1491          buffer.append(unsolicitedNotificationHandler.getClass().getName());
1492        }
1493    
1494        buffer.append(", sslSocketVerifierClass='");
1495        buffer.append(sslSocketVerifier.getClass().getName());
1496        buffer.append('\'');
1497    
1498        buffer.append(')');
1499      }
1500    }