Closed reiroldan closed 10 years ago
I took a brief look at this. It looks like the issue is that each of these binds on a different IP address:
* -> 0.0.0.0
127,0.0.1 -> 127,0.0.1
localhost -> 0.0.0.0.0.1 (IPv6)
compname -> full IPv6 address
There is a parameter that is called IPv4Only that defaults to true, however, this parameter is not used in the function TcpAddress.Resolve function. The relevant line is: ipAddress = Dns.GetHostEntry(addrStr).AddressList.FirstOrDefault();
In the host entry addresslist, the IPv6 addresses are first for my local computer. I changed this line to filter out the IPv6 if ip4only is set:: ipAddress = Dns.GetHostEntry(addrStr).AddressList.FirstOrDefault(s => !ip4Only || s.AddressFamily == AddressFamily.InterNetwork);
Then using * will properly accept all incoming connections from localhost, 127.0.0.1, compname, or the exact IP of my computer. This is a fix for when you are using IPv4 only, but according to the option documentation it should work when you choose IPv6 and accept v4 and v6 connections. I think that is a much harder thing to fix.
// If 1, indicates the use of IPv4 sockets only, it will not be
// possible to communicate with IPv6-only hosts. If 0, the socket can
// connect to and accept connections from both IPv4 and IPv6 hosts.
public bool IPv4Only { get; set; }
@reiroldan and @dnallicus can you write a small unit test with what should be the expected result? I'm working on a bug fixes branch and want to solve this...
The following unit test should succeed, because 127.0.0.1, localhost, and the
[Test]
public void BindToLocal()
{
var validAliasesForLocalHost = new[] { "127.0.0.1", "localhost", System.Net.Dns.GetHostName() };
foreach (var alias in validAliasesForLocalHost)
{
using (NetMQContext context = NetMQContext.Create())
{
using (NetMQSocket localDealer = context.CreateDealerSocket())
{
localDealer.Bind("tcp://*:5002");
using (NetMQSocket connectingDealer = context.CreateDealerSocket())
{
connectingDealer.Connect("tcp://" + alias + ":5002");
localDealer.Send("test");
Assert.AreEqual("test", connectingDealer.ReceiveString());
Console.WriteLine(alias + " connected ");
}
}
}
}
}
}
thanks @dnallicus, as you suggested ip4only is checked, you can take a look at: https://github.com/somdoron/netmq/commit/29cb8568207aeb85e237138effc2b2abbe1cf1af
will add a pull request soon
@reiroldan can you confirm it solved now?
@somdoron, It was @dnallicus who brought up the issue, I copied it over from the google groups to convert it into an issue :)
@dnallicus can you confirm?
As per dnallicus post on the mailing list:
Hi,
I am converting a project from clrzmq to NetMQ and I am running into issues with interface names in my TCP connections. In clrzmq, binding to tcp://:5000 means I can reach that socket using tcp://localhost:5000 or tcp://:5000, where is the dns host name of the computer. In NetMQ, binding to tcp:// :5000 seems to only connect to tcp://127.0.0.1:5000, which means I can't even reach it from outside the local computer. If I bind to tcp://localhost:5000, then I can only reach the socket by connecting to tcp://localhost:5000. Likewise, if I use tcp://:5000 I can only connect using tcp://:5000. From the ZMQ docs, it seems that binding to tcp://*:5000 should listen for all interfaces, so it should handle any of localhost, , or 127.0.0.1.
What is the recommended way of doing the bind and connect in NetMQ. Is it to use:5000 for both the bind and the connect?
Thanks