diff options
author | irungentoo <irungentoo@gmail.com> | 2015-05-20 15:52:03 -0400 |
---|---|---|
committer | irungentoo <irungentoo@gmail.com> | 2015-05-20 15:52:03 -0400 |
commit | 7315ad08dde478f9f1c82b7a88aff46ce3f24888 (patch) | |
tree | f3225a052791d18a0f57f9cb8ee1ddcaba36958a | |
parent | 8760aba257b5f96d082a58abbc9fb4ca2dd73638 (diff) | |
parent | 782d68cdc34121c84837a41fa97dce03575e76a4 (diff) |
Merge branch 'tcp_server'
-rw-r--r-- | auto_tests/tox_test.c | 192 | ||||
-rw-r--r-- | other/apidsl/tox.in.h | 5 | ||||
-rw-r--r-- | testing/irc_syncbot.c | 20 | ||||
-rw-r--r-- | toxcore/LAN_discovery.c | 37 | ||||
-rw-r--r-- | toxcore/LAN_discovery.h | 3 | ||||
-rw-r--r-- | toxcore/Messenger.c | 38 | ||||
-rw-r--r-- | toxcore/Messenger.h | 3 | ||||
-rw-r--r-- | toxcore/friend_connection.c | 15 | ||||
-rw-r--r-- | toxcore/friend_connection.h | 2 | ||||
-rw-r--r-- | toxcore/onion_announce.h | 2 | ||||
-rw-r--r-- | toxcore/onion_client.c | 2 | ||||
-rw-r--r-- | toxcore/tox.c | 132 | ||||
-rw-r--r-- | toxcore/tox.h | 6 |
13 files changed, 394 insertions, 63 deletions
diff --git a/auto_tests/tox_test.c b/auto_tests/tox_test.c index 0dab2e69..142a178f 100644 --- a/auto_tests/tox_test.c +++ b/auto_tests/tox_test.c | |||
@@ -809,6 +809,196 @@ loop_top: | |||
809 | } | 809 | } |
810 | END_TEST | 810 | END_TEST |
811 | 811 | ||
812 | #define TCP_RELAY_PORT 33448 | ||
813 | |||
814 | START_TEST(test_many_clients_tcp) | ||
815 | { | ||
816 | long long unsigned int cur_time = time(NULL); | ||
817 | Tox *toxes[NUM_TOXES]; | ||
818 | uint32_t i, j; | ||
819 | uint32_t to_comp = 974536; | ||
820 | |||
821 | for (i = 0; i < NUM_TOXES; ++i) { | ||
822 | struct Tox_Options opts; | ||
823 | tox_options_default(&opts); | ||
824 | |||
825 | if (i == 0) { | ||
826 | opts.tcp_port = TCP_RELAY_PORT; | ||
827 | } else { | ||
828 | opts.udp_enabled = 0; | ||
829 | } | ||
830 | |||
831 | toxes[i] = tox_new(&opts, 0, 0, 0); | ||
832 | ck_assert_msg(toxes[i] != 0, "Failed to create tox instances %u", i); | ||
833 | tox_callback_friend_request(toxes[i], accept_friend_request, &to_comp); | ||
834 | uint8_t dpk[TOX_PUBLIC_KEY_SIZE]; | ||
835 | tox_self_get_dht_id(toxes[0], dpk); | ||
836 | ck_assert_msg(tox_add_tcp_relay(toxes[i], "::1", TCP_RELAY_PORT, dpk, 0), "add relay error"); | ||
837 | ck_assert_msg(tox_bootstrap(toxes[i], "::1", 33445, dpk, 0), "Bootstrap error"); | ||
838 | } | ||
839 | |||
840 | { | ||
841 | TOX_ERR_GET_PORT error; | ||
842 | ck_assert_msg(tox_self_get_udp_port(toxes[0], &error) == 33445, "First Tox instance did not bind to udp port 33445.\n"); | ||
843 | ck_assert_msg(error == TOX_ERR_GET_PORT_OK, "wrong error"); | ||
844 | ck_assert_msg(tox_self_get_tcp_port(toxes[0], &error) == TCP_RELAY_PORT, | ||
845 | "First Tox instance did not bind to tcp port %u.\n", TCP_RELAY_PORT); | ||
846 | ck_assert_msg(error == TOX_ERR_GET_PORT_OK, "wrong error"); | ||
847 | } | ||
848 | |||
849 | struct { | ||
850 | uint16_t tox1; | ||
851 | uint16_t tox2; | ||
852 | } pairs[NUM_FRIENDS]; | ||
853 | |||
854 | uint8_t address[TOX_ADDRESS_SIZE]; | ||
855 | |||
856 | for (i = 0; i < NUM_FRIENDS; ++i) { | ||
857 | loop_top: | ||
858 | pairs[i].tox1 = rand() % NUM_TOXES; | ||
859 | pairs[i].tox2 = (pairs[i].tox1 + rand() % (NUM_TOXES - 1) + 1) % NUM_TOXES; | ||
860 | |||
861 | for (j = 0; j < i; ++j) { | ||
862 | if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2) | ||
863 | goto loop_top; | ||
864 | } | ||
865 | |||
866 | tox_self_get_address(toxes[pairs[i].tox1], address); | ||
867 | |||
868 | TOX_ERR_FRIEND_ADD test; | ||
869 | uint32_t num = tox_friend_add(toxes[pairs[i].tox2], address, (uint8_t *)"Gentoo", 7, &test); | ||
870 | |||
871 | if (test == TOX_ERR_FRIEND_ADD_ALREADY_SENT) { | ||
872 | goto loop_top; | ||
873 | } | ||
874 | |||
875 | ck_assert_msg(num != UINT32_MAX && test == TOX_ERR_FRIEND_ADD_OK, "Failed to add friend error code: %i", test); | ||
876 | } | ||
877 | |||
878 | while (1) { | ||
879 | uint16_t counter = 0; | ||
880 | |||
881 | for (i = 0; i < NUM_TOXES; ++i) { | ||
882 | for (j = 0; j < tox_self_get_friend_list_size(toxes[i]); ++j) | ||
883 | if (tox_friend_get_connection_status(toxes[i], j, 0) == TOX_CONNECTION_TCP) | ||
884 | ++counter; | ||
885 | } | ||
886 | |||
887 | if (counter == NUM_FRIENDS * 2) { | ||
888 | break; | ||
889 | } | ||
890 | |||
891 | for (i = 0; i < NUM_TOXES; ++i) { | ||
892 | tox_iterate(toxes[i]); | ||
893 | } | ||
894 | |||
895 | c_sleep(50); | ||
896 | } | ||
897 | |||
898 | for (i = 0; i < NUM_TOXES; ++i) { | ||
899 | tox_kill(toxes[i]); | ||
900 | } | ||
901 | |||
902 | printf("test_many_clients_tcp succeeded, took %llu seconds\n", time(NULL) - cur_time); | ||
903 | } | ||
904 | END_TEST | ||
905 | |||
906 | #define NUM_TCP_RELAYS 3 | ||
907 | |||
908 | START_TEST(test_many_clients_tcp_b) | ||
909 | { | ||
910 | long long unsigned int cur_time = time(NULL); | ||
911 | Tox *toxes[NUM_TOXES]; | ||
912 | uint32_t i, j; | ||
913 | uint32_t to_comp = 974536; | ||
914 | |||
915 | for (i = 0; i < NUM_TOXES; ++i) { | ||
916 | struct Tox_Options opts; | ||
917 | tox_options_default(&opts); | ||
918 | |||
919 | if (i < NUM_TCP_RELAYS) { | ||
920 | opts.tcp_port = TCP_RELAY_PORT + i; | ||
921 | } else { | ||
922 | opts.udp_enabled = 0; | ||
923 | } | ||
924 | |||
925 | toxes[i] = tox_new(&opts, 0, 0, 0); | ||
926 | ck_assert_msg(toxes[i] != 0, "Failed to create tox instances %u", i); | ||
927 | tox_callback_friend_request(toxes[i], accept_friend_request, &to_comp); | ||
928 | uint8_t dpk[TOX_PUBLIC_KEY_SIZE]; | ||
929 | tox_self_get_dht_id(toxes[(i % NUM_TCP_RELAYS)], dpk); | ||
930 | ck_assert_msg(tox_add_tcp_relay(toxes[i], "::1", TCP_RELAY_PORT + (i % NUM_TCP_RELAYS), dpk, 0), "add relay error"); | ||
931 | tox_self_get_dht_id(toxes[0], dpk); | ||
932 | ck_assert_msg(tox_bootstrap(toxes[i], "::1", 33445, dpk, 0), "Bootstrap error"); | ||
933 | } | ||
934 | |||
935 | { | ||
936 | TOX_ERR_GET_PORT error; | ||
937 | ck_assert_msg(tox_self_get_udp_port(toxes[0], &error) == 33445, "First Tox instance did not bind to udp port 33445.\n"); | ||
938 | ck_assert_msg(error == TOX_ERR_GET_PORT_OK, "wrong error"); | ||
939 | ck_assert_msg(tox_self_get_tcp_port(toxes[0], &error) == TCP_RELAY_PORT, | ||
940 | "First Tox instance did not bind to tcp port %u.\n", TCP_RELAY_PORT); | ||
941 | ck_assert_msg(error == TOX_ERR_GET_PORT_OK, "wrong error"); | ||
942 | } | ||
943 | |||
944 | struct { | ||
945 | uint16_t tox1; | ||
946 | uint16_t tox2; | ||
947 | } pairs[NUM_FRIENDS]; | ||
948 | |||
949 | uint8_t address[TOX_ADDRESS_SIZE]; | ||
950 | |||
951 | for (i = 0; i < NUM_FRIENDS; ++i) { | ||
952 | loop_top: | ||
953 | pairs[i].tox1 = rand() % NUM_TOXES; | ||
954 | pairs[i].tox2 = (pairs[i].tox1 + rand() % (NUM_TOXES - 1) + 1) % NUM_TOXES; | ||
955 | |||
956 | for (j = 0; j < i; ++j) { | ||
957 | if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2) | ||
958 | goto loop_top; | ||
959 | } | ||
960 | |||
961 | tox_self_get_address(toxes[pairs[i].tox1], address); | ||
962 | |||
963 | TOX_ERR_FRIEND_ADD test; | ||
964 | uint32_t num = tox_friend_add(toxes[pairs[i].tox2], address, (uint8_t *)"Gentoo", 7, &test); | ||
965 | |||
966 | if (test == TOX_ERR_FRIEND_ADD_ALREADY_SENT) { | ||
967 | goto loop_top; | ||
968 | } | ||
969 | |||
970 | ck_assert_msg(num != UINT32_MAX && test == TOX_ERR_FRIEND_ADD_OK, "Failed to add friend error code: %i", test); | ||
971 | } | ||
972 | |||
973 | while (1) { | ||
974 | uint16_t counter = 0; | ||
975 | |||
976 | for (i = 0; i < NUM_TOXES; ++i) { | ||
977 | for (j = 0; j < tox_self_get_friend_list_size(toxes[i]); ++j) | ||
978 | if (tox_friend_get_connection_status(toxes[i], j, 0) == TOX_CONNECTION_TCP) | ||
979 | ++counter; | ||
980 | } | ||
981 | |||
982 | if (counter == NUM_FRIENDS * 2) { | ||
983 | break; | ||
984 | } | ||
985 | |||
986 | for (i = 0; i < NUM_TOXES; ++i) { | ||
987 | tox_iterate(toxes[i]); | ||
988 | } | ||
989 | |||
990 | c_sleep(50); | ||
991 | } | ||
992 | |||
993 | for (i = 0; i < NUM_TOXES; ++i) { | ||
994 | tox_kill(toxes[i]); | ||
995 | } | ||
996 | |||
997 | printf("test_many_clients_tcp_b succeeded, took %llu seconds\n", time(NULL) - cur_time); | ||
998 | } | ||
999 | END_TEST | ||
1000 | |||
1001 | |||
812 | #define NUM_GROUP_TOX 32 | 1002 | #define NUM_GROUP_TOX 32 |
813 | 1003 | ||
814 | void g_accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) | 1004 | void g_accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata) |
@@ -996,6 +1186,8 @@ Suite *tox_suite(void) | |||
996 | DEFTESTCASE(one); | 1186 | DEFTESTCASE(one); |
997 | DEFTESTCASE_SLOW(few_clients, 50); | 1187 | DEFTESTCASE_SLOW(few_clients, 50); |
998 | DEFTESTCASE_SLOW(many_clients, 150); | 1188 | DEFTESTCASE_SLOW(many_clients, 150); |
1189 | DEFTESTCASE_SLOW(many_clients_tcp, 20); | ||
1190 | DEFTESTCASE_SLOW(many_clients_tcp_b, 20); | ||
999 | DEFTESTCASE_SLOW(many_group, 100); | 1191 | DEFTESTCASE_SLOW(many_group, 100); |
1000 | return s; | 1192 | return s; |
1001 | } | 1193 | } |
diff --git a/other/apidsl/tox.in.h b/other/apidsl/tox.in.h index 84a4a03e..dd47df23 100644 --- a/other/apidsl/tox.in.h +++ b/other/apidsl/tox.in.h | |||
@@ -411,6 +411,11 @@ static class options { | |||
411 | * The end port of the inclusive port range to attempt to use. | 411 | * The end port of the inclusive port range to attempt to use. |
412 | */ | 412 | */ |
413 | uint16_t end_port; | 413 | uint16_t end_port; |
414 | |||
415 | /** | ||
416 | * The port to use for the TCP server. If 0, the tcp server is disabled. | ||
417 | */ | ||
418 | uint16_t tcp_port; | ||
414 | } | 419 | } |
415 | 420 | ||
416 | 421 | ||
diff --git a/testing/irc_syncbot.c b/testing/irc_syncbot.c index b879e4eb..2d326c4b 100644 --- a/testing/irc_syncbot.c +++ b/testing/irc_syncbot.c | |||
@@ -163,9 +163,15 @@ void send_irc_group(Tox *tox, uint8_t *msg, uint16_t len) | |||
163 | uint8_t req[len]; | 163 | uint8_t req[len]; |
164 | unsigned int i; | 164 | unsigned int i; |
165 | 165 | ||
166 | unsigned int spaces = 0; | ||
167 | |||
166 | for (i = 0; i < (len - 1); ++i) { | 168 | for (i = 0; i < (len - 1); ++i) { |
167 | if (msg[i + 1] == ':') { | 169 | if (msg[i + 1] == ' ') { |
168 | break; | 170 | ++spaces; |
171 | } else { | ||
172 | if (spaces >= 3 && msg[i + 1] == ':') { | ||
173 | break; | ||
174 | } | ||
169 | } | 175 | } |
170 | 176 | ||
171 | req[i] = msg[i + 1]; | 177 | req[i] = msg[i + 1]; |
@@ -227,11 +233,6 @@ Tox *init_tox(int argc, char *argv[]) | |||
227 | tox_callback_group_message(tox, ©_groupmessage, 0); | 233 | tox_callback_group_message(tox, ©_groupmessage, 0); |
228 | tox_callback_group_action(tox, ©_groupmessage, 0); | 234 | tox_callback_group_action(tox, ©_groupmessage, 0); |
229 | 235 | ||
230 | uint16_t port = atoi(argv[argvoffset + 2]); | ||
231 | unsigned char *binary_string = hex_string_to_bin(argv[argvoffset + 3]); | ||
232 | tox_bootstrap(tox, argv[argvoffset + 1], port, binary_string, 0); | ||
233 | free(binary_string); | ||
234 | |||
235 | char temp_id[128]; | 236 | char temp_id[128]; |
236 | printf("\nEnter the address of irc_syncbots master (38 bytes HEX format):\n"); | 237 | printf("\nEnter the address of irc_syncbots master (38 bytes HEX format):\n"); |
237 | 238 | ||
@@ -239,6 +240,11 @@ Tox *init_tox(int argc, char *argv[]) | |||
239 | exit (1); | 240 | exit (1); |
240 | } | 241 | } |
241 | 242 | ||
243 | uint16_t port = atoi(argv[argvoffset + 2]); | ||
244 | unsigned char *binary_string = hex_string_to_bin(argv[argvoffset + 3]); | ||
245 | tox_bootstrap(tox, argv[argvoffset + 1], port, binary_string, 0); | ||
246 | free(binary_string); | ||
247 | |||
242 | uint8_t *bin_id = hex_string_to_bin(temp_id); | 248 | uint8_t *bin_id = hex_string_to_bin(temp_id); |
243 | uint32_t num = tox_friend_add(tox, bin_id, (uint8_t *)"Install Gentoo", sizeof("Install Gentoo") - 1, 0); | 249 | uint32_t num = tox_friend_add(tox, bin_id, (uint8_t *)"Install Gentoo", sizeof("Install Gentoo") - 1, 0); |
244 | free(bin_id); | 250 | free(bin_id); |
diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c index dbce762e..5ab5b0e1 100644 --- a/toxcore/LAN_discovery.c +++ b/toxcore/LAN_discovery.c | |||
@@ -227,18 +227,43 @@ static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast) | |||
227 | return ip; | 227 | return ip; |
228 | } | 228 | } |
229 | 229 | ||
230 | /* Is IP a local ip or not. */ | ||
231 | _Bool Local_ip(IP ip) | ||
232 | { | ||
233 | if (ip.family == AF_INET) { | ||
234 | IP4 ip4 = ip.ip4; | ||
235 | |||
236 | /* Loopback. */ | ||
237 | if (ip4.uint8[0] == 127) | ||
238 | return 1; | ||
239 | } else { | ||
240 | /* embedded IPv4-in-IPv6 */ | ||
241 | if (IPV6_IPV4_IN_V6(ip.ip6)) { | ||
242 | IP ip4; | ||
243 | ip4.family = AF_INET; | ||
244 | ip4.ip4.uint32 = ip.ip6.uint32[3]; | ||
245 | return Local_ip(ip4); | ||
246 | } | ||
247 | |||
248 | /* localhost in IPv6 (::1) */ | ||
249 | if (ip.ip6.uint64[0] == 0 && ip.ip6.uint32[2] == 0 && ip.ip6.uint32[3] == htonl(1)) | ||
250 | return 1; | ||
251 | } | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
230 | /* return 0 if ip is a LAN ip. | 256 | /* return 0 if ip is a LAN ip. |
231 | * return -1 if it is not. | 257 | * return -1 if it is not. |
232 | */ | 258 | */ |
233 | int LAN_ip(IP ip) | 259 | int LAN_ip(IP ip) |
234 | { | 260 | { |
261 | if (Local_ip(ip)) | ||
262 | return 0; | ||
263 | |||
235 | if (ip.family == AF_INET) { | 264 | if (ip.family == AF_INET) { |
236 | IP4 ip4 = ip.ip4; | 265 | IP4 ip4 = ip.ip4; |
237 | 266 | ||
238 | /* Loopback. */ | ||
239 | if (ip4.uint8[0] == 127) | ||
240 | return 0; | ||
241 | |||
242 | /* 10.0.0.0 to 10.255.255.255 range. */ | 267 | /* 10.0.0.0 to 10.255.255.255 range. */ |
243 | if (ip4.uint8[0] == 10) | 268 | if (ip4.uint8[0] == 10) |
244 | return 0; | 269 | return 0; |
@@ -276,10 +301,6 @@ int LAN_ip(IP ip) | |||
276 | ip4.ip4.uint32 = ip.ip6.uint32[3]; | 301 | ip4.ip4.uint32 = ip.ip6.uint32[3]; |
277 | return LAN_ip(ip4); | 302 | return LAN_ip(ip4); |
278 | } | 303 | } |
279 | |||
280 | /* localhost in IPv6 (::1) */ | ||
281 | if (ip.ip6.uint64[0] == 0 && ip.ip6.uint32[2] == 0 && ip.ip6.uint32[3] == htonl(1)) | ||
282 | return 0; | ||
283 | } | 304 | } |
284 | 305 | ||
285 | return -1; | 306 | return -1; |
diff --git a/toxcore/LAN_discovery.h b/toxcore/LAN_discovery.h index 5243bd93..358bea2f 100644 --- a/toxcore/LAN_discovery.h +++ b/toxcore/LAN_discovery.h | |||
@@ -40,6 +40,9 @@ void LANdiscovery_init(DHT *dht); | |||
40 | /* Clear packet handlers. */ | 40 | /* Clear packet handlers. */ |
41 | void LANdiscovery_kill(DHT *dht); | 41 | void LANdiscovery_kill(DHT *dht); |
42 | 42 | ||
43 | /* Is IP a local ip or not. */ | ||
44 | _Bool Local_ip(IP ip); | ||
45 | |||
43 | /* checks if a given IP isn't routable | 46 | /* checks if a given IP isn't routable |
44 | * | 47 | * |
45 | * return 0 if ip is a LAN ip. | 48 | * return 0 if ip is a LAN ip. |
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 5b7a7f61..6294aa9c 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c | |||
@@ -1807,6 +1807,27 @@ Messenger *new_messenger(Messenger_Options *options, unsigned int *error) | |||
1807 | return NULL; | 1807 | return NULL; |
1808 | } | 1808 | } |
1809 | 1809 | ||
1810 | if (options->tcp_server_port) { | ||
1811 | m->tcp_server = new_TCP_server(options->ipv6enabled, 1, &options->tcp_server_port, m->dht->self_public_key, | ||
1812 | m->dht->self_secret_key, m->onion); | ||
1813 | |||
1814 | if (m->tcp_server == NULL) { | ||
1815 | kill_friend_connections(m->fr_c); | ||
1816 | kill_onion(m->onion); | ||
1817 | kill_onion_announce(m->onion_a); | ||
1818 | kill_onion_client(m->onion_c); | ||
1819 | kill_DHT(m->dht); | ||
1820 | kill_net_crypto(m->net_crypto); | ||
1821 | kill_networking(m->net); | ||
1822 | free(m); | ||
1823 | |||
1824 | if (error) | ||
1825 | *error = MESSENGER_ERROR_TCP_SERVER; | ||
1826 | |||
1827 | return NULL; | ||
1828 | } | ||
1829 | } | ||
1830 | |||
1810 | m->options = *options; | 1831 | m->options = *options; |
1811 | friendreq_init(&(m->fr), m->fr_c); | 1832 | friendreq_init(&(m->fr), m->fr_c); |
1812 | set_nospam(&(m->fr), random_int()); | 1833 | set_nospam(&(m->fr), random_int()); |
@@ -1826,6 +1847,10 @@ void kill_messenger(Messenger *m) | |||
1826 | 1847 | ||
1827 | uint32_t i; | 1848 | uint32_t i; |
1828 | 1849 | ||
1850 | if (m->tcp_server) { | ||
1851 | kill_TCP_server(m->tcp_server); | ||
1852 | } | ||
1853 | |||
1829 | kill_friend_connections(m->fr_c); | 1854 | kill_friend_connections(m->fr_c); |
1830 | kill_onion(m->onion); | 1855 | kill_onion(m->onion); |
1831 | kill_onion_announce(m->onion_a); | 1856 | kill_onion_announce(m->onion_a); |
@@ -2261,6 +2286,15 @@ void do_messenger(Messenger *m) | |||
2261 | for (i = 0; i < NUM_SAVED_TCP_RELAYS; ++i) { | 2286 | for (i = 0; i < NUM_SAVED_TCP_RELAYS; ++i) { |
2262 | add_tcp_relay(m->net_crypto, m->loaded_relays[i].ip_port, m->loaded_relays[i].public_key); | 2287 | add_tcp_relay(m->net_crypto, m->loaded_relays[i].ip_port, m->loaded_relays[i].public_key); |
2263 | } | 2288 | } |
2289 | |||
2290 | if (m->tcp_server) { | ||
2291 | /* Add self tcp server. */ | ||
2292 | IP_Port local_ip_port; | ||
2293 | local_ip_port.port = m->options.tcp_server_port; | ||
2294 | local_ip_port.ip.family = AF_INET; | ||
2295 | local_ip_port.ip.ip4.uint32 = INADDR_LOOPBACK; | ||
2296 | add_tcp_relay(m->net_crypto, local_ip_port, m->tcp_server->public_key); | ||
2297 | } | ||
2264 | } | 2298 | } |
2265 | 2299 | ||
2266 | unix_time_update(); | 2300 | unix_time_update(); |
@@ -2270,6 +2304,10 @@ void do_messenger(Messenger *m) | |||
2270 | do_DHT(m->dht); | 2304 | do_DHT(m->dht); |
2271 | } | 2305 | } |
2272 | 2306 | ||
2307 | if (m->tcp_server) { | ||
2308 | do_TCP_server(m->tcp_server); | ||
2309 | } | ||
2310 | |||
2273 | do_net_crypto(m->net_crypto); | 2311 | do_net_crypto(m->net_crypto); |
2274 | do_onion_client(m->onion_c); | 2312 | do_onion_client(m->onion_c); |
2275 | do_friend_connections(m->fr_c); | 2313 | do_friend_connections(m->fr_c); |
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index 8ab6b6ed..26704dd1 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h | |||
@@ -70,6 +70,7 @@ typedef struct { | |||
70 | uint8_t udp_disabled; | 70 | uint8_t udp_disabled; |
71 | TCP_Proxy_Info proxy_info; | 71 | TCP_Proxy_Info proxy_info; |
72 | uint16_t port_range[2]; | 72 | uint16_t port_range[2]; |
73 | uint16_t tcp_server_port; | ||
73 | } Messenger_Options; | 74 | } Messenger_Options; |
74 | 75 | ||
75 | 76 | ||
@@ -219,6 +220,7 @@ struct Messenger { | |||
219 | 220 | ||
220 | Friend_Connections *fr_c; | 221 | Friend_Connections *fr_c; |
221 | 222 | ||
223 | TCP_Server *tcp_server; | ||
222 | Friend_Requests fr; | 224 | Friend_Requests fr; |
223 | uint8_t name[MAX_NAME_LENGTH]; | 225 | uint8_t name[MAX_NAME_LENGTH]; |
224 | uint16_t name_length; | 226 | uint16_t name_length; |
@@ -727,6 +729,7 @@ int send_custom_lossless_packet(const Messenger *m, int32_t friendnumber, const | |||
727 | enum { | 729 | enum { |
728 | MESSENGER_ERROR_NONE, | 730 | MESSENGER_ERROR_NONE, |
729 | MESSENGER_ERROR_PORT, | 731 | MESSENGER_ERROR_PORT, |
732 | MESSENGER_ERROR_TCP_SERVER, | ||
730 | MESSENGER_ERROR_OTHER | 733 | MESSENGER_ERROR_OTHER |
731 | }; | 734 | }; |
732 | 735 | ||
diff --git a/toxcore/friend_connection.c b/toxcore/friend_connection.c index de34e570..1656def0 100644 --- a/toxcore/friend_connection.c +++ b/toxcore/friend_connection.c | |||
@@ -158,6 +158,15 @@ int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_ | |||
158 | if (!friend_con) | 158 | if (!friend_con) |
159 | return -1; | 159 | return -1; |
160 | 160 | ||
161 | /* Local ip and same pk means that they are hosting a TCP relay. */ | ||
162 | if (Local_ip(ip_port.ip) && memcmp(friend_con->dht_temp_pk, public_key, crypto_box_PUBLICKEYBYTES) == 0) { | ||
163 | if (friend_con->dht_ip_port.ip.family != 0) { | ||
164 | ip_port.ip = friend_con->dht_ip_port.ip; | ||
165 | } else { | ||
166 | friend_con->hosting_tcp_relay = 0; | ||
167 | } | ||
168 | } | ||
169 | |||
161 | unsigned int i; | 170 | unsigned int i; |
162 | 171 | ||
163 | uint16_t index = friend_con->tcp_relay_counter % FRIEND_MAX_STORED_TCP_RELAYS; | 172 | uint16_t index = friend_con->tcp_relay_counter % FRIEND_MAX_STORED_TCP_RELAYS; |
@@ -268,6 +277,11 @@ static void dht_ip_callback(void *object, int32_t number, IP_Port ip_port) | |||
268 | set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, ip_port, 1); | 277 | set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, ip_port, 1); |
269 | friend_con->dht_ip_port = ip_port; | 278 | friend_con->dht_ip_port = ip_port; |
270 | friend_con->dht_ip_port_lastrecv = unix_time(); | 279 | friend_con->dht_ip_port_lastrecv = unix_time(); |
280 | |||
281 | if (friend_con->hosting_tcp_relay) { | ||
282 | friend_add_tcp_relay(fr_c, number, ip_port, friend_con->dht_temp_pk); | ||
283 | friend_con->hosting_tcp_relay = 0; | ||
284 | } | ||
271 | } | 285 | } |
272 | 286 | ||
273 | static void change_dht_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t *dht_public_key) | 287 | static void change_dht_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t *dht_public_key) |
@@ -317,6 +331,7 @@ static int handle_status(void *object, int number, uint8_t status) | |||
317 | 331 | ||
318 | friend_con->status = FRIENDCONN_STATUS_CONNECTING; | 332 | friend_con->status = FRIENDCONN_STATUS_CONNECTING; |
319 | friend_con->crypt_connection_id = -1; | 333 | friend_con->crypt_connection_id = -1; |
334 | friend_con->hosting_tcp_relay = 0; | ||
320 | } | 335 | } |
321 | 336 | ||
322 | if (call_cb) { | 337 | if (call_cb) { |
diff --git a/toxcore/friend_connection.h b/toxcore/friend_connection.h index baca4b76..32e947ac 100644 --- a/toxcore/friend_connection.h +++ b/toxcore/friend_connection.h | |||
@@ -96,6 +96,8 @@ typedef struct { | |||
96 | 96 | ||
97 | Node_format tcp_relays[FRIEND_MAX_STORED_TCP_RELAYS]; | 97 | Node_format tcp_relays[FRIEND_MAX_STORED_TCP_RELAYS]; |
98 | uint16_t tcp_relay_counter; | 98 | uint16_t tcp_relay_counter; |
99 | |||
100 | _Bool hosting_tcp_relay; | ||
99 | } Friend_Conn; | 101 | } Friend_Conn; |
100 | 102 | ||
101 | 103 | ||
diff --git a/toxcore/onion_announce.h b/toxcore/onion_announce.h index 36ffe767..0e041e50 100644 --- a/toxcore/onion_announce.h +++ b/toxcore/onion_announce.h | |||
@@ -25,7 +25,7 @@ | |||
25 | 25 | ||
26 | #include "onion.h" | 26 | #include "onion.h" |
27 | 27 | ||
28 | #define ONION_ANNOUNCE_MAX_ENTRIES 64 | 28 | #define ONION_ANNOUNCE_MAX_ENTRIES 96 |
29 | #define ONION_ANNOUNCE_TIMEOUT 300 | 29 | #define ONION_ANNOUNCE_TIMEOUT 300 |
30 | #define ONION_PING_ID_SIZE crypto_hash_sha256_BYTES | 30 | #define ONION_PING_ID_SIZE crypto_hash_sha256_BYTES |
31 | 31 | ||
diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c index 5db426d3..6575f632 100644 --- a/toxcore/onion_client.c +++ b/toxcore/onion_client.c | |||
@@ -1204,7 +1204,7 @@ static void populate_path_nodes_tcp(Onion_Client *onion_c) | |||
1204 | unsigned int i; | 1204 | unsigned int i; |
1205 | 1205 | ||
1206 | for (i = 0; i < num_nodes; ++i) { | 1206 | for (i = 0; i < num_nodes; ++i) { |
1207 | onion_add_path_node(onion_c, nodes_list[i].ip_port, nodes_list[i].public_key); | 1207 | onion_add_bs_path_node(onion_c, nodes_list[i].ip_port, nodes_list[i].public_key); |
1208 | } | 1208 | } |
1209 | } | 1209 | } |
1210 | 1210 | ||
diff --git a/toxcore/tox.c b/toxcore/tox.c index 848f81c7..de615768 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c | |||
@@ -152,6 +152,7 @@ Tox *tox_new(const struct Tox_Options *options, const uint8_t *data, size_t leng | |||
152 | m_options.udp_disabled = !options->udp_enabled; | 152 | m_options.udp_disabled = !options->udp_enabled; |
153 | m_options.port_range[0] = options->start_port; | 153 | m_options.port_range[0] = options->start_port; |
154 | m_options.port_range[1] = options->end_port; | 154 | m_options.port_range[1] = options->end_port; |
155 | m_options.tcp_server_port = options->tcp_port; | ||
155 | 156 | ||
156 | switch (options->proxy_type) { | 157 | switch (options->proxy_type) { |
157 | case TOX_PROXY_TYPE_HTTP: | 158 | case TOX_PROXY_TYPE_HTTP: |
@@ -238,31 +239,6 @@ void tox_get_savedata(const Tox *tox, uint8_t *data) | |||
238 | } | 239 | } |
239 | } | 240 | } |
240 | 241 | ||
241 | static int address_to_ip(Messenger *m, const char *address, IP_Port *ip_port, IP_Port *ip_port_v4) | ||
242 | { | ||
243 | if (!addr_parse_ip(address, &ip_port->ip)) { | ||
244 | if (m->options.udp_disabled) { /* Disable DNS when udp is disabled. */ | ||
245 | return -1; | ||
246 | } | ||
247 | |||
248 | IP *ip_extra = NULL; | ||
249 | ip_init(&ip_port->ip, m->options.ipv6enabled); | ||
250 | |||
251 | if (m->options.ipv6enabled && ip_port_v4) { | ||
252 | /* setup for getting BOTH: an IPv6 AND an IPv4 address */ | ||
253 | ip_port->ip.family = AF_UNSPEC; | ||
254 | ip_reset(&ip_port_v4->ip); | ||
255 | ip_extra = &ip_port_v4->ip; | ||
256 | } | ||
257 | |||
258 | if (!addr_resolve(address, &ip_port->ip, ip_extra)) { | ||
259 | return -1; | ||
260 | } | ||
261 | } | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | bool tox_bootstrap(Tox *tox, const char *address, uint16_t port, const uint8_t *public_key, TOX_ERR_BOOTSTRAP *error) | 242 | bool tox_bootstrap(Tox *tox, const char *address, uint16_t port, const uint8_t *public_key, TOX_ERR_BOOTSTRAP *error) |
267 | { | 243 | { |
268 | if (!address || !public_key) { | 244 | if (!address || !public_key) { |
@@ -270,23 +246,53 @@ bool tox_bootstrap(Tox *tox, const char *address, uint16_t port, const uint8_t * | |||
270 | return 0; | 246 | return 0; |
271 | } | 247 | } |
272 | 248 | ||
273 | Messenger *m = tox; | 249 | if (port == 0) { |
274 | bool ret = tox_add_tcp_relay(tox, address, port, public_key, error); | 250 | SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_PORT); |
251 | return 0; | ||
252 | } | ||
275 | 253 | ||
276 | if (!ret) { | 254 | struct addrinfo *root, *info; |
255 | |||
256 | if (getaddrinfo(address, NULL, NULL, &root) != 0) { | ||
257 | SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST); | ||
277 | return 0; | 258 | return 0; |
278 | } | 259 | } |
279 | 260 | ||
280 | if (m->options.udp_disabled) { | 261 | info = root; |
281 | return ret; | 262 | |
282 | } else { /* DHT only works on UDP. */ | 263 | unsigned int count = 0; |
283 | if (DHT_bootstrap_from_address(m->dht, address, m->options.ipv6enabled, htons(port), public_key) == 0) { | 264 | |
284 | SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST); | 265 | do { |
285 | return 0; | 266 | IP_Port ip_port; |
267 | ip_port.port = htons(port); | ||
268 | ip_port.ip.family = info->ai_family; | ||
269 | |||
270 | if (info->ai_socktype && info->ai_socktype != SOCK_DGRAM) { | ||
271 | continue; | ||
272 | } | ||
273 | |||
274 | if (info->ai_family == AF_INET) { | ||
275 | ip_port.ip.ip4.in_addr = ((struct sockaddr_in *)info->ai_addr)->sin_addr; | ||
276 | } else if (info->ai_family == AF_INET6) { | ||
277 | ip_port.ip.ip6.in6_addr = ((struct sockaddr_in6 *)info->ai_addr)->sin6_addr; | ||
278 | } else { | ||
279 | continue; | ||
286 | } | 280 | } |
287 | 281 | ||
282 | Messenger *m = tox; | ||
283 | onion_add_bs_path_node(m->onion_c, ip_port, public_key); | ||
284 | DHT_bootstrap(m->dht, ip_port, public_key); | ||
285 | ++count; | ||
286 | } while ((info = info->ai_next)); | ||
287 | |||
288 | freeaddrinfo(root); | ||
289 | |||
290 | if (count) { | ||
288 | SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_OK); | 291 | SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_OK); |
289 | return 1; | 292 | return 1; |
293 | } else { | ||
294 | SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST); | ||
295 | return 0; | ||
290 | } | 296 | } |
291 | } | 297 | } |
292 | 298 | ||
@@ -298,25 +304,53 @@ bool tox_add_tcp_relay(Tox *tox, const char *address, uint16_t port, const uint8 | |||
298 | return 0; | 304 | return 0; |
299 | } | 305 | } |
300 | 306 | ||
301 | Messenger *m = tox; | ||
302 | IP_Port ip_port, ip_port_v4; | ||
303 | |||
304 | if (port == 0) { | 307 | if (port == 0) { |
305 | SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_PORT); | 308 | SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_PORT); |
306 | return 0; | 309 | return 0; |
307 | } | 310 | } |
308 | 311 | ||
309 | if (address_to_ip(m, address, &ip_port, &ip_port_v4) == -1) { | 312 | struct addrinfo *root, *info; |
313 | |||
314 | if (getaddrinfo(address, NULL, NULL, &root) != 0) { | ||
310 | SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST); | 315 | SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST); |
311 | return 0; | 316 | return 0; |
312 | } | 317 | } |
313 | 318 | ||
314 | ip_port.port = htons(port); | 319 | info = root; |
315 | add_tcp_relay(m->net_crypto, ip_port, public_key); | ||
316 | onion_add_bs_path_node(m->onion_c, ip_port, public_key); //TODO: move this | ||
317 | 320 | ||
318 | SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_OK); | 321 | unsigned int count = 0; |
319 | return 1; | 322 | |
323 | do { | ||
324 | IP_Port ip_port; | ||
325 | ip_port.port = htons(port); | ||
326 | ip_port.ip.family = info->ai_family; | ||
327 | |||
328 | if (info->ai_socktype && info->ai_socktype != SOCK_STREAM) { | ||
329 | continue; | ||
330 | } | ||
331 | |||
332 | if (info->ai_family == AF_INET) { | ||
333 | ip_port.ip.ip4.in_addr = ((struct sockaddr_in *)info->ai_addr)->sin_addr; | ||
334 | } else if (info->ai_family == AF_INET6) { | ||
335 | ip_port.ip.ip6.in6_addr = ((struct sockaddr_in6 *)info->ai_addr)->sin6_addr; | ||
336 | } else { | ||
337 | continue; | ||
338 | } | ||
339 | |||
340 | Messenger *m = tox; | ||
341 | add_tcp_relay(m->net_crypto, ip_port, public_key); | ||
342 | ++count; | ||
343 | } while ((info = info->ai_next)); | ||
344 | |||
345 | freeaddrinfo(root); | ||
346 | |||
347 | if (count) { | ||
348 | SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_OK); | ||
349 | return 1; | ||
350 | } else { | ||
351 | SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST); | ||
352 | return 0; | ||
353 | } | ||
320 | } | 354 | } |
321 | 355 | ||
322 | TOX_CONNECTION tox_self_get_connection_status(const Tox *tox) | 356 | TOX_CONNECTION tox_self_get_connection_status(const Tox *tox) |
@@ -1205,9 +1239,15 @@ uint16_t tox_self_get_udp_port(const Tox *tox, TOX_ERR_GET_PORT *error) | |||
1205 | 1239 | ||
1206 | uint16_t tox_self_get_tcp_port(const Tox *tox, TOX_ERR_GET_PORT *error) | 1240 | uint16_t tox_self_get_tcp_port(const Tox *tox, TOX_ERR_GET_PORT *error) |
1207 | { | 1241 | { |
1208 | /* TCP server not yet implemented in clients. */ | 1242 | const Messenger *m = tox; |
1209 | SET_ERROR_PARAMETER(error, TOX_ERR_GET_PORT_NOT_BOUND); | 1243 | |
1210 | return 0; | 1244 | if (m->tcp_server) { |
1245 | SET_ERROR_PARAMETER(error, TOX_ERR_GET_PORT_OK); | ||
1246 | return m->options.tcp_server_port; | ||
1247 | } else { | ||
1248 | SET_ERROR_PARAMETER(error, TOX_ERR_GET_PORT_NOT_BOUND); | ||
1249 | return 0; | ||
1250 | } | ||
1211 | } | 1251 | } |
1212 | 1252 | ||
1213 | #include "tox_old_code.h" | 1253 | #include "tox_old_code.h" |
diff --git a/toxcore/tox.h b/toxcore/tox.h index abd2f051..4afdf7c3 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h | |||
@@ -426,6 +426,12 @@ struct Tox_Options { | |||
426 | */ | 426 | */ |
427 | uint16_t end_port; | 427 | uint16_t end_port; |
428 | 428 | ||
429 | |||
430 | /** | ||
431 | * The port to use for the TCP server. If 0, the tcp server is disabled. | ||
432 | */ | ||
433 | uint16_t tcp_port; | ||
434 | |||
429 | }; | 435 | }; |
430 | 436 | ||
431 | 437 | ||