Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending HttpWebRequest through a specific network adapter

I have two wireless network adapters connected to my computer, each connected to a different network. I would like to build a kind of proxy server that my browser would connect to and it will send HTTP requests each from different adapter so loading time on webpages would be smaller. Do you guys know how can I decide from which network adapter to send the HttpWebRequest?

Thanks :)

UPDATE

I used this code:

public static IPEndPoint BindIPEndPointCallback(ServicePoint servicePoint, IPEndPoint remoteEndPoint, int retryCount)
{
    List<IPEndPoint> ipep = new List<IPEndPoint>();
    foreach (var i in System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces())
    {
        foreach (var ua in i.GetIPProperties().UnicastAddresses)
            ipep.Add(new IPEndPoint(ua.Address, 0));
    }
    return new IPEndPoint(ipep[1].Address, ipep[1].Port);
}

private void button1_Click(object sender, EventArgs e)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://whatismyip.com");
    request.ServicePoint.BindIPEndPointDelegate = new BindIPEndPoint(BindIPEndPointCallback);
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    StreamReader sr = new StreamReader(response.GetResponseStream());
    string x = sr.ReadToEnd();
}

But even if a change the IPEndPoint I send the IP I get from WhatIsMyIp is still the same.. any help?

like image 581
Ephi Avatar asked May 02 '11 18:05

Ephi


3 Answers

This example works for me:

using System;
using System.Net;

class Program
{
    public static void Main ()
    {
        foreach (var ip in Dns.GetHostAddresses (Dns.GetHostName ())) 
        {
            Console.WriteLine ("Request from: " + ip);
            var request = (HttpWebRequest)HttpWebRequest.Create ("http://ns1.vianett.no/");
            request.ServicePoint.BindIPEndPointDelegate = delegate {
                return new IPEndPoint (ip, 0);
            };
            var response = (HttpWebResponse)request.GetResponse ();
            Console.WriteLine ("Actual IP: " + response.GetResponseHeader ("X-YourIP"));
            response.Close ();
        }
    }
}
like image 89
moander Avatar answered Nov 11 '22 15:11

moander


This is because WebRequest uses ServicePointManager and it caches actual ServicePoint that is been used for single URI. So in your case BindIPEndPointDelegate called only once and all subsequent CreateRequest reuses same binded interface. Here is a little bit more lower level example with TcpClient that actually works:

        foreach (var iface in NetworkInterface.GetAllNetworkInterfaces())
        {
            if (iface.OperationalStatus == OperationalStatus.Up && iface.NetworkInterfaceType != NetworkInterfaceType.Loopback)
            {
                Console.WriteLine("Interface: {0}\t{1}\t{2}", iface.Name, iface.NetworkInterfaceType, iface.OperationalStatus);
                foreach (var ua in iface.GetIPProperties().UnicastAddresses)
                {
                    Console.WriteLine("Address: " + ua.Address);
                    try
                    {
                        using (var client = new TcpClient(new IPEndPoint(ua.Address, 0)))
                        {
                            client.Connect("ns1.vianett.no", 80);
                            var buf = Encoding.UTF8.GetBytes("GET / HTTP/1.1\r\nConnection: close\r\nHost: ns1.vianett.no\r\n\r\n");
                            client.GetStream().Write(buf, 0, buf.Length);
                            var sr = new StreamReader(client.GetStream());
                            var all = sr.ReadToEnd();
                            var match = Regex.Match(all, "(?mi)^X-YourIP: (?'a'.+)$");
                            Console.WriteLine("Your address is " + (match.Success ? match.Groups["a"].Value : all));
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }
            }
        }
like image 42
Dmitry Gusarov Avatar answered Nov 11 '22 15:11

Dmitry Gusarov


BindIPEndPointDelegate may well be what you're after here. It allows you to force a particular local IP to be the end-point via which the HttpWebRequest is sent.

like image 24
Will A Avatar answered Nov 11 '22 15:11

Will A