static int saslclientio_receive_byte()

in src/saslclientio.c [346:444]


static int saslclientio_receive_byte(SASL_CLIENT_IO_INSTANCE* sasl_client_io_instance, unsigned char b)
{
    int result;

    switch (sasl_client_io_instance->sasl_header_exchange_state)
    {
    default:
        LogError("Byte being received in unexpected state: %" PRI_MU_ENUM "", MU_ENUM_VALUE(SASL_HEADER_EXCHANGE_STATE, sasl_client_io_instance->sasl_header_exchange_state));
        result = MU_FAILURE;
        break;

    case SASL_HEADER_EXCHANGE_HEADER_EXCH:
        switch (sasl_client_io_instance->sasl_client_negotiation_state)
        {
        case SASL_CLIENT_NEGOTIATION_ERROR:
            LogError("Byte being received in unexpected state: %" PRI_MU_ENUM "", MU_ENUM_VALUE(SASL_CLIENT_NEGOTIATION_STATE, SASL_CLIENT_NEGOTIATION_ERROR));
            result = MU_FAILURE;
            break;

        default:
            /* Codes_SRS_SASLCLIENTIO_01_068: [During the SASL frame exchange that constitutes the handshake the received bytes from the underlying IO shall be fed to the frame codec instance created in `saslclientio_create` by calling `frame_codec_receive_bytes`.]*/
            if (frame_codec_receive_bytes(sasl_client_io_instance->frame_codec, &b, 1) != 0)
            {
                /* Codes_SRS_SASLCLIENTIO_01_088: [If `frame_codec_receive_bytes` fails, the `on_io_error` callback shall be triggered.]*/
                result = MU_FAILURE;
            }
            else
            {
                result = 0;
            }

            break;

        case SASL_CLIENT_NEGOTIATION_OUTCOME_RCVD:
            sasl_client_io_instance->on_bytes_received(sasl_client_io_instance->on_bytes_received_context, &b, 1);
            result = 0;
            break;
        }

        break;

    /* Codes_SRS_SASLCLIENTIO_01_003: [Other than using a protocol id of three, the exchange of SASL layer headers follows the same rules specified in the version negotiation section of the transport specification (See Part 2: section 2.2).] */
    case SASL_HEADER_EXCHANGE_IDLE:
    case SASL_HEADER_EXCHANGE_HEADER_SENT:
        if (b != sasl_header[sasl_client_io_instance->header_bytes_received])
        {
            LogError("Mismatched SASL header");
            result = MU_FAILURE;
        }
        else
        {
            sasl_client_io_instance->header_bytes_received++;
            if (sasl_client_io_instance->header_bytes_received == sizeof(sasl_header))
            {
                if (sasl_client_io_instance->is_trace_on != 0)
                {
                    LOG(AZ_LOG_TRACE, LOG_LINE, "<- Header (AMQP 3.1.0.0)");
                }

                switch (sasl_client_io_instance->sasl_header_exchange_state)
                {
                default:
                    LogError("Invalid SASL header exchange state: %" PRI_MU_ENUM "", MU_ENUM_VALUE(SASL_HEADER_EXCHANGE_STATE, sasl_client_io_instance->sasl_header_exchange_state));
                    result = MU_FAILURE;
                    break;

                case SASL_HEADER_EXCHANGE_HEADER_SENT:
                    /* from this point on we need to decode SASL frames */
                    sasl_client_io_instance->sasl_header_exchange_state = SASL_HEADER_EXCHANGE_HEADER_EXCH;
                    result = 0;
                    break;

                case SASL_HEADER_EXCHANGE_IDLE:
                    sasl_client_io_instance->sasl_header_exchange_state = SASL_HEADER_EXCHANGE_HEADER_RCVD;
                    if (send_sasl_header(sasl_client_io_instance) != 0)
                    {
                        /* Codes_SRS_SASLCLIENTIO_01_077: [If sending the SASL header fails, the `on_io_open_complete` callback shall be triggered with `IO_OPEN_ERROR`.]*/
                        LogError("Could not send SASL header");
                        result = MU_FAILURE;
                    }
                    else
                    {
                        result = 0;
                    }

                    break;
                }
            }
            else
            {
                result = 0;
            }
        }

        break;
    }

    return result;
}