static void Outprocess_Receive(MODULE_HANDLE moduleHandle, MESSAGE_HANDLE messageHandle)
{
	OUTPROCESS_HANDLE_DATA* handleData = moduleHandle;
	/*Codes_SRS_OUTPROCESS_MODULE_17_022: [ If module or message_handle is NULL, this function shall do nothing. ]*/
	if (handleData != NULL && messageHandle != NULL)
	{
		/*Codes_SRS_OUTPROCESS_MODULE_17_046: [ This function shall clone the message to ensure the message is kept allocated until forwarded to module host. ]*/
		MESSAGE_HANDLE queued_message = Message_Clone(messageHandle);
		if (queued_message == NULL)
		{
			LogError("unable to clone message");
		}
		else
		{
			/*Codes_SRS_OUTPROCESS_MODULE_17_045: [ This function shall ensure thread safety for the module data. ]*/
			if (Lock(handleData->handle_lock) != LOCK_OK)
			{
				LogError("unable to Lock handle data");
				Message_Destroy(queued_message);
			}
			else
			{
				/*Codes_SRS_OUTPROCESS_MODULE_17_047: [ This function shall push the message onto the end of the outgoing gateway message queue. ]*/
				if (MESSAGE_QUEUE_push(handleData->outgoing_messages, queued_message) != 0)
				{
					LogError("unable to queue the message");
					Message_Destroy(queued_message);
				}
				(void)Unlock(handleData->handle_lock);
			}
		}
	}
}
Пример #2
0
Файл: dht.c Проект: nja/dumhet
int Dht_AddNode(void *client_, uint32_t addr, uint16_t port)
{
    Message *qping = NULL;
    Client *client = (Client *)client_;
    check(client != NULL, "NULL client pointer");

    Node node = { .addr.s_addr = addr, .port = port, .is_new = 1 };

    qping = Message_CreateQPing(client, &node);
    check(qping != NULL, "Message_CreateQPing failed");

    int rc = MessageQueue_Push(client->queries, qping);
    check(rc == 0, "Messagequeue_Push failed");

    return 0;
error:
    Message_Destroy(qping);
    return -1;
}

