Commit 2e091262 authored by Kurt Zeilenga's avatar Kurt Zeilenga
Browse files

ITS#537: lber io rewrite from Gambor Gombas.

Copyright 2000 Gábor Gombás. All rights reserved.
This is free software. You may redistribute and use it under the same
terms as OpenLDAP itself.
parent 1605a045
......@@ -123,11 +123,26 @@ typedef struct lber_memory_fns {
BER_MEMFREE_FN bmf_free;
} BerMemoryFunctions;
/* LBER Sockbuf options */
#define LBER_TO_FILE 0x01 /* to a file referenced by sb_fd */
#define LBER_TO_FILE_ONLY 0x02 /* only write to file, not network */
#define LBER_MAX_INCOMING_SIZE 0x04 /* impose limit on incoming stuff */
#define LBER_NO_READ_AHEAD 0x08 /* read only as much as requested */
/* LBER Sockbuf_IO options */
#define LBER_SB_OPT_GET_FD 1
#define LBER_SB_OPT_SET_FD 2
#define LBER_SB_OPT_HAS_IO 3
#define LBER_SB_OPT_SET_NONBLOCK 4
#define LBER_SB_OPT_UDP_GET_SRC 5
#define LBER_SB_OPT_UDP_SET_DST 6
#define LBER_SB_OPT_GET_SSL 7
#define LBER_SB_OPT_DATA_READY 8
#define LBER_SB_OPT_SET_READAHEAD 9
#define LBER_SB_OPT_DRAIN 10
#define LBER_SB_OPT_NEEDS_READ 11
#define LBER_SB_OPT_NEEDS_WRITE 12
/* Largest option used by the library */
#define LBER_SB_OPT_OPT_MAX 12
/* LBER IO operations stacking levels */
#define LBER_SBIOD_LEVEL_PROVIDER 10
#define LBER_SBIOD_LEVEL_TRANSPORT 20
#define LBER_SBIOD_LEVEL_APPLICATION 30
/* get/set options for Sockbuf */
#define LBER_OPT_SOCKBUF_DESC 0x1000
......@@ -145,6 +160,43 @@ typedef struct berelement BerElement;
typedef struct sockbuf Sockbuf;
typedef struct seqorset Seqorset;
typedef struct sockbuf_io Sockbuf_IO;
/* Structure for LBER IO operarion descriptor */
typedef struct sockbuf_io_desc {
int sbiod_level;
Sockbuf *sbiod_sb;
Sockbuf_IO *sbiod_io;
void *sbiod_pvt;
struct sockbuf_io_desc *sbiod_next;
} Sockbuf_IO_Desc;
/* Structure for LBER IO operation functions */
struct sockbuf_io {
int (*sbi_setup)( Sockbuf_IO_Desc *sbiod, void *arg );
int (*sbi_remove)( Sockbuf_IO_Desc *sbiod );
int (*sbi_ctrl)( Sockbuf_IO_Desc *sbiod, int opt, void *arg);
ber_slen_t (*sbi_read)( Sockbuf_IO_Desc *sbiod, void *buf,
ber_len_t len );
ber_slen_t (*sbi_write)( Sockbuf_IO_Desc *sbiod, void *buf,
ber_len_t len );
int (*sbi_close)( Sockbuf_IO_Desc *sbiod );
};
/* Helper macros for LBER IO functions */
#define LBER_SBIOD_READ_NEXT( sbiod, buf, len ) \
( (sbiod)->sbiod_next->sbiod_io->sbi_read( (sbiod)->sbiod_next, \
buf, len ) )
#define LBER_SBIOD_WRITE_NEXT( sbiod, buf, len ) \
( (sbiod)->sbiod_next->sbiod_io->sbi_write( (sbiod)->sbiod_next, \
buf, len ) )
#define LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg ) \
( (sbiod)->sbiod_next ? \
( (sbiod)->sbiod_next->sbiod_io->sbi_ctrl( \
(sbiod)->sbiod_next, opt, arg ) ) : 0 )
/* structure for returning a sequence of octet strings + length */
typedef struct berval {
ber_len_t bv_len;
......@@ -428,16 +480,38 @@ ber_set_option LDAP_P((
* LBER sockbuf.c
*/
LIBLBER_F( Sockbuf * )
ber_sockbuf_alloc( void );
LIBLBER_F( Sockbuf * )
ber_sockbuf_alloc_fd(
ber_socket_t fd );
ber_sockbuf_alloc LDAP_P((
void ));
LIBLBER_F( void )
ber_sockbuf_free(
Sockbuf *sb );
ber_sockbuf_free LDAP_P((
Sockbuf *sb ));
LIBLBER_F( int )
ber_sockbuf_add_io LDAP_P((
Sockbuf *sb,
Sockbuf_IO *sbio,
int layer,
void *arg ));
LIBLBER_F( int )
ber_sockbuf_remove_io LDAP_P((
Sockbuf *sb,
Sockbuf_IO *sbio,
int layer ));
LIBLBER_F( int )
ber_sockbuf_ctrl LDAP_P((
Sockbuf *sb,
int opt,
void *arg ));
LIBLBER_F( Sockbuf_IO ) ber_sockbuf_io_tcp;
LIBLBER_F( Sockbuf_IO ) ber_sockbuf_io_udp;
LIBLBER_F( Sockbuf_IO ) ber_sockbuf_io_readahead;
LIBLBER_F( Sockbuf_IO ) ber_sockbuf_io_fd;
LIBLBER_F( Sockbuf_IO ) ber_sockbuf_io_debug;
/*
* LBER memory.c
......
......@@ -20,6 +20,13 @@
LDAP_BEGIN_DECL
typedef struct sockbuf_buf {
ber_len_t buf_size;
ber_len_t buf_ptr;
ber_len_t buf_end;
char *buf_base;
} Sockbuf_Buf;
/*
* bprint.c
*/
......@@ -32,6 +39,27 @@ ber_pvt_log_printf LDAP_P((
const char *fmt,
... )) LDAP_GCCATTR((format(printf, 3, 4)));
/*
* sockbuf.c
*/
LIBLBER_F( ber_slen_t )
ber_pvt_sb_do_write LDAP_P(( Sockbuf_IO_Desc *sbiod, Sockbuf_Buf *buf_out ));
LIBLBER_F( void )
ber_pvt_sb_buf_init LDAP_P(( Sockbuf_Buf *buf ));
LIBLBER_F( void )
ber_pvt_sb_buf_destroy LDAP_P(( Sockbuf_Buf *buf ));
LIBLBER_F( int )
ber_pvt_sb_grow_buffer LDAP_P(( Sockbuf_Buf *buf, ber_len_t minsize ));
LIBLBER_F( ber_len_t )
ber_pvt_sb_copy_out LDAP_P(( Sockbuf_Buf *sbb, char *buf, ber_len_t len ));
LIBLBER_F( int )
ber_pvt_socket_set_nonblock LDAP_P(( ber_socket_t sd, int nb ));
LDAP_END_DECL
#endif
......
......@@ -47,6 +47,7 @@ main( int argc, char **argv )
BerElement *ber;
Sockbuf *sb;
int fd;
/* enable debugging */
int ival = -1;
......@@ -62,7 +63,10 @@ main( int argc, char **argv )
cshow( stdout );
#endif
sb = ber_sockbuf_alloc_fd( fileno(stdin) );
sb = ber_sockbuf_alloc();
fd = fileno( stdin );
ber_sockbuf_add_io( sb, &ber_sockbuf_io_fd, LBER_SBIOD_LEVEL_PROVIDER,
(void *)&fd );
if( (ber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
perror( "ber_alloc_t" );
......
......@@ -75,7 +75,9 @@ main( int argc, char **argv )
fd = fileno(stdout);
#endif
sb = ber_sockbuf_alloc_fd( fd );
sb = ber_sockbuf_alloc();
ber_sockbuf_add_io( sb, &ber_sockbuf_io_fd, LBER_SBIOD_LEVEL_PROVIDER,
(void *)&fd );
if( sb == NULL ) {
perror( "ber_sockbuf_alloc_fd" );
......
......@@ -64,7 +64,7 @@ BerRead(
assert( SOCKBUF_VALID( sb ) );
while ( len > 0 ) {
if ( (c = ber_pvt_sb_read( sb, buf, len )) <= 0 ) {
if ( (c = ber_int_sb_read( sb, buf, len )) <= 0 ) {
if ( nread > 0 )
break;
return( c );
......@@ -232,26 +232,15 @@ ber_flush( Sockbuf *sb, BerElement *ber, int freeit )
if ( sb->sb_debug ) {
ber_log_printf( LDAP_DEBUG_ANY, sb->sb_debug,
"ber_flush: %ld bytes to sd %ld%s\n", towrite,
(long) sb->sb_sd, ber->ber_rwptr != ber->ber_buf ? " (re-flush)"
: "" );
(long) sb->sb_fd, ber->ber_rwptr != ber->ber_buf ?
" (re-flush)" : "" );
ber_log_bprint( LDAP_DEBUG_PACKETS, sb->sb_debug,
ber->ber_rwptr, towrite );
}
#if HAVE_WRITE
if ( sb->sb_options & (LBER_TO_FILE | LBER_TO_FILE_ONLY) ) {
rc = write( sb->sb_fd, ber->ber_rwptr, towrite );
if ( sb->sb_options & LBER_TO_FILE_ONLY ) {
if ( freeit )
ber_free( ber, 1 );
return( (int)rc );
}
}
#endif
nwritten = 0;
do {
rc = ber_pvt_sb_write( sb, ber->ber_rwptr, towrite );
rc = ber_int_sb_write( sb, ber->ber_rwptr, towrite );
if (rc<=0) {
return -1;
}
......@@ -446,7 +435,7 @@ get_tag( Sockbuf *sb )
assert( sb != NULL );
assert( SOCKBUF_VALID( sb ) );
if ( ber_pvt_sb_read( sb, (char *) &xbyte, 1 ) != 1 )
if ( ber_int_sb_read( sb, (char *) &xbyte, 1 ) != 1 )
return( LBER_DEFAULT );
if ( (xbyte & LBER_BIG_TAG_MASK) != LBER_BIG_TAG_MASK )
......@@ -455,7 +444,7 @@ get_tag( Sockbuf *sb )
tagp = (char *) &tag;
tagp[0] = xbyte;
for ( i = 1; i < sizeof(ber_tag_t); i++ ) {
if ( ber_pvt_sb_read( sb, (char *) &xbyte, 1 ) != 1 )
if ( ber_int_sb_read( sb, (char *) &xbyte, 1 ) != 1 )
return( LBER_DEFAULT );
tagp[i] = xbyte;
......@@ -522,7 +511,7 @@ ber_get_next(
if (PTR_IN_VAR(ber->ber_rwptr, ber->ber_tag)) {
if (ber->ber_rwptr == (char *) &ber->ber_tag) {
if (ber_pvt_sb_read( sb, ber->ber_rwptr, 1)<=0)
if (ber_int_sb_read( sb, ber->ber_rwptr, 1)<=0)
return LBER_DEFAULT;
if ((ber->ber_rwptr[0] & LBER_BIG_TAG_MASK)
!= LBER_BIG_TAG_MASK) {
......@@ -534,7 +523,7 @@ ber_get_next(
}
do {
/* reading the tag... */
if (ber_pvt_sb_read( sb, ber->ber_rwptr, 1)<=0)
if (ber_int_sb_read( sb, ber->ber_rwptr, 1)<=0)
return LBER_DEFAULT;
if (! (ber->ber_rwptr[0] & LBER_MORE_TAG_MASK) ) {
ber->ber_tag>>=sizeof(ber->ber_tag) -
......@@ -550,7 +539,7 @@ ber_get_next(
get_lenbyte:
if (ber->ber_rwptr==(char *) &ber->ber_usertag) {
unsigned char c;
if (ber_pvt_sb_read( sb, (char *) &c, 1)<=0)
if (ber_int_sb_read( sb, (char *) &c, 1)<=0)
return LBER_DEFAULT;
if (c & 0x80U) {
int len = c & 0x7fU;
......@@ -611,7 +600,7 @@ fill_buffer:
to_go = ber->ber_end - ber->ber_rwptr;
assert( to_go > 0 );
res = ber_pvt_sb_read( sb, ber->ber_rwptr, to_go );
res = ber_int_sb_read( sb, ber->ber_rwptr, to_go );
if (res<=0)
return LBER_DEFAULT;
ber->ber_rwptr+=res;
......
......@@ -28,15 +28,15 @@ LIBLBER_F (BER_ERRNO_FN) ber_int_errno_fn;
struct lber_options {
short lbo_valid;
unsigned short lbo_options;
int lbo_debug;
};
#define LBER_UNINITIALIZED 0x0
#define LBER_INITIALIZED 0x1
#define LBER_VALID_BERELEMENT 0x2
#define LBER_VALID_SOCKBUF 0x3
unsigned short lbo_options;
int lbo_debug;
};
LIBLBER_F (struct lber_options) ber_int_options;
#define ber_int_debug ber_int_options.lbo_debug
......@@ -62,106 +62,21 @@ struct berelement {
};
#define BER_VALID(ber) ((ber)->ber_valid==LBER_VALID_BERELEMENT)
#define ber_pvt_ber_bytes(ber) ((ber)->ber_ptr - (ber)->ber_buf)
#define ber_pvt_ber_remaining(ber) ((ber)->ber_end - (ber)->ber_ptr)
struct sockbuf;
struct sockbuf_io {
int (*sbi_setup)( struct sockbuf * sb, void *arg );
int (*sbi_remove)( struct sockbuf *sb );
ber_slen_t (*sbi_read)( struct sockbuf *sb, void *buf, ber_len_t len );
ber_slen_t (*sbi_write)( struct sockbuf *sb, void *buf, ber_len_t len );
int (*sbi_close)( struct sockbuf *sb );
};
struct sockbuf_sec {
int (*sbs_setup)( struct sockbuf * sb, void *arg );
int (*sbs_remove)( struct sockbuf *sb );
long (*sbs_protect)( struct sockbuf *sb, char *in, long *ilen,
char *out, long olen );
long (*sbs_release)( struct sockbuf *sb, char *in, long ilen,
char *out0, long olen0, char *out1, long olen1 );
};
struct sockbuf_buf {
ber_len_t buf_size;
ber_len_t buf_ptr;
ber_len_t buf_end;
char *buf_base;
};
typedef struct sockbuf_io Sockbuf_IO;
typedef struct sockbuf_sec Sockbuf_Sec;
typedef struct sockbuf_buf Sockbuf_Buf;
LIBLBER_F( Sockbuf_IO ) ber_pvt_sb_io_tcp;
LIBLBER_F( Sockbuf_IO ) ber_pvt_sb_io_udp;
struct sockbuf {
struct lber_options sb_opts;
Sockbuf_IO_Desc *sb_iod; /* I/O functions */
#define sb_valid sb_opts.lbo_valid
#define sb_options sb_opts.lbo_options
#define sb_debug sb_opts.lbo_debug
int sb_non_block:1;
int sb_read_ahead:1;
int sb_buf_ready:1;
int sb_trans_ready:1;
int sb_sec_ready:1;
/* these bits indicate if the transport layer
* needs to read or write
*/
ber_socket_t sb_fd;
int sb_trans_needs_read:1;
int sb_trans_needs_write:1;
int sb_fd;
void *sb_iodata; /* transport-layer data pointer */
Sockbuf_IO *sb_io; /* I/O functions */
#ifdef LDAP_SASL
void *sb_sdata; /* security-layer data pointer */
Sockbuf_Sec *sb_sec;
#endif
ber_socket_t sb_sd;
#ifdef DEADWOOD
long sb_max_incoming;
#endif
Sockbuf_Buf sb_buf;
#ifdef LDAP_SASL
Sockbuf_Buf sb_sec_buf_in;
Sockbuf_Buf sb_sec_buf_out;
ber_len_t sb_sec_prev_len;
#endif
};
#define SOCKBUF_VALID(ber) ((sb)->sb_valid==LBER_VALID_SOCKBUF)
/* these should be internal ie: ber_int_* */
#define ber_pvt_sb_get_desc( sb ) ((sb)->sb_sd)
#define ber_pvt_sb_set_desc( sb, val ) ((sb)->sb_sd =(val))
#define ber_pvt_sb_in_use( sb ) ((sb)->sb_sd != AC_SOCKET_INVALID)
#ifdef USE_SASL
#define ber_pvt_sb_data_ready( sb ) \
(((sb)->sb_buf_ready) || ((sb)->sb_trans_ready) || ((sb)->sb_sec_ready))
#else
#define ber_pvt_sb_data_ready( sb ) \
(((sb)->sb_buf_ready) || ((sb)->sb_trans_ready))
#endif
#define ber_pvt_sb_needs_read( sb ) \
((sb)->sb_trans_needs_read)
#define ber_pvt_sb_needs_write( sb ) \
((sb)->sb_trans_needs_write)
#define SOCKBUF_VALID( sb ) ( (sb)->sb_valid == LBER_VALID_SOCKBUF )
#define READBUFSIZ 8192
......@@ -245,51 +160,20 @@ LIBLBER_F (BerMemoryFunctions *) ber_int_memory_fns;
/* sockbuf.c */
/* these should be ber_int*() functions */
LIBLBER_F( int )
ber_pvt_sb_init LDAP_P(( Sockbuf *sb ));
LIBLBER_F( int )
ber_pvt_sb_destroy LDAP_P(( Sockbuf *sb ));
ber_int_sb_init LDAP_P(( Sockbuf *sb ));
#ifdef USE_SASL
LIBLBER_F( int )
ber_pvt_sb_set_sec LDAP_P(( Sockbuf *sb, Sockbuf_Sec *sec, void *arg ));
LIBLBER_F( int )
ber_pvt_sb_clear_sec LDAP_P(( Sockbuf *sb ));
#endif
ber_int_sb_close LDAP_P(( Sockbuf *sb ));
LIBLBER_F( int )
ber_pvt_sb_set_io LDAP_P(( Sockbuf *sb, Sockbuf_IO *layer, void *arg ));
LIBLBER_F( int )
ber_pvt_sb_clear_io LDAP_P(( Sockbuf *sb ));
LIBLBER_F( int )
ber_pvt_sb_close LDAP_P((Sockbuf *sb ));
LIBLBER_F( int )
ber_pvt_sb_set_nonblock LDAP_P(( Sockbuf *sb, int nb ));
LIBLBER_F( int )
ber_pvt_sb_set_readahead LDAP_P(( Sockbuf *sb, int rh ));
ber_int_sb_destroy LDAP_P(( Sockbuf *sb ));
LIBLBER_F( ber_slen_t )
ber_pvt_sb_read LDAP_P(( Sockbuf *sb, void *buf, ber_len_t len ));
ber_int_sb_read LDAP_P(( Sockbuf *sb, void *buf, ber_len_t len ));
LIBLBER_F( ber_slen_t )
ber_pvt_sb_write LDAP_P(( Sockbuf *sb, void *buf, ber_len_t len ));
LIBLBER_F( int )
ber_pvt_sb_udp_set_dst LDAP_P((Sockbuf *sb, void *addr ));
LIBLBER_F( void * )
ber_pvt_sb_udp_get_src LDAP_P((Sockbuf *sb ));
LIBLBER_F( int )
ber_pvt_socket_set_nonblock LDAP_P(( ber_socket_t sd, int nb ));
ber_int_sb_write LDAP_P(( Sockbuf *sb, void *buf, ber_len_t len ));
LDAP_END_DECL
......
This diff is collapsed.
......@@ -180,7 +180,7 @@ do_abandon(
if ( lr != NULL ) {
sb = lr->lr_conn->lconn_sb;
} else {
sb = &ld->ld_sb;
sb = ld->ld_sb;
}
if ( ber_flush( sb, ber, 1 ) != 0 ) {
......
......@@ -94,10 +94,20 @@ cldap_open( LDAP_CONST char *host, int port )
ld->ld_cldapnaddr = 0;
ld->ld_cldapaddrs = NULL;
if (ber_pvt_sb_set_io( &(ld->ld_sb), &ber_pvt_sb_io_udp, NULL )<0) {
if ( ber_sockbuf_add_io( ld->ld_sb, &ber_sockbuf_io_udp,
LBER_SBIOD_LEVEL_PROVIDER, (void *)&s ) < 0 ) {
ldap_ld_free(ld, 1, NULL, NULL );
tcp_close( s );
return NULL;
}
if ( ber_sockbuf_add_io( ld->ld_sb, &ber_sockbuf_io_readahead,
LBER_SBIOD_LEVEL_PROVIDER, NULL ) < 0 ) {
ldap_ld_free( ld, 1, NULL, NULL );
return NULL;
}
#ifdef LDAP_DEBUG
ber_sockbuf_add_io( ld->ld_sb, &ber_sockbuf_io_debug, INT_MAX, NULL );
#endif
ld->ld_version = LDAP_VERSION2;
......@@ -168,7 +178,8 @@ cldap_open( LDAP_CONST char *host, int port )
DO_RETURN( NULL );
}
ber_pvt_sb_udp_set_dst( &ld->ld_sb, ld->ld_cldapaddrs[0] );
ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_UDP_SET_DST,
ld->ld_cldapaddrs[0] );
cldap_setretryinfo( ld, 0, 0 );
......@@ -229,8 +240,8 @@ cldap_search_s( LDAP *ld,
--ld->ld_msgid; /* use same id as before */
}
ber_pvt_sb_udp_set_dst( &(ld->ld_sb),
ld->ld_cldapaddrs[ cri.cri_useaddr ] );
ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_UDP_SET_DST,
(void *)ld->ld_cldapaddrs[cri.cri_useaddr] );
Debug( LDAP_DEBUG_TRACE, "cldap_search_s try %d (to %s)\n",
cri.cri_try, inet_ntoa( ((struct sockaddr_in *)
......@@ -287,7 +298,6 @@ static int
cldap_result( LDAP *ld, int msgid, LDAPMessage **res,
struct cldap_retinfo *crip, const char *base )
{
Sockbuf *sb = &ld->ld_sb;
BerElement ber;
char *logdn;
int ret, fromaddr, i;
......@@ -365,7 +375,7 @@ cldap_result( LDAP *ld, int msgid, LDAPMessage **res,
* got a result: determine which server it came from
* decode into ldap message chain
*/
src = (struct sockaddr_in *) ber_pvt_sb_udp_get_src( sb );
ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_UDP_GET_SRC, (void *)&src );
for ( fromaddr = 0; fromaddr < ld->ld_cldapnaddr; ++fromaddr ) {
if ( memcmp( &((struct sockaddr_in *)
......@@ -401,7 +411,8 @@ cldap_result( LDAP *ld, int msgid, LDAPMessage **res,
if ( i == fromaddr ) {
continue;
}
ber_pvt_sb_udp_set_dst( sb, ld->ld_cldapaddrs[i] );
ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_UDP_SET_DST,
(void *)ld->ld_cldapaddrs[i] );
Debug( LDAP_DEBUG_TRACE, "cldap_result abandoning id %d (to %s)\n",
msgid, inet_ntoa( ((struct sockaddr_in *)
......
......@@ -273,7 +273,7 @@ ldap_get_kerberosv4_credentials(
return( NULL );
}
if( ! ber_pvt_sb_in_use( &ld->ld_sb ) ) {
if ( ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, NULL ) == -1 ) {
/* not connected yet */
int rc = ldap_open_defconn( ld );
......
......@@ -20,12 +20,13 @@
#include "../liblber/lber-int.h"
#define ldap_debug (ldap_int_global_options.ldo_debug)
#include "ldap_log.h"
#undef Debug
#define Debug( level, fmt, arg1, arg2, arg3 ) \
ldap_log_printf( NULL, (level), (fmt), (arg1), (arg2), (arg3) )
#include "ldap_log.h"
#include "ldap.h"
#include "ldap_pvt.h"
......@@ -230,7 +231,7 @@ typedef struct ldapreqinfo {
*/
struct ldap {
Sockbuf ld_sb; /* socket descriptor & buffer */
Sockbuf *ld_sb; /* socket descriptor & buffer */
struct ldapoptions ld_options;
......@@ -391,8 +392,6 @@ LIBLDAP_F (int) ldap_int_tblsize;
LIBLDAP_F (int) ldap_int_timeval_dup( struct timeval **dest, const struct timeval *tm );
LIBLDAP_F (int) ldap_connect_to_host( LDAP *ld, Sockbuf *sb, const char *host, unsigned long address, int port, int async );
LIBLDAP_F (void) ldap_close_connection( Sockbuf *sb );
#if defined(LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND) || defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
LIBLDAP_F (char *) ldap_host_connected_to( Sockbuf *sb );
#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */
......
......@@ -161,7 +161,13 @@ ldap_create( LDAP **ldp )
#endif /* LDAP_CHARSET_8859 == LDAP_DEFAULT_CHARSET */
#endif /* STR_TRANSLATION && LDAP_DEFAULT_CHARSET */
ber_pvt_sb_init( &(ld->ld_sb) );
ld->ld_sb = ber_sockbuf_alloc( );
if ( ld->ld_sb == NULL ) {
ldap_free_urllist( ld->ld_options.ldo_defludp );
LDAP_FREE( (char*) ld );
WSACleanup( );
return LDAP_NO_MEMORY;
}
*ldp = ld;
return LDAP_SUCCESS;
......@@ -283,24 +289,41 @@ open_ldap_connection( LDAP *ld, Sockbuf *sb, LDAPURLDesc *srv,
switch ( srv->lud_protocol ) {
case LDAP_PROTO_TCP:
rc = ldap_connect_to_host( ld, sb, srv->lud_host,
addr, port, async );
if ( rc == -1 )
return rc;