mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-10 09:19:28 +00:00
Fix bug # 140182 - async I/O improvements.
A queue of pending outbound requests is kept. UnBind requests are NOT queued however. Abandon requests are not sent if a request is not outstanding. Cleaned up the code in result.c to avoid use of magic return values such as -1 and -2. Also removed some dead code and dead files. ltest (test.c) now supports SSL and async I/O options.
This commit is contained in:
parent
acf075ad8c
commit
2aa4fa531d
@ -38,6 +38,8 @@ static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of
|
||||
|
||||
static int do_abandon( LDAP *ld, int origid, int msgid,
|
||||
LDAPControl **serverctrls, LDAPControl **clientctrls );
|
||||
static int nsldapi_send_abandon_message( LDAP *ld, LDAPConn *lc,
|
||||
BerElement *ber, int abandon_msgid );
|
||||
|
||||
/*
|
||||
* ldap_abandon - perform an ldap abandon operation. Parameters:
|
||||
@ -111,7 +113,6 @@ do_abandon( LDAP *ld, int origid, int msgid, LDAPControl **serverctrls,
|
||||
{
|
||||
BerElement *ber;
|
||||
int i, bererr, lderr, sendabandon;
|
||||
Sockbuf *sb;
|
||||
LDAPRequest *lr = NULL;
|
||||
|
||||
/*
|
||||
@ -124,92 +125,60 @@ do_abandon( LDAP *ld, int origid, int msgid, LDAPControl **serverctrls,
|
||||
/* optimistic */
|
||||
lderr = LDAP_SUCCESS;
|
||||
|
||||
/*
|
||||
* this is not the best implementation...
|
||||
* the code special cases the when async io is enabled.
|
||||
* The logic is clear this way, at the cost of code bloat.
|
||||
* This logic should be cleaned up post nova 4.5 rtm
|
||||
*/
|
||||
if (ld->ld_options & LDAP_BITOPT_ASYNC)
|
||||
{
|
||||
/* Don't send an abandon message unless there is something to abandon. */
|
||||
/*
|
||||
* Find the request that we are abandoning. Don't send an
|
||||
* abandon message unless there is something to abandon.
|
||||
*/
|
||||
sendabandon = 0;
|
||||
for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
|
||||
if ( lr->lr_msgid == msgid ) { /* this message */
|
||||
if ( origid == msgid && lr->lr_parent != NULL ) {
|
||||
/* don't let caller abandon child requests! */
|
||||
lderr = LDAP_PARAM_ERROR;
|
||||
goto set_errorcode_and_return;
|
||||
}
|
||||
if ( lr->lr_status == LDAP_REQST_INPROGRESS ) {
|
||||
/*
|
||||
* We only need to send an abandon message if
|
||||
* the request is in progress.
|
||||
*/
|
||||
sendabandon = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ( lr->lr_origid == msgid ) { /* child: abandon it */
|
||||
(void)do_abandon( ld, msgid, lr->lr_msgid,
|
||||
serverctrls, clientctrls );
|
||||
/* we ignore errors from child abandons... */
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the request that we are abandoning. */
|
||||
if (ld->ld_requests != NULL) {
|
||||
for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
|
||||
if ( lr->lr_msgid == msgid ) { /* this message */
|
||||
if ( origid == msgid && lr->lr_parent != NULL ) {
|
||||
/* don't let caller abandon child requests! */
|
||||
lderr = LDAP_PARAM_ERROR;
|
||||
goto set_errorcode_and_return;
|
||||
}
|
||||
if ( lr->lr_status == LDAP_REQST_INPROGRESS ) {
|
||||
/* We only need to send an abandon message if the request
|
||||
* is in progress.
|
||||
*/
|
||||
sendabandon = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ( lr->lr_origid == msgid ) { /* child: abandon it */
|
||||
(void)do_abandon( ld, msgid, lr->lr_msgid,
|
||||
serverctrls, clientctrls );
|
||||
/* we ignore errors from child abandons... */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sendabandon = 1;
|
||||
/* find the request that we are abandoning */
|
||||
for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
|
||||
if ( lr->lr_msgid == msgid ) { /* this message */
|
||||
break;
|
||||
}
|
||||
if ( lr->lr_origid == msgid ) { /* child: abandon it */
|
||||
(void)do_abandon( ld, msgid, lr->lr_msgid,
|
||||
serverctrls, clientctrls );
|
||||
/* we ignore errors from child abandons... */
|
||||
}
|
||||
}
|
||||
|
||||
if ( lr != NULL ) {
|
||||
if ( origid == msgid && lr->lr_parent != NULL ) {
|
||||
/* don't let caller abandon child requests! */
|
||||
lderr = LDAP_PARAM_ERROR;
|
||||
goto set_errorcode_and_return;
|
||||
}
|
||||
if ( lr->lr_status != LDAP_REQST_INPROGRESS ) {
|
||||
/* no need to send abandon message */
|
||||
sendabandon = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ldap_msgdelete( ld, msgid ) == 0 ) {
|
||||
/* we had all the results and deleted them */
|
||||
goto set_errorcode_and_return;
|
||||
}
|
||||
|
||||
if ( sendabandon ) {
|
||||
if ( lr != NULL && sendabandon ) {
|
||||
/* create a message to send */
|
||||
if (( lderr = nsldapi_alloc_ber_with_options( ld, &ber )) ==
|
||||
LDAP_SUCCESS ) {
|
||||
int abandon_msgid;
|
||||
|
||||
LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
|
||||
abandon_msgid = ++ld->ld_msgid;
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );
|
||||
#ifdef CLDAP
|
||||
if ( ld->ld_dbp->sb_naddr > 0 ) {
|
||||
bererr = ber_printf( ber, "{isti",
|
||||
++ld->ld_msgid, ld->ld_cldapdn,
|
||||
abandon_msgid, ld->ld_cldapdn,
|
||||
LDAP_REQ_ABANDON, msgid );
|
||||
} else {
|
||||
#endif /* CLDAP */
|
||||
bererr = ber_printf( ber, "{iti",
|
||||
++ld->ld_msgid, LDAP_REQ_ABANDON, msgid );
|
||||
abandon_msgid, LDAP_REQ_ABANDON, msgid );
|
||||
#ifdef CLDAP
|
||||
}
|
||||
#endif /* CLDAP */
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );
|
||||
|
||||
if ( bererr == -1 ||
|
||||
( lderr = nsldapi_put_controls( ld, serverctrls,
|
||||
@ -217,31 +186,36 @@ do_abandon( LDAP *ld, int origid, int msgid, LDAPControl **serverctrls,
|
||||
lderr = LDAP_ENCODING_ERROR;
|
||||
ber_free( ber, 1 );
|
||||
} else {
|
||||
/* send the message */
|
||||
if ( lr != NULL ) {
|
||||
sb = lr->lr_conn->lconn_sb;
|
||||
} else {
|
||||
sb = ld->ld_sbp;
|
||||
}
|
||||
if ( nsldapi_ber_flush( ld, sb, ber, 1, 0 )
|
||||
!= 0 ) {
|
||||
lderr = LDAP_SERVER_DOWN;
|
||||
}
|
||||
/* try to send the message */
|
||||
lderr = nsldapi_send_abandon_message( ld,
|
||||
lr->lr_conn, ber, abandon_msgid );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( lr != NULL ) {
|
||||
if ( sendabandon ) {
|
||||
nsldapi_free_connection( ld, lr->lr_conn, NULL, NULL,
|
||||
0, 1 );
|
||||
}
|
||||
/*
|
||||
* Always call nsldapi_free_connection() so that the connection's
|
||||
* ref count is correctly decremented. It is OK to always pass
|
||||
* 1 for the "unbind" parameter because doing so will only affect
|
||||
* connections that resulted from a child request (because the
|
||||
* default connection's ref count never goes to zero).
|
||||
*/
|
||||
nsldapi_free_connection( ld, lr->lr_conn, NULL, NULL,
|
||||
0 /* do not force */, 1 /* send unbind before closing */ );
|
||||
|
||||
/*
|
||||
* Free the entire request chain if we finished abandoning everything.
|
||||
*/
|
||||
if ( origid == msgid ) {
|
||||
nsldapi_free_request( ld, lr, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Record the abandoned message ID (used to discard any server responses
|
||||
* that arrive later).
|
||||
*/
|
||||
LDAP_MUTEX_LOCK( ld, LDAP_ABANDON_LOCK );
|
||||
if ( ld->ld_abandoned == NULL ) {
|
||||
if ( (ld->ld_abandoned = (int *)NSLDAPI_MALLOC( 2
|
||||
@ -269,3 +243,46 @@ set_errorcode_and_return:
|
||||
LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
|
||||
return( lderr );
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to send the abandon message that is encoded in ber. Returns an
|
||||
* LDAP result code.
|
||||
*/
|
||||
static int
|
||||
nsldapi_send_abandon_message( LDAP *ld, LDAPConn *lc, BerElement *ber,
|
||||
int abandon_msgid )
|
||||
{
|
||||
int lderr = LDAP_SUCCESS;
|
||||
int err = 0;
|
||||
|
||||
err = nsldapi_send_ber_message( ld, lc->lconn_sb,
|
||||
ber, 1 /* free ber */ );
|
||||
if ( err == -2 ) {
|
||||
/*
|
||||
* "Would block" error. Queue the abandon as
|
||||
* a pending request.
|
||||
*/
|
||||
LDAPRequest *lr;
|
||||
|
||||
lr = nsldapi_new_request( lc, ber, abandon_msgid,
|
||||
0 /* no response expected */ );
|
||||
if ( lr == NULL ) {
|
||||
lderr = LDAP_NO_MEMORY;
|
||||
ber_free( ber, 1 );
|
||||
} else {
|
||||
lr->lr_status = LDAP_REQST_WRITING;
|
||||
nsldapi_queue_request_nolock( ld, lr );
|
||||
++lc->lconn_pending_requests;
|
||||
nsldapi_iostatus_interest_write( ld,
|
||||
lc->lconn_sb );
|
||||
}
|
||||
} else if ( err != 0 ) {
|
||||
/*
|
||||
* Fatal error (not a "would block" error).
|
||||
*/
|
||||
lderr = LDAP_SERVER_DOWN;
|
||||
ber_free( ber, 1 );
|
||||
}
|
||||
|
||||
return( lderr );
|
||||
}
|
||||
|
@ -201,6 +201,12 @@ ldap_get_option( LDAP *ld, int option, void *optdata )
|
||||
*((struct ldap_thread_fns *) optdata) = ld->ld_thread;
|
||||
break;
|
||||
|
||||
/* extra thread function pointers */
|
||||
case LDAP_OPT_EXTRA_THREAD_FN_PTRS:
|
||||
/* struct copy */
|
||||
*((struct ldap_extra_thread_fns *) optdata) = ld->ld_thread2;
|
||||
break;
|
||||
|
||||
/* DNS function pointers */
|
||||
case LDAP_OPT_DNS_FN_PTRS:
|
||||
/* struct copy */
|
||||
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code, released
|
||||
* March 31, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1996 Regents of the University of Michigan.
|
||||
* All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* LIBLDAP globals.c -- LDAP library global variables
|
||||
*/
|
||||
|
||||
|
||||
#ifdef LDAP_DEBUG
|
||||
int ldap_debug;
|
||||
#endif
|
@ -170,13 +170,13 @@ typedef struct ldap_conn {
|
||||
int lconn_refcnt;
|
||||
unsigned long lconn_lastused; /* time */
|
||||
int lconn_status;
|
||||
#define LDAP_CONNST_NEEDSOCKET 1
|
||||
#define LDAP_CONNST_CONNECTING 2
|
||||
#define LDAP_CONNST_CONNECTED 3
|
||||
#define LDAP_CONNST_DEAD 4
|
||||
LDAPServer *lconn_server;
|
||||
char *lconn_binddn; /* DN of last successful bind */
|
||||
int lconn_bound; /* has a bind been done? */
|
||||
int lconn_pending_requests; /* count of unsent req*/
|
||||
char *lconn_krbinstance;
|
||||
struct ldap_conn *lconn_next;
|
||||
} LDAPConn;
|
||||
@ -190,13 +190,13 @@ typedef struct ldapreq {
|
||||
int lr_status; /* status of request */
|
||||
#define LDAP_REQST_INPROGRESS 1
|
||||
#define LDAP_REQST_CHASINGREFS 2
|
||||
#define LDAP_REQST_NOTCONNECTED 3
|
||||
#define LDAP_REQST_WRITING 4
|
||||
#define LDAP_REQST_CONNDEAD 5 /* associated conn. has failed */
|
||||
int lr_outrefcnt; /* count of outstanding referrals */
|
||||
int lr_origid; /* original request's message id */
|
||||
int lr_parentcnt; /* count of parent requests */
|
||||
int lr_res_msgtype; /* result message type */
|
||||
int lr_expect_resp; /* if non-zero, expect a response */
|
||||
int lr_res_errno; /* result LDAP errno */
|
||||
char *lr_res_error; /* result error string */
|
||||
char *lr_res_matched;/* result matched DN string */
|
||||
@ -241,7 +241,10 @@ struct ldap_x_ext_io_fns_rev0 {
|
||||
|
||||
|
||||
/*
|
||||
* structure representing an ldap connection
|
||||
* Structure representing an ldap connection.
|
||||
*
|
||||
* This is an opaque struct; the fields are not visible to
|
||||
* applications that use the LDAP API.
|
||||
*/
|
||||
struct ldap {
|
||||
struct sockbuf *ld_sbp; /* pointer to socket desc. & buffer */
|
||||
@ -261,13 +264,12 @@ struct ldap {
|
||||
char *ld_matched;
|
||||
int ld_msgid;
|
||||
|
||||
/* do not mess with these */
|
||||
/* Note: the ld_requests list is ordered old to new */
|
||||
LDAPRequest *ld_requests; /* list of outstanding requests */
|
||||
LDAPMessage *ld_responses; /* list of outstanding responses */
|
||||
int *ld_abandoned; /* array of abandoned requests */
|
||||
char *ld_cldapdn; /* DN used in connectionless search */
|
||||
|
||||
/* it is OK to change these next four values directly */
|
||||
int ld_cldaptries; /* connectionless search retry count */
|
||||
int ld_cldaptimeout;/* time between retries */
|
||||
int ld_refhoplimit; /* limit on referral nesting */
|
||||
@ -280,7 +282,6 @@ struct ldap {
|
||||
#define LDAP_BITOPT_RECONNECT 0x08000000
|
||||
#define LDAP_BITOPT_ASYNC 0x04000000
|
||||
|
||||
/* do not mess with the rest though */
|
||||
char *ld_defhost; /* full name of default server */
|
||||
int ld_defport; /* port of default server */
|
||||
BERTranslateProc ld_lber_encode_translate_proc;
|
||||
@ -365,11 +366,11 @@ struct ldap {
|
||||
/* extra thread function pointers */
|
||||
struct ldap_extra_thread_fns ld_thread2;
|
||||
|
||||
/* With the 4.0 version of the LDAP SDK */
|
||||
/* the extra thread functions except for */
|
||||
/* the ld_threadid_fn has been disabled */
|
||||
/* Look at the release notes for the full */
|
||||
/* explanation */
|
||||
/*
|
||||
* With the 4.0 and later versions of the LDAP SDK, the extra thread
|
||||
* functions except for the ld_threadid_fn have been disabled.
|
||||
* Look at the release notes for the full explanation.
|
||||
*/
|
||||
#define ld_mutex_trylock_fn ld_thread2.ltf_mutex_trylock
|
||||
#define ld_sema_alloc_fn ld_thread2.ltf_sema_alloc
|
||||
#define ld_sema_free_fn ld_thread2.ltf_sema_free
|
||||
@ -701,17 +702,21 @@ int nsldapi_post_result( LDAP *ld, int msgid, LDAPMessage *result );
|
||||
*/
|
||||
int nsldapi_send_initial_request( LDAP *ld, int msgid, unsigned long msgtype,
|
||||
char *dn, BerElement *ber );
|
||||
int nsldapi_send_pending_requests_nolock( LDAP *ld, LDAPConn *lc );
|
||||
int nsldapi_alloc_ber_with_options( LDAP *ld, BerElement **berp );
|
||||
void nsldapi_set_ber_options( LDAP *ld, BerElement *ber );
|
||||
int nsldapi_ber_flush( LDAP *ld, Sockbuf *sb, BerElement *ber, int freeit,
|
||||
int async );
|
||||
int nsldapi_send_ber_message( LDAP *ld, Sockbuf *sb, BerElement *ber,
|
||||
int freeit );
|
||||
int nsldapi_send_server_request( LDAP *ld, BerElement *ber, int msgid,
|
||||
LDAPRequest *parentreq, LDAPServer *srvlist, LDAPConn *lc,
|
||||
char *bindreqdn, int bind );
|
||||
LDAPConn *nsldapi_new_connection( LDAP *ld, LDAPServer **srvlistp, int use_ldsb,
|
||||
int connect, int bind );
|
||||
LDAPRequest *nsldapi_find_request_by_msgid( LDAP *ld, int msgid );
|
||||
LDAPRequest *nsldapi_new_request( LDAPConn *lc, BerElement *ber, int msgid,
|
||||
int expect_resp );
|
||||
void nsldapi_free_request( LDAP *ld, LDAPRequest *lr, int free_conn );
|
||||
void nsldapi_queue_request_nolock( LDAP *ld, LDAPRequest *lr );
|
||||
void nsldapi_free_connection( LDAP *ld, LDAPConn *lc,
|
||||
LDAPControl **serverctrls, LDAPControl **clientctrls,
|
||||
int force, int unbind );
|
||||
|
@ -795,21 +795,23 @@ nsldapi_host_connected_to( Sockbuf *sb )
|
||||
int
|
||||
nsldapi_iostatus_interest_write( LDAP *ld, Sockbuf *sb )
|
||||
{
|
||||
int rc = 0;
|
||||
NSLDAPIIOStatus *iosp;
|
||||
|
||||
LDAP_MUTEX_LOCK( ld, LDAP_IOSTATUS_LOCK );
|
||||
|
||||
if ( ld->ld_iostatus == NULL
|
||||
&& nsldapi_iostatus_init_nolock( ld ) < 0 ) {
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_IOSTATUS_LOCK );
|
||||
return( -1 );
|
||||
rc = -1;
|
||||
goto unlock_and_return;
|
||||
}
|
||||
|
||||
iosp = ld->ld_iostatus;
|
||||
|
||||
if ( iosp->ios_type == NSLDAPI_IOSTATUS_TYPE_OSNATIVE ) {
|
||||
#ifdef NSLDAPI_AVOID_OS_SOCKETS
|
||||
return( -1 );
|
||||
rc = -1;
|
||||
goto unlock_and_return;
|
||||
#else /* NSLDAPI_AVOID_OS_SOCKETS */
|
||||
#ifdef NSLDAPI_HAVE_POLL
|
||||
if ( nsldapi_add_to_os_pollfds( sb->sb_sd,
|
||||
@ -838,9 +840,9 @@ nsldapi_iostatus_interest_write( LDAP *ld, Sockbuf *sb )
|
||||
iosp->ios_type, 0, 0 );
|
||||
}
|
||||
|
||||
unlock_and_return:
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_IOSTATUS_LOCK );
|
||||
|
||||
return( 0 );
|
||||
return( rc );
|
||||
}
|
||||
|
||||
|
||||
@ -851,21 +853,23 @@ nsldapi_iostatus_interest_write( LDAP *ld, Sockbuf *sb )
|
||||
int
|
||||
nsldapi_iostatus_interest_read( LDAP *ld, Sockbuf *sb )
|
||||
{
|
||||
int rc = 0;
|
||||
NSLDAPIIOStatus *iosp;
|
||||
|
||||
LDAP_MUTEX_LOCK( ld, LDAP_IOSTATUS_LOCK );
|
||||
|
||||
if ( ld->ld_iostatus == NULL
|
||||
&& nsldapi_iostatus_init_nolock( ld ) < 0 ) {
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_IOSTATUS_LOCK );
|
||||
return( -1 );
|
||||
rc = -1;
|
||||
goto unlock_and_return;
|
||||
}
|
||||
|
||||
iosp = ld->ld_iostatus;
|
||||
|
||||
if ( iosp->ios_type == NSLDAPI_IOSTATUS_TYPE_OSNATIVE ) {
|
||||
#ifdef NSLDAPI_AVOID_OS_SOCKETS
|
||||
return( -1 );
|
||||
rc = -1;
|
||||
goto unlock_and_return;
|
||||
#else /* NSLDAPI_AVOID_OS_SOCKETS */
|
||||
#ifdef NSLDAPI_HAVE_POLL
|
||||
if ( nsldapi_add_to_os_pollfds( sb->sb_sd,
|
||||
@ -893,9 +897,9 @@ nsldapi_iostatus_interest_read( LDAP *ld, Sockbuf *sb )
|
||||
iosp->ios_type, 0, 0 );
|
||||
}
|
||||
|
||||
unlock_and_return:
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_IOSTATUS_LOCK );
|
||||
|
||||
return( 0 );
|
||||
return( rc );
|
||||
}
|
||||
|
||||
|
||||
@ -906,21 +910,23 @@ nsldapi_iostatus_interest_read( LDAP *ld, Sockbuf *sb )
|
||||
int
|
||||
nsldapi_iostatus_interest_clear( LDAP *ld, Sockbuf *sb )
|
||||
{
|
||||
int rc = 0;
|
||||
NSLDAPIIOStatus *iosp;
|
||||
|
||||
LDAP_MUTEX_LOCK( ld, LDAP_IOSTATUS_LOCK );
|
||||
|
||||
if ( ld->ld_iostatus == NULL
|
||||
&& nsldapi_iostatus_init_nolock( ld ) < 0 ) {
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_IOSTATUS_LOCK );
|
||||
return( -1 );
|
||||
rc = -1;
|
||||
goto unlock_and_return;
|
||||
}
|
||||
|
||||
iosp = ld->ld_iostatus;
|
||||
|
||||
if ( iosp->ios_type == NSLDAPI_IOSTATUS_TYPE_OSNATIVE ) {
|
||||
#ifdef NSLDAPI_AVOID_OS_SOCKETS
|
||||
return( -1 );
|
||||
rc = -1;
|
||||
goto unlock_and_return;
|
||||
#else /* NSLDAPI_AVOID_OS_SOCKETS */
|
||||
#ifdef NSLDAPI_HAVE_POLL
|
||||
if ( nsldapi_clear_from_os_pollfds( sb->sb_sd,
|
||||
@ -962,9 +968,9 @@ nsldapi_iostatus_interest_clear( LDAP *ld, Sockbuf *sb )
|
||||
iosp->ios_type, 0, 0 );
|
||||
}
|
||||
|
||||
unlock_and_return:
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_IOSTATUS_LOCK );
|
||||
|
||||
return( 0 );
|
||||
return( rc );
|
||||
}
|
||||
|
||||
|
||||
@ -974,15 +980,18 @@ nsldapi_iostatus_interest_clear( LDAP *ld, Sockbuf *sb )
|
||||
int
|
||||
nsldapi_iostatus_is_write_ready( LDAP *ld, Sockbuf *sb )
|
||||
{
|
||||
int rc;
|
||||
int rc = 0;
|
||||
NSLDAPIIOStatus *iosp;
|
||||
|
||||
LDAP_MUTEX_LOCK( ld, LDAP_IOSTATUS_LOCK );
|
||||
iosp = ld->ld_iostatus;
|
||||
if ( iosp == NULL ) {
|
||||
goto unlock_and_return;
|
||||
}
|
||||
|
||||
if ( iosp->ios_type == NSLDAPI_IOSTATUS_TYPE_OSNATIVE ) {
|
||||
#ifdef NSLDAPI_AVOID_OS_SOCKETS
|
||||
return 0;
|
||||
goto unlock_and_return;
|
||||
#else /* NSLDAPI_AVOID_OS_SOCKETS */
|
||||
#ifdef NSLDAPI_HAVE_POLL
|
||||
/*
|
||||
@ -1013,6 +1022,7 @@ nsldapi_iostatus_is_write_ready( LDAP *ld, Sockbuf *sb )
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
unlock_and_return:
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_IOSTATUS_LOCK );
|
||||
return( rc );
|
||||
}
|
||||
@ -1024,15 +1034,18 @@ nsldapi_iostatus_is_write_ready( LDAP *ld, Sockbuf *sb )
|
||||
int
|
||||
nsldapi_iostatus_is_read_ready( LDAP *ld, Sockbuf *sb )
|
||||
{
|
||||
int rc;
|
||||
int rc = 0;
|
||||
NSLDAPIIOStatus *iosp;
|
||||
|
||||
LDAP_MUTEX_LOCK( ld, LDAP_IOSTATUS_LOCK );
|
||||
iosp = ld->ld_iostatus;
|
||||
if ( iosp == NULL ) {
|
||||
goto unlock_and_return;
|
||||
}
|
||||
|
||||
if ( iosp->ios_type == NSLDAPI_IOSTATUS_TYPE_OSNATIVE ) {
|
||||
#ifdef NSLDAPI_AVOID_OS_SOCKETS
|
||||
return 0;
|
||||
goto unlock_and_return;
|
||||
#else /* NSLDAPI_AVOID_OS_SOCKETS */
|
||||
#ifdef NSLDAPI_HAVE_POLL
|
||||
/*
|
||||
@ -1063,6 +1076,7 @@ nsldapi_iostatus_is_read_ready( LDAP *ld, Sockbuf *sb )
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
unlock_and_return:
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_IOSTATUS_LOCK );
|
||||
return( rc );
|
||||
}
|
||||
@ -1208,7 +1222,7 @@ nsldapi_iostatus_poll( LDAP *ld, struct timeval *timeout )
|
||||
iosp = ld->ld_iostatus;
|
||||
|
||||
if ( iosp == NULL ||
|
||||
( iosp->ios_read_count <= 0 && iosp->ios_read_count <= 0 )) {
|
||||
( iosp->ios_read_count <= 0 && iosp->ios_write_count <= 0 )) {
|
||||
rc = 0; /* simulate a timeout */
|
||||
|
||||
} else if ( iosp->ios_type == NSLDAPI_IOSTATUS_TYPE_OSNATIVE ) {
|
||||
|
@ -36,7 +36,6 @@ static char copyright[] = "@(#) Copyright (c) 1995 Regents of the University of
|
||||
#include "ldap-int.h"
|
||||
|
||||
static LDAPConn *find_connection( LDAP *ld, LDAPServer *srv, int any );
|
||||
static void use_connection( LDAP *ld, LDAPConn *lc );
|
||||
static void free_servers( LDAPServer *srvlist );
|
||||
static int chase_one_referral( LDAP *ld, LDAPRequest *lr, LDAPRequest *origreq,
|
||||
char *refurl, char *desc, int *unknownp );
|
||||
@ -195,22 +194,18 @@ nsldapi_send_server_request(
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* the logic here is:
|
||||
* if
|
||||
* 1. no connections exists,
|
||||
* or
|
||||
* 2. if the connection is either not in the connected
|
||||
* or connecting state in an async io model
|
||||
* or
|
||||
* 3. the connection is notin a connected state with normal (non async io)
|
||||
*/
|
||||
/*
|
||||
* return a fatal error if:
|
||||
* 1. no connections exists
|
||||
* or
|
||||
* 2. the connection is dead
|
||||
* or
|
||||
* 3. it is not in the connected state with normal (non async) I/O
|
||||
*/
|
||||
if ( lc == NULL
|
||||
|| ( (ld->ld_options & LDAP_BITOPT_ASYNC
|
||||
&& lc->lconn_status != LDAP_CONNST_CONNECTING
|
||||
&& lc->lconn_status != LDAP_CONNST_CONNECTED)
|
||||
|| (!(ld->ld_options & LDAP_BITOPT_ASYNC )
|
||||
&& lc->lconn_status != LDAP_CONNST_CONNECTED) ) ) {
|
||||
|| ( lc->lconn_status == LDAP_CONNST_DEAD )
|
||||
|| ( 0 == (ld->ld_options & LDAP_BITOPT_ASYNC) &&
|
||||
lc->lconn_status != LDAP_CONNST_CONNECTED) ) {
|
||||
|
||||
ber_free( ber, 1 );
|
||||
if ( lc != NULL ) {
|
||||
@ -224,9 +219,9 @@ nsldapi_send_server_request(
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
use_connection( ld, lc );
|
||||
if (( lr = (LDAPRequest *)NSLDAPI_CALLOC( 1, sizeof( LDAPRequest ))) ==
|
||||
NULL || ( bindreqdn != NULL && ( bindreqdn =
|
||||
if (( lr = nsldapi_new_request( lc, ber, msgid,
|
||||
1 /* expect a response */)) == NULL
|
||||
|| ( bindreqdn != NULL && ( bindreqdn =
|
||||
nsldapi_strdup( bindreqdn )) == NULL )) {
|
||||
if ( lr != NULL ) {
|
||||
NSLDAPI_FREE( lr );
|
||||
@ -242,11 +237,6 @@ nsldapi_send_server_request(
|
||||
return( -1 );
|
||||
}
|
||||
lr->lr_binddn = bindreqdn;
|
||||
lr->lr_msgid = msgid;
|
||||
lr->lr_status = LDAP_REQST_INPROGRESS;
|
||||
lr->lr_res_errno = LDAP_SUCCESS; /* optimistic */
|
||||
lr->lr_ber = ber;
|
||||
lr->lr_conn = lc;
|
||||
|
||||
if ( parentreq != NULL ) { /* sub-request */
|
||||
if ( !incparent ) {
|
||||
@ -265,40 +255,100 @@ nsldapi_send_server_request(
|
||||
}
|
||||
|
||||
LDAP_MUTEX_LOCK( ld, LDAP_REQ_LOCK );
|
||||
if (( lr->lr_next = ld->ld_requests ) != NULL ) {
|
||||
lr->lr_next->lr_prev = lr;
|
||||
/* add new request to the end of the list of outstanding requests */
|
||||
nsldapi_queue_request_nolock( ld, lr );
|
||||
|
||||
/*
|
||||
* Issue a non-blocking poll() if we need to check this
|
||||
* connection's status.
|
||||
*/
|
||||
if ( lc->lconn_status == LDAP_CONNST_CONNECTING ||
|
||||
lc->lconn_pending_requests > 0 ) {
|
||||
struct timeval tv;
|
||||
|
||||
tv.tv_sec = tv.tv_usec = 0;
|
||||
(void)nsldapi_iostatus_poll( ld, &tv );
|
||||
}
|
||||
ld->ld_requests = lr;
|
||||
lr->lr_prev = NULL;
|
||||
|
||||
if (( err = nsldapi_ber_flush( ld, lc->lconn_sb, ber, 0, 1 )) != 0 ) {
|
||||
/*
|
||||
* If the connect is pending, check to see if it has now completed.
|
||||
*/
|
||||
if ( lc->lconn_status == LDAP_CONNST_CONNECTING &&
|
||||
nsldapi_iostatus_is_write_ready( ld, lc->lconn_sb )) {
|
||||
lc->lconn_status = LDAP_CONNST_CONNECTED;
|
||||
|
||||
LDAPDebug( LDAP_DEBUG_TRACE,
|
||||
"nsldapi_send_server_request: connection 0x%x -"
|
||||
" LDAP_CONNST_CONNECTING -> LDAP_CONNST_CONNECTED\n",
|
||||
lc, 0, 0 );
|
||||
}
|
||||
|
||||
if ( lc->lconn_status == LDAP_CONNST_CONNECTING ||
|
||||
lc->lconn_pending_requests > 0 ) {
|
||||
/*
|
||||
* The connect is not yet complete, or there are existing
|
||||
* requests that have not yet been sent to the server.
|
||||
* Delay sending this request.
|
||||
*/
|
||||
lr->lr_status = LDAP_REQST_WRITING;
|
||||
++lc->lconn_pending_requests;
|
||||
nsldapi_iostatus_interest_write( ld, lc->lconn_sb );
|
||||
|
||||
/*
|
||||
* If the connection is now connected, and it is ready
|
||||
* to accept some more outbound data, send as many
|
||||
* pending requests as possible.
|
||||
*/
|
||||
if ( lc->lconn_status != LDAP_CONNST_CONNECTING
|
||||
&& nsldapi_iostatus_is_write_ready( ld, lc->lconn_sb )) {
|
||||
if ( nsldapi_send_pending_requests_nolock( ld, lc )
|
||||
== -1 ) { /* error */
|
||||
/*
|
||||
* Since nsldapi_send_pending_requests_nolock()
|
||||
* sets LDAP errno, there is no need to do so
|
||||
* here.
|
||||
*/
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_REQ_LOCK );
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
|
||||
return( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (( err = nsldapi_send_ber_message( ld, lc->lconn_sb,
|
||||
ber, 0 /* do not free ber */ )) != 0 ) {
|
||||
|
||||
/* need to continue write later */
|
||||
if (err == -2 ) {
|
||||
lr->lr_status = LDAP_REQST_WRITING;
|
||||
++lc->lconn_pending_requests;
|
||||
nsldapi_iostatus_interest_write( ld,
|
||||
lc->lconn_sb );
|
||||
} else {
|
||||
|
||||
LDAP_SET_LDERRNO( ld, LDAP_SERVER_DOWN,
|
||||
NULL, NULL );
|
||||
nsldapi_free_request( ld, lr, 0 );
|
||||
nsldapi_free_connection( ld, lc, NULL, NULL,
|
||||
0, 0 );
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_REQ_LOCK );
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* need to continue write later */
|
||||
if (ld->ld_options & LDAP_BITOPT_ASYNC && err == -2 ) {
|
||||
lr->lr_status = LDAP_REQST_WRITING;
|
||||
nsldapi_iostatus_interest_write( ld, lc->lconn_sb );
|
||||
} else {
|
||||
if ( parentreq == NULL ) {
|
||||
ber->ber_end = ber->ber_ptr;
|
||||
ber->ber_ptr = ber->ber_buf;
|
||||
}
|
||||
|
||||
LDAP_SET_LDERRNO( ld, LDAP_SERVER_DOWN, NULL, NULL );
|
||||
nsldapi_free_request( ld, lr, 0 );
|
||||
nsldapi_free_connection( ld, lc, NULL, NULL, 0, 0 );
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_REQ_LOCK );
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
|
||||
return( -1 );
|
||||
/* sent -- waiting for a response */
|
||||
if (ld->ld_options & LDAP_BITOPT_ASYNC) {
|
||||
lc->lconn_status = LDAP_CONNST_CONNECTED;
|
||||
}
|
||||
|
||||
nsldapi_iostatus_interest_read( ld, lc->lconn_sb );
|
||||
}
|
||||
|
||||
} else {
|
||||
if ( parentreq == NULL ) {
|
||||
ber->ber_end = ber->ber_ptr;
|
||||
ber->ber_ptr = ber->ber_buf;
|
||||
}
|
||||
|
||||
/* sent -- waiting for a response */
|
||||
if (ld->ld_options & LDAP_BITOPT_ASYNC) {
|
||||
lc->lconn_status = LDAP_CONNST_CONNECTED;
|
||||
}
|
||||
|
||||
nsldapi_iostatus_interest_read( ld, lc->lconn_sb );
|
||||
}
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_REQ_LOCK );
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
|
||||
@ -309,16 +359,22 @@ nsldapi_send_server_request(
|
||||
|
||||
|
||||
/*
|
||||
* returns -1 if a fatal error occurs. If async is non-zero and the flush
|
||||
* would block, -2 is returned.
|
||||
* nsldapi_send_ber_message(): Attempt to send a BER-encoded message.
|
||||
* If freeit is non-zero, ber is freed when the send succeeds.
|
||||
*
|
||||
* Return values:
|
||||
* 0: message sent successfully.
|
||||
* -1: a fatal error occurred while trying to send.
|
||||
* -2: async. I/O is enabled and the send would block.
|
||||
*/
|
||||
int
|
||||
nsldapi_ber_flush( LDAP *ld, Sockbuf *sb, BerElement *ber, int freeit,
|
||||
int async )
|
||||
nsldapi_send_ber_message( LDAP *ld, Sockbuf *sb, BerElement *ber, int freeit )
|
||||
{
|
||||
int terrno;
|
||||
int rc = 0; /* optimistic */
|
||||
int async = ( 0 != (ld->ld_options & LDAP_BITOPT_ASYNC));
|
||||
int more_to_send = 1;
|
||||
|
||||
for ( ;; ) {
|
||||
while ( more_to_send) {
|
||||
/*
|
||||
* ber_flush() doesn't set errno on EOF, so we pre-set it to
|
||||
* zero to avoid getting tricked by leftover "EAGAIN" errors
|
||||
@ -326,29 +382,116 @@ nsldapi_ber_flush( LDAP *ld, Sockbuf *sb, BerElement *ber, int freeit,
|
||||
LDAP_SET_ERRNO( ld, 0 );
|
||||
|
||||
if ( ber_flush( sb, ber, freeit ) == 0 ) {
|
||||
return( 0 ); /* success */
|
||||
more_to_send = 0; /* success */
|
||||
} else {
|
||||
int terrno = LDAP_GET_ERRNO( ld );
|
||||
if ( NSLDAPI_ERRNO_IO_INPROGRESS( terrno )) {
|
||||
if ( async ) {
|
||||
rc = -2;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
nsldapi_connection_lost_nolock( ld, sb );
|
||||
rc = -1; /* fatal error */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
terrno = LDAP_GET_ERRNO( ld );
|
||||
|
||||
if (ld->ld_options & LDAP_BITOPT_ASYNC) {
|
||||
if ( terrno != 0 && !NSLDAPI_ERRNO_IO_INPROGRESS( terrno )) {
|
||||
nsldapi_connection_lost_nolock( ld, sb );
|
||||
return( -1 ); /* fatal error */
|
||||
}
|
||||
}
|
||||
else if ( !NSLDAPI_ERRNO_IO_INPROGRESS( terrno )) {
|
||||
|
||||
nsldapi_connection_lost_nolock( ld, sb );
|
||||
return( -1 ); /* fatal error */
|
||||
return( rc );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nsldapi_send_pending_requests_nolock(): Send one or more pending requests
|
||||
* that are associated with connection 'lc'.
|
||||
*
|
||||
* Return values: 0 -- success.
|
||||
* -1 -- fatal error; connection closed.
|
||||
*
|
||||
* Must be called with these two mutexes locked, in this order:
|
||||
* LDAP_CONN_LOCK
|
||||
* LDAP_REQ_LOCK
|
||||
*/
|
||||
int
|
||||
nsldapi_send_pending_requests_nolock( LDAP *ld, LDAPConn *lc )
|
||||
{
|
||||
int err;
|
||||
int waiting_for_a_response = 0;
|
||||
int rc = 0;
|
||||
LDAPRequest *lr;
|
||||
char *logname = "nsldapi_send_pending_requests_nolock";
|
||||
|
||||
LDAPDebug( LDAP_DEBUG_TRACE, "%s\n", logname, 0, 0 );
|
||||
|
||||
for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
|
||||
/*
|
||||
* This code relies on the fact that the ld_requests list
|
||||
* is in order from oldest to newest request (the oldest
|
||||
* requests that have not yet been sent to the server are
|
||||
* sent first).
|
||||
*/
|
||||
if ( lr->lr_status == LDAP_REQST_WRITING
|
||||
&& lr->lr_conn == lc ) {
|
||||
err = nsldapi_send_ber_message( ld, lc->lconn_sb,
|
||||
lr->lr_ber, 0 /* do not free ber */ );
|
||||
if ( err == 0 ) { /* send succeeded */
|
||||
LDAPDebug( LDAP_DEBUG_TRACE,
|
||||
"%s: 0x%x SENT\n", logname, lr, 0 );
|
||||
lr->lr_ber->ber_end = lr->lr_ber->ber_ptr;
|
||||
lr->lr_ber->ber_ptr = lr->lr_ber->ber_buf;
|
||||
lr->lr_status = LDAP_REQST_INPROGRESS;
|
||||
--lc->lconn_pending_requests;
|
||||
} else if ( err == -2 ) { /* would block */
|
||||
rc = 0; /* not an error */
|
||||
LDAPDebug( LDAP_DEBUG_TRACE,
|
||||
"%s: 0x%x WOULD BLOCK\n", logname, lr, 0 );
|
||||
break;
|
||||
} else { /* fatal error */
|
||||
LDAPDebug( LDAP_DEBUG_TRACE,
|
||||
"%s: 0x%x FATAL ERROR\n", logname, lr, 0 );
|
||||
LDAP_SET_LDERRNO( ld, LDAP_SERVER_DOWN,
|
||||
NULL, NULL );
|
||||
nsldapi_free_request( ld, lr, 0 );
|
||||
lr = NULL;
|
||||
nsldapi_free_connection( ld, lc, NULL, NULL,
|
||||
0, 0 );
|
||||
lc = NULL;
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( async ) {
|
||||
return( -2 ); /* would block */
|
||||
if (lr->lr_status == LDAP_REQST_INPROGRESS ) {
|
||||
if (lr->lr_expect_resp) {
|
||||
++waiting_for_a_response;
|
||||
} else {
|
||||
LDAPDebug( LDAP_DEBUG_TRACE,
|
||||
"%s: 0x%x NO RESPONSE EXPECTED;"
|
||||
" freeing request \n", logname, lr, 0 );
|
||||
nsldapi_free_request( ld, lr, 0 );
|
||||
lr = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( lc != NULL ) {
|
||||
if ( lc->lconn_pending_requests < 1 ) {
|
||||
/* no need to poll for "write ready" any longer */
|
||||
nsldapi_iostatus_interest_clear( ld, lc->lconn_sb );
|
||||
}
|
||||
|
||||
if ( waiting_for_a_response ) {
|
||||
/* need to poll for "read ready" */
|
||||
nsldapi_iostatus_interest_read( ld, lc->lconn_sb );
|
||||
}
|
||||
}
|
||||
|
||||
LDAPDebug( LDAP_DEBUG_TRACE, "%s <- %d\n", logname, rc, 0 );
|
||||
return( rc );
|
||||
}
|
||||
|
||||
|
||||
LDAPConn *
|
||||
nsldapi_new_connection( LDAP *ld, LDAPServer **srvlistp, int use_ldsb,
|
||||
int connect, int bind )
|
||||
@ -437,11 +580,15 @@ nsldapi_new_connection( LDAP *ld, LDAPServer **srvlistp, int use_ldsb,
|
||||
lc->lconn_server = srv;
|
||||
}
|
||||
|
||||
if (ld->ld_options & LDAP_BITOPT_ASYNC && rc == -2)
|
||||
{
|
||||
if ( 0 != (ld->ld_options & LDAP_BITOPT_ASYNC)) {
|
||||
/*
|
||||
* Technically, the socket may already be connected but we are
|
||||
* not sure. By setting the state to LDAP_CONNST_CONNECTING, we
|
||||
* ensure that we will check the socket status to make sure it
|
||||
* is connected before we try to send any LDAP messages.
|
||||
*/
|
||||
lc->lconn_status = LDAP_CONNST_CONNECTING;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
lc->lconn_status = LDAP_CONNST_CONNECTED;
|
||||
}
|
||||
|
||||
@ -550,15 +697,6 @@ find_connection( LDAP *ld, LDAPServer *srv, int any )
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
use_connection( LDAP *ld, LDAPConn *lc )
|
||||
{
|
||||
++lc->lconn_refcnt;
|
||||
lc->lconn_lastused = time( 0 );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsldapi_free_connection( LDAP *ld, LDAPConn *lc, LDAPControl **serverctrls,
|
||||
LDAPControl **clientctrls, int force, int unbind )
|
||||
@ -568,8 +706,8 @@ nsldapi_free_connection( LDAP *ld, LDAPConn *lc, LDAPControl **serverctrls,
|
||||
LDAPDebug( LDAP_DEBUG_TRACE, "nsldapi_free_connection\n", 0, 0, 0 );
|
||||
|
||||
if ( force || --lc->lconn_refcnt <= 0 ) {
|
||||
nsldapi_iostatus_interest_clear( ld, lc->lconn_sb );
|
||||
if ( lc->lconn_status == LDAP_CONNST_CONNECTED ) {
|
||||
nsldapi_iostatus_interest_clear( ld, lc->lconn_sb );
|
||||
if ( unbind ) {
|
||||
nsldapi_send_unbind( ld, lc->lconn_sb,
|
||||
serverctrls, clientctrls );
|
||||
@ -634,8 +772,8 @@ nsldapi_dump_connection( LDAP *ld, LDAPConn *lconns, int all )
|
||||
ber_err_print( msg );
|
||||
for ( lc = lconns; lc != NULL; lc = lc->lconn_next ) {
|
||||
if ( lc->lconn_server != NULL ) {
|
||||
sprintf( msg, "* host: %s port: %d secure: %s%s\n",
|
||||
( lc->lconn_server->lsrv_host == NULL ) ? "(null)"
|
||||
sprintf( msg, "* 0x%x - host: %s port: %d secure: %s%s\n",
|
||||
lc, ( lc->lconn_server->lsrv_host == NULL ) ? "(null)"
|
||||
: lc->lconn_server->lsrv_host,
|
||||
lc->lconn_server->lsrv_port,
|
||||
( lc->lconn_server->lsrv_options &
|
||||
@ -644,10 +782,10 @@ nsldapi_dump_connection( LDAP *ld, LDAPConn *lconns, int all )
|
||||
" (default)" : "" );
|
||||
ber_err_print( msg );
|
||||
}
|
||||
sprintf( msg, " refcnt: %d status: %s\n", lc->lconn_refcnt,
|
||||
( lc->lconn_status == LDAP_CONNST_NEEDSOCKET ) ?
|
||||
"NeedSocket" : ( lc->lconn_status ==
|
||||
LDAP_CONNST_CONNECTING ) ? "Connecting" :
|
||||
sprintf( msg, " refcnt: %d pending: %d status: %s\n",
|
||||
lc->lconn_refcnt, lc->lconn_pending_requests,
|
||||
( lc->lconn_status == LDAP_CONNST_CONNECTING )
|
||||
? "Connecting" :
|
||||
( lc->lconn_status == LDAP_CONNST_DEAD ) ? "Dead" :
|
||||
"Connected" );
|
||||
ber_err_print( msg );
|
||||
@ -681,11 +819,10 @@ nsldapi_dump_requests_and_responses( LDAP *ld )
|
||||
ber_err_print( " Empty\n" );
|
||||
}
|
||||
for ( ; lr != NULL; lr = lr->lr_next ) {
|
||||
sprintf( msg, " * msgid %d, origid %d, status %s\n",
|
||||
lr->lr_msgid, lr->lr_origid, ( lr->lr_status ==
|
||||
sprintf( msg, " * 0x%x - msgid %d, origid %d, status %s\n",
|
||||
lr, lr->lr_msgid, lr->lr_origid, ( lr->lr_status ==
|
||||
LDAP_REQST_INPROGRESS ) ? "InProgress" :
|
||||
( lr->lr_status == LDAP_REQST_CHASINGREFS ) ? "ChasingRefs" :
|
||||
( lr->lr_status == LDAP_REQST_NOTCONNECTED ) ? "NotConnected" :
|
||||
( lr->lr_status == LDAP_REQST_CONNDEAD ) ? "Dead" :
|
||||
"Writing" );
|
||||
ber_err_print( msg );
|
||||
@ -705,15 +842,15 @@ nsldapi_dump_requests_and_responses( LDAP *ld )
|
||||
ber_err_print( " Empty\n" );
|
||||
}
|
||||
for ( ; lm != NULLMSG; lm = lm->lm_next ) {
|
||||
sprintf( msg, " * msgid %d, type %d\n",
|
||||
lm->lm_msgid, lm->lm_msgtype );
|
||||
sprintf( msg, " * 0x%x - msgid %d, type %d\n",
|
||||
lm, lm->lm_msgid, lm->lm_msgtype );
|
||||
ber_err_print( msg );
|
||||
if (( l = lm->lm_chain ) != NULL ) {
|
||||
ber_err_print( " chained responses:\n" );
|
||||
for ( ; l != NULLMSG; l = l->lm_chain ) {
|
||||
sprintf( msg,
|
||||
" * msgid %d, type %d\n",
|
||||
l->lm_msgid, l->lm_msgtype );
|
||||
" * 0x%x - msgid %d, type %d\n",
|
||||
l, l->lm_msgid, l->lm_msgtype );
|
||||
ber_err_print( msg );
|
||||
}
|
||||
}
|
||||
@ -723,6 +860,31 @@ nsldapi_dump_requests_and_responses( LDAP *ld )
|
||||
#endif /* LDAP_DEBUG */
|
||||
|
||||
|
||||
LDAPRequest *
|
||||
nsldapi_new_request( LDAPConn *lc, BerElement *ber, int msgid, int expect_resp )
|
||||
{
|
||||
LDAPRequest *lr;
|
||||
|
||||
lr = (LDAPRequest *)NSLDAPI_CALLOC( 1, sizeof( LDAPRequest ));
|
||||
|
||||
if ( lr != NULL ) {
|
||||
lr->lr_conn = lc;
|
||||
lr->lr_ber = ber;
|
||||
lr->lr_msgid = lr->lr_origid = msgid;
|
||||
lr->lr_expect_resp = expect_resp;
|
||||
lr->lr_status = LDAP_REQST_INPROGRESS;
|
||||
lr->lr_res_errno = LDAP_SUCCESS; /* optimistic */
|
||||
|
||||
if ( lc != NULL ) { /* mark connection as in use */
|
||||
++lc->lconn_refcnt;
|
||||
lc->lconn_lastused = time( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
return( lr );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsldapi_free_request( LDAP *ld, LDAPRequest *lr, int free_conn )
|
||||
{
|
||||
@ -736,6 +898,10 @@ nsldapi_free_request( LDAP *ld, LDAPRequest *lr, int free_conn )
|
||||
--lr->lr_parent->lr_outrefcnt;
|
||||
}
|
||||
|
||||
if ( lr->lr_status == LDAP_REQST_WRITING ) {
|
||||
--lr->lr_conn->lconn_pending_requests;
|
||||
}
|
||||
|
||||
/* free all of our spawned referrals (child requests) */
|
||||
for ( tmplr = lr->lr_child; tmplr != NULL; tmplr = nextlr ) {
|
||||
nextlr = tmplr->lr_sibling;
|
||||
@ -775,6 +941,31 @@ nsldapi_free_request( LDAP *ld, LDAPRequest *lr, int free_conn )
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Add a request to the end of the list of outstanding requests.
|
||||
* This function must be called with these two locks in hand, acquired in
|
||||
* this order:
|
||||
* LDAP_CONN_LOCK
|
||||
* LDAP_REQ_LOCK
|
||||
*/
|
||||
void
|
||||
nsldapi_queue_request_nolock( LDAP *ld, LDAPRequest *lr )
|
||||
{
|
||||
if ( NULL == ld->ld_requests ) {
|
||||
ld->ld_requests = lr;
|
||||
} else {
|
||||
LDAPRequest *tmplr;
|
||||
|
||||
for ( tmplr = ld->ld_requests; tmplr->lr_next != NULL;
|
||||
tmplr = tmplr->lr_next ) {
|
||||
;
|
||||
}
|
||||
tmplr->lr_next = lr;
|
||||
lr->lr_prev = tmplr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
free_servers( LDAPServer *srvlist )
|
||||
{
|
||||
|
@ -35,6 +35,13 @@ static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of
|
||||
|
||||
#include "ldap-int.h"
|
||||
|
||||
/*
|
||||
* Special return values used by some functions (wait4msg() and read1msg()).
|
||||
*/
|
||||
#define NSLDAPI_RESULT_TIMEOUT 0
|
||||
#define NSLDAPI_RESULT_ERROR (-1)
|
||||
#define NSLDAPI_RESULT_NOT_FOUND (-2)
|
||||
|
||||
static int check_response_queue( LDAP *ld, int msgid, int all,
|
||||
int do_abandon_check, LDAPMessage **result );
|
||||
static int ldap_abandoned( LDAP *ld, int msgid );
|
||||
@ -51,10 +58,6 @@ static void merge_error_info( LDAP *ld, LDAPRequest *parentr, LDAPRequest *lr );
|
||||
static int cldap_select1( LDAP *ld, struct timeval *timeout );
|
||||
#endif
|
||||
static void link_pend( LDAP *ld, LDAPPend *lp );
|
||||
#if 0 /* these functions are no longer used */
|
||||
static void unlink_pend( LDAP *ld, LDAPPend *lp );
|
||||
static int unlink_msg( LDAP *ld, int msgid, int all );
|
||||
#endif /* 0 */
|
||||
|
||||
/*
|
||||
* ldap_result - wait for an ldap result response to a message from the
|
||||
@ -259,14 +262,23 @@ check_response_queue( LDAP *ld, int msgid, int all, int do_abandon_check,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* wait4msg(): Poll for incoming LDAP messages, respecting the timeout.
|
||||
*
|
||||
* Return values:
|
||||
* > 0: message received; value is the tag of the message.
|
||||
* NSLDAPI_RESULT_TIMEOUT timeout exceeded.
|
||||
* NSLDAPI_RESULT_ERROR fatal error occurred such as connection closed.
|
||||
*/
|
||||
static int
|
||||
wait4msg( LDAP *ld, int msgid, int all, int unlock_permitted,
|
||||
struct timeval *timeout, LDAPMessage **result )
|
||||
{
|
||||
int rc;
|
||||
int err, rc = NSLDAPI_RESULT_NOT_FOUND;
|
||||
struct timeval tv, *tvp;
|
||||
long start_time = 0, tmp_time;
|
||||
LDAPConn *lc, *nextlc;
|
||||
/* lr points to the specific request we are waiting for, if any */
|
||||
LDAPRequest *lr = NULL;
|
||||
|
||||
#ifdef LDAP_DEBUG
|
||||
@ -286,12 +298,12 @@ wait4msg( LDAP *ld, int msgid, int all, int unlock_permitted,
|
||||
rc = (ld->ld_cache_result)( ld, msgid, all, timeout, result );
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
|
||||
/* if ( unlock_permitted ) LDAP_MUTEX_LOCK( ld ); */
|
||||
if ( rc != 0 ) {
|
||||
if ( rc != NSLDAPI_RESULT_TIMEOUT ) {
|
||||
return( rc );
|
||||
}
|
||||
if ( ld->ld_cache_strategy == LDAP_CACHE_LOCALDB ) {
|
||||
LDAP_SET_LDERRNO( ld, LDAP_TIMEOUT, NULL, NULL );
|
||||
return( 0 ); /* timeout */
|
||||
return( NSLDAPI_RESULT_TIMEOUT );
|
||||
}
|
||||
}
|
||||
|
||||
@ -306,14 +318,14 @@ wait4msg( LDAP *ld, int msgid, int all, int unlock_permitted,
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_REQ_LOCK );
|
||||
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL,
|
||||
nsldapi_strdup( "unknown message id" ));
|
||||
return( -1 ); /* could not find request for msgid */
|
||||
return( NSLDAPI_RESULT_ERROR ); /* could not find request for msgid */
|
||||
}
|
||||
if ( lr->lr_conn != NULL &&
|
||||
lr->lr_conn->lconn_status == LDAP_CONNST_DEAD ) {
|
||||
nsldapi_free_request( ld, lr, 1 );
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_REQ_LOCK );
|
||||
LDAP_SET_LDERRNO( ld, LDAP_SERVER_DOWN, NULL, NULL );
|
||||
return( -1 ); /* connection dead */
|
||||
return( NSLDAPI_RESULT_ERROR ); /* connection dead */
|
||||
}
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_REQ_LOCK );
|
||||
}
|
||||
@ -326,14 +338,19 @@ wait4msg( LDAP *ld, int msgid, int all, int unlock_permitted,
|
||||
start_time = (long)time( NULL );
|
||||
}
|
||||
|
||||
rc = -2;
|
||||
while ( rc == -2 ) {
|
||||
rc = NSLDAPI_RESULT_NOT_FOUND;
|
||||
while ( rc == NSLDAPI_RESULT_NOT_FOUND ) {
|
||||
#ifdef LDAP_DEBUG
|
||||
if ( ldap_debug & LDAP_DEBUG_TRACE ) {
|
||||
nsldapi_dump_connection( ld, ld->ld_conns, 1 );
|
||||
nsldapi_dump_requests_and_responses( ld );
|
||||
}
|
||||
#endif /* LDAP_DEBUG */
|
||||
|
||||
/*
|
||||
* Check if we have some data in a connection's BER buffer.
|
||||
* If so, use it.
|
||||
*/
|
||||
LDAP_MUTEX_LOCK( ld, LDAP_CONN_LOCK );
|
||||
LDAP_MUTEX_LOCK( ld, LDAP_REQ_LOCK );
|
||||
for ( lc = ld->ld_conns; lc != NULL; lc = lc->lconn_next ) {
|
||||
@ -348,10 +365,14 @@ wait4msg( LDAP *ld, int msgid, int all, int unlock_permitted,
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
|
||||
|
||||
if ( lc == NULL ) {
|
||||
rc = nsldapi_iostatus_poll( ld, tvp );
|
||||
/*
|
||||
* There was no buffered data. Poll to check connection
|
||||
* status (read/write readiness).
|
||||
*/
|
||||
err = nsldapi_iostatus_poll( ld, tvp );
|
||||
|
||||
#if defined( LDAP_DEBUG ) && !defined( macintosh ) && !defined( DOS )
|
||||
if ( rc == -1 ) {
|
||||
if ( err == -1 ) {
|
||||
LDAPDebug( LDAP_DEBUG_TRACE,
|
||||
"nsldapi_iostatus_poll returned -1: errno %d\n",
|
||||
LDAP_GET_ERRNO( ld ), 0, 0 );
|
||||
@ -359,67 +380,100 @@ wait4msg( LDAP *ld, int msgid, int all, int unlock_permitted,
|
||||
#endif
|
||||
|
||||
#if !defined( macintosh ) && !defined( DOS )
|
||||
if ( rc == 0 || ( rc == -1 && (( ld->ld_options &
|
||||
LDAP_BITOPT_RESTART ) == 0 ||
|
||||
LDAP_GET_ERRNO( ld ) != EINTR ))) {
|
||||
#else
|
||||
if ( rc == -1 || rc == 0 ) {
|
||||
/*
|
||||
* If the restart option is enabled and the error
|
||||
* was EINTR, try again.
|
||||
*/
|
||||
if ( err == -1
|
||||
&& 0 != ( ld->ld_options & LDAP_BITOPT_RESTART )
|
||||
&& LDAP_GET_ERRNO( ld ) == EINTR ) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
LDAP_SET_LDERRNO( ld, (rc == -1 ?
|
||||
|
||||
/*
|
||||
* Handle timeouts (no activity) and fatal errors.
|
||||
*/
|
||||
if ( err == -1 || err == 0 ) {
|
||||
LDAP_SET_LDERRNO( ld, (err == -1 ?
|
||||
LDAP_SERVER_DOWN : LDAP_TIMEOUT), NULL,
|
||||
NULL );
|
||||
if ( rc == -1 ) {
|
||||
if ( err == -1 ) {
|
||||
LDAP_MUTEX_LOCK( ld, LDAP_REQ_LOCK );
|
||||
nsldapi_connection_lost_nolock( ld,
|
||||
NULL );
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_REQ_LOCK );
|
||||
rc = NSLDAPI_RESULT_ERROR;
|
||||
} else {
|
||||
rc = NSLDAPI_RESULT_TIMEOUT;
|
||||
}
|
||||
return( rc );
|
||||
}
|
||||
|
||||
if ( rc == -1 ) {
|
||||
rc = -2; /* select interrupted: loop */
|
||||
} else {
|
||||
rc = -2;
|
||||
LDAP_MUTEX_LOCK( ld, LDAP_CONN_LOCK );
|
||||
LDAP_MUTEX_LOCK( ld, LDAP_REQ_LOCK );
|
||||
for ( lc = ld->ld_conns; rc == -2 && lc != NULL;
|
||||
lc = nextlc ) {
|
||||
nextlc = lc->lconn_next;
|
||||
if ( lc->lconn_status ==
|
||||
LDAP_CONNST_CONNECTED &&
|
||||
nsldapi_iostatus_is_read_ready( ld,
|
||||
lc->lconn_sb )) {
|
||||
rc = read1msg( ld, msgid, all,
|
||||
lc->lconn_sb, lc, result );
|
||||
}
|
||||
else if (ld->ld_options & LDAP_BITOPT_ASYNC) {
|
||||
if ( lr
|
||||
&& lc->lconn_status == LDAP_CONNST_CONNECTING
|
||||
&& nsldapi_iostatus_is_write_ready( ld,
|
||||
lc->lconn_sb ) ) {
|
||||
rc = nsldapi_ber_flush( ld, lc->lconn_sb, lr->lr_ber, 0, 1 );
|
||||
if ( rc == 0 ) {
|
||||
rc = LDAP_RES_BIND;
|
||||
lc->lconn_status = LDAP_CONNST_CONNECTED;
|
||||
|
||||
lr->lr_ber->ber_end = lr->lr_ber->ber_ptr;
|
||||
lr->lr_ber->ber_ptr = lr->lr_ber->ber_buf;
|
||||
nsldapi_iostatus_interest_read( ld, lc->lconn_sb );
|
||||
}
|
||||
else if ( rc == -1 ) {
|
||||
LDAP_SET_LDERRNO( ld, LDAP_SERVER_DOWN, NULL, NULL );
|
||||
nsldapi_free_request( ld, lr, 0 );
|
||||
nsldapi_free_connection( ld, lc, NULL, NULL,
|
||||
0, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check each connection for interesting activity.
|
||||
*/
|
||||
LDAP_MUTEX_LOCK( ld, LDAP_CONN_LOCK );
|
||||
LDAP_MUTEX_LOCK( ld, LDAP_REQ_LOCK );
|
||||
for ( lc = ld->ld_conns;
|
||||
rc == NSLDAPI_RESULT_NOT_FOUND && lc != NULL;
|
||||
lc = nextlc ) {
|
||||
nextlc = lc->lconn_next;
|
||||
|
||||
/*
|
||||
* For connections that are in the CONNECTING
|
||||
* state, check for write ready (which
|
||||
* indicates that the connection completed) and
|
||||
* transition to the CONNECTED state.
|
||||
*/
|
||||
if ( lc->lconn_status == LDAP_CONNST_CONNECTING
|
||||
&& nsldapi_iostatus_is_write_ready( ld,
|
||||
lc->lconn_sb ) ) {
|
||||
lc->lconn_status = LDAP_CONNST_CONNECTED;
|
||||
LDAPDebug( LDAP_DEBUG_TRACE,
|
||||
"wait4msg: connection 0x%x -"
|
||||
" LDAP_CONNST_CONNECTING ->"
|
||||
" LDAP_CONNST_CONNECTED\n",
|
||||
lc, 0, 0 );
|
||||
}
|
||||
|
||||
if ( lc->lconn_status
|
||||
!= LDAP_CONNST_CONNECTED ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* For connections that are CONNECTED, check
|
||||
* for read ready (which indicates that data
|
||||
* from server is available), and, for
|
||||
* connections with associated requests that
|
||||
* have not yet been sent, write ready (okay
|
||||
* to send some data to the server).
|
||||
*/
|
||||
if ( nsldapi_iostatus_is_read_ready( ld,
|
||||
lc->lconn_sb )) {
|
||||
rc = read1msg( ld, msgid, all,
|
||||
lc->lconn_sb, lc, result );
|
||||
}
|
||||
|
||||
/*
|
||||
* Send pending requests if possible.
|
||||
*/
|
||||
if ( lc->lconn_pending_requests > 0
|
||||
&& nsldapi_iostatus_is_write_ready( ld,
|
||||
lc->lconn_sb )) {
|
||||
err = nsldapi_send_pending_requests_nolock(
|
||||
ld, lc );
|
||||
if ( err == -1 &&
|
||||
rc == NSLDAPI_RESULT_NOT_FOUND ) {
|
||||
rc = NSLDAPI_RESULT_ERROR;
|
||||
}
|
||||
}
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_REQ_LOCK );
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
|
||||
|
||||
}
|
||||
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_REQ_LOCK );
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -430,7 +484,7 @@ wait4msg( LDAP *ld, int msgid, int all, int unlock_permitted,
|
||||
* waiting on the network for a message that we already
|
||||
* received!
|
||||
*/
|
||||
if ( rc == -2 &&
|
||||
if ( rc == NSLDAPI_RESULT_NOT_FOUND &&
|
||||
check_response_queue( ld, msgid, all, 0, result ) != 0 ) {
|
||||
LDAP_SET_LDERRNO( ld, LDAP_SUCCESS, NULL, NULL );
|
||||
rc = (*result)->lm_msgtype;
|
||||
@ -439,10 +493,10 @@ wait4msg( LDAP *ld, int msgid, int all, int unlock_permitted,
|
||||
/*
|
||||
* honor the timeout if specified
|
||||
*/
|
||||
if ( rc == -2 && tvp != NULL ) {
|
||||
if ( rc == NSLDAPI_RESULT_NOT_FOUND && tvp != NULL ) {
|
||||
tmp_time = (long)time( NULL );
|
||||
if (( tv.tv_sec -= ( tmp_time - start_time )) <= 0 ) {
|
||||
rc = 0; /* timed out */
|
||||
rc = NSLDAPI_RESULT_TIMEOUT;
|
||||
LDAP_SET_LDERRNO( ld, LDAP_TIMEOUT, NULL,
|
||||
NULL );
|
||||
break;
|
||||
@ -458,7 +512,6 @@ wait4msg( LDAP *ld, int msgid, int all, int unlock_permitted,
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define NSLDAPI_REQUEST_COMPLETE( lr ) \
|
||||
( (lr)->lr_outrefcnt <= 0 && \
|
||||
(lr)->lr_res_msgtype != LDAP_RES_SEARCH_ENTRY && \
|
||||
@ -466,6 +519,12 @@ wait4msg( LDAP *ld, int msgid, int all, int unlock_permitted,
|
||||
|
||||
/*
|
||||
* read1msg() should be called with LDAP_CONN_LOCK and LDAP_REQ_LOCK locked.
|
||||
*
|
||||
* Return values:
|
||||
* > 0: message received; value is the tag of the message.
|
||||
* NSLDAPI_RESULT_TIMEOUT timeout exceeded.
|
||||
* NSLDAPI_RESULT_ERROR fatal error occurred such as connection closed.
|
||||
* NSLDAPI_RESULT_NOT_FOUND message not yet complete; keep waiting.
|
||||
*/
|
||||
static int
|
||||
read1msg( LDAP *ld, int msgid, int all, Sockbuf *sb, LDAPConn *lc,
|
||||
@ -490,7 +549,7 @@ read1msg( LDAP *ld, int msgid, int all, Sockbuf *sb, LDAPConn *lc,
|
||||
*/
|
||||
if ( lc->lconn_ber == NULLBER && nsldapi_alloc_ber_with_options( ld,
|
||||
&lc->lconn_ber ) != LDAP_SUCCESS ) {
|
||||
return( -1 );
|
||||
return( NSLDAPI_RESULT_ERROR );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -504,14 +563,14 @@ read1msg( LDAP *ld, int msgid, int all, Sockbuf *sb, LDAPConn *lc,
|
||||
!= LDAP_TAG_MESSAGE ) {
|
||||
terrno = LDAP_GET_ERRNO( ld );
|
||||
if ( terrno == EWOULDBLOCK || terrno == EAGAIN ) {
|
||||
return( -2 ); /* try again */
|
||||
return( NSLDAPI_RESULT_NOT_FOUND ); /* try again */
|
||||
}
|
||||
LDAP_SET_LDERRNO( ld, (tag == LBER_DEFAULT ? LDAP_SERVER_DOWN :
|
||||
LDAP_LOCAL_ERROR), NULL, NULL );
|
||||
if ( tag == LBER_DEFAULT ) {
|
||||
nsldapi_connection_lost_nolock( ld, sb );
|
||||
}
|
||||
return( -1 );
|
||||
return( NSLDAPI_RESULT_ERROR );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -525,13 +584,13 @@ read1msg( LDAP *ld, int msgid, int all, Sockbuf *sb, LDAPConn *lc,
|
||||
if ( ber_get_int( ber, &id ) == LBER_ERROR ) {
|
||||
ber_free( ber, 1 );
|
||||
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
|
||||
return( -1 );
|
||||
return( NSLDAPI_RESULT_ERROR );
|
||||
}
|
||||
|
||||
/* if it's been abandoned, toss it */
|
||||
if ( ldap_abandoned( ld, (int)id ) ) {
|
||||
ber_free( ber, 1 );
|
||||
return( -2 ); /* continue looking */
|
||||
return( NSLDAPI_RESULT_NOT_FOUND ); /* continue looking */
|
||||
}
|
||||
|
||||
if ( id == LDAP_RES_UNSOLICITED ) {
|
||||
@ -541,14 +600,14 @@ read1msg( LDAP *ld, int msgid, int all, Sockbuf *sb, LDAPConn *lc,
|
||||
"no request for response with msgid %ld (tossing)\n",
|
||||
id, 0, 0 );
|
||||
ber_free( ber, 1 );
|
||||
return( -2 ); /* continue looking */
|
||||
return( NSLDAPI_RESULT_NOT_FOUND ); /* continue looking */
|
||||
}
|
||||
|
||||
/* the message type */
|
||||
if ( (tag = ber_peek_tag( ber, &len )) == LBER_ERROR ) {
|
||||
ber_free( ber, 1 );
|
||||
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
|
||||
return( -1 );
|
||||
return( NSLDAPI_RESULT_ERROR );
|
||||
}
|
||||
LDAPDebug( LDAP_DEBUG_TRACE, "got %s msgid %ld, original id %d\n",
|
||||
( tag == LDAP_RES_SEARCH_ENTRY ) ? "ENTRY" :
|
||||
@ -559,7 +618,7 @@ read1msg( LDAP *ld, int msgid, int all, Sockbuf *sb, LDAPConn *lc,
|
||||
id = lr->lr_origid;
|
||||
lr->lr_res_msgtype = tag;
|
||||
}
|
||||
rc = -2; /* default is to keep looking (no response found) */
|
||||
rc = NSLDAPI_RESULT_NOT_FOUND; /* default is to keep looking (no response found) */
|
||||
|
||||
if ( id != LDAP_RES_UNSOLICITED && ( tag == LDAP_RES_SEARCH_REFERENCE ||
|
||||
tag != LDAP_RES_SEARCH_ENTRY )) {
|
||||
@ -657,7 +716,7 @@ lr->lr_res_matched ? lr->lr_res_matched : "" );
|
||||
}
|
||||
if ( build_result_ber( ld, &ber, lr )
|
||||
!= LDAP_SUCCESS ) {
|
||||
rc = -1; /* fatal error */
|
||||
rc = NSLDAPI_RESULT_ERROR;
|
||||
} else {
|
||||
manufactured_result = 1;
|
||||
}
|
||||
@ -678,7 +737,7 @@ lr->lr_res_matched ? lr->lr_res_matched : "" );
|
||||
if ( (new = (LDAPMessage*)NSLDAPI_CALLOC( 1, sizeof(struct ldapmsg) ))
|
||||
== NULL ) {
|
||||
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
|
||||
return( -1 );
|
||||
return( NSLDAPI_RESULT_ERROR );
|
||||
}
|
||||
new->lm_msgid = (int)id;
|
||||
new->lm_msgtype = tag;
|
||||
@ -744,12 +803,13 @@ lr->lr_res_matched ? lr->lr_res_matched : "" );
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_RESP_LOCK );
|
||||
if( message_can_be_returned )
|
||||
POST( ld, new->lm_msgid, new );
|
||||
return( -2 ); /* continue looking */
|
||||
return( NSLDAPI_RESULT_NOT_FOUND ); /* continue looking */
|
||||
}
|
||||
|
||||
LDAPDebug( LDAP_DEBUG_TRACE,
|
||||
"adding response id %d type %d (looking for id %d)\n",
|
||||
new->lm_msgid, new->lm_msgtype, msgid );
|
||||
"adding response 0x%x - id %d type %d",
|
||||
new, new->lm_msgid, new->lm_msgtype );
|
||||
LDAPDebug( LDAP_DEBUG_TRACE, " (looking for id %d)\n", msgid, 0, 0 );
|
||||
|
||||
/*
|
||||
* part of a search response - add to end of list of entries
|
||||
@ -864,7 +924,7 @@ lr->lr_res_matched ? lr->lr_res_matched : "" );
|
||||
return( tag );
|
||||
}
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_RESP_LOCK );
|
||||
return( -2 ); /* continue looking */
|
||||
return( NSLDAPI_RESULT_NOT_FOUND ); /* continue looking */
|
||||
}
|
||||
|
||||
|
||||
@ -1354,98 +1414,3 @@ link_pend( LDAP *ld, LDAPPend *lp )
|
||||
ld->ld_pend = lp;
|
||||
lp->lp_prev = NULL;
|
||||
}
|
||||
|
||||
#if 0 /* these functions are no longer used */
|
||||
static void
|
||||
unlink_pend( LDAP *ld, LDAPPend *lp )
|
||||
{
|
||||
if ( lp->lp_prev == NULL ) {
|
||||
ld->ld_pend = lp->lp_next;
|
||||
} else {
|
||||
lp->lp_prev->lp_next = lp->lp_next;
|
||||
}
|
||||
|
||||
if ( lp->lp_next != NULL ) {
|
||||
lp->lp_next->lp_prev = lp->lp_prev;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
unlink_msg( LDAP *ld, int msgid, int all )
|
||||
{
|
||||
int rc;
|
||||
LDAPMessage *lm, *lastlm, *nextlm;
|
||||
|
||||
lastlm = NULL;
|
||||
LDAP_MUTEX_LOCK( ld, LDAP_RESP_LOCK );
|
||||
for ( lm = ld->ld_responses; lm != NULL; lm = nextlm )
|
||||
{
|
||||
nextlm = lm->lm_next;
|
||||
|
||||
if ( lm->lm_msgid == msgid )
|
||||
{
|
||||
LDAPMessage *tmp;
|
||||
|
||||
if ( all == 0
|
||||
|| (lm->lm_msgtype != LDAP_RES_SEARCH_RESULT
|
||||
&& lm->lm_msgtype != LDAP_RES_SEARCH_REFERENCE
|
||||
&& lm->lm_msgtype != LDAP_RES_SEARCH_ENTRY) )
|
||||
break;
|
||||
|
||||
for ( tmp = lm; tmp != NULL; tmp = tmp->lm_chain ) {
|
||||
if ( tmp->lm_msgtype == LDAP_RES_SEARCH_RESULT )
|
||||
break;
|
||||
}
|
||||
if( tmp != NULL )
|
||||
break;
|
||||
}
|
||||
lastlm = lm;
|
||||
}
|
||||
|
||||
if( lm != NULL )
|
||||
{
|
||||
|
||||
if ( all == 0 )
|
||||
{
|
||||
if ( lm->lm_chain == NULL )
|
||||
{
|
||||
if ( lastlm == NULL )
|
||||
ld->ld_responses = lm->lm_next;
|
||||
else
|
||||
lastlm->lm_next = lm->lm_next;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( lastlm == NULL )
|
||||
{
|
||||
ld->ld_responses = lm->lm_chain;
|
||||
ld->ld_responses->lm_next = lm->lm_next;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastlm->lm_next = lm->lm_chain;
|
||||
lastlm->lm_next->lm_next = lm->lm_next;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( lastlm == NULL )
|
||||
ld->ld_responses = lm->lm_next;
|
||||
else
|
||||
lastlm->lm_next = lm->lm_next;
|
||||
}
|
||||
|
||||
if ( all == 0 )
|
||||
lm->lm_chain = NULL;
|
||||
lm->lm_next = NULL;
|
||||
rc = lm->lm_msgtype;
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = -2;
|
||||
}
|
||||
LDAP_MUTEX_UNLOCK( ld, LDAP_RESP_LOCK );
|
||||
return ( rc );
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
@ -1,35 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code, released
|
||||
* March 31, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
/* This stub function allows us to get around
|
||||
the linking error we were seeing on OSF
|
||||
because of the svrcore component. This
|
||||
module should be deleted as soon as the
|
||||
svrcore mess is cleaned up */
|
||||
|
||||
#ifdef OSF1
|
||||
void SVRPLCY_InstallSSLPolicy()
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
@ -59,13 +59,6 @@
|
||||
#endif /* DOS */
|
||||
#endif /* MACOS */
|
||||
|
||||
#undef NET_SSL
|
||||
|
||||
#if defined(NET_SSL)
|
||||
#include <sec.h>
|
||||
static SECCertDBHandle certdbhandle;
|
||||
#endif
|
||||
|
||||
#include "ldap.h"
|
||||
#include "disptmpl.h"
|
||||
#include "ldaplog.h"
|
||||
@ -74,6 +67,13 @@ static SECCertDBHandle certdbhandle;
|
||||
#include "lcache.h"
|
||||
#endif /* !NO_LIBLCACHE */
|
||||
|
||||
#undef NET_SSL
|
||||
#if defined(NET_SSL)
|
||||
#include <nss.h>
|
||||
#include <ldap_ssl.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined( PCNFS ) && !defined( WINSOCK ) && !defined( MACOS )
|
||||
#define MOD_USE_BVALS
|
||||
#endif /* !PCNFS && !WINSOCK && !MACOS */
|
||||
@ -315,12 +315,13 @@ bind_prompt( LDAP *ld, char **dnp, char **passwdp, int *authmethodp,
|
||||
}
|
||||
|
||||
|
||||
#define HEX2BIN( h ) ( (h) >= '0' && (h) <='0' ? (h) - '0' : (h) - 'A' + 10 )
|
||||
#define HEX2BIN( h ) ( (h) >= '0' && (h) <='9' ? (h) - '0' : (h) - 'A' + 10 )
|
||||
|
||||
void
|
||||
berval_from_hex( struct berval *bvp, char *hexstr )
|
||||
{
|
||||
char *src, *dst, c, abyte;
|
||||
char *src, *dst, c;
|
||||
unsigned char abyte;
|
||||
|
||||
dst = bvp->bv_val;
|
||||
bvp->bv_len = 0;
|
||||
@ -803,9 +804,13 @@ main(
|
||||
|
||||
getline( oid, sizeof(oid), stdin, "oid? " );
|
||||
getline( value, sizeof(value), stdin, "value? " );
|
||||
|
||||
val.bv_val = value;
|
||||
val.bv_len = strlen( value );
|
||||
if ( strncmp( value, "0x", 2 ) == 0 ) {
|
||||
val.bv_val = (char *)malloc( strlen( value ) / 2 );
|
||||
berval_from_hex( &val, value + 2 );
|
||||
} else {
|
||||
val.bv_val = strdup( value );
|
||||
val.bv_len = strlen( value );
|
||||
}
|
||||
if ( ldap_extended_operation( ld, oid, &val, NULL,
|
||||
NULL, &id ) != LDAP_SUCCESS ) {
|
||||
ldap_perror( ld, "ldap_extended_operation" );
|
||||
@ -813,6 +818,7 @@ main(
|
||||
printf( "Extended op initiated with id %d\n",
|
||||
id );
|
||||
}
|
||||
free( val.bv_val );
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1267,7 +1273,7 @@ main(
|
||||
getline( line, sizeof(line), stdin,
|
||||
"security DB path?" );
|
||||
if ( ldapssl_client_init( (*line == '\0') ?
|
||||
NULL : line, &certdbhandle ) < 0 ) {
|
||||
NULL : line, NULL ) < 0 ) {
|
||||
perror( "ldapssl_client_init" );
|
||||
optval = 0; /* SSL not avail. */
|
||||
} else if ( ldapssl_install_routines( ld )
|
||||
@ -1280,12 +1286,38 @@ main(
|
||||
|
||||
ldap_set_option( ld, LDAP_OPT_SSL,
|
||||
optval ? LDAP_OPT_ON : LDAP_OPT_OFF );
|
||||
|
||||
getline( line, sizeof(line), stdin,
|
||||
"Set SSL options (0=no, 1=yes)?" );
|
||||
optval = ( atoi( line ) != 0 );
|
||||
while ( 1 ) {
|
||||
PRInt32 sslopt;
|
||||
PRBool on;
|
||||
|
||||
getline( line, sizeof(line), stdin,
|
||||
"Option to set (0 if done)?" );
|
||||
sslopt = atoi(line);
|
||||
if ( sslopt == 0 ) {
|
||||
break;
|
||||
}
|
||||
getline( line, sizeof(line), stdin,
|
||||
"On=1, Off=0?" );
|
||||
on = ( atoi( line ) != 0 );
|
||||
if ( ldapssl_set_option( ld, sslopt, on ) != 0 ) {
|
||||
ldap_perror( ld, "ldapssl_set_option" );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
getline( line, sizeof(line), stdin, "Reconnect?" );
|
||||
ldap_set_option( ld, LDAP_OPT_RECONNECT,
|
||||
( atoi( line ) == 0 ) ? LDAP_OPT_OFF :
|
||||
LDAP_OPT_ON );
|
||||
|
||||
getline( line, sizeof(line), stdin, "Async I/O?" );
|
||||
ldap_set_option( ld, LDAP_OPT_ASYNC_CONNECT,
|
||||
( atoi( line ) == 0 ) ? LDAP_OPT_OFF :
|
||||
LDAP_OPT_ON );
|
||||
break;
|
||||
|
||||
case 'I': /* initialize display templates */
|
||||
|
@ -205,11 +205,21 @@ nsldapi_send_unbind( LDAP *ld, Sockbuf *sb, LDAPControl **serverctrls,
|
||||
}
|
||||
|
||||
/* send the message */
|
||||
if ( nsldapi_ber_flush( ld, sb, ber, 1, 0 ) != 0 ) {
|
||||
err = nsldapi_send_ber_message( ld, sb, ber, 1 /* free ber */ );
|
||||
if ( err != 0 ) {
|
||||
ber_free( ber, 1 );
|
||||
err = LDAP_SERVER_DOWN;
|
||||
LDAP_SET_LDERRNO( ld, err, NULL, NULL );
|
||||
return( err );
|
||||
if (err != -2 ) {
|
||||
/*
|
||||
* Message could not be sent, and the reason is
|
||||
* something other than a "would block" error.
|
||||
* Note that we ignore "would block" errors because
|
||||
* it is not critical that an UnBind request
|
||||
* actually reach the LDAP server.
|
||||
*/
|
||||
err = LDAP_SERVER_DOWN;
|
||||
LDAP_SET_LDERRNO( ld, err, NULL, NULL );
|
||||
return( err );
|
||||
}
|
||||
}
|
||||
|
||||
return( LDAP_SUCCESS );
|
||||
|
@ -340,7 +340,8 @@ prldap_try_one_address( struct lextiof_socket_private *prsockp,
|
||||
* Try to open the TCP connection itself:
|
||||
*/
|
||||
if ( PR_SUCCESS != PR_Connect( prsockp->prsock_prfd, addrp,
|
||||
prldap_timeout2it( timeout, prsockp->prsock_io_max_timeout ))) {
|
||||
prldap_timeout2it( timeout, prsockp->prsock_io_max_timeout ))
|
||||
&& PR_IN_PROGRESS_ERROR != PR_GetError() ) {
|
||||
PR_Close( prsockp->prsock_prfd );
|
||||
prsockp->prsock_prfd = NULL;
|
||||
return( -1 );
|
||||
|
Loading…
x
Reference in New Issue
Block a user