Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: captive portal auto-detect + DNS fallback + clean udhcpc script

- After WiFi connects, curl connectivity check (gstatic 204)
- Auto-follow redirects to clear simple captive portals
- DNS: always add 8.8.8.8 + 1.1.1.1 as fallback in udhcpc script
- Log portal status for debugging

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+47 -4
+6 -4
fedac/native/docker-build.sh
··· 149 149 ip addr flush dev "$interface" 150 150 ip addr add "$ip/${mask:-24}" dev "$interface" 151 151 [ -n "$router" ] && ip route add default via "$router" dev "$interface" 152 - [ -n "$dns" ] && { 153 - : > /etc/resolv.conf 154 - for d in $dns; do echo "nameserver $d" >> /etc/resolv.conf; done 155 - } 152 + # DNS: use DHCP-provided + fallback to Google/Cloudflare 153 + { 154 + for d in $dns; do echo "nameserver $d"; done 155 + echo "nameserver 8.8.8.8" 156 + echo "nameserver 1.1.1.1" 157 + } > /etc/resolv.conf 156 158 ;; 157 159 deconfig) 158 160 ip addr flush dev "$interface"
+41
fedac/native/src/wifi.c
··· 390 390 pthread_mutex_unlock(&wifi->lock); 391 391 wifi_log(wifi, "Connected! IP: %s", ip); 392 392 393 + // Captive portal detection + auto-accept 394 + { 395 + char portal_cmd[256]; 396 + snprintf(portal_cmd, sizeof(portal_cmd), 397 + "curl -sL -o /dev/null -w '%%{http_code}' " 398 + "--max-time 5 --connect-timeout 3 " 399 + "http://connectivitycheck.gstatic.com/generate_204 " 400 + "2>/dev/null"); 401 + FILE *pf = popen(portal_cmd, "r"); 402 + if (pf) { 403 + char code[8] = ""; 404 + if (fgets(code, sizeof(code), pf)) 405 + code[strcspn(code, "\n")] = 0; 406 + pclose(pf); 407 + if (strcmp(code, "204") == 0) { 408 + wifi_log(wifi, "Internet: OK (no captive portal)"); 409 + } else if (code[0]) { 410 + wifi_log(wifi, "Captive portal detected (HTTP %s), trying auto-accept...", code); 411 + // Follow redirect and accept — many portals just need a GET 412 + snprintf(portal_cmd, sizeof(portal_cmd), 413 + "curl -sL --max-time 10 --connect-timeout 5 " 414 + "-o /dev/null -w '%%{http_code}' " 415 + "http://connectivitycheck.gstatic.com/generate_204 " 416 + "2>/dev/null"); 417 + FILE *af = popen(portal_cmd, "r"); 418 + if (af) { 419 + char acode[8] = ""; 420 + if (fgets(acode, sizeof(acode), af)) 421 + acode[strcspn(acode, "\n")] = 0; 422 + pclose(af); 423 + if (strcmp(acode, "204") == 0) 424 + wifi_log(wifi, "Captive portal cleared!"); 425 + else 426 + wifi_log(wifi, "Captive portal may need manual login (HTTP %s)", acode); 427 + } 428 + } else { 429 + wifi_log(wifi, "Connectivity check failed (no response)"); 430 + } 431 + } 432 + } 433 + 393 434 // Save credentials for auto-reconnect 394 435 strncpy(wifi->last_ssid, ssid, WIFI_SSID_MAX - 1); 395 436 strncpy(wifi->last_pass, password ? password : "", WIFI_PASS_MAX - 1);