[nanomsg] Re: accessing control IDs

  • From: Drew Crawford <drew@xxxxxxxxxxxxxxxxxx>
  • To: nanomsg@xxxxxxxxxxxxx
  • Date: Tue, 6 May 2014 03:23:12 -0500

> There are many cases that require state full networking
> 
I’m in such a case.  The open question at this point is how to achieve it.


On May 5, 2014, at 10:52 PM, Apostolis Xekoukoulotakis <xekoukou@xxxxxxxxx> 
wrote:

> Req rep were designed by default to be stateless, that is why finding the 
> address of the message has been hidden on purpose.
> 
> There are many cases that require state full networking but state full is 
> more difficult because it requires that you implement an update mechanism on 
> the routing information.
> 
> On May 6, 2014 5:02 AM, "Drew Crawford" <drew@xxxxxxxxxxxxxxxxxx> wrote:
> I have dug a little deeper into this.  it appears that in global.c [1] 
> msg_controllen is never set.  I’m not sure if that’s expected.
> 
> The attached patch sets controllen based on the size of the chunk.  Whether 
> right or wrong, this seems to produce the behavior expected by zerotacg and 
> Achille, e.g., control bytes are emitted in the RAW case.  The 8 bytes are
> 
>> d0,4e,c0,00,c1,7f,00,00,
> 
> 
> Three of which (bytes[3],bytes[4],and bytes[5]) seem to change from 
> run-to-run.  This is mildly surprising, because the RFC documents the control 
> ID at being 32 bits, so one would expect four bytes to change from one 
> execution to the next.  I’m also unable to account for the presence of the 
> remaining bytes.  Something may be wrong with my patch, or with my 
> understanding of the codebase or RFC.
> 
> This is an interesting line of inquiry, but since a solution along this line 
> has the limitation of requiring me to implement my own end-to-end behaviors 
> on top of a raw socket, I’m wondering if it would be desirable to introduce 
> an API for this purpose
> 
>> /* Returns an integer that uniquely identifies the immediate sender of the 
>> most-recently-received message.  Returns an error if no messages have ever 
>> been received on the socket */
> 
>> int nn_sender(int socket);
> 
> Such API could work equally well for raw sockets as full sockets, could be 
> implemented for different socket topologies, and does not introduce an 
> application-layer dependency on parsing the control header format.
> 
> 
> [1] https://github.com/nanomsg/nanomsg/blob/master/src/core/global.c#L817
> 
> 
> 
> 
> On May 5, 2014, at 4:38 PM, Drew Crawford <drew@xxxxxxxxxxxxxxxxxx> wrote:
> 
>> I thought about that, however, msg_controllen still returns -1 when using 
>> raw sockets, suggesting there are no control information available, as the 
>> sample below illustrates.  Maybe something is wrong with the code sample?
>> 
>> Another problem is that use of raw sockets would require me to roll my own 
>> end-to-end behavior which may be undesirable.
>> 
>> 
>>>     int client = nn_socket(AF_SP,NN_REQ);
>>>     int server = nn_socket(AF_SP_RAW,NN_REP);
>>>     nn_connect(client,"inproc://test");
>>>     nn_bind(server,"inproc://test");
>>>     nn_send(client,"A",1,0);
>>>     
>>>     int rc;
>>>     void *body;
>>>     void *control;
>>>     struct nn_iovec iov;
>>>     struct nn_msghdr hdr;
>>> 
>>>     iov.iov_base = &body;
>>>     iov.iov_len = NN_MSG;
>>>     memset (&hdr, 0, sizeof (hdr));
>>>     hdr.msg_iov = &iov;
>>>     hdr.msg_iovlen = 1;
>>>     hdr.msg_control = &control;
>>>     hdr.msg_controllen = NN_MSG;
>>>     rc = nn_recvmsg (server, &hdr, 0);
>>>     print_array(body,rc,"body”); //contains only A
>>> 
>>>     printf("msg_iovlen %d\n",hdr.msg_iovlen); // 1
>>>     printf("msg_controllen %d\n",hdr.msg_controllen); // -1
>> 
>> 
>> On May 5, 2014, at 4:32 PM, Achille Roussel <achille.roussel@xxxxxxxxx> 
>> wrote:
>> 
>>> You have to use AF_SP_RAW sockets to get access to these info in the 
>>> control header when receiving a message with nn_recvmsg. 
>>> 
>>> On May 5, 2014, at 2:27 PM, Drew Crawford <drew@xxxxxxxxxxxxxxxxxx> wrote:
>>> 
>>>> I have a REP socket.  I’m trying to identify the channel (sender or 
>>>> forwarder) on which some message has arrived to the socket.  A 
>>>> transport-layer understanding of the sender is not required; any 
>>>> identifying value, such as an integer, is sufficient.  Consulting the 
>>>> REQREP spec  suggests that the topmost “channel ID”, one of the records in 
>>>> the “backtrace”, is the identifier I’m looking for.
>>>> 
>>>> Clearly this identifier is not exposed over the nn_recv interface.  I had 
>>>> some hopes that it would be accessible in the nn_recvmsg interface, 
>>>> possibly as control information, but it seems not to be the case:
>>>> 
>>>>>     int client = nn_socket(AF_SP,NN_REQ);
>>>>>     int server = nn_socket(AF_SP,NN_REP);
>>>>>     nn_connect(client,"inproc://test");
>>>>>     nn_bind(server,"inproc://test");
>>>>>     nn_send(client,"A",1,0);
>>>>>     
>>>>>     int rc;
>>>>>     void *body;
>>>>>     void *control;
>>>>>     struct nn_iovec iov;
>>>>>     struct nn_msghdr hdr;
>>>>> 
>>>>>     iov.iov_base = &body;
>>>>>     iov.iov_len = NN_MSG;
>>>>>     memset (&hdr, 0, sizeof (hdr));
>>>>>     hdr.msg_iov = &iov;
>>>>>     hdr.msg_iovlen = 1;
>>>>>     hdr.msg_control = &control;
>>>>>     hdr.msg_controllen = NN_MSG;
>>>>>     rc = nn_recvmsg (server, &hdr, 0);
>>>>>     print_array(body,rc,"body”); //contains only A
>>>>> 
>>>>>     printf("msg_iovlen %d\n",hdr.msg_iovlen); //1
>>>>>     printf("msg_controllen %d\n",hdr.msg_controllen); //-1
>>>> 
>>>> 
>>>> I have consulted a previous mailing thread on this topic which suggests 
>>>> channel IDs are manipulated in rep.c.  Indeed, the information I’m looking 
>>>> for seems to be moved around between nn_sockbase, nn_msg, nn_rep, and 
>>>> similar structures.  However I cannot work out a sane way to get those 
>>>> structures from application code.  
>>>> 
>>>> Any suggestions on identifying the sender of a remote message?
>>>> 
>>>> Drew
>>> 
>> 
> 
> 

Other related posts: