Discussion:
[zeromq-dev] automatically choosing a free TCP port
David Robinson
2010-03-15 11:46:49 UTC
Permalink
Hi all,

I'm looking at using avahi (eg, zeroconf) with a zeromq based
application. I'd like to be able to have zeromq bind to any free port
so that I can announce the service via avahi, but afaict the string
passed to zmq_bind must have a port number. Is there any way to avoid
specifying a TCP port number and just have one automatically assigned?

Apparently you can "just create the socket and call listen() on it.
Then, the IP stack will automatically assign a free port number. Use
getsockname() to query the port number that has been chosen and use
that when registering the Avahi service." I tried using an address
string of "tcp://lo" without success (eg, zmq_bind (socket,
"tcp://lo")).

There is an example at the link below that shows how this is done with
normal sockets:

http://git.0pointer.de/?p=avahi.git;a=blob;f=docs/socket-auto-port.c;h=75dffafe75f35c0aa2143e62f16ba8aa1c2804de;hb=HEAD

-Dave
Martin Sustrik
2010-03-15 11:52:54 UTC
Permalink
Hi David,
Post by David Robinson
I'm looking at using avahi (eg, zeroconf) with a zeromq based
application. I'd like to be able to have zeromq bind to any free port
so that I can announce the service via avahi, but afaict the string
passed to zmq_bind must have a port number. Is there any way to avoid
specifying a TCP port number and just have one automatically assigned?
Apparently you can "just create the socket and call listen() on it.
Then, the IP stack will automatically assign a free port number. Use
getsockname() to query the port number that has been chosen and use
that when registering the Avahi service." I tried using an address
string of "tcp://lo" without success (eg, zmq_bind (socket,
"tcp://lo")).
No, the feature was deliberately omitted. The idea is that you can
connect even to services that are not running (connecting side tries to
reconnect automatically and queues the messages in the meantime). In
that case there's no application that could ask kernel to assign a port
number. For that reason we stick with fixed port numbers.

I am not familiar with avahi details. What's the use case and how would
you except the whole thing to work?

Thanks.
Martin
David Robinson
2010-03-15 12:23:57 UTC
Permalink
Hi Martin,
Post by Martin Sustrik
Hi David,
Post by David Robinson
I'm looking at using avahi (eg, zeroconf) with a zeromq based
application. I'd like to be able to have zeromq bind to any free port
so that I can announce the service via avahi, but afaict the string
passed to zmq_bind must have a port number. Is there any way to avoid
specifying a TCP port number and just have one automatically assigned?
Apparently you can "just create the socket and call listen() on it.
Then, the IP stack will automatically assign a free port number. Use
getsockname() to query the port number that has been chosen and use
that when registering the Avahi service."  I tried using an address
string of "tcp://lo" without success (eg, zmq_bind (socket,
"tcp://lo")).
No, the feature was deliberately omitted. The idea is that you can connect
even to services that are not running (connecting side tries to reconnect
automatically and queues the messages in the meantime). In that case there's
no application that could ask kernel to assign a port number. For that
reason we stick with fixed port numbers.
I'm not sure that I explained it very well. Automatically getting a
port would only make sense on the receive side of the connection
(obviously you can't send to a socket if you don't know what port to
send to).
Post by Martin Sustrik
I am not familiar with avahi details. What's the use case and how would you
except the whole thing to work?
The basic use-case would be to announce a service(s) to a network. eg,
you have an application that consumes something (using zmq_sub or
zmq_rep) and you don't want to have to tell all the clients how to
connect to it (eg, the IP address and port number that your zmq based
app is listening on - the address argument for zmq_bind). You can use
avahi to tell everything on the network what IP and port your
application is listening on. The publishing application(s) can then
feed your consumer because they learned the address details.

Its basically makes configuration a bit more flexible because you
don't have to care where your app runs - as long as everything that
needs to find it can find it you're happy. Avahi will make sure that
your producers can find your consumers (provided that you've hooked
them up correctly).

