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>
30 #define LDAP_F_PRE LDAP_F_EXPORT
35 #undef TEST_PARTIAL_READ
36 #undef TEST_PARTIAL_WRITE
39 #define MAX_BUF_SIZE 65535
40 #define MIN_BUF_SIZE 4096
42 #define sockbuf_io_write( sb, buf, len ) \
43 ((sb)->sb_io->sbi_write( (sb), (buf), (len) ))
45 #define sockbuf_io_read( sb, buf, len ) \
46 ((sb)->sb_io->sbi_read( (sb), (buf), (len) ))
48 static ber_slen_t have_no_read( Sockbuf *sb, void *buf, ber_len_t len );
49 static ber_slen_t have_no_write( Sockbuf *sb, void *buf, ber_len_t len );
50 static int have_no_close( Sockbuf *sb );
52 static Sockbuf_IO sb_IO_None=
55 NULL, /* sbi_release */
56 have_no_read, /* sbi_read */
57 have_no_write, /* sbi_write */
58 have_no_close /* sbi_close */
62 update_status( Sockbuf *sb )
65 assert( SOCKBUF_VALID( sb ) );
67 sb->sb_buf_ready = (sb->sb_buf.buf_ptr < sb->sb_buf.buf_end);
69 sb->sb_sec_ready = ((sb->sb_sec_buf_in.buf_end!=0) &&
70 (sb->sb_sec_buf_in.buf_ptr >=
71 sb->sb_sec_buf_in.buf_end));
77 status_is_ok( Sockbuf *sb )
85 assert( SOCKBUF_VALID( sb ) );
87 obr = sb->sb_buf_ready;
89 osr = sb->sb_sec_ready;
93 if (obr!=sb->sb_buf_ready)
97 if (osr!=sb->sb_sec_ready)
107 packet_length( Sockbuf *sb, const char *buf )
111 assert( buf != NULL );
113 size = (((ber_len_t)buf[0])<<24)|
114 (((ber_len_t)buf[1])<<16)|
115 (((ber_len_t)buf[2])<<8)|
116 (((ber_len_t)buf[3]));
118 if ( size > MAX_BUF_SIZE ) {
119 /* somebody is trying to mess me up. */
120 ber_log_printf( LDAP_DEBUG_SASL, sb->sb_debug,
121 "SASL: received packet length of %lu bytes\n",
122 (unsigned long) size );
123 size = 16; /* this should lead to an error. */
126 return size + 4; /* include the size !!! */
131 grow_buffer( Sockbuf_Buf * buf, ber_len_t minsize )
135 assert( buf != NULL );
137 for( pw=MIN_BUF_SIZE; pw<minsize; pw<<=1 ) {
138 if (pw > MAX_BUF_SIZE) {
139 /* this could mean that somebody is trying to crash us. */
145 if (buf->buf_size<minsize) {
146 if ((buf->buf_base==NULL) || ((buf->buf_end==0) && (buf->buf_ptr==0))) {
148 if (buf->buf_base!=NULL)
149 LBER_FREE( buf->buf_base );
150 assert( buf->buf_ptr==0 );
151 assert( buf->buf_end==0 );
152 buf->buf_base = LBER_MALLOC( minsize );
153 if (buf->buf_base==NULL)
157 nb = LBER_REALLOC( buf->buf_base, minsize );
162 buf->buf_size = minsize;
169 sockbuf_sec_release( Sockbuf *sb, char *buf, ber_len_t len )
171 /* when this is called:
172 * sb->sb_sec_buf_in.buf_base points to a packet.
173 * sb->sb_sec_buf_in.buf_ptr contains the total bytes read.
174 * sb->sb_sec_end.buf_end contains the packet length.
176 * sb->sb_buf.buf_ptr == sb->sb_buf.buf_end == 0;
184 assert( buf != NULL );
185 assert( sb != NULL );
186 assert( SOCKBUF_VALID( sb ) );
188 assert( sb->sb_sec );
189 assert( sb->sb_sec->sbs_release );
190 assert( sb->sb_sec_buf_in.sb_ptr >= sb->sb_sec_buf_in.sb_end );
192 assert( sb->sb_buf.sb_ptr == 0 );
193 assert( sb->sb_buf.sb_end == 0 );
195 assert( status_is_ok(sb) );
199 ptr = sb->sb_sec_buf_in.buf_base;
200 end = ptr+ sb->sb_sec_buf_in.buf_ptr;
201 size = sb->sb_sec_buf_in.buf_end;
203 sb->sb_sec_ready = 1;
205 for(;(ptr+size<=end);) {
207 rlen = sb->sb_sec->sbs_release( sb, ptr, size,
210 sb->sb_buf.buf_size );
212 /* this means a security violation. */
213 return total; /* total ? total : 0 */
216 /* this means that the buffer isn't big enough. */
217 if (grow_buffer( &(sb->sb_buf), -rlen )<0)
218 /* memory violation. */
219 return total; /* total ? total : 0 */
227 /* move to the next packet... */
231 size = packet_length( sb, ptr );
232 /* size is always at least 4, so the loop condition is always OK !!*/
239 sb->sb_buf_ready = (sb->sb_buf.buf_end = rlen - len) ? 1 : 0;
245 sb->sb_sec_ready = 0;
246 /* clean up the mess. */
248 /* copy back to beginning of buffer. */
249 SAFEMEMCPY( sb->sb_sec_buf_in.buf_base, ptr, end-ptr );
250 sb->sb_sec_buf_in.buf_ptr = 0;
251 sb->sb_sec_buf_in.buf_end -= (ptr - sb->sb_sec_buf_in.buf_base);
253 assert( status_is_ok(sb) );
258 sockbuf_sec_protect( Sockbuf *sb, char *buf, long len )
264 assert( buf != NULL );
266 assert( sb != NULL );
267 assert( SOCKBUF_VALID( sb ) );
269 assert( sb->sb_sec_out.buf_end == 0 );
270 assert( sb->sb_sec_out.buf_ptr == 0 );
272 assert( sb->sb_sec );
273 assert( sb->sb_sec->sbs_protect );
275 assert( status_is_ok(sb) );
281 ret = sb->sb_sec->sbs_protect( sb, buf, &blen,
282 sb->sb_sec_out.buf_base+
283 sb->sb_sec_out.buf_end,
284 sb->sb_sec_out.buf_size -
285 sb->sb_sec_out.buf_end );
287 /* protection error ? */
290 if (grow_buffer( &(sb->sb_sec_out),-ret-sb->sb_sec_out.buf_end )<0)
295 /* else if (ret>0) */
298 sb->sb_sec_out.buf_end += ret;
302 assert( status_is_ok(sb) );
308 sockbuf_copy_out( Sockbuf *sb, char **buf, ber_len_t len )
310 ber_len_t blen = (sb->sb_buf.buf_end - sb->sb_buf.buf_ptr );
312 assert( buf != NULL );
314 assert( sb != NULL );
315 assert( SOCKBUF_VALID( sb ) );
316 assert( status_is_ok(sb) );
319 ber_len_t rlen = (blen<len) ? blen : len;
320 memcpy( *buf, sb->sb_buf.buf_base + sb->sb_buf.buf_ptr, rlen );
321 sb->sb_buf.buf_ptr+=rlen;
324 if (sb->sb_buf.buf_ptr >= sb->sb_buf.buf_end) {
325 sb->sb_buf.buf_ptr = sb->sb_buf.buf_end = 0;
326 sb->sb_buf_ready = 0;
328 sb->sb_buf_ready = 1;
331 assert( status_is_ok(sb) );
335 Sockbuf *ber_sockbuf_alloc( void )
339 ber_int_options.lbo_valid = LBER_INITIALIZED;
341 sb = LBER_CALLOC(1, sizeof(Sockbuf));
343 if( sb == NULL ) return NULL;
345 ber_pvt_sb_init( sb );
349 Sockbuf *ber_sockbuf_alloc_fd( ber_socket_t fd )
351 Sockbuf *sb = ber_sockbuf_alloc();
353 if( sb == NULL ) return NULL;
355 ber_pvt_sb_set_desc( sb, fd );
356 ber_pvt_sb_set_io( sb, &ber_pvt_sb_io_tcp, NULL );
360 void ber_sockbuf_free( Sockbuf *sb )
363 assert( SOCKBUF_VALID( sb ) );
364 ber_pvt_sb_destroy( sb );
369 ber_pvt_sb_read( Sockbuf *sb, void *buf_arg, ber_len_t len )
374 assert( buf_arg != NULL );
375 assert( sb != NULL );
376 assert( SOCKBUF_VALID( sb ) );
377 assert( status_is_ok(sb) );
379 /* slapd might have problems with this */
380 assert( ber_pvt_sb_in_use( sb ) );
382 #ifdef TEST_PARTIAL_READ
383 if ((rand() & 3)==1) { /* 1 out of 4 */
389 len = (rand() % len)+1;
392 buf = (char *) buf_arg;
394 if (sb->sb_buf.buf_ptr!=sb->sb_buf.buf_end) {
395 len = sockbuf_copy_out( sb, &buf, len );
397 return (buf - (char *) buf_arg);
404 assert( sb->sb_sec->sbs_release );
405 assert( sb->sb_sec_buf_in.buf_base );
406 if (sb->sb_read_ahead) {
407 max = sb->sb_sec_buf_in.buf_size - sb->sb_sec_buf_in.buf_ptr;
409 max = sb->sb_sec_buf_in.buf_end - sb->sb_sec_buf_in.buf_ptr;
411 /* special situation. This means that we need to read the first
412 * four bytes for the packet length.
418 /* read from stream into sb_sec_buf_in */
420 ret = sockbuf_io_read( sb, sb->sb_sec_buf_in.buf_base +
421 sb->sb_sec_buf_in.buf_ptr, max );
423 if ((ret<0) && (errno==EINTR))
429 /* read error. return */
432 sb->sb_sec_buf_in.buf_ptr += ret;
434 if (sb->sb_sec_buf_in.buf_ptr < sb->sb_sec_buf_in.buf_end) {
435 /* did not finish a packet. give up. */
439 if (sb->sb_sec_buf_in.buf_end == 0) {
440 /* Were trying to read the first four bytes... */
441 if (sb->sb_sec_buf_in.buf_ptr < 4) {
442 /* did not read enough for packet length. give up. */
445 /* calculate the packet length. */
446 sb->sb_sec_buf_in.buf_end =
447 packet_length(sb, sb->sb_sec_buf_in.buf_base );
448 if ((sb->sb_sec_buf_in.buf_end > sb->sb_sec_buf_in.buf_size) &&
449 (grow_buffer( &(sb->sb_sec_buf_in), sb->sb_sec_buf_in.buf_end)<0)) {
450 /* buffer has to be to big. exit with error. */
454 if (sb->sb_sec_buf_in.buf_ptr >= sb->sb_sec_buf_in.buf_end) {
455 /* finished packet. decode it. */
458 /* did not finish packet yet. try again ? */
459 if (sb->sb_read_ahead) {
460 /* we were trying to read the max anyway. forget it */
465 /* we read enough for at least 1 packet */
466 ret = sockbuf_sec_release( sb, buf, len );
468 /* something went wrong... */
473 /* we are finished !!! */
474 if ((len==0) || (ret!=max))
479 if (sb->sb_read_ahead) {
481 max = sb->sb_buf.buf_size - sb->sb_buf.buf_end;
482 if (max> (ber_slen_t) len) {
484 ret = sockbuf_io_read( sb,
485 sb->sb_buf.buf_base +
489 if ((ret<0) && (errno==EINTR))
495 /* some error occured */
498 sb->sb_buf.buf_end += ret;
499 /* move out the data... */
500 len = sockbuf_copy_out( sb, &buf, len );
504 /* no read_ahead, just try to put the data in the buf. */
506 ret = sockbuf_io_read( sb, buf, len );
508 if ((ret<0) && (errno==EINTR))
517 /* we might as well return, since there is nothing to do... */
522 assert( status_is_ok(sb) );
523 if ((ret<=0) && (buf==buf_arg)) {
524 /* there was an error. */
527 return (buf - ((char *) buf_arg));
531 long sockbuf_do_write( Sockbuf *sb )
536 assert( sb != NULL );
537 assert( SOCKBUF_VALID( sb ) );
539 to_go = sb->sb_sec_out.buf_end - sb->sb_sec_out.buf_ptr;
541 /* there is something left of the last time... */
543 ret = sockbuf_io_write( sb, sb->sb_sec_out.buf_base+
544 sb->sb_sec_out.buf_ptr, to_go );
546 if ((ret<0) && (errno==EINTR))
551 if (ret<=0) /* error */
553 sb->sb_sec_out.buf_ptr += ret;
554 if (ret<to_go) /* not enough data, so pretend no data was sent. */
560 ber_slen_t ber_pvt_sb_write( Sockbuf *sb, void *buf, ber_len_t len_arg )
563 ber_len_t len = len_arg;
565 assert( buf != NULL );
566 assert( sb != NULL );
567 assert( SOCKBUF_VALID( sb ) );
568 assert( status_is_ok(sb) );
570 /* slapd might have problems with this */
571 assert( ber_pvt_sb_in_use( sb ) );
573 #ifdef TEST_PARTIAL_WRITE
574 if ((rand() & 3)==1) { /* 1 out of 4 */
579 len_arg = (rand() % len_arg)+1;
585 assert( sb->sb_sec_prev_len <= len );
586 if (sb->sb_sec_prev_len) {
587 ret = sockbuf_do_write( sb );
591 len -= sb->sb_sec_prev_len;
592 sb->sb_sec_prev_len = 0;
593 sb->sb_sec_out.buf_end = sb->sb_sec_out.buf_ptr = 0;
595 /* now protect the next packet. */
596 ret = sockbuf_sec_protect( sb, buf, len );
599 ret = sockbuf_do_write( sb );
601 sb->sb_sec_prev_len = len;
608 ret = sockbuf_io_write( sb, buf, len );
610 if ((ret<0) && (errno==EINTR))
622 int ber_pvt_sb_close( Sockbuf *sb )
626 assert( sb != NULL );
627 assert( SOCKBUF_VALID( sb ) );
629 assert( sb->sb_io->sbi_close );
630 assert( status_is_ok(sb) );
631 assert( ber_pvt_sb_in_use( sb ) );
633 ret = sb->sb_io->sbi_close( sb );
634 ber_pvt_sb_set_desc( sb, -1 );
639 int ber_pvt_sb_set_readahead( Sockbuf *sb, int rh )
641 assert( sb != NULL );
642 assert( SOCKBUF_VALID( sb ) );
643 assert( status_is_ok(sb) );
644 sb->sb_read_ahead = (rh!=0);
648 int ber_pvt_socket_set_nonblock( ber_socket_t sd, int nb )
651 int flags = fcntl(ber_pvt_sb_get_desc(sb), F_GETFL);
655 flags &= ~O_NONBLOCK;
657 return fcntl( ber_pvt_sb_get_desc(sb), F_SETFL, flags );
659 #elif defined( FIONBIO )
660 ioctl_t status = nb ? 1 : 0;
661 return ioctl( sd, FIONBIO, &status );
667 int ber_pvt_sb_set_nonblock( Sockbuf *sb, int nb )
669 assert( sb != NULL );
670 assert( SOCKBUF_VALID( sb ) );
671 assert( status_is_ok(sb) );
673 sb->sb_non_block = 1;
675 sb->sb_read_ahead = 1;
678 sb->sb_non_block = 0;
680 sb->sb_read_ahead = 0;
683 if (ber_pvt_sb_in_use(sb)) {
684 return ber_pvt_socket_set_nonblock(
685 ber_pvt_sb_get_desc(sb), nb );
691 #define sockbuf_buf_init( bb ) do { \
692 Sockbuf_Buf *sbb = (bb); \
693 sbb->buf_base = NULL; \
700 sockbuf_buf_destroy( Sockbuf_Buf *buf )
702 assert( buf != NULL);
705 LBER_FREE( buf->buf_base );
706 sockbuf_buf_init( buf );
710 int ber_pvt_sb_init( Sockbuf *sb )
714 ber_int_options.lbo_valid = LBER_INITIALIZED;
716 sb->sb_valid=LBER_VALID_SOCKBUF;
719 sb->sb_trans_ready = 0;
720 sb->sb_buf_ready = 0;
722 sb->sb_sec_ready = 0;
724 sb->sb_read_ahead = 1; /* test */
725 sb->sb_non_block = 0;
726 sb->sb_trans_needs_read = 0;
727 sb->sb_trans_needs_write = 0;
729 sb->sb_iodata = NULL;
730 sb->sb_io = &sb_IO_None;
733 sb->sb_max_incoming = 0;
735 sockbuf_buf_init( &(sb->sb_buf) );
737 sockbuf_buf_init( &(sb->sb_sec_buf_in) );
738 sockbuf_buf_init( &(sb->sb_sec_buf_out) );
741 sb->sb_sec_prev_len = 0;
744 assert( SOCKBUF_VALID( sb ) );
748 int ber_pvt_sb_destroy( Sockbuf *sb )
751 assert( SOCKBUF_VALID(sb) );
753 ber_pvt_sb_clear_sec(sb);
754 sockbuf_buf_destroy( &(sb->sb_sec_buf_in) );
755 sockbuf_buf_destroy( &(sb->sb_sec_buf_out) );
757 ber_pvt_sb_clear_io(sb);
758 sockbuf_buf_destroy( &(sb->sb_buf) );
759 return ber_pvt_sb_init( sb );
763 int ber_pvt_sb_set_sec( Sockbuf *sb, Sockbuf_Sec * sec, void *arg )
767 assert( SOCKBUF_VALID( *sb ) );
768 if ((sb->sb_sec) || (sec==NULL))
773 if ((sec->sbs_setup) && (sec->sbs_setup( sb, arg)<0)) {
777 len = sb->sb_buf.buf_end - sb->sb_buf.buf_ptr;
780 /* move this to the security layer. */
781 if (grow_buffer( &(sb->sb_sec_buf_in), len )<0)
783 memcpy( sb->sb_sec_buf_in.buf_base,
784 sb->sb_buf.buf_base + sb->sb_buf.buf_ptr, len );
785 sb->sb_sec_buf_in.buf_ptr = len;
786 sb->sb_sec_buf_in.buf_end = (len>4) ? packet_length( sb, sb->sb_sec_buf_in ) : 0;
787 sb->sb_buf.buf_ptr = sb->sb_buf.buf_end = 0;
793 int ber_pvt_sb_clear_sec( Sockbuf *sb )
796 assert( SOCKBUF_VALID( sb ) );
798 if (sb->sb_buf.buf_ptr!=0)
800 if (sb->sb_sec==NULL)
802 if ((sb->sb_sec->sbs_remove) && (sb->sb_sec->sbs_remove(sb)<0))
806 if (sb->sb_sec_buf_in.buf_ptr!=0) {
807 if (grow_buffer( &(sb->sb_buf),
808 sb->sb_buf.buf_end + sb->sb_sec_buf_in.buf_ptr)<0)
810 memcpy( sb->sb_buf.buf_base + sb->sb_buf.buf_end,
811 sb->sb_sec_buf_in.buf_base, sb->sb_sec_buf_in.buf_ptr );
812 sb->sb_buf.buf_end += sb->sb_sec_buf_in.buf_ptr;
813 sb->sb_buf_ready = 1;
815 sockbuf_buf_destroy( &(sb->sb_sec_buf_in) );
816 assert( sb->sb_sec_buf.buf_end==0 );
817 sockbuf_buf_destroy( &(sb->sb_sec_buf_out) );
819 sb->sb_sec_ready = 0;
825 int ber_pvt_sb_set_io( Sockbuf *sb, Sockbuf_IO *trans, void *arg )
828 assert( SOCKBUF_VALID( sb ) );
829 assert( sb->sb_io == &sb_IO_None );
836 if ((trans->sbi_setup) && (trans->sbi_setup( sb, arg)<0))
842 int ber_pvt_sb_clear_io( Sockbuf *sb )
845 assert( SOCKBUF_VALID( sb ) );
847 if (sb->sb_io==&sb_IO_None)
850 if ((sb->sb_io->sbi_remove) && (sb->sb_io->sbi_remove( sb )<0))
853 sb->sb_io = &sb_IO_None;
855 sb->sb_trans_ready = 0;
856 sb->sb_trans_needs_read = 0;
857 sb->sb_trans_needs_write = 0;
867 stream_read( Sockbuf *sb, void *buf, ber_len_t len )
870 assert( SOCKBUF_VALID( sb ) );
874 * MacTCP/OpenTransport
876 return tcpread( ber_pvt_sb_get_desc(sb), 0, (unsigned char *)buf,
879 #elif defined( HAVE_PCNFS ) || \
880 defined( HAVE_WINSOCK ) || defined ( __BEOS__ )
885 * Windows Socket API (under DOS/Windows 3.x)
888 * 32-bit Windows Socket API (under Windows NT or Windows 95)
892 rc = recv( ber_pvt_sb_get_desc(sb), buf, len, 0 );
894 if ( rc < 0 ) errno = WSAGetLastError();
898 #elif defined( HAVE_NCSA )
900 * NCSA Telnet TCP/IP stack (under DOS)
902 return nread( ber_pvt_sb_get_desc(sb), buf, len );
905 return read( ber_pvt_sb_get_desc(sb), buf, len );
910 stream_write( Sockbuf *sb, void *buf, ber_len_t len )
913 assert( SOCKBUF_VALID( sb ) );
917 * MacTCP/OpenTransport
919 #define MAX_WRITE 65535
920 return tcpwrite( ber_pvt_sb_get_desc(sb),
921 (unsigned char *)(buf),
922 (len<MAX_WRITE)? len : MAX_WRITE );
924 #elif defined( HAVE_PCNFS) \
925 || defined( HAVE_WINSOCK) || defined ( __BEOS__ )
930 * Windows Socket API (under DOS/Windows 3.x)
933 * 32-bit Windows Socket API (under Windows NT or Windows 95)
938 rc = send( ber_pvt_sb_get_desc(sb), buf, len, 0 );
940 if ( rc < 0 ) errno = WSAGetLastError();
945 #elif defined(HAVE_NCSA)
946 return netwrite( ber_pvt_sb_get_desc(sb), buf, len );
950 * VMS -- each write must be 64K or smaller
952 #define MAX_WRITE 65535
953 return write( ber_pvt_sb_get_desc(sb), buf,
954 (len<MAX_WRITE)? len : MAX_WRITE);
956 return write( ber_pvt_sb_get_desc(sb), buf, len );
961 stream_close( Sockbuf *sb )
964 assert( SOCKBUF_VALID( sb ) );
965 tcp_close( ber_pvt_sb_get_desc( sb ) );
969 Sockbuf_IO ber_pvt_sb_io_tcp=
971 NULL, /* sbi_setup */
972 NULL, /* sbi_release */
973 stream_read, /* sbi_read */
974 stream_write, /* sbi_write */
975 stream_close, /* sbi_close */
979 * Support for UDP (CLDAP)
989 dgram_setup( Sockbuf *sb, void *arg )
992 assert( SOCKBUF_VALID( sb ) );
994 sb->sb_iodata = LBER_MALLOC( sizeof( struct dgram_data ) );
995 if (sb->sb_iodata==NULL)
997 sb->sb_read_ahead = 1; /* important since udp is packet based. */
1002 dgram_release( Sockbuf *sb )
1004 assert( sb != NULL);
1005 assert( SOCKBUF_VALID( sb ) );
1007 LBER_FREE( sb->sb_iodata );
1012 dgram_read( Sockbuf *sb, void *buf, ber_len_t len )
1014 #ifdef LDAP_CONNECTIONLESS
1017 struct dgram_data *dd;
1019 assert( sb != NULL );
1020 assert( SOCKBUF_VALID( sb ) );
1021 assert( buf != NULL );
1023 dd = (struct dgram_data *)(sb->sb_iodata);
1025 addrlen = sizeof( struct sockaddr );
1026 rc=recvfrom( ber_pvt_sb_get_desc(sb), buf, len, 0, &(dd->src), &addrlen );
1028 if ( sb->sb_debug ) {
1029 ber_log_printf( LDAP_DEBUG_ANY, sb->sb_debug,
1030 "dgram_read udp_read %ld bytes\n",
1033 ber_log_bprint( LDAP_DEBUG_PACKETS, sb->sb_debug,
1037 # else /* LDAP_CONNECTIONLESS */
1039 # endif /* LDAP_CONNECTIONLESS */
1043 dgram_write( Sockbuf *sb, void *buf, ber_len_t len )
1045 #ifdef LDAP_CONNECTIONLESS
1047 struct dgram_data *dd;
1049 assert( sb != NULL );
1050 assert( SOCKBUF_VALID( sb ) );
1051 assert( buf != NULL );
1053 dd = (struct dgram_data *)(sb->sb_iodata);
1055 rc=sendto( ber_pvt_sb_get_desc(sb), buf, len, 0, &(dd->dst),
1056 sizeof( struct sockaddr ) );
1061 /* fake error if write was not atomic */
1075 dgram_close( Sockbuf *sb )
1077 assert( sb != NULL );
1078 assert( SOCKBUF_VALID( sb ) );
1080 tcp_close( ber_pvt_sb_get_desc(sb) );
1084 Sockbuf_IO ber_pvt_sb_io_udp=
1086 dgram_setup, /* sbi_setup */
1087 dgram_release, /* sbi_release */
1088 dgram_read, /* sbi_read */
1089 dgram_write, /* sbi_write */
1090 dgram_close, /* sbi_close */
1093 int ber_pvt_sb_udp_set_dst(Sockbuf *sb, void *addr )
1095 struct dgram_data *dd;
1096 assert( sb != NULL );
1097 assert( SOCKBUF_VALID( sb ) );
1098 assert( sb->sb_io == &ber_pvt_sb_io_udp );
1099 dd = (struct dgram_data *) (sb->sb_iodata);
1100 memcpy( &(dd->dst), addr, sizeof( struct sockaddr ) );
1104 void *ber_pvt_sb_udp_get_src( Sockbuf *sb )
1106 struct dgram_data *dd;
1108 assert( sb != NULL );
1109 assert( SOCKBUF_VALID( sb ) );
1110 assert( sb->sb_io == &ber_pvt_sb_io_udp );
1111 dd = (struct dgram_data *) (sb->sb_iodata);
1119 * These routines should really call abort, but at the moment that would
1120 * break the servers.
1124 have_no_read( Sockbuf *sb, void *buf, ber_len_t len )
1126 assert( sb != NULL );
1127 assert( SOCKBUF_VALID( sb ) );
1129 ber_log_printf( LDAP_DEBUG_ANY, ber_int_debug,
1130 "warning: reading from uninitialized sockbuf\n");
1136 have_no_write( Sockbuf *sb, void *buf, ber_len_t len )
1138 assert( sb != NULL );
1139 assert( SOCKBUF_VALID( sb ) );
1141 ber_log_printf( LDAP_DEBUG_ANY, ber_int_debug,
1142 "warning: writing to uninitialized sockbuf\n");
1148 have_no_close( Sockbuf *sb )
1150 assert( sb != NULL );
1151 assert( SOCKBUF_VALID( sb ) );