]> git.sur5r.net Git - openldap/blobdiff - libraries/liblber/sockbuf.c
ITS#6932: Move assert(str) before Debug(..str).
[openldap] / libraries / liblber / sockbuf.c
index eca111a8dd8eae725e784959a5e8c0bb66edf404..0d1c513b9bcda930aba4fe0c059e59384c3e1249 100644 (file)
@@ -1,8 +1,17 @@
 /* sockbuf.c - i/o routines with support for adding i/o layers. */
 /* $OpenLDAP$ */
-/*
- * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1998-2011 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
+ * <http://www.OpenLDAP.org/license.html>.
  */
 
 #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,6 +150,20 @@ 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 );
                        break;
@@ -212,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;
        }
@@ -318,7 +339,7 @@ ber_pvt_sb_do_write( Sockbuf_IO_Desc *sbiod, Sockbuf_Buf *buf_out )
 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;
@@ -460,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 )
 /*
@@ -513,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 );
@@ -546,7 +541,8 @@ sb_stream_close( Sockbuf_IO_Desc *sbiod )
 {
        assert( sbiod != NULL );
        assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
-       tcp_close( sbiod->sbiod_sb->sb_fd );
+       if ( sbiod->sbiod_sb->sb_fd != AC_SOCKET_INVALID )
+               tcp_close( sbiod->sbiod_sb->sb_fd );
    return 0;
 }
 
@@ -723,6 +719,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 );
 }
 
@@ -741,7 +755,8 @@ sb_fd_close( Sockbuf_IO_Desc *sbiod )
        assert( sbiod != NULL );
        assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
 
-       close( sbiod->sbiod_sb->sb_fd );
+       if ( sbiod->sbiod_sb->sb_fd != AC_SOCKET_INVALID )
+               close( sbiod->sbiod_sb->sb_fd );
        return 0;
 }
 
@@ -809,14 +824,15 @@ 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) {
-               int err = errno;
+               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, STRERROR( errno ) );
+                               (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,
@@ -824,7 +840,7 @@ sb_debug_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
                        ber_log_bprint( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
                                (const char *)buf, ret );
                }
-               errno = err;
+               sock_errset(err);
        }
        return ret;
 }
@@ -833,16 +849,16 @@ 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) {
-               int err = errno;
+               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,
-                               STRERROR( errno ) );
-                       errno = err;
+                               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",
@@ -850,7 +866,7 @@ sb_debug_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
                        ber_log_bprint( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
                                (const char *)buf, ret );
                }
-               errno = err;
+               sock_errset(err);
        }
 
        return ret;
@@ -891,7 +907,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 );
@@ -900,7 +916,8 @@ sb_dgram_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
 
        addrlen = sizeof( struct sockaddr );
        src = buf;
-       buf += 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;
@@ -917,7 +934,7 @@ 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,
@@ -941,8 +958,9 @@ sb_dgram_close( Sockbuf_IO_Desc *sbiod )
 {
        assert( sbiod != NULL );
        assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
-
-       tcp_close( sbiod->sbiod_sb->sb_fd );
+  
+       if ( sbiod->sbiod_sb->sb_fd != AC_SOCKET_INVALID )
+               tcp_close( sbiod->sbiod_sb->sb_fd );
        return 0;
 }