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