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>
32 #undef TEST_PARTIAL_READ
33 #undef TEST_PARTIAL_WRITE
35 #define assert( cond )
38 #define MAX_BUF_SIZE 65535
39 #define MIN_BUF_SIZE 4096
41 #define sockbuf_io_write( sb, buf, len ) \
42 ((sb)->sb_io->sbi_write( (sb), (buf), (len) ))
44 #define sockbuf_io_read( sb, buf, len ) \
45 ((sb)->sb_io->sbi_read( (sb), (buf), (len) ))
47 static long have_no_read( Sockbuf *sb, void *buf, long len );
48 static long have_no_write( Sockbuf *sb, void *buf, long len );
49 static int have_no_close( Sockbuf *sb );
51 static Sockbuf_IO lber_pvt_sb_IO_None=
54 NULL, /* sbi_release */
55 have_no_read, /* sbi_read */
56 have_no_write, /* sbi_write */
57 have_no_close /* sbi_close */
61 update_status( Sockbuf *sb )
63 sb->sb_buf_ready = (sb->sb_buf.buf_ptr < sb->sb_buf.buf_end);
65 sb->sb_sec_ready = ((sb->sb_sec_buf_in.buf_end!=0) &&
66 (sb->sb_sec_buf_in.buf_ptr >=
67 sb->sb_sec_buf_in.buf_end));
73 status_is_ok( Sockbuf *sb )
77 obr = sb->sb_buf_ready;
79 osr = sb->sb_sec_ready;
82 if (obr!=sb->sb_buf_ready)
85 if (osr!=sb->sb_sec_ready)
94 packet_length( char *buf )
97 size = (((unsigned long)buf[0])<<24)|
98 (((unsigned long)buf[1])<<16)|
99 (((unsigned long)buf[2])<<8)|
100 (((unsigned long)buf[3]));
102 if ((size<0) || (size>MAX_BUF_SIZE)) {
103 /* somebody is trying to mess me up. */
104 lber_log_printf( LDAP_DEBUG_SASL, sb->sb_debug,
105 "SASL: received packet length of %d bytes\n",
107 size = 16; /* this should lead to an error. */
110 return size + 4; /* include the size !!! */
115 grow_buffer( Sockbuf_Buf * buf, long minsize )
117 long pw=MIN_BUF_SIZE;
119 for(;(pw<minsize);pw<<=1) {
120 if (pw > MAX_BUF_SIZE) {
121 /* this could mean that somebody is trying to crash us. */
127 if (buf->buf_size<minsize) {
128 if ((buf->buf_base==NULL) || ((buf->buf_end==0) && (buf->buf_ptr==0))) {
130 if (buf->buf_base!=NULL)
131 free( buf->buf_base );
132 assert( buf->buf_ptr==0 );
133 assert( buf->buf_end==0 );
134 buf->buf_base = malloc( minsize );
135 if (buf->buf_base==NULL)
139 nb = realloc( buf->buf_base, minsize );
144 buf->buf_size = minsize;
151 sockbuf_sec_release( Sockbuf *sb, char *buf, long len )
153 /* when this is called:
154 * sb->sb_sec_buf_in.buf_base points to a packet.
155 * sb->sb_sec_buf_in.buf_ptr contains the total bytes read.
156 * sb->sb_sec_end.buf_end contains the packet length.
158 * sb->sb_buf.buf_ptr == sb->sb_buf.buf_end == 0;
166 assert( sb->sb_sec );
167 assert( sb->sb_sec->sbs_release );
168 assert( sb->sb_sec_buf_in.sb_ptr >= sb->sb_sec_buf_in.sb_end );
170 assert( sb->sb_buf.sb_ptr == 0 );
171 assert( sb->sb_buf.sb_end == 0 );
173 assert( status_is_ok(sb) );
177 ptr = sb->sb_sec_buf_in.buf_base;
178 end = ptr+ sb->sb_sec_buf_in.buf_ptr;
179 size = sb->sb_sec_buf_in.buf_end;
181 sb->sb_sec_ready = 1;
183 for(;(ptr+size<=end);) {
185 rlen = sb->sb_sec->sbs_release( sb, ptr, size,
188 sb->sb_buf.buf_size );
190 /* this means a security violation. */
191 return total; /* total ? total : 0 */
194 /* this means that the buffer isn't big enough. */
195 if (grow_buffer( &(sb->sb_buf), -rlen )<0)
196 /* memory violation. */
197 return total; /* total ? total : 0 */
205 /* move to the next packet... */
209 size = packet_length( ptr );
210 /* size is always at least 4, so the loop condition is always OK !!*/
217 sb->sb_buf_ready = (sb->sb_buf.buf_end = rlen - len) ? 1 : 0;
223 sb->sb_sec_ready = 0;
224 /* clean up the mess. */
226 /* copy back to beginning of buffer. */
227 SAFEMEMCPY( sb->sb_sec_buf_in.buf_base, ptr, end-ptr );
228 sb->sb_sec_buf_in.buf_ptr = 0;
229 sb->sb_sec_buf_in.buf_end -= (ptr - sb->sb_sec_buf_in.buf_base);
231 assert( status_is_ok(sb) );
236 sockbuf_sec_protect( Sockbuf *sb, char *buf, long len )
242 assert( sb->sb_sec_out.buf_end == 0 );
243 assert( sb->sb_sec_out.buf_ptr == 0 );
245 assert( sb->sb_sec );
246 assert( sb->sb_sec->sbs_protect );
248 assert( status_is_ok(sb) );
254 ret = sb->sb_sec->sbs_protect( sb, buf, &blen,
255 sb->sb_sec_out.buf_base+
256 sb->sb_sec_out.buf_end,
257 sb->sb_sec_out.buf_size -
258 sb->sb_sec_out.buf_end );
260 /* protection error ? */
263 if (grow_buffer( &(sb->sb_sec_out),-ret-sb->sb_sec_out.buf_end )<0)
268 /* else if (ret>0) */
271 sb->sb_sec_out.buf_end += ret;
275 assert( status_is_ok(sb) );
281 sockbuf_copy_out( Sockbuf *sb, char **buf, long len )
283 long blen = (sb->sb_buf.buf_end - sb->sb_buf.buf_ptr );
284 assert( status_is_ok(sb) );
286 long rlen = (blen<len) ? blen : len;
287 memcpy( *buf, sb->sb_buf.buf_base + sb->sb_buf.buf_ptr, rlen );
288 sb->sb_buf.buf_ptr+=rlen;
291 if (sb->sb_buf.buf_ptr >= sb->sb_buf.buf_end) {
292 sb->sb_buf.buf_ptr = sb->sb_buf.buf_end = 0;
293 sb->sb_buf_ready = 0;
295 sb->sb_buf_ready = 1;
298 assert( status_is_ok(sb) );
304 lber_pvt_sb_read( Sockbuf *sb, void *buf_arg, long len )
309 assert( status_is_ok(sb) );
311 /* breaks slapd :-) */
312 assert( lber_pvt_sb_in_use( sb ) );
315 #ifdef TEST_PARTIAL_READ
316 if ((rand() & 3)==1) { /* 1 out of 4 */
321 len = (rand() % len)+1;
324 buf = (char *) buf_arg;
326 if (sb->sb_buf.buf_ptr!=sb->sb_buf.buf_end) {
327 len = sockbuf_copy_out( sb, &buf, len );
329 return (buf - (char *) buf_arg);
336 assert( sb->sb_sec->sbs_release );
337 assert( sb->sb_sec_buf_in.buf_base );
338 if (sb->sb_read_ahead) {
339 max = sb->sb_sec_buf_in.buf_size - sb->sb_sec_buf_in.buf_ptr;
341 max = sb->sb_sec_buf_in.buf_end - sb->sb_sec_buf_in.buf_ptr;
343 /* special situation. This means that we need to read the first
344 * four bytes for the packet length.
350 /* read from stream into sb_sec_buf_in */
352 ret = sockbuf_io_read( sb, sb->sb_sec_buf_in.buf_base +
353 sb->sb_sec_buf_in.buf_ptr, max );
355 if ((ret<0) && (errno==EINTR))
361 /* read error. return */
364 sb->sb_sec_buf_in.buf_ptr += ret;
366 if (sb->sb_sec_buf_in.buf_ptr < sb->sb_sec_buf_in.buf_end) {
367 /* did not finish a packet. give up. */
371 if (sb->sb_sec_buf_in.buf_end == 0) {
372 /* Were trying to read the first four bytes... */
373 if (sb->sb_sec_buf_in.buf_ptr < 4) {
374 /* did not read enough for packet length. give up. */
377 /* calculate the packet length. */
378 sb->sb_sec_buf_in.buf_end =
379 packet_length(sb->sb_sec_buf_in.buf_base );
380 if ((sb->sb_sec_buf_in.buf_end > sb->sb_sec_buf_in.buf_size) &&
381 (grow_buffer( &(sb->sb_sec_buf_in), sb->sb_sec_buf_in.buf_end)<0)) {
382 /* buffer has to be to big. exit with error. */
386 if (sb->sb_sec_buf_in.buf_ptr >= sb_sec_buf_in.buf_end) {
387 /* finished packet. decode it. */
390 /* did not finish packet yet. try again ? */
391 if (sb->sb_read_ahead) {
392 /* we were trying to read the max anyway. forget it */
397 /* we read enough for at least 1 packet */
398 ret = sockbuf_sec_release( sb, buf, len );
400 /* something went wrong... */
405 /* we are finished !!! */
406 if ((len==0) || (ret!=max))
411 if (sb->sb_read_ahead) {
413 max = sb->sb_buf.buf_size - sb->sb_buf.buf_end;
416 ret = sockbuf_io_read( sb,
417 sb->sb_buf.buf_base +
421 if ((ret<0) && (errno==EINTR))
427 /* some error occured */
430 sb->sb_buf.buf_end += ret;
431 /* move out the data... */
432 len = sockbuf_copy_out( sb, &buf, len );
436 /* no read_ahead, just try to put the data in the buf. */
438 ret = sockbuf_io_read( sb, buf, len );
440 if ((ret<0) && (errno==EINTR))
449 /* we might as well return, since there is nothing to do... */
454 assert( status_is_ok(sb) );
455 if ((ret<=0) && (buf==buf_arg)) {
456 /* there was an error. */
459 return (buf - ((char *) buf_arg));
463 long sockbuf_do_write( Sockbuf *sb )
466 to_go = sb->sb_sec_out.buf_end - sb->sb_sec_out.buf_ptr;
468 /* there is something left of the last time... */
470 ret = sockbuf_io_write( sb, sb->sb_sec_out.buf_base+
471 sb->sb_sec_out.buf_ptr, to_go );
473 if ((ret<0) && (errno==EINTR))
478 if (ret<=0) /* error */
480 sb->sb_sec_out.buf_ptr += ret;
481 if (ret<to_go) /* not enough data, so pretend no data was sent. */
487 long lber_pvt_sb_write( Sockbuf *sb, void *buf, long len_arg )
491 assert( status_is_ok(sb) );
493 /* unfortunately breaks slapd */
494 assert( lber_pvt_sb_in_use( sb ) );
496 #ifdef TEST_PARTIAL_WRITE
497 if ((rand() & 3)==1) { /* 1 out of 4 */
502 len_arg = (rand() % len_arg)+1;
508 assert( sb->sb_sec_prev_len <= len );
509 if (sb->sb_sec_prev_len) {
510 ret = sockbuf_do_write( sb );
514 len -= sb->sb_sec_prev_len;
515 sb->sb_sec_prev_len = 0;
516 sb->sb_sec_out.buf_end = sb->sb_sec_out.buf_ptr = 0;
518 /* now protect the next packet. */
519 ret = sockbuf_sec_protect( sb, buf, len );
522 ret = sockbuf_do_write( sb );
524 sb->sb_sec_prev_len = len;
531 ret = sockbuf_io_write( sb, buf, len );
533 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);
564 int lber_pvt_sb_set_nonblock( Sockbuf *sb, int nb )
566 assert( status_is_ok(sb) );
568 sb->sb_non_block = 1;
570 sb->sb_read_ahead = 1;
573 sb->sb_non_block = 0;
575 sb->sb_read_ahead = 0;
578 if (lber_pvt_sb_in_use(sb)) {
579 int status = (nb!=0);
580 if (ioctl( lber_pvt_sb_get_desc(sb), FIONBIO, (caddr_t)&status ) == -1 ) {
587 #define sockbuf_buf_init( bb ) \
588 (bb)->buf_base=NULL;\
594 sockbuf_buf_destroy( Sockbuf_Buf *buf )
597 free( buf->buf_base );
598 sockbuf_buf_init( buf );
602 int lber_pvt_sb_init( Sockbuf *sb )
604 sb->sb_item_type=LBER_ITEM_SOCKBUF;
607 sb->sb_trans_ready = 0;
608 sb->sb_buf_ready = 0;
610 sb->sb_sec_ready = 0;
612 sb->sb_read_ahead = 0;
613 sb->sb_non_block = 0;
615 sb->sb_iodata = NULL;
616 sb->sb_io = &lber_pvt_sb_IO_None;
619 sb->sb_max_incoming = 0;
621 sockbuf_buf_init( &(sb->sb_buf) );
623 sockbuf_buf_init( &(sb->sb_sec_buf_in) );
624 sockbuf_buf_init( &(sb->sb_sec_buf_out) );
627 sb->sb_sec_prev_len = 0;
632 int lber_pvt_sb_destroy( Sockbuf *sb )
635 lber_pvt_sb_clear_sec(sb);
636 sockbuf_buf_destroy( &(sb->sb_sec_buf_in) );
637 sockbuf_buf_destroy( &(sb->sb_sec_buf_out) );
639 lber_pvt_sb_clear_io(sb);
640 sockbuf_buf_destroy( &(sb->sb_buf) );
641 return lber_pvt_sb_init( sb );
645 int lber_pvt_sb_set_sec( Sockbuf *sb, Sockbuf_Sec * sec, void *arg )
648 if ((sb->sb_sec) || (sec==NULL))
653 if ((sec->sbs_setup) && (sec->sbs_setup( sb, arg)<0)) {
657 len = sb->sb_buf.buf_end - sb->sb_buf.buf_ptr;
660 /* move this to the security layer. */
661 if (grow_buffer( &(sb->sb_sec_buf_in), len )<0)
663 memcpy( sb->sb_sec_buf_in.buf_base,
664 sb->sb_buf.buf_base + sb->sb_buf.buf_ptr, len );
665 sb->sb_sec_buf_in.buf_ptr = len;
666 sb->sb_sec_buf_in.buf_end = (len>4) ? packet_length( sb->sb_sec_buf_in ) : 0;
667 sb->sb_buf.buf_ptr = sb->sb_buf.buf_end = 0;
673 int lber_pvt_sb_clear_sec( Sockbuf *sb )
675 if (sb->sb_buf.buf_ptr!=0)
677 if (sb->sb_sec==NULL)
679 if ((sb->sb_sec->sbs_remove) && (sb->sb_sec->sbs_remove(sb)<0))
683 if (sb->sb_sec_buf_in.buf_ptr!=0) {
684 if (grow_buffer( &(sb->sb_buf),
685 sb->sb_buf.buf_end + sb->sb_sec_buf_in.buf_ptr)<0)
687 memcpy( sb->sb_buf.buf_base + sb->sb_buf.buf_end,
688 sb->sb_sec_buf_in.buf_base, sb->sb_sec_buf_in.buf_ptr );
689 sb->sb_buf.buf_end += sb->sb_sec_buf_in.buf_ptr;
690 sb->sb_buf_ready = 1;
692 sockbuf_buf_destroy( &(sb->sb_sec_buf_in) );
693 assert( sb->sb_sec_buf.buf_end==0 );
694 sockbuf_buf_destroy( &(sb->sb_sec_buf_out) );
696 sb->sb_sec_ready = 0;
702 int lber_pvt_sb_set_io( Sockbuf *sb, Sockbuf_IO *trans, void *arg )
704 assert( sb->sb_io == &lber_pvt_sb_IO_None );
711 if ((trans->sbi_setup) && (trans->sbi_setup( sb, arg)<0))
717 int lber_pvt_sb_clear_io( Sockbuf *sb )
719 if (sb->sb_io==&lber_pvt_sb_IO_None)
722 if ((sb->sb_io->sbi_remove) && (sb->sb_io->sbi_remove( sb )<0))
725 sb->sb_io = &lber_pvt_sb_IO_None;
727 sb->sb_trans_ready = 0;
737 stream_read( Sockbuf *sb, void *buf, long len )
741 * MacTCP/OpenTransport
743 return tcpread( lber_pvt_sb_get_desc(sb), 0, (unsigned char *)buf,
745 #elif (defined(DOS) && (defined(PCNFS) || defined( WINSOCK))) \
751 * Windows Socket API (under DOS/Windows 3.x)
754 * 32-bit Windows Socket API (under Windows NT or Windows 95)
756 return recv( lber_pvt_sb_get_desc(sb), buf, len, 0 );
757 #elif (defined(DOS) && defined( NCSA ))
759 * NCSA Telnet TCP/IP stack (under DOS)
761 return nread( lber_pvt_sb_get_desc(sb), buf, len );
763 return read( lber_pvt_sb_get_desc(sb), buf, len );
768 stream_write( Sockbuf *sb, void *buf, long len )
772 * MacTCP/OpenTransport
774 #define MAX_WRITE 65535
775 return tcpwrite( lber_pvt_sb_get_desc(sb),
776 (unsigned char *)(buf),
777 (len<MAX_WRITE)? len : MAX_WRITE );
778 #elif (defined(DOS) && (defined(PCNFS) || defined( WINSOCK))) \
784 * Windows Socket API (under DOS/Windows 3.x)
787 * 32-bit Windows Socket API (under Windows NT or Windows 95)
789 return send( lber_pvt_sb_get_desc(sb), buf, len, 0 );
791 return netwrite( lber_pvt_sb_get_desc(sb), buf, len );
794 * VMS -- each write must be 64K or smaller
796 #define MAX_WRITE 65535
797 return write( lber_pvt_sb_get_desc(sb), buf,
798 (len<MAX_WRITE)? len : MAX_WRITE);
800 return write( lber_pvt_sb_get_desc(sb), buf, len );
805 stream_close( Sockbuf *sb )
807 tcp_close( lber_pvt_sb_get_desc( sb ) );
811 Sockbuf_IO lber_pvt_sb_io_tcp=
813 NULL, /* sbi_setup */
814 NULL, /* sbi_release */
815 stream_read, /* sbi_read */
816 stream_write, /* sbi_write */
817 stream_close, /* sbi_close */
821 * Support for UDP (CLDAP)
831 dgram_setup( Sockbuf *sb, void *arg )
833 sb->sb_iodata = malloc( sizeof( struct dgram_data ) );
834 if (sb->sb_iodata==NULL)
836 sb->sb_read_ahead = 1; /* important since udp is packet based. */
841 dgram_release( Sockbuf *sb )
843 free( sb->sb_iodata );
848 dgram_read( Sockbuf *sb, void *buf, long len )
850 #ifdef LDAP_CONNECTIONLESS
853 struct dgram_data *dd;
855 dd = (struct dgram_data *)(sb->sb_iodata);
857 # if !defined( MACOS) && !defined(DOS) && !defined( _WIN32)
858 addrlen = sizeof( struct sockaddr );
859 rc=recvfrom( lber_pvt_sb_get_desc(sb), buf, len, 0, &(dd->src), &addrlen );
864 if ( sb->sb_debug ) {
865 lber_log_printf( LDAP_DEBUG_ANY, sb->sb_debug,
866 "dgram_read udp_read %d bytes\n",
869 lber_log_bprint( LDAP_DEBUG_PACKETS, sb->sb_debug,
873 # else /* LDAP_CONNECTIONLESS */
875 # endif /* LDAP_CONNECTIONLESS */
879 dgram_write( Sockbuf *sb, void *buf, long len )
881 #ifdef LDAP_CONNECTIONLESS
883 struct dgram_data *dd;
885 dd = (struct dgram_data *)(sb->sb_iodata);
887 # if !defined( MACOS) && !defined(DOS) && !defined( _WIN32)
888 rc=sendto( lber_pvt_sb_get_desc(sb), buf, len, 0, &(dd->dst),
889 sizeof( struct sockaddr ) );
896 /* fake error if write was not atomic */
910 dgram_close( Sockbuf *sb )
912 tcp_close( lber_pvt_sb_get_desc(sb) );
916 Sockbuf_IO lber_pvt_sb_io_udp=
918 dgram_setup, /* sbi_setup */
919 dgram_release, /* sbi_release */
920 dgram_read, /* sbi_read */
921 dgram_write, /* sbi_write */
922 dgram_close, /* sbi_close */
925 int lber_pvt_sb_udp_set_dst(Sockbuf *sb, void *addr )
927 struct dgram_data *dd;
928 assert( sb->sb_io == &lber_pvt_sb_io_udp );
929 dd = (struct dgram_data *) (sb->sb_iodata);
930 memcpy( &(dd->dst), addr, sizeof( struct sockaddr ) );
934 void *lber_pvt_sb_udp_get_src( Sockbuf *sb )
936 struct dgram_data *dd;
937 assert( sb->sb_io == &lber_pvt_sb_io_udp );
938 dd = (struct dgram_data *) (sb->sb_iodata);
946 * These routines should really call abort, but at the moment that would
951 have_no_read( Sockbuf *sb, void *buf, long len )
953 lber_log_printf( LDAP_DEBUG_ANY, lber_int_debug,
954 "warning: reading from uninitialized sockbuf\n");
960 have_no_write( Sockbuf *sb, void *buf, long len )
962 lber_log_printf( LDAP_DEBUG_ANY, lber_int_debug,
963 "warning: writing to uninitialized sockbuf\n");
969 have_no_close( Sockbuf *sb )