1

I'm attempting to connect to a remote server using a specific local interface. My logs tell me everything is working as intended, but checking with netstat, every connection is using the default interface.

I'm using the following code to bind a TcpClient to a specific Local Endpoint

Console.WriteLine("Binding to {0}", connectionArgs.LocalBindingInterface.ToString());
client = new TcpClient(connectionArgs.LocalBindingInterface);
Console.WriteLine("Bound to {0}", client.Client.LocalEndPoint.ToString());

Where connectionArgs.LocalBindingInterface is an IPEndPoint specified as such

IPEndPoint[] localEndPoints = new IPEndPoint[2];
localEndPoints[0] = new IPEndPoint(IPAddress.Parse("192.168.0.99"), 0);
localEndPoints[1] = new IPEndPoint(IPAddress.Parse("192.168.0.100"), 0);

The IP addresses listed here are not the actual addresses.

When i check my logs, this is the info I get

Binding to 192.168.0.99:0
Bound to 192.168.0.99:59252
Binding to 192.168.0.100:0
Bound to 192.168.0.100:53527

But when i netstat -n -p --tcp -a I get

tcp        0      0 192.168.0.98:39948    remote_addr_here:443       ESTABLISHED 17857/mono
tcp        0      0 192.168.0.98:60009    remote_addr_here:443       ESTABLISHED 17857/mono

Clearly something's wrong here. None of the ports, nor the interfaces match. Netstat is run as sudo so I can't assume it's wrong. I also tried to manually create a socket, call it's bind method, and set the TcpClient's Client property to the manually bound socket, but I get the same result.

Is there something i'm doing wrong here? Is there a different way to force a Socket to use a specific Local EndPoint on mono?

I'm running this app as a non-root user, mono --version is Mono JIT compiler version 3.2.8 (Debian 3.2.8+dfsg-4ubuntu1.1), server's ubuntu version is Ubuntu 14.04.3 LTS

Edit 1:

Added an extra logging call after calling TcpClient.Connect()

Binding to 192.168.0.100:59000
Bound to 192.168.0.100:59000
After connect bound to 192.168.0.98:55484
logisticalerror
  • 391
  • 3
  • 5

1 Answers1

2

Bottom line: you can't do this, not at the socket level.

The routing of outbound traffic is determined by the network routing configuration. You would have to create an explicit routing table entry for your destination to force a specific adapter to be used.

You can bind to a specific IP address, but this only causes inbound traffic to be filtered, i.e. you'll only receive traffic sent to that IP address.


There are related questions you may want to read as well:

How to stop behaviour: C++ Socket sendto changes interface — context is C++ and not constrained to Windows, but it has what is IMHO the most direct, most relevant notes on the topic.

Using a specific network interface for a socket in windows — fairly poor question and answer both, frankly. But it does contain some quotes and links that you might find useful anyway.

Arguably, this question might have been closed as a duplicate of one of those, or perhaps even another similar question. But those two don't really answer the question in an accurate, C#/.NET-specific way, and I didn't actually find any others that seemed any better.

Community
  • 1
  • 1
Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
  • Well this isn't what I was hoping to hear. Luckily, it appears the remote server has multiple IP's so I might just use the routing table. I'll wait a day or two for (hopefully) any more responses though. – logisticalerror Feb 09 '16 at 08:43