The new&improved Sockbuf. This adds the infrastructure on which

support for TLS and SASL will be build.

Please inform me of any problems.
This commit is contained in:
Bart Hartgers 1999-03-02 20:23:14 +00:00
parent e0fdd89432
commit 8153a4039b
27 changed files with 1209 additions and 332 deletions

View file

@ -205,9 +205,9 @@ lber_set_option LDAP_P((void *item, int option, void *invalue));
/*
* LBER Sockbuf functions
*/
LDAP_F Sockbuf *lber_sockbuf_alloc LDAP_P((void));
LDAP_F Sockbuf *lber_sockbuf_alloc_fd LDAP_P((int fd));
LDAP_F void lber_sockbuf_free LDAP_P((Sockbuf *sb));
LDAP_F Sockbuf *lber_pvt_sockbuf_alloc LDAP_P((void));
LDAP_F Sockbuf *lber_pvt_sockbuf_alloc_fd LDAP_P((int fd));
LDAP_F void lber_pvt_sockbuf_free LDAP_P((Sockbuf *sb));
LDAP_END_DECL

View file

@ -443,13 +443,6 @@ typedef struct ldap_friendly {
char *lf_friendly;
} LDAPFriendlyMap;
/*
* handy macro to check whether LDAP struct is set up for CLDAP or not
*/
#define LDAP_IS_CLDAP( ld ) ( (ld)->ld_sb.sb_naddr > 0 )
/*
* types for ldap URL handling
*/

View file

@ -7,8 +7,8 @@
LIBRARY = liblber.la
XLIBRARY = ../liblber.a
SRCS= decode.c encode.c io.c bprint.c options.c
OBJS= decode.lo encode.lo io.lo bprint.lo options.lo
SRCS= decode.c encode.c io.c bprint.c options.c sockbuf.c
OBJS= decode.lo encode.lo io.lo bprint.lo options.lo sockbuf.lo
XSRCS= version.c
PROGRAMS= dtest etest idtest

View file

@ -49,7 +49,7 @@ main( int argc, char **argv )
cshow( stdout );
#endif /* MACOS */
sb = lber_sockbuf_alloc_fd( fileno(stdin) );
sb = lber_pvt_sb_alloc_fd( fileno(stdin) );
if( (ber = ber_alloc_t(LBER_USE_DER)) == NULL ) {
perror( "ber_alloc_t" );
@ -68,6 +68,6 @@ main( int argc, char **argv )
}
printf( "got int %ld\n", i );
lber_sockbuf_free( sb );
lber_pvt_sb_free( sb );
return( 0 );
}

View file

@ -58,7 +58,7 @@ main( int argc, char **argv )
fd = fileno(stdout);
#endif /* MACOS */
sb = lber_sockbuf_alloc_fd( fd );
sb = lber_pvt_sb_alloc_fd( fd );
if ( (ber = ber_alloc()) == NULLBER ) {
perror( "ber_alloc" );
@ -171,6 +171,6 @@ main( int argc, char **argv )
#endif
lber_sockbuf_free( sb );
lber_pvt_sb_free( sb );
return( 0 );
}

View file

