Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to control the source IP address of a ZeroMQ packet on a machine with multiple IPs?

The Python standard library's socket.create_connection()method has a source address option, for controlling which source IP a connection uses.

How do I do the same thing with a Python ZeroMQ socket, given a machine that has multiple addresses?

In this case, I've been using Linux's iproute2 ip addr add to create the addresses and the ZeroMQ PUB/SUB socket-archetypes.

like image 396
ceridwen Avatar asked Oct 06 '17 23:10

ceridwen


Video Answer


2 Answers

Well, ZeroMQ is a bit tricky to read as a socket-"counterparty" ( it's not )

Why?

Classical socket is a free-to-harness resource.

ZeroMQ is a rather complex hierarchy of ideas and principles of behaviours ( better - distributed behaviours ), that help design smart distributed computing systems, without touching the low-level ( ZeroMQ well abstracted ) details, that control the actual flow of events in the storms of harsh conditions all distributed computing systems are open to face ( and have to handle at low level accordingly, if the high-level abstractions "promised" by ZeroMQ to keep are to be fulfilled and ease the designers' minds to focus rather on his/her core application part, not re-designing wheels ( with all trials and errors ) on pulling strings on O/S resources and shaking systems services for collecting just a few low-hanging types of fruits ).


For these reasons better straight forget ZeroMQ to be "something-like-socket"


ZeroMQ hierarchy in less than a five seconds

1:
ZeroMQ promises an easy re-use of a few trivial Scalable Formal Communication Pattern archetypes offering a particular distributed behaviour { PUB/SUB | PUSH/PULL | PAIR/PAIR | XPUB/XSUB | ... | REQ/REP }.

2:
Except a case of exclusively using just a device-less inproc:// transport-class, in all other cases, ZeroMQ needs one or more instances of a tunable "engine" - a Context( nIOthreads = N ), N >= 1.

3:
Having this, any ( future socket ) Access Point could get instantiated, bearing a behavioural archetype since the very moment of birth:

aSubscribeCHANNEL = aLocalCONTEXT.socket( zmq.SUB )      # this is NOT a <SOCKET>
#                                 ^^^^^^__________________ even it was typed in

4:
Having an "Access Point" instance ready "inside" the local "engine", one can lock-in its materialisation in the external-reality, using one or more ( yes, more ... WOW! Meaning more incoming pulling-strings into / whistles blowing out from a single Access Point "behaviour-node" ) calls to either of these methods:
.bind( <transport-class>://<a-class-specific-address> )
or
.connect( <transport-class>://<a-class-specific-address> )

5:
If and only if a .bind()-RTO-ready Access Point A "gets visited" by a first live .connect()-RTO-ready Access Point B, having any matching behaviour pairing, the ZeroMQ-messaging/signalling archetype gets live ( naming it also a socket was probably used for historical reasons, to ease an explanation in times )

( PUB/PUB will never fit, for obvious reasons, whereas PUB/SUB and many other behaviour-archetype pairs will and do lovely match and form the mutually-"compatible"-behaviours that will finally go live and stay so )


So,
how do I do the same thing with a Python ZeroMQ socket,
given a machine that has multiple addresses?

Simply use the fully qualified specification in a call to
.bind( "{ tcp | pgm | epgm }://<ip>:<port#>" ) method and you are done.

That easy.

Cool, isn't it?

Many further pleasant surprises under the hood of performance tuning, latency shaving and security tweaking.

like image 133
user3666197 Avatar answered Sep 20 '22 13:09

user3666197


When trying to .connect() to a remote, I found the answer in the protocol documentation, put the source ip before a semicolon in the connect string:

rc = zmq_connect(socket, "tcp://192.168.1.17:5555;192.168.1.1:5555")

In Python, this looks like:

socket = zmq.Context().socket(zmq.SUB)
socket.connect('tcp://192.168.1.17:5555;192.168.1.1:5555')
like image 36
ceridwen Avatar answered Sep 18 '22 13:09

ceridwen