> -----Original Message-----
> From: Pierangelo Masarati [mailto:[EMAIL PROTECTED] 
> 
> 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
[EMAIL PROTECTED]


Reply via email to