in src/connection.c [630:713]
static int connection_byte_received(CONNECTION_HANDLE connection, unsigned char b)
{
int result;
switch (connection->connection_state)
{
default:
LogError("Unknown connection state: %d", (int)connection->connection_state);
result = MU_FAILURE;
break;
/* Codes_S_R_S_CONNECTION_01_039: [START In this state a connection exists, but nothing has been sent or received. This is the state an implementation would be in immediately after performing a socket connect or socket accept.] */
case CONNECTION_STATE_START:
/* Codes_S_R_S_CONNECTION_01_041: [HDR SENT In this state the connection header has been sent to the peer but no connection header has been received.] */
case CONNECTION_STATE_HDR_SENT:
if (b != amqp_header[connection->header_bytes_received])
{
/* Codes_S_R_S_CONNECTION_01_089: [If the incoming and outgoing protocol headers do not match, both peers MUST close their outgoing stream] */
if (xio_close(connection->io, NULL, NULL) != 0)
{
LogError("xio_close failed");
}
connection_set_state(connection, CONNECTION_STATE_END);
result = MU_FAILURE;
}
else
{
connection->header_bytes_received++;
if (connection->header_bytes_received == sizeof(amqp_header))
{
if (connection->is_trace_on == 1)
{
LOG(AZ_LOG_TRACE, LOG_LINE, "<- Header (AMQP 0.1.0.0)");
}
connection_set_state(connection, CONNECTION_STATE_HDR_EXCH);
if (send_open_frame(connection) != 0)
{
LogError("Cannot send open frame");
connection_set_state(connection, CONNECTION_STATE_END);
}
}
result = 0;
}
break;
/* Codes_S_R_S_CONNECTION_01_040: [HDR RCVD In this state the connection header has been received from the peer but a connection header has not been sent.] */
case CONNECTION_STATE_HDR_RCVD:
/* Codes_S_R_S_CONNECTION_01_042: [HDR EXCH In this state the connection header has been sent to the peer and a connection header has been received from the peer.] */
/* we should not really get into this state, but just in case, we would treat that in the same way as HDR_RCVD */
case CONNECTION_STATE_HDR_EXCH:
/* Codes_S_R_S_CONNECTION_01_045: [OPEN RCVD In this state the connection headers have been exchanged. An open frame has been received from the peer but an open frame has not been sent.] */
case CONNECTION_STATE_OPEN_RCVD:
/* Codes_S_R_S_CONNECTION_01_046: [OPEN SENT In this state the connection headers have been exchanged. An open frame has been sent to the peer but no open frame has yet been received.] */
case CONNECTION_STATE_OPEN_SENT:
/* Codes_S_R_S_CONNECTION_01_048: [OPENED In this state the connection header and the open frame have been both sent and received.] */
case CONNECTION_STATE_OPENED:
/* Codes_S_R_S_CONNECTION_01_212: [After the initial handshake has been done all bytes received from the io instance shall be passed to the frame_codec for decoding by calling frame_codec_receive_bytes.] */
if (frame_codec_receive_bytes(connection->frame_codec, &b, 1) != 0)
{
LogError("Cannot process received bytes");
/* Codes_S_R_S_CONNECTION_01_218: [The error amqp:internal-error shall be set in the error.condition field of the CLOSE frame.] */
/* Codes_S_R_S_CONNECTION_01_219: [The error description shall be set to an implementation defined string.] */
close_connection_with_error(connection, "amqp:internal-error", "connection_byte_received::frame_codec_receive_bytes failed", NULL);
result = MU_FAILURE;
}
else
{
result = 0;
}
break;
}
return result;
}