diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c index 5028c13ec7..90f90e464f 100644 --- a/libraries/libldap/tls2.c +++ b/libraries/libldap/tls2.c @@ -1099,78 +1099,71 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv ) ld->ld_errno = LDAP_SUCCESS; ret = ldap_int_tls_connect( ld, conn, host ); + /* this mainly only happens for non-blocking io + * but can also happen when the handshake is too + * big for a single network message. + */ + while ( ret > 0 ) { #ifdef LDAP_USE_NON_BLOCKING_TLS - while ( ret > 0 ) { /* this should only happen for non-blocking io */ - int wr=0; - - if ( sb->sb_trans_needs_read ) { - wr=0; - } else if ( sb->sb_trans_needs_write ) { - wr=1; - } - Debug1( LDAP_DEBUG_TRACE, "ldap_int_tls_start: ldap_int_tls_connect needs %s\n", - wr ? "write": "read" ); - - ret = ldap_int_poll( ld, sd, &tv, wr); - if ( ret < 0 ) { - ld->ld_errno = LDAP_TIMEOUT; - break; - } else { - /* ldap_int_poll called ldap_pvt_ndelay_off if not async */ - if ( !async ) { - ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_NONBLOCK, (void*)1 ); + if ( async ) { + struct timeval curr_time_tv, delta_tv; + int wr=0; + + if ( sb->sb_trans_needs_read ) { + wr=0; + } else if ( sb->sb_trans_needs_write ) { + wr=1; } - ret = ldap_int_tls_connect( ld, conn, host ); - if ( ret > 0 ) { /* need to call tls_connect once more */ - struct timeval curr_time_tv, delta_tv; + Debug1( LDAP_DEBUG_TRACE, "ldap_int_tls_start: ldap_int_tls_connect needs %s\n", + wr ? "write": "read" ); - /* This is mostly copied from result.c:wait4msg(), should - * probably be moved into a separate function */ + /* This is mostly copied from result.c:wait4msg(), should + * probably be moved into a separate function */ #ifdef HAVE_GETTIMEOFDAY - gettimeofday( &curr_time_tv, NULL ); + gettimeofday( &curr_time_tv, NULL ); #else /* ! HAVE_GETTIMEOFDAY */ - time( &curr_time_tv.tv_sec ); - curr_time_tv.tv_usec = 0; + time( &curr_time_tv.tv_sec ); + curr_time_tv.tv_usec = 0; #endif /* ! HAVE_GETTIMEOFDAY */ - /* delta = curr - start */ - delta_tv.tv_sec = curr_time_tv.tv_sec - start_time_tv.tv_sec; - delta_tv.tv_usec = curr_time_tv.tv_usec - start_time_tv.tv_usec; - if ( delta_tv.tv_usec < 0 ) { - delta_tv.tv_sec--; - delta_tv.tv_usec += 1000000; - } + /* delta = curr - start */ + delta_tv.tv_sec = curr_time_tv.tv_sec - start_time_tv.tv_sec; + delta_tv.tv_usec = curr_time_tv.tv_usec - start_time_tv.tv_usec; + if ( delta_tv.tv_usec < 0 ) { + delta_tv.tv_sec--; + delta_tv.tv_usec += 1000000; + } - /* tv0 < delta ? */ - if ( ( tv0.tv_sec < delta_tv.tv_sec ) || - ( ( tv0.tv_sec == delta_tv.tv_sec ) && - ( tv0.tv_usec < delta_tv.tv_usec ) ) ) - { - ret = -1; - ld->ld_errno = LDAP_TIMEOUT; - break; - } else { - /* timeout -= delta_time */ - tv0.tv_sec -= delta_tv.tv_sec; - tv0.tv_usec -= delta_tv.tv_usec; - if ( tv0.tv_usec < 0 ) { - tv0.tv_sec--; - tv0.tv_usec += 1000000; - } - start_time_tv.tv_sec = curr_time_tv.tv_sec; - start_time_tv.tv_usec = curr_time_tv.tv_usec; - } - tv = tv0; - Debug3( LDAP_DEBUG_TRACE, "ldap_int_tls_start: ld %p %ld s %ld us to go\n", - (void *)ld, (long) tv.tv_sec, (long) tv.tv_usec ); + /* tv0 < delta ? */ + if ( ( tv0.tv_sec < delta_tv.tv_sec ) || + ( ( tv0.tv_sec == delta_tv.tv_sec ) && + ( tv0.tv_usec < delta_tv.tv_usec ) ) ) + { + ret = -1; + ld->ld_errno = LDAP_TIMEOUT; + break; + } + /* timeout -= delta_time */ + tv0.tv_sec -= delta_tv.tv_sec; + tv0.tv_usec -= delta_tv.tv_usec; + if ( tv0.tv_usec < 0 ) { + tv0.tv_sec--; + tv0.tv_usec += 1000000; + } + start_time_tv.tv_sec = curr_time_tv.tv_sec; + start_time_tv.tv_usec = curr_time_tv.tv_usec; + tv = tv0; + Debug3( LDAP_DEBUG_TRACE, "ldap_int_tls_start: ld %p %ld s %ld us to go\n", + (void *)ld, (long) tv.tv_sec, (long) tv.tv_usec ); + ret = ldap_int_poll( ld, sd, &tv, wr); + if ( ret < 0 ) { + ld->ld_errno = LDAP_TIMEOUT; + break; } } - } - /* Leave it nonblocking if async */ - if ( !async && ld->ld_options.ldo_tm_net.tv_sec >= 0 ) { - ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_NONBLOCK, NULL ); - } #endif /* LDAP_USE_NON_BLOCKING_TLS */ + ret = ldap_int_tls_connect( ld, conn, host ); + } if ( ret < 0 ) { if ( ld->ld_errno == LDAP_SUCCESS )