Depends on what level of internet connectivity you need? Is just being connected to a router enough? Do you need to connect to a wider part of the internet? Or do you need uncensored access to the entire internet? Browsers and phones generally check for captive portals by connecting to a website of the vendor over http (not https) and checking that the result matches expectation rather than redirecting to the captive portal itself.
I became curious how they check for internet connectivity recently because my Windows machine often tells me that my WiFi is connected to my phone(or mobile modem/router) but "No Internet Connection". But everything works fine though my browser or whatever other connectivity I use.
Looks like as a minimum you need the ICMP protocol to make a "ping". There is a crate for that:icmp::IcmpSocket - Rust. If you don't want to use a crate you will have to write your own to do ICMP. Or copy the code from IcmpSocket crate.
The UDP protocol does not have any notion of connections. With UDP you use send packets of data out to some address and it sends them. There is no checking that the packet arrives at the other end. No responses at all.
The code you have shown there does not try to make a connection with anything. It does not send anything to anything. It only binds you to an IP address and port number. Which basically means that any packets you do eventually send will contain that IP address and port number as their source IP and port.
use std::io::prelude::*;
use std::net::TcpStream;
fn main() -> std::io::Result<()> {
let mut stream = TcpStream::connect("64.233.161.100")?;
stream.write(&[1])?;
stream.read(&mut [0; 128])?;
Ok(())
} // the stream is closed here
Can't you just try to create a UDP or TCP to a server online and if it fails you can see that there is no internet connection. That is what I am trying to do as the features are already in the Rust std.
As I said above, with UDP you send individual packets to remote IP addresses. There is no "connection" There is no response. There is way to know the packet arrived at the other end. Or even that it did not get lost along the route through intermediate routers on the internet.
Unless....unless you have something running on the remote address that also uses UDP and will make replies to whatever UDP packets you send it. I guess you do not.
Due to firewalls, NATs and other middleboxes there are different degrees of "internet access". Does hostname resolution work? HTTP? any TCP port? are listening ports externally reachable? UDP? Any IP protocol? IPv4 or IPv6?
And even if those work, do they work reliably and fast enough? E.g. a small-packet ping may succeed but big packets can get lost due to MTU problems. Or some ISPs kill TCP connections when they look like traffic they don't like (e.g. VPNs or p2p applications). And just because one remote host is reachable doesn't mean others are, sometimes there are routing issues. E.g. my ISP had IPv6 peering issues with cloudflare a while back, which made services behind cloudflare only IPv4-reachable, but other IPv6 services worked fine.
Depending on what your software needs you'll have to test different things.
Well, at least on linux you can listen for the ICMP errors in reply to a UDP packet (via MSG_ERRQUEUE, this doesn't need extra privileges). That's how UDP traceroutes work.