[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
RE: Notice of disconnection
- To: "Pierangelo Masarati" <ando@sys-net.it>
- Subject: RE: Notice of disconnection
- From: "Lars Hesel Christensen XX \(AH/LMD\)" <lars.hesel.xx.christensen@ericsson.com>
- Date: Wed, 3 Jan 2007 14:00:13 +0100
- Cc: openldap-devel@openldap.org
- Content-class: urn:content-classes:message
- In-reply-to: <45969C60.6050704@sys-net.it>
- Thread-index: AccsNK07SY5cbD9OTkCB7BdGqCLoBQC/hxDw
- Thread-topic: Notice of disconnection
> -----Original Message-----
> From: Pierangelo Masarati [mailto:ando@sys-net.it]
>
> Lars Hesel Christensen XX (AH/LMD) wrote:
> > Hi all
> >
> > I've been looking at the Notice of disconnection handling
> in OpenLDAP
> > and there is a thing that is confusing me a bit.
> >
> > in result.c, the function try_read1msg reads data from socket and
> > creates a new message from that. If we receive an
> unsolicited message,
> > e.g, notice of disconnection, then the msgId will be zero,
> and we will
> > go through the following code(taken from /* $OpenLDAP:
> > /libraries/libldap/result.c,v 1.144 2006/12/17 21:04:25
> ando Exp $ */):
> >
> > /* message id */
> > if ( ber_get_int( ber, &id ) == LBER_ERROR ) {
> > ber_free( ber, 1 );
> > ld->ld_errno = LDAP_DECODING_ERROR;
> > return( -1 );
> > }
> >
> > /* if it's been abandoned, toss it */
> > if ( ldap_abandoned( ld, id, &idx ) ) {
> >
> > <REMOVED since the msgId is not abandoned>
> >
> > retry_ber:
> > ber_free( ber, 1 );
> > if ( ber_sockbuf_ctrl( lc->lconn_sb,
> LBER_SB_OPT_DATA_READY, NULL )
> > ) {
> > goto retry;
> > }
> > --> return( LDAP_MSG_X_KEEP_LOOKING ); /* continue
> > looking */
> > }
> >
> > lr = ldap_find_request_by_msgid( ld, id );
> > if ( lr == NULL ) {
> > const char *msg = "unknown";
> >
> > /* the message type */
> > tag = ber_peek_tag( ber, &len );
> > switch ( tag ) {
> > case LBER_ERROR:
> > break;
> >
> > default:
> > msg = ldap_int_msgtype2str( tag );
> > break;
> > }
> >
> > Debug( LDAP_DEBUG_ANY,
> > "no request for response on ld %p msgid
> %ld message type %s
> > (tossing)\n",
> > (void *)ld, (long)id, msg );
> >
> > goto retry_ber;
> > }
> >
> > Assuming there is no more data to be read from the socket we will
> > return in the line marked with the arrow '-->' since
> > ldap_find_request_by_msgid() returns NULL.
> >
> > What confuses me is that later on in try_read1msg we get to (after
> > constructing the message:
> >
> > /* is this the one we're looking for? */
> > if ( msgid == LDAP_RES_ANY || id == msgid ) {
> > if ( all == LDAP_MSG_ONE
> > || ( newmsg->lm_msgtype !=
> > LDAP_RES_SEARCH_RESULT
> > && newmsg->lm_msgtype !=
> > LDAP_RES_SEARCH_ENTRY
> > && newmsg->lm_msgtype !=
> > LDAP_RES_SEARCH_REFERENCE ) )
> > {
> > *result = newmsg;
> > ld->ld_errno = LDAP_SUCCESS;
> > return( tag );
> >
> > } else if ( newmsg->lm_msgtype ==
> > LDAP_RES_SEARCH_RESULT) {
> > foundit = 1; /* return the chain later */
> > }
> > }
> >
> > Do we have a test case testing notice of disconnection? I tried to
> > grep the 'tests' directory for 'notice', 'disconnection'
> and 'unsolicited'
> > but nothing came up.
> >
> > Perhaps I'm misunderstanding something here, so if I am I
> would very
> > much appreciate a hint.
> >
> Lars,
>
> AFAIK there's no handling, in OpenLDAP's code, of "Notice of
> Disconnect". Your analysis is correct, the message will be
> ignored since no request can be found for it. Note that
> there's no means, right now, to test this condition within
> OpenLDAP since its server side implementation never returns
> that message. The point, at the client library side, is: how
> should this be handled? I mean: if the caller requests
> "msgid == LDAP_RES_ANY", then the message can be returned,
> and that's it; otherwise, any unsolicited message should not
> be queued, but either dealt with by the library, if known, or
> ignored. This because, in principle, multiple unsolicited
> messages could be returned, and they would share the same msgid (0).
>
> In the case of notice of disconnect, the library could
> determine it should no longer expect any message from the
> server and, as soon as the client tries to submit a new
> request, or asks for response to a pending request, it should
> return something like LDAP_UNAVAILABLE or a (yet to be
> defined) specific return code.
>
> I think we should discuss details of how this is supposed to
> be handled by the client library, since RFC 4511 seems to
> give implementors a lot of freedom.
>
> p.
Ok, what really confused me when looking at this is the fact that the
comments for ldap_result (as well as the man pages) claims that we will
receive unsolicited messages when calling ldap_result with LDAP_RES_ANY
or LDAP_RES_UNSOLICITED.
I'm not sure about how to handle unsolicited messages other than notice
of disconnect, but as it is, when the user can just ignore unsolicited
messages, I suppose it would be a good thing if the library itself could
deal with them and dispose of them. I think this is what is intended
when reading the section about unsolicited messages in the RFC. At least
it seems to me that it would be bad/confusing if some unsolicited
messages are handled by the application and some are handled by the
library.
I think it would not be to hard to create a mock-up server that can
accept a new session and then send a notice of disconnection to the
client. That would be a simple way to test that client-side
code/handling of notice of disconnection - whatever the outcome of the
above discussion might be :)
Best regards,
Lars
--
Lars Hesel Christensen
Ericsson Denmark A/S, Telebit
lars.hesel.xx.christensen@ericsson.com