X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Fliblber%2Fsockbuf.c;h=5bdce3efbca2e76492e0a71063463d3039c32523;hb=304a57740a0dbb8c95bbbdada7b7972eee521fa0;hp=5241833c467245be1d3bcf86d9b988c0c48dd70a;hpb=21c70857f1029309d6bc5a5b6a93d7537494b742;p=openldap diff --git a/libraries/liblber/sockbuf.c b/libraries/liblber/sockbuf.c index 5241833c46..5bdce3efbc 100644 --- a/libraries/liblber/sockbuf.c +++ b/libraries/liblber/sockbuf.c @@ -1,4 +1,5 @@ /* sockbuf.c - i/o routines with support for adding i/o layers. */ +/* $OpenLDAP$ */ /* * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file @@ -42,8 +43,8 @@ #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 ber_slen_t have_no_read( Sockbuf *sb, void *buf, ber_len_t len ); +static ber_slen_t have_no_write( Sockbuf *sb, void *buf, ber_len_t len ); static int have_no_close( Sockbuf *sb ); static Sockbuf_IO sb_IO_None= @@ -100,23 +101,23 @@ status_is_ok( Sockbuf *sb ) #endif #ifdef USE_SASL -static long -packet_length( char *buf ) +static ber_len_t +packet_length( Sockbuf *sb, const char *buf ) { - long size; + ber_len_t size; assert( buf != NULL ); - size = (((unsigned long)buf[0])<<24)| - (((unsigned long)buf[1])<<16)| - (((unsigned long)buf[2])<<8)| - (((unsigned long)buf[3])); + size = (((ber_len_t)buf[0])<<24)| + (((ber_len_t)buf[1])<<16)| + (((ber_len_t)buf[2])<<8)| + (((ber_len_t)buf[3])); - if ((size<0) || (size>MAX_BUF_SIZE)) { + if ( 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 ); + ber_log_printf( LDAP_DEBUG_SASL, sb->sb_debug, + "SASL: received packet length of %lu bytes\n", + (unsigned long) size ); size = 16; /* this should lead to an error. */ } @@ -125,9 +126,9 @@ packet_length( char *buf ) #endif static int -grow_buffer( Sockbuf_Buf * buf, long minsize ) +grow_buffer( Sockbuf_Buf * buf, ber_len_t minsize ) { - long pw;; + ber_len_t pw;; assert( buf != NULL ); @@ -162,8 +163,8 @@ grow_buffer( Sockbuf_Buf * buf, long minsize ) } #ifdef USE_SASL -static long -sockbuf_sec_release( Sockbuf *sb, char *buf, long len ) +static ber_slen_t +sockbuf_sec_release( Sockbuf *sb, char *buf, ber_len_t len ) { /* when this is called: * sb->sb_sec_buf_in.buf_base points to a packet. @@ -225,7 +226,7 @@ sockbuf_sec_release( Sockbuf *sb, char *buf, long len ) ptr+=size; if (ptr+4<=end) - size = packet_length( ptr ); + size = packet_length( sb, ptr ); /* size is always at least 4, so the loop condition is always OK !!*/ assert( size>=4 ); @@ -301,10 +302,10 @@ sockbuf_sec_protect( Sockbuf *sb, char *buf, long len ) } #endif -static long -sockbuf_copy_out( Sockbuf *sb, char **buf, long len ) +static ber_len_t +sockbuf_copy_out( Sockbuf *sb, char **buf, ber_len_t len ) { - long blen = (sb->sb_buf.buf_end - sb->sb_buf.buf_ptr ); + ber_len_t blen = (sb->sb_buf.buf_end - sb->sb_buf.buf_ptr ); assert( buf != NULL ); @@ -313,7 +314,7 @@ sockbuf_copy_out( Sockbuf *sb, char **buf, long len ) assert( status_is_ok(sb) ); if (blen) { - long rlen = (blensb_buf.buf_base + sb->sb_buf.buf_ptr, rlen ); sb->sb_buf.buf_ptr+=rlen; *buf+=rlen; @@ -343,7 +344,7 @@ Sockbuf *ber_sockbuf_alloc( void ) return sb; } -Sockbuf *ber_sockbuf_alloc_fd( int fd ) +Sockbuf *ber_sockbuf_alloc_fd( ber_socket_t fd ) { Sockbuf *sb = ber_sockbuf_alloc(); @@ -362,20 +363,19 @@ void ber_sockbuf_free( Sockbuf *sb ) LBER_FREE(sb); } -long -ber_pvt_sb_read( Sockbuf *sb, void *buf_arg, long len ) +ber_slen_t +ber_pvt_sb_read( Sockbuf *sb, void *buf_arg, ber_len_t len ) { char *buf; - long ret; + ber_slen_t ret; assert( buf_arg != NULL ); assert( sb != NULL ); - assert( SOCKBUF_VALID( sb ) ); + assert( SOCKBUF_VALID( sb ) ); assert( status_is_ok(sb) ); -#if 0 - /* breaks slapd :-< */ + + /* slapd might have problems with this */ assert( ber_pvt_sb_in_use( sb ) ); -#endif #ifdef TEST_PARTIAL_READ if ((rand() & 3)==1) { /* 1 out of 4 */ @@ -398,7 +398,7 @@ ber_pvt_sb_read( Sockbuf *sb, void *buf_arg, long len ) #ifdef USE_SASL if (sb->sb_sec) { - int max; + ber_slen_t max; assert( sb->sb_sec->sbs_release ); assert( sb->sb_sec_buf_in.buf_base ); if (sb->sb_read_ahead) { @@ -442,14 +442,14 @@ ber_pvt_sb_read( Sockbuf *sb, void *buf_arg, long len ) } /* calculate the packet length. */ sb->sb_sec_buf_in.buf_end = - packet_length(sb->sb_sec_buf_in.buf_base ); + packet_length(sb, 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) { + if (sb->sb_sec_buf_in.buf_ptr >= sb->sb_sec_buf_in.buf_end) { /* finished packet. decode it. */ goto decode_packet; } @@ -475,9 +475,9 @@ decode_packet: } else { #endif if (sb->sb_read_ahead) { - long max; + ber_slen_t max; max = sb->sb_buf.buf_size - sb->sb_buf.buf_end; - if (max>len) { + if (max> (ber_slen_t) len) { for(;;) { ret = sockbuf_io_read( sb, sb->sb_buf.buf_base + @@ -529,6 +529,7 @@ do_return: long sockbuf_do_write( Sockbuf *sb ) { long to_go; + ber_slen_t ret; assert( sb != NULL ); assert( SOCKBUF_VALID( sb ) ); @@ -554,19 +555,19 @@ long sockbuf_do_write( Sockbuf *sb ) } #endif -long ber_pvt_sb_write( Sockbuf *sb, void *buf, long len_arg ) +ber_slen_t ber_pvt_sb_write( Sockbuf *sb, void *buf, ber_len_t len_arg ) { - long ret; - long len = len_arg; + ber_slen_t ret; + ber_len_t len = len_arg; assert( buf != NULL ); assert( sb != NULL ); assert( SOCKBUF_VALID( sb ) ); assert( status_is_ok(sb) ); -#if 0 - /* unfortunately breaks slapd */ + + /* slapd might have problems with this */ assert( ber_pvt_sb_in_use( sb ) ); -#endif + #ifdef TEST_PARTIAL_WRITE if ((rand() & 3)==1) { /* 1 out of 4 */ errno = EWOULDBLOCK; @@ -642,6 +643,23 @@ int ber_pvt_sb_set_readahead( Sockbuf *sb, int rh ) return 0; } +int ber_pvt_socket_set_nonblock( ber_socket_t sd, int nb ) +{ +#if HAVE_FCNTL + int flags = fcntl(ber_pvt_sb_get_desc(sb), F_GETFL); + if( nb ) { + flags |= O_NONBLOCK; + } else { + flags &= ~O_NONBLOCK; + } + return fcntl( ber_pvt_sb_get_desc(sb), F_SETFL, flags ); + +#elif defined( FIONBIO ) + ioctl_t status = nb ? 1 : 0; + return ioctl( sd, FIONBIO, &status ); +#endif +} + #define USE_NONBLOCK #ifdef USE_NONBLOCK int ber_pvt_sb_set_nonblock( Sockbuf *sb, int nb ) @@ -660,19 +678,11 @@ int ber_pvt_sb_set_nonblock( Sockbuf *sb, int nb ) sb->sb_read_ahead = 0; #endif } - if (ber_pvt_sb_in_use(sb)) { -#if HAVE_FCNTL - int flags = fcntl(ber_pvt_sb_get_desc(sb), F_GETFL); - flags |= O_NONBLOCK; - return fcntl(ber_pvt_sb_get_desc(sb), F_SETFL, flags); - -#elif defined( FIONBIO ) - /* WINSOCK requires the status to be a long */ - ioctl_t status = (nb!=0); - return ioctl( ber_pvt_sb_get_desc(sb), FIONBIO, &status ); -#endif /* FIONBIO */ - } - return 0; + if (ber_pvt_sb_in_use(sb)) { + return ber_pvt_socket_set_nonblock( + ber_pvt_sb_get_desc(sb), nb ); + } + return 0; } #endif @@ -709,8 +719,10 @@ int ber_pvt_sb_init( Sockbuf *sb ) #ifdef USE_SASL sb->sb_sec_ready = 0; #endif - sb->sb_read_ahead = 0; + sb->sb_read_ahead = 1; /* test */ sb->sb_non_block = 0; + sb->sb_trans_needs_read = 0; + sb->sb_trans_needs_write = 0; sb->sb_fd = -1; sb->sb_iodata = NULL; sb->sb_io = &sb_IO_None; @@ -769,10 +781,10 @@ int ber_pvt_sb_set_sec( Sockbuf *sb, Sockbuf_Sec * sec, void *arg ) 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_sec_buf_in.buf_end = (len>4) ? packet_length( sb, sb->sb_sec_buf_in ) : 0; sb->sb_buf.buf_ptr = sb->sb_buf.buf_end = 0; } - update_status(); + update_status( sb ); return 0; } @@ -839,7 +851,9 @@ int ber_pvt_sb_clear_io( Sockbuf *sb ) sb->sb_io = &sb_IO_None; sb->sb_trans_ready = 0; - + sb->sb_trans_needs_read = 0; + sb->sb_trans_needs_write = 0; + return 0; } @@ -847,8 +861,8 @@ int ber_pvt_sb_clear_io( Sockbuf *sb ) * Support for TCP */ -static long -stream_read( Sockbuf *sb, void *buf, long len ) +static ber_slen_t +stream_read( Sockbuf *sb, void *buf, ber_len_t len ) { assert( sb != NULL); assert( SOCKBUF_VALID( sb ) ); @@ -874,9 +888,17 @@ stream_read( Sockbuf *sb, void *buf, long len ) { int rc; rc = recv( ber_pvt_sb_get_desc(sb), buf, len, 0 ); + #ifdef HAVE_WINSOCK - if ( rc < 0 ) errno = WSAGetLastError(); + if ( rc < 0 ) + { + int err; + + err = WSAGetLastError(); + errno = err; + } #endif + return rc; } #elif defined( HAVE_NCSA ) @@ -890,8 +912,8 @@ stream_read( Sockbuf *sb, void *buf, long len ) #endif } -static long -stream_write( Sockbuf *sb, void *buf, long len ) +static ber_slen_t +stream_write( Sockbuf *sb, void *buf, ber_len_t len ) { assert( sb != NULL); assert( SOCKBUF_VALID( sb ) ); @@ -921,7 +943,12 @@ stream_write( Sockbuf *sb, void *buf, long len ) int rc; rc = send( ber_pvt_sb_get_desc(sb), buf, len, 0 ); #ifdef HAVE_WINSOCK - if ( rc < 0 ) errno = WSAGetLastError(); + if ( rc < 0 ) + { + int err; + err = WSAGetLastError(); + errno = err; + } #endif return rc; } @@ -992,12 +1019,12 @@ dgram_release( Sockbuf *sb ) return 0; } -static long -dgram_read( Sockbuf *sb, void *buf, long len ) +static ber_slen_t +dgram_read( Sockbuf *sb, void *buf, ber_len_t len ) { #ifdef LDAP_CONNECTIONLESS - long rc; - int addrlen; + ber_slen_t rc; + socklen_t addrlen; struct dgram_data *dd; assert( sb != NULL ); @@ -1011,8 +1038,8 @@ dgram_read( Sockbuf *sb, void *buf, long len ) if ( sb->sb_debug ) { ber_log_printf( LDAP_DEBUG_ANY, sb->sb_debug, - "dgram_read udp_read %d bytes\n", - rc ); + "dgram_read udp_read %ld bytes\n", + (long) rc ); if ( rc > 0 ) ber_log_bprint( LDAP_DEBUG_PACKETS, sb->sb_debug, buf, rc ); @@ -1023,11 +1050,11 @@ dgram_read( Sockbuf *sb, void *buf, long len ) # endif /* LDAP_CONNECTIONLESS */ } -static long -dgram_write( Sockbuf *sb, void *buf, long len ) +static ber_slen_t +dgram_write( Sockbuf *sb, void *buf, ber_len_t len ) { #ifdef LDAP_CONNECTIONLESS - int rc; + ber_slen_t rc; struct dgram_data *dd; assert( sb != NULL ); @@ -1104,8 +1131,8 @@ void *ber_pvt_sb_udp_get_src( Sockbuf *sb ) * break the servers. */ -static long -have_no_read( Sockbuf *sb, void *buf, long len ) +static ber_slen_t +have_no_read( Sockbuf *sb, void *buf, ber_len_t len ) { assert( sb != NULL ); assert( SOCKBUF_VALID( sb ) ); @@ -1116,8 +1143,8 @@ have_no_read( Sockbuf *sb, void *buf, long len ) return -1; } -static long -have_no_write( Sockbuf *sb, void *buf, long len ) +static ber_slen_t +have_no_write( Sockbuf *sb, void *buf, ber_len_t len ) { assert( sb != NULL ); assert( SOCKBUF_VALID( sb ) );