get_next_from_buffer(void *buffer __attribute__((unused)), size_t buffer_size __attribute__((unused)), ber_len_t *lenp, ber_tag_t *tagp, BerElement *ber, Connection *conn)
{
    PRErrorCode err = 0;
    PRInt32 syserr = 0;
    ber_len_t bytes_scanned = 0;

    *lenp = 0;
    *tagp = ber_get_next(conn->c_sb, &bytes_scanned, ber);
    /* openldap ber_get_next doesn't return partial bytes_scanned if it hasn't
       read a whole pdu - so we have to check the errno for the
       "would block" condition meaning openldap needs more data to read */
    if ((LBER_OVERFLOW == *tagp || LBER_DEFAULT == *tagp) && 0 == bytes_scanned &&
        !SLAPD_SYSTEM_WOULD_BLOCK_ERROR(errno)) {
        if ((LBER_OVERFLOW == *tagp) || (errno == ERANGE)) {
            ber_len_t maxbersize = conn->c_maxbersize;
            ber_len_t tmplen = 0;
            (void)_ber_get_len(ber, &tmplen);
            /* openldap does not differentiate between length == 0
               and length > max - all we know is that there was a
               problem with the length - assume too big */
            err = SLAPD_DISCONNECT_BER_TOO_BIG;
            log_ber_too_big_error(conn, tmplen, maxbersize);
        } else {
            err = SLAPD_DISCONNECT_BAD_BER_TAG;
        }
        syserr = errno;
        /* Bad stuff happened, like the client sent us some junk */
        slapi_log_err(SLAPI_LOG_CONNS, "get_next_from_buffer",
                      "ber_get_next failed for connection %" PRIu64 "\n", conn->c_connid);
        /* reset private buffer */
        conn->c_private->c_buffer_bytes = conn->c_private->c_buffer_offset = 0;

        /* drop connection */
        disconnect_server_nomutex(conn, conn->c_connid, -1, err, syserr);
        return -1;
    } else if (CONNECTION_BUFFER_OFF == conn->c_private->use_buffer) {
        *lenp = bytes_scanned;
        if ((LBER_OVERFLOW == *tagp || LBER_DEFAULT == *tagp) && 0 == bytes_scanned &&
            SLAPD_SYSTEM_WOULD_BLOCK_ERROR(errno)) {
            return -2; /* tells connection_read_operation we need to try again */
        }
    } /* else, openldap_read_function will advance c_buffer_offset,
         nothing to do (we had to previously with mozldap) */
    return 0;
}
get_next_from_buffer(void *buffer __attribute__((unused)), size_t buffer_size __attribute__((unused)), ber_len_t *lenp, ber_tag_t *tagp, BerElement *ber, Connection *conn)
{
    PRErrorCode err = 0;
    PRInt32 syserr = 0;
    ber_len_t bytes_scanned = 0;

    *lenp = 0;
    *tagp = ber_get_next(conn->c_sb, &bytes_scanned, ber);
     
    if ((LBER_OVERFLOW == *tagp || LBER_DEFAULT == *tagp) && 0 == bytes_scanned &&
        !SLAPD_SYSTEM_WOULD_BLOCK_ERROR(errno)) {
        if ((LBER_OVERFLOW == *tagp) || (errno == ERANGE)) {
            ber_len_t maxbersize = conn->c_maxbersize;
            ber_len_t tmplen = 0;
            (void)_ber_get_len(ber, &tmplen);
             
            err = SLAPD_DISCONNECT_BER_TOO_BIG;
            log_ber_too_big_error(conn, tmplen, maxbersize);
        } else {
            err = SLAPD_DISCONNECT_BAD_BER_TAG;
        }
        syserr = errno;
         
        slapi_log_err(SLAPI_LOG_CONNS, "get_next_from_buffer",
                      "ber_get_next failed for connection %" PRIu64 "\n", conn->c_connid);
         
        conn->c_private->c_buffer_bytes = conn->c_private->c_buffer_offset = 0;

         
        disconnect_server_nomutex(conn, conn->c_connid, -1, err, syserr);
        return -1;
    } else if (CONNECTION_BUFFER_OFF == conn->c_private->use_buffer) {
        *lenp = bytes_scanned;
        if ((LBER_OVERFLOW == *tagp || LBER_DEFAULT == *tagp) && 0 == bytes_scanned &&
            SLAPD_SYSTEM_WOULD_BLOCK_ERROR(errno)) {
            return -2;  
        }
    }  
    return 0;
}