Esempio n. 1
0
int
ber_sockbuf_remove_io( Sockbuf *sb, Sockbuf_IO *sbio, int layer )
{
	Sockbuf_IO_Desc		*p, **q;

	assert( sb != NULL );
	assert( SOCKBUF_VALID( sb ) );
   
	if ( sb->sb_iod == NULL ) {
		return -1;
	}
   
	q = &sb->sb_iod;
	while ( *q != NULL ) {
		p = *q;
		if ( layer == p->sbiod_level && p->sbiod_io == sbio ) {
			if ( p->sbiod_io->sbi_remove != NULL &&
				p->sbiod_io->sbi_remove( p ) < 0 )
			{
				return -1;
			}
			*q = p->sbiod_next;
			LBER_FREE( p );
			break;
		}
		q = &p->sbiod_next;
	}

	return 0;
}
Esempio n. 2
0
static ber_slen_t
sb_dgram_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
{
	ber_slen_t rc;
	struct sockaddr *dst;
	socklen_t dstsize;

	assert( sbiod != NULL );
	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
	assert( buf != NULL );

	dst = buf;
	buf = (char *) buf + sizeof( struct sockaddr_storage );
	len -= sizeof( struct sockaddr_storage );
	dstsize = dst->sa_family == AF_INET ? sizeof( struct sockaddr_in )
#ifdef LDAP_PF_INET6
		: dst->sa_family == AF_INET6 ? sizeof( struct sockaddr_in6 )
#endif
		: sizeof( struct sockaddr_storage );
	rc = sendto( sbiod->sbiod_sb->sb_fd, buf, len, 0, dst, dstsize );

	if ( rc < 0 ) return -1;

	/* fake error if write was not atomic */
	if (rc < len) {
# ifdef EMSGSIZE
		errno = EMSGSIZE;
# endif
		return -1;
	}
	rc = len + sizeof(struct sockaddr_storage);
	return rc;
}
Esempio n. 3
0
File: tls_g.c Progetto: 1ack/Impala
static ber_slen_t
tlsg_sb_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
{
	struct tls_data		*p;
	ber_slen_t		ret;

	assert( sbiod != NULL );
	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );

	p = (struct tls_data *)sbiod->sbiod_pvt;

	ret = gnutls_record_recv ( p->session->session, buf, len );
	switch (ret) {
	case GNUTLS_E_INTERRUPTED:
	case GNUTLS_E_AGAIN:
		sbiod->sbiod_sb->sb_trans_needs_read = 1;
		sock_errset(EWOULDBLOCK);
		ret = 0;
		break;
	case GNUTLS_E_REHANDSHAKE:
		for ( ret = gnutls_handshake ( p->session->session );
		      ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN;
		      ret = gnutls_handshake ( p->session->session ) );
		sbiod->sbiod_sb->sb_trans_needs_read = 1;
		ret = 0;
		break;
	default:
		sbiod->sbiod_sb->sb_trans_needs_read = 0;
	}
	return ret;
}
Esempio n. 4
0
ber_slen_t
ber_int_sb_write( Sockbuf *sb, void *buf, ber_len_t len )
{
    ber_slen_t		ret;

    assert( buf != NULL );
    assert( sb != NULL);
    assert( sb->sb_iod != NULL );
    assert( SOCKBUF_VALID( sb ) );

    for (;;) {
        ret = sb->sb_iod->sbiod_io->sbi_write( sb->sb_iod, buf, len );

#ifdef EINTR
        if ( ret < 0 )
        {
#ifdef HAVE_WINSOCK     // on Windows, errno is NOT set by send call automatically.
            if ( (errno = sock_errno()) == WSAEINTR)
            {
                errno = EINTR;
            }
#endif
            if( errno == EINTR )  continue;
        }
#endif

        break;
    }

    return ret;
}
Esempio n. 5
0
static ber_slen_t
sb_fd_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
{
	assert( sbiod != NULL);
	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );

#ifdef LDAP_PF_LOCAL_SENDMSG
	if ( sbiod->sbiod_sb->sb_ungetlen ) {
		ber_len_t blen = sbiod->sbiod_sb->sb_ungetlen;
		if ( blen > len )
			blen = len;
		AC_MEMCPY( buf, sbiod->sbiod_sb->sb_ungetbuf, blen );
		buf = (char *) buf + blen;
		len -= blen;
		sbiod->sbiod_sb->sb_ungetlen -= blen;
		if ( sbiod->sbiod_sb->sb_ungetlen ) {
			AC_MEMCPY( sbiod->sbiod_sb->sb_ungetbuf,
				sbiod->sbiod_sb->sb_ungetbuf+blen,
				sbiod->sbiod_sb->sb_ungetlen );
		}
		if ( len == 0 )
			return blen;
	}
#endif
	return read( sbiod->sbiod_sb->sb_fd, buf, len );
}
Esempio n. 6
0
static ber_slen_t
sb_fd_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
{
    assert( sbiod != NULL);
    assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );

#ifdef LDAP_PF_LOCAL_SENDMSG
    if ( sbiod->sbiod_sb->sb_ungetlen ) {
        ber_len_t blen = sbiod->sbiod_sb->sb_ungetlen;
        if ( blen > len )
            blen = len;
        AC_MEMCPY( buf, sbiod->sbiod_sb->sb_ungetbuf, blen );
        buf = (char *) buf + blen;
        len -= blen;
        sbiod->sbiod_sb->sb_ungetlen -= blen;
        if ( sbiod->sbiod_sb->sb_ungetlen ) {
            AC_MEMCPY( sbiod->sbiod_sb->sb_ungetbuf,
                       sbiod->sbiod_sb->sb_ungetbuf+blen,
                       sbiod->sbiod_sb->sb_ungetlen );
        }
        if ( len == 0 )
            return blen;
    }
#endif
    return _read( (int)sbiod->sbiod_sb->sb_fd, buf, (unsigned int)len ); // This should be safe, as ret will not exceed 2G.
}
Esempio n. 7
0
ber_slen_t
ber_pvt_sb_do_write( Sockbuf_IO_Desc *sbiod, Sockbuf_Buf *buf_out )
{
	ber_len_t		to_go;
	ber_slen_t ret;

	assert( sbiod != NULL );
	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );

	to_go = buf_out->buf_end - buf_out->buf_ptr;
	assert( to_go > 0 );
   
	for(;;) {
		ret = LBER_SBIOD_WRITE_NEXT( sbiod, buf_out->buf_base +
			buf_out->buf_ptr, to_go );
#ifdef EINTR
		if ((ret<0) && (errno==EINTR)) continue;
#endif
		break;
	}

	if ( ret <= 0 ) return ret;
   
	buf_out->buf_ptr += ret;
	if (buf_out->buf_ptr == buf_out->buf_end) {
		buf_out->buf_end = buf_out->buf_ptr = 0;
	}

	return ret;
}
Esempio n. 8
0
static ber_slen_t
tlso_sb_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
{
	struct tls_data		*p;
	ber_slen_t		ret;
	int			err;

	assert( sbiod != NULL );
	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );

	p = (struct tls_data *)sbiod->sbiod_pvt;

	ret = SSL_write( p->session, (char *)buf, len );
#ifdef HAVE_WINSOCK
	errno = WSAGetLastError();