@ -32,130 +32,11 @@
#include "lber-int.h"
static int ber_realloc LDAP_P(( BerElement *ber, unsigned long len ));
static int ber_filbuf LDAP_P(( Sockbuf *sb, long len ));
static long BerRead LDAP_P(( Sockbuf *sb, char *buf, long len ));
#ifdef PCNFS
static int BerWrite LDAP_P(( Sockbuf *sb, char *buf, long len ));
#endif /* PCNFS */
#define bergetc( sb, len ) ( sb->sb_ber.ber_end > sb->sb_ber.ber_ptr ? \
(unsigned char)*sb->sb_ber.ber_ptr++ : \
ber_filbuf( sb, len ))
#ifdef MACOS
/*
* MacTCP/OpenTransport
*/
#define read( s, b, l ) tcpread( s, 0, (unsigned char *)b, l, NULL )
#define MAX_WRITE 65535
#define BerWrite( sb, b, l ) tcpwrite( sb->sb_sd, (unsigned char *)(b), (l<MAX_WRITE)? l : MAX_WRITE )
#else /* MACOS */
#ifdef DOS
#ifdef PCNFS
/*
* PCNFS (under DOS)
*/
#define read( s, b, l ) recv( s, b, l, 0 )
#define BerWrite( s, b, l ) send( s->sb_sd, b, (int) l, 0 )
#endif /* PCNFS */
#ifdef NCSA
/*
* NCSA Telnet TCP/IP stack (under DOS)
*/
#define read( s, b, l ) nread( s, b, l )
#define BerWrite( s, b, l ) netwrite( s->sb_sd, b, l )
#endif /* NCSA */
#ifdef WINSOCK
/*
* Windows Socket API (under DOS/Windows 3.x)
*/
#define read( s, b, l ) recv( s, b, l, 0 )
#define BerWrite( s, b, l ) send( s->sb_sd, b, l, 0 )
#endif /* WINSOCK */
#else /* DOS */
#ifdef _WIN32
/*
* 32-bit Windows Socket API (under Windows NT or Windows 95)
*/
#define read( s, b, l ) recv( s, b, l, 0 )
#define BerWrite( s, b, l ) send( s->sb_sd, b, l, 0 )
#else /* _WIN32 */
#ifdef VMS
/*
* VMS -- each write must be 64K or smaller
*/
#define MAX_WRITE 65535
#define BerWrite( sb, b, l ) write( sb->sb_sd, b, (l<MAX_WRITE)? l : MAX_WRITE)
#else /* VMS */
/*
* everything else (Unix/BSD 4.3 socket API)
*/
#define BerWrite( sb, b, l ) write( sb->sb_sd, b, l )
#endif /* VMS */
#define udp_read( sb, b, l, al ) recvfrom(sb->sb_sd, (char *)b, l, 0, \
(struct sockaddr *)sb->sb_fromaddr, \
(al = sizeof(struct sockaddr), &al))
#define udp_write( sb, b, l ) sendto(sb->sb_sd, (char *)(b), l, 0, \
(struct sockaddr *)sb->sb_useaddr, sizeof(struct sockaddr))
#endif /* _WIN32 */
#endif /* DOS */
#endif /* MACOS */
#ifndef udp_read
#define udp_read( sb, b, l, al ) CLDAP NOT SUPPORTED
#define udp_write( sb, b, l ) CLDAP NOT SUPPORTED
#endif /* udp_read */
static int ber_realloc LDAP_P(( BerElement *ber, unsigned long len ));
#define EXBUFSIZ 1024
static int
ber_filbuf( Sockbuf *sb, long len )
{
short rc;
#ifdef LDAP_CONNECTIONLESS
int addrlen;
#endif /* LDAP_CONNECTIONLESS */
if ( sb->sb_ber.ber_buf == NULL ) {
if ( (sb->sb_ber.ber_buf = (char *) malloc( READBUFSIZ )) ==
NULL )
return( -1 );
sb->sb_ber.ber_ptr = sb->sb_ber.ber_buf;
sb->sb_ber.ber_end = sb->sb_ber.ber_buf;
}
if ( sb->sb_naddr > 0 ) {
#ifdef LDAP_CONNECTIONLESS
rc = udp_read(sb, sb->sb_ber.ber_buf, READBUFSIZ, addrlen );
if ( sb->sb_debug ) {
lber_log_printf( LDAP_DEBUG_ANY, sb->sb_debug,
"ber_filbuf udp_read %d bytes\n",
rc );
if ( rc > 0 )
lber_log_bprint( LDAP_DEBUG_PACKETS, sb->sb_debug,
sb->sb_ber.ber_buf, rc );
}
#else /* LDAP_CONNECTIONLESS */
rc = -1;
#endif /* LDAP_CONNECTIONLESS */
} else {
rc = read( sb->sb_sd, sb->sb_ber.ber_buf,
((sb->sb_options & LBER_NO_READ_AHEAD) && (len < READBUFSIZ)) ?
len : READBUFSIZ );
}
if ( rc > 0 ) {
sb->sb_ber.ber_ptr = sb->sb_ber.ber_buf + 1;
sb->sb_ber.ber_end = sb->sb_ber.ber_buf + rc;
return( (unsigned char)*sb->sb_ber.ber_buf );
}
return( -1 );
}
static long
BerRead( Sockbuf *sb, char *buf, long len )
{
@ -163,20 +44,19 @@ BerRead( Sockbuf *sb, char *buf, long len )
long nread = 0;
while ( len > 0 ) {
if ( (c = bergetc( sb, len )) < 0 ) {
if ( (c = lber_pvt_sb_read( sb, buf, len )) <= 0 ) {
if ( nread > 0 )
break;
return( c );
}
*buf++ = (char) c;
nread++;
len--;
buf+= c;
nread+=c;
len-=c;
}
return( nread );
}
long
ber_read( BerElement *ber, char *buf, unsigned long len )
{
@ -271,7 +151,7 @@ ber_free( BerElement *ber, int freebuf )
int
ber_flush( Sockbuf *sb, BerElement *ber, int freeit )
{
long nwritten, towrite, rc;
long nwritten, towrite, rc;
if ( ber->ber_rwptr == NULL ) {
ber->ber_rwptr = ber->ber_buf;
@ -289,37 +169,18 @@ ber_flush( Sockbuf *sb, BerElement *ber, int freeit )
#if !defined(MACOS) && !defined(DOS)
if ( sb->sb_options & (LBER_TO_FILE | LBER_TO_FILE_ONLY) ) {
rc = write( sb->sb_fd, ber->ber_buf, towrite );
rc = write( sb->sb_fd, ber->ber_rwptr, towrite );
if ( sb->sb_options & LBER_TO_FILE_ONLY ) {
return( (int)rc );
}
}
#endif
nwritten = 0;
do {
if (sb->sb_naddr > 0) {
#ifdef LDAP_CONNECTIONLESS
rc = udp_write( sb, ber->ber_buf + nwritten,
(size_t)towrite );
#else /* LDAP_CONNECTIONLESS */
rc = -1;
#endif /* LDAP_CONNECTIONLESS */
if ( rc <= 0 )
return( -1 );
/* fake error if write was not atomic */
if (rc < towrite) {
#ifdef EMSGSIZE
errno = EMSGSIZE;
#endif
return( -1 );
}
} else {
if ( (rc = BerWrite( sb, ber->ber_rwptr,
(size_t) towrite )) <= 0 ) {
return( -1 );
}
rc = lber_pvt_sb_write( sb, ber->ber_rwptr, towrite );
if (rc<=0) {
return -1;
}
towrite -= rc;
nwritten += rc;
@ -477,7 +338,7 @@ get_tag( Sockbuf *sb )
char *tagp;
unsigned int i;
if ( BerRead( sb, (char *) &xbyte, 1 ) != 1 )
if ( lber_pvt_sb_read( sb, (char *) &xbyte, 1 ) != 1 )
return( LBER_DEFAULT );
if ( (xbyte & LBER_BIG_TAG_MASK) != LBER_BIG_TAG_MASK )
@ -486,7 +347,7 @@ get_tag( Sockbuf *sb )
tagp = (char *) &tag;
tagp[0] = xbyte;
for ( i = 1; i < sizeof(long); i++ ) {
if ( BerRead( sb, (char *) &xbyte, 1 ) != 1 )
if ( lber_pvt_sb_read( sb, (char *) &xbyte, 1 ) != 1 )
return( LBER_DEFAULT );
tagp[i] = xbyte;
@ -553,7 +414,7 @@ ber_get_next( Sockbuf *sb, unsigned long *len, BerElement *ber )
*/
*len = netlen = 0;
if ( BerRead( sb, (char *) &lc, 1 ) != 1 ) {
if ( lber_pvt_sb_read( sb, (char *) &lc, 1 ) != 1 ) {
return( LBER_DEFAULT );
}
if ( lc & 0x80 ) {
@ -582,12 +443,12 @@ ber_get_next( Sockbuf *sb, unsigned long *len, BerElement *ber )
return( LBER_DEFAULT );
}
#endif /* DOS && !_WIN32 */
#ifdef DEADWOOD
if ( ( sb->sb_options & LBER_MAX_INCOMING_SIZE ) &&
*len > (unsigned long) sb->sb_max_incoming ) {
return( LBER_DEFAULT );
}
#endif
if ( (ber->ber_buf = (char *) malloc( (size_t)*len )) == NULL ) {
return( LBER_DEFAULT );
}
@ -598,7 +459,7 @@ ber_get_next( Sockbuf *sb, unsigned long *len, BerElement *ber )
toread = (unsigned long)ber->ber_end - (unsigned long)ber->ber_rwptr;
do {
if ( (rc = BerRead( sb, ber->ber_rwptr, (long)toread )) <= 0 ) {
if ( (rc = lber_pvt_sb_read( sb, ber->ber_rwptr, (long)toread )) <= 0 ) {
return( LBER_DEFAULT );
}
@ -619,34 +480,34 @@ ber_get_next( Sockbuf *sb, unsigned long *len, BerElement *ber )
return( ber->ber_tag );
}
Sockbuf *lber_sockbuf_alloc( void )
Sockbuf *lber_pvt_sb_alloc( void )
{
Sockbuf *sb = calloc(1, sizeof(Sockbuf));
sb->sb_debug = lber_int_debug;
lber_pvt_sb_init( sb );
return sb;
}
Sockbuf *lber_sockbuf_alloc_fd( int fd )
Sockbuf *lber_pvt_sb_alloc_fd( int fd )
{
Sockbuf *sb = lber_sockbuf_alloc();
sb->sb_sd = fd;
Sockbuf *sb = lber_pvt_sb_alloc();
lber_pvt_sb_set_desc( sb, fd );
lber_pvt_sb_set_io( sb, &lber_pvt_sb_io_tcp, NULL );
return sb;
}
void lber_sockbuf_free( Sockbuf *sb )
void lber_pvt_sb_free( Sockbuf *sb )
{
if(sb == NULL) return;
lber_pvt_sb_destroy( sb );
free(sb);
}
int lber_sockbuf_get_option( Sockbuf *sb, int opt, void *outvalue )
int lber_pvt_sb_get_option( Sockbuf *sb, int opt, void *outvalue )
{
return LBER_OPT_ERROR;
}
int lber_sockbuf_set_option( Sockbuf *sb, int opt, void *invalue )
int lber_pvt_sb_set_option( Sockbuf *sb, int opt, void *invalue )
{
return LBER_OPT_ERROR;
}

View file

@ -50,28 +50,90 @@ struct berelement {
};
#define NULLBER ((BerElement *) 0)
struct sockbuf;
struct sockbuf_io {
int (*sbi_setup)( struct sockbuf * sb, void *arg );
int (*sbi_remove)( struct sockbuf *sb );
long (*sbi_read)( struct sockbuf *sb, void *buf, long len );
long (*sbi_write)( struct sockbuf *sb, void *buf, long 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
{
long buf_size;
long buf_ptr;
long buf_end;
char *buf_base;
};
typedef struct sockbuf_io Sockbuf_IO;
typedef struct sockbuf_sec Sockbuf_Sec;
typedef struct sockbuf_buf Sockbuf_Buf;
#define lber_pvt_sb_get_desc( sb ) ((sb)->sb_sd)
#define lber_pvt_sb_set_desc( sb, val ) ((sb)->sb_sd =(val))
#define lber_pvt_sb_in_use( sb ) ((sb)->sb_sd!=-1)
#ifdef USE_SASL
#define lber_pvt_sb_data_ready( sb ) \
(((sb)->sb_buf_ready) || ((sb)->sb_trans_ready) || ((sb)->sb_sec_ready))
#else
#define lber_pvt_sb_data_ready( sb ) \
(((sb)->sb_buf_ready) || ((sb)->sb_trans_ready))
#endif
struct sockbuf {
short sb_item_type; /* always LBER_ITEM_SOCKBUF */
short sb_options; /* to support copying ber elements */
int sb_debug;
int sb_fd;
int sb_debug:1;
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;
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
#ifndef MACOS
int sb_sd;
#else /* MACOS */
void *sb_sd;
#endif /* MACOS */
#ifdef DEADWOOD
long sb_max_incoming;
BerElement sb_ber;
int sb_naddr; /* > 0 implies using CLDAP (UDP) */
void *sb_useaddr; /* pointer to sockaddr to use next */
void *sb_fromaddr; /* pointer to message source sockaddr */
void **sb_addrs; /* actually an array of pointers to
sockaddrs */
#endif
Sockbuf_Buf sb_buf;
#ifdef LDAP_SASL
Sockbuf_Buf sb_sec_buf_in;
Sockbuf_Buf sb_sec_buf_out;
long sb_sec_prev_len;
#endif
};
#define READBUFSIZ 8192
struct seqorset {
@ -104,4 +166,25 @@ LDAP_F int lber_log_sos_dump LDAP_P((
int loglvl,
Seqorset *sos ));
/* sockbuf.c */
LDAP_F int lber_pvt_sb_init LDAP_P(( Sockbuf *sb ));
LDAP_F int lber_pvt_sb_destroy LDAP_P(( Sockbuf *sb ));
#ifdef USE_SASL
LDAP_F int lber_pvt_sb_set_sec LDAP_P(( Sockbuf *sb, Sockbuf_Sec *sec, void *arg ));
LDAP_F int lber_pvt_sb_clear_sec LDAP_P(( Sockbuf *sb ));
#endif
LDAP_F int lber_pvt_sb_set_io LDAP_P(( Sockbuf *sb, Sockbuf_IO *layer, void *arg ));
LDAP_F int lber_pvt_sb_clear_io LDAP_P(( Sockbuf *sb ));
LDAP_F int lber_pvt_sb_close LDAP_P((Sockbuf *sb ));
LDAP_F int lber_pvt_sb_set_nonblock LDAP_P(( Sockbuf *sb, int nb ));
LDAP_F int lber_pvt_sb_set_readahead LDAP_P(( Sockbuf *sb, int rh ));
LDAP_F long lber_pvt_sb_read LDAP_P(( Sockbuf *sb, void *buf, long len ));
LDAP_F long lber_pvt_sb_write LDAP_P(( Sockbuf *sb, void *buf, long len ));
LDAP_F int lber_pvt_sb_udp_set_dst LDAP_P((Sockbuf *sb, void *addr ));
LDAP_F void *lber_pvt_sb_udp_get_src LDAP_P((Sockbuf *sb ));
extern Sockbuf_IO lber_pvt_sb_io_tcp;
extern Sockbuf_IO lber_pvt_sb_io_udp;
#endif /* _LBER_INT_H */

916
libraries/liblber/sockbuf.c Normal file
View file

@ -0,0 +1,916 @@
/* sockbuf.c - i/o routines with support for adding i/o layers. */
/*
* Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#include "portable.h"
#include <stdio.h>
#include <stdlib.h>
#include <ac/ctype.h>
#include <ac/errno.h>
#include <ac/socket.h>
#include <ac/string.h>
#include <ac/unistd.h>
#ifdef HAVE_IO_H
#include <io.h>
#endif /* HAVE_IO_H */
#if defined( HAVE_SYS_FILIO_H )
#include <sys/filio.h>
#elif defined( HAVE_SYS_IOCTL_H )
#include <sys/ioctl.h>
#endif
#include "lber-int.h"
#ifdef LDAP_DEBUG
#include <assert.h>
#else
#define assert( cond )
#endif
#define MAX_BUF_SIZE 65535
#define MIN_BUF_SIZE 4096
#define sockbuf_io_write( sb, buf, len ) \
((sb)->sb_io->sbi_write( (sb), (buf), (len) ))
#define sockbuf_io_read( sb, buf, len ) \
((sb)->sb_io->sbi_read( (sb), (buf), (len) ))
static long have_no_read( Sockbuf *sb, void *buf, long len );
static long have_no_write( Sockbuf *sb, void *buf, long len );
static int have_no_close( Sockbuf *sb );
static Sockbuf_IO lber_pvt_sb_IO_None=
{
NULL, /* sbi_setup */
NULL, /* sbi_release */
have_no_read, /* sbi_read */
have_no_write, /* sbi_write */
have_no_close /* sbi_close */
};
static void
update_status( Sockbuf *sb )
{
sb->sb_buf_ready = (sb->sb_buf.buf_ptr < sb->sb_buf.buf_end);
#ifdef USE_SASL
sb->sb_sec_ready = ((sb->sb_sec_buf_in.buf_end!=0) &&
(sb->sb_sec_buf_in.buf_ptr >=
sb->sb_sec_buf_in.buf_end));
#endif
}
#ifdef LDAP_DEBUG
static int
status_is_ok( Sockbuf *sb )
{
int obr;
int osr;
obr = sb->sb_buf_ready;
#ifdef USE_SASL
osr = sb->sb_sec_ready;
#endif
update_status(sb);
if (obr!=sb->sb_buf_ready)
return 0;
#ifdef USE_SASL
if (osr!=sb->sb_sec_ready)
return 0;
#endif
return 1;
}
#endif
#ifdef USE_SASL
static long
packet_length( char *buf )
{
long size;
size = (((unsigned long)buf[0])<<24)|
(((unsigned long)buf[1])<<16)|
(((unsigned long)buf[2])<<8)|
(((unsigned long)buf[3]));
if ((size<0) || (size>MAX_BUF_SIZE)) {
/* somebody is trying to mess me up. */
lber_log_printf( LDAP_DEBUG_SASL, sb->sb_debug,
"SASL: received packet length of %d bytes\n",
size );
size = 16; /* this should lead to an error. */
}
return size + 4; /* include the size !!! */
}
#endif
static int
grow_buffer( Sockbuf_Buf * buf, long minsize )
{
/* round to nearest 2k */
if (minsize < MIN_BUF_SIZE) {
minsize = MIN_BUF_SIZE;
} else {
minsize=((minsize-1)|2047)+1;
if (minsize > MAX_BUF_SIZE) {
/* this could mean that somebody is trying to crash us. */
return -1;
}
}
if (buf->buf_size<minsize) {
if ((buf->buf_base==NULL) || ((buf->buf_end==0) && (buf->buf_ptr==0))) {
/* empty buffer */
if (buf->buf_base!=NULL)
free( buf->buf_base );
assert( buf->buf_ptr==0 );
assert( buf->buf_end==0 );
buf->buf_base = malloc( minsize );
if (buf->buf_base==NULL)
return -1;
} else {
char *nb;
nb = realloc( buf->buf_base, minsize );
if (nb==NULL)
return -1;
buf->buf_base = nb;
}
buf->buf_size = minsize;
}
return 0;
}
#ifdef USE_SASL
static long
sockbuf_sec_release( Sockbuf *sb, char *buf, long len )
{
/* when this is called:
* sb->sb_sec_buf_in.buf_base points to a packet.
* sb->sb_sec_buf_in.buf_ptr contains the total bytes read.
* sb->sb_sec_end.buf_end contains the packet length.
*
* sb->sb_buf.buf_ptr == sb->sb_buf.buf_end == 0;
*/
long rlen;
long total;
char *ptr;
char *end;
long size;
assert( sb->sb_sec );
assert( sb->sb_sec->sbs_release );
assert( sb->sb_sec_buf_in.sb_ptr >= sb->sb_sec_buf_in.sb_end );
assert( sb->sb_buf.sb_ptr == 0 );
assert( sb->sb_buf.sb_end == 0 );
assert( status_is_ok(sb) );
total = 0;
ptr = sb->sb_sec_buf_in.buf_base;
end = ptr+ sb->sb_sec_buf_in.buf_ptr;
size = sb->sb_sec_buf_in.buf_end;
sb->sb_sec_ready = 1;
for(;(ptr+size<=end);) {
for(;;) {
rlen = sb->sb_sec->sbs_release( sb, ptr, size,
buf, len,
sb->sb_buf.buf_base,
sb->sb_buf.buf_size );
if (rlen==0) {
/* this means a security violation. */
return total; /* total ? total : 0 */
}
if (rlen<0) {
/* this means that the buffer isn't big enough. */
if (grow_buffer( &(sb->sb_buf), -rlen )<0)
/* memory violation. */
return total; /* total ? total : 0 */
continue;
}
/* if (rlen>0) */
break;
}
total+=rlen;
/* move to the next packet... */
ptr+=size;
if (ptr+4<=end)
size = packet_length( ptr );
/* size is always at least 4, so the loop condition is always OK !!*/
assert( size>=4 );
if (rlen<len) {
len-=rlen;
buf+=rlen;
} else {
sb->sb_buf_ready = (sb->sb_buf.buf_end = rlen - len) ? 1 : 0;
break;
}
}
if (ptr+size>end)
sb->sb_sec_ready = 0;
/* clean up the mess. */
if (ptr<end) {
/* copy back to beginning of buffer. */
SAFEMEMCPY( sb->sb_sec_buf_in.buf_base, ptr, end-ptr );
sb->sb_sec_buf_in.buf_ptr = 0;
sb->sb_sec_buf_in.buf_end -= (ptr - sb->sb_sec_buf_in.buf_base);
}
assert( status_is_ok(sb) );
return total;
}
static long
sockbuf_sec_protect( Sockbuf *sb, char *buf, long len )
{
long ret;
long blen;
long total;
assert( sb->sb_sec_out.buf_end == 0 );
assert( sb->sb_sec_out.buf_ptr == 0 );
assert( sb->sb_sec );
assert( sb->sb_sec->sbs_protect );
assert( status_is_ok(sb) );
total = 0;
for(;(len);) {
for(;;) {
blen = len;
ret = sb->sb_sec->sbs_protect( sb, buf, &blen,
sb->sb_sec_out.buf_base+
sb->sb_sec_out.buf_end,
sb->sb_sec_out.buf_size -
sb->sb_sec_out.buf_end );
if (ret==0)
/* protection error ? */
return total;
if (ret<0) {
if (grow_buffer( &(sb->sb_sec_out),-ret-sb->sb_sec_out.buf_end )<0)
/* memory error */
return total;
continue;
}
/* else if (ret>0) */
break;
}
sb->sb_sec_out.buf_end += ret;
len -= blen;
total += blen;
}
assert( status_is_ok(sb) );
return total;
}
#endif
static long
sockbuf_copy_out( Sockbuf *sb, char **buf, long len )
{
long blen = (sb->sb_buf.buf_end - sb->sb_buf.buf_ptr );
assert( status_is_ok(sb) );
if (blen) {
long rlen = (blen<len) ? blen : len;
memcpy( *buf, sb->sb_buf.buf_base + sb->sb_buf.buf_ptr, rlen );
sb->sb_buf.buf_ptr+=rlen;
*buf+=rlen;
len -= rlen;
if (sb->sb_buf.buf_ptr >= sb->sb_buf.buf_end) {
sb->sb_buf.buf_ptr = sb->sb_buf.buf_end = 0;
sb->sb_buf_ready = 0;
} else {
sb->sb_buf_ready = 1;
}
}
assert( status_is_ok(sb) );
return len;
}
long
lber_pvt_sb_read( Sockbuf *sb, void *buf_arg, long len )
{
char *buf;
long ret;
assert( status_is_ok(sb) );
#if 0
/* breaks slapd :-) */
assert( lber_pvt_sb_in_use( sb ) );
#endif
buf = (char *) buf_arg;
len = sockbuf_copy_out( sb, &buf, len );
if (len==0) {
return (buf - (char *) buf_arg);
}
#ifdef USE_SASL
if (sb->sb_sec) {
int max;
assert( sb->sb_sec->sbs_release );
assert( sb->sb_sec_buf_in.buf_base );
if (sb->sb_read_ahead) {
max = sb->sb_sec_buf_in.buf_size - sb->sb_sec_buf_in.buf_ptr;
} else {
max = sb->sb_sec_buf_in.buf_end - sb->sb_sec_buf_in.buf_ptr;
if (max<=0) {
/* special situation. This means that we need to read the first
* four bytes for the packet length.
*/
max += 4;
}
}
for(;;) {
/* read from stream into sb_sec_buf_in */
ret = sockbuf_io_read( sb, sb->sb_sec_buf_in.buf_base +
sb->sb_sec_buf_in.buf_ptr, max );
if (ret<=0) {
/* read error. return */
goto do_return;
}
sb->sb_sec_buf_in.buf_ptr += ret;
if (sb->sb_sec_buf_in.buf_ptr < sb->sb_sec_buf_in.buf_end) {
/* did not finish a packet. give up. */
goto do_return;
}
if (sb->sb_sec_buf_in.buf_end == 0) {
/* Were trying to read the first four bytes... */
if (sb->sb_sec_buf_in.buf_ptr < 4) {
/* did not read enough for packet length. give up. */
goto do_return;
}
/* calculate the packet length. */
sb->sb_sec_buf_in.buf_end =
packet_length(sb->sb_sec_buf_in.buf_base );
if ((sb->sb_sec_buf_in.buf_end > sb->sb_sec_buf_in.buf_size) &&
(grow_buffer( &(sb->sb_sec_buf_in), sb->sb_sec_buf_in.buf_end)<0)) {
/* buffer has to be to big. exit with error. */
ret = -1;
goto do_return;
}
if (sb->sb_sec_buf_in.buf_ptr >= sb_sec_buf_in.buf_end) {
/* finished packet. decode it. */
goto decode_packet;
}
/* did not finish packet yet. try again ? */
if (sb->sb_read_ahead) {
/* we were trying to read the max anyway. forget it */
goto do_return;
}
}
decode_packet:
/* we read enough for at least 1 packet */
ret = sockbuf_sec_release( sb, buf, len );
if (ret<=0) {
/* something went wrong... */
goto do_return;
}
buf+=ret;
len-=ret;
/* we are finished !!! */
if ((len==0) || (ret!=max))
goto do_return;
}
} else {
#endif
if (sb->sb_read_ahead) {
long max;
max = sb->sb_buf.buf_size - sb->sb_buf.buf_end;
if (max>len) {
ret = sockbuf_io_read( sb,
sb->sb_buf.buf_base +
sb->sb_buf.buf_end,
max );
if (ret<=0) {
/* some error occured */
goto do_return;
}
sb->sb_buf.buf_end += ret;
/* move out the data... */
len = sockbuf_copy_out( sb, &buf, len );
goto do_return;
}
}
/* no read_ahead, just try to put the data in the buf. */
ret = sockbuf_io_read( sb, buf, len );
if (ret>0) {
buf+=ret;
len-=ret;
}
/* we might as well return, since there is nothing to do... */
#ifdef USE_SASL
}
#endif
do_return:
assert( status_is_ok(sb) );
if ((ret<=0) && (buf==buf_arg)) {
/* there was an error. */
return ret;
}
return (buf - ((char *) buf_arg));
}
#ifdef USE_SASL
long sockbuf_do_write( Sockbuf *sb )
{
long to_go;
to_go = sb->sb_sec_out.buf_end - sb->sb_sec_out.buf_ptr;
assert( to_go > 0 );
/* there is something left of the last time... */
ret = sockbuf_io_write( sb, sb->sb_sec_out.buf_base+
sb->sb_sec_out.buf_ptr, to_go );
if (ret<=0) /* error */
return ret;
sb->sb_sec_out.buf_ptr += ret;
if (ret<to_go) /* not enough data, so pretend no data was sent. */
return -1;
return ret;
}
#endif
long lber_pvt_sb_write( Sockbuf *sb, void *buf, long len_arg )
{
long ret;
long len = len_arg;
assert( status_is_ok(sb) );
#if 0
/* unfortunately breaks slapd */
assert( lber_pvt_sb_in_use( sb ) );
#endif
#ifdef USE_SASL
if (sb->sb_sec) {
assert( sb->sb_sec_prev_len <= len );
if (sb->sb_sec_prev_len) {
ret = sockbuf_do_write( sb );
if (ret<=0)
return ret;
/* finished. */
len -= sb->sb_sec_prev_len;
sb->sb_sec_prev_len = 0;
sb->sb_sec_out.buf_end = sb->sb_sec_out.buf_ptr = 0;
}
/* now protect the next packet. */
ret = sockbuf_sec_protect( sb, buf, len );
if (ret<=0)
return ret;
ret = sockbuf_do_write( sb );
if (ret<=0) {
sb->sb_sec_prev_len = len;
return ret;
}
return len_arg;
} else {
#endif
return sockbuf_io_write( sb, buf, len );
#ifdef USE_SASL
}
#endif
}
int lber_pvt_sb_close( Sockbuf *sb )
{
int ret;
assert( sb->sb_io );
assert( sb->sb_io->sbi_close );
assert( status_is_ok(sb) );
assert( lber_pvt_sb_in_use( sb ) );
ret = sb->sb_io->sbi_close( sb );
lber_pvt_sb_set_desc( sb, -1 );
return ret;
}
int lber_pvt_sb_set_readahead( Sockbuf *sb, int rh )
{
assert( status_is_ok(sb) );
sb->sb_read_ahead = (rh!=0);
return 0;
}
int lber_pvt_sb_set_nonblock( Sockbuf *sb, int nb )
{
assert( status_is_ok(sb) );
if (nb) {
sb->sb_non_block = 1;
#if 0
sb->sb_read_ahead = 1;
#endif
} else {
sb->sb_non_block = 0;
#if 0
sb->sb_read_ahead = 0;
#endif
}
if (lber_pvt_sb_in_use(sb)) {
int status = (nb!=0);
if (ioctl( lber_pvt_sb_get_desc(sb), FIONBIO, (caddr_t)&status ) == -1 ) {
return -1;
}
}
return 0;
}
#define sockbuf_buf_init( bb ) \
(bb)->buf_base=NULL;\
(bb)->buf_ptr = 0;\
(bb)->buf_end = 0;\
(bb)->buf_size = 0;
static int
sockbuf_buf_destroy( Sockbuf_Buf *buf )
{
if (buf->buf_base)
free( buf->buf_base );
sockbuf_buf_init( buf );
return 0;
}
int lber_pvt_sb_init( Sockbuf *sb )
{
sb->sb_item_type=LBER_ITEM_SOCKBUF;
sb->sb_options = 0;
sb->sb_debug = 0;
sb->sb_trans_ready = 0;
sb->sb_buf_ready = 0;
#ifdef USE_SASL
sb->sb_sec_ready = 0;
#endif
sb->sb_read_ahead = 0;
sb->sb_non_block = 0;
sb->sb_fd = -1;
sb->sb_iodata = NULL;
sb->sb_io = &lber_pvt_sb_IO_None;
sb->sb_sd = -1;
#ifdef DEADWOOD
sb->sb_max_incoming = 0;
#endif
sockbuf_buf_init( &(sb->sb_buf) );
#ifdef USE_SASL
sockbuf_buf_init( &(sb->sb_sec_buf_in) );
sockbuf_buf_init( &(sb->sb_sec_buf_out) );
sb->sb_sdata = NULL;
sb->sb_sec = NULL;
sb->sb_sec_prev_len = 0;
#endif
return 0;
}
int lber_pvt_sb_destroy( Sockbuf *sb )
{
#ifdef USE_SASL
lber_pvt_sb_clear_sec(sb);
sockbuf_buf_destroy( &(sb->sb_sec_buf_in) );
sockbuf_buf_destroy( &(sb->sb_sec_buf_out) );
#endif
lber_pvt_sb_clear_io(sb);
sockbuf_buf_destroy( &(sb->sb_buf) );
return lber_pvt_sb_init( sb );
}
#ifdef USE_SASL
int lber_pvt_sb_set_sec( Sockbuf *sb, Sockbuf_Sec * sec, void *arg )
{
int len;
if ((sb->sb_sec) || (sec==NULL))
return -1;
sb->sb_sec = sec;
if ((sec->sbs_setup) && (sec->sbs_setup( sb, arg)<0)) {
return -1;
}
len = sb->sb_buf.buf_end - sb->sb_buf.buf_ptr;
if (len>0) {
/* move this to the security layer. */
if (grow_buffer( &(sb->sb_sec_buf_in), len )<0)
return -1;
memcpy( sb->sb_sec_buf_in.buf_base,
sb->sb_buf.buf_base + sb->sb_buf.buf_ptr, len );
sb->sb_sec_buf_in.buf_ptr = len;
sb->sb_sec_buf_in.buf_end = (len>4) ? packet_length( sb->sb_sec_buf_in ) : 0;
sb->sb_buf.buf_ptr = sb->sb_buf.buf_end = 0;
}
update_status();
return 0;
}
int lber_pvt_sb_clear_sec( Sockbuf *sb )
{
if (sb->sb_buf.buf_ptr!=0)
return -1;
if (sb->sb_sec==NULL)
return -1;
if ((sb->sb_sec->sbs_remove) && (sb->sb_sec->sbs_remove(sb)<0))
return -1;
sb->sb_sec = NULL;
if (sb->sb_sec_buf_in.buf_ptr!=0) {
if (grow_buffer( &(sb->sb_buf),
sb->sb_buf.buf_end + sb->sb_sec_buf_in.buf_ptr)<0)
return -1;
memcpy( sb->sb_buf.buf_base + sb->sb_buf.buf_end,
sb->sb_sec_buf_in.buf_base, sb->sb_sec_buf_in.buf_ptr );
sb->sb_buf.buf_end += sb->sb_sec_buf_in.buf_ptr;
sb->sb_buf_ready = 1;
}
sockbuf_buf_destroy( &(sb->sb_sec_buf_in) );
assert( sb->sb_sec_buf.buf_end==0 );
sockbuf_buf_destroy( &(sb->sb_sec_buf_out) );
sb->sb_sec_ready = 0;
return 0;
}
#endif
int lber_pvt_sb_set_io( Sockbuf *sb, Sockbuf_IO *trans, void *arg )
{
assert( sb->sb_io == &lber_pvt_sb_IO_None );
if (trans==NULL)
return -1;
sb->sb_io = trans;
if ((trans->sbi_setup) && (trans->sbi_setup( sb, arg)<0))
return -1;
return 0;
}
int lber_pvt_sb_clear_io( Sockbuf *sb )
{
if (sb->sb_io==&lber_pvt_sb_IO_None)
return -1;
if ((sb->sb_io->sbi_remove) && (sb->sb_io->sbi_remove( sb )<0))
return -1;
sb->sb_io = &lber_pvt_sb_IO_None;
sb->sb_trans_ready = 0;
return 0;
}
/*
* Support for TCP
*/
static long
stream_read( Sockbuf *sb, void *buf, long len )
{
#if defined(MACOS)
/*
* MacTCP/OpenTransport
*/
return tcpread( lber_pvt_sb_get_desc(sb), 0, (unsigned char *)buf,
len, NULL );
#elif (defined(DOS) && (defined(PCNFS) || defined( WINSOCK))) \
|| defined( _WIN32)
/*
* PCNFS (under DOS)
*/
/*
* Windows Socket API (under DOS/Windows 3.x)
*/
/*
* 32-bit Windows Socket API (under Windows NT or Windows 95)
*/
return recv( lber_pvt_sb_get_desc(sb), buf, len, 0 );
#elif (defined(DOS) && defined( NCSA ))
/*
* NCSA Telnet TCP/IP stack (under DOS)
*/
return nread( lber_pvt_sb_get_desc(sb), buf, len );
#else
return read( lber_pvt_sb_get_desc(sb), buf, len );
#endif
}
static long
stream_write( Sockbuf *sb, void *buf, long len )
{
#if defined(MACOS)
/*
* MacTCP/OpenTransport
*/
#define MAX_WRITE 65535
return tcpwrite( lber_pvt_sb_get_desc(sb),
(unsigned char *)(buf),
(len<MAX_WRITE)? len : MAX_WRITE );
#elif (defined(DOS) && (defined(PCNFS) || defined( WINSOCK))) \
|| defined( _WIN32)
/*
* PCNFS (under DOS)
*/
/*
* Windows Socket API (under DOS/Windows 3.x)
*/
/*
* 32-bit Windows Socket API (under Windows NT or Windows 95)
*/
return send( lber_pvt_sb_get_desc(sb), buf, len, 0 );
#elif defined(NCSA)
return netwrite( lber_pvt_sb_get_desc(sb), buf, len );
#elif defined(VMS)
/*
* VMS -- each write must be 64K or smaller
*/
#define MAX_WRITE 65535
return write( lber_pvt_sb_get_desc(sb), buf,
(len<MAX_WRITE)? len : MAX_WRITE);
#else
return write( lber_pvt_sb_get_desc(sb), buf, len );
#endif
}
static int
stream_close( Sockbuf *sb )
{
tcp_close( lber_pvt_sb_get_desc( sb ) );
return 0;
}
Sockbuf_IO lber_pvt_sb_io_tcp=
{
NULL, /* sbi_setup */
NULL, /* sbi_release */
stream_read, /* sbi_read */
stream_write, /* sbi_write */
stream_close, /* sbi_close */
};
/*
* Support for UDP (CLDAP)
*/
struct dgram_data
{
struct sockaddr dst;
struct sockaddr src;
};
static int
dgram_setup( Sockbuf *sb, void *arg )
{
sb->sb_iodata = malloc( sizeof( struct dgram_data ) );
if (sb->sb_iodata==NULL)
return -1;
sb->sb_read_ahead = 1; /* important since udp is packet based. */
return 0;
}
static int
dgram_release( Sockbuf *sb )
{
free( sb->sb_iodata );
return 0;
}
static long
dgram_read( Sockbuf *sb, void *buf, long len )
{
#ifdef LDAP_CONNECTIONLESS
long rc;
int addrlen;
struct dgram_data *dd;
dd = (struct dgram_data *)(sb->sb_iodata);
# if !defined( MACOS) && !defined(DOS) && !defined( _WIN32)
addrlen = sizeof( struct sockaddr );
rc=recvfrom( lber_pvt_sb_get_desc(sb), buf, len, 0, &(dd->src), &addrlen );
# else
UDP not supported
# endif
if ( sb->sb_debug ) {
lber_log_printf( LDAP_DEBUG_ANY, sb->sb_debug,
"dgram_read udp_read %d bytes\n",
rc );
if ( rc > 0 )
lber_log_bprint( LDAP_DEBUG_PACKETS, sb->sb_debug,
buf, rc );
}
return rc;
# else /* LDAP_CONNECTIONLESS */
return -1;
# endif /* LDAP_CONNECTIONLESS */
}
static long
dgram_write( Sockbuf *sb, void *buf, long len )
{
#ifdef LDAP_CONNECTIONLESS
int rc;
struct dgram_data *dd;
dd = (struct dgram_data *)(sb->sb_iodata);
# if !defined( MACOS) && !defined(DOS) && !defined( _WIN32)
rc=sendto( lber_pvt_sb_get_desc(sb), buf, len, 0, &(dd->dst),
sizeof( struct sockaddr ) );
# else
UDP not supported
# endif
if ( rc <= 0 )
return( -1 );
/* fake error if write was not atomic */
if (rc < len) {
# ifdef EMSGSIZE
errno = EMSGSIZE;
# endif
return( -1 );
}
return rc;
#else
return -1;
#endif
}
static int
dgram_close( Sockbuf *sb )
{
tcp_close( lber_pvt_sb_get_desc(sb) );
return 0;
}
Sockbuf_IO lber_pvt_sb_io_udp=
{
dgram_setup, /* sbi_setup */
dgram_release, /* sbi_release */
dgram_read, /* sbi_read */
dgram_write, /* sbi_write */
dgram_close, /* sbi_close */
};
int lber_pvt_sb_udp_set_dst(Sockbuf *sb, void *addr )
{
struct dgram_data *dd;
assert( sb->sb_io == &lber_pvt_sb_io_udp );
dd = (struct dgram_data *) (sb->sb_iodata);
memcpy( &(dd->dst), addr, sizeof( struct sockaddr ) );
return 0;
}
void *lber_pvt_sb_udp_get_src( Sockbuf *sb )
{
struct dgram_data *dd;
assert( sb->sb_io == &lber_pvt_sb_io_udp );
dd = (struct dgram_data *) (sb->sb_iodata);
return &(dd->src);
}
/*
* debug routines.
*
* BUGS:
* These routines should really call abort, but at the moment that would
* break the servers.
*/
static long
have_no_read( Sockbuf *sb, void *buf, long len )
{
lber_log_printf( LDAP_DEBUG_ANY, lber_int_debug,
"warning: reading from uninitialized sockbuf\n");
errno = EBADF;
return -1;
}
static long
have_no_write( Sockbuf *sb, void *buf, long len )
{
lber_log_printf( LDAP_DEBUG_ANY, lber_int_debug,
"warning: writing to uninitialized sockbuf\n");
errno = EBADF;
return -1;
}
static int
have_no_close( Sockbuf *sb )
{
assert( 0 );
return -1;
}

View file

@ -98,7 +98,7 @@ do_abandon( LDAP *ld, int origid, int msgid )
ld->ld_errno = LDAP_NO_MEMORY;
} else {
#ifdef LDAP_CONNECTIONLESS
if ( ld->ld_sb.sb_naddr > 0 ) {
if ( ld->ld_cldapnaddr > 0 ) {
err = ber_printf( ber, "{isti}",
++ld->ld_msgid, ld->ld_cldapdn,
LDAP_REQ_ABANDON, msgid );

View file

@ -84,19 +84,19 @@ cldap_open( char *host, int port )
close( s );
return( NULL );
}
if (( ld = ldap_init( host, port )) == NULL ) {
close( s );
return( NULL );
}
if ( (ld->ld_sb.sb_fromaddr = (void *) calloc( 1,
sizeof( struct sockaddr ))) == NULL ) {
ld->ld_cldapnaddr = 0;
ld->ld_cldapaddrs = NULL;
ldap_ld_free(ld, 1);
return( NULL );
}
ld->ld_sb.sb_sd = s;
ld->ld_sb.sb_naddr = 0;
if (lber_pvt_sb_set_io( &(ld->ld_sb), &lber_pvt_sb_io_udp, NULL )<0) {
ldap_ld_free(ld, 1 );
return NULL;
}
ld->ld_version = LDAP_VERSION;
sock.sin_family = AF_INET;
@ -155,7 +155,7 @@ cldap_open( char *host, int port )
}
}
if ( ld->ld_sb.sb_addrs == NULL
if ( ld->ld_cldapaddrs == NULL
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
|| ( ld->ld_defconn = ldap_new_connection( ld, NULL, 1,0,0 )) == NULL
#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */
@ -164,15 +164,16 @@ cldap_open( char *host, int port )
DO_RETURN( NULL );
}
ld->ld_sb.sb_useaddr = ld->ld_sb.sb_addrs[ 0 ];
lber_pvt_sb_udp_set_dst( &ld->ld_sb, ld->ld_cldapaddrs[0] );
cldap_setretryinfo( ld, 0, 0 );
#ifdef LDAP_DEBUG
putchar( '\n' );
for ( i = 0; i < ld->ld_sb.sb_naddr; ++i ) {
for ( i = 0; i < ld->ld_cldapnaddr; ++i ) {
Debug( LDAP_DEBUG_TRACE, "end of cldap_open address %d is %s\n",
i, inet_ntoa( ((struct sockaddr_in *)
ld->ld_sb.sb_addrs[ i ])->sin_addr ), 0 );
ld->ld_cldapaddrs[ i ])->sin_addr ), 0 );
}
#endif
@ -217,11 +218,13 @@ cldap_search_s( LDAP *ld, char *base, int scope, char *filter, char **attrs,
if ( cri.cri_try != 0 ) {
--ld->ld_msgid; /* use same id as before */
}
ld->ld_sb.sb_useaddr = ld->ld_sb.sb_addrs[ cri.cri_useaddr ];
lber_pvt_sb_udp_set_dst( &(ld->ld_sb),
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 *)
ld->ld_sb.sb_useaddr)->sin_addr ), 0 );
ld->ld_cldapaddrs[ cri.cri_useaddr ])->sin_addr), 0 );
if ( (msgid = ldap_search( ld, base, scope, filter, attrs,
attrsonly )) == -1 ) {
@ -253,12 +256,12 @@ add_addr( LDAP *ld, struct sockaddr *sap )
ld->ld_errno = LDAP_NO_MEMORY;
return( -1 );
}
if ( ld->ld_sb.sb_naddr == 0 ) {
if ( ld->ld_cldapnaddr == 0 ) {
addrs = (struct sockaddr **)malloc( sizeof(struct sockaddr *));
} else {
addrs = (struct sockaddr **)realloc( ld->ld_sb.sb_addrs,
( ld->ld_sb.sb_naddr + 1 ) * sizeof(struct sockaddr *));
addrs = (struct sockaddr **)realloc( ld->ld_cldapaddrs,
( ld->ld_cldapnaddr + 1 ) * sizeof(struct sockaddr *));
}
if ( addrs == NULL ) {
@ -268,8 +271,8 @@ add_addr( LDAP *ld, struct sockaddr *sap )
}
SAFEMEMCPY( (char *)newsap, (char *)sap, sizeof( struct sockaddr ));
addrs[ ld->ld_sb.sb_naddr++ ] = newsap;
ld->ld_sb.sb_addrs = (void **)addrs;
addrs[ ld->ld_cldapnaddr++ ] = newsap;
ld->ld_cldapaddrs = (void **)addrs;
return( 0 );
}
@ -287,14 +290,14 @@ cldap_result( LDAP *ld, int msgid, LDAPMessage **res,
fromaddr = -1;
if ( crip->cri_try == 0 ) {
crip->cri_maxtries = ld->ld_cldaptries * sb->sb_naddr;
crip->cri_maxtries = ld->ld_cldaptries * ld->ld_cldapnaddr;
crip->cri_timeout = ld->ld_cldaptimeout;
crip->cri_useaddr = 0;
Debug( LDAP_DEBUG_TRACE, "cldap_result tries %d timeout %d\n",
ld->ld_cldaptries, ld->ld_cldaptimeout, 0 );
}
if ((tv.tv_sec = crip->cri_timeout / sb->sb_naddr) < 1 ) {
if ((tv.tv_sec = crip->cri_timeout / ld->ld_cldapnaddr) < 1 ) {
tv.tv_sec = 1;
}
tv.tv_usec = 0;
@ -319,7 +322,7 @@ cldap_result( LDAP *ld, int msgid, LDAPMessage **res,
ret = LDAP_TIMEOUT;
--crip->cri_try;
} else {
if ( ++crip->cri_useaddr >= sb->sb_naddr ) {
if ( ++crip->cri_useaddr >= ld->ld_cldapnaddr ) {
/*
* new round: reset address to first one and
* double the timeout
@ -350,14 +353,17 @@ cldap_result( LDAP *ld, int msgid, LDAPMessage **res,
msgid, id, 0 );
ret = -1; /* ignore and keep looking */
} else {
struct sockaddr_in * src;
/*
* got a result: determine which server it came from
* decode into ldap message chain
*/
for ( fromaddr = 0; fromaddr < sb->sb_naddr; ++fromaddr ) {
src = (struct sockaddr_in *) lber_pvt_sb_udp_get_src( sb );
for ( fromaddr = 0; fromaddr < ld->ld_cldapnaddr; ++fromaddr ) {
if ( memcmp( &((struct sockaddr_in *)
sb->sb_addrs[ fromaddr ])->sin_addr,
&((struct sockaddr_in *)sb->sb_fromaddr)->sin_addr,
ld->ld_cldapaddrs[ fromaddr ])->sin_addr,
&(src->sin_addr),
sizeof( struct in_addr )) == 0 ) {
break;
}
@ -380,18 +386,19 @@ cldap_result( LDAP *ld, int msgid, LDAPMessage **res,
*/
if ( ret != -1 ) {
i = crip->cri_try;
if ( i >= sb->sb_naddr ) {
i = sb->sb_naddr - 1;
if ( i >= ld->ld_cldapnaddr ) {
i = ld->ld_cldapnaddr - 1;
}
for ( ; i >= 0; --i ) {
if ( i == fromaddr ) {
continue;
}
sb->sb_useaddr = sb->sb_addrs[ i ];
lber_pvt_sb_udp_set_dst( sb, ld->ld_cldapaddrs[i] );
Debug( LDAP_DEBUG_TRACE, "cldap_result abandoning id %d (to %s)\n",
msgid, inet_ntoa( ((struct sockaddr_in *)
sb->sb_useaddr)->sin_addr ), 0 );
ld->ld_cldapaddrs[i])->sin_addr ), 0 );
(void) ldap_abandon( ld, msgid );
}
}

View file

@ -173,6 +173,11 @@ typedef struct ldapcache {
} LDAPCache;
#define NULLLDCACHE ((LDAPCache *)NULL)
/*
* handy macro for checking if handle is connectionless
*/
#define LDAP_IS_CLDAP(ld) ((ld)->ld_cldapnaddr>0)
/*
* structure representing an ldap connection
@ -219,8 +224,11 @@ struct ldap {
int *ld_abandoned; /* array of abandoned requests */
char ld_attrbuffer[LDAP_MAX_ATTR_LEN];
LDAPCache *ld_cache; /* non-null if cache is initialized */
char *ld_cldapdn; /* DN used in connectionless search */
/* stuff used by connectionless searches. */
char *ld_cldapdn; /* DN used in connectionless search */
int ld_cldapnaddr; /* number of addresses */
void **ld_cldapaddrs;/* addresses to send request to */
/* do not mess with the rest though */
BERTranslateProc ld_lber_encode_translate_proc;
BERTranslateProc ld_lber_decode_translate_proc;

View file

@ -24,6 +24,7 @@
#include "ldap-int.h"
/*
* ldap_open - initialize and connect to an ldap server. A magic cookie to
* be used for future communication is returned on success, NULL on failure.
@ -143,7 +144,7 @@ ldap_init( char *defhost, int defport )
WSACleanup( );
return( NULL );
}
/* copy the global options */
memcpy(&ld->ld_options, &openldap_ldap_global_options,
sizeof(ld->ld_options));
@ -198,7 +199,8 @@ ldap_init( char *defhost, int defport )
/* we'll assume we're talking version 2 for now */
ld->ld_version = LDAP_VERSION2;
ld->ld_sb.sb_sd = -1;
lber_pvt_sb_init( &(ld->ld_sb) );
return( ld );
}
@ -255,6 +257,8 @@ open_ldap_connection( LDAP *ld, Sockbuf *sb, char *host, int defport,
if ( rc == -1 ) {
return( rc );
}
lber_pvt_sb_set_io( sb, &lber_pvt_sb_io_tcp, NULL );
if ( krbinstancep != NULL ) {
#ifdef HAVE_KERBEROS

View file

@ -111,7 +111,7 @@ ldap_get_option(
break;
}
* (int *) outvalue = ld->ld_sb.sb_sd;
* (int *) outvalue = lber_pvt_sb_get_desc( &(ld->ld_sb) );
return 0;
case LDAP_OPT_DEREF:

View file

@ -140,9 +140,10 @@ ldap_connect_to_host( Sockbuf *sb, char *host, unsigned long address,
}
}
sb->sb_sd = s;
lber_pvt_sb_set_desc( sb, s );
if ( connected ) {
#ifdef notyet
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
status = 0;
@ -158,8 +159,6 @@ ldap_connect_to_host( Sockbuf *sb, char *host, unsigned long address,
}
DO_RETURN( rc );
}
#undef DO_RETURN
@ -168,11 +167,11 @@ ldap_connect_to_host( Sockbuf *sb, char *host, unsigned long address,
void
ldap_close_connection( Sockbuf *sb )
{
tcp_close( sb->sb_sd );
lber_pvt_sb_close( sb );
}
#ifdef HAVE_KERBEROS
#if defined( HAVE_KERBEROS ) || defined( HAVE_TLS )
char *
ldap_host_connected_to( Sockbuf *sb )
{
@ -189,7 +188,8 @@ ldap_host_connected_to( Sockbuf *sb )
(void)memset( (char *)&sin, 0, sizeof( struct sockaddr_in ));
len = sizeof( sin );
if ( getpeername( sb->sb_sd, (struct sockaddr *)&sin, &len ) == -1 ) {
if ( getpeername( lber_pvt_sb_get_desc(sb), (struct sockaddr *)&sin, &len ) == -1 ) {
return( NULL );
}
@ -204,7 +204,8 @@ ldap_host_connected_to( Sockbuf *sb )
&hp,&local_h_errno ) ==0 ) && (hp != NULL) )
{
if ( hp->h_name != NULL ) {
DO_RETURN( strdup( hp->h_name ));
char *host = strdup( hp->h_name );
DO_RETURN( host );
}
}
@ -212,7 +213,7 @@ ldap_host_connected_to( Sockbuf *sb )
}
#undef DO_RETURN
#endif /* HAVE_KERBEROS */
#endif /* HAVE_KERBEROS || HAVE_TLS */
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
@ -231,8 +232,8 @@ ldap_mark_select_write( LDAP *ld, Sockbuf *sb )
struct selectinfo *sip;
sip = (struct selectinfo *)ld->ld_selectinfo;
if ( !FD_ISSET( sb->sb_sd, &sip->si_writefds )) {
if ( !FD_ISSET( lber_pvt_sb_get_desc(sb), &sip->si_writefds )) {
FD_SET( (u_int) sb->sb_sd, &sip->si_writefds );
}
}
@ -245,7 +246,7 @@ ldap_mark_select_read( LDAP *ld, Sockbuf *sb )
sip = (struct selectinfo *)ld->ld_selectinfo;
if ( !FD_ISSET( sb->sb_sd, &sip->si_readfds )) {
if ( !FD_ISSET( lber_pvt_sb_get_desc(sb), &sip->si_readfds )) {
FD_SET( (u_int) sb->sb_sd, &sip->si_readfds );
}
}
@ -258,8 +259,8 @@ ldap_mark_select_clear( LDAP *ld, Sockbuf *sb )
sip = (struct selectinfo *)ld->ld_selectinfo;
FD_CLR( (u_int) sb->sb_sd, &sip->si_writefds );
FD_CLR( (u_int) sb->sb_sd, &sip->si_readfds );
FD_CLR( (u_int) lber_pvt_sb_get_desc(sb), &sip->si_writefds );
FD_CLR( (u_int) lber_pvt_sb_get_desc(sb), &sip->si_readfds );
}
@ -270,7 +271,7 @@ ldap_is_write_ready( LDAP *ld, Sockbuf *sb )
sip = (struct selectinfo *)ld->ld_selectinfo;
return( FD_ISSET( sb->sb_sd, &sip->si_use_writefds ));
return( FD_ISSET( lber_pvt_sb_get_desc(sb), &sip->si_use_writefds ));
}
@ -281,7 +282,7 @@ ldap_is_read_ready( LDAP *ld, Sockbuf *sb )
sip = (struct selectinfo *)ld->ld_selectinfo;
return( FD_ISSET( sb->sb_sd, &sip->si_use_readfds ));
return( FD_ISSET( lber_pvt_sb_get_desc(sb), &sip->si_use_readfds ));
}

View file

@ -80,7 +80,7 @@ ldap_send_initial_request( LDAP *ld, unsigned long msgtype, char *dn,
Debug( LDAP_DEBUG_TRACE, "ldap_send_initial_request\n", 0, 0, 0 );
if ( ld->ld_sb.sb_sd == -1 ) {
if ( ! lber_pvt_sb_in_use(&ld->ld_sb ) ) {
/* not connected yet */
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
@ -296,8 +296,7 @@ ldap_new_connection( LDAP *ld, LDAPServer **srvlistp, int use_ldsb,
* XXX open connection synchronously for now
*/
if (( lc = (LDAPConn *)calloc( 1, sizeof( LDAPConn ))) == NULL ||
( !use_ldsb && ( sb = (Sockbuf *)calloc( 1, sizeof( Sockbuf )))
== NULL )) {
( !use_ldsb && ( (sb = lber_pvt_sb_alloc()) == NULL ))) {
if ( lc != NULL ) {
free( (char *)lc );
}
@ -321,7 +320,7 @@ ldap_new_connection( LDAP *ld, LDAPServer **srvlistp, int use_ldsb,
if ( srv == NULL ) {
if ( !use_ldsb ) {
free( (char *)lc->lconn_sb );
lber_pvt_sb_free( lc->lconn_sb );
}
free( (char *)lc );
ld->ld_errno = LDAP_SERVER_DOWN;
@ -444,9 +443,7 @@ ldap_free_connection( LDAP *ld, LDAPConn *lc, int force, int unbind )
ldap_send_unbind( ld, lc->lconn_sb );
}
ldap_close_connection( lc->lconn_sb );
if ( lc->lconn_sb->sb_ber.ber_buf != NULL ) {
free( lc->lconn_sb->sb_ber.ber_buf );
}
lber_pvt_sb_destroy( lc->lconn_sb );
}
prevlc = NULL;
for ( tmplc = ld->ld_conns; tmplc != NULL;
@ -466,7 +463,7 @@ ldap_free_connection( LDAP *ld, LDAPConn *lc, int force, int unbind )
free( lc->lconn_krbinstance );
}
if ( lc->lconn_sb != &ld->ld_sb ) {
free( (char *)lc->lconn_sb );
lber_pvt_sb_free( lc->lconn_sb );
}
free( lc );
Debug( LDAP_DEBUG_TRACE, "ldap_free_connection: actually freed\n",

View file

@ -166,7 +166,7 @@ wait4msg( LDAP *ld, int msgid, int all, struct timeval *timeout,
while ( rc == -2 ) {
#ifndef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
/* hack attack */
if ( ld->ld_sb.sb_ber.ber_ptr >= ld->ld_sb.sb_ber.ber_end ) {
if ( ! lber_pvt_sb_data_ready(&ld->ld_sb) ) {
rc = ldap_select1( ld, tvp );
if ( rc == 0 || ( rc == -1 && (
@ -192,8 +192,7 @@ wait4msg( LDAP *ld, int msgid, int all, struct timeval *timeout,
}
#endif /* LDAP_DEBUG */
for ( lc = ld->ld_conns; lc != NULL; lc = lc->lconn_next ) {
if ( lc->lconn_sb->sb_ber.ber_ptr <
lc->lconn_sb->sb_ber.ber_end ) {
if ( lber_pvt_sb_data_ready(lc->lconn_sb) ) {
rc = read1msg( ld, msgid, all, lc->lconn_sb,
lc, result );
break;
@ -610,7 +609,7 @@ ldap_select1( LDAP *ld, struct timeval *timeout )
}
FD_ZERO( &readfds );
FD_SET( ld->ld_sb.sb_sd, &readfds );
FD_SET( lber_pvt_sb_get_desc(&ld->ld_sb), &readfds );
return( select( tblsize, &readfds, 0, 0, timeout ) );
}
@ -732,7 +731,7 @@ cldap_getmsg( LDAP *ld, struct timeval *timeout, BerElement *ber )
int rc;
unsigned long tag, len;
if ( ld->ld_sb.sb_ber.ber_ptr >= ld->ld_sb.sb_ber.ber_end ) {
if ( ! lber_pvt_sb_data_ready(&ld->ld_sb) ) {
rc = ldap_select1( ld, timeout );
if ( rc == -1 || rc == 0 ) {
ld->ld_errno = (rc == -1 ? LDAP_SERVER_DOWN :

View file

@ -122,7 +122,7 @@ ldap_build_search_req( LDAP *ld, char *base, int scope, char *filter,
}
#ifdef LDAP_CONNECTIONLESS
if ( ld->ld_sb.sb_naddr > 0 ) {
if ( ld->ld_cldapnaddr > 0 ) {
err = ber_printf( ber, "{ist{seeiib", ++ld->ld_msgid,
ld->ld_cldapdn, LDAP_REQ_SEARCH, base, scope, ld->ld_deref,
ld->ld_sizelimit, ld->ld_timelimit, attrsonly );

View file

@ -39,7 +39,7 @@ ldap_ld_free( LDAP *ld, int close )
LDAPRequest *lr, *nextlr;
#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */
if ( ld->ld_sb.sb_naddr == 0 ) {
if ( ld->ld_cldapnaddr == 0 ) {
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
/* free LDAP structure and outstanding requests/responses */
for ( lr = ld->ld_requests; lr != NULL; lr = nextlr ) {
@ -60,11 +60,10 @@ ldap_ld_free( LDAP *ld, int close )
} else {
int i;
for ( i = 0; i < ld->ld_sb.sb_naddr; ++i ) {
free( ld->ld_sb.sb_addrs[ i ] );
for ( i = 0; i < ld->ld_cldapnaddr; ++i ) {
free( ld->ld_cldapaddrs[ i ] );
}
free( ld->ld_sb.sb_addrs );
free( ld->ld_sb.sb_fromaddr );
free( ld->ld_cldapaddrs );
}
for ( lm = ld->ld_responses; lm != NULL; lm = next ) {
@ -86,10 +85,6 @@ ldap_ld_free( LDAP *ld, int close )
free( ld->ld_ufnprefix );
if ( ld->ld_filtd != NULL )
ldap_getfilter_free( ld->ld_filtd );
#ifndef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
if ( ld->ld_sb.sb_ber.ber_buf != NULL )
free( ld->ld_sb.sb_ber.ber_buf );
#endif /* !LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */
if ( ld->ld_abandoned != NULL )
free( ld->ld_abandoned );
@ -104,8 +99,10 @@ ldap_ld_free( LDAP *ld, int close )
if ( ld->ld_options.ldo_defhost != NULL )
free( ld->ld_options.ldo_defhost );
lber_pvt_sb_destroy( &(ld->ld_sb) );
free( (char *) ld );
WSACleanup();
return( err );

View file

@ -515,18 +515,10 @@ do_queries(
conn_init();
}
(void) memset( (void *) &sb, '\0', sizeof( sb ) );
sb.sb_sd = clientsock;
sb.sb_naddr = ( udp ) ? 1 : 0;
#ifdef LDAP_CONNECTIONLESS
sb.sb_addrs = (void **)saddrlist;
sb.sb_fromaddr = &faddr;
sb.sb_useaddr = saddrlist[ 0 ] = &saddr;
#endif
sb.sb_ber.ber_buf = NULL;
sb.sb_ber.ber_ptr = NULL;
sb.sb_ber.ber_end = NULL;
lber_pvt_sb_init( &sb );
lber_pvt_sb_set_desc( &sb, clientsock );
lber_pvt_sb_set_io( &sb, (udp) ? &lber_pvt_sb_io_udp :
&lber_pvt_sb_io_tcp, NULL );
timeout.tv_sec = idletime;
timeout.tv_usec = 0;
for ( ;; ) {
@ -555,7 +547,7 @@ do_queries(
* already waiting for us on the client sock.
*/
if ( sb.sb_ber.ber_ptr >= sb.sb_ber.ber_end ) {
if ( ! lber_pvt_sb_data_ready( &sb ) ) {
if ( (rc = select( dtblsize, &readfds, 0, 0,
udp ? 0 : &timeout )) < 1 ) {
#ifdef LDAP_DEBUG
@ -581,7 +573,7 @@ do_queries(
}
}
if ( sb.sb_ber.ber_ptr < sb.sb_ber.ber_end ||
if ( lber_pvt_sb_data_ready( &sb ) ||
FD_ISSET( clientsock, &readfds ) ) {
client_request( &sb, conns, udp );
} else {

View file

@ -68,12 +68,15 @@ client_request(
BerElement ber, *copyofber;
struct msg *m;
static int bound;
#ifdef LDAP_CONNECTIONLESS
struct sockaddr_in *sai;
#endif
Debug( LDAP_DEBUG_TRACE, "client_request%s\n",
udp ? " udp" : "", 0, 0 );
/*
* Get the ldap message, which is a sequence of message id
* and then the actual request choice.
*/
@ -85,9 +88,9 @@ client_request(
#ifdef LDAP_CONNECTIONLESS
if ( udp && dosyslog ) {
sai = (struct sockaddr_in *)lber_pvt_sb_udp_get_src( &clientsb );
syslog( LOG_INFO, "UDP request from unknown (%s)",
inet_ntoa( ((struct sockaddr_in *)
clientsb->sb_fromaddr)->sin_addr ));
inet_ntoa( sai->sin_addr ) );
}
#endif
@ -189,16 +192,17 @@ client_request(
free( ber.ber_buf );
return;
}
sai = (struct sockaddr_in *) lber_pvt_sb_udp_get_src( &clientsb );
if ( get_cldap_msg( msgid, tag,
(struct sockaddr *)clientsb->sb_fromaddr ) != NULL ) {
(struct sockaddr *)sai ) != NULL ) {
/*
* duplicate request: toss this one
*/
Debug( LDAP_DEBUG_TRACE,
"client_request tossing dup request id %ld from %s\n",
msgid, inet_ntoa( ((struct sockaddr_in *)
clientsb->sb_fromaddr)->sin_addr ), 0 );
msgid, inet_ntoa( sai->sin_addr ), 0 );
free( ber.ber_buf );
return;
}
@ -208,7 +212,7 @@ client_request(
m = add_msg( msgid, tag, copyofber, dsaconn, udp,
#ifdef LDAP_CONNECTIONLESS
(struct sockaddr *)clientsb->sb_fromaddr );
(struct sockaddr *)sai );
#else
NULL );
#endif

View file

@ -280,12 +280,12 @@ send_ldap_msgresult(
{
#ifdef LDAP_CONNECTIONLESS
if ( m->m_cldap ) {
SAFEMEMCPY( (char *)sb->sb_useaddr, &m->m_clientaddr,
sizeof( struct sockaddr ));
lber_pvt_sb_udp_set_dst( &sb, &m->m_clientaddr );
Debug( LDAP_DEBUG_TRACE, "UDP response to %s port %d\n",
inet_ntoa(((struct sockaddr_in *)
sb->sb_useaddr)->sin_addr ),
((struct sockaddr_in *)sb->sb_useaddr)->sin_port, 0 );
&m->m_clientaddr)->sin_addr ),
((struct sockaddr_in *)&m->m_clientaddr)->sin_port, 0 );
}
#endif
return( send_ldap_result( sb, tag, m->m_msgid, err, matched, text ) );
@ -305,7 +305,7 @@ send_ldap_result(
int rc;
#ifdef LDAP_CONNECTIONLESS
int cldap;
cldap = ( sb->sb_naddr > 0 );
cldap = ( sb->sb_io == &lber_pvt_sb_io_udp );
#endif
Debug( LDAP_DEBUG_TRACE, "send_ldap_result\n", 0, 0, 0 );

View file

@ -700,8 +700,8 @@ search_result(
LDAP_OPERATIONS_ERROR, NULL, "ber_printf" );
return;
}
SAFEMEMCPY( (char *)sb->sb_useaddr, &m->m_clientaddr,
sizeof( struct sockaddr ));
lber_pvt_sb_udp_set_dst( sb, &m->m_clientaddr );
if ( ber_flush( sb, ber, 1 ) != 0 ) {
send_ldap_msgresult( sb, SEARCHRESTAG, m,
LDAP_RESULTS_TOO_LARGE, NULL, "ber_flush" );

View file

@ -133,7 +133,7 @@ connection_activity(
!= LDAP_TAG_MESSAGE ) {
Debug( LDAP_DEBUG_TRACE,
"ber_get_next on fd %d failed errno %d (%s)\n",
conn->c_sb.sb_sd, errno, errno > -1 && errno < sys_nerr ?
lber_pvt_sb_get_desc(&conn->c_sb), errno, errno > -1 && errno < sys_nerr ?
sys_errlist[errno] : "unknown" );
Debug( LDAP_DEBUG_TRACE, "*** got %ld of %lu so far\n",
(long)(conn->c_currentber->ber_rwptr - conn->c_currentber->ber_buf),

View file

@ -26,6 +26,12 @@
#include <sys/ioctl.h>
#endif
#ifdef LDAP_DEBUG
#include <assert.h>
#else
#define assert( cond )
#endif
#ifdef HAVE_TCPD
#include <tcpd.h>
@ -80,12 +86,7 @@ slapd_daemon(
c[i].c_addr = NULL;
c[i].c_domain = NULL;
c[i].c_ops = NULL;
c[i].c_sb.sb_sd = -1;
c[i].c_sb.sb_options = LBER_NO_READ_AHEAD;
c[i].c_sb.sb_naddr = 0;
c[i].c_sb.sb_ber.ber_buf = NULL;
c[i].c_sb.sb_ber.ber_ptr = NULL;
c[i].c_sb.sb_ber.ber_end = NULL;
lber_pvt_sb_init( &c[i].c_sb );
c[i].c_writewaiter = 0;
c[i].c_connid = 0;
ldap_pvt_thread_mutex_init( &c[i].c_dnmutex );
@ -150,6 +151,7 @@ slapd_daemon(
struct timeval zero;
struct timeval *tvp;
int len, pid;
int data_ready;
char *client_name;
char *client_addr;
@ -165,14 +167,19 @@ slapd_daemon(
Debug( LDAP_DEBUG_CONNS,
"listening for connections on %d, activity on:",
tcps, 0, 0 );
data_ready = 0;
ldap_pvt_thread_mutex_lock( &new_conn_mutex );
for ( i = 0; i < dtblsize; i++ ) {
if ( c[i].c_sb.sb_sd != -1 ) {
FD_SET( c[i].c_sb.sb_sd, &readfds );
if ( lber_pvt_sb_in_use( &c[i].c_sb )) {
FD_SET( lber_pvt_sb_get_desc(&c[i].c_sb),
&readfds );
if (lber_pvt_sb_data_ready(&c[i].c_sb))
data_ready = 1;
if ( c[i].c_writewaiter ) {
FD_SET( c[i].c_sb.sb_sd, &writefds );
FD_SET( lber_pvt_sb_get_desc(&c[i].c_sb),
&writefds );
}
Debug( LDAP_DEBUG_CONNS, " %dr%s", i,
c[i].c_writewaiter ? "w" : "", 0 );
@ -184,9 +191,9 @@ slapd_daemon(
Debug( LDAP_DEBUG_CONNS, "before select active_threads %d\n",
active_threads, 0, 0 );
#if defined( HAVE_YIELDING_SELECT ) || defined( NO_THREADS )
tvp = NULL;
tvp = (data_ready) ? &zero : NULL;
#else
tvp = active_threads ? &zero : NULL;
tvp = (active_threads || data_ready) ? &zero : NULL;
#endif
ldap_pvt_thread_mutex_unlock( &active_threads_mutex );
@ -201,7 +208,8 @@ slapd_daemon(
case 0: /* timeout - let threads run */
Debug( LDAP_DEBUG_CONNS, "select timeout - yielding\n",
0, 0, 0 );
ldap_pvt_thread_yield();
if (!data_ready)
ldap_pvt_thread_yield();
continue;
default: /* something happened - deal with it */
@ -225,7 +233,11 @@ slapd_daemon(
ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
continue;
}
if ( ioctl( ns, FIONBIO, (caddr_t) &on ) == -1 ) {
lber_pvt_sb_set_desc( &c[ns].c_sb, ns );
lber_pvt_sb_set_io( &c[ns].c_sb, &lber_pvt_sb_io_tcp, NULL );
if (lber_pvt_sb_set_nonblock( &c[ns].c_sb, 1)<0) {
Debug( LDAP_DEBUG_ANY,
"FIONBIO ioctl on %d failed\n", ns, 0, 0 );
}
@ -279,13 +291,14 @@ slapd_daemon(
client_addr == NULL ? "unknown" : client_addr,
0, 0 );
close(ns);
lber_pvt_sb_close( &c[ns].c_sb );
lber_pvt_sb_destroy( &c[ns].c_sb );
ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
continue;
}
#endif /* HAVE_TCPD */
c[ns].c_sb.sb_sd = ns;
ldap_pvt_thread_mutex_lock( &ops_mutex );
c[ns].c_connid = num_conns++;
ldap_pvt_thread_mutex_unlock( &ops_mutex );
@ -355,7 +368,8 @@ slapd_daemon(
ldap_pvt_thread_mutex_unlock( &active_threads_mutex );
}
if ( FD_ISSET( i, &readfds ) ) {
if ( FD_ISSET( i, &readfds ) ||
lber_pvt_sb_data_ready( &c[i].c_sb ) ) {
Debug( LDAP_DEBUG_CONNS,
"read activity on %d\n", i, 0, 0 );

View file

@ -246,12 +246,14 @@ main( int argc, char **argv )
c.c_dn = NULL;
c.c_cdn = NULL;
c.c_ops = NULL;
c.c_sb.sb_sd = 0;
c.c_sb.sb_options = 0;
c.c_sb.sb_naddr = udp ? 1 : 0;
c.c_sb.sb_ber.ber_buf = NULL;
c.c_sb.sb_ber.ber_ptr = NULL;
c.c_sb.sb_ber.ber_end = NULL;
lber_pvt_sb_init( &c.c_sb );
lber_pvt_sb_set_desc( &c.c_sb, 0 );
lber_pvt_sb_set_io( &c.c_sb,
(udp) ? &lber_pvt_sb_io_udp : &lber_pvt_sb_io_tcp,
NULL );
/* FIXME: handle udp here */
ldap_pvt_thread_mutex_init( &c.c_dnmutex );
ldap_pvt_thread_mutex_init( &c.c_opsmutex );
ldap_pvt_thread_mutex_init( &c.c_pdumutex );
@ -303,8 +305,8 @@ main( int argc, char **argv )
Debug( LDAP_DEBUG_ANY,
"ber_peek_tag returns 0x%lx\n", tag, 0, 0 );
ber_free( &ber, 1 );
close( c.c_sb.sb_sd );
c.c_sb.sb_sd = -1;
lber_pvt_sb_close( &c.c_sb );
lber_pvt_sb_destroy( &c.c_sb );
return 1;
}

View file

@ -70,7 +70,7 @@ monitor_info( Connection *conn, Operation *op )
ldap_pvt_thread_mutex_lock( &new_conn_mutex );
for ( i = 0; i < dtblsize; i++ ) {
if ( c[i].c_sb.sb_sd != -1 ) {
if ( lber_pvt_sb_in_use(&(c[i].c_sb)) ) {
nconns++;
if ( c[i].c_writewaiter ) {
nwritewaiters++;

View file

@ -150,12 +150,11 @@ send_ldap_result(
{
#ifdef LDAP_CONNECTIONLESS
if ( op->o_cldap ) {
SAFEMEMCPY( (char *)conn->c_sb.sb_useaddr, &op->o_clientaddr,
sizeof( struct sockaddr ));
lber_pvt_sb_udp_set_dst( &conn->c_sb, &op->o_clientaddr );
Debug( LDAP_DEBUG_TRACE, "UDP response to %s port %d\n",
inet_ntoa(((struct sockaddr_in *)
conn->c_sb.sb_useaddr)->sin_addr ),
((struct sockaddr_in *) conn->c_sb.sb_useaddr)->sin_port,
&op->o_clientaddr)->sin_addr ),
((struct sockaddr_in *) &op->o_clientaddr)->sin_port,
0 );
}
#endif
@ -448,12 +447,12 @@ void
close_connection( Connection *conn, int opconnid, int opid )
{
ldap_pvt_thread_mutex_lock( &new_conn_mutex );
if ( conn->c_sb.sb_sd != -1 && conn->c_connid == opconnid ) {
if ( lber_pvt_sb_in_use(&conn->c_sb) && conn->c_connid == opconnid ) {
Statslog( LDAP_DEBUG_STATS,
"conn=%d op=%d fd=%d closed errno=%d\n", conn->c_connid,
opid, conn->c_sb.sb_sd, errno, 0 );
close( conn->c_sb.sb_sd );
conn->c_sb.sb_sd = -1;
opid, lber_pvt_sb_get_desc(&conn->c_sb), errno, 0 );
lber_pvt_sb_close( &conn->c_sb );
lber_pvt_sb_destroy( &conn->c_sb );
conn->c_version = 0;
conn->c_protocol = 0;
}