Example #1
0
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;
}
Example #2
0
void write_actions(void **state)
{
    struct flow *fl = flow_new();
    struct instruction_set is;
    instruction_set_init(&is);
    set_eth_type(fl, 0x800);
    struct write_actions wa;
    struct action_set as;
    struct action gen_act;
    action_set_init(&as);
    action_output(&gen_act, 2);
    action_set_add(&as, gen_act);
    inst_write_actions(&wa, as);
    add_write_actions(&is, wa);
    flow_add_instructions(fl, is);
    assert_int_equal(fl->insts.active, INSTRUCTION_WRITE_ACTIONS);
    unsigned int actions_num;
    actions_num = HASH_COUNT(fl->insts.write_act.actions.actions);
    assert_int_equal(actions_num, 1);
    flow_destroy(fl);
}
Example #3
0
void apply_actions(void **state)
{
    struct flow *fl = flow_new();
    struct instruction_set is;
    instruction_set_init(&is);
    set_eth_type(fl, 0x800);
    struct apply_actions aa;
    struct action_list al;
    struct action gen_act;
    action_list_init(&al);
    action_output(&gen_act, 2);
    action_list_add(&al, gen_act);
    action_set_field_u16(&gen_act, SET_IP_PROTO, 6);
    action_list_add(&al, gen_act);
    inst_apply_actions(&aa, al);
    add_apply_actions(&is, aa);
    flow_add_instructions(fl, is);
    assert_int_equal(fl->insts.active, INSTRUCTION_APPLY_ACTIONS);
    int count = 0;
    struct action_list_elem *elem;
    LL_COUNT(fl->insts.apply_act.actions.actions, elem, count);
    assert_int_equal(count, 2);
    flow_destroy(fl);
}
Example #4
0
static void on_frame_received(void* context, AMQP_VALUE performative, uint32_t payload_size, const unsigned char* payload_bytes)
{
	SESSION_INSTANCE* session_instance = (SESSION_INSTANCE*)context;
	AMQP_VALUE descriptor = amqpvalue_get_inplace_descriptor(performative);

	if (is_begin_type_by_descriptor(descriptor))
	{
		BEGIN_HANDLE begin_handle;

		if (amqpvalue_get_begin(performative, &begin_handle) != 0)
		{
			connection_close(session_instance->connection, "amqp:decode-error", "Cannot decode BEGIN frame");
		}
		else
		{
			if ((begin_get_incoming_window(begin_handle, &session_instance->remote_incoming_window) != 0) ||
				(begin_get_next_outgoing_id(begin_handle, &session_instance->next_incoming_id) != 0))
			{
				/* error */
				begin_destroy(begin_handle);
				session_set_state(session_instance, SESSION_STATE_DISCARDING);
				connection_close(session_instance->connection, "amqp:decode-error", "Cannot get incoming windows and next outgoing id");
			}
			else
			{
				begin_destroy(begin_handle);

				if (session_instance->session_state == SESSION_STATE_BEGIN_SENT)
				{
					session_set_state(session_instance, SESSION_STATE_MAPPED);
				}
				else if(session_instance->session_state == SESSION_STATE_UNMAPPED)
				{
					session_set_state(session_instance, SESSION_STATE_BEGIN_RCVD);
					if (send_begin(session_instance) != 0)
					{
						connection_close(session_instance->connection, "amqp:internal-error", "Failed sending BEGIN frame");
						session_set_state(session_instance, SESSION_STATE_DISCARDING);
					}
					else
					{
						session_set_state(session_instance, SESSION_STATE_MAPPED);
					}
				}
			}
		}
	}
	else if (is_attach_type_by_descriptor(descriptor))
	{
		const char* name = NULL;
		ATTACH_HANDLE attach_handle;

		if (amqpvalue_get_attach(performative, &attach_handle) != 0)
		{
			end_session_with_error(session_instance, "amqp:decode-error", "Cannot decode ATTACH frame");
		}
		else
		{
			role role;
			AMQP_VALUE source;
			AMQP_VALUE target;

			if ((attach_get_name(attach_handle, &name) != 0) ||
				(attach_get_role(attach_handle, &role) != 0) ||
				(attach_get_source(attach_handle, &source) != 0) ||
				(attach_get_target(attach_handle, &target) != 0))
			{
				end_session_with_error(session_instance, "amqp:decode-error", "Cannot get link name from ATTACH frame");
			}
			else
			{
				LINK_ENDPOINT_INSTANCE* link_endpoint = find_link_endpoint_by_name(session_instance, name);
				if (link_endpoint == NULL)
				{
					/* new link attach */
					if (session_instance->on_link_attached != NULL)
					{
						LINK_ENDPOINT_HANDLE new_link_endpoint = session_create_link_endpoint(session_instance, name);
						if (new_link_endpoint == NULL)
						{
							end_session_with_error(session_instance, "amqp:internal-error", "Cannot create link endpoint");
						}
						else
						{
							if (!session_instance->on_link_attached(session_instance->on_link_attached_callback_context, new_link_endpoint, name, role, source, target))
							{
								session_destroy_link_endpoint(new_link_endpoint);
								new_link_endpoint = NULL;
							}
							else
							{
								if (new_link_endpoint->frame_received_callback != NULL)
								{
									new_link_endpoint->frame_received_callback(new_link_endpoint->callback_context, performative, payload_size, payload_bytes);
								}
							}
						}
					}
				}
				else
				{
					if (attach_get_handle(attach_handle, &link_endpoint->input_handle) != 0)
					{
						end_session_with_error(session_instance, "amqp:decode-error", "Cannot get input handle from ATTACH frame");
					}
					else
					{
						link_endpoint->frame_received_callback(link_endpoint->callback_context, performative, payload_size, payload_bytes);
					}
				}
			}

			attach_destroy(attach_handle);
		}
	}
	else if (is_detach_type_by_descriptor(descriptor))
	{
		DETACH_HANDLE detach_handle;

		if (amqpvalue_get_detach(performative, &detach_handle) != 0)
		{
			end_session_with_error(session_instance, "amqp:decode-error", "Cannot decode DETACH frame");
		}
		else
		{
			uint32_t remote_handle;
			if (detach_get_handle(detach_handle, &remote_handle) != 0)
			{
				end_session_with_error(session_instance, "amqp:decode-error", "Cannot get handle from DETACH frame");

				detach_destroy(detach_handle);
			}
			else
			{
				detach_destroy(detach_handle);

				LINK_ENDPOINT_INSTANCE* link_endpoint = find_link_endpoint_by_input_handle(session_instance, remote_handle);
				if (link_endpoint == NULL)
				{
					end_session_with_error(session_instance, "amqp:session:unattached-handle", "");
				}
				else
				{
					link_endpoint->frame_received_callback(link_endpoint->callback_context, performative, payload_size, payload_bytes);
				}
			}
		}
	}
	else if (is_flow_type_by_descriptor(descriptor))
	{
		FLOW_HANDLE flow_handle;

		if (amqpvalue_get_flow(performative, &flow_handle) != 0)
		{
			end_session_with_error(session_instance, "amqp:decode-error", "Cannot decode FLOW frame");
		}
		else
		{
			uint32_t remote_handle;
			transfer_number flow_next_incoming_id;
			uint32_t flow_incoming_window;
			if ((flow_get_next_outgoing_id(flow_handle, &session_instance->next_incoming_id) != 0) ||
				(flow_get_next_incoming_id(flow_handle, &flow_next_incoming_id) != 0) ||
				(flow_get_incoming_window(flow_handle, &flow_incoming_window) != 0))
			{
				flow_destroy(flow_handle);

				end_session_with_error(session_instance, "amqp:decode-error", "Cannot decode FLOW frame");
			}
			else
			{
				LINK_ENDPOINT_INSTANCE* link_endpoint_instance = NULL;

				session_instance->remote_incoming_window = flow_next_incoming_id + flow_incoming_window - session_instance->next_outgoing_id;

				if (flow_get_handle(flow_handle, &remote_handle) == 0)
				{
					link_endpoint_instance = find_link_endpoint_by_input_handle(session_instance, remote_handle);
				}

				flow_destroy(flow_handle);

				if (link_endpoint_instance != NULL)
				{
					link_endpoint_instance->frame_received_callback(link_endpoint_instance->callback_context, performative, payload_size, payload_bytes);
				}

				size_t i = 0;
				while ((session_instance->remote_incoming_window > 0) && (i < session_instance->link_endpoint_count))
				{
					/* notify the caller that it can send here */
					if (session_instance->link_endpoints[i]->on_session_flow_on != NULL)
					{
						session_instance->link_endpoints[i]->on_session_flow_on(session_instance->link_endpoints[i]->callback_context);
					}

					i++;
				}
			}
		}
	}
	else if (is_transfer_type_by_descriptor(descriptor))
	{
		TRANSFER_HANDLE transfer_handle;

		if (amqpvalue_get_transfer(performative, &transfer_handle) != 0)
		{
			end_session_with_error(session_instance, "amqp:decode-error", "Cannot decode TRANSFER frame");
		}
		else
		{
			uint32_t remote_handle;
			delivery_number delivery_id;

			transfer_get_delivery_id(transfer_handle, &delivery_id);
			if (transfer_get_handle(transfer_handle, &remote_handle) != 0)
			{
				transfer_destroy(transfer_handle);
				end_session_with_error(session_instance, "amqp:decode-error", "Cannot get handle from TRANSFER frame");
			}
			else
			{
				transfer_destroy(transfer_handle);

				session_instance->next_incoming_id++;
				session_instance->remote_outgoing_window--;
				session_instance->incoming_window--;

				LINK_ENDPOINT_INSTANCE* link_endpoint = find_link_endpoint_by_output_handle(session_instance, remote_handle);
				if (link_endpoint == NULL)
				{
					end_session_with_error(session_instance, "amqp:session:unattached-handle", "");
				}
				else
				{
					link_endpoint->frame_received_callback(link_endpoint->callback_context, performative, payload_size, payload_bytes);
				}

				if (session_instance->incoming_window == 0)
				{
                    session_instance->incoming_window = session_instance->desired_incoming_window;
					send_flow(session_instance);
				}
			}
		}
	}
	else if (is_disposition_type_by_descriptor(descriptor))
	{
		uint32_t i;

		for (i = 0; i < session_instance->link_endpoint_count; i++)
		{
			LINK_ENDPOINT_INSTANCE* link_endpoint = session_instance->link_endpoints[i];
			link_endpoint->frame_received_callback(link_endpoint->callback_context, performative, payload_size, payload_bytes);
		}
	}
	else if (is_end_type_by_descriptor(descriptor))
	{
		END_HANDLE end_handle;

		if (amqpvalue_get_end(performative, &end_handle) != 0)
		{
			end_session_with_error(session_instance, "amqp:decode-error", "Cannot decode END frame");
		}
		else
		{
			if ((session_instance->session_state != SESSION_STATE_END_RCVD) &&
				(session_instance->session_state != SESSION_STATE_DISCARDING))
			{
				session_set_state(session_instance, SESSION_STATE_END_RCVD);
				if (send_end_frame(session_instance, NULL) != 0)
				{
					/* fatal error */
					(void)connection_close(session_instance->connection, "amqp:internal-error", "Cannot send END frame.");
				}

				session_set_state(session_instance, SESSION_STATE_DISCARDING);
			}
		}
	}
}