Esempio n. 1
0
static uint8_t send_data(Group_Chat *chat, uint8_t *data, uint32_t len, uint8_t message_id)
{
    if (len + GROUP_DATA_MIN_SIZE > MAX_DATA_SIZE) /*NOTE: not the real maximum len.*/
        return 1;

    uint8_t packet[MAX_DATA_SIZE];
    ++chat->message_number;

    if (chat->message_number == 0)
        chat->message_number = 1;

    uint32_t message_num = htonl(chat->message_number);
//TODO
    id_copy(packet, chat->self_public_key);
    memcpy(packet + crypto_box_PUBLICKEYBYTES, &message_num, sizeof(message_num));
    memcpy(packet + GROUP_DATA_MIN_SIZE, data, len);
    packet[crypto_box_PUBLICKEYBYTES + sizeof(message_num)] = message_id;
    return sendto_allpeers(chat, packet, len + GROUP_DATA_MIN_SIZE, 50);
}
static int handle_data(Group_Chat *chat, uint8_t *data, uint32_t len)
{
    if (len < GROUP_DATA_MIN_SIZE)
        return 1;

//TODO:
    int peernum = peer_in_chat(chat, data);

    if (peernum == -1) { /*NOTE: This is just for testing and will be removed later.*/
        peernum = addpeer(chat, data);
    }

    if (peernum == -1)
        return 1;

    /* Spam prevention (1 message per peer per second limit.)

        if (chat->group[peernum].last_recv == temp_time)
            return 1;
    */
    chat->group[peernum].last_recv = unix_time();

    uint32_t message_num;
    memcpy(&message_num, data + crypto_box_PUBLICKEYBYTES, sizeof(uint32_t));
    message_num = ntohl(message_num);

    if (chat->group[peernum].last_message_number == 0) {
        chat->group[peernum].last_message_number = message_num;
    } else if (message_num - chat->group[peernum].last_message_number > 64 ||
               message_num == chat->group[peernum].last_message_number)
        return 1;

    chat->group[peernum].last_message_number = message_num;

    int handled = 1;
    uint8_t *contents = data + GROUP_DATA_MIN_SIZE;
    uint16_t contents_len = len - GROUP_DATA_MIN_SIZE;

    switch (data[crypto_box_PUBLICKEYBYTES + sizeof(message_num)]) {
        case GROUP_CHAT_PING: /* If message is ping */
            if (contents_len != 0)
                return 1;

            chat->group[peernum].last_recv_msgping = unix_time();
            break;

        case GROUP_CHAT_NEW_PEER: /* If message is new peer */
            if (contents_len != crypto_box_PUBLICKEYBYTES)
                return 1;

            addpeer(chat, contents);
            send_names_new_peer(chat);
            break;

        case GROUP_CHAT_PEER_NICK:
            if (contents_len > MAX_NICK_BYTES || contents_len == 0)
                return 1;

            setnick(chat, peernum, contents, contents_len);
            break;

        case GROUP_CHAT_CHAT_MESSAGE: /* If message is chat message */
            if (chat->group_message != NULL)
                (*chat->group_message)(chat, peernum, contents, contents_len, chat->group_message_userdata);

            break;

        default:
            handled = 0;
            break;

    }

    if (handled == 1) {
        sendto_allpeers(chat, data, len, CRYPTO_PACKET_GROUP_CHAT_BROADCAST);
        return 0;
    }

    return 1;
}