Пример #1
0
/* return 1 on success.
 * return 0 if could not send packet.
 * return -1 on failure (connection must be killed).
 */
static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const uint8_t *data, uint16_t length,
        bool priority)
{
    if (length + CRYPTO_MAC_SIZE > MAX_PACKET_SIZE) {
        return -1;
    }

    bool sendpriority = 1;

    if (send_pending_data(con) == -1) {
        if (priority) {
            sendpriority = 0;
        } else {
            return 0;
        }
    }

    VLA(uint8_t, packet, sizeof(uint16_t) + length + CRYPTO_MAC_SIZE);

    uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE);
    memcpy(packet, &c_length, sizeof(uint16_t));
    int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));

    if ((unsigned int)len != (SIZEOF_VLA(packet) - sizeof(uint16_t))) {
        return -1;
    }

    if (priority) {
        len = sendpriority ? send(con->sock, (const char *)packet, SIZEOF_VLA(packet), MSG_NOSIGNAL) : 0;

        if (len <= 0) {
            len = 0;
        }

        increment_nonce(con->sent_nonce);

        if ((unsigned int)len == SIZEOF_VLA(packet)) {
            return 1;
        }

        return add_priority(con, packet, SIZEOF_VLA(packet), len);
    }

    len = send(con->sock, (const char *)packet, SIZEOF_VLA(packet), MSG_NOSIGNAL);

    if (len <= 0) {
        return 0;
    }

    increment_nonce(con->sent_nonce);

    if ((unsigned int)len == SIZEOF_VLA(packet)) {
        return 1;
    }

    memcpy(con->last_packet, packet, SIZEOF_VLA(packet));
    con->last_packet_length = SIZEOF_VLA(packet);
    con->last_packet_sent = len;
    return 1;
}
Пример #2
0
static int handle_onion_recv_1(void *object, IP_Port dest, const uint8_t *data, uint16_t length)
{
    TCP_Server *TCP_server = (TCP_Server *)object;
    uint32_t index = dest.ip.ip6.uint32[0];

    if (index >= TCP_server->size_accepted_connections) {
        return 1;
    }

    TCP_Secure_Connection *con = &TCP_server->accepted_connection_array[index];

    if (con->identifier != dest.ip.ip6.uint64[1]) {
        return 1;
    }

    VLA(uint8_t, packet, 1 + length);
    memcpy(packet + 1, data, length);
    packet[0] = TCP_PACKET_ONION_RESPONSE;

    if (write_packet_TCP_secure_connection(con, packet, SIZEOF_VLA(packet), 0) != 1) {
        return 1;
    }

    return 0;
}
Пример #3
0
static int handle_data_request(void *object, IP_Port source, const uint8_t *packet, uint16_t length, void *userdata)
{
    Onion_Announce *onion_a = (Onion_Announce *)object;

    if (length <= DATA_REQUEST_MIN_SIZE_RECV) {
        return 1;
    }

    if (length > ONION_MAX_PACKET_SIZE) {
        return 1;
    }

    int index = in_entries(onion_a, packet + 1);

    if (index == -1) {
        return 1;
    }

    VLA(uint8_t, data, length - (CRYPTO_PUBLIC_KEY_SIZE + ONION_RETURN_3));
    data[0] = NET_PACKET_ONION_DATA_RESPONSE;
    memcpy(data + 1, packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, length - (1 + CRYPTO_PUBLIC_KEY_SIZE + ONION_RETURN_3));

    if (send_onion_response(onion_a->net, onion_a->entries[index].ret_ip_port, data, SIZEOF_VLA(data),
                            onion_a->entries[index].ret) == -1) {
        return 1;
    }

    return 0;
}
Пример #4
0
/* return 1 on success.
 * return 0 if could not send packet.
 * return -1 on failure (connection must be killed).
 */
int send_onion_request(TCP_Client_Connection *con, const uint8_t *data, uint16_t length)
{
    VLA(uint8_t, packet, 1 + length);
    packet[0] = TCP_PACKET_ONION_REQUEST;
    memcpy(packet + 1, data, length);
    return write_packet_TCP_secure_connection(con, packet, SIZEOF_VLA(packet), 0);
}
Пример #5
0
static void set_random(Tox *m, bool (*setter)(Tox *, const uint8_t *, size_t, Tox_Err_Set_Info *), size_t length)
{
    VLA(uint8_t, text, length);
    uint32_t i;

    for (i = 0; i < length; ++i) {
        text[i] = random_u08();
    }

    setter(m, text, SIZEOF_VLA(text), nullptr);
}
Пример #6
0
static void set_random(Tox *m, bool (*setter)(Tox *, const uint8_t *, size_t, TOX_ERR_SET_INFO *), size_t length)
{
    VLA(uint8_t, text, length);
    uint32_t i;

    for (i = 0; i < length; ++i) {
        text[i] = rand();
    }

    setter(m, text, SIZEOF_VLA(text), 0);
}
Пример #7
0
/* return 1 on success.
 * return 0 if could not send packet.
 * return -1 on failure.
 */
