X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=libraries%2Fliblber%2Fsockbuf.c;h=9237bb8bb805106d849f869eb567f4bc95bc2715;hb=467a5bd9cd94abb7476d5ce9487fa1367668d056;hp=5ce23ac656d310ccd7c246544d4adf27f903fe9b;hpb=647b5f84eee3a910c99518080e5fe562d4f7a32c;p=openldap
diff --git a/libraries/liblber/sockbuf.c b/libraries/liblber/sockbuf.c
index 5ce23ac656..9237bb8bb8 100644
--- a/libraries/liblber/sockbuf.c
+++ b/libraries/liblber/sockbuf.c
@@ -1,8 +1,17 @@
/* sockbuf.c - i/o routines with support for adding i/o layers. */
/* $OpenLDAP$ */
-/*
- * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+/* This work is part of OpenLDAP Software .
+ *
+ * Copyright 1998-2009 The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * .
*/
#include "portable.h"
@@ -37,7 +46,7 @@
#define LBER_MIN_BUFF_SIZE 4096
#endif
#ifndef LBER_MAX_BUFF_SIZE
-#define LBER_MAX_BUFF_SIZE 65536
+#define LBER_MAX_BUFF_SIZE (65536*256)
#endif
#ifndef LBER_DEFAULT_READAHEAD
#define LBER_DEFAULT_READAHEAD 16384
@@ -48,8 +57,6 @@ ber_sockbuf_alloc( void )
{
Sockbuf *sb;
- ber_int_options.lbo_valid = LBER_INITIALIZED;
-
sb = LBER_CALLOC( 1, sizeof( Sockbuf ) );
if( sb == NULL ) return NULL;
@@ -95,13 +102,13 @@ ber_sockbuf_ctrl( Sockbuf *sb, int opt, void *arg )
case LBER_SB_OPT_GET_FD:
if ( arg != NULL ) {
- *((int *)arg) = sb->sb_fd;
+ *((ber_socket_t *)arg) = sb->sb_fd;
}
ret = ( sb->sb_fd == AC_SOCKET_INVALID ? -1 : 1);
break;
case LBER_SB_OPT_SET_FD:
- sb->sb_fd = *((int *)arg);
+ sb->sb_fd = *((ber_socket_t *)arg);
ret = 1;
break;
@@ -143,9 +150,22 @@ ber_sockbuf_ctrl( Sockbuf *sb, int opt, void *arg )
ret = 1;
break;
+ case LBER_SB_OPT_UNGET_BUF:
+#ifdef LDAP_PF_LOCAL_SENDMSG
+ sb->sb_ungetlen = ((struct berval *)arg)->bv_len;
+ if ( sb->sb_ungetlen <= sizeof( sb->sb_ungetbuf )) {
+ AC_MEMCPY( sb->sb_ungetbuf, ((struct berval *)arg)->bv_val,
+ sb->sb_ungetlen );
+ ret = 1;
+ } else {
+ sb->sb_ungetlen = 0;
+ ret = -1;
+ }
+#endif
+ break;
+
default:
- ret = sb->sb_iod->sbiod_io->sbi_ctrl( sb->sb_iod,
- opt, arg );
+ ret = sb->sb_iod->sbiod_io->sbi_ctrl( sb->sb_iod, opt, arg );
break;
}
@@ -182,11 +202,11 @@ ber_sockbuf_add_io( Sockbuf *sb, Sockbuf_IO *sbio, int layer, void *arg )
memset( &d->sbiod_pvt, '\0', sizeof( d->sbiod_pvt ) );
d->sbiod_next = p;
*q = d;
-
+
if ( sbio->sbi_setup != NULL && ( sbio->sbi_setup( d, arg ) < 0 ) ) {
return -1;
}
-
+
return 0;
}
@@ -213,7 +233,7 @@ ber_sockbuf_remove_io( Sockbuf *sb, Sockbuf_IO *sbio, int layer )
}
*q = p->sbiod_next;
LBER_FREE( p );
- break;
+ break;
}
q = &p->sbiod_next;
}
@@ -313,18 +333,13 @@ ber_pvt_sb_do_write( Sockbuf_IO_Desc *sbiod, Sockbuf_Buf *buf_out )
buf_out->buf_end = buf_out->buf_ptr = 0;
}
- if ( (ber_len_t)ret < to_go ) {
- /* not enough data, so pretend no data was sent. */
- return -1;
- }
-
return ret;
}
int
ber_pvt_socket_set_nonblock( ber_socket_t sd, int nb )
{
-#if HAVE_FCNTL
+#ifdef HAVE_FCNTL
int flags = fcntl( sd, F_GETFL);
if( nb ) {
flags |= O_NONBLOCK;
@@ -365,9 +380,7 @@ ber_int_sb_close( Sockbuf *sb )
p = sb->sb_iod;
while ( p ) {
- if ( p->sbiod_io->sbi_close &&
- p->sbiod_io->sbi_close( p ) < 0 )
- {
+ if ( p->sbiod_io->sbi_close && p->sbiod_io->sbi_close( p ) < 0 ) {
return -1;
}
p = p->sbiod_next;
@@ -455,7 +468,7 @@ sb_stream_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
* MacTCP/OpenTransport
*/
return tcpread( sbiod->sbiod_sb->sb_fd, 0, (unsigned char *)buf,
- len, NULL );
+ len, NULL );
#elif defined( HAVE_PCNFS ) || \
defined( HAVE_WINSOCK ) || defined ( __BEOS__ )
@@ -468,22 +481,7 @@ sb_stream_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
/*
* 32-bit Windows Socket API (under Windows NT or Windows 95)
*/
- {
- int rc;
-
- rc = recv( sbiod->sbiod_sb->sb_fd, buf, len, 0 );
-
-#ifdef HAVE_WINSOCK
- if ( rc < 0 ) {
- int err;
-
- err = WSAGetLastError();
- errno = err;
- }
-#endif
-
- return rc;
- }
+ return recv( sbiod->sbiod_sb->sb_fd, buf, len, 0 );
#elif defined( HAVE_NCSA )
/*
@@ -521,18 +519,7 @@ sb_stream_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
/*
* 32-bit Windows Socket API (under Windows NT or Windows 95)
*/
- {
- int rc = send( sbiod->sbiod_sb->sb_fd, buf, len, 0 );
-
-#ifdef HAVE_WINSOCK
- if ( rc < 0 ) {
- int err;
- err = WSAGetLastError();
- errno = err;
- }
-#endif
- return rc;
- }
+ return send( sbiod->sbiod_sb->sb_fd, buf, len, 0 );
#elif defined(HAVE_NCSA)
return netwrite( sbiod->sbiod_sb->sb_fd, buf, len );
@@ -731,6 +718,24 @@ sb_fd_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
assert( sbiod != NULL);
assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
+#ifdef LDAP_PF_LOCAL_SENDMSG
+ if ( sbiod->sbiod_sb->sb_ungetlen ) {
+ ber_len_t blen = sbiod->sbiod_sb->sb_ungetlen;
+ if ( blen > len )
+ blen = len;
+ AC_MEMCPY( buf, sbiod->sbiod_sb->sb_ungetbuf, blen );
+ buf = (char *) buf + blen;
+ len -= blen;
+ sbiod->sbiod_sb->sb_ungetlen -= blen;
+ if ( sbiod->sbiod_sb->sb_ungetlen ) {
+ AC_MEMCPY( sbiod->sbiod_sb->sb_ungetbuf,
+ sbiod->sbiod_sb->sb_ungetbuf+blen,
+ sbiod->sbiod_sb->sb_ungetlen );
+ }
+ if ( len == 0 )
+ return blen;
+ }
+#endif
return read( sbiod->sbiod_sb->sb_fd, buf, len );
}
@@ -817,22 +822,23 @@ static ber_slen_t
sb_debug_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
{
ber_slen_t ret;
+ char ebuf[128];
ret = LBER_SBIOD_READ_NEXT( sbiod, buf, len );
- if (sbiod->sbiod_sb->sb_debug & LDAP_DEBUG_PACKETS)
- {
- if ( ret < 0 ) {
- ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
- "%sread: want=%ld error=%s\n", (char *)sbiod->sbiod_pvt,
- (long)len, STRERROR( errno ) );
-
- } else {
- ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
- "%sread: want=%ld, got=%ld\n", (char *)sbiod->sbiod_pvt,
- (long)len, (long)ret );
- ber_log_bprint( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
- (const char *)buf, ret );
- }
+ if (sbiod->sbiod_sb->sb_debug & LDAP_DEBUG_PACKETS) {
+ int err = sock_errno();
+ if ( ret < 0 ) {
+ ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
+ "%sread: want=%ld error=%s\n", (char *)sbiod->sbiod_pvt,
+ (long)len, AC_STRERROR_R( err, ebuf, sizeof ebuf ) );
+ } else {
+ ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
+ "%sread: want=%ld, got=%ld\n", (char *)sbiod->sbiod_pvt,
+ (long)len, (long)ret );
+ ber_log_bprint( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
+ (const char *)buf, ret );
+ }
+ sock_errset(err);
}
return ret;
}
@@ -841,23 +847,24 @@ static ber_slen_t
sb_debug_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
{
ber_slen_t ret;
+ char ebuf[128];
ret = LBER_SBIOD_WRITE_NEXT( sbiod, buf, len );
- if (sbiod->sbiod_sb->sb_debug & LDAP_DEBUG_PACKETS)
- {
- if ( ret < 0 ) {
- ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
- "%swrite: want=%ld error=%s\n",
- (char *)sbiod->sbiod_pvt, (long)len,
- STRERROR( errno ) );
-
- } else {
- ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
- "%swrite: want=%ld, written=%ld\n",
- (char *)sbiod->sbiod_pvt, (long)len, (long)ret );
- ber_log_bprint( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
- (const char *)buf, ret );
- }
+ if (sbiod->sbiod_sb->sb_debug & LDAP_DEBUG_PACKETS) {
+ int err = sock_errno();
+ if ( ret < 0 ) {
+ ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
+ "%swrite: want=%ld error=%s\n",
+ (char *)sbiod->sbiod_pvt, (long)len,
+ AC_STRERROR_R( err, ebuf, sizeof ebuf ) );
+ } else {
+ ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
+ "%swrite: want=%ld, written=%ld\n",
+ (char *)sbiod->sbiod_pvt, (long)len, (long)ret );
+ ber_log_bprint( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
+ (const char *)buf, ret );
+ }
+ sock_errset(err);
}
return ret;
@@ -890,8 +897,7 @@ sb_dgram_setup( Sockbuf_IO_Desc *sbiod, void *arg )
assert( sbiod != NULL);
assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
- if ( arg != NULL )
- sbiod->sbiod_sb->sb_fd = *((int *)arg);
+ if ( arg != NULL ) sbiod->sbiod_sb->sb_fd = *((int *)arg);
return 0;
}
@@ -899,7 +905,7 @@ static ber_slen_t
sb_dgram_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
{
ber_slen_t rc;
- socklen_t addrlen;
+ ber_socklen_t addrlen;
struct sockaddr *src;
assert( sbiod != NULL );
@@ -908,9 +914,9 @@ sb_dgram_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
addrlen = sizeof( struct sockaddr );
src = buf;
- buf += addrlen;
- rc = recvfrom( sbiod->sbiod_sb->sb_fd, buf, len, 0, src,
- &addrlen );
+ buf = (char *) buf + addrlen;
+ len -= addrlen;
+ rc = recvfrom( sbiod->sbiod_sb->sb_fd, buf, len, 0, src, &addrlen );
return rc > 0 ? rc+sizeof(struct sockaddr) : rc;
}
@@ -926,19 +932,18 @@ sb_dgram_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
assert( buf != NULL );
dst = buf;
- buf += sizeof( struct sockaddr );
+ buf = (char *) buf + sizeof( struct sockaddr );
len -= sizeof( struct sockaddr );
rc = sendto( sbiod->sbiod_sb->sb_fd, buf, len, 0, dst,
- sizeof( struct sockaddr ) );
+ sizeof( struct sockaddr ) );
- if ( rc < 0 )
- return -1;
+ if ( rc < 0 ) return -1;
/* fake error if write was not atomic */
if (rc < len) {
# ifdef EMSGSIZE
- errno = EMSGSIZE;
+ errno = EMSGSIZE;
# endif
return -1;
}