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>
33 #undef TEST_PARTIAL_READ
34 #undef TEST_PARTIAL_WRITE
37 #define MAX_BUF_SIZE 65535
38 #define MIN_BUF_SIZE 4096
40 #define sockbuf_io_write( sb, buf, len ) \
41 ((sb)->sb_io->sbi_write( (sb), (buf), (len) ))
43 #define sockbuf_io_read( sb, buf, len ) \
44 ((sb)->sb_io->sbi_read( (sb), (buf), (len) ))
46 static ber_slen_t have_no_read( Sockbuf *sb, void *buf, ber_len_t len );
47 static ber_slen_t have_no_write( Sockbuf *sb, void *buf, ber_len_t len );
48 static int have_no_close( Sockbuf *sb );
50 static Sockbuf_IO sb_IO_None=
53 NULL, /* sbi_release */
54 have_no_read, /* sbi_read */
55 have_no_write, /* sbi_write */
56 have_no_close /* sbi_close */
60 update_status( Sockbuf *sb )
63 assert( SOCKBUF_VALID( sb ) );
65 sb->sb_buf_ready = (sb->sb_buf.buf_ptr < sb->sb_buf.buf_end);
67 sb->sb_sec_ready = ((sb->sb_sec_buf_in.buf_end!=0) &&
68 (sb->sb_sec_buf_in.buf_ptr >=
69 sb->sb_sec_buf_in.buf_end));
75 status_is_ok( Sockbuf *sb )
83 assert( SOCKBUF_VALID( sb ) );
85 obr = sb->sb_buf_ready;
87 osr = sb->sb_sec_ready;
91 if (obr!=sb->sb_buf_ready)
95 if (osr!=sb->sb_sec_ready)
105 packet_length( Sockbuf *sb, const char *buf )
109 assert( buf != NULL );
111 size = (((ber_len_t)buf[0])<<24)|
112 (((ber_len_t)buf[1])<<16)|
113 (((ber_len_t)buf[2])<<8)|
114 (((ber_len_t)buf[3]));
116 if ( size > MAX_BUF_SIZE ) {
117 /* somebody is trying to mess me up. */
118 ber_log_printf( LDAP_DEBUG_SASL, sb->sb_debug,
119 "SASL: received packet length of %lu bytes\n",
120 (unsigned long) size );
121 size = 16; /* this should lead to an error. */
124 return size + 4; /* include the size !!! */
129 grow_buffer( Sockbuf_Buf * buf, ber_len_t minsize )
133 assert( buf != NULL );
135 for( pw=MIN_BUF_SIZE; pw<minsize; pw<<=1 ) {
136 if (pw > MAX_BUF_SIZE) {
137 /* this could mean that somebody is trying to crash us. */
143 if (buf->buf_size<minsize) {
144 if ((buf->buf_base==NULL) || ((buf->buf_end==0) && (buf->buf_ptr==0))) {
146 if (buf->buf_base!=NULL)
147 LBER_FREE( buf->buf_base );
148 assert( buf->buf_ptr==0 );
149 assert( buf->buf_end==0 );
150 buf->buf_base = LBER_MALLOC( minsize );
151 if (buf->buf_base==NULL)
155 nb = LBER_REALLOC( buf->buf_base, minsize );
160 buf->buf_size = minsize;
167 sockbuf_sec_release( Sockbuf *sb, char *buf, ber_len_t len )
169 /* when this is called:
170 * sb->sb_sec_buf_in.buf_base points to a packet.
171 * sb->sb_sec_buf_in.buf_ptr contains the total bytes read.
172 * sb->sb_sec_end.buf_end contains the packet length.
174 * sb->sb_buf.buf_ptr == sb->sb_buf.buf_end == 0;
182 assert( buf != NULL );
183 assert( sb != NULL );
184 assert( SOCKBUF_VALID( sb ) );
186 assert( sb->sb_sec );
187 assert( sb->sb_sec->sbs_release );
188 assert( sb->sb_sec_buf_in.sb_ptr >= sb->sb_sec_buf_in.sb_end );
190 assert( sb->sb_buf.sb_ptr == 0 );
191 assert( sb->sb_buf.sb_end == 0 );
193 assert( status_is_ok(sb) );
197 ptr = sb->sb_sec_buf_in.buf_base;
198 end = ptr+ sb->sb_sec_buf_in.buf_ptr;
199 size = sb->sb_sec_buf_in.buf_end;
201 sb->sb_sec_ready = 1;
203 for(;(ptr+size<=end);) {
205 rlen = sb->sb_sec->sbs_release( sb, ptr, size,
208 sb->sb_buf.buf_size );
210 /* this means a security violation. */
211 return total; /* total ? total : 0 */
214 /* this means that the buffer isn't big enough. */
215 if (grow_buffer( &(sb->sb_buf), -rlen )<0)
216 /* memory violation. */
217 return total; /* total ? total : 0 */
225 /* move to the next packet... */
229 size = packet_length( sb, ptr );
230 /* size is always at least 4, so the loop condition is always OK !!*/
237 sb->sb_buf_ready = (sb->sb_buf.buf_end = rlen - len) ? 1 : 0;
243 sb->sb_sec_ready = 0;
244 /* clean up the mess. */
246 /* copy back to beginning of buffer. */
247 SAFEMEMCPY( sb->sb_sec_buf_in.buf_base, ptr, end-ptr );
248 sb->sb_sec_buf_in.buf_ptr = 0;
249 sb->sb_sec_buf_in.buf_end -= (ptr - sb->sb_sec_buf_in.buf_base);
251 assert( status_is_ok(sb) );
256 sockbuf_sec_protect( Sockbuf *sb, char *buf, long len )
262 assert( buf != NULL );
264 assert( sb != NULL );
265 assert( SOCKBUF_VALID( sb ) );
267 assert( sb->sb_sec_out.buf_end == 0 );
268 assert( sb->sb_sec_out.buf_ptr == 0 );
270 assert( sb->sb_sec );
271 assert( sb->sb_sec->sbs_protect );
273 assert( status_is_ok(sb) );
279 ret = sb->sb_sec->sbs_protect( sb, buf, &blen,
280 sb->sb_sec_out.buf_base+
281 sb->sb_sec_out.buf_end,
282 sb->sb_sec_out.buf_size -
283 sb->sb_sec_out.buf_end );
285 /* protection error ? */
288 if (grow_buffer( &(sb->sb_sec_out),-ret-sb->sb_sec_out.buf_end )<0)
293 /* else if (ret>0) */
296 sb->sb_sec_out.buf_end += ret;
300 assert( status_is_ok(sb) );
306 sockbuf_copy_out( Sockbuf *sb, char **buf, ber_len_t len )
308 ber_len_t blen = (sb->sb_buf.buf_end - sb->sb_buf.buf_ptr );
310 assert( buf != NULL );
312 assert( sb != NULL );
313 assert( SOCKBUF_VALID( sb ) );
314 assert( status_is_ok(sb) );
317 ber_len_t rlen = (blen<len) ? blen : len;
318 memcpy( *buf, sb->sb_buf.buf_base + sb->sb_buf.buf_ptr, rlen );
319 sb->sb_buf.buf_ptr+=rlen;
322 if (sb->sb_buf.buf_ptr >= sb->sb_buf.buf_end) {
323 sb->sb_buf.buf_ptr = sb->sb_buf.buf_end = 0;
324 sb->sb_buf_ready = 0;
326 sb->sb_buf_ready = 1;
329 assert( status_is_ok(sb) );
333 Sockbuf *ber_sockbuf_alloc( void )
337 ber_int_options.lbo_valid = LBER_INITIALIZED;
339 sb = LBER_CALLOC(1, sizeof(Sockbuf));
341 if( sb == NULL ) return NULL;
343 ber_pvt_sb_init( sb );
347 Sockbuf *ber_sockbuf_alloc_fd( ber_socket_t fd )
349 Sockbuf *sb = ber_sockbuf_alloc();
351 if( sb == NULL ) return NULL;
353 ber_pvt_sb_set_desc( sb, fd );
354 ber_pvt_sb_set_io( sb, &ber_pvt_sb_io_tcp, NULL );
358 void ber_sockbuf_free( Sockbuf *sb )
361 assert( SOCKBUF_VALID( sb ) );
362 ber_pvt_sb_destroy( sb );
367 ber_pvt_sb_read( Sockbuf *sb, void *buf_arg, ber_len_t len )
372 assert( buf_arg != NULL );
373 assert( sb != NULL );
374 assert( SOCKBUF_VALID( sb ) );
375 assert( status_is_ok(sb) );
377 /* slapd might have problems with this */
378 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->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->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;
480 if (max> (ber_slen_t) len) {
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 )
534 assert( sb != NULL );
535 assert( SOCKBUF_VALID( sb ) );
537 to_go = sb->sb_sec_out.buf_end - sb->sb_sec_out.buf_ptr;
539 /* there is something left of the last time... */
541 ret = sockbuf_io_write( sb, sb->sb_sec_out.buf_base+
542 sb->sb_sec_out.buf_ptr, to_go );
544 if ((ret<0) && (errno==EINTR))
549 if (ret<=0) /* error */
551 sb->sb_sec_out.buf_ptr += ret;
552 if (ret<to_go) /* not enough data, so pretend no data was sent. */
558 ber_slen_t ber_pvt_sb_write( Sockbuf *sb, void *buf, ber_len_t len_arg )
561 ber_len_t len = len_arg;
563 assert( buf != NULL );
564 assert( sb != NULL );
565 assert( SOCKBUF_VALID( sb ) );
566 assert( status_is_ok(sb) );
568 /* slapd might have problems with this */
569 assert( ber_pvt_sb_in_use( sb ) );
571 #ifdef TEST_PARTIAL_WRITE
572 if ((rand() & 3)==1) { /* 1 out of 4 */
577 len_arg = (rand() % len_arg)+1;
583 assert( sb->sb_sec_prev_len <= len );
584 if (sb->sb_sec_prev_len) {
585 ret = sockbuf_do_write( sb );
589 len -= sb->sb_sec_prev_len;
590 sb->sb_sec_prev_len = 0;
591 sb->sb_sec_out.buf_end = sb->sb_sec_out.buf_ptr = 0;
593 /* now protect the next packet. */
594 ret = sockbuf_sec_protect( sb, buf, len );
597 ret = sockbuf_do_write( sb );
599 sb->sb_sec_prev_len = len;
606 ret = sockbuf_io_write( sb, buf, len );
608 if ((ret<0) && (errno==EINTR))
620 int ber_pvt_sb_close( Sockbuf *sb )
624 assert( sb != NULL );
625 assert( SOCKBUF_VALID( sb ) );
627 assert( sb->sb_io->sbi_close );
628 assert( status_is_ok(sb) );
629 assert( ber_pvt_sb_in_use( sb ) );
631 ret = sb->sb_io->sbi_close( sb );
632 ber_pvt_sb_set_desc( sb, -1 );
637 int ber_pvt_sb_set_readahead( Sockbuf *sb, int rh )
639 assert( sb != NULL );
640 assert( SOCKBUF_VALID( sb ) );
641 assert( status_is_ok(sb) );
642 sb->sb_read_ahead = (rh!=0);
646 int ber_pvt_socket_set_nonblock( ber_socket_t sd, int nb )
649 int flags = fcntl(ber_pvt_sb_get_desc(sb), F_GETFL);
653 flags &= ~O_NONBLOCK;
655 return fcntl( ber_pvt_sb_get_desc(sb), F_SETFL, flags );
657 #elif defined( FIONBIO )
658 ioctl_t status = nb ? 1 : 0;
659 return ioctl( sd, FIONBIO, &status );
665 int ber_pvt_sb_set_nonblock( Sockbuf *sb, int nb )
667 assert( sb != NULL );
668 assert( SOCKBUF_VALID( sb ) );
669 assert( status_is_ok(sb) );
671 sb->sb_non_block = 1;
673 sb->sb_read_ahead = 1;
676 sb->sb_non_block = 0;
678 sb->sb_read_ahead = 0;
681 if (ber_pvt_sb_in_use(sb)) {
682 return ber_pvt_socket_set_nonblock(
683 ber_pvt_sb_get_desc(sb), nb );
689 #define sockbuf_buf_init( bb ) do { \
690 Sockbuf_Buf *sbb = (bb); \
691 sbb->buf_base = NULL; \
698 sockbuf_buf_destroy( Sockbuf_Buf *buf )
700 assert( buf != NULL);
703 LBER_FREE( buf->buf_base );
704 sockbuf_buf_init( buf );
708 int ber_pvt_sb_init( Sockbuf *sb )
712 ber_int_options.lbo_valid = LBER_INITIALIZED;
714 sb->sb_valid=LBER_VALID_SOCKBUF;
717 sb->sb_trans_ready = 0;
718 sb->sb_buf_ready = 0;
720 sb->sb_sec_ready = 0;
722 sb->sb_read_ahead = 1; /* test */
723 sb->sb_non_block = 0;
724 sb->sb_trans_needs_read = 0;
725 sb->sb_trans_needs_write = 0;
727 sb->sb_iodata = NULL;
728 sb->sb_io = &sb_IO_None;
731 sb->sb_max_incoming = 0;
733 sockbuf_buf_init( &(sb->sb_buf) );
735 sockbuf_buf_init( &(sb->sb_sec_buf_in) );
736 sockbuf_buf_init( &(sb->sb_sec_buf_out) );
739 sb->sb_sec_prev_len = 0;
742 assert( SOCKBUF_VALID( sb ) );
746 int ber_pvt_sb_destroy( Sockbuf *sb )
749 assert( SOCKBUF_VALID(sb) );
751 ber_pvt_sb_clear_sec(sb);
752 sockbuf_buf_destroy( &(sb->sb_sec_buf_in) );
753 sockbuf_buf_destroy( &(sb->sb_sec_buf_out) );
755 ber_pvt_sb_clear_io(sb);
756 sockbuf_buf_destroy( &(sb->sb_buf) );
757 return ber_pvt_sb_init( sb );
761 int ber_pvt_sb_set_sec( Sockbuf *sb, Sockbuf_Sec * sec, void *arg )
765 assert( SOCKBUF_VALID( *sb ) );
766 if ((sb->sb_sec) || (sec==NULL))
771 if ((sec->sbs_setup) && (sec->sbs_setup( sb, arg)<0)) {
775 len = sb->sb_buf.buf_end - sb->sb_buf.buf_ptr;
778 /* move this to the security layer. */
779 if (grow_buffer( &(sb->sb_sec_buf_in), len )<0)
781 memcpy( sb->sb_sec_buf_in.buf_base,
782 sb->sb_buf.buf_base + sb->sb_buf.buf_ptr, len );
783 sb->sb_sec_buf_in.buf_ptr = len;
784 sb->sb_sec_buf_in.buf_end = (len>4) ? packet_length( sb, sb->sb_sec_buf_in ) : 0;
785 sb->sb_buf.buf_ptr = sb->sb_buf.buf_end = 0;
791 int ber_pvt_sb_clear_sec( Sockbuf *sb )
794 assert( SOCKBUF_VALID( sb ) );
796 if (sb->sb_buf.buf_ptr!=0)
798 if (sb->sb_sec==NULL)
800 if ((sb->sb_sec->sbs_remove) && (sb->sb_sec->sbs_remove(sb)<0))
804 if (sb->sb_sec_buf_in.buf_ptr!=0) {
805 if (grow_buffer( &(sb->sb_buf),
806 sb->sb_buf.buf_end + sb->sb_sec_buf_in.buf_ptr)<0)
808 memcpy( sb->sb_buf.buf_base + sb->sb_buf.buf_end,
809 sb->sb_sec_buf_in.buf_base, sb->sb_sec_buf_in.buf_ptr );
810 sb->sb_buf.buf_end += sb->sb_sec_buf_in.buf_ptr;
811 sb->sb_buf_ready = 1;
813 sockbuf_buf_destroy( &(sb->sb_sec_buf_in) );
814 assert( sb->sb_sec_buf.buf_end==0 );
815 sockbuf_buf_destroy( &(sb->sb_sec_buf_out) );
817 sb->sb_sec_ready = 0;
823 int ber_pvt_sb_set_io( Sockbuf *sb, Sockbuf_IO *trans, void *arg )
826 assert( SOCKBUF_VALID( sb ) );
827 assert( sb->sb_io == &sb_IO_None );
834 if ((trans->sbi_setup) && (trans->sbi_setup( sb, arg)<0))
840 int ber_pvt_sb_clear_io( Sockbuf *sb )
843 assert( SOCKBUF_VALID( sb ) );
845 if (sb->sb_io==&sb_IO_None)
848 if ((sb->sb_io->sbi_remove) && (sb->sb_io->sbi_remove( sb )<0))
851 sb->sb_io = &sb_IO_None;
853 sb->sb_trans_ready = 0;
854 sb->sb_trans_needs_read = 0;
855 sb->sb_trans_needs_write = 0;
865 stream_read( Sockbuf *sb, void *buf, ber_len_t len )
868 assert( SOCKBUF_VALID( sb ) );
872 * MacTCP/OpenTransport
874 return tcpread( ber_pvt_sb_get_desc(sb), 0, (unsigned char *)buf,
877 #elif defined( HAVE_PCNFS ) || \
878 defined( HAVE_WINSOCK ) || defined ( __BEOS__ )
883 * Windows Socket API (under DOS/Windows 3.x)
886 * 32-bit Windows Socket API (under Windows NT or Windows 95)
890 rc = recv( ber_pvt_sb_get_desc(sb), buf, len, 0 );
897 err = WSAGetLastError();
904 #elif defined( HAVE_NCSA )
906 * NCSA Telnet TCP/IP stack (under DOS)
908 return nread( ber_pvt_sb_get_desc(sb), buf, len );
911 return read( ber_pvt_sb_get_desc(sb), buf, len );
916 stream_write( Sockbuf *sb, void *buf, ber_len_t len )
919 assert( SOCKBUF_VALID( sb ) );
923 * MacTCP/OpenTransport
925 #define MAX_WRITE 65535
926 return tcpwrite( ber_pvt_sb_get_desc(sb),
927 (unsigned char *)(buf),
928 (len<MAX_WRITE)? len : MAX_WRITE );
930 #elif defined( HAVE_PCNFS) \
931 || defined( HAVE_WINSOCK) || defined ( __BEOS__ )
936 * Windows Socket API (under DOS/Windows 3.x)
939 * 32-bit Windows Socket API (under Windows NT or Windows 95)
944 rc = send( ber_pvt_sb_get_desc(sb), buf, len, 0 );
949 err = WSAGetLastError();
956 #elif defined(HAVE_NCSA)
957 return netwrite( ber_pvt_sb_get_desc(sb), buf, len );
961 * VMS -- each write must be 64K or smaller
963 #define MAX_WRITE 65535
964 return write( ber_pvt_sb_get_desc(sb), buf,
965 (len<MAX_WRITE)? len : MAX_WRITE);
967 return write( ber_pvt_sb_get_desc(sb), buf, len );
972 stream_close( Sockbuf *sb )
975 assert( SOCKBUF_VALID( sb ) );
976 tcp_close( ber_pvt_sb_get_desc( sb ) );
980 Sockbuf_IO ber_pvt_sb_io_tcp=
982 NULL, /* sbi_setup */
983 NULL, /* sbi_release */
984 stream_read, /* sbi_read */
985 stream_write, /* sbi_write */
986 stream_close, /* sbi_close */
990 * Support for UDP (CLDAP)
1000 dgram_setup( Sockbuf *sb, void *arg )
1002 assert( sb != NULL);
1003 assert( SOCKBUF_VALID( sb ) );
1005 sb->sb_iodata = LBER_MALLOC( sizeof( struct dgram_data ) );
1006 if (sb->sb_iodata==NULL)
1008 sb->sb_read_ahead = 1; /* important since udp is packet based. */
1013 dgram_release( Sockbuf *sb )
1015 assert( sb != NULL);
1016 assert( SOCKBUF_VALID( sb ) );
1018 LBER_FREE( sb->sb_iodata );
1023 dgram_read( Sockbuf *sb, void *buf, ber_len_t len )
1025 #ifdef LDAP_CONNECTIONLESS
1028 struct dgram_data *dd;
1030 assert( sb != NULL );
1031 assert( SOCKBUF_VALID( sb ) );
1032 assert( buf != NULL );
1034 dd = (struct dgram_data *)(sb->sb_iodata);
1036 addrlen = sizeof( struct sockaddr );
1037 rc=recvfrom( ber_pvt_sb_get_desc(sb), buf, len, 0, &(dd->src), &addrlen );
1039 if ( sb->sb_debug ) {
1040 ber_log_printf( LDAP_DEBUG_ANY, sb->sb_debug,
1041 "dgram_read udp_read %ld bytes\n",
1044 ber_log_bprint( LDAP_DEBUG_PACKETS, sb->sb_debug,
1048 # else /* LDAP_CONNECTIONLESS */
1050 # endif /* LDAP_CONNECTIONLESS */
1054 dgram_write( Sockbuf *sb, void *buf, ber_len_t len )
1056 #ifdef LDAP_CONNECTIONLESS
1058 struct dgram_data *dd;
1060 assert( sb != NULL );
1061 assert( SOCKBUF_VALID( sb ) );
1062 assert( buf != NULL );
1064 dd = (struct dgram_data *)(sb->sb_iodata);
1066 rc=sendto( ber_pvt_sb_get_desc(sb), buf, len, 0, &(dd->dst),
1067 sizeof( struct sockaddr ) );
1072 /* fake error if write was not atomic */
1086 dgram_close( Sockbuf *sb )
1088 assert( sb != NULL );
1089 assert( SOCKBUF_VALID( sb ) );
1091 tcp_close( ber_pvt_sb_get_desc(sb) );
1095 Sockbuf_IO ber_pvt_sb_io_udp=
1097 dgram_setup, /* sbi_setup */
1098 dgram_release, /* sbi_release */
1099 dgram_read, /* sbi_read */
1100 dgram_write, /* sbi_write */
1101 dgram_close, /* sbi_close */
1104 int ber_pvt_sb_udp_set_dst(Sockbuf *sb, void *addr )
1106 struct dgram_data *dd;
1107 assert( sb != NULL );
1108 assert( SOCKBUF_VALID( sb ) );
1109 assert( sb->sb_io == &ber_pvt_sb_io_udp );
1110 dd = (struct dgram_data *) (sb->sb_iodata);
1111 memcpy( &(dd->dst), addr, sizeof( struct sockaddr ) );
1115 void *ber_pvt_sb_udp_get_src( Sockbuf *sb )
1117 struct dgram_data *dd;
1119 assert( sb != NULL );
1120 assert( SOCKBUF_VALID( sb ) );
1121 assert( sb->sb_io == &ber_pvt_sb_io_udp );
1122 dd = (struct dgram_data *) (sb->sb_iodata);
1130 * These routines should really call abort, but at the moment that would
1131 * break the servers.
1135 have_no_read( Sockbuf *sb, void *buf, ber_len_t len )
1137 assert( sb != NULL );
1138 assert( SOCKBUF_VALID( sb ) );
1140 ber_log_printf( LDAP_DEBUG_ANY, ber_int_debug,
1141 "warning: reading from uninitialized sockbuf\n");
1147 have_no_write( Sockbuf *sb, void *buf, ber_len_t len )
1149 assert( sb != NULL );
1150 assert( SOCKBUF_VALID( sb ) );
1152 ber_log_printf( LDAP_DEBUG_ANY, ber_int_debug,
1153 "warning: writing to uninitialized sockbuf\n");
1159 have_no_close( Sockbuf *sb )
1161 assert( sb != NULL );
1162 assert( SOCKBUF_VALID( sb ) );