Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
openldap
OpenLDAP
Commits
3bd1b090
Commit
3bd1b090
authored
Mar 29, 2019
by
Ondřej Kuzník
Committed by
Ondřej Kuzník
Mar 30, 2021
Browse files
ITS
#9001
Use a TAvl for request tracking in libldap
parent
e36d1e31
Pipeline
#2316
passed with stage
in 48 minutes and 30 seconds
Changes
6
Pipelines
2
Hide whitespace changes
Inline
Side-by-side
libraries/libldap/abandon.c
View file @
3bd1b090
...
...
@@ -40,7 +40,7 @@ static int
do_abandon
(
LDAP
*
ld
,
ber_int_t
origid
,
ber_int_t
msgid
,
LDAPRequest
*
lr
,
LDAPControl
**
sctrls
,
int
sendabandon
);
...
...
@@ -75,7 +75,7 @@ ldap_abandon_ext(
rc
=
ldap_int_client_controls
(
ld
,
cctrls
);
if
(
rc
==
LDAP_SUCCESS
)
{
rc
=
do_abandon
(
ld
,
msgid
,
msgid
,
sctrls
,
1
);
rc
=
do_abandon
(
ld
,
msgid
,
NULL
,
sctrls
,
1
);
}
LDAP_MUTEX_UNLOCK
(
&
ld
->
ld_req_mutex
);
...
...
@@ -112,7 +112,7 @@ ldap_pvt_discard(
int
rc
;
LDAP_MUTEX_LOCK
(
&
ld
->
ld_req_mutex
);
rc
=
do_abandon
(
ld
,
msgid
,
msgid
,
NULL
,
0
);
rc
=
do_abandon
(
ld
,
msgid
,
NULL
,
NULL
,
0
);
LDAP_MUTEX_UNLOCK
(
&
ld
->
ld_req_mutex
);
return
rc
;
}
...
...
@@ -121,49 +121,52 @@ static int
do_abandon
(
LDAP
*
ld
,
ber_int_t
origid
,
ber_int_t
msgid
,
LDAPRequest
*
lr
,
LDAPControl
**
sctrls
,
int
sendabandon
)
{
BerElement
*
ber
;
int
i
,
err
;
ber_int_t
msgid
=
origid
;
Sockbuf
*
sb
;
LDAPRequest
*
lr
;
Debug2
(
LDAP_DEBUG_TRACE
,
"do_abandon origid %d, msgid %d
\n
"
,
origid
,
msgid
);
/* find the request that we are abandoning */
start_again:
;
lr
=
ld
->
ld_requests
;
while
(
lr
!=
NULL
)
{
/* this message */
if
(
lr
->
lr_msgid
==
msgid
)
{
break
;
}
/* child: abandon it */
if
(
lr
->
lr_origid
==
msgid
&&
!
lr
->
lr_abandoned
)
{
(
void
)
do_abandon
(
ld
,
lr
->
lr_origid
,
lr
->
lr_msgid
,
sctrls
,
sendabandon
);
/* restart, as lr may now be dangling... */
goto
start_again
;
}
LDAPRequest
needle
=
{
0
};
lr
=
lr
->
lr_next
;
}
needle
.
lr_msgid
=
origid
;
if
(
lr
!=
NULL
)
{
if
(
origid
==
msgid
&&
lr
->
lr_parent
!=
NULL
)
{
msgid
=
lr
->
lr_msgid
;
Debug2
(
LDAP_DEBUG_TRACE
,
"do_abandon origid %d, msgid %d
\n
"
,
origid
,
msgid
);
}
else
if
(
(
lr
=
ldap_tavl_find
(
ld
->
ld_requests
,
&
needle
,
ldap_req_cmp
))
!=
NULL
)
{
Debug2
(
LDAP_DEBUG_TRACE
,
"do_abandon origid %d, msgid %d
\n
"
,
origid
,
msgid
);
if
(
lr
->
lr_parent
!=
NULL
)
{
/* don't let caller abandon child requests! */
ld
->
ld_errno
=
LDAP_PARAM_ERROR
;
return
(
LDAP_PARAM_ERROR
);
}
msgid
=
lr
->
lr_msgid
;
}
if
(
lr
!=
NULL
)
{
LDAPRequest
**
childp
=
&
lr
->
lr_child
;
needle
.
lr_msgid
=
lr
->
lr_msgid
;
if
(
lr
->
lr_status
!=
LDAP_REQST_INPROGRESS
)
{
/* no need to send abandon message */
sendabandon
=
0
;
}
while
(
*
childp
)
{
/* Abandon children */
LDAPRequest
*
child
=
*
childp
;
(
void
)
do_abandon
(
ld
,
lr
->
lr_origid
,
child
,
sctrls
,
sendabandon
);
if
(
*
childp
==
child
)
{
childp
=
&
child
->
lr_refnext
;
}
}
}
/* ldap_msgdelete locks the res_mutex. Give up the req_mutex
...
...
@@ -179,12 +182,7 @@ start_again:;
/* fetch again the request that we are abandoning */
if
(
lr
!=
NULL
)
{
for
(
lr
=
ld
->
ld_requests
;
lr
!=
NULL
;
lr
=
lr
->
lr_next
)
{
/* this message */
if
(
lr
->
lr_msgid
==
msgid
)
{
break
;
}
}
lr
=
ldap_tavl_find
(
ld
->
ld_requests
,
&
needle
,
ldap_req_cmp
);
}
err
=
0
;
...
...
libraries/libldap/ldap-int.h
View file @
3bd1b090
...
...
@@ -26,6 +26,7 @@
#include
"../liblber/lber-int.h"
#include
"lutil.h"
#include
"ldap_avl.h"
#ifdef LDAP_R_COMPILE
#include
<ldap_pvt_thread.h>
...
...
@@ -438,7 +439,7 @@ struct ldap_common {
/* do not mess with these */
/* protected by req_mutex */
LDAPRequest
*
ldc_requests
;
/* list of outstanding requests */
TAvlnode
*
ldc_requests
;
/* list of outstanding requests */
/* protected by res_mutex */
LDAPMessage
*
ldc_responses
;
/* list of outstanding responses */
#define ld_requests ldc->ldc_requests
...
...
@@ -776,6 +777,8 @@ LDAP_F (LDAPConn *) ldap_new_connection( LDAP *ld, LDAPURLDesc **srvlist,
int
use_ldsb
,
int
connect
,
LDAPreqinfo
*
bind
,
int
m_req
,
int
m_res
);
LDAP_F
(
LDAPRequest
*
)
ldap_find_request_by_msgid
(
LDAP
*
ld
,
ber_int_t
msgid
);
LDAP_F
(
void
)
ldap_return_request
(
LDAP
*
ld
,
LDAPRequest
*
lr
,
int
freeit
);
LDAP_F
(
int
)
ldap_req_cmp
(
const
void
*
l
,
const
void
*
r
);
LDAP_F
(
void
)
ldap_do_free_request
(
void
*
arg
);
LDAP_F
(
void
)
ldap_free_request
(
LDAP
*
ld
,
LDAPRequest
*
lr
);
LDAP_F
(
void
)
ldap_free_connection
(
LDAP
*
ld
,
LDAPConn
*
lc
,
int
force
,
int
unbind
);
LDAP_F
(
void
)
ldap_dump_connection
(
LDAP
*
ld
,
LDAPConn
*
lconns
,
int
all
);
...
...
libraries/libldap/open.c
View file @
3bd1b090
...
...
@@ -574,7 +574,8 @@ ldap_open_internal_connection( LDAP **ldp, ber_socket_t *fdp )
lr
->
lr_status
=
LDAP_REQST_INPROGRESS
;
lr
->
lr_res_errno
=
LDAP_SUCCESS
;
/* no mutex lock needed, we just created this ld here */
ld
->
ld_requests
=
lr
;
rc
=
ldap_tavl_insert
(
&
ld
->
ld_requests
,
lr
,
ldap_req_cmp
,
ldap_avl_dup_error
);
assert
(
rc
==
LDAP_SUCCESS
);
LDAP_MUTEX_LOCK
(
&
ld
->
ld_conn_mutex
);
/* Attach the passed socket as the *LDAP's connection */
...
...
libraries/libldap/request.c
View file @
3bd1b090
...
...
@@ -328,11 +328,16 @@ ldap_send_server_request(
* request to be in WRITING state.
*/
rc
=
0
;
if
(
ld
->
ld_requests
&&
ld
->
ld_requests
->
lr_status
==
LDAP_REQST_WRITING
&&
ldap_int_flush_request
(
ld
,
ld
->
ld_requests
)
<
0
)
{
rc
=
-
1
;
if
(
ld
->
ld_requests
!=
NULL
)
{
TAvlnode
*
node
=
ldap_tavl_end
(
ld
->
ld_requests
,
TAVL_DIR_RIGHT
);
LDAPRequest
*
lr
;
assert
(
node
!=
NULL
);
lr
=
node
->
avl_data
;
if
(
lr
->
lr_status
==
LDAP_REQST_WRITING
&&
ldap_int_flush_request
(
ld
,
lr
)
<
0
)
{
rc
=
-
1
;
}
}
if
(
rc
)
{
ber_free
(
ber
,
1
);
...
...
@@ -399,12 +404,8 @@ ldap_send_server_request(
}
}
lr
->
lr_prev
=
NULL
;
lr
->
lr_next
=
ld
->
ld_requests
;
if
(
lr
->
lr_next
!=
NULL
)
{
lr
->
lr_next
->
lr_prev
=
lr
;
}
ld
->
ld_requests
=
lr
;
rc
=
ldap_tavl_insert
(
&
ld
->
ld_requests
,
lr
,
ldap_req_cmp
,
ldap_avl_dup_error
);
assert
(
rc
==
LDAP_SUCCESS
);
ld
->
ld_errno
=
LDAP_SUCCESS
;
if
(
ldap_int_flush_request
(
ld
,
lr
)
==
-
1
)
{
...
...
@@ -803,19 +804,10 @@ ldap_free_connection( LDAP *ld, LDAPConn *lc, int force, int unbind )
/* FIXME: is this at all possible?
* ldap_ld_free() in unbind.c calls ldap_free_connection()
* with force == 1 __after__ explicitly calling
* ldap_
free_request() on all
requests */
* ldap_
tavl_free on ld->ld_
requests */
if
(
force
)
{
LDAPRequest
*
lr
;
for
(
lr
=
ld
->
ld_requests
;
lr
;
)
{
LDAPRequest
*
lr_next
=
lr
->
lr_next
;
if
(
lr
->
lr_conn
==
lc
)
{
ldap_free_request_int
(
ld
,
lr
);
}
lr
=
lr_next
;
}
ldap_tavl_free
(
ld
->
ld_requests
,
ldap_do_free_request
);
ld
->
ld_requests
=
NULL
;
}
if
(
lc
->
lconn_sb
!=
ld
->
ld_sb
)
{
...
...
@@ -913,17 +905,19 @@ ldap_dump_connection( LDAP *ld, LDAPConn *lconns, int all )
void
ldap_dump_requests_and_responses
(
LDAP
*
ld
)
{
LDAPRequest
*
lr
;
LDAPMessage
*
lm
,
*
l
;
TAvlnode
*
node
;
int
i
;
Debug1
(
LDAP_DEBUG_TRACE
,
"** ld %p Outstanding Requests:
\n
"
,
(
void
*
)
ld
);
lr
=
ld
->
ld_requests
;
if
(
lr
==
NULL
)
{
node
=
ld
ap_tavl_end
(
ld
->
ld_requests
,
TAVL_DIR_LEFT
)
;
if
(
node
==
NULL
)
{
Debug0
(
LDAP_DEBUG_TRACE
,
" Empty
\n
"
);
}
for
(
i
=
0
;
lr
!=
NULL
;
lr
=
lr
->
lr_next
,
i
++
)
{
for
(
i
=
0
;
node
!=
NULL
;
i
++
,
node
=
ldap_tavl_next
(
node
,
TAVL_DIR_RIGHT
)
)
{
LDAPRequest
*
lr
=
node
->
avl_data
;
Debug3
(
LDAP_DEBUG_TRACE
,
" * msgid %d, origid %d, status %s
\n
"
,
lr
->
lr_msgid
,
lr
->
lr_origid
,
(
lr
->
lr_status
==
LDAP_REQST_INPROGRESS
)
?
"InProgress"
:
...
...
@@ -959,39 +953,21 @@ ldap_dump_requests_and_responses( LDAP *ld )
#endif
/* LDAP_DEBUG */
/* protected by req_mutex */
static
void
ldap_free_request
_int
(
LDAP
*
ld
,
LDAPRequest
*
lr
)
void
ldap_
do_
free_request
(
void
*
arg
)
{
LDAP_ASSERT_MUTEX_OWNER
(
&
ld
->
ld_req_mutex
);
LDAPRequest
*
lr
=
arg
;
Debug3
(
LDAP_DEBUG_TRACE
,
"ldap_do_free_request: "
"asked to free lr %p msgid %d refcnt %d
\n
"
,
lr
,
lr
->
lr_msgid
,
lr
->
lr_refcnt
);
/* if lr_refcnt > 0, the request has been looked up
* by ldap_find_request_by_msgid(); if in the meanwhile
* the request is free()'d by someone else, just decrease
* the reference count and extract it from the request
* list; later on, it will be freed. */
if
(
lr
->
lr_prev
==
NULL
)
{
if
(
lr
->
lr_refcnt
==
0
)
{
/* free'ing the first request? */
assert
(
ld
->
ld_requests
==
lr
);
}
if
(
ld
->
ld_requests
==
lr
)
{
ld
->
ld_requests
=
lr
->
lr_next
;
}
}
else
{
lr
->
lr_prev
->
lr_next
=
lr
->
lr_next
;
}
if
(
lr
->
lr_next
!=
NULL
)
{
lr
->
lr_next
->
lr_prev
=
lr
->
lr_prev
;
}
* the reference count; later on, it will be freed. */
if
(
lr
->
lr_refcnt
>
0
)
{
assert
(
lr
->
lr_refcnt
==
1
);
lr
->
lr_refcnt
=
-
lr
->
lr_refcnt
;
lr
->
lr_prev
=
NULL
;
lr
->
lr_next
=
NULL
;
return
;
}
...
...
@@ -1013,6 +989,29 @@ ldap_free_request_int( LDAP *ld, LDAPRequest *lr )
LDAP_FREE
(
lr
);
}
int
ldap_req_cmp
(
const
void
*
l
,
const
void
*
r
)
{
const
LDAPRequest
*
left
=
l
,
*
right
=
r
;
return
left
->
lr_msgid
-
right
->
lr_msgid
;
}
/* protected by req_mutex */
static
void
ldap_free_request_int
(
LDAP
*
ld
,
LDAPRequest
*
lr
)
{
LDAPRequest
*
removed
;
LDAP_ASSERT_MUTEX_OWNER
(
&
ld
->
ld_req_mutex
);
removed
=
ldap_tavl_delete
(
&
ld
->
ld_requests
,
lr
,
ldap_req_cmp
);
assert
(
!
removed
||
removed
==
lr
);
Debug3
(
LDAP_DEBUG_TRACE
,
"ldap_free_request_int: "
"lr %p msgid %d%s removed
\n
"
,
lr
,
lr
->
lr_msgid
,
removed
?
""
:
" not"
);
ldap_do_free_request
(
lr
);
}
/* protected by req_mutex */
void
ldap_free_request
(
LDAP
*
ld
,
LDAPRequest
*
lr
)
...
...
@@ -1662,19 +1661,24 @@ re_encode_request( LDAP *ld,
LDAPRequest
*
ldap_find_request_by_msgid
(
LDAP
*
ld
,
ber_int_t
msgid
)
{
LDAPRequest
*
lr
;
for
(
lr
=
ld
->
ld_requests
;
lr
!=
NULL
;
lr
=
lr
->
lr_next
)
{
if
(
lr
->
lr_status
==
LDAP_REQST_COMPLETED
)
{
continue
;
/* Skip completed requests */
}
if
(
msgid
==
lr
->
lr_msgid
)
{
lr
->
lr_refcnt
++
;
break
;
}
LDAPRequest
*
lr
,
needle
=
{
0
};
needle
.
lr_msgid
=
msgid
;
lr
=
ldap_tavl_find
(
ld
->
ld_requests
,
&
needle
,
ldap_req_cmp
);
if
(
lr
!=
NULL
&&
lr
->
lr_status
!=
LDAP_REQST_COMPLETED
)
{
/* try_read1msg is the only user at the moment and we would free it
* multiple times if retrieving the request again */
assert
(
lr
->
lr_refcnt
==
0
);
lr
->
lr_refcnt
++
;
Debug3
(
LDAP_DEBUG_TRACE
,
"ldap_find_request_by_msgid: "
"msgid %d, lr %p lr->lr_refcnt = %d
\n
"
,
msgid
,
lr
,
lr
->
lr_refcnt
);
return
lr
;
}
return
(
lr
);
Debug2
(
LDAP_DEBUG_TRACE
,
"ldap_find_request_by_msgid: "
"msgid %d, lr %p
\n
"
,
msgid
,
lr
);
return
NULL
;
}
/* protected by req_mutex */
...
...
@@ -1683,23 +1687,26 @@ ldap_return_request( LDAP *ld, LDAPRequest *lrx, int freeit )
{
LDAPRequest
*
lr
;
for
(
lr
=
ld
->
ld_requests
;
lr
!=
NULL
;
lr
=
lr
->
lr_next
)
{
if
(
lr
==
lrx
)
{
if
(
lr
->
lr_refcnt
>
0
)
{
lr
->
lr_refcnt
--
;
}
else
if
(
lr
->
lr_refcnt
<
0
)
{
lr
->
lr_refcnt
++
;
if
(
lr
->
lr_refcnt
==
0
)
{
lr
=
NULL
;
}
lr
=
ldap_tavl_find
(
ld
->
ld_requests
,
lrx
,
ldap_req_cmp
);
Debug2
(
LDAP_DEBUG_TRACE
,
"ldap_return_request: "
"lrx %p, lr %p
\n
"
,
lrx
,
lr
);
if
(
lr
)
{
assert
(
lr
==
lrx
);
if
(
lr
->
lr_refcnt
>
0
)
{
lr
->
lr_refcnt
--
;
}
else
if
(
lr
->
lr_refcnt
<
0
)
{
lr
->
lr_refcnt
++
;
if
(
lr
->
lr_refcnt
==
0
)
{
lr
=
NULL
;
}
break
;
}
}
Debug3
(
LDAP_DEBUG_TRACE
,
"ldap_return_request: "
"lrx->lr_msgid %d, lrx->lr_refcnt is now %d, lr is %s present
\n
"
,
lrx
->
lr_msgid
,
lrx
->
lr_refcnt
,
lr
?
"still"
:
"not"
);
/* The request is not tracked anymore */
if
(
lr
==
NULL
)
{
ldap_free_request_int
(
ld
,
lrx
);
}
else
if
(
freeit
)
{
ldap_free_request
(
ld
,
lrx
);
}
...
...
libraries/libldap/result.c
View file @
3bd1b090
...
...
@@ -344,13 +344,17 @@ wait4msg(
int
serviced
=
0
;
rc
=
LDAP_MSG_X_KEEP_LOOKING
;
LDAP_MUTEX_LOCK
(
&
ld
->
ld_req_mutex
);
if
(
ld
->
ld_requests
&&
ld
->
ld_requests
->
lr_status
==
LDAP_REQST_WRITING
&&
ldap_is_write_ready
(
ld
,
ld
->
ld_requests
->
lr_conn
->
lconn_sb
)
)
{
serviced
=
1
;
ldap_int_flush_request
(
ld
,
ld
->
ld_requests
);
if
(
ld
->
ld_requests
!=
NULL
)
{
TAvlnode
*
node
=
ldap_tavl_end
(
ld
->
ld_requests
,
TAVL_DIR_RIGHT
);
LDAPRequest
*
lr
;
assert
(
node
!=
NULL
);
lr
=
node
->
avl_data
;
if
(
lr
->
lr_status
==
LDAP_REQST_WRITING
&&
ldap_is_write_ready
(
ld
,
lr
->
lr_conn
->
lconn_sb
)
)
{
serviced
=
1
;
ldap_int_flush_request
(
ld
,
lr
);
}
}
for
(
lc
=
ld
->
ld_conns
;
rc
==
LDAP_MSG_X_KEEP_LOOKING
&&
lc
!=
NULL
;
...
...
@@ -452,7 +456,7 @@ try_read1msg(
LDAPRequest
*
lr
,
*
tmplr
,
dummy_lr
=
{
0
};
BerElement
tmpber
;
int
rc
,
refer_cnt
,
hadref
,
simple_request
,
err
;
ber_int_t
lderr
;
ber_int_t
lderr
=
-
1
;
#ifdef LDAP_CONNECTIONLESS
LDAPMessage
*
tmp
=
NULL
,
*
chain_head
=
NULL
;
...
...
libraries/libldap/unbind.c
View file @
3bd1b090
...
...
@@ -108,9 +108,8 @@ ldap_ld_free(
/* free LDAP structure and outstanding requests/responses */
LDAP_MUTEX_LOCK
(
&
ld
->
ld_req_mutex
);
while
(
ld
->
ld_requests
!=
NULL
)
{
ldap_free_request
(
ld
,
ld
->
ld_requests
);
}
ldap_tavl_free
(
ld
->
ld_requests
,
ldap_do_free_request
);
ld
->
ld_requests
=
NULL
;
LDAP_MUTEX_UNLOCK
(
&
ld
->
ld_req_mutex
);
LDAP_MUTEX_LOCK
(
&
ld
->
ld_conn_mutex
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment