1 /* sockbuf.c - i/o routines with support for adding i/o layers. */
3 * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
14 #include <ac/socket.h>
15 #include <ac/string.h>
16 #include <ac/unistd.h>
20 #endif /* HAVE_IO_H */
22 #if defined( HAVE_SYS_FILIO_H )
23 #include <sys/filio.h>
24 #elif defined( HAVE_SYS_IOCTL_H )
25 #include <sys/ioctl.h>
31 #undef TEST_PARTIAL_READ
32 #undef TEST_PARTIAL_WRITE
35 #define MAX_BUF_SIZE 65535
36 #define MIN_BUF_SIZE 4096
38 #define sockbuf_io_write( sb, buf, len ) \
39 ((sb)->sb_io->sbi_write( (sb), (buf), (len) ))
41 #define sockbuf_io_read( sb, buf, len ) \
42 ((sb)->sb_io->sbi_read( (sb), (buf), (len) ))
44 static long have_no_read( Sockbuf *sb, void *buf, long len );
45 static long have_no_write( Sockbuf *sb, void *buf, long len );
46 static int have_no_close( Sockbuf *sb );
48 static Sockbuf_IO sb_IO_None=
51 NULL, /* sbi_release */
52 have_no_read, /* sbi_read */
53 have_no_write, /* sbi_write */
54 have_no_close /* sbi_close */
58 update_status( Sockbuf *sb )
62 sb->sb_buf_ready = (sb->sb_buf.buf_ptr < sb->sb_buf.buf_end);
64 sb->sb_sec_ready = ((sb->sb_sec_buf_in.buf_end!=0) &&
65 (sb->sb_sec_buf_in.buf_ptr >=
66 sb->sb_sec_buf_in.buf_end));
72 status_is_ok( Sockbuf *sb )
81 obr = sb->sb_buf_ready;
83 osr = sb->sb_sec_ready;
87 if (obr!=sb->sb_buf_ready)
91 if (osr!=sb->sb_sec_ready)
101 packet_length( char *buf )
105 assert( buf != NULL );
107 size = (((unsigned long)buf[0])<<24)|
108 (((unsigned long)buf[1])<<16)|
109 (((unsigned long)buf[2])<<8)|
110 (((unsigned long)buf[3]));
112 if ((size<0) || (size>MAX_BUF_SIZE)) {
113 /* somebody is trying to mess me up. */
114 lber_log_printf( LDAP_DEBUG_SASL, sb->sb_debug,
115 "SASL: received packet length of %d bytes\n",
117 size = 16; /* this should lead to an error. */
120 return size + 4; /* include the size !!! */
125 grow_buffer( Sockbuf_Buf * buf, long minsize )
129 assert( buf != NULL );
131 for( pw=MIN_BUF_SIZE; pw<minsize; pw<<=1 ) {
132 if (pw > MAX_BUF_SIZE) {
133 /* this could mean that somebody is trying to crash us. */
139 if (buf->buf_size<minsize) {
140 if ((buf->buf_base==NULL) || ((buf->buf_end==0) && (buf->buf_ptr==0))) {
142 if (buf->buf_base!=NULL)
143 free( buf->buf_base );
144 assert( buf->buf_ptr==0 );
145 assert( buf->buf_end==0 );
146 buf->buf_base = malloc( minsize );
147 if (buf->buf_base==NULL)
151 nb = realloc( buf->buf_base, minsize );
156 buf->buf_size = minsize;
163 sockbuf_sec_release( Sockbuf *sb, char *buf, long len )
165 /* when this is called:
166 * sb->sb_sec_buf_in.buf_base points to a packet.
167 * sb->sb_sec_buf_in.buf_ptr contains the total bytes read.
168 * sb->sb_sec_end.buf_end contains the packet length.
170 * sb->sb_buf.buf_ptr == sb->sb_buf.buf_end == 0;
178 assert( buf != NULL );
179 assert( sb != NULL );
181 assert( sb->sb_sec );
182 assert( sb->sb_sec->sbs_release );
183 assert( sb->sb_sec_buf_in.sb_ptr >= sb->sb_sec_buf_in.sb_end );
185 assert( sb->sb_buf.sb_ptr == 0 );
186 assert( sb->sb_buf.sb_end == 0 );
188 assert( status_is_ok(sb) );
192 ptr = sb->sb_sec_buf_in.buf_base;
193 end = ptr+ sb->sb_sec_buf_in.buf_ptr;
194 size = sb->sb_sec_buf_in.buf_end;
196 sb->sb_sec_ready = 1;
198 for(;(ptr+size<=end);) {
200 rlen = sb->sb_sec->sbs_release( sb, ptr, size,
203 sb->sb_buf.buf_size );
205 /* this means a security violation. */
206 return total; /* total ? total : 0 */
209 /* this means that the buffer isn't big enough. */
210 if (grow_buffer( &(sb->sb_buf), -rlen )<0)
211 /* memory violation. */
212 return total; /* total ? total : 0 */
220 /* move to the next packet... */
224 size = packet_length( ptr );
225 /* size is always at least 4, so the loop condition is always OK !!*/
232 sb->sb_buf_ready = (sb->sb_buf.buf_end = rlen - len) ? 1 : 0;
238 sb->sb_sec_ready = 0;
239 /* clean up the mess. */
241 /* copy back to beginning of buffer. */
242 SAFEMEMCPY( sb->sb_sec_buf_in.buf_base, ptr, end-ptr );
243 sb->sb_sec_buf_in.buf_ptr = 0;
244 sb->sb_sec_buf_in.buf_end -= (ptr - sb->sb_sec_buf_in.buf_base);
246 assert( status_is_ok(sb) );
251 sockbuf_sec_protect( Sockbuf *sb, char *buf, long len )
257 assert( buf != NULL );
259 assert( sb != NULL );
260 assert( sb->sb_sec_out.buf_end == 0 );
261 assert( sb->sb_sec_out.buf_ptr == 0 );
263 assert( sb->sb_sec );
264 assert( sb->sb_sec->sbs_protect );
266 assert( status_is_ok(sb) );
272 ret = sb->sb_sec->sbs_protect( sb, buf, &blen,
273 sb->sb_sec_out.buf_base+
274 sb->sb_sec_out.buf_end,
275 sb->sb_sec_out.buf_size -
276 sb->sb_sec_out.buf_end );
278 /* protection error ? */
281 if (grow_buffer( &(sb->sb_sec_out),-ret-sb->sb_sec_out.buf_end )<0)
286 /* else if (ret>0) */
289 sb->sb_sec_out.buf_end += ret;
293 assert( status_is_ok(sb) );
299 sockbuf_copy_out( Sockbuf *sb, char **buf, long len )
301 long blen = (sb->sb_buf.buf_end - sb->sb_buf.buf_ptr );
303 assert( buf != NULL );
305 assert( sb != NULL );
306 assert( status_is_ok(sb) );
309 long rlen = (blen<len) ? blen : len;
310 memcpy( *buf, sb->sb_buf.buf_base + sb->sb_buf.buf_ptr, rlen );
311 sb->sb_buf.buf_ptr+=rlen;
314 if (sb->sb_buf.buf_ptr >= sb->sb_buf.buf_end) {
315 sb->sb_buf.buf_ptr = sb->sb_buf.buf_end = 0;
316 sb->sb_buf_ready = 0;
318 sb->sb_buf_ready = 1;
321 assert( status_is_ok(sb) );
325 Sockbuf *ber_sockbuf_alloc( void )
327 Sockbuf *sb = calloc(1, sizeof(Sockbuf));
329 if( sb == NULL ) return NULL;
331 ber_pvt_sb_init( sb );
335 Sockbuf *ber_sockbuf_alloc_fd( int fd )
337 Sockbuf *sb = ber_sockbuf_alloc();
339 if( sb == NULL ) return NULL;
341 ber_pvt_sb_set_desc( sb, fd );
342 ber_pvt_sb_set_io( sb, &ber_pvt_sb_io_tcp, NULL );
346 void ber_sockbuf_free( Sockbuf *sb )
349 ber_pvt_sb_destroy( sb );
354 ber_pvt_sb_read( Sockbuf *sb, void *buf_arg, long len )
359 assert( buf_arg != NULL );
360 assert( sb != NULL );
361 assert( status_is_ok(sb) );
363 /* breaks slapd :-< */
364 assert( ber_pvt_sb_in_use( sb ) );
367 #ifdef TEST_PARTIAL_READ
368 if ((rand() & 3)==1) { /* 1 out of 4 */
374 len = (rand() % len)+1;
377 buf = (char *) buf_arg;
379 if (sb->sb_buf.buf_ptr!=sb->sb_buf.buf_end) {
380 len = sockbuf_copy_out( sb, &buf, len );
382 return (buf - (char *) buf_arg);
389 assert( sb->sb_sec->sbs_release );
390 assert( sb->sb_sec_buf_in.buf_base );
391 if (sb->sb_read_ahead) {
392 max = sb->sb_sec_buf_in.buf_size - sb->sb_sec_buf_in.buf_ptr;
394 max = sb->sb_sec_buf_in.buf_end - sb->sb_sec_buf_in.buf_ptr;
396 /* special situation. This means that we need to read the first
397 * four bytes for the packet length.
403 /* read from stream into sb_sec_buf_in */
405 ret = sockbuf_io_read( sb, sb->sb_sec_buf_in.buf_base +
406 sb->sb_sec_buf_in.buf_ptr, max );
408 if ((ret<0) && (errno==EINTR))
414 /* read error. return */
417 sb->sb_sec_buf_in.buf_ptr += ret;
419 if (sb->sb_sec_buf_in.buf_ptr < sb->sb_sec_buf_in.buf_end) {
420 /* did not finish a packet. give up. */
424 if (sb->sb_sec_buf_in.buf_end == 0) {
425 /* Were trying to read the first four bytes... */
426 if (sb->sb_sec_buf_in.buf_ptr < 4) {
427 /* did not read enough for packet length. give up. */
430 /* calculate the packet length. */
431 sb->sb_sec_buf_in.buf_end =
432 packet_length(sb->sb_sec_buf_in.buf_base );
433 if ((sb->sb_sec_buf_in.buf_end > sb->sb_sec_buf_in.buf_size) &&
434 (grow_buffer( &(sb->sb_sec_buf_in), sb->sb_sec_buf_in.buf_end)<0)) {
435 /* buffer has to be to big. exit with error. */
439 if (sb->sb_sec_buf_in.buf_ptr >= sb_sec_buf_in.buf_end) {
440 /* finished packet. decode it. */
443 /* did not finish packet yet. try again ? */
444 if (sb->sb_read_ahead) {
445 /* we were trying to read the max anyway. forget it */
450 /* we read enough for at least 1 packet */
451 ret = sockbuf_sec_release( sb, buf, len );
453 /* something went wrong... */
458 /* we are finished !!! */
459 if ((len==0) || (ret!=max))
464 if (sb->sb_read_ahead) {
466 max = sb->sb_buf.buf_size - sb->sb_buf.buf_end;
469 ret = sockbuf_io_read( sb,
470 sb->sb_buf.buf_base +
474 if ((ret<0) && (errno==EINTR))
480 /* some error occured */
483 sb->sb_buf.buf_end += ret;
484 /* move out the data... */
485 len = sockbuf_copy_out( sb, &buf, len );
489 /* no read_ahead, just try to put the data in the buf. */
491 ret = sockbuf_io_read( sb, buf, len );
493 if ((ret<0) && (errno==EINTR))
502 /* we might as well return, since there is nothing to do... */
507 assert( status_is_ok(sb) );
508 if ((ret<=0) && (buf==buf_arg)) {
509 /* there was an error. */
512 return (buf - ((char *) buf_arg));
516 long sockbuf_do_write( Sockbuf *sb )
520 assert( sb != NULL );
522 to_go = sb->sb_sec_out.buf_end - sb->sb_sec_out.buf_ptr;
524 /* there is something left of the last time... */
526 ret = sockbuf_io_write( sb, sb->sb_sec_out.buf_base+
527 sb->sb_sec_out.buf_ptr, to_go );
529 if ((ret<0) && (errno==EINTR))
534 if (ret<=0) /* error */
536 sb->sb_sec_out.buf_ptr += ret;
537 if (ret<to_go) /* not enough data, so pretend no data was sent. */
543 long ber_pvt_sb_write( Sockbuf *sb, void *buf, long len_arg )
547 assert( status_is_ok(sb) );
549 /* unfortunately breaks slapd */
550 assert( ber_pvt_sb_in_use( sb ) );
552 #ifdef TEST_PARTIAL_WRITE
553 if ((rand() & 3)==1) { /* 1 out of 4 */
558 len_arg = (rand() % len_arg)+1;
564 assert( sb->sb_sec_prev_len <= len );
565 if (sb->sb_sec_prev_len) {
566 ret = sockbuf_do_write( sb );
570 len -= sb->sb_sec_prev_len;
571 sb->sb_sec_prev_len = 0;
572 sb->sb_sec_out.buf_end = sb->sb_sec_out.buf_ptr = 0;
574 /* now protect the next packet. */
575 ret = sockbuf_sec_protect( sb, buf, len );
578 ret = sockbuf_do_write( sb );
580 sb->sb_sec_prev_len = len;
587 ret = sockbuf_io_write( sb, buf, len );
589 if ((ret<0) && (errno==EINTR))
601 int ber_pvt_sb_close( Sockbuf *sb )
605 assert( sb != NULL );
607 assert( sb->sb_io->sbi_close );
608 assert( status_is_ok(sb) );
609 assert( ber_pvt_sb_in_use( sb ) );
611 ret = sb->sb_io->sbi_close( sb );
612 ber_pvt_sb_set_desc( sb, -1 );
617 int ber_pvt_sb_set_readahead( Sockbuf *sb, int rh )
619 assert( sb != NULL );
620 assert( status_is_ok(sb) );
621 sb->sb_read_ahead = (rh!=0);
627 int ber_pvt_sb_set_nonblock( Sockbuf *sb, int nb )
629 assert( sb != NULL );
630 assert( status_is_ok(sb) );
632 sb->sb_non_block = 1;
634 sb->sb_read_ahead = 1;
637 sb->sb_non_block = 0;
639 sb->sb_read_ahead = 0;
642 if (ber_pvt_sb_in_use(sb)) {
644 int flags = fcntl(ber_pvt_sb_get_desc(sb), F_GETFL);
646 return fcntl(ber_pvt_sb_get_desc(sb), F_SETFL, flags);
648 #elif defined( FIONBIO )
649 /* WINSOCK requires the status to be a long */
650 ioctl_t status = (nb!=0);
651 return ioctl( ber_pvt_sb_get_desc(sb), FIONBIO, &status );
658 #define sockbuf_buf_init( bb ) do { \
659 Sockbuf_Buf *sbb = (bb); \
660 sbb->buf_base = NULL; \
667 sockbuf_buf_destroy( Sockbuf_Buf *buf )
669 assert( buf != NULL);
672 free( buf->buf_base );
673 sockbuf_buf_init( buf );
677 int ber_pvt_sb_init( Sockbuf *sb )
681 sb->sb_item_type=LBER_ITEM_SOCKBUF;
684 sb->sb_trans_ready = 0;
685 sb->sb_buf_ready = 0;
687 sb->sb_sec_ready = 0;
689 sb->sb_read_ahead = 0;
690 sb->sb_non_block = 0;
692 sb->sb_iodata = NULL;
693 sb->sb_io = &sb_IO_None;
696 sb->sb_max_incoming = 0;
698 sockbuf_buf_init( &(sb->sb_buf) );
700 sockbuf_buf_init( &(sb->sb_sec_buf_in) );
701 sockbuf_buf_init( &(sb->sb_sec_buf_out) );
704 sb->sb_sec_prev_len = 0;
709 int ber_pvt_sb_destroy( Sockbuf *sb )
713 ber_pvt_sb_clear_sec(sb);
714 sockbuf_buf_destroy( &(sb->sb_sec_buf_in) );
715 sockbuf_buf_destroy( &(sb->sb_sec_buf_out) );
717 ber_pvt_sb_clear_io(sb);
718 sockbuf_buf_destroy( &(sb->sb_buf) );
719 return ber_pvt_sb_init( sb );
723 int ber_pvt_sb_set_sec( Sockbuf *sb, Sockbuf_Sec * sec, void *arg )
727 if ((sb->sb_sec) || (sec==NULL))
732 if ((sec->sbs_setup) && (sec->sbs_setup( sb, arg)<0)) {
736 len = sb->sb_buf.buf_end - sb->sb_buf.buf_ptr;
739 /* move this to the security layer. */
740 if (grow_buffer( &(sb->sb_sec_buf_in), len )<0)
742 memcpy( sb->sb_sec_buf_in.buf_base,
743 sb->sb_buf.buf_base + sb->sb_buf.buf_ptr, len );
744 sb->sb_sec_buf_in.buf_ptr = len;
745 sb->sb_sec_buf_in.buf_end = (len>4) ? packet_length( sb->sb_sec_buf_in ) : 0;
746 sb->sb_buf.buf_ptr = sb->sb_buf.buf_end = 0;
752 int ber_pvt_sb_clear_sec( Sockbuf *sb )
756 if (sb->sb_buf.buf_ptr!=0)
758 if (sb->sb_sec==NULL)
760 if ((sb->sb_sec->sbs_remove) && (sb->sb_sec->sbs_remove(sb)<0))
764 if (sb->sb_sec_buf_in.buf_ptr!=0) {
765 if (grow_buffer( &(sb->sb_buf),
766 sb->sb_buf.buf_end + sb->sb_sec_buf_in.buf_ptr)<0)
768 memcpy( sb->sb_buf.buf_base + sb->sb_buf.buf_end,
769 sb->sb_sec_buf_in.buf_base, sb->sb_sec_buf_in.buf_ptr );
770 sb->sb_buf.buf_end += sb->sb_sec_buf_in.buf_ptr;
771 sb->sb_buf_ready = 1;
773 sockbuf_buf_destroy( &(sb->sb_sec_buf_in) );
774 assert( sb->sb_sec_buf.buf_end==0 );
775 sockbuf_buf_destroy( &(sb->sb_sec_buf_out) );
777 sb->sb_sec_ready = 0;
783 int ber_pvt_sb_set_io( Sockbuf *sb, Sockbuf_IO *trans, void *arg )
786 assert( sb->sb_io == &sb_IO_None );
793 if ((trans->sbi_setup) && (trans->sbi_setup( sb, arg)<0))
799 int ber_pvt_sb_clear_io( Sockbuf *sb )
802 if (sb->sb_io==&sb_IO_None)
805 if ((sb->sb_io->sbi_remove) && (sb->sb_io->sbi_remove( sb )<0))
808 sb->sb_io = &sb_IO_None;
810 sb->sb_trans_ready = 0;
820 stream_read( Sockbuf *sb, void *buf, long len )
826 * MacTCP/OpenTransport
828 return tcpread( ber_pvt_sb_get_desc(sb), 0, (unsigned char *)buf,
831 #elif defined( HAVE_PCNFS ) || \
832 defined( HAVE_WINSOCK ) || defined ( __BEOS__ )
837 * Windows Socket API (under DOS/Windows 3.x)
840 * 32-bit Windows Socket API (under Windows NT or Windows 95)
844 rc = recv( ber_pvt_sb_get_desc(sb), buf, len, 0 );
846 if ( rc < 0 ) errno = WSAGetLastError();
850 #elif defined( HAVE_NCSA )
852 * NCSA Telnet TCP/IP stack (under DOS)
854 return nread( ber_pvt_sb_get_desc(sb), buf, len );
857 return read( ber_pvt_sb_get_desc(sb), buf, len );
862 stream_write( Sockbuf *sb, void *buf, long len )
868 * MacTCP/OpenTransport
870 #define MAX_WRITE 65535
871 return tcpwrite( ber_pvt_sb_get_desc(sb),
872 (unsigned char *)(buf),
873 (len<MAX_WRITE)? len : MAX_WRITE );
875 #elif defined( HAVE_PCNFS) \
876 || defined( HAVE_WINSOCK) || defined ( __BEOS__ )
881 * Windows Socket API (under DOS/Windows 3.x)
884 * 32-bit Windows Socket API (under Windows NT or Windows 95)
889 rc = send( ber_pvt_sb_get_desc(sb), buf, len, 0 );
891 if ( rc < 0 ) errno = WSAGetLastError();
896 #elif defined(HAVE_NCSA)
897 return netwrite( ber_pvt_sb_get_desc(sb), buf, len );
901 * VMS -- each write must be 64K or smaller
903 #define MAX_WRITE 65535
904 return write( ber_pvt_sb_get_desc(sb), buf,
905 (len<MAX_WRITE)? len : MAX_WRITE);
907 return write( ber_pvt_sb_get_desc(sb), buf, len );
912 stream_close( Sockbuf *sb )
915 tcp_close( ber_pvt_sb_get_desc( sb ) );
919 Sockbuf_IO ber_pvt_sb_io_tcp=
921 NULL, /* sbi_setup */
922 NULL, /* sbi_release */
923 stream_read, /* sbi_read */
924 stream_write, /* sbi_write */
925 stream_close, /* sbi_close */
929 * Support for UDP (CLDAP)
939 dgram_setup( Sockbuf *sb, void *arg )
942 sb->sb_iodata = malloc( sizeof( struct dgram_data ) );
943 if (sb->sb_iodata==NULL)
945 sb->sb_read_ahead = 1; /* important since udp is packet based. */
950 dgram_release( Sockbuf *sb )
953 free( sb->sb_iodata );
958 dgram_read( Sockbuf *sb, void *buf, long len )
960 #ifdef LDAP_CONNECTIONLESS
963 struct dgram_data *dd;
965 assert( sb != NULL );
966 assert( buf != NULL );
968 dd = (struct dgram_data *)(sb->sb_iodata);
970 addrlen = sizeof( struct sockaddr );
971 rc=recvfrom( ber_pvt_sb_get_desc(sb), buf, len, 0, &(dd->src), &addrlen );
973 if ( sb->sb_debug ) {
974 ber_log_printf( LDAP_DEBUG_ANY, sb->sb_debug,
975 "dgram_read udp_read %d bytes\n",
978 ber_log_bprint( LDAP_DEBUG_PACKETS, sb->sb_debug,
982 # else /* LDAP_CONNECTIONLESS */
984 # endif /* LDAP_CONNECTIONLESS */
988 dgram_write( Sockbuf *sb, void *buf, long len )
990 #ifdef LDAP_CONNECTIONLESS
992 struct dgram_data *dd;
994 assert( sb != NULL );
995 assert( buf != NULL );
997 dd = (struct dgram_data *)(sb->sb_iodata);
999 rc=sendto( ber_pvt_sb_get_desc(sb), buf, len, 0, &(dd->dst),
1000 sizeof( struct sockaddr ) );
1005 /* fake error if write was not atomic */
1019 dgram_close( Sockbuf *sb )
1021 assert( sb != NULL );
1023 tcp_close( ber_pvt_sb_get_desc(sb) );
1027 Sockbuf_IO ber_pvt_sb_io_udp=
1029 dgram_setup, /* sbi_setup */
1030 dgram_release, /* sbi_release */
1031 dgram_read, /* sbi_read */
1032 dgram_write, /* sbi_write */
1033 dgram_close, /* sbi_close */
1036 int ber_pvt_sb_udp_set_dst(Sockbuf *sb, void *addr )
1038 struct dgram_data *dd;
1039 assert( sb != NULL );
1040 assert( sb->sb_io == &ber_pvt_sb_io_udp );
1041 dd = (struct dgram_data *) (sb->sb_iodata);
1042 memcpy( &(dd->dst), addr, sizeof( struct sockaddr ) );
1046 void *ber_pvt_sb_udp_get_src( Sockbuf *sb )
1048 struct dgram_data *dd;
1049 assert( sb != NULL );
1050 assert( sb->sb_io == &ber_pvt_sb_io_udp );
1051 dd = (struct dgram_data *) (sb->sb_iodata);
1059 * These routines should really call abort, but at the moment that would
1060 * break the servers.
1064 have_no_read( Sockbuf *sb, void *buf, long len )
1066 assert( sb != NULL );
1067 ber_log_printf( LDAP_DEBUG_ANY, ber_int_debug,
1068 "warning: reading from uninitialized sockbuf\n");
1074 have_no_write( Sockbuf *sb, void *buf, long len )
1076 assert( sb != NULL );
1077 ber_log_printf( LDAP_DEBUG_ANY, ber_int_debug,
1078 "warning: writing to uninitialized sockbuf\n");
1084 have_no_close( Sockbuf *sb )
1086 assert( sb != NULL );