1 /* sockbuf.c - i/o routines with support for adding i/o layers. */
4 * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
12 #include <ac/stdlib.h>
16 #include <ac/socket.h>
17 #include <ac/string.h>
18 #include <ac/unistd.h>
22 #endif /* HAVE_IO_H */
24 #if defined( HAVE_SYS_FILIO_H )
25 #include <sys/filio.h>
26 #elif defined( HAVE_SYS_IOCTL_H )
27 #include <sys/ioctl.h>
31 #define LDAP_F_PRE LDAP_F_EXPORT
36 #undef TEST_PARTIAL_READ
37 #undef TEST_PARTIAL_WRITE
40 #define MAX_BUF_SIZE 65535
41 #define MIN_BUF_SIZE 4096
43 #define sockbuf_io_write( sb, buf, len ) \
44 ((sb)->sb_io->sbi_write( (sb), (buf), (len) ))
46 #define sockbuf_io_read( sb, buf, len ) \
47 ((sb)->sb_io->sbi_read( (sb), (buf), (len) ))
49 static ber_slen_t have_no_read( Sockbuf *sb, void *buf, ber_len_t len );
50 static ber_slen_t have_no_write( Sockbuf *sb, void *buf, ber_len_t len );
51 static int have_no_close( Sockbuf *sb );
53 static Sockbuf_IO sb_IO_None=
56 NULL, /* sbi_release */
57 have_no_read, /* sbi_read */
58 have_no_write, /* sbi_write */
59 have_no_close /* sbi_close */
63 update_status( Sockbuf *sb )
66 assert( SOCKBUF_VALID( sb ) );
68 sb->sb_buf_ready = (sb->sb_buf.buf_ptr < sb->sb_buf.buf_end);
70 sb->sb_sec_ready = ((sb->sb_sec_buf_in.buf_end!=0) &&
71 (sb->sb_sec_buf_in.buf_ptr >=
72 sb->sb_sec_buf_in.buf_end));
78 status_is_ok( Sockbuf *sb )
86 assert( SOCKBUF_VALID( sb ) );
88 obr = sb->sb_buf_ready;
90 osr = sb->sb_sec_ready;
94 if (obr!=sb->sb_buf_ready)
98 if (osr!=sb->sb_sec_ready)
108 packet_length( Sockbuf *sb, const char *buf )
112 assert( buf != NULL );
114 size = (((ber_len_t)buf[0])<<24)|
115 (((ber_len_t)buf[1])<<16)|
116 (((ber_len_t)buf[2])<<8)|
117 (((ber_len_t)buf[3]));
119 if ( size > MAX_BUF_SIZE ) {
120 /* somebody is trying to mess me up. */
121 ber_log_printf( LDAP_DEBUG_SASL, sb->sb_debug,
122 "SASL: received packet length of %lu bytes\n",
123 (unsigned long) size );
124 size = 16; /* this should lead to an error. */
127 return size + 4; /* include the size !!! */
132 grow_buffer( Sockbuf_Buf * buf, ber_len_t minsize )
136 assert( buf != NULL );
138 for( pw=MIN_BUF_SIZE; pw<minsize; pw<<=1 ) {
139 if (pw > MAX_BUF_SIZE) {
140 /* this could mean that somebody is trying to crash us. */
146 if (buf->buf_size<minsize) {
147 if ((buf->buf_base==NULL) || ((buf->buf_end==0) && (buf->buf_ptr==0))) {
149 if (buf->buf_base!=NULL)
150 LBER_FREE( buf->buf_base );
151 assert( buf->buf_ptr==0 );
152 assert( buf->buf_end==0 );
153 buf->buf_base = LBER_MALLOC( minsize );
154 if (buf->buf_base==NULL)
158 nb = LBER_REALLOC( buf->buf_base, minsize );
163 buf->buf_size = minsize;
170 sockbuf_sec_release( Sockbuf *sb, char *buf, ber_len_t len )
172 /* when this is called:
173 * sb->sb_sec_buf_in.buf_base points to a packet.
174 * sb->sb_sec_buf_in.buf_ptr contains the total bytes read.
175 * sb->sb_sec_end.buf_end contains the packet length.
177 * sb->sb_buf.buf_ptr == sb->sb_buf.buf_end == 0;
185 assert( buf != NULL );
186 assert( sb != NULL );
187 assert( SOCKBUF_VALID( sb ) );
189 assert( sb->sb_sec );
190 assert( sb->sb_sec->sbs_release );
191 assert( sb->sb_sec_buf_in.sb_ptr >= sb->sb_sec_buf_in.sb_end );
193 assert( sb->sb_buf.sb_ptr == 0 );
194 assert( sb->sb_buf.sb_end == 0 );
196 assert( status_is_ok(sb) );
200 ptr = sb->sb_sec_buf_in.buf_base;
201 end = ptr+ sb->sb_sec_buf_in.buf_ptr;
202 size = sb->sb_sec_buf_in.buf_end;
204 sb->sb_sec_ready = 1;
206 for(;(ptr+size<=end);) {
208 rlen = sb->sb_sec->sbs_release( sb, ptr, size,
211 sb->sb_buf.buf_size );
213 /* this means a security violation. */
214 return total; /* total ? total : 0 */
217 /* this means that the buffer isn't big enough. */
218 if (grow_buffer( &(sb->sb_buf), -rlen )<0)
219 /* memory violation. */
220 return total; /* total ? total : 0 */
228 /* move to the next packet... */
232 size = packet_length( sb, ptr );
233 /* size is always at least 4, so the loop condition is always OK !!*/
240 sb->sb_buf_ready = (sb->sb_buf.buf_end = rlen - len) ? 1 : 0;
246 sb->sb_sec_ready = 0;
247 /* clean up the mess. */
249 /* copy back to beginning of buffer. */
250 SAFEMEMCPY( sb->sb_sec_buf_in.buf_base, ptr, end-ptr );
251 sb->sb_sec_buf_in.buf_ptr = 0;
252 sb->sb_sec_buf_in.buf_end -= (ptr - sb->sb_sec_buf_in.buf_base);
254 assert( status_is_ok(sb) );
259 sockbuf_sec_protect( Sockbuf *sb, char *buf, long len )
265 assert( buf != NULL );
267 assert( sb != NULL );
268 assert( SOCKBUF_VALID( sb ) );
270 assert( sb->sb_sec_out.buf_end == 0 );
271 assert( sb->sb_sec_out.buf_ptr == 0 );
273 assert( sb->sb_sec );
274 assert( sb->sb_sec->sbs_protect );
276 assert( status_is_ok(sb) );
282 ret = sb->sb_sec->sbs_protect( sb, buf, &blen,
283 sb->sb_sec_out.buf_base+
284 sb->sb_sec_out.buf_end,
285 sb->sb_sec_out.buf_size -
286 sb->sb_sec_out.buf_end );
288 /* protection error ? */
291 if (grow_buffer( &(sb->sb_sec_out),-ret-sb->sb_sec_out.buf_end )<0)
296 /* else if (ret>0) */
299 sb->sb_sec_out.buf_end += ret;
303 assert( status_is_ok(sb) );
309 sockbuf_copy_out( Sockbuf *sb, char **buf, ber_len_t len )
311 ber_len_t blen = (sb->sb_buf.buf_end - sb->sb_buf.buf_ptr );
313 assert( buf != NULL );
315 assert( sb != NULL );
316 assert( SOCKBUF_VALID( sb ) );
317 assert( status_is_ok(sb) );
320 ber_len_t rlen = (blen<len) ? blen : len;
321 memcpy( *buf, sb->sb_buf.buf_base + sb->sb_buf.buf_ptr, rlen );
322 sb->sb_buf.buf_ptr+=rlen;
325 if (sb->sb_buf.buf_ptr >= sb->sb_buf.buf_end) {
326 sb->sb_buf.buf_ptr = sb->sb_buf.buf_end = 0;
327 sb->sb_buf_ready = 0;
329 sb->sb_buf_ready = 1;
332 assert( status_is_ok(sb) );
336 Sockbuf *ber_sockbuf_alloc( void )
340 ber_int_options.lbo_valid = LBER_INITIALIZED;
342 sb = LBER_CALLOC(1, sizeof(Sockbuf));
344 if( sb == NULL ) return NULL;
346 ber_pvt_sb_init( sb );
350 Sockbuf *ber_sockbuf_alloc_fd( ber_socket_t fd )
352 Sockbuf *sb = ber_sockbuf_alloc();
354 if( sb == NULL ) return NULL;
356 ber_pvt_sb_set_desc( sb, fd );
357 ber_pvt_sb_set_io( sb, &ber_pvt_sb_io_tcp, NULL );
361 void ber_sockbuf_free( Sockbuf *sb )
364 assert( SOCKBUF_VALID( sb ) );
365 ber_pvt_sb_destroy( sb );
370 ber_pvt_sb_read( Sockbuf *sb, void *buf_arg, ber_len_t len )
375 assert( buf_arg != NULL );
376 assert( sb != NULL );
377 assert( SOCKBUF_VALID( sb ) );
378 assert( status_is_ok(sb) );
380 /* slapd might have problems with this */
381 assert( ber_pvt_sb_in_use( sb ) );
383 #ifdef TEST_PARTIAL_READ
384 if ((rand() & 3)==1) { /* 1 out of 4 */
390 len = (rand() % len)+1;
393 buf = (char *) buf_arg;
395 if (sb->sb_buf.buf_ptr!=sb->sb_buf.buf_end) {
396 len = sockbuf_copy_out( sb, &buf, len );
398 return (buf - (char *) buf_arg);
405 assert( sb->sb_sec->sbs_release );
406 assert( sb->sb_sec_buf_in.buf_base );
407 if (sb->sb_read_ahead) {
408 max = sb->sb_sec_buf_in.buf_size - sb->sb_sec_buf_in.buf_ptr;
410 max = sb->sb_sec_buf_in.buf_end - sb->sb_sec_buf_in.buf_ptr;
412 /* special situation. This means that we need to read the first
413 * four bytes for the packet length.
419 /* read from stream into sb_sec_buf_in */
421 ret = sockbuf_io_read( sb, sb->sb_sec_buf_in.buf_base +
422 sb->sb_sec_buf_in.buf_ptr, max );
424 if ((ret<0) && (errno==EINTR))
430 /* read error. return */
433 sb->sb_sec_buf_in.buf_ptr += ret;
435 if (sb->sb_sec_buf_in.buf_ptr < sb->sb_sec_buf_in.buf_end) {
436 /* did not finish a packet. give up. */
440 if (sb->sb_sec_buf_in.buf_end == 0) {
441 /* Were trying to read the first four bytes... */
442 if (sb->sb_sec_buf_in.buf_ptr < 4) {
443 /* did not read enough for packet length. give up. */
446 /* calculate the packet length. */
447 sb->sb_sec_buf_in.buf_end =
448 packet_length(sb, sb->sb_sec_buf_in.buf_base );
449 if ((sb->sb_sec_buf_in.buf_end > sb->sb_sec_buf_in.buf_size) &&
450 (grow_buffer( &(sb->sb_sec_buf_in), sb->sb_sec_buf_in.buf_end)<0)) {
451 /* buffer has to be to big. exit with error. */
455 if (sb->sb_sec_buf_in.buf_ptr >= sb->sb_sec_buf_in.buf_end) {
456 /* finished packet. decode it. */
459 /* did not finish packet yet. try again ? */
460 if (sb->sb_read_ahead) {
461 /* we were trying to read the max anyway. forget it */
466 /* we read enough for at least 1 packet */
467 ret = sockbuf_sec_release( sb, buf, len );
469 /* something went wrong... */
474 /* we are finished !!! */
475 if ((len==0) || (ret!=max))
480 if (sb->sb_read_ahead) {
482 max = sb->sb_buf.buf_size - sb->sb_buf.buf_end;
483 if (max> (ber_slen_t) len) {
485 ret = sockbuf_io_read( sb,
486 sb->sb_buf.buf_base +
490 if ((ret<0) && (errno==EINTR))
496 /* some error occured */
499 sb->sb_buf.buf_end += ret;
500 /* move out the data... */
501 len = sockbuf_copy_out( sb, &buf, len );
505 /* no read_ahead, just try to put the data in the buf. */
507 ret = sockbuf_io_read( sb, buf, len );
509 if ((ret<0) && (errno==EINTR))
518 /* we might as well return, since there is nothing to do... */
523 assert( status_is_ok(sb) );
524 if ((ret<=0) && (buf==buf_arg)) {
525 /* there was an error. */
528 return (buf - ((char *) buf_arg));
532 long sockbuf_do_write( Sockbuf *sb )
537 assert( sb != NULL );
538 assert( SOCKBUF_VALID( sb ) );
540 to_go = sb->sb_sec_out.buf_end - sb->sb_sec_out.buf_ptr;
542 /* there is something left of the last time... */
544 ret = sockbuf_io_write( sb, sb->sb_sec_out.buf_base+
545 sb->sb_sec_out.buf_ptr, to_go );
547 if ((ret<0) && (errno==EINTR))
552 if (ret<=0) /* error */
554 sb->sb_sec_out.buf_ptr += ret;
555 if (ret<to_go) /* not enough data, so pretend no data was sent. */
561 ber_slen_t ber_pvt_sb_write( Sockbuf *sb, void *buf, ber_len_t len_arg )
564 ber_len_t len = len_arg;
566 assert( buf != NULL );
567 assert( sb != NULL );
568 assert( SOCKBUF_VALID( sb ) );
569 assert( status_is_ok(sb) );
571 /* slapd might have problems with this */
572 assert( ber_pvt_sb_in_use( sb ) );
574 #ifdef TEST_PARTIAL_WRITE
575 if ((rand() & 3)==1) { /* 1 out of 4 */
580 len_arg = (rand() % len_arg)+1;
586 assert( sb->sb_sec_prev_len <= len );
587 if (sb->sb_sec_prev_len) {
588 ret = sockbuf_do_write( sb );
592 len -= sb->sb_sec_prev_len;
593 sb->sb_sec_prev_len = 0;
594 sb->sb_sec_out.buf_end = sb->sb_sec_out.buf_ptr = 0;
596 /* now protect the next packet. */
597 ret = sockbuf_sec_protect( sb, buf, len );
600 ret = sockbuf_do_write( sb );
602 sb->sb_sec_prev_len = len;
609 ret = sockbuf_io_write( sb, buf, len );
611 if ((ret<0) && (errno==EINTR))
623 int ber_pvt_sb_close( Sockbuf *sb )
627 assert( sb != NULL );
628 assert( SOCKBUF_VALID( sb ) );
630 assert( sb->sb_io->sbi_close );
631 assert( status_is_ok(sb) );
632 assert( ber_pvt_sb_in_use( sb ) );
634 ret = sb->sb_io->sbi_close( sb );
635 ber_pvt_sb_set_desc( sb, -1 );
640 int ber_pvt_sb_set_readahead( Sockbuf *sb, int rh )
642 assert( sb != NULL );
643 assert( SOCKBUF_VALID( sb ) );
644 assert( status_is_ok(sb) );
645 sb->sb_read_ahead = (rh!=0);
649 int ber_pvt_socket_set_nonblock( ber_socket_t sd, int nb )
652 int flags = fcntl(ber_pvt_sb_get_desc(sb), F_GETFL);
656 flags &= ~O_NONBLOCK;
658 return fcntl( ber_pvt_sb_get_desc(sb), F_SETFL, flags );
660 #elif defined( FIONBIO )
661 ioctl_t status = nb ? 1 : 0;
662 return ioctl( sd, FIONBIO, &status );
668 int ber_pvt_sb_set_nonblock( Sockbuf *sb, int nb )
670 assert( sb != NULL );
671 assert( SOCKBUF_VALID( sb ) );
672 assert( status_is_ok(sb) );
674 sb->sb_non_block = 1;
676 sb->sb_read_ahead = 1;
679 sb->sb_non_block = 0;
681 sb->sb_read_ahead = 0;
684 if (ber_pvt_sb_in_use(sb)) {
685 return ber_pvt_socket_set_nonblock(
686 ber_pvt_sb_get_desc(sb), nb );
692 #define sockbuf_buf_init( bb ) do { \
693 Sockbuf_Buf *sbb = (bb); \
694 sbb->buf_base = NULL; \
701 sockbuf_buf_destroy( Sockbuf_Buf *buf )
703 assert( buf != NULL);
706 LBER_FREE( buf->buf_base );
707 sockbuf_buf_init( buf );
711 int ber_pvt_sb_init( Sockbuf *sb )
715 ber_int_options.lbo_valid = LBER_INITIALIZED;
717 sb->sb_valid=LBER_VALID_SOCKBUF;
720 sb->sb_trans_ready = 0;
721 sb->sb_buf_ready = 0;
723 sb->sb_sec_ready = 0;
725 sb->sb_read_ahead = 1; /* test */
726 sb->sb_non_block = 0;
727 sb->sb_trans_needs_read = 0;
728 sb->sb_trans_needs_write = 0;
730 sb->sb_iodata = NULL;
731 sb->sb_io = &sb_IO_None;
734 sb->sb_max_incoming = 0;
736 sockbuf_buf_init( &(sb->sb_buf) );
738 sockbuf_buf_init( &(sb->sb_sec_buf_in) );
739 sockbuf_buf_init( &(sb->sb_sec_buf_out) );
742 sb->sb_sec_prev_len = 0;
745 assert( SOCKBUF_VALID( sb ) );
749 int ber_pvt_sb_destroy( Sockbuf *sb )
752 assert( SOCKBUF_VALID(sb) );
754 ber_pvt_sb_clear_sec(sb);
755 sockbuf_buf_destroy( &(sb->sb_sec_buf_in) );
756 sockbuf_buf_destroy( &(sb->sb_sec_buf_out) );
758 ber_pvt_sb_clear_io(sb);
759 sockbuf_buf_destroy( &(sb->sb_buf) );
760 return ber_pvt_sb_init( sb );
764 int ber_pvt_sb_set_sec( Sockbuf *sb, Sockbuf_Sec * sec, void *arg )
768 assert( SOCKBUF_VALID( *sb ) );
769 if ((sb->sb_sec) || (sec==NULL))
774 if ((sec->sbs_setup) && (sec->sbs_setup( sb, arg)<0)) {
778 len = sb->sb_buf.buf_end - sb->sb_buf.buf_ptr;
781 /* move this to the security layer. */
782 if (grow_buffer( &(sb->sb_sec_buf_in), len )<0)
784 memcpy( sb->sb_sec_buf_in.buf_base,
785 sb->sb_buf.buf_base + sb->sb_buf.buf_ptr, len );
786 sb->sb_sec_buf_in.buf_ptr = len;
787 sb->sb_sec_buf_in.buf_end = (len>4) ? packet_length( sb, sb->sb_sec_buf_in ) : 0;
788 sb->sb_buf.buf_ptr = sb->sb_buf.buf_end = 0;
794 int ber_pvt_sb_clear_sec( Sockbuf *sb )
797 assert( SOCKBUF_VALID( sb ) );
799 if (sb->sb_buf.buf_ptr!=0)
801 if (sb->sb_sec==NULL)
803 if ((sb->sb_sec->sbs_remove) && (sb->sb_sec->sbs_remove(sb)<0))
807 if (sb->sb_sec_buf_in.buf_ptr!=0) {
808 if (grow_buffer( &(sb->sb_buf),
809 sb->sb_buf.buf_end + sb->sb_sec_buf_in.buf_ptr)<0)
811 memcpy( sb->sb_buf.buf_base + sb->sb_buf.buf_end,
812 sb->sb_sec_buf_in.buf_base, sb->sb_sec_buf_in.buf_ptr );
813 sb->sb_buf.buf_end += sb->sb_sec_buf_in.buf_ptr;
814 sb->sb_buf_ready = 1;
816 sockbuf_buf_destroy( &(sb->sb_sec_buf_in) );
817 assert( sb->sb_sec_buf.buf_end==0 );
818 sockbuf_buf_destroy( &(sb->sb_sec_buf_out) );
820 sb->sb_sec_ready = 0;
826 int ber_pvt_sb_set_io( Sockbuf *sb, Sockbuf_IO *trans, void *arg )
829 assert( SOCKBUF_VALID( sb ) );
830 assert( sb->sb_io == &sb_IO_None );
837 if ((trans->sbi_setup) && (trans->sbi_setup( sb, arg)<0))
843 int ber_pvt_sb_clear_io( Sockbuf *sb )
846 assert( SOCKBUF_VALID( sb ) );
848 if (sb->sb_io==&sb_IO_None)
851 if ((sb->sb_io->sbi_remove) && (sb->sb_io->sbi_remove( sb )<0))
854 sb->sb_io = &sb_IO_None;
856 sb->sb_trans_ready = 0;
857 sb->sb_trans_needs_read = 0;
858 sb->sb_trans_needs_write = 0;
868 stream_read( Sockbuf *sb, void *buf, ber_len_t len )
871 assert( SOCKBUF_VALID( sb ) );
875 * MacTCP/OpenTransport
877 return tcpread( ber_pvt_sb_get_desc(sb), 0, (unsigned char *)buf,
880 #elif defined( HAVE_PCNFS ) || \
881 defined( HAVE_WINSOCK ) || defined ( __BEOS__ )
886 * Windows Socket API (under DOS/Windows 3.x)
889 * 32-bit Windows Socket API (under Windows NT or Windows 95)
893 rc = recv( ber_pvt_sb_get_desc(sb), buf, len, 0 );
895 if ( rc < 0 ) errno = WSAGetLastError();
899 #elif defined( HAVE_NCSA )
901 * NCSA Telnet TCP/IP stack (under DOS)
903 return nread( ber_pvt_sb_get_desc(sb), buf, len );
906 return read( ber_pvt_sb_get_desc(sb), buf, len );
911 stream_write( Sockbuf *sb, void *buf, ber_len_t len )
914 assert( SOCKBUF_VALID( sb ) );
918 * MacTCP/OpenTransport
920 #define MAX_WRITE 65535
921 return tcpwrite( ber_pvt_sb_get_desc(sb),
922 (unsigned char *)(buf),
923 (len<MAX_WRITE)? len : MAX_WRITE );
925 #elif defined( HAVE_PCNFS) \
926 || defined( HAVE_WINSOCK) || defined ( __BEOS__ )
931 * Windows Socket API (under DOS/Windows 3.x)
934 * 32-bit Windows Socket API (under Windows NT or Windows 95)
939 rc = send( ber_pvt_sb_get_desc(sb), buf, len, 0 );
941 if ( rc < 0 ) errno = WSAGetLastError();
946 #elif defined(HAVE_NCSA)
947 return netwrite( ber_pvt_sb_get_desc(sb), buf, len );
951 * VMS -- each write must be 64K or smaller
953 #define MAX_WRITE 65535
954 return write( ber_pvt_sb_get_desc(sb), buf,
955 (len<MAX_WRITE)? len : MAX_WRITE);
957 return write( ber_pvt_sb_get_desc(sb), buf, len );
962 stream_close( Sockbuf *sb )
965 assert( SOCKBUF_VALID( sb ) );
966 tcp_close( ber_pvt_sb_get_desc( sb ) );
970 Sockbuf_IO ber_pvt_sb_io_tcp=
972 NULL, /* sbi_setup */
973 NULL, /* sbi_release */
974 stream_read, /* sbi_read */
975 stream_write, /* sbi_write */
976 stream_close, /* sbi_close */
980 * Support for UDP (CLDAP)
990 dgram_setup( Sockbuf *sb, void *arg )
993 assert( SOCKBUF_VALID( sb ) );
995 sb->sb_iodata = LBER_MALLOC( sizeof( struct dgram_data ) );
996 if (sb->sb_iodata==NULL)
998 sb->sb_read_ahead = 1; /* important since udp is packet based. */
1003 dgram_release( Sockbuf *sb )
1005 assert( sb != NULL);
1006 assert( SOCKBUF_VALID( sb ) );
1008 LBER_FREE( sb->sb_iodata );
1013 dgram_read( Sockbuf *sb, void *buf, ber_len_t len )
1015 #ifdef LDAP_CONNECTIONLESS
1018 struct dgram_data *dd;
1020 assert( sb != NULL );
1021 assert( SOCKBUF_VALID( sb ) );
1022 assert( buf != NULL );
1024 dd = (struct dgram_data *)(sb->sb_iodata);
1026 addrlen = sizeof( struct sockaddr );
1027 rc=recvfrom( ber_pvt_sb_get_desc(sb), buf, len, 0, &(dd->src), &addrlen );
1029 if ( sb->sb_debug ) {
1030 ber_log_printf( LDAP_DEBUG_ANY, sb->sb_debug,
1031 "dgram_read udp_read %ld bytes\n",
1034 ber_log_bprint( LDAP_DEBUG_PACKETS, sb->sb_debug,
1038 # else /* LDAP_CONNECTIONLESS */
1040 # endif /* LDAP_CONNECTIONLESS */
1044 dgram_write( Sockbuf *sb, void *buf, ber_len_t len )
1046 #ifdef LDAP_CONNECTIONLESS
1048 struct dgram_data *dd;
1050 assert( sb != NULL );
1051 assert( SOCKBUF_VALID( sb ) );
1052 assert( buf != NULL );
1054 dd = (struct dgram_data *)(sb->sb_iodata);
1056 rc=sendto( ber_pvt_sb_get_desc(sb), buf, len, 0, &(dd->dst),
1057 sizeof( struct sockaddr ) );
1062 /* fake error if write was not atomic */
1076 dgram_close( Sockbuf *sb )
1078 assert( sb != NULL );
1079 assert( SOCKBUF_VALID( sb ) );
1081 tcp_close( ber_pvt_sb_get_desc(sb) );
1085 Sockbuf_IO ber_pvt_sb_io_udp=
1087 dgram_setup, /* sbi_setup */
1088 dgram_release, /* sbi_release */
1089 dgram_read, /* sbi_read */
1090 dgram_write, /* sbi_write */
1091 dgram_close, /* sbi_close */
1094 int ber_pvt_sb_udp_set_dst(Sockbuf *sb, void *addr )
1096 struct dgram_data *dd;
1097 assert( sb != NULL );
1098 assert( SOCKBUF_VALID( sb ) );
1099 assert( sb->sb_io == &ber_pvt_sb_io_udp );
1100 dd = (struct dgram_data *) (sb->sb_iodata);
1101 memcpy( &(dd->dst), addr, sizeof( struct sockaddr ) );
1105 void *ber_pvt_sb_udp_get_src( Sockbuf *sb )
1107 struct dgram_data *dd;
1109 assert( sb != NULL );
1110 assert( SOCKBUF_VALID( sb ) );
1111 assert( sb->sb_io == &ber_pvt_sb_io_udp );
1112 dd = (struct dgram_data *) (sb->sb_iodata);
1120 * These routines should really call abort, but at the moment that would
1121 * break the servers.
1125 have_no_read( Sockbuf *sb, void *buf, ber_len_t len )
1127 assert( sb != NULL );
1128 assert( SOCKBUF_VALID( sb ) );
1130 ber_log_printf( LDAP_DEBUG_ANY, ber_int_debug,
1131 "warning: reading from uninitialized sockbuf\n");
1137 have_no_write( Sockbuf *sb, void *buf, ber_len_t len )
1139 assert( sb != NULL );
1140 assert( SOCKBUF_VALID( sb ) );
1142 ber_log_printf( LDAP_DEBUG_ANY, ber_int_debug,
1143 "warning: writing to uninitialized sockbuf\n");
1149 have_no_close( Sockbuf *sb )
1151 assert( sb != NULL );
1152 assert( SOCKBUF_VALID( sb ) );