-Dave
Martin Sustrik
2010-03-15 12:39:39 UTC
Permalink
David,
Post by David Robinson
Post by Martin Sustrik
I am not familiar with avahi details. What's the use case and how would you
except the whole thing to work?
The basic use-case would be to announce a service(s) to a network. eg,
you have an application that consumes something (using zmq_sub or
zmq_rep) and you don't want to have to tell all the clients how to
connect to it (eg, the IP address and port number that your zmq based
app is listening on - the address argument for zmq_bind). You can use
avahi to tell everything on the network what IP and port your
application is listening on. The publishing application(s) can then
feed your consumer because they learned the address details.
Its basically makes configuration a bit more flexible because you
don't have to care where your app runs - as long as everything that
needs to find it can find it you're happy. Avahi will make sure that
your producers can find your consumers (provided that you've hooked
them up correctly).
Fair enough! We've been discussing this scenario, thinking more of DNS
as a provider of routing info...

However, even in your scenario fixed port numbers would work well. It'll
take a bit of manual setup, however, that way you'll avoid nasty
problems when service goes down, is restarted and assigned a different
port number.

Martin
Martin Lucina
2010-03-15 13:45:22 UTC
Permalink
Post by Martin Sustrik
Fair enough! We've been discussing this scenario, thinking more of DNS
as a provider of routing info...
FYI, see this thread for the proposal on locating services via DNS:

http://lists.zeromq.org/pipermail/zeromq-dev/2010-January/001807.html

-mato
Brian Granger
2010-03-15 14:35:23 UTC
Permalink
I have not used Avahi before (zeroconf for Linux), but have used
zeroconf on OS X (apple invented it). At least on OS X, it is quite
robust and used throughout Apple's products for autodiscovery. I
can't vouch for the quality of Avahi's implementation, but I think the
idea itself of using dynamic DNS in this manner is reasonably well
proven.

Cheers,

Brian
Post by Martin Lucina
Post by Martin Sustrik
Fair enough! We've been discussing this scenario, thinking more of DNS
as a provider of routing info...
http://lists.zeromq.org/pipermail/zeromq-dev/2010-January/001807.html
-mato
_______________________________________________
zeromq-dev mailing list
http://lists.zeromq.org/mailman/listinfo/zeromq-dev
--
Brian E. Granger, Ph.D.
Assistant Professor of Physics
Cal Poly State University, San Luis Obispo
***@calpoly.edu
***@gmail.com
Martin Lucina
2010-03-15 14:55:30 UTC
Permalink
Post by Brian Granger
I have not used Avahi before (zeroconf for Linux), but have used
zeroconf on OS X (apple invented it). At least on OS X, it is quite
robust and used throughout Apple's products for autodiscovery. I
can't vouch for the quality of Avahi's implementation, but I think the
idea itself of using dynamic DNS in this manner is reasonably well
proven.
<rant>
My only use of Avahi thus far has been in anger when confronted with
various Ubuntu Linux machines that have decided "the network/NIC/DHCP
server/dog has gone away" and instead of talking to the (all the while
perfectly functional) DHCP server insisted on using a 169.254.x.x IP
address until I removed all traces of anything Avahi from the system and
"ifup eth0" started working again.

So, as you can see I'm not exactly in favour of the technology :-/

Maybe in another few years when the implementations are mature enough...
but even then it all feels slightly too "automagical" for my taste.
</rant>

Cheers,

-mato
David Robinson
2010-03-15 14:36:30 UTC
Permalink
Post by Martin Lucina
Post by Martin Sustrik
Fair enough! We've been discussing this scenario, thinking more of DNS
as a provider of routing info...
http://lists.zeromq.org/pipermail/zeromq-dev/2010-January/001807.html
Interesting... fwiw the simple static file that was proposed is quite
similar to what avahi uses for static DNS-SD service data. Here's what
was proposed:

