Try as I might, I'm unable to resolve an address to IP. The code snippet is shown below. I keep getting the No such host is known exception, even though I could access google with my browser (The DNS server is almost certainly working). I'm however behind company's firewall.
try
{
foreach (IPAddress address in Dns.GetHostAddresses("www.google.com"))
{
Console.WriteLine(address.ToString());
}
}
catch (SocketException e)
{
Console.WriteLine("Source : " + e.Source); // System
Console.WriteLine("Message : " + e.Message); // No such host is known
}
There is nothing wrong with your code. Given that you can access www.google.com from a web browser the next most likely problem is that the web browser is using a proxy server. The web browser is actually accessing www.google.com through the proxy server which is allowed through the firewall. The simple application you wrote is not allowed through the firewall and is resulting in an exception.
You can verify this by looking at the proxy settings in Internet Explorer.
Tools -> Options -> Connections -> Lan Settings
There will be a proxy server group of settings. If there is a value present, this is almost certainly your problem.
You need to set up the proxy:
here's a snippet that should set it up for all the following calls:
protected void SetupProxy(string proxyUrl, string proxyLogin, string proxyPassword, string[] proxyBypass)
{
WebProxy proxy = new WebProxy(proxyUrl);
proxy.Credentials = new NetworkCredential(proxyLogin, proxyPassword);
proxy.BypassList = proxyBypass;
proxy.BypassProxyOnLocal = true;
WebRequest.DefaultWebProxy = proxy;
}
Rather than try through a browser, try pinging www.google.com (or some other host, of course) from the command line.
The ping itself may well not work, but it should show the IP address resolution first. If you get an error message like this:
Ping request could not find host www.google.com.
Please check the name and try again.
then it's likely that the proxy server is doing the DNS lookup for you when you're browsing, and your DNS server is either not working or your machine's network settings are incorrect.
Related
So I have a very basic script:
#region Get Hostname IP
IPAddress[] dnsRecords = Dns.GetHostAddresses(hostname);
string ipHostname = dnsRecords[0].ToString();
if (ipHostname.Length == 0) {
responseCode = imapLoginResponse.Failed;
return false;
}
#endregion
#region Try make a request to the Host, Port
try {
_Connection = new TcpClient(ipHostname, port);
} catch (SocketException ex) {
System.Diagnostics.Debug.Write("-" + hostname + "-" + ipHostname + "- " + ex.Message);
responseCode = ex.Message == "No such host is known" || ex.Message.StartsWith("No connection could be made because the target machine actively refused it") ? imapLoginResponse.BadHostname : imapLoginResponse.Failed;
return false;
}
The code above simply tries to connect to an IMAP Server.
Get imap.{domain.ext} DNS Record IP
Try connect to that IP with port 993
Voila
What's happening for either dead/bad/abandoned/parked websites is:
Get imap.{domain.ext} DNS Record IP, somehow will get one even though it doesn't exist
Try to connect to that IP with port 993
Server doesn't respond resulting in a timeout
Now what do I do? I cant turn this down to an "BadHostname" as it could just be a connection issue on the user's end or even not connected to internet.
If I were to just retry here, it will end up infinitely looping.
While yes, I could do a 5 retries == invalid thing, but that's not accurate and could still be a temporary internet issue.
My question is, why is it getting a DNS Record IP for a record that doesnt exist?
And what am I meant to do when something like this occurs?
If you need to test, try it with this: imap.celerityinc.com (no celebrityinc.com) and you can see for yourself.
Name resolution and services provided on an IP address are independent.
You get a DNS record because it does exist at some point in the DNS hierarchy with a certain lifetime.
What you can do when something like this occurs? Flush your local DNS cache. Try different DNS servers. Go back to the SOA with your own DNS query solution.
I set up a rest service with the grapevine, plus I'm having trouble accessing remotely even with the firewall turned off.
Are you only accepting connections through localhost or 127.0.0.1, when I try to access the IP of the machine or remotely gives this error
Bad Request - Invalid Hostname
HTTP Error 400. The request hostname is invalid.
using (var server = new RestServer())
{
server.Port = "9999";
server.LogToConsole().Start();
Console.ReadLine();
server.Stop();
}
Edit: Please refer to the (updated) documentation, specifically the page On Using HttpListener
The current default value is localhost. You can change the directly using the Host property:
server.Host = "*";
Use "*" to indicate that the HttpListener accepts requests sent to the port if the requested URI does not match any other prefix. Similarly, to specify that the HttpListener accepts all requests sent to a port, replace the host element with the "+" character.
So, for Grapevine 4, you could write your code as follows:
using (var server = new RestServer{Port = "9999", Host = "*"})
{
server.LogToConsole().Start();
Console.ReadLine();
server.Stop();
}
I know that I can change the computers global proxy setting, Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings, to affect IE instances created using Watin.
But is there any way to intercept requests made by the IE browsers and run them through a proxy? My goal is to run multiple instances of IE, each with its own proxy, which isn't possible with my current solution above.
WatiN IE creates multiple ProcessIDs (single instance IE creates multiple process ids). in order to overwrite proxy settings just for WatiN by using Fiddler Core we need to get all child process ids which are created by WatiN IE. Helper class can be found here PInvoke: Getting all child handles of window – Svett Ralchev class. And then we check all process ids inside the BeforeRequest event and wait for watin process id to overwrite proxy settings.
private void FiddlerApplication_BeforeRequest(Session sess)
{
//Debug.WriteLine("FiddlerApplication_BeforeRequest: " + sess.LocalProcessID.ToString());
if (WatinIEprocessHolder.ContainsKey(sess.LocalProcessID))
{
//see http://stackoverflow.com/questions/14284256/how-to-manually-set-upstream-proxy-for-fiddler-core
sess["X-OverrideGateway"] = WatinIEprocessHolder[sess.LocalProcessID];
}
}
Working Test Application can be downloaded here http://www.rentanadviser.com/downloads/WatiN-2.1.0.1196.zip
Test results with different anonymous proxy below. (ipaddress=browser.Text)
Process Ids:3852,7852,, Your IP address: 119.46.110.17, Proxy:119.46.110.17:8080
Process Ids:2508,6948,, Your IP address: 178.21.112.27, Proxy:178.21.112.27:3128
Process Ids:1348,1368,, Your IP address: 122.96.59.107, Proxy:122.96.59.107:83
Process Ids:7152,5104,, Your IP address: 136.0.16.217, Proxy:136.0.16.217:3127
Process Ids:4128,3480,, Your IP address: 198.52.199.152, Proxy:198.52.199.152:7808
Process Ids:2036,7844,, Your IP address: 122.96.59.107, Proxy:122.96.59.107:82
Sample code:
private void this_FormClosing(object sender, FormClosingEventArgs e)
{
StopFiddler();
}
private void Form1_Load(object sender, EventArgs e)
{
this.FormClosing += this_FormClosing;
ProxyHolder = new List<string>();
ProxyHolder.Add("119.46.110.17:8080");
ProxyHolder.Add("178.21.112.27:3128");
ProxyHolder.Add("122.96.59.107:83");
ProxyHolder.Add("136.0.16.217:3127");
ProxyHolder.Add("198.52.199.152:7808");
ProxyHolder.Add("122.96.59.107:82");
StartFiddler();
System.Threading.Thread.Sleep(500);
for (var i = 0; i < ProxyHolder.Count; i++)
{
WhatIsMyIpThroughProxy(ProxyHolder[i]);
Application.DoEvents();
System.Threading.Thread.Sleep(500);
}
//WhatIsMyIpThroughProxy();
}
private Dictionary<int, string> WatinIEprocessHolder = new Dictionary<int, string>();
private List<string> ProxyHolder = null;
public void WhatIsMyIpThroughProxy(string ProxyIPandPort)
{
using (var browser = new IE(true))// we should not navigate now. Because we need process ids.
{
WindowHandleInfo ChildHandles = new WindowHandleInfo(browser.hWnd);
foreach (var cHandle in ChildHandles.GetAllChildHandles())
{
int pid = new WatiN.Core.Native.Windows.Window(cHandle).ProcessID;
if (WatinIEprocessHolder.ContainsKey(pid) == false)
WatinIEprocessHolder.Add(pid, ProxyIPandPort);
}
System.Text.StringBuilder processIDs = new System.Text.StringBuilder();
foreach (var k in WatinIEprocessHolder.Keys)
{
processIDs.Append(k.ToString() + ",");
//Debug.WriteLine(string.Format("{0}:{1}", k, WatinIEprocessHolder[k]));
}
//we got the process ids above. Navigate now.
browser.GoTo("http://www.rentanadviser.com/en/common/tools.ashx?action=whatismyip");
browser.WaitForComplete();
WatinIEprocessHolder.Clear();
System.Net.IPAddress ip;
if (System.Net.IPAddress.TryParse(browser.Text, out ip))
{
Debug.WriteLine(string.Format("Process Ids:{0}, Your IP address: {1}, Proxy:{2}", processIDs.ToString(), browser.Text, ProxyIPandPort));
}
else
{
Debug.WriteLine(string.Format("Process Ids:{0}, Your IP address: {1}, Proxy:{2}", processIDs.ToString(), "Failed", ProxyIPandPort));
}
}
}
private void StartFiddler()
{
FiddlerApplication.BeforeRequest += FiddlerApplication_BeforeRequest;
FiddlerApplication.Startup(8888, true, true, true);
}
private void StopFiddler()
{
FiddlerApplication.BeforeRequest -= FiddlerApplication_BeforeRequest;
if (FiddlerApplication.IsStarted())
{
FiddlerApplication.Shutdown();
}
}
private void FiddlerApplication_BeforeRequest(Session sess)
{
//Debug.WriteLine("FiddlerApplication_BeforeRequest: " + sess.LocalProcessID.ToString());
if (WatinIEprocessHolder.ContainsKey(sess.LocalProcessID))
{
//see http://stackoverflow.com/questions/14284256/how-to-manually-set-upstream-proxy-for-fiddler-core
sess["X-OverrideGateway"] = WatinIEprocessHolder[sess.LocalProcessID];
}
}
I've created an app called Process Proxifier which uses FiddlerCore to add proxy settings to the Windows applications dynamically. You can find its full source code here: https://processproxifier.codeplex.com/
Also I should mention that this solution is limited to target processes with system's default "CERN" proxy setting (which is pointed at Fiddler/FiddlerCore).
It's not possible to do that with IE or even with WebBrowser (it's just an instance of IE).
But you can manipute WebBrowser behavior to achieve your desired feature.
It's possible to write your custom WebBrowser which fetched data by sending your custom WebRequest that contain your different proxy.
How to load web browser with web response
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("http://example.com");
webRequest.Proxy = new WebProxy(host, port);
HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse();
Stream receiveStream = response.GetResponseStream();
WebBrowser webBrowser = new WebBrowser();
webBrowser.DocumentStream = receiveStream;
WebRequest.Proxy
I know you are looking for an alternative solution without using the computers global proxy setting but I thought of adding this here so others who don't have this constraint know about it.
The solution was on your question - The Windows Registry.
It is simple to change the proxy settings globally at runtime, you need to change the registry keys you are interested in using the Microsoft.Win32.Registry class in the Microsoft.Win32 namespace.
You can find MSDN documentation for this here: http://msdn.microsoft.com/en-us/library/microsoft.win32.registry(v=vs.110).aspx
See below an example of how to do this.
RegistryKey myKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Your key", true);
myKey.SetValue("My String Value", "Test Value", RegistryValueKind.String);
Now to change proxy settings on the box you need to change or create the right proxy registry keys you can find all the available keys at:
MSDN Documentation - 2.2.1.10 Internet Settings.
Below is a few of the keys you need to set. Each version of IE has their own keys but the ones below are identical to all browsers.
UseProxyServer
REG_DWORD
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyEnable
ProxyServerAndPort
REG_DWORD
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyServer
ProxyOverride
REG_SZ
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyOverride
HTTP1_1ThroughProxy
REG_DWORD
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\HTTP1_1ThroughProxy
User Specific
Please bear in mind these are Current user registry entries so you may need to set them in the context of the windows identity. Also the simplest way to see what should be the values for these keys is to apply the proxy changes on the Internet Settings dialog and check them on RegEdit.exe.
Create user automatically
This is your saving grace here because you can run your process for watin on a local windows account with the settings that way you dont need to change your own proxy settings.
You can then have one user called WatinUser that the proxy settings are set against you can automate the creation of this user using the System.DirectoryServices.AccountManagement Namespace classses.
See examples here at SO: create local user account
There are products like Proxifier that let you setup rules to route traffic to different proxies based on application names, IP addresses, hostnames and port numbers. This would not let you use different proxies for multiple IE processes, but if those processes were accessing different URLs you could route the traffic through separate proxy servers. Proxifier works using the WinSocks stack, similar to what many antivirus use, and it is transparent to the application layer.
Another suggestion is to write your own web request interceptor/proxy server that will grab proxy server info from requested url and forward normalized url to the real proxy server.
for e.g. from watin you launch url "someurl?ProxyServer=10.10.10.12" now this will be intercepted by your own proxy server and it will use the proxy server param to redirect requested url i.e. "someurl" to 10.10.10.12 your proxy server implementation can set proxy details at run time and fetch the results from your server using dynamic proxy.
I hope it makes some sense.
I am able to ping smtp.mail.yahoo.com from my system but when i send email from following code using yahoo address it gives error transport failed to connect to server.
The same code successfully sends the email from gmail account.
I am using port 465 for yahoo.
MailMessage oMsg = new MailMessage();
oMsg.From = from.Text;
oMsg.To = to.Text;
oMsg.Subject = "Hi";
oMsg.BodyFormat = MailFormat.Html;
oMsg.Body = msg.Text;
oMsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpserverport", port);
oMsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpserver", host);
oMsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusing", 2);
WebProxy proxy = WebProxy.GetDefaultProxy();
if (proxy.Address != null)
{
oMsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/urlproxyserver", proxy.Address.Host);
oMsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/proxyserverport", proxy.Address.Port);
}
oMsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpusessl", true);
oMsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", "1");
oMsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusername",from.Text);
oMsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendpassword", pass.Text);
// ADD AN ATTACHMENT.
/* MailAttachment oAttch = new MailAttachment(path+ "\\Image.bmp", MailEncoding.Base64);
oMsg.Attachments.Add(oAttch);*/
SmtpMail.SmtpServer.Insert(0,host);
if (proxy.Address != null)
MessageBox.Show("Sending via proxy settings: " + proxy.Address.ToString());
try
{
SmtpMail.Send(oMsg);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
oMsg = null;
Any ideas why this error occurs?
Being able (or not) to ping a host does not say anything about whether you will be able to connect to a particular service on it. For that, you need to try to actually establish a connection. (And of course, the fact that you can establish a connection does not necessarily imply that the service in question is working properly.)
Usually, it's a good idea to use telnet to try connecting to the remote host on the port in question. The syntax on the command line is simply telnet host.fqdn.example.com portnumber. This will tell you if there is anything at all at the other end of the pipe responding to connection attempts, which is a first step in determining where the problem is.
Second, it's usually a good idea to trim the code to the minimal version that exhibits the problematic behavior, and include the full code to show the problematic behavior. You are using a number of variables in your code which we really know nothing about.
Some ISPs block outgoing connections to the SMTP ports on hosts other than their own mail servers, to reduce the amount of outgoing spam. Maybe there is a typo in the value in host? Maybe you are inadvertantly using some unexpected MailMessage implementation? And so on.
That said, I would definitely first try to connect to the mail server in question manually, through a proxy if you are using one to connect using that code. If that doesn't work either, then your problem at least has nothing to do with the code in the question, and you can look elsewhere (in which case one possible candidate would be ISP filters; maybe they have a list of allowed external SMTP hosts and Yahoo's isn't on it?).
how can I get the client's computer name in a web application. The user in a network.
Regards
// Already tryed this option
string IP = System.Web.HttpContext.Current.Request.UserHostAddress;
string compName = DetermineCompName(IP);
System.Net.IPHostEntry teste = System.Net.Dns.GetHostEntry(IP);
ssresult = IP + " - " + teste.HostName;
// TODO: Write implementation for action
private static string DetermineCompName(string IP)
{
IPAddress myIP = IPAddress.Parse(IP);
IPHostEntry GetIPHost = Dns.GetHostEntry(myIP);
string[] compName = GetIPHost.HostName.ToString().Split('.');
return compName[0];
}
All of that, gives me only the IP :/
You can't do this in a way that is guaranteed to work.
The closest you will be able to get is to go down the route of doing a reverse dns lookup using System.Net.Dns.GetHostEntry which is what you have already tried.
The problem is that your machine has no way of knowing the hostname of a remote web client via its IP address alone (unless it is on the same subnet, in which case you may be able to retrieve it).
You have to fall back on your DNS infrastructure being able to map the IP back into a hostname [this is what nslookup does when you type in a hostname], and plenty of places just won't bother setting up reverse IP records.
Plus, often if they do, they won't match the hostname. It is quite common to see a reverse lookup for "1.2.3.4" come back as something line "machine-1.2.3.4", instead of the actual hostname.
This problem is exacerbated further if the clients are behind any sort of Network Address Translation so that many client computers have a single IP from an external perspective. This is probably not the case for you since you state "The user in a network".
As an aside, if you go to the server and type in, at a command prompt,
nslookup <some ip>
(where is an example of one of these client machines), do you get a hostname back?
If you do, then System.Net.Dns.GetHostEntry should be able to as well, if not then it probably can't for the reasons mentioned above.
you can get the windows machine name with - System.Environment.MachineName
Assuming your clients are Windows based running IE you could use this client side code to get the names and pass them back to the server:
<script type="text/javascript">
function create()
{
var net = new ActiveXObject("wscript.network");
document.write(net.ComputerName);
}
</script>
Yeah would require you to keep requesting and caching the computers terribly inefficient, was a bad idea.
I would go with running nslookup in the background I haven't tested this code and neither is it handling errors for failures, but basically, you can do:
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo sInfo = new System.Diagnostics.ProcessStartInfo("nslookup.exe", "192.168.1.100");
string result = process.StandardOutput.ReadToEnd();
Then just parse the result value.