testing for Internet connection

Alex Tweedly alex at tweedly.net
Sun Dec 19 19:50:21 EST 2004


At 13:18 19/12/2004 -0800, Chipp Walters wrote:
>Then there's always the question, what ip address do you ping? Any 
>IPaddress I have may or may not be available at a given time as 
>IPAddresses are even less reliable than domains. Perhaps you know of an 
>IPaddress which is 'always on'? Then, it would make a good first ping for 
>the handler/function.

Most of the IP addresses of the root DNS servers should be very reliable - 
recursive DNS servers will typically have these IP numbers stored in their 
cache file, and will try them as necessary to get the top-level delegated 
server address. Since they're stored as numeric addresses in thousands of 
hosts, they need to be fairly permanent.


But - they don't always work all the time, so need to try a number of them 
and if they don't succeed, then it's reasonable to assume there is no 
working connection. Should have a scheme to periodically update the list of 
addresses (leaving out the unreliable ones) and this should be very safe.

These addresses do change over time, but only very slowly, and typically 
the "old" addresses continue to be supported (for ping and DNS requests) 
for long periods (months or years).

(if the root servers are not reachable, then your DNS server is likely to 
be not very operational anyway :-)

>I, like Richard, and others, have perused the lists to no final outcome 
>regarding this 'am I connected' issue. I like your idea of pinging first, 
>and it would be a wonderful contribution to the community to collectively 
>create the best handler/function for this.

Here's a slightly modified version of your code (watch out for newlines).

Note 1. this allows an optional parameter of a numeric IP address to try 
first. This can (should) be set by the app to the last successful numeric 
IP address used (i.e. if the app succeeds in connecting, it should remember 
that IP address, and use it next time). Although server addresses do 
change, most of the time they will remain the same - and hence we avoid 
putting load on the public servers. If the server address has changed - 
well, we might succeed in getting a ping to work anyway - and that will 
imply that we have an internet connection. If not - no harm done, we then 
try the public servers.   [NB client apps that are likely to be run on an 
intranet should avoid this, since that can give a false-positive for having 
an internet connection]

Note 2. this does the pings one after another. It would be cool to set them 
off in parallel - but I don't know how (if?) that can be done in Rev. This 
means the worst case time-out (i.e. if not connected to the internet) is 
rather long, about 3 seconds. If this is too long, could trim out some of 
the root servers, or put a limit of maybe 5 to be tried.

Note 3. If you need to deal with long latency, might need to increase the 
timeout value, and/or try the "get URL" multiple times.

local rootServers = 
"198.41.0.4,128.9.0.107,192.33.4.12,128.8.10.90,192.5.5.241,128.63.2.53,192.36.148.17,192.58.128.30,193.0.14.129,198.32.64.12,202.12.27.33"
-- omit "new-B", E and G.root-servers.net - they have been temperamental

function IsConnected pNumericIPAddress, pURL
   -- optional pNumericIPAddress - an IP address for a previous 
"interesting server"
   -- optional URL to use for testing
   -- hide shell activity from user
   set the hideConsoleWindows to true

   put "Cannot reach Internet" into tResult
   -- if we have an "interesting server" try it first
   if pNumericIPAddress is not empty then
     put shell("ping -n 1 -w 200 " & pNumericIPAddress) into tVar
     if "Received = 1" is in tVar then put empty into tResult
   end if

   if tResult is not empty then
     sort items of rootServers by random(the number of items of rootServers)
     repeat for each item I in rootServers
       put shell("ping -n 1 -w 200 " & I) into tVar
       if "Received = 1" is in tVar then
         put empty into tResult
         exit repeat
       end if
     end repeat
   end if

   -- If we have succeeded so far, let's try a "get"
   if tResult is empty then
     if pURL is empty then put "www.google.com" into pURL
     if char 1 to 7 of pUrl <> "http://" then put "http://" before pUrl
     get URL pUrl
     put the result into tResult
   end if

   if tResult is empty then
     return true
   else
     answer information "Problem connecting to the internet: " & tResult
     return false
   end if
end IsConnected


-- Alex.


More information about the use-livecode mailing list