
Show HN: Rust Library to check your Internet connectivity - jesusprubio
https://github.com/jesusprubio/online
======
OskarS
So... the test is "can I connect to either the website icanhazip.com or
OpenDNS". With the IPv4 addresses of both burned into the code.

So this depends on two external servers never going down and not ever changing
IP addresses, one of which is pretty sketchy ("icanhazip.com", seriously?),
and it wouldn't work AT ALL in an IPv6-only environment (which I grant is
rather unlikely at the moment, but might not be in the future).

I like Rust a lot, but micro-packages like these are giving me real bad "left-
pad" vibes.

~~~
sushibowl
Am I currently connected to the internet isn't really a question which has a
meaningful answer in the first place. The internet is not a monolithic object
you can connect to, and achieving a connection to any endpoint doesn't
particularly guarantee your connection to anything else.

The actually meaningful question you almost always want answered instead of
"am I online?" is "will I be able to connect to X host?" The obvious check is
to try to connect to that host.

~~~
jesusprubio
Obviously, you're right. And I can imagine any developer can imagine the same
thing :).

But I couldn't find a better way to check if I am online than making a request
to any server. In fact, I'm using two over different protocols just in case.

~~~
oconnor663
One area for improvement: Default to a set of domains to check rather than
just one, for example google.com, facebook.com, baidu.com. Check them all in
parallel, and return success as soon as you get a good answer from 2 out of 3.
This avoids falsely reporting "offline" when one host happens to be down, and
it avoids slowing down the check when one host happens to be slow. Probably
use `mio` to orchestrate this, to avoid the overhead of threads. (Note that
this is similar to how musl libc implements DNS.)

Another area: Think about what should be reported in a country like China. For
example, facebook.com is blocked. If China blocks google.com tomorrow, does
that mean that every computer in China is offline? Probably not. On the one
hand, this isn't something that a library can give a one-size-fits all answer
for. On the other hand, since China has the most internet users of any country
in the world, this is probably something that the design of the library should
consider and offer documentation and best practices for.

Another area: Many GUI apps expect to make ongoing connections, e.g. chat apps
that are always listening for messages. These apps need to persistently check
the status of the network in the background, and many would be willing to
dedicate a background thread to this library if it helped with some of the
details of that, like 1) detecting hardware-level state changes, like WiFi
coming and going, to prompt an immediate re-check, 2) checking in a rapid loop
after a network change, but backing off to a lower background rate when the
network is stable, 3) "de-bouncing" network events in case the network seems
to be coming and going multiple times a second, so that UIs responding to
those events don't flicker.

Higher level: This is a common problem. Find other libraries that have solved
this problem before, compare the different ways they've solved it, and
document the tradeoffs. I appreciate that I'm suggesting that you do a lot of
work, but if you intend for production applications to use this code then it's
very important work.

~~~
jesusprubio
Thank you for the feedback. It's only my first crate I wrote to learn about
the environment. It emulates more or less this one in Node.js a lot of people
uses: [https://github.com/sindresorhus/is-
online](https://github.com/sindresorhus/is-online)

I wanted to implement it in this way. But I'm waiting for async/await, it
should be trivial with a map function or something similar. But now it already
tries a fallback connection if the first one fails.

Good point about the countries, I need to add an issue to cover it.

------
dsl
This library is dangerous and should not be used.

It contains hardcoded values that could result in the library not working as
intended, or unintentional DoS attacks against innocent third parties if it
were implemented in a widely distributed piece of software.

~~~
ay
In general “checking whether the connectivity to internet exists” is an idea
that may create a massive pain down the road when implemented, because the
heuristics used are not equal to actual connectivity, thus will break one day.

Just attempt to perform the operation you want, and if it fails, give the
feedback to the user that it failed. Why does it have to be more complicated
than that ? (It is not a rhetorical question)

~~~
spuz
Way back in the dial-up days, I wrote a program to measure the periods of time
that a user was online and the corresponding phone call charges which varied
depending on the time of day. This meant I had to know to the second whether
or not the user was 'online'. Since the days of per-minute charges for
internet are long gone, I find it hard to imagine other reasons you would need
to know if the user is online rather than able to access a specific server.

~~~
jesusprubio
It's only my first crate I made to learn about the environment.

But I truly believe in this micro modules way of building things. If it
reduces complexity it's welcome. :)

------
twic
I don't know of any IP addresses that it's safe to hardcode in software like
this.

However, there are hostnames that it's safe to hardcode: the DNS root servers,
a.root-servers.net etc.

If you have working hostname resolution, even if intermittently, you could _in
principle_ resolve those, and then check connectivity. However, it's probably
not a good idea to use these crucial public resources for something so
pointless!

Interestingly, all of the root servers except G also have a companion website,
${letter}.root-servers.org, which could perhaps be used for an HTTP
connectivity check. Those websites aren't hosted on the same machines as the
nameservers.

~~~
jesusprubio
Thank you! Very interesting thoughts, adding them to the repo
here:[https://github.com/jesusprubio/online/issues/7](https://github.com/jesusprubio/online/issues/7)

Please feel free to contribute ;).

------
georgyo
The universal consensus after anyone looking at the code is that they should
not use it.

What I don't understand is why and who are they people who are up voting this
and keeping it on the front page.

Do people just see rust, and then up vote? If so, while rust may be good,
blind voting everything written in rust is good will cause distrust later.

------
maltalex
I don't think there's a reason to use TCP for this unless you want to check
for TCP connectivity specifically.

Just do a DNS lookup against a list of well-known public DNS servers.

~~~
oconnor663
One reason not to do DNS exclusively is that many networks allow DNS requests
(and intercept them) but block HTTP requests.

