summaryrefslogtreecommitdiff
path: root/protocols/Tox/libtox/src/toxcore/tox_private.c
blob: 847e96d426241af42c28a93d8c424afde190d82c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/* SPDX-License-Identifier: GPL-3.0-or-later
 * Copyright © 2016-2022 The TokTok team.
 * Copyright © 2013 Tox project.
 */

/**
 * The Tox private API (for tests).
 */
#include "tox_private.h"

#include <assert.h>

#include "ccompat.h"
#include "network.h"
#include "tox_struct.h"

#define SET_ERROR_PARAMETER(param, x) \
    do {                              \
        if (param != nullptr) {       \
            *param = x;               \
        }                             \
    } while (0)

Tox_System tox_default_system(void)
{
    const Tox_System sys = {
        nullptr,  // mono_time_callback
        nullptr,  // mono_time_user_data
        system_random(),
        system_network(),
    };
    return sys;
}

void tox_lock(const Tox *tox)
{
    if (tox->mutex != nullptr) {
        pthread_mutex_lock(tox->mutex);
    }
}

void tox_unlock(const Tox *tox)
{
    if (tox->mutex != nullptr) {
        pthread_mutex_unlock(tox->mutex);
    }
}

void tox_callback_friend_lossy_packet_per_pktid(Tox *tox, tox_friend_lossy_packet_cb *callback, uint8_t pktid)
{
    assert(tox != nullptr);

    if (pktid >= PACKET_ID_RANGE_LOSSY_START && pktid <= PACKET_ID_RANGE_LOSSY_END) {
        tox->friend_lossy_packet_callback_per_pktid[pktid] = callback;
    }
}

void tox_callback_friend_lossless_packet_per_pktid(Tox *tox, tox_friend_lossless_packet_cb *callback, uint8_t pktid)
{
    assert(tox != nullptr);

    if ((pktid >= PACKET_ID_RANGE_LOSSLESS_CUSTOM_START && pktid <= PACKET_ID_RANGE_LOSSLESS_CUSTOM_END)
            || pktid == PACKET_ID_MSI) {
        tox->friend_lossless_packet_callback_per_pktid[pktid] = callback;
    }
}

void tox_set_av_object(Tox *tox, void *object)
{
    assert(tox != nullptr);
    tox_lock(tox);
    tox->toxav_object = object;
    tox_unlock(tox);
}

void *tox_get_av_object(const Tox *tox)
{
    assert(tox != nullptr);
    tox_lock(tox);
    void *object = tox->toxav_object;
    tox_unlock(tox);
    return object;
}

void tox_callback_dht_get_nodes_response(Tox *tox, tox_dht_get_nodes_response_cb *callback)
{
    assert(tox != nullptr);
    tox->dht_get_nodes_response_callback = callback;
}

bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip, uint16_t port,
                       const uint8_t *target_public_key, Tox_Err_Dht_Get_Nodes *error)
{
    assert(tox != nullptr);

    tox_lock(tox);

    if (tox->m->options.udp_disabled) {
        SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_UDP_DISABLED);
        tox_unlock(tox);
        return false;
    }

    if (public_key == nullptr || ip == nullptr || target_public_key == nullptr) {
        SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_NULL);
        tox_unlock(tox);
        return false;
    }

    if (port == 0) {
        SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_BAD_PORT);
        tox_unlock(tox);
        return false;
    }

    IP_Port *root;

    const int32_t count = net_getipport(ip, &root, TOX_SOCK_DGRAM);

    if (count < 1) {
        SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_BAD_IP);
        net_freeipport(root);
        tox_unlock(tox);
        return false;
    }

    bool success = false;

    for (int32_t i = 0; i < count; ++i) {
        root[i].port = net_htons(port);

        if (dht_getnodes(tox->m->dht, &root[i], public_key, target_public_key)) {
            success = true;
        }
    }

    tox_unlock(tox);

    net_freeipport(root);

    if (!success) {
        SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_FAIL);
        return false;
    }

    SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_OK);

    return true;
}