> -----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]
