[zeromq-dev] Can I make a ROUTER ignore a client's ZMQ_IDENTITY?

Tom Nakamura tnakamura at eml.cc
Sat Dec 28 10:40:41 CET 2013



On Sat, Dec 28, 2013, at 12:02 AM, Pieter Hintjens wrote:
> On Sat, Dec 28, 2013 at 12:32 AM, Tom Nakamura <tnakamura at eml.cc> wrote:
> 
> If I expose
> > a ROUTER socket to unknown/untrusted clients, then the router may get
> > multiple connections with the same identity by accident or malice
> > resulting in a denial of service.  Or am I missing something in the way
> > routers work?
> 
> You can't ignore identities. However duplicate clients with the same
> ID will be treated as anonymous (their ID will be ignored) so there is
> no risk of a denial of service. You can switch off that behavior using
> ZMQ_ROUTER_HANDOVER, which lets clients "steal" connections by
> specifying an already-used ID.
> 
> -Pieter

Wait, so what am I doing wrong below? I create two detached threads
which creates a DEALER socket (same thing happens with REQ but DEALER
makes it shorter) that sends a message every second (and printf()s a
debug message, see code), and receives those messages on a ROUTER in the
main thread and calls zmsg_dump(). 

    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    #include <zmq.h>
    #include <czmq.h>
    
    // connection point does not seem to make a difference
    //#define ENDPOINT "tcp://127.0.0.1:8888"
    #define ENDPOINT "ipc://myipc.ipc"
    
    void * client_thread(void * args){
        zctx_t * context = zctx_new();
        void * client = zsocket_new (context, ZMQ_DEALER);
    
        zsocket_set_identity(client, "CUSTOMID");
        
        int rc = zsocket_connect(client, ENDPOINT); assert(rc != -1);
    
        while (! zctx_interrupted){
            // i'm just using the context address as an id to 
            // differentiate the two client's printfs
            printf("> %p sent msg\n", context);
            zstr_send(client, "SOMEMSG");
            zclock_sleep(1000);
        }
    
        zsocket_destroy(context, client);
        zctx_destroy(&context);
        return NULL;
    }
    
    int main(int argc, char * argv[]) {
        int rc;
    
        rc = zthread_new (client_thread, NULL); assert(rc == 0);
        rc = zthread_new (client_thread, NULL); assert(rc == 0);
    
        zctx_t * context = zctx_new();
        assert(context);
    
        void * server = zsocket_new (context, ZMQ_ROUTER);
        assert(server);
    
        rc = zsocket_bind(server, ENDPOINT); assert(rc != -1);
    
        while (!zctx_interrupted){
            zmsg_t * msg = zmsg_recv(server);
            if (!msg)
                break;
            zmsg_dump(msg);
        }
    
        zsocket_destroy(context, server);
        zctx_destroy(&context);
    
        return 0;
    }

By setting the client identity, I only get one reply for each time the
clients both send a message:

    > 0x7f77380008c0 sent msg
    > 0x7f77300008c0 sent msg
    --------------------------------------
    [008] CUSTOMID
    [007] SOMEMSG
    > 0x7f77380008c0 sent msg
    > 0x7f77300008c0 sent msg
    --------------------------------------
    [008] CUSTOMID
    [007] SOMEMSG
    > 0x7f77380008c0 sent msg
    > 0x7f77300008c0 sent msg
    --------------------------------------
    [008] CUSTOMID
    [007] SOMEMSG

But if I comment out the zsocket_set_identity() call, I get what one
would expect (a response to each):

    > 0x7f44e80008c0 sent msg
    > 0x7f44e00008c0 sent msg
    --------------------------------------
    [005] 006B8B4567
    [007] SOMEMSG
    --------------------------------------
    [005] 006B8B4568
    [007] SOMEMSG
    > 0x7f44e00008c0 sent msg
    > 0x7f44e80008c0 sent msg
    --------------------------------------
    [005] 006B8B4568
    [007] SOMEMSG
    --------------------------------------
    [005] 006B8B4567
    [007] SOMEMSG
    > 0x7f44e80008c0 sent msg
    > 0x7f44e00008c0 sent msg
    --------------------------------------
    [005] 006B8B4567
    [007] SOMEMSG
    --------------------------------------
    [005] 006B8B4568
    [007] SOMEMSG

I am using zeromq 4.0.3 and czmq 2.0.3 on Linux Mint 15 64 bit.
Thank you,
Tom



More information about the zeromq-dev mailing list