HttpClient.GetAsync times out when connected to VPN - c#

C# 4.5.2 framework HttpClient.GetAsync() method works fine on Windows 10 when system is not using VPN.
When VPN is connected HttpClient.GetAsync() call to the same address just blocks until it times out. Both Edge and Chrome have no issues accessing that same address.
Is there a way to see what is happening? What is HttpClient doing differently?
Update: Got some interesting clues by calling Dns.GetHostEntry(). Without VPN
this call returned only IPv4 addresses that all could be connected to. With VPN client connected Dns.GetHostEntry() returned additional IPv6 addresses at the top of the list. Connection to all IPv6 addresses timed out but all IPv4 ones still worked OK. Now is there a way to figure out without trying to connect which addresses work and which ones do not?

In my experience, this sounds like a VPN / firewall issue to me. One quick thing to toggle in windows is under you VPN adapter properties, try unchecking "Use default gateway on remote network" - I know it sounds like a long shot but have had this problem in the past...

Have to answer this myself as this problem has a simple cause but very confusing symptoms.
The root cause:
DNS reports only IPv4 addresses for the host when system is not connected to VPN. All IPv4 addresses are usable.
When VPN connection is active DNS returns IPv6 addresses in addition to IPv4. IPv4 addresses are still accessible but IPv6 are not.
The cause of such invalid network configuration is still a mystery that deserves its own separate post.
Confusing part:
Some apps work no matter what VPN connection status is.
"But web browser can connect to the same host with or without VPN." True. Browsers may use Happy eyeballs approach attempting to connect using both IPv4 and IPv6 at the same time.
"But my old app has not problems connecting." Also true. Some older and not so old apps use IPv4 protocol by default. Support for IPv6 or IPv4+IPv6 has to be explicitly implemented.
"But it works sometimes". This happens when VPN connections are not reliable. It leads to all sorts of solutions that are mere coincidences.
What exactly is happening:
HttpClient.GetAsync() uses default DNS resolution and can connect using both IPv4 and IPv6 addresses. It does not discriminate and there is no direct way to influence protocol selection. If DNS returns inaccessible address then HttpClient may use that invalid address to connect resulting in timeout.
Possible workarounds:
The best: ask IT to fix IPv6 DNS issues. DNS should not report inaccessible addresses.
Good: implement Happy eyeballs approach. Connect to both IPv6 and IPv4 host addresses using numeric IP instead of automatic resolution using host name.
OK: Always connect to IPv4 using numeric IP.
Here is the piece of code that shows how to connect to a specific IP address:
// Get DNS entries for the host.
var hostEntry = Dns.GetHostEntry(uri.Host);
// Get IPv4 address
var ip4 = hostEntry.AddressList.First(addr => addr.AddressFamily == AddressFamily.InterNetwork);
// Build URI with numeric IPv4
var uriBuilderIP4 = new UriBuilder(uri);
uriBuilderIP4.Host = ip4.ToString());
var uri4 = uriBuilder4.Uri;
// Get IPv6 address
var ip6 = hostEntry.AddressList.First(addr => addr.AddressFamily == AddressFamily.InterNetworkV6);
// Build URI with numeric IPv6
var uriBuilderIP6 = new UriBuilder(uri);
uriBuilderIP6.Host = $"[{ip6}]";
var uri6 = uriBuilder6.Uri;
For HTTPS connections numeric addresses work only with "host" header with the name of the host (not an IP address) in it. Here is the way to add it.
var client = new HttpClient();
// Add "host" header with real host name e.g. stackoverflow.com
client.DefaultRequestHeaders.Add("Host", uri.Host);

Related

DNS resolution fails on android

There is restriction on UDP response size for DNS protocol. It can only contain ~500bytes. When data exceeds the limit all the DNS servers sets flag "truncated" in response but some (google 8.8.8.8 for example) does not put any IPs in response others just put trimmed list. Utilities like nslookup and dig tries to ask DNS server by TCP to get full response but android does not. Instead it fails. The example of code that fails is bellow.
var host = "prdimg.affili.net";
var addressList = Dns.GetHostEntry(host).AddressList;
The Modernhttpclient uses gets IPs the same way so I cannot get files from prdimg.affili.net. To fix it I've implemented the temporary solution. I use GooglePublicDnsClient to resolve DNS and then change hostname to resolved ip with UriBuilder.
var builder = new UriBuilder(originalUrl);
builder.Host = ip;
But the solution has two disadvantages
it does not work for https because of certificate check
it does not work if server uses Vhosts
Can anyone propose a better solution?

