summaryrefslogtreecommitdiff
path: root/toxcore/onion_announce.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore/onion_announce.c')
-rw-r--r--toxcore/onion_announce.c112
1 files changed, 87 insertions, 25 deletions
diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c
index 27d13a8f..dff05135 100644
--- a/toxcore/onion_announce.c
+++ b/toxcore/onion_announce.c
@@ -35,7 +35,7 @@
35#define DATA_REQUEST_MIN_SIZE ONION_DATA_REQUEST_MIN_SIZE 35#define DATA_REQUEST_MIN_SIZE ONION_DATA_REQUEST_MIN_SIZE
36#define DATA_REQUEST_MIN_SIZE_RECV (DATA_REQUEST_MIN_SIZE + ONION_RETURN_3) 36#define DATA_REQUEST_MIN_SIZE_RECV (DATA_REQUEST_MIN_SIZE + ONION_RETURN_3)
37 37
38/* Create and send an onion announce request packet. 38/* Create an onion announce request packet in packet of max_packet_length (recommended size ONION_MAX_PACKET_SIZE).
39 * 39 *
40 * path is the path the request will take before it is sent to dest. 40 * path is the path the request will take before it is sent to dest.
41 * 41 *
@@ -47,10 +47,11 @@
47 * receive back in the response. 47 * receive back in the response.
48 * 48 *
49 * return -1 on failure. 49 * return -1 on failure.
50 * return 0 on success. 50 * return packet length on success.
51 */ 51 */
52int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format dest, uint8_t *public_key, 52int create_announce_request(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, Node_format dest,
53 uint8_t *secret_key, uint8_t *ping_id, uint8_t *client_id, uint8_t *data_public_key, uint64_t sendback_data) 53 const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id,
54 const uint8_t *data_public_key, uint64_t sendback_data)
54{ 55{
55 uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES + 56 uint8_t plain[ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES +
56 ONION_ANNOUNCE_SENDBACK_DATA_LENGTH]; 57 ONION_ANNOUNCE_SENDBACK_DATA_LENGTH];
@@ -59,22 +60,22 @@ int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format de
59 memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES, data_public_key, crypto_box_PUBLICKEYBYTES); 60 memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES, data_public_key, crypto_box_PUBLICKEYBYTES);
60 memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES, &sendback_data, 61 memcpy(plain + ONION_PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_PUBLICKEYBYTES, &sendback_data,
61 sizeof(sendback_data)); 62 sizeof(sendback_data));
62 uint8_t packet[ANNOUNCE_REQUEST_SIZE]; 63 uint8_t temp[ANNOUNCE_REQUEST_SIZE];
63 packet[0] = NET_PACKET_ANNOUNCE_REQUEST; 64 temp[0] = NET_PACKET_ANNOUNCE_REQUEST;
64 random_nonce(packet + 1); 65 random_nonce(temp + 1);
65 66
66 int len = encrypt_data(dest.client_id, secret_key, packet + 1, plain, sizeof(plain), 67 int len = encrypt_data(dest.client_id, secret_key, temp + 1, plain, sizeof(plain),
67 packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES); 68 temp + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES);
68 69
69 if ((uint32_t)len + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES != ANNOUNCE_REQUEST_SIZE) 70 if ((uint32_t)len + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES != ANNOUNCE_REQUEST_SIZE)
70 return -1; 71 return -1;
71 72
72 memcpy(packet + 1 + crypto_box_NONCEBYTES, public_key, crypto_box_PUBLICKEYBYTES); 73 memcpy(temp + 1 + crypto_box_NONCEBYTES, public_key, crypto_box_PUBLICKEYBYTES);
73 74
74 return send_onion_packet(net, path, dest.ip_port, packet, sizeof(packet)); 75 return create_onion_packet(packet, max_packet_length, path, dest.ip_port, temp, sizeof(temp));
75} 76}
76 77
77/* Create and send an onion data request packet. 78/* Create an onion data request packet in packet of max_packet_length (recommended size ONION_MAX_PACKET_SIZE).
78 * 79 *
79 * path is the path the request will take before it is sent to dest. 80 * path is the path the request will take before it is sent to dest.
80 * (if dest knows the person with the public_key they should 81 * (if dest knows the person with the public_key they should
@@ -88,35 +89,96 @@ int send_announce_request(Networking_Core *net, Onion_Path *path, Node_format de
88 * return -1 on failure. 89 * return -1 on failure.
89 * return 0 on success. 90 * return 0 on success.
90 */ 91 */
91int send_data_request(Networking_Core *net, Onion_Path *path, IP_Port dest, uint8_t *public_key, 92int create_data_request(uint8_t *packet, uint16_t max_packet_length, const Onion_Path *path, IP_Port dest,
92 uint8_t *encrypt_public_key, uint8_t *nonce, uint8_t *data, uint16_t length) 93 const uint8_t *public_key, const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data,
94 uint16_t length)
93{ 95{
94 if ((unsigned int)DATA_REQUEST_MIN_SIZE + length > ONION_MAX_DATA_SIZE) 96 if ((unsigned int)DATA_REQUEST_MIN_SIZE + length > ONION_MAX_DATA_SIZE)
95 return -1; 97 return -1;
96 98
97 uint8_t packet[DATA_REQUEST_MIN_SIZE + length]; 99 uint8_t temp[DATA_REQUEST_MIN_SIZE + length];
98 packet[0] = NET_PACKET_ONION_DATA_REQUEST; 100 temp[0] = NET_PACKET_ONION_DATA_REQUEST;
99 memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); 101 memcpy(temp + 1, public_key, crypto_box_PUBLICKEYBYTES);
100 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES); 102 memcpy(temp + 1 + crypto_box_PUBLICKEYBYTES, nonce, crypto_box_NONCEBYTES);
101 103
102 uint8_t random_public_key[crypto_box_PUBLICKEYBYTES]; 104 uint8_t random_public_key[crypto_box_PUBLICKEYBYTES];
103 uint8_t random_secret_key[crypto_box_SECRETKEYBYTES]; 105 uint8_t random_secret_key[crypto_box_SECRETKEYBYTES];
104 crypto_box_keypair(random_public_key, random_secret_key); 106 crypto_box_keypair(random_public_key, random_secret_key);
105 107
106 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, random_public_key, crypto_box_PUBLICKEYBYTES); 108 memcpy(temp + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, random_public_key, crypto_box_PUBLICKEYBYTES);
109
110 int len = encrypt_data(encrypt_public_key, random_secret_key, temp + 1 + crypto_box_PUBLICKEYBYTES,
111 data, length, temp + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES);
107 112
108 int len = encrypt_data(encrypt_public_key, random_secret_key, packet + 1 + crypto_box_PUBLICKEYBYTES, 113 if (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + (uint32_t)len != sizeof(temp))
109 data, length, packet + 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES); 114 return -1;
115
116 return create_onion_packet(packet, max_packet_length, path, dest, temp, sizeof(temp));
117}
118
119/* Create and send an onion announce request packet.
120 *
121 * path is the path the request will take before it is sent to dest.
122 *
123 * public_key and secret_key is the kepair which will be used to encrypt the request.
124 * ping_id is the ping id that will be sent in the request.
125 * client_id is the client id of the node we are searching for.
126 * data_public_key is the public key we want others to encrypt their data packets with.
127 * sendback_data is the data of ONION_ANNOUNCE_SENDBACK_DATA_LENGTH length that we expect to
128 * receive back in the response.
129 *
130 * return -1 on failure.
131 * return 0 on success.
132 */
133int send_announce_request(Networking_Core *net, const Onion_Path *path, Node_format dest, const uint8_t *public_key,
134 const uint8_t *secret_key, const uint8_t *ping_id, const uint8_t *client_id, const uint8_t *data_public_key,
135 uint64_t sendback_data)
136{
137 uint8_t packet[ONION_MAX_PACKET_SIZE];
138 int len = create_announce_request(packet, sizeof(packet), path, dest, public_key, secret_key, ping_id, client_id,
139 data_public_key, sendback_data);
140
141 if (len == -1)
142 return -1;
110 143
111 if (1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + (uint32_t)len != sizeof(packet)) 144 if (sendpacket(net, path->ip_port1, packet, len) != len)
112 return -1; 145 return -1;
113 146
114 return send_onion_packet(net, path, dest, packet, sizeof(packet)); 147 return 0;
148}
149
150/* Create and send an onion data request packet.
151 *
152 * path is the path the request will take before it is sent to dest.
153 * (if dest knows the person with the public_key they should
154 * send the packet to that person in the form of a response)
155 *
156 * public_key is the real public key of the node which we want to send the data of length length to.
157 * encrypt_public_key is the public key used to encrypt the data packet.
158 *
159 * nonce is the nonce to encrypt this packet with
160 *
161 * return -1 on failure.
162 * return 0 on success.
163 */
164int send_data_request(Networking_Core *net, const Onion_Path *path, IP_Port dest, const uint8_t *public_key,
165 const uint8_t *encrypt_public_key, const uint8_t *nonce, const uint8_t *data, uint16_t length)
166{
167 uint8_t packet[ONION_MAX_PACKET_SIZE];
168 int len = create_data_request(packet, sizeof(packet), path, dest, public_key, encrypt_public_key, nonce, data, length);
169
170 if (len == -1)
171 return -1;
172
173 if (sendpacket(net, path->ip_port1, packet, len) != len)
174 return -1;
175
176 return 0;
115} 177}
116 178
117/* Generate a ping_id and put it in ping_id */ 179/* Generate a ping_id and put it in ping_id */
118static void generate_ping_id(Onion_Announce *onion_a, uint64_t time, const uint8_t *public_key, IP_Port ret_ip_port, 180static void generate_ping_id(const Onion_Announce *onion_a, uint64_t time, const uint8_t *public_key,
119 uint8_t *ping_id) 181 IP_Port ret_ip_port, uint8_t *ping_id)
120{ 182{
121 time /= PING_ID_TIMEOUT; 183 time /= PING_ID_TIMEOUT;
122 uint8_t data[crypto_box_KEYBYTES + sizeof(time) + crypto_box_PUBLICKEYBYTES + sizeof(ret_ip_port)]; 184 uint8_t data[crypto_box_KEYBYTES + sizeof(time) + crypto_box_PUBLICKEYBYTES + sizeof(ret_ip_port)];