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
150
151
152
153
154
155
156
157
|
/*
* onion_client.h -- Implementation of the client part of docs/Prevent_Tracking.txt
* (The part that uses the onion stuff to connect to the friend)
*
* Copyright (C) 2013 Tox project All Rights Reserved.
*
* This file is part of Tox.
*
* Tox is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tox is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ONION_CLIENT_H
#define ONION_CLIENT_H
#include "onion_announce.h"
#define MAX_ONION_CLIENTS 8
#define ONION_NODE_TIMEOUT 240
/* The interval in seconds at which to tell our friends where we are */
#define ONION_FAKEID_INTERVAL 30
#define DHT_FAKEID_INTERVAL 20
typedef struct {
uint8_t client_id[CLIENT_ID_SIZE];
IP_Port ip_port;
uint8_t ping_id[ONION_PING_ID_SIZE];
uint8_t data_public_key[crypto_box_PUBLICKEYBYTES];
uint8_t is_stored;
uint64_t timestamp;
uint64_t last_pinged;
} Onion_Node;
typedef struct {
uint8_t status; /* 0 if friend is not valid, 1 if friend is valid.*/
uint8_t is_online; /* Set by the onion_set_friend_status function. */
uint8_t is_fake_clientid; /* 0 if we don't know the fake client id of the other 1 if we do. */
uint8_t fake_client_id[crypto_box_PUBLICKEYBYTES];
uint8_t real_client_id[crypto_box_PUBLICKEYBYTES];
Onion_Node clients_list[MAX_ONION_CLIENTS];
uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES];
uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES];
uint64_t last_fakeid_onion_sent;
uint64_t last_fakeid_dht_sent;
uint64_t last_noreplay;
} Onion_Friend;
typedef int (*oniondata_handler_callback)(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t len);
typedef struct {
DHT *dht;
Networking_Core *net;
Onion_Friend *friends_list;
uint16_t num_friends;
Onion_Node clients_announce_list[MAX_ONION_CLIENTS];
uint8_t secret_symmetric_key[crypto_secretbox_KEYBYTES];
uint64_t last_run;
uint8_t temp_public_key[crypto_box_PUBLICKEYBYTES];
uint8_t temp_secret_key[crypto_box_SECRETKEYBYTES];
struct {
oniondata_handler_callback function;
void *object;
} Onion_Data_Handlers[256];
} Onion_Client;
/* Add a friend who we want to connect to.
*
* return -1 on failure.
* return the friend number on success or if the friend was already added.
*/
int onion_friend_num(Onion_Client *onion_c, uint8_t *client_id);
/* Add a friend who we want to connect to.
*
* return -1 on failure.
* return the friend number on success.
*/
int onion_addfriend(Onion_Client *onion_c, uint8_t *client_id);
/* Delete a friend.
*
* return -1 on failure.
* return the deleted friend number on success.
*/
int onion_delfriend(Onion_Client *onion_c, int friend_num);
/* Set if friend is online or not.
* NOTE: This function is there and should be used so that we don't send useless packets to the friend if he is online.
*
* is_online 1 means friend is online.
* is_online 0 means friend is offline
*
* return -1 on failure.
* return 0 on success.
*/
int onion_set_friend_online(Onion_Client *onion_c, int friend_num, uint8_t is_online);
/* Get the ip of friend friendnum and put it in ip_port
*
* return -1, -- if client_id does NOT refer to a friend
* return 0, -- if client_id refers to a friend and we failed to find the friend (yet)
* return 1, ip if client_id refers to a friend and we found him
*
*/
int onion_getfriendip(Onion_Client *onion_c, int friend_num, IP_Port *ip_port);
/* Takes 3 random nodes that we know and puts them in nodes
*
* nodes must be longer than 3.
*
* return -1 on failure
* return 0 on success
*
*/
int random_path(Onion_Client *onion_c, Node_format *nodes);
/* Send data of length length to friendnum.
* This data will be recieved by the friend using the Onion_Data_Handlers callbacks.
*
* Even if this function succeeds, the friend might not recieve any data.
*
* return the number of packets sent on success
* return -1 on failure.
*/
int send_onion_data(Onion_Client *onion_c, int friend_num, uint8_t *data, uint32_t length);
/* Function to call when onion data packet with contents beginning with byte is received. */
void oniondata_registerhandler(Onion_Client *onion_c, uint8_t byte, oniondata_handler_callback cb, void *object);
void do_onion_client(Onion_Client *onion_c);
Onion_Client *new_onion_client(DHT *dht);
void kill_onion_client(Onion_Client *onion_c);
#endif
|