xref: /aosp_15_r20/external/libwebsockets/READMEs/README.captive-portal-detection.md (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker# Captive Portal Detection
2*1c60b9acSAndroid Build Coastguard Worker
3*1c60b9acSAndroid Build Coastguard Worker## Background
4*1c60b9acSAndroid Build Coastguard Worker
5*1c60b9acSAndroid Build Coastguard WorkerWifi devices may face some interception of their connection to the
6*1c60b9acSAndroid Build Coastguard Workerinternet, it's very common for, eg, coffee shop wifi to present some
7*1c60b9acSAndroid Build Coastguard Workerkind of login or other clickthrough before access to the Internet is
8*1c60b9acSAndroid Build Coastguard Workergranted.  Devices may need to understand that they are in this
9*1c60b9acSAndroid Build Coastguard Workersituation, and there are several different techniques for trying to
10*1c60b9acSAndroid Build Coastguard Workergague it.
11*1c60b9acSAndroid Build Coastguard Worker
12*1c60b9acSAndroid Build Coastguard WorkerSequence-wise the device has been granted a DHCP lease and has been
13*1c60b9acSAndroid Build Coastguard Workerconfigured with DNS, but the DNS may be wrongly resolving everything
14*1c60b9acSAndroid Build Coastguard Workerto an address on the LAN or a portal on the net.
15*1c60b9acSAndroid Build Coastguard Worker
16*1c60b9acSAndroid Build Coastguard WorkerWhether there is a captive portal active should be a sticky state for a given
17*1c60b9acSAndroid Build Coastguard Workerconnection if there is not going to be any attempt to login or pass the landing
18*1c60b9acSAndroid Build Coastguard Workerpage, it only needs checking for after DHCP acquisition then.  If there will be
19*1c60b9acSAndroid Build Coastguard Workeran attempt to satisfy the landing page, the test should be repeated after the
20*1c60b9acSAndroid Build Coastguard Workerattempt.
21*1c60b9acSAndroid Build Coastguard Worker
22*1c60b9acSAndroid Build Coastguard Worker## Detection schemes
23*1c60b9acSAndroid Build Coastguard Worker
24*1c60b9acSAndroid Build Coastguard WorkerThe most popular detection scheme by numbers is Android's method,
25*1c60b9acSAndroid Build Coastguard Workerwhich is to make an HTTP client GET to `http://connectivitycheck.android.com/generate_204`
26*1c60b9acSAndroid Build Coastguard Workerand see if a 204 is coming back... if intercepted, typically there'll be a
27*1c60b9acSAndroid Build Coastguard Worker3xx redirect to the portal, perhaps on https.  Or, it may reply on http with
28*1c60b9acSAndroid Build Coastguard Workera 200 and show the portal directly... either way it won't deliver a 204
29*1c60b9acSAndroid Build Coastguard Workerlike the real remote server does.
30*1c60b9acSAndroid Build Coastguard Worker
31*1c60b9acSAndroid Build Coastguard WorkerVariations include expecting a 200 but with specific http body content, and
32*1c60b9acSAndroid Build Coastguard Workerdoing a DNS lookup for a static IP that the device knows; if it's resolved to
33*1c60b9acSAndroid Build Coastguard Workersomething else, it knows there's monkey business implying a captive portal.
34*1c60b9acSAndroid Build Coastguard Worker
35*1c60b9acSAndroid Build Coastguard WorkerOther schemes involve https connections going out and detecting that the cert
36*1c60b9acSAndroid Build Coastguard Workerof the server it's actually talking to doesn't check out, although this is
37*1c60b9acSAndroid Build Coastguard Workerpotentially ambiguous.
38*1c60b9acSAndroid Build Coastguard Worker
39*1c60b9acSAndroid Build Coastguard WorkerYet more methods are possible outside of tcp or http.
40*1c60b9acSAndroid Build Coastguard Worker
41*1c60b9acSAndroid Build Coastguard Worker## lws captive portal detect support
42*1c60b9acSAndroid Build Coastguard Worker
43*1c60b9acSAndroid Build Coastguard Workerlws provides a generic api to start captive portal detection...
44*1c60b9acSAndroid Build Coastguard Worker
45*1c60b9acSAndroid Build Coastguard Worker```
46*1c60b9acSAndroid Build Coastguard WorkerLWS_EXTERN LWS_VISIBLE int
47*1c60b9acSAndroid Build Coastguard Workerlws_system_cpd_start(struct lws_context *context);
48*1c60b9acSAndroid Build Coastguard Worker```
49*1c60b9acSAndroid Build Coastguard Worker
50*1c60b9acSAndroid Build Coastguard Workerand two states in `lws_system` states to trigger it from, either
51*1c60b9acSAndroid Build Coastguard Worker`LWS_SYSTATE_CPD_PRE_TIME` which happens after DHCP acquisition but before
52*1c60b9acSAndroid Build Coastguard Workerntpclient and is suitable for non https-based scheme where the time doesn't
53*1c60b9acSAndroid Build Coastguard Workerneed to be known, or the alternative `LWS_SYSTATE_CPD_POST_TIME` state which
54*1c60b9acSAndroid Build Coastguard Workerhappens after ntpclient has completed and we know the time.
55*1c60b9acSAndroid Build Coastguard Worker
56*1c60b9acSAndroid Build Coastguard WorkerThe actual platform implementation is set using `lws_system_ops_t` function
57*1c60b9acSAndroid Build Coastguard Workerpointer `captive_portal_detect_request`, ie
58*1c60b9acSAndroid Build Coastguard Worker
59*1c60b9acSAndroid Build Coastguard Worker```
60*1c60b9acSAndroid Build Coastguard Worker	int (*captive_portal_detect_request)(struct lws_context *context);
61*1c60b9acSAndroid Build Coastguard Worker	/**< Check if we can go out on the internet cleanly, or if we are being
62*1c60b9acSAndroid Build Coastguard Worker	 * redirected or intercepted by a captive portal.
63*1c60b9acSAndroid Build Coastguard Worker	 * Start the check that proceeds asynchronously, and report the results
64*1c60b9acSAndroid Build Coastguard Worker	 * by calling lws_captive_portal_detect_result() api
65*1c60b9acSAndroid Build Coastguard Worker	 */
66*1c60b9acSAndroid Build Coastguard Worker```
67*1c60b9acSAndroid Build Coastguard Worker
68*1c60b9acSAndroid Build Coastguard WorkerUser platform code can provide this to implement whatever scheme they want, when
69*1c60b9acSAndroid Build Coastguard Workerit has arrived at a result, it can call the lws api `lws_system_cpd_result()` to
70*1c60b9acSAndroid Build Coastguard Workerinform lws.  If there isn't any captive portal, this will also try to advance the
71*1c60b9acSAndroid Build Coastguard Workersystem state towards OPERATIONAL.
72*1c60b9acSAndroid Build Coastguard Worker
73*1c60b9acSAndroid Build Coastguard Worker```
74*1c60b9acSAndroid Build Coastguard Worker/**
75*1c60b9acSAndroid Build Coastguard Worker * lws_system_cpd_result() - report the result of the captive portal detection
76*1c60b9acSAndroid Build Coastguard Worker *
77*1c60b9acSAndroid Build Coastguard Worker * \param context: the lws_context
78*1c60b9acSAndroid Build Coastguard Worker * \param result: one of the LWS_CPD_ constants representing captive portal state
79*1c60b9acSAndroid Build Coastguard Worker * \param redirect_url: NULL, or the url we were redirected to if result is
80*1c60b9acSAndroid Build Coastguard Worker *     LWS_CPD_HTTP_REDIRECT
81*1c60b9acSAndroid Build Coastguard Worker *
82*1c60b9acSAndroid Build Coastguard Worker * Sets the context's captive portal detection state to result.  User captive
83*1c60b9acSAndroid Build Coastguard Worker * portal detection code would call this once it had a result from its test.
84*1c60b9acSAndroid Build Coastguard Worker */
85*1c60b9acSAndroid Build Coastguard WorkerLWS_EXTERN LWS_VISIBLE int
86*1c60b9acSAndroid Build Coastguard Workerlws_system_cpd_result(struct lws_context *context, int result, const char *redirect_url);
87*1c60b9acSAndroid Build Coastguard Worker```
88*1c60b9acSAndroid Build Coastguard Worker
89