[nanomsg] Re: accessing control IDs

  • From: Vlad Seryakov <vseryakov@xxxxxxxxx>
  • To: nanomsg@xxxxxxxxxxxxx
  • Date: Tue, 6 May 2014 15:06:10 -0400

Hello,

I also see one more reason for getting connection info or even some simple 
handshake kind of stage:

i am experimenting with a mobile app where i'd like to use nanomsg sockets for 
persistent connections, PUB/SUB specifically to exchange small chat messages. I 
can provide all auth info in the messages but one area where this will not work 
is in the "hostile" environment anybody can create lots of connections and do 
nothing and for me it is impossible to distinguish friendly connection from not 
without exchanging some kind of additional information. A SUB socket can only 
read, nothing i can send.

I am going to try to implement handshake functionality with user provided 
callback that will provide that info, so on connect, if i need it, the client 
socket, the one who connects will send some handshake info to the server and 
the server will decide to drop it or not.

Of course nanomsg will try to reconnect but still it will give an equal chance 
to everybody to connect without filling my descriptor table.

On May 6, 2014, at 2:32 PM, Garrett D'Amore <garrett@xxxxxxxxxx> wrote:

> Nanomsg is ill suited IMO for stateful transactions beyond the minimal kinds 
> of state needed for req and rep processing.  An application that wants more 
> state should do in the application payload as you suggest. 
> 
> BUT I do see a use for being able to pass additional metadata with message 
> bodies.  I see this as being primarily useful for passing transport specific 
> details about the peer (and I only see these being passed in receive with no 
> provision for an app to send them on transmit.)
> 
> For example it might be nice to get peer unix credentials for IPC transports 
> or peer cert info when using TLS. 
> 
> I am expecting to add this capability to mangos.  I am not exactly sure what 
> the best way to do this nanomsg itself would be. 
> 
> Btw I have started the work to add the TLS over TCP transport to nanomsg 
> itself.  Stay tuned. 
> 
> Sent from my iPhone
> 
> On May 6, 2014, at 10:13 AM, Achille Roussel <achille.roussel@xxxxxxxxx> 
> wrote:
> 
>> Could you put the state information in the body of your message instead of 
>> attempting to get it from nanomsg. HTTP is also stateless but websites 
>> maintain more or less state using cookies, session ids or access tokens… 
>> maybe you can implement this at the application logic level.
>> 
>> I think it’s a sain design to have your transport protocol separated from 
>> your application logic, let’s think about cases where the client sending 
>> requests loses connection, then reconnects with a different address, or 
>> connects from multiple endpoints (mobile device, desktop computer, …), if 
>> remote endpoint information is provided by nanomsg all these endpoints will 
>> appear as different entities, whereas in your application logic they should 
>> be considered the same.
>> 
>> On May 6, 2014, at 1:23 AM, Drew Crawford <drew@xxxxxxxxxxxxxxxxxx> wrote:
>> 
>>>> 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: