mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-02-23 14:09:39 +08:00
Connect callbacks need error recovery checks
This commit is contained in:
parent
80d1dba901
commit
baad2b249d
@ -531,6 +531,9 @@ LDAP_F (void) ldap_mark_select_clear( LDAP *ld, Sockbuf *sb );
|
||||
LDAP_F (int) ldap_is_read_ready( LDAP *ld, Sockbuf *sb );
|
||||
LDAP_F (int) ldap_is_write_ready( LDAP *ld, Sockbuf *sb );
|
||||
|
||||
LDAP_F (int) ldap_int_connect_cbs( LDAP *ld, Sockbuf *sb,
|
||||
ber_socket_t *s, const char *name, struct sockaddr *addr );
|
||||
|
||||
/*
|
||||
* in os-local.c
|
||||
*/
|
||||
|
@ -424,6 +424,56 @@ ldap_pvt_inet_aton( const char *host, struct in_addr *in)
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
ldap_int_connect_cbs(LDAP *ld, Sockbuf *sb, ber_socket_t *s, const char *host, struct sockaddr *addr)
|
||||
{
|
||||
struct ldapoptions *lo;
|
||||
ldaplist *ll;
|
||||
ldap_conncb *cb;
|
||||
int rc;
|
||||
|
||||
ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_FD, s );
|
||||
|
||||
/* Invoke all handle-specific callbacks first */
|
||||
lo = &ld->ld_options;
|
||||
for (ll = lo->ldo_conn_cbs; ll; ll = ll->ll_next) {
|
||||
cb = ll->ll_data;
|
||||
rc = cb->lc_add( ld, sb, host, addr, cb );
|
||||
/* on any failure, call the teardown functions for anything
|
||||
* that previously succeeded
|
||||
*/
|
||||
if ( rc ) {
|
||||
ldaplist *l2;
|
||||
for (l2 = lo->ldo_conn_cbs; l2 != ll; l2 = l2->ll_next) {
|
||||
cb = l2->ll_data;
|
||||
cb->lc_del( ld, sb, cb );
|
||||
}
|
||||
/* a failure might have implicitly closed the fd */
|
||||
ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, s );
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
lo = LDAP_INT_GLOBAL_OPT();
|
||||
for (ll = lo->ldo_conn_cbs; ll; ll = ll->ll_next) {
|
||||
cb = ll->ll_data;
|
||||
rc = cb->lc_add( ld, sb, host, addr, cb );
|
||||
if ( rc ) {
|
||||
ldaplist *l2;
|
||||
for (l2 = lo->ldo_conn_cbs; l2 != ll; l2 = l2->ll_next) {
|
||||
cb = l2->ll_data;
|
||||
cb->lc_del( ld, sb, cb );
|
||||
}
|
||||
lo = &ld->ld_options;
|
||||
for (l2 = lo->ldo_conn_cbs; l2; l2 = l2->ll_next) {
|
||||
cb = l2->ll_data;
|
||||
cb->lc_del( ld, sb, cb );
|
||||
}
|
||||
ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, s );
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ldap_connect_to_host(LDAP *ld, Sockbuf *sb,
|
||||
@ -537,20 +587,11 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb,
|
||||
rc = ldap_pvt_connect( ld, s,
|
||||
sai->ai_addr, sai->ai_addrlen, async );
|
||||
if ( rc == 0 || rc == -2 ) {
|
||||
ldaplist *ll;
|
||||
struct ldapoptions *lo;
|
||||
ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_FD, &s );
|
||||
lo = &ld->ld_options;
|
||||
for (ll = lo->ldo_conn_cbs; ll; ll = ll->ll_next) {
|
||||
ldap_conncb *cb = ll->ll_data;
|
||||
cb->lc_add( ld, sb, host, sai->ai_addr, cb );
|
||||
}
|
||||
lo = LDAP_INT_GLOBAL_OPT();
|
||||
for (ll = lo->ldo_conn_cbs; ll; ll = ll->ll_next) {
|
||||
ldap_conncb *cb = ll->ll_data;
|
||||
cb->lc_add( ld, sb, host, sai->ai_addr, cb );
|
||||
}
|
||||
break;
|
||||
err = ldap_int_connect_cbs( ld, sb, &s, host, sai->ai_addr );
|
||||
if ( err )
|
||||
rc = err;
|
||||
else
|
||||
break;
|
||||
}
|
||||
ldap_pvt_close_socket(ld, s);
|
||||
}
|
||||
@ -621,20 +662,11 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb,
|
||||
async);
|
||||
|
||||
if ( (rc == 0) || (rc == -2) ) {
|
||||
ldaplist *ll;
|
||||
struct ldapoptions *lo;
|
||||
ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_FD, &s );
|
||||
lo = &ld->ld_options;
|
||||
for (ll = lo->ldo_conn_cbs; ll; ll = ll->ll_next) {
|
||||
ldap_conncb *cb = ll->ll_data;
|
||||
cb->lc_add( ld, sb, host, (struct sockaddr *)&sin, cb );
|
||||
}
|
||||
lo = LDAP_INT_GLOBAL_OPT();
|
||||
for (ll = lo->ldo_conn_cbs; ll; ll = ll->ll_next) {
|
||||
ldap_conncb *cb = ll->ll_data;
|
||||
cb->lc_add( ld, sb, host, (struct sockaddr *)&sin, cb );
|
||||
}
|
||||
break;
|
||||
i = ldap_int_connect_cbs( ld, sb, &s, host, (struct sockaddr *)&sin );
|
||||
if ( i )
|
||||
rc = i;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
ldap_pvt_close_socket(ld, s);
|
||||
|
@ -350,20 +350,12 @@ ldap_connect_to_path(LDAP *ld, Sockbuf *sb, const char *path, int async)
|
||||
rc = ldap_pvt_connect(ld, s, &server, async);
|
||||
|
||||
if (rc == 0) {
|
||||
ldaplist *ll;
|
||||
struct ldapoptions *lo;
|
||||
ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_FD, (void *)&s );
|
||||
lo = &ld->ld_options;
|
||||
for (ll = lo->ldo_conn_cbs; ll; ll = ll->ll_next) {
|
||||
ldap_conncb *cb = ll->ll_data;
|
||||
cb->lc_add( ld, sb, path, (struct sockaddr *)&server, cb );
|
||||
}
|
||||
lo = LDAP_INT_GLOBAL_OPT();
|
||||
for (ll = lo->ldo_conn_cbs; ll; ll = ll->ll_next) {
|
||||
ldap_conncb *cb = ll->ll_data;
|
||||
cb->lc_add( ld, sb, path, (struct sockaddr *)&server, cb );
|
||||
}
|
||||
} else {
|
||||
int err;
|
||||
err = ldap_int_connect_cbs( ld, sb, &s, path, (struct sockaddr *)&server );
|
||||
if ( err )
|
||||
rc = err;
|
||||
}
|
||||
if ( rc ) {
|
||||
ldap_pvt_close_socket(ld, s);
|
||||
}
|
||||
return rc;
|
||||
|
Loading…
Reference in New Issue
Block a user