… | |
… | |
30 | |
30 | |
31 | $cv->recv; |
31 | $cv->recv; |
32 | |
32 | |
33 | =head1 DESCRIPTION |
33 | =head1 DESCRIPTION |
34 | |
34 | |
35 | This is a helper module to make it easier to do event-based I/O on |
35 | This is a helper module to make it easier to do event-based I/O |
36 | stream-based filehandles (sockets, pipes, and other stream things). |
36 | on stream-based filehandles (sockets, pipes, and other stream |
|
|
37 | things). Specifically, it doesn't work as expected on files, packet-based |
|
|
38 | sockets or similar things. |
37 | |
39 | |
38 | The L<AnyEvent::Intro> tutorial contains some well-documented |
40 | The L<AnyEvent::Intro> tutorial contains some well-documented |
39 | AnyEvent::Handle examples. |
41 | AnyEvent::Handle examples. |
40 | |
42 | |
41 | In the following, where the documentation refers to "bytes", it means |
43 | In the following, where the documentation refers to "bytes", it means |
… | |
… | |
53 | package AnyEvent::Handle; |
55 | package AnyEvent::Handle; |
54 | |
56 | |
55 | use Scalar::Util (); |
57 | use Scalar::Util (); |
56 | use List::Util (); |
58 | use List::Util (); |
57 | use Carp (); |
59 | use Carp (); |
58 | use Errno qw(EAGAIN EINTR); |
60 | use Errno qw(EAGAIN EWOULDBLOCK EINTR); |
59 | |
61 | |
60 | use AnyEvent (); BEGIN { AnyEvent::common_sense } |
62 | use AnyEvent (); BEGIN { AnyEvent::common_sense } |
61 | use AnyEvent::Util qw(WSAEWOULDBLOCK); |
63 | use AnyEvent::Util qw(WSAEWOULDBLOCK); |
62 | |
64 | |
63 | our $VERSION = $AnyEvent::VERSION; |
65 | our $VERSION = $AnyEvent::VERSION; |
… | |
… | |
91 | |
93 | |
92 | =item fh => $filehandle [C<fh> or C<connect> MANDATORY] |
94 | =item fh => $filehandle [C<fh> or C<connect> MANDATORY] |
93 | |
95 | |
94 | The filehandle this L<AnyEvent::Handle> object will operate on. |
96 | The filehandle this L<AnyEvent::Handle> object will operate on. |
95 | NOTE: The filehandle will be set to non-blocking mode (using |
97 | NOTE: The filehandle will be set to non-blocking mode (using |
96 | C<AnyEvent::Util::fh_nonblocking>) by the constructor and needs to stay in |
98 | C<AnyEvent::fh_unblock>) by the constructor and needs to stay in |
97 | that mode. |
99 | that mode. |
98 | |
100 | |
99 | =item connect => [$host, $service] [C<fh> or C<connect> MANDATORY] |
101 | =item connect => [$host, $service] [C<fh> or C<connect> MANDATORY] |
100 | |
102 | |
101 | Try to connect to the specified host and service (port), using |
103 | Try to connect to the specified host and service (port), using |
… | |
… | |
131 | |
133 | |
132 | The peer's numeric host and port (the socket peername) are passed as |
134 | The peer's numeric host and port (the socket peername) are passed as |
133 | parameters, together with a retry callback. At the time it is called the |
135 | parameters, together with a retry callback. At the time it is called the |
134 | read and write queues, EOF status, TLS status and similar properties of |
136 | read and write queues, EOF status, TLS status and similar properties of |
135 | the handle will have been reset. |
137 | the handle will have been reset. |
136 | |
|
|
137 | It is not allowed to use the read or write queues while the handle object |
|
|
138 | is connecting. |
|
|
139 | |
138 | |
140 | If, for some reason, the handle is not acceptable, calling C<$retry> will |
139 | If, for some reason, the handle is not acceptable, calling C<$retry> will |
141 | continue with the next connection target (in case of multi-homed hosts or |
140 | continue with the next connection target (in case of multi-homed hosts or |
142 | SRV records there can be multiple connection endpoints). The C<$retry> |
141 | SRV records there can be multiple connection endpoints). The C<$retry> |
143 | callback can be invoked after the connect callback returns, i.e. one can |
142 | callback can be invoked after the connect callback returns, i.e. one can |
… | |
… | |
584 | } else { |
583 | } else { |
585 | if ($self->{on_connect_error}) { |
584 | if ($self->{on_connect_error}) { |
586 | $self->{on_connect_error}($self, "$!"); |
585 | $self->{on_connect_error}($self, "$!"); |
587 | $self->destroy if $self; |
586 | $self->destroy if $self; |
588 | } else { |
587 | } else { |
589 | $self->_error ($!, 1); |
588 | $self->error ($!, 1); |
590 | } |
589 | } |
591 | } |
590 | } |
592 | }, |
591 | }, |
593 | sub { |
592 | sub { |
594 | local $self->{fh} = $_[0]; |
593 | local $self->{fh} = $_[0]; |
… | |
… | |
614 | # with AnyEvent::Handle, do them a favour. |
613 | # with AnyEvent::Handle, do them a favour. |
615 | my $type = getsockopt $self->{fh}, Socket::SOL_SOCKET (), Socket::SO_TYPE (); |
614 | my $type = getsockopt $self->{fh}, Socket::SOL_SOCKET (), Socket::SO_TYPE (); |
616 | Carp::croak "AnyEvent::Handle: only stream sockets supported, anything else will NOT work!" |
615 | Carp::croak "AnyEvent::Handle: only stream sockets supported, anything else will NOT work!" |
617 | if Socket::SOCK_STREAM () != (unpack "I", $type) && defined $type; |
616 | if Socket::SOCK_STREAM () != (unpack "I", $type) && defined $type; |
618 | |
617 | |
619 | AnyEvent::Util::fh_nonblocking $self->{fh}, 1; |
618 | AnyEvent::fh_unblock $self->{fh}; |
620 | |
619 | |
621 | $self->{_activity} = |
620 | $self->{_activity} = |
622 | $self->{_ractivity} = |
621 | $self->{_ractivity} = |
623 | $self->{_wactivity} = AE::now; |
622 | $self->{_wactivity} = AE::now; |
624 | |
623 | |
… | |
… | |
644 | if $self->{on_read} || @{ $self->{_queue} }; |
643 | if $self->{on_read} || @{ $self->{_queue} }; |
645 | |
644 | |
646 | $self->_drain_wbuf; |
645 | $self->_drain_wbuf; |
647 | } |
646 | } |
648 | |
647 | |
|
|
648 | =item $handle->error ($errno[, $fatal[, $message]]) |
|
|
649 | |
|
|
650 | Generates an error event, just like AnyEvent::Handle itself would do, i.e. |
|
|
651 | calls the C<on_error> callback. |
|
|
652 | |
|
|
653 | The only rerquired parameter is C<$errno>, which sets C<$!>. C<$fatal> |
|
|
654 | defaults to false and C<$message> defaults to the stringified version |
|
|
655 | of C<$1>. |
|
|
656 | |
|
|
657 | Example: generate C<EIO> when you read unexpected data. |
|
|
658 | |
|
|
659 | $handle->push_read (line => sub { |
|
|
660 | $_[1] eq "hello" |
|
|
661 | or return $handle->error (Errno::EIO); |
|
|
662 | }); |
|
|
663 | |
|
|
664 | =cut |
|
|
665 | |
649 | sub _error { |
666 | sub error { |
650 | my ($self, $errno, $fatal, $message) = @_; |
667 | my ($self, $errno, $fatal, $message) = @_; |
651 | |
668 | |
652 | $! = $errno; |
669 | $! = $errno; |
653 | $message ||= "$!"; |
670 | $message ||= "$!"; |
654 | |
671 | |
… | |
… | |
760 | setsockopt $_[0]{fh}, Socket::SOL_SOCKET (), Socket::SO_OOBINLINE (), int $_[1] |
777 | setsockopt $_[0]{fh}, Socket::SOL_SOCKET (), Socket::SO_OOBINLINE (), int $_[1] |
761 | if $_[0]{fh}; |
778 | if $_[0]{fh}; |
762 | }; |
779 | }; |
763 | } |
780 | } |
764 | |
781 | |
765 | =item $handle->keepalive ($boolean) |
|
|
766 | |
|
|
767 | Enables or disables the C<keepalive> setting (see constructor argument of |
|
|
768 | the same name for details). |
|
|
769 | |
|
|
770 | =cut |
|
|
771 | |
|
|
772 | sub keepalive { |
|
|
773 | $_[0]{keepalive} = $_[1]; |
|
|
774 | |
|
|
775 | eval { |
|
|
776 | local $SIG{__DIE__}; |
|
|
777 | setsockopt $_[0]{fh}, Socket::SOL_SOCKET (), Socket::SO_KEEPALIVE (), int $_[1] |
|
|
778 | if $_[0]{fh}; |
|
|
779 | }; |
|
|
780 | } |
|
|
781 | |
|
|
782 | =item $handle->on_starttls ($cb) |
782 | =item $handle->on_starttls ($cb) |
783 | |
783 | |
784 | Replace the current C<on_starttls> callback (see the C<on_starttls> constructor argument). |
784 | Replace the current C<on_starttls> callback (see the C<on_starttls> constructor argument). |
785 | |
785 | |
786 | =cut |
786 | =cut |
… | |
… | |
884 | $self->{$activity} = $NOW; |
884 | $self->{$activity} = $NOW; |
885 | |
885 | |
886 | if ($self->{$on_timeout}) { |
886 | if ($self->{$on_timeout}) { |
887 | $self->{$on_timeout}($self); |
887 | $self->{$on_timeout}($self); |
888 | } else { |
888 | } else { |
889 | $self->_error (Errno::ETIMEDOUT); |
889 | $self->error (Errno::ETIMEDOUT); |
890 | } |
890 | } |
891 | |
891 | |
892 | # callback could have changed timeout value, optimise |
892 | # callback could have changed timeout value, optimise |
893 | return unless $self->{$timeout}; |
893 | return unless $self->{$timeout}; |
894 | |
894 | |
… | |
… | |
974 | $self->{on_drain}($self) |
974 | $self->{on_drain}($self) |
975 | if $self->{low_water_mark} >= (length $self->{wbuf}) + (length $self->{_tls_wbuf}) |
975 | if $self->{low_water_mark} >= (length $self->{wbuf}) + (length $self->{_tls_wbuf}) |
976 | && $self->{on_drain}; |
976 | && $self->{on_drain}; |
977 | |
977 | |
978 | delete $self->{_ww} unless length $self->{wbuf}; |
978 | delete $self->{_ww} unless length $self->{wbuf}; |
979 | } elsif ($! != EAGAIN && $! != EINTR && $! != WSAEWOULDBLOCK) { |
979 | } elsif ($! != EAGAIN && $! != EINTR && $! != EWOULDBLOCK && $! != WSAEWOULDBLOCK) { |
980 | $self->_error ($!, 1); |
980 | $self->error ($!, 1); |
981 | } |
981 | } |
982 | }; |
982 | }; |
983 | |
983 | |
984 | # try to write data immediately |
984 | # try to write data immediately |
985 | $cb->() unless $self->{autocork}; |
985 | $cb->() unless $self->{autocork}; |
… | |
… | |
990 | |
990 | |
991 | if ( |
991 | if ( |
992 | defined $self->{wbuf_max} |
992 | defined $self->{wbuf_max} |
993 | && $self->{wbuf_max} < length $self->{wbuf} |
993 | && $self->{wbuf_max} < length $self->{wbuf} |
994 | ) { |
994 | ) { |
995 | $self->_error (Errno::ENOSPC, 1), return; |
995 | $self->error (Errno::ENOSPC, 1), return; |
996 | } |
996 | } |
997 | }; |
997 | }; |
998 | } |
998 | } |
999 | |
999 | |
1000 | our %WH; |
1000 | our %WH; |
… | |
… | |
1331 | |
1331 | |
1332 | if (my $cb = shift @{ $self->{_queue} }) { |
1332 | if (my $cb = shift @{ $self->{_queue} }) { |
1333 | unless ($cb->($self)) { |
1333 | unless ($cb->($self)) { |
1334 | # no progress can be made |
1334 | # no progress can be made |
1335 | # (not enough data and no data forthcoming) |
1335 | # (not enough data and no data forthcoming) |
1336 | $self->_error (Errno::EPIPE, 1), return |
1336 | $self->error (Errno::EPIPE, 1), return |
1337 | if $self->{_eof}; |
1337 | if $self->{_eof}; |
1338 | |
1338 | |
1339 | unshift @{ $self->{_queue} }, $cb; |
1339 | unshift @{ $self->{_queue} }, $cb; |
1340 | last; |
1340 | last; |
1341 | } |
1341 | } |
… | |
… | |
1349 | && !@{ $self->{_queue} } # and the queue is still empty |
1349 | && !@{ $self->{_queue} } # and the queue is still empty |
1350 | && $self->{on_read} # but we still have on_read |
1350 | && $self->{on_read} # but we still have on_read |
1351 | ) { |
1351 | ) { |
1352 | # no further data will arrive |
1352 | # no further data will arrive |
1353 | # so no progress can be made |
1353 | # so no progress can be made |
1354 | $self->_error (Errno::EPIPE, 1), return |
1354 | $self->error (Errno::EPIPE, 1), return |
1355 | if $self->{_eof}; |
1355 | if $self->{_eof}; |
1356 | |
1356 | |
1357 | last; # more data might arrive |
1357 | last; # more data might arrive |
1358 | } |
1358 | } |
1359 | } else { |
1359 | } else { |
… | |
… | |
1364 | } |
1364 | } |
1365 | |
1365 | |
1366 | if ($self->{_eof}) { |
1366 | if ($self->{_eof}) { |
1367 | $self->{on_eof} |
1367 | $self->{on_eof} |
1368 | ? $self->{on_eof}($self) |
1368 | ? $self->{on_eof}($self) |
1369 | : $self->_error (0, 1, "Unexpected end-of-file"); |
1369 | : $self->error (0, 1, "Unexpected end-of-file"); |
1370 | |
1370 | |
1371 | return; |
1371 | return; |
1372 | } |
1372 | } |
1373 | |
1373 | |
1374 | if ( |
1374 | if ( |
1375 | defined $self->{rbuf_max} |
1375 | defined $self->{rbuf_max} |
1376 | && $self->{rbuf_max} < length $self->{rbuf} |
1376 | && $self->{rbuf_max} < length $self->{rbuf} |
1377 | ) { |
1377 | ) { |
1378 | $self->_error (Errno::ENOSPC, 1), return; |
1378 | $self->error (Errno::ENOSPC, 1), return; |
1379 | } |
1379 | } |
1380 | |
1380 | |
1381 | # may need to restart read watcher |
1381 | # may need to restart read watcher |
1382 | unless ($self->{_rw}) { |
1382 | unless ($self->{_rw}) { |
1383 | $self->start_read |
1383 | $self->start_read |
… | |
… | |
1573 | }; |
1573 | }; |
1574 | |
1574 | |
1575 | =item regex => $accept[, $reject[, $skip], $cb->($handle, $data) |
1575 | =item regex => $accept[, $reject[, $skip], $cb->($handle, $data) |
1576 | |
1576 | |
1577 | Makes a regex match against the regex object C<$accept> and returns |
1577 | Makes a regex match against the regex object C<$accept> and returns |
1578 | everything up to and including the match. |
1578 | everything up to and including the match. All the usual regex variables |
|
|
1579 | ($1, %+ etc.) from the regex match are available in the callback. |
1579 | |
1580 | |
1580 | Example: read a single line terminated by '\n'. |
1581 | Example: read a single line terminated by '\n'. |
1581 | |
1582 | |
1582 | $handle->push_read (regex => qr<\n>, sub { ... }); |
1583 | $handle->push_read (regex => qr<\n>, sub { ... }); |
1583 | |
1584 | |
… | |
… | |
1628 | return 1; |
1629 | return 1; |
1629 | } |
1630 | } |
1630 | |
1631 | |
1631 | # reject |
1632 | # reject |
1632 | if ($reject && $$rbuf =~ $reject) { |
1633 | if ($reject && $$rbuf =~ $reject) { |
1633 | $_[0]->_error (Errno::EBADMSG); |
1634 | $_[0]->error (Errno::EBADMSG); |
1634 | } |
1635 | } |
1635 | |
1636 | |
1636 | # skip |
1637 | # skip |
1637 | if ($skip && $$rbuf =~ $skip) { |
1638 | if ($skip && $$rbuf =~ $skip) { |
1638 | $data .= substr $$rbuf, 0, $+[0], ""; |
1639 | $data .= substr $$rbuf, 0, $+[0], ""; |
… | |
… | |
1654 | my ($self, $cb) = @_; |
1655 | my ($self, $cb) = @_; |
1655 | |
1656 | |
1656 | sub { |
1657 | sub { |
1657 | unless ($_[0]{rbuf} =~ s/^(0|[1-9][0-9]*)://) { |
1658 | unless ($_[0]{rbuf} =~ s/^(0|[1-9][0-9]*)://) { |
1658 | if ($_[0]{rbuf} =~ /[^0-9]/) { |
1659 | if ($_[0]{rbuf} =~ /[^0-9]/) { |
1659 | $_[0]->_error (Errno::EBADMSG); |
1660 | $_[0]->error (Errno::EBADMSG); |
1660 | } |
1661 | } |
1661 | return; |
1662 | return; |
1662 | } |
1663 | } |
1663 | |
1664 | |
1664 | my $len = $1; |
1665 | my $len = $1; |
… | |
… | |
1667 | my $string = $_[1]; |
1668 | my $string = $_[1]; |
1668 | $_[0]->unshift_read (chunk => 1, sub { |
1669 | $_[0]->unshift_read (chunk => 1, sub { |
1669 | if ($_[1] eq ",") { |
1670 | if ($_[1] eq ",") { |
1670 | $cb->($_[0], $string); |
1671 | $cb->($_[0], $string); |
1671 | } else { |
1672 | } else { |
1672 | $_[0]->_error (Errno::EBADMSG); |
1673 | $_[0]->error (Errno::EBADMSG); |
1673 | } |
1674 | } |
1674 | }); |
1675 | }); |
1675 | }); |
1676 | }); |
1676 | |
1677 | |
1677 | 1 |
1678 | 1 |
… | |
… | |
1763 | $json->incr_skip; |
1764 | $json->incr_skip; |
1764 | |
1765 | |
1765 | $_[0]{rbuf} = $json->incr_text; |
1766 | $_[0]{rbuf} = $json->incr_text; |
1766 | $json->incr_text = ""; |
1767 | $json->incr_text = ""; |
1767 | |
1768 | |
1768 | $_[0]->_error (Errno::EBADMSG); |
1769 | $_[0]->error (Errno::EBADMSG); |
1769 | |
1770 | |
1770 | () |
1771 | () |
1771 | } else { |
1772 | } else { |
1772 | $_[0]{rbuf} = ""; |
1773 | $_[0]{rbuf} = ""; |
1773 | |
1774 | |
… | |
… | |
1811 | 1 |
1812 | 1 |
1812 | } elsif ($@) { |
1813 | } elsif ($@) { |
1813 | # error case |
1814 | # error case |
1814 | $cbor->incr_reset; |
1815 | $cbor->incr_reset; |
1815 | |
1816 | |
1816 | $_[0]->_error (Errno::EBADMSG); |
1817 | $_[0]->error (Errno::EBADMSG); |
1817 | |
1818 | |
1818 | () |
1819 | () |
1819 | } else { |
1820 | } else { |
1820 | () |
1821 | () |
1821 | } |
1822 | } |
… | |
… | |
1848 | if ($format + $len <= length $_[0]{rbuf}) { |
1849 | if ($format + $len <= length $_[0]{rbuf}) { |
1849 | my $data = substr $_[0]{rbuf}, $format, $len; |
1850 | my $data = substr $_[0]{rbuf}, $format, $len; |
1850 | substr $_[0]{rbuf}, 0, $format + $len, ""; |
1851 | substr $_[0]{rbuf}, 0, $format + $len, ""; |
1851 | |
1852 | |
1852 | eval { $cb->($_[0], Storable::thaw ($data)); 1 } |
1853 | eval { $cb->($_[0], Storable::thaw ($data)); 1 } |
1853 | or return $_[0]->_error (Errno::EBADMSG); |
1854 | or return $_[0]->error (Errno::EBADMSG); |
1854 | } else { |
1855 | } else { |
1855 | # remove prefix |
1856 | # remove prefix |
1856 | substr $_[0]{rbuf}, 0, $format, ""; |
1857 | substr $_[0]{rbuf}, 0, $format, ""; |
1857 | |
1858 | |
1858 | # read remaining chunk |
1859 | # read remaining chunk |
1859 | $_[0]->unshift_read (chunk => $len, sub { |
1860 | $_[0]->unshift_read (chunk => $len, sub { |
1860 | eval { $cb->($_[0], Storable::thaw ($_[1])); 1 } |
1861 | eval { $cb->($_[0], Storable::thaw ($_[1])); 1 } |
1861 | or $_[0]->_error (Errno::EBADMSG); |
1862 | or $_[0]->error (Errno::EBADMSG); |
1862 | }); |
1863 | }); |
1863 | } |
1864 | } |
1864 | |
1865 | |
1865 | 1 |
1866 | 1 |
1866 | } |
1867 | } |
… | |
… | |
1873 | is handled, up to the fictituous protocol 4.x (but both SSL3+ and |
1874 | is handled, up to the fictituous protocol 4.x (but both SSL3+ and |
1874 | SSL2-compatible framing is supported). |
1875 | SSL2-compatible framing is supported). |
1875 | |
1876 | |
1876 | If it detects that the input data is likely TLS, it calls the callback |
1877 | If it detects that the input data is likely TLS, it calls the callback |
1877 | with a true value for C<$detect> and the (on-wire) TLS version as second |
1878 | with a true value for C<$detect> and the (on-wire) TLS version as second |
1878 | and third argument (C<$major> is C<3>, and C<$minor> is 0..3 for SSL |
1879 | and third argument (C<$major> is C<3>, and C<$minor> is 0..4 for SSL |
1879 | 3.0, TLS 1.0, 1.1 and 1.2, respectively). If it detects the input to |
1880 | 3.0, TLS 1.0, 1.1, 1.2 and 1.3, respectively). If it detects the input |
1880 | be definitely not TLS, it calls the callback with a false value for |
1881 | to be definitely not TLS, it calls the callback with a false value for |
1881 | C<$detect>. |
1882 | C<$detect>. |
1882 | |
1883 | |
1883 | The callback could use this information to decide whether or not to start |
1884 | The callback could use this information to decide whether or not to start |
1884 | TLS negotiation. |
1885 | TLS negotiation. |
1885 | |
1886 | |
… | |
… | |
1895 | accomodate protocol changes. |
1896 | accomodate protocol changes. |
1896 | |
1897 | |
1897 | This read type does not rely on L<AnyEvent::TLS> (and thus, not on |
1898 | This read type does not rely on L<AnyEvent::TLS> (and thus, not on |
1898 | L<Net::SSLeay>). |
1899 | L<Net::SSLeay>). |
1899 | |
1900 | |
1900 | =item tls_autostart => $tls[, $tls_ctx] |
1901 | =item tls_autostart => [$tls_ctx, ]$tls |
1901 | |
1902 | |
1902 | Tries to detect a valid SSL or TLS handshake. If one is detected, it tries |
1903 | Tries to detect a valid SSL or TLS handshake. If one is detected, it tries |
1903 | to start tls by calling C<starttls> with the given arguments. |
1904 | to start tls by calling C<starttls> with the given arguments. |
1904 | |
1905 | |
1905 | In practise, C<$tls> must be C<accept>, or a Net::SSLeay context that has |
1906 | In practice, C<$tls> must be C<accept>, or a Net::SSLeay context that has |
1906 | been configured to accept, as servers do not normally send a handshake on |
1907 | been configured to accept, as servers do not normally send a handshake on |
1907 | their own and ths cannot be detected in this way. |
1908 | their own and ths cannot be detected in this way. |
1908 | |
1909 | |
1909 | See C<tls_detect> above for more details. |
1910 | See C<tls_detect> above for more details. |
1910 | |
1911 | |
1911 | Example: give the client a chance to start TLS before accepting a text |
1912 | Example: give the client a chance to start TLS before accepting a text |
1912 | line. |
1913 | line. |
1913 | |
1914 | |
1914 | $hdl->push_read (tls_detect => "accept"); |
1915 | $hdl->push_read (tls_autostart => "accept"); |
1915 | $hdl->push_read (line => sub { |
1916 | $hdl->push_read (line => sub { |
1916 | print "received ", ($_[0]{tls} ? "encrypted" : "cleartext"), " <$_[1]>\n"; |
1917 | print "received ", ($_[0]{tls} ? "encrypted" : "cleartext"), " <$_[1]>\n"; |
1917 | }); |
1918 | }); |
1918 | |
1919 | |
1919 | =cut |
1920 | =cut |
… | |
… | |
1931 | ) { |
1932 | ) { |
1932 | return if 3 != length $1; # partial match, can't decide yet |
1933 | return if 3 != length $1; # partial match, can't decide yet |
1933 | |
1934 | |
1934 | # full match, valid TLS record |
1935 | # full match, valid TLS record |
1935 | my ($major, $minor) = unpack "CC", $1; |
1936 | my ($major, $minor) = unpack "CC", $1; |
1936 | $cb->($self, "accept", $major + $minor * 0.1); |
1937 | $cb->($self, "accept", $major, $minor); |
1937 | } else { |
1938 | } else { |
1938 | # mismatch == guaranteed not TLS |
1939 | # mismatch == guaranteed not TLS |
1939 | $cb->($self, undef); |
1940 | $cb->($self, undef); |
1940 | } |
1941 | } |
1941 | |
1942 | |
… | |
… | |
2041 | } elsif (defined $len) { |
2042 | } elsif (defined $len) { |
2042 | delete $self->{_rw}; |
2043 | delete $self->{_rw}; |
2043 | $self->{_eof} = 1; |
2044 | $self->{_eof} = 1; |
2044 | $self->_drain_rbuf; |
2045 | $self->_drain_rbuf; |
2045 | |
2046 | |
2046 | } elsif ($! != EAGAIN && $! != EINTR && $! != WSAEWOULDBLOCK) { |
2047 | } elsif ($! != EAGAIN && $! != EINTR && $! != EWOULDBLOCK && $! != WSAEWOULDBLOCK) { |
2047 | return $self->_error ($!, 1); |
2048 | return $self->error ($!, 1); |
2048 | } |
2049 | } |
2049 | }; |
2050 | }; |
2050 | } |
2051 | } |
2051 | } |
2052 | } |
2052 | |
2053 | |
… | |
… | |
2054 | our $ERROR_WANT_READ; |
2055 | our $ERROR_WANT_READ; |
2055 | |
2056 | |
2056 | sub _tls_error { |
2057 | sub _tls_error { |
2057 | my ($self, $err) = @_; |
2058 | my ($self, $err) = @_; |
2058 | |
2059 | |
2059 | return $self->_error ($!, 1) |
2060 | return $self->error ($!, 1) |
2060 | if $err == Net::SSLeay::ERROR_SYSCALL (); |
2061 | if $err == Net::SSLeay::ERROR_SYSCALL (); |
2061 | |
2062 | |
2062 | my $err = Net::SSLeay::ERR_error_string (Net::SSLeay::ERR_get_error ()); |
2063 | my $err = Net::SSLeay::ERR_error_string (Net::SSLeay::ERR_get_error ()); |
2063 | |
2064 | |
2064 | # reduce error string to look less scary |
2065 | # reduce error string to look less scary |
… | |
… | |
2067 | if ($self->{_on_starttls}) { |
2068 | if ($self->{_on_starttls}) { |
2068 | (delete $self->{_on_starttls})->($self, undef, $err); |
2069 | (delete $self->{_on_starttls})->($self, undef, $err); |
2069 | &_freetls; |
2070 | &_freetls; |
2070 | } else { |
2071 | } else { |
2071 | &_freetls; |
2072 | &_freetls; |
2072 | $self->_error (Errno::EPROTO, 1, $err); |
2073 | $self->error (Errno::EPROTO, 1, $err); |
2073 | } |
2074 | } |
2074 | } |
2075 | } |
2075 | |
2076 | |
2076 | # poll the write BIO and send the data if applicable |
2077 | # poll the write BIO and send the data if applicable |
2077 | # also decode read data if possible |
2078 | # also decode read data if possible |
2078 | # this is basiclaly our TLS state machine |
2079 | # this is basically our TLS state machine |
2079 | # more efficient implementations are possible with openssl, |
2080 | # more efficient implementations are possible with openssl, |
2080 | # but not with the buggy and incomplete Net::SSLeay. |
2081 | # but not with the buggy and incomplete Net::SSLeay. |
2081 | sub _dotls { |
2082 | sub _dotls { |
2082 | my ($self) = @_; |
2083 | my ($self) = @_; |
2083 | |
2084 | |
… | |
… | |
2179 | unless (defined $AnyEvent::TLS::VERSION) { |
2180 | unless (defined $AnyEvent::TLS::VERSION) { |
2180 | eval { |
2181 | eval { |
2181 | require Net::SSLeay; |
2182 | require Net::SSLeay; |
2182 | require AnyEvent::TLS; |
2183 | require AnyEvent::TLS; |
2183 | 1 |
2184 | 1 |
2184 | } or return $self->_error (Errno::EPROTO, 1, "TLS support not available on this system"); |
2185 | } or return $self->error (Errno::EPROTO, 1, "TLS support not available on this system"); |
2185 | } |
2186 | } |
2186 | |
2187 | |
2187 | $self->{tls} = $tls; |
2188 | $self->{tls} = $tls; |
2188 | $self->{tls_ctx} = $ctx if @_ > 2; |
2189 | $self->{tls_ctx} = $ctx if @_ > 2; |
2189 | |
2190 | |
… | |
… | |
2210 | $self->{tls} = $tls = $self->{tls_ctx}->_get_session ($tls, $self, $self->{peername}); |
2211 | $self->{tls} = $tls = $self->{tls_ctx}->_get_session ($tls, $self, $self->{peername}); |
2211 | |
2212 | |
2212 | # basically, this is deep magic (because SSL_read should have the same issues) |
2213 | # basically, this is deep magic (because SSL_read should have the same issues) |
2213 | # but the openssl maintainers basically said: "trust us, it just works". |
2214 | # but the openssl maintainers basically said: "trust us, it just works". |
2214 | # (unfortunately, we have to hardcode constants because the abysmally misdesigned |
2215 | # (unfortunately, we have to hardcode constants because the abysmally misdesigned |
2215 | # and mismaintained ssleay-module doesn't even offer them). |
2216 | # and mismaintained ssleay-module didn't offer them for a decade or so). |
2216 | # http://www.mail-archive.com/openssl-dev@openssl.org/msg22420.html |
2217 | # http://www.mail-archive.com/openssl-dev@openssl.org/msg22420.html |
2217 | # |
2218 | # |
2218 | # in short: this is a mess. |
2219 | # in short: this is a mess. |
2219 | # |
2220 | # |
2220 | # note that we do not try to keep the length constant between writes as we are required to do. |
2221 | # note that we do not try to keep the length constant between writes as we are required to do. |
2221 | # we assume that most (but not all) of this insanity only applies to non-blocking cases, |
2222 | # we assume that most (but not all) of this insanity only applies to non-blocking cases, |
2222 | # and we drive openssl fully in blocking mode here. Or maybe we don't - openssl seems to |
2223 | # and we drive openssl fully in blocking mode here. Or maybe we don't - openssl seems to |
2223 | # have identity issues in that area. |
2224 | # have identity issues in that area. |
2224 | # Net::SSLeay::CTX_set_mode ($ssl, |
2225 | # Net::SSLeay::set_mode ($ssl, |
2225 | # (eval { local $SIG{__DIE__}; Net::SSLeay::MODE_ENABLE_PARTIAL_WRITE () } || 1) |
2226 | # (eval { local $SIG{__DIE__}; Net::SSLeay::MODE_ENABLE_PARTIAL_WRITE () } || 1) |
2226 | # | (eval { local $SIG{__DIE__}; Net::SSLeay::MODE_ACCEPT_MOVING_WRITE_BUFFER () } || 2)); |
2227 | # | (eval { local $SIG{__DIE__}; Net::SSLeay::MODE_ACCEPT_MOVING_WRITE_BUFFER () } || 2)); |
2227 | Net::SSLeay::CTX_set_mode ($tls, 1|2); |
2228 | Net::SSLeay::set_mode ($tls, 1|2); |
2228 | |
2229 | |
2229 | $self->{_rbio} = Net::SSLeay::BIO_new (Net::SSLeay::BIO_s_mem ()); |
2230 | $self->{_rbio} = Net::SSLeay::BIO_new (Net::SSLeay::BIO_s_mem ()); |
2230 | $self->{_wbio} = Net::SSLeay::BIO_new (Net::SSLeay::BIO_s_mem ()); |
2231 | $self->{_wbio} = Net::SSLeay::BIO_new (Net::SSLeay::BIO_s_mem ()); |
2231 | |
2232 | |
2232 | Net::SSLeay::BIO_write ($self->{_rbio}, $self->{rbuf}); |
2233 | Net::SSLeay::BIO_write ($self->{_rbio}, $self->{rbuf}); |
… | |
… | |
2272 | |
2273 | |
2273 | return unless $self->{tls}; |
2274 | return unless $self->{tls}; |
2274 | |
2275 | |
2275 | $self->{tls_ctx}->_put_session (delete $self->{tls}) |
2276 | $self->{tls_ctx}->_put_session (delete $self->{tls}) |
2276 | if $self->{tls} > 0; |
2277 | if $self->{tls} > 0; |
2277 | |
2278 | |
2278 | delete @$self{qw(_rbio _wbio _tls_wbuf _on_starttls)}; |
2279 | delete @$self{qw(_rbio _wbio _tls_wbuf _on_starttls)}; |
2279 | } |
2280 | } |
2280 | |
2281 | |
2281 | =item $handle->resettls |
2282 | =item $handle->resettls |
2282 | |
2283 | |
… | |
… | |
2307 | push @linger, AE::io $fh, 1, sub { |
2308 | push @linger, AE::io $fh, 1, sub { |
2308 | my $len = syswrite $fh, $wbuf, length $wbuf; |
2309 | my $len = syswrite $fh, $wbuf, length $wbuf; |
2309 | |
2310 | |
2310 | if ($len > 0) { |
2311 | if ($len > 0) { |
2311 | substr $wbuf, 0, $len, ""; |
2312 | substr $wbuf, 0, $len, ""; |
2312 | } elsif (defined $len || ($! != EAGAIN && $! != EINTR && $! != WSAEWOULDBLOCK)) { |
2313 | } elsif (defined $len || ($! != EAGAIN && $! != EINTR && $! != EWOULDBLOCK && $! != WSAEWOULDBLOCK)) { |
2313 | @linger = (); # end |
2314 | @linger = (); # end |
2314 | } |
2315 | } |
2315 | }; |
2316 | }; |
2316 | push @linger, AE::timer $linger, 0, sub { |
2317 | push @linger, AE::timer $linger, 0, sub { |
2317 | @linger = (); |
2318 | @linger = (); |