#endif
	err = SSL_get_error( p->session, ret );
	if (err == SSL_ERROR_WANT_WRITE ) {
		sbiod->sbiod_sb->sb_trans_needs_write = 1;
		sock_errset(EWOULDBLOCK);

	} else {
		sbiod->sbiod_sb->sb_trans_needs_write = 0;
	}
	return ret;
}
Esempio n. 9
0
static ber_slen_t 
sb_dgram_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
{
	ber_slen_t rc;
	struct sockaddr *dst;
   
	assert( sbiod != NULL );
	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
	assert( buf != NULL );

	dst = buf;
	buf = (char *) buf + sizeof( struct sockaddr );
	len -= sizeof( struct sockaddr );
   
	rc = sendto( sbiod->sbiod_sb->sb_fd, buf, len, 0, dst,
		sizeof( struct sockaddr ) );

	if ( rc < 0 ) return -1;
   
	/* fake error if write was not atomic */
	if (rc < len) {
# ifdef EMSGSIZE
		errno = EMSGSIZE;
# endif
		return -1;
	}
	rc = len + sizeof(struct sockaddr);
	return rc;
}
Esempio n. 10
0
static int 
sb_stream_close( Sockbuf_IO_Desc *sbiod )
{
	assert( sbiod != NULL );
	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
	tcp_close( sbiod->sbiod_sb->sb_fd );
   return 0;
}
Esempio n. 11
0
static ber_slen_t
sb_fd_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
{
    assert( sbiod != NULL);
    assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );

    return _write( (int)sbiod->sbiod_sb->sb_fd, buf, (unsigned int)len ); // This should be safe, as ret will not exceed 2G.
}
Esempio n. 12
0
static ber_slen_t
sb_fd_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
{
	assert( sbiod != NULL);
	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );

	return write( sbiod->sbiod_sb->sb_fd, buf, len );
}
Esempio n. 13
0
static int 
sb_dgram_setup( Sockbuf_IO_Desc *sbiod, void *arg )
{
	assert( sbiod != NULL);
	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );

	if ( arg != NULL ) sbiod->sbiod_sb->sb_fd = *((int *)arg);
	return 0;
}
Esempio n. 14
0
void
ber_sockbuf_free( Sockbuf *sb )
{
	assert( sb != NULL );
	assert( SOCKBUF_VALID( sb ) );

	ber_int_sb_close( sb );
	ber_int_sb_destroy( sb );
	LBER_FREE( sb );
}
Esempio n. 15
0
static int
sb_dgram_close( Sockbuf_IO_Desc *sbiod )
{
	assert( sbiod != NULL );
	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );

	if ( sbiod->sbiod_sb->sb_fd != AC_SOCKET_INVALID )
		tcp_close( sbiod->sbiod_sb->sb_fd );
	return 0;
}
Esempio n. 16
0
static ber_slen_t
sb_stream_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
{
	assert( sbiod != NULL);
	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );

#if defined(MACOS) 
/*
 * MacTCP/OpenTransport
 */
#define MAX_WRITE	65535
	return tcpwrite( sbiod->sbiod_sb->sb_fd, (unsigned char *)buf,
		(len<MAX_WRITE) ? len : MAX_WRITE );

#elif defined( HAVE_PCNFS) \
	|| defined( HAVE_WINSOCK) || defined ( __BEOS__ )
/*
 * PCNFS (under DOS)
 */
/*
 * Windows Socket API (under DOS/Windows 3.x)
 */
/*
 * 32-bit Windows Socket API (under Windows NT or Windows 95)
 */
	{
		int rc = send( sbiod->sbiod_sb->sb_fd, buf, len, 0 );

#ifdef HAVE_WINSOCK
		if ( rc < 0 ) {
			int err;
			err = WSAGetLastError();
			errno = err;
		}
#endif
		return rc;
	}

#elif defined(HAVE_NCSA)
	return netwrite( sbiod->sbiod_sb->sb_fd, buf, len );

#elif defined(VMS)
/*
 * VMS -- each write must be 64K or smaller
 */
#define MAX_WRITE 65535
	return write( sbiod->sbiod_sb->sb_fd, buf,
		(len<MAX_WRITE) ? len : MAX_WRITE);
#else
	return write( sbiod->sbiod_sb->sb_fd, buf, len );
#endif   
}   
Esempio n. 17
0
static ber_slen_t
sb_stream_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
{
	assert( sbiod != NULL);
	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );

#if defined(MACOS)
/*
 * MacTCP/OpenTransport
 */
	return tcpread( sbiod->sbiod_sb->sb_fd, 0, (unsigned char *)buf,
		   len, NULL );

#elif defined( HAVE_PCNFS ) || \
   defined( HAVE_WINSOCK ) || defined ( __BEOS__ )
/*
 * PCNFS (under DOS)
 */
/*
 * Windows Socket API (under DOS/Windows 3.x)
 */
/*
 * 32-bit Windows Socket API (under Windows NT or Windows 95)
 */
	{
		int rc;

		rc = recv( sbiod->sbiod_sb->sb_fd, buf, len, 0 );

#ifdef HAVE_WINSOCK
		if ( rc < 0 ) {
			int err;

			err = WSAGetLastError();
			errno = err;
		}
#endif

		return rc;
	}

