mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-03-07 14:18:15 +08:00
Fix ITS#1983, handle writing of large requests. Only one pending request is
allowed per LDAP* handle. It works, but needs review.
This commit is contained in:
parent
20f6bae612
commit
456e6c73ab
@ -224,7 +224,7 @@ do_abandon(
|
||||
}
|
||||
|
||||
if ( lr != NULL ) {
|
||||
if ( sendabandon ) {
|
||||
if ( sendabandon || lr->lr_status == LDAP_REQST_WRITING ) {
|
||||
ldap_free_connection( ld, lr->lr_conn, 0, 1 );
|
||||
}
|
||||
if ( origid == msgid ) {
|
||||
|
@ -467,6 +467,7 @@ LDAP_F (int) ldap_chase_referrals( LDAP *ld, LDAPRequest *lr,
|
||||
LDAP_F (int) ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr,
|
||||
char **refs, int sref, char **referralsp, int *hadrefp );
|
||||
LDAP_F (int) ldap_append_referral( LDAP *ld, char **referralsp, char *s );
|
||||
LDAP_F (int) ldap_int_flush_request( LDAP *ld, LDAPRequest *lr );
|
||||
|
||||
/*
|
||||
* in result.c:
|
||||
|
@ -137,6 +137,39 @@ ldap_send_initial_request(
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ldap_int_flush_request(
|
||||
LDAP *ld,
|
||||
LDAPRequest *lr
|
||||
)
|
||||
{
|
||||
LDAPConn *lc = lr->lr_conn;
|
||||
|
||||
if ( ber_flush( lc->lconn_sb, lr->lr_ber, 0 ) != 0 ) {
|
||||
if ( errno == EWOULDBLOCK || errno == EAGAIN ) {
|
||||
/* need to continue write later */
|
||||
lr->lr_status = LDAP_REQST_WRITING;
|
||||
ldap_mark_select_write( ld, lc->lconn_sb );
|
||||
ld->ld_errno = LDAP_BUSY;
|
||||
return -2;
|
||||
} else {
|
||||
ld->ld_errno = LDAP_SERVER_DOWN;
|
||||
ldap_free_request( ld, lr );
|
||||
ldap_free_connection( ld, lc, 0, 0 );
|
||||
return( -1 );
|
||||
}
|
||||
} else {
|
||||
if ( lr->lr_parent == NULL ) {
|
||||
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;
|
||||
|
||||
/* sent -- waiting for a response */
|
||||
ldap_mark_select_read( ld, lc->lconn_sb );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ldap_send_server_request(
|
||||
@ -189,6 +222,18 @@ ldap_send_server_request(
|
||||
}
|
||||
|
||||
use_connection( ld, lc );
|
||||
|
||||
/* If we still have an incomplete write, try to finish it before
|
||||
* dealing with the new request. If we don't finish here, return
|
||||
* LDAP_BUSY and let the caller retry later. We only allow a single
|
||||
* request to be in WRITING state.
|
||||
*/
|
||||
if ( ld->ld_requests &&
|
||||
ld->ld_requests->lr_status == LDAP_REQST_WRITING &&
|
||||
ldap_int_flush_request( ld, ld->ld_requests ) < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (( lr = (LDAPRequest *)LDAP_CALLOC( 1, sizeof( LDAPRequest ))) ==
|
||||
NULL ) {
|
||||
ld->ld_errno = LDAP_NO_MEMORY;
|
||||
@ -225,30 +270,8 @@ ldap_send_server_request(
|
||||
ld->ld_requests = lr;
|
||||
lr->lr_prev = NULL;
|
||||
|
||||
if ( ber_flush( lc->lconn_sb, ber, 0 ) != 0 ) {
|
||||
#ifdef notyet
|
||||
if ( errno == EWOULDBLOCK ) {
|
||||
/* need to continue write later */
|
||||
lr->lr_status = LDAP_REQST_WRITING;
|
||||
ldap_mark_select_write( ld, lc->lconn_sb );
|
||||
} else {
|
||||
#else /* notyet */
|
||||
ld->ld_errno = LDAP_SERVER_DOWN;
|
||||
ldap_free_request( ld, lr );
|
||||
ldap_free_connection( ld, lc, 0, 0 );
|
||||
return( -1 );
|
||||
#endif /* notyet */
|
||||
#ifdef notyet
|
||||
}
|
||||
#endif /* notyet */
|
||||
} else {
|
||||
if ( parentreq == NULL ) {
|
||||
ber->ber_end = ber->ber_ptr;
|
||||
ber->ber_ptr = ber->ber_buf;
|
||||
}
|
||||
|
||||
/* sent -- waiting for a response */
|
||||
ldap_mark_select_read( ld, lc->lconn_sb );
|
||||
if ( ldap_int_flush_request( ld, lr ) == -1 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ld->ld_errno = LDAP_SUCCESS;
|
||||
|
@ -334,6 +334,12 @@ wait4msg(
|
||||
rc = -2; /* select interrupted: loop */
|
||||
} else {
|
||||
rc = -2;
|
||||
if ( ld->ld_requests &&
|
||||
ld->ld_requests->lr_status == LDAP_REQST_WRITING &&
|
||||
ldap_is_write_ready( ld,
|
||||
ld->ld_requests->lr_conn->lconn_sb ) ) {
|
||||
ldap_int_flush_request( ld, ld->ld_requests );
|
||||
}
|
||||
for ( lc = ld->ld_conns; rc == -2 && lc != NULL;
|
||||
lc = nextlc ) {
|
||||
nextlc = lc->lconn_next;
|
||||
|
Loading…
Reference in New Issue
Block a user