int Dht_Start(void *client_)
{
    Client *client = (Client *)client_;
    check(client != NULL, "NULL client pointer");

    Search *search = Client_AddSearch(client, &client->table->id);
    check(search != NULL, "Client_AddSearch failed");

    int rc = NetworkUp(client);
    check(rc == 0, "NetworkUp failed");

    return 0;
error:
    return -1;
}
Пример #3
0
char *test_junk_response(char **junk, void **gettype)
{
    int i = 0;
    while (junk[i])
    {
	int j = 0,
	    len = strlen(junk[i]);

	while (gettype[j])
	{
	    Message *result = Message_Decode(junk[i], len, gettype[j]);
	    mu_assert(result != NULL, "Message_Decode failed");
            mu_assert(result->errors, "Decoded junk without error");
            Message_DestroyNodes(result);
            Message_Destroy(result);

	    j++;
	}
	i++;
    }

    i = 0;
    while (gettype[i])
	free(gettype[i++]);

    return NULL;
}    
Пример #4
0
char *test_Decode_QPing()
{
    char *data = "d1:ad2:id20:abcdefghij0123456789e1:q4:ping1:t2:aa1:y1:qe";

    Message *message = Message_Decode(data, strlen(data), NULL);

    mu_assert(check_Message(message, QPing) == NULL, "Bad decoded message");

    Message_Destroy(message);

    return NULL;
}
Пример #5
0
char *test_Roundtrip()
{
    char *input[] = {
	"d1:ad2:id20:abcdefghij0123456789e1:q4:ping1:t2:aa1:y1:qe",
	"d1:ad2:id20:abcdefghij01234567896:target20:mnopqrstuvwxyz123456e1:q9:find_node1:t2:aa1:y1:qe",
	"d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz123456e1:q9:get_peers1:t2:aa1:y1:qe",
	"d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz1234564:porti6881e5:token8:aoeusnthe1:q13:announce_peer1:t2:aa1:y1:qe",
	"d1:rd2:id20:abcdefghij0123456789e1:t2:pi1:y1:re",
	"d1:rd2:id20:abcdefghij01234567895:nodes52:01234567890123456789ABCDEF????????????????????xxxxyye1:t2:fn1:y1:re",
	"d1:rd2:id20:abcdefghij01234567895:nodes208:012345678901234567890xxxy0112345678901234567891xxxy1212345678901234567892xxxy2312345678901234567893xxxy3412345678901234567894xxxy4512345678901234567895xxxy5612345678901234567896xxxy6712345678901234567897xxxy75:token8:aoeusnthe1:t2:gp1:y1:re",
	"d1:rd2:id20:abcdefghij01234567895:token8:aoeusnth6:valuesl6:0xxxy06:1xxxy16:2xxxy2ee1:t2:gp1:y1:re",
	"d1:rd2:id20:abcdefghij0123456789e1:t2:ap1:y1:re",
	"d1:eli201e23:A Generic Error Ocurrede1:t2:ee1:y1:ee",
	NULL
    };

    struct PendingResponses responses = { .getPendingResponse = GetRoundtripResponseMessageType };

    int i = 0;
    while (input[i])
    {
	int len = strlen(input[i]);

	Message *message = Message_Decode(input[i], len, &responses);

	mu_assert(message != NULL, "Decode failed");

	char *dest = calloc(1, len);
	mu_assert(dest != NULL, "malloc failed");

	int rc = Message_Encode(message, dest, len - 1);
	mu_assert(rc == -1, "Encoded to too small dest");

	rc = Message_Encode(message, dest, len);
	mu_assert(rc >= 0, "Encode failed");

	mu_assert(rc == len, "Encoded too little");
	mu_assert(same_bytes_len(input[i], dest, len), "Roundtrip failed");

        Message_DestroyNodes(message);
	Message_Destroy(message);
	free(dest);

	i++;
    }

    return NULL;
}
Пример #6
0
char *test_Decode_RAnnouncePeer()
{
    char *data = "d1:rd2:id20:mnopqrstuvwxyz123456e1:t2:aa1:y1:re";
    void *responses = GetMockResponses("aa", RAnnouncePeer, ID(data), 1);

    Message *message = Message_Decode(data,
                                      strlen(data),
                                      responses);

    mu_assert(check_Message(message, RAnnouncePeer) == NULL, "Bad decoded message");

    Message_Destroy(message);
    free(responses);

    return NULL;
}
Пример #7
0
char *test_Decode_RGetPeers_nodes()
{
    char *input = "d1:rd2:id20:mnopqrstuvwxyz1234565:nodes208:"
	"012345678901234567890xxxy0"
	"112345678901234567891xxxy1"
	"212345678901234567892xxxy2"
	"312345678901234567893xxxy3"
	"412345678901234567894xxxy4"
	"512345678901234567895xxxy5"
	"612345678901234567896xxxy6"
	"712345678901234567897xxxy7"
	"5:token8:aoeusnthe1:t2:aa1:y1:re";
    void *responses = GetMockResponses("aa", RGetPeers, ID(input), 1);

    Message *message = Message_Decode(input, strlen(input), responses);

    mu_assert(check_Message(message, RGetPeers) == NULL, "Bad decoded message");

    RGetPeersData *data = &message->data.rgetpeers;

    mu_assert(same_bytes_len("aoeusnth", data->token.data, data->token.len),
              "Bad token");
    mu_assert(data->values == NULL, "Bad values");
    mu_assert(data->count == BUCKET_K, "Wrong nodes count");

    char id[] = "_1234567890123456789",
    	addr[] = "_xxx",
    	port[] = "y_";

    int i = 0;
    for (i = 0; i < BUCKET_K; i++)
    {
	id[0] = '0' + i;
	addr[0] = '0' + i;
	port[1] = '0' + i;

	mu_assert(same_bytes(id, data->nodes[i]->id.value), "Bad id");
	mu_assert(data->nodes[i]->addr.s_addr == chntohl(addr), "Bad addr");
	mu_assert(data->nodes[i]->port == chntohs(port), "Bad port");
    }

    Message_DestroyNodes(message);
    Message_Destroy(message);
    free(responses);
    
    return NULL;
}
Пример #8
0
char *test_Decode_QGetPeers()
{
    char *data = "d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz123456e1:q9:get_peers1:t2:aa1:y1:qe";
    char *info_hash = "mnopqrstuvwxyz123456";

    Message *message = Message_Decode(data, strlen(data), NULL);

    mu_assert(check_Message(message, QGetPeers) == NULL, "Bad decoded message");

    mu_assert(message->data.qgetpeers.info_hash != NULL, "Missing info_hash");
    mu_assert(same_bytes(info_hash, message->data.qgetpeers.info_hash->value),
	      "Wrong info_hash");

    Message_Destroy(message);

    return NULL;
}
Пример #9
0
char *test_Decode_QFindNode()
{
    char *data = "d1:ad2:id20:abcdefghij01234567896:target20:mnopqrstuvwxyz123456e1:q9:find_node1:t2:aa1:y1:qe";

    Message *message = Message_Decode(data, strlen(data), NULL);

    mu_assert(check_Message(message, QFindNode) == NULL, "Bad decoded message");

    mu_assert(message->data.qfindnode.target != NULL, "No target");
    mu_assert(same_bytes("mnopqrstuvwxyz123456",
			 message->data.qfindnode.target->value),
	      "Wrong target");

    Message_Destroy(message);

    return NULL;
}
Пример #10
0
void MESSAGE_QUEUE_destroy(MESSAGE_QUEUE_HANDLE handle)
{
    if (handle == NULL)
    {
        /*Codes_SRS_MESSAGE_QUEUE_17_004: [ MESSAGE_QUEUE_destroy shall not perform any actions on a NULL message queue. ]*/
        LogError("invalid argument handle(NULL).");
    }
    else
    {
		MESSAGE_QUEUE_HANDLE_DATA * mq = (MESSAGE_QUEUE_HANDLE_DATA*)handle;
        MESSAGE_HANDLE message;
        while((message = message_pop(mq)) != NULL)
        {
            /*Codes_SRS_MESSAGE_QUEUE_17_005: [ If the message queue is not empty, MESSAGE_QUEUE_destroy shall destroy all messages in the queue. ]*/
            Message_Destroy(message);
        }
        /*Codes_SRS_MESSAGE_QUEUE_17_006: [ MESSAGE_QUEUE_destroy shall free all allocated resources. ]*/
        free(handle);
    }
}
Пример #11
0
char *test_Decode_RError()
{
    char *data[] = {
	"d1:eli201e7:Generice1:t2:aa1:y1:ee",
	"d1:eli202e6:Servere1:t2:aa1:y1:ee",
	"d1:eli203e8:Protocole1:t2:aa1:y1:ee",
	"d1:eli204e6:Methode1:t2:aa1:y1:ee",
	NULL
    };

    int expected_code[] = { 201, 202, 203, 204 };
    struct tagbstring expected_msg[] = {
	bsStatic("Generic"),
	bsStatic("Server"),
	bsStatic("Protocol"),
	bsStatic("Method")
    };

    int i = 0;
    while (data[i])
    {
	Message *message = Message_Decode(data[i], strlen(data[i]), NULL);

	mu_assert(message->type == RError, "Wrong message type");
	mu_assert(same_bytes_len("aa", message->t, message->t_len), "Wrong transaction id");

	RErrorData *data = &message->data.rerror;

	mu_assert(data->code == expected_code[i], "Wrong error code");
	mu_assert(bstrcmp(&expected_msg[i], data->message) == 0, "Wrong message");

	Message_Destroy(message);

	i++;
    }

    return NULL;
}
Пример #12
0
static void publish_with_new_properties(MAP_HANDLE newProperties, MESSAGE_HANDLE messageHandle, IDENTITY_MAP_DATA * idModule)
{
	/*Codes_SRS_IDMAP_17_034: [IdentityMap_Receive shall clone message content.] */ 
	CONSTBUFFER_HANDLE content = Message_GetContentHandle(messageHandle);
	if (content == NULL)
	{
		/*Codes_SRS_IDMAP_17_035: [If cloning message content fails, IdentityMap_Receive shall deallocate all resources and return.]*/
		LogError("Could not extract message content");
	}
	else
	{
		MESSAGE_BUFFER_CONFIG newMessageConfig =
		{
			content,
			newProperties
		};
		/*Codes_SRS_IDMAP_17_036: [IdentityMap_Receive shall create a new message by calling Message_CreateFromBuffer with new map and cloned content.]*/
		MESSAGE_HANDLE newMessage = Message_CreateFromBuffer(&newMessageConfig);
		if (newMessage == NULL)
		{
			/*Codes_SRS_IDMAP_17_037: [If creating new message fails, IdentityMap_Receive shall deallocate all resources and return.]*/
			LogError("Could not create new message to publish");
		}
		else
		{
			MESSAGE_BUS_RESULT busStatus;
			/*Codes_SRS_IDMAP_17_038: [IdentityMap_Receive shall call MessageBus_Publish with busHandle and new message.]*/
			busStatus = MessageBus_Publish(idModule->busHandle, newMessage);
			if (busStatus != MESSAGE_BUS_OK)
			{
				LogError("Message bus publish failure: %s", ENUM_TO_STRING(MESSAGE_BUS_RESULT, busStatus));
			}
			Message_Destroy(newMessage);
		}
		/*Codes_SRS_IDMAP_17_039: [IdentityMap_Receive will destroy all resources it created.]*/
		CONSTBUFFER_Destroy(content);
	}
}
Пример #13
0
char *test_Decode_RGetPeers_values()
{
    char *input = "d1:rd2:id20:mnopqrstuvwxyz1234565:token8:aoeusnth6:valuesl"
	"6:" "0xxxy0"
	"6:" "1xxxy1"
	"6:" "2xxxy2"
	"ee1:t2:aa1:y1:re";
    void *responses = GetMockResponses("aa", RGetPeers, ID(input), 1);

    Message *message = Message_Decode(input, strlen(input), responses);

    mu_assert(check_Message(message, RGetPeers) == NULL, "Bad decoded message");

    RGetPeersData *data = &message->data.rgetpeers;

    mu_assert(same_bytes_len("aoeusnth", data->token.data, data->token.len),
              "Bad token");
    mu_assert(data->nodes == NULL, "Bad nodes");
    mu_assert(data->count == 3, "Wrong values count");

    char addr[] = "_xxx",
    	port[] = "y_";

    int i = 0;
    for (i = 0; i < 3; i++)
    {
	addr[0] = '0' + i;
	port[1] = '0' + i;
	mu_assert(data->values[i].addr == chntohl(addr), "Bad addr");
	mu_assert(data->values[i].port == chntohs(port), "Bad port");
    }

    Message_Destroy(message);
    free(responses);

    return NULL;
}
Пример #14
0
char *test_Decode_RFindNode()
{
    char *data = "d1:rd2:id20:mnopqrstuvwxyz1234565:nodes52:"
	"01234567890123456789ABCDEF"
	"????????????????????xxxxyy"
	"e1:t2:aa1:y1:re";
    void *responses = GetMockResponses("aa", RFindNode, ID(data), 1);

    Message *message = Message_Decode(data, strlen(data), responses);

    mu_assert(check_Message(message, RFindNode) == NULL, "Bad decoded message");

    mu_assert(message->data.rfindnode.nodes != NULL, "NULL nodes");
    mu_assert(message->data.rfindnode.count == 2, "Wrong node count");

    mu_assert(same_bytes("01234567890123456789",
			 message->data.rfindnode.nodes[0]->id.value),
	      "Wrong nodes[0] id");
    mu_assert(message->data.rfindnode.nodes[0]->addr.s_addr == chntohl("ABCD"),
	      "Wrong nodes[0] addr");
    mu_assert(message->data.rfindnode.nodes[0]->port == chntohs("EF"),
    	      "Wrong nodes[0] port");

    mu_assert(same_bytes("????????????????????",
			 message->data.rfindnode.nodes[1]->id.value),
	      "Wrong nodes[1] id");
    mu_assert(message->data.rfindnode.nodes[1]->addr.s_addr == chntohl("xxxx"),
	      "Wrong nodes[1] addr");
    mu_assert(message->data.rfindnode.nodes[1]->port == chntohs("yy"),
	      "Wrong nodes[1] port");

    Message_DestroyNodes(message);
    Message_Destroy(message);
    free(responses);

    return NULL;
}
Пример #15
0
char *test_Decode_QAnnouncePeer()
{
    char *data = "d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz1234564:porti6881e5:token8:aoeusnthe1:q13:announce_peer1:t2:aa1:y1:qe";
    char *info_hash = "mnopqrstuvwxyz123456", *token = "aoeusnth";
    const int port = 6881;

    Message *message = Message_Decode(data, strlen(data), NULL);

    mu_assert(check_Message(message, QAnnouncePeer) == NULL, "Bad decoded message");

    mu_assert(message->data.qannouncepeer.info_hash != NULL, "Missing info_hash");
    mu_assert(same_bytes(info_hash, message->data.qannouncepeer.info_hash->value),
	      "Wrong info_hash");
    mu_assert(message->data.qannouncepeer.token.data != NULL, "No token");
    mu_assert(message->data.qannouncepeer.token.len == strlen(token),
	      "Wrong token length");
    mu_assert(same_bytes(token, message->data.qannouncepeer.token.data),
	      "Wrong token");
    mu_assert(message->data.qannouncepeer.port == port, "Wrong port");

    Message_Destroy(message);

    return NULL;
}
Пример #16
0
BROKER_RESULT Broker_Publish(BROKER_HANDLE broker, MODULE_HANDLE source, MESSAGE_HANDLE message)
{
    BROKER_RESULT result;
    /*Codes_SRS_BROKER_13_030: [If broker or message is NULL the function shall return BROKER_INVALIDARG.]*/
    if (broker == NULL || source == NULL || message == NULL)
    {
        result = BROKER_INVALIDARG;
        LogError("Broker handle, source, and/or message handle is NULL");
    }
    else
    {
        BROKER_HANDLE_DATA* broker_data = (BROKER_HANDLE_DATA*)broker;
        /*Codes_SRS_BROKER_17_022: [ Broker_Publish shall Lock the modules lock. ]*/
        if (Lock(broker_data->modules_lock) != LOCK_OK)
        {
            /*Codes_SRS_BROKER_13_053: [This function shall return BROKER_ERROR if an underlying API call to the platform causes an error or BROKER_OK otherwise.]*/
            LogError("Lock on broker_data->modules_lock failed");
            result = BROKER_ERROR;
        }
        else
        {
            int32_t msg_size;
            int32_t buf_size;
            /*Codes_SRS_BROKER_17_007: [ Broker_Publish shall clone the message. ]*/
            MESSAGE_HANDLE msg = Message_Clone(message);
            /*Codes_SRS_BROKER_17_008: [ Broker_Publish shall serialize the message. ]*/
            msg_size = Message_ToByteArray(message, NULL, 0);
            if (msg_size < 0)
            {
                /*Codes_SRS_BROKER_13_053: [This function shall return BROKER_ERROR if an underlying API call to the platform causes an error or BROKER_OK otherwise.]*/
                LogError("unable to serialize a message [%p]", msg);
                Message_Destroy(msg);
                result = BROKER_ERROR;
            }
            else
            {
                /*Codes_SRS_BROKER_17_025: [ Broker_Publish shall allocate a nanomsg buffer the size of the serialized message + sizeof(MODULE_HANDLE). ]*/
                buf_size = msg_size + sizeof(MODULE_HANDLE);
                void* nn_msg = nn_allocmsg(buf_size, 0);
                if (nn_msg == NULL)
                {
                    /*Codes_SRS_BROKER_13_053: [This function shall return BROKER_ERROR if an underlying API call to the platform causes an error or BROKER_OK otherwise.]*/
                    LogError("unable to serialize a message [%p]", msg);
                    result = BROKER_ERROR;
                }
                else
                {
                    /*Codes_SRS_BROKER_17_026: [ Broker_Publish shall copy source into the beginning of the nanomsg buffer. ]*/
                    unsigned char *nn_msg_bytes = (unsigned char *)nn_msg;
                    memcpy(nn_msg_bytes, &source, sizeof(MODULE_HANDLE));
                    /*Codes_SRS_BROKER_17_027: [ Broker_Publish shall serialize the message into the remainder of the nanomsg buffer. ]*/
                    nn_msg_bytes += sizeof(MODULE_HANDLE);
                    Message_ToByteArray(message, nn_msg_bytes, msg_size);

                    /*Codes_SRS_BROKER_17_010: [ Broker_Publish shall send a message on the publish_socket. ]*/
                    int nbytes = nn_send(broker_data->publish_socket, &nn_msg, NN_MSG, 0);
                    if (nbytes != buf_size)
                    {
                        /*Codes_SRS_BROKER_13_053: [This function shall return BROKER_ERROR if an underlying API call to the platform causes an error or BROKER_OK otherwise.]*/
                        LogError("unable to send a message [%p]", msg);
                        /*Codes_SRS_BROKER_17_012: [ Broker_Publish shall free the message. ]*/
                        nn_freemsg(nn_msg);
                        result = BROKER_ERROR;
                    }
                    else
                    {
                        result = BROKER_OK;
                    }
                }
                /*Codes_SRS_BROKER_17_012: [ Broker_Publish shall free the message. ]*/
                Message_Destroy(msg);
                /*Codes_SRS_BROKER_17_011: [ Broker_Publish shall free the serialized message data. ]*/
            }
            /*Codes_SRS_BROKER_17_023: [ Broker_Publish shall Unlock the modules lock. ]*/
            Unlock(broker_data->modules_lock);
        }

    }
    /*Codes_SRS_BROKER_13_037: [ This function shall return BROKER_ERROR if an underlying API call to the platform causes an error or BROKER_OK otherwise. ]*/
    return result;
}
Пример #17
0
static int SimulatorModule_thread(void * context)
{
    int thread_result;
    SIMULATOR_MODULE_HANDLE * module = (SIMULATOR_MODULE_HANDLE *)context;
    MESSAGE_CONFIG message_to_send;

    thread_result = SimulatorModule_create_message(module, &message_to_send);
    if (thread_result != 0)
    {
        LogError("unable to continue with simulation");
        if (message_to_send.sourceProperties != NULL)
        {
            Map_Destroy(message_to_send.sourceProperties);
        }
        if (message_to_send.source != NULL)
        {
            free( (void*)message_to_send.source);
        }
    }
    else
    {
        using HrClock = std::chrono::high_resolution_clock;
        using MicroSeconds = std::chrono::microseconds;
        long long time_to_wait = module->message_delay * 1000;

        size_t messages_produced = 0;
        thread_result = 0;
        while (module->thread_flag)
        {
            std::chrono::time_point<HrClock, MicroSeconds> t1 = std::chrono::time_point_cast<MicroSeconds>(HrClock::now());
            auto t1_as_int = t1.time_since_epoch().count();
            std::string t1_as_string = std::to_string(t1_as_int);
            messages_produced++;
            std::string messages_produced_as_string = std::to_string(messages_produced);
            if (Map_AddOrUpdate(message_to_send.sourceProperties, "timestamp", t1_as_string.c_str()) != MAP_OK)
            {
                LogError("Unable to update timestamp in message");
                module->thread_flag = false;
                thread_result = -__LINE__;
                break;
            }
            else if (Map_AddOrUpdate(message_to_send.sourceProperties, "sequence number", messages_produced_as_string.c_str()) != MAP_OK)
            {
                LogError("Unable to update sequence number in message");
                module->thread_flag = false;
                thread_result = -__LINE__;
                break;
            }
            else
            {
                MESSAGE_HANDLE next_message = Message_Create(&message_to_send);
                if (next_message == NULL)
                {
                    LogError("Unable to create next message");
                    module->thread_flag = false;
                    thread_result = -__LINE__;
                    break;
                }
                else
                {
                    if (Broker_Publish(module->broker, module, next_message) != BROKER_OK)
                    {
                        LogError("Unable to publish message");
                        module->thread_flag = false;
                        thread_result = -__LINE__;
                        break;
                    }
                    else
                    {
                        Message_Destroy(next_message);
                        std::chrono::time_point<HrClock, MicroSeconds> t2 = std::chrono::time_point_cast<MicroSeconds>(HrClock::now());
                        auto time_to_publish = t2.time_since_epoch().count() - t1_as_int;
                        if (time_to_publish < time_to_wait)
                        {
                            unsigned int remaining_time = static_cast<unsigned int>((time_to_wait - time_to_publish)/1000);
                            ThreadAPI_Sleep(remaining_time);
                        }
                    }
                }
            }
        }
        if (message_to_send.sourceProperties != NULL)
        {
            Map_Destroy(message_to_send.sourceProperties);
        }
        if (message_to_send.source != NULL)
        {
            free((void*)message_to_send.source);
        }
    }
    return thread_result;
}
Пример #18
0
/**
* This function runs for each module. It receives a pointer to a MODULE_INFO
* object that describes the module. Its job is to call the Receive function on
* the associated module whenever it receives a message.
*/
static int module_worker(void * user_data)
{
    /*Codes_SRS_BROKER_13_026: [This function shall assign `user_data` to a local variable called `module_info` of type `BROKER_MODULEINFO*`.]*/
    BROKER_MODULEINFO* module_info = (BROKER_MODULEINFO*)user_data;

    int should_continue = 1;
    while (should_continue)
    {
        /*Codes_SRS_BROKER_13_089: [ This function shall acquire the lock on module_info->socket_lock. ]*/
        if (Lock(module_info->socket_lock))
        {
            /*Codes_SRS_BROKER_02_004: [ If acquiring the lock fails, then module_worker shall return. ]*/
            LogError("unable to Lock");
            should_continue = 0;
            break;
        }
        int nn_fd = module_info->receive_socket;
        int nbytes;
        unsigned char *buf = NULL;

        /*Codes_SRS_BROKER_17_005: [ For every iteration of the loop, the function shall wait on the receive_socket for messages. ]*/
        nbytes = nn_recv(nn_fd, (void *)&buf, NN_MSG, 0);
        /*Codes_SRS_BROKER_13_091: [ The function shall unlock module_info->socket_lock. ]*/
        if (Unlock(module_info->socket_lock) != LOCK_OK)
        {
            /*Codes_SRS_BROKER_17_016: [ If releasing the lock fails, then module_worker shall return. ]*/
            should_continue = 0;
            if (nbytes > 0)
            {
                /*Codes_SRS_BROKER_17_019: [ The function shall free the buffer received on the receive_socket. ]*/
                nn_freemsg(buf);
            }
            break;
        }

        if (nbytes < 0)
        {
            /*Codes_SRS_BROKER_17_006: [ An error on receiving a message shall terminate the loop. ]*/
            should_continue = 0;
        }
        else
        {
            if (nbytes == BROKER_GUID_SIZE &&
                (strncmp(STRING_c_str(module_info->quit_message_guid), (const char *)buf, BROKER_GUID_SIZE-1)==0))
            {
                /*Codes_SRS_BROKER_13_068: [ This function shall run a loop that keeps running until module_info->quit_message_guid is sent to the thread. ]*/
                /* received special quit message for this module */
                should_continue = 0;
            }
            else
            {
                /*Codes_SRS_BROKER_17_024: [ The function shall strip off the topic from the message. ]*/
                const unsigned char*buf_bytes = (const unsigned char*)buf;
                buf_bytes += sizeof(MODULE_HANDLE);
                /*Codes_SRS_BROKER_17_017: [ The function shall deserialize the message received. ]*/
                MESSAGE_HANDLE msg = Message_CreateFromByteArray(buf_bytes, nbytes - sizeof(MODULE_HANDLE));
                /*Codes_SRS_BROKER_17_018: [ If the deserialization is not successful, the message loop shall continue. ]*/
                if (msg != NULL)
                {
                    /*Codes_SRS_BROKER_13_092: [The function shall deliver the message to the module's callback function via module_info->module_apis. ]*/
                    MODULE_RECEIVE(module_info->module->module_apis)(module_info->module->module_handle, msg);
                    /*Codes_SRS_BROKER_13_093: [ The function shall destroy the message that was dequeued by calling Message_Destroy. ]*/
                    Message_Destroy(msg);
                }
            }
            /*Codes_SRS_BROKER_17_019: [ The function shall free the buffer received on the receive_socket. ]*/
            nn_freemsg(buf);
        }    
    }

    return 0;
}
Пример #19
0
/* Codes_SRS_BROKER_17_026: [ N/A - Broker_Publish shall copy source into the beginning of the nanomsg buffer. ] */
BROKER_RESULT
Broker_Publish (
    BROKER_HANDLE broker,
    MODULE_HANDLE source,
    MESSAGE_HANDLE message
) {
    (void)source;
    REMOTE_MODULE_HANDLE remote_module = (REMOTE_MODULE_HANDLE)broker;
    BROKER_RESULT result;

    /* Codes_SRS_BROKER_13_030: [If broker or message is NULL the function shall return BROKER_INVALIDARG.] */
    if (broker == NULL || message == NULL)
    {
        result = BROKER_INVALIDARG;
        LogError("Broker handle and/or message handle is NULL");
    }
    else
    {
        // Send message_ to nanomsg
        int32_t msg_size;
        int32_t buf_size;
        /* Codes_SRS_BROKER_17_007: [ Broker_Publish shall clone the message. ] */
        MESSAGE_HANDLE msg = Message_Clone(message);
        /* Codes_SRS_BROKER_17_008: [ Broker_Publish shall serialize the message. ] */
        msg_size = Message_ToByteArray(message, NULL, 0);
        if (msg_size < 0)
        {
            /* Codes_SRS_BROKER_13_037: [ This function shall return BROKER_ERROR if an underlying API call to the platform causes an error or BROKER_OK otherwise. ] */
            LogError("unable to serialize a message [%p]", msg);
            Message_Destroy(msg);
            result = BROKER_ERROR;
        }
        else
        {
            /* Codes_SRS_BROKER_17_025: [ Broker_Publish shall allocate a nanomsg buffer the size of the serialized message + sizeof(MODULE_HANDLE). ] */
            buf_size = msg_size;
            void* nn_msg = nn_allocmsg(buf_size, 0);
            if (nn_msg == NULL)
            {
                /* Codes_SRS_BROKER_13_037: [ This function shall return BROKER_ERROR if an underlying API call to the platform causes an error or BROKER_OK otherwise. ] */
                LogError("unable to serialize a message [%p]", msg);
                result = BROKER_ERROR;
            }
            else
            {
                unsigned char *nn_msg_bytes = (unsigned char *)nn_msg;
                /* Codes_SRS_BROKER_17_027: [ Broker_Publish shall serialize the message into the remainder of the nanomsg buffer. ] */
                Message_ToByteArray(message, nn_msg_bytes, msg_size);

                /* Codes_SRS_BROKER_17_010: [ Broker_Publish shall send a message on the publish_socket. ] */
                int nbytes = nn_really_send(remote_module->message_socket, &nn_msg, NN_MSG, 0);
                if (nbytes != buf_size)
                {
                    /* Codes_SRS_BROKER_13_037: [ This function shall return BROKER_ERROR if an underlying API call to the platform causes an error or BROKER_OK otherwise. ] */
                    LogError("unable to send a message [%p]", msg);
                    /* Codes_SRS_BROKER_17_012: [ Broker_Publish shall free the message. ] */
                    nn_freemsg(nn_msg);
                    result = BROKER_ERROR;
                }
                else
                {
                    result = BROKER_OK;
                }
            }
            /* Codes_SRS_BROKER_17_012: [ Broker_Publish shall free the message. ] */
            Message_Destroy(msg);
            /* Codes_SRS_BROKER_17_011: [ Broker_Publish shall free the serialized message data. ] */
        }

    }

    /* Codes_SRS_BROKER_13_037: [ This function shall return BROKER_ERROR if an underlying API call to the platform causes an error or BROKER_OK otherwise. ] */
    return result;
}
Пример #20
0
void
ProxyGateway_DoWork (
    REMOTE_MODULE_HANDLE remote_module
) {
    if (NULL == remote_module) {
        /* Codes_SRS_PROXY_GATEWAY_027_026: [Prerequisite Check - If the `remote_module` parameter is `NULL`, then `ProxyGateway_DoWork` shall do nothing] */
        LogError("%s: NULL parameter - remote_module!", __FUNCTION__);
    } else {
        int32_t bytes_received;
        void * control_message = NULL;

        /* Codes_SRS_PROXY_GATEWAY_027_027: [Control Channel - `ProxyGateway_DoWork` shall poll the gateway control channel by calling `int nn_recv(int s, void * buf, size_t len, int flags)` with the control socket for `s`, `NULL` for `buf`, `NN_MSG` for `len` and NN_DONTWAIT for `flags`] */
        if (0 > (bytes_received = nn_recv(remote_module->control_socket, &control_message, NN_MSG, NN_DONTWAIT))) {
            if (EAGAIN == nn_errno()) {
                /* Codes_SRS_PROXY_GATEWAY_027_028: [Control Channel - If no message is available, then `ProxyGateway_DoWork` shall abandon the control channel request] */
            } else {
                /* Codes_SRS_PROXY_GATEWAY_027_066: [Control Channel - If an error occurred when polling the gateway, then `ProxyGateway_DoWork` shall signal the gateway abandon the control channel request] */
                LogError("%s: Unexpected error received from the control channel!", __FUNCTION__);
                (void)send_control_reply(remote_module, (uint8_t)REMOTE_MODULE_GATEWAY_CONNECTION_ERROR);
            }
        } else {
            CONTROL_MESSAGE * structured_control_message;

            /* Codes_SRS_PROXY_GATEWAY_027_029: [Control Channel - If a control message was received, then `ProxyGateway_DoWork` will parse that message by calling `CONTROL_MESSAGE * ControlMessage_CreateFromByteArray(const unsigned char * source, size_t size)` with the buffer received from `nn_recv` as `source` and return value from `nn_recv` as `size`] */
            if (NULL == (structured_control_message = ControlMessage_CreateFromByteArray((const unsigned char *)control_message, bytes_received))) {
                /* Codes_SRS_PROXY_GATEWAY_027_030: [Control Channel - If unable to parse the control message, then `ProxyGateway_DoWork` shall signal the gateway, free any previously allocated memory and abandon the control channel request] */
                LogError("%s: Unable to parse control message!", __FUNCTION__);
                (void)send_control_reply(remote_module, (uint8_t)REMOTE_MODULE_GATEWAY_CONNECTION_ERROR);
            } else {
                // Route control channel messages to appropriate functions
                switch (structured_control_message->type) {
                  case CONTROL_MESSAGE_TYPE_MODULE_CREATE:
                    /* Codes_SRS_PROXY_GATEWAY_027_031: [Control Channel - If the message type is CONTROL_MESSAGE_TYPE_MODULE_CREATE, then `ProxyGateway_DoWork` shall process the create message] */
                    if (0 != process_module_create_message(remote_module, (const CONTROL_MESSAGE_MODULE_CREATE *)structured_control_message)) {
                        LogError("%s: Unable to process create message!", __FUNCTION__);
                    }
                    break;
                  case CONTROL_MESSAGE_TYPE_MODULE_START:
                    /* Codes_SRS_PROXY_GATEWAY_027_032: [Control Channel - If the message type is CONTROL_MESSAGE_TYPE_MODULE_START and `Module_Start` was provided, then `ProxyGateway_DoWork` shall call `void Module_Start(MODULE_HANDLE moduleHandle)`] */
                    if (((MODULE_API_1 *)remote_module->module.module_apis)->Module_Start) {
                        ((MODULE_API_1 *)remote_module->module.module_apis)->Module_Start(remote_module->module.module_handle);
                    }
                    break;
                  case CONTROL_MESSAGE_TYPE_MODULE_DESTROY:
                    /* Codes_SRS_PROXY_GATEWAY_027_033: [Control Channel - If the message type is CONTROL_MESSAGE_TYPE_MODULE_DESTROY, then `ProxyGateway_DoWork` shall call `void Module_Destroy(MODULE_HANDLE moduleHandle)`] */
                    ((MODULE_API_1 *)remote_module->module.module_apis)->Module_Destroy(remote_module->module.module_handle);
                    remote_module->module.module_handle = NULL;
                    /* Codes_SRS_PROXY_GATEWAY_027_034: [Control Channel - If the message type is CONTROL_MESSAGE_TYPE_MODULE_DESTROY, then `ProxyGateway_DoWork` shall disconnect from the message channel] */
                    disconnect_from_message_channel(remote_module);
                    break;
                  default: LogError("ERROR: REMOTE_MODULE - Received unsupported message type! [%d]\n", structured_control_message->type); break;
                }
                /* Codes_SRS_PROXY_GATEWAY_027_035: [Control Channel - `ProxyGateway_DoWork` shall free the resources held by the parsed control message by calling `void ControlMessage_Destroy(CONTROL_MESSAGE * message)` using the parsed control message as `message`] */
                ControlMessage_Destroy(structured_control_message);
            }
            /* Codes_SRS_PROXY_GATEWAY_027_036: [Control Channel - `ProxyGateway_DoWork` shall free the resources held by the gateway message by calling `int nn_freemsg(void * msg)` with the resulting buffer from the previous call to `nn_recv`] */
            (void)nn_freemsg(control_message);
        }

        /* Codes_SRS_PROXY_GATEWAY_027_037: [Message Channel - `ProxyGateway_DoWork` shall not check for messages, if the message socket is not available] */
        if ( 0 > remote_module->message_socket ) {
            // not connected to message channel
        } else {
            void * module_message = NULL;

            /* Codes_SRS_PROXY_GATEWAY_027_038: [Message Channel - `ProxyGateway_DoWork` shall poll the gateway message channel by calling `int nn_recv(int s, void * buf, size_t len, int flags)` with each message socket for `s`, `NULL` for `buf`, `NN_MSG` for `len` and NN_DONTWAIT for `flags`] */
            if (0 > (bytes_received = nn_recv(remote_module->message_socket, &module_message, NN_MSG, NN_DONTWAIT))) {
                /* Codes_SRS_PROXY_GATEWAY_027_039: [Message Channel - If no message is available or an error occurred, then `ProxyGateway_DoWork` shall abandon the message channel request] */
                if (EAGAIN == nn_errno()) {
                    // no messages available at this time
                } else {
                    LogError("%s: Unexpected error received from the message channel!", __FUNCTION__);
                }
            } else {
                MESSAGE_HANDLE structured_module_message;

                /* Codes_SRS_PROXY_GATEWAY_027_040: [Message Channel - If a module message was received, then `ProxyGateway_DoWork` will parse that message by calling `MESSAGE_HANDLE Message_CreateFromByteArray(const unsigned char * source, int32_t size)` with the buffer received from `nn_recv` as `source` and return value from `nn_recv` as `size`] */
                if (NULL == (structured_module_message = Message_CreateFromByteArray((const unsigned char *)module_message, bytes_received))) {
                    /* Codes_SRS_PROXY_GATEWAY_027_041: [Message Channel - If unable to parse the module message, then `ProxyGateway_DoWork` shall free any previously allocated memory and abandon the message channel request] */
                    LogError("%s: Unable to parse control message!", __FUNCTION__);
                } else {
                    /* Codes_SRS_PROXY_GATEWAY_027_042: [Message Channel - `ProxyGateway_DoWork` shall pass the structured message to the module by calling `void Module_Receive(MODULE_HANDLE moduleHandle)` using the parsed message as `moduleHandle`] */
                    ((MODULE_API_1 *)remote_module->module.module_apis)->Module_Receive(remote_module->module.module_handle, structured_module_message);
                    /* Codes_SRS_PROXY_GATEWAY_027_043: [Message Channel - `ProxyGateway_DoWork` shall free the resources held by the parsed module message by calling `void Message_Destroy(MESSAGE_HANDLE * message)` using the parsed module message as `message`] */
                    Message_Destroy(structured_module_message);
                }
                /* Codes_SRS_PROXY_GATEWAY_027_044: [Message Channel - `ProxyGateway_DoWork` shall free the resources held by the gateway message by calling `int nn_freemsg(void * msg)` with the resulting buffer from the previous call to `nn_recv`] */
                (void)nn_freemsg(module_message);
            }
        }
    }

    return;
}
int outprocessIncomingMessageThread(void *param)
{
	/*Codes_SRS_OUTPROCESS_MODULE_17_037: [ This function shall receive the module handle data as the thread parameter. ]*/
	OUTPROCESS_HANDLE_DATA * handleData = (OUTPROCESS_HANDLE_DATA*)param;
	if (handleData == NULL)
	{
		LogError("outprocess thread: parameter is NULL");
	}
	else
	{
		int should_continue = 1;

		while (should_continue)
		{
			/*Codes_SRS_OUTPROCESS_MODULE_17_036: [ This function shall ensure thread safety on execution. ]*/
			if (Lock(handleData->handle_lock) != LOCK_OK)
			{
				LogError("unable to Lock handle data");
				should_continue = 0;
				break;
			}
			int nn_fd = handleData->message_socket;
			if (Unlock(handleData->handle_lock) != LOCK_OK)
			{
				should_continue = 0;
				break;
			}

			/*Codes_SRS_OUTPROCESS_MODULE_17_036: [ This function shall ensure thread safety on execution. ]*/
			if (Lock(handleData->message_receive_thread.thread_lock) != LOCK_OK)
			{
				LogError("unable to Lock");
				should_continue = 0;
				break;
			}
			if (handleData->message_receive_thread.thread_flag == THREAD_FLAG_STOP)
			{
				should_continue = 0;
				(void)Unlock(handleData->message_receive_thread.thread_lock);
				break;
			}
			if (Unlock(handleData->message_receive_thread.thread_lock) != LOCK_OK)
			{
				should_continue = 0;
				break;
			}

			int nbytes;
			unsigned char *buf = NULL;
			errno = 0;
			/*Codes_SRS_OUTPROCESS_MODULE_17_038: [ This function shall read from the message channel for gateway messages from the module host. ]*/
			nbytes = nn_recv(nn_fd, (void *)&buf, NN_MSG, 0);
			if (nbytes < 0)
			{
				int receive_error = nn_errno();
				if (receive_error != ETIMEDOUT && receive_error != EINTR)
					should_continue = 0;
			}
			else
			{
				/*Codes_SRS_OUTPROCESS_MODULE_17_039: [ Upon successful receiving a gateway message, this function shall deserialize the message. ]*/
				const unsigned char*buf_bytes = (const unsigned char*)buf;
				MESSAGE_HANDLE msg = Message_CreateFromByteArray(buf_bytes, nbytes);
				if (msg != NULL)
				{
					/*Codes_SRS_OUTPROCESS_MODULE_17_040: [ This function shall publish any successfully created gateway message to the broker. ]*/
					Broker_Publish(handleData->broker, (MODULE_HANDLE)handleData, msg);
					Message_Destroy(msg);
				}
				nn_freemsg(buf);
			}
			ThreadAPI_Sleep(1);
		}
	}
	return 0;
}
static int outprocessOutgoingMessagesThread(void * param)
{
	OUTPROCESS_HANDLE_DATA * handleData = (OUTPROCESS_HANDLE_DATA*)param;
	if (handleData == NULL)
	{
		LogError("outprocess send message thread: parameter is NULL");
	}
	else
	{
		int should_continue = 1;

		while (should_continue)
		{
			/*Codes_SRS_OUTPROCESS_MODULE_17_053: [ This thread shall ensure thread safety on the module data. ]*/
			if (Lock(handleData->message_send_thread.thread_lock) != LOCK_OK)
			{
				LogError("unable to Lock");
				should_continue = 0;
				break;
			}
			if (handleData->message_send_thread.thread_flag == THREAD_FLAG_STOP)
			{
				should_continue = 0;
				(void)Unlock(handleData->message_send_thread.thread_lock);
				break;
			}
			if (Unlock(handleData->message_send_thread.thread_lock) != LOCK_OK)
			{
				should_continue = 0;
				break;
			}
			MESSAGE_HANDLE messageHandle;
			/*Codes_SRS_OUTPROCESS_MODULE_17_053: [ This thread shall ensure thread safety on the module data. ]*/
			if (Lock(handleData->handle_lock) != LOCK_OK)
			{
				LogError("unable to Lock");
				should_continue = 0;
				break;
			}
			
			if (MESSAGE_QUEUE_is_empty(handleData->outgoing_messages))
			{
				messageHandle = NULL;
			}
			else
			{
				/*Codes_SRS_OUTPROCESS_MODULE_17_054: [ This function shall remove the oldest message from the outgoing gateway message queue. ]*/
				messageHandle = MESSAGE_QUEUE_pop(handleData->outgoing_messages);
				if (messageHandle == NULL)
				{
					LogError("bad condition: message handle in queue is NULL");
					(void)Unlock(handleData->handle_lock);
					should_continue = 0;
					break;
				}
			}
			if (Unlock(handleData->handle_lock) != LOCK_OK)
			{
				should_continue = 0;
				break;
			}

			/* forward message to remote */
			if (messageHandle != NULL)
			{
				/*Codes_SRS_OUTPROCESS_MODULE_17_023: [ This function shall serialize the message for transmission on the message channel. ]*/
				int32_t msg_size = Message_ToByteArray(messageHandle, NULL, 0);
				if (msg_size < 0)
				{
					LogError("unable to serialize outgoing message [%p]", messageHandle);
				}
				else
				{
					void* result = nn_allocmsg(msg_size, 0);
					if (result == NULL)
					{
						LogError("unable to allocate buffer for outgoing message [%p]", messageHandle);
					}
					else
					{
						unsigned char *nn_msg_bytes = (unsigned char *)result;
						Message_ToByteArray(messageHandle, nn_msg_bytes, msg_size);
						/*Codes_SRS_OUTPROCESS_MODULE_17_024: [ This function shall send the message on the message channel. ]*/
						int nbytes = nn_really_send(handleData->message_socket, &result, NN_MSG, 0);
						if (nbytes != msg_size)
						{
							LogError("unable to send buffer to remote for message [%p]", messageHandle);
							/*Codes_SRS_OUTPROCESS_MODULE_17_025: [ This function shall free any resources created. ]*/
							nn_freemsg(result);
						}
					}
				}
				// We are finally finished with this message
				/*Codes_SRS_OUTPROCESS_MODULE_17_055: [ This function shall Destroy the message once successfully transmitted. ]*/
				Message_Destroy(messageHandle);
			}
			ThreadAPI_Sleep(1);
		}
	}
	return 0;
}
Пример #23
0
char *test_Decode_JunkQuery()
{
    char *ok[] = {
	"d1:ad2:id20:abcdefghij0123456789e1:q4:ping1:t2:aa1:y1:qe",
	"d1:ad2:id20:abcdefghij01234567896:target20:mnopqrstuvwxyz123456e1:q9:find_node1:t2:aa1:y1:qe",
	"d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz123456e1:q9:get_peers1:t2:aa1:y1:qe",
	"d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz1234564:porti6881e5:token8:aoeusnthe1:q13:announce_peer1:t2:aa1:y1:qe",
    };
    ok[1]=ok[1];

    char *junk[] = {
	/* Wrong bencode */
	"foo",
	"i0e",
	"le",
	"1:x",
	/* No 'y' */
	"d1:ad2:id20:abcdefghij0123456789e1:q4:ping1:t2:aae"
	/* No 'q' */
	"d1:ad2:id20:abcdefghij0123456789e1:t2:aa1:y1:qe",
	/* Unknown 'q' value */
	"d1:ad2:id20:abcdefghij0123456789e1:q3:foo:t2:aa1:y1:qe",
	/* No 't' */
	"d1:ad2:id20:abcdefghij01234567896:target20:mnopqrstuvwxyz123456e1:q9:find_node1:y1:qe",
	/* No arguments */
	"d1:q4:ping1:t2:aa1:y1:qe",
	"d1:q9:find_node1:t2:aa1:y1:qe",
	"d1:q9:get_peers1:t2:aa1:y1:qe",
	"d1:q13:announce_peer1:t2:aa1:y1:qe",
	/* Bad id */
	"d1:ad2:id19:bcdefghij0123456789e1:q4:ping1:t2:aa1:y1:qe",
	"d1:ad2:id21:+abcdefghij01234567896:target20:mnopqrstuvwxyz123456e1:q9:find_node1:t2:aa1:y1:qe",
	"d1:ad2:id0:9:info_hash20:mnopqrstuvwxyz123456e1:q9:get_peers1:t2:aa1:y1:qe",
	"d1:ad2:idi0e9:info_hash20:mnopqrstuvwxyz1234564:porti6881e5:token8:aoeusnthe1:q13:announce_peer1:t2:aa1:y1:qe",
	/* find_node target */
	"d1:ad2:id20:abcdefghij0123456789e1:q9:find_node1:t2:aa1:y1:qe",
	"d1:ad2:id20:abcdefghij01234567896:target19:nopqrstuvwxyz123456e1:q9:find_node1:t2:aa1:y1:qe",
	/* get_peers info_hash */
	"d1:ad2:id20:abcdefghij01234567899:info_h___20:mnopqrstuvwxyz123456e1:q9:get_peers1:t2:aa1:y1:qe",
	"d1:ad2:id20:abcdefghij01234567899:info_hash0:e1:q9:get_peers1:t2:aa1:y1:qe",
	"d1:ad2:id20:abcdefghij01234567899:info_hashi0ee1:q9:get_peers1:t2:aa1:y1:qe",
	/* announce_peer info_hash */
	"d1:ad2:id20:abcdefghij01234567899:info_h___0:mnopqrstuvwxyz1234564:porti6881e5:token8:aoeusnthe1:q13:announce_peer1:t2:aa1:y1:qe",
	"d1:ad2:id20:abcdefghij01234567899:info_hash1:x4:porti6881e5:token8:aoeusnthe1:q13:announce_peer1:t2:aa1:y1:qe",
	"d1:ad2:id20:abcdefghij01234567899:info_hashi0e4:porti6881e5:token8:aoeusnthe1:q13:announce_peer1:t2:aa1:y1:qe",
	/* announce_peer port */
	"d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz1234564:po__i6881e5:token8:aoeusnthe1:q13:announce_peer1:t2:aa1:y1:qe",
	"d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz1234564:port4:68815:token8:aoeusnthe1:q13:announce_peer1:t2:aa1:y1:qe",
	"d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz1234564:porti65536e5:token8:aoeusnthe1:q13:announce_peer1:t2:aa1:y1:qe",
	"d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz1234564:porti18446744073709551616e5:token8:aoeusnthe1:q13:announce_peer1:t2:aa1:y1:qe",
	"d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz1234564:porti-1e5:token8:aoeusnthe1:q13:announce_peer1:t2:aa1:y1:qe",
	/* announce_peer token */
	"d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz1234564:porti6881e5:to___8:aoeusnthe1:q13:announce_peer1:t2:aa1:y1:qe",
	"d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz1234564:porti6881e5:tokeni0ee1:q13:announce_peer1:t2:aa1:y1:qe",
	NULL
    };

    int i = 0;
    while (junk[i])
    {
	Message *result = Message_Decode(junk[i], strlen(junk[i]), NULL);
        mu_assert(result != NULL, "Message_Decode failed");
        mu_assert(result->errors, "Junk decoded without errors");
        Message_Destroy(result);
	i++;
    }

    return NULL;
}