1 /* sockbuf.c - i/o routines with support for adding i/o layers. */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 1998-2004 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
21 #include <ac/stdlib.h>
25 #include <ac/socket.h>
26 #include <ac/string.h>
27 #include <ac/unistd.h>
31 #endif /* HAVE_IO_H */
33 #if defined( HAVE_FCNTL_H )
37 #if defined( HAVE_SYS_FILIO_H )
38 #include <sys/filio.h>
39 #elif defined( HAVE_SYS_IOCTL_H )
40 #include <sys/ioctl.h>
45 #ifndef LBER_MIN_BUFF_SIZE
46 #define LBER_MIN_BUFF_SIZE 4096
48 #ifndef LBER_MAX_BUFF_SIZE
49 #define LBER_MAX_BUFF_SIZE 65536
51 #ifndef LBER_DEFAULT_READAHEAD
52 #define LBER_DEFAULT_READAHEAD 16384
56 ber_sockbuf_alloc( void )
60 ber_int_options.lbo_valid = LBER_INITIALIZED;
62 sb = LBER_CALLOC( 1, sizeof( Sockbuf ) );
64 if( sb == NULL ) return NULL;
66 ber_int_sb_init( sb );
71 ber_sockbuf_free( Sockbuf *sb )
74 assert( SOCKBUF_VALID( sb ) );
76 ber_int_sb_close( sb );
77 ber_int_sb_destroy( sb );
81 /* Return values: -1: error, 0: no operation performed or the answer is false,
82 * 1: successful operation or the answer is true
85 ber_sockbuf_ctrl( Sockbuf *sb, int opt, void *arg )
91 assert( SOCKBUF_VALID( sb ) );
94 case LBER_SB_OPT_HAS_IO:
96 while ( p && p->sbiod_io != (Sockbuf_IO *)arg ) {
105 case LBER_SB_OPT_GET_FD:
107 *((int *)arg) = sb->sb_fd;
109 ret = ( sb->sb_fd == AC_SOCKET_INVALID ? -1 : 1);
112 case LBER_SB_OPT_SET_FD:
113 sb->sb_fd = *((int *)arg);
117 case LBER_SB_OPT_SET_NONBLOCK:
118 ret = ber_pvt_socket_set_nonblock( sb->sb_fd, arg != NULL)
122 case LBER_SB_OPT_DRAIN: {
123 /* Drain the data source to enable possible errors (e.g.
124 * TLS) to be propagated to the upper layers
126 char buf[LBER_MIN_BUFF_SIZE];
129 ret = ber_int_sb_read( sb, buf, sizeof( buf ) );
130 } while ( ret == sizeof( buf ) );
135 case LBER_SB_OPT_NEEDS_READ:
136 ret = ( sb->sb_trans_needs_read ? 1 : 0 );
139 case LBER_SB_OPT_NEEDS_WRITE:
140 ret = ( sb->sb_trans_needs_write ? 1 : 0 );
143 case LBER_SB_OPT_GET_MAX_INCOMING:
145 *((ber_len_t *)arg) = sb->sb_max_incoming;
150 case LBER_SB_OPT_SET_MAX_INCOMING:
151 sb->sb_max_incoming = *((ber_len_t *)arg);
156 ret = sb->sb_iod->sbiod_io->sbi_ctrl( sb->sb_iod, opt, arg );
164 ber_sockbuf_add_io( Sockbuf *sb, Sockbuf_IO *sbio, int layer, void *arg )
166 Sockbuf_IO_Desc *d, *p, **q;
168 assert( sb != NULL );
169 assert( SOCKBUF_VALID( sb ) );
171 if ( sbio == NULL ) {
177 while ( p && p->sbiod_level > layer ) {
182 d = LBER_MALLOC( sizeof( *d ) );
187 d->sbiod_level = layer;
190 memset( &d->sbiod_pvt, '\0', sizeof( d->sbiod_pvt ) );
194 if ( sbio->sbi_setup != NULL && ( sbio->sbi_setup( d, arg ) < 0 ) ) {
202 ber_sockbuf_remove_io( Sockbuf *sb, Sockbuf_IO *sbio, int layer )
204 Sockbuf_IO_Desc *p, **q;
206 assert( sb != NULL );
207 assert( SOCKBUF_VALID( sb ) );
209 if ( sb->sb_iod == NULL ) {
214 while ( *q != NULL ) {
216 if ( layer == p->sbiod_level && p->sbiod_io == sbio ) {
217 if ( p->sbiod_io->sbi_remove != NULL &&
218 p->sbiod_io->sbi_remove( p ) < 0 )
233 ber_pvt_sb_buf_init( Sockbuf_Buf *buf )
235 buf->buf_base = NULL;
242 ber_pvt_sb_buf_destroy( Sockbuf_Buf *buf )
244 assert( buf != NULL);
247 LBER_FREE( buf->buf_base );
249 ber_pvt_sb_buf_init( buf );
253 ber_pvt_sb_grow_buffer( Sockbuf_Buf *buf, ber_len_t minsize )
258 assert( buf != NULL );
260 for ( pw = LBER_MIN_BUFF_SIZE; pw < minsize; pw <<= 1 ) {
261 if (pw > LBER_MAX_BUFF_SIZE) return -1;
264 if ( buf->buf_size < pw ) {
265 p = LBER_REALLOC( buf->buf_base, pw );
266 if ( p == NULL ) return -1;
274 ber_pvt_sb_copy_out( Sockbuf_Buf *sbb, char *buf, ber_len_t len )
278 assert( buf != NULL );
279 assert( sbb != NULL );
281 assert( sbb->buf_size > 0 );
284 max = sbb->buf_end - sbb->buf_ptr;
285 max = ( max < len) ? max : len;
287 AC_MEMCPY( buf, sbb->buf_base + sbb->buf_ptr, max );
289 if ( sbb->buf_ptr >= sbb->buf_end ) {
290 sbb->buf_ptr = sbb->buf_end = 0;
297 ber_pvt_sb_do_write( Sockbuf_IO_Desc *sbiod, Sockbuf_Buf *buf_out )
302 assert( sbiod != NULL );
303 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
305 to_go = buf_out->buf_end - buf_out->buf_ptr;
309 ret = LBER_SBIOD_WRITE_NEXT( sbiod, buf_out->buf_base +
310 buf_out->buf_ptr, to_go );
312 if ((ret<0) && (errno==EINTR)) continue;
317 if ( ret <= 0 ) return ret;
319 buf_out->buf_ptr += ret;
320 if (buf_out->buf_ptr == buf_out->buf_end) {
321 buf_out->buf_end = buf_out->buf_ptr = 0;
328 ber_pvt_socket_set_nonblock( ber_socket_t sd, int nb )
331 int flags = fcntl( sd, F_GETFL);
335 flags &= ~O_NONBLOCK;
337 return fcntl( sd, F_SETFL, flags );
339 #elif defined( FIONBIO )
340 ioctl_t status = nb ? 1 : 0;
341 return ioctl( sd, FIONBIO, &status );
346 ber_int_sb_init( Sockbuf *sb )
350 sb->sb_valid=LBER_VALID_SOCKBUF;
352 sb->sb_debug = ber_int_debug;
353 sb->sb_fd = AC_SOCKET_INVALID;
355 sb->sb_trans_needs_read = 0;
356 sb->sb_trans_needs_write = 0;
358 assert( SOCKBUF_VALID( sb ) );
363 ber_int_sb_close( Sockbuf *sb )
371 if ( p->sbiod_io->sbi_close && p->sbiod_io->sbi_close( p ) < 0 ) {
377 sb->sb_fd = AC_SOCKET_INVALID;
383 ber_int_sb_destroy( Sockbuf *sb )
388 assert( SOCKBUF_VALID( sb ) );
390 while ( sb->sb_iod ) {
391 p = sb->sb_iod->sbiod_next;
392 ber_sockbuf_remove_io( sb, sb->sb_iod->sbiod_io,
393 sb->sb_iod->sbiod_level );
397 return ber_int_sb_init( sb );
401 ber_int_sb_read( Sockbuf *sb, void *buf, ber_len_t len )
405 assert( buf != NULL );
407 assert( sb->sb_iod != NULL );
408 assert( SOCKBUF_VALID( sb ) );
411 ret = sb->sb_iod->sbiod_io->sbi_read( sb->sb_iod, buf, len );
414 if ( ( ret < 0 ) && ( errno == EINTR ) ) continue;
423 ber_int_sb_write( Sockbuf *sb, void *buf, ber_len_t len )
427 assert( buf != NULL );
429 assert( sb->sb_iod != NULL );
430 assert( SOCKBUF_VALID( sb ) );
433 ret = sb->sb_iod->sbiod_io->sbi_write( sb->sb_iod, buf, len );
436 if ( ( ret < 0 ) && ( errno == EINTR ) ) continue;
449 sb_stream_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
451 assert( sbiod != NULL);
452 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
456 * MacTCP/OpenTransport
458 return tcpread( sbiod->sbiod_sb->sb_fd, 0, (unsigned char *)buf,
461 #elif defined( HAVE_PCNFS ) || \
462 defined( HAVE_WINSOCK ) || defined ( __BEOS__ )
467 * Windows Socket API (under DOS/Windows 3.x)
470 * 32-bit Windows Socket API (under Windows NT or Windows 95)
475 rc = recv( sbiod->sbiod_sb->sb_fd, buf, len, 0 );
481 err = WSAGetLastError();
489 #elif defined( HAVE_NCSA )
491 * NCSA Telnet TCP/IP stack (under DOS)
493 return nread( sbiod->sbiod_sb->sb_fd, buf, len );
496 return read( sbiod->sbiod_sb->sb_fd, buf, len );
501 sb_stream_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
503 assert( sbiod != NULL);
504 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
508 * MacTCP/OpenTransport
510 #define MAX_WRITE 65535
511 return tcpwrite( sbiod->sbiod_sb->sb_fd, (unsigned char *)buf,
512 (len<MAX_WRITE) ? len : MAX_WRITE );
514 #elif defined( HAVE_PCNFS) \
515 || defined( HAVE_WINSOCK) || defined ( __BEOS__ )
520 * Windows Socket API (under DOS/Windows 3.x)
523 * 32-bit Windows Socket API (under Windows NT or Windows 95)
526 int rc = send( sbiod->sbiod_sb->sb_fd, buf, len, 0 );
531 err = WSAGetLastError();
538 #elif defined(HAVE_NCSA)
539 return netwrite( sbiod->sbiod_sb->sb_fd, buf, len );
543 * VMS -- each write must be 64K or smaller
545 #define MAX_WRITE 65535
546 return write( sbiod->sbiod_sb->sb_fd, buf,
547 (len<MAX_WRITE) ? len : MAX_WRITE);
549 return write( sbiod->sbiod_sb->sb_fd, buf, len );
554 sb_stream_close( Sockbuf_IO_Desc *sbiod )
556 assert( sbiod != NULL );
557 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
558 tcp_close( sbiod->sbiod_sb->sb_fd );
562 /* The argument is a pointer to the socket descriptor */
564 sb_stream_setup( Sockbuf_IO_Desc *sbiod, void *arg ) {
565 assert( sbiod != NULL );
568 sbiod->sbiod_sb->sb_fd = *((int *)arg);
574 sb_stream_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg ) {
575 /* This is an end IO descriptor */
579 Sockbuf_IO ber_sockbuf_io_tcp = {
580 sb_stream_setup, /* sbi_setup */
581 NULL, /* sbi_remove */
582 sb_stream_ctrl, /* sbi_ctrl */
583 sb_stream_read, /* sbi_read */
584 sb_stream_write, /* sbi_write */
585 sb_stream_close /* sbi_close */
590 * Support for readahead (UDP needs it)
594 sb_rdahead_setup( Sockbuf_IO_Desc *sbiod, void *arg )
598 assert( sbiod != NULL );
600 p = LBER_MALLOC( sizeof( *p ) );
601 if ( p == NULL ) return -1;
603 ber_pvt_sb_buf_init( p );
606 ber_pvt_sb_grow_buffer( p, LBER_DEFAULT_READAHEAD );
608 ber_pvt_sb_grow_buffer( p, *((int *)arg) );
611 sbiod->sbiod_pvt = p;
616 sb_rdahead_remove( Sockbuf_IO_Desc *sbiod )
620 assert( sbiod != NULL );
622 p = (Sockbuf_Buf *)sbiod->sbiod_pvt;
624 if ( p->buf_ptr != p->buf_end ) return -1;
626 ber_pvt_sb_buf_destroy( (Sockbuf_Buf *)(sbiod->sbiod_pvt) );
627 LBER_FREE( sbiod->sbiod_pvt );
628 sbiod->sbiod_pvt = NULL;
634 sb_rdahead_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
637 ber_slen_t bufptr = 0, ret, max;
639 assert( sbiod != NULL );
640 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
641 assert( sbiod->sbiod_next != NULL );
643 p = (Sockbuf_Buf *)sbiod->sbiod_pvt;
645 assert( p->buf_size > 0 );
647 /* Are there anything left in the buffer? */
648 ret = ber_pvt_sb_copy_out( p, buf, len );
652 if ( len == 0 ) return bufptr;
654 max = p->buf_size - p->buf_end;
657 ret = LBER_SBIOD_READ_NEXT( sbiod, p->buf_base + p->buf_end,
660 if ( ( ret < 0 ) && ( errno == EINTR ) ) continue;
666 return ( bufptr ? bufptr : ret );
670 bufptr += ber_pvt_sb_copy_out( p, (char *) buf + bufptr, len );
675 sb_rdahead_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
677 assert( sbiod != NULL );
678 assert( sbiod->sbiod_next != NULL );
680 return LBER_SBIOD_WRITE_NEXT( sbiod, buf, len );
684 sb_rdahead_close( Sockbuf_IO_Desc *sbiod )
686 assert( sbiod != NULL );
688 /* Just erase the buffer */
689 ber_pvt_sb_buf_destroy((Sockbuf_Buf *)sbiod->sbiod_pvt);
694 sb_rdahead_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
698 p = (Sockbuf_Buf *)sbiod->sbiod_pvt;
700 if ( opt == LBER_SB_OPT_DATA_READY ) {
701 if ( p->buf_ptr != p->buf_end ) {
705 } else if ( opt == LBER_SB_OPT_SET_READAHEAD ) {
706 if ( p->buf_size >= *((ber_len_t *)arg) ) {
709 return ( ber_pvt_sb_grow_buffer( p, *((int *)arg) ) ?
713 return LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg );
716 Sockbuf_IO ber_sockbuf_io_readahead = {
717 sb_rdahead_setup, /* sbi_setup */
718 sb_rdahead_remove, /* sbi_remove */
719 sb_rdahead_ctrl, /* sbi_ctrl */
720 sb_rdahead_read, /* sbi_read */
721 sb_rdahead_write, /* sbi_write */
722 sb_rdahead_close /* sbi_close */
726 * Support for simple file IO
730 sb_fd_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
732 assert( sbiod != NULL);
733 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
735 return read( sbiod->sbiod_sb->sb_fd, buf, len );
739 sb_fd_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
741 assert( sbiod != NULL);
742 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
744 return write( sbiod->sbiod_sb->sb_fd, buf, len );
748 sb_fd_close( Sockbuf_IO_Desc *sbiod )
750 assert( sbiod != NULL );
751 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
753 close( sbiod->sbiod_sb->sb_fd );
757 /* The argument is a pointer to the file descriptor */
759 sb_fd_setup( Sockbuf_IO_Desc *sbiod, void *arg ) {
760 assert( sbiod != NULL );
763 sbiod->sbiod_sb->sb_fd = *((int *)arg);
768 sb_fd_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg ) {
769 /* This is an end IO descriptor */
773 Sockbuf_IO ber_sockbuf_io_fd = {
774 sb_fd_setup, /* sbi_setup */
775 NULL, /* sbi_remove */
776 sb_fd_ctrl, /* sbi_ctrl */
777 sb_fd_read, /* sbi_read */
778 sb_fd_write, /* sbi_write */
779 sb_fd_close /* sbi_close */
787 sb_debug_setup( Sockbuf_IO_Desc *sbiod, void *arg )
789 assert( sbiod != NULL );
791 if ( arg == NULL ) arg = "sockbuf_";
793 sbiod->sbiod_pvt = LBER_MALLOC( strlen( arg ) + 1 );
794 if ( sbiod->sbiod_pvt == NULL ) return -1;
796 strcpy( (char *)sbiod->sbiod_pvt, (char *)arg );
801 sb_debug_remove( Sockbuf_IO_Desc *sbiod )
803 assert( sbiod != NULL );
804 assert( sbiod->sbiod_pvt != NULL );
806 LBER_FREE( sbiod->sbiod_pvt );
807 sbiod->sbiod_pvt = NULL;
812 sb_debug_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
814 return LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg );
818 sb_debug_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
823 ret = LBER_SBIOD_READ_NEXT( sbiod, buf, len );
824 if (sbiod->sbiod_sb->sb_debug & LDAP_DEBUG_PACKETS) {
827 ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
828 "%sread: want=%ld error=%s\n", (char *)sbiod->sbiod_pvt,
829 (long)len, AC_STRERROR_R( errno, ebuf, sizeof ebuf ) );
831 ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
832 "%sread: want=%ld, got=%ld\n", (char *)sbiod->sbiod_pvt,
833 (long)len, (long)ret );
834 ber_log_bprint( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
835 (const char *)buf, ret );
843 sb_debug_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
848 ret = LBER_SBIOD_WRITE_NEXT( sbiod, buf, len );
849 if (sbiod->sbiod_sb->sb_debug & LDAP_DEBUG_PACKETS) {
852 ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
853 "%swrite: want=%ld error=%s\n",
854 (char *)sbiod->sbiod_pvt, (long)len,
855 AC_STRERROR_R( errno, ebuf, sizeof ebuf ) );
857 ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
858 "%swrite: want=%ld, written=%ld\n",
859 (char *)sbiod->sbiod_pvt, (long)len, (long)ret );
860 ber_log_bprint( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
861 (const char *)buf, ret );
869 Sockbuf_IO ber_sockbuf_io_debug = {
870 sb_debug_setup, /* sbi_setup */
871 sb_debug_remove, /* sbi_remove */
872 sb_debug_ctrl, /* sbi_ctrl */
873 sb_debug_read, /* sbi_read */
874 sb_debug_write, /* sbi_write */
878 #ifdef LDAP_CONNECTIONLESS
881 * Support for UDP (CLDAP)
883 * All I/O at this level must be atomic. For ease of use, the sb_readahead
884 * must be used above this module. All data reads and writes are prefixed
885 * with a sockaddr containing the address of the remote entity. Upper levels
886 * must read and write this sockaddr before doing the usual ber_printf/scanf
887 * operations on LDAP messages.
891 sb_dgram_setup( Sockbuf_IO_Desc *sbiod, void *arg )
893 assert( sbiod != NULL);
894 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
896 if ( arg != NULL ) sbiod->sbiod_sb->sb_fd = *((int *)arg);
901 sb_dgram_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
905 struct sockaddr *src;
907 assert( sbiod != NULL );
908 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
909 assert( buf != NULL );
911 addrlen = sizeof( struct sockaddr );
914 rc = recvfrom( sbiod->sbiod_sb->sb_fd, buf, len, 0, src, &addrlen );
916 return rc > 0 ? rc+sizeof(struct sockaddr) : rc;
920 sb_dgram_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
923 struct sockaddr *dst;
925 assert( sbiod != NULL );
926 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
927 assert( buf != NULL );
930 buf += sizeof( struct sockaddr );
931 len -= sizeof( struct sockaddr );
933 rc = sendto( sbiod->sbiod_sb->sb_fd, buf, len, 0, dst,
934 sizeof( struct sockaddr ) );
936 if ( rc < 0 ) return -1;
938 /* fake error if write was not atomic */
945 rc = len + sizeof(struct sockaddr);
950 sb_dgram_close( Sockbuf_IO_Desc *sbiod )
952 assert( sbiod != NULL );
953 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
955 tcp_close( sbiod->sbiod_sb->sb_fd );
960 sb_dgram_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
962 /* This is an end IO descriptor */
966 Sockbuf_IO ber_sockbuf_io_udp =
968 sb_dgram_setup, /* sbi_setup */
969 NULL, /* sbi_remove */
970 sb_dgram_ctrl, /* sbi_ctrl */
971 sb_dgram_read, /* sbi_read */
972 sb_dgram_write, /* sbi_write */
973 sb_dgram_close /* sbi_close */
976 #endif /* LDAP_CONNECTIONLESS */