[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
RE: Infinite chasing of cycled V3 referrals/references (ITS#2894)
Hello Howard.
I've tested the fix you'd made.
I checked out the HEAD sources from the CVS, compiled them and rebuilt my
simple program.
Unfortunately, it still goes into infinite loop while chasing cycled
references.
When I was studying the changes I found that original request (origreq) is
still used as a parent for a child request.
rc = ldap_send_server_request( ld, ber, id,
(sref && !parent_was_reference) ? origreq :
lr,
srv, NULL, &rinfo );
Assume we're chasing a chain of references, I mean a reference points to the
entries one of which is another reference and so on:
Entry (search - origreq)
|--entry
|--sref --[step1]-->|--entry
|--entry
|--sref --[step2]-->|--entry
|--sref-->...
Step1. Chasing the first reference in the chain: sref==1,
paren_was_reference==0 (lr actually doesn't have a parent, it is the
original request). So origreq becomes the parent for the new request.
Step2. Chasing the second reference in the chain: serf==1,
parent_was-reference==0, because on the step1 we assigned origreq as the
parent for the new request and
origreq->lr_res_msgtype<>LDAP_RES_SEARCH_REFERENCE actually. Again, origreq
becomes the parent for the new child request.
Investigating the code I can't understand why you preserved the 'origreq' as
a parent for a child request? Why and how does the using of 'origreq' or
'lr' as a parent depend on 'sref' parameter? I mean that counting of parents
should be correct for search references as well as for result referrals. It
seems I don't understand something in the library's ideology...
Actually, I tried to fix the issue by myself:
- replaced the call of the ldap_send_server_request organizing requests
into a tree, not a list:
rc = ldap_send_server_request( ld, ber, id, lr, srv, NULL, &rinfo );
- changed the procedure of determining whether or not the request is
completed.
------------------
static LDAPRequest* get_noncompleted_child(LDAPRequest* lr);
/* lr - parent request in a request tree
* Returns NULL or the non-completed request from the tree
*/
LDAPRequest* get_noncompleted_child(LDAPRequest* lr)
{
LDAPRequest *childlr = NULL, *tmplr = NULL;
if (lr && lr->lr_status == LDAP_REQST_COMPLETED && lr->lr_outrefcnt <=
0)
{
for(childlr = lr->lr_child; childlr != NULL; childlr =
childlr->lr_refnext)
{
if (childlr->lr_child) // has an own child?
{
if(tmplr = get_noncompleted_child(childlr))
return tmplr;
}
else
{
if(childlr->lr_status !=
LDAP_REQST_COMPLETED || childlr->lr_outrefcnt > 0)
break;
}
}
return childlr;
}
return lr;
}
---------------------------------
The existing procedure verifies a list of requests. I had to add a recursive
function (presented above) and change the code to check a request tree
(result.c, lines 775-...):
/* Check if all requests are finished, lr is now parent */
tmplr = lr;
if (lr->lr_outrefcnt <= 0) // there is no sense to check if outrefcnt >
0
{
tmplr = get_noncompleted_child(tmplr);
}
Then I performed testing of chasing cycled references and it worked fine.
But it worked only when the references were placed on a single server. When
I made references from one server to another and back to the first one the
tests failed again: though they didn't go into infinite loop they couldn't
fetch all expected entries. Unfortunately, I didn't have enough time to
finish investigations and complete the fix.
With best regards,
Alexander.
> -----Original Message-----
> From: Howard Chu [mailto:openldap-its@OpenLDAP.org]
> Sent: Sunday, January 25, 2004 11:32 AM
> To: alex_dz@softhome.net
> Subject: Re: Infinite chasing of cycled V3 referrals/references (ITS#2894)
>
> I've just committed a patch to CVS HEAD for this, please test.