4.1 KiB
Fallback IP Routing And TLS Verification
The app stores the server as a normal URL plus optional fallback IP addresses. The fallback IPs are used as DNS answers for the URL host; the app does not rewrite the request URL to an IP address.
Where It Is Implemented
ServerProfile.baseUrlandServerProfile.fallbackIpAddressesstore the URL and fallback list inapp/src/main/java/net/rodakot/ngxhttpmonitoringclient/model/MonitorModels.kt.- The editor exposes those values as
Base URLandFallback LAN IPsinapp/src/main/java/net/rodakot/ngxhttpmonitoringclient/ui/MonitorApp.kt. MonitorRepository.buildServer()normalizes the URL, checks whether plain HTTP is allowed, and parses fallback addresses inapp/src/main/java/net/rodakot/ngxhttpmonitoringclient/data/MonitorRepository.kt.RouteAttemptPlanner.attempts()triesSystemDnsfirst, thenFallbackDnswhen fallback addresses exist. When a VPN is active and a LAN network is available, it also addsLanSystemDnsandLanFallbackDns.MonitorHttpClient.clientFor()installs a custom OkHttpDnsimplementation for fallback routes.
Request Flow
For a server configured like this:
Base URL: https://monitor.example.com
Fallback LAN IPs: 192.168.1.20, 10.0.0.5
the app builds endpoint URLs from the base URL:
https://monitor.example.com/monitor/api
https://monitor.example.com/monitor/health
https://monitor.example.com/monitor/live
The first request uses normal system DNS. If that network request fails before
a usable HTTP response is returned, the app tries the fallback route. In that
route, OkHttp still receives a request for https://monitor.example.com/...,
but the custom FallbackDns returns 192.168.1.20 and 10.0.0.5 when OkHttp
asks how to resolve monitor.example.com.
The LAN variants do the same thing through Android's LAN network socket factory when the active device state includes both VPN and Wi-Fi or Ethernet.
Why TLS Still Works
TLS verification is based on the URL hostname, not the numeric socket address.
Because the app keeps the request URL as https://monitor.example.com/...,
OkHttp still uses monitor.example.com for:
- SNI during the TLS handshake.
- Certificate hostname verification after the certificate is received.
That means the server certificate must be valid for monitor.example.com.
It does not need to contain 192.168.1.20 as an IP subject alternative name
because the client is not asking TLS to verify 192.168.1.20.
This is different from requesting:
https://192.168.1.20/monitor/api
With that URL, the TLS hostname is 192.168.1.20, so the certificate would
need to be valid for the IP address. Adding only an HTTP Host header is not
enough to fix that because TLS verification happens before the HTTP request is
processed.
If the fallback IP reaches a server that does not present a certificate valid
for the original URL host, OkHttp throws an SSL error and the app reports it as
TlsFailure.
Bash Equivalent
The same behavior in curl is --resolve:
curl --resolve monitor.example.com:443:192.168.1.20 \
https://monitor.example.com/monitor/api
--resolve says "connect to this IP for this host and port." The URL still
uses monitor.example.com, so curl sends SNI for monitor.example.com and
verifies the certificate against monitor.example.com.
The sample script in this directory wraps that pattern:
bash docs/fallback-ip-curl-example.sh \
--base-url https://monitor.example.com \
--fallback-ip 192.168.1.20 \
--fallback-ip 10.0.0.5 \
--token '<monitor token>'
For Basic Auth:
bash docs/fallback-ip-curl-example.sh \
--base-url https://monitor.example.com \
--fallback-ips "192.168.1.20,10.0.0.5" \
--basic-auth 'user:password'
For the health endpoint:
bash docs/fallback-ip-curl-example.sh \
--base-url https://monitor.example.com \
--fallback-ip 192.168.1.20 \
--endpoint /monitor/health
Do not use --insecure for this behavior. --insecure disables certificate
verification, while the app's fallback keeps verification enabled.