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 )
61 assert( SOCKBUF_VALID( 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 )
81 assert( SOCKBUF_VALID( sb ) );
83 obr = sb->sb_buf_ready;
85 osr = sb->sb_sec_ready;
89 if (obr!=sb->sb_buf_ready)
93 if (osr!=sb->sb_sec_ready)
103 packet_length( char *buf )
107 assert( buf != NULL );
109 size = (((unsigned long)buf[0])<<24)|
110 (((unsigned long)buf[1])<<16)|
111 (((unsigned long)buf[2])<<8)|
112 (((unsigned long)buf[3]));
114 if ((size<0) || (size>MAX_BUF_SIZE)) {
115 /* somebody is trying to mess me up. */
116 lber_log_printf( LDAP_DEBUG_SASL, sb->sb_debug,
117 "SASL: received packet length of %d bytes\n",
119 size = 16; /* this should lead to an error. */
122 return size + 4; /* include the size !!! */
127 grow_buffer( Sockbuf_Buf * buf, long minsize )
131 assert( buf != NULL );
133 for( pw=MIN_BUF_SIZE; pw<minsize; pw<<=1 ) {
134 if (pw > MAX_BUF_SIZE) {
135 /* this could mean that somebody is trying to crash us. */
141 if (buf->buf_size<minsize) {
142 if ((buf->buf_base==NULL) || ((buf->buf_end==0) && (buf->buf_ptr==0))) {
144 if (buf->buf_base!=NULL)
145 LBER_FREE( buf->buf_base );
146 assert( buf->buf_ptr==0 );
147 assert( buf->buf_end==0 );
148 buf->buf_base = LBER_MALLOC( minsize );
149 if (buf->buf_base==NULL)
153 nb = LBER_REALLOC( buf->buf_base, minsize );
158 buf->buf_size = minsize;
165 sockbuf_sec_release( Sockbuf *sb, char *buf, long len )
167 /* when this is called:
168 * sb->sb_sec_buf_in.buf_base points to a packet.
169 * sb->sb_sec_buf_in.buf_ptr contains the total bytes read.
170 * sb->sb_sec_end.buf_end contains the packet length.
172 * sb->sb_buf.buf_ptr == sb->sb_buf.buf_end == 0;
180 assert( buf != NULL );
181 assert( sb != NULL );
182 assert( SOCKBUF_VALID( sb ) );
184 assert( sb->sb_sec );
185 assert( sb->sb_sec->sbs_release );
186 assert( sb->sb_sec_buf_in.sb_ptr >= sb->sb_sec_buf_in.sb_end );
188 assert( sb->sb_buf.sb_ptr == 0 );
189 assert( sb->sb_buf.sb_end == 0 );
191 assert( status_is_ok(sb) );
195 ptr = sb->sb_sec_buf_in.buf_base;
196 end = ptr+ sb->sb_sec_buf_in.buf_ptr;
197 size = sb->sb_sec_buf_in.buf_end;
199 sb->sb_sec_ready = 1;
201 for(;(ptr+size<=end);) {
203 rlen = sb->sb_sec->sbs_release( sb, ptr, size,
206 sb->sb_buf.buf_size );
208 /* this means a security violation. */
209 return total; /* total ? total : 0 */
212 /* this means that the buffer isn't big enough. */
213 if (grow_buffer( &(sb->sb_buf), -rlen )<0)
214 /* memory violation. */
215 return total; /* total ? total : 0 */
223 /* move to the next packet... */
227 size = packet_length( ptr );
228 /* size is always at least 4, so the loop condition is always OK !!*/
235 sb->sb_buf_ready = (sb->sb_buf.buf_end = rlen - len) ? 1 : 0;
241 sb->sb_sec_ready = 0;
242 /* clean up the mess. */
244 /* copy back to beginning of buffer. */
245 SAFEMEMCPY( sb->sb_sec_buf_in.buf_base, ptr, end-ptr );
246 sb->sb_sec_buf_in.buf_ptr = 0;
247 sb->sb_sec_buf_in.buf_end -= (ptr - sb->sb_sec_buf_in.buf_base);
249 assert( status_is_ok(sb) );
254 sockbuf_sec_protect( Sockbuf *sb, char *buf, long len )
260 assert( buf != NULL );
262 assert( sb != NULL );
263 assert( SOCKBUF_VALID( sb ) );
265 assert( sb->sb_sec_out.buf_end == 0 );
266 assert( sb->sb_sec_out.buf_ptr == 0 );
268 assert( sb->sb_sec );
269 assert( sb->sb_sec->sbs_protect );
271 assert( status_is_ok(sb) );
277 ret = sb->sb_sec->sbs_protect( sb, buf, &blen,
278 sb->sb_sec_out.buf_base+
279 sb->sb_sec_out.buf_end,
280 sb->sb_sec_out.buf_size -
281 sb->sb_sec_out.buf_end );
283 /* protection error ? */
286 if (grow_buffer( &(sb->sb_sec_out),-ret-sb->sb_sec_out.buf_end )<0)
291 /* else if (ret>0) */
294 sb->sb_sec_out.buf_end += ret;
298 assert( status_is_ok(sb) );
304 sockbuf_copy_out( Sockbuf *sb, char **buf, long len )
306 long blen = (sb->sb_buf.buf_end - sb->sb_buf.buf_ptr );
308 assert( buf != NULL );
310 assert( sb != NULL );
311 assert( SOCKBUF_VALID( sb ) );
312 assert( status_is_ok(sb) );
315 long rlen = (blen<len) ? blen : len;
316 memcpy( *buf, sb->sb_buf.buf_base + sb->sb_buf.buf_ptr, rlen );
317 sb->sb_buf.buf_ptr+=rlen;
320 if (sb->sb_buf.buf_ptr >= sb->sb_buf.buf_end) {
321 sb->sb_buf.buf_ptr = sb->sb_buf.buf_end = 0;
322 sb->sb_buf_ready = 0;
324 sb->sb_buf_ready = 1;
327 assert( status_is_ok(sb) );
331 Sockbuf *ber_sockbuf_alloc( void )
335 ber_int_options.lbo_valid = LBER_INITIALIZED;
337 sb = LBER_CALLOC(1, sizeof(Sockbuf));
339 if( sb == NULL ) return NULL;
341 ber_pvt_sb_init( sb );
345 Sockbuf *ber_sockbuf_alloc_fd( int fd )
347 Sockbuf *sb = ber_sockbuf_alloc();
349 if( sb == NULL ) return NULL;
351 ber_pvt_sb_set_desc( sb, fd );
352 ber_pvt_sb_set_io( sb, &ber_pvt_sb_io_tcp, NULL );
356 void ber_sockbuf_free( Sockbuf *sb )
359 assert( SOCKBUF_VALID( sb ) );
360 ber_pvt_sb_destroy( sb );
365 ber_pvt_sb_read( Sockbuf *sb, void *buf_arg, long len )
370 assert( buf_arg != NULL );
371 assert( sb != NULL );
372 assert( SOCKBUF_VALID( sb ) );
373 assert( status_is_ok(sb) );
375 /* breaks slapd :-< */
376 assert( ber_pvt_sb_in_use( sb ) );
379 #ifdef TEST_PARTIAL_READ
380 if ((rand() & 3)==1) { /* 1 out of 4 */
386 len = (rand() % len)+1;
389 buf = (char *) buf_arg;
391 if (sb->sb_buf.buf_ptr!=sb->sb_buf.buf_end) {
392 len = sockbuf_copy_out( sb, &buf, len );
394 return (buf - (char *) buf_arg);
401 assert( sb->sb_sec->sbs_release );
402 assert( sb->sb_sec_buf_in.buf_base );
403 if (sb->sb_read_ahead) {
404 max = sb->sb_sec_buf_in.buf_size - sb->sb_sec_buf_in.buf_ptr;
406 max = sb->sb_sec_buf_in.buf_end - sb->sb_sec_buf_in.buf_ptr;
408 /* special situation. This means that we need to read the first
409 * four bytes for the packet length.
415 /* read from stream into sb_sec_buf_in */
417 ret = sockbuf_io_read( sb, sb->sb_sec_buf_in.buf_base +
418 sb->sb_sec_buf_in.buf_ptr, max );
420 if ((ret<0) && (errno==EINTR))
426 /* read error. return */
429 sb->sb_sec_buf_in.buf_ptr += ret;
431 if (sb->sb_sec_buf_in.buf_ptr < sb->sb_sec_buf_in.buf_end) {
432 /* did not finish a packet. give up. */
436 if (sb->sb_sec_buf_in.buf_end == 0) {
437 /* Were trying to read the first four bytes... */
438 if (sb->sb_sec_buf_in.buf_ptr < 4) {
439 /* did not read enough for packet length. give up. */
442 /* calculate the packet length. */
443 sb->sb_sec_buf_in.buf_end =
444 packet_length(sb->sb_sec_buf_in.buf_base );
445 if ((sb->sb_sec_buf_in.buf_end > sb->sb_sec_buf_in.buf_size) &&
446 (grow_buffer( &(sb->sb_sec_buf_in), sb->sb_sec_buf_in.buf_end)<0)) {
447 /* buffer has to be to big. exit with error. */
451 if (sb->sb_sec_buf_in.buf_ptr >= sb_sec_buf_in.buf_end) {
452 /* finished packet. decode it. */
455 /* did not finish packet yet. try again ? */
456 if (sb->sb_read_ahead) {
457 /* we were trying to read the max anyway. forget it */
462 /* we read enough for at least 1 packet */
463 ret = sockbuf_sec_release( sb, buf, len );
465 /* something went wrong... */
470 /* we are finished !!! */
471 if ((len==0) || (ret!=max))
476 if (sb->sb_read_ahead) {
478 max = sb->sb_buf.buf_size - sb->sb_buf.buf_end;
481 ret = sockbuf_io_read( sb,
482 sb->sb_buf.buf_base +
486 if ((ret<0) && (errno==EINTR))
492 /* some error occured */
495 sb->sb_buf.buf_end += ret;
496 /* move out the data... */
497 len = sockbuf_copy_out( sb, &buf, len );
501 /* no read_ahead, just try to put the data in the buf. */
503 ret = sockbuf_io_read( sb, buf, len );
505 if ((ret<0) && (errno==EINTR))
514 /* we might as well return, since there is nothing to do... */
519 assert( status_is_ok(sb) );
520 if ((ret<=0) && (buf==buf_arg)) {
521 /* there was an error. */
524 return (buf - ((char *) buf_arg));
528 long sockbuf_do_write( Sockbuf *sb )
532 assert( sb != NULL );
533 assert( SOCKBUF_VALID( sb ) );
535 to_go = sb->sb_sec_out.buf_end - sb->sb_sec_out.buf_ptr;
537 /* there is something left of the last time... */
539 ret = sockbuf_io_write( sb, sb->sb_sec_out.buf_base+
540 sb->sb_sec_out.buf_ptr, to_go );
542 if ((ret<0) && (errno==EINTR))
547 if (ret<=0) /* error */
549 sb->sb_sec_out.buf_ptr += ret;
550 if (ret<to_go) /* not enough data, so pretend no data was sent. */
556 long ber_pvt_sb_write( Sockbuf *sb, void *buf, long len_arg )
561 assert( buf != NULL );
562 assert( sb != NULL );
563 assert( SOCKBUF_VALID( sb ) );
564 assert( status_is_ok(sb) );
566 /* unfortunately breaks slapd */
567 assert( ber_pvt_sb_in_use( sb ) );
569 #ifdef TEST_PARTIAL_WRITE
570 if ((rand() & 3)==1) { /* 1 out of 4 */
575 len_arg = (rand() % len_arg)+1;
581 assert( sb->sb_sec_prev_len <= len );
582 if (sb->sb_sec_prev_len) {
583 ret = sockbuf_do_write( sb );
587 len -= sb->sb_sec_prev_len;
588 sb->sb_sec_prev_len = 0;
589 sb->sb_sec_out.buf_end = sb->sb_sec_out.buf_ptr = 0;
591 /* now protect the next packet. */
592 ret = sockbuf_sec_protect( sb, buf, len );
595 ret = sockbuf_do_write( sb );
597 sb->sb_sec_prev_len = len;
604 ret = sockbuf_io_write( sb, buf, len );
606 if ((ret<0) && (errno==EINTR))
618 int ber_pvt_sb_close( Sockbuf *sb )
622 assert( sb != NULL );
623 assert( SOCKBUF_VALID( sb ) );
625 assert( sb->sb_io->sbi_close );
626 assert( status_is_ok(sb) );
627 assert( ber_pvt_sb_in_use( sb ) );
629 ret = sb->sb_io->sbi_close( sb );
630 ber_pvt_sb_set_desc( sb, -1 );
635 int ber_pvt_sb_set_readahead( Sockbuf *sb, int rh )
637 assert( sb != NULL );
638 assert( SOCKBUF_VALID( sb ) );
639 assert( status_is_ok(sb) );
640 sb->sb_read_ahead = (rh!=0);
646 int ber_pvt_sb_set_nonblock( Sockbuf *sb, int nb )
648 assert( sb != NULL );
649 assert( SOCKBUF_VALID( sb ) );
650 assert( status_is_ok(sb) );
652 sb->sb_non_block = 1;
654 sb->sb_read_ahead = 1;
657 sb->sb_non_block = 0;
659 sb->sb_read_ahead = 0;
662 if (ber_pvt_sb_in_use(sb)) {
664 int flags = fcntl(ber_pvt_sb_get_desc(sb), F_GETFL);
666 return fcntl(ber_pvt_sb_get_desc(sb), F_SETFL, flags);
668 #elif defined( FIONBIO )
669 /* WINSOCK requires the status to be a long */
670 ioctl_t status = (nb!=0);
671 return ioctl( ber_pvt_sb_get_desc(sb), FIONBIO, &status );
678 #define sockbuf_buf_init( bb ) do { \
679 Sockbuf_Buf *sbb = (bb); \
680 sbb->buf_base = NULL; \
687 sockbuf_buf_destroy( Sockbuf_Buf *buf )
689 assert( buf != NULL);
692 LBER_FREE( buf->buf_base );
693 sockbuf_buf_init( buf );
697 int ber_pvt_sb_init( Sockbuf *sb )
701 ber_int_options.lbo_valid = LBER_INITIALIZED;
703 sb->sb_valid=LBER_VALID_SOCKBUF;
706 sb->sb_trans_ready = 0;
707 sb->sb_buf_ready = 0;
709 sb->sb_sec_ready = 0;
711 sb->sb_read_ahead = 0;
712 sb->sb_non_block = 0;
714 sb->sb_iodata = NULL;
715 sb->sb_io = &sb_IO_None;
718 sb->sb_max_incoming = 0;
720 sockbuf_buf_init( &(sb->sb_buf) );
722 sockbuf_buf_init( &(sb->sb_sec_buf_in) );
723 sockbuf_buf_init( &(sb->sb_sec_buf_out) );
726 sb->sb_sec_prev_len = 0;
729 assert( SOCKBUF_VALID( sb ) );
733 int ber_pvt_sb_destroy( Sockbuf *sb )
736 assert( SOCKBUF_VALID(sb) );
738 ber_pvt_sb_clear_sec(sb);
739 sockbuf_buf_destroy( &(sb->sb_sec_buf_in) );
740 sockbuf_buf_destroy( &(sb->sb_sec_buf_out) );
742 ber_pvt_sb_clear_io(sb);
743 sockbuf_buf_destroy( &(sb->sb_buf) );
744 return ber_pvt_sb_init( sb );
748 int ber_pvt_sb_set_sec( Sockbuf *sb, Sockbuf_Sec * sec, void *arg )
752 assert( SOCKBUF_VALID( *sb ) );
753 if ((sb->sb_sec) || (sec==NULL))
758 if ((sec->sbs_setup) && (sec->sbs_setup( sb, arg)<0)) {
762 len = sb->sb_buf.buf_end - sb->sb_buf.buf_ptr;
765 /* move this to the security layer. */
766 if (grow_buffer( &(sb->sb_sec_buf_in), len )<0)
768 memcpy( sb->sb_sec_buf_in.buf_base,
769 sb->sb_buf.buf_base + sb->sb_buf.buf_ptr, len );
770 sb->sb_sec_buf_in.buf_ptr = len;
771 sb->sb_sec_buf_in.buf_end = (len>4) ? packet_length( sb->sb_sec_buf_in ) : 0;
772 sb->sb_buf.buf_ptr = sb->sb_buf.buf_end = 0;
778 int ber_pvt_sb_clear_sec( Sockbuf *sb )
781 assert( SOCKBUF_VALID( sb ) );
783 if (sb->sb_buf.buf_ptr!=0)
785 if (sb->sb_sec==NULL)
787 if ((sb->sb_sec->sbs_remove) && (sb->sb_sec->sbs_remove(sb)<0))
791 if (sb->sb_sec_buf_in.buf_ptr!=0) {
792 if (grow_buffer( &(sb->sb_buf),
793 sb->sb_buf.buf_end + sb->sb_sec_buf_in.buf_ptr)<0)
795 memcpy( sb->sb_buf.buf_base + sb->sb_buf.buf_end,
796 sb->sb_sec_buf_in.buf_base, sb->sb_sec_buf_in.buf_ptr );
797 sb->sb_buf.buf_end += sb->sb_sec_buf_in.buf_ptr;
798 sb->sb_buf_ready = 1;
800 sockbuf_buf_destroy( &(sb->sb_sec_buf_in) );
801 assert( sb->sb_sec_buf.buf_end==0 );
802 sockbuf_buf_destroy( &(sb->sb_sec_buf_out) );
804 sb->sb_sec_ready = 0;
810 int ber_pvt_sb_set_io( Sockbuf *sb, Sockbuf_IO *trans, void *arg )
813 assert( SOCKBUF_VALID( sb ) );
814 assert( sb->sb_io == &sb_IO_None );
821 if ((trans->sbi_setup) && (trans->sbi_setup( sb, arg)<0))
827 int ber_pvt_sb_clear_io( Sockbuf *sb )
830 assert( SOCKBUF_VALID( sb ) );
832 if (sb->sb_io==&sb_IO_None)
835 if ((sb->sb_io->sbi_remove) && (sb->sb_io->sbi_remove( sb )<0))
838 sb->sb_io = &sb_IO_None;
840 sb->sb_trans_ready = 0;
850 stream_read( Sockbuf *sb, void *buf, long len )
853 assert( SOCKBUF_VALID( sb ) );
857 * MacTCP/OpenTransport
859 return tcpread( ber_pvt_sb_get_desc(sb), 0, (unsigned char *)buf,
862 #elif defined( HAVE_PCNFS ) || \
863 defined( HAVE_WINSOCK ) || defined ( __BEOS__ )
868 * Windows Socket API (under DOS/Windows 3.x)
871 * 32-bit Windows Socket API (under Windows NT or Windows 95)
875 rc = recv( ber_pvt_sb_get_desc(sb), buf, len, 0 );
877 if ( rc < 0 ) errno = WSAGetLastError();
881 #elif defined( HAVE_NCSA )
883 * NCSA Telnet TCP/IP stack (under DOS)
885 return nread( ber_pvt_sb_get_desc(sb), buf, len );
888 return read( ber_pvt_sb_get_desc(sb), buf, len );
893 stream_write( Sockbuf *sb, void *buf, long len )
896 assert( SOCKBUF_VALID( sb ) );
900 * MacTCP/OpenTransport
902 #define MAX_WRITE 65535
903 return tcpwrite( ber_pvt_sb_get_desc(sb),
904 (unsigned char *)(buf),
905 (len<MAX_WRITE)? len : MAX_WRITE );
907 #elif defined( HAVE_PCNFS) \
908 || defined( HAVE_WINSOCK) || defined ( __BEOS__ )
913 * Windows Socket API (under DOS/Windows 3.x)
916 * 32-bit Windows Socket API (under Windows NT or Windows 95)
921 rc = send( ber_pvt_sb_get_desc(sb), buf, len, 0 );
923 if ( rc < 0 ) errno = WSAGetLastError();
928 #elif defined(HAVE_NCSA)
929 return netwrite( ber_pvt_sb_get_desc(sb), buf, len );
933 * VMS -- each write must be 64K or smaller
935 #define MAX_WRITE 65535
936 return write( ber_pvt_sb_get_desc(sb), buf,
937 (len<MAX_WRITE)? len : MAX_WRITE);
939 return write( ber_pvt_sb_get_desc(sb), buf, len );
944 stream_close( Sockbuf *sb )
947 assert( SOCKBUF_VALID( sb ) );
948 tcp_close( ber_pvt_sb_get_desc( sb ) );
952 Sockbuf_IO ber_pvt_sb_io_tcp=
954 NULL, /* sbi_setup */
955 NULL, /* sbi_release */
956 stream_read, /* sbi_read */
957 stream_write, /* sbi_write */
958 stream_close, /* sbi_close */
962 * Support for UDP (CLDAP)
972 dgram_setup( Sockbuf *sb, void *arg )
975 assert( SOCKBUF_VALID( sb ) );
977 sb->sb_iodata = LBER_MALLOC( sizeof( struct dgram_data ) );
978 if (sb->sb_iodata==NULL)
980 sb->sb_read_ahead = 1; /* important since udp is packet based. */
985 dgram_release( Sockbuf *sb )
988 assert( SOCKBUF_VALID( sb ) );
990 LBER_FREE( sb->sb_iodata );
995 dgram_read( Sockbuf *sb, void *buf, long len )
997 #ifdef LDAP_CONNECTIONLESS
1000 struct dgram_data *dd;
1002 assert( sb != NULL );
1003 assert( SOCKBUF_VALID( sb ) );
1004 assert( buf != NULL );
1006 dd = (struct dgram_data *)(sb->sb_iodata);
1008 addrlen = sizeof( struct sockaddr );
1009 rc=recvfrom( ber_pvt_sb_get_desc(sb), buf, len, 0, &(dd->src), &addrlen );
1011 if ( sb->sb_debug ) {
1012 ber_log_printf( LDAP_DEBUG_ANY, sb->sb_debug,
1013 "dgram_read udp_read %d bytes\n",
1016 ber_log_bprint( LDAP_DEBUG_PACKETS, sb->sb_debug,
1020 # else /* LDAP_CONNECTIONLESS */
1022 # endif /* LDAP_CONNECTIONLESS */
1026 dgram_write( Sockbuf *sb, void *buf, long len )
1028 #ifdef LDAP_CONNECTIONLESS
1030 struct dgram_data *dd;
1032 assert( sb != NULL );
1033 assert( SOCKBUF_VALID( sb ) );
1034 assert( buf != NULL );
1036 dd = (struct dgram_data *)(sb->sb_iodata);
1038 rc=sendto( ber_pvt_sb_get_desc(sb), buf, len, 0, &(dd->dst),
1039 sizeof( struct sockaddr ) );
1044 /* fake error if write was not atomic */
1058 dgram_close( Sockbuf *sb )
1060 assert( sb != NULL );
1061 assert( SOCKBUF_VALID( sb ) );
1063 tcp_close( ber_pvt_sb_get_desc(sb) );
1067 Sockbuf_IO ber_pvt_sb_io_udp=
1069 dgram_setup, /* sbi_setup */
1070 dgram_release, /* sbi_release */
1071 dgram_read, /* sbi_read */
1072 dgram_write, /* sbi_write */
1073 dgram_close, /* sbi_close */
1076 int ber_pvt_sb_udp_set_dst(Sockbuf *sb, void *addr )
1078 struct dgram_data *dd;
1079 assert( sb != NULL );
1080 assert( SOCKBUF_VALID( sb ) );
1081 assert( sb->sb_io == &ber_pvt_sb_io_udp );
1082 dd = (struct dgram_data *) (sb->sb_iodata);
1083 memcpy( &(dd->dst), addr, sizeof( struct sockaddr ) );
1087 void *ber_pvt_sb_udp_get_src( Sockbuf *sb )
1089 struct dgram_data *dd;
1091 assert( sb != NULL );
1092 assert( SOCKBUF_VALID( sb ) );
1093 assert( sb->sb_io == &ber_pvt_sb_io_udp );
1094 dd = (struct dgram_data *) (sb->sb_iodata);
1102 * These routines should really call abort, but at the moment that would
1103 * break the servers.
1107 have_no_read( Sockbuf *sb, void *buf, long len )
1109 assert( sb != NULL );
1110 assert( SOCKBUF_VALID( sb ) );
1112 ber_log_printf( LDAP_DEBUG_ANY, ber_int_debug,
1113 "warning: reading from uninitialized sockbuf\n");
1119 have_no_write( Sockbuf *sb, void *buf, long len )
1121 assert( sb != NULL );
1122 assert( SOCKBUF_VALID( sb ) );
1124 ber_log_printf( LDAP_DEBUG_ANY, ber_int_debug,
1125 "warning: writing to uninitialized sockbuf\n");
1131 have_no_close( Sockbuf *sb )
1133 assert( sb != NULL );
1134 assert( SOCKBUF_VALID( sb ) );