<locator>
<service name = "feed1">
<connect addr = "tcp://10.10.10.1:5555" />
<!-- for failover -->
<connect addr = "tcp://10.10.11.1:5555" />
<!-- for services binding to this name as opposed to connecting -->
<bind addr = "tcp://eth0:5555" />
</service>
</locator>

and here's what avahi has sitting in /etc/avahi/services/ssh.service on my pc:

<service-group>
<name replace-wildcards="yes">%h</name>
<service>
<type>_ssh._tcp</type>
<port>22</port>
</service>
</service-group>

iirc the 169.254. IP addresses are for multicast DNS. I suspect DNS-SD
could be used without multicast DNS and that would give at least half
a solution.

I'll see if I can find some time to investigate this further. It may
end up that avahi doesn't meet my needs wrt playing nicely in HA (like
what was mentioned before about restarting on a different port).

-Dave
Martin Lucina
2010-03-15 15:06:56 UTC
Permalink
Dave,
Post by David Robinson
I'll see if I can find some time to investigate this further. It may
end up that avahi doesn't meet my needs wrt playing nicely in HA (like
what was mentioned before about restarting on a different port).
HA should work nicely with the proposed scheme (DNS TXT records) and fixed
ports. Fire up instance one of 'service' on server1:5555, instance two of
'service' on server2:5556 and you could have two TXT records for 'service':

service IN TXT "tcp://server1:5555"
service IN TXT "tcp://server2:5556"

0MQ would get back two records from DNS and try in a round-robin fashion
until it can connect to one or the other. Straightforward to debug and not
prone to "magic failures" like I mentioned in my other email.

The only downside is you need access to your DNS zone.

-mato
Martin Sustrik
2010-03-16 10:15:07 UTC
Permalink
Post by Martin Lucina
Dave,
Post by David Robinson
I'll see if I can find some time to investigate this further. It may
end up that avahi doesn't meet my needs wrt playing nicely in HA (like
what was mentioned before about restarting on a different port).
HA should work nicely with the proposed scheme (DNS TXT records) and fixed
ports. Fire up instance one of 'service' on server1:5555, instance two of
service IN TXT "tcp://server1:5555"
service IN TXT "tcp://server2:5556"
0MQ would get back two records from DNS and try in a round-robin fashion
until it can connect to one or the other. Straightforward to debug and not
prone to "magic failures" like I mentioned in my other email.
The only downside is you need access to your DNS zone.
However, the above still requires using _fixed_ ports rather than
auto-generating port numbers.

Martin
Martin Lucina
2010-03-16 12:43:43 UTC
Permalink
Post by Martin Sustrik
Post by Martin Lucina
0MQ would get back two records from DNS and try in a round-robin fashion
until it can connect to one or the other. Straightforward to debug and not
prone to "magic failures" like I mentioned in my other email.
The only downside is you need access to your DNS zone.
However, the above still requires using _fixed_ ports rather than
auto-generating port numbers.
Sure. It's a matter of taste. The moment you want to use dynamic port
numbers you end up with a dependency on some kind of dynamic "registry" of
services, which introduces extra complexity.

Also, dynamic port numbers make it *impossible* to firewall your services
sensibly without doing some kind of stateful inspection of packet content
which doesn't work well in many cases. On the other hand, if I know that my
super-important service communicates on TCP port 12123, I can trivially
block that specific traffic on my firewall.

Personally I prefer the simpler, less magic, solutions ...

-mato

Brian Granger
2010-03-15 14:37:46 UTC
Permalink
Post by Martin Sustrik
However, even in your scenario fixed port numbers would work well. It'll
take a bit of manual setup, however, that way you'll avoid nasty
problems when service goes down, is restarted and assigned a different
port number.
Yes, this would be an issue with zeroconf and 0MQ. Because 0MQ
sockets don't error when the remote side goes away, your wouldn't know
to re-connect to a diferent port.

Cheers,