int send_oob_packet(TCP_Client_Connection *con, const uint8_t *public_key, const uint8_t *data, uint16_t length)
{
    if (length == 0 || length > TCP_MAX_OOB_DATA_LENGTH) {
        return -1;
    }

    VLA(uint8_t, packet, 1 + CRYPTO_PUBLIC_KEY_SIZE + length);
    packet[0] = TCP_PACKET_OOB_SEND;
    memcpy(packet + 1, public_key, CRYPTO_PUBLIC_KEY_SIZE);
    memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length);
    return write_packet_TCP_secure_connection(con, packet, SIZEOF_VLA(packet), 0);
}
Пример #8
0
/* return 1 on success.
 * return 0 if could not send packet.
 * return -1 on failure.
 */
int send_data(TCP_Client_Connection *con, uint8_t con_id, const uint8_t *data, uint16_t length)
{
    if (con_id >= NUM_CLIENT_CONNECTIONS) {
        return -1;
    }

    if (con->connections[con_id].status != 2) {
        return -1;
    }

    if (send_ping_response(con) == 0 || send_ping_request(con) == 0) {
        return 0;
    }

    VLA(uint8_t, packet, 1 + length);
    packet[0] = con_id + NUM_RESERVED_PORTS;
    memcpy(packet + 1, data, length);
    return write_packet_TCP_secure_connection(con, packet, SIZEOF_VLA(packet), 0);
}
Пример #9
0
/* return 0 on success.
 * return -1 on failure (connection must be killed).
 */
static int handle_TCP_oob_send(TCP_Server *TCP_server, uint32_t con_id, const uint8_t *public_key, const uint8_t *data,
                               uint16_t length)
{
    if (length == 0 || length > TCP_MAX_OOB_DATA_LENGTH) {
        return -1;
    }

    TCP_Secure_Connection *con = &TCP_server->accepted_connection_array[con_id];

    int other_index = get_TCP_connection_index(TCP_server, public_key);

    if (other_index != -1) {
        VLA(uint8_t, resp_packet, 1 + CRYPTO_PUBLIC_KEY_SIZE + length);
        resp_packet[0] = TCP_PACKET_OOB_RECV;
        memcpy(resp_packet + 1, con->public_key, CRYPTO_PUBLIC_KEY_SIZE);
        memcpy(resp_packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, data, length);
        write_packet_TCP_secure_connection(&TCP_server->accepted_connection_array[other_index], resp_packet,
                                           SIZEOF_VLA(resp_packet), 0);
    }

    return 0;
}
Пример #10
0
/* Send a Friend request packet.
 *
 *  return -1 if failure.
 *  return  0 if it sent the friend request directly to the friend.
 *  return the number of peers it was routed through if it did not send it directly.
 */
int send_friend_request_packet(Friend_Connections *fr_c, int friendcon_id, uint32_t nospam_num, const uint8_t *data,
                               uint16_t length)
{
    if (1 + sizeof(nospam_num) + length > ONION_CLIENT_MAX_DATA_SIZE || length == 0) {
        return -1;
    }

    const Friend_Conn *const friend_con = get_conn(fr_c, friendcon_id);

    if (!friend_con) {
        return -1;
    }

    VLA(uint8_t, packet, 1 + sizeof(nospam_num) + length);
    memcpy(packet + 1, &nospam_num, sizeof(nospam_num));
    memcpy(packet + 1 + sizeof(nospam_num), data, length);

    if (friend_con->status == FRIENDCONN_STATUS_CONNECTED) {
        packet[0] = PACKET_ID_FRIEND_REQUESTS;
        return write_cryptpacket(fr_c->net_crypto, friend_con->crypt_connection_id, packet, SIZEOF_VLA(packet), 0) != -1;
    }

    packet[0] = CRYPTO_PACKET_FRIEND_REQ;
    const int num = send_onion_data(fr_c->onion_c, friend_con->onion_friendnum, packet, SIZEOF_VLA(packet));

    if (num <= 0) {
        return -1;
    }

    return num;
}