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
11 #include <ac/stdlib.h>
15 #include <ac/socket.h>
16 #include <ac/string.h>
17 #include <ac/unistd.h>
21 #endif /* HAVE_IO_H */
23 #if defined( HAVE_SYS_FILIO_H )
24 #include <sys/filio.h>
25 #elif defined( HAVE_SYS_IOCTL_H )
26 #include <sys/ioctl.h>
32 #undef TEST_PARTIAL_READ
33 #undef TEST_PARTIAL_WRITE
36 #define MAX_BUF_SIZE 65535
37 #define MIN_BUF_SIZE 4096
39 #define sockbuf_io_write( sb, buf, len ) \
40 ((sb)->sb_io->sbi_write( (sb), (buf), (len) ))
42 #define sockbuf_io_read( sb, buf, len ) \
43 ((sb)->sb_io->sbi_read( (sb), (buf), (len) ))
45 static long have_no_read( Sockbuf *sb, void *buf, long len );
46 static long have_no_write( Sockbuf *sb, void *buf, long len );
47 static int have_no_close( Sockbuf *sb );
49 static Sockbuf_IO sb_IO_None=
52 NULL, /* sbi_release */
53 have_no_read, /* sbi_read */
54 have_no_write, /* sbi_write */
55 have_no_close /* sbi_close */
59 update_status( Sockbuf *sb )
62 assert( SOCKBUF_VALID( sb ) );
64 sb->sb_buf_ready = (sb->sb_buf.buf_ptr < sb->sb_buf.buf_end);
66 sb->sb_sec_ready = ((sb->sb_sec_buf_in.buf_end!=0) &&
67 (sb->sb_sec_buf_in.buf_ptr >=
68 sb->sb_sec_buf_in.buf_end));
74 status_is_ok( Sockbuf *sb )
82 assert( SOCKBUF_VALID( sb ) );
84 obr = sb->sb_buf_ready;
86 osr = sb->sb_sec_ready;
90 if (obr!=sb->sb_buf_ready)
94 if (osr!=sb->sb_sec_ready)
104 packet_length( char *buf )
108 assert( buf != NULL );
110 size = (((unsigned long)buf[0])<<24)|
111 (((unsigned long)buf[1])<<16)|
112 (((unsigned long)buf[2])<<8)|
113 (((unsigned long)buf[3]));
115 if ((size<0) || (size>MAX_BUF_SIZE)) {
116 /* somebody is trying to mess me up. */
117 lber_log_printf( LDAP_DEBUG_SASL, sb->sb_debug,
118 "SASL: received packet length of %d bytes\n",
120 size = 16; /* this should lead to an error. */
123 return size + 4; /* include the size !!! */
128 grow_buffer( Sockbuf_Buf * buf, long minsize )
132 assert( buf != NULL );
134 for( pw=MIN_BUF_SIZE; pw<minsize; pw<<=1 ) {
135 if (pw > MAX_BUF_SIZE) {
136 /* this could mean that somebody is trying to crash us. */
142 if (buf->buf_size<minsize) {
143 if ((buf->buf_base==NULL) || ((buf->buf_end==0) && (buf->buf_ptr==0))) {
145 if (buf->buf_base!=NULL)
146 LBER_FREE( buf->buf_base );
147 assert( buf->buf_ptr==0 );
148 assert( buf->buf_end==0 );
149 buf->buf_base = LBER_MALLOC( minsize );
150 if (buf->buf_base==NULL)
154 nb = LBER_REALLOC( buf->buf_base, minsize );
159 buf->buf_size = minsize;
166 sockbuf_sec_release( Sockbuf *sb, char *buf, long len )
168 /* when this is called:
169 * sb->sb_sec_buf_in.buf_base points to a packet.
170 * sb->sb_sec_buf_in.buf_ptr contains the total bytes read.
171 * sb->sb_sec_end.buf_end contains the packet length.
173 * sb->sb_buf.buf_ptr == sb->sb_buf.buf_end == 0;
181 assert( buf != NULL );
182 assert( sb != NULL );
183 assert( SOCKBUF_VALID( sb ) );
185 assert( sb->sb_sec );
186 assert( sb->sb_sec->sbs_release );
187 assert( sb->sb_sec_buf_in.sb_ptr >= sb->sb_sec_buf_in.sb_end );
189 assert( sb->sb_buf.sb_ptr == 0 );
190 assert( sb->sb_buf.sb_end == 0 );
192 assert( status_is_ok(sb) );
196 ptr = sb->sb_sec_buf_in.buf_base;
197 end = ptr+ sb->sb_sec_buf_in.buf_ptr;
198 size = sb->sb_sec_buf_in.buf_end;
200 sb->sb_sec_ready = 1;
202 for(;(ptr+size<=end);) {
204 rlen = sb->sb_sec->sbs_release( sb, ptr, size,
207 sb->sb_buf.buf_size );
209 /* this means a security violation. */
210 return total; /* total ? total : 0 */
213 /* this means that the buffer isn't big enough. */
214 if (grow_buffer( &(sb->sb_buf), -rlen )<0)
215 /* memory violation. */
216 return total; /* total ? total : 0 */
224 /* move to the next packet... */
228 size = packet_length( ptr );
229 /* size is always at least 4, so the loop condition is always OK !!*/
236 sb->sb_buf_ready = (sb->sb_buf.buf_end = rlen - len) ? 1 : 0;
242 sb->sb_sec_ready = 0;
243 /* clean up the mess. */
245 /* copy back to beginning of buffer. */
246 SAFEMEMCPY( sb->sb_sec_buf_in.buf_base, ptr, end-ptr );
247 sb->sb_sec_buf_in.buf_ptr = 0;
248 sb->sb_sec_buf_in.buf_end -= (ptr - sb->sb_sec_buf_in.buf_base);
250 assert( status_is_ok(sb) );
255 sockbuf_sec_protect( Sockbuf *sb, char *buf, long len )
261 assert( buf != NULL );
263 assert( sb != NULL );
264 assert( SOCKBUF_VALID( sb ) );
266 assert( sb->sb_sec_out.buf_end == 0 );
267 assert( sb->sb_sec_out.buf_ptr == 0 );
269 assert( sb->sb_sec );
270 assert( sb->sb_sec->sbs_protect );
272 assert( status_is_ok(sb) );
278 ret = sb->sb_sec->sbs_protect( sb, buf, &blen,
279 sb->sb_sec_out.buf_base+
280 sb->sb_sec_out.buf_end,
281 sb->sb_sec_out.buf_size -
282 sb->sb_sec_out.buf_end );
284 /* protection error ? */
287 if (grow_buffer( &(sb->sb_sec_out),-ret-sb->sb_sec_out.buf_end )<0)
292 /* else if (ret>0) */
295 sb->sb_sec_out.buf_end += ret;
299 assert( status_is_ok(sb) );
305 sockbuf_copy_out( Sockbuf *sb, char **buf, long len )
307 long blen = (sb->sb_buf.buf_end - sb->sb_buf.buf_ptr );
309 assert( buf != NULL );
311 assert( sb != NULL );
312 assert( SOCKBUF_VALID( sb ) );
313 assert( status_is_ok(sb) );
316 long rlen = (blen<len) ? blen : len;
317 memcpy( *buf, sb->sb_buf.buf_base + sb->sb_buf.buf_ptr, rlen );
318 sb->sb_buf.buf_ptr+=rlen;
321 if (sb->sb_buf.buf_ptr >= sb->sb_buf.buf_end) {
322 sb->sb_buf.buf_ptr = sb->sb_buf.buf_end = 0;
323 sb->sb_buf_ready = 0;
325 sb->sb_buf_ready = 1;
328 assert( status_is_ok(sb) );
332 Sockbuf *ber_sockbuf_alloc( void )
336 ber_int_options.lbo_valid = LBER_INITIALIZED;
338 sb = LBER_CALLOC(1, sizeof(Sockbuf));
340 if( sb == NULL ) return NULL;
342 ber_pvt_sb_init( sb );
346 Sockbuf *ber_sockbuf_alloc_fd( int fd )
348 Sockbuf *sb = ber_sockbuf_alloc();
350 if( sb == NULL ) return NULL;
352 ber_pvt_sb_set_desc( sb, fd );
353 ber_pvt_sb_set_io( sb, &ber_pvt_sb_io_tcp, NULL );
357 void ber_sockbuf_free( Sockbuf *sb )
360 assert( SOCKBUF_VALID( sb ) );
361 ber_pvt_sb_destroy( sb );
366 ber_pvt_sb_read( Sockbuf *sb, void *buf_arg, long len )
371 assert( buf_arg != NULL );
372 assert( sb != NULL );
373 assert( SOCKBUF_VALID( sb ) );
374 assert( status_is_ok(sb) );
376 /* breaks slapd :-< */
377 assert( ber_pvt_sb_in_use( sb ) );
380 #ifdef TEST_PARTIAL_READ
381 if ((rand() & 3)==1) { /* 1 out of 4 */
387 len = (rand() % len)+1;
390 buf = (char *) buf_arg;
392 if (sb->sb_buf.buf_ptr!=sb->sb_buf.buf_end) {
393 len = sockbuf_copy_out( sb, &buf, len );
395 return (buf - (char *) buf_arg);
402 assert( sb->sb_sec->sbs_release );
403 assert( sb->sb_sec_buf_in.buf_base );
404 if (sb->sb_read_ahead) {
405 max = sb->sb_sec_buf_in.buf_size - sb->sb_sec_buf_in.buf_ptr;
407 max = sb->sb_sec_buf_in.buf_end - sb->sb_sec_buf_in.buf_ptr;
409 /* special situation. This means that we need to read the first
410 * four bytes for the packet length.
416 /* read from stream into sb_sec_buf_in */
418 ret = sockbuf_io_read( sb, sb->sb_sec_buf_in.buf_base +
419 sb->sb_sec_buf_in.buf_ptr, max );
421 if ((ret<0) && (errno==EINTR))
427 /* read error. return */
430 sb->sb_sec_buf_in.buf_ptr += ret;
432 if (sb->sb_sec_buf_in.buf_ptr < sb->sb_sec_buf_in.buf_end) {
433 /* did not finish a packet. give up. */
437 if (sb->sb_sec_buf_in.buf_end == 0) {
438 /* Were trying to read the first four bytes... */
439 if (sb->sb_sec_buf_in.buf_ptr < 4) {
440 /* did not read enough for packet length. give up. */
443 /* calculate the packet length. */
444 sb->sb_sec_buf_in.buf_end =
445 packet_length(sb->sb_sec_buf_in.buf_base );
446 if ((sb->sb_sec_buf_in.buf_end > sb->sb_sec_buf_in.buf_size) &&
447 (grow_buffer( &(sb->sb_sec_buf_in), sb->sb_sec_buf_in.buf_end)<0)) {
448 /* buffer has to be to big. exit with error. */
452 if (sb->sb_sec_buf_in.buf_ptr >= sb_sec_buf_in.buf_end) {
453 /* finished packet. decode it. */
456 /* did not finish packet yet. try again ? */
457 if (sb->sb_read_ahead) {
458 /* we were trying to read the max anyway. forget it */
463 /* we read enough for at least 1 packet */
464 ret = sockbuf_sec_release( sb, buf, len );
466 /* something went wrong... */
471 /* we are finished !!! */
472 if ((len==0) || (ret!=max))
477 if (sb->sb_read_ahead) {
479 max = sb->sb_buf.buf_size - sb->sb_buf.buf_end;
482 ret = sockbuf_io_read( sb,
483 sb->sb_buf.buf_base +
487 if ((ret<0) && (errno==EINTR))
493 /* some error occured */
496 sb->sb_buf.buf_end += ret;
497 /* move out the data... */
498 len = sockbuf_copy_out( sb, &buf, len );
502 /* no read_ahead, just try to put the data in the buf. */
504 ret = sockbuf_io_read( sb, buf, len );
506 if ((ret<0) && (errno==EINTR))
515 /* we might as well return, since there is nothing to do... */
520 assert( status_is_ok(sb) );
521 if ((ret<=0) && (buf==buf_arg)) {
522 /* there was an error. */
525 return (buf - ((char *) buf_arg));
529 long sockbuf_do_write( Sockbuf *sb )
533 assert( sb != NULL );
534 assert( SOCKBUF_VALID( sb ) );
536 to_go = sb->sb_sec_out.buf_end - sb->sb_sec_out.buf_ptr;
538 /* there is something left of the last time... */
540 ret = sockbuf_io_write( sb, sb->sb_sec_out.buf_base+
541 sb->sb_sec_out.buf_ptr, to_go );
543 if ((ret<0) && (errno==EINTR))
548 if (ret<=0) /* error */
550 sb->sb_sec_out.buf_ptr += ret;
551 if (ret<to_go) /* not enough data, so pretend no data was sent. */
557 long ber_pvt_sb_write( Sockbuf *sb, void *buf, long len_arg )
562 assert( buf != NULL );
563 assert( sb != NULL );
564 assert( SOCKBUF_VALID( sb ) );
565 assert( status_is_ok(sb) );
567 /* unfortunately breaks slapd */
568 assert( ber_pvt_sb_in_use( sb ) );
570 #ifdef TEST_PARTIAL_WRITE
571 if ((rand() & 3)==1) { /* 1 out of 4 */
576 len_arg = (rand() % len_arg)+1;
582 assert( sb->sb_sec_prev_len <= len );
583 if (sb->sb_sec_prev_len) {
584 ret = sockbuf_do_write( sb );
588 len -= sb->sb_sec_prev_len;
589 sb->sb_sec_prev_len = 0;
590 sb->sb_sec_out.buf_end = sb->sb_sec_out.buf_ptr = 0;
592 /* now protect the next packet. */
593 ret = sockbuf_sec_protect( sb, buf, len );
596 ret = sockbuf_do_write( sb );
598 sb->sb_sec_prev_len = len;
605 ret = sockbuf_io_write( sb, buf, len );
607 if ((ret<0) && (errno==EINTR))
619 int ber_pvt_sb_close( Sockbuf *sb )
623 assert( sb != NULL );
624 assert( SOCKBUF_VALID( sb ) );
626 assert( sb->sb_io->sbi_close );
627 assert( status_is_ok(sb) );
628 assert( ber_pvt_sb_in_use( sb ) );
630 ret = sb->sb_io->sbi_close( sb );
631 ber_pvt_sb_set_desc( sb, -1 );
636 int ber_pvt_sb_set_readahead( Sockbuf *sb, int rh )
638 assert( sb != NULL );
639 assert( SOCKBUF_VALID( sb ) );
640 assert( status_is_ok(sb) );
641 sb->sb_read_ahead = (rh!=0);
647 int ber_pvt_sb_set_nonblock( Sockbuf *sb, int nb )
649 assert( sb != NULL );
650 assert( SOCKBUF_VALID( sb ) );
651 assert( status_is_ok(sb) );
653 sb->sb_non_block = 1;
655 sb->sb_read_ahead = 1;
658 sb->sb_non_block = 0;
660 sb->sb_read_ahead = 0;
663 if (ber_pvt_sb_in_use(sb)) {
665 int flags = fcntl(ber_pvt_sb_get_desc(sb), F_GETFL);
667 return fcntl(ber_pvt_sb_get_desc(sb), F_SETFL, flags);
669 #elif defined( FIONBIO )
670 /* WINSOCK requires the status to be a long */
671 ioctl_t status = (nb!=0);
672 return ioctl( ber_pvt_sb_get_desc(sb), FIONBIO, &status );
679 #define sockbuf_buf_init( bb ) do { \
680 Sockbuf_Buf *sbb = (bb); \
681 sbb->buf_base = NULL; \
688 sockbuf_buf_destroy( Sockbuf_Buf *buf )
690 assert( buf != NULL);
693 LBER_FREE( buf->buf_base );
694 sockbuf_buf_init( buf );
698 int ber_pvt_sb_init( Sockbuf *sb )
702 ber_int_options.lbo_valid = LBER_INITIALIZED;
704 sb->sb_valid=LBER_VALID_SOCKBUF;
707 sb->sb_trans_ready = 0;
708 sb->sb_buf_ready = 0;
710 sb->sb_sec_ready = 0;
712 sb->sb_read_ahead = 0;
713 sb->sb_non_block = 0;
715 sb->sb_iodata = NULL;
716 sb->sb_io = &sb_IO_None;
719 sb->sb_max_incoming = 0;
721 sockbuf_buf_init( &(sb->sb_buf) );
723 sockbuf_buf_init( &(sb->sb_sec_buf_in) );
724 sockbuf_buf_init( &(sb->sb_sec_buf_out) );
727 sb->sb_sec_prev_len = 0;
730 assert( SOCKBUF_VALID( sb ) );
734 int ber_pvt_sb_destroy( Sockbuf *sb )
737 assert( SOCKBUF_VALID(sb) );
739 ber_pvt_sb_clear_sec(sb);
740 sockbuf_buf_destroy( &(sb->sb_sec_buf_in) );
741 sockbuf_buf_destroy( &(sb->sb_sec_buf_out) );
743 ber_pvt_sb_clear_io(sb);
744 sockbuf_buf_destroy( &(sb->sb_buf) );
745 return ber_pvt_sb_init( sb );
749 int ber_pvt_sb_set_sec( Sockbuf *sb, Sockbuf_Sec * sec, void *arg )
753 assert( SOCKBUF_VALID( *sb ) );
754 if ((sb->sb_sec) || (sec==NULL))
759 if ((sec->sbs_setup) && (sec->sbs_setup( sb, arg)<0)) {
763 len = sb->sb_buf.buf_end - sb->sb_buf.buf_ptr;
766 /* move this to the security layer. */
767 if (grow_buffer( &(sb->sb_sec_buf_in), len )<0)
769 memcpy( sb->sb_sec_buf_in.buf_base,
770 sb->sb_buf.buf_base + sb->sb_buf.buf_ptr, len );
771 sb->sb_sec_buf_in.buf_ptr = len;
772 sb->sb_sec_buf_in.buf_end = (len>4) ? packet_length( sb->sb_sec_buf_in ) : 0;
773 sb->sb_buf.buf_ptr = sb->sb_buf.buf_end = 0;
779 int ber_pvt_sb_clear_sec( Sockbuf *sb )
782 assert( SOCKBUF_VALID( sb ) );
784 if (sb->sb_buf.buf_ptr!=0)
786 if (sb->sb_sec==NULL)
788 if ((sb->sb_sec->sbs_remove) && (sb->sb_sec->sbs_remove(sb)<0))
792 if (sb->sb_sec_buf_in.buf_ptr!=0) {
793 if (grow_buffer( &(sb->sb_buf),
794 sb->sb_buf.buf_end + sb->sb_sec_buf_in.buf_ptr)<0)
796 memcpy( sb->sb_buf.buf_base + sb->sb_buf.buf_end,
797 sb->sb_sec_buf_in.buf_base, sb->sb_sec_buf_in.buf_ptr );
798 sb->sb_buf.buf_end += sb->sb_sec_buf_in.buf_ptr;
799 sb->sb_buf_ready = 1;
801 sockbuf_buf_destroy( &(sb->sb_sec_buf_in) );
802 assert( sb->sb_sec_buf.buf_end==0 );
803 sockbuf_buf_destroy( &(sb->sb_sec_buf_out) );
805 sb->sb_sec_ready = 0;
811 int ber_pvt_sb_set_io( Sockbuf *sb, Sockbuf_IO *trans, void *arg )
814 assert( SOCKBUF_VALID( sb ) );
815 assert( sb->sb_io == &sb_IO_None );
822 if ((trans->sbi_setup) && (trans->sbi_setup( sb, arg)<0))
828 int ber_pvt_sb_clear_io( Sockbuf *sb )
831 assert( SOCKBUF_VALID( sb ) );
833 if (sb->sb_io==&sb_IO_None)
836 if ((sb->sb_io->sbi_remove) && (sb->sb_io->sbi_remove( sb )<0))
839 sb->sb_io = &sb_IO_None;
841 sb->sb_trans_ready = 0;
851 stream_read( Sockbuf *sb, void *buf, long len )
854 assert( SOCKBUF_VALID( sb ) );
858 * MacTCP/OpenTransport
860 return tcpread( ber_pvt_sb_get_desc(sb), 0, (unsigned char *)buf,
863 #elif defined( HAVE_PCNFS ) || \
864 defined( HAVE_WINSOCK ) || defined ( __BEOS__ )
869 * Windows Socket API (under DOS/Windows 3.x)
872 * 32-bit Windows Socket API (under Windows NT or Windows 95)
876 rc = recv( ber_pvt_sb_get_desc(sb), buf, len, 0 );
878 if ( rc < 0 ) errno = WSAGetLastError();
882 #elif defined( HAVE_NCSA )
884 * NCSA Telnet TCP/IP stack (under DOS)
886 return nread( ber_pvt_sb_get_desc(sb), buf, len );
889 return read( ber_pvt_sb_get_desc(sb), buf, len );
894 stream_write( Sockbuf *sb, void *buf, long len )
897 assert( SOCKBUF_VALID( sb ) );
901 * MacTCP/OpenTransport
903 #define MAX_WRITE 65535
904 return tcpwrite( ber_pvt_sb_get_desc(sb),
905 (unsigned char *)(buf),
906 (len<MAX_WRITE)? len : MAX_WRITE );
908 #elif defined( HAVE_PCNFS) \
909 || defined( HAVE_WINSOCK) || defined ( __BEOS__ )
914 * Windows Socket API (under DOS/Windows 3.x)
917 * 32-bit Windows Socket API (under Windows NT or Windows 95)
922 rc = send( ber_pvt_sb_get_desc(sb), buf, len, 0 );
924 if ( rc < 0 ) errno = WSAGetLastError();
929 #elif defined(HAVE_NCSA)
930 return netwrite( ber_pvt_sb_get_desc(sb), buf, len );
934 * VMS -- each write must be 64K or smaller
936 #define MAX_WRITE 65535
937 return write( ber_pvt_sb_get_desc(sb), buf,
938 (len<MAX_WRITE)? len : MAX_WRITE);
940 return write( ber_pvt_sb_get_desc(sb), buf, len );
945 stream_close( Sockbuf *sb )
948 assert( SOCKBUF_VALID( sb ) );
949 tcp_close( ber_pvt_sb_get_desc( sb ) );
953 Sockbuf_IO ber_pvt_sb_io_tcp=
955 NULL, /* sbi_setup */
956 NULL, /* sbi_release */
957 stream_read, /* sbi_read */
958 stream_write, /* sbi_write */
959 stream_close, /* sbi_close */
963 * Support for UDP (CLDAP)
973 dgram_setup( Sockbuf *sb, void *arg )
976 assert( SOCKBUF_VALID( sb ) );
978 sb->sb_iodata = LBER_MALLOC( sizeof( struct dgram_data ) );
979 if (sb->sb_iodata==NULL)
981 sb->sb_read_ahead = 1; /* important since udp is packet based. */
986 dgram_release( Sockbuf *sb )
989 assert( SOCKBUF_VALID( sb ) );
991 LBER_FREE( sb->sb_iodata );
996 dgram_read( Sockbuf *sb, void *buf, long len )
998 #ifdef LDAP_CONNECTIONLESS
1001 struct dgram_data *dd;
1003 assert( sb != NULL );
1004 assert( SOCKBUF_VALID( sb ) );
1005 assert( buf != NULL );
1007 dd = (struct dgram_data *)(sb->sb_iodata);
1009 addrlen = sizeof( struct sockaddr );
1010 rc=recvfrom( ber_pvt_sb_get_desc(sb), buf, len, 0, &(dd->src), &addrlen );
1012 if ( sb->sb_debug ) {
1013 ber_log_printf( LDAP_DEBUG_ANY, sb->sb_debug,
1014 "dgram_read udp_read %d bytes\n",
1017 ber_log_bprint( LDAP_DEBUG_PACKETS, sb->sb_debug,
1021 # else /* LDAP_CONNECTIONLESS */
1023 # endif /* LDAP_CONNECTIONLESS */
1027 dgram_write( Sockbuf *sb, void *buf, long len )
1029 #ifdef LDAP_CONNECTIONLESS
1031 struct dgram_data *dd;
1033 assert( sb != NULL );
1034 assert( SOCKBUF_VALID( sb ) );
1035 assert( buf != NULL );
1037 dd = (struct dgram_data *)(sb->sb_iodata);
1039 rc=sendto( ber_pvt_sb_get_desc(sb), buf, len, 0, &(dd->dst),
1040 sizeof( struct sockaddr ) );
1045 /* fake error if write was not atomic */
1059 dgram_close( Sockbuf *sb )
1061 assert( sb != NULL );
1062 assert( SOCKBUF_VALID( sb ) );
1064 tcp_close( ber_pvt_sb_get_desc(sb) );
1068 Sockbuf_IO ber_pvt_sb_io_udp=
1070 dgram_setup, /* sbi_setup */
1071 dgram_release, /* sbi_release */
1072 dgram_read, /* sbi_read */
1073 dgram_write, /* sbi_write */
1074 dgram_close, /* sbi_close */
1077 int ber_pvt_sb_udp_set_dst(Sockbuf *sb, void *addr )
1079 struct dgram_data *dd;
1080 assert( sb != NULL );
1081 assert( SOCKBUF_VALID( sb ) );
1082 assert( sb->sb_io == &ber_pvt_sb_io_udp );
1083 dd = (struct dgram_data *) (sb->sb_iodata);
1084 memcpy( &(dd->dst), addr, sizeof( struct sockaddr ) );
1088 void *ber_pvt_sb_udp_get_src( Sockbuf *sb )
1090 struct dgram_data *dd;
1092 assert( sb != NULL );
1093 assert( SOCKBUF_VALID( sb ) );
1094 assert( sb->sb_io == &ber_pvt_sb_io_udp );
1095 dd = (struct dgram_data *) (sb->sb_iodata);
1103 * These routines should really call abort, but at the moment that would
1104 * break the servers.
1108 have_no_read( Sockbuf *sb, void *buf, long len )
1110 assert( sb != NULL );
1111 assert( SOCKBUF_VALID( sb ) );
1113 ber_log_printf( LDAP_DEBUG_ANY, ber_int_debug,
1114 "warning: reading from uninitialized sockbuf\n");
1120 have_no_write( Sockbuf *sb, void *buf, long len )
1122 assert( sb != NULL );
1123 assert( SOCKBUF_VALID( sb ) );
1125 ber_log_printf( LDAP_DEBUG_ANY, ber_int_debug,
1126 "warning: writing to uninitialized sockbuf\n");
1132 have_no_close( Sockbuf *sb )
1134 assert( sb != NULL );
1135 assert( SOCKBUF_VALID( sb ) );