Brian
--
Brian E. Granger, Ph.D.
Assistant Professor of Physics
Cal Poly State University, San Luis Obispo
***@calpoly.edu
***@gmail.com
David Robinson
2010-03-15 12:40:35 UTC
Permalink
Post by David Robinson
The basic use-case would be to announce a service(s) to a network. eg,
you have an application that consumes something (using zmq_sub or
zmq_rep) and you don't want to have to tell all the clients how to
So, rereading this it still didn't seem clear. Clearly you will have
to tell the clients how to connect, but I don't want to have to do it
manually. I want the consumer to announce its addr details via avahi
and I want the producer to get those same details from avahi.
Post by David Robinson
connect to it (eg, the IP address and port number that your zmq based
app is listening on - the address argument for zmq_bind). You can use
avahi to tell everything on the network what IP and port your
application is listening on. The publishing application(s) can then
feed your consumer because they learned the address details.
Its basically makes configuration a bit more flexible because you
don't have to care where your app runs - as long as everything that
needs to find it can find it you're happy. Avahi will make sure that
your producers can find your consumers (provided that you've hooked
them up correctly).
fwiw, I could manually tell the consumer what port to listen on then
use avahi to tell the producer how to connect. I just don't really
want to tell the consumer what port to listen on because I couldn't
care less what port it listens on :-)

-Dave
Brian Granger
2010-03-15 14:31:17 UTC
Permalink
David,

Using avahi with 0MQ would be quite nice. The Python bindings have
the ability to bind to a random port in a range:

http://github.com/ellisonbg/pyzmq/blob/master/zmq/_zmq.pyx#L367

I would love to have Avahi integration in the Python bindings and have
worked with zeroconf a little bit before. Let me know if you want to
pursue this.

Cheers,

Brian
Post by David Robinson
Hi all,
I'm looking at using avahi (eg, zeroconf) with a zeromq based
application. I'd like to be able to have zeromq bind to any free port
so that I can announce the service via avahi, but afaict the string
passed to zmq_bind must have a port number. Is there any way to avoid
specifying a TCP port number and just have one automatically assigned?
Apparently you can "just create the socket and call listen() on it.
Then, the IP stack will automatically assign a free port number. Use
getsockname() to query the port number that has been chosen and use
that when registering the Avahi service."  I tried using an address
string of "tcp://lo" without success (eg, zmq_bind (socket,
"tcp://lo")).
There is an example at the link below that shows how this is done with
http://git.0pointer.de/?p=avahi.git;a=blob;f=docs/socket-auto-port.c;h=75dffafe75f35c0aa2143e62f16ba8aa1c2804de;hb=HEAD
-Dave
_______________________________________________
zeromq-dev mailing list
http://lists.zeromq.org/mailman/listinfo/zeromq-dev
--
Brian E. Granger, Ph.D.
Assistant Professor of Physics
Cal Poly State University, San Luis Obispo
***@calpoly.edu
***@gmail.com
David Robinson
2010-03-15 14:39:50 UTC
Permalink
Using avahi with 0MQ would be quite nice.  The Python bindings have
http://github.com/ellisonbg/pyzmq/blob/master/zmq/_zmq.pyx#L367
I would love to have Avahi integration in the Python bindings and have
worked with zeroconf a little bit before.  Let me know if you want to
pursue this.
Yep, I'll pursue it a bit more. I'll be using the Python bindings
too... and I didn't realise you'd added an option to select a random
port - that's more incentive for me to upgrade and start using the new
bindings.

-Dave
Brian Granger
2010-03-15 14:57:59 UTC
Permalink
David,
Post by David Robinson
Yep, I'll pursue it a bit more. I'll be using the Python bindings
too... and I didn't realise you'd added an option to select a random
port - that's more incentive for me to upgrade and start using the new
bindings.
Great, let me know if you have questions about the Python bindings.

Cheers,

Brian
--
Brian E. Granger, Ph.D.
Assistant Professor of Physics
Cal Poly State University, San Luis Obispo
***@calpoly.edu
***@gmail.com
Loading...