diff options
-rw-r--r-- | toxcore/TCP_connection.c | 153 | ||||
-rw-r--r-- | toxcore/TCP_connection.h | 35 |
2 files changed, 163 insertions, 25 deletions
diff --git a/toxcore/TCP_connection.c b/toxcore/TCP_connection.c index 328aa518..352a58d9 100644 --- a/toxcore/TCP_connection.c +++ b/toxcore/TCP_connection.c | |||
@@ -32,7 +32,7 @@ | |||
32 | * return -1 if realloc fails. | 32 | * return -1 if realloc fails. |
33 | * return 0 if it succeeds. | 33 | * return 0 if it succeeds. |
34 | */ | 34 | */ |
35 | #define realloc_tox_array(array, element_size, num, temp_pointer) (num ? (temp_pointer = realloc(array, num * element_size), temp_pointer ? (array = temp_pointer, 0) : (-1) ) : (free(array), array = NULL, 0)) | 35 | #define realloc_tox_array(array, element_size, num, temp_pointer) (num ? (temp_pointer = realloc(array, ((num) * (element_size))), temp_pointer ? (array = temp_pointer, 0) : (-1) ) : (free(array), array = NULL, 0)) |
36 | 36 | ||
37 | 37 | ||
38 | /* return 1 if the connections_number is not valid. | 38 | /* return 1 if the connections_number is not valid. |
@@ -199,7 +199,7 @@ static TCP_con *get_tcp_connection(const TCP_Connections *tcp_c, int tcp_connect | |||
199 | * return -1 on failure. | 199 | * return -1 on failure. |
200 | * return 0 on success. | 200 | * return 0 on success. |
201 | */ | 201 | */ |
202 | int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, uint8_t *packet, uint16_t length) | 202 | int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, const uint8_t *packet, uint16_t length) |
203 | { | 203 | { |
204 | TCP_Connection_to *con_to = get_connection(tcp_c, connections_number); | 204 | TCP_Connection_to *con_to = get_connection(tcp_c, connections_number); |
205 | 205 | ||
@@ -217,7 +217,7 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, u | |||
217 | uint8_t status = con_to->connections[i].status; | 217 | uint8_t status = con_to->connections[i].status; |
218 | uint8_t connection_id = con_to->connections[i].connection_id; | 218 | uint8_t connection_id = con_to->connections[i].connection_id; |
219 | 219 | ||
220 | if (tcp_con_num && status == TCP_CONN_CONNECTED) { | 220 | if (tcp_con_num && status == TCP_CONNECTIONS_STATUS_ONLINE) { |
221 | tcp_con_num -= 1; | 221 | tcp_con_num -= 1; |
222 | TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_con_num); | 222 | TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_con_num); |
223 | 223 | ||
@@ -236,7 +236,32 @@ int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, u | |||
236 | if (ret == 1) { | 236 | if (ret == 1) { |
237 | return 0; | 237 | return 0; |
238 | } else { | 238 | } else { |
239 | return -1; | 239 | for (i = 0; i < MAX_FRIEND_TCP_CONNECTIONS; ++i) { |
240 | uint32_t tcp_con_num = con_to->connections[i].tcp_connection; | ||
241 | uint8_t status = con_to->connections[i].status; | ||
242 | uint8_t connection_id = con_to->connections[i].connection_id; | ||
243 | |||
244 | if (tcp_con_num && status == TCP_CONNECTIONS_STATUS_REGISTERED) { | ||
245 | tcp_con_num -= 1; | ||
246 | TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_con_num); | ||
247 | |||
248 | if (!tcp_con) { | ||
249 | continue; | ||
250 | } | ||
251 | |||
252 | ret = send_oob_packet(tcp_con->connection, con_to->public_key, packet, length); | ||
253 | |||
254 | if (ret == 1) { | ||
255 | break; | ||
256 | } | ||
257 | } | ||
258 | } | ||
259 | |||
260 | if (ret == 1) { | ||
261 | return 0; | ||
262 | } else { | ||
263 | return -1; | ||
264 | } | ||
240 | } | 265 | } |
241 | } | 266 | } |
242 | 267 | ||
@@ -283,6 +308,27 @@ int tcp_send_onion_request(TCP_Connections *tcp_c, unsigned int tcp_connections_ | |||
283 | return -1; | 308 | return -1; |
284 | } | 309 | } |
285 | 310 | ||
311 | /* Send an oob packet via the TCP relay corresponding to tcp_connections_number. | ||
312 | * | ||
313 | * return 0 on success. | ||
314 | * return -1 on failure. | ||
315 | */ | ||
316 | int tcp_send_oob_packet(TCP_Connections *tcp_c, unsigned int tcp_connections_number, const uint8_t *public_key, | ||
317 | const uint8_t *packet, uint16_t length) | ||
318 | { | ||
319 | TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); | ||
320 | |||
321 | if (!tcp_con) | ||
322 | return -1; | ||
323 | |||
324 | int ret = send_oob_packet(tcp_con->connection, public_key, packet, length); | ||
325 | |||
326 | if (ret == 1) | ||
327 | return 0; | ||
328 | |||
329 | return -1; | ||
330 | } | ||
331 | |||
286 | /* Set the callback for TCP data packets. | 332 | /* Set the callback for TCP data packets. |
287 | */ | 333 | */ |
288 | void set_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_data_callback)(void *object, int id, | 334 | void set_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_data_callback)(void *object, int id, |
@@ -292,10 +338,10 @@ void set_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_data_c | |||
292 | tcp_c->tcp_data_callback_object = object; | 338 | tcp_c->tcp_data_callback_object = object; |
293 | } | 339 | } |
294 | 340 | ||
295 | /* Set the callback for TCP oob data packets. | 341 | /* Set the callback for TCP onion packets. |
296 | */ | 342 | */ |
297 | void set_oob_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_oob_callback)(void *object, | 343 | void set_oob_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_oob_callback)(void *object, |
298 | const uint8_t *public_key, const uint8_t *relay_pk, const uint8_t *data, uint16_t length), void *object) | 344 | const uint8_t *public_key, unsigned int tcp_connections_number, const uint8_t *data, uint16_t length), void *object) |
299 | { | 345 | { |
300 | tcp_c->tcp_oob_callback = tcp_oob_callback; | 346 | tcp_c->tcp_oob_callback = tcp_oob_callback; |
301 | tcp_c->tcp_oob_callback_object = object; | 347 | tcp_c->tcp_oob_callback_object = object; |
@@ -628,7 +674,7 @@ static int tcp_oob_callback(void *object, const uint8_t *public_key, const uint8 | |||
628 | memcpy(relay_pk, tcp_con->connection->public_key, crypto_box_PUBLICKEYBYTES); | 674 | memcpy(relay_pk, tcp_con->connection->public_key, crypto_box_PUBLICKEYBYTES); |
629 | 675 | ||
630 | if (tcp_c->tcp_oob_callback) | 676 | if (tcp_c->tcp_oob_callback) |
631 | tcp_c->tcp_oob_callback(tcp_c->tcp_oob_callback_object, public_key, relay_pk, data, length); | 677 | tcp_c->tcp_oob_callback(tcp_c->tcp_oob_callback_object, public_key, tcp_connections_number, data, length); |
632 | 678 | ||
633 | return 0; | 679 | return 0; |
634 | } | 680 | } |
@@ -694,6 +740,15 @@ static int tcp_relay_on_online(TCP_Connections *tcp_c, int tcp_connections_numbe | |||
694 | 740 | ||
695 | static int add_tcp_relay(TCP_Connections *tcp_c, IP_Port ip_port, const uint8_t *relay_pk) | 741 | static int add_tcp_relay(TCP_Connections *tcp_c, IP_Port ip_port, const uint8_t *relay_pk) |
696 | { | 742 | { |
743 | if (ip_port.ip.family == TCP_INET) { | ||
744 | ip_port.ip.family = AF_INET; | ||
745 | } else if (ip_port.ip.family == TCP_INET6) { | ||
746 | ip_port.ip.family = AF_INET6; | ||
747 | } | ||
748 | |||
749 | if (ip_port.ip.family != AF_INET && ip_port.ip.family != AF_INET6) | ||
750 | return -1; | ||
751 | |||
697 | int tcp_connections_number = create_tcp_connection(tcp_c); | 752 | int tcp_connections_number = create_tcp_connection(tcp_c); |
698 | 753 | ||
699 | if (tcp_connections_number == -1) | 754 | if (tcp_connections_number == -1) |
@@ -720,6 +775,11 @@ static int add_tcp_relay(TCP_Connections *tcp_c, IP_Port ip_port, const uint8_t | |||
720 | */ | 775 | */ |
721 | int add_tcp_relay_global(TCP_Connections *tcp_c, IP_Port ip_port, const uint8_t *relay_pk) | 776 | int add_tcp_relay_global(TCP_Connections *tcp_c, IP_Port ip_port, const uint8_t *relay_pk) |
722 | { | 777 | { |
778 | int tcp_connections_number = find_tcp_connection_relay(tcp_c, relay_pk); | ||
779 | |||
780 | if (tcp_connections_number != -1) | ||
781 | return -1; | ||
782 | |||
723 | if (add_tcp_relay(tcp_c, ip_port, relay_pk) == -1) | 783 | if (add_tcp_relay(tcp_c, ip_port, relay_pk) == -1) |
724 | return -1; | 784 | return -1; |
725 | 785 | ||
@@ -731,31 +791,46 @@ int add_tcp_relay_global(TCP_Connections *tcp_c, IP_Port ip_port, const uint8_t | |||
731 | * return 0 on success. | 791 | * return 0 on success. |
732 | * return -1 on failure. | 792 | * return -1 on failure. |
733 | */ | 793 | */ |
734 | int add_tcp_relay_connection(TCP_Connections *tcp_c, int connections_number, IP_Port ip_port, const uint8_t *relay_pk) | 794 | int add_tcp_number_relay_connection(TCP_Connections *tcp_c, int connections_number, unsigned int tcp_connections_number) |
735 | { | 795 | { |
736 | TCP_Connection_to *con_to = get_connection(tcp_c, connections_number); | 796 | TCP_Connection_to *con_to = get_connection(tcp_c, connections_number); |
737 | 797 | ||
738 | if (!con_to) | 798 | if (!con_to) |
739 | return -1; | 799 | return -1; |
740 | 800 | ||
741 | int tcp_connections_number = find_tcp_connection_relay(tcp_c, relay_pk); | 801 | TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); |
742 | 802 | ||
743 | if (tcp_connections_number != -1) { | 803 | if (!tcp_con) |
744 | if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1) | 804 | return -1; |
745 | return -1; | ||
746 | 805 | ||
747 | TCP_con *tcp_con = get_tcp_connection(tcp_c, tcp_connections_number); | 806 | if (add_tcp_connection_to_conn(con_to, tcp_connections_number) == -1) |
807 | return -1; | ||
748 | 808 | ||
749 | if (!tcp_con) | 809 | ++tcp_con->lock_count; |
750 | return -1; | ||
751 | 810 | ||
752 | ++tcp_con->lock_count; | 811 | if (tcp_con->status == TCP_CONN_CONNECTED) { |
812 | send_tcp_relay_routing_request(tcp_c, tcp_connections_number, con_to->public_key); | ||
813 | } | ||
753 | 814 | ||
754 | if (tcp_con->status == TCP_CONN_CONNECTED) { | 815 | return 0; |
755 | send_tcp_relay_routing_request(tcp_c, tcp_connections_number, con_to->public_key); | 816 | } |
756 | } | ||
757 | 817 | ||
758 | return 0; | 818 | /* Add a TCP relay tied to a connection. |
819 | * | ||
820 | * return 0 on success. | ||
821 | * return -1 on failure. | ||
822 | */ | ||
823 | int add_tcp_relay_connection(TCP_Connections *tcp_c, int connections_number, IP_Port ip_port, const uint8_t *relay_pk) | ||
824 | { | ||
825 | TCP_Connection_to *con_to = get_connection(tcp_c, connections_number); | ||
826 | |||
827 | if (!con_to) | ||
828 | return -1; | ||
829 | |||
830 | int tcp_connections_number = find_tcp_connection_relay(tcp_c, relay_pk); | ||
831 | |||
832 | if (tcp_connections_number != -1) { | ||
833 | return add_tcp_number_relay_connection(tcp_c, connections_number, tcp_connections_number); | ||
759 | } else { | 834 | } else { |
760 | int tcp_connections_number = add_tcp_relay(tcp_c, ip_port, relay_pk); | 835 | int tcp_connections_number = add_tcp_relay(tcp_c, ip_port, relay_pk); |
761 | 836 | ||
@@ -773,6 +848,40 @@ int add_tcp_relay_connection(TCP_Connections *tcp_c, int connections_number, IP_ | |||
773 | } | 848 | } |
774 | } | 849 | } |
775 | 850 | ||
851 | /* Copy a maximum of max_num TCP relays we are connected to to tcp_relays. | ||
852 | * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6. | ||
853 | * | ||
854 | * return number of relays copied to tcp_relays on success. | ||
855 | * return 0 on failure. | ||
856 | */ | ||
857 | unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num) | ||
858 | { | ||
859 | unsigned int i, copied = 0; | ||
860 | |||
861 | for (i = 0; (i < tcp_c->tcp_connections_length) && (copied < max_num); ++i) { | ||
862 | TCP_con *tcp_con = get_tcp_connection(tcp_c, i); | ||
863 | |||
864 | if (!tcp_con) { | ||
865 | continue; | ||
866 | } | ||
867 | |||
868 | if (tcp_con->status == TCP_CONN_CONNECTED) { | ||
869 | memcpy(tcp_relays[copied].public_key, tcp_con->connection->public_key, crypto_box_PUBLICKEYBYTES); | ||
870 | tcp_relays[copied].ip_port = tcp_con->connection->ip_port; | ||
871 | |||
872 | if (tcp_relays[copied].ip_port.ip.family == AF_INET) { | ||
873 | tcp_relays[copied].ip_port.ip.family = TCP_INET; | ||
874 | } else if (tcp_relays[copied].ip_port.ip.family == AF_INET6) { | ||
875 | tcp_relays[copied].ip_port.ip.family = TCP_INET6; | ||
876 | } | ||
877 | |||
878 | ++copied; | ||
879 | } | ||
880 | } | ||
881 | |||
882 | return copied; | ||
883 | } | ||
884 | |||
776 | TCP_Connections *new_tcp_connections(DHT *dht) | 885 | TCP_Connections *new_tcp_connections(DHT *dht) |
777 | { | 886 | { |
778 | if (dht == NULL) | 887 | if (dht == NULL) |
@@ -797,6 +906,9 @@ static void do_tcp_conns(TCP_Connections *tcp_c) | |||
797 | if (tcp_con) { | 906 | if (tcp_con) { |
798 | do_TCP_connection(tcp_con->connection); | 907 | do_TCP_connection(tcp_con->connection); |
799 | 908 | ||
909 | /* callbacks can change TCP connection address. */ | ||
910 | tcp_con = get_tcp_connection(tcp_c, i); | ||
911 | |||
800 | if (tcp_con->connection->status == TCP_CLIENT_DISCONNECTED) { | 912 | if (tcp_con->connection->status == TCP_CLIENT_DISCONNECTED) { |
801 | kill_tcp_relay_connection(tcp_c, i); | 913 | kill_tcp_relay_connection(tcp_c, i); |
802 | continue; | 914 | continue; |
@@ -831,6 +943,7 @@ static void kill_nonused_tcp(TCP_Connections *tcp_c) | |||
831 | 943 | ||
832 | void do_tcp_connections(TCP_Connections *tcp_c) | 944 | void do_tcp_connections(TCP_Connections *tcp_c) |
833 | { | 945 | { |
946 | //TODO reconnect to TCP relays if disconnects happen. | ||
834 | do_tcp_conns(tcp_c); | 947 | do_tcp_conns(tcp_c); |
835 | kill_nonused_tcp(tcp_c); | 948 | kill_nonused_tcp(tcp_c); |
836 | } | 949 | } |
diff --git a/toxcore/TCP_connection.h b/toxcore/TCP_connection.h index fc7925a3..2c86304f 100644 --- a/toxcore/TCP_connection.h +++ b/toxcore/TCP_connection.h | |||
@@ -68,8 +68,8 @@ typedef struct { | |||
68 | int (*tcp_data_callback)(void *object, int id, const uint8_t *data, uint16_t length); | 68 | int (*tcp_data_callback)(void *object, int id, const uint8_t *data, uint16_t length); |
69 | void *tcp_data_callback_object; | 69 | void *tcp_data_callback_object; |
70 | 70 | ||
71 | int (*tcp_oob_callback)(void *object, const uint8_t *public_key, const uint8_t *relay_pk, const uint8_t *data, | 71 | int (*tcp_oob_callback)(void *object, const uint8_t *public_key, unsigned int tcp_connections_number, |
72 | uint16_t length); | 72 | const uint8_t *data, uint16_t length); |
73 | void *tcp_oob_callback_object; | 73 | void *tcp_oob_callback_object; |
74 | 74 | ||
75 | int (*tcp_onion_callback)(void *object, const uint8_t *data, uint16_t length); | 75 | int (*tcp_onion_callback)(void *object, const uint8_t *data, uint16_t length); |
@@ -83,7 +83,7 @@ typedef struct { | |||
83 | * return -1 on failure. | 83 | * return -1 on failure. |
84 | * return 0 on success. | 84 | * return 0 on success. |
85 | */ | 85 | */ |
86 | int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, uint8_t *packet, uint16_t length); | 86 | int send_packet_tcp_connection(TCP_Connections *tcp_c, int connections_number, const uint8_t *packet, uint16_t length); |
87 | 87 | ||
88 | /* Return a random TCP connection number for use in send_tcp_onion_request. | 88 | /* Return a random TCP connection number for use in send_tcp_onion_request. |
89 | * | 89 | * |
@@ -103,12 +103,20 @@ int get_random_tcp_conn_number(TCP_Connections *tcp_c); | |||
103 | int tcp_send_onion_request(TCP_Connections *tcp_c, unsigned int tcp_connections_number, const uint8_t *data, | 103 | int tcp_send_onion_request(TCP_Connections *tcp_c, unsigned int tcp_connections_number, const uint8_t *data, |
104 | uint16_t length); | 104 | uint16_t length); |
105 | 105 | ||
106 | /* Send an oob packet via the TCP relay corresponding to tcp_connections_number. | ||
107 | * | ||
108 | * return 0 on success. | ||
109 | * return -1 on failure. | ||
110 | */ | ||
111 | int tcp_send_oob_packet(TCP_Connections *tcp_c, unsigned int tcp_connections_number, const uint8_t *public_key, | ||
112 | const uint8_t *packet, uint16_t length); | ||
113 | |||
106 | /* Set the callback for TCP data packets. | 114 | /* Set the callback for TCP data packets. |
107 | */ | 115 | */ |
108 | void set_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_data_callback)(void *object, int id, | 116 | void set_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_data_callback)(void *object, int id, |
109 | const uint8_t *data, uint16_t length), void *object); | 117 | const uint8_t *data, uint16_t length), void *object); |
110 | 118 | ||
111 | /* Set the callback for TCP oob data packets. | 119 | /* Set the callback for TCP onion packets. |
112 | */ | 120 | */ |
113 | void set_onion_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_onion_callback)(void *object, | 121 | void set_onion_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_onion_callback)(void *object, |
114 | const uint8_t *data, uint16_t length), void *object); | 122 | const uint8_t *data, uint16_t length), void *object); |
@@ -116,7 +124,7 @@ void set_onion_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_ | |||
116 | /* Set the callback for TCP oob data packets. | 124 | /* Set the callback for TCP oob data packets. |
117 | */ | 125 | */ |
118 | void set_oob_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_oob_callback)(void *object, | 126 | void set_oob_packet_tcp_connection_callback(TCP_Connections *tcp_c, int (*tcp_oob_callback)(void *object, |
119 | const uint8_t *public_key, const uint8_t *relay_pk, const uint8_t *data, uint16_t length), void *object); | 127 | const uint8_t *public_key, unsigned int tcp_connections_number, const uint8_t *data, uint16_t length), void *object); |
120 | 128 | ||
121 | /* Create a new TCP connection to public_key. | 129 | /* Create a new TCP connection to public_key. |
122 | * | 130 | * |
@@ -134,6 +142,16 @@ int kill_tcp_connection_to(TCP_Connections *tcp_c, int connections_number); | |||
134 | 142 | ||
135 | /* Add a TCP relay tied to a connection. | 143 | /* Add a TCP relay tied to a connection. |
136 | * | 144 | * |
145 | * NOTE: This can only be used during the tcp_oob_callback. | ||
146 | * | ||
147 | * return 0 on success. | ||
148 | * return -1 on failure. | ||
149 | */ | ||
150 | int add_tcp_number_relay_connection(TCP_Connections *tcp_c, int connections_number, | ||
151 | unsigned int tcp_connections_number); | ||
152 | |||
153 | /* Add a TCP relay tied to a connection. | ||
154 | * | ||
137 | * return 0 on success. | 155 | * return 0 on success. |
138 | * return -1 on failure. | 156 | * return -1 on failure. |
139 | */ | 157 | */ |
@@ -146,6 +164,13 @@ int add_tcp_relay_connection(TCP_Connections *tcp_c, int connections_number, IP_ | |||
146 | */ | 164 | */ |
147 | int add_tcp_relay_global(TCP_Connections *tcp_c, IP_Port ip_port, const uint8_t *relay_pk); | 165 | int add_tcp_relay_global(TCP_Connections *tcp_c, IP_Port ip_port, const uint8_t *relay_pk); |
148 | 166 | ||
167 | /* Copy a maximum of max_num TCP relays we are connected to to tcp_relays. | ||
168 | * NOTE that the family of the copied ip ports will be set to TCP_INET or TCP_INET6. | ||
169 | * | ||
170 | * return number of relays copied to tcp_relays on success. | ||
171 | * return 0 on failure. | ||
172 | */ | ||
173 | unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_relays, uint16_t max_num); | ||
149 | 174 | ||
150 | TCP_Connections *new_tcp_connections(DHT *dht); | 175 | TCP_Connections *new_tcp_connections(DHT *dht); |
151 | void do_tcp_connections(TCP_Connections *tcp_c); | 176 | void do_tcp_connections(TCP_Connections *tcp_c); |