Im getting frustrated because of OpenDNS and other services (ie: roadrunner) that now always returns a ping even if you type any invalid url ie: lkjsdaflkjdsjf.com --- I had created software for my own use that would ping a url to verify if the site was up or not. This no longer works. Does anyone have any ideas about this?
Requirements:
It should work with any valid web site, even ones i dont control
It should be able to run from any network that has internet access
I would greatly appreciate to hear how others now handle this. I would like to add, im attempting to do this using System.Net in c#
Thank you greatly :-)
New addition: Looking for a solution that i can either buy and run on my windows machine, or program in c#. :-)
Update:
Thank you all very much for your answers. Ultimately i ended up creating a solution by doing this:
Creating a simple webclient that downloaed the specified page from the url (may change to just headers or use this to notify of page changes)
Read in xml file that simply lists the full url to the site/pages to check
Created a windows service to host the solution so it would recover server restarts.
On error an email and text message is sent to defined list of recipients
Most values (interval, smtp, to, from, etc) are defined in the .config for easy change
I will be taking some of your advice to add 'features' to this later, which includes:
AJAX page for real-time monitoring. I will use WCF to connect to the existing windows service from the asp.net page
Download Headers only (with option for page change comparison)
make more configurable (ie: retries on failure before notification)
Wget is a nice alternative. It will check not only whether the machine is active, but also whether the HTTP server is accepting connections.
You could create a simple web page with an address bar for the website and some javascript that uses AJAX to hit a site. If you get any HTTP response other than 200 on the async callback, the site isn't working.
<html>
<head>
<script language="javascript" type="text/javascript">
<!--
var ajax = new XMLHttpRequest();
function pingSite() {
ajax.onreadystatechange = stateChanged;
ajax.open('GET', document.getElementById('siteToCheck').value, true);
ajax.send(null);
}
function stateChanged() {
if (ajax.readyState == 4) {
if (ajax.status == 200) {
document.getElementById('statusLabel').innerHTML = "Success!";
}
else {
document.getElementById('statusLabel').innerHTML = "Failure!";
}
}
}
-->
</script>
</head>
<body>
Site To Check:<br />
<input type="text" id="siteToCheck" /><input type="button" onclick="javascript:pingSite()" />
<p>
<span id="statusLabel"></span>
</p>
</body>
This code depends on the browser not being IE and I haven't tested it, but it should give you a really good idea.
To see if a service is up, not only should you ping, but it's good to have scripts that will hit a service, such as a website, and get back a valid response. I've used What's Up Gold in the past, rather than write my own. I like all the features in products like that. such as sending me a page when a service is down.
For the record, lkjsdaflkjdsjf.com is a hostname (which at the moment is not registered to anyone). ping does not work with URLs, ping works with hostnames. hostnames are looked up using the Domain Name System. DNS is supposed to fail when hostnames are not registered.
The problem is that some services (apparently your ISP, and definitely OpenDNS) do NOT fail DNS requests for hostnames that aren't registered. Instead they return the IP address of a host on their network that presents a search page to any http request.
You appear to want to know two things: Is the name real (that is, is there a host with this name registered to some actual machine)? and Is that machine functioning?
If you already know that the name in question is real (for instance, you want to know if www.google.com is up), then you can use ping because you know that the name will resolve to a real address (the ISP can't return their IP for a registered name) and you'll only be measuring whether that machine is in operation.
If you don't know whether the name is real, then the problem is harder because your ISP is returning false data to your DNS request. The ONLY solution here is to find a DNS server that is not going to lie to you about unresolved names.
The only way I can think of to differentiate between your ISP's fake records and real ones is to do a reverse lookup on the IP you get back and see if that IP is in your ISP's network. The problem with this trick is that if the ISP doesn't have reverse DNS info for that IP, you won't know whether it's the ISP or just some knucklehead who didn't configure his DNS properly (I've made that mistake many times in the past).
I'm sure there are other techniques, but the fact that DNS lies underneath everything makes it hard to deal with this problem.
Don't directly know of any off the shelf options in c#, although I'd be very suprised if there aren't a few available.
I wrote something similar a few years ago, don't have the code anymore cos it belongs to someone else, but the basic idea was using a WebClient to hit the domain default page, and check for a http status code of 200.
You can then wire any notification logic around the success or fail of this operation.
If bandwidth is a concern you can trim it back to just use a HEAD request.
For more complex sites that you control, you can wire up a health monitoring page that does some more in depth testing before it sends the response, eg is DB connection up etc.
Often a machine that is dead on port 80 will still respond to a ping, so testing port 80 (or whatever other one you are interested in) will be a much more reliable way to go.
I've found ping to be very unreliable just because of all the hops you're having to jump through, and something in between can always interfere.
Trying to open up an http connection with a web server is probably the best way to go.
You could try running 'httping' if you have cygwin available or
http://freshmeat.net/projects/httping/
As far as I can see, the problem here that OpenDNS resolves invalid domains back to themselves to forward you on to something close to what you're after (so if you typo ggooggllee.com you end up at the right place via a bounce from the OpenDNS servers). (correct me if I'm wrong)
If that's the case, you should just be able to check whether the IP you've resolved == any of the IPs of OpenDNS? No more ping - no protocol (HTTP) level stuff - just checking for the exceptional case?
If you tend toward the sys-admin solution rather than the programming solution you could install a local name server and tell it not to accept anything but NS records for delegation only zones. This was the fix I (and I assumed everyone else on the internet) used when Network Solution/Verisign broke this last time. I installed BIND on a couple of local machine, told my DHCP servers to hand out those addrs as the local name servers, and set up something like the following for each of the delegation only zones that I cared about:
zone "com" { type delegation-only; };
zone "net" { type delegation-only; };
Come to think of this, I think this might be turned on by default in later BIND versions. As an added bonus you tend to get more stable DNS resolution than most ISPs provide, you control your own cache, a little patching and you don't have to rely on your ISP to fix the latest DNS attack, etc.
i like CALM for this sort of thing as it logs to a database and provides email notifications as well as a status dashboard
you can set up a test page on the site and periodically do a GET on it to receive either a 'true' result (all is well) or an error message result that gets emailed to you
caveat: i am the author of CALM
Related
I am currently using Httpclient and I can successfully gather my data with a specific network/internet-connection at the place that has the data.
However when I try to gather the data at home with another internet-connection I receive an "NameResolutionFailure" error.
My goal is to be able to reach the data from any type of connection but I am not sure what I am quite missing here. (I am also new in this area).
This is the code that I use when I talk to the db:
string dataurl = "my-url-here";
var http = new HttpClientHandler()
{
Credentials = new NetworkCredential("user", "password", "domain"),
};
var httpClient = new HttpClient(http);
try
{
var result = await httpClient.GetStringAsync(dataurl);
System.Diagnostics.Debug.WriteLine(result);
}
catch (HttpRequestException ex)
{
if (ex.GetBaseException() != null)
{
System.Diagnostics.Debug.WriteLine(ex.GetBaseException().Message); //this is where i recieve the NameResolutionFailure error
}
else
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
}
How come I can only reach the data when I am on a certain network and not with every network? Am I missing code or is there something else in play here?
Appreciate every help, tips, code-examples i can get!
The problem is likely to be in the string dataurl = "my-url-here"; and where that's accessible from. There are likely to be two obstacles:
Name resolution
Network Access
While your error message only mentions Name resolution, I'm guessing you'll need to do something about network access as well.
Name resolution (or DNS) is about translating a host name into an I.P. address.
When you're on a work network, there'll be a name resolution service that resolves local computer names to I.P. addresses on the network. Normally these local computer names are not visible to public DNS servers. If you connect your device to a different network (e.g. a mobile network), it uses the public DNS servers, which know nothing about the local domain named computers.
For example MyServer might resolve on your local network because it's part of your local domain, and the local network infrastructure will sort that out. MyServer.MyCompany.com is usually similar, as by default machines names aren't exposed externally.
For a mobile application, you're going to need a public domain name. Something like MyServer.MyDomain.com (or www.google.com is the same thing, essential). A public DNS server translates this name to an I.P. address.
This is probably where the problem you're experiencing is occurring. You're probably using a local host name, that the public DNS servers don't know about.
If you're working for an organisation they may already have a domain, or you may need to purchase a domain for your application.
In the meantime you could look at one of the dynamic DNS solutions that may allow you to progress for development purposes.
For my Xamarin app, I use the name of the local machine when I'm developing, and the mobile device is on the same network.
If I'm not on the same network, I have a VPN that I can use. This connects into the work network as if I'm on the same network. If I'm developing at home and both devices are on my home network, I use the I.P. address of my development box, because I haven't made local DNS work on my home wifi.
When we go to release we use a public URL, like api.MyApp.com - which public DNS points to our prod server.
Network Access might be a thing that you need to deal with too.
A major part of a Network Engineer's job is to keep the hackers out. When your mobile device is on the same network as the server (i.e. when it's working for you), this isn't a problem because because mostly networks are configured so that two devices on the same network can see each other. It sounds like this is the sort of network you have, if your app can see your server on one connection.
But if you're needing to connect to your server from a mobile network, you need a way to tell your network router to forward specific traffic from the internet to your server.
This gets complicated, but for development purposes, strategies I've seen work are:
A VPN - we have a VPN that I fire up on the mobile device, enter my work network credentials, and then I can access my development box as if I'm on the same network
Virtual server / port forwarding - if you're at home, you can probably configure your modem to forward a particular port to your development box. Every modem is different, so you'd have to search up instructions for your particular one.
Network Engineer - if you're in a corporate, and want traffic from outside to get to a server that you're managing (and don't have a VPN), you probably need to talk to your networks department. Good luck.
I've seen loads post on this forum about exchange API, but I've never found something like I have.
I' m trying to connect to Exchange using Exchange API in order to get all room's meetings.
My problem : Sometimes, it's working, I can connect and get all my informations. And 5m later, impossible to connect. I got Unauthorized.
It's not an error on code because it's working, I think it's a problem with exchange server, but I really don't know what it is...
On the next picture, there are traces.
On the left, when it's working, And the same 30m later (same identification, same room) which is not working.
http://hpics.li/2d9b216
If you have any ideas ? I really don't know what to do.
thanks (and sorry for my english !)
I notice that the working request comes from server A (look at the value of X-FEServer header), and the failing one comes from server B. Perhaps there is a configuration problem on server B.
thx for this.
I've done some tests : I've modified my host file in my computer. when the url is pointing to serveur A, it's working. When it's on the other server, not working. It's the same configuration on both, cannot find what's wrong. So I will conserve my actual host file (pointing always on serveur A).
Got an asp.net web page in c#. One thing we would like to do is track hits to the site including their IP address. I implemented some code (thanks to SO) but the logged IP address always seem to be local, ie: 192.168.x.x. I have tried it from a variety of devices, even my phone and Version MiFi just to make sure its not something weird with the ISP but the log always list the same 2-3 different internal ip addresses (seems to change a little as the day goes on).
Here is my function that gets the IP (again thanks to postings here on SO):
protected IPAddress GetIp(HttpRequest request)
{
string ipString;
if (string.IsNullOrEmpty(request.ServerVariables["HTTP_X_FORWARDED_FOR"]))
ipString = request.ServerVariables["REMOTE_ADDR"];
else
ipString = request.ServerVariables["HTTP_X_FORWARDED_FOR"].Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
IPAddress result;
if (!IPAddress.TryParse(ipString, out result))
result = IPAddress.None;
return result;
}
public void logHit()
{
IPAddress ip = GetIp(Request);
string sIP = ip.ToString();
}
I tried this as well which yields the same result:
HttpContext.Current.Request.UserHostAddress;
When I do a call on the client side using something like the service on appspot, it works just fine:
<script type="application/javascript">
function getip(json) {
//txtIP is a input box on the form
document.getElementById("txtIP").value = json.ip;
}
</script>
<script type="application/javascript" src="http://jsonip.appspot.com/?callback=getip"></script>
I suppose I could do a round-about way by hitting that appspot link and parse it out but that seems like a whole lot of trouble for something that should be simple.
Could it be the IIS on the server? Some kind of redirect going on? The ip addresses logged are NOT the servers. The problem is I dont have direct access to it so I have to talk to the guys that admin it and would like to give them some direction before they just start changing things.
Thanks
Ernie
If the HTTP_X_FORWARDED_FOR header is truly supported, then I think this would not be either forward or reverse proxy server causing this, but more likely Dynamic Network Address Translation or Dynamic Port Address Translation, which is happening below the application layer on the TCP/IP stack and thus would not affect an HTTP request header.
There are many ways to configure NAT, most of which would not cause these symptoms, but it is certainly possible to configure NAT in a way that would present this problem. Dynamic NAT or Dynamic PAT would be two such examples, and I would suggest this is what you ask your network administrators.
For more on Dynamic NAT/PAT, with good examples, you could review: http://www.cisco.com/en/US/docs/security/asa/asa82/configuration/guide/nat_dynamic.html
In a typical NAT scenario, the request packets reach the NAT device (firewall or router) as:
FROM - 5.5.5.5 (public address of the client)
TO - 6.6.6.6 (the public address of the server)
The "typical" NAT configuration would rewrite only the destination, as follows:
FROM - 5.5.5.5
TO - 192.168.6.6 (the private address of the server)
In this typical case, the server would still see REMOTE_ADDR as 5.5.5.5, as that is the source address on the incoming request. Then, the packets would be returned to 5.5.5.5, and the response would return to the client successfully.
Now, in the case of dynamic PAT, for example, the request would reach the NAT device as follows:
FROM - 5.5.5.5
TO - 6.6.6.6
Then, the NAT device would rewrite both source and destination packets, maintaining this "dynamic" mapping for only the lifetime of the request:
FROM - 192.168.1.1:12345 (the dynamic PAT address)
TO - 192.168.6.6 (the private address of the server)
Now, when the server sees this request, it appears to be from private address 192.168.1.1. In fact, with a strict PAT all requests will appear to be from this address. In your case, there are 2 or 3 of these addresses, probably because you may have enough traffic that you risk running out of ports if you use only a single dynamic PAT address.
So, your REMOTE_ADDR is 192.168.1.1, because that is actually the source address on the request packets. There is no HTTP_X_FORWARDED_FOR, because the Dynamic PAT is occurring at a lower TCP/IP layer (address and not application).
Finally, the response is sent back to 192.168.1.1:12345, which routs to the NAT device, which for the duration of the request/response (see the Cisco documentation above) maps it back to 5.5.5.5, and then drops the "dynamic" mapping.
Everything worked perfectly, the client gets the response back, except that you have no idea of the actual client address from the viewpoint of the server. And if it is dynamic NAT in play, I don't see how you could get this information from the server.
Fortunately, you did exactly the right thing to get the information in javascript on the client, so this likely solves your problem as well as it could be solved.
It depends on your network structure. Simply a firewall or load balancer can change the variables which you are checking.
if you are using a load balancer check this:
How to get visitor IP on load balancing machine using asp.net
if your sever is behind a firewall check this:
Find if request was forwarded from firewall to IIS
I have a c#.net wpf application which sends data to a webservice on daily basis.
I am planning to host my webservice on shared hosting.
My question is How to ensure my webservice is always up and running ? i.e What should I need to take care if my webserver is down for few days? Do I need to maintain multiple servers if one goes down another will be available ?
To acheive this do I need to mention both the servers ip addresses in wpf windows application?
I have searched google but couldnt find the correct answer.
Any links from the community will be appreciated.
i have two suggestions:
1. call a method of web service method and handle it with exception.
2. get the dynamic URL from section <applicationSettings> and then do a httprequest to check if url is valid or not
solution 1 example:
[WebMethod]
public DateTime GetCurrentServerTime()
{
return System.DateTime.UtcNow.ToString("yyyyMMddZHHmmss");
}
and in you application :
catch (System.Net.WebException ex)
{
messgabebox.show( "Your Web Service not available");
}
it cause about 10 seconds for a response ....
solution 2 example:
HttpWebRequest objRequest = (System.Net.HttpWebRequest)HttpWebRequest.Create(strWebServiceUrl);
HttpWebResponse myHttpWebResponse = (HttpWebResponse)objRequest.GetResponse();
if (myHttpWebResponse.StatusCode != HttpStatusCode.OK)
{
DisplayMessage("Your Web Service not available" + "\r" + "Please try after some time");
return;
}
I think this is the better way to check for webservice availability..
The reason you haven't found an answer on google is that there is no correct answer. Everyone approaches these problems differently based on the needs of their application. To answer some of your questions, I can really only provide general suggestions and even those are just approaches I would take to solving this problem:
My question is How to ensure my webservice is always up and running ?
Maximizing uptime is important and can require careful design. You need to gracefully handle error conditions and be able to handle any input thrown at you. One caveat with this is that, while uptime is important, accuracy of your data may be more important. If this is the case, it may be better for your webservice to be down, than to appear to be up, but have it corrupting data.
What should I need to take care if my webserver is down for few days?
You need to code your client application in such a way that it can properly queue data up and send it when the service is back up. Also, you need to be smart in your service (i.e. not assuming that upload data == data date). Don't forget that the client application can be down for days at a time too (natural disaster, power outage, downtime for maintenace, crashing on a weekend...)
Do I need to maintain multiple servers if one goes down another will be available ?
To acheive this do I need to mention both the servers ip addresses in wpf windows application?`
That is definitely an option. Redundancy can allow you to perform maintenance on servers or upgrade while minimizing downtime. There are a lot of ways to approach this. I would probably use multiple FQDNs. So I would have server1.example.com and server2.example.com each pointing to a different server (ideally in a different data center). I would also have these servers have a very low TTL on their DNS entries, so I can swap out the servers to a new IP if they start going down.
Then in your client app, you can either round robin between the two servers or you can have a main server and the other just serves as a backup.
With all of that being said, the point many people forget about when setting something like this up is testing. You need to test one server coming down, both servers coming down, switching DNS and any other permutations you can think of to ensure your redundancy solution works, is scalable, and doesn't cause other issues.
We have the following situation:
The clients are sending events / messages to the server over a webservice. The server can identify the clients according to the "Sender URI". The server must now distribute the message to the "interested listeners".
Now it can be that a client says it is e.g. http://127.0.0.1:8000/ on the server this client is configured with http://localhost:8000.
Uri.Compare( ) and Uri.Equals return both false.
Does anybody knows an algorithm who can identify the URI with all its representations? I mean Localhost == 127.0.0.1 == "Real IP" == "DNS-Name" ?
Thanks
Thomas
Because nobody has posted an answer yet, I will stay with my own made "algorithm" / method which tries to compare all different representations.
What I found out: At the server it is not possible to determine in all cases a remote URL. It can be that the user - account or the subnetwork the server is in, does not have enough privileges to determine e.g. which IP is behind the Active Directory Name.
So there will be always the problem that the server needs a manually filled file or so, which it uses as a base to determine if it knows the sender-URI.