summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriphydf <iphydf@users.noreply.github.com>2018-02-27 01:07:46 +0000
committeriphydf <iphydf@users.noreply.github.com>2018-05-20 19:35:28 +0000
commit21675ce0d2581597b0e0a727ab4cf6cfb796a037 (patch)
treee1ac4ca63c5cc2b2dc78fcd5b20a8202eab98d9d
parent4f6ab0708c85f3e3da7726f6caecc381c6d21370 (diff)
Finish @Diadlo's network Family abstraction.
The Family stuff in toxcore is a big mess. I'm sure I saw a bunch of bugs on the way, but I'm not verifying that code now, so the bugs stay.
-rw-r--r--auto_tests/TCP_test.c11
-rw-r--r--auto_tests/dht_test.c18
-rw-r--r--auto_tests/network_test.c21
-rw-r--r--auto_tests/onion_test.c6
-rw-r--r--toxcore/DHT.c89
-rw-r--r--toxcore/DHT.h2
-rw-r--r--toxcore/LAN_discovery.c44
-rw-r--r--toxcore/Messenger.c10
-rw-r--r--toxcore/TCP_client.c8
-rw-r--r--toxcore/TCP_connection.c20
-rw-r--r--toxcore/TCP_server.c12
-rw-r--r--toxcore/friend_connection.c10
-rw-r--r--toxcore/net_crypto.c26
-rw-r--r--toxcore/network.c204
-rw-r--r--toxcore/network.h32
-rw-r--r--toxcore/onion.c17
-rw-r--r--toxcore/onion_announce.c2
-rw-r--r--toxcore/onion_client.c22
-rw-r--r--toxcore/ping.c2
-rw-r--r--toxcore/tox.c2
20 files changed, 329 insertions, 229 deletions
diff --git a/auto_tests/TCP_test.c b/auto_tests/TCP_test.c
index 41125116..8b61c4b1 100644
--- a/auto_tests/TCP_test.c
+++ b/auto_tests/TCP_test.c
@@ -29,18 +29,17 @@
29#endif 29#endif
30 30
31#if !USE_IPV6 31#if !USE_IPV6
32#undef TOX_AF_INET6 32#define net_family_ipv6 net_family_ipv4
33#define TOX_AF_INET6 TOX_AF_INET
34#endif 33#endif
35 34
36static inline IP get_loopback() 35static inline IP get_loopback()
37{ 36{
38 IP ip; 37 IP ip;
39#if USE_IPV6 38#if USE_IPV6
40 ip.family = TOX_AF_INET6; 39 ip.family = net_family_ipv6;
41 ip.ip.v6 = get_ip6_loopback(); 40 ip.ip.v6 = get_ip6_loopback();
42#else 41#else
43 ip.family = TOX_AF_INET; 42 ip.family = net_family_ipv4;
44 ip.ip.v4 = get_ip4_loopback(); 43 ip.ip.v4 = get_ip4_loopback();
45#endif 44#endif
46 return ip; 45 return ip;
@@ -57,7 +56,7 @@ START_TEST(test_basic)
57 ck_assert_msg(tcp_s != nullptr, "Failed to create TCP relay server"); 56 ck_assert_msg(tcp_s != nullptr, "Failed to create TCP relay server");
58 ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind to all ports"); 57 ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind to all ports");
59 58
60 Socket sock = net_socket(TOX_AF_INET6, TOX_SOCK_STREAM, TOX_PROTO_TCP); 59 Socket sock = net_socket(net_family_ipv6, TOX_SOCK_STREAM, TOX_PROTO_TCP);
61 IP_Port ip_port_loopback; 60 IP_Port ip_port_loopback;
62 ip_port_loopback.ip = get_loopback(); 61 ip_port_loopback.ip = get_loopback();
63 ip_port_loopback.port = net_htons(ports[random_u32() % NUM_PORTS]); 62 ip_port_loopback.port = net_htons(ports[random_u32() % NUM_PORTS]);
@@ -157,7 +156,7 @@ struct sec_TCP_con {
157static struct sec_TCP_con *new_TCP_con(TCP_Server *tcp_s) 156static struct sec_TCP_con *new_TCP_con(TCP_Server *tcp_s)
158{ 157{
159 struct sec_TCP_con *sec_c = (struct sec_TCP_con *)malloc(sizeof(struct sec_TCP_con)); 158 struct sec_TCP_con *sec_c = (struct sec_TCP_con *)malloc(sizeof(struct sec_TCP_con));
160 Socket sock = net_socket(TOX_AF_INET6, TOX_SOCK_STREAM, TOX_PROTO_TCP); 159 Socket sock = net_socket(net_family_ipv6, TOX_SOCK_STREAM, TOX_PROTO_TCP);
161 160
162 IP_Port ip_port_loopback; 161 IP_Port ip_port_loopback;
163 ip_port_loopback.ip = get_loopback(); 162 ip_port_loopback.ip = get_loopback();
diff --git a/auto_tests/dht_test.c b/auto_tests/dht_test.c
index 803dad76..17f4563b 100644
--- a/auto_tests/dht_test.c
+++ b/auto_tests/dht_test.c
@@ -31,10 +31,10 @@ static inline IP get_loopback()
31{ 31{
32 IP ip; 32 IP ip;
33#if USE_IPV6 33#if USE_IPV6
34 ip.family = TOX_AF_INET6; 34 ip.family = net_family_ipv6;
35 ip.ip.v6 = get_ip6_loopback(); 35 ip.ip.v6 = get_ip6_loopback();
36#else 36#else
37 ip.family = TOX_AF_INET; 37 ip.family = net_family_ipv4;
38 ip.ip.v4 = get_ip4_loopback(); 38 ip.ip.v4 = get_ip4_loopback();
39#endif 39#endif
40 return ip; 40 return ip;
@@ -113,7 +113,7 @@ static void test_addto_lists_update(DHT *dht,
113 int used, test, test1, test2, found; 113 int used, test, test1, test2, found;
114 IP_Port test_ipp; 114 IP_Port test_ipp;
115 uint8_t test_id[CRYPTO_PUBLIC_KEY_SIZE]; 115 uint8_t test_id[CRYPTO_PUBLIC_KEY_SIZE];
116 uint8_t ipv6 = ip_port->ip.family == TOX_AF_INET6 ? 1 : 0; 116 uint8_t ipv6 = net_family_is_ipv6(ip_port->ip.family) ? 1 : 0;
117 117
118 // check id update for existing ip_port 118 // check id update for existing ip_port
119 test = random_u32() % length; 119 test = random_u32() % length;
@@ -188,7 +188,7 @@ static void test_addto_lists_bad(DHT *dht,
188 int used, test1, test2, test3; 188 int used, test1, test2, test3;
189 uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], test_id1[CRYPTO_PUBLIC_KEY_SIZE], test_id2[CRYPTO_PUBLIC_KEY_SIZE], 189 uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], test_id1[CRYPTO_PUBLIC_KEY_SIZE], test_id2[CRYPTO_PUBLIC_KEY_SIZE],
190 test_id3[CRYPTO_PUBLIC_KEY_SIZE]; 190 test_id3[CRYPTO_PUBLIC_KEY_SIZE];
191 uint8_t ipv6 = ip_port->ip.family == TOX_AF_INET6 ? 1 : 0; 191 uint8_t ipv6 = net_family_is_ipv6(ip_port->ip.family) ? 1 : 0;
192 192
193 random_bytes(public_key, sizeof(public_key)); 193 random_bytes(public_key, sizeof(public_key));
194 mark_all_good(list, length, ipv6); 194 mark_all_good(list, length, ipv6);
@@ -232,7 +232,7 @@ static void test_addto_lists_possible_bad(DHT *dht,
232 int used, test1, test2, test3; 232 int used, test1, test2, test3;
233 uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], test_id1[CRYPTO_PUBLIC_KEY_SIZE], test_id2[CRYPTO_PUBLIC_KEY_SIZE], 233 uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], test_id1[CRYPTO_PUBLIC_KEY_SIZE], test_id2[CRYPTO_PUBLIC_KEY_SIZE],
234 test_id3[CRYPTO_PUBLIC_KEY_SIZE]; 234 test_id3[CRYPTO_PUBLIC_KEY_SIZE];
235 uint8_t ipv6 = ip_port->ip.family == TOX_AF_INET6 ? 1 : 0; 235 uint8_t ipv6 = net_family_is_ipv6(ip_port->ip.family) ? 1 : 0;
236 236
237 random_bytes(public_key, sizeof(public_key)); 237 random_bytes(public_key, sizeof(public_key));
238 mark_all_good(list, length, ipv6); 238 mark_all_good(list, length, ipv6);
@@ -294,7 +294,7 @@ static void test_addto_lists_good(DHT *dht,
294 const uint8_t *comp_client_id) 294 const uint8_t *comp_client_id)
295{ 295{
296 uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; 296 uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE];
297 uint8_t ipv6 = ip_port->ip.family == TOX_AF_INET6 ? 1 : 0; 297 uint8_t ipv6 = net_family_is_ipv6(ip_port->ip.family) ? 1 : 0;
298 298
299 mark_all_good(list, length, ipv6); 299 mark_all_good(list, length, ipv6);
300 300
@@ -547,7 +547,7 @@ static void test_list_main(void)
547 ck_assert_msg(count == 1, "Nodes in search don't know ip of friend. %u %u %u", i, j, count); 547 ck_assert_msg(count == 1, "Nodes in search don't know ip of friend. %u %u %u", i, j, count);
548 548
549 Node_format ln[MAX_SENT_NODES]; 549 Node_format ln[MAX_SENT_NODES];
550 int n = get_close_nodes(dhts[(l + j) % NUM_DHT], dhts[l]->self_public_key, ln, 0, 1, 0); 550 int n = get_close_nodes(dhts[(l + j) % NUM_DHT], dhts[l]->self_public_key, ln, net_family_unspec, 1, 0);
551 ck_assert_msg(n == MAX_SENT_NODES, "bad num close %u | %u %u", n, i, j); 551 ck_assert_msg(n == MAX_SENT_NODES, "bad num close %u | %u %u", n, i, j);
552 552
553 count = 0; 553 count = 0;
@@ -744,8 +744,8 @@ static void random_ip(IP_Port *ipp, int family)
744 uint8_t *port = (uint8_t *)&ipp->port; 744 uint8_t *port = (uint8_t *)&ipp->port;
745 random_bytes(port, sizeof(ipp->port)); 745 random_bytes(port, sizeof(ipp->port));
746 random_bytes(ip, size); 746 random_bytes(ip, size);
747 ipp->ip.family = family; 747 // TODO(iphydf): Pass the net_family variant to random_ip.
748 748 ipp->ip.family.value = family;
749} 749}
750 750
751#define PACKED_NODES_SIZE (SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE) 751#define PACKED_NODES_SIZE (SIZE_IPPORT + CRYPTO_PUBLIC_KEY_SIZE)
diff --git a/auto_tests/network_test.c b/auto_tests/network_test.c
index 6f535ee1..0abd14a4 100644
--- a/auto_tests/network_test.c
+++ b/auto_tests/network_test.c
@@ -44,7 +44,7 @@ START_TEST(test_addr_resolv_localhost)
44 net_kill_strerror(strerror); 44 net_kill_strerror(strerror);
45 45
46 char ip_str[IP_NTOA_LEN]; 46 char ip_str[IP_NTOA_LEN];
47 ck_assert_msg(ip.family == TOX_AF_INET, "Expected family TOX_AF_INET, got %u.", ip.family); 47 ck_assert_msg(net_family_is_ipv4(ip.family), "Expected family TOX_AF_INET, got %u.", ip.family.value);
48 const uint32_t loopback = get_ip4_loopback().uint32; 48 const uint32_t loopback = get_ip4_loopback().uint32;
49 ck_assert_msg(ip.ip.v4.uint32 == loopback, "Expected 127.0.0.1, got %s.", 49 ck_assert_msg(ip.ip.v4.uint32 == loopback, "Expected 127.0.0.1, got %s.",
50 ip_ntoa(&ip, ip_str, sizeof(ip_str))); 50 ip_ntoa(&ip, ip_str, sizeof(ip_str)));
@@ -62,7 +62,8 @@ START_TEST(test_addr_resolv_localhost)
62 ck_assert_msg(res > 0, "Resolver failed: %d, %s", error, strerror); 62 ck_assert_msg(res > 0, "Resolver failed: %d, %s", error, strerror);
63 net_kill_strerror(strerror); 63 net_kill_strerror(strerror);
64 64
65 ck_assert_msg(ip.family == TOX_AF_INET6, "Expected family TOX_AF_INET6 (%u), got %u.", TOX_AF_INET6, ip.family); 65 ck_assert_msg(net_family_is_ipv6(ip.family), "Expected family TOX_AF_INET6 (%u), got %u.", TOX_AF_INET6,
66 ip.family.value);
66 IP6 ip6_loopback = get_ip6_loopback(); 67 IP6 ip6_loopback = get_ip6_loopback();
67 ck_assert_msg(!memcmp(&ip.ip.v6, &ip6_loopback, sizeof(IP6)), "Expected ::1, got %s.", 68 ck_assert_msg(!memcmp(&ip.ip.v6, &ip6_loopback, sizeof(IP6)), "Expected ::1, got %s.",
68 ip_ntoa(&ip, ip_str, sizeof(ip_str))); 69 ip_ntoa(&ip, ip_str, sizeof(ip_str)));
@@ -73,7 +74,7 @@ START_TEST(test_addr_resolv_localhost)
73 } 74 }
74 75
75 ip_init(&ip, 1); // ipv6enabled = 1 76 ip_init(&ip, 1); // ipv6enabled = 1
76 ip.family = TOX_AF_UNSPEC; 77 ip.family = net_family_unspec;
77 IP extra; 78 IP extra;
78 ip_reset(&extra); 79 ip_reset(&extra);
79 res = addr_resolve(localhost, &ip, &extra); 80 res = addr_resolve(localhost, &ip, &extra);
@@ -83,15 +84,17 @@ START_TEST(test_addr_resolv_localhost)
83 net_kill_strerror(strerror); 84 net_kill_strerror(strerror);
84 85
85#if USE_IPV6 86#if USE_IPV6
86 ck_assert_msg(ip.family == TOX_AF_INET6, "Expected family TOX_AF_INET6 (%u), got %u.", TOX_AF_INET6, ip.family); 87 ck_assert_msg(net_family_is_ipv6(ip.family), "Expected family TOX_AF_INET6 (%u), got %u.", TOX_AF_INET6,
88 ip.family.value);
87 ck_assert_msg(!memcmp(&ip.ip.v6, &ip6_loopback, sizeof(IP6)), "Expected ::1, got %s.", 89 ck_assert_msg(!memcmp(&ip.ip.v6, &ip6_loopback, sizeof(IP6)), "Expected ::1, got %s.",
88 ip_ntoa(&ip, ip_str, sizeof(ip_str))); 90 ip_ntoa(&ip, ip_str, sizeof(ip_str)));
89 91
90 ck_assert_msg(extra.family == TOX_AF_INET, "Expected family TOX_AF_INET (%u), got %u.", TOX_AF_INET, extra.family); 92 ck_assert_msg(net_family_is_ipv4(extra.family), "Expected family TOX_AF_INET (%d), got %u.", TOX_AF_INET,
93 extra.family.value);
91 ck_assert_msg(extra.ip.v4.uint32 == loopback, "Expected 127.0.0.1, got %s.", 94 ck_assert_msg(extra.ip.v4.uint32 == loopback, "Expected 127.0.0.1, got %s.",
92 ip_ntoa(&ip, ip_str, sizeof(ip_str))); 95 ip_ntoa(&ip, ip_str, sizeof(ip_str)));
93#else 96#else
94 ck_assert_msg(ip.family == TOX_AF_INET, "Expected family TOX_AF_INET (%u), got %u.", TOX_AF_INET, ip.family); 97 ck_assert_msg(net_family_is_ipv4(ip.family), "Expected family TOX_AF_INET (%d), got %u.", TOX_AF_INET, ip.family.value);
95 ck_assert_msg(ip.ip.v4.uint32 == loopback, "Expected 127.0.0.1, got %s.", 98 ck_assert_msg(ip.ip.v4.uint32 == loopback, "Expected 127.0.0.1, got %s.",
96 ip_ntoa(&ip, ip_str, sizeof(ip_str))); 99 ip_ntoa(&ip, ip_str, sizeof(ip_str)));
97#endif 100#endif
@@ -114,14 +117,14 @@ START_TEST(test_ip_equal)
114 res = ip_equal(nullptr, &ip1); 117 res = ip_equal(nullptr, &ip1);
115 ck_assert_msg(res == 0, "ip_equal(NULL, PTR): expected result 0, got %u.", res); 118 ck_assert_msg(res == 0, "ip_equal(NULL, PTR): expected result 0, got %u.", res);
116 119
117 ip1.family = TOX_AF_INET; 120 ip1.family = net_family_ipv4;
118 ip1.ip.v4.uint32 = net_htonl(0x7F000001); 121 ip1.ip.v4.uint32 = net_htonl(0x7F000001);
119 122
120 res = ip_equal(&ip1, &ip2); 123 res = ip_equal(&ip1, &ip2);
121 ck_assert_msg(res == 0, "ip_equal( {TOX_AF_INET, 127.0.0.1}, {TOX_AF_UNSPEC, 0} ): " 124 ck_assert_msg(res == 0, "ip_equal( {TOX_AF_INET, 127.0.0.1}, {TOX_AF_UNSPEC, 0} ): "
122 "expected result 0, got %u.", res); 125 "expected result 0, got %u.", res);
123 126
124 ip2.family = TOX_AF_INET; 127 ip2.family = net_family_ipv4;
125 ip2.ip.v4.uint32 = net_htonl(0x7F000001); 128 ip2.ip.v4.uint32 = net_htonl(0x7F000001);
126 129
127 res = ip_equal(&ip1, &ip2); 130 res = ip_equal(&ip1, &ip2);
@@ -134,7 +137,7 @@ START_TEST(test_ip_equal)
134 ck_assert_msg(res == 0, "ip_equal( {TOX_AF_INET, 127.0.0.1}, {TOX_AF_INET, 127.0.0.2} ): " 137 ck_assert_msg(res == 0, "ip_equal( {TOX_AF_INET, 127.0.0.1}, {TOX_AF_INET, 127.0.0.2} ): "
135 "expected result 0, got %u.", res); 138 "expected result 0, got %u.", res);
136 139
137 ip2.family = TOX_AF_INET6; 140 ip2.family = net_family_ipv6;
138 ip2.ip.v6.uint32[0] = 0; 141 ip2.ip.v6.uint32[0] = 0;
139 ip2.ip.v6.uint32[1] = 0; 142 ip2.ip.v6.uint32[1] = 0;
140 ip2.ip.v6.uint32[2] = net_htonl(0xFFFF); 143 ip2.ip.v6.uint32[2] = net_htonl(0xFFFF);
diff --git a/auto_tests/onion_test.c b/auto_tests/onion_test.c
index 501114a5..c60d3e1a 100644
--- a/auto_tests/onion_test.c
+++ b/auto_tests/onion_test.c
@@ -29,10 +29,10 @@ static inline IP get_loopback()
29{ 29{
30 IP ip; 30 IP ip;
31#if USE_IPV6 31#if USE_IPV6
32 ip.family = TOX_AF_INET6; 32 ip.family = net_family_ipv6;
33 ip.ip.v6 = get_ip6_loopback(); 33 ip.ip.v6 = get_ip6_loopback();
34#else 34#else
35 ip.family = TOX_AF_INET; 35 ip.family = net_family_ipv4;
36 ip.ip.v4 = get_ip4_loopback(); 36 ip.ip.v4 = get_ip4_loopback();
37#endif 37#endif
38 return ip; 38 return ip;
@@ -375,7 +375,7 @@ static Onions *new_onions(uint16_t port, uint32_t *index)
375 return nullptr; 375 return nullptr;
376 } 376 }
377 377
378 TCP_Proxy_Info inf = {{{0}}}; 378 TCP_Proxy_Info inf = {{{{0}}}};
379 on->onion_c = new_onion_client(new_net_crypto(on->log, dht, &inf)); 379 on->onion_c = new_onion_client(new_net_crypto(on->log, dht, &inf));
380 380
381 if (!on->onion_c) { 381 if (!on->onion_c) {
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index 31d2ca0a..6134f59b 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -385,20 +385,17 @@ int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_ke
385/* Return packet size of packed node with ip_family on success. 385/* Return packet size of packed node with ip_family on success.
386 * Return -1 on failure. 386 * Return -1 on failure.
387 */ 387 */
388int packed_node_size(uint8_t ip_family) 388int packed_node_size(Family ip_family)
389{ 389{
390 switch (ip_family) { 390 if (net_family_is_ipv4(ip_family) || net_family_is_tcp_ipv4(ip_family)) {
391 case TOX_AF_INET: 391 return PACKED_NODE_SIZE_IP4;
392 case TCP_INET: 392 }
393 return PACKED_NODE_SIZE_IP4;
394
395 case TOX_AF_INET6:
396 case TCP_INET6:
397 return PACKED_NODE_SIZE_IP6;
398 393
399 default: 394 if (net_family_is_ipv6(ip_family) || net_family_is_tcp_ipv6(ip_family)) {
400 return -1; 395 return PACKED_NODE_SIZE_IP6;
401 } 396 }
397
398 return -1;
402} 399}
403 400
404 401
@@ -416,17 +413,17 @@ int pack_ip_port(uint8_t *data, uint16_t length, const IP_Port *ip_port)
416 bool is_ipv4; 413 bool is_ipv4;
417 uint8_t net_family; 414 uint8_t net_family;
418 415
419 if (ip_port->ip.family == TOX_AF_INET) { 416 if (net_family_is_ipv4(ip_port->ip.family)) {
420 // TODO(irungentoo): use functions to convert endianness 417 // TODO(irungentoo): use functions to convert endianness
421 is_ipv4 = true; 418 is_ipv4 = true;
422 net_family = TOX_AF_INET; 419 net_family = TOX_AF_INET;
423 } else if (ip_port->ip.family == TCP_INET) { 420 } else if (net_family_is_tcp_ipv4(ip_port->ip.family)) {
424 is_ipv4 = true; 421 is_ipv4 = true;
425 net_family = TOX_TCP_INET; 422 net_family = TOX_TCP_INET;
426 } else if (ip_port->ip.family == TOX_AF_INET6) { 423 } else if (net_family_is_ipv6(ip_port->ip.family)) {
427 is_ipv4 = false; 424 is_ipv4 = false;
428 net_family = TOX_AF_INET6; 425 net_family = TOX_AF_INET6;
429 } else if (ip_port->ip.family == TCP_INET6) { 426 } else if (net_family_is_tcp_ipv6(ip_port->ip.family)) {
430 is_ipv4 = false; 427 is_ipv4 = false;
431 net_family = TOX_TCP_INET6; 428 net_family = TOX_TCP_INET6;
432 } else { 429 } else {
@@ -492,28 +489,28 @@ int unpack_ip_port(IP_Port *ip_port, const uint8_t *data, uint16_t length, uint8
492 } 489 }
493 490
494 bool is_ipv4; 491 bool is_ipv4;
495 uint8_t host_family; 492 Family host_family;
496 493
497 if (data[0] == TOX_AF_INET) { 494 if (data[0] == TOX_AF_INET) {
498 is_ipv4 = true; 495 is_ipv4 = true;
499 host_family = TOX_AF_INET; 496 host_family = net_family_ipv4;
500 } else if (data[0] == TOX_TCP_INET) { 497 } else if (data[0] == TOX_TCP_INET) {
501 if (!tcp_enabled) { 498 if (!tcp_enabled) {
502 return -1; 499 return -1;
503 } 500 }
504 501
505 is_ipv4 = true; 502 is_ipv4 = true;
506 host_family = TCP_INET; 503 host_family = net_family_tcp_ipv4;
507 } else if (data[0] == TOX_AF_INET6) { 504 } else if (data[0] == TOX_AF_INET6) {
508 is_ipv4 = false; 505 is_ipv4 = false;
509 host_family = TOX_AF_INET6; 506 host_family = net_family_ipv6;
510 } else if (data[0] == TOX_TCP_INET6) { 507 } else if (data[0] == TOX_TCP_INET6) {
511 if (!tcp_enabled) { 508 if (!tcp_enabled) {
512 return -1; 509 return -1;
513 } 510 }
514 511
515 is_ipv4 = false; 512 is_ipv4 = false;
516 host_family = TCP_INET6; 513 host_family = net_family_tcp_ipv6;
517 } else { 514 } else {
518 return -1; 515 return -1;
519 } 516 }
@@ -650,8 +647,8 @@ static uint32_t index_of_node_pk(const Node_format *array, uint32_t size, const
650static uint32_t index_of_client_ip_port(const Client_data *array, uint32_t size, const IP_Port *ip_port) 647static uint32_t index_of_client_ip_port(const Client_data *array, uint32_t size, const IP_Port *ip_port)
651{ 648{
652 for (uint32_t i = 0; i < size; ++i) { 649 for (uint32_t i = 0; i < size; ++i) {
653 if ((ip_port->ip.family == TOX_AF_INET && ipport_equal(&array[i].assoc4.ip_port, ip_port)) || 650 if ((net_family_is_ipv4(ip_port->ip.family) && ipport_equal(&array[i].assoc4.ip_port, ip_port)) ||
654 (ip_port->ip.family == TOX_AF_INET6 && ipport_equal(&array[i].assoc6.ip_port, ip_port))) { 651 (net_family_is_ipv6(ip_port->ip.family) && ipport_equal(&array[i].assoc6.ip_port, ip_port))) {
655 return i; 652 return i;
656 } 653 }
657 } 654 }
@@ -666,10 +663,10 @@ static void update_client(Logger *log, int index, Client_data *client, IP_Port i
666 IPPTsPng *assoc; 663 IPPTsPng *assoc;
667 int ip_version; 664 int ip_version;
668 665
669 if (ip_port.ip.family == TOX_AF_INET) { 666 if (net_family_is_ipv4(ip_port.ip.family)) {
670 assoc = &client->assoc4; 667 assoc = &client->assoc4;
671 ip_version = 4; 668 ip_version = 4;
672 } else if (ip_port.ip.family == TOX_AF_INET6) { 669 } else if (net_family_is_ipv6(ip_port.ip.family)) {
673 assoc = &client->assoc6; 670 assoc = &client->assoc6;
674 ip_version = 6; 671 ip_version = 6;
675 } else { 672 } else {
@@ -727,7 +724,7 @@ static int client_or_ip_port_in_list(Logger *log, Client_data *list, uint16_t le
727 IPPTsPng *assoc; 724 IPPTsPng *assoc;
728 int ip_version; 725 int ip_version;
729 726
730 if (ip_port.ip.family == TOX_AF_INET) { 727 if (net_family_is_ipv4(ip_port.ip.family)) {
731 assoc = &list[index].assoc4; 728 assoc = &list[index].assoc4;
732 ip_version = 4; 729 ip_version = 4;
733 } else { 730 } else {
@@ -791,7 +788,7 @@ static void get_close_nodes_inner(const uint8_t *public_key, Node_format *nodes_
791 Family sa_family, const Client_data *client_list, uint32_t client_list_length, 788 Family sa_family, const Client_data *client_list, uint32_t client_list_length,
792 uint32_t *num_nodes_ptr, uint8_t is_LAN, uint8_t want_good) 789 uint32_t *num_nodes_ptr, uint8_t is_LAN, uint8_t want_good)
793{ 790{
794 if ((sa_family != TOX_AF_INET) && (sa_family != TOX_AF_INET6) && (sa_family != 0)) { 791 if (!net_family_is_ipv4(sa_family) && !net_family_is_ipv6(sa_family) && !net_family_is_unspec(sa_family)) {
795 return; 792 return;
796 } 793 }
797 794
@@ -807,9 +804,9 @@ static void get_close_nodes_inner(const uint8_t *public_key, Node_format *nodes_
807 804
808 const IPPTsPng *ipptp = nullptr; 805 const IPPTsPng *ipptp = nullptr;
809 806
810 if (sa_family == TOX_AF_INET) { 807 if (net_family_is_ipv4(sa_family)) {
811 ipptp = &client->assoc4; 808 ipptp = &client->assoc4;
812 } else if (sa_family == TOX_AF_INET6) { 809 } else if (net_family_is_ipv6(sa_family)) {
813 ipptp = &client->assoc6; 810 ipptp = &client->assoc6;
814 } else if (client->assoc4.timestamp >= client->assoc6.timestamp) { 811 } else if (client->assoc4.timestamp >= client->assoc6.timestamp) {
815 ipptp = &client->assoc4; 812 ipptp = &client->assoc4;
@@ -978,7 +975,7 @@ static void update_client_with_reset(Client_data *client, const IP_Port *ip_port
978 IPPTsPng *ipptp_write = nullptr; 975 IPPTsPng *ipptp_write = nullptr;
979 IPPTsPng *ipptp_clear = nullptr; 976 IPPTsPng *ipptp_clear = nullptr;
980 977
981 if (ip_port->ip.family == TOX_AF_INET) { 978 if (net_family_is_ipv4(ip_port->ip.family)) {
982 ipptp_write = &client->assoc4; 979 ipptp_write = &client->assoc4;
983 ipptp_clear = &client->assoc6; 980 ipptp_clear = &client->assoc6;
984 } else { 981 } else {
@@ -1016,7 +1013,7 @@ static bool replace_all(Client_data *list,
1016 IP_Port ip_port, 1013 IP_Port ip_port,
1017 const uint8_t *comp_public_key) 1014 const uint8_t *comp_public_key)
1018{ 1015{
1019 if ((ip_port.ip.family != TOX_AF_INET) && (ip_port.ip.family != TOX_AF_INET6)) { 1016 if (!net_family_is_ipv4(ip_port.ip.family) && !net_family_is_ipv6(ip_port.ip.family)) {
1020 return false; 1017 return false;
1021 } 1018 }
1022 1019
@@ -1087,7 +1084,7 @@ static bool is_pk_in_client_list(const Client_data *list, unsigned int client_li
1087 return 0; 1084 return 0;
1088 } 1085 }
1089 1086
1090 const IPPTsPng *assoc = ip_port.ip.family == TOX_AF_INET 1087 const IPPTsPng *assoc = net_family_is_ipv4(ip_port.ip.family)
1091 ? &list[index].assoc4 1088 ? &list[index].assoc4
1092 : &list[index].assoc6; 1089 : &list[index].assoc6;
1093 1090
@@ -1180,8 +1177,8 @@ uint32_t addto_lists(DHT *dht, IP_Port ip_port, const uint8_t *public_key)
1180 uint32_t used = 0; 1177 uint32_t used = 0;
1181 1178
1182 /* convert IPv4-in-IPv6 to IPv4 */ 1179 /* convert IPv4-in-IPv6 to IPv4 */
1183 if ((ip_port.ip.family == TOX_AF_INET6) && IPV6_IPV4_IN_V6(ip_port.ip.ip.v6)) { 1180 if (net_family_is_ipv6(ip_port.ip.family) && IPV6_IPV4_IN_V6(ip_port.ip.ip.v6)) {
1184 ip_port.ip.family = TOX_AF_INET; 1181 ip_port.ip.family = net_family_ipv4;
1185 ip_port.ip.ip.v4.uint32 = ip_port.ip.ip.v6.uint32[3]; 1182 ip_port.ip.ip.v4.uint32 = ip_port.ip.ip.v6.uint32[3];
1186 } 1183 }
1187 1184
@@ -1241,9 +1238,9 @@ static bool update_client_data(Client_data *array, size_t size, IP_Port ip_port,
1241 Client_data *const data = &array[index]; 1238 Client_data *const data = &array[index];
1242 IPPTsPng *assoc; 1239 IPPTsPng *assoc;
1243 1240
1244 if (ip_port.ip.family == TOX_AF_INET) { 1241 if (net_family_is_ipv4(ip_port.ip.family)) {
1245 assoc = &data->assoc4; 1242 assoc = &data->assoc4;
1246 } else if (ip_port.ip.family == TOX_AF_INET6) { 1243 } else if (net_family_is_ipv6(ip_port.ip.family)) {
1247 assoc = &data->assoc6; 1244 assoc = &data->assoc6;
1248 } else { 1245 } else {
1249 return true; 1246 return true;
@@ -1260,8 +1257,8 @@ static bool update_client_data(Client_data *array, size_t size, IP_Port ip_port,
1260static void returnedip_ports(DHT *dht, IP_Port ip_port, const uint8_t *public_key, const uint8_t *nodepublic_key) 1257static void returnedip_ports(DHT *dht, IP_Port ip_port, const uint8_t *public_key, const uint8_t *nodepublic_key)
1261{ 1258{
1262 /* convert IPv4-in-IPv6 to IPv4 */ 1259 /* convert IPv4-in-IPv6 to IPv4 */
1263 if ((ip_port.ip.family == TOX_AF_INET6) && IPV6_IPV4_IN_V6(ip_port.ip.ip.v6)) { 1260 if (net_family_is_ipv6(ip_port.ip.family) && IPV6_IPV4_IN_V6(ip_port.ip.ip.v6)) {
1264 ip_port.ip.family = TOX_AF_INET; 1261 ip_port.ip.family = net_family_ipv4;
1265 ip_port.ip.ip.v4.uint32 = ip_port.ip.ip.v6.uint32[3]; 1262 ip_port.ip.ip.v4.uint32 = ip_port.ip.ip.v6.uint32[3];
1266 } 1263 }
1267 1264
@@ -1346,7 +1343,8 @@ static int sendnodes_ipv6(const DHT *dht, IP_Port ip_port, const uint8_t *public
1346 const size_t node_format_size = sizeof(Node_format); 1343 const size_t node_format_size = sizeof(Node_format);
1347 1344
1348 Node_format nodes_list[MAX_SENT_NODES]; 1345 Node_format nodes_list[MAX_SENT_NODES];
1349 const uint32_t num_nodes = get_close_nodes(dht, client_id, nodes_list, 0, ip_is_lan(ip_port.ip) == 0, 1); 1346 const uint32_t num_nodes = get_close_nodes(dht, client_id, nodes_list, net_family_unspec, ip_is_lan(ip_port.ip) == 0,
1347 1);
1350 1348
1351 VLA(uint8_t, plain, 1 + node_format_size * MAX_SENT_NODES + length); 1349 VLA(uint8_t, plain, 1 + node_format_size * MAX_SENT_NODES + length);
1352 1350
@@ -1591,7 +1589,8 @@ int DHT_addfriend(DHT *dht, const uint8_t *public_key, void (*ip_callback)(void
1591 *lock_count = lock_num + 1; 1589 *lock_count = lock_num + 1;
1592 } 1590 }
1593 1591
1594 dht_friend->num_to_bootstrap = get_close_nodes(dht, dht_friend->public_key, dht_friend->to_bootstrap, 0, 1, 0); 1592 dht_friend->num_to_bootstrap = get_close_nodes(dht, dht_friend->public_key, dht_friend->to_bootstrap, net_family_unspec,
1593 1, 0);
1595 1594
1596 return 0; 1595 return 0;
1597} 1596}
@@ -1823,7 +1822,7 @@ int DHT_bootstrap_from_address(DHT *dht, const char *address, uint8_t ipv6enable
1823 1822
1824 if (ipv6enabled) { 1823 if (ipv6enabled) {
1825 /* setup for getting BOTH: an IPv6 AND an IPv4 address */ 1824 /* setup for getting BOTH: an IPv6 AND an IPv4 address */
1826 ip_port_v64.ip.family = TOX_AF_UNSPEC; 1825 ip_port_v64.ip.family = net_family_unspec;
1827 ip_reset(&ip_port_v4.ip); 1826 ip_reset(&ip_port_v4.ip);
1828 ip_extra = &ip_port_v4.ip; 1827 ip_extra = &ip_port_v4.ip;
1829 } 1828 }
@@ -2350,11 +2349,11 @@ static IPPTsPng *get_closelist_IPPTsPng(DHT *dht, const uint8_t *public_key, Fam
2350 continue; 2349 continue;
2351 } 2350 }
2352 2351
2353 if (sa_family == TOX_AF_INET) { 2352 if (net_family_is_ipv4(sa_family)) {
2354 return &dht->close_clientlist[i].assoc4; 2353 return &dht->close_clientlist[i].assoc4;
2355 } 2354 }
2356 2355
2357 if (sa_family == TOX_AF_INET6) { 2356 if (net_family_is_ipv6(sa_family)) {
2358 return &dht->close_clientlist[i].assoc6; 2357 return &dht->close_clientlist[i].assoc6;
2359 } 2358 }
2360 } 2359 }
@@ -2579,10 +2578,10 @@ static void do_hardening(DHT *dht)
2579 2578
2580 if (i % 2 == 0) { 2579 if (i % 2 == 0) {
2581 cur_iptspng = &dht->close_clientlist[i / 2].assoc4; 2580 cur_iptspng = &dht->close_clientlist[i / 2].assoc4;
2582 sa_family = TOX_AF_INET; 2581 sa_family = net_family_ipv4;
2583 } else { 2582 } else {
2584 cur_iptspng = &dht->close_clientlist[i / 2].assoc6; 2583 cur_iptspng = &dht->close_clientlist[i / 2].assoc6;
2585 sa_family = TOX_AF_INET6; 2584 sa_family = net_family_ipv6;
2586 } 2585 }
2587 2586
2588 if (is_timeout(cur_iptspng->timestamp, BAD_NODE_TIMEOUT)) { 2587 if (is_timeout(cur_iptspng->timestamp, BAD_NODE_TIMEOUT)) {
@@ -2794,7 +2793,7 @@ uint32_t DHT_size(const DHT *dht)
2794 const uint32_t size32 = sizeof(uint32_t); 2793 const uint32_t size32 = sizeof(uint32_t);
2795 const uint32_t sizesubhead = size32 * 2; 2794 const uint32_t sizesubhead = size32 * 2;
2796 2795
2797 return size32 + sizesubhead + (packed_node_size(TOX_AF_INET) * numv4) + (packed_node_size(TOX_AF_INET6) * numv6); 2796 return size32 + sizesubhead + packed_node_size(net_family_ipv4) * numv4 + packed_node_size(net_family_ipv6) * numv6;
2798} 2797}
2799 2798
2800static uint8_t *DHT_save_subheader(uint8_t *data, uint32_t len, uint16_t type) 2799static uint8_t *DHT_save_subheader(uint8_t *data, uint32_t len, uint16_t type)
diff --git a/toxcore/DHT.h b/toxcore/DHT.h
index 3c87804f..3ad28d8c 100644
--- a/toxcore/DHT.h
+++ b/toxcore/DHT.h
@@ -160,7 +160,7 @@ const Client_data *dht_friend_client(const DHT_Friend *dht_friend, size_t index)
160/* Return packet size of packed node with ip_family on success. 160/* Return packet size of packed node with ip_family on success.
161 * Return -1 on failure. 161 * Return -1 on failure.
162 */ 162 */
163int packed_node_size(uint8_t ip_family); 163int packed_node_size(Family ip_family);
164 164
165/* Packs an IP_Port structure into data of max size length. 165/* Packs an IP_Port structure into data of max size length.
166 * 166 *
diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c
index 0bb96926..d25aace3 100644
--- a/toxcore/LAN_discovery.c
+++ b/toxcore/LAN_discovery.c
@@ -86,9 +86,9 @@ static void fetch_broadcast_info(uint16_t port)
86 86
87 if (addr_parse_ip(pAdapter->IpAddressList.IpMask.String, &subnet_mask) 87 if (addr_parse_ip(pAdapter->IpAddressList.IpMask.String, &subnet_mask)
88 && addr_parse_ip(pAdapter->GatewayList.IpAddress.String, &gateway)) { 88 && addr_parse_ip(pAdapter->GatewayList.IpAddress.String, &gateway)) {
89 if (gateway.family == TOX_AF_INET && subnet_mask.family == TOX_AF_INET) { 89 if (net_family_is_ipv4(gateway.family) && net_family_is_ipv4(subnet_mask.family)) {
90 IP_Port *ip_port = &ip_ports[count]; 90 IP_Port *ip_port = &ip_ports[count];
91 ip_port->ip.family = TOX_AF_INET; 91 ip_port->ip.family = net_family_ipv4;
92 uint32_t gateway_ip = net_ntohl(gateway.ip.v4.uint32), subnet_ip = net_ntohl(subnet_mask.ip.v4.uint32); 92 uint32_t gateway_ip = net_ntohl(gateway.ip.v4.uint32), subnet_ip = net_ntohl(subnet_mask.ip.v4.uint32);
93 uint32_t broadcast_ip = gateway_ip + ~subnet_ip - 1; 93 uint32_t broadcast_ip = gateway_ip + ~subnet_ip - 1;
94 ip_port->ip.ip.v4.uint32 = net_htonl(broadcast_ip); 94 ip_port->ip.ip.v4.uint32 = net_htonl(broadcast_ip);
@@ -139,7 +139,7 @@ static void fetch_broadcast_info(uint16_t port)
139 * Definitely won't work like this on Windows... 139 * Definitely won't work like this on Windows...
140 */ 140 */
141 broadcast_count = 0; 141 broadcast_count = 0;
142 const Socket sock = net_socket(TOX_AF_INET, TOX_SOCK_STREAM, 0); 142 const Socket sock = net_socket(net_family_ipv4, TOX_SOCK_STREAM, 0);
143 143
144 if (!sock_valid(sock)) { 144 if (!sock_valid(sock)) {
145 return; 145 return;
@@ -190,7 +190,7 @@ static void fetch_broadcast_info(uint16_t port)
190 } 190 }
191 191
192 IP_Port *ip_port = &ip_ports[count]; 192 IP_Port *ip_port = &ip_ports[count];
193 ip_port->ip.family = TOX_AF_INET; 193 ip_port->ip.family = net_family_ipv4;
194 ip_port->ip.ip.v4.uint32 = sock4->sin_addr.s_addr; 194 ip_port->ip.ip.v4.uint32 = sock4->sin_addr.s_addr;
195 195
196 if (ip_port->ip.ip.v4.uint32 == 0) { 196 if (ip_port->ip.ip.v4.uint32 == 0) {
@@ -248,24 +248,22 @@ static IP broadcast_ip(Family family_socket, Family family_broadcast)
248 IP ip; 248 IP ip;
249 ip_reset(&ip); 249 ip_reset(&ip);
250 250
251 if (family_socket == TOX_AF_INET6) { 251 if (net_family_is_ipv6(family_socket)) {
252 if (family_broadcast == TOX_AF_INET6) { 252 if (net_family_is_ipv6(family_broadcast)) {
253 ip.family = TOX_AF_INET6; 253 ip.family = net_family_ipv6;
254 /* FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */ 254 /* FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */
255 /* FE80::*: MUST be exact, for that we would need to look over all 255 /* FE80::*: MUST be exact, for that we would need to look over all
256 * interfaces and check in which status they are */ 256 * interfaces and check in which status they are */
257 ip.ip.v6.uint8[ 0] = 0xFF; 257 ip.ip.v6.uint8[ 0] = 0xFF;
258 ip.ip.v6.uint8[ 1] = 0x02; 258 ip.ip.v6.uint8[ 1] = 0x02;
259 ip.ip.v6.uint8[15] = 0x01; 259 ip.ip.v6.uint8[15] = 0x01;
260 } else if (family_broadcast == TOX_AF_INET) { 260 } else if (net_family_is_ipv4(family_broadcast)) {
261 ip.family = TOX_AF_INET6; 261 ip.family = net_family_ipv6;
262 ip.ip.v6 = IP6_BROADCAST; 262 ip.ip.v6 = IP6_BROADCAST;
263 } 263 }
264 } else if (family_socket == TOX_AF_INET) { 264 } else if (net_family_is_ipv4(family_socket) && net_family_is_ipv4(family_broadcast)) {
265 if (family_broadcast == TOX_AF_INET) { 265 ip.family = net_family_ipv4;
266 ip.family = TOX_AF_INET; 266 ip.ip.v4 = IP4_BROADCAST;
267 ip.ip.v4 = IP4_BROADCAST;
268 }
269 } 267 }
270 268
271 return ip; 269 return ip;
@@ -274,7 +272,7 @@ static IP broadcast_ip(Family family_socket, Family family_broadcast)
274/* Is IP a local ip or not. */ 272/* Is IP a local ip or not. */
275bool ip_is_local(IP ip) 273bool ip_is_local(IP ip)
276{ 274{
277 if (ip.family == TOX_AF_INET) { 275 if (net_family_is_ipv4(ip.family)) {
278 IP4 ip4 = ip.ip.v4; 276 IP4 ip4 = ip.ip.v4;
279 277
280 /* Loopback. */ 278 /* Loopback. */
@@ -285,7 +283,7 @@ bool ip_is_local(IP ip)
285 /* embedded IPv4-in-IPv6 */ 283 /* embedded IPv4-in-IPv6 */
286 if (IPV6_IPV4_IN_V6(ip.ip.v6)) { 284 if (IPV6_IPV4_IN_V6(ip.ip.v6)) {
287 IP ip4; 285 IP ip4;
288 ip4.family = TOX_AF_INET; 286 ip4.family = net_family_ipv4;
289 ip4.ip.v4.uint32 = ip.ip.v6.uint32[3]; 287 ip4.ip.v4.uint32 = ip.ip.v6.uint32[3];
290 return ip_is_local(ip4); 288 return ip_is_local(ip4);
291 } 289 }
@@ -308,7 +306,7 @@ int ip_is_lan(IP ip)
308 return 0; 306 return 0;
309 } 307 }
310 308
311 if (ip.family == TOX_AF_INET) { 309 if (net_family_is_ipv4(ip.family)) {
312 IP4 ip4 = ip.ip.v4; 310 IP4 ip4 = ip.ip.v4;
313 311
314 /* 10.0.0.0 to 10.255.255.255 range. */ 312 /* 10.0.0.0 to 10.255.255.255 range. */
@@ -337,7 +335,7 @@ int ip_is_lan(IP ip)
337 if ((ip4.uint8[0] == 100) && ((ip4.uint8[1] & 0xC0) == 0x40)) { 335 if ((ip4.uint8[0] == 100) && ((ip4.uint8[1] & 0xC0) == 0x40)) {
338 return 0; 336 return 0;
339 } 337 }
340 } else if (ip.family == TOX_AF_INET6) { 338 } else if (net_family_is_ipv6(ip.family)) {
341 339
342 /* autogenerated for each interface: FE80::* (up to FEBF::*) 340 /* autogenerated for each interface: FE80::* (up to FEBF::*)
343 FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */ 341 FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */
@@ -349,7 +347,7 @@ int ip_is_lan(IP ip)
349 /* embedded IPv4-in-IPv6 */ 347 /* embedded IPv4-in-IPv6 */
350 if (IPV6_IPV4_IN_V6(ip.ip.v6)) { 348 if (IPV6_IPV4_IN_V6(ip.ip.v6)) {
351 IP ip4; 349 IP ip4;
352 ip4.family = TOX_AF_INET; 350 ip4.family = net_family_ipv4;
353 ip4.ip.v4.uint32 = ip.ip.v6.uint32[3]; 351 ip4.ip.v4.uint32 = ip.ip.v6.uint32[3];
354 return ip_is_lan(ip4); 352 return ip_is_lan(ip4);
355 } 353 }
@@ -391,8 +389,8 @@ int lan_discovery_send(uint16_t port, DHT *dht)
391 ip_port.port = port; 389 ip_port.port = port;
392 390
393 /* IPv6 multicast */ 391 /* IPv6 multicast */
394 if (net_family(dht_get_net(dht)) == TOX_AF_INET6) { 392 if (net_family_is_ipv6(net_family(dht_get_net(dht)))) {
395 ip_port.ip = broadcast_ip(TOX_AF_INET6, TOX_AF_INET6); 393 ip_port.ip = broadcast_ip(net_family_ipv6, net_family_ipv6);
396 394
397 if (ip_isset(&ip_port.ip)) { 395 if (ip_isset(&ip_port.ip)) {
398 if (sendpacket(dht_get_net(dht), ip_port, data, 1 + CRYPTO_PUBLIC_KEY_SIZE) > 0) { 396 if (sendpacket(dht_get_net(dht), ip_port, data, 1 + CRYPTO_PUBLIC_KEY_SIZE) > 0) {
@@ -401,8 +399,8 @@ int lan_discovery_send(uint16_t port, DHT *dht)
401 } 399 }
402 } 400 }
403 401
404 /* IPv4 broadcast (has to be IPv4-in-IPv6 mapping if socket is TOX_AF_INET6 */ 402 /* IPv4 broadcast (has to be IPv4-in-IPv6 mapping if socket is IPv6 */
405 ip_port.ip = broadcast_ip(net_family(dht_get_net(dht)), TOX_AF_INET); 403 ip_port.ip = broadcast_ip(net_family(dht_get_net(dht)), net_family_ipv4);
406 404
407 if (ip_isset(&ip_port.ip)) { 405 if (ip_isset(&ip_port.ip)) {
408 if (sendpacket(dht_get_net(dht), ip_port, data, 1 + CRYPTO_PUBLIC_KEY_SIZE)) { 406 if (sendpacket(dht_get_net(dht), ip_port, data, 1 + CRYPTO_PUBLIC_KEY_SIZE)) {
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index c381db0c..11109815 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -2599,7 +2599,7 @@ void do_messenger(Messenger *m, void *userdata)
2599 /* Add self tcp server. */ 2599 /* Add self tcp server. */
2600 IP_Port local_ip_port; 2600 IP_Port local_ip_port;
2601 local_ip_port.port = m->options.tcp_server_port; 2601 local_ip_port.port = m->options.tcp_server_port;
2602 local_ip_port.ip.family = TOX_AF_INET; 2602 local_ip_port.ip.family = net_family_ipv4;
2603 local_ip_port.ip.ip.v4 = get_ip4_loopback(); 2603 local_ip_port.ip.ip.v4 = get_ip4_loopback();
2604 add_tcp_relay(m->net_crypto, local_ip_port, 2604 add_tcp_relay(m->net_crypto, local_ip_port,
2605 tcp_server_public_key(m->tcp_server)); 2605 tcp_server_public_key(m->tcp_server));
@@ -2970,8 +2970,8 @@ uint32_t messenger_size(const Messenger *m)
2970 + sizesubhead + m->name_length // Own nickname. 2970 + sizesubhead + m->name_length // Own nickname.
2971 + sizesubhead + m->statusmessage_length // status message 2971 + sizesubhead + m->statusmessage_length // status message
2972 + sizesubhead + 1 // status 2972 + sizesubhead + 1 // status
2973 + sizesubhead + NUM_SAVED_TCP_RELAYS * packed_node_size(TCP_INET6) //TCP relays 2973 + sizesubhead + NUM_SAVED_TCP_RELAYS * packed_node_size(net_family_tcp_ipv6) //TCP relays
2974 + sizesubhead + NUM_SAVED_PATH_NODES * packed_node_size(TCP_INET6) //saved path nodes 2974 + sizesubhead + NUM_SAVED_PATH_NODES * packed_node_size(net_family_tcp_ipv6) //saved path nodes
2975 + sizesubhead; 2975 + sizesubhead;
2976} 2976}
2977 2977
@@ -3041,7 +3041,7 @@ void messenger_save(const Messenger *m, uint8_t *data)
3041 uint8_t *temp_data = data; 3041 uint8_t *temp_data = data;
3042 data = messenger_save_subheader(temp_data, 0, type); 3042 data = messenger_save_subheader(temp_data, 0, type);
3043 unsigned int num = copy_connected_tcp_relays(m->net_crypto, relays, NUM_SAVED_TCP_RELAYS); 3043 unsigned int num = copy_connected_tcp_relays(m->net_crypto, relays, NUM_SAVED_TCP_RELAYS);
3044 int l = pack_nodes(data, NUM_SAVED_TCP_RELAYS * packed_node_size(TCP_INET6), relays, num); 3044 int l = pack_nodes(data, NUM_SAVED_TCP_RELAYS * packed_node_size(net_family_tcp_ipv6), relays, num);
3045 3045
3046 if (l > 0) { 3046 if (l > 0) {
3047 len = l; 3047 len = l;
@@ -3055,7 +3055,7 @@ void messenger_save(const Messenger *m, uint8_t *data)
3055 data = messenger_save_subheader(data, 0, type); 3055 data = messenger_save_subheader(data, 0, type);
3056 memset(nodes, 0, sizeof(nodes)); 3056 memset(nodes, 0, sizeof(nodes));
3057 num = onion_backup_nodes(m->onion_c, nodes, NUM_SAVED_PATH_NODES); 3057 num = onion_backup_nodes(m->onion_c, nodes, NUM_SAVED_PATH_NODES);
3058 l = pack_nodes(data, NUM_SAVED_PATH_NODES * packed_node_size(TCP_INET6), nodes, num); 3058 l = pack_nodes(data, NUM_SAVED_PATH_NODES * packed_node_size(net_family_tcp_ipv6), nodes, num);
3059 3059
3060 if (l > 0) { 3060 if (l > 0) {
3061 len = l; 3061 len = l;
diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c
index 58e8de49..d1cd4d66 100644
--- a/toxcore/TCP_client.c
+++ b/toxcore/TCP_client.c
@@ -227,7 +227,7 @@ static void proxy_socks5_generate_connection_request(TCP_Client_Connection *TCP_
227 TCP_conn->last_packet[2] = 0; /* reserved, must be 0 */ 227 TCP_conn->last_packet[2] = 0; /* reserved, must be 0 */
228 uint16_t length = 3; 228 uint16_t length = 3;
229 229
230 if (TCP_conn->ip_port.ip.family == TOX_AF_INET) { 230 if (net_family_is_ipv4(TCP_conn->ip_port.ip.family)) {
231 TCP_conn->last_packet[3] = 1; /* IPv4 address */ 231 TCP_conn->last_packet[3] = 1; /* IPv4 address */
232 ++length; 232 ++length;
233 memcpy(TCP_conn->last_packet + length, TCP_conn->ip_port.ip.ip.v4.uint8, sizeof(IP4)); 233 memcpy(TCP_conn->last_packet + length, TCP_conn->ip_port.ip.ip.v4.uint8, sizeof(IP4));
@@ -252,7 +252,7 @@ static void proxy_socks5_generate_connection_request(TCP_Client_Connection *TCP_
252 */ 252 */
253static int proxy_socks5_read_connection_response(TCP_Client_Connection *TCP_conn) 253static int proxy_socks5_read_connection_response(TCP_Client_Connection *TCP_conn)
254{ 254{
255 if (TCP_conn->ip_port.ip.family == TOX_AF_INET) { 255 if (net_family_is_ipv4(TCP_conn->ip_port.ip.family)) {
256 uint8_t data[4 + sizeof(IP4) + sizeof(uint16_t)]; 256 uint8_t data[4 + sizeof(IP4) + sizeof(uint16_t)];
257 int ret = read_TCP_packet(TCP_conn->sock, data, sizeof(data)); 257 int ret = read_TCP_packet(TCP_conn->sock, data, sizeof(data));
258 258
@@ -696,7 +696,7 @@ TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, const uint8_t *public
696 return nullptr; 696 return nullptr;
697 } 697 }
698 698
699 if (ip_port.ip.family != TOX_AF_INET && ip_port.ip.family != TOX_AF_INET6) { 699 if (!net_family_is_ipv4(ip_port.ip.family) && !net_family_is_ipv6(ip_port.ip.family)) {
700 return nullptr; 700 return nullptr;
701 } 701 }
702 702
@@ -707,7 +707,7 @@ TCP_Client_Connection *new_TCP_connection(IP_Port ip_port, const uint8_t *public
707 proxy_info = &default_proxyinfo; 707 proxy_info = &default_proxyinfo;
708 } 708 }
709 709
710 uint8_t family = ip_port.ip.family; 710 Family family = ip_port.ip.family;
711 711
712 if (proxy_info->proxy_type != TCP_PROXY_NONE) { 712 if (proxy_info->proxy_type != TCP_PROXY_NONE) {
713 family = proxy_info->ip_port.ip.family; 713 family = proxy_info->ip_port.ip.family;
diff --git a/toxcore/TCP_connection.c b/toxcore/TCP_connection.c
index 72642264..06cb6e34 100644
--- a/toxcore/TCP_connection.c
+++ b/toxcore/TCP_connection.c
@@ -1125,13 +1125,13 @@ static int tcp_relay_on_online(TCP_Connections *tcp_c, int tcp_connections_numbe
1125 1125
1126static int add_tcp_relay_instance(TCP_Connections *tcp_c, IP_Port ip_port, const uint8_t *relay_pk) 1126static int add_tcp_relay_instance(TCP_Connections *tcp_c, IP_Port ip_port, const uint8_t *relay_pk)
1127{ 1127{
1128 if (ip_port.ip.family == TCP_INET) { 1128 if (net_family_is_tcp_ipv4(ip_port.ip.family)) {
1129 ip_port.ip.family = TOX_AF_INET; 1129 ip_port.ip.family = net_family_ipv4;
1130 } else if (ip_port.ip.family == TCP_INET6) { 1130 } else if (net_family_is_tcp_ipv6(ip_port.ip.family)) {
1131 ip_port.ip.family = TOX_AF_INET6; 1131 ip_port.ip.family = net_family_ipv6;
1132 } 1132 }
1133 1133
1134 if (ip_port.ip.family != TOX_AF_INET && ip_port.ip.family != TOX_AF_INET6) { 1134 if (!net_family_is_ipv4(ip_port.ip.family) && !net_family_is_ipv6(ip_port.ip.family)) {
1135 return -1; 1135 return -1;
1136 } 1136 }
1137 1137
@@ -1286,10 +1286,12 @@ unsigned int tcp_copy_connected_relays(TCP_Connections *tcp_c, Node_format *tcp_
1286 memcpy(tcp_relays[copied].public_key, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE); 1286 memcpy(tcp_relays[copied].public_key, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE);
1287 tcp_relays[copied].ip_port = tcp_con_ip_port(tcp_con->connection); 1287 tcp_relays[copied].ip_port = tcp_con_ip_port(tcp_con->connection);
1288 1288
1289 if (tcp_relays[copied].ip_port.ip.family == TOX_AF_INET) { 1289 Family *const family = &tcp_relays[copied].ip_port.ip.family;
1290 tcp_relays[copied].ip_port.ip.family = TCP_INET; 1290
1291 } else if (tcp_relays[copied].ip_port.ip.family == TOX_AF_INET6) { 1291 if (net_family_is_ipv4(*family)) {
1292 tcp_relays[copied].ip_port.ip.family = TCP_INET6; 1292 *family = net_family_tcp_ipv4;
1293 } else if (net_family_is_ipv6(*family)) {
1294 *family = net_family_tcp_ipv6;
1293 } 1295 }
1294 1296
1295 ++copied; 1297 ++copied;
diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c
index 28a441ad..65dc81c3 100644
--- a/toxcore/TCP_server.c
+++ b/toxcore/TCP_server.c
@@ -889,7 +889,7 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint
889 889
890 IP_Port source; 890 IP_Port source;
891 source.port = 0; // dummy initialise 891 source.port = 0; // dummy initialise
892 source.ip.family = TCP_ONION_FAMILY; 892 source.ip.family = net_family_tcp_onion;
893 source.ip.ip.v6.uint32[0] = con_id; 893 source.ip.ip.v6.uint32[0] = con_id;
894 source.ip.ip.v6.uint32[1] = 0; 894 source.ip.ip.v6.uint32[1] = 0;
895 source.ip.ip.v6.uint64[1] = con->identifier; 895 source.ip.ip.v6.uint64[1] = con->identifier;
@@ -1007,7 +1007,7 @@ static Socket new_listening_TCP_socket(Family family, uint16_t port)
1007 1007
1008 int ok = set_socket_nonblock(sock); 1008 int ok = set_socket_nonblock(sock);
1009 1009
1010 if (ok && family == TOX_AF_INET6) { 1010 if (ok && net_family_is_ipv6(family)) {
1011 ok = set_socket_dualstack(sock); 1011 ok = set_socket_dualstack(sock);
1012 } 1012 }
1013 1013
@@ -1060,13 +1060,7 @@ TCP_Server *new_TCP_server(uint8_t ipv6_enabled, uint16_t num_sockets, const uin
1060 1060
1061#endif 1061#endif
1062 1062
1063 uint8_t family; 1063 const Family family = ipv6_enabled ? net_family_ipv6 : net_family_ipv4;
1064
1065 if (ipv6_enabled) {
1066 family = TOX_AF_INET6;
1067 } else {
1068 family = TOX_AF_INET;
1069 }
1070 1064
1071 uint32_t i; 1065 uint32_t i;
1072#ifdef TCP_SERVER_USE_EPOLL 1066#ifdef TCP_SERVER_USE_EPOLL
diff --git a/toxcore/friend_connection.c b/toxcore/friend_connection.c
index 0ba8178f..fd5e3078 100644
--- a/toxcore/friend_connection.c
+++ b/toxcore/friend_connection.c
@@ -221,7 +221,7 @@ int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_
221 221
222 /* Local ip and same pk means that they are hosting a TCP relay. */ 222 /* Local ip and same pk means that they are hosting a TCP relay. */
223 if (ip_is_local(ip_port.ip) && public_key_cmp(friend_con->dht_temp_pk, public_key) == 0) { 223 if (ip_is_local(ip_port.ip) && public_key_cmp(friend_con->dht_temp_pk, public_key) == 0) {
224 if (friend_con->dht_ip_port.ip.family != 0) { 224 if (!net_family_is_unspec(friend_con->dht_ip_port.ip.family)) {
225 ip_port.ip = friend_con->dht_ip_port.ip; 225 ip_port.ip = friend_con->dht_ip_port.ip;
226 } else { 226 } else {
227 friend_con->hosting_tcp_relay = 0; 227 friend_con->hosting_tcp_relay = 0;
@@ -231,7 +231,7 @@ int friend_add_tcp_relay(Friend_Connections *fr_c, int friendcon_id, IP_Port ip_
231 const uint16_t index = friend_con->tcp_relay_counter % FRIEND_MAX_STORED_TCP_RELAYS; 231 const uint16_t index = friend_con->tcp_relay_counter % FRIEND_MAX_STORED_TCP_RELAYS;
232 232
233 for (unsigned i = 0; i < FRIEND_MAX_STORED_TCP_RELAYS; ++i) { 233 for (unsigned i = 0; i < FRIEND_MAX_STORED_TCP_RELAYS; ++i) {
234 if (friend_con->tcp_relays[i].ip_port.ip.family != 0 234 if (!net_family_is_unspec(friend_con->tcp_relays[i].ip_port.ip.family)
235 && public_key_cmp(friend_con->tcp_relays[i].public_key, public_key) == 0) { 235 && public_key_cmp(friend_con->tcp_relays[i].public_key, public_key) == 0) {
236 memset(&friend_con->tcp_relays[i], 0, sizeof(Node_format)); 236 memset(&friend_con->tcp_relays[i], 0, sizeof(Node_format));
237 } 237 }
@@ -256,7 +256,7 @@ static void connect_to_saved_tcp_relays(Friend_Connections *fr_c, int friendcon_
256 for (unsigned i = 0; (i < FRIEND_MAX_STORED_TCP_RELAYS) && (number != 0); ++i) { 256 for (unsigned i = 0; (i < FRIEND_MAX_STORED_TCP_RELAYS) && (number != 0); ++i) {
257 const uint16_t index = (friend_con->tcp_relay_counter - (i + 1)) % FRIEND_MAX_STORED_TCP_RELAYS; 257 const uint16_t index = (friend_con->tcp_relay_counter - (i + 1)) % FRIEND_MAX_STORED_TCP_RELAYS;
258 258
259 if (friend_con->tcp_relays[index].ip_port.ip.family) { 259 if (!net_family_is_unspec(friend_con->tcp_relays[index].ip_port.ip.family)) {
260 if (add_tcp_relay_peer(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->tcp_relays[index].ip_port, 260 if (add_tcp_relay_peer(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->tcp_relays[index].ip_port,
261 friend_con->tcp_relays[index].public_key) == 0) { 261 friend_con->tcp_relays[index].public_key) == 0) {
262 --number; 262 --number;
@@ -550,7 +550,7 @@ static int handle_new_connections(void *object, New_Connection *n_c)
550 connection_lossy_data_handler(fr_c->net_crypto, id, &handle_lossy_packet, fr_c, friendcon_id); 550 connection_lossy_data_handler(fr_c->net_crypto, id, &handle_lossy_packet, fr_c, friendcon_id);
551 friend_con->crypt_connection_id = id; 551 friend_con->crypt_connection_id = id;
552 552
553 if (n_c->source.ip.family != TOX_AF_INET && n_c->source.ip.family != TOX_AF_INET6) { 553 if (!net_family_is_ipv4(n_c->source.ip.family) && !net_family_is_ipv6(n_c->source.ip.family)) {
554 set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->dht_ip_port, 0); 554 set_direct_ip_port(fr_c->net_crypto, friend_con->crypt_connection_id, friend_con->dht_ip_port, 0);
555 } else { 555 } else {
556 friend_con->dht_ip_port = n_c->source; 556 friend_con->dht_ip_port = n_c->source;
@@ -916,7 +916,7 @@ void do_friend_connections(Friend_Connections *fr_c, void *userdata)
916 } 916 }
917 917
918 if (friend_con->dht_ip_port_lastrecv + FRIEND_DHT_TIMEOUT < temp_time) { 918 if (friend_con->dht_ip_port_lastrecv + FRIEND_DHT_TIMEOUT < temp_time) {
919 friend_con->dht_ip_port.ip.family = 0; 919 friend_con->dht_ip_port.ip.family = net_family_unspec;
920 } 920 }
921 921
922 if (friend_con->dht_lock) { 922 if (friend_con->dht_lock) {
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index b9d8a360..5477fea7 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -573,7 +573,7 @@ static int add_ip_port_connection(Net_Crypto *c, int crypt_connection_id, IP_Por
573 return -1; 573 return -1;
574 } 574 }
575 575
576 if (ip_port.ip.family == TOX_AF_INET) { 576 if (net_family_is_ipv4(ip_port.ip.family)) {
577 if (!ipport_equal(&ip_port, &conn->ip_portv4) && ip_is_lan(conn->ip_portv4.ip) != 0) { 577 if (!ipport_equal(&ip_port, &conn->ip_portv4) && ip_is_lan(conn->ip_portv4.ip) != 0) {
578 if (!bs_list_add(&c->ip_port_list, (uint8_t *)&ip_port, crypt_connection_id)) { 578 if (!bs_list_add(&c->ip_port_list, (uint8_t *)&ip_port, crypt_connection_id)) {
579 return -1; 579 return -1;
@@ -583,7 +583,7 @@ static int add_ip_port_connection(Net_Crypto *c, int crypt_connection_id, IP_Por
583 conn->ip_portv4 = ip_port; 583 conn->ip_portv4 = ip_port;
584 return 0; 584 return 0;
585 } 585 }
586 } else if (ip_port.ip.family == TOX_AF_INET6) { 586 } else if (net_family_is_ipv6(ip_port.ip.family)) {
587 if (!ipport_equal(&ip_port, &conn->ip_portv6)) { 587 if (!ipport_equal(&ip_port, &conn->ip_portv6)) {
588 if (!bs_list_add(&c->ip_port_list, (uint8_t *)&ip_port, crypt_connection_id)) { 588 if (!bs_list_add(&c->ip_port_list, (uint8_t *)&ip_port, crypt_connection_id)) {
589 return -1; 589 return -1;
@@ -605,7 +605,7 @@ static int add_ip_port_connection(Net_Crypto *c, int crypt_connection_id, IP_Por
605 */ 605 */
606static IP_Port return_ip_port_connection(Net_Crypto *c, int crypt_connection_id) 606static IP_Port return_ip_port_connection(Net_Crypto *c, int crypt_connection_id)
607{ 607{
608 const IP_Port empty = {{0}}; 608 const IP_Port empty = {{{0}}};
609 609
610 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id); 610 Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
611 611
@@ -628,11 +628,11 @@ static IP_Port return_ip_port_connection(Net_Crypto *c, int crypt_connection_id)
628 return conn->ip_portv4; 628 return conn->ip_portv4;
629 } 629 }
630 630
631 if (v6 && conn->ip_portv6.ip.family == TOX_AF_INET6) { 631 if (v6 && net_family_is_ipv6(conn->ip_portv6.ip.family)) {
632 return conn->ip_portv6; 632 return conn->ip_portv6;
633 } 633 }
634 634
635 if (conn->ip_portv4.ip.family == TOX_AF_INET) { 635 if (net_family_is_ipv4(conn->ip_portv4.ip.family)) {
636 return conn->ip_portv4; 636 return conn->ip_portv4;
637 } 637 }
638 638
@@ -659,7 +659,7 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
659 IP_Port ip_port = return_ip_port_connection(c, crypt_connection_id); 659 IP_Port ip_port = return_ip_port_connection(c, crypt_connection_id);
660 660
661 // TODO(irungentoo): on bad networks, direct connections might not last indefinitely. 661 // TODO(irungentoo): on bad networks, direct connections might not last indefinitely.
662 if (ip_port.ip.family != 0) { 662 if (!net_family_is_unspec(ip_port.ip.family)) {
663 bool direct_connected = 0; 663 bool direct_connected = 0;
664 crypto_connection_status(c, crypt_connection_id, &direct_connected, nullptr); 664 crypto_connection_status(c, crypt_connection_id, &direct_connected, nullptr);
665 665
@@ -1835,12 +1835,12 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id,
1835 return -1; 1835 return -1;
1836 } 1836 }
1837 1837
1838 if (source.ip.family == TOX_AF_INET || source.ip.family == TOX_AF_INET6) { 1838 if (net_family_is_ipv4(source.ip.family) || net_family_is_ipv6(source.ip.family)) {
1839 if (add_ip_port_connection(c, crypt_connection_id, source) != 0) { 1839 if (add_ip_port_connection(c, crypt_connection_id, source) != 0) {
1840 return -1; 1840 return -1;
1841 } 1841 }
1842 1842
1843 if (source.ip.family == TOX_AF_INET) { 1843 if (net_family_is_ipv4(source.ip.family)) {
1844 conn->direct_lastrecv_timev4 = unix_time(); 1844 conn->direct_lastrecv_timev4 = unix_time();
1845 } else { 1845 } else {
1846 conn->direct_lastrecv_timev6 = unix_time(); 1846 conn->direct_lastrecv_timev6 = unix_time();
@@ -1849,7 +1849,7 @@ static int crypto_connection_add_source(Net_Crypto *c, int crypt_connection_id,
1849 return 0; 1849 return 0;
1850 } 1850 }
1851 1851
1852 if (source.ip.family == TCP_FAMILY) { 1852 if (net_family_is_tcp_family(source.ip.family)) {
1853 if (add_tcp_number_relay_connection(c->tcp_c, conn->connection_number_tcp, source.ip.ip.v6.uint32[0]) == 0) { 1853 if (add_tcp_number_relay_connection(c->tcp_c, conn->connection_number_tcp, source.ip.ip.v6.uint32[0]) == 0) {
1854 return 1; 1854 return 1;
1855 } 1855 }
@@ -2065,13 +2065,13 @@ int set_direct_ip_port(Net_Crypto *c, int crypt_connection_id, IP_Port ip_port,
2065 2065
2066 if (add_ip_port_connection(c, crypt_connection_id, ip_port) == 0) { 2066 if (add_ip_port_connection(c, crypt_connection_id, ip_port) == 0) {
2067 if (connected) { 2067 if (connected) {
2068 if (ip_port.ip.family == TOX_AF_INET) { 2068 if (net_family_is_ipv4(ip_port.ip.family)) {
2069 conn->direct_lastrecv_timev4 = unix_time(); 2069 conn->direct_lastrecv_timev4 = unix_time();
2070 } else { 2070 } else {
2071 conn->direct_lastrecv_timev6 = unix_time(); 2071 conn->direct_lastrecv_timev6 = unix_time();
2072 } 2072 }
2073 } else { 2073 } else {
2074 if (ip_port.ip.family == TOX_AF_INET) { 2074 if (net_family_is_ipv4(ip_port.ip.family)) {
2075 conn->direct_lastrecv_timev4 = 0; 2075 conn->direct_lastrecv_timev4 = 0;
2076 } else { 2076 } else {
2077 conn->direct_lastrecv_timev6 = 0; 2077 conn->direct_lastrecv_timev6 = 0;
@@ -2133,7 +2133,7 @@ static int tcp_oob_callback(void *object, const uint8_t *public_key, unsigned in
2133 if (data[0] == NET_PACKET_CRYPTO_HS) { 2133 if (data[0] == NET_PACKET_CRYPTO_HS) {
2134 IP_Port source; 2134 IP_Port source;
2135 source.port = 0; 2135 source.port = 0;
2136 source.ip.family = TCP_FAMILY; 2136 source.ip.family = net_family_tcp_family;
2137 source.ip.ip.v6.uint32[0] = tcp_connections_number; 2137 source.ip.ip.v6.uint32[0] = tcp_connections_number;
2138 2138
2139 if (handle_new_connection_handshake(c, source, data, length, userdata) != 0) { 2139 if (handle_new_connection_handshake(c, source, data, length, userdata) != 0) {
@@ -2411,7 +2411,7 @@ static int udp_handle_packet(void *object, IP_Port source, const uint8_t *packet
2411 2411
2412 pthread_mutex_lock(&conn->mutex); 2412 pthread_mutex_lock(&conn->mutex);
2413 2413
2414 if (source.ip.family == TOX_AF_INET) { 2414 if (net_family_is_ipv4(source.ip.family)) {
2415 conn->direct_lastrecv_timev4 = unix_time(); 2415 conn->direct_lastrecv_timev4 = unix_time();
2416 } else { 2416 } else {
2417 conn->direct_lastrecv_timev6 = unix_time(); 2417 conn->direct_lastrecv_timev6 = unix_time();
diff --git a/toxcore/network.c b/toxcore/network.c
index f357d887..e7e754c5 100644
--- a/toxcore/network.c
+++ b/toxcore/network.c
@@ -196,7 +196,7 @@ static int make_socktype(int type);
196 196
197static int make_family(Family tox_family) 197static int make_family(Family tox_family)
198{ 198{
199 switch (tox_family) { 199 switch (tox_family.value) {
200 case TOX_AF_INET: 200 case TOX_AF_INET:
201 return AF_INET; 201 return AF_INET;
202 202
@@ -207,24 +207,24 @@ static int make_family(Family tox_family)
207 return AF_UNSPEC; 207 return AF_UNSPEC;
208 208
209 default: 209 default:
210 return tox_family; 210 return tox_family.value;
211 } 211 }
212} 212}
213 213
214static Family make_tox_family(int family) 214static const Family *make_tox_family(int family)
215{ 215{
216 switch (family) { 216 switch (family) {
217 case AF_INET: 217 case AF_INET:
218 return TOX_AF_INET; 218 return &net_family_ipv4;
219 219
220 case AF_INET6: 220 case AF_INET6:
221 return TOX_AF_INET6; 221 return &net_family_ipv6;
222 222
223 case AF_UNSPEC: 223 case AF_UNSPEC:
224 return TOX_AF_UNSPEC; 224 return &net_family_unspec;
225 225
226 default: 226 default:
227 return family; 227 return nullptr;
228 } 228 }
229} 229}
230 230
@@ -281,6 +281,61 @@ const Socket net_invalid_socket = {
281#endif 281#endif
282}; 282};
283 283
284const Family net_family_unspec = {TOX_AF_UNSPEC};
285const Family net_family_ipv4 = {TOX_AF_INET};
286const Family net_family_ipv6 = {TOX_AF_INET6};
287const Family net_family_tcp_family = {TCP_FAMILY};
288const Family net_family_tcp_onion = {TCP_ONION_FAMILY};
289const Family net_family_tcp_ipv4 = {TCP_INET};
290const Family net_family_tcp_ipv6 = {TCP_INET6};
291const Family net_family_tox_tcp_ipv4 = {TOX_TCP_INET};
292const Family net_family_tox_tcp_ipv6 = {TOX_TCP_INET6};
293
294bool net_family_is_unspec(Family family)
295{
296 return family.value == net_family_unspec.value;
297}
298
299bool net_family_is_ipv4(Family family)
300{
301 return family.value == net_family_ipv4.value;
302}
303
304bool net_family_is_ipv6(Family family)
305{
306 return family.value == net_family_ipv6.value;
307}
308
309bool net_family_is_tcp_family(Family family)
310{
311 return family.value == net_family_tcp_family.value;
312}
313
314bool net_family_is_tcp_onion(Family family)
315{
316 return family.value == net_family_tcp_onion.value;
317}
318
319bool net_family_is_tcp_ipv4(Family family)
320{
321 return family.value == net_family_tcp_ipv4.value;
322}
323
324bool net_family_is_tcp_ipv6(Family family)
325{
326 return family.value == net_family_tcp_ipv6.value;
327}
328
329bool net_family_is_tox_tcp_ipv4(Family family)
330{
331 return family.value == net_family_tox_tcp_ipv4.value;
332}
333
334bool net_family_is_tox_tcp_ipv6(Family family)
335{
336 return family.value == net_family_tox_tcp_ipv6.value;
337}
338
284/* Check if socket is valid. 339/* Check if socket is valid.
285 * 340 *
286 * return 1 if valid 341 * return 1 if valid
@@ -496,20 +551,19 @@ uint16_t net_port(const Networking_Core *net)
496 */ 551 */
497int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint16_t length) 552int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint16_t length)
498{ 553{
499 if (net->family == TOX_AF_UNSPEC) { /* Socket not initialized */ 554 if (net_family_is_unspec(net->family)) { /* Socket not initialized */
555 LOGGER_ERROR(net->log, "attempted to send message of length %u on uninitialised socket", (unsigned)length);
500 return -1; 556 return -1;
501 } 557 }
502 558
503 /* socket TOX_AF_INET, but target IP NOT: can't send */ 559 /* socket TOX_AF_INET, but target IP NOT: can't send */
504 if ((net->family == TOX_AF_INET) && (ip_port.ip.family != TOX_AF_INET)) { 560 if (net_family_is_ipv4(net->family) && !net_family_is_ipv4(ip_port.ip.family)) {
561 LOGGER_ERROR(net->log, "attempted to send message with network family %d (probably IPv6) on IPv4 socket",
562 ip_port.ip.family.value);
505 return -1; 563 return -1;
506 } 564 }
507 565
508 struct sockaddr_storage addr; 566 if (net_family_is_ipv4(ip_port.ip.family) && net_family_is_ipv6(net->family)) {
509
510 size_t addrsize = 0;
511
512 if (ip_port.ip.family == TOX_AF_INET && net->family == TOX_AF_INET6) {
513 /* must convert to IPV4-in-IPV6 address */ 567 /* must convert to IPV4-in-IPV6 address */
514 IP6 ip6; 568 IP6 ip6;
515 569
@@ -520,29 +574,33 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint1
520 ip6.uint32[2] = net_htonl(0xFFFF); 574 ip6.uint32[2] = net_htonl(0xFFFF);
521 ip6.uint32[3] = ip_port.ip.ip.v4.uint32; 575 ip6.uint32[3] = ip_port.ip.ip.v4.uint32;
522 576
523 ip_port.ip.family = TOX_AF_INET6; 577 ip_port.ip.family = net_family_ipv6;
524 ip_port.ip.ip.v6 = ip6; 578 ip_port.ip.ip.v6 = ip6;
525 } 579 }
526 580
527 if (ip_port.ip.family == TOX_AF_INET) { 581 struct sockaddr_storage addr;
528 struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; 582
583 size_t addrsize;
584
585 if (net_family_is_ipv4(ip_port.ip.family)) {
586 struct sockaddr_in *const addr4 = (struct sockaddr_in *)&addr;
529 587
530 addrsize = sizeof(struct sockaddr_in); 588 addrsize = sizeof(struct sockaddr_in);
531 fill_addr4(ip_port.ip.ip.v4, &addr4->sin_addr);
532 addr4->sin_family = AF_INET; 589 addr4->sin_family = AF_INET;
533 addr4->sin_port = ip_port.port; 590 addr4->sin_port = ip_port.port;
534 } else if (ip_port.ip.family == TOX_AF_INET6) { 591 fill_addr4(ip_port.ip.ip.v4, &addr4->sin_addr);
535 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; 592 } else if (net_family_is_ipv6(ip_port.ip.family)) {
593 struct sockaddr_in6 *const addr6 = (struct sockaddr_in6 *)&addr;
536 594
537 addrsize = sizeof(struct sockaddr_in6); 595 addrsize = sizeof(struct sockaddr_in6);
538 fill_addr6(ip_port.ip.ip.v6, &addr6->sin6_addr);
539 addr6->sin6_family = AF_INET6; 596 addr6->sin6_family = AF_INET6;
540 addr6->sin6_port = ip_port.port; 597 addr6->sin6_port = ip_port.port;
598 fill_addr6(ip_port.ip.ip.v6, &addr6->sin6_addr);
541 599
542 addr6->sin6_flowinfo = 0; 600 addr6->sin6_flowinfo = 0;
543 addr6->sin6_scope_id = 0; 601 addr6->sin6_scope_id = 0;
544 } else { 602 } else {
545 LOGGER_WARNING(net->log, "unknown address type: %d", ip_port.ip.family); 603 LOGGER_WARNING(net->log, "unknown address type: %d", ip_port.ip.family.value);
546 return -1; 604 return -1;
547 } 605 }
548 606
@@ -587,17 +645,31 @@ static int receivepacket(Logger *log, Socket sock, IP_Port *ip_port, uint8_t *da
587 if (addr.ss_family == AF_INET) { 645 if (addr.ss_family == AF_INET) {
588 struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr; 646 struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr;
589 647
590 ip_port->ip.family = make_tox_family(addr_in->sin_family); 648 const Family *const family = make_tox_family(addr_in->sin_family);
649 assert(family != nullptr);
650
651 if (family == nullptr) {
652 return -1;
653 }
654
655 ip_port->ip.family = *family;
591 get_ip4(&ip_port->ip.ip.v4, &addr_in->sin_addr); 656 get_ip4(&ip_port->ip.ip.v4, &addr_in->sin_addr);
592 ip_port->port = addr_in->sin_port; 657 ip_port->port = addr_in->sin_port;
593 } else if (addr.ss_family == AF_INET6) { 658 } else if (addr.ss_family == AF_INET6) {
594 struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)&addr; 659 struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)&addr;
595 ip_port->ip.family = make_tox_family(addr_in6->sin6_family); 660 const Family *const family = make_tox_family(addr_in6->sin6_family);
661 assert(family != nullptr);
662
663 if (family == nullptr) {
664 return -1;
665 }
666
667 ip_port->ip.family = *family;
596 get_ip6(&ip_port->ip.ip.v6, &addr_in6->sin6_addr); 668 get_ip6(&ip_port->ip.ip.v6, &addr_in6->sin6_addr);
597 ip_port->port = addr_in6->sin6_port; 669 ip_port->port = addr_in6->sin6_port;
598 670
599 if (IPV6_IPV4_IN_V6(ip_port->ip.ip.v6)) { 671 if (IPV6_IPV4_IN_V6(ip_port->ip.ip.v6)) {
600 ip_port->ip.family = TOX_AF_INET; 672 ip_port->ip.family = net_family_ipv4;
601 ip_port->ip.ip.v4.uint32 = ip_port->ip.ip.v6.uint32[3]; 673 ip_port->ip.ip.v4.uint32 = ip_port->ip.ip.v6.uint32[3];
602 } 674 }
603 } else { 675 } else {
@@ -617,7 +689,8 @@ void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handl
617 689
618void networking_poll(Networking_Core *net, void *userdata) 690void networking_poll(Networking_Core *net, void *userdata)
619{ 691{
620 if (net->family == 0) { /* Socket not initialized */ 692 if (net_family_is_unspec(net->family)) {
693 /* Socket not initialized */
621 return; 694 return;
622 } 695 }
623 696
@@ -732,8 +805,8 @@ Networking_Core *new_networking_ex(Logger *log, IP ip, uint16_t port_from, uint1
732 } 805 }
733 806
734 /* maybe check for invalid IPs like 224+.x.y.z? if there is any IP set ever */ 807 /* maybe check for invalid IPs like 224+.x.y.z? if there is any IP set ever */
735 if (ip.family != TOX_AF_INET && ip.family != TOX_AF_INET6) { 808 if (!net_family_is_ipv4(ip.family) && !net_family_is_ipv6(ip.family)) {
736 LOGGER_ERROR(log, "Invalid address family: %u", ip.family); 809 LOGGER_ERROR(log, "invalid address family: %u\n", ip.family.value);
737 return nullptr; 810 return nullptr;
738 } 811 }
739 812
@@ -809,7 +882,7 @@ Networking_Core *new_networking_ex(Logger *log, IP ip, uint16_t port_from, uint1
809 882
810 memset(&addr, 0, sizeof(struct sockaddr_storage)); 883 memset(&addr, 0, sizeof(struct sockaddr_storage));
811 884
812 if (temp->family == TOX_AF_INET) { 885 if (net_family_is_ipv4(temp->family)) {
813 struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; 886 struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr;
814 887
815 addrsize = sizeof(struct sockaddr_in); 888 addrsize = sizeof(struct sockaddr_in);
@@ -818,7 +891,7 @@ Networking_Core *new_networking_ex(Logger *log, IP ip, uint16_t port_from, uint1
818 fill_addr4(ip.ip.v4, &addr4->sin_addr); 891 fill_addr4(ip.ip.v4, &addr4->sin_addr);
819 892
820 portptr = &addr4->sin_port; 893 portptr = &addr4->sin_port;
821 } else if (temp->family == TOX_AF_INET6) { 894 } else if (net_family_is_ipv6(temp->family)) {
822 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; 895 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr;
823 896
824 addrsize = sizeof(struct sockaddr_in6); 897 addrsize = sizeof(struct sockaddr_in6);
@@ -835,8 +908,8 @@ Networking_Core *new_networking_ex(Logger *log, IP ip, uint16_t port_from, uint1
835 return nullptr; 908 return nullptr;
836 } 909 }
837 910
838 if (ip.family == TOX_AF_INET6) { 911 if (net_family_is_ipv6(ip.family)) {
839 int is_dualstack = set_socket_dualstack(temp->sock); 912 const int is_dualstack = set_socket_dualstack(temp->sock);
840 LOGGER_DEBUG(log, "Dual-stack socket: %s", 913 LOGGER_DEBUG(log, "Dual-stack socket: %s",
841 is_dualstack ? "enabled" : "Failed to enable, won't be able to receive from/send to IPv4 addresses"); 914 is_dualstack ? "enabled" : "Failed to enable, won't be able to receive from/send to IPv4 addresses");
842 /* multicast local nodes */ 915 /* multicast local nodes */
@@ -944,7 +1017,8 @@ void kill_networking(Networking_Core *net)
944 return; 1017 return;
945 } 1018 }
946 1019
947 if (net->family != 0) { /* Socket not initialized */ 1020 if (!net_family_is_unspec(net->family)) {
1021 /* Socket is initialized, so we close it. */
948 kill_sock(net->sock); 1022 kill_sock(net->sock);
949 } 1023 }
950 1024
@@ -965,8 +1039,8 @@ int ip_equal(const IP *a, const IP *b)
965 } 1039 }
966 1040
967 /* same family */ 1041 /* same family */
968 if (a->family == b->family) { 1042 if (a->family.value == b->family.value) {
969 if (a->family == TOX_AF_INET || a->family == TCP_INET) { 1043 if (net_family_is_ipv4(a->family) || net_family_is_tcp_ipv4(a->family)) {
970 struct in_addr addr_a; 1044 struct in_addr addr_a;
971 struct in_addr addr_b; 1045 struct in_addr addr_b;
972 fill_addr4(a->ip.v4, &addr_a); 1046 fill_addr4(a->ip.v4, &addr_a);
@@ -974,7 +1048,7 @@ int ip_equal(const IP *a, const IP *b)
974 return addr_a.s_addr == addr_b.s_addr; 1048 return addr_a.s_addr == addr_b.s_addr;
975 } 1049 }
976 1050
977 if (a->family == TOX_AF_INET6 || a->family == TCP_INET6) { 1051 if (net_family_is_ipv6(a->family) || net_family_is_tcp_ipv6(a->family)) {
978 return a->ip.v6.uint64[0] == b->ip.v6.uint64[0] && 1052 return a->ip.v6.uint64[0] == b->ip.v6.uint64[0] &&
979 a->ip.v6.uint64[1] == b->ip.v6.uint64[1]; 1053 a->ip.v6.uint64[1] == b->ip.v6.uint64[1];
980 } 1054 }
@@ -983,13 +1057,13 @@ int ip_equal(const IP *a, const IP *b)
983 } 1057 }
984 1058
985 /* different family: check on the IPv6 one if it is the IPv4 one embedded */ 1059 /* different family: check on the IPv6 one if it is the IPv4 one embedded */
986 if ((a->family == TOX_AF_INET) && (b->family == TOX_AF_INET6)) { 1060 if (net_family_is_ipv4(a->family) && net_family_is_ipv6(b->family)) {
987 if (IPV6_IPV4_IN_V6(b->ip.v6)) { 1061 if (IPV6_IPV4_IN_V6(b->ip.v6)) {
988 struct in_addr addr_a; 1062 struct in_addr addr_a;
989 fill_addr4(a->ip.v4, &addr_a); 1063 fill_addr4(a->ip.v4, &addr_a);
990 return addr_a.s_addr == b->ip.v6.uint32[3]; 1064 return addr_a.s_addr == b->ip.v6.uint32[3];
991 } 1065 }
992 } else if ((a->family == TOX_AF_INET6) && (b->family == TOX_AF_INET)) { 1066 } else if (net_family_is_ipv6(a->family) && net_family_is_ipv4(b->family)) {
993 if (IPV6_IPV4_IN_V6(a->ip.v6)) { 1067 if (IPV6_IPV4_IN_V6(a->ip.v6)) {
994 struct in_addr addr_b; 1068 struct in_addr addr_b;
995 fill_addr4(b->ip.v4, &addr_b); 1069 fill_addr4(b->ip.v4, &addr_b);
@@ -1037,28 +1111,28 @@ void ip_init(IP *ip, bool ipv6enabled)
1037 } 1111 }
1038 1112
1039 memset(ip, 0, sizeof(IP)); 1113 memset(ip, 0, sizeof(IP));
1040 ip->family = ipv6enabled ? TOX_AF_INET6 : TOX_AF_INET; 1114 ip->family = ipv6enabled ? net_family_ipv6 : net_family_ipv4;
1041} 1115}
1042 1116
1043/* checks if ip is valid */ 1117/* checks if ip is valid */
1044int ip_isset(const IP *ip) 1118bool ip_isset(const IP *ip)
1045{ 1119{
1046 if (!ip) { 1120 if (!ip) {
1047 return 0; 1121 return false;
1048 } 1122 }
1049 1123
1050 return (ip->family != 0); 1124 return !net_family_is_unspec(ip->family);
1051} 1125}
1052 1126
1053/* checks if ip is valid */ 1127/* checks if ip is valid */
1054int ipport_isset(const IP_Port *ipport) 1128bool ipport_isset(const IP_Port *ipport)
1055{ 1129{
1056 if (!ipport) { 1130 if (!ipport) {
1057 return 0; 1131 return true;
1058 } 1132 }
1059 1133
1060 if (!ipport->port) { 1134 if (!ipport->port) {
1061 return 0; 1135 return true;
1062 } 1136 }
1063 1137
1064 return ip_isset(&ipport->ip); 1138 return ip_isset(&ipport->ip);
@@ -1103,14 +1177,14 @@ const char *ip_ntoa(const IP *ip, char *ip_str, size_t length)
1103 if (ip) { 1177 if (ip) {
1104 const int family = make_family(ip->family); 1178 const int family = make_family(ip->family);
1105 1179
1106 if (ip->family == TOX_AF_INET) { 1180 if (net_family_is_ipv4(ip->family)) {
1107 /* returns standard quad-dotted notation */ 1181 /* returns standard quad-dotted notation */
1108 struct in_addr addr; 1182 struct in_addr addr;
1109 fill_addr4(ip->ip.v4, &addr); 1183 fill_addr4(ip->ip.v4, &addr);
1110 1184
1111 ip_str[0] = 0; 1185 ip_str[0] = 0;
1112 inet_ntop(family, &addr, ip_str, length); 1186 inet_ntop(family, &addr, ip_str, length);
1113 } else if (ip->family == TOX_AF_INET6) { 1187 } else if (net_family_is_ipv6(ip->family)) {
1114 /* returns hex-groups enclosed into square brackets */ 1188 /* returns hex-groups enclosed into square brackets */
1115 struct in6_addr addr; 1189 struct in6_addr addr;
1116 fill_addr6(ip->ip.v6, &addr); 1190 fill_addr6(ip->ip.v6, &addr);
@@ -1121,7 +1195,7 @@ const char *ip_ntoa(const IP *ip, char *ip_str, size_t length)
1121 ip_str[len] = ']'; 1195 ip_str[len] = ']';
1122 ip_str[len + 1] = 0; 1196 ip_str[len + 1] = 0;
1123 } else { 1197 } else {
1124 snprintf(ip_str, length, "(IP invalid, family %u)", ip->family); 1198 snprintf(ip_str, length, "(IP invalid, family %u)", ip->family.value);
1125 } 1199 }
1126 } else { 1200 } else {
1127 snprintf(ip_str, length, "(IP invalid: NULL)"); 1201 snprintf(ip_str, length, "(IP invalid: NULL)");
@@ -1153,14 +1227,14 @@ int ip_parse_addr(const IP *ip, char *address, size_t length)
1153 return 0; 1227 return 0;
1154 } 1228 }
1155 1229
1156 if (ip->family == TOX_AF_INET) { 1230 if (net_family_is_ipv4(ip->family)) {
1157 const struct in_addr *addr = (const struct in_addr *)&ip->ip.v4; 1231 const struct in_addr *addr = (const struct in_addr *)&ip->ip.v4;
1158 return inet_ntop(ip->family, addr, address, length) != nullptr; 1232 return inet_ntop(make_family(ip->family), addr, address, length) != nullptr;
1159 } 1233 }
1160 1234
1161 if (ip->family == TOX_AF_INET6) { 1235 if (net_family_is_ipv6(ip->family)) {
1162 const struct in6_addr *addr = (const struct in6_addr *)&ip->ip.v6; 1236 const struct in6_addr *addr = (const struct in6_addr *)&ip->ip.v6;
1163 return inet_ntop(ip->family, addr, address, length) != nullptr; 1237 return inet_ntop(make_family(ip->family), addr, address, length) != nullptr;
1164 } 1238 }
1165 1239
1166 return 0; 1240 return 0;
@@ -1188,7 +1262,7 @@ int addr_parse_ip(const char *address, IP *to)
1188 struct in_addr addr4; 1262 struct in_addr addr4;
1189 1263
1190 if (inet_pton(AF_INET, address, &addr4) == 1) { 1264 if (inet_pton(AF_INET, address, &addr4) == 1) {
1191 to->family = TOX_AF_INET; 1265 to->family = net_family_ipv4;
1192 get_ip4(&to->ip.v4, &addr4); 1266 get_ip4(&to->ip.v4, &addr4);
1193 return 1; 1267 return 1;
1194 } 1268 }
@@ -1196,7 +1270,7 @@ int addr_parse_ip(const char *address, IP *to)
1196 struct in6_addr addr6; 1270 struct in6_addr addr6;
1197 1271
1198 if (inet_pton(AF_INET6, address, &addr6) == 1) { 1272 if (inet_pton(AF_INET6, address, &addr6) == 1) {
1199 to->family = TOX_AF_INET6; 1273 to->family = net_family_ipv6;
1200 get_ip6(&to->ip.v6, &addr6); 1274 get_ip6(&to->ip.v6, &addr6);
1201 return 1; 1275 return 1;
1202 } 1276 }
@@ -1228,7 +1302,7 @@ int addr_resolve(const char *address, IP *to, IP *extra)
1228 } 1302 }
1229 1303
1230 Family tox_family = to->family; 1304 Family tox_family = to->family;
1231 Family family = make_family(tox_family); 1305 int family = make_family(tox_family);
1232 1306
1233 struct addrinfo *server = nullptr; 1307 struct addrinfo *server = nullptr;
1234 struct addrinfo *walker = nullptr; 1308 struct addrinfo *walker = nullptr;
@@ -1342,14 +1416,14 @@ int net_connect(Socket sock, IP_Port ip_port)
1342 struct sockaddr_storage addr = {0}; 1416 struct sockaddr_storage addr = {0};
1343 size_t addrsize; 1417 size_t addrsize;
1344 1418
1345 if (ip_port.ip.family == TOX_AF_INET) { 1419 if (net_family_is_ipv4(ip_port.ip.family)) {
1346 struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; 1420 struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr;
1347 1421
1348 addrsize = sizeof(struct sockaddr_in); 1422 addrsize = sizeof(struct sockaddr_in);
1349 addr4->sin_family = AF_INET; 1423 addr4->sin_family = AF_INET;
1350 fill_addr4(ip_port.ip.ip.v4, &addr4->sin_addr); 1424 fill_addr4(ip_port.ip.ip.v4, &addr4->sin_addr);
1351 addr4->sin_port = ip_port.port; 1425 addr4->sin_port = ip_port.port;
1352 } else if (ip_port.ip.family == TOX_AF_INET6) { 1426 } else if (net_family_is_ipv6(ip_port.ip.family)) {
1353 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; 1427 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr;
1354 1428
1355 addrsize = sizeof(struct sockaddr_in6); 1429 addrsize = sizeof(struct sockaddr_in6);
@@ -1422,7 +1496,15 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type)
1422 continue; 1496 continue;
1423 } 1497 }
1424 1498
1425 ip_port->ip.family = make_tox_family(cur->ai_family); 1499 const Family *const family = make_tox_family(cur->ai_family);
1500 assert(family != nullptr);
1501
1502 if (family == nullptr) {
1503 freeaddrinfo(infos);
1504 return -1;
1505 }
1506
1507 ip_port->ip.family = *family;
1426 1508
1427 ip_port++; 1509 ip_port++;
1428 } 1510 }
@@ -1440,18 +1522,18 @@ void net_freeipport(IP_Port *ip_ports)
1440/* return 1 on success 1522/* return 1 on success
1441 * return 0 on failure 1523 * return 0 on failure
1442 */ 1524 */
1443int bind_to_port(Socket sock, int family, uint16_t port) 1525int bind_to_port(Socket sock, Family family, uint16_t port)
1444{ 1526{
1445 struct sockaddr_storage addr = {0}; 1527 struct sockaddr_storage addr = {0};
1446 size_t addrsize; 1528 size_t addrsize;
1447 1529
1448 if (family == TOX_AF_INET) { 1530 if (net_family_is_ipv4(family)) {
1449 struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; 1531 struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr;
1450 1532
1451 addrsize = sizeof(struct sockaddr_in); 1533 addrsize = sizeof(struct sockaddr_in);
1452 addr4->sin_family = AF_INET; 1534 addr4->sin_family = AF_INET;
1453 addr4->sin_port = net_htons(port); 1535 addr4->sin_port = net_htons(port);
1454 } else if (family == TOX_AF_INET6) { 1536 } else if (net_family_is_ipv6(family)) {
1455 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr; 1537 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr;
1456 1538
1457 addrsize = sizeof(struct sockaddr_in6); 1539 addrsize = sizeof(struct sockaddr_in6);
diff --git a/toxcore/network.h b/toxcore/network.h
index bdfebd7e..8071375b 100644
--- a/toxcore/network.h
+++ b/toxcore/network.h
@@ -34,7 +34,29 @@
34extern "C" { 34extern "C" {
35#endif 35#endif
36 36
37typedef uint8_t Family; 37typedef struct Family {
38 uint8_t value;
39} Family;
40
41bool net_family_is_unspec(Family family);
42bool net_family_is_ipv4(Family family);
43bool net_family_is_ipv6(Family family);
44bool net_family_is_tcp_family(Family family);
45bool net_family_is_tcp_onion(Family family);
46bool net_family_is_tcp_ipv4(Family family);
47bool net_family_is_tcp_ipv6(Family family);
48bool net_family_is_tox_tcp_ipv4(Family family);
49bool net_family_is_tox_tcp_ipv6(Family family);
50
51extern const Family net_family_unspec;
52extern const Family net_family_ipv4;
53extern const Family net_family_ipv6;
54extern const Family net_family_tcp_family;
55extern const Family net_family_tcp_onion;
56extern const Family net_family_tcp_ipv4;
57extern const Family net_family_tcp_ipv6;
58extern const Family net_family_tox_tcp_ipv4;
59extern const Family net_family_tox_tcp_ipv6;
38 60
39typedef struct Socket { 61typedef struct Socket {
40 int socket; 62 int socket;
@@ -152,7 +174,7 @@ extern const IP6 IP6_BROADCAST;
152 174
153#define IP_DEFINED 175#define IP_DEFINED
154typedef struct IP { 176typedef struct IP {
155 uint8_t family; 177 Family family;
156 union { 178 union {
157 IP4 v4; 179 IP4 v4;
158 IP6 v6; 180 IP6 v6;
@@ -264,9 +286,9 @@ void ip_reset(IP *ip);
264/* nulls out ip, sets family according to flag */ 286/* nulls out ip, sets family according to flag */
265void ip_init(IP *ip, bool ipv6enabled); 287void ip_init(IP *ip, bool ipv6enabled);
266/* checks if ip is valid */ 288/* checks if ip is valid */
267int ip_isset(const IP *ip); 289bool ip_isset(const IP *ip);
268/* checks if ip is valid */ 290/* checks if ip is valid */
269int ipport_isset(const IP_Port *ipport); 291bool ipport_isset(const IP_Port *ipport);
270/* copies an ip structure */ 292/* copies an ip structure */
271void ip_copy(IP *target, const IP *source); 293void ip_copy(IP *target, const IP *source);
272/* copies an ip_port structure */ 294/* copies an ip_port structure */
@@ -396,7 +418,7 @@ void net_freeipport(IP_Port *ip_ports);
396/* return 1 on success 418/* return 1 on success
397 * return 0 on failure 419 * return 0 on failure
398 */ 420 */
399int bind_to_port(Socket sock, int family, uint16_t port); 421int bind_to_port(Socket sock, Family family, uint16_t port);
400 422
401/* Get the last networking error code. 423/* Get the last networking error code.
402 * 424 *
diff --git a/toxcore/onion.c b/toxcore/onion.c
index 476f76e9..5bbc7f75 100644
--- a/toxcore/onion.c
+++ b/toxcore/onion.c
@@ -54,9 +54,9 @@ static void change_symmetric_key(Onion *onion)
54/* packing and unpacking functions */ 54/* packing and unpacking functions */
55static void ip_pack(uint8_t *data, IP source) 55static void ip_pack(uint8_t *data, IP source)
56{ 56{
57 data[0] = source.family; 57 data[0] = source.family.value;
58 58
59 if (source.family == TOX_AF_INET || source.family == TOX_TCP_INET) { 59 if (net_family_is_ipv4(source.family) || net_family_is_tox_tcp_ipv4(source.family)) {
60 memset(data + 1, 0, SIZE_IP6); 60 memset(data + 1, 0, SIZE_IP6);
61 memcpy(data + 1, source.ip.v4.uint8, SIZE_IP4); 61 memcpy(data + 1, source.ip.v4.uint8, SIZE_IP4);
62 } else { 62 } else {
@@ -71,17 +71,18 @@ static int ip_unpack(IP *target, const uint8_t *data, unsigned int data_size, bo
71 return -1; 71 return -1;
72 } 72 }
73 73
74 target->family = data[0]; 74 // TODO(iphydf): Validate input.
75 target->family.value = data[0];
75 76
76 if (target->family == TOX_AF_INET || target->family == TOX_TCP_INET) { 77 if (net_family_is_ipv4(target->family) || net_family_is_tox_tcp_ipv4(target->family)) {
77 memcpy(target->ip.v4.uint8, data + 1, SIZE_IP4); 78 memcpy(target->ip.v4.uint8, data + 1, SIZE_IP4);
78 } else { 79 } else {
79 memcpy(target->ip.v6.uint8, data + 1, SIZE_IP6); 80 memcpy(target->ip.v6.uint8, data + 1, SIZE_IP6);
80 } 81 }
81 82
82 bool valid = disable_family_check || 83 bool valid = disable_family_check ||
83 target->family == TOX_AF_INET || 84 net_family_is_ipv4(target->family) ||
84 target->family == TOX_AF_INET6; 85 net_family_is_ipv6(target->family);
85 86
86 return valid ? 0 : -1; 87 return valid ? 0 : -1;
87} 88}
@@ -642,8 +643,8 @@ static int handle_recv_1(void *object, IP_Port source, const uint8_t *packet, ui
642 uint16_t data_len = length - (1 + RETURN_1); 643 uint16_t data_len = length - (1 + RETURN_1);
643 644
644 if (onion->recv_1_function && 645 if (onion->recv_1_function &&
645 send_to.ip.family != TOX_AF_INET && 646 !net_family_is_ipv4(send_to.ip.family) &&
646 send_to.ip.family != TOX_AF_INET6) { 647 !net_family_is_ipv6(send_to.ip.family)) {
647 return onion->recv_1_function(onion->callback_object, send_to, packet + (1 + RETURN_1), data_len); 648 return onion->recv_1_function(onion->callback_object, send_to, packet + (1 + RETURN_1), data_len);
648 } 649 }
649 650
diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c
index 5aec3492..6c9e8659 100644
--- a/toxcore/onion_announce.c
+++ b/toxcore/onion_announce.c
@@ -405,7 +405,7 @@ static int handle_announce_request(void *object, IP_Port source, const uint8_t *
405 405
406 /*Respond with a announce response packet*/ 406 /*Respond with a announce response packet*/
407 Node_format nodes_list[MAX_SENT_NODES]; 407 Node_format nodes_list[MAX_SENT_NODES];
408 unsigned int num_nodes = get_close_nodes(onion_a->dht, plain + ONION_PING_ID_SIZE, nodes_list, 0, 408 unsigned int num_nodes = get_close_nodes(onion_a->dht, plain + ONION_PING_ID_SIZE, nodes_list, net_family_unspec,
409 ip_is_lan(source.ip) == 0, 1); 409 ip_is_lan(source.ip) == 0, 1);
410 uint8_t nonce[CRYPTO_NONCE_SIZE]; 410 uint8_t nonce[CRYPTO_NONCE_SIZE];
411 random_nonce(nonce); 411 random_nonce(nonce);
diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c
index 3ee3e0ca..fa6c08c9 100644
--- a/toxcore/onion_client.c
+++ b/toxcore/onion_client.c
@@ -163,7 +163,7 @@ Net_Crypto *onion_get_net_crypto(const Onion_Client *onion_c)
163 */ 163 */
164int onion_add_bs_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t *public_key) 164int onion_add_bs_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t *public_key)
165{ 165{
166 if (ip_port.ip.family != TOX_AF_INET && ip_port.ip.family != TOX_AF_INET6) { 166 if (!net_family_is_ipv4(ip_port.ip.family) && !net_family_is_ipv6(ip_port.ip.family)) {
167 return -1; 167 return -1;
168 } 168 }
169 169
@@ -196,7 +196,7 @@ int onion_add_bs_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t
196 */ 196 */
197static int onion_add_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t *public_key) 197static int onion_add_path_node(Onion_Client *onion_c, IP_Port ip_port, const uint8_t *public_key)
198{ 198{
199 if (ip_port.ip.family != TOX_AF_INET && ip_port.ip.family != TOX_AF_INET6) { 199 if (!net_family_is_ipv4(ip_port.ip.family) && !net_family_is_ipv6(ip_port.ip.family)) {
200 return -1; 200 return -1;
201 } 201 }
202 202
@@ -282,7 +282,7 @@ static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format
282 } 282 }
283 283
284 if (num_nodes >= 2) { 284 if (num_nodes >= 2) {
285 nodes[0].ip_port.ip.family = TCP_FAMILY; 285 nodes[0].ip_port.ip.family = net_family_tcp_family;
286 nodes[0].ip_port.ip.ip.v4.uint32 = random_tcp; 286 nodes[0].ip_port.ip.ip.v4.uint32 = random_tcp;
287 287
288 for (i = 1; i < max_num; ++i) { 288 for (i = 1; i < max_num; ++i) {
@@ -296,7 +296,7 @@ static uint16_t random_nodes_path_onion(const Onion_Client *onion_c, Node_format
296 return 0; 296 return 0;
297 } 297 }
298 298
299 nodes[0].ip_port.ip.family = TCP_FAMILY; 299 nodes[0].ip_port.ip.family = net_family_tcp_family;
300 nodes[0].ip_port.ip.ip.v4.uint32 = random_tcp; 300 nodes[0].ip_port.ip.ip.v4.uint32 = random_tcp;
301 301
302 for (i = 1; i < max_num; ++i) { 302 for (i = 1; i < max_num; ++i) {
@@ -465,7 +465,7 @@ static uint32_t set_path_timeouts(Onion_Client *onion_c, uint32_t num, uint32_t
465static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Path *path, IP_Port dest, 465static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Path *path, IP_Port dest,
466 const uint8_t *data, uint16_t length) 466 const uint8_t *data, uint16_t length)
467{ 467{
468 if (path->ip_port1.ip.family == TOX_AF_INET || path->ip_port1.ip.family == TOX_AF_INET6) { 468 if (net_family_is_ipv4(path->ip_port1.ip.family) || net_family_is_ipv6(path->ip_port1.ip.family)) {
469 uint8_t packet[ONION_MAX_PACKET_SIZE]; 469 uint8_t packet[ONION_MAX_PACKET_SIZE];
470 int len = create_onion_packet(packet, sizeof(packet), path, dest, data, length); 470 int len = create_onion_packet(packet, sizeof(packet), path, dest, data, length);
471 471
@@ -480,7 +480,7 @@ static int send_onion_packet_tcp_udp(const Onion_Client *onion_c, const Onion_Pa
480 return 0; 480 return 0;
481 } 481 }
482 482
483 if (path->ip_port1.ip.family == TCP_FAMILY) { 483 if (net_family_is_tcp_family(path->ip_port1.ip.family)) {
484 uint8_t packet[ONION_MAX_PACKET_SIZE]; 484 uint8_t packet[ONION_MAX_PACKET_SIZE];
485 int len = create_onion_packet_tcp(packet, sizeof(packet), path, dest, data, length); 485 int len = create_onion_packet_tcp(packet, sizeof(packet), path, dest, data, length);
486 486
@@ -987,11 +987,11 @@ static int handle_dhtpk_announce(void *object, const uint8_t *source_pubkey, con
987 int i; 987 int i;
988 988
989 for (i = 0; i < num_nodes; ++i) { 989 for (i = 0; i < num_nodes; ++i) {
990 uint8_t family = nodes[i].ip_port.ip.family; 990 const Family family = nodes[i].ip_port.ip.family;
991 991
992 if (family == TOX_AF_INET || family == TOX_AF_INET6) { 992 if (net_family_is_ipv4(family) || net_family_is_ipv6(family)) {
993 DHT_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].public_key, onion_c->friends_list[friend_num].dht_public_key); 993 DHT_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].public_key, onion_c->friends_list[friend_num].dht_public_key);
994 } else if (family == TCP_INET || family == TCP_INET6) { 994 } else if (net_family_is_tcp_ipv4(family) || net_family_is_tcp_ipv6(family)) {
995 if (onion_c->friends_list[friend_num].tcp_relay_node_callback) { 995 if (onion_c->friends_list[friend_num].tcp_relay_node_callback) {
996 void *obj = onion_c->friends_list[friend_num].tcp_relay_node_callback_object; 996 void *obj = onion_c->friends_list[friend_num].tcp_relay_node_callback_object;
997 uint32_t number = onion_c->friends_list[friend_num].tcp_relay_node_callback_number; 997 uint32_t number = onion_c->friends_list[friend_num].tcp_relay_node_callback_number;
@@ -1010,8 +1010,8 @@ static int handle_tcp_onion(void *object, const uint8_t *data, uint16_t length,
1010 return 1; 1010 return 1;
1011 } 1011 }
1012 1012
1013 IP_Port ip_port = {{0}}; 1013 IP_Port ip_port = {{{0}}};
1014 ip_port.ip.family = TCP_FAMILY; 1014 ip_port.ip.family = net_family_tcp_family;
1015 1015
1016 if (data[0] == NET_PACKET_ANNOUNCE_RESPONSE) { 1016 if (data[0] == NET_PACKET_ANNOUNCE_RESPONSE) {
1017 return handle_announce_response(object, ip_port, data, length, userdata); 1017 return handle_announce_response(object, ip_port, data, length, userdata);
diff --git a/toxcore/ping.c b/toxcore/ping.c
index cc77f2b1..3daeff86 100644
--- a/toxcore/ping.c
+++ b/toxcore/ping.c
@@ -250,7 +250,7 @@ static int in_list(const Client_data *list, uint16_t length, const uint8_t *publ
250 if (id_equal(list[i].public_key, public_key)) { 250 if (id_equal(list[i].public_key, public_key)) {
251 const IPPTsPng *ipptp; 251 const IPPTsPng *ipptp;
252 252
253 if (ip_port.ip.family == TOX_AF_INET) { 253 if (net_family_is_ipv4(ip_port.ip.family)) {
254 ipptp = &list[i].assoc4; 254 ipptp = &list[i].assoc4;
255 } else { 255 } else {
256 ipptp = &list[i].assoc6; 256 ipptp = &list[i].assoc6;
diff --git a/toxcore/tox.c b/toxcore/tox.c
index 6b50c5e8..2f210209 100644
--- a/toxcore/tox.c
+++ b/toxcore/tox.c
@@ -155,7 +155,7 @@ Tox *tox_new(const struct Tox_Options *options, TOX_ERR_NEW *error)
155 ip_init(&m_options.proxy_info.ip_port.ip, m_options.ipv6enabled); 155 ip_init(&m_options.proxy_info.ip_port.ip, m_options.ipv6enabled);
156 156
157 if (m_options.ipv6enabled) { 157 if (m_options.ipv6enabled) {
158 m_options.proxy_info.ip_port.ip.family = TOX_AF_UNSPEC; 158 m_options.proxy_info.ip_port.ip.family = net_family_unspec;
159 } 159 }
160 160
161 if (addr_resolve_or_parse_ip(tox_options_get_proxy_host(options), &m_options.proxy_info.ip_port.ip, nullptr) == 0) { 161 if (addr_resolve_or_parse_ip(tox_options_get_proxy_host(options), &m_options.proxy_info.ip_port.ip, nullptr) == 0) {