Show HN: Rust Library to check your Internet connectivity
github.com
github.com
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.
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.
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.
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.
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.
It's easy to make comparisons with left-pad, but left-pad was an issue because of the dependency graph. It wasn't an issue as a package in isolation.
I mean I know this is google we're talking about, their uptime is second-to-none, but that still seems like a hell of a dependency.
But hey, give it a whirl: block detectportal.firefox.com with your hosts file and see what happens.
So, your solution to "left-pad" is to write all your own code? xD. I think you need to review what was the problem there.
About the support to different services, those are the ones I use in my applications. But you are right, it would be a nice feature. PR's are welcome by the way ;).
The same about IPv6 support, this is an important feature.
Added both as issues: - https://github.com/jesusprubio/online/issues/5 - https://github.com/jesusprubio/online/issues/6
1. Use platform-native APIs. Both Windows and macOS has apis for this [0] [1], and you are not going to know better than them. Use the "test websites" option only as a fallback or on platforms that aren't supported.
2. Remove all burned-in IP addresses and use system DNS. Since the whole point of this is to make a generic "can the system reach the internet" indicator that is never going to be 100% accurate, you can pretty much just say that "if you don't have access to DNS, you don't have access to the internet".
3. Make sure it works with IPv6.
4. Have a long list (at least 20-30, preferably more) of servers that you check, of companies you can be very sure will not go down. Things like "google.com", "apple.com", "microsoft.com", etc (other good endpoints have been suggested in this thread). When you want to check if you have internet, pick a random 5 and check if any of them works. Consider censorship here, Wikipedia is not going to work for you because it's blocked in many countries. Also: try and find sites that are cool with you using them like this, which I imagine will be a challenge. Preferably, you should get explicit permission.
(honestly, I'm unsure about this part. It feels very skeevy to use these kinds of sites in this way, but it's hard to think of an alternative. I guess check what sites other libraries that provides this kind of support uses)
5. Preferably provide some extended error information. Is the problem that we don't have any network adapters, or a cable not plugged in?
Point number 1 would probably be the most important thing, since that's a genuinely annoying and difficult thing to do. That might be worthy of a package/crate that properly abstracts away the native APIs. But if I were to even consider using this for anything, I would want a FAR more robust system than what you cooked up.
In regards to your comment about engineers: what your package does is trivial. It makes two requests and than reports if either worked. If this is what I wanted, it would have taken me ten minutes to write my own version.
If I had tasked an engineer with a task that could be solved this trivially, and their solution was to pull in an external dependency you have no control over, that would be unacceptable. It would fail code-review in a second and we would have a serious chat about what their job is. I realize that JavaScript and NPM has a different culture, but for systems programming for production use, this would simply not be an acceptable solution.
An engineer is not just a person who "put pieces together". An engineer also considers questions like "what is the cost of using this piece? What are the risks with bringing in an external dependency? What is the code quality of this dependency? Is any of these costs bigger than writing the code myself, from scratch?" As an engineer, you have a responsibility to ensure the robustness and stability of the whole system over the long term. It not just your job to slap together a few packages and call it a day when the CI build passes. A package/crate is not just "free code, yay!". Every dependency you add to any project brings with it costs and risks.
I hate to be this harsh. I understand your eagerness to contribute to open source, and I commend you for that instinct. But when you "Show HN", we're going to give you our honest opinions.
[0]: https://docs.microsoft.com/en-gb/windows/desktop/api/netlist...
[1]: https://stackoverflow.com/questions/15184490/check-for-activ...
The downside is that there's definitely a learning curve and you get packages like this early in the process. The upside is that it's bringing a whole bunch of new people in who are willing (and increasingly more able over time as they learn) to help write new open-source software.
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.
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)
But I truly believe in this micro modules way of building things. If it reduces complexity it's welcome. :)
EDIT: it looks like I'm getting downvoted for this opinion - could any of the downvoters also reply as to why it's a bad idea?
That is pretty much what happend with this dubious WordPress plugin developers that changed their "license check" or keep-alive check or whatever to do some hundred thousand (or so) "checks" to their competitors website per hour.
You are being downvoted because the author pointed at random services not under his control. So if a mobile app with million of users deployed this, an innocent third party that has nothing to do with the author would be hit with millions of requests they didn't ask for.
About DoS attack, I think you need to review how those work, the library is not implementing amplification or something similar.
If you don't understand what I mean - just pull the project and do some more research before you release something like this.
You can relax, I know how they work. My final year project was about DoS. I would send you the link but it's Spanish.
But I can say you I've written a tool to implement this vector (among others) against VoIP services and it was presented even at the BlackHat conference.
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.
Please feel free to contribute ;).
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.
Just do a DNS lookup against a list of well-known public DNS servers.