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-2007 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*256)
51 #ifndef LBER_DEFAULT_READAHEAD
52 #define LBER_DEFAULT_READAHEAD 16384
56 ber_sockbuf_alloc( void )
60 sb = LBER_CALLOC( 1, sizeof( Sockbuf ) );
62 if( sb == NULL ) return NULL;
64 ber_int_sb_init( sb );
69 ber_sockbuf_free( Sockbuf *sb )
72 assert( SOCKBUF_VALID( sb ) );
74 ber_int_sb_close( sb );
75 ber_int_sb_destroy( sb );
79 /* Return values: -1: error, 0: no operation performed or the answer is false,
80 * 1: successful operation or the answer is true
83 ber_sockbuf_ctrl( Sockbuf *sb, int opt, void *arg )
89 assert( SOCKBUF_VALID( sb ) );
92 case LBER_SB_OPT_HAS_IO:
94 while ( p && p->sbiod_io != (Sockbuf_IO *)arg ) {
103 case LBER_SB_OPT_GET_FD:
105 *((ber_socket_t *)arg) = sb->sb_fd;
107 ret = ( sb->sb_fd == AC_SOCKET_INVALID ? -1 : 1);
110 case LBER_SB_OPT_SET_FD:
111 sb->sb_fd = *((ber_socket_t *)arg);
115 case LBER_SB_OPT_SET_NONBLOCK:
116 ret = ber_pvt_socket_set_nonblock( sb->sb_fd, arg != NULL)
120 case LBER_SB_OPT_DRAIN: {
121 /* Drain the data source to enable possible errors (e.g.
122 * TLS) to be propagated to the upper layers
124 char buf[LBER_MIN_BUFF_SIZE];
127 ret = ber_int_sb_read( sb, buf, sizeof( buf ) );
128 } while ( ret == sizeof( buf ) );
133 case LBER_SB_OPT_NEEDS_READ:
134 ret = ( sb->sb_trans_needs_read ? 1 : 0 );
137 case LBER_SB_OPT_NEEDS_WRITE:
138 ret = ( sb->sb_trans_needs_write ? 1 : 0 );
141 case LBER_SB_OPT_GET_MAX_INCOMING:
143 *((ber_len_t *)arg) = sb->sb_max_incoming;
148 case LBER_SB_OPT_SET_MAX_INCOMING:
149 sb->sb_max_incoming = *((ber_len_t *)arg);
154 ret = sb->sb_iod->sbiod_io->sbi_ctrl( sb->sb_iod, opt, arg );
162 ber_sockbuf_add_io( Sockbuf *sb, Sockbuf_IO *sbio, int layer, void *arg )
164 Sockbuf_IO_Desc *d, *p, **q;
166 assert( sb != NULL );
167 assert( SOCKBUF_VALID( sb ) );
169 if ( sbio == NULL ) {
175 while ( p && p->sbiod_level > layer ) {
180 d = LBER_MALLOC( sizeof( *d ) );
185 d->sbiod_level = layer;
188 memset( &d->sbiod_pvt, '\0', sizeof( d->sbiod_pvt ) );
192 if ( sbio->sbi_setup != NULL && ( sbio->sbi_setup( d, arg ) < 0 ) ) {
200 ber_sockbuf_remove_io( Sockbuf *sb, Sockbuf_IO *sbio, int layer )
202 Sockbuf_IO_Desc *p, **q;
204 assert( sb != NULL );
205 assert( SOCKBUF_VALID( sb ) );
207 if ( sb->sb_iod == NULL ) {
212 while ( *q != NULL ) {
214 if ( layer == p->sbiod_level && p->sbiod_io == sbio ) {
215 if ( p->sbiod_io->sbi_remove != NULL &&
216 p->sbiod_io->sbi_remove( p ) < 0 )
231 ber_pvt_sb_buf_init( Sockbuf_Buf *buf )
233 buf->buf_base = NULL;
240 ber_pvt_sb_buf_destroy( Sockbuf_Buf *buf )
242 assert( buf != NULL);
245 LBER_FREE( buf->buf_base );
247 ber_pvt_sb_buf_init( buf );
251 ber_pvt_sb_grow_buffer( Sockbuf_Buf *buf, ber_len_t minsize )
256 assert( buf != NULL );
258 for ( pw = LBER_MIN_BUFF_SIZE; pw < minsize; pw <<= 1 ) {
259 if (pw > LBER_MAX_BUFF_SIZE) return -1;
262 if ( buf->buf_size < pw ) {
263 p = LBER_REALLOC( buf->buf_base, pw );
264 if ( p == NULL ) return -1;
272 ber_pvt_sb_copy_out( Sockbuf_Buf *sbb, char *buf, ber_len_t len )
276 assert( buf != NULL );
277 assert( sbb != NULL );
279 assert( sbb->buf_size > 0 );
282 max = sbb->buf_end - sbb->buf_ptr;
283 max = ( max < len) ? max : len;
285 AC_MEMCPY( buf, sbb->buf_base + sbb->buf_ptr, max );
287 if ( sbb->buf_ptr >= sbb->buf_end ) {
288 sbb->buf_ptr = sbb->buf_end = 0;
295 ber_pvt_sb_do_write( Sockbuf_IO_Desc *sbiod, Sockbuf_Buf *buf_out )
300 assert( sbiod != NULL );
301 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
303 to_go = buf_out->buf_end - buf_out->buf_ptr;
307 ret = LBER_SBIOD_WRITE_NEXT( sbiod, buf_out->buf_base +
308 buf_out->buf_ptr, to_go );
310 if ((ret<0) && (errno==EINTR)) continue;
315 if ( ret <= 0 ) return ret;
317 buf_out->buf_ptr += ret;
318 if (buf_out->buf_ptr == buf_out->buf_end) {
319 buf_out->buf_end = buf_out->buf_ptr = 0;
326 ber_pvt_socket_set_nonblock( ber_socket_t sd, int nb )
329 int flags = fcntl( sd, F_GETFL);
333 flags &= ~O_NONBLOCK;
335 return fcntl( sd, F_SETFL, flags );
337 #elif defined( FIONBIO )
338 ioctl_t status = nb ? 1 : 0;
339 return ioctl( sd, FIONBIO, &status );
344 ber_int_sb_init( Sockbuf *sb )
348 sb->sb_valid=LBER_VALID_SOCKBUF;
350 sb->sb_debug = ber_int_debug;
351 sb->sb_fd = AC_SOCKET_INVALID;
353 sb->sb_trans_needs_read = 0;
354 sb->sb_trans_needs_write = 0;
356 assert( SOCKBUF_VALID( sb ) );
361 ber_int_sb_close( Sockbuf *sb )
369 if ( p->sbiod_io->sbi_close && p->sbiod_io->sbi_close( p ) < 0 ) {
375 sb->sb_fd = AC_SOCKET_INVALID;
381 ber_int_sb_destroy( Sockbuf *sb )
386 assert( SOCKBUF_VALID( sb ) );
388 while ( sb->sb_iod ) {
389 p = sb->sb_iod->sbiod_next;
390 ber_sockbuf_remove_io( sb, sb->sb_iod->sbiod_io,
391 sb->sb_iod->sbiod_level );
395 return ber_int_sb_init( sb );
399 ber_int_sb_read( Sockbuf *sb, void *buf, ber_len_t len )
403 assert( buf != NULL );
405 assert( sb->sb_iod != NULL );
406 assert( SOCKBUF_VALID( sb ) );
409 ret = sb->sb_iod->sbiod_io->sbi_read( sb->sb_iod, buf, len );
412 if ( ( ret < 0 ) && ( errno == EINTR ) ) continue;
421 ber_int_sb_write( Sockbuf *sb, void *buf, ber_len_t len )
425 assert( buf != NULL );
427 assert( sb->sb_iod != NULL );
428 assert( SOCKBUF_VALID( sb ) );
431 ret = sb->sb_iod->sbiod_io->sbi_write( sb->sb_iod, buf, len );
434 if ( ( ret < 0 ) && ( errno == EINTR ) ) continue;
447 sb_stream_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
449 assert( sbiod != NULL);
450 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
454 * MacTCP/OpenTransport
456 return tcpread( sbiod->sbiod_sb->sb_fd, 0, (unsigned char *)buf,
459 #elif defined( HAVE_PCNFS ) || \
460 defined( HAVE_WINSOCK ) || defined ( __BEOS__ )
465 * Windows Socket API (under DOS/Windows 3.x)
468 * 32-bit Windows Socket API (under Windows NT or Windows 95)
470 return recv( sbiod->sbiod_sb->sb_fd, buf, len, 0 );
472 #elif defined( HAVE_NCSA )
474 * NCSA Telnet TCP/IP stack (under DOS)
476 return nread( sbiod->sbiod_sb->sb_fd, buf, len );
479 return read( sbiod->sbiod_sb->sb_fd, buf, len );
484 sb_stream_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
486 assert( sbiod != NULL);
487 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
491 * MacTCP/OpenTransport
493 #define MAX_WRITE 65535
494 return tcpwrite( sbiod->sbiod_sb->sb_fd, (unsigned char *)buf,
495 (len<MAX_WRITE) ? len : MAX_WRITE );
497 #elif defined( HAVE_PCNFS) \
498 || defined( HAVE_WINSOCK) || defined ( __BEOS__ )
503 * Windows Socket API (under DOS/Windows 3.x)
506 * 32-bit Windows Socket API (under Windows NT or Windows 95)
508 return send( sbiod->sbiod_sb->sb_fd, buf, len, 0 );
510 #elif defined(HAVE_NCSA)
511 return netwrite( sbiod->sbiod_sb->sb_fd, buf, len );
515 * VMS -- each write must be 64K or smaller
517 #define MAX_WRITE 65535
518 return write( sbiod->sbiod_sb->sb_fd, buf,
519 (len<MAX_WRITE) ? len : MAX_WRITE);
521 return write( sbiod->sbiod_sb->sb_fd, buf, len );
526 sb_stream_close( Sockbuf_IO_Desc *sbiod )
528 assert( sbiod != NULL );
529 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
530 tcp_close( sbiod->sbiod_sb->sb_fd );
534 /* The argument is a pointer to the socket descriptor */
536 sb_stream_setup( Sockbuf_IO_Desc *sbiod, void *arg ) {
537 assert( sbiod != NULL );
540 sbiod->sbiod_sb->sb_fd = *((int *)arg);
546 sb_stream_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg ) {
547 /* This is an end IO descriptor */
551 Sockbuf_IO ber_sockbuf_io_tcp = {
552 sb_stream_setup, /* sbi_setup */
553 NULL, /* sbi_remove */
554 sb_stream_ctrl, /* sbi_ctrl */
555 sb_stream_read, /* sbi_read */
556 sb_stream_write, /* sbi_write */
557 sb_stream_close /* sbi_close */
562 * Support for readahead (UDP needs it)
566 sb_rdahead_setup( Sockbuf_IO_Desc *sbiod, void *arg )
570 assert( sbiod != NULL );
572 p = LBER_MALLOC( sizeof( *p ) );
573 if ( p == NULL ) return -1;
575 ber_pvt_sb_buf_init( p );
578 ber_pvt_sb_grow_buffer( p, LBER_DEFAULT_READAHEAD );
580 ber_pvt_sb_grow_buffer( p, *((int *)arg) );
583 sbiod->sbiod_pvt = p;
588 sb_rdahead_remove( Sockbuf_IO_Desc *sbiod )
592 assert( sbiod != NULL );
594 p = (Sockbuf_Buf *)sbiod->sbiod_pvt;
596 if ( p->buf_ptr != p->buf_end ) return -1;
598 ber_pvt_sb_buf_destroy( (Sockbuf_Buf *)(sbiod->sbiod_pvt) );
599 LBER_FREE( sbiod->sbiod_pvt );
600 sbiod->sbiod_pvt = NULL;
606 sb_rdahead_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
609 ber_slen_t bufptr = 0, ret, max;
611 assert( sbiod != NULL );
612 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
613 assert( sbiod->sbiod_next != NULL );
615 p = (Sockbuf_Buf *)sbiod->sbiod_pvt;
617 assert( p->buf_size > 0 );
619 /* Are there anything left in the buffer? */
620 ret = ber_pvt_sb_copy_out( p, buf, len );
624 if ( len == 0 ) return bufptr;
626 max = p->buf_size - p->buf_end;
629 ret = LBER_SBIOD_READ_NEXT( sbiod, p->buf_base + p->buf_end,
632 if ( ( ret < 0 ) && ( errno == EINTR ) ) continue;
638 return ( bufptr ? bufptr : ret );
642 bufptr += ber_pvt_sb_copy_out( p, (char *) buf + bufptr, len );
647 sb_rdahead_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
649 assert( sbiod != NULL );
650 assert( sbiod->sbiod_next != NULL );
652 return LBER_SBIOD_WRITE_NEXT( sbiod, buf, len );
656 sb_rdahead_close( Sockbuf_IO_Desc *sbiod )
658 assert( sbiod != NULL );
660 /* Just erase the buffer */
661 ber_pvt_sb_buf_destroy((Sockbuf_Buf *)sbiod->sbiod_pvt);
666 sb_rdahead_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
670 p = (Sockbuf_Buf *)sbiod->sbiod_pvt;
672 if ( opt == LBER_SB_OPT_DATA_READY ) {
673 if ( p->buf_ptr != p->buf_end ) {
677 } else if ( opt == LBER_SB_OPT_SET_READAHEAD ) {
678 if ( p->buf_size >= *((ber_len_t *)arg) ) {
681 return ( ber_pvt_sb_grow_buffer( p, *((int *)arg) ) ?
685 return LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg );
688 Sockbuf_IO ber_sockbuf_io_readahead = {
689 sb_rdahead_setup, /* sbi_setup */
690 sb_rdahead_remove, /* sbi_remove */
691 sb_rdahead_ctrl, /* sbi_ctrl */
692 sb_rdahead_read, /* sbi_read */
693 sb_rdahead_write, /* sbi_write */
694 sb_rdahead_close /* sbi_close */
698 * Support for simple file IO
702 sb_fd_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
704 assert( sbiod != NULL);
705 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
707 return read( sbiod->sbiod_sb->sb_fd, buf, len );
711 sb_fd_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
713 assert( sbiod != NULL);
714 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
716 return write( sbiod->sbiod_sb->sb_fd, buf, len );
720 sb_fd_close( Sockbuf_IO_Desc *sbiod )
722 assert( sbiod != NULL );
723 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
725 close( sbiod->sbiod_sb->sb_fd );
729 /* The argument is a pointer to the file descriptor */
731 sb_fd_setup( Sockbuf_IO_Desc *sbiod, void *arg ) {
732 assert( sbiod != NULL );
735 sbiod->sbiod_sb->sb_fd = *((int *)arg);
740 sb_fd_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg ) {
741 /* This is an end IO descriptor */
745 Sockbuf_IO ber_sockbuf_io_fd = {
746 sb_fd_setup, /* sbi_setup */
747 NULL, /* sbi_remove */
748 sb_fd_ctrl, /* sbi_ctrl */
749 sb_fd_read, /* sbi_read */
750 sb_fd_write, /* sbi_write */
751 sb_fd_close /* sbi_close */
759 sb_debug_setup( Sockbuf_IO_Desc *sbiod, void *arg )
761 assert( sbiod != NULL );
763 if ( arg == NULL ) arg = "sockbuf_";
765 sbiod->sbiod_pvt = LBER_MALLOC( strlen( arg ) + 1 );
766 if ( sbiod->sbiod_pvt == NULL ) return -1;
768 strcpy( (char *)sbiod->sbiod_pvt, (char *)arg );
773 sb_debug_remove( Sockbuf_IO_Desc *sbiod )
775 assert( sbiod != NULL );
776 assert( sbiod->sbiod_pvt != NULL );
778 LBER_FREE( sbiod->sbiod_pvt );
779 sbiod->sbiod_pvt = NULL;
784 sb_debug_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
786 return LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg );
790 sb_debug_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
795 ret = LBER_SBIOD_READ_NEXT( sbiod, buf, len );
796 if (sbiod->sbiod_sb->sb_debug & LDAP_DEBUG_PACKETS) {
797 int err = sock_errno();
799 ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
800 "%sread: want=%ld error=%s\n", (char *)sbiod->sbiod_pvt,
801 (long)len, AC_STRERROR_R( err, ebuf, sizeof ebuf ) );
803 ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
804 "%sread: want=%ld, got=%ld\n", (char *)sbiod->sbiod_pvt,
805 (long)len, (long)ret );
806 ber_log_bprint( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
807 (const char *)buf, ret );
815 sb_debug_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
820 ret = LBER_SBIOD_WRITE_NEXT( sbiod, buf, len );
821 if (sbiod->sbiod_sb->sb_debug & LDAP_DEBUG_PACKETS) {
822 int err = sock_errno();
824 ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
825 "%swrite: want=%ld error=%s\n",
826 (char *)sbiod->sbiod_pvt, (long)len,
827 AC_STRERROR_R( err, ebuf, sizeof ebuf ) );
829 ber_log_printf( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
830 "%swrite: want=%ld, written=%ld\n",
831 (char *)sbiod->sbiod_pvt, (long)len, (long)ret );
832 ber_log_bprint( LDAP_DEBUG_PACKETS, sbiod->sbiod_sb->sb_debug,
833 (const char *)buf, ret );
841 Sockbuf_IO ber_sockbuf_io_debug = {
842 sb_debug_setup, /* sbi_setup */
843 sb_debug_remove, /* sbi_remove */
844 sb_debug_ctrl, /* sbi_ctrl */
845 sb_debug_read, /* sbi_read */
846 sb_debug_write, /* sbi_write */
850 #ifdef LDAP_CONNECTIONLESS
853 * Support for UDP (CLDAP)
855 * All I/O at this level must be atomic. For ease of use, the sb_readahead
856 * must be used above this module. All data reads and writes are prefixed
857 * with a sockaddr containing the address of the remote entity. Upper levels
858 * must read and write this sockaddr before doing the usual ber_printf/scanf
859 * operations on LDAP messages.
863 sb_dgram_setup( Sockbuf_IO_Desc *sbiod, void *arg )
865 assert( sbiod != NULL);
866 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
868 if ( arg != NULL ) sbiod->sbiod_sb->sb_fd = *((int *)arg);
873 sb_dgram_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
877 struct sockaddr *src;
879 assert( sbiod != NULL );
880 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
881 assert( buf != NULL );
883 addrlen = sizeof( struct sockaddr );
887 rc = recvfrom( sbiod->sbiod_sb->sb_fd, buf, len, 0, src, &addrlen );
889 return rc > 0 ? rc+sizeof(struct sockaddr) : rc;
893 sb_dgram_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
896 struct sockaddr *dst;
898 assert( sbiod != NULL );
899 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
900 assert( buf != NULL );
903 buf += sizeof( struct sockaddr );
904 len -= sizeof( struct sockaddr );
906 rc = sendto( sbiod->sbiod_sb->sb_fd, buf, len, 0, dst,
907 sizeof( struct sockaddr ) );
909 if ( rc < 0 ) return -1;
911 /* fake error if write was not atomic */
918 rc = len + sizeof(struct sockaddr);
923 sb_dgram_close( Sockbuf_IO_Desc *sbiod )
925 assert( sbiod != NULL );
926 assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
928 tcp_close( sbiod->sbiod_sb->sb_fd );
933 sb_dgram_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
935 /* This is an end IO descriptor */
939 Sockbuf_IO ber_sockbuf_io_udp =
941 sb_dgram_setup, /* sbi_setup */
942 NULL, /* sbi_remove */
943 sb_dgram_ctrl, /* sbi_ctrl */
944 sb_dgram_read, /* sbi_read */
945 sb_dgram_write, /* sbi_write */
946 sb_dgram_close /* sbi_close */
949 #endif /* LDAP_CONNECTIONLESS */