A small memory footprint AMQP implimentation
Dependents: iothub_client_sample_amqp remote_monitoring simplesample_amqp
Diff: sasl_frame_codec.c
- Revision:
- 23:1111ee8bcba4
- Parent:
- 20:206846c14c80
- Child:
- 28:add19eb7defa
diff -r 524bded3f7a8 -r 1111ee8bcba4 sasl_frame_codec.c --- a/sasl_frame_codec.c Thu Apr 06 14:11:27 2017 -0700 +++ b/sasl_frame_codec.c Fri Apr 21 14:50:32 2017 -0700 @@ -7,6 +7,7 @@ #include <string.h> #include "azure_c_shared_utility/gballoc.h" #include "azure_c_shared_utility/optimize_size.h" +#include "azure_c_shared_utility/xlogging.h" #include "azure_uamqp_c/sasl_frame_codec.h" #include "azure_uamqp_c/frame_codec.h" #include "azure_uamqp_c/amqpvalue.h" @@ -44,6 +45,7 @@ if (descriptor == NULL) { + LogError("Cannot get frame descriptor"); sasl_frame_codec_instance->decode_state = SASL_FRAME_DECODE_ERROR; /* Codes_SRS_SASL_FRAME_CODEC_01_049: [If any error occurs while decoding a frame, the decoder shall call the on_sasl_frame_codec_error and pass to it the callback_context, both of those being the ones given to sasl_frame_codec_create.] */ @@ -58,7 +60,8 @@ !is_sasl_response_type_by_descriptor(descriptor) && !is_sasl_outcome_type_by_descriptor(descriptor)) { - sasl_frame_codec_instance->decode_state = SASL_FRAME_DECODE_ERROR; + LogError("Not a SASL frame"); + sasl_frame_codec_instance->decode_state = SASL_FRAME_DECODE_ERROR; /* Codes_SRS_SASL_FRAME_CODEC_01_049: [If any error occurs while decoding a frame, the decoder shall call the on_sasl_frame_codec_error and pass to it the callback_context, both of those being the ones given to sasl_frame_codec_create.] */ sasl_frame_codec_instance->on_sasl_frame_codec_error(sasl_frame_codec_instance->callback_context); @@ -83,7 +86,7 @@ /* Codes_SRS_SASL_FRAME_CODEC_01_010: [Receipt of an empty frame is an irrecoverable error.] */ (frame_body_size == 0)) { - /* error */ + LogError("Bad SASL frame size"); /* Codes_SRS_SASL_FRAME_CODEC_01_049: [If any error occurs while decoding a frame, the decoder shall call the on_sasl_frame_codec_error and pass to it the callback_context, both of those being the ones given to sasl_frame_codec_create.] */ sasl_frame_codec_instance->on_sasl_frame_codec_error(sasl_frame_codec_instance->callback_context); @@ -94,7 +97,6 @@ { default: case SASL_FRAME_DECODE_ERROR: - /* error */ break; case SASL_FRAME_DECODE_FRAME: @@ -109,7 +111,8 @@ /* Codes_SRS_SASL_FRAME_CODEC_01_040: [Decoding the sasl-frame type shall be done by feeding the bytes to the decoder create in sasl_frame_codec_create.] */ if (amqpvalue_decode_bytes(sasl_frame_codec_instance->decoder, frame_body, 1) != 0) { - sasl_frame_codec_instance->decode_state = SASL_FRAME_DECODE_ERROR; + LogError("Could not decode SASL frame AMQP value"); + sasl_frame_codec_instance->decode_state = SASL_FRAME_DECODE_ERROR; } else { @@ -121,17 +124,14 @@ /* Codes_SRS_SASL_FRAME_CODEC_01_009: [The frame body of a SASL frame MUST contain exactly one AMQP type, whose type encoding MUST have provides="sasl-frame".] */ if (frame_body_size > 0) { - sasl_frame_codec_instance->decode_state = SASL_FRAME_DECODE_ERROR; + LogError("More than one AMQP value detected in SASL frame"); + sasl_frame_codec_instance->decode_state = SASL_FRAME_DECODE_ERROR; /* Codes_SRS_SASL_FRAME_CODEC_01_049: [If any error occurs while decoding a frame, the decoder shall call the on_sasl_frame_codec_error and pass to it the callback_context, both of those being the ones given to sasl_frame_codec_create.] */ sasl_frame_codec_instance->on_sasl_frame_codec_error(sasl_frame_codec_instance->callback_context); } - if (sasl_frame_codec_instance->decode_state == SASL_FRAME_DECODE_ERROR) - { - /* error */ - } - else + if (sasl_frame_codec_instance->decode_state != SASL_FRAME_DECODE_ERROR) { /* Codes_SRS_SASL_FRAME_CODEC_01_041: [Once the sasl frame is decoded, the callback on_sasl_frame_received shall be called.] */ /* Codes_SRS_SASL_FRAME_CODEC_01_042: [The decoded sasl-frame value and the context passed in sasl_frame_codec_create shall be passed to on_sasl_frame_received.] */ @@ -159,14 +159,20 @@ (on_sasl_frame_received == NULL) || (on_sasl_frame_codec_error == NULL)) { - result = NULL; + LogError("Bad arguments: frame_codec = %p, on_sasl_frame_received = %p, on_sasl_frame_codec_error = %p", + frame_codec, on_sasl_frame_received, on_sasl_frame_codec_error); + result = NULL; } else { /* Codes_SRS_SASL_FRAME_CODEC_01_018: [sasl_frame_codec_create shall create an instance of an sasl_frame_codec and return a non-NULL handle to it.] */ result = (SASL_FRAME_CODEC_INSTANCE*)malloc(sizeof(SASL_FRAME_CODEC_INSTANCE)); - if (result != NULL) - { + if (result == NULL) + { + LogError("Cannot allocate memory for SASL frame codec"); + } + else + { result->frame_codec = frame_codec; result->on_sasl_frame_received = on_sasl_frame_received; result->on_sasl_frame_codec_error = on_sasl_frame_codec_error; @@ -178,7 +184,8 @@ if (result->decoder == NULL) { /* Codes_SRS_SASL_FRAME_CODEC_01_023: [If creating the decoder fails, sasl_frame_codec_create shall fail and return NULL.] */ - free(result); + LogError("Cannot create AMQP value decoder"); + free(result); result = NULL; } else @@ -188,7 +195,8 @@ if (frame_codec_subscribe(frame_codec, FRAME_TYPE_SASL, frame_received, result) != 0) { /* Codes_SRS_SASL_FRAME_CODEC_01_021: [If subscribing for SASL frames fails, sasl_frame_codec_create shall fail and return NULL.] */ - amqpvalue_decoder_destroy(result->decoder); + LogError("Cannot subscribe for SASL frames"); + amqpvalue_decoder_destroy(result->decoder); free(result); result = NULL; } @@ -202,8 +210,12 @@ void sasl_frame_codec_destroy(SASL_FRAME_CODEC_HANDLE sasl_frame_codec) { /* Codes_SRS_SASL_FRAME_CODEC_01_026: [If sasl_frame_codec is NULL, sasl_frame_codec_destroy shall do nothing.] */ - if (sasl_frame_codec != NULL) - { + if (sasl_frame_codec == NULL) + { + LogError("NULL sasl_frame_codec"); + } + else + { /* Codes_SRS_SASL_FRAME_CODEC_01_025: [sasl_frame_codec_destroy shall free all resources associated with the sasl_frame_codec instance.] */ SASL_FRAME_CODEC_INSTANCE* sasl_frame_codec_instance = (SASL_FRAME_CODEC_INSTANCE*)sasl_frame_codec; @@ -227,38 +239,58 @@ (sasl_frame_value == NULL)) { /* Codes_SRS_SASL_FRAME_CODEC_01_034: [If any error occurs during encoding, sasl_frame_codec_encode_frame shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Bad arguments: sasl_frame_codec = %p, sasl_frame_value = %p", + sasl_frame_codec, sasl_frame_value); + result = __FAILURE__; } else { AMQP_VALUE descriptor; uint64_t sasl_frame_descriptor_ulong; - size_t encoded_size; + size_t encoded_size; - if (((descriptor = amqpvalue_get_inplace_descriptor(sasl_frame_value)) == NULL) || - (amqpvalue_get_ulong(descriptor, &sasl_frame_descriptor_ulong) != 0) || - /* Codes_SRS_SASL_FRAME_CODEC_01_047: [The frame body of a SASL frame MUST contain exactly one AMQP type, whose type encoding MUST have provides="sasl-frame".] */ - (sasl_frame_descriptor_ulong < SASL_MECHANISMS) || + if ((descriptor = amqpvalue_get_inplace_descriptor(sasl_frame_value)) == NULL) + { + /* Codes_SRS_SASL_FRAME_CODEC_01_034: [If any error occurs during encoding, sasl_frame_codec_encode_frame shall fail and return a non-zero value.] */ + LogError("Cannot get SASL frame descriptor AMQP value"); + result = __FAILURE__; + } + else if (amqpvalue_get_ulong(descriptor, &sasl_frame_descriptor_ulong) != 0) + { + /* Codes_SRS_SASL_FRAME_CODEC_01_034: [If any error occurs during encoding, sasl_frame_codec_encode_frame shall fail and return a non-zero value.] */ + LogError("Cannot get SASL frame descriptor ulong"); + result = __FAILURE__; + } + /* Codes_SRS_SASL_FRAME_CODEC_01_047: [The frame body of a SASL frame MUST contain exactly one AMQP type, whose type encoding MUST have provides="sasl-frame".] */ + else if ((sasl_frame_descriptor_ulong < SASL_MECHANISMS) || (sasl_frame_descriptor_ulong > SASL_OUTCOME)) { /* Codes_SRS_SASL_FRAME_CODEC_01_034: [If any error occurs during encoding, sasl_frame_codec_encode_frame shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Bad SASL frame descriptor"); + result = __FAILURE__; } /* Codes_SRS_SASL_FRAME_CODEC_01_032: [The payload frame size shall be computed based on the encoded size of the sasl_frame_value and its fields.] */ /* Codes_SRS_SASL_FRAME_CODEC_01_033: [The encoded size of the sasl_frame_value and its fields shall be obtained by calling amqpvalue_get_encoded_size.] */ - else if ((amqpvalue_get_encoded_size(sasl_frame_value, &encoded_size) != 0) || + else if (amqpvalue_get_encoded_size(sasl_frame_value, &encoded_size) != 0) + { + /* Codes_SRS_SASL_FRAME_CODEC_01_034: [If any error occurs during encoding, sasl_frame_codec_encode_frame shall fail and return a non-zero value.] */ + LogError("Cannot get SASL frame encoded size"); + result = __FAILURE__; + } /* Codes_SRS_SASL_FRAME_CODEC_01_016: [The maximum size of a SASL frame is defined by MIN-MAX-FRAME-SIZE.] */ - (encoded_size > MIX_MAX_FRAME_SIZE - 8)) + else if (encoded_size > MIX_MAX_FRAME_SIZE - 8) { /* Codes_SRS_SASL_FRAME_CODEC_01_034: [If any error occurs during encoding, sasl_frame_codec_encode_frame shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("SASL frame encoded size too big"); + result = __FAILURE__; } else { unsigned char* sasl_frame_bytes = (unsigned char*)malloc(encoded_size); if (sasl_frame_bytes == NULL) { - result = __FAILURE__; + LogError("Cannot allocate SASL frame bytes"); + result = __FAILURE__; } else { @@ -269,7 +301,8 @@ if (amqpvalue_encode(sasl_frame_value, encode_bytes, &payload) != 0) { - result = __FAILURE__; + LogError("Cannot encode SASL frame value"); + result = __FAILURE__; } else { @@ -281,7 +314,8 @@ if (frame_codec_encode_frame(sasl_frame_codec_instance->frame_codec, FRAME_TYPE_SASL, &payload, 1, NULL, 0, on_bytes_encoded, callback_context) != 0) { /* Codes_SRS_SASL_FRAME_CODEC_01_034: [If any error occurs during encoding, sasl_frame_codec_encode_frame shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Cannot encode SASL frame"); + result = __FAILURE__; } else {