We have a server which we connect with .Net remoting.
The server is on two network, the client is on two network. The client and the server have only one network in common:
Using discovery, we find the IP of the server(in this case: 10.10.10.110). We create the TcpChannel
and we connect to the server.
The server receives the calls, but when it tries to send some information to the client sink. we get an exception saying that we tried to send data to an unreacheable IP(10.12.10.100).
So the server is announcing correctly his address, but how can we indicate to the client to use the network interface with a specific IP?
Some code:
Client side, Initialization:
IDictionary tcpChannelConfiguration = new Hashtable();
string instanceName = "RemotingClient" + Utils.GenerateRandomString(5);
tcpChannelConfiguration["name"] = instanceName);
tcpChannelConfiguration["port"] = 0;
tcpChannelConfiguration["machineName"] = m_interfaceToHost;//This is containing the local interface to use
tcpChannelConfiguration["bindTo"] = m_interfaceToHost;
IClientChannelSinkProvider formatClient = new BinaryClientFormatterSinkProvider(tcpChannelConfiguration, null);
IClientChannelSinkProvider identityFormatClient = new IdentityClientSinkProvider{Next = formatClient};
BinaryServerFormatterSinkProvider formatServer = new BinaryServerFormatterSinkProvider(tcpChannelConfiguration, null)
{TypeFilterLevel = TypeFilterLevel.Full};
m_channel = new TcpChannel(tcpChannelConfiguration, identityFormatClient, formatServer);
ChannelServices.RegisterChannel(m_channel, false);
//Then we get the remote object:
IServer server = (IServer)Activator.GetObject(typeof(IServer), String.Format("tcp://{0}:{1}/{2}", m_ipAddress, m_port, instanceName));
[...]
Here is the exception I'm having server side:
System.Net.Sockets.SocketException (0x80004005): A socket operation was attempted to an unreachable network 10.12.10.100:54330
Server stack trace:
at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
at System.Runtime.Remoting.Channels.RemoteConnection.CreateNewSocket(EndPoint ipEndPoint)
at System.Runtime.Remoting.Channels.RemoteConnection.CreateNewSocket()
at System.Runtime.Remoting.Channels.RemoteConnection.GetSocket()
at System.Runtime.Remoting.Channels.SocketCache.GetSocket(String machinePortAndSid, Boolean openNew)
at System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.SendRequestWithRetry(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream)
at System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.ProcessMessage(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream, ITransportHeaders& responseHeaders, Stream& responseStream)
at System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SyncProcessMessage(IMessage msg)
How can I indicate to the client which IP/interface it has to provide to the server?
Is this something we can do by giving a custom ClientSinkProvider
?
Edit
I found something that might be interessting, I noticed that for simple Query-response, the .Net Remoting is working fine, but for some of them, the query gives a object that will be used as callback by the service, and in this case, it is not working.
I just got the source code of .Net to check how this is done, but I didn't found YET the creation of the proxy for the opposite direction.
While having the source code of the TcpChannel, I see that at some point, the method, on the server side(which will establish a connection to the callback on the client) receives the request with the correct remote IP in the header, but ends by having the wrong IP in the URI: