static int add_string_key_value_pair_to_map(AMQP_VALUE map, const char* key, const char* value) { int result; AMQP_VALUE key_value = amqpvalue_create_string(key); if (key == NULL) { result = __LINE__; } else { AMQP_VALUE value_value = amqpvalue_create_string(value); if (value_value == NULL) { result = __LINE__; } else { if (amqpvalue_set_map_value(map, key_value, value_value) != 0) { result = __LINE__; } else { result = 0; } amqpvalue_destroy(key_value); } amqpvalue_destroy(value_value); } return result; }
int session_send_disposition(LINK_ENDPOINT_HANDLE link_endpoint, DISPOSITION_HANDLE disposition) { int result; if ((link_endpoint == NULL) || (disposition == NULL)) { result = __LINE__; } else { LINK_ENDPOINT_INSTANCE* link_endpoint_instance = (LINK_ENDPOINT_INSTANCE*)link_endpoint; AMQP_VALUE disposition_performative_value = amqpvalue_create_disposition(disposition); if (disposition_performative_value == NULL) { result = __LINE__; } else { if (encode_frame(link_endpoint, disposition_performative_value, NULL, 0) != 0) { result = __LINE__; } else { result = 0; } amqpvalue_destroy(disposition_performative_value); } } return result; }
int session_send_flow(LINK_ENDPOINT_HANDLE link_endpoint, FLOW_HANDLE flow) { int result; if ((link_endpoint == NULL) || (flow == NULL)) { result = __LINE__; } else { LINK_ENDPOINT_INSTANCE* link_endpoint_instance = (LINK_ENDPOINT_INSTANCE*)link_endpoint; SESSION_INSTANCE* session_instance = (SESSION_INSTANCE*)link_endpoint_instance->session; result = 0; if ((session_instance->session_state == SESSION_STATE_BEGIN_RCVD) || ((session_instance->session_state == SESSION_STATE_MAPPED))) { if (flow_set_next_incoming_id(flow, session_instance->next_incoming_id) != 0) { result = __LINE__; } } if (result == 0) { if ((flow_set_incoming_window(flow, session_instance->incoming_window) != 0) || (flow_set_next_outgoing_id(flow, session_instance->next_outgoing_id) != 0) || (flow_set_outgoing_window(flow, session_instance->outgoing_window) != 0) || (flow_set_handle(flow, link_endpoint_instance->output_handle) != 0)) { result = __LINE__; } else { AMQP_VALUE flow_performative_value = amqpvalue_create_flow(flow); if (flow_performative_value == NULL) { result = __LINE__; } else { if (encode_frame(link_endpoint, flow_performative_value, NULL, 0) != 0) { result = __LINE__; } else { result = 0; } amqpvalue_destroy(flow_performative_value); } } } } return result; }
static int send_begin(SESSION_INSTANCE* session_instance) { int result; BEGIN_HANDLE begin = begin_create(session_instance->next_outgoing_id, session_instance->incoming_window, session_instance->outgoing_window); if (begin == NULL) { result = __LINE__; } else { uint16_t remote_channel; if (begin_set_handle_max(begin, session_instance->handle_max) != 0) { result = __LINE__; } else if ((session_instance->session_state == SESSION_STATE_BEGIN_RCVD) && ((connection_endpoint_get_incoming_channel(session_instance->endpoint, &remote_channel) != 0) || (begin_set_remote_channel(begin, remote_channel) != 0))) { result = __LINE__; } else { AMQP_VALUE begin_performative_value = amqpvalue_create_begin(begin); if (begin_performative_value == NULL) { result = __LINE__; } else { if (connection_encode_frame(session_instance->endpoint, begin_performative_value, NULL, 0, NULL, NULL) != 0) { result = __LINE__; } else { result = 0; } amqpvalue_destroy(begin_performative_value); } } begin_destroy(begin); } return result; }
static int send_flow(SESSION_INSTANCE* session) { int result; if (session == NULL) { result = __LINE__; } else { FLOW_HANDLE flow = flow_create(session->incoming_window, session->next_outgoing_id, session->outgoing_window); if (flow == NULL) { result = __LINE__; } else { if (flow_set_next_incoming_id(flow, session->next_incoming_id) != 0) { result = __LINE__; } else { AMQP_VALUE flow_performative_value = amqpvalue_create_flow(flow); if (flow_performative_value == NULL) { result = __LINE__; } else { if (connection_encode_frame(session->endpoint, flow_performative_value, NULL, 0, NULL, NULL) != 0) { result = __LINE__; } else { result = 0; } amqpvalue_destroy(flow_performative_value); } } flow_destroy(flow); } } return result; }
static int send_end_frame(SESSION_INSTANCE* session_instance, ERROR_HANDLE error_handle) { int result; END_HANDLE end_performative; end_performative = end_create(); if (end_performative == NULL) { result = __LINE__; } else { if ((error_handle != NULL) && (end_set_error(end_performative, error_handle) != 0)) { result = __LINE__; } else { AMQP_VALUE end_performative_value = amqpvalue_create_end(end_performative); if (end_performative_value == NULL) { result = __LINE__; } else { if (connection_encode_frame(session_instance->endpoint, end_performative_value, NULL, 0, NULL, NULL) != 0) { result = __LINE__; } else { result = 0; } amqpvalue_destroy(end_performative_value); } } end_destroy(end_performative); } return result; }
int session_send_detach(LINK_ENDPOINT_HANDLE link_endpoint, DETACH_HANDLE detach) { int result; if ((link_endpoint == NULL) || (detach == NULL)) { result = __LINE__; } else { LINK_ENDPOINT_INSTANCE* link_endpoint_instance = (LINK_ENDPOINT_INSTANCE*)link_endpoint; if (detach_set_handle(detach, link_endpoint_instance->output_handle) != 0) { result = __LINE__; } else { AMQP_VALUE detach_performative_value = amqpvalue_create_detach(detach); if (detach_performative_value == NULL) { result = __LINE__; } else { if (encode_frame(link_endpoint, detach_performative_value, NULL, 0) != 0) { result = __LINE__; } else { result = 0; } amqpvalue_destroy(detach_performative_value); } } } return result; }
static int send_sasl_response(SASL_CLIENT_IO_INSTANCE* sasl_client_io, SASL_MECHANISM_BYTES sasl_response) { int result; SASL_RESPONSE_HANDLE sasl_response_handle; amqp_binary response_binary_value = { sasl_response.bytes, sasl_response.length }; /* Codes_SRS_SASLCLIENTIO_01_055: [Send the SASL response data as defined by the SASL specification.] */ /* Codes_SRS_SASLCLIENTIO_01_056: [A block of opaque data passed to the security mechanism.] */ if ((sasl_response_handle = sasl_response_create(response_binary_value)) == NULL) { result = __LINE__; } else { AMQP_VALUE sasl_response_value = amqpvalue_create_sasl_response(sasl_response_handle); if (sasl_response_value == NULL) { result = __LINE__; } else { /* Codes_SRS_SASLCLIENTIO_01_070: [When a frame needs to be sent as part of the SASL handshake frame exchange, the send shall be done by calling sasl_frame_codec_encode_frame.] */ if (sasl_frame_codec_encode_frame(sasl_client_io->sasl_frame_codec, sasl_response_value, on_bytes_encoded, sasl_client_io) != 0) { result = __LINE__; } else { log_outgoing_frame(sasl_client_io, sasl_response_value); result = 0; } amqpvalue_destroy(sasl_response_value); } sasl_response_destroy(sasl_response_handle); } return result; }
static int set_message_id(MESSAGE_HANDLE message, unsigned long next_message_id) { int result = 0; PROPERTIES_HANDLE properties; if (message_get_properties(message, &properties) != 0) { result = __LINE__; } else { AMQP_VALUE message_id = amqpvalue_create_message_id_ulong(next_message_id); if (message_id == NULL) { result = __LINE__; } else { if (properties_set_message_id(properties, message_id) != 0) { result = __LINE__; } amqpvalue_destroy(message_id); } if (message_set_properties(message, properties) != 0) { result = __LINE__; } properties_destroy(properties); } return result; }
/* Codes_SRS_SESSION_01_051: [session_send_transfer shall send a transfer frame with the performative indicated in the transfer argument.] */ SESSION_SEND_TRANSFER_RESULT session_send_transfer(LINK_ENDPOINT_HANDLE link_endpoint, TRANSFER_HANDLE transfer, PAYLOAD* payloads, size_t payload_count, delivery_number* delivery_id, ON_SEND_COMPLETE on_send_complete, void* callback_context) { SESSION_SEND_TRANSFER_RESULT result; /* Codes_SRS_SESSION_01_054: [If link_endpoint or transfer is NULL, session_send_transfer shall fail and return a non-zero value.] */ if ((link_endpoint == NULL) || (transfer == NULL)) { result = SESSION_SEND_TRANSFER_ERROR; } else { LINK_ENDPOINT_INSTANCE* link_endpoint_instance = (LINK_ENDPOINT_INSTANCE*)link_endpoint; SESSION_INSTANCE* session_instance = (SESSION_INSTANCE*)link_endpoint_instance->session; /* Codes_SRS_SESSION_01_059: [When session_send_transfer is called while the session is not in the MAPPED state, session_send_transfer shall fail and return a non-zero value.] */ if (session_instance->session_state != SESSION_STATE_MAPPED) { result = SESSION_SEND_TRANSFER_ERROR; } else { uint32_t payload_size = 0; size_t i; for (i = 0; i < payload_count; i++) { payload_size += payloads[i].length; } if (session_instance->remote_incoming_window == 0) { result = SESSION_SEND_TRANSFER_BUSY; } else { /* Codes_SRS_SESSION_01_012: [The session endpoint assigns each outgoing transfer frame an implicit transfer-id from a session scoped sequence.] */ /* Codes_SRS_SESSION_01_027: [sending a transfer Upon sending a transfer, the sending endpoint will increment its next-outgoing-id] */ *delivery_id = session_instance->next_outgoing_id; if ((transfer_set_handle(transfer, link_endpoint_instance->output_handle) != 0) || (transfer_set_delivery_id(transfer, *delivery_id) != 0)) { /* Codes_SRS_SESSION_01_058: [When any other error occurs, session_send_transfer shall fail and return a non-zero value.] */ result = SESSION_SEND_TRANSFER_ERROR; } else { AMQP_VALUE transfer_value; transfer_value = amqpvalue_create_transfer(transfer); if (transfer_value == NULL) { /* Codes_SRS_SESSION_01_058: [When any other error occurs, session_send_transfer shall fail and return a non-zero value.] */ result = SESSION_SEND_TRANSFER_ERROR; } else { uint32_t available_frame_size; size_t encoded_size; if ((connection_get_remote_max_frame_size(session_instance->connection, &available_frame_size) != 0) || (amqpvalue_get_encoded_size(transfer_value, &encoded_size) != 0)) { result = SESSION_SEND_TRANSFER_ERROR; } else { uint32_t payload_size = 0; size_t i; for (i = 0; i < payload_count; i++) { payload_size += payloads[i].length; } available_frame_size -= encoded_size; available_frame_size -= 8; if (available_frame_size >= payload_size) { /* Codes_SRS_SESSION_01_055: [The encoding of the frame shall be done by calling connection_encode_frame and passing as arguments: the connection handle associated with the session, the transfer performative and the payload chunks passed to session_send_transfer.] */ if (connection_encode_frame(session_instance->endpoint, transfer_value, payloads, payload_count, on_send_complete, callback_context) != 0) { /* Codes_SRS_SESSION_01_056: [If connection_encode_frame fails then session_send_transfer shall fail and return a non-zero value.] */ result = SESSION_SEND_TRANSFER_ERROR; } else { /* Codes_SRS_SESSION_01_018: [is incremented after each successive transfer according to RFC-1982 [RFC1982] serial number arithmetic.] */ session_instance->next_outgoing_id++; session_instance->remote_incoming_window--; session_instance->outgoing_window--; /* Codes_SRS_SESSION_01_053: [On success, session_send_transfer shall return 0.] */ result = SESSION_SEND_TRANSFER_OK; } } else { size_t current_payload_index = 0; uint32_t current_payload_pos = 0; /* break it down into different deliveries */ while (payload_size > 0) { uint32_t transfer_frame_payload_count = 0; uint32_t current_transfer_frame_payload_size = payload_size; uint32_t byte_counter; size_t temp_current_payload_index = current_payload_index; uint32_t temp_current_payload_pos = current_payload_pos; AMQP_VALUE multi_transfer_amqp_value; bool more; if (current_transfer_frame_payload_size > available_frame_size) { current_transfer_frame_payload_size = available_frame_size; } if (available_frame_size >= payload_size) { more = false; } else { more = true; } if (transfer_set_more(transfer, more) != 0) { break; } multi_transfer_amqp_value = amqpvalue_create_transfer(transfer); if (multi_transfer_amqp_value == NULL) { break; } byte_counter = current_transfer_frame_payload_size; while (byte_counter > 0) { if (payloads[temp_current_payload_index].length - temp_current_payload_pos >= byte_counter) { /* more data than we need */ temp_current_payload_pos += byte_counter; byte_counter = 0; } else { byte_counter -= payloads[temp_current_payload_index].length - temp_current_payload_pos; temp_current_payload_index++; temp_current_payload_pos = 0; } } transfer_frame_payload_count = temp_current_payload_index - current_payload_index + 1; PAYLOAD* transfer_frame_payloads = (PAYLOAD*)amqpalloc_malloc(transfer_frame_payload_count * sizeof(PAYLOAD)); if (transfer_frame_payloads == NULL) { amqpvalue_destroy(multi_transfer_amqp_value); break; } /* copy data */ byte_counter = current_transfer_frame_payload_size; transfer_frame_payload_count = 0; while (byte_counter > 0) { if (payloads[current_payload_index].length - current_payload_pos > byte_counter) { /* more data than we need */ transfer_frame_payloads[transfer_frame_payload_count].bytes = payloads[current_payload_index].bytes + current_payload_pos; transfer_frame_payloads[transfer_frame_payload_count].length = byte_counter; current_payload_pos += byte_counter; byte_counter = 0; } else { /* copy entire payload and move to the next */ transfer_frame_payloads[transfer_frame_payload_count].bytes = payloads[current_payload_index].bytes + current_payload_pos; transfer_frame_payloads[transfer_frame_payload_count].length = payloads[current_payload_index].length - current_payload_pos; byte_counter -= payloads[current_payload_index].length - current_payload_pos; current_payload_index++; current_payload_pos = 0; } transfer_frame_payload_count++; } if (connection_encode_frame(session_instance->endpoint, multi_transfer_amqp_value, transfer_frame_payloads, transfer_frame_payload_count, on_send_complete, callback_context) != 0) { amqpalloc_free(transfer_frame_payloads); amqpvalue_destroy(multi_transfer_amqp_value); break; } amqpalloc_free(transfer_frame_payloads); amqpvalue_destroy(multi_transfer_amqp_value); payload_size -= current_transfer_frame_payload_size; } if (payload_size > 0) { result = SESSION_SEND_TRANSFER_ERROR; } else { /* Codes_SRS_SESSION_01_018: [is incremented after each successive transfer according to RFC-1982 [RFC1982] serial number arithmetic.] */ session_instance->next_outgoing_id++; session_instance->remote_incoming_window--; session_instance->outgoing_window--; result = SESSION_SEND_TRANSFER_OK; } } } amqpvalue_destroy(transfer_value); } } } } } return result; }
static int send_sasl_init(SASL_CLIENT_IO_INSTANCE* sasl_client_io, const char* sasl_mechanism_name) { int result; SASL_INIT_HANDLE sasl_init; SASL_MECHANISM_BYTES init_bytes; /* Codes_SRS_SASLCLIENTIO_01_045: [The name of the SASL mechanism used for the SASL exchange.] */ sasl_init = sasl_init_create(sasl_mechanism_name); if (sasl_init == NULL) { /* Codes_SRS_SASLCLIENTIO_01_119: [If any error is encountered when parsing the received frame, the SASL client IO state shall be switched to IO_STATE_ERROR and the on_state_changed callback shall be triggered.] */ result = __LINE__; } else { /* Codes_SRS_SASLCLIENTIO_01_048: [The contents of this data are defined by the SASL security mechanism.] */ if (saslmechanism_get_init_bytes(sasl_client_io->sasl_mechanism, &init_bytes) != 0) { /* Codes_SRS_SASLCLIENTIO_01_119: [If any error is encountered when parsing the received frame, the SASL client IO state shall be switched to IO_STATE_ERROR and the on_state_changed callback shall be triggered.] */ result = __LINE__; } else { amqp_binary creds = { init_bytes.bytes, init_bytes.length }; if ((init_bytes.length > 0) && /* Codes_SRS_SASLCLIENTIO_01_047: [A block of opaque data passed to the security mechanism.] */ (sasl_init_set_initial_response(sasl_init, creds) != 0)) { /* Codes_SRS_SASLCLIENTIO_01_119: [If any error is encountered when parsing the received frame, the SASL client IO state shall be switched to IO_STATE_ERROR and the on_state_changed callback shall be triggered.] */ result = __LINE__; } else { AMQP_VALUE sasl_init_value = amqpvalue_create_sasl_init(sasl_init); if (sasl_init_value == NULL) { /* Codes_SRS_SASLCLIENTIO_01_119: [If any error is encountered when parsing the received frame, the SASL client IO state shall be switched to IO_STATE_ERROR and the on_state_changed callback shall be triggered.] */ result = __LINE__; } else { /* Codes_SRS_SASLCLIENTIO_01_070: [When a frame needs to be sent as part of the SASL handshake frame exchange, the send shall be done by calling sasl_frame_codec_encode_frame.] */ if (sasl_frame_codec_encode_frame(sasl_client_io->sasl_frame_codec, sasl_init_value, on_bytes_encoded, sasl_client_io) != 0) { /* Codes_SRS_SASLCLIENTIO_01_071: [If sasl_frame_codec_encode_frame fails, then the state of SASL client IO shall be switched to IO_STATE_ERROR and the on_state_changed callback shall be triggered.] */ result = __LINE__; } else { log_outgoing_frame(sasl_client_io, sasl_init_value); result = 0; } amqpvalue_destroy(sasl_init_value); } } } sasl_init_destroy(sasl_init); } return result; }
int main(int argc, char** argv) { int result; XIO_HANDLE sasl_io = NULL; CONNECTION_HANDLE connection = NULL; SESSION_HANDLE session = NULL; LINK_HANDLE link = NULL; MESSAGE_RECEIVER_HANDLE message_receiver = NULL; amqpalloc_set_memory_tracing_enabled(true); if (platform_init() != 0) { result = -1; } else { size_t last_memory_used = 0; /* create SASL plain handler */ SASL_PLAIN_CONFIG sasl_plain_config = { EH_KEY_NAME, EH_KEY, NULL }; SASL_MECHANISM_HANDLE sasl_mechanism_handle = saslmechanism_create(saslplain_get_interface(), &sasl_plain_config); XIO_HANDLE tls_io; /* create the TLS IO */ TLSIO_CONFIG tls_io_config = { EH_HOST, 5671 }; const IO_INTERFACE_DESCRIPTION* tlsio_interface = platform_get_default_tlsio(); tls_io = xio_create(tlsio_interface, &tls_io_config, NULL); /* create the SASL client IO using the TLS IO */ SASLCLIENTIO_CONFIG sasl_io_config = { tls_io, sasl_mechanism_handle }; sasl_io = xio_create(saslclientio_get_interface_description(), &sasl_io_config, NULL); /* create the connection, session and link */ connection = connection_create(sasl_io, EH_HOST, "whatever", NULL, NULL); session = session_create(connection, NULL, NULL); /* set incoming window to 100 for the session */ session_set_incoming_window(session, 100); AMQP_VALUE source = messaging_create_source("amqps://" EH_HOST "/ingress/ConsumerGroups/$Default/Partitions/0"); AMQP_VALUE target = messaging_create_target("ingress-rx"); link = link_create(session, "receiver-link", role_receiver, source, target); link_set_rcv_settle_mode(link, receiver_settle_mode_first); amqpvalue_destroy(source); amqpvalue_destroy(target); /* create a message receiver */ message_receiver = messagereceiver_create(link, NULL, NULL); if ((message_receiver == NULL) || (messagereceiver_open(message_receiver, on_message_received, message_receiver) != 0)) { result = -1; } else { while (true) { size_t current_memory_used; size_t maximum_memory_used; connection_dowork(connection); current_memory_used = amqpalloc_get_current_memory_used(); maximum_memory_used = amqpalloc_get_maximum_memory_used(); if (current_memory_used != last_memory_used) { printf("Current memory usage:%lu (max:%lu)\r\n", (unsigned long)current_memory_used, (unsigned long)maximum_memory_used); last_memory_used = current_memory_used; } } result = 0; } messagereceiver_destroy(message_receiver); link_destroy(link); session_destroy(session); connection_destroy(connection); platform_deinit(); printf("Max memory usage:%lu\r\n", (unsigned long)amqpalloc_get_maximum_memory_used()); printf("Current memory usage:%lu\r\n", (unsigned long)amqpalloc_get_current_memory_used()); #ifdef _CRTDBG_MAP_ALLOC _CrtDumpMemoryLeaks(); #endif } return result; }
int amqpmanagement_start_operation(AMQP_MANAGEMENT_HANDLE amqp_management, const char* operation, const char* type, const char* locales, MESSAGE_HANDLE message, ON_OPERATION_COMPLETE on_operation_complete, void* context) { int result; if ((amqp_management == NULL) || (operation == NULL)) { result = __LINE__; } else { AMQP_VALUE application_properties; if (message_get_application_properties(message, &application_properties) != 0) { result = __LINE__; } else { if ((add_string_key_value_pair_to_map(application_properties, "operation", operation) != 0) || (add_string_key_value_pair_to_map(application_properties, "type", type) != 0) || ((locales != NULL) && (add_string_key_value_pair_to_map(application_properties, "locales", locales) != 0))) { result = __LINE__; } else { if ((message_set_application_properties(message, application_properties) != 0) || (set_message_id(message, amqp_management->next_message_id) != 0)) { result = __LINE__; } else { OPERATION_MESSAGE_INSTANCE* pending_operation_message = amqpalloc_malloc(sizeof(OPERATION_MESSAGE_INSTANCE)); if (pending_operation_message == NULL) { result = __LINE__; } else { pending_operation_message->message = message_clone(message); pending_operation_message->callback_context = context; pending_operation_message->on_operation_complete = on_operation_complete; pending_operation_message->operation_state = OPERATION_STATE_NOT_SENT; pending_operation_message->message_id = amqp_management->next_message_id; amqp_management->next_message_id++; OPERATION_MESSAGE_INSTANCE** new_operation_messages = amqpalloc_realloc(amqp_management->operation_messages, (amqp_management->operation_message_count + 1) * sizeof(OPERATION_MESSAGE_INSTANCE*)); if (new_operation_messages == NULL) { message_destroy(message); amqpalloc_free(pending_operation_message); result = __LINE__; } else { amqp_management->operation_messages = new_operation_messages; amqp_management->operation_messages[amqp_management->operation_message_count] = pending_operation_message; amqp_management->operation_message_count++; if (send_operation_messages(amqp_management) != 0) { if (on_operation_complete != NULL) { on_operation_complete(context, OPERATION_RESULT_CBS_ERROR, 0, NULL); } result = __LINE__; } else { result = 0; } } } } } amqpvalue_destroy(application_properties); } } return result; }
AMQP_MANAGEMENT_HANDLE amqpmanagement_create(SESSION_HANDLE session, const char* management_node, ON_AMQP_MANAGEMENT_STATE_CHANGED on_amqp_management_state_changed, void* callback_context) { AMQP_MANAGEMENT_INSTANCE* result; if (session == NULL) { result = NULL; } else { result = (AMQP_MANAGEMENT_INSTANCE*)amqpalloc_malloc(sizeof(AMQP_MANAGEMENT_INSTANCE)); if (result != NULL) { result->session = session; result->sender_connected = 0; result->receiver_connected = 0; result->operation_message_count = 0; result->operation_messages = NULL; result->on_amqp_management_state_changed = on_amqp_management_state_changed; result->callback_context = callback_context; AMQP_VALUE source = messaging_create_source(management_node); if (source == NULL) { amqpalloc_free(result); result = NULL; } else { AMQP_VALUE target = messaging_create_target(management_node); if (target == NULL) { amqpalloc_free(result); result = NULL; } else { static const char* sender_suffix = "-sender"; char* sender_link_name = (char*)amqpalloc_malloc(strlen(management_node) + strlen(sender_suffix) + 1); if (sender_link_name == NULL) { result = NULL; } else { static const char* receiver_suffix = "-receiver"; (void)strcpy(sender_link_name, management_node); (void)strcat(sender_link_name, sender_suffix); char* receiver_link_name = (char*)amqpalloc_malloc(strlen(management_node) + strlen(receiver_suffix) + 1); if (receiver_link_name == NULL) { result = NULL; } else { (void)strcpy(receiver_link_name, management_node); (void)strcat(receiver_link_name, receiver_suffix); result->sender_link = link_create(session, "cbs-sender", role_sender, source, target); if (result->sender_link == NULL) { amqpalloc_free(result); result = NULL; } else { result->receiver_link = link_create(session, "cbs-receiver", role_receiver, source, target); if (result->receiver_link == NULL) { link_destroy(result->sender_link); amqpalloc_free(result); result = NULL; } else { if ((link_set_max_message_size(result->sender_link, 65535) != 0) || (link_set_max_message_size(result->receiver_link, 65535) != 0)) { link_destroy(result->sender_link); link_destroy(result->receiver_link); amqpalloc_free(result); result = NULL; } else { result->message_sender = messagesender_create(result->sender_link, on_message_sender_state_changed, result, NULL); if (result->message_sender == NULL) { link_destroy(result->sender_link); link_destroy(result->receiver_link); amqpalloc_free(result); result = NULL; } else { result->message_receiver = messagereceiver_create(result->receiver_link, on_message_receiver_state_changed, result); if (result->message_receiver == NULL) { messagesender_destroy(result->message_sender); link_destroy(result->sender_link); link_destroy(result->receiver_link); amqpalloc_free(result); result = NULL; } else { result->next_message_id = 0; } } } } } amqpalloc_free(receiver_link_name); } amqpalloc_free(sender_link_name); } amqpvalue_destroy(target); } amqpvalue_destroy(source); } } } return result; }
int main(int argc, char** argv) { int result; (void)argc, argv; amqpalloc_set_memory_tracing_enabled(true); if (platform_init() != 0) { result = -1; } else { CONNECTION_HANDLE connection; SESSION_HANDLE session; LINK_HANDLE link; MESSAGE_SENDER_HANDLE message_sender; MESSAGE_HANDLE message; size_t last_memory_used = 0; /* create socket IO */ XIO_HANDLE socket_io; SOCKETIO_CONFIG socketio_config = { "localhost", 5672, NULL }; socket_io = xio_create(socketio_get_interface_description(), &socketio_config); /* create the connection, session and link */ connection = connection_create(socket_io, "localhost", "some", NULL, NULL); session = session_create(connection, NULL, NULL); session_set_incoming_window(session, 2147483647); session_set_outgoing_window(session, 65536); AMQP_VALUE source = messaging_create_source("ingress"); AMQP_VALUE target = messaging_create_target("localhost/ingress"); link = link_create(session, "sender-link", role_sender, source, target); link_set_snd_settle_mode(link, sender_settle_mode_settled); (void)link_set_max_message_size(link, 65536); amqpvalue_destroy(source); amqpvalue_destroy(target); message = message_create(); unsigned char hello[] = { 'H', 'e', 'l', 'l', 'o' }; BINARY_DATA binary_data; binary_data.bytes = hello; binary_data.length = sizeof(hello); message_add_body_amqp_data(message, binary_data); /* create a message sender */ message_sender = messagesender_create(link, NULL, NULL); if (messagesender_open(message_sender) == 0) { uint32_t i; #if _WIN32 unsigned long startTime = (unsigned long)GetTickCount64(); #endif for (i = 0; i < msg_count; i++) { (void)messagesender_send(message_sender, message, on_message_send_complete, message); } message_destroy(message); while (true) { size_t current_memory_used; size_t maximum_memory_used; connection_dowork(connection); current_memory_used = amqpalloc_get_current_memory_used(); maximum_memory_used = amqpalloc_get_maximum_memory_used(); if (current_memory_used != last_memory_used) { (void)printf("Current memory usage:%lu (max:%lu)\r\n", (unsigned long)current_memory_used, (unsigned long)maximum_memory_used); last_memory_used = current_memory_used; } if (sent_messages == msg_count) { break; } } #if _WIN32 unsigned long endTime = (unsigned long)GetTickCount64(); (void)printf("Send %zu messages in %lu ms: %.02f msgs/sec\r\n", msg_count, (endTime - startTime), (float)msg_count / ((float)(endTime - startTime) / 1000)); #endif } messagesender_destroy(message_sender); link_destroy(link); session_destroy(session); connection_destroy(connection); xio_destroy(socket_io); platform_deinit(); (void)printf("Max memory usage:%lu\r\n", (unsigned long)amqpalloc_get_maximum_memory_used()); (void)printf("Current memory usage:%lu\r\n", (unsigned long)amqpalloc_get_current_memory_used()); result = 0; } #ifdef _CRTDBG_MAP_ALLOC _CrtDumpMemoryLeaks(); #endif return result; }
static void sasl_frame_received_callback(void* context, AMQP_VALUE sasl_frame) { SASL_CLIENT_IO_INSTANCE* sasl_client_io_instance = (SASL_CLIENT_IO_INSTANCE*)context; /* Codes_SRS_SASLCLIENTIO_01_067: [The SASL frame exchange shall be started as soon as the SASL header handshake is done.] */ switch (sasl_client_io_instance->io_state) { default: break; case IO_STATE_OPEN: case IO_STATE_OPENING_UNDERLYING_IO: case IO_STATE_CLOSING: /* Codes_SRS_SASLCLIENTIO_01_117: [If on_sasl_frame_received_callback is called when the state of the IO is OPEN then the SASL client IO state shall be switched to IO_STATE_ERROR and the on_state_changed callback shall be triggered.] */ handle_error(sasl_client_io_instance); break; case IO_STATE_SASL_HANDSHAKE: if (sasl_client_io_instance->sasl_header_exchange_state != SASL_HEADER_EXCHANGE_HEADER_EXCH) { /* Codes_SRS_SASLCLIENTIO_01_118: [If on_sasl_frame_received_callback is called in the OPENING state but the header exchange has not yet been completed, then the SASL client IO state shall be switched to IO_STATE_ERROR and the on_state_changed callback shall be triggered.] */ handle_error(sasl_client_io_instance); } else { AMQP_VALUE descriptor = amqpvalue_get_inplace_descriptor(sasl_frame); if (descriptor == NULL) { /* Codes_SRS_SASLCLIENTIO_01_119: [If any error is encountered when parsing the received frame, the SASL client IO state shall be switched to IO_STATE_ERROR and the on_state_changed callback shall be triggered.] */ handle_error(sasl_client_io_instance); } else { log_incoming_frame(sasl_client_io_instance, sasl_frame); /* Codes_SRS_SASLCLIENTIO_01_032: [The peer acting as the SASL server MUST announce supported authentication mechanisms using the sasl-mechanisms frame.] */ /* Codes_SRS_SASLCLIENTIO_01_040: [The peer playing the role of the SASL client and the peer playing the role of the SASL server MUST correspond to the TCP client and server respectively.] */ /* Codes_SRS_SASLCLIENTIO_01_034: [<-- SASL-MECHANISMS] */ if (is_sasl_mechanisms_type_by_descriptor(descriptor)) { switch (sasl_client_io_instance->sasl_client_negotiation_state) { case SASL_CLIENT_NEGOTIATION_NOT_STARTED: { SASL_MECHANISMS_HANDLE sasl_mechanisms_handle; if (amqpvalue_get_sasl_mechanisms(sasl_frame, &sasl_mechanisms_handle) != 0) { /* Codes_SRS_SASLCLIENTIO_01_119: [If any error is encountered when parsing the received frame, the SASL client IO state shall be switched to IO_STATE_ERROR and the on_state_changed callback shall be triggered.] */ handle_error(sasl_client_io_instance); } else { AMQP_VALUE sasl_server_mechanisms; uint32_t mechanisms_count; if ((sasl_mechanisms_get_sasl_server_mechanisms(sasl_mechanisms_handle, &sasl_server_mechanisms) != 0) || (amqpvalue_get_array_item_count(sasl_server_mechanisms, &mechanisms_count) != 0) || (mechanisms_count == 0)) { /* Codes_SRS_SASLCLIENTIO_01_042: [It is invalid for this list to be null or empty.] */ handle_error(sasl_client_io_instance); } else { const char* sasl_mechanism_name = saslmechanism_get_mechanism_name(sasl_client_io_instance->sasl_mechanism); if (sasl_mechanism_name == NULL) { /* Codes_SRS_SASLCLIENTIO_01_119: [If any error is encountered when parsing the received frame, the SASL client IO state shall be switched to IO_STATE_ERROR and the on_state_changed callback shall be triggered.] */ handle_error(sasl_client_io_instance); } else { uint32_t i; for (i = 0; i < mechanisms_count; i++) { AMQP_VALUE sasl_server_mechanism; sasl_server_mechanism = amqpvalue_get_array_item(sasl_server_mechanisms, i); if (sasl_server_mechanism == NULL) { i = mechanisms_count; } else { const char* sasl_server_mechanism_name; if (amqpvalue_get_symbol(sasl_server_mechanism, &sasl_server_mechanism_name) != 0) { i = mechanisms_count; } else { if (strcmp(sasl_mechanism_name, sasl_server_mechanism_name) == 0) { amqpvalue_destroy(sasl_server_mechanism); break; } } amqpvalue_destroy(sasl_server_mechanism); } } if (i == mechanisms_count) { /* Codes_SRS_SASLCLIENTIO_01_119: [If any error is encountered when parsing the received frame, the SASL client IO state shall be switched to IO_STATE_ERROR and the on_state_changed callback shall be triggered.] */ handle_error(sasl_client_io_instance); } else { sasl_client_io_instance->sasl_client_negotiation_state = SASL_CLIENT_NEGOTIATION_MECH_RCVD; /* Codes_SRS_SASLCLIENTIO_01_035: [SASL-INIT -->] */ /* Codes_SRS_SASLCLIENTIO_01_033: [The partner MUST then choose one of the supported mechanisms and initiate a sasl exchange.] */ /* Codes_SRS_SASLCLIENTIO_01_054: [Selects the sasl mechanism and provides the initial response if needed.] */ if (send_sasl_init(sasl_client_io_instance, sasl_mechanism_name) != 0) { /* Codes_SRS_SASLCLIENTIO_01_119: [If any error is encountered when parsing the received frame, the SASL client IO state shall be switched to IO_STATE_ERROR and the on_state_changed callback shall be triggered.] */ handle_error(sasl_client_io_instance); } else { sasl_client_io_instance->sasl_client_negotiation_state = SASL_CLIENT_NEGOTIATION_INIT_SENT; } } } } sasl_mechanisms_destroy(sasl_mechanisms_handle); } break; } } } /* Codes_SRS_SASLCLIENTIO_01_052: [Send the SASL challenge data as defined by the SASL specification.] */ /* Codes_SRS_SASLCLIENTIO_01_036: [<-- SASL-CHALLENGE *] */ /* Codes_SRS_SASLCLIENTIO_01_039: [the SASL challenge/response step can occur zero or more times depending on the details of the SASL mechanism chosen.] */ else if (is_sasl_challenge_type_by_descriptor(descriptor)) { /* Codes_SRS_SASLCLIENTIO_01_032: [The peer acting as the SASL server MUST announce supported authentication mechanisms using the sasl-mechanisms frame.] */ if ((sasl_client_io_instance->sasl_client_negotiation_state != SASL_CLIENT_NEGOTIATION_INIT_SENT) && (sasl_client_io_instance->sasl_client_negotiation_state != SASL_CLIENT_NEGOTIATION_RESPONSE_SENT)) { handle_error(sasl_client_io_instance); } else { SASL_CHALLENGE_HANDLE sasl_challenge_handle; if (amqpvalue_get_sasl_challenge(sasl_frame, &sasl_challenge_handle) != 0) { /* Codes_SRS_SASLCLIENTIO_01_119: [If any error is encountered when parsing the received frame, the SASL client IO state shall be switched to IO_STATE_ERROR and the on_state_changed callback shall be triggered.] */ handle_error(sasl_client_io_instance); } else { amqp_binary challenge_binary_value; SASL_MECHANISM_BYTES response_bytes; /* Codes_SRS_SASLCLIENTIO_01_053: [Challenge information, a block of opaque binary data passed to the security mechanism.] */ if (sasl_challenge_get_challenge(sasl_challenge_handle, &challenge_binary_value) != 0) { /* Codes_SRS_SASLCLIENTIO_01_119: [If any error is encountered when parsing the received frame, the SASL client IO state shall be switched to IO_STATE_ERROR and the on_state_changed callback shall be triggered.] */ handle_error(sasl_client_io_instance); } else { SASL_MECHANISM_BYTES challenge = { challenge_binary_value.bytes, challenge_binary_value.length }; /* Codes_SRS_SASLCLIENTIO_01_057: [The contents of this data are defined by the SASL security mechanism.] */ /* Codes_SRS_SASLCLIENTIO_01_037: [SASL-RESPONSE -->] */ if ((saslmechanism_challenge(sasl_client_io_instance->sasl_mechanism, &challenge, &response_bytes) != 0) || (send_sasl_response(sasl_client_io_instance, response_bytes) != 0)) { /* Codes_SRS_SASLCLIENTIO_01_119: [If any error is encountered when parsing the received frame, the SASL client IO state shall be switched to IO_STATE_ERROR and the on_state_changed callback shall be triggered.] */ handle_error(sasl_client_io_instance); } } sasl_challenge_destroy(sasl_challenge_handle); } } } /* Codes_SRS_SASLCLIENTIO_01_058: [This frame indicates the outcome of the SASL dialog.] */ /* Codes_SRS_SASLCLIENTIO_01_038: [<-- SASL-OUTCOME] */ else if (is_sasl_outcome_type_by_descriptor(descriptor)) { /* Codes_SRS_SASLCLIENTIO_01_032: [The peer acting as the SASL server MUST announce supported authentication mechanisms using the sasl-mechanisms frame.] */ if ((sasl_client_io_instance->sasl_client_negotiation_state != SASL_CLIENT_NEGOTIATION_INIT_SENT) && (sasl_client_io_instance->sasl_client_negotiation_state != SASL_CLIENT_NEGOTIATION_RESPONSE_SENT)) { handle_error(sasl_client_io_instance); } else { SASL_OUTCOME_HANDLE sasl_outcome; sasl_client_io_instance->sasl_client_negotiation_state = SASL_CLIENT_NEGOTIATION_OUTCOME_RCVD; if (amqpvalue_get_sasl_outcome(sasl_frame, &sasl_outcome) != 0) { handle_error(sasl_client_io_instance); } else { sasl_code sasl_code; /* Codes_SRS_SASLCLIENTIO_01_060: [A reply-code indicating the outcome of the SASL dialog.] */ if (sasl_outcome_get_code(sasl_outcome, &sasl_code) != 0) { handle_error(sasl_client_io_instance); } else { switch (sasl_code) { default: case sasl_code_auth: /* Codes_SRS_SASLCLIENTIO_01_063: [1 Connection authentication failed due to an unspecified problem with the supplied credentials.] */ case sasl_code_sys: /* Codes_SRS_SASLCLIENTIO_01_064: [2 Connection authentication failed due to a system error.] */ case sasl_code_sys_perm: /* Codes_SRS_SASLCLIENTIO_01_065: [3 Connection authentication failed due to a system error that is unlikely to be corrected without intervention.] */ case sasl_code_sys_temp: /* Codes_SRS_SASLCLIENTIO_01_066: [4 Connection authentication failed due to a transient system error.] */ handle_error(sasl_client_io_instance); break; case sasl_code_ok: /* Codes_SRS_SASLCLIENTIO_01_059: [Upon successful completion of the SASL dialog the security layer has been established] */ /* Codes_SRS_SASLCLIENTIO_01_062: [0 Connection authentication succeeded.] */ sasl_client_io_instance->io_state = IO_STATE_OPEN; indicate_open_complete(sasl_client_io_instance, IO_OPEN_OK); break; } } sasl_outcome_destroy(sasl_outcome); } } } else { LOG(sasl_client_io_instance->logger_log, LOG_LINE, "Bad SASL frame"); } } } break; } }
static AMQP_VALUE on_message_received(const void* context, MESSAGE_HANDLE message) { AMQP_MANAGEMENT_INSTANCE* amqp_management_instance = (AMQP_MANAGEMENT_INSTANCE*)context; AMQP_VALUE application_properties; if (message_get_application_properties(message, &application_properties) != 0) { /* error */ } else { PROPERTIES_HANDLE response_properties; if (message_get_properties(message, &response_properties) != 0) { /* error */ } else { AMQP_VALUE key; AMQP_VALUE value; AMQP_VALUE map; AMQP_VALUE correlation_id_value; if (properties_get_correlation_id(response_properties, &correlation_id_value) != 0) { /* error */ } else { map = amqpvalue_get_inplace_described_value(application_properties); if (map == NULL) { /* error */ } else { key = amqpvalue_create_string("status-code"); if (key == NULL) { /* error */ } else { value = amqpvalue_get_map_value(map, key); if (value == NULL) { /* error */ } else { int32_t status_code; if (amqpvalue_get_int(value, &status_code) != 0) { /* error */ } else { size_t i = 0; while (i < amqp_management_instance->operation_message_count) { if (amqp_management_instance->operation_messages[i]->operation_state == OPERATION_STATE_AWAIT_REPLY) { AMQP_VALUE expected_message_id = amqpvalue_create_ulong(amqp_management_instance->operation_messages[i]->message_id); OPERATION_RESULT operation_result; if (expected_message_id == NULL) { break; } else { if (amqpvalue_are_equal(correlation_id_value, expected_message_id)) { /* 202 is not mentioned in the draft in any way, this is a workaround for an EH bug for now */ if ((status_code != 200) && (status_code != 202)) { operation_result = OPERATION_RESULT_OPERATION_FAILED; } else { operation_result = OPERATION_RESULT_OK; } amqp_management_instance->operation_messages[i]->on_operation_complete(amqp_management_instance->operation_messages[i]->callback_context, operation_result, 0, NULL); remove_operation_message_by_index(amqp_management_instance, i); amqpvalue_destroy(expected_message_id); break; } amqpvalue_destroy(expected_message_id); } } } } amqpvalue_destroy(value); } amqpvalue_destroy(key); } } } properties_destroy(response_properties); } application_properties_destroy(application_properties); } return messaging_delivery_accepted(); }
static SEND_ONE_MESSAGE_RESULT send_one_message(MESSAGE_SENDER_INSTANCE* message_sender_instance, MESSAGE_WITH_CALLBACK* message_with_callback, MESSAGE_HANDLE message) { SEND_ONE_MESSAGE_RESULT result; size_t encoded_size; size_t total_encoded_size = 0; MESSAGE_BODY_TYPE message_body_type; message_format message_format; if ((message_get_body_type(message, &message_body_type) != 0) || (message_get_message_format(message, &message_format) != 0)) { result = SEND_ONE_MESSAGE_ERROR; } else { // header HEADER_HANDLE header; AMQP_VALUE header_amqp_value; PROPERTIES_HANDLE properties; AMQP_VALUE properties_amqp_value; AMQP_VALUE application_properties; AMQP_VALUE application_properties_value; AMQP_VALUE body_amqp_value = NULL; size_t body_data_count; message_get_header(message, &header); header_amqp_value = amqpvalue_create_header(header); if (header != NULL) { amqpvalue_get_encoded_size(header_amqp_value, &encoded_size); total_encoded_size += encoded_size; } // properties message_get_properties(message, &properties); properties_amqp_value = amqpvalue_create_properties(properties); if (properties != NULL) { amqpvalue_get_encoded_size(properties_amqp_value, &encoded_size); total_encoded_size += encoded_size; } // application properties message_get_application_properties(message, &application_properties); application_properties_value = amqpvalue_create_application_properties(application_properties); if (application_properties != NULL) { amqpvalue_get_encoded_size(application_properties_value, &encoded_size); total_encoded_size += encoded_size; } result = SEND_ONE_MESSAGE_OK; // body - amqp data switch (message_body_type) { default: result = SEND_ONE_MESSAGE_ERROR; break; case MESSAGE_BODY_TYPE_VALUE: { AMQP_VALUE message_body_amqp_value; if (message_get_inplace_body_amqp_value(message, &message_body_amqp_value) != 0) { result = SEND_ONE_MESSAGE_ERROR; } else { body_amqp_value = amqpvalue_create_amqp_value(message_body_amqp_value); if ((body_amqp_value == NULL) || (amqpvalue_get_encoded_size(body_amqp_value, &encoded_size) != 0)) { result = SEND_ONE_MESSAGE_ERROR; } else { total_encoded_size += encoded_size; } } break; } case MESSAGE_BODY_TYPE_DATA: { BINARY_DATA binary_data; size_t i; if (message_get_body_amqp_data_count(message, &body_data_count) != 0) { result = SEND_ONE_MESSAGE_ERROR; } else { for (i = 0; i < body_data_count; i++) { if (message_get_body_amqp_data(message, i, &binary_data) != 0) { result = SEND_ONE_MESSAGE_ERROR; } else { amqp_binary binary_value = { binary_data.bytes, binary_data.length }; AMQP_VALUE body_amqp_data = amqpvalue_create_data(binary_value); if (body_amqp_data == NULL) { result = SEND_ONE_MESSAGE_ERROR; } else { if (amqpvalue_get_encoded_size(body_amqp_data, &encoded_size) != 0) { result = SEND_ONE_MESSAGE_ERROR; } else { total_encoded_size += encoded_size; } amqpvalue_destroy(body_amqp_data); } } } } break; } } if (result == 0) { void* data_bytes = amqpalloc_malloc(total_encoded_size); PAYLOAD payload = { data_bytes, 0 }; result = SEND_ONE_MESSAGE_OK; if (header != NULL) { if (amqpvalue_encode(header_amqp_value, encode_bytes, &payload) != 0) { result = SEND_ONE_MESSAGE_ERROR; } log_message_chunk(message_sender_instance, "Header:", header_amqp_value); } if ((result == SEND_ONE_MESSAGE_OK) && (properties != NULL)) { if (amqpvalue_encode(properties_amqp_value, encode_bytes, &payload) != 0) { result = SEND_ONE_MESSAGE_ERROR; } log_message_chunk(message_sender_instance, "Properties:", properties_amqp_value); } if ((result == SEND_ONE_MESSAGE_OK) && (application_properties != NULL)) { if (amqpvalue_encode(application_properties_value, encode_bytes, &payload) != 0) { result = SEND_ONE_MESSAGE_ERROR; } log_message_chunk(message_sender_instance, "Application properties:", application_properties_value); } if (result == SEND_ONE_MESSAGE_OK) { switch (message_body_type) { case MESSAGE_BODY_TYPE_VALUE: { if (amqpvalue_encode(body_amqp_value, encode_bytes, &payload) != 0) { result = SEND_ONE_MESSAGE_ERROR; } log_message_chunk(message_sender_instance, "Body - amqp value:", body_amqp_value); break; } case MESSAGE_BODY_TYPE_DATA: { BINARY_DATA binary_data; size_t i; for (i = 0; i < body_data_count; i++) { if (message_get_body_amqp_data(message, i, &binary_data) != 0) { result = SEND_ONE_MESSAGE_ERROR; } else { amqp_binary binary_value = { binary_data.bytes, binary_data.length }; AMQP_VALUE body_amqp_data = amqpvalue_create_data(binary_value); if (body_amqp_data == NULL) { result = SEND_ONE_MESSAGE_ERROR; } else { if (amqpvalue_encode(body_amqp_data, encode_bytes, &payload) != 0) { result = SEND_ONE_MESSAGE_ERROR; break; } amqpvalue_destroy(body_amqp_data); } } } break; } } } if (result == SEND_ONE_MESSAGE_OK) { message_with_callback->message_send_state = MESSAGE_SEND_STATE_PENDING; switch (link_transfer(message_sender_instance->link, message_format, &payload, 1, on_delivery_settled, message_with_callback)) { default: case LINK_TRANSFER_ERROR: if (message_with_callback->on_message_send_complete != NULL) { message_with_callback->on_message_send_complete(message_with_callback->context, MESSAGE_SEND_ERROR); } result = SEND_ONE_MESSAGE_ERROR; break; case LINK_TRANSFER_BUSY: message_with_callback->message_send_state = MESSAGE_SEND_STATE_NOT_SENT; result = SEND_ONE_MESSAGE_BUSY; break; case LINK_TRANSFER_OK: result = SEND_ONE_MESSAGE_OK; break; } } amqpalloc_free(data_bytes); if (body_amqp_value != NULL) { amqpvalue_destroy(body_amqp_value); } amqpvalue_destroy(application_properties); amqpvalue_destroy(application_properties_value); amqpvalue_destroy(properties_amqp_value); properties_destroy(properties); } } return result; }
int main(int argc, char** argv) { int result; (void)argc, argv; amqpalloc_set_memory_tracing_enabled(true); if (platform_init() != 0) { result = -1; } else { XIO_HANDLE sasl_io; CONNECTION_HANDLE connection; SESSION_HANDLE session; LINK_HANDLE link; MESSAGE_SENDER_HANDLE message_sender; MESSAGE_HANDLE message; size_t last_memory_used = 0; /* create SASL PLAIN handler */ SASL_PLAIN_CONFIG sasl_plain_config = { EH_KEY_NAME, EH_KEY, NULL }; SASL_MECHANISM_HANDLE sasl_mechanism_handle = saslmechanism_create(saslplain_get_interface(), &sasl_plain_config); XIO_HANDLE tls_io; /* create the TLS IO */ TLSIO_CONFIG tls_io_config = { EH_HOST, 5671 }; const IO_INTERFACE_DESCRIPTION* tlsio_interface = platform_get_default_tlsio(); tls_io = xio_create(tlsio_interface, &tls_io_config); /* create the SASL client IO using the TLS IO */ SASLCLIENTIO_CONFIG sasl_io_config; sasl_io_config.underlying_io = tls_io; sasl_io_config.sasl_mechanism = sasl_mechanism_handle; sasl_io = xio_create(saslclientio_get_interface_description(), &sasl_io_config); /* create the connection, session and link */ connection = connection_create(sasl_io, EH_HOST, "some", NULL, NULL); session = session_create(connection, NULL, NULL); session_set_incoming_window(session, 2147483647); session_set_outgoing_window(session, 65536); AMQP_VALUE source = messaging_create_source("ingress"); AMQP_VALUE target = messaging_create_target("amqps://" EH_HOST "/" EH_NAME); link = link_create(session, "sender-link", role_sender, source, target); link_set_snd_settle_mode(link, sender_settle_mode_unsettled); (void)link_set_max_message_size(link, 65536); amqpvalue_destroy(source); amqpvalue_destroy(target); message = message_create(); unsigned char hello[] = { 'H', 'e', 'l', 'l', 'o' }; BINARY_DATA binary_data; binary_data.bytes = hello; binary_data.length = sizeof(hello); message_add_body_amqp_data(message, binary_data); /* create a message sender */ message_sender = messagesender_create(link, NULL, NULL); if (messagesender_open(message_sender) == 0) { uint32_t i; #if _WIN32 unsigned long startTime = (unsigned long)GetTickCount64(); #endif for (i = 0; i < msg_count; i++) { (void)messagesender_send(message_sender, message, on_message_send_complete, message); } message_destroy(message); while (true) { size_t current_memory_used; size_t maximum_memory_used; connection_dowork(connection); current_memory_used = amqpalloc_get_current_memory_used(); maximum_memory_used = amqpalloc_get_maximum_memory_used(); if (current_memory_used != last_memory_used) { (void)printf("Current memory usage:%lu (max:%lu)\r\n", (unsigned long)current_memory_used, (unsigned long)maximum_memory_used); last_memory_used = current_memory_used; } if (sent_messages == msg_count) { break; } } #if _WIN32 unsigned long endTime = (unsigned long)GetTickCount64(); (void)printf("Send %zu messages in %lu ms: %.02f msgs/sec\r\n", msg_count, (endTime - startTime), (float)msg_count / ((float)(endTime - startTime) / 1000)); #endif } messagesender_destroy(message_sender); link_destroy(link); session_destroy(session); connection_destroy(connection); xio_destroy(sasl_io); xio_destroy(tls_io); saslmechanism_destroy(sasl_mechanism_handle); platform_deinit(); (void)printf("Max memory usage:%lu\r\n", (unsigned long)amqpalloc_get_maximum_memory_used()); (void)printf("Current memory usage:%lu\r\n", (unsigned long)amqpalloc_get_current_memory_used()); result = 0; } #ifdef _CRTDBG_MAP_ALLOC _CrtDumpMemoryLeaks(); #endif return result; }
int main(int argc, char** argv) { int result; (void)argc; (void)argv; if (platform_init() != 0) { result = -1; } else { XIO_HANDLE sasl_io; CONNECTION_HANDLE connection; SESSION_HANDLE session; LINK_HANDLE link; MESSAGE_SENDER_HANDLE message_sender; MESSAGE_HANDLE message; size_t last_memory_used = 0; /* create SASL PLAIN handler */ SASL_MECHANISM_HANDLE sasl_mechanism_handle = saslmechanism_create(saslmssbcbs_get_interface(), NULL); XIO_HANDLE tls_io; STRING_HANDLE sas_key_name; STRING_HANDLE sas_key_value; STRING_HANDLE resource_uri; STRING_HANDLE encoded_resource_uri; STRING_HANDLE sas_token; BUFFER_HANDLE buffer; TLSIO_CONFIG tls_io_config = { EH_HOST, 5671 }; const IO_INTERFACE_DESCRIPTION* tlsio_interface; SASLCLIENTIO_CONFIG sasl_io_config; time_t currentTime; size_t expiry_time; CBS_HANDLE cbs; AMQP_VALUE source; AMQP_VALUE target; unsigned char hello[] = { 'H', 'e', 'l', 'l', 'o' }; BINARY_DATA binary_data; gballoc_init(); /* create the TLS IO */ tlsio_interface = platform_get_default_tlsio(); tls_io = xio_create(tlsio_interface, &tls_io_config); /* create the SASL client IO using the TLS IO */ sasl_io_config.underlying_io = tls_io; sasl_io_config.sasl_mechanism = sasl_mechanism_handle; sasl_io = xio_create(saslclientio_get_interface_description(), &sasl_io_config); /* create the connection, session and link */ connection = connection_create(sasl_io, EH_HOST, "some", NULL, NULL); session = session_create(connection, NULL, NULL); session_set_incoming_window(session, 2147483647); session_set_outgoing_window(session, 65536); /* Construct a SAS token */ sas_key_name = STRING_construct(EH_KEY_NAME); /* unfortunately SASToken wants an encoded key - this should be fixed at a later time */ buffer = BUFFER_create((unsigned char*)EH_KEY, strlen(EH_KEY)); sas_key_value = Base64_Encoder(buffer); BUFFER_delete(buffer); resource_uri = STRING_construct("sb://" EH_HOST "/" EH_NAME "/publishers/" EH_PUBLISHER); encoded_resource_uri = URL_EncodeString(STRING_c_str(resource_uri)); /* Make a token that expires in one hour */ currentTime = time(NULL); expiry_time = (size_t)(difftime(currentTime, 0) + 3600); sas_token = SASToken_Create(sas_key_value, encoded_resource_uri, sas_key_name, expiry_time); cbs = cbs_create(session); if (cbs_open_async(cbs, on_cbs_open_complete, cbs, on_cbs_error, cbs) == 0) { (void)cbs_put_token_async(cbs, "servicebus.windows.net:sastoken", "sb://" EH_HOST "/" EH_NAME "/publishers/" EH_PUBLISHER, STRING_c_str(sas_token), on_cbs_put_token_complete, cbs); while (!auth) { size_t current_memory_used; size_t maximum_memory_used; connection_dowork(connection); current_memory_used = gballoc_getCurrentMemoryUsed(); maximum_memory_used = gballoc_getMaximumMemoryUsed(); if (current_memory_used != last_memory_used) { (void)printf("Current memory usage:%lu (max:%lu)\r\n", (unsigned long)current_memory_used, (unsigned long)maximum_memory_used); last_memory_used = current_memory_used; } } } STRING_delete(sas_token); STRING_delete(sas_key_name); STRING_delete(sas_key_value); STRING_delete(resource_uri); STRING_delete(encoded_resource_uri); source = messaging_create_source("ingress"); target = messaging_create_target("amqps://" EH_HOST "/" EH_NAME); link = link_create(session, "sender-link", role_sender, source, target); link_set_snd_settle_mode(link, sender_settle_mode_settled); (void)link_set_max_message_size(link, 65536); amqpvalue_destroy(source); amqpvalue_destroy(target); message = message_create(); binary_data.bytes = hello; binary_data.length = sizeof(hello); message_add_body_amqp_data(message, binary_data); /* create a message sender */ message_sender = messagesender_create(link, NULL, NULL); if (messagesender_open(message_sender) == 0) { uint32_t i; bool keep_running = true; tickcounter_ms_t start_time; TICK_COUNTER_HANDLE tick_counter = tickcounter_create(); if (tickcounter_get_current_ms(tick_counter, &start_time) != 0) { (void)printf("Error getting start time\r\n"); } else { for (i = 0; i < msg_count; i++) { (void)messagesender_send(message_sender, message, on_message_send_complete, message); } message_destroy(message); while (keep_running) { size_t current_memory_used; size_t maximum_memory_used; connection_dowork(connection); current_memory_used = gballoc_getCurrentMemoryUsed(); maximum_memory_used = gballoc_getMaximumMemoryUsed(); if (current_memory_used != last_memory_used) { (void)printf("Current memory usage:%lu (max:%lu)\r\n", (unsigned long)current_memory_used, (unsigned long)maximum_memory_used); last_memory_used = current_memory_used; } if (sent_messages == msg_count) { break; } } { tickcounter_ms_t end_time; if (tickcounter_get_current_ms(tick_counter, &end_time) != 0) { (void)printf("Error getting end time\r\n"); } else { (void)printf("Send %u messages in %lu ms: %.02f msgs/sec\r\n", (unsigned int)msg_count, (unsigned long)(end_time - start_time), (float)msg_count / ((float)(end_time - start_time) / 1000)); } } } } messagesender_destroy(message_sender); link_destroy(link); session_destroy(session); connection_destroy(connection); xio_destroy(sasl_io); xio_destroy(tls_io); saslmechanism_destroy(sasl_mechanism_handle); platform_deinit(); (void)printf("Max memory usage:%lu\r\n", (unsigned long)gballoc_getCurrentMemoryUsed()); (void)printf("Current memory usage:%lu\r\n", (unsigned long)gballoc_getMaximumMemoryUsed()); gballoc_deinit(); result = 0; } return result; }