diff options
-rw-r--r-- | other/DHT_bootstrap.c | 13 | ||||
-rw-r--r-- | other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c | 9 | ||||
-rw-r--r-- | testing/DHT_test.c | 33 | ||||
-rw-r--r-- | testing/Lossless_UDP_testclient.c | 16 | ||||
-rw-r--r-- | testing/Lossless_UDP_testserver.c | 8 | ||||
-rw-r--r-- | testing/Messenger_test.c | 5 | ||||
-rw-r--r-- | testing/nTox.c | 19 | ||||
-rw-r--r-- | toxcore/DHT.c | 116 | ||||
-rw-r--r-- | toxcore/DHT.h | 25 | ||||
-rw-r--r-- | toxcore/LAN_discovery.c | 85 | ||||
-rw-r--r-- | toxcore/Lossless_UDP.c | 52 | ||||
-rw-r--r-- | toxcore/Lossless_UDP.h | 6 | ||||
-rw-r--r-- | toxcore/Messenger.c | 15 | ||||
-rw-r--r-- | toxcore/friend_requests.c | 10 | ||||
-rw-r--r-- | toxcore/group_chats.c | 2 | ||||
-rw-r--r-- | toxcore/net_crypto.c | 2 | ||||
-rw-r--r-- | toxcore/network.c | 332 | ||||
-rw-r--r-- | toxcore/network.h | 48 | ||||
-rw-r--r-- | toxcore/ping.c | 6 | ||||
-rw-r--r-- | toxcore/tox.c | 5 | ||||
-rw-r--r-- | toxcore/tox.h | 47 | ||||
-rw-r--r-- | toxcore/util.c | 5 | ||||
-rw-r--r-- | toxcore/util.h | 1 |
23 files changed, 625 insertions, 235 deletions
diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c index bc0c592a..7355ca10 100644 --- a/other/DHT_bootstrap.c +++ b/other/DHT_bootstrap.c | |||
@@ -81,10 +81,14 @@ void manage_keys(DHT *dht) | |||
81 | 81 | ||
82 | int main(int argc, char *argv[]) | 82 | int main(int argc, char *argv[]) |
83 | { | 83 | { |
84 | /* let use decide by cmdline: TODO */ | ||
85 | uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; | ||
86 | |||
84 | /* Initialize networking - | 87 | /* Initialize networking - |
85 | Bind to ip 0.0.0.0:PORT */ | 88 | Bind to ip 0.0.0.0:PORT */ |
86 | IP4 ip; | 89 | IP ip; |
87 | ip.uint32 = 0; | 90 | ip_init(&ip, ipv6enabled); |
91 | |||
88 | DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT))); | 92 | DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT))); |
89 | manage_keys(dht); | 93 | manage_keys(dht); |
90 | printf("Public key: "); | 94 | printf("Public key: "); |
@@ -110,11 +114,8 @@ int main(int argc, char *argv[]) | |||
110 | 114 | ||
111 | if (argc > 3) { | 115 | if (argc > 3) { |
112 | printf("Trying to bootstrap into the network...\n"); | 116 | printf("Trying to bootstrap into the network...\n"); |
113 | IP_Port bootstrap_info; | ||
114 | bootstrap_info.ip.uint32 = inet_addr(argv[1]); | ||
115 | bootstrap_info.port = htons(atoi(argv[2])); | ||
116 | uint8_t *bootstrap_key = hex_string_to_bin(argv[3]); | 117 | uint8_t *bootstrap_key = hex_string_to_bin(argv[3]); |
117 | DHT_bootstrap(dht, bootstrap_info, bootstrap_key); | 118 | DHT_bootstrap_ex(dht, argv[1], ipv6enabled, htons(atoi(argv[2])), bootstrap_key); |
118 | free(bootstrap_key); | 119 | free(bootstrap_key); |
119 | } | 120 | } |
120 | 121 | ||
diff --git a/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c b/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c index 58af2751..cf19435d 100644 --- a/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c +++ b/other/bootstrap_serverdaemon/DHT_bootstrap_daemon.c | |||
@@ -301,7 +301,12 @@ struct server_conf_s configure_server(char *cfg_file) | |||
301 | printf("bootstrap_server %d: Invalid port.\n", i); | 301 | printf("bootstrap_server %d: Invalid port.\n", i); |
302 | } | 302 | } |
303 | 303 | ||
304 | #ifdef TOX_ENABLE_IPV6 | ||
305 | server_conf.info[i].conn.ip.family = AF_INET; | ||
306 | server_conf.info[i].conn.ip.ip4.uint32 = resolve_addr(strcpy(tmp_ip, bs_ip)); | ||
307 | #else | ||
304 | server_conf.info[i].conn.ip.uint32 = resolve_addr(strcpy(tmp_ip, bs_ip)); | 308 | server_conf.info[i].conn.ip.uint32 = resolve_addr(strcpy(tmp_ip, bs_ip)); |
309 | #endif | ||
305 | server_conf.info[i].conn.port = htons(bs_port); | 310 | server_conf.info[i].conn.port = htons(bs_port); |
306 | b16_to_key(strcpy(tmp_pk, bs_pk), bs_pk_p); | 311 | b16_to_key(strcpy(tmp_pk, bs_pk), bs_pk_p); |
307 | } | 312 | } |
@@ -339,8 +344,8 @@ int main(int argc, char *argv[]) | |||
339 | 344 | ||
340 | /* Initialize networking | 345 | /* Initialize networking |
341 | bind to ip 0.0.0.0:PORT */ | 346 | bind to ip 0.0.0.0:PORT */ |
342 | IP4 ip; | 347 | IP ip; |
343 | ip.uint32 = 0; | 348 | ip_init(&ip, 0); |
344 | DHT *dht = new_DHT(new_net_crypto(new_networking(ip, server_conf.port))); | 349 | DHT *dht = new_DHT(new_net_crypto(new_networking(ip, server_conf.port))); |
345 | /* Read the config file */ | 350 | /* Read the config file */ |
346 | printf("PID file: %s\n", server_conf.pid_file); | 351 | printf("PID file: %s\n", server_conf.pid_file); |
diff --git a/testing/DHT_test.c b/testing/DHT_test.c index a7349a65..caa0cde2 100644 --- a/testing/DHT_test.c +++ b/testing/DHT_test.c | |||
@@ -66,13 +66,11 @@ void print_clientlist(DHT *dht) | |||
66 | } | 66 | } |
67 | 67 | ||
68 | p_ip = dht->close_clientlist[i].ip_port; | 68 | p_ip = dht->close_clientlist[i].ip_port; |
69 | printf("\nIP: %u.%u.%u.%u Port: %u", p_ip.ip.uint8[0], p_ip.ip.uint8[1], p_ip.ip.uint8[2], p_ip.ip.uint8[3], | 69 | printf("\nIP: %s Port: %u", ip_ntoa(&p_ip.ip), ntohs(p_ip.port)); |
70 | ntohs(p_ip.port)); | ||
71 | printf("\nTimestamp: %llu", (long long unsigned int) dht->close_clientlist[i].timestamp); | 70 | printf("\nTimestamp: %llu", (long long unsigned int) dht->close_clientlist[i].timestamp); |
72 | printf("\nLast pinged: %llu\n", (long long unsigned int) dht->close_clientlist[i].last_pinged); | 71 | printf("\nLast pinged: %llu\n", (long long unsigned int) dht->close_clientlist[i].last_pinged); |
73 | p_ip = dht->close_clientlist[i].ret_ip_port; | 72 | p_ip = dht->close_clientlist[i].ret_ip_port; |
74 | printf("OUR IP: %u.%u.%u.%u Port: %u\n", p_ip.ip.uint8[0], p_ip.ip.uint8[1], p_ip.ip.uint8[2], p_ip.ip.uint8[3], | 73 | printf("OUR IP: %s Port: %u\n", ip_ntoa(&p_ip.ip), ntohs(p_ip.port)); |
75 | ntohs(p_ip.port)); | ||
76 | printf("Timestamp: %llu\n", (long long unsigned int) dht->close_clientlist[i].ret_timestamp); | 74 | printf("Timestamp: %llu\n", (long long unsigned int) dht->close_clientlist[i].ret_timestamp); |
77 | } | 75 | } |
78 | } | 76 | } |
@@ -91,9 +89,8 @@ void print_friendlist(DHT *dht) | |||
91 | printf("%c", dht->friends_list[k].client_id[j]); | 89 | printf("%c", dht->friends_list[k].client_id[j]); |
92 | } | 90 | } |
93 | 91 | ||
94 | p_ip = DHT_getfriendip(dht, dht->friends_list[k].client_id); | 92 | int friendok = DHT_getfriendip(dht, dht->friends_list[k].client_id, &p_ip); |
95 | printf("\nIP: %u.%u.%u.%u:%u", p_ip.ip.uint8[0], p_ip.ip.uint8[1], p_ip.ip.uint8[2], p_ip.ip.uint8[3], | 93 | printf("\nIP: %s:%u", ip_ntoa(&p_ip.ip), ntohs(p_ip.port)); |
96 | ntohs(p_ip.port)); | ||
97 | 94 | ||
98 | printf("\nCLIENTS IN LIST:\n\n"); | 95 | printf("\nCLIENTS IN LIST:\n\n"); |
99 | 96 | ||
@@ -108,13 +105,11 @@ void print_friendlist(DHT *dht) | |||
108 | } | 105 | } |
109 | 106 | ||
110 | p_ip = dht->friends_list[k].client_list[i].ip_port; | 107 | p_ip = dht->friends_list[k].client_list[i].ip_port; |
111 | printf("\nIP: %u.%u.%u.%u:%u", p_ip.ip.uint8[0], p_ip.ip.uint8[1], p_ip.ip.uint8[2], p_ip.ip.uint8[3], | 108 | printf("\nIP: %s:%u", ip_ntoa(&p_ip.ip), ntohs(p_ip.port)); |
112 | ntohs(p_ip.port)); | ||
113 | printf("\nTimestamp: %llu", (long long unsigned int) dht->friends_list[k].client_list[i].timestamp); | 109 | printf("\nTimestamp: %llu", (long long unsigned int) dht->friends_list[k].client_list[i].timestamp); |
114 | printf("\nLast pinged: %llu\n", (long long unsigned int) dht->friends_list[k].client_list[i].last_pinged); | 110 | printf("\nLast pinged: %llu\n", (long long unsigned int) dht->friends_list[k].client_list[i].last_pinged); |
115 | p_ip = dht->friends_list[k].client_list[i].ret_ip_port; | 111 | p_ip = dht->friends_list[k].client_list[i].ret_ip_port; |
116 | printf("ret IP: %u.%u.%u.%u:%u\n", p_ip.ip.uint8[0], p_ip.ip.uint8[1], p_ip.ip.uint8[2], p_ip.ip.uint8[3], | 112 | printf("ret IP: %s:%u\n", ip_ntoa(&p_ip.ip), ntohs(p_ip.port)); |
117 | ntohs(p_ip.port)); | ||
118 | printf("Timestamp: %llu\n", (long long unsigned int)dht->friends_list[k].client_list[i].ret_timestamp); | 113 | printf("Timestamp: %llu\n", (long long unsigned int)dht->friends_list[k].client_list[i].ret_timestamp); |
119 | } | 114 | } |
120 | } | 115 | } |
@@ -138,11 +133,14 @@ void printpacket(uint8_t *data, uint32_t length, IP_Port ip_port) | |||
138 | 133 | ||
139 | int main(int argc, char *argv[]) | 134 | int main(int argc, char *argv[]) |
140 | { | 135 | { |
136 | /* let use decide by cmdline: TODO */ | ||
137 | uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; | ||
138 | |||
141 | //memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32); | 139 | //memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32); |
142 | /* initialize networking */ | 140 | /* initialize networking */ |
143 | /* bind to ip 0.0.0.0:PORT */ | 141 | /* bind to ip 0.0.0.0:PORT */ |
144 | IP4 ip; | 142 | IP ip; |
145 | ip.uint32 = 0; | 143 | ip_init(&ip, ipv6enabled); |
146 | 144 | ||
147 | DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT))); | 145 | DHT *dht = new_DHT(new_net_crypto(new_networking(ip, PORT))); |
148 | 146 | ||
@@ -172,14 +170,7 @@ int main(int argc, char *argv[]) | |||
172 | 170 | ||
173 | 171 | ||
174 | perror("Initialization"); | 172 | perror("Initialization"); |
175 | IP_Port bootstrap_ip_port; | 173 | DHT_bootstrap_ex(dht, argv[1], ipv6enabled, htons(atoi(argv[2])), hex_string_to_bin(argv[3])); |
176 | bootstrap_ip_port.port = htons(atoi(argv[2])); | ||
177 | /* bootstrap_ip_port.ip.c[0] = 127; | ||
178 | * bootstrap_ip_port.ip.c[1] = 0; | ||
179 | * bootstrap_ip_port.ip.c[2] = 0; | ||
180 | * bootstrap_ip_port.ip.c[3] = 1; */ | ||
181 | bootstrap_ip_port.ip.uint32 = inet_addr(argv[1]); | ||
182 | DHT_bootstrap(dht, bootstrap_ip_port, hex_string_to_bin(argv[3])); | ||
183 | 174 | ||
184 | /* | 175 | /* |
185 | IP_Port ip_port; | 176 | IP_Port ip_port; |
diff --git a/testing/Lossless_UDP_testclient.c b/testing/Lossless_UDP_testclient.c index 4ac94b4b..564b2ecf 100644 --- a/testing/Lossless_UDP_testclient.c +++ b/testing/Lossless_UDP_testclient.c | |||
@@ -66,8 +66,7 @@ void printpacket(uint8_t *data, uint32_t length, IP_Port ip_port) | |||
66 | 66 | ||
67 | void printip(IP_Port ip_port) | 67 | void printip(IP_Port ip_port) |
68 | { | 68 | { |
69 | printf("\nIP: %u.%u.%u.%u Port: %u", ip_port.ip.uint8[0], ip_port.ip.uint8[1], ip_port.ip.uint8[2], ip_port.ip.uint8[3], | 69 | printf("\nIP: %s Port: %u", ip_ntoa(&ip_port.ip), ntohs(ip_port.port)); |
70 | ntohs(ip_port.port)); | ||
71 | } | 70 | } |
72 | /* | 71 | /* |
73 | void printpackets(Data test) | 72 | void printpackets(Data test) |
@@ -152,6 +151,9 @@ void printconnection(int connection_id) | |||
152 | 151 | ||
153 | int main(int argc, char *argv[]) | 152 | int main(int argc, char *argv[]) |
154 | { | 153 | { |
154 | /* let use decide by cmdline: TODO */ | ||
155 | uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; | ||
156 | |||
155 | if (argc < 4) { | 157 | if (argc < 4) { |
156 | printf("usage: %s ip port filename\n", argv[0]); | 158 | printf("usage: %s ip port filename\n", argv[0]); |
157 | exit(0); | 159 | exit(0); |
@@ -168,14 +170,18 @@ int main(int argc, char *argv[]) | |||
168 | 170 | ||
169 | /* initialize networking */ | 171 | /* initialize networking */ |
170 | /* bind to ip 0.0.0.0:PORT */ | 172 | /* bind to ip 0.0.0.0:PORT */ |
171 | IP4 ip; | 173 | IP ip; |
172 | ip.uint32 = 0; | 174 | ip_init(&ip, ipv6enabled); |
175 | |||
173 | Lossless_UDP *ludp = new_lossless_udp(new_networking(ip, PORT)); | 176 | Lossless_UDP *ludp = new_lossless_udp(new_networking(ip, PORT)); |
174 | perror("Initialization"); | 177 | perror("Initialization"); |
178 | |||
175 | IP_Port serverip; | 179 | IP_Port serverip; |
176 | serverip.ip.uint32 = inet_addr(argv[1]); | 180 | ip_init(&serverip.ip, ipv6enabled); |
181 | addr_resolve(argv[1], &serverip.ip); | ||
177 | serverip.port = htons(atoi(argv[2])); | 182 | serverip.port = htons(atoi(argv[2])); |
178 | printip(serverip); | 183 | printip(serverip); |
184 | |||
179 | int connection = new_connection(ludp, serverip); | 185 | int connection = new_connection(ludp, serverip); |
180 | uint64_t timer = current_time(); | 186 | uint64_t timer = current_time(); |
181 | 187 | ||
diff --git a/testing/Lossless_UDP_testserver.c b/testing/Lossless_UDP_testserver.c index e0ea92bc..3e54e9be 100644 --- a/testing/Lossless_UDP_testserver.c +++ b/testing/Lossless_UDP_testserver.c | |||
@@ -147,6 +147,9 @@ void printconnection(int connection_id) | |||
147 | 147 | ||
148 | int main(int argc, char *argv[]) | 148 | int main(int argc, char *argv[]) |
149 | { | 149 | { |
150 | /* let use decide by cmdline: TODO */ | ||
151 | uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; | ||
152 | |||
150 | if (argc < 2) { | 153 | if (argc < 2) { |
151 | printf("usage: %s filename\n", argv[0]); | 154 | printf("usage: %s filename\n", argv[0]); |
152 | exit(0); | 155 | exit(0); |
@@ -163,8 +166,9 @@ int main(int argc, char *argv[]) | |||
163 | 166 | ||
164 | //initialize networking | 167 | //initialize networking |
165 | //bind to ip 0.0.0.0:PORT | 168 | //bind to ip 0.0.0.0:PORT |
166 | IP4 ip; | 169 | IP ip; |
167 | ip.uint32 = 0; | 170 | ip_init(&ip, ipv6enabled); |
171 | |||
168 | Lossless_UDP *ludp = new_lossless_udp(new_networking(ip, PORT)); | 172 | Lossless_UDP *ludp = new_lossless_udp(new_networking(ip, PORT)); |
169 | perror("Initialization"); | 173 | perror("Initialization"); |
170 | 174 | ||
diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c index 04d3bc14..73d44efb 100644 --- a/testing/Messenger_test.c +++ b/testing/Messenger_test.c | |||
@@ -101,7 +101,8 @@ int main(int argc, char *argv[]) | |||
101 | } | 101 | } |
102 | 102 | ||
103 | /* IPv6: maybe allow from cmdline --ipv6? sticking to IPv4 for now */ | 103 | /* IPv6: maybe allow from cmdline --ipv6? sticking to IPv4 for now */ |
104 | m = initMessenger(0); | 104 | uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; |
105 | m = initMessenger(ipv6enabled); | ||
105 | 106 | ||
106 | if ( !m ) { | 107 | if ( !m ) { |
107 | fputs("Failed to allocate messenger datastructure\n", stderr); | 108 | fputs("Failed to allocate messenger datastructure\n", stderr); |
@@ -110,7 +111,7 @@ int main(int argc, char *argv[]) | |||
110 | 111 | ||
111 | if (argc > 3) { | 112 | if (argc > 3) { |
112 | uint16_t port = htons(atoi(argv[2])); | 113 | uint16_t port = htons(atoi(argv[2])); |
113 | DHT_bootstrap_ex(m->dht, argv[1], port, hex_string_to_bin(argv[3])); | 114 | DHT_bootstrap_ex(m->dht, argv[1], ipv6enabled, port, hex_string_to_bin(argv[3])); |
114 | } else { | 115 | } else { |
115 | FILE *file = fopen(argv[1], "rb"); | 116 | FILE *file = fopen(argv[1], "rb"); |
116 | 117 | ||
diff --git a/testing/nTox.c b/testing/nTox.c index 438468bd..6084aeda 100644 --- a/testing/nTox.c +++ b/testing/nTox.c | |||
@@ -537,6 +537,9 @@ void print_help(void) | |||
537 | 537 | ||
538 | int main(int argc, char *argv[]) | 538 | int main(int argc, char *argv[]) |
539 | { | 539 | { |
540 | /* let use decide by cmdline: TODO */ | ||
541 | uint8_t ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; | ||
542 | |||
540 | int on = 0; | 543 | int on = 0; |
541 | int c = 0; | 544 | int c = 0; |
542 | int i = 0; | 545 | int i = 0; |
@@ -566,7 +569,7 @@ int main(int argc, char *argv[]) | |||
566 | } | 569 | } |
567 | } | 570 | } |
568 | 571 | ||
569 | m = tox_new(); | 572 | m = tox_new_ex(ipv6enabled); |
570 | 573 | ||
571 | if ( !m ) { | 574 | if ( !m ) { |
572 | fputs("Failed to allocate Messenger datastructure", stderr); | 575 | fputs("Failed to allocate Messenger datastructure", stderr); |
@@ -590,20 +593,12 @@ int main(int argc, char *argv[]) | |||
590 | new_lines(idstring); | 593 | new_lines(idstring); |
591 | strcpy(line, ""); | 594 | strcpy(line, ""); |
592 | 595 | ||
593 | tox_IP_Port bootstrap_ip_port; | 596 | uint16_t port = htons(atoi(argv[2])); |
594 | bootstrap_ip_port.port = htons(atoi(argv[2])); | ||
595 | int resolved_address = resolve_addr(argv[1]); | ||
596 | |||
597 | if (resolved_address != 0) | ||
598 | bootstrap_ip_port.ip.i = resolved_address; | ||
599 | else | ||
600 | exit(1); | ||
601 | |||
602 | unsigned char *binary_string = hex_string_to_bin(argv[3]); | 597 | unsigned char *binary_string = hex_string_to_bin(argv[3]); |
603 | tox_bootstrap(m, bootstrap_ip_port, binary_string); | 598 | tox_bootstrap_ex(m, argv[1], ipv6enabled, port, binary_string); |
604 | free(binary_string); | 599 | free(binary_string); |
605 | nodelay(stdscr, TRUE); | ||
606 | 600 | ||
601 | nodelay(stdscr, TRUE); | ||
607 | while (1) { | 602 | while (1) { |
608 | if (on == 0 && tox_isconnected(m)) { | 603 | if (on == 0 && tox_isconnected(m)) { |
609 | new_lines("[i] connected to DHT\n[i] define username with /n"); | 604 | new_lines("[i] connected to DHT\n[i] define username with /n"); |
diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 4c15c1eb..a4734747 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c | |||
@@ -115,11 +115,6 @@ static int client_id_cmp(ClientPair p1, ClientPair p2) | |||
115 | return c; | 115 | return c; |
116 | } | 116 | } |
117 | 117 | ||
118 | static int ip4port_equal(IP_Port a, IP_Port b) | ||
119 | { | ||
120 | return (a.ip.uint32 == b.ip.uint32) && (a.port == b.port); | ||
121 | } | ||
122 | |||
123 | static int id_equal(uint8_t *a, uint8_t *b) | 118 | static int id_equal(uint8_t *a, uint8_t *b) |
124 | { | 119 | { |
125 | return memcmp(a, b, CLIENT_ID_SIZE) == 0; | 120 | return memcmp(a, b, CLIENT_ID_SIZE) == 0; |
@@ -144,15 +139,14 @@ static int client_in_list(Client_data *list, uint32_t length, uint8_t *client_id | |||
144 | 139 | ||
145 | for (i = 0; i < length; ++i) { | 140 | for (i = 0; i < length; ++i) { |
146 | /* If ip_port is assigned to a different client_id replace it */ | 141 | /* If ip_port is assigned to a different client_id replace it */ |
147 | if (ip4port_equal(list[i].ip_port, ip_port)) { | 142 | if (ipport_equal(&list[i].ip_port, &ip_port)) { |
148 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); | 143 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); |
149 | } | 144 | } |
150 | 145 | ||
151 | if (id_equal(list[i].client_id, client_id)) { | 146 | if (id_equal(list[i].client_id, client_id)) { |
152 | /* Refresh the client timestamp. */ | 147 | /* Refresh the client timestamp. */ |
153 | list[i].timestamp = temp_time; | 148 | list[i].timestamp = temp_time; |
154 | list[i].ip_port.ip.uint32 = ip_port.ip.uint32; | 149 | ipport_copy(&list[i].ip_port, &ip_port); |
155 | list[i].ip_port.port = ip_port.port; | ||
156 | return 1; | 150 | return 1; |
157 | } | 151 | } |
158 | } | 152 | } |
@@ -216,7 +210,7 @@ static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list | |||
216 | * we COULD send ALL as NET_PACKET_SEND_NODES_EX if we KNEW that the | 210 | * we COULD send ALL as NET_PACKET_SEND_NODES_EX if we KNEW that the |
217 | * partner node understands - that's true if *they* are on IPv6 | 211 | * partner node understands - that's true if *they* are on IPv6 |
218 | */ | 212 | */ |
219 | #ifdef NETWORK_IP_PORT_IS_IPV6 | 213 | #ifdef TOX_ENABLE_IPV6 |
220 | ipv46x = 0; | 214 | ipv46x = 0; |
221 | if (sa_family == AF_INET) | 215 | if (sa_family == AF_INET) |
222 | ipv46x = dht->close_clientlist[i].ip_port.ip.family != AF_INET; | 216 | ipv46x = dht->close_clientlist[i].ip_port.ip.family != AF_INET; |
@@ -266,7 +260,7 @@ static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list | |||
266 | MAX_SENT_NODES, | 260 | MAX_SENT_NODES, |
267 | dht->friends_list[i].client_list[j].client_id); | 261 | dht->friends_list[i].client_list[j].client_id); |
268 | 262 | ||
269 | #ifdef NETWORK_IP_PORT_IS_IPV6 | 263 | #ifdef TOX_ENABLE_IPV6 |
270 | ipv46x = 0; | 264 | ipv46x = 0; |
271 | if (sa_family == AF_INET) | 265 | if (sa_family == AF_INET) |
272 | ipv46x = dht->friends_list[i].client_list[j].ip_port.ip.family != AF_INET; | 266 | ipv46x = dht->friends_list[i].client_list[j].ip_port.ip.family != AF_INET; |
@@ -330,7 +324,7 @@ static int replace_bad( Client_data *list, | |||
330 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); | 324 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); |
331 | list[i].ip_port = ip_port; | 325 | list[i].ip_port = ip_port; |
332 | list[i].timestamp = temp_time; | 326 | list[i].timestamp = temp_time; |
333 | list[i].ret_ip_port.ip.uint32 = 0; | 327 | ip_reset(&list[i].ret_ip_port.ip); |
334 | list[i].ret_ip_port.port = 0; | 328 | list[i].ret_ip_port.port = 0; |
335 | list[i].ret_timestamp = 0; | 329 | list[i].ret_timestamp = 0; |
336 | return 0; | 330 | return 0; |
@@ -378,7 +372,7 @@ static int replace_good( Client_data *list, | |||
378 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); | 372 | memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE); |
379 | list[i].ip_port = ip_port; | 373 | list[i].ip_port = ip_port; |
380 | list[i].timestamp = temp_time; | 374 | list[i].timestamp = temp_time; |
381 | list[i].ret_ip_port.ip.uint32 = 0; | 375 | ip_reset(&list[i].ret_ip_port.ip); |
382 | list[i].ret_ip_port.port = 0; | 376 | list[i].ret_ip_port.port = 0; |
383 | list[i].ret_timestamp = 0; | 377 | list[i].ret_timestamp = 0; |
384 | return 0; | 378 | return 0; |
@@ -476,13 +470,13 @@ static int is_gettingnodes(DHT *dht, IP_Port ip_port, uint64_t ping_id) | |||
476 | if (!is_timeout(temp_time, dht->send_nodes[i].timestamp, PING_TIMEOUT)) { | 470 | if (!is_timeout(temp_time, dht->send_nodes[i].timestamp, PING_TIMEOUT)) { |
477 | pinging = 0; | 471 | pinging = 0; |
478 | 472 | ||
479 | if (ip_port.ip.uint32 != 0 && ip4port_equal(dht->send_nodes[i].ip_port, ip_port)) | 473 | if (ping_id != 0 && dht->send_nodes[i].ping_id == ping_id) |
480 | ++pinging; | 474 | ++pinging; |
481 | 475 | ||
482 | if (ping_id != 0 && dht->send_nodes[i].ping_id == ping_id) | 476 | if (ip_isset(&ip_port.ip) && ipport_equal(&dht->send_nodes[i].ip_port, &ip_port)) |
483 | ++pinging; | 477 | ++pinging; |
484 | 478 | ||
485 | if (pinging == (ping_id != 0) + (ip_port.ip.uint32 != 0)) | 479 | if (pinging == (ping_id != 0) + (ip_isset(&ip_port.ip) != 0)) |
486 | return 1; | 480 | return 1; |
487 | } | 481 | } |
488 | } | 482 | } |
@@ -575,11 +569,11 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl | |||
575 | random_nonce(nonce); | 569 | random_nonce(nonce); |
576 | 570 | ||
577 | memcpy(plain, &ping_id, sizeof(ping_id)); | 571 | memcpy(plain, &ping_id, sizeof(ping_id)); |
578 | #if DHT_NODEFORMAT == 46 | 572 | #ifdef TOX_ENABLE_IPV6 |
579 | Node4_format *nodes4_list = &(plain + sizeof(ping_id)); | 573 | Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id)); |
580 | int i, num_nodes_ok = 0; | 574 | int i, num_nodes_ok = 0; |
581 | for(i = 0; i < num_nodes, i++) | 575 | for(i = 0; i < num_nodes; i++) |
582 | if (nodes_list[i].ip.family == AF_INET) { | 576 | if (nodes_list[i].ip_port.ip.family == AF_INET) { |
583 | memcpy(nodes4_list[num_nodes_ok].client_id, nodes_list[i].client_id, CLIENT_ID_SIZE); | 577 | memcpy(nodes4_list[num_nodes_ok].client_id, nodes_list[i].client_id, CLIENT_ID_SIZE); |
584 | nodes4_list[num_nodes_ok].ip_port.ip.uint32 = nodes_list[i].ip_port.ip.ip4.uint32; | 578 | nodes4_list[num_nodes_ok].ip_port.ip.uint32 = nodes_list[i].ip_port.ip.ip4.uint32; |
585 | nodes4_list[num_nodes_ok].ip_port.port = nodes_list[i].ip_port.port; | 579 | nodes4_list[num_nodes_ok].ip_port.port = nodes_list[i].ip_port.port; |
@@ -680,14 +674,15 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3 | |||
680 | if (!is_gettingnodes(dht, source, ping_id)) | 674 | if (!is_gettingnodes(dht, source, ping_id)) |
681 | return 1; | 675 | return 1; |
682 | 676 | ||
677 | uint32_t i; | ||
683 | Node_format nodes_list[MAX_SENT_NODES]; | 678 | Node_format nodes_list[MAX_SENT_NODES]; |
684 | 679 | ||
685 | #if DHT_NODEFORMAT == 46 | 680 | #ifdef TOX_ENABLE_IPV6 |
686 | Node4_format *nodes4_list = &(plain + sizeof(ping_id)); | 681 | Node4_format *nodes4_list = (Node4_format *)(plain + sizeof(ping_id)); |
687 | 682 | ||
688 | int i, num_nodes_ok = 0; | 683 | int num_nodes_ok = 0; |
689 | for(i = 0; i < num_nodes, i++) | 684 | for(i = 0; i < num_nodes; i++) |
690 | if ((nodes_list[i].ip != 0) && (nodes_list[i].ip != ~0)) { | 685 | if ((nodes4_list[i].ip_port.ip.uint32 != 0) && (nodes4_list[i].ip_port.ip.uint32 != ~0)) { |
691 | memcpy(nodes_list[num_nodes_ok].client_id, nodes4_list[i].client_id, CLIENT_ID_SIZE); | 686 | memcpy(nodes_list[num_nodes_ok].client_id, nodes4_list[i].client_id, CLIENT_ID_SIZE); |
692 | nodes_list[num_nodes_ok].ip_port.ip.family = AF_INET; | 687 | nodes_list[num_nodes_ok].ip_port.ip.family = AF_INET; |
693 | nodes_list[num_nodes_ok].ip_port.ip.ip4.uint32 = nodes4_list[i].ip_port.ip.uint32; | 688 | nodes_list[num_nodes_ok].ip_port.ip.ip4.uint32 = nodes4_list[i].ip_port.ip.uint32; |
@@ -706,8 +701,6 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3 | |||
706 | 701 | ||
707 | addto_lists(dht, source, packet + 1); | 702 | addto_lists(dht, source, packet + 1); |
708 | 703 | ||
709 | uint32_t i; | ||
710 | |||
711 | for (i = 0; i < num_nodes; ++i) { | 704 | for (i = 0; i < num_nodes; ++i) { |
712 | send_ping_request(dht->ping, dht->c, nodes_list[i].ip_port, nodes_list[i].client_id); | 705 | send_ping_request(dht->ping, dht->c, nodes_list[i].ip_port, nodes_list[i].client_id); |
713 | returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); | 706 | returnedip_ports(dht, nodes_list[i].ip_port, nodes_list[i].client_id, packet + 1); |
@@ -775,27 +768,30 @@ int DHT_delfriend(DHT *dht, uint8_t *client_id) | |||
775 | } | 768 | } |
776 | 769 | ||
777 | /* TODO: Optimize this. */ | 770 | /* TODO: Optimize this. */ |
778 | IP_Port DHT_getfriendip(DHT *dht, uint8_t *client_id) | 771 | int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port) |
779 | { | 772 | { |
780 | uint32_t i, j; | 773 | uint32_t i, j; |
781 | uint64_t temp_time = unix_time(); | 774 | uint64_t temp_time = unix_time(); |
782 | IP_Port empty = {{{{0}}, 0, 0}}; | 775 | |
776 | ip_reset(&ip_port->ip); | ||
777 | ip_port->port = 0; | ||
783 | 778 | ||
784 | for (i = 0; i < dht->num_friends; ++i) { | 779 | for (i = 0; i < dht->num_friends; ++i) { |
785 | /* Equal */ | 780 | /* Equal */ |
786 | if (id_equal(dht->friends_list[i].client_id, client_id)) { | 781 | if (id_equal(dht->friends_list[i].client_id, client_id)) { |
787 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { | 782 | for (j = 0; j < MAX_FRIEND_CLIENTS; ++j) { |
788 | if (id_equal(dht->friends_list[i].client_list[j].client_id, client_id) | 783 | if (id_equal(dht->friends_list[i].client_list[j].client_id, client_id) |
789 | && !is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) | 784 | && !is_timeout(temp_time, dht->friends_list[i].client_list[j].timestamp, BAD_NODE_TIMEOUT)) { |
790 | return dht->friends_list[i].client_list[j].ip_port; | 785 | *ip_port = dht->friends_list[i].client_list[j].ip_port; |
786 | return 1; | ||
787 | } | ||
791 | } | 788 | } |
792 | 789 | ||
793 | return empty; | 790 | return 0; |
794 | } | 791 | } |
795 | } | 792 | } |
796 | 793 | ||
797 | empty.ip.uint32 = 1; | 794 | return -1; |
798 | return empty; | ||
799 | } | 795 | } |
800 | 796 | ||
801 | /* Ping each client in the "friends" list every PING_INTERVAL seconds. Send a get nodes request | 797 | /* Ping each client in the "friends" list every PING_INTERVAL seconds. Send a get nodes request |
@@ -880,16 +876,12 @@ void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key) | |||
880 | getnodes(dht, ip_port, public_key, dht->c->self_public_key); | 876 | getnodes(dht, ip_port, public_key, dht->c->self_public_key); |
881 | send_ping_request(dht->ping, dht->c, ip_port, public_key); | 877 | send_ping_request(dht->ping, dht->c, ip_port, public_key); |
882 | } | 878 | } |
883 | void DHT_bootstrap_ex(DHT *dht, const char *address, uint16_t port, uint8_t *public_key) | 879 | void DHT_bootstrap_ex(DHT *dht, const char *address, uint8_t ipv6enabled, uint16_t port, uint8_t *public_key) |
884 | { | 880 | { |
885 | IPAny_Port ipany_port; | 881 | IP_Port ip_port; |
886 | ipany_port.ip.family = AF_INET; | 882 | ip_init(&ip_port.ip, ipv6enabled); |
887 | if (addr_resolve_or_parse_ip(address, &ipany_port.ip)) { | 883 | if (addr_resolve_or_parse_ip(address, &ip_port.ip)) { |
888 | /* IPAny temporary: copy down */ | ||
889 | IP_Port ip_port; | ||
890 | ip_port.ip.uint32 = ipany_port.ip.ip4.uint32; | ||
891 | ip_port.port = port; | 884 | ip_port.port = port; |
892 | |||
893 | DHT_bootstrap(dht, ip_port, public_key); | 885 | DHT_bootstrap(dht, ip_port, public_key); |
894 | } | 886 | } |
895 | } | 887 | } |
@@ -933,7 +925,7 @@ static int friend_iplist(DHT *dht, IP_Port *ip_portlist, uint16_t friend_num) | |||
933 | client = &friend->client_list[i]; | 925 | client = &friend->client_list[i]; |
934 | 926 | ||
935 | /* If ip is not zero and node is good. */ | 927 | /* If ip is not zero and node is good. */ |
936 | if (client->ret_ip_port.ip.uint32 != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { | 928 | if (ip_isset(&client->ret_ip_port.ip) && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { |
937 | 929 | ||
938 | if (id_equal(client->client_id, friend->client_id)) | 930 | if (id_equal(client->client_id, friend->client_id)) |
939 | return 0; | 931 | return 0; |
@@ -975,7 +967,7 @@ int route_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint32_t lengt | |||
975 | client = &friend->client_list[i]; | 967 | client = &friend->client_list[i]; |
976 | 968 | ||
977 | /* If ip is not zero and node is good. */ | 969 | /* If ip is not zero and node is good. */ |
978 | if (client->ret_ip_port.ip.uint32 != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { | 970 | if (ip_isset(&client->ret_ip_port.ip) && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { |
979 | int retval = sendpacket(dht->c->lossless_udp->net, client->ip_port, packet, length); | 971 | int retval = sendpacket(dht->c->lossless_udp->net, client->ip_port, packet, length); |
980 | 972 | ||
981 | if ((unsigned int)retval == length) | 973 | if ((unsigned int)retval == length) |
@@ -1009,7 +1001,7 @@ static int routeone_tofriend(DHT *dht, uint8_t *friend_id, uint8_t *packet, uint | |||
1009 | client = &friend->client_list[i]; | 1001 | client = &friend->client_list[i]; |
1010 | 1002 | ||
1011 | /* If ip is not zero and node is good. */ | 1003 | /* If ip is not zero and node is good. */ |
1012 | if (client->ret_ip_port.ip.uint32 != 0 && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { | 1004 | if (ip_isset(&client->ret_ip_port.ip) && !is_timeout(temp_time, client->ret_timestamp, BAD_NODE_TIMEOUT)) { |
1013 | ip_list[n] = client->ip_port; | 1005 | ip_list[n] = client->ip_port; |
1014 | ++n; | 1006 | ++n; |
1015 | } | 1007 | } |
@@ -1115,9 +1107,10 @@ static int handle_NATping(void *object, IP_Port source, uint8_t *source_pubkey, | |||
1115 | * | 1107 | * |
1116 | * return ip of 0 if failure. | 1108 | * return ip of 0 if failure. |
1117 | */ | 1109 | */ |
1118 | static IP4 NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num) | 1110 | static IP NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num) |
1119 | { | 1111 | { |
1120 | IP4 zero = {{0}}; | 1112 | IP zero; |
1113 | ip_reset(&zero); | ||
1121 | 1114 | ||
1122 | if (len > MAX_FRIEND_CLIENTS) | 1115 | if (len > MAX_FRIEND_CLIENTS) |
1123 | return zero; | 1116 | return zero; |
@@ -1127,7 +1120,7 @@ static IP4 NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num) | |||
1127 | 1120 | ||
1128 | for (i = 0; i < len; ++i) { | 1121 | for (i = 0; i < len; ++i) { |
1129 | for (j = 0; j < len; ++j) { | 1122 | for (j = 0; j < len; ++j) { |
1130 | if (ip_portlist[i].ip.uint32 == ip_portlist[j].ip.uint32) | 1123 | if (ip_equal(&ip_portlist[i].ip, &ip_portlist[j].ip)) |
1131 | ++numbers[i]; | 1124 | ++numbers[i]; |
1132 | } | 1125 | } |
1133 | 1126 | ||
@@ -1144,13 +1137,13 @@ static IP4 NAT_commonip(IP_Port *ip_portlist, uint16_t len, uint16_t min_num) | |||
1144 | * | 1137 | * |
1145 | * return number of ports and puts the list of ports in portlist. | 1138 | * return number of ports and puts the list of ports in portlist. |
1146 | */ | 1139 | */ |
1147 | static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t len, IP4 ip) | 1140 | static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t len, IP ip) |
1148 | { | 1141 | { |
1149 | uint32_t i; | 1142 | uint32_t i; |
1150 | uint16_t num = 0; | 1143 | uint16_t num = 0; |
1151 | 1144 | ||
1152 | for (i = 0; i < len; ++i) { | 1145 | for (i = 0; i < len; ++i) { |
1153 | if (ip_portlist[i].ip.uint32 == ip.uint32) { | 1146 | if (ip_equal(&ip_portlist[i].ip, &ip)) { |
1154 | portlist[num] = ntohs(ip_portlist[i].port); | 1147 | portlist[num] = ntohs(ip_portlist[i].port); |
1155 | ++num; | 1148 | ++num; |
1156 | } | 1149 | } |
@@ -1159,7 +1152,7 @@ static uint16_t NAT_getports(uint16_t *portlist, IP_Port *ip_portlist, uint16_t | |||
1159 | return num; | 1152 | return num; |
1160 | } | 1153 | } |
1161 | 1154 | ||
1162 | static void punch_holes(DHT *dht, IP4 ip, uint16_t *port_list, uint16_t numports, uint16_t friend_num) | 1155 | static void punch_holes(DHT *dht, IP ip, uint16_t *port_list, uint16_t numports, uint16_t friend_num) |
1163 | { | 1156 | { |
1164 | if (numports > MAX_FRIEND_CLIENTS || numports == 0) | 1157 | if (numports > MAX_FRIEND_CLIENTS || numports == 0) |
1165 | return; | 1158 | return; |
@@ -1170,7 +1163,9 @@ static void punch_holes(DHT *dht, IP4 ip, uint16_t *port_list, uint16_t numports | |||
1170 | for (i = dht->friends_list[friend_num].punching_index; i != top; i++) { | 1163 | for (i = dht->friends_list[friend_num].punching_index; i != top; i++) { |
1171 | /* TODO: Improve port guessing algorithm. */ | 1164 | /* TODO: Improve port guessing algorithm. */ |
1172 | uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1); | 1165 | uint16_t port = port_list[(i / 2) % numports] + (i / (2 * numports)) * ((i % 2) ? -1 : 1); |
1173 | IP_Port pinging = {{ip, htons(port), 0}}; | 1166 | IP_Port pinging; |
1167 | ip_copy(&pinging.ip, &ip); | ||
1168 | pinging.port = htons(port); | ||
1174 | send_ping_request(dht->ping, dht->c, pinging, dht->friends_list[friend_num].client_id); | 1169 | send_ping_request(dht->ping, dht->c, pinging, dht->friends_list[friend_num].client_id); |
1175 | } | 1170 | } |
1176 | 1171 | ||
@@ -1199,9 +1194,8 @@ static void do_NAT(DHT *dht) | |||
1199 | dht->friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time && | 1194 | dht->friends_list[i].punching_timestamp + PUNCH_INTERVAL < temp_time && |
1200 | dht->friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) { | 1195 | dht->friends_list[i].recvNATping_timestamp + PUNCH_INTERVAL * 2 >= temp_time) { |
1201 | 1196 | ||
1202 | IP4 ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2); | 1197 | IP ip = NAT_commonip(ip_list, num, MAX_FRIEND_CLIENTS / 2); |
1203 | 1198 | if (!ip_isset(&ip)) | |
1204 | if (ip.uint32 == 0) | ||
1205 | continue; | 1199 | continue; |
1206 | 1200 | ||
1207 | uint16_t port_list[MAX_FRIEND_CLIENTS]; | 1201 | uint16_t port_list[MAX_FRIEND_CLIENTS]; |
@@ -1230,16 +1224,15 @@ static void do_NAT(DHT *dht) | |||
1230 | */ | 1224 | */ |
1231 | int add_toping(DHT *dht, uint8_t *client_id, IP_Port ip_port) | 1225 | int add_toping(DHT *dht, uint8_t *client_id, IP_Port ip_port) |
1232 | { | 1226 | { |
1233 | if (ip_port.ip.uint32 == 0) | 1227 | if (!ip_isset(&ip_port.ip)) |
1234 | return -1; | 1228 | return -1; |
1235 | 1229 | ||
1236 | uint32_t i; | 1230 | uint32_t i; |
1237 | 1231 | ||
1238 | for (i = 0; i < MAX_TOPING; ++i) { | 1232 | for (i = 0; i < MAX_TOPING; ++i) { |
1239 | if (dht->toping[i].ip_port.ip.uint32 == 0) { | 1233 | if (!ip_isset(&dht->toping[i].ip_port.ip)) { |
1240 | memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE); | 1234 | memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE); |
1241 | dht->toping[i].ip_port.ip.uint32 = ip_port.ip.uint32; | 1235 | ipport_copy(&dht->toping[i].ip_port, &ip_port); |
1242 | dht->toping[i].ip_port.port = ip_port.port; | ||
1243 | return 0; | 1236 | return 0; |
1244 | } | 1237 | } |
1245 | } | 1238 | } |
@@ -1247,8 +1240,7 @@ int add_toping(DHT *dht, uint8_t *client_id, IP_Port ip_port) | |||
1247 | for (i = 0; i < MAX_TOPING; ++i) { | 1240 | for (i = 0; i < MAX_TOPING; ++i) { |
1248 | if (id_closest(dht->c->self_public_key, dht->toping[i].client_id, client_id) == 2) { | 1241 | if (id_closest(dht->c->self_public_key, dht->toping[i].client_id, client_id) == 2) { |
1249 | memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE); | 1242 | memcpy(dht->toping[i].client_id, client_id, CLIENT_ID_SIZE); |
1250 | dht->toping[i].ip_port.ip.uint32 = ip_port.ip.uint32; | 1243 | ipport_copy(&dht->toping[i].ip_port, &ip_port); |
1251 | dht->toping[i].ip_port.port = ip_port.port; | ||
1252 | return 0; | 1244 | return 0; |
1253 | } | 1245 | } |
1254 | } | 1246 | } |
@@ -1270,11 +1262,11 @@ static void do_toping(DHT *dht) | |||
1270 | uint32_t i; | 1262 | uint32_t i; |
1271 | 1263 | ||
1272 | for (i = 0; i < MAX_TOPING; ++i) { | 1264 | for (i = 0; i < MAX_TOPING; ++i) { |
1273 | if (dht->toping[i].ip_port.ip.uint32 == 0) | 1265 | if (!ip_isset(&dht->toping[i].ip_port.ip)) |
1274 | return; | 1266 | return; |
1275 | 1267 | ||
1276 | send_ping_request(dht->ping, dht->c, dht->toping[i].ip_port, dht->toping[i].client_id); | 1268 | send_ping_request(dht->ping, dht->c, dht->toping[i].ip_port, dht->toping[i].client_id); |
1277 | dht->toping[i].ip_port.ip.uint32 = 0; | 1269 | ip_reset(&dht->toping[i].ip_port.ip); |
1278 | } | 1270 | } |
1279 | } | 1271 | } |
1280 | 1272 | ||
diff --git a/toxcore/DHT.h b/toxcore/DHT.h index 5963d297..d980f269 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h | |||
@@ -83,13 +83,14 @@ typedef struct { | |||
83 | 83 | ||
84 | typedef struct { | 84 | typedef struct { |
85 | uint8_t client_id[CLIENT_ID_SIZE]; | 85 | uint8_t client_id[CLIENT_ID_SIZE]; |
86 | IPAny_Port ip_port; | 86 | IP_Port ip_port; |
87 | } Node46_format; | 87 | } Node46_format; |
88 | /* IPAny temporary: change to 46 */ | 88 | |
89 | #define DHT_NODEFORMAT 4 | 89 | #ifdef TOX_ENABLE_IPV6 |
90 | typedef Node46_format Node_format; | ||
91 | #else | ||
90 | typedef Node4_format Node_format; | 92 | typedef Node4_format Node_format; |
91 | /* #define DHT_NODEFORMAT 46 */ | 93 | #endif |
92 | /* typedef Node46_format Node_format; */ | ||
93 | 94 | ||
94 | typedef struct { | 95 | typedef struct { |
95 | IP_Port ip_port; | 96 | IP_Port ip_port; |
@@ -135,11 +136,21 @@ int DHT_delfriend(DHT *dht, uint8_t *client_id); | |||
135 | * ip must be 4 bytes long. | 136 | * ip must be 4 bytes long. |
136 | * port must be 2 bytes long. | 137 | * port must be 2 bytes long. |
137 | * | 138 | * |
139 | * !!! Signature changed!!! | ||
140 | * | ||
141 | * OLD: IP_Port DHT_getfriendip(DHT *dht, uint8_t *client_id); | ||
142 | * | ||
138 | * return ip if success. | 143 | * return ip if success. |
139 | * return ip of 0 if failure (This means the friend is either offline or we have not found him yet). | 144 | * return ip of 0 if failure (This means the friend is either offline or we have not found him yet). |
140 | * return ip of 1 if friend is not in list. | 145 | * return ip of 1 if friend is not in list. |
146 | * | ||
147 | * NEW: int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port); | ||
148 | * | ||
149 | * return -1, -- if client_id does NOT refer to a friend | ||
150 | * return 0, -- if client_id refers to a friend and we failed to find the friend (yet) | ||
151 | * return 1, ip if client_id refers to a friend and we found him | ||
141 | */ | 152 | */ |
142 | IP_Port DHT_getfriendip(DHT *dht, uint8_t *client_id); | 153 | int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port); |
143 | 154 | ||
144 | /* Run this function at least a couple times per second (It's the main loop). */ | 155 | /* Run this function at least a couple times per second (It's the main loop). */ |
145 | void do_DHT(DHT *dht); | 156 | void do_DHT(DHT *dht); |
@@ -148,7 +159,7 @@ void do_DHT(DHT *dht); | |||
148 | * Sends a get nodes request to the given node with ip port and public_key. | 159 | * Sends a get nodes request to the given node with ip port and public_key. |
149 | */ | 160 | */ |
150 | void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key); | 161 | void DHT_bootstrap(DHT *dht, IP_Port ip_port, uint8_t *public_key); |
151 | void DHT_bootstrap_ex(DHT *dht, const char *address, uint16_t port, uint8_t *public_key); | 162 | void DHT_bootstrap_ex(DHT *dht, const char *address, uint8_t ipv6enabled, uint16_t port, uint8_t *public_key); |
152 | 163 | ||
153 | /* Add nodes to the toping list. | 164 | /* Add nodes to the toping list. |
154 | * All nodes in this list are pinged every TIME_TOPING seconds | 165 | * All nodes in this list are pinged every TIME_TOPING seconds |
diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c index bc73a6a1..4cbe3177 100644 --- a/toxcore/LAN_discovery.c +++ b/toxcore/LAN_discovery.c | |||
@@ -81,33 +81,76 @@ static uint32_t send_broadcasts(Networking_Core *net, uint16_t port, uint8_t * d | |||
81 | #endif | 81 | #endif |
82 | 82 | ||
83 | /* Return the broadcast ip. */ | 83 | /* Return the broadcast ip. */ |
84 | static IP4 broadcast_ip(void) | 84 | static IP broadcast_ip(sa_family_t sa_family) |
85 | { | 85 | { |
86 | IP4 ip; | 86 | IP ip; |
87 | ip.uint32 = ~0; | 87 | ip_reset(&ip); |
88 | |||
89 | #ifdef TOX_ENABLE_IPV6 | ||
90 | if (sa_family == AF_INET) | ||
91 | { | ||
92 | ip.family = AF_INET; | ||
93 | ip.ip4.uint32 = INADDR_BROADCAST; | ||
94 | } | ||
95 | |||
96 | if (sa_family == AF_INET6) | ||
97 | { | ||
98 | ip.family = AF_INET6; | ||
99 | /* FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */ | ||
100 | /* FE80::*: MUST be exact, for that we would need to look over all | ||
101 | * interfaces and check in which status they are */ | ||
102 | ip.ip6.s6_addr[ 0] = 0xFF; | ||
103 | ip.ip6.s6_addr[ 1] = 0x02; | ||
104 | ip.ip6.s6_addr[15] = 0x01; | ||
105 | } | ||
106 | #else | ||
107 | ip.uint32 = INADDR_BROADCAST; | ||
108 | #endif | ||
109 | |||
88 | return ip; | 110 | return ip; |
89 | } | 111 | } |
90 | 112 | ||
91 | /* return 0 if ip is a LAN ip. | 113 | /* return 0 if ip is a LAN ip. |
92 | * return -1 if it is not. | 114 | * return -1 if it is not. |
93 | */ | 115 | */ |
94 | static int LAN_ip(IP4 ip) | 116 | static int LAN_ip(IP ip) |
95 | { | 117 | { |
96 | if (ip.uint8[0] == 127) /* Loopback. */ | 118 | #ifdef TOX_ENABLE_IPV6 |
97 | return 0; | 119 | if (ip.family == AF_INET) { |
98 | 120 | IP4 ip4 = ip.ip4; | |
99 | if (ip.uint8[0] == 10) /* 10.0.0.0 to 10.255.255.255 range. */ | 121 | #else |
100 | return 0; | 122 | IP4 ip4 = ip; |
101 | 123 | #endif | |
102 | if (ip.uint8[0] == 172 && ip.uint8[1] >= 16 && ip.uint8[1] <= 31) /* 172.16.0.0 to 172.31.255.255 range. */ | 124 | /* Loopback. */ |
103 | return 0; | 125 | if (ip4.uint8[0] == 127) |
104 | 126 | return 0; | |
105 | if (ip.uint8[0] == 192 && ip.uint8[1] == 168) /* 192.168.0.0 to 192.168.255.255 range. */ | 127 | |
106 | return 0; | 128 | /* 10.0.0.0 to 10.255.255.255 range. */ |
107 | 129 | if (ip4.uint8[0] == 10) | |
108 | if (ip.uint8[0] == 169 && ip.uint8[1] == 254 && ip.uint8[2] != 0 | 130 | return 0; |
109 | && ip.uint8[2] != 255)/* 169.254.1.0 to 169.254.254.255 range. */ | 131 | |
110 | return 0; | 132 | /* 172.16.0.0 to 172.31.255.255 range. */ |
133 | if (ip4.uint8[0] == 172 && ip4.uint8[1] >= 16 && ip4.uint8[1] <= 31) | ||
134 | return 0; | ||
135 | |||
136 | /* 192.168.0.0 to 192.168.255.255 range. */ | ||
137 | if (ip4.uint8[0] == 192 && ip4.uint8[1] == 168) | ||
138 | return 0; | ||
139 | |||
140 | /* 169.254.1.0 to 169.254.254.255 range. */ | ||
141 | if (ip4.uint8[0] == 169 && ip4.uint8[1] == 254 && ip4.uint8[2] != 0 | ||
142 | && ip4.uint8[2] != 255) | ||
143 | return 0; | ||
144 | #ifdef TOX_ENABLE_IPV6 | ||
145 | } | ||
146 | else if (ip.family == AF_INET6) { | ||
147 | /* autogenerated for each interface: FE80::* (up to FEBF::*) | ||
148 | /* FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */ | ||
149 | if (((ip.ip6.s6_addr[0] == 0xFF) && (ip.ip6.s6_addr[1] < 3) && (ip.ip6.s6_addr[15] == 1)) || | ||
150 | ((ip.ip6.s6_addr[0] == 0xFE) && ((ip.ip6.s6_addr[1] & 0xC0) == 0x80))) | ||
151 | return 0; | ||
152 | } | ||
153 | #endif | ||
111 | 154 | ||
112 | return -1; | 155 | return -1; |
113 | } | 156 | } |
@@ -135,7 +178,9 @@ int send_LANdiscovery(uint16_t port, Net_Crypto *c) | |||
135 | #ifdef __linux | 178 | #ifdef __linux |
136 | send_broadcasts(c->lossless_udp->net, port, data, 1 + crypto_box_PUBLICKEYBYTES); | 179 | send_broadcasts(c->lossless_udp->net, port, data, 1 + crypto_box_PUBLICKEYBYTES); |
137 | #endif | 180 | #endif |
138 | IP_Port ip_port = {{broadcast_ip(), port, 0}}; | 181 | IP_Port ip_port; |
182 | ip_port.ip = broadcast_ip(c->lossless_udp->net->family); | ||
183 | ip_port.port = port; | ||
139 | return sendpacket(c->lossless_udp->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES); | 184 | return sendpacket(c->lossless_udp->net, ip_port, data, 1 + crypto_box_PUBLICKEYBYTES); |
140 | } | 185 | } |
141 | 186 | ||
diff --git a/toxcore/Lossless_UDP.c b/toxcore/Lossless_UDP.c index f66d5b62..ca874562 100644 --- a/toxcore/Lossless_UDP.c +++ b/toxcore/Lossless_UDP.c | |||
@@ -44,9 +44,7 @@ | |||
44 | int getconnection_id(Lossless_UDP *ludp, IP_Port ip_port) | 44 | int getconnection_id(Lossless_UDP *ludp, IP_Port ip_port) |
45 | { | 45 | { |
46 | tox_array_for_each(&ludp->connections, Connection, tmp) { | 46 | tox_array_for_each(&ludp->connections, Connection, tmp) { |
47 | if (tmp->ip_port.ip.uint32 == ip_port.ip.uint32 && | 47 | if (tmp-> status > 0 && ipport_equal(&tmp->ip_port, &ip_port)) { |
48 | tmp->ip_port.port == ip_port.port && | ||
49 | tmp->status > 0) { | ||
50 | return tmp_i; | 48 | return tmp_i; |
51 | } | 49 | } |
52 | } | 50 | } |
@@ -61,17 +59,49 @@ int getconnection_id(Lossless_UDP *ludp, IP_Port ip_port) | |||
61 | * | 59 | * |
62 | * TODO: make this better | 60 | * TODO: make this better |
63 | */ | 61 | */ |
64 | static uint32_t handshake_id(Lossless_UDP *ludp, IP_Port source) | 62 | |
63 | static uint8_t randtable_initget(Lossless_UDP *ludp, uint32_t index, uint8_t value) | ||
65 | { | 64 | { |
66 | uint32_t id = 0, i; | 65 | if (ludp->randtable[index][value] == 0) |
66 | ludp->randtable[index][value] = random_int(); | ||
67 | 67 | ||
68 | for (i = 0; i < 6; ++i) { | 68 | return ludp->randtable[index][value]; |
69 | if (ludp->randtable[i][source.uint8[i]] == 0) | 69 | } |
70 | ludp->randtable[i][source.uint8[i]] = random_int(); | ||
71 | 70 | ||
72 | id ^= ludp->randtable[i][source.uint8[i]]; | 71 | static uint32_t handshake_id(Lossless_UDP *ludp, IP_Port source) |
72 | { | ||
73 | uint32_t id = 0, i = 0; | ||
74 | |||
75 | uint8_t *uint8; | ||
76 | uint8 = (uint8_t *)&source.port; | ||
77 | id ^= randtable_initget(ludp, i, *uint8); | ||
78 | i++, uint8++; | ||
79 | id ^= randtable_initget(ludp, i, *uint8); | ||
80 | i++; | ||
81 | |||
82 | #ifdef TOX_ENABLE_IPV6 | ||
83 | if (source.ip.family == AF_INET) | ||
84 | { | ||
85 | IP4 ip4 = source.ip.ip4; | ||
86 | #else | ||
87 | IP4 ip4 = source.ip; | ||
88 | #endif | ||
89 | int k; | ||
90 | for (k = 0; k < 4; k++) { | ||
91 | id ^= randtable_initget(ludp, i++, ip4.uint8[k]); | ||
92 | } | ||
93 | #ifdef TOX_ENABLE_IPV6 | ||
73 | } | 94 | } |
74 | 95 | ||
96 | if (source.ip.family == AF_INET6) | ||
97 | { | ||
98 | int k; | ||
99 | for (k = 0; k < 16; k++) { | ||
100 | id ^= randtable_initget(ludp, i++, source.ip.ip6.s6_addr[k]); | ||
101 | } | ||
102 | } | ||
103 | #endif | ||
104 | |||
75 | /* id can't be zero. */ | 105 | /* id can't be zero. */ |
76 | if (id == 0) | 106 | if (id == 0) |
77 | id = 1; | 107 | id = 1; |
@@ -290,7 +320,9 @@ IP_Port connection_ip(Lossless_UDP *ludp, int connection_id) | |||
290 | if ((unsigned int)connection_id < ludp->connections.len) | 320 | if ((unsigned int)connection_id < ludp->connections.len) |
291 | return tox_array_get(&ludp->connections, connection_id, Connection).ip_port; | 321 | return tox_array_get(&ludp->connections, connection_id, Connection).ip_port; |
292 | 322 | ||
293 | IP_Port zero = {{{{0}}, 0, 0}}; | 323 | IP_Port zero; |
324 | ip_reset(&zero.ip); | ||
325 | zero.port = 0; | ||
294 | return zero; | 326 | return zero; |
295 | } | 327 | } |
296 | 328 | ||
diff --git a/toxcore/Lossless_UDP.h b/toxcore/Lossless_UDP.h index 20471b0a..f0ce0e87 100644 --- a/toxcore/Lossless_UDP.h +++ b/toxcore/Lossless_UDP.h | |||
@@ -123,7 +123,13 @@ typedef struct { | |||
123 | tox_array connections; | 123 | tox_array connections; |
124 | 124 | ||
125 | /* Table of random numbers used in handshake_id. */ | 125 | /* Table of random numbers used in handshake_id. */ |
126 | #ifdef TOX_ENABLE_IPV6 | ||
127 | /* IPv6 (16) + port (2)*/ | ||
128 | uint32_t randtable[18][256]; | ||
129 | #else | ||
130 | /* IPv4 (4) + port (2) */ | ||
126 | uint32_t randtable[6][256]; | 131 | uint32_t randtable[6][256]; |
132 | #endif | ||
127 | 133 | ||
128 | } Lossless_UDP; | 134 | } Lossless_UDP; |
129 | 135 | ||
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 61a76a76..cf744e23 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c | |||
@@ -658,14 +658,8 @@ Messenger *initMessenger(uint8_t ipv6enabled) | |||
658 | if ( ! m ) | 658 | if ( ! m ) |
659 | return NULL; | 659 | return NULL; |
660 | 660 | ||
661 | #ifdef NETWORK_IP_PORT_IS_IPV6 | 661 | IP ip; |
662 | IPAny ip; | 662 | ip_init(&ip, ipv6enabled); |
663 | memset(&ip, 0, sizeof(ip)); | ||
664 | ip.family = ipv6enabled ? AF_INET6 : AF_INET; | ||
665 | #else | ||
666 | IP4 ip; | ||
667 | ip.uint32 = 0; | ||
668 | #endif | ||
669 | m->net = new_networking(ip, PORT); | 663 | m->net = new_networking(ip, PORT); |
670 | 664 | ||
671 | if (m->net == NULL) { | 665 | if (m->net == NULL) { |
@@ -749,11 +743,12 @@ void doFriends(Messenger *m) | |||
749 | } | 743 | } |
750 | } | 744 | } |
751 | 745 | ||
752 | IP_Port friendip = DHT_getfriendip(m->dht, m->friendlist[i].client_id); | 746 | IP_Port friendip; |
747 | int friendok = DHT_getfriendip(m->dht, m->friendlist[i].client_id, &friendip); | ||
753 | 748 | ||
754 | switch (is_cryptoconnected(m->net_crypto, m->friendlist[i].crypt_connection_id)) { | 749 | switch (is_cryptoconnected(m->net_crypto, m->friendlist[i].crypt_connection_id)) { |
755 | case 0: | 750 | case 0: |
756 | if (friendip.ip.uint32 > 1) | 751 | if (friendok == 1) |
757 | m->friendlist[i].crypt_connection_id = crypto_connect(m->net_crypto, m->friendlist[i].client_id, friendip); | 752 | m->friendlist[i].crypt_connection_id = crypto_connect(m->net_crypto, m->friendlist[i].client_id, friendip); |
758 | 753 | ||
759 | break; | 754 | break; |
diff --git a/toxcore/friend_requests.c b/toxcore/friend_requests.c index 51a8112f..c821d998 100644 --- a/toxcore/friend_requests.c +++ b/toxcore/friend_requests.c | |||
@@ -50,18 +50,22 @@ int send_friendrequest(DHT *dht, uint8_t *public_key, uint32_t nospam_num, uint8 | |||
50 | if (len == -1) | 50 | if (len == -1) |
51 | return -1; | 51 | return -1; |
52 | 52 | ||
53 | IP_Port ip_port = DHT_getfriendip(dht, public_key); | 53 | IP_Port ip_port; |
54 | int friendok = DHT_getfriendip(dht, public_key, &ip_port); | ||
54 | 55 | ||
55 | if (ip_port.ip.uint32 == 1) | 56 | // not a friend |
57 | if (friendok == -1) | ||
56 | return -1; | 58 | return -1; |
57 | 59 | ||
58 | if (ip_port.ip.uint32 != 0) { | 60 | // is a friend and we know how to reach him |
61 | if (friendok == 1) { | ||
59 | if (sendpacket(dht->c->lossless_udp->net, ip_port, packet, len) != -1) | 62 | if (sendpacket(dht->c->lossless_udp->net, ip_port, packet, len) != -1) |
60 | return 0; | 63 | return 0; |
61 | 64 | ||
62 | return -1; | 65 | return -1; |
63 | } | 66 | } |
64 | 67 | ||
68 | // is a friend, we DON'T know how to reach him | ||
65 | int num = route_tofriend(dht, public_key, packet, len); | 69 | int num = route_tofriend(dht, public_key, packet, len); |
66 | 70 | ||
67 | if (num == 0) | 71 | if (num == 0) |
diff --git a/toxcore/group_chats.c b/toxcore/group_chats.c index 1b021e20..59266b7a 100644 --- a/toxcore/group_chats.c +++ b/toxcore/group_chats.c | |||
@@ -204,7 +204,7 @@ static uint8_t sendto_allpeers(Group_Chat *chat, uint8_t *data, uint16_t length, | |||
204 | uint64_t temp_time = unix_time(); | 204 | uint64_t temp_time = unix_time(); |
205 | 205 | ||
206 | for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { | 206 | for (i = 0; i < GROUP_CLOSE_CONNECTIONS; ++i) { |
207 | if (chat->close[i].ip_port.ip.uint32 != 0 && chat->close[i].last_recv + BAD_NODE_TIMEOUT > temp_time) { | 207 | if (ip_isset(&chat->close[i].ip_port.ip) && chat->close[i].last_recv + BAD_NODE_TIMEOUT > temp_time) { |
208 | if (send_groupchatpacket(chat, chat->close[i].ip_port, chat->close[i].client_id, data, length, request_id) == 0) | 208 | if (send_groupchatpacket(chat, chat->close[i].ip_port, chat->close[i].client_id, data, length, request_id) == 0) |
209 | ++sent; | 209 | ++sent; |
210 | } | 210 | } |
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index a182bb53..b6f08fe4 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c | |||
@@ -439,7 +439,7 @@ int crypto_connect(Net_Crypto *c, uint8_t *public_key, IP_Port ip_port) | |||
439 | if (id != -1) { | 439 | if (id != -1) { |
440 | IP_Port c_ip = connection_ip(c->lossless_udp, c->crypto_connections[id].number); | 440 | IP_Port c_ip = connection_ip(c->lossless_udp, c->crypto_connections[id].number); |
441 | 441 | ||
442 | if (c_ip.ip.uint32 == ip_port.ip.uint32 && c_ip.port == ip_port.port) | 442 | if (ipport_equal(&c_ip, &ip_port)) |
443 | return -1; | 443 | return -1; |
444 | } | 444 | } |
445 | 445 | ||
diff --git a/toxcore/network.c b/toxcore/network.c index 1fb5b77a..d65e2077 100644 --- a/toxcore/network.c +++ b/toxcore/network.c | |||
@@ -66,8 +66,63 @@ uint32_t random_int(void) | |||
66 | */ | 66 | */ |
67 | int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t length) | 67 | int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t length) |
68 | { | 68 | { |
69 | ADDR addr = {AF_INET, ip_port.port, ip_port.ip, {0}}; | 69 | #ifdef TOX_ENABLE_IPV6 |
70 | return sendto(net->sock, (char *) data, length, 0, (struct sockaddr *)&addr, sizeof(addr)); | 70 | /* socket AF_INET, but target IP NOT: can't send */ |
71 | if ((net->family == AF_INET) && (ip_port.ip.family != AF_INET)) | ||
72 | return 0; | ||
73 | #endif | ||
74 | |||
75 | struct sockaddr_storage addr; | ||
76 | size_t addrsize = 0; | ||
77 | |||
78 | #ifdef TOX_ENABLE_IPV6 | ||
79 | if (ip_port.ip.family == AF_INET) { | ||
80 | if (net->family == AF_INET6) { | ||
81 | /* must convert to IPV4-in-IPV6 address */ | ||
82 | addrsize = sizeof(struct sockaddr_in6); | ||
83 | struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; | ||
84 | addr6->sin6_family = AF_INET6; | ||
85 | addr6->sin6_port = ip_port.port; | ||
86 | |||
87 | /* there should be a macro for this in a standards compliant | ||
88 | * environment, not found */ | ||
89 | addr6->sin6_addr.s6_addr32[0] = 0; | ||
90 | addr6->sin6_addr.s6_addr32[1] = 0; | ||
91 | addr6->sin6_addr.s6_addr32[2] = htonl(0xFFFF); | ||
92 | addr6->sin6_addr.s6_addr32[3] = ip_port.ip.ip4.uint32; | ||
93 | |||
94 | addr6->sin6_flowinfo = 0; | ||
95 | addr6->sin6_scope_id = 0; | ||
96 | } | ||
97 | else { | ||
98 | IP4 ip4 = ip_port.ip.ip4; | ||
99 | #else | ||
100 | IP4 ip4 = ip_port.ip; | ||
101 | #endif | ||
102 | addrsize = sizeof(struct sockaddr_in); | ||
103 | struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; | ||
104 | addr4->sin_family = AF_INET; | ||
105 | addr4->sin_addr = ip4.in_addr; | ||
106 | addr4->sin_port = ip_port.port; | ||
107 | #ifdef TOX_ENABLE_IPV6 | ||
108 | } | ||
109 | } | ||
110 | else if (ip_port.ip.family == AF_INET6) { | ||
111 | addrsize = sizeof(struct sockaddr_in6); | ||
112 | struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; | ||
113 | addr6->sin6_family = AF_INET6; | ||
114 | addr6->sin6_port = ip_port.port; | ||
115 | addr6->sin6_addr = ip_port.ip.ip6; | ||
116 | |||
117 | addr6->sin6_flowinfo = 0; | ||
118 | addr6->sin6_scope_id = 0; | ||
119 | } else { | ||
120 | /* unknown address type*/ | ||
121 | return 0; | ||
122 | } | ||
123 | #endif | ||
124 | |||
125 | return sendto(net->sock, (char *) data, length, 0, (struct sockaddr *)&addr, addrsize); | ||
71 | } | 126 | } |
72 | 127 | ||
73 | /* Function to receive data | 128 | /* Function to receive data |
@@ -82,7 +137,7 @@ static int receivepacket(unsigned int sock, IP_Port *ip_port, uint8_t *data, uin | |||
82 | static int receivepacket(int sock, IP_Port *ip_port, uint8_t *data, uint32_t *length) | 137 | static int receivepacket(int sock, IP_Port *ip_port, uint8_t *data, uint32_t *length) |
83 | #endif | 138 | #endif |
84 | { | 139 | { |
85 | ADDR addr; | 140 | struct sockaddr_storage addr; |
86 | #ifdef WIN32 | 141 | #ifdef WIN32 |
87 | int addrlen = sizeof(addr); | 142 | int addrlen = sizeof(addr); |
88 | #else | 143 | #else |
@@ -93,8 +148,31 @@ static int receivepacket(int sock, IP_Port *ip_port, uint8_t *data, uint32_t *le | |||
93 | if (*(int32_t *)length <= 0) | 148 | if (*(int32_t *)length <= 0) |
94 | return -1; /* Nothing received or empty packet. */ | 149 | return -1; /* Nothing received or empty packet. */ |
95 | 150 | ||
96 | ip_port->ip = addr.ip; | 151 | #ifdef TOX_ENABLE_IPV6 |
97 | ip_port->port = addr.port; | 152 | if (addr.ss_family == AF_INET) { |
153 | struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr; | ||
154 | ip_port->ip.family = addr_in->sin_family; | ||
155 | ip_port->ip.ip4.in_addr = addr_in->sin_addr; | ||
156 | ip_port->port = addr_in->sin_port; | ||
157 | } | ||
158 | else if (addr.ss_family == AF_INET6) { | ||
159 | struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)&addr; | ||
160 | ip_port->ip.family = addr_in6->sin6_family; | ||
161 | ip_port->ip.ip6 = addr_in6->sin6_addr; | ||
162 | ip_port->port = addr_in6->sin6_port; | ||
163 | } | ||
164 | else | ||
165 | return -1; | ||
166 | #else | ||
167 | if (addr.ss_family == AF_INET) { | ||
168 | struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr; | ||
169 | ip_port->ip.in_addr = addr_in->sin_addr; | ||
170 | ip_port->port = addr_in->sin_port; | ||
171 | } | ||
172 | else | ||
173 | return -1; | ||
174 | #endif | ||
175 | |||
98 | return 0; | 176 | return 0; |
99 | } | 177 | } |
100 | 178 | ||
@@ -156,18 +234,32 @@ static void at_shutdown(void) | |||
156 | * return Networking_Core object if no problems | 234 | * return Networking_Core object if no problems |
157 | * return NULL if there are problems. | 235 | * return NULL if there are problems. |
158 | */ | 236 | */ |
159 | Networking_Core *new_networking(IP4 ip, uint16_t port) | 237 | Networking_Core *new_networking(IP ip, uint16_t port) |
160 | { | 238 | { |
239 | #ifdef TOX_ENABLE_IPV6 | ||
240 | /* maybe check for invalid IPs like 224+.x.y.z? if there is any IP set ever */ | ||
241 | if (ip.family != AF_INET && ip.family != AF_INET6) | ||
242 | return NULL; | ||
243 | #endif | ||
244 | |||
161 | if (at_startup() != 0) | 245 | if (at_startup() != 0) |
162 | return NULL; | 246 | return NULL; |
163 | 247 | ||
164 | /* Initialize our socket. */ | ||
165 | Networking_Core *temp = calloc(1, sizeof(Networking_Core)); | 248 | Networking_Core *temp = calloc(1, sizeof(Networking_Core)); |
166 | |||
167 | if (temp == NULL) | 249 | if (temp == NULL) |
168 | return NULL; | 250 | return NULL; |
169 | 251 | ||
170 | temp->family = AF_INET; | 252 | sa_family_t family = 0; |
253 | #ifdef TOX_ENABLE_IPV6 | ||
254 | family = ip.family; | ||
255 | #else | ||
256 | family = AF_INET; | ||
257 | #endif | ||
258 | temp->family = family; | ||
259 | temp->port = 0; | ||
260 | |||
261 | /* Initialize our socket. */ | ||
262 | /* add log message what we're creating */ | ||
171 | temp->sock = socket(temp->family, SOCK_DGRAM, IPPROTO_UDP); | 263 | temp->sock = socket(temp->family, SOCK_DGRAM, IPPROTO_UDP); |
172 | 264 | ||
173 | /* Check for socket error. */ | 265 | /* Check for socket error. */ |
@@ -201,7 +293,7 @@ Networking_Core *new_networking(IP4 ip, uint16_t port) | |||
201 | return -1; | 293 | return -1; |
202 | */ | 294 | */ |
203 | 295 | ||
204 | /* Enable broadcast on socket. */ | 296 | /* Enable broadcast on socket? */ |
205 | int broadcast = 1; | 297 | int broadcast = 1; |
206 | setsockopt(temp->sock, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast)); | 298 | setsockopt(temp->sock, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast)); |
207 | 299 | ||
@@ -216,11 +308,72 @@ Networking_Core *new_networking(IP4 ip, uint16_t port) | |||
216 | #endif | 308 | #endif |
217 | 309 | ||
218 | /* Bind our socket to port PORT and address 0.0.0.0 */ | 310 | /* Bind our socket to port PORT and address 0.0.0.0 */ |
219 | ADDR addr = {temp->family, htons(port), ip, {0}}; | 311 | uint16_t *portptr = NULL; |
220 | if (!bind(temp->sock, (struct sockaddr *)&addr, sizeof(addr))) | 312 | struct sockaddr_storage addr; |
221 | temp->port = port; | 313 | size_t addrsize; |
314 | #ifdef TOX_ENABLE_IPV6 | ||
315 | if (temp->family == AF_INET) | ||
316 | { | ||
317 | IP4 ip4 = ip.ip4; | ||
318 | #else | ||
319 | IP4 ip4 = ip; | ||
320 | #endif | ||
321 | addrsize = sizeof(struct sockaddr_in); | ||
322 | struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; | ||
323 | addr4->sin_family = AF_INET; | ||
324 | addr4->sin_port = htons(port); | ||
325 | addr4->sin_addr = ip4.in_addr; | ||
326 | |||
327 | portptr = &addr4->sin_port; | ||
328 | #ifdef TOX_ENABLE_IPV6 | ||
329 | } | ||
330 | else if (temp->family == AF_INET6) | ||
331 | { | ||
332 | addrsize = sizeof(struct sockaddr_in6); | ||
333 | struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; | ||
334 | addr6->sin6_family = AF_INET6; | ||
335 | addr6->sin6_port = htons(port); | ||
336 | addr6->sin6_addr = ip.ip6; | ||
337 | |||
338 | addr6->sin6_flowinfo = 0; | ||
339 | addr6->sin6_scope_id = 0; | ||
340 | |||
341 | portptr = &addr6->sin6_port; | ||
342 | } | ||
343 | else | ||
344 | return NULL; | ||
222 | 345 | ||
223 | return temp; | 346 | if (ip.family == AF_INET6) { |
347 | char ipv6only = 0; | ||
348 | int res = setsockopt(temp->sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, sizeof(ipv6only)); | ||
349 | if (res < 0) { | ||
350 | /* add log message*/ | ||
351 | } | ||
352 | } | ||
353 | #endif | ||
354 | |||
355 | /* a hanging program or a different user might block the standard port; | ||
356 | * as long as it isn't a parameter coming from the commandline, | ||
357 | * try a few ports after it, to see if we can find a "free" one | ||
358 | */ | ||
359 | int tries, res; | ||
360 | for(tries = 0; tries < 9; tries++) | ||
361 | { | ||
362 | res = bind(temp->sock, (struct sockaddr *)&addr, addrsize); | ||
363 | if (!res) | ||
364 | { | ||
365 | temp->port = *portptr; | ||
366 | return temp; | ||
367 | } | ||
368 | |||
369 | uint16_t port = ntohs(*portptr); | ||
370 | port++; | ||
371 | *portptr = htons(port); | ||
372 | } | ||
373 | |||
374 | printf("Failed to bind socket: %s (IP/Port: %s:%u\n", strerror(errno), ip_ntoa(&ip), port); | ||
375 | free(temp); | ||
376 | return NULL; | ||
224 | } | 377 | } |
225 | 378 | ||
226 | /* Function to cleanup networking stuff. */ | 379 | /* Function to cleanup networking stuff. */ |
@@ -241,11 +394,12 @@ void kill_networking(Networking_Core *net) | |||
241 | * | 394 | * |
242 | * returns 0 when not equal or when uninitialized | 395 | * returns 0 when not equal or when uninitialized |
243 | */ | 396 | */ |
244 | int ip_equal(IPAny *a, IPAny *b) | 397 | int ip_equal(IP *a, IP *b) |
245 | { | 398 | { |
246 | if (!a || !b) | 399 | if (!a || !b) |
247 | return 0; | 400 | return 0; |
248 | 401 | ||
402 | #ifdef TOX_ENABLE_IPV6 | ||
249 | if (a->family == AF_INET) | 403 | if (a->family == AF_INET) |
250 | return (a->ip4.in_addr.s_addr == b->ip4.in_addr.s_addr); | 404 | return (a->ip4.in_addr.s_addr == b->ip4.in_addr.s_addr); |
251 | 405 | ||
@@ -253,6 +407,9 @@ int ip_equal(IPAny *a, IPAny *b) | |||
253 | return IN6_ARE_ADDR_EQUAL(&a->ip6, &b->ip6); | 407 | return IN6_ARE_ADDR_EQUAL(&a->ip6, &b->ip6); |
254 | 408 | ||
255 | return 0; | 409 | return 0; |
410 | #else | ||
411 | return (a->uint32 == b->uint32); | ||
412 | #endif | ||
256 | }; | 413 | }; |
257 | 414 | ||
258 | /* ipport_equal | 415 | /* ipport_equal |
@@ -261,7 +418,7 @@ int ip_equal(IPAny *a, IPAny *b) | |||
261 | * | 418 | * |
262 | * returns 0 when not equal or when uninitialized | 419 | * returns 0 when not equal or when uninitialized |
263 | */ | 420 | */ |
264 | int ipport_equal(IPAny_Port *a, IPAny_Port *b) | 421 | int ipport_equal(IP_Port *a, IP_Port *b) |
265 | { | 422 | { |
266 | if (!a || !b) | 423 | if (!a || !b) |
267 | return 0; | 424 | return 0; |
@@ -272,15 +429,86 @@ int ipport_equal(IPAny_Port *a, IPAny_Port *b) | |||
272 | return ip_equal(&a->ip, &b->ip); | 429 | return ip_equal(&a->ip, &b->ip); |
273 | }; | 430 | }; |
274 | 431 | ||
275 | /* ipany_ntoa | 432 | /* nulls out ip */ |
433 | void ip_reset(IP *ip) | ||
434 | { | ||
435 | if (!ip) | ||
436 | return; | ||
437 | |||
438 | #ifdef TOX_ENABLE_IPV6 | ||
439 | memset(ip, 0, sizeof(*ip)); | ||
440 | #else | ||
441 | ip->uint32 = 0; | ||
442 | #endif | ||
443 | }; | ||
444 | |||
445 | /* nulls out ip, sets family according to flag */ | ||
446 | void ip_init(IP *ip, uint8_t ipv6enabled) | ||
447 | { | ||
448 | if (!ip) | ||
449 | return; | ||
450 | |||
451 | #ifdef TOX_ENABLE_IPV6 | ||
452 | memset(ip, 0, sizeof(ip)); | ||
453 | ip->family = ipv6enabled ? AF_INET6 : AF_INET; | ||
454 | #else | ||
455 | ip->uint32 = 0; | ||
456 | #endif | ||
457 | }; | ||
458 | |||
459 | /* checks if ip is valid */ | ||
460 | int ip_isset(IP *ip) | ||
461 | { | ||
462 | if (!ip) | ||
463 | return 0; | ||
464 | |||
465 | #ifdef TOX_ENABLE_IPV6 | ||
466 | return (ip->family != 0); | ||
467 | #else | ||
468 | return (ip->uint32 != 0); | ||
469 | #endif | ||
470 | }; | ||
471 | |||
472 | /* checks if ip is valid */ | ||
473 | int ipport_isset(IP_Port *ipport) | ||
474 | { | ||
475 | if (!ipport) | ||
476 | return 0; | ||
477 | |||
478 | if (!ipport->port) | ||
479 | return 0; | ||
480 | |||
481 | return ip_isset(&ipport->ip); | ||
482 | }; | ||
483 | |||
484 | /* copies an ip structure (careful about direction!) */ | ||
485 | void ip_copy(IP *target, IP *source) | ||
486 | { | ||
487 | if (!source || !target) | ||
488 | return; | ||
489 | |||
490 | memcpy(target, source, sizeof(IP)); | ||
491 | }; | ||
492 | |||
493 | /* copies an ip_port structure (careful about direction!) */ | ||
494 | void ipport_copy(IP_Port *target, IP_Port *source) | ||
495 | { | ||
496 | if (!source || !target) | ||
497 | return; | ||
498 | |||
499 | memcpy(target, source, sizeof(IP_Port)); | ||
500 | }; | ||
501 | |||
502 | /* ip_ntoa | ||
276 | * converts ip into a string | 503 | * converts ip into a string |
277 | * uses a static buffer, so mustn't used multiple times in the same output | 504 | * uses a static buffer, so mustn't used multiple times in the same output |
278 | */ | 505 | */ |
279 | /* there would be INET6_ADDRSTRLEN, but it might be too short for the error message */ | 506 | /* there would be INET6_ADDRSTRLEN, but it might be too short for the error message */ |
280 | static char addresstext[96]; | 507 | static char addresstext[96]; |
281 | const char *ipany_ntoa(IPAny *ip) | 508 | const char *ip_ntoa(IP *ip) |
282 | { | 509 | { |
283 | if (ip) { | 510 | if (ip) { |
511 | #ifdef TOX_ENABLE_IPV6 | ||
284 | if (ip->family == AF_INET) { | 512 | if (ip->family == AF_INET) { |
285 | addresstext[0] = 0; | 513 | addresstext[0] = 0; |
286 | struct in_addr *addr = (struct in_addr *)&ip->ip4; | 514 | struct in_addr *addr = (struct in_addr *)&ip->ip4; |
@@ -296,6 +524,11 @@ const char *ipany_ntoa(IPAny *ip) | |||
296 | } | 524 | } |
297 | else | 525 | else |
298 | snprintf(addresstext, sizeof(addresstext), "(IP invalid, family %u)", ip->family); | 526 | snprintf(addresstext, sizeof(addresstext), "(IP invalid, family %u)", ip->family); |
527 | #else | ||
528 | addresstext[0] = 0; | ||
529 | struct in_addr *addr = (struct in_addr *)&ip; | ||
530 | inet_ntop(AF_INET, addr, addresstext, sizeof(addresstext)); | ||
531 | #endif | ||
299 | } | 532 | } |
300 | else | 533 | else |
301 | snprintf(addresstext, sizeof(addresstext), "(IP invalid: NULL)"); | 534 | snprintf(addresstext, sizeof(addresstext), "(IP invalid: NULL)"); |
@@ -318,8 +551,12 @@ const char *ipany_ntoa(IPAny *ip) | |||
318 | * returns 1 on success, 0 on failure | 551 | * returns 1 on success, 0 on failure |
319 | */ | 552 | */ |
320 | 553 | ||
321 | int addr_parse_ip(const char *address, IPAny *to) | 554 | int addr_parse_ip(const char *address, IP *to) |
322 | { | 555 | { |
556 | if (!address || !to) | ||
557 | return 0; | ||
558 | |||
559 | #ifdef TOX_ENABLE_IPV6 | ||
323 | struct in_addr addr4; | 560 | struct in_addr addr4; |
324 | if (1 == inet_pton(AF_INET, address, &addr4)) { | 561 | if (1 == inet_pton(AF_INET, address, &addr4)) { |
325 | to->family = AF_INET; | 562 | to->family = AF_INET; |
@@ -333,6 +570,13 @@ int addr_parse_ip(const char *address, IPAny *to) | |||
333 | to->ip6 = addr6; | 570 | to->ip6 = addr6; |
334 | return 1; | 571 | return 1; |
335 | }; | 572 | }; |
573 | #else | ||
574 | struct in_addr addr4; | ||
575 | if (1 == inet_pton(AF_INET, address, &addr4)) { | ||
576 | to->in_addr = addr4; | ||
577 | return 1; | ||
578 | }; | ||
579 | #endif | ||
336 | 580 | ||
337 | return 0; | 581 | return 0; |
338 | }; | 582 | }; |
@@ -353,15 +597,25 @@ int addr_parse_ip(const char *address, IPAny *to) | |||
353 | * returns 0 on failure | 597 | * returns 0 on failure |
354 | */ | 598 | */ |
355 | 599 | ||
356 | int addr_resolve(const char *address, IPAny *ip) | 600 | int addr_resolve(const char *address, IP *to) |
357 | { | 601 | { |
602 | if (!address || !to) | ||
603 | return 0; | ||
604 | |||
605 | sa_family_t family; | ||
606 | #ifdef TOX_ENABLE_IPV6 | ||
607 | family = to->family; | ||
608 | #else | ||
609 | family = AF_INET; | ||
610 | #endif | ||
611 | |||
358 | struct addrinfo *server = NULL; | 612 | struct addrinfo *server = NULL; |
359 | struct addrinfo *walker = NULL; | 613 | struct addrinfo *walker = NULL; |
360 | struct addrinfo hints; | 614 | struct addrinfo hints; |
361 | int rc; | 615 | int rc; |
362 | 616 | ||
363 | memset(&hints, 0, sizeof(hints)); | 617 | memset(&hints, 0, sizeof(hints)); |
364 | hints.ai_family = ip->family; | 618 | hints.ai_family = family; |
365 | hints.ai_socktype = SOCK_DGRAM; // type of socket Tox uses. | 619 | hints.ai_socktype = SOCK_DGRAM; // type of socket Tox uses. |
366 | 620 | ||
367 | #ifdef __WIN32__ | 621 | #ifdef __WIN32__ |
@@ -385,31 +639,40 @@ int addr_resolve(const char *address, IPAny *ip) | |||
385 | return 0; | 639 | return 0; |
386 | } | 640 | } |
387 | 641 | ||
642 | #ifdef TOX_ENABLE_IPV6 | ||
388 | IP4 ip4; | 643 | IP4 ip4; |
389 | memset(&ip4, 0, sizeof(ip4)); | 644 | memset(&ip4, 0, sizeof(ip4)); |
390 | IP6 ip6; | 645 | IP6 ip6; |
391 | memset(&ip6, 0, sizeof(ip6)); | 646 | memset(&ip6, 0, sizeof(ip6)); |
647 | #endif | ||
392 | 648 | ||
393 | walker = server; | 649 | walker = server; |
394 | while (walker && (rc != 3)) { | 650 | while (walker && (rc != 3)) { |
395 | if (ip->family != AF_UNSPEC) { | 651 | if (family != AF_UNSPEC) { |
396 | if (walker->ai_family == ip->family) { | 652 | if (walker->ai_family == family) { |
397 | if (ip->family == AF_INET) { | 653 | if (family == AF_INET) { |
398 | if (walker->ai_addrlen == sizeof(struct sockaddr_in)) { | 654 | if (walker->ai_addrlen == sizeof(struct sockaddr_in)) { |
399 | struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; | 655 | struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr; |
400 | ip->ip4.in_addr = addr->sin_addr; | 656 | #ifdef TOX_ENABLE_IPV6 |
657 | to->ip4.in_addr = addr->sin_addr; | ||
658 | #else | ||
659 | to->in_addr = addr->sin_addr; | ||
660 | #endif | ||
401 | rc = 3; | 661 | rc = 3; |
402 | } | 662 | } |
403 | } | 663 | } |
404 | else if (ip->family == AF_INET6) { | 664 | #ifdef TOX_ENABLE_IPV6 |
665 | else if (family == AF_INET6) { | ||
405 | if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) { | 666 | if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) { |
406 | struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr; | 667 | struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr; |
407 | ip->ip6 = addr->sin6_addr; | 668 | to->ip6 = addr->sin6_addr; |
408 | rc = 3; | 669 | rc = 3; |
409 | } | 670 | } |
410 | } | 671 | } |
672 | #endif | ||
411 | } | 673 | } |
412 | } | 674 | } |
675 | #ifdef TOX_ENABLE_IPV6 | ||
413 | else { | 676 | else { |
414 | if (walker->ai_family == AF_INET) { | 677 | if (walker->ai_family == AF_INET) { |
415 | if (walker->ai_addrlen == sizeof(struct sockaddr_in)) { | 678 | if (walker->ai_addrlen == sizeof(struct sockaddr_in)) { |
@@ -426,22 +689,25 @@ int addr_resolve(const char *address, IPAny *ip) | |||
426 | } | 689 | } |
427 | } | 690 | } |
428 | } | 691 | } |
692 | #endif | ||
429 | 693 | ||
430 | walker = walker->ai_next; | 694 | walker = walker->ai_next; |
431 | } | 695 | } |
432 | 696 | ||
433 | if (ip->family == AF_UNSPEC) { | 697 | #ifdef TOX_ENABLE_IPV6 |
698 | if (to->family == AF_UNSPEC) { | ||
434 | if (rc & 2) { | 699 | if (rc & 2) { |
435 | ip->family = AF_INET6; | 700 | to->family = AF_INET6; |
436 | ip->ip6 = ip6; | 701 | to->ip6 = ip6; |
437 | } | 702 | } |
438 | else if (rc & 1) { | 703 | else if (rc & 1) { |
439 | ip->family = AF_INET; | 704 | to->family = AF_INET; |
440 | ip->ip4 = ip4; | 705 | to->ip4 = ip4; |
441 | } | 706 | } |
442 | else | 707 | else |
443 | rc = 0; | 708 | rc = 0; |
444 | } | 709 | } |
710 | #endif | ||
445 | 711 | ||
446 | 712 | ||
447 | freeaddrinfo(server); | 713 | freeaddrinfo(server); |
@@ -458,7 +724,7 @@ int addr_resolve(const char *address, IPAny *ip) | |||
458 | * to->family MUST be set (AF_UNSPEC, AF_INET, AF_INET6) | 724 | * to->family MUST be set (AF_UNSPEC, AF_INET, AF_INET6) |
459 | * returns 1 on success, 0 on failure | 725 | * returns 1 on success, 0 on failure |
460 | */ | 726 | */ |
461 | int addr_resolve_or_parse_ip(const char *address, IPAny *to) | 727 | int addr_resolve_or_parse_ip(const char *address, IP *to) |
462 | { | 728 | { |
463 | if (!addr_resolve(address, to)) | 729 | if (!addr_resolve(address, to)) |
464 | if (!addr_parse_ip(address, to)) | 730 | if (!addr_parse_ip(address, to)) |
diff --git a/toxcore/network.h b/toxcore/network.h index 913763ee..0d31ffac 100644 --- a/toxcore/network.h +++ b/toxcore/network.h | |||
@@ -101,12 +101,6 @@ typedef struct { | |||
101 | }; | 101 | }; |
102 | } IPAny; | 102 | } IPAny; |
103 | 103 | ||
104 | /* ipany_ntoa | ||
105 | * converts ip into a string | ||
106 | * uses a static buffer, so mustn't used multiple times in the same output | ||
107 | */ | ||
108 | const char *ipany_ntoa(IPAny *ip); | ||
109 | |||
110 | typedef union { | 104 | typedef union { |
111 | struct { | 105 | struct { |
112 | IP4 ip; | 106 | IP4 ip; |
@@ -124,29 +118,43 @@ typedef struct { | |||
124 | uint16_t port; | 118 | uint16_t port; |
125 | } IPAny_Port; | 119 | } IPAny_Port; |
126 | 120 | ||
127 | #ifdef NETWORK_IP_PORT_IS_IPV6 | 121 | #undef TOX_ENABLE_IPV6 |
122 | #ifdef TOX_ENABLE_IPV6 | ||
123 | #define TOX_ENABLE_IPV6_DEFAULT 1 | ||
124 | typedef IPAny IP; | ||
128 | typedef IPAny_Port IP_Port; | 125 | typedef IPAny_Port IP_Port; |
129 | #else | 126 | #else |
127 | #define TOX_ENABLE_IPV6_DEFAULT 0 | ||
128 | typedef IP4 IP; | ||
130 | typedef IP4_Port IP_Port; | 129 | typedef IP4_Port IP_Port; |
131 | #endif | 130 | #endif |
132 | 131 | ||
132 | /* ip_ntoa | ||
133 | * converts ip into a string | ||
134 | * uses a static buffer, so mustn't used multiple times in the same output | ||
135 | */ | ||
136 | const char *ip_ntoa(IP *ip); | ||
137 | |||
133 | /* ipport_equal | 138 | /* ipport_equal |
134 | * compares two IPAny_Port structures | 139 | * compares two IPAny_Port structures |
135 | * unset means unequal | 140 | * unset means unequal |
136 | * | 141 | * |
137 | * returns 0 when not equal or when uninitialized | 142 | * returns 0 when not equal or when uninitialized |
138 | */ | 143 | */ |
139 | int ipport_equal(IPAny_Port *a, IPAny_Port *b); | 144 | int ipport_equal(IP_Port *a, IP_Port *b); |
140 | 145 | ||
141 | typedef struct { | 146 | /* nulls out ip */ |
142 | int16_t family; | 147 | void ip_reset(IP *ip); |
143 | uint16_t port; | 148 | /* nulls out ip, sets family according to flag */ |
144 | IP4 ip; | 149 | void ip_init(IP *ip, uint8_t ipv6enabled); |
145 | uint8_t zeroes[8]; | 150 | /* checks if ip is valid */ |
146 | #ifdef ENABLE_IPV6 | 151 | int ip_isset(IP *ip); |
147 | uint8_t zeroes2[12]; | 152 | /* checks if ip is valid */ |
148 | #endif | 153 | int ipport_isset(IP_Port *ipport); |
149 | } ADDR; | 154 | /* copies an ip structure */ |
155 | void ip_copy(IP *target, IP *source); | ||
156 | /* copies an ip_port structure */ | ||
157 | void ipport_copy(IP_Port *target, IP_Port *source); | ||
150 | 158 | ||
151 | /* | 159 | /* |
152 | * addr_resolve_or_parse_ip | 160 | * addr_resolve_or_parse_ip |
@@ -155,7 +163,7 @@ typedef struct { | |||
155 | * to->family MUST be set (AF_UNSPEC, AF_INET, AF_INET6) | 163 | * to->family MUST be set (AF_UNSPEC, AF_INET, AF_INET6) |
156 | * returns 1 on success, 0 on failure | 164 | * returns 1 on success, 0 on failure |
157 | */ | 165 | */ |
158 | int addr_resolve_or_parse_ip(const char *address, IPAny *to); | 166 | int addr_resolve_or_parse_ip(const char *address, IP *to); |
159 | 167 | ||
160 | /* Function to receive data, ip and port of sender is put into ip_port. | 168 | /* Function to receive data, ip and port of sender is put into ip_port. |
161 | * Packet data is put into data. | 169 | * Packet data is put into data. |
@@ -204,7 +212,7 @@ void networking_poll(Networking_Core *net); | |||
204 | * return 0 if no problems. | 212 | * return 0 if no problems. |
205 | * return -1 if there were problems. | 213 | * return -1 if there were problems. |
206 | */ | 214 | */ |
207 | Networking_Core *new_networking(IP4 ip, uint16_t port); | 215 | Networking_Core *new_networking(IP ip, uint16_t port); |
208 | 216 | ||
209 | /* Function to cleanup networking stuff (doesn't do much right now). */ | 217 | /* Function to cleanup networking stuff (doesn't do much right now). */ |
210 | void kill_networking(Networking_Core *net); | 218 | void kill_networking(Networking_Core *net); |
diff --git a/toxcore/ping.c b/toxcore/ping.c index 5f405b52..49e0dba9 100644 --- a/toxcore/ping.c +++ b/toxcore/ping.c | |||
@@ -100,7 +100,8 @@ bool is_pinging(void *ping, IP_Port ipp, uint64_t ping_id) // O(n) TODO: Repl | |||
100 | { | 100 | { |
101 | PING *png = ping; | 101 | PING *png = ping; |
102 | 102 | ||
103 | if (ipp.ip.uint32 == 0 && ping_id == 0) | 103 | /* shouldn't that be an OR ? */ |
104 | if (!ip_isset(&ipp.ip) && ping_id == 0) | ||
104 | return false; | 105 | return false; |
105 | 106 | ||
106 | size_t i, id; | 107 | size_t i, id; |
@@ -111,7 +112,8 @@ bool is_pinging(void *ping, IP_Port ipp, uint64_t ping_id) // O(n) TODO: Repl | |||
111 | id = (png->pos_pings + i) % PING_NUM_MAX; | 112 | id = (png->pos_pings + i) % PING_NUM_MAX; |
112 | 113 | ||
113 | /* ping_id = 0 means match any id. */ | 114 | /* ping_id = 0 means match any id. */ |
114 | if ((ipp_eq(png->pings[id].ipp, ipp) || ipp.ip.uint32 == 0) && (png->pings[id].id == ping_id || ping_id == 0)) { | 115 | if ((!ip_isset(&ipp.ip) || ipport_equal(&png->pings[id].ipp, &ipp)) && |
116 | (png->pings[id].id == ping_id || ping_id == 0)) { | ||
115 | return true; | 117 | return true; |
116 | } | 118 | } |
117 | } | 119 | } |
diff --git a/toxcore/tox.c b/toxcore/tox.c index e37eac3e..6417b16a 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c | |||
@@ -374,10 +374,11 @@ void tox_bootstrap(void *tox, IP_Port ip_port, uint8_t *public_key) | |||
374 | Messenger *m = tox; | 374 | Messenger *m = tox; |
375 | DHT_bootstrap(m->dht, ip_port, public_key); | 375 | DHT_bootstrap(m->dht, ip_port, public_key); |
376 | } | 376 | } |
377 | void tox_bootstrap_ex(void *tox, const char *address, uint16_t port, uint8_t *public_key) | 377 | void tox_bootstrap_ex(void *tox, const char *address, uint8_t ipv6enabled, |
378 | uint16_t port, uint8_t *public_key) | ||
378 | { | 379 | { |
379 | Messenger *m = tox; | 380 | Messenger *m = tox; |
380 | DHT_bootstrap_ex(m->dht, address, port, public_key); | 381 | DHT_bootstrap_ex(m->dht, address, ipv6enabled, port, public_key); |
381 | }; | 382 | }; |
382 | 383 | ||
383 | /* return 0 if we are not connected to the DHT. | 384 | /* return 0 if we are not connected to the DHT. |
diff --git a/toxcore/tox.h b/toxcore/tox.h index f8d7975f..44eba081 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h | |||
@@ -36,21 +36,51 @@ extern "C" { | |||
36 | 36 | ||
37 | #define TOX_FRIEND_ADDRESS_SIZE (TOX_CLIENT_ID_SIZE + sizeof(uint32_t) + sizeof(uint16_t)) | 37 | #define TOX_FRIEND_ADDRESS_SIZE (TOX_CLIENT_ID_SIZE + sizeof(uint32_t) + sizeof(uint16_t)) |
38 | 38 | ||
39 | |||
40 | typedef union { | 39 | typedef union { |
41 | uint8_t c[4]; | 40 | uint8_t c[4]; |
42 | uint16_t s[2]; | 41 | uint16_t s[2]; |
43 | uint32_t i; | 42 | uint32_t i; |
44 | } tox_IP; | 43 | } tox_IP4; |
44 | |||
45 | |||
46 | typedef struct in6_addr tox_IP6; | ||
45 | 47 | ||
46 | typedef struct { | 48 | typedef struct { |
47 | tox_IP ip; | 49 | sa_family_t family; |
50 | union { | ||
51 | tox_IP4 ip4; | ||
52 | tox_IP6 ip6; | ||
53 | }; | ||
54 | } tox_IPAny; | ||
55 | |||
56 | typedef union { | ||
57 | struct { | ||
58 | tox_IP4 ip; | ||
59 | uint16_t port; | ||
60 | /* Not used for anything right now. */ | ||
61 | uint16_t padding; | ||
62 | }; | ||
63 | uint8_t uint8[8]; | ||
64 | } tox_IP4_Port; | ||
65 | |||
66 | /* will replace IP_Port as soon as the complete infrastructure is in place | ||
67 | * removed the unused union and padding also */ | ||
68 | typedef struct { | ||
69 | tox_IPAny ip; | ||
48 | uint16_t port; | 70 | uint16_t port; |
49 | /* Not used for anything right now. */ | 71 | } tox_IPAny_Port; |
50 | uint16_t padding; | 72 | |
51 | } tox_IP_Port; | 73 | #undef TOX_ENABLE_IPV6 |
74 | #ifdef TOX_ENABLE_IPV6 | ||
75 | #define TOX_ENABLE_IPV6_DEFAULT 1 | ||
76 | typedef tox_IPAny tox_IP; | ||
77 | typedef tox_IPAny_Port tox_IP_Port; | ||
78 | #else | ||
79 | #define TOX_ENABLE_IPV6_DEFAULT 0 | ||
80 | typedef tox_IP4 tox_IP; | ||
81 | typedef tox_IP4_Port tox_IP_Port; | ||
82 | #endif | ||
52 | 83 | ||
53 | #define TOX_IP_IS_IPV6 0 | ||
54 | 84 | ||
55 | /* Errors for m_addfriend | 85 | /* Errors for m_addfriend |
56 | * FAERR - Friend Add Error | 86 | * FAERR - Friend Add Error |
@@ -296,7 +326,8 @@ void tox_callback_connectionstatus(Tox *tox, void (*function)(Tox *tox, int, uin | |||
296 | * tox_bootstrap_ex converts the address into an IP_Port structure internally | 326 | * tox_bootstrap_ex converts the address into an IP_Port structure internally |
297 | */ | 327 | */ |
298 | void tox_bootstrap(Tox *tox, tox_IP_Port ip_port, uint8_t *public_key); | 328 | void tox_bootstrap(Tox *tox, tox_IP_Port ip_port, uint8_t *public_key); |
299 | void tox_bootstrap_ex(Tox *tox, const char *address, uint16_t port, uint8_t *public_key); | 329 | void tox_bootstrap_ex(Tox *tox, const char *address, uint8_t ipv6enabled, |
330 | uint16_t port, uint8_t *public_key); | ||
300 | 331 | ||
301 | /* return 0 if we are not connected to the DHT. | 332 | /* return 0 if we are not connected to the DHT. |
302 | * return 1 if we are. | 333 | * return 1 if we are. |
diff --git a/toxcore/util.c b/toxcore/util.c index 1728ea21..ff366a07 100644 --- a/toxcore/util.c +++ b/toxcore/util.c | |||
@@ -32,11 +32,6 @@ uint64_t random_64b() | |||
32 | return r; | 32 | return r; |
33 | } | 33 | } |
34 | 34 | ||
35 | bool ipp_eq(IP_Port a, IP_Port b) | ||
36 | { | ||
37 | return (a.ip.uint32 == b.ip.uint32) && (a.port == b.port); | ||
38 | } | ||
39 | |||
40 | bool id_eq(uint8_t *dest, uint8_t *src) | 35 | bool id_eq(uint8_t *dest, uint8_t *src) |
41 | { | 36 | { |
42 | return memcmp(dest, src, CLIENT_ID_SIZE) == 0; | 37 | return memcmp(dest, src, CLIENT_ID_SIZE) == 0; |
diff --git a/toxcore/util.h b/toxcore/util.h index 90a3c8e4..7dea3eac 100644 --- a/toxcore/util.h +++ b/toxcore/util.h | |||
@@ -7,6 +7,5 @@ | |||
7 | 7 | ||
8 | uint64_t now(); | 8 | uint64_t now(); |
9 | uint64_t random_64b(); | 9 | uint64_t random_64b(); |
10 | bool ipp_eq(IP_Port a, IP_Port b); | ||
11 | bool id_eq(uint8_t *dest, uint8_t *src); | 10 | bool id_eq(uint8_t *dest, uint8_t *src); |
12 | void id_cpy(uint8_t *dest, uint8_t *src); | 11 | void id_cpy(uint8_t *dest, uint8_t *src); |