static int sb_sasl_generic_setup( Sockbuf_IO_Desc *sbiod, void *arg ) { struct sb_sasl_generic_data *p; struct sb_sasl_generic_install *i; assert( sbiod != NULL ); i = (struct sb_sasl_generic_install *)arg; p = LBER_MALLOC( sizeof( *p ) ); if ( p == NULL ) return -1; p->ops = i->ops; p->ops_private = i->ops_private; p->sbiod = sbiod; p->flags = 0; ber_pvt_sb_buf_init( &p->sec_buf_in ); ber_pvt_sb_buf_init( &p->buf_in ); ber_pvt_sb_buf_init( &p->buf_out ); sbiod->sbiod_pvt = p; p->ops->init( p, &p->min_send, &p->max_send, &p->max_recv ); if ( ber_pvt_sb_grow_buffer( &p->sec_buf_in, p->min_send ) < 0 ) { sb_sasl_generic_remove( sbiod ); sock_errset(ENOMEM); return -1; } return 0; }
static int sb_rdahead_setup( Sockbuf_IO_Desc *sbiod, void *arg ) { Sockbuf_Buf *p; assert( sbiod != NULL ); p = LBER_MALLOC( sizeof( *p ) ); if ( p == NULL ) return -1; ber_pvt_sb_buf_init( p ); if ( arg == NULL ) { ber_pvt_sb_grow_buffer( p, LBER_DEFAULT_READAHEAD ); } else { ber_pvt_sb_grow_buffer( p, *((int *)arg) ); } sbiod->sbiod_pvt = p; return 0; }
static int sb_rdahead_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg ) { Sockbuf_Buf *p; p = (Sockbuf_Buf *)sbiod->sbiod_pvt; if ( opt == LBER_SB_OPT_DATA_READY ) { if ( p->buf_ptr != p->buf_end ) { return 1; } } else if ( opt == LBER_SB_OPT_SET_READAHEAD ) { if ( p->buf_size >= *((ber_len_t *)arg) ) { return 0; } return ( ber_pvt_sb_grow_buffer( p, *((int *)arg) ) ? -1 : 1 ); } return LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg ); }
static ber_slen_t sb_sasl_generic_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) { struct sb_sasl_generic_data *p; ber_slen_t ret, bufptr; assert( sbiod != NULL ); assert( SOCKBUF_VALID( sbiod->sbiod_sb ) ); p = (struct sb_sasl_generic_data *)sbiod->sbiod_pvt; /* Are there anything left in the buffer? */ ret = ber_pvt_sb_copy_out( &p->buf_in, buf, len ); bufptr = ret; len -= ret; if ( len == 0 ) return bufptr; p->ops->reset_buf( p, &p->buf_in ); /* Read the length of the packet */ while ( p->sec_buf_in.buf_ptr < 4 ) { ret = LBER_SBIOD_READ_NEXT( sbiod, p->sec_buf_in.buf_base + p->sec_buf_in.buf_ptr, 4 - p->sec_buf_in.buf_ptr ); #ifdef EINTR if ( ( ret < 0 ) && ( errno == EINTR ) ) continue; #endif if ( ret <= 0 ) return bufptr ? bufptr : ret; p->sec_buf_in.buf_ptr += ret; } /* The new packet always starts at p->sec_buf_in.buf_base */ ret = sb_sasl_generic_pkt_length(p, (unsigned char *) p->sec_buf_in.buf_base, sbiod->sbiod_sb->sb_debug ); /* Grow the packet buffer if neccessary */ if ( ( p->sec_buf_in.buf_size < (ber_len_t) ret ) && ber_pvt_sb_grow_buffer( &p->sec_buf_in, ret ) < 0 ) { sock_errset(ENOMEM); return -1; } p->sec_buf_in.buf_end = ret; /* Did we read the whole encrypted packet? */ while ( p->sec_buf_in.buf_ptr < p->sec_buf_in.buf_end ) { /* No, we have got only a part of it */ ret = p->sec_buf_in.buf_end - p->sec_buf_in.buf_ptr; ret = LBER_SBIOD_READ_NEXT( sbiod, p->sec_buf_in.buf_base + p->sec_buf_in.buf_ptr, ret ); #ifdef EINTR if ( ( ret < 0 ) && ( errno == EINTR ) ) continue; #endif if ( ret <= 0 ) return bufptr ? bufptr : ret; p->sec_buf_in.buf_ptr += ret; } /* Decode the packet */ ret = p->ops->decode( p, &p->sec_buf_in, &p->buf_in ); /* Drop the packet from the input buffer */ sb_sasl_generic_drop_packet( p, sbiod->sbiod_sb->sb_debug ); if ( ret != 0 ) { ber_log_printf( LDAP_DEBUG_ANY, sbiod->sbiod_sb->sb_debug, "sb_sasl_generic_read: failed to decode packet\n" ); sock_errset(EIO); return -1; } bufptr += ber_pvt_sb_copy_out( &p->buf_in, (char*) buf + bufptr, len ); return bufptr; }