summaryrefslogtreecommitdiff
path: root/toxcore/TCP_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore/TCP_client.c')
-rw-r--r--toxcore/TCP_client.c178
1 files changed, 143 insertions, 35 deletions
diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c
index 087188f7..45220538 100644
--- a/toxcore/TCP_client.c
+++ b/toxcore/TCP_client.c
@@ -109,7 +109,7 @@ static int handle_handshake(TCP_Client_Connection *TCP_conn, const uint8_t *data
109/* return 0 if pending data was sent completely 109/* return 0 if pending data was sent completely
110 * return -1 if it wasn't 110 * return -1 if it wasn't
111 */ 111 */
112static int send_pending_data(TCP_Client_Connection *con) 112static int send_pending_data_nonpriority(TCP_Client_Connection *con)
113{ 113{
114 if (con->last_packet_length == 0) { 114 if (con->last_packet_length == 0) {
115 return 0; 115 return 0;
@@ -127,24 +127,95 @@ static int send_pending_data(TCP_Client_Connection *con)
127 return 0; 127 return 0;
128 } 128 }
129 129
130 if (len > left) 130 con->last_packet_sent += len;
131 return -1;
132}
133
134/* return 0 if pending data was sent completely
135 * return -1 if it wasn't
136 */
137static int send_pending_data(TCP_Client_Connection *con)
138{
139 /* finish sending current non-priority packet */
140 if (send_pending_data_nonpriority(con) == -1) {
131 return -1; 141 return -1;
142 }
143
144 TCP_Priority_List *p = con->priority_queue_start;
145
146 while (p) {
147 uint16_t left = p->size - p->sent;
148 int len = send(con->sock, p->data + p->sent, left, MSG_NOSIGNAL);
149
150 if (len != left) {
151 if (len > 0) {
152 p->sent += len;
153 }
154
155 break;
156 }
157
158 TCP_Priority_List *pp = p;
159 p = p->next;
160 free(pp);
161 }
162
163 con->priority_queue_start = p;
164
165 if (!p) {
166 con->priority_queue_end = NULL;
167 return 0;
168 }
132 169
133 con->last_packet_sent += len;
134 return -1; 170 return -1;
135} 171}
136 172
173/* return 0 on failure (only if malloc fails)
174 * return 1 on success
175 */
176static _Bool add_priority(TCP_Client_Connection *con, const uint8_t *packet, uint16_t size, uint16_t sent)
177{
178 TCP_Priority_List *p = con->priority_queue_end, *new;
179 new = malloc(sizeof(TCP_Priority_List) + size);
180
181 if (!new) {
182 return 0;
183 }
184
185 new->next = NULL;
186 new->size = size;
187 new->sent = sent;
188 memcpy(new->data, packet, size);
189
190 if (p) {
191 p->next = new;
192 } else {
193 con->priority_queue_start = new;
194 }
195
196 con->priority_queue_end = new;
197 return 1;
198}
199
137/* return 1 on success. 200/* return 1 on success.
138 * return 0 if could not send packet. 201 * return 0 if could not send packet.
139 * return -1 on failure (connection must be killed). 202 * return -1 on failure (connection must be killed).
140 */ 203 */
141static int write_packet_TCP_secure_connection(TCP_Client_Connection *con, const uint8_t *data, uint16_t length) 204static int write_packet_TCP_secure_connection(TCP_Client_Connection *con, const uint8_t *data, uint16_t length,
205 _Bool priority)
142{ 206{
143 if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE) 207 if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE)
144 return -1; 208 return -1;
145 209
146 if (send_pending_data(con) == -1) 210 _Bool sendpriority = 1;
147 return 0; 211
212 if (send_pending_data(con) == -1) {
213 if (priority) {
214 sendpriority = 0;
215 } else {
216 return 0;
217 }
218 }
148 219
149 uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES]; 220 uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES];
150 221
@@ -155,17 +226,33 @@ static int write_packet_TCP_secure_connection(TCP_Client_Connection *con, const
155 if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t))) 226 if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t)))
156 return -1; 227 return -1;
157 228
158 increment_nonce(con->sent_nonce); 229 if (priority) {
230 len = sendpriority ? send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL) : 0;
159 231
160 len = send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL); 232 if (len <= 0) {
233 len = 0;
234 }
161 235
162 if ((unsigned int)len == sizeof(packet)) 236 increment_nonce(con->sent_nonce);
163 return 1; 237
238 if (len == sizeof(packet)) {
239 return 1;
240 }
241
242 return add_priority(con, packet, sizeof(packet), len);
243 }
244
245 len = send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL);
164 246
165 if (len <= 0) 247 if (len <= 0)
166 return 0; 248 return 0;
167 249
168 memcpy(con->last_packet, packet, length); 250 increment_nonce(con->sent_nonce);
251
252 if ((unsigned int)len == sizeof(packet))
253 return 1;
254
255 memcpy(con->last_packet, packet, sizeof(packet));
169 con->last_packet_length = sizeof(packet); 256 con->last_packet_length = sizeof(packet);
170 con->last_packet_sent = len; 257 con->last_packet_sent = len;
171 return 1; 258 return 1;
@@ -180,7 +267,7 @@ int send_routing_request(TCP_Client_Connection *con, uint8_t *public_key)
180 uint8_t packet[1 + crypto_box_PUBLICKEYBYTES]; 267 uint8_t packet[1 + crypto_box_PUBLICKEYBYTES];
181 packet[0] = TCP_PACKET_ROUTING_REQUEST; 268 packet[0] = TCP_PACKET_ROUTING_REQUEST;
182 memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); 269 memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES);
183 return write_packet_TCP_secure_connection(con, packet, sizeof(packet)); 270 return write_packet_TCP_secure_connection(con, packet, sizeof(packet), 1);
184} 271}
185 272
186void routing_response_handler(TCP_Client_Connection *con, int (*response_callback)(void *object, uint8_t connection_id, 273void routing_response_handler(TCP_Client_Connection *con, int (*response_callback)(void *object, uint8_t connection_id,
@@ -197,6 +284,9 @@ void routing_status_handler(TCP_Client_Connection *con, int (*status_callback)(v
197 con->status_callback_object = object; 284 con->status_callback_object = object;
198} 285}
199 286
287static int send_ping_response(TCP_Client_Connection *con);
288static int send_ping_request(TCP_Client_Connection *con);
289
200/* return 1 on success. 290/* return 1 on success.
201 * return 0 if could not send packet. 291 * return 0 if could not send packet.
202 * return -1 on failure. 292 * return -1 on failure.
@@ -209,10 +299,13 @@ int send_data(TCP_Client_Connection *con, uint8_t con_id, const uint8_t *data, u
209 if (con->connections[con_id].status != 2) 299 if (con->connections[con_id].status != 2)
210 return -1; 300 return -1;
211 301
302 if (send_ping_response(con) == 0 || send_ping_request(con) == 0)
303 return 0;
304
212 uint8_t packet[1 + length]; 305 uint8_t packet[1 + length];
213 packet[0] = con_id + NUM_RESERVED_PORTS; 306 packet[0] = con_id + NUM_RESERVED_PORTS;
214 memcpy(packet + 1, data, length); 307 memcpy(packet + 1, data, length);
215 return write_packet_TCP_secure_connection(con, packet, sizeof(packet)); 308 return write_packet_TCP_secure_connection(con, packet, sizeof(packet), 0);
216} 309}
217 310
218/* return 1 on success. 311/* return 1 on success.
@@ -228,7 +321,7 @@ int send_oob_packet(TCP_Client_Connection *con, const uint8_t *public_key, const
228 packet[0] = TCP_PACKET_OOB_SEND; 321 packet[0] = TCP_PACKET_OOB_SEND;
229 memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); 322 memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES);
230 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, data, length); 323 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, data, length);
231 return write_packet_TCP_secure_connection(con, packet, sizeof(packet)); 324 return write_packet_TCP_secure_connection(con, packet, sizeof(packet), 0);
232} 325}
233 326
234 327
@@ -274,31 +367,49 @@ static int send_disconnect_notification(TCP_Client_Connection *con, uint8_t id)
274 uint8_t packet[1 + 1]; 367 uint8_t packet[1 + 1];
275 packet[0] = TCP_PACKET_DISCONNECT_NOTIFICATION; 368 packet[0] = TCP_PACKET_DISCONNECT_NOTIFICATION;
276 packet[1] = id; 369 packet[1] = id;
277 return write_packet_TCP_secure_connection(con, packet, sizeof(packet)); 370 return write_packet_TCP_secure_connection(con, packet, sizeof(packet), 1);
278} 371}
279 372
280/* return 1 on success. 373/* return 1 on success.
281 * return 0 if could not send packet. 374 * return 0 if could not send packet.
282 * return -1 on failure (connection must be killed). 375 * return -1 on failure (connection must be killed).
283 */ 376 */
284static int send_ping_request(TCP_Client_Connection *con, uint64_t ping_id) 377static int send_ping_request(TCP_Client_Connection *con)
285{ 378{
379 if (!con->ping_request_id)
380 return 1;
381
286 uint8_t packet[1 + sizeof(uint64_t)]; 382 uint8_t packet[1 + sizeof(uint64_t)];
287 packet[0] = TCP_PACKET_PING; 383 packet[0] = TCP_PACKET_PING;
288 memcpy(packet + 1, &ping_id, sizeof(uint64_t)); 384 memcpy(packet + 1, &con->ping_request_id, sizeof(uint64_t));
289 return write_packet_TCP_secure_connection(con, packet, sizeof(packet)); 385 int ret;
386
387 if ((ret = write_packet_TCP_secure_connection(con, packet, sizeof(packet), 1)) == 1) {
388 con->ping_request_id = 0;
389 }
390
391 return ret;
290} 392}
291 393
292/* return 1 on success. 394/* return 1 on success.
293 * return 0 if could not send packet. 395 * return 0 if could not send packet.
294 * return -1 on failure (connection must be killed). 396 * return -1 on failure (connection must be killed).
295 */ 397 */
296static int send_ping_response(TCP_Client_Connection *con, uint64_t ping_id) 398static int send_ping_response(TCP_Client_Connection *con)
297{ 399{
400 if (!con->ping_response_id)
401 return 1;
402
298 uint8_t packet[1 + sizeof(uint64_t)]; 403 uint8_t packet[1 + sizeof(uint64_t)];
299 packet[0] = TCP_PACKET_PONG; 404 packet[0] = TCP_PACKET_PONG;
300 memcpy(packet + 1, &ping_id, sizeof(uint64_t)); 405 memcpy(packet + 1, &con->ping_response_id, sizeof(uint64_t));
301 return write_packet_TCP_secure_connection(con, packet, sizeof(packet)); 406 int ret;
407
408 if ((ret = write_packet_TCP_secure_connection(con, packet, sizeof(packet), 1)) == 1) {
409 con->ping_response_id = 0;
410 }
411
412 return ret;
302} 413}
303 414
304/* return 1 on success. 415/* return 1 on success.
@@ -324,7 +435,7 @@ int send_onion_request(TCP_Client_Connection *con, const uint8_t *data, uint16_t
324 uint8_t packet[1 + length]; 435 uint8_t packet[1 + length];
325 packet[0] = TCP_PACKET_ONION_REQUEST; 436 packet[0] = TCP_PACKET_ONION_REQUEST;
326 memcpy(packet + 1, data, length); 437 memcpy(packet + 1, data, length);
327 return write_packet_TCP_secure_connection(con, packet, sizeof(packet)); 438 return write_packet_TCP_secure_connection(con, packet, sizeof(packet), 0);
328} 439}
329 440
330void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(void *object, const uint8_t *data, 441void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(void *object, const uint8_t *data,
@@ -427,7 +538,7 @@ static int handle_TCP_packet(TCP_Client_Connection *conn, const uint8_t *data, u
427 uint8_t con_id = data[1] - NUM_RESERVED_PORTS; 538 uint8_t con_id = data[1] - NUM_RESERVED_PORTS;
428 539
429 if (conn->connections[con_id].status != 1) 540 if (conn->connections[con_id].status != 1)
430 return -1; 541 return 0;
431 542
432 conn->connections[con_id].status = 2; 543 conn->connections[con_id].status = 2;
433 544
@@ -451,7 +562,7 @@ static int handle_TCP_packet(TCP_Client_Connection *conn, const uint8_t *data, u
451 return 0; 562 return 0;
452 563
453 if (conn->connections[con_id].status != 2) 564 if (conn->connections[con_id].status != 2)
454 return -1; 565 return 0;
455 566
456 conn->connections[con_id].status = 1; 567 conn->connections[con_id].status = 1;
457 568
@@ -468,7 +579,8 @@ static int handle_TCP_packet(TCP_Client_Connection *conn, const uint8_t *data, u
468 579
469 uint64_t ping_id; 580 uint64_t ping_id;
470 memcpy(&ping_id, data + 1, sizeof(uint64_t)); 581 memcpy(&ping_id, data + 1, sizeof(uint64_t));
471 send_ping_response(conn, ping_id); 582 conn->ping_response_id = ping_id;
583 send_ping_response(conn);
472 return 0; 584 return 0;
473 } 585 }
474 586
@@ -523,6 +635,9 @@ static int handle_TCP_packet(TCP_Client_Connection *conn, const uint8_t *data, u
523static int do_confirmed_TCP(TCP_Client_Connection *conn) 635static int do_confirmed_TCP(TCP_Client_Connection *conn)
524{ 636{
525 send_pending_data(conn); 637 send_pending_data(conn);
638 send_ping_response(conn);
639 send_ping_request(conn);
640
526 uint8_t packet[MAX_PACKET_SIZE]; 641 uint8_t packet[MAX_PACKET_SIZE];
527 int len; 642 int len;
528 643
@@ -532,16 +647,9 @@ static int do_confirmed_TCP(TCP_Client_Connection *conn)
532 if (!ping_id) 647 if (!ping_id)
533 ++ping_id; 648 ++ping_id;
534 649
535 int ret = send_ping_request(conn, ping_id); 650 conn->ping_request_id = conn->ping_id = ping_id;
536 651 send_ping_request(conn);
537 if (ret == 1) { 652 conn->last_pinged = unix_time();
538 conn->last_pinged = unix_time();
539 conn->ping_id = ping_id;
540 } else {
541 if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY + TCP_PING_TIMEOUT)) {
542 conn->status = TCP_CLIENT_DISCONNECTED;
543 }
544 }
545 } 653 }
546 654
547 if (conn->ping_id && is_timeout(conn->last_pinged, TCP_PING_TIMEOUT)) { 655 if (conn->ping_id && is_timeout(conn->last_pinged, TCP_PING_TIMEOUT)) {