How to get network ip address in internet dotted-integer format in c# winforms

I am trying to get Network IP Address as http://checkip.dyndns.org/ returns.
but i am getting this result from follwoing code.
fe80::28d3:b8e8:caab:63b3%10
i want ip address in internet dot-integer format lilke 122.168.149.143
foreach (IPAddress ipa in Dns.GetHostAddresses(Dns.GetHostName()))
{
if (ipa.AddressFamily == AddressFamily.InterNetwork)
{
textBox2.Text = ipa.ToString();
break;
}
}
You are currently filtering by IPv6 addresses when you mean to be filtering by IPv4 addresses! This is why IPAddress.ToString() is returning the IP in colon-hexadecimal notation.
To filter by IPv4 addresses you will need to filter according to AddressFamily.InterNetwork instead:
if (ipa.AddressFamily == AddressFamily.InterNetwork)
{ }
It is my understanding that you would like to obtain your public address. The code you listed will return your private (local) address!
The Windows Operating system does not care about your public IP. The Operating System simply routes out to the defined gateway and doesn't worry about the details. The only way to resolve your public IP is to query some external system. You need external help.
The most reliable way to obtain your public address is to connect to an external web server that can resolve and output your public address in plain-text. You already listed a suitable service with your question. You can even take responsibility for the service by providing the service yourself. The PHP code to achieve this is very simple.
If your router supports UPnP (or SNMP) you could query your router, although, this might not work. This might suffice for YOUR machine but some routers do not support UPnP and security conscious users may very well have disabled UPnP due to security holes. See this SO question for a managed UpNp library.
I have read that you can use tracert to an established website (one you know will be online) and the first "hop" will be to your route. I have never tried this.
The dot-integer format can be used only for IP ver. 4 addresses.
In the code sample you even explicitly select only IP ver. 6 addresses.
Use AddressFamily.InterNetwork instead of AddressFamily.InterNetworkV6 to select IPv4 address, then ToString will format it in the way you expect.

How to get my correct IP address?

