示例#1
0
char const *sql_info_2_str(struct proto_info const *info_)
{
    struct sql_proto_info const *info = DOWNCAST(info_, info, sql_proto_info);
    char *str = tempstr();

    char const *(*spec_info_2_str)(struct sql_proto_info const *) = NULL;
    switch (info->msg_type) {
        case SQL_UNKNOWN:
            break;
        case SQL_STARTUP:
            spec_info_2_str = info->is_query ? startup_query_2_str : startup_reply_2_str;
            break;
        case SQL_QUERY:
            spec_info_2_str = info->is_query ? query_query_2_str : query_reply_2_str;
            break;
        case SQL_EXIT:
            spec_info_2_str = exit_2_str;
            break;
    }

    snprintf(str, TEMPSTR_SIZE, "%s, %s%s, %s%s%s%s%s%s%s%s%s%s",
        proto_info_2_str(info_),
        info->is_query ? "Clt->Srv" : "Srv->Clt",
        version_info_2_str(info),
        sql_msg_type_2_str(info->msg_type),
        spec_info_2_str ? spec_info_2_str(info) : "",
        info->set_values & SQL_REQUEST_STATUS ? ", Status=" : "",
        info->set_values & SQL_REQUEST_STATUS ? sql_request_status_2_str(info->request_status) : "",
        info->set_values & SQL_ERROR_SQL_STATUS ? ", SqlCode=" : "",
        info->set_values & SQL_ERROR_SQL_STATUS ? info->error_sql_status : "",
        info->set_values & SQL_ERROR_CODE ? ", ErrorCode=" : "",
        info->set_values & SQL_ERROR_CODE ? info->error_code : "",
        info->set_values & SQL_ERROR_MESSAGE ? ", ErrorMessage=" : "",
        info->set_values & SQL_ERROR_MESSAGE ? info->error_message : "");
    return str;
}
示例#2
0
/*
 * | 2 bytes | 1 byte   | Variable |
 * | Flags   | TTC code | TTC body |
 */
static enum proto_parse_status tns_parse_data(struct tns_parser *tns_parser, struct sql_proto_info *info, struct cursor *cursor,
        unsigned way)
{
    SLOG(LOG_DEBUG, "Parsing TNS data PDU of size %zu", cursor->cap_len);
    enum proto_parse_status status = PROTO_OK;

    // First, read the data flags
    CHECK(2);
    unsigned flags = cursor_read_u16n(cursor);
    SLOG(LOG_DEBUG, "Data flags = 0x%x", flags);
    if (flags & 0x40) { // End Of File
        if (cursor->cap_len != 0) return PROTO_PARSE_ERR;   // This may be wrong, maybe a command is allowed anyway
        info->msg_type = SQL_EXIT;
        sql_set_request_status(info, SQL_REQUEST_COMPLETE);
        return PROTO_OK;
    }
    info->msg_type = tns_parser->msg_type;
    while (status == PROTO_OK && cursor->cap_len) {
        CHECK(1);
        enum ttc_code ttc_code = cursor_read_u8(cursor);
        SLOG(LOG_DEBUG, "Ttc code = 0x%02x, msg type %s", ttc_code, sql_msg_type_2_str(tns_parser->msg_type));
        switch (ttc_code) {
            case TTC_ROW_PREFIX:
                status = tns_parse_row_prefix(tns_parser, info, cursor);
                break;
            case TTC_ROW_DATA:
                status = tns_parse_row_data(tns_parser, info, cursor);
                break;
            case TTC_ROW_DESCRIPTION_PREFIX:
                status = tns_parse_row_description_prefix(tns_parser, info, cursor);
                break;
            case TTC_ROW_RECAP:
                status = tns_parse_row_recap(cursor);
                break;
            case TTC_ROW_DESCRIPTION:
                status = tns_parse_row_description(cursor);
                break;
            case TTC_LOGIN_PROPERTY:
                status = tns_parse_login_property(info, cursor);
                break;
            case TTC_QUERY:
                status = tns_parse_query(tns_parser, info, cursor);
                break;
            case TTC_END_MESSAGE:
                status = tns_parse_end(info, cursor);
                break;
            case TTC_CLOSE:
                status = tns_parse_close_statement(cursor);
                break;
            default:
                SLOG(LOG_DEBUG, "Unknown ttc_code = %u", ttc_code);
                return PROTO_OK;
        }
        if (status == PROTO_OK) {
            enum sql_msg_type ttc_msg_type = ttc_to_msg_type(tns_parser, ttc_code);
            if (ttc_msg_type != SQL_UNKNOWN) {
                info->msg_type = ttc_msg_type;
                tns_parser->msg_type = ttc_msg_type;
            }
            // Fix c2s_way
            bool old_c2s_way = tns_parser->c2s_way;
            switch (ttc_code) {
                case TTC_ROW_DESCRIPTION_PREFIX:
                case TTC_ROW_RECAP:
                case TTC_ROW_DESCRIPTION:
                case TTC_END_MESSAGE:
                    tns_parser->c2s_way = !way;
                    break;
                case TTC_QUERY:
                case TTC_CLOSE:
                    tns_parser->c2s_way = way;
                    break;
                default:
                    break;
            }
            if (old_c2s_way != tns_parser->c2s_way) {
                SLOG(LOG_DEBUG, "Fix c2s way from %d to %d", old_c2s_way, tns_parser->c2s_way);
            }
            info->is_query = way == tns_parser->c2s_way;
        }
    }
    return status;
}