Libzmq: Problem: ZMQ_SRCFD is broken from the beginning and takes precious space in zmq_msg structure

Created on 3 May 2016  Â·  17Comments  Â·  Source: zeromq/libzmq

the implementation from following commit only works if socket is bound and have only one connected peer.

When more than one peer the return FD is actually the FD of the last connected peer.

https://github.com/zeromq/libzmq/commit/f30fb8501ef845eae9a44c032813e5c45e189ac4

my suggest solution is remove it, to unbreak the API we can just return -1 when some try to get the SRCFD.

@sterad are you okay with us removing this? are you using it?

@hintjens do you think it is ok to remove the implementation and just return -1 and set errno to not break the API?

Area (API change) Area (RelEng) Request For Comments

Most helpful comment

@bluca of course, however return -1 from this method is actually a valid option as it the default value when msg is coming from inproc or connected tcp peer (vs accepted) so it should not break existing implementation.

[1] https://github.com/zeromq/libzmq/blob/master/src/msg.cpp#L103

All 17 comments

Given it's borken and it's always been borken I'd say it would probably be OK to change it to always return -1, but in general an API is more than just the sum of function signatures and defines. If a functionality of an API radically changes, even if no code build is broken, it's still an API change.
Just being pedantic :-)

@bluca of course, however return -1 from this method is actually a valid option as it the default value when msg is coming from inproc or connected tcp peer (vs accepted) so it should not break existing implementation.

[1] https://github.com/zeromq/libzmq/blob/master/src/msg.cpp#L103

we can mark is as deprecated, release v4.2 and then remove it.

That sounds like a reasonable proposal.

We were aware of the short-comings at the time, i.e. the filehandle might already be abandoned, worse yet, reused. But it did provide a "for the time good enough" solution to get information about the source of a message, which was a feature requested many times. Is there any other approach to get information about the message's sender now that made it into 0mq in the meantime?

yes, via the message metadata
On 4 May 2016 09:34, "Stefan Radomski" [email protected] wrote:

We were aware of the short-comings at the time, i.e. the filehandle might
already be abandoned, worse yet, reused. But it did provide a "for the time
good enough" solution to get information about the source of a message,
which was a feature requested many times. Is there any other approach to
get information about the message's sender now that made it into 0mq in the
meantime?

—
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
https://github.com/zeromq/libzmq/issues/1950#issuecomment-216766723

@sradomski the FD is not necessarily the FD of the msg originator. Just the last accepted socket.

Also it is violates don't share data between threads, as the FD is set on the socket from the IO thread and read from the user thread.

We can make it work by setting the FD on the msg at stream engine (like metadata).
@sradomski are you still using this?

Yes, I am indeed still using it in an old 3.x prebuilt library but that is not an issue - just go ahead and make the changes. I'll have a look how to get the senders ip/port from the meta-data when I am updating our dependencies eventually.

@sradomski I managed to solve the issue, it should now work accurately with following PR.
However I suggest to use metadata instead of the SRCFD, it is now include the peer address, if you need more information just add it to the metadata in stream_engine.cpp.

[1] https://github.com/zeromq/libzmq/issues/1953

@somdoron Questioning the wisdom in deprecating SRCFD -- as "peer address" (in metadata) doesn't map correctly to the "event" details provided by zmq_socket_monitor(3) .

I'm using a ROUTER socket and trying to track connections and disconnections using zmq_socket_monitor's output. I don't see how that's possible without knowing the SRCFD -- as that's what zmq_socket_monitor produces as output.

Since it's now marked as Deprecated, is there a better/different/new way to do this?

as "peer address" (in metadata) doesn't map correctly to the "event" details provided by zmq_socket_monitor(3) .

Could you please clarify what you mean by this?

@angelobonet SRCFD never really worked, so you cannot even do what you just described with it. However, when SRCFD was deprecated it was also fixed. So now it at least works.

My best suggestion for your problem is to use application keep alive to find out which socket are connected and which are not.

@bluca

  • In my ROUTER process, when I call zmq_msg_gets(&msg, "Peer-Address"); I get back an IP-address only, e.g.: 192.168.0.100. This isn't terribly helpful since I can have multiple connections from the same IP address.
  • zmq_socket_monitor() tells me if a connection was ACCEPTED or DISCONNECTED by giving me a socket descriptor number and an endpoint. The endpoint may look like this: tcp://somehost:34913.

As you can see, the IP address returned back from zmq_msg_gets() is no help in cross-referencing what I'm getting from zmq_socket_monitor(), but ZMQ_SRCFD would, since it returns back the same descriptor number I get from zmq_socket_monitor().

@somdoron By "application keep alive", I assume you mean implementing some kind of a custom heart-beating scheme between each of my connected processes?

If so, I agree that would be the most definitive method of knowing who's connected, but it's also much more work versus the zmq_msg_get(&msg, ZMQ_SRCFD) API call -- which in many cases may be good enough.

From my outsider's perspective, it seems like there is a reluctance to support the zmq_socket_monitor() call from the rest of ZeroMQ. With things like SRCFD not working (at first), and now being deprecated, I'm just confused about what is the intent of zmq_socket_monitor().

I myself not a big fan of the monitoring within zeromq. Anyway I think it should be used for logging and diagnostic.

To offer you a solution I need to understand the problem, why do you need to know who is connected? Do you need it from server side or client side?

On my protocols I always use heart-beat and pretty happy with it and it is pretty easy to configure.

On router, you can configure the router to mandatory mode and get an error if the peer is not connected, so sending a heartbeet that the client should just discard every 1 minute should give you the list of connected peers.

@somdoron I have a ROUTER server with multiple DEALERS connected to it. The ROUTER accounts for the identity of each connected DEALER and expects them to acknowledge that their message data was processed.

If one DEALER is slow, he holds up the data flow to the rest of the DEALERS until his acknowledgement arrives at the ROUTER. This is normal for some cases -- and we want this blocking to occur.

But if a DEALER disconnects ungracefully (or crashes, etc) the ROUTER will hold everything up waiting for an acknowledgement that will never arrive -- in which case, we would like to know that so we can move on.

Hi,

In general case server cannot rely on the disconnect being received. In the
event of kernel crash or power down of the client no disconnects will be
sent. Server should have some form of heartbeat to detect the faulty
clients and forcefully disconnect if the client has not done so already.
Depending on your application, a simple timeout maybe appropriate,
disconnect the clients that have not sent an acknowledgement over a period
of time.

Dead TCP connections can be detected with TCP keep alive, however this does
not take care of faulty/malicious clients that keep tcp connection alive
but never send a reply.

Heartbeat/timeout works in all cases so it is usually better just to use
that.

Max

On Tue, Mar 28, 2017 at 1:53 PM, angelobonet notifications@github.com
wrote:

@somdoron https://github.com/somdoron I have a ROUTER server with
multiple DEALERS connected to it. The ROUTER accounts for the identity of
each connected DEALER and expects them to acknowledge that their message
data was processed.

If one DEALER is slow, he holds up the data flow to the rest of the
DEALERS until his acknowledgement arrives at the ROUTER. This is normal for
some cases -- and we want this blocking to occur.

But if a DEALER disconnects ungracefully (or crashes, etc) the ROUTER
will hold everything up waiting for an acknowledgement that will never
arrive -- in which case, we would like to know that so we can move on.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/zeromq/libzmq/issues/1950#issuecomment-289901159, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AKHK5yTbgphdjO6fdwTQP3osbH9py8vPks5rqXNLgaJpZM4IWbRY
.

Was this page helpful?
0 / 5 - 0 ratings