DeterministicESPAsyncWebServer v6.28.0
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
happy_eyeballs.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file happy_eyeballs.h
6 * @brief Dual-stack destination selection + Happy Eyeballs fallback (DETWS_ENABLE_HAPPY_EYEBALLS).
7 *
8 * On a dual-stack device (DETWS_ENABLE_IPV6), an outbound connection often has both IPv6 and IPv4
9 * candidate addresses for the same host. RFC 8305 (Happy Eyeballs v2) says: sort them by RFC 6724
10 * preference, interleave the families so you do not try every IPv6 before any IPv4, then start
11 * connection attempts staggered by a short "Connection Attempt Delay" and take whichever connects first.
12 * That gives fast IPv6 when it works and a quick fallback to IPv4 when it does not.
13 *
14 * This is the pure decision layer on top of the shipped `DetIp`: a preference score, the ordering +
15 * family interleave over a candidate list, and the attempt-delay gate. The app owns the sockets and the
16 * DNS; this owns *which address to try next, and when*. No heap, no stdlib, host-testable.
17 */
18
19#ifndef DETERMINISTICESPASYNCWEBSERVER_HAPPY_EYEBALLS_H
20#define DETERMINISTICESPASYNCWEBSERVER_HAPPY_EYEBALLS_H
21
22#include "ServerConfig.h"
24#include <stddef.h>
25#include <stdint.h>
26
27#if DETWS_ENABLE_HAPPY_EYEBALLS
28
29#ifndef DETWS_HE_MAX
30#define DETWS_HE_MAX 16 ///< candidate list size the interleave step handles (larger lists are only sorted).
31#endif
32
33/** @brief RFC 8305 recommended Connection Attempt Delay (ms); the spec floor is 100, default 250. */
34#define DETWS_HE_ATTEMPT_DELAY_MS 250
35
36/**
37 * @brief RFC 6724-style preference score for a destination address (higher is tried first).
38 * Ordered by scope (global > private/ULA > link-local > loopback > multicast > unspecified),
39 * and within a scope a native IPv6 address outranks IPv4 (v4-mapped counts as IPv4).
40 */
41int detws_he_pref(const DetIp *ip);
42
43/**
44 * @brief Order a candidate list for Happy Eyeballs: stable-sort by preference (desc), then interleave
45 * address families (RFC 8305 sec 4) so successive attempts alternate v6/v4 where possible.
46 * Lists longer than DETWS_HE_MAX are sorted but not interleaved.
47 */
48void detws_he_order(DetIp *list, size_t n);
49
50/**
51 * @brief Connection Attempt Delay gate (RFC 8305 sec 5): may the next candidate's attempt start yet?
52 * @return true when @p now_ms - @p last_start_ms >= @p attempt_delay_ms (wrap-safe).
53 */
54bool detws_he_attempt_due(uint32_t last_start_ms, uint32_t now_ms, uint32_t attempt_delay_ms);
55
56#endif // DETWS_ENABLE_HAPPY_EYEBALLS
57#endif // DETERMINISTICESPASYNCWEBSERVER_HAPPY_EYEBALLS_H
User-facing configuration for DeterministicESPAsyncWebServer.
Layer 3 (Network) - a family-tagged IP address (IPv4 or IPv6) with RFC-faithful text parsing,...
A v4 or v6 address in network (big-endian) byte order.
Definition ip.h:52