11#if PC_ENABLE_HAPPY_EYEBALLS
16bool eff_is_v6(
const pc_ip *ip)
21int scope_rank(
const pc_ip *ip)
41int pc_he_pref(
const pc_ip *ip)
48 return scope_rank(ip) * 2 + (eff_is_v6(ip) ? 1 : 0);
51void pc_he_order(
pc_ip *list,
size_t n)
59 for (
size_t i = 1; i < n; i++)
62 int kp = pc_he_pref(&key);
64 while (j > 0 && pc_he_pref(&list[j - 1]) < kp)
66 list[j] = list[j - 1];
88 for (
size_t i = 0; i < n; i++)
90 if (eff_is_v6(&list[i]))
99 bool take_v6 = eff_is_v6(&list[0]);
100 while (iv6 < nv6 || iv4 < nv4)
102 if (take_v6 && iv6 < nv6)
104 out[o++] = list[v6[iv6++]];
106 else if (!take_v6 && iv4 < nv4)
108 out[o++] = list[v4[iv4++]];
112 out[o++] = list[v6[iv6++]];
116 out[o++] = list[v4[iv4++]];
120 for (
size_t i = 0; i < n; i++)
126bool pc_he_attempt_due(uint32_t last_start_ms, uint32_t now_ms, uint32_t attempt_delay_ms)
128 uint32_t elapsed = now_ms - last_start_ms;
129 return elapsed >= attempt_delay_ms;
Dual-stack destination selection + Happy Eyeballs fallback (PC_ENABLE_HAPPY_EYEBALLS).
pc_ip_scope pc_ip_classify(const pc_ip *ip)
Classify ip into a pc_ip_scope.
bool pc_ip_is_v4_mapped(const pc_ip *ip)
True if ip is an IPv4-mapped IPv6 address (::ffff:a.b.c.d, RFC 4291 ยง2.5.5.2).
@ PC_IP_SCOPE_GLOBAL
globally routable unicast
@ PC_IP_SCOPE_LINK_LOCAL
169.254.0.0/16 / fe80::/10
@ PC_IP_SCOPE_LOOPBACK
127.0.0.0/8 / ::1
@ PC_IP_SCOPE_MULTICAST
224.0.0.0/4 / ff00::/8
@ PC_IP_SCOPE_PRIVATE
RFC1918 (10/8, 172.16/12, 192.168/16) / ULA fc00::/7.
@ PC_IP_NONE
empty / unparsed
@ PC_IP_V6
IPv6 (bytes[0..15])
A v4 or v6 address in network (big-endian) byte order.
pc_ip_family family
address family tag