END_TEST START_TEST(test_ip_equal) { int res; IP ip1, ip2; ip_reset(&ip1); ip_reset(&ip2); res = ip_equal(NULL, NULL); ck_assert_msg(res == 0, "ip_equal(NULL, NULL): expected result 0, got %u.", res); res = ip_equal(&ip1, NULL); ck_assert_msg(res == 0, "ip_equal(PTR, NULL): expected result 0, got %u.", res); res = ip_equal(NULL, &ip1); ck_assert_msg(res == 0, "ip_equal(NULL, PTR): expected result 0, got %u.", res); ip1.family = AF_INET; ip1.ip4.uint32 = net_htonl(0x7F000001); res = ip_equal(&ip1, &ip2); ck_assert_msg(res == 0, "ip_equal( {AF_INET, 127.0.0.1}, {AF_UNSPEC, 0} ): expected result 0, got %u.", res); ip2.family = AF_INET; ip2.ip4.uint32 = net_htonl(0x7F000001); res = ip_equal(&ip1, &ip2); ck_assert_msg(res != 0, "ip_equal( {AF_INET, 127.0.0.1}, {AF_INET, 127.0.0.1} ): expected result != 0, got 0."); ip2.ip4.uint32 = net_htonl(0x7F000002); res = ip_equal(&ip1, &ip2); ck_assert_msg(res == 0, "ip_equal( {AF_INET, 127.0.0.1}, {AF_INET, 127.0.0.2} ): expected result 0, got %u.", res); ip2.family = AF_INET6; ip2.ip6.uint32[0] = 0; ip2.ip6.uint32[1] = 0; ip2.ip6.uint32[2] = net_htonl(0xFFFF); ip2.ip6.uint32[3] = net_htonl(0x7F000001); ck_assert_msg(IPV6_IPV4_IN_V6(ip2.ip6) != 0, "IPV6_IPV4_IN_V6(::ffff:127.0.0.1): expected != 0, got 0."); res = ip_equal(&ip1, &ip2); ck_assert_msg(res != 0, "ip_equal( {AF_INET, 127.0.0.1}, {AF_INET6, ::ffff:127.0.0.1} ): expected result != 0, got 0."); memcpy(&ip2.ip6, &in6addr_loopback, sizeof(IP6)); res = ip_equal(&ip1, &ip2); ck_assert_msg(res == 0, "ip_equal( {AF_INET, 127.0.0.1}, {AF_INET6, ::1} ): expected result 0, got %u.", res); memcpy(&ip1, &ip2, sizeof(IP)); res = ip_equal(&ip1, &ip2); ck_assert_msg(res != 0, "ip_equal( {AF_INET6, ::1}, {AF_INET6, ::1} ): expected result != 0, got 0."); ip2.ip6.uint8[15]++; res = ip_equal(&ip1, &ip2); ck_assert_msg(res == 0, "ip_equal( {AF_INET6, ::1}, {AF_INET6, ::2} ): expected result 0, got %res.", res); }
/* Return the broadcast ip. */ static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast) { IP ip; ip_reset(&ip); if (family_socket == AF_INET6) { if (family_broadcast == AF_INET6) { ip.family = AF_INET6; /* FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */ /* FE80::*: MUST be exact, for that we would need to look over all * interfaces and check in which status they are */ ip.ip6.uint8[ 0] = 0xFF; ip.ip6.uint8[ 1] = 0x02; ip.ip6.uint8[15] = 0x01; } else if (family_broadcast == AF_INET) { ip.family = AF_INET6; ip.ip6.uint32[0] = 0; ip.ip6.uint32[1] = 0; ip.ip6.uint32[2] = htonl(0xFFFF); ip.ip6.uint32[3] = INADDR_BROADCAST; } } else if (family_socket == AF_INET) { if (family_broadcast == AF_INET) { ip.family = AF_INET; ip.ip4.uint32 = INADDR_BROADCAST; } } return ip; }
/* Like tox_bootstrap_from_address but for TCP relays only. * * return 0 on failure. * return 1 on success. */ int tox_add_tcp_relay(Tox *tox, const char *address, uint16_t port, const uint8_t *public_key) { Messenger *m = tox; IP_Port ip_port, ip_port_v4; if (!addr_parse_ip(address, &ip_port.ip)) { if (m->options.udp_disabled) /* Disable DNS when udp is disabled. */ return 0; IP *ip_extra = NULL; ip_init(&ip_port.ip, m->options.ipv6enabled); if (m->options.ipv6enabled) { /* setup for getting BOTH: an IPv6 AND an IPv4 address */ ip_port.ip.family = AF_UNSPEC; ip_reset(&ip_port_v4.ip); ip_extra = &ip_port_v4.ip; } if (!addr_resolve(address, &ip_port.ip, ip_extra)) return 0; } ip_port.port = htons(port); add_tcp_relay(m->net_crypto, ip_port, public_key); onion_add_path_node(m->onion_c, ip_port, public_key); //TODO: move this return 1; }
/* Return the broadcast ip. */ static IP broadcast_ip(Family family_socket, Family family_broadcast) { IP ip; ip_reset(&ip); if (family_socket == TOX_AF_INET6) { if (family_broadcast == TOX_AF_INET6) { ip.family = TOX_AF_INET6; /* FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */ /* FE80::*: MUST be exact, for that we would need to look over all * interfaces and check in which status they are */ ip.ip.v6.uint8[ 0] = 0xFF; ip.ip.v6.uint8[ 1] = 0x02; ip.ip.v6.uint8[15] = 0x01; } else if (family_broadcast == TOX_AF_INET) { ip.family = TOX_AF_INET6; ip.ip.v6 = IP6_BROADCAST; } } else if (family_socket == TOX_AF_INET) { if (family_broadcast == TOX_AF_INET) { ip.family = TOX_AF_INET; ip.ip.v4 = IP4_BROADCAST; } } return ip; }
/* Ping all the valid nodes in the to_ping list every TIME_TO_PING seconds. * This function must be run at least once every TIME_TO_PING seconds. */ void do_to_ping(PING *ping) { if (!is_timeout(ping->last_to_ping, TIME_TO_PING)) { return; } if (!ip_isset(&ping->to_ping[0].ip_port.ip)) { return; } unsigned int i; for (i = 0; i < MAX_TO_PING; ++i) { if (!ip_isset(&ping->to_ping[i].ip_port.ip)) { break; } if (!node_addable_to_close_list(ping->dht, ping->to_ping[i].public_key, ping->to_ping[i].ip_port)) { continue; } send_ping_request(ping, ping->to_ping[i].ip_port, ping->to_ping[i].public_key); ip_reset(&ping->to_ping[i].ip_port.ip); } if (i != 0) { ping->last_to_ping = unix_time(); } }
/* Ping all the valid nodes in the toping list every TIME_TOPING seconds. * This function must be run at least once every TIME_TOPING seconds. */ void do_toping(PING *ping) { if (!is_timeout(ping->last_toping, TIME_TOPING)) return; ping->last_toping = unix_time(); size_t i; for (i = 0; i < MAX_TOPING; ++i) { if (!ip_isset(&ping->toping[i].ip_port.ip)) return; send_ping_request(ping, ping->toping[i].ip_port, ping->toping[i].client_id); ip_reset(&ping->toping[i].ip_port.ip); } }
/* Ping all the valid nodes in the to_ping list every TIME_TO_PING seconds. * This function must be run at least once every TIME_TO_PING seconds. */ void do_to_ping(PING *ping) { if (!is_timeout(ping->last_to_ping, TIME_TO_PING)) return; if (!ip_isset(&ping->to_ping[0].ip_port.ip)) return; uint32_t i; for (i = 0; i < MAX_TO_PING; ++i) { if (!ip_isset(&ping->to_ping[i].ip_port.ip)) break; send_ping_request(ping, ping->to_ping[i].ip_port, ping->to_ping[i].public_key); ip_reset(&ping->to_ping[i].ip_port.ip); } if (i != 0) ping->last_to_ping = unix_time(); }
/* TODO: expose this properly. */ static int tox_add_tcp_relay(Tox *tox, const char *address, uint8_t ipv6enabled, uint16_t port, uint8_t *public_key) { Messenger *m = tox; IP_Port ip_port_v64; IP *ip_extra = NULL; IP_Port ip_port_v4; ip_init(&ip_port_v64.ip, ipv6enabled); if (ipv6enabled) { /* setup for getting BOTH: an IPv6 AND an IPv4 address */ ip_port_v64.ip.family = AF_UNSPEC; ip_reset(&ip_port_v4.ip); ip_extra = &ip_port_v4.ip; } if (addr_resolve_or_parse_ip(address, &ip_port_v64.ip, ip_extra)) { ip_port_v64.port = port; add_tcp_relay(m->net_crypto, ip_port_v64, public_key); return 1; } else { return 0; } }