Open Bug 341217 Opened 18 years ago Updated 18 years ago

add capability to set socket options via ldap_set_option()

Categories

(Directory :: LDAP C SDK, enhancement, P2)

x86
Windows XP
enhancement

Tracking

(Not tracked)

People

(Reporter: sraut, Assigned: mcs)

Details

User-Agent:       Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
Build Identifier: 

ldap_result() is supposed to return -1 in case of an error and 0 on successful return of the function or in case of timeout. Considering the scenario that client program and ldap server are running on different machines, this function returns correctly as -1 if the remote ldap server is brought down, or the network cable of client machine is plugged out. But it returns as 0 if the network cable of server machine is plugged out, thus giving the false indication that the API returned successfully.

This has been tested with SunOne directory server 5.2.

Reproducible: Always

Steps to Reproduce:
1. Write a small program to bind to a remore ldap server, call ldap_search_ext, and then in a loop call ldap_result to fetch the search results of this asynchronous function.
2. Debug the program and observe that ldap_result returns 0 everytime.
3. Now while debug session is still in progress, plug out the network cable of ldap server and observe the return value of ldap_result. 
Actual Results:  
The function still returns as 0.


Expected Results:  
The function should return -1 in case of host not being reachable
I am not sure if this is a bug, although I understand the behavior is difficult to handle within a client program.  A 0 return value from ldap_result() means "the request timed out" which is probably exactly what is happening at the TCP/IP layer.  In other words, the client operating system is probably not returning an error to libldap, so libldap can't report an error to the calling program.

You could enable TCP keepalives on your system or on a particular LDAP connection; that should allow you to detect this "server has gone away" problem much more quickly.
This function returns 0 even if keepalives are enabled. I have tested it by setting the value of KeepAliveTime registery parameter to 1 minute.
LDAP C SDK uses the standard OS TCP/IP stack.  Is there some way to get information from the OS about the particular mode of failure?  How do other network APIs work in this regard?  e.g. can telnet or ftp tell?
(In reply to comment #2)
> This function returns 0 even if keepalives are enabled. I have tested it by
> setting the value of KeepAliveTime registery parameter to 1 minute.

I do not have much experience using keep alives.  Are you sure keep alive packets were sent?  Did you set the appropriate socket option from your LDAP application?  Sorry for the dumb questions, but I am surprised keep alives do not help.

(In reply to comment #4)
> (In reply to comment #2)
> > This function returns 0 even if keepalives are enabled. I have tested it by
> > setting the value of KeepAliveTime registery parameter to 1 minute.
> I do not have much experience using keep alives.  Are you sure keep alive
> packets were sent?  Did you set the appropriate socket option from your LDAP
> application?  Sorry for the dumb questions, but I am surprised keep alives do
> not help.

The LDAP application I have is using the LDAP C SDK. So to make a connection to LDAP server, it is using ldap_init(). ldap_init() does not take any parameter to indicate keepalives. Other session options can be set through ldap_set_option(), but even this does not directly support an option for keepalive. 

One alternative is to use LDAP_IOF_CONNECT_CALLBACK or LDAP_IOF_SOCKET_CALLBACK and set the keepalive option on the socket in this callback function. This function pointer can then be set through ldap_set_option. But that means we are overriding the connect functionality of LDAP SDK, which may not be appropriate.

Instead, would it be good to add support for an option of keepalive in ldap_set_option()?
(In reply to comment #5)
>
> The LDAP application I have is using the LDAP C SDK. So to make a connection to
> LDAP server, it is using ldap_init(). ldap_init() does not take any parameter
> to indicate keepalives. Other session options can be set through
> ldap_set_option(), but even this does not directly support an option for
> keepalive.

Once the connection is established (i.e., after you use it for at least one LDAP operation), you should be able to use the LDAP_OPT_DESC option to retrieve the OS socket.

> One alternative is to use LDAP_IOF_CONNECT_CALLBACK or LDAP_IOF_SOCKET_CALLBACK
> and set the keepalive option on the socket in this callback function. This
> function pointer can then be set through ldap_set_option. But that means we are
> overriding the connect functionality of LDAP SDK, which may not be appropriate.

Agreed.  If you are willing to use libprldap, you can "subclass" the connect function by calling prldap_init(), using ldap_get_option() to retrieve the extended I/O functions, saving the old connection function pointer, and then installing your own connect function which does something like:

  - Call prldap (old) connect function.
  - Turn on keepalives on the socket.


> Instead, would it be good to add support for an option of keepalive in
> ldap_set_option()?

I am not opposed to this, but have you confirmed that keepalives help fix your problem?
(In reply to comment #6)
> Once the connection is established (i.e., after you use it for at least one
> LDAP operation), you should be able to use the LDAP_OPT_DESC option to retrieve
> the OS socket.
With this I was able to set the keepalive option and that fixed the problem I was facing. After the interval of keepAliveTime, the ldap application detects the connection failure.
What is the action item to resolve this issue?  Do we need to add something to our documentation?  Are any code changes required?
We are currently doing a lot of work on the ldap c sdk.  This is our window of opportunity.  So if there is any work needed on this bug, please let us know asap before our window of opportunity closes.
It would be good to add support for socket options (e.g. SO_KEEPALIVE) in ldap_set_option(). 
Updated summary, severity, and priority.  I agree it would be nice to be able to set socket options, but I do not have time to do the work right now.
Severity: normal → enhancement
Priority: -- → P2
Summary: ldap_result() returns success even if the LDAP server is not reachable → add capability to set socket options via ldap_set_option()
You need to log in before you can comment on or make changes to this bug.