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 lber_pvt_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 )
60 sb->sb_buf_ready = (sb->sb_buf.buf_ptr < sb->sb_buf.buf_end);
62 sb->sb_sec_ready = ((sb->sb_sec_buf_in.buf_end!=0) &&
63 (sb->sb_sec_buf_in.buf_ptr >=
64 sb->sb_sec_buf_in.buf_end));
70 status_is_ok( Sockbuf *sb )
72 int obr = sb->sb_buf_ready;
74 int osr = sb->sb_sec_ready;
78 if (obr!=sb->sb_buf_ready)
82 if (osr!=sb->sb_sec_ready)
92 packet_length( char *buf )
95 size = (((unsigned long)buf[0])<<24)|
96 (((unsigned long)buf[1])<<16)|
97 (((unsigned long)buf[2])<<8)|
98 (((unsigned long)buf[3]));
100 if ((size<0) || (size>MAX_BUF_SIZE)) {
101 /* somebody is trying to mess me up. */
102 lber_log_printf( LDAP_DEBUG_SASL, sb->sb_debug,
103 "SASL: received packet length of %d bytes\n",
105 size = 16; /* this should lead to an error. */
108 return size + 4; /* include the size !!! */
113 grow_buffer( Sockbuf_Buf * buf, long minsize )
115 long pw=MIN_BUF_SIZE;
117 for(;(pw<minsize);pw<<=1) {
118 if (pw > MAX_BUF_SIZE) {
119 /* this could mean that somebody is trying to crash us. */
125 if (buf->buf_size<minsize) {
126 if ((buf->buf_base==NULL) || ((buf->buf_end==0) && (buf->buf_ptr==0))) {
128 if (buf->buf_base!=NULL)
129 free( buf->buf_base );
130 assert( buf->buf_ptr==0 );
131 assert( buf->buf_end==0 );
132 buf->buf_base = malloc( minsize );
133 if (buf->buf_base==NULL)
137 nb = realloc( buf->buf_base, minsize );
142 buf->buf_size = minsize;
149 sockbuf_sec_release( Sockbuf *sb, char *buf, long len )
151 /* when this is called:
152 * sb->sb_sec_buf_in.buf_base points to a packet.
153 * sb->sb_sec_buf_in.buf_ptr contains the total bytes read.
154 * sb->sb_sec_end.buf_end contains the packet length.
156 * sb->sb_buf.buf_ptr == sb->sb_buf.buf_end == 0;
164 assert( sb->sb_sec );
165 assert( sb->sb_sec->sbs_release );
166 assert( sb->sb_sec_buf_in.sb_ptr >= sb->sb_sec_buf_in.sb_end );
168 assert( sb->sb_buf.sb_ptr == 0 );
169 assert( sb->sb_buf.sb_end == 0 );
171 assert( status_is_ok(sb) );
175 ptr = sb->sb_sec_buf_in.buf_base;
176 end = ptr+ sb->sb_sec_buf_in.buf_ptr;
177 size = sb->sb_sec_buf_in.buf_end;
179 sb->sb_sec_ready = 1;
181 for(;(ptr+size<=end);) {
183 rlen = sb->sb_sec->sbs_release( sb, ptr, size,
186 sb->sb_buf.buf_size );
188 /* this means a security violation. */
189 return total; /* total ? total : 0 */
192 /* this means that the buffer isn't big enough. */
193 if (grow_buffer( &(sb->sb_buf), -rlen )<0)
194 /* memory violation. */
195 return total; /* total ? total : 0 */
203 /* move to the next packet... */
207 size = packet_length( ptr );
208 /* size is always at least 4, so the loop condition is always OK !!*/
215 sb->sb_buf_ready = (sb->sb_buf.buf_end = rlen - len) ? 1 : 0;
221 sb->sb_sec_ready = 0;
222 /* clean up the mess. */
224 /* copy back to beginning of buffer. */
225 SAFEMEMCPY( sb->sb_sec_buf_in.buf_base, ptr, end-ptr );
226 sb->sb_sec_buf_in.buf_ptr = 0;
227 sb->sb_sec_buf_in.buf_end -= (ptr - sb->sb_sec_buf_in.buf_base);
229 assert( status_is_ok(sb) );
234 sockbuf_sec_protect( Sockbuf *sb, char *buf, long len )
240 assert( sb->sb_sec_out.buf_end == 0 );
241 assert( sb->sb_sec_out.buf_ptr == 0 );
243 assert( sb->sb_sec );
244 assert( sb->sb_sec->sbs_protect );
246 assert( status_is_ok(sb) );
252 ret = sb->sb_sec->sbs_protect( sb, buf, &blen,
253 sb->sb_sec_out.buf_base+
254 sb->sb_sec_out.buf_end,
255 sb->sb_sec_out.buf_size -
256 sb->sb_sec_out.buf_end );
258 /* protection error ? */
261 if (grow_buffer( &(sb->sb_sec_out),-ret-sb->sb_sec_out.buf_end )<0)
266 /* else if (ret>0) */
269 sb->sb_sec_out.buf_end += ret;
273 assert( status_is_ok(sb) );
279 sockbuf_copy_out( Sockbuf *sb, char **buf, long len )
281 long blen = (sb->sb_buf.buf_end - sb->sb_buf.buf_ptr );
282 assert( status_is_ok(sb) );
284 long rlen = (blen<len) ? blen : len;
285 memcpy( *buf, sb->sb_buf.buf_base + sb->sb_buf.buf_ptr, rlen );
286 sb->sb_buf.buf_ptr+=rlen;
289 if (sb->sb_buf.buf_ptr >= sb->sb_buf.buf_end) {
290 sb->sb_buf.buf_ptr = sb->sb_buf.buf_end = 0;
291 sb->sb_buf_ready = 0;
293 sb->sb_buf_ready = 1;
296 assert( status_is_ok(sb) );
302 lber_pvt_sb_read( Sockbuf *sb, void *buf_arg, long len )
307 assert( status_is_ok(sb) );
309 /* breaks slapd :-) */
310 assert( lber_pvt_sb_in_use( sb ) );
313 #ifdef TEST_PARTIAL_READ
314 if ((rand() & 3)==1) { /* 1 out of 4 */
319 len = (rand() % len)+1;
322 buf = (char *) buf_arg;
324 if (sb->sb_buf.buf_ptr!=sb->sb_buf.buf_end) {
325 len = sockbuf_copy_out( sb, &buf, len );
327 return (buf - (char *) buf_arg);
334 assert( sb->sb_sec->sbs_release );
335 assert( sb->sb_sec_buf_in.buf_base );
336 if (sb->sb_read_ahead) {
337 max = sb->sb_sec_buf_in.buf_size - sb->sb_sec_buf_in.buf_ptr;
339 max = sb->sb_sec_buf_in.buf_end - sb->sb_sec_buf_in.buf_ptr;
341 /* special situation. This means that we need to read the first
342 * four bytes for the packet length.
348 /* read from stream into sb_sec_buf_in */
350 ret = sockbuf_io_read( sb, sb->sb_sec_buf_in.buf_base +
351 sb->sb_sec_buf_in.buf_ptr, max );
353 if ((ret<0) && (errno==EINTR))
359 /* read error. return */
362 sb->sb_sec_buf_in.buf_ptr += ret;
364 if (sb->sb_sec_buf_in.buf_ptr < sb->sb_sec_buf_in.buf_end) {
365 /* did not finish a packet. give up. */
369 if (sb->sb_sec_buf_in.buf_end == 0) {
370 /* Were trying to read the first four bytes... */
371 if (sb->sb_sec_buf_in.buf_ptr < 4) {
372 /* did not read enough for packet length. give up. */
375 /* calculate the packet length. */
376 sb->sb_sec_buf_in.buf_end =
377 packet_length(sb->sb_sec_buf_in.buf_base );
378 if ((sb->sb_sec_buf_in.buf_end > sb->sb_sec_buf_in.buf_size) &&
379 (grow_buffer( &(sb->sb_sec_buf_in), sb->sb_sec_buf_in.buf_end)<0)) {
380 /* buffer has to be to big. exit with error. */
384 if (sb->sb_sec_buf_in.buf_ptr >= sb_sec_buf_in.buf_end) {
385 /* finished packet. decode it. */
388 /* did not finish packet yet. try again ? */
389 if (sb->sb_read_ahead) {
390 /* we were trying to read the max anyway. forget it */
395 /* we read enough for at least 1 packet */
396 ret = sockbuf_sec_release( sb, buf, len );
398 /* something went wrong... */
403 /* we are finished !!! */
404 if ((len==0) || (ret!=max))
409 if (sb->sb_read_ahead) {
411 max = sb->sb_buf.buf_size - sb->sb_buf.buf_end;
414 ret = sockbuf_io_read( sb,
415 sb->sb_buf.buf_base +
419 if ((ret<0) && (errno==EINTR))
425 /* some error occured */
428 sb->sb_buf.buf_end += ret;
429 /* move out the data... */
430 len = sockbuf_copy_out( sb, &buf, len );
434 /* no read_ahead, just try to put the data in the buf. */
436 ret = sockbuf_io_read( sb, buf, len );
438 if ((ret<0) && (errno==EINTR))
447 /* we might as well return, since there is nothing to do... */
452 assert( status_is_ok(sb) );
453 if ((ret<=0) && (buf==buf_arg)) {
454 /* there was an error. */
457 return (buf - ((char *) buf_arg));
461 long sockbuf_do_write( Sockbuf *sb )
464 to_go = sb->sb_sec_out.buf_end - sb->sb_sec_out.buf_ptr;
466 /* there is something left of the last time... */
468 ret = sockbuf_io_write( sb, sb->sb_sec_out.buf_base+
469 sb->sb_sec_out.buf_ptr, to_go );
471 if ((ret<0) && (errno==EINTR))
476 if (ret<=0) /* error */
478 sb->sb_sec_out.buf_ptr += ret;
479 if (ret<to_go) /* not enough data, so pretend no data was sent. */
485 long lber_pvt_sb_write( Sockbuf *sb, void *buf, long len_arg )
489 assert( status_is_ok(sb) );
491 /* unfortunately breaks slapd */
492 assert( lber_pvt_sb_in_use( sb ) );
494 #ifdef TEST_PARTIAL_WRITE
495 if ((rand() & 3)==1) { /* 1 out of 4 */
500 len_arg = (rand() % len_arg)+1;
506 assert( sb->sb_sec_prev_len <= len );
507 if (sb->sb_sec_prev_len) {
508 ret = sockbuf_do_write( sb );
512 len -= sb->sb_sec_prev_len;
513 sb->sb_sec_prev_len = 0;
514 sb->sb_sec_out.buf_end = sb->sb_sec_out.buf_ptr = 0;
516 /* now protect the next packet. */
517 ret = sockbuf_sec_protect( sb, buf, len );
520 ret = sockbuf_do_write( sb );
522 sb->sb_sec_prev_len = len;
529 ret = sockbuf_io_write( sb, buf, len );
531 if ((ret<0) && (errno==EINTR))
543 int lber_pvt_sb_close( Sockbuf *sb )
547 assert( sb->sb_io->sbi_close );
548 assert( status_is_ok(sb) );
549 assert( lber_pvt_sb_in_use( sb ) );
551 ret = sb->sb_io->sbi_close( sb );
552 lber_pvt_sb_set_desc( sb, -1 );
557 int lber_pvt_sb_set_readahead( Sockbuf *sb, int rh )
559 assert( status_is_ok(sb) );
560 sb->sb_read_ahead = (rh!=0);
566 int lber_pvt_sb_set_nonblock( Sockbuf *sb, int nb )
568 assert( status_is_ok(sb) );
570 sb->sb_non_block = 1;
572 sb->sb_read_ahead = 1;
575 sb->sb_non_block = 0;
577 sb->sb_read_ahead = 0;
580 if (lber_pvt_sb_in_use(sb)) {
582 int flags = fcntl(lber_pvt_sb_get_desc(sb), F_GETFL);
584 return fcntl(lber_pvt_sb_get_desc(sb), F_SETFL, flags);
586 #elif defined( FIONBIO )
587 /* WINSOCK requires the status to be a long */
588 ioctl_t status = (nb!=0);
589 return ioctl( lber_pvt_sb_get_desc(sb), FIONBIO, &status );
596 #define sockbuf_buf_init( bb ) do { \
597 Sockbuf_Buf *sbb = (bb); \
598 sbb->buf_base = NULL; \
605 sockbuf_buf_destroy( Sockbuf_Buf *buf )
608 free( buf->buf_base );
609 sockbuf_buf_init( buf );
613 int lber_pvt_sb_init( Sockbuf *sb )
615 sb->sb_item_type=LBER_ITEM_SOCKBUF;
618 sb->sb_trans_ready = 0;
619 sb->sb_buf_ready = 0;
621 sb->sb_sec_ready = 0;
623 sb->sb_read_ahead = 0;
624 sb->sb_non_block = 0;
626 sb->sb_iodata = NULL;
627 sb->sb_io = &lber_pvt_sb_IO_None;
630 sb->sb_max_incoming = 0;
632 sockbuf_buf_init( &(sb->sb_buf) );
634 sockbuf_buf_init( &(sb->sb_sec_buf_in) );
635 sockbuf_buf_init( &(sb->sb_sec_buf_out) );
638 sb->sb_sec_prev_len = 0;
643 int lber_pvt_sb_destroy( Sockbuf *sb )
646 lber_pvt_sb_clear_sec(sb);
647 sockbuf_buf_destroy( &(sb->sb_sec_buf_in) );
648 sockbuf_buf_destroy( &(sb->sb_sec_buf_out) );
650 lber_pvt_sb_clear_io(sb);
651 sockbuf_buf_destroy( &(sb->sb_buf) );
652 return lber_pvt_sb_init( sb );
656 int lber_pvt_sb_set_sec( Sockbuf *sb, Sockbuf_Sec * sec, void *arg )
659 if ((sb->sb_sec) || (sec==NULL))
664 if ((sec->sbs_setup) && (sec->sbs_setup( sb, arg)<0)) {
668 len = sb->sb_buf.buf_end - sb->sb_buf.buf_ptr;
671 /* move this to the security layer. */
672 if (grow_buffer( &(sb->sb_sec_buf_in), len )<0)
674 memcpy( sb->sb_sec_buf_in.buf_base,
675 sb->sb_buf.buf_base + sb->sb_buf.buf_ptr, len );
676 sb->sb_sec_buf_in.buf_ptr = len;
677 sb->sb_sec_buf_in.buf_end = (len>4) ? packet_length( sb->sb_sec_buf_in ) : 0;
678 sb->sb_buf.buf_ptr = sb->sb_buf.buf_end = 0;
684 int lber_pvt_sb_clear_sec( Sockbuf *sb )
686 if (sb->sb_buf.buf_ptr!=0)
688 if (sb->sb_sec==NULL)
690 if ((sb->sb_sec->sbs_remove) && (sb->sb_sec->sbs_remove(sb)<0))
694 if (sb->sb_sec_buf_in.buf_ptr!=0) {
695 if (grow_buffer( &(sb->sb_buf),
696 sb->sb_buf.buf_end + sb->sb_sec_buf_in.buf_ptr)<0)
698 memcpy( sb->sb_buf.buf_base + sb->sb_buf.buf_end,
699 sb->sb_sec_buf_in.buf_base, sb->sb_sec_buf_in.buf_ptr );
700 sb->sb_buf.buf_end += sb->sb_sec_buf_in.buf_ptr;
701 sb->sb_buf_ready = 1;
703 sockbuf_buf_destroy( &(sb->sb_sec_buf_in) );
704 assert( sb->sb_sec_buf.buf_end==0 );
705 sockbuf_buf_destroy( &(sb->sb_sec_buf_out) );
707 sb->sb_sec_ready = 0;
713 int lber_pvt_sb_set_io( Sockbuf *sb, Sockbuf_IO *trans, void *arg )
715 assert( sb->sb_io == &lber_pvt_sb_IO_None );
722 if ((trans->sbi_setup) && (trans->sbi_setup( sb, arg)<0))
728 int lber_pvt_sb_clear_io( Sockbuf *sb )
730 if (sb->sb_io==&lber_pvt_sb_IO_None)
733 if ((sb->sb_io->sbi_remove) && (sb->sb_io->sbi_remove( sb )<0))
736 sb->sb_io = &lber_pvt_sb_IO_None;
738 sb->sb_trans_ready = 0;
748 stream_read( Sockbuf *sb, void *buf, long len )
752 * MacTCP/OpenTransport
754 return tcpread( lber_pvt_sb_get_desc(sb), 0, (unsigned char *)buf,
757 #elif defined( HAVE_PCNFS ) || \
758 defined( HAVE_WINSOCK ) || defined ( __BEOS__ )
763 * Windows Socket API (under DOS/Windows 3.x)
766 * 32-bit Windows Socket API (under Windows NT or Windows 95)
768 return recv( lber_pvt_sb_get_desc(sb), buf, len, 0 );
770 #elif defined( HAVE_NCSA )
772 * NCSA Telnet TCP/IP stack (under DOS)
774 return nread( lber_pvt_sb_get_desc(sb), buf, len );
777 return read( lber_pvt_sb_get_desc(sb), buf, len );
782 stream_write( Sockbuf *sb, void *buf, long len )
786 * MacTCP/OpenTransport
788 #define MAX_WRITE 65535
789 return tcpwrite( lber_pvt_sb_get_desc(sb),
790 (unsigned char *)(buf),
791 (len<MAX_WRITE)? len : MAX_WRITE );
793 #elif defined( HAVE_PCNFS) \
794 || defined( HAVE_WINSOCK) || defined ( __BEOS__ )
799 * Windows Socket API (under DOS/Windows 3.x)
802 * 32-bit Windows Socket API (under Windows NT or Windows 95)
804 return send( lber_pvt_sb_get_desc(sb), buf, len, 0 );
806 #elif defined(HAVE_NCSA)
807 return netwrite( lber_pvt_sb_get_desc(sb), buf, len );
811 * VMS -- each write must be 64K or smaller
813 #define MAX_WRITE 65535
814 return write( lber_pvt_sb_get_desc(sb), buf,
815 (len<MAX_WRITE)? len : MAX_WRITE);
817 return write( lber_pvt_sb_get_desc(sb), buf, len );
822 stream_close( Sockbuf *sb )
824 tcp_close( lber_pvt_sb_get_desc( sb ) );
828 Sockbuf_IO lber_pvt_sb_io_tcp=
830 NULL, /* sbi_setup */
831 NULL, /* sbi_release */
832 stream_read, /* sbi_read */
833 stream_write, /* sbi_write */
834 stream_close, /* sbi_close */
838 * Support for UDP (CLDAP)
848 dgram_setup( Sockbuf *sb, void *arg )
850 sb->sb_iodata = malloc( sizeof( struct dgram_data ) );
851 if (sb->sb_iodata==NULL)
853 sb->sb_read_ahead = 1; /* important since udp is packet based. */
858 dgram_release( Sockbuf *sb )
860 free( sb->sb_iodata );
865 dgram_read( Sockbuf *sb, void *buf, long len )
867 #ifdef LDAP_CONNECTIONLESS
870 struct dgram_data *dd;
872 dd = (struct dgram_data *)(sb->sb_iodata);
874 addrlen = sizeof( struct sockaddr );
875 rc=recvfrom( lber_pvt_sb_get_desc(sb), buf, len, 0, &(dd->src), &addrlen );
877 if ( sb->sb_debug ) {
878 lber_log_printf( LDAP_DEBUG_ANY, sb->sb_debug,
879 "dgram_read udp_read %d bytes\n",
882 lber_log_bprint( LDAP_DEBUG_PACKETS, sb->sb_debug,
886 # else /* LDAP_CONNECTIONLESS */
888 # endif /* LDAP_CONNECTIONLESS */
892 dgram_write( Sockbuf *sb, void *buf, long len )
894 #ifdef LDAP_CONNECTIONLESS
896 struct dgram_data *dd;
898 dd = (struct dgram_data *)(sb->sb_iodata);
900 rc=sendto( lber_pvt_sb_get_desc(sb), buf, len, 0, &(dd->dst),
901 sizeof( struct sockaddr ) );
906 /* fake error if write was not atomic */
920 dgram_close( Sockbuf *sb )
922 tcp_close( lber_pvt_sb_get_desc(sb) );
926 Sockbuf_IO lber_pvt_sb_io_udp=
928 dgram_setup, /* sbi_setup */
929 dgram_release, /* sbi_release */
930 dgram_read, /* sbi_read */
931 dgram_write, /* sbi_write */
932 dgram_close, /* sbi_close */
935 int lber_pvt_sb_udp_set_dst(Sockbuf *sb, void *addr )
937 struct dgram_data *dd;
938 assert( sb->sb_io == &lber_pvt_sb_io_udp );
939 dd = (struct dgram_data *) (sb->sb_iodata);
940 memcpy( &(dd->dst), addr, sizeof( struct sockaddr ) );
944 void *lber_pvt_sb_udp_get_src( Sockbuf *sb )
946 struct dgram_data *dd;
947 assert( sb->sb_io == &lber_pvt_sb_io_udp );
948 dd = (struct dgram_data *) (sb->sb_iodata);
956 * These routines should really call abort, but at the moment that would
961 have_no_read( Sockbuf *sb, void *buf, long len )
963 lber_log_printf( LDAP_DEBUG_ANY, lber_int_debug,
964 "warning: reading from uninitialized sockbuf\n");
970 have_no_write( Sockbuf *sb, void *buf, long len )
972 lber_log_printf( LDAP_DEBUG_ANY, lber_int_debug,
973 "warning: writing to uninitialized sockbuf\n");
979 have_no_close( Sockbuf *sb )