X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Frequest.c;h=9894301b88dcf52090aa89464db300a2abc41b03;hb=cdcc24691a3d272ba9fca46151ea5294a18c4922;hp=25cdee57b66d7bad5ae07745c2b7538cf824d5a6;hpb=dc871de33d529622f90c75f3d2be570e1e315821;p=openldap diff --git a/libraries/libldap/request.c b/libraries/libldap/request.c index 25cdee57b6..9894301b88 100644 --- a/libraries/libldap/request.c +++ b/libraries/libldap/request.c @@ -1,7 +1,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2006 The OpenLDAP Foundation. + * Copyright 1998-2008 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -209,11 +209,43 @@ ldap_send_server_request( } } + /* async connect... */ + if ( lc != NULL && lc->lconn_status == LDAP_CONNST_CONNECTING ) { + ber_socket_t sd = AC_SOCKET_ERROR; + struct timeval tv = { 0 }; + + ber_sockbuf_ctrl( lc->lconn_sb, LBER_SB_OPT_GET_FD, &sd ); + + /* poll ... */ + switch ( ldap_int_poll( ld, sd, &tv ) ) { + case 0: + /* go on! */ + lc->lconn_status = LDAP_CONNST_CONNECTED; + break; + + case -2: + /* async only occurs if a network timeout is set */ + + /* honor network timeout */ + if ( time( NULL ) - lc->lconn_created <= ld->ld_options.ldo_tm_net.tv_sec ) + { + /* caller will have to call again */ + ld->ld_errno = LDAP_X_CONNECTING; + } + /* fallthru */ + + default: + /* error */ + break; + } + } + if ( lc == NULL || lc->lconn_status != LDAP_CONNST_CONNECTED ) { - ber_free( ber, 1 ); if ( ld->ld_errno == LDAP_SUCCESS ) { ld->ld_errno = LDAP_SERVER_DOWN; } + + ber_free( ber, 1 ); if ( incparent ) { /* Forget about the bind */ --parentreq->lr_outrefcnt; @@ -223,6 +255,19 @@ ldap_send_server_request( use_connection( ld, lc ); +#ifdef LDAP_CONNECTIONLESS + if ( LDAP_IS_UDP( ld )) { + BerElement tmpber = *ber; + ber_rewind( &tmpber ); + rc = ber_write( &tmpber, ld->ld_options.ldo_peer, + sizeof( struct sockaddr ), 0 ); + if ( rc == -1 ) { + ld->ld_errno = LDAP_ENCODING_ERROR; + return rc; + } + } +#endif + /* 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 @@ -312,6 +357,7 @@ ldap_new_connection( LDAP *ld, LDAPURLDesc **srvlist, int use_ldsb, int connect, LDAPreqinfo *bind ) { LDAPConn *lc; + int async = 0; Debug( LDAP_DEBUG_TRACE, "ldap_new_connection %d %d %d\n", use_ldsb, connect, (bind != NULL) ); @@ -341,12 +387,16 @@ ldap_new_connection( LDAP *ld, LDAPURLDesc **srvlist, int use_ldsb, if ( connect ) { LDAPURLDesc **srvp, *srv = NULL; + async = LDAP_BOOL_GET( &ld->ld_options, LDAP_BOOL_CONNECT_ASYNC ); + for ( srvp = srvlist; *srvp != NULL; srvp = &(*srvp)->lud_next ) { - if ( ldap_int_open_connection( ld, lc, *srvp, 0 ) != -1 ) - { + int rc; + + rc = ldap_int_open_connection( ld, lc, *srvp, async ); + if ( rc != -1 ) { srv = *srvp; - if ( ld->ld_urllist_proc ) { + if ( ld->ld_urllist_proc && ( !async || rc != -2 ) ) { ld->ld_urllist_proc( ld, srvlist, srvp, ld->ld_urllist_params ); } @@ -366,7 +416,7 @@ ldap_new_connection( LDAP *ld, LDAPURLDesc **srvlist, int use_ldsb, lc->lconn_server = ldap_url_dup( srv ); } - lc->lconn_status = LDAP_CONNST_CONNECTED; + lc->lconn_status = async ? LDAP_CONNST_CONNECTING : LDAP_CONNST_CONNECTED; #ifdef LDAP_R_COMPILE ldap_pvt_thread_mutex_lock( &ld->ld_conn_mutex ); #endif @@ -430,7 +480,10 @@ ldap_new_connection( LDAP *ld, LDAPURLDesc **srvlist, int use_ldsb, ++lc->lconn_refcnt; /* avoid premature free */ ld->ld_defconn = lc; - Debug( LDAP_DEBUG_TRACE, "anonymous rebind via ldap_bind_s\n", 0, 0, 0); + Debug( LDAP_DEBUG_TRACE, + "anonymous rebind via ldap_sasl_bind(\"\")\n", + 0, 0, 0); + #ifdef LDAP_R_COMPILE ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex ); ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex ); @@ -468,7 +521,13 @@ ldap_new_connection( LDAP *ld, LDAPURLDesc **srvlist, int use_ldsb, break; default: - assert( 0 ); + Debug( LDAP_DEBUG_TRACE, + "ldap_new_connection %p: " + "unexpected response %d " + "from BIND request id=%d\n", + (void *) ld, ldap_msgtype( res ), msgid ); + err = -1; + break; } } } @@ -595,11 +654,6 @@ ldap_free_connection( LDAP *ld, LDAPConn *lc, int force, int unbind ) ldap_int_sasl_close( ld, lc ); ldap_free_urllist( lc->lconn_server ); -#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND - if ( lc->lconn_krbinstance != NULL ) { - LDAP_FREE( lc->lconn_krbinstance ); - } -#endif /* FIXME: is this at all possible? * ldap_ld_free() in unbind.c calls ldap_free_connection() @@ -663,8 +717,9 @@ ldap_dump_connection( LDAP *ld, LDAPConn *lconns, int all ) } Debug( LDAP_DEBUG_TRACE, " refcnt: %d status: %s\n", lc->lconn_refcnt, ( lc->lconn_status == LDAP_CONNST_NEEDSOCKET ) - ? "NeedSocket" : ( lc->lconn_status == LDAP_CONNST_CONNECTING ) - ? "Connecting" : "Connected", 0 ); + ? "NeedSocket" : + ( lc->lconn_status == LDAP_CONNST_CONNECTING ) + ? "Connecting" : "Connected", 0 ); Debug( LDAP_DEBUG_TRACE, " last used: %s%s\n", ldap_pvt_ctime( &lc->lconn_lastused, timebuf ), lc->lconn_rebind_inprogress ? " rebind in progress" : "", 0 ); @@ -716,7 +771,7 @@ ldap_dump_requests_and_responses( LDAP *ld ) Debug( LDAP_DEBUG_TRACE, " outstanding referrals %d, parent count %d\n", lr->lr_outrefcnt, lr->lr_parentcnt, 0 ); } - Debug( LDAP_DEBUG_TRACE, " ld %p request count %d (abandoned %d)\n", + Debug( LDAP_DEBUG_TRACE, " ld %p request count %d (abandoned %lu)\n", (void *)ld, i, ld->ld_nabandoned ); Debug( LDAP_DEBUG_TRACE, "** ld %p Response Queue:\n", (void *)ld, 0, 0 ); if ( ( lm = ld->ld_responses ) == NULL ) { @@ -725,9 +780,9 @@ ldap_dump_requests_and_responses( LDAP *ld ) for ( i = 0; lm != NULL; lm = lm->lm_next, i++ ) { Debug( LDAP_DEBUG_TRACE, " * msgid %d, type %lu\n", lm->lm_msgid, (unsigned long)lm->lm_msgtype, 0 ); - if ( ( l = lm->lm_chain ) != NULL ) { + if ( lm->lm_chain != NULL ) { Debug( LDAP_DEBUG_TRACE, " chained responses:\n", 0, 0, 0 ); - for ( ; l != NULL; l = l->lm_chain ) { + for ( l = lm->lm_chain; l != NULL; l = l->lm_chain ) { Debug( LDAP_DEBUG_TRACE, " * msgid %d, type %lu\n", l->lm_msgid, @@ -795,7 +850,6 @@ ldap_free_request_int( LDAP *ld, LDAPRequest *lr ) void ldap_free_request( LDAP *ld, LDAPRequest *lr ) { - LDAPRequest **ttmplr; #ifdef LDAP_R_COMPILE LDAP_PVT_THREAD_ASSERT_MUTEX_OWNER( &ld->ld_req_mutex ); #endif @@ -804,16 +858,21 @@ ldap_free_request( LDAP *ld, LDAPRequest *lr ) lr->lr_origid, lr->lr_msgid, 0 ); /* free all referrals (child requests) */ - while ( lr->lr_child ) + while ( lr->lr_child ) { ldap_free_request( ld, lr->lr_child ); + } if ( lr->lr_parent != NULL ) { + LDAPRequest **lrp; + --lr->lr_parent->lr_outrefcnt; - for ( ttmplr = &lr->lr_parent->lr_child; - *ttmplr && *ttmplr != lr; - ttmplr = &(*ttmplr)->lr_refnext ); - if ( *ttmplr == lr ) - *ttmplr = lr->lr_refnext; + for ( lrp = &lr->lr_parent->lr_child; + *lrp && *lrp != lr; + lrp = &(*lrp)->lr_refnext ); + + if ( *lrp == lr ) { + *lrp = lr->lr_refnext; + } } ldap_free_request_int( ld, lr ); } @@ -956,7 +1015,7 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char * if ( lp == origreq ) { lp = lp->lr_child; } else { - lp = lr->lr_refnext; + lp = lp->lr_refnext; } } if ( looped ) { @@ -1214,7 +1273,7 @@ ldap_chase_referrals( LDAP *ld, } } if ( looped ) { - ldap_free_urllist(srv); + ldap_free_urllist( srv ); ld->ld_errno = LDAP_CLIENT_LOOP; rc = -1; continue;