#elif defined( HAVE_NCSA )
/*
 * NCSA Telnet TCP/IP stack (under DOS)
 */
	return nread( sbiod->sbiod_sb->sb_fd, buf, len );

#else
	return read( sbiod->sbiod_sb->sb_fd, buf, len );
#endif
}
Esempio n. 18
0
int
ber_int_sb_init( Sockbuf *sb )
{
	assert( sb != NULL);

	sb->sb_valid=LBER_VALID_SOCKBUF;
	sb->sb_options = 0;
	sb->sb_debug = ber_int_debug;
	sb->sb_fd = AC_SOCKET_INVALID;
	sb->sb_iod = NULL;
	sb->sb_trans_needs_read = 0;
	sb->sb_trans_needs_write = 0;
   
	assert( SOCKBUF_VALID( sb ) );
	return 0;
}
Esempio n. 19
0
int
ber_int_sb_destroy( Sockbuf *sb )
{
	Sockbuf_IO_Desc		*p;

	assert( sb != NULL);
	assert( SOCKBUF_VALID( sb ) );
   
	while ( sb->sb_iod ) {
		p = sb->sb_iod->sbiod_next;
		ber_sockbuf_remove_io( sb, sb->sb_iod->sbiod_io,
			sb->sb_iod->sbiod_level );
		sb->sb_iod = p;
	}

	return ber_int_sb_init( sb );
}
Esempio n. 20
0
ber_slen_t
ber_int_sb_read( Sockbuf *sb, void *buf, ber_len_t len )
{
    ber_slen_t		ret;

    assert( buf != NULL );
    assert( sb != NULL);
    assert( sb->sb_iod != NULL );
    assert( SOCKBUF_VALID( sb ) );

    for (;;) {
        ret = sb->sb_iod->sbiod_io->sbi_read( sb->sb_iod, buf, len );


#ifdef EINTR
        if ( ret < 0 )
        {
#ifdef HAVE_WINSOCK     // on Windows, errno is NOT set by recv call automatically.
            if ( (errno = sock_errno()) == WSAEINTR)
            {
                errno = EINTR;
            }
#endif
            if( errno == EINTR )  continue;
        }
#endif

        break;
    }

#ifdef _WIN32
    if (ret <= 0)
    {
        DWORD dwLastError = WSAGetLastError();
        DWORD dwLevel = LDAP_DEBUG_ANY;

        if ( dwLastError == WSAETIMEDOUT )
        {
            dwLevel = LDAP_DEBUG_CONNS;
        }
        VmLberLog( dwLevel, "sockbuf read return (%d)(%d)", ret, dwLastError);
    }
#endif

    return ret;
}
Esempio n. 21
0
int
ber_flush2( Sockbuf *sb, BerElement *ber, int freeit )
{
	ber_len_t	towrite;
	ber_slen_t	rc;

	assert( sb != NULL );
	assert( ber != NULL );

	assert( SOCKBUF_VALID( sb ) );
	assert( LBER_VALID( ber ) );

	if ( ber->ber_rwptr == NULL ) {
		ber->ber_rwptr = ber->ber_buf;
	}
	towrite = ber->ber_ptr - ber->ber_rwptr;

	if ( sb->sb_debug ) {
		ber_log_printf( LDAP_DEBUG_TRACE, sb->sb_debug,
			"ber_flush2: %ld bytes to sd %ld%s\n",
			towrite, (long) sb->sb_fd,
			ber->ber_rwptr != ber->ber_buf ?  " (re-flush)" : "" );
		ber_log_bprint( LDAP_DEBUG_BER, sb->sb_debug,
			ber->ber_rwptr, towrite );
	}

	while ( towrite > 0 ) {
#ifdef LBER_TRICKLE
		sleep(1);
		rc = ber_int_sb_write( sb, ber->ber_rwptr, 1 );
#else
		rc = ber_int_sb_write( sb, ber->ber_rwptr, towrite );
#endif
		if ( rc <= 0 ) {
			if ( freeit & LBER_FLUSH_FREE_ON_ERROR ) ber_free( ber, 1 );
			return -1;
		}
		towrite -= rc;
		ber->ber_rwptr += rc;
	} 

	if ( freeit & LBER_FLUSH_FREE_ON_SUCCESS ) ber_free( ber, 1 );

	return 0;
}
Esempio n. 22
0
static ber_slen_t
sb_dgram_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
{
	ber_slen_t rc;
	ber_socklen_t addrlen;
	struct sockaddr *src;
   
	assert( sbiod != NULL );
	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
	assert( buf != NULL );

	addrlen = sizeof( struct sockaddr );
	src = buf;
	buf = (char *) buf + addrlen;
	len -= addrlen;
	rc = recvfrom( sbiod->sbiod_sb->sb_fd, buf, len, 0, src, &addrlen );

	return rc > 0 ? rc+sizeof(struct sockaddr) : rc;
}
Esempio n. 23
0
static ber_slen_t
sb_stream_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
{
    assert( sbiod != NULL);
    assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );

