/* 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
#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=
#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. */
}
#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 );
}
#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.
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 );
}
#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 );
assert( status_is_ok(sb) );
if (blen) {
- long rlen = (blen<len) ? blen : len;
+ ber_len_t 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;
return sb;
}
-Sockbuf *ber_sockbuf_alloc_fd( int fd )
+Sockbuf *ber_sockbuf_alloc_fd( ber_socket_t fd )
{
Sockbuf *sb = ber_sockbuf_alloc();
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 */
#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) {
}
/* 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;
}
} 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 +
long sockbuf_do_write( Sockbuf *sb )
{
long to_go;
+ ber_slen_t ret;
assert( sb != NULL );
assert( SOCKBUF_VALID( 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;
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 )
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
#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;
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;
}
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;
}
* 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 ) );
{
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 )
#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 ) );
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;
}
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 );
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 );
# 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 );
* 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 ) );
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 ) );