Add -S flag for configurable source address on outbound connections
Motivation:
Enable routing DNS-over-HTTPS traffic through different network paths per instance. Primary use case: running multiple https_dns_proxy instances on a router where each WiFi LAN gateway routes through a different WireGuard tunnel to different geographic locations. This allows DNS traffic from different WiFi networks to exit via different VPN endpoints.
Implementation:
- Added
source_addrfield tostruct Options - New
-Scommand-line flag to specify source IPv4/v6 address - Uses
CURLOPT_INTERFACEto bind outbound HTTPS connections - Backward compatible: without -S, uses system default routing
- Logs
Using source address: Xatdebuglevel when configured
Example Usage:
Instance 1: WiFi LAN 1 gateway (routes via WireGuard to US)
https_dns_proxy -a 192.168.1.1 -p 53 -S 192.168.1.1 \
-r https://security.cloudflare-dns.com/dns-query \
-b 1.1.1.2,1.0.0.2
Instance 2: WiFi LAN 2 gateway (routes via WireGuard to EU)
https_dns_proxy -a 192.168.2.1 -p 53 -S 192.168.2.1 \
-r https://security.cloudflare-dns.com/dns-query \
-b 1.1.1.2,1.0.0.2
Each instance binds to its WiFi interface address for both listening and outbound HTTPS, ensuring traffic routes through the correct WireGuard tunnel configured for that interface.
Verification:
With -S flag, CURL binds to specified source address:
[D] https_client.c:260 F0C1: Requesting HTTP/2
[D] https_client.c:324 F0C1: Using source address: 192.168.1.1
[D] https_client.c:218 F0C1: * Added security.cloudflare-dns.com:443:1.0.0.2,1.1.1.2,... to DNS cache
[D] https_client.c:218 F0C1: * Hostname security.cloudflare-dns.com was found in DNS cache
[D] https_client.c:94 curl opened socket: 9
[D] https_client.c:218 F0C1: * Trying 1.0.0.2:443...
[D] https_client.c:218 F0C1: * Name '192.168.1.1' family 2 resolved to '192.168.1.1' family 2
[D] https_client.c:218 F0C1: * Local port: 0
[D] https_client.c:639 Reserved new io event: 0xffffc0ed3568
[D] https_client.c:218 F0C1: * Connected to security.cloudflare-dns.com (1.0.0.2) port 443 (#0)
Without -S flag, no source binding (backward compatible):
[D] https_client.c:260 39BF: Requesting HTTP/2
[D] https_client.c:218 39BF: * Added security.cloudflare-dns.com:443:1.1.1.2,1.0.0.2,... to DNS cache
[D] https_client.c:218 39BF: * Hostname security.cloudflare-dns.com was found in DNS cache
[D] https_client.c:94 curl opened socket: 9
[D] https_client.c:218 39BF: * Trying 1.1.1.2:443...
[D] https_client.c:639 Reserved new io event: 0xffffe69a0f18
[D] https_client.c:218 39BF: * Connected to security.cloudflare-dns.com (1.1.1.2) port 443 (#0)
Note the presence of Using source address and Name '192.168.1.1' ... resolved lines only when -S is specified.
Files Modified:
src/options.h: Added source_addr fieldsrc/options.c: Added -S flag parsing and help textsrc/https_client.c: Implemented CURLOPT_INTERFACE bindingtests/robot/functional_tests.robot: Added test caseREADME.md: Updated documentation