… | |
… | |
310 | $self->{hdl}->on_wtimeout (sub { $self->send ([]) }); |
310 | $self->{hdl}->on_wtimeout (sub { $self->send ([]) }); |
311 | } |
311 | } |
312 | |
312 | |
313 | # receive handling |
313 | # receive handling |
314 | my $src_node = $self->{node}; |
314 | my $src_node = $self->{node}; |
315 | my $rmsg; $rmsg = $self->{rmsg} = sub { |
|
|
316 | $_[0]->push_read ($r_framing => $rmsg); |
|
|
317 | |
|
|
318 | local $AnyEvent::MP::Kernel::SRCNODE = $src_node; |
|
|
319 | AnyEvent::MP::Kernel::_inject (@{ $_[1] }); |
|
|
320 | }; |
|
|
321 | $hdl->push_read ($r_framing => $rmsg); |
|
|
322 | |
|
|
323 | Scalar::Util::weaken $rmsg; |
|
|
324 | Scalar::Util::weaken $src_node; |
315 | Scalar::Util::weaken $src_node; |
|
|
316 | |
|
|
317 | if ($r_framing eq "\njsonxyz") {#d# |
|
|
318 | } else { |
|
|
319 | my $rmsg; $rmsg = $self->{rmsg} = sub { |
|
|
320 | $_[0]->push_read ($r_framing => $rmsg); |
|
|
321 | |
|
|
322 | local $AnyEvent::MP::Kernel::SRCNODE = $src_node; |
|
|
323 | AnyEvent::MP::Kernel::_inject (@{ $_[1] }); |
|
|
324 | }; |
|
|
325 | eval { |
|
|
326 | $hdl->push_read ($r_framing => $rmsg); |
|
|
327 | }; |
|
|
328 | Scalar::Util::weaken $rmsg; |
|
|
329 | return $self->error ("$r_framing: unusable remote framing") |
|
|
330 | if $@; |
|
|
331 | } |
325 | } |
332 | } |
326 | }); |
333 | }); |
327 | }); |
334 | }); |
328 | }); |
335 | }); |
329 | } |
336 | } |
… | |
… | |
635 | < ["","AnyEvent::MP::_spawn","57Cs1CggVJjzYaQp13XXg4.c","AnyEvent::MP::Global::connect",0,"anon/57Cs1CggVJjzYaQp13XXg4"] |
642 | < ["","AnyEvent::MP::_spawn","57Cs1CggVJjzYaQp13XXg4.c","AnyEvent::MP::Global::connect",0,"anon/57Cs1CggVJjzYaQp13XXg4"] |
636 | ... |
643 | ... |
637 | |
644 | |
638 | The shared secret in use was C<8ugxrtw6H5tKnfPWfaSr4HGhE8MoJXmzTT1BWq7sLutNcD0IbXprQlZjIbl7MBKoeklG3IEfY9GlJthC0pENzk>. |
645 | The shared secret in use was C<8ugxrtw6H5tKnfPWfaSr4HGhE8MoJXmzTT1BWq7sLutNcD0IbXprQlZjIbl7MBKoeklG3IEfY9GlJthC0pENzk>. |
639 | |
646 | |
|
|
647 | =head2 SIMPLE HANDSHAKE FOR NON-PERL NODES |
|
|
648 | |
|
|
649 | Implementing the full set of options for handshaking can be a daunting |
|
|
650 | task. |
|
|
651 | |
|
|
652 | If security is not so important (because you only connect locally and |
|
|
653 | control the host, a common case), and you want to interface with an AEMP |
|
|
654 | node from another programming language, then you can also implement a |
|
|
655 | simplified handshake. |
|
|
656 | |
|
|
657 | For example, in a simple implementation you could decide to simply not |
|
|
658 | check the authenticity of the other side and use cleartext authentication |
|
|
659 | yourself. The the handshake is as simple as sending three lines of text, |
|
|
660 | reading three lines of text, and then you can exchange JSON-formatted |
|
|
661 | messages: |
|
|
662 | |
|
|
663 | aemp;1;<nodename>;hmac_md6_64_256;json |
|
|
664 | <nonce> |
|
|
665 | cleartext;<hexencoded secret>;json |
|
|
666 | |
|
|
667 | The nodename should be unique within the network, preferably unique with |
|
|
668 | every connection, the <nonce> could be empty or some random data, and the |
|
|
669 | hexencoded secret would be the shared secret, in lowercase hex (e.g. if |
|
|
670 | the secret is "geheim", the hex-encoded version would be "67656865696d"). |
|
|
671 | |
|
|
672 | Note that apart from the low-level handshake and framing protocol, there |
|
|
673 | is a high-level protocol, e.g. for monitoring, building the mesh or |
|
|
674 | spawning. All these messages are sent to the node port (the empty string) |
|
|
675 | and can safely be ignored if you do not need the relevant functionality. |
|
|
676 | |
|
|
677 | =head3 USEFUL HINTS |
|
|
678 | |
|
|
679 | Since taking part in the global protocol to find port groups is |
|
|
680 | nontrivial, hardcoding port names should be considered as well, i.e. the |
|
|
681 | non-Perl node could simply listen to messages for a few well-known ports. |
|
|
682 | |
|
|
683 | Alternatively, the non-Perl node could call a (already loaded) function |
|
|
684 | in the Perl node by sending it a special message: |
|
|
685 | |
|
|
686 | ["", "Some::Function::name", "myownport", 1, 2, 3] |
|
|
687 | |
|
|
688 | This would call the function C<Some::Function::name> with the string |
|
|
689 | C<myownport> and some additional arguments. |
|
|
690 | |
640 | =head2 MONITORING |
691 | =head2 MONITORING |
641 | |
692 | |
642 | Monitoring the connection itself is transport-specific. For TCP, all |
693 | Monitoring the connection itself is transport-specific. For TCP, all |
643 | connection monitoring is currently left to TCP retransmit time-outs |
694 | connection monitoring is currently left to TCP retransmit time-outs |
644 | on a busy link, and TCP keepalive (which should be enabled) for idle |
695 | on a busy link, and TCP keepalive (which should be enabled) for idle |