#if defined(MACOS)
    /*
     * MacTCP/OpenTransport
     */
#define MAX_WRITE	65535
    return tcpwrite( sbiod->sbiod_sb->sb_fd, (unsigned char *)buf,
                     (len<MAX_WRITE) ? len : MAX_WRITE );

#elif defined( HAVE_PCNFS) \
	|| defined( HAVE_WINSOCK) || defined ( __BEOS__ )
    /*
     * PCNFS (under DOS)
     */
    /*
     * Windows Socket API (under DOS/Windows 3.x)
     */
    /*
     * 32-bit Windows Socket API (under Windows NT or Windows 95)
     */
    return send( sbiod->sbiod_sb->sb_fd, (char*)buf, (int)len, 0 );// This should be safe, as ret will not exceed 2G.

#elif defined(HAVE_NCSA)
    return netwrite( sbiod->sbiod_sb->sb_fd, buf, len );

#elif defined(VMS)
    /*
     * VMS -- each write must be 64K or smaller
     */
#define MAX_WRITE 65535
    return write( sbiod->sbiod_sb->sb_fd, buf,
                  (len<MAX_WRITE) ? len : MAX_WRITE);
#else
    return write( sbiod->sbiod_sb->sb_fd, buf, len );
#endif
}
Esempio n. 24
0
ber_slen_t
ber_int_sb_write( Sockbuf *sb, void *buf, ber_len_t len )
{
	ber_slen_t		ret;

	assert( buf != NULL );
	assert( sb != NULL);
	assert( sb->sb_iod != NULL );
	assert( SOCKBUF_VALID( sb ) );

	for (;;) {
		ret = sb->sb_iod->sbiod_io->sbi_write( sb->sb_iod, buf, len );

#ifdef EINTR	
		if ( ( ret < 0 ) && ( errno == EINTR ) ) continue;
#endif
		break;
	}

	return ret;
}
Esempio n. 25
0
static ber_slen_t
sb_rdahead_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
{
	Sockbuf_Buf		*p;
	ber_slen_t		bufptr = 0, ret, max;

	assert( sbiod != NULL );
	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
	assert( sbiod->sbiod_next != NULL );

	p = (Sockbuf_Buf *)sbiod->sbiod_pvt;

	assert( p->buf_size > 0 );

	/* Are there anything left in the buffer? */
	ret = ber_pvt_sb_copy_out( p, buf, len );
	bufptr += ret;
	len -= ret;

	if ( len == 0 ) return bufptr;

	max = p->buf_size - p->buf_end;
	ret = 0;
	while ( max > 0 ) {
		ret = LBER_SBIOD_READ_NEXT( sbiod, p->buf_base + p->buf_end,
			max );
#ifdef EINTR	
		if ( ( ret < 0 ) && ( errno == EINTR ) ) continue;
#endif
		break;
	}

	if ( ret < 0 ) {
		return ( bufptr ? bufptr : ret );
	}

	p->buf_end += ret;
	bufptr += ber_pvt_sb_copy_out( p, (char *) buf + bufptr, len );
	return bufptr;
}
Esempio n. 26
0
File: tls_g.c Progetto: 1ack/Impala
static ber_slen_t
tlsg_sb_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
{
	struct tls_data		*p;
	ber_slen_t		ret;

	assert( sbiod != NULL );
	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );

	p = (struct tls_data *)sbiod->sbiod_pvt;

	ret = gnutls_record_send ( p->session->session, (char *)buf, len );

	if ( ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN ) {
		sbiod->sbiod_sb->sb_trans_needs_write = 1;
		sock_errset(EWOULDBLOCK);
		ret = 0;
	} else {
		sbiod->sbiod_sb->sb_trans_needs_write = 0;
	}
	return ret;
}
Esempio n. 27
0
int
ber_sockbuf_add_io( Sockbuf *sb, Sockbuf_IO *sbio, int layer, void *arg )
{
	Sockbuf_IO_Desc		*d, *p, **q;
   
	assert( sb != NULL );
	assert( SOCKBUF_VALID( sb ) );
   
	if ( sbio == NULL ) {
		return -1;
	}
   
	q = &sb->sb_iod;
	p = *q;
	while ( p && p->sbiod_level > layer ) {
		q = &p->sbiod_next;
		p = *q;
	}
   
	d = LBER_MALLOC( sizeof( *d ) );
	if ( d == NULL ) {
		return -1;
	}
   
	d->sbiod_level = layer;
	d->sbiod_sb = sb;
	d->sbiod_io = sbio;
	memset( &d->sbiod_pvt, '\0', sizeof( d->sbiod_pvt ) );
	d->sbiod_next = p;
	*q = d;

	if ( sbio->sbi_setup != NULL && ( sbio->sbi_setup( d, arg ) < 0 ) ) {
		return -1;
	}

	return 0;
}
Esempio n. 28
0
static ber_slen_t
sb_stream_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
{
    assert( sbiod != NULL);
    assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );

