ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-MP/MP/Transport.pm
Revision: 1.60
Committed: Sat Nov 7 02:36:31 2009 UTC (14 years, 7 months ago) by root
Branch: MAIN
Changes since 1.59: +13 -5 lines
Log Message:
bleh

File Contents

# User Rev Content
1 root 1.1 =head1 NAME
2    
3 root 1.13 AnyEvent::MP::Transport - actual transport protocol handler
4 root 1.1
5     =head1 SYNOPSIS
6    
7     use AnyEvent::MP::Transport;
8    
9     =head1 DESCRIPTION
10    
11 root 1.43 This module implements (and documents) the actual transport protocol for
12     AEMP.
13 root 1.1
14 root 1.7 See the "PROTOCOL" section below if you want to write another client for
15     this protocol.
16 root 1.1
17     =head1 FUNCTIONS/METHODS
18    
19     =over 4
20    
21     =cut
22    
23     package AnyEvent::MP::Transport;
24    
25     use common::sense;
26    
27 root 1.27 use Scalar::Util ();
28     use List::Util ();
29 root 1.1 use MIME::Base64 ();
30     use Storable ();
31 root 1.2 use JSON::XS ();
32 root 1.1
33 root 1.19 use Digest::MD6 ();
34     use Digest::HMAC_MD6 ();
35    
36 root 1.1 use AE ();
37     use AnyEvent::Socket ();
38 root 1.27 use AnyEvent::Handle 4.92 ();
39 root 1.2
40 root 1.30 use AnyEvent::MP::Config ();
41    
42 root 1.55 our $PROTOCOL_VERSION = 1;
43 root 1.1
44 root 1.52 our @HOOK_CONNECT; # called at connect/accept time
45     our @HOOK_GREETING; # called at greeting1 time
46     our @HOOK_CONNECTED; # called at data phase
47     our @HOOK_DESTROY; # called at destroy time
48 root 1.59 our %HOOK_PROTOCOL = (
49     "aemp-dataconn" => sub {
50     require AnyEvent::MP::DataConn;
51     &AnyEvent::MP::DataConn::_inject;
52     },
53     );
54 root 1.52
55 root 1.39 =item $listener = mp_listener $host, $port, <constructor-args>
56 root 1.1
57     Creates a listener on the given host/port using
58     C<AnyEvent::Socket::tcp_server>.
59    
60     See C<new>, below, for constructor arguments.
61    
62 root 1.10 Defaults for peerhost, peerport and fh are provided.
63 root 1.1
64     =cut
65    
66 root 1.46 sub mp_server($$;%) {
67     my ($host, $port, %arg) = @_;
68 root 1.1
69     AnyEvent::Socket::tcp_server $host, $port, sub {
70     my ($fh, $host, $port) = @_;
71    
72 root 1.39 my $tp = new AnyEvent::MP::Transport
73 root 1.1 fh => $fh,
74     peerhost => $host,
75     peerport => $port,
76 root 1.46 %arg,
77 root 1.39 ;
78     $tp->{keepalive} = $tp;
79 root 1.46 }, delete $arg{prepare}
80 root 1.1 }
81    
82 root 1.2 =item $guard = mp_connect $host, $port, <constructor-args>, $cb->($transport)
83    
84     =cut
85    
86     sub mp_connect {
87 root 1.31 my $release = pop;
88 root 1.2 my ($host, $port, @args) = @_;
89    
90 root 1.51 new AnyEvent::MP::Transport
91     connect => [$host, $port],
92 root 1.52 peerhost => $host,
93     peerport => $port,
94 root 1.51 release => $release,
95     @args,
96     ;
97 root 1.2 }
98    
99 root 1.1 =item new AnyEvent::MP::Transport
100    
101     # immediately starts negotiation
102     my $transport = new AnyEvent::MP::Transport
103 root 1.2 # mandatory
104 root 1.1 fh => $filehandle,
105 root 1.2 local_id => $identifier,
106 root 1.1 on_recv => sub { receive-callback },
107     on_error => sub { error-callback },
108    
109     # optional
110     on_eof => sub { clean-close-callback },
111     on_connect => sub { successful-connect-callback },
112 root 1.2 greeting => { key => value },
113 root 1.1
114     # tls support
115     tls_ctx => AnyEvent::TLS,
116     peername => $peername, # for verification
117     ;
118    
119     =cut
120    
121     sub new {
122     my ($class, %arg) = @_;
123    
124     my $self = bless \%arg, $class;
125    
126     {
127     Scalar::Util::weaken (my $self = $self);
128    
129 root 1.50 my $config = $AnyEvent::MP::Kernel::CONFIG;
130 root 1.30
131 root 1.50 my $timeout = $config->{monitor_timeout};
132     my $lframing = $config->{data_format};
133     my $auth_snd = $config->{auth_offer};
134     my $auth_rcv = $config->{auth_accept};
135 root 1.31
136 root 1.42 $self->{secret} = $config->{secret}
137     unless exists $self->{secret};
138 root 1.2
139 root 1.42 my $secret = $self->{secret};
140 root 1.19
141 root 1.30 if (exists $config->{cert}) {
142 root 1.42 $self->{tls_ctx} = {
143 root 1.19 sslv2 => 0,
144     sslv3 => 0,
145     tlsv1 => 1,
146     verify => 1,
147 root 1.30 cert => $config->{cert},
148     ca_cert => $config->{cert},
149 root 1.19 verify_require_client_cert => 1,
150     };
151     }
152    
153 root 1.1 $self->{hdl} = new AnyEvent::Handle
154 root 1.52 +($self->{fh} ? (fh => $self->{fh}) : (connect => $self->{connect})),
155 root 1.48 autocork => 1,
156     no_delay => 1,
157     keepalive => 1,
158     on_error => sub {
159 root 1.1 $self->error ($_[2]);
160     },
161 root 1.49 rtimeout => $timeout,
162 root 1.1 ;
163    
164 root 1.52 my $greeting_kv = $self->{local_greeting} ||= {};
165 root 1.24
166 root 1.42 $greeting_kv->{tls} = "1.0" if $self->{tls_ctx};
167 root 1.31 $greeting_kv->{provider} = "AE-$AnyEvent::MP::Kernel::VERSION";
168 root 1.7 $greeting_kv->{peeraddr} = AnyEvent::Socket::format_hostport $self->{peerhost}, $self->{peerport};
169 root 1.42 $greeting_kv->{timeout} = $self->{timeout};
170 root 1.23
171 root 1.58 my $protocol = $self->{protocol} || "aemp";
172    
173 root 1.52 # can modify greeting_kv
174 root 1.58 $_->($self) for $protocol eq "aemp" ? @HOOK_CONNECT : ();
175 root 1.52
176 root 1.1 # send greeting
177 root 1.58 my $lgreeting1 = "$protocol;$PROTOCOL_VERSION"
178 root 1.52 . ";$AnyEvent::MP::Kernel::NODE"
179 root 1.50 . ";" . (join ",", @$auth_rcv)
180     . ";" . (join ",", @$lframing)
181 root 1.7 . (join "", map ";$_=$greeting_kv->{$_}", keys %$greeting_kv);
182 root 1.12
183 root 1.31 my $lgreeting2 = MIME::Base64::encode_base64 AnyEvent::MP::Kernel::nonce (66), "";
184 root 1.1
185 root 1.7 $self->{hdl}->push_write ("$lgreeting1\012$lgreeting2\012");
186 root 1.1
187     # expect greeting
188 root 1.12 $self->{hdl}->rbuf_max (4 * 1024);
189 root 1.1 $self->{hdl}->push_read (line => sub {
190 root 1.7 my $rgreeting1 = $_[1];
191 root 1.1
192 root 1.26 my ($aemp, $version, $rnode, $auths, $framings, @kv) = split /;/, $rgreeting1;
193 root 1.1
194 root 1.53 $self->{remote_node} = $rnode;
195    
196     $self->{remote_greeting} = {
197     map /^([^=]+)(?:=(.*))?/ ? ($1 => $2) : (),
198     @kv
199     };
200    
201 root 1.60 # maybe upgrade the protocol
202     if ($protocol eq "aemp" and $aemp =~ /^aemp-\w+$/) {
203     # maybe check for existence of the protocol handler?
204     $self->{protocol} = $protocol = $aemp;
205     }
206    
207 root 1.58 $_->($self) for $protocol eq "aemp" ? @HOOK_GREETING : ();
208 root 1.54
209 root 1.60 if ($aemp ne $protocol and $aemp ne "aemp") {
210 root 1.58 return $self->error ("unparsable greeting, expected '$protocol', got '$aemp'");
211 root 1.12 } elsif ($version != $PROTOCOL_VERSION) {
212     return $self->error ("version mismatch (we: $PROTOCOL_VERSION, they: $version)");
213 root 1.60 } elsif ($protocol eq "aemp") {
214     if ($rnode eq $AnyEvent::MP::Kernel::NODE) {
215     return $self->error ("I refuse to talk to myself");
216     } elsif ($AnyEvent::MP::Kernel::NODE{$rnode} && $AnyEvent::MP::Kernel::NODE{$rnode}{transport}) {
217     return $self->error ("$rnode already connected, not connecting again.");
218     }
219 root 1.1 }
220    
221 root 1.7 # read nonce
222     $self->{hdl}->push_read (line => sub {
223     my $rgreeting2 = $_[1];
224    
225 root 1.19 "$lgreeting1\012$lgreeting2" ne "$rgreeting1\012$rgreeting2" # echo attack?
226     or return $self->error ("authentication error, echo attack?");
227    
228 root 1.41 my $tls = $self->{tls_ctx} && 1 == int $self->{remote_greeting}{tls};
229    
230     my $s_auth;
231     for my $auth_ (split /,/, $auths) {
232 root 1.50 if (grep $auth_ eq $_, @$auth_snd and ($auth_ !~ /^tls_/ or $tls)) {
233 root 1.41 $s_auth = $auth_;
234     last;
235     }
236     }
237    
238     defined $s_auth
239     or return $self->error ("$auths: no common auth type supported");
240    
241     my $s_framing;
242     for my $framing_ (split /,/, $framings) {
243 root 1.50 if (grep $framing_ eq $_, @$lframing) {
244 root 1.41 $s_framing = $framing_;
245     last;
246     }
247     }
248    
249     defined $s_framing
250     or return $self->error ("$framings: no common framing method supported");
251    
252 root 1.30 my $key;
253 root 1.19 my $lauth;
254    
255 root 1.41 if ($tls) {
256 root 1.8 $self->{tls} = $lgreeting2 lt $rgreeting2 ? "connect" : "accept";
257     $self->{hdl}->starttls ($self->{tls}, $self->{tls_ctx});
258 root 1.41
259     $lauth =
260     $s_auth eq "tls_anon" ? ""
261     : $s_auth eq "tls_md6_64_256" ? Digest::MD6::md6_hex "$lgreeting1\012$lgreeting2\012$rgreeting1\012$rgreeting2\012"
262     : return $self->error ("$s_auth: fatal, selected unsupported snd auth method");
263    
264 root 1.30 } elsif (length $secret) {
265 root 1.41 return $self->error ("$s_auth: fatal, selected unsupported snd auth method")
266     unless $s_auth eq "hmac_md6_64_256"; # hardcoded atm.
267    
268 root 1.30 $key = Digest::MD6::md6 $secret;
269 root 1.19 # we currently only support hmac_md6_64_256
270     $lauth = Digest::HMAC_MD6::hmac_md6_hex $key, "$lgreeting1\012$lgreeting2\012$rgreeting1\012$rgreeting2\012", 64, 256;
271 root 1.41
272 root 1.30 } else {
273     return $self->error ("unable to handshake TLS and no shared secret configured");
274 root 1.8 }
275 root 1.2
276 root 1.7 $self->{hdl}->push_write ("$s_auth;$lauth;$s_framing\012");
277 root 1.2
278 root 1.19 # read the authentication response
279 root 1.7 $self->{hdl}->push_read (line => sub {
280     my ($hdl, $rline) = @_;
281 root 1.2
282 root 1.7 my ($auth_method, $rauth2, $r_framing) = split /;/, $rline;
283 root 1.1
284 root 1.19 my $rauth =
285     $auth_method eq "hmac_md6_64_256" ? Digest::HMAC_MD6::hmac_md6_hex $key, "$rgreeting1\012$rgreeting2\012$lgreeting1\012$lgreeting2\012", 64, 256
286     : $auth_method eq "cleartext" ? unpack "H*", $secret
287 root 1.41 : $auth_method eq "tls_anon" ? ($tls ? "" : "\012\012") # \012\012 never matches
288     : $auth_method eq "tls_md6_64_256" ? ($tls ? Digest::MD6::md6_hex "$rgreeting1\012$rgreeting2\012$lgreeting1\012$lgreeting2\012" : "\012\012")
289     : return $self->error ("$auth_method: fatal, selected unsupported rcv auth method");
290 root 1.19
291 root 1.7 if ($rauth2 ne $rauth) {
292     return $self->error ("authentication failure/shared secret mismatch");
293     }
294 root 1.1
295 root 1.7 $self->{s_framing} = $s_framing;
296 root 1.2
297 root 1.7 $hdl->rbuf_max (undef);
298 root 1.1
299 root 1.49 # we rely on TCP retransmit timeouts and keepalives
300     $self->{hdl}->rtimeout (undef);
301    
302     $self->{remote_greeting}{untrusted} = 1
303     if $auth_method eq "tls_anon";
304 root 1.24
305 root 1.7 $self->connected;
306 root 1.1
307 root 1.58 if ($protocol eq "aemp") {
308 root 1.59 # listener-less node need to continuously probe
309     unless (@$AnyEvent::MP::Kernel::LISTENER) {
310     $self->{hdl}->wtimeout ($timeout);
311     $self->{hdl}->on_wtimeout (sub { $self->send ([]) });
312     }
313 root 1.58
314     # receive handling
315     my $src_node = $self->{node};
316     my $rmsg; $rmsg = $self->{rmsg} = sub {
317     $_[0]->push_read ($r_framing => $rmsg);
318    
319     local $AnyEvent::MP::Kernel::SRCNODE = $src_node;
320     AnyEvent::MP::Kernel::_inject (@{ $_[1] });
321     };
322     $hdl->push_read ($r_framing => $rmsg);
323 root 1.45
324 root 1.58 Scalar::Util::weaken $rmsg;
325     Scalar::Util::weaken $src_node;
326     }
327 root 1.7 });
328 root 1.1 });
329     });
330     }
331    
332     $self
333     }
334    
335     sub error {
336     my ($self, $msg) = @_;
337    
338 root 1.39 delete $self->{keepalive};
339    
340 root 1.58 if ($self->{protocol}) {
341 root 1.59 $HOOK_PROTOCOL{$self->{protocol}}->($self, $msg);
342 root 1.58 } else {
343     $AnyEvent::MP::Kernel::WARN->(9, "$self->{peerhost}:$self->{peerport} $msg");#d#
344 root 1.39
345 root 1.58 $self->{node}->transport_error (transport_error => $self->{node}{id}, $msg)
346     if $self->{node} && $self->{node}{transport} == $self;
347     }
348 root 1.31
349     (delete $self->{release})->()
350     if exists $self->{release};
351    
352 root 1.37 # $AnyEvent::MP::Kernel::WARN->(7, "$self->{peerhost}:$self->{peerport}: $msg");
353 root 1.4 $self->destroy;
354 root 1.1 }
355    
356 root 1.2 sub connected {
357     my ($self) = @_;
358    
359 root 1.39 delete $self->{keepalive};
360    
361 root 1.31 (delete $self->{release})->()
362     if exists $self->{release};
363 root 1.23
364 root 1.58 if ($self->{protocol}) {
365 root 1.59 $self->{hdl}->on_error (undef);
366     $HOOK_PROTOCOL{$self->{protocol}}->($self, undef);
367 root 1.58 } else {
368     $AnyEvent::MP::Kernel::WARN->(9, "$self->{peerhost}:$self->{peerport} connected as $self->{remote_node}");
369    
370     my $node = AnyEvent::MP::Kernel::add_node ($self->{remote_node});
371     Scalar::Util::weaken ($self->{node} = $node);
372     $node->transport_connect ($self);
373 root 1.39
374 root 1.58 $_->($self) for @HOOK_CONNECTED;
375     }
376 root 1.2 }
377    
378 root 1.1 sub send {
379 root 1.2 $_[0]{hdl}->push_write ($_[0]{s_framing} => $_[1]);
380 root 1.1 }
381    
382     sub destroy {
383     my ($self) = @_;
384    
385 root 1.42 (delete $self->{release})->()
386     if exists $self->{release};
387    
388 root 1.2 $self->{hdl}->destroy
389     if $self->{hdl};
390 root 1.52
391 root 1.59 $_->($self) for $self->{protocol} ? () : @HOOK_DESTROY;
392 root 1.1 }
393    
394     sub DESTROY {
395     my ($self) = @_;
396    
397     $self->destroy;
398     }
399    
400     =back
401    
402 root 1.7 =head1 PROTOCOL
403    
404 root 1.59 The AEMP protocol is comparatively simple, and consists of three phases
405     which are symmetrical for both sides: greeting (followed by optionally
406     switching to TLS mode), authentication and packet exchange.
407 root 1.7
408 root 1.43 The protocol is designed to allow both full-text and binary streams.
409 root 1.7
410     The greeting consists of two text lines that are ended by either an ASCII
411     CR LF pair, or a single ASCII LF (recommended).
412    
413     =head2 GREETING
414    
415 root 1.15 All the lines until after authentication must not exceed 4kb in length,
416 root 1.43 including line delimiter. Afterwards there is no limit on the packet size
417     that can be received.
418 root 1.15
419     =head3 First Greeting Line
420 root 1.12
421 root 1.16 Example:
422    
423 root 1.43 aemp;0;rain;tls_md6_64_256,hmac_md6_64_256,tls_anon,cleartext;json,storable;timeout=12;peeraddr=10.0.0.1:48082
424 root 1.16
425     The first line contains strings separated (not ended) by C<;>
426 root 1.43 characters. The first five strings are fixed by the protocol, the
427 root 1.16 remaining strings are C<KEY=VALUE> pairs. None of them may contain C<;>
428 root 1.43 characters themselves (when escaping is needed, use C<%3b> to represent
429     C<;> and C<%25> to represent C<%>)-
430 root 1.16
431 root 1.12 The fixed strings are:
432 root 1.7
433     =over 4
434    
435 root 1.18 =item protocol identification
436 root 1.7
437 root 1.43 The constant C<aemp> to identify this protocol.
438 root 1.7
439     =item protocol version
440    
441 root 1.55 The protocol version supported by this end, currently C<1>. If the
442 root 1.12 versions don't match then no communication is possible. Minor extensions
443 root 1.18 are supposed to be handled through additional key-value pairs.
444 root 1.7
445 root 1.43 =item the node ID
446 root 1.7
447 root 1.57 This is the node ID of the connecting node.
448 root 1.7
449     =item the acceptable authentication methods
450    
451     A comma-separated list of authentication methods supported by the
452     node. Note that AnyEvent::MP supports a C<hex_secret> authentication
453 root 1.43 method that accepts a clear-text password (hex-encoded), but will not use
454     this authentication method itself.
455 root 1.7
456 root 1.43 The receiving side should choose the first authentication method it
457     supports.
458 root 1.7
459     =item the acceptable framing formats
460    
461 root 1.43 A comma-separated list of packet encoding/framing formats understood. The
462 root 1.7 receiving side should choose the first framing format it supports for
463     sending packets (which might be different from the format it has to accept).
464    
465 root 1.10 =back
466 root 1.8
467     The remaining arguments are C<KEY=VALUE> pairs. The following key-value
468     pairs are known at this time:
469    
470     =over 4
471    
472     =item provider=<module-version>
473    
474     The software provider for this implementation. For AnyEvent::MP, this is
475     C<AE-0.0> or whatever version it currently is at.
476    
477     =item peeraddr=<host>:<port>
478    
479 root 1.39 The peer address (socket address of the other side) as seen locally.
480 root 1.8
481     =item tls=<major>.<minor>
482    
483     Indicates that the other side supports TLS (version should be 1.0) and
484     wishes to do a TLS handshake.
485    
486     =back
487    
488 root 1.15 =head3 Second Greeting Line
489    
490 root 1.8 After this greeting line there will be a second line containing a
491     cryptographic nonce, i.e. random data of high quality. To keep the
492     protocol text-only, these are usually 32 base64-encoded octets, but
493     it could be anything that doesn't contain any ASCII CR or ASCII LF
494     characters.
495    
496 root 1.14 I<< The two nonces B<must> be different, and an aemp implementation
497     B<must> check and fail when they are identical >>.
498    
499 root 1.43 Example of a nonce line (yes, it's random-looking because it is random
500     data):
501 root 1.8
502 root 1.43 2XYhdG7/O6epFa4wuP0ujAEx1rXYWRcOypjUYK7eF6yWAQr7gwIN9m/2+mVvBrTPXz5GJDgfGm9d8QRABAbmAP/s
503 root 1.8
504     =head2 TLS handshake
505    
506 root 1.14 I<< If, after the handshake, both sides indicate interest in TLS, then the
507 root 1.43 connection B<must> use TLS, or fail to continue. >>
508 root 1.8
509     Both sides compare their nonces, and the side who sent the lower nonce
510     value ("string" comparison on the raw octet values) becomes the client,
511     and the one with the higher nonce the server.
512    
513     =head2 AUTHENTICATION PHASE
514    
515     After the greeting is received (and the optional TLS handshake),
516     the authentication phase begins, which consists of sending a single
517     C<;>-separated line with three fixed strings and any number of
518     C<KEY=VALUE> pairs.
519    
520     The three fixed strings are:
521    
522     =over 4
523    
524     =item the authentication method chosen
525    
526     This must be one of the methods offered by the other side in the greeting.
527    
528 root 1.41 Note that all methods starting with C<tls_> are only valid I<iff> TLS was
529     successfully handshaked (and to be secure the implementation must enforce
530     this).
531    
532 root 1.13 The currently supported authentication methods are:
533    
534     =over 4
535    
536     =item cleartext
537    
538     This is simply the shared secret, lowercase-hex-encoded. This method is of
539 root 1.43 course very insecure if TLS is not used (and not completely secure even
540     if TLS is used), which is why this module will accept, but not generate,
541     cleartext auth replies.
542 root 1.13
543     =item hmac_md6_64_256
544    
545 root 1.43 This method uses an MD6 HMAC with 64 bit blocksize and 256 bit hash, and
546     requires a shared secret. It is the preferred auth method when a shared
547     secret is available.
548    
549     First, the shared secret is hashed with MD6:
550 root 1.13
551     key = MD6 (secret)
552    
553     This secret is then used to generate the "local auth reply", by taking
554     the two local greeting lines and the two remote greeting lines (without
555     line endings), appending \012 to all of them, concatenating them and
556 root 1.43 calculating the MD6 HMAC with the key:
557 root 1.13
558     lauth = HMAC_MD6 key, "lgreeting1\012lgreeting2\012rgreeting1\012rgreeting2\012"
559    
560     This authentication token is then lowercase-hex-encoded and sent to the
561     other side.
562    
563     Then the remote auth reply is generated using the same method, but local
564     and remote greeting lines swapped:
565    
566     rauth = HMAC_MD6 key, "rgreeting1\012rgreeting2\012lgreeting1\012lgreeting2\012"
567    
568     This is the token that is expected from the other side.
569    
570 root 1.41 =item tls_anon
571 root 1.19
572 root 1.43 This type is only valid I<iff> TLS was enabled and the TLS handshake
573 root 1.19 was successful. It has no authentication data, as the server/client
574     certificate was successfully verified.
575    
576 root 1.43 This authentication type is somewhat insecure, as it allows a
577     man-in-the-middle attacker to change some of the connection parameters
578     (such as the framing format), although there is no known attack that
579     exploits this in a way that is worse than just denying the service.
580 root 1.41
581 root 1.43 By default, this implementation accepts but never generates this auth
582     reply.
583 root 1.41
584     =item tls_md6_64_256
585    
586 root 1.43 This type is only valid I<iff> TLS was enabled and the TLS handshake was
587     successful.
588 root 1.41
589     This authentication type simply calculates:
590    
591     lauth = MD6 "rgreeting1\012rgreeting2\012lgreeting1\012lgreeting2\012"
592    
593     and lowercase-hex encodes the result and sends it as authentication
594     data. No shared secret is required (authentication is done by TLS). The
595 root 1.43 checksum exists only to make tinkering with the greeting hard.
596 root 1.19
597 root 1.13 =back
598    
599 root 1.8 =item the authentication data
600    
601 root 1.13 The authentication data itself, usually base64 or hex-encoded data, see
602     above.
603 root 1.8
604     =item the framing protocol chosen
605    
606     This must be one of the framing protocols offered by the other side in the
607 root 1.43 greeting. Each side must accept the choice of the other side, and generate
608     packets in the format it chose itself.
609 root 1.8
610     =back
611    
612 root 1.16 Example of an authentication reply:
613 root 1.9
614 root 1.13 hmac_md6_64_256;363d5175df38bd9eaddd3f6ca18aa1c0c4aa22f0da245ac638d048398c26b8d3;json
615 root 1.9
616 root 1.8 =head2 DATA PHASE
617    
618     After this, packets get exchanged using the chosen framing protocol. It is
619     quite possible that both sides use a different framing protocol.
620    
621 root 1.16 =head2 FULL EXAMPLE
622    
623 root 1.17 This is an actual protocol dump of a handshake, followed by a single data
624 root 1.16 packet. The greater than/less than lines indicate the direction of the
625     transfer only.
626    
627 root 1.43 > aemp;0;anon/57Cs1CggVJjzYaQp13XXg4;tls_md6_64_256,hmac_md6_64_256,tls_anon,cleartext;json,storable;provider=AE-0.8;timeout=12;peeraddr=10.0.0.17:4040
628     > yLgdG1ov/02shVkVQer3wzeuywZK+oraTdEQBmIqWHaegxSGDG4g+HqogLQbvdypFOsoDWJ1Sh4ImV4DMhvUBwTK
629    
630     < aemp;0;ruth;tls_md6_64_256,hmac_md6_64_256,tls_anon,cleartext;json,storable;provider=AE-0.8;timeout=12;peeraddr=10.0.0.1:37108
631     < +xMQXP8ElfNmuvEhsmcp+s2wCJOuQAsPxSg3d2Ewhs6gBnJz+ypVdWJ/wAVrXqlIJfLeVS/CBy4gEGkyWHSuVb1L
632    
633     > hmac_md6_64_256;5ad913855742ae5a03a5aeb7eafa4c78629de136bed6acd73eea36c9e98df44a;json
634    
635     < hmac_md6_64_256;84cd590976f794914c2ca26dac3a207a57a6798b9171289c114de07cf0c20401;json
636     < ["","AnyEvent::MP::_spawn","57Cs1CggVJjzYaQp13XXg4.c","AnyEvent::MP::Global::connect",0,"anon/57Cs1CggVJjzYaQp13XXg4"]
637     ...
638    
639     The shared secret in use was C<8ugxrtw6H5tKnfPWfaSr4HGhE8MoJXmzTT1BWq7sLutNcD0IbXprQlZjIbl7MBKoeklG3IEfY9GlJthC0pENzk>.
640 root 1.16
641 root 1.49 =head2 MONITORING
642    
643     Monitoring the connection itself is transport-specific. For TCP, all
644     connection monitoring is currently left to TCP retransmit time-outs
645     on a busy link, and TCP keepalive (which should be enabled) for idle
646     connections.
647    
648     This is not sufficient for listener-less nodes, however: they need
649     to regularly send data (30 seconds, or the monitoring interval, is
650     recommended), so TCP actively probes.
651    
652     Future implementations of AnyEvent::Transport might query the kernel TCP
653     buffer after a write timeout occurs, and if it is non-empty, shut down the
654     connections, but this is an area of future research :)
655    
656     =head2 NODE PROTOCOL
657    
658     The transport simply transfers messages, but to implement a full node, a
659     special node port must exist that understands a number of requests.
660    
661     If you are interested in implementing this, drop us a note so we finish
662     the documentation.
663    
664 root 1.1 =head1 SEE ALSO
665    
666 root 1.29 L<AnyEvent::MP>.
667 root 1.1
668     =head1 AUTHOR
669    
670     Marc Lehmann <schmorp@schmorp.de>
671     http://home.schmorp.de/
672    
673     =cut
674    
675     1
676