11#if DETWS_ENABLE_HAPPY_EYEBALLS
16bool eff_is_v6(
const DetIp *ip)
21int scope_rank(
const DetIp *ip)
41int detws_he_pref(
const DetIp *ip)
46 return scope_rank(ip) * 2 + (eff_is_v6(ip) ? 1 : 0);
49void detws_he_order(
DetIp *list,
size_t n)
55 for (
size_t i = 1; i < n; i++)
58 int kp = detws_he_pref(&key);
60 while (j > 0 && detws_he_pref(&list[j - 1]) < kp)
62 list[j] = list[j - 1];
73 DetIp out[DETWS_HE_MAX];
78 size_t v6[DETWS_HE_MAX];
79 size_t v4[DETWS_HE_MAX];
82 for (
size_t i = 0; i < n; i++)
84 if (eff_is_v6(&list[i]))
89 bool take_v6 = eff_is_v6(&list[0]);
90 while (iv6 < nv6 || iv4 < nv4)
92 if (take_v6 && iv6 < nv6)
93 out[o++] = list[v6[iv6++]];
94 else if (!take_v6 && iv4 < nv4)
95 out[o++] = list[v4[iv4++]];
97 out[o++] = list[v6[iv6++]];
99 out[o++] = list[v4[iv4++]];
102 for (
size_t i = 0; i < n; i++)
106bool detws_he_attempt_due(uint32_t last_start_ms, uint32_t now_ms, uint32_t attempt_delay_ms)
108 uint32_t elapsed = now_ms - last_start_ms;
109 return elapsed >= attempt_delay_ms;
Dual-stack destination selection + Happy Eyeballs fallback (DETWS_ENABLE_HAPPY_EYEBALLS).
DetIpScope det_ip_classify(const DetIp *ip)
Classify ip into a DetIpScope.
bool det_ip_is_v4_mapped(const DetIp *ip)
True if ip is an IPv4-mapped IPv6 address (::ffff:a.b.c.d, RFC 4291 §2.5.5.2).
@ DET_IP_V6
IPv6 (bytes[0..15])
@ DET_IP_NONE
empty / unparsed
@ DET_IP_SCOPE_GLOBAL
globally routable unicast
@ DET_IP_SCOPE_LOOPBACK
127.0.0.0/8 / ::1
@ DET_IP_SCOPE_PRIVATE
RFC1918 (10/8, 172.16/12, 192.168/16) / ULA fc00::/7.
@ DET_IP_SCOPE_MULTICAST
224.0.0.0/4 / ff00::/8
@ DET_IP_SCOPE_LINK_LOCAL
169.254.0.0/16 / fe80::/10
A v4 or v6 address in network (big-endian) byte order.
DetIpFamily family
address family tag