#if defined(MACOS)
    /*
     * MacTCP/OpenTransport
     */
    return tcpread( sbiod->sbiod_sb->sb_fd, 0, (unsigned char *)buf,
                    len, NULL );

#elif defined( HAVE_PCNFS ) || \
   defined( HAVE_WINSOCK ) || defined ( __BEOS__ )
    /*
     * PCNFS (under DOS)
     */
    /*
     * Windows Socket API (under DOS/Windows 3.x)
     */
    /*
     * 32-bit Windows Socket API (under Windows NT or Windows 95)
     */
    return recv( sbiod->sbiod_sb->sb_fd, (char*)buf, (int)len, 0 ); // This should be safe, as ret will not exceed 2G.

#elif defined( HAVE_NCSA )
    /*
     * NCSA Telnet TCP/IP stack (under DOS)
     */
    return nread( sbiod->sbiod_sb->sb_fd, buf, len );

#else
    return read( sbiod->sbiod_sb->sb_fd, buf, len );
#endif
}
Esempio n. 29
0
/* Return values: -1: error, 0: no operation performed or the answer is false,
 * 1: successful operation or the answer is true
 */
int
ber_sockbuf_ctrl( Sockbuf *sb, int opt, void *arg )
{
	Sockbuf_IO_Desc		*p;
	int			ret = 0;

	assert( sb != NULL );
	assert( SOCKBUF_VALID( sb ) );

	switch ( opt ) {
		case LBER_SB_OPT_HAS_IO:
			p = sb->sb_iod;
			while ( p && p->sbiod_io != (Sockbuf_IO *)arg ) {
				p = p->sbiod_next;
			}
   
			if ( p ) {
				ret = 1;
			}
			break;

		case LBER_SB_OPT_GET_FD:
			if ( arg != NULL ) {
				*((ber_socket_t *)arg) = sb->sb_fd;
			}
			ret = ( sb->sb_fd == AC_SOCKET_INVALID ? -1 : 1);
			break;

		case LBER_SB_OPT_SET_FD:
			sb->sb_fd = *((ber_socket_t *)arg);
			ret = 1;
			break;

		case LBER_SB_OPT_SET_NONBLOCK:
			ret = ber_pvt_socket_set_nonblock( sb->sb_fd, arg != NULL)
				? -1 : 1;
			break;

		case LBER_SB_OPT_DRAIN: {
				/* Drain the data source to enable possible errors (e.g.
				 * TLS) to be propagated to the upper layers
				 */
				char buf[LBER_MIN_BUFF_SIZE];

				do {
					ret = ber_int_sb_read( sb, buf, sizeof( buf ) );
				} while ( ret == sizeof( buf ) );

				ret = 1;
			} break;

		case LBER_SB_OPT_NEEDS_READ:
			ret = ( sb->sb_trans_needs_read ? 1 : 0 );
			break;

		case LBER_SB_OPT_NEEDS_WRITE:
			ret = ( sb->sb_trans_needs_write ? 1 : 0 );
			break;

		case LBER_SB_OPT_GET_MAX_INCOMING:
			if ( arg != NULL ) {
				*((ber_len_t *)arg) = sb->sb_max_incoming;
			}
			ret = 1;
			break;

		case LBER_SB_OPT_SET_MAX_INCOMING:
			sb->sb_max_incoming = *((ber_len_t *)arg);
			ret = 1;
			break;

		case LBER_SB_OPT_UNGET_BUF:
#ifdef LDAP_PF_LOCAL_SENDMSG
			sb->sb_ungetlen = ((struct berval *)arg)->bv_len;
			if ( sb->sb_ungetlen <= sizeof( sb->sb_ungetbuf )) {
				AC_MEMCPY( sb->sb_ungetbuf, ((struct berval *)arg)->bv_val,
					sb->sb_ungetlen );
				ret = 1;
			} else {
				sb->sb_ungetlen = 0;
				ret = -1;
			}
#endif
			break;

		default:
			ret = sb->sb_iod->sbiod_io->sbi_ctrl( sb->sb_iod, opt, arg );
			break;
   }

	return ret;
}
Esempio n. 30
0
static ber_slen_t
sb_sasl_generic_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
{
	struct sb_sasl_generic_data	*p;
	int				ret;
	ber_len_t			len2;

	assert( sbiod != NULL );
	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );

	p = (struct sb_sasl_generic_data *)sbiod->sbiod_pvt;

	/* Is there anything left in the buffer? */
	if ( p->buf_out.buf_ptr != p->buf_out.buf_end ) {
		ret = ber_pvt_sb_do_write( sbiod, &p->buf_out );
		if ( ret < 0 ) return ret;

		/* Still have something left?? */
		if ( p->buf_out.buf_ptr != p->buf_out.buf_end ) {
			sock_errset(EAGAIN);
			return -1;
		}
	}

	len2 = p->max_send - 100;	/* For safety margin */
	len2 = len > len2 ? len2 : len;

	/* If we're just retrying a partial write, tell the
	 * caller it's done. Let them call again if there's
	 * still more left to write.
	 */
	if ( p->flags & LDAP_PVT_SASL_PARTIAL_WRITE ) {
		p->flags ^= LDAP_PVT_SASL_PARTIAL_WRITE;
		return len2;
	}

	/* now encode the next packet. */
	p->ops->reset_buf( p, &p->buf_out );

	ret = p->ops->encode( p, buf, len2, &p->buf_out );

	if ( ret != 0 ) {
		ber_log_printf( LDAP_DEBUG_ANY, sbiod->sbiod_sb->sb_debug,
			"sb_sasl_generic_write: failed to encode packet\n" );
		sock_errset(EIO);
		return -1;
	}

	ret = ber_pvt_sb_do_write( sbiod, &p->buf_out );

	if ( ret < 0 ) {
		/* error? */
		int err = sock_errno();
		/* caller can retry this */
		if ( err == EAGAIN || err == EWOULDBLOCK || err == EINTR )
			p->flags |= LDAP_PVT_SASL_PARTIAL_WRITE;
		return ret;
	} else if ( p->buf_out.buf_ptr != p->buf_out.buf_end ) {
		/* partial write? pretend nothing got written */
		p->flags |= LDAP_PVT_SASL_PARTIAL_WRITE;
		sock_errset(EAGAIN);
		len2 = -1;
	}

	/* return number of bytes encoded, not written, to ensure
	 * no byte is encoded twice (even if only sent once).
	 */
	return len2;
}