I try to get my correct IP but I can't
I'm using this code:
{
IPHostEntry host;
string localIP = "?";
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
localIP = ip.ToString();
}
}
return localIP;
}
But it does not work for me!
For example my real IP is 151.246.147.86 but with this code I get 192.168.1.2.
Note: I have 4 Network adapters and in DOC with IPConfig I see this:
Network adapter: Local Area Connection 6
Media state : Media disconnected
Network adapter: Local Area Connection 4
Media state : Media disconnected
Network adapter: Local Area Connection 3
IP Address: 10.10.255.222
Network adapter: Local Area Connection
IP Address: 192.168.1.2
Now I connect to net and using with "Local Area Connection"; the public IP of my WAN connection is 151.246.147.86. I want to get this public IP (151.246.147.86), how can I do that?
Note : I don't want (and I can't, since I am using a VPN) use third party websites to get my IP
Please help!
-------EDIT :-------------
Note : I using from VPN and my VPN IP (for example) is : 176.227.197.111. But the IP of my WAN is: 151.246.147.86 and i want to get this address.
You (probably) are using a router/modem, therefore 192.168.1.2 is your "real IP". Your modem/router will be on the same (private) network, and its public interface (WAN) will have a public IP. So you need to get the IP on the public interface of your modem/router.
How to get the WAN IP of your modem depends on your mark and model; if it supports UPnP you can probably do it, or maybe if it is an enterprise class router it may also support SNMP...
You should specify your make and model.
Another way without using external sites: do a tracert to a known site (google?) the first hop will be your route.
Also, if you are on a VPN, you may be able to use the same technique. For example, if you know another host on the VPN (A server maybe?) you can ping/tracert it and discover your router from there. I don't know if in this case you will obtain what you call "a real IP" (by the way, how do you know this IP in the first place? You may be able to obtain it in the same way, programmatically).
Another solution for your VPN-based scenario: you can use Windows to help you. Windows has some kind of VPN management (RAS) which may help you; I would suggest starting from here to understand the basics, and then look for a library/SDK to help you (a quick google returned http://dotras.codeplex.com/).
What you ask is not possible unless there is some way to query your router/modem/external-most endpoint for its WAN address. The only IP address your computer knows about is its own (internal IP).
Technical note: there is nothing non-"real" about the IP address 192.168.1.2 - this is your computer's address. It is simply local to your given internal network and all but useless to anything outside.
If your router supports uPnP, you will need to query GetExternalIPAddress (starting point Is there a UPnP Library for .NET (C# or VB.NET)?). However since uPnP is considered dangerous and many security-conscious users turn it off, I would not count on it being enabled.
Querying an external service will be your most reliable bet for getting your external IP, whether it is one you write, or a third party service (see also https://superuser.com/questions/420969/services-that-just-return-your-public-ip-as-text).
There are many methods and tutorials that teach you how to find an ip address,I use this tool http://www.ipgp.net/ to display information about any ip address, just enter any IP address into the box and you will get the country, city, region, ISP, street address and the satellite location map for every query.
you're trying to get your IP address from your computer or a server? It will make a lot of difference. If you're trying to get your IP address from your computer/laptop use http://www.howtochangeipaddress.com. Your IP will pop up in front of you soon you enter the site.

C# - How to get IP Address when connected to (RAS) VPN

Good afternoon,
Can anyone give any examples of how to obtain the IP Address of the local machine when it's connected to a remote windows domain network via VPN (RAS)? i.e. I need the VPN address and not the remote users local network address.
For example, my Server Side Windows Service communicates with my client side application and needs to create a log of all connected users and their IP Addresses.
This solution is easy enough when using a computer on the local network, but I wondered how I can go about getting the IP addresses of the users who are connected to the server via VPN. Please note that the IP address get method will be executed client side and sent to the server.
Here's my current code that works only when locally connected to the domain network:
public static string GetLocalIPv4()
{
string ipv4Address = String.Empty;
foreach (IPAddress currrentIPAddress in Dns.GetHostAddresses(Dns.GetHostName()))
{
if (currrentIPAddress.AddressFamily.ToString() == System.Net.Sockets.AddressFamily.InterNetwork.ToString())
{
ipv4Address = currrentIPAddress.ToString();
break;
}
}
return ipv4Address;
}
Our internal network is controlled by Windows SBS and uses a domain such as mycompany.local.
Thank you very much for your time and I look forward to reading your responses.
Rob
As the comment from #MarcB notes, cannot think of a good reason why you might want that info... so would be interesting if you could explain a use for this in an application just out of curiosity.
However, there are a lot of incorrect answers on here and online regarding enumerating IP addresses for a machine by using Dns.GetHostAddresses. It appears most people are not realizing the difference between looking up a machine name in the configured DNS resolver versus enumerating the machine address. These are very different things and while it might seem to return the right results in many cases, this is absolutely the wrong way to go about it because they are not the same thing. For example, see this link to an article on here where the original poster flagged an incorrect response as the answer but the correct response is below by #StephanCleary. See:
Get IPv4 Addresses
The difference is you want to look at the machines configuration and enumerate whatever IP address you are interested in locating from the machines own TCPIP stack. The code above and many of the incorrect responses try to lookup the name in the DNS resolver. Once you have that part correct, then you should be able to determine the VPN connection based on the network adaptor (by name or other attribute).

IIS7 or ASP.NET is returning an odd client IP Address

In my ASP.NET application, I'm saying something like this to get the client IP address:
string ipAddress = HttpContext.Current.Request.UserHostAddress;
This is the normal, straightforward way that I've always used, and it's always seemed to work. Everybody knows that the above statement is just a wrapper for the REMOTE_ADDR server variable.
Simple enough, right? Well, in the last few days I've been noticing that on my local dev machine, it's returning this as the value:
"fe80::dde4:def3:7f1b:a582%10"
I have no earthly idea why. I'm running Vista x64 and running my app with IIS7. I do have IPv4 and IPv6 enabled, but that usually returns something like:
"1::"
I have no idea why this is happening. Rebooting solves nothing.
EDIT:
I'm using Chrome when this happens.
It looks like it's returning IPv6.
::1 is the loopback address for IPv6, which is simply the reversed byte order of 1::.
I should also note that fe80::/10 addresses in IPv6 are Autoconfiguration IP addresses (in IPv4, these are 169.254.0.0/16). If for example you are on a private LAN and cannot access a DHCP server, Windows will automatically assign your ethernet adapter an autoconfiguration IP address.
Just FYI, You should generally assign a private IP address to adapters that are not able to reach a DHCP server.
Are you using FireFox when you see this issue? That by default will use IPv6 when available. I'd recommend turning that off:
Navigate to "about:config"
Find the "network.dns.disableIPv6" entry
Set it to true
This will also speed up local development and debugging, as FF hangs sometimes for no apparent reason when IPv6 is enabled.
The other option I'd recommend is to just disable IPv6. It's not useful right now unless you're running IPv6 end-to-end, which no end user ISP's are. Just open connection properties on your connection and untick the "Internet Protocol Version 6 (TCP/IPv6)" box.

Categories

Resources