AnyEvent
view release on metacpan or search on metacpan
lib/AnyEvent/Handle.pm view on Meta::CPAN
BSD majorly fucked up the implementation of TCP urgent data. The result
is that almost no OS implements TCP according to the specs, and every OS
implements it slightly differently.
If you want to handle TCP urgent data, then setting this flag (the default
is enabled) gives you the most portable way of getting urgent data, by
putting it into the stream.
Since BSD emulation of OOB data on top of TCP's urgent data can have
security implications, AnyEvent::Handle sets this flag automatically
unless explicitly specified. Note that setting this flag after
establishing a connection I<may> be a bit too late (data loss could
already have occured on BSD systems), but at least it will protect you
from most attacks.
=item read_size => <bytes>
The initial read block size, the number of bytes this module will try
to read during each loop iteration. Each handle object will consume
at least this amount of memory for the read buffer as well, so when
handling many connections watch out for memory requirements). See also
C<max_read_size>. Default: C<2048>.
=item max_read_size => <bytes>
The maximum read buffer size used by the dynamic adjustment
algorithm: Each time AnyEvent::Handle can read C<read_size> bytes in
one go it will double C<read_size> up to the maximum given by this
option. Default: C<131072> or C<read_size>, whichever is higher.
=item low_water_mark => <bytes>
Sets the number of bytes (default: C<0>) that make up an "empty" write
buffer: If the buffer reaches this size or gets even samller it is
considered empty.
Sometimes it can be beneficial (for performance reasons) to add data to
the write buffer before it is fully drained, but this is a rare case, as
the operating system kernel usually buffers data as well, so the default
is good in almost all cases.
=item linger => <seconds>
If this is non-zero (default: C<3600>), the destructor of the
AnyEvent::Handle object will check whether there is still outstanding
write data and will install a watcher that will write this data to the
socket. No errors will be reported (this mostly matches how the operating
system treats outstanding data at socket close time).
This will not work for partial TLS data that could not be encoded
yet. This data will be lost. Calling the C<stoptls> method in time might
help.
=item peername => $string
A string used to identify the remote site - usually the DNS hostname
(I<not> IDN!) used to create the connection, rarely the IP address.
Apart from being useful in error messages, this string is also used in TLS
peername verification (see C<verify_peername> in L<AnyEvent::TLS>). This
verification will be skipped when C<peername> is not specified or is
C<undef>.
=item tls => "accept" | "connect" | Net::SSLeay::SSL object
When this parameter is given, it enables TLS (SSL) mode, that means
AnyEvent will start a TLS handshake as soon as the connection has been
established and will transparently encrypt/decrypt data afterwards.
All TLS protocol errors will be signalled as C<EPROTO>, with an
appropriate error message.
TLS mode requires Net::SSLeay to be installed (it will be loaded
automatically when you try to create a TLS handle): this module doesn't
have a dependency on that module, so if your module requires it, you have
to add the dependency yourself. If Net::SSLeay cannot be loaded or is too
old, you get an C<EPROTO> error.
Unlike TCP, TLS has a server and client side: for the TLS server side, use
C<accept>, and for the TLS client side of a connection, use C<connect>
mode.
You can also provide your own TLS connection object, but you have
to make sure that you call either C<Net::SSLeay::set_connect_state>
or C<Net::SSLeay::set_accept_state> on it before you pass it to
AnyEvent::Handle. Also, this module will take ownership of this connection
object.
At some future point, AnyEvent::Handle might switch to another TLS
implementation, then the option to use your own session object will go
away.
B<IMPORTANT:> since Net::SSLeay "objects" are really only integers,
passing in the wrong integer will lead to certain crash. This most often
happens when one uses a stylish C<< tls => 1 >> and is surprised about the
segmentation fault.
Use the C<< ->starttls >> method if you need to start TLS negotiation later.
=item tls_ctx => $anyevent_tls
Use the given C<AnyEvent::TLS> object to create the new TLS connection
(unless a connection object was specified directly). If this
parameter is missing (or C<undef>), then AnyEvent::Handle will use
C<AnyEvent::Handle::TLS_CTX>.
Instead of an object, you can also specify a hash reference with C<< key
=> value >> pairs. Those will be passed to L<AnyEvent::TLS> to create a
new TLS context object.
=item on_starttls => $cb->($handle, $success[, $error_message])
This callback will be invoked when the TLS/SSL handshake has finished. If
C<$success> is true, then the TLS handshake succeeded, otherwise it failed
(C<on_stoptls> will not be called in this case).
The session in C<< $handle->{tls} >> can still be examined in this
callback, even when the handshake was not successful.
TLS handshake failures will not cause C<on_error> to be invoked when this
lib/AnyEvent/Handle.pm view on Meta::CPAN
clearing the C<on_eof> callback and in the C<on_error> callback, the data
will be in C<$_[0]{rbuf}>:
$handle->on_read (sub { });
$handle->on_eof (undef);
$handle->on_error (sub {
my $data = delete $_[0]{rbuf};
});
Note that this example removes the C<rbuf> member from the handle object,
which is not normally allowed by the API. It is expressly permitted in
this case only, as the handle object needs to be destroyed afterwards.
The reason to use C<on_error> is that TCP connections, due to latencies
and packets loss, might get closed quite violently with an error, when in
fact all data has been received.
It is usually better to use acknowledgements when transferring data,
to make sure the other side hasn't just died and you got the data
intact. This is also one reason why so many internet protocols have an
explicit QUIT command.
=item I don't want to destroy the handle too early - how do I wait until
all data has been written?
After writing your last bits of data, set the C<on_drain> callback
and destroy the handle in there - with the default setting of
C<low_water_mark> this will be called precisely when all data has been
written to the socket:
$handle->push_write (...);
$handle->on_drain (sub {
AE::log debug => "All data submitted to the kernel.";
undef $handle;
});
If you just want to queue some data and then signal EOF to the other side,
consider using C<< ->push_shutdown >> instead.
=item I want to contact a TLS/SSL server, I don't care about security.
If your TLS server is a pure TLS server (e.g. HTTPS) that only speaks TLS,
connect to it and then create the AnyEvent::Handle with the C<tls>
parameter:
tcp_connect $host, $port, sub {
my ($fh) = @_;
my $handle = new AnyEvent::Handle
fh => $fh,
tls => "connect",
on_error => sub { ... };
$handle->push_write (...);
};
=item I want to contact a TLS/SSL server, I do care about security.
Then you should additionally enable certificate verification, including
peername verification, if the protocol you use supports it (see
L<AnyEvent::TLS>, C<verify_peername>).
E.g. for HTTPS:
tcp_connect $host, $port, sub {
my ($fh) = @_;
my $handle = new AnyEvent::Handle
fh => $fh,
peername => $host,
tls => "connect",
tls_ctx => { verify => 1, verify_peername => "https" },
...
Note that you must specify the hostname you connected to (or whatever
"peername" the protocol needs) as the C<peername> argument, otherwise no
peername verification will be done.
The above will use the system-dependent default set of trusted CA
certificates. If you want to check against a specific CA, add the
C<ca_file> (or C<ca_cert>) arguments to C<tls_ctx>:
tls_ctx => {
verify => 1,
verify_peername => "https",
ca_file => "my-ca-cert.pem",
},
=item I want to create a TLS/SSL server, how do I do that?
Well, you first need to get a server certificate and key. You have
three options: a) ask a CA (buy one, use cacert.org etc.) b) create a
self-signed certificate (cheap. check the search engine of your choice,
there are many tutorials on the net) or c) make your own CA (tinyca2 is a
nice program for that purpose).
Then create a file with your private key (in PEM format, see
L<AnyEvent::TLS>), followed by the certificate (also in PEM format). The
file should then look like this:
-----BEGIN RSA PRIVATE KEY-----
...header data
... lots of base64'y-stuff
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
... lots of base64'y-stuff
-----END CERTIFICATE-----
The important bits are the "PRIVATE KEY" and "CERTIFICATE" parts. Then
specify this file as C<cert_file>:
tcp_server undef, $port, sub {
my ($fh) = @_;
my $handle = new AnyEvent::Handle
fh => $fh,
tls => "accept",
tls_ctx => { cert_file => "my-server-keycert.pem" },
...
When you have intermediate CA certificates that your clients might not
know about, just append them to the C<cert_file>.
=back
=head1 SUBCLASSING AnyEvent::Handle
In many cases, you might want to subclass AnyEvent::Handle.
To make this easier, a given version of AnyEvent::Handle uses these
conventions:
=over 4
=item * all constructor arguments become object members.
At least initially, when you pass a C<tls>-argument to the constructor it
will end up in C<< $handle->{tls} >>. Those members might be changed or
mutated later on (for example C<tls> will hold the TLS connection object).
=item * other object member names are prefixed with an C<_>.
All object members not explicitly documented (internal use) are prefixed
with an underscore character, so the remaining non-C<_>-namespace is free
( run in 0.754 second using v1.01-cache-2.11-cpan-39bf76dae61 )