>> If it's the latter, we can defer calling it until select() says there's
>> data ready. TIEHANDLE can do everything up to the accept() call, then
>> we can wait for the client to send something before accepting the
>> connection.
>
> Not sure but maybe we could select and peek until we got 11 bytes and
> then pass it on to SSL_accept?
Maybe something like this, just a hack which unfortunately spins
because I do not know how to tell POE not to call READ again after I
have PEEK'ed at the socket...
--- SslServer.pm.orig Thu Jan 15 11:12:43 2004
+++ SslServer.pm Thu Jan 15 15:22:10 2004
@@ -18,8 +18,6 @@
use Net::SSLeay qw(die_if_ssl_error);
use POSIX qw(F_GETFL F_SETFL O_NONBLOCK EAGAIN EWOULDBLOCK);
-sub TIMEOUT () { 5 }
-
sub TIEHANDLE {
my ($class, $socket, $key, $cert) = @_;
@@ -53,22 +51,7 @@
);
die_if_ssl_error("certificate");
- eval {
- local $SIG{ALRM} = sub { die "alarm\n" };
- alarm TIMEOUT;
- my $resp = Net::SSLeay::accept($ssl);
- alarm 0;
- if ($resp == -1) {
- # handshake could not complete
- die ("handshake failed");
- }
- };
- if ($@) {
- die unless $@ eq "alarm\n";
- # timed out
- die("SSL handshake timed out, maybe increase timeout in SslServer.pm");
- }
-
+ # delay accept() until we have atleast 11 bytes on socket
$class->_set_filenum_obj($fileno, $ssl, $ctx, $socket);
return bless $socket, $class;
--- SslClient.pm.orig Thu Jan 15 11:12:36 2004
+++ SslClient.pm Thu Jan 15 15:20:19 2004
@@ -14,6 +14,8 @@
use vars qw(@ISA);
@ISA = qw(Net::SSLeay::Handle);
+sub SIZE_SSL23_HANDSHAKE () { 11 }
+
my %Filenum_Object;
sub _get_self {
@@ -25,6 +27,26 @@
return $Filenum_Object{fileno($socket)}->{ssl};
}
+sub _is_server_side {
+ my $socket = shift;
+ return exists $Filenum_Object{fileno($socket)}->{accepted} ? 1 : 0;
+}
+
+sub _is_accepted {
+ my $socket = shift;
+ return $Filenum_Object{fileno($socket)}->{accepted} ? 1 : 0;
+}
+
+sub _accepted {
+ my $socket = shift;
+ $Filenum_Object{fileno($socket)}->{accepted} = 1;
+}
+
+sub _get_filenum_obj {
+ my $socket = shift;
+ return $Filenum_Object{fileno($socket)};
+}
+
sub _set_filenum_obj {
my ($self, $fileno, $ssl, $ctx, $socket) = @_;
$Filenum_Object{$fileno} =
@@ -32,6 +54,9 @@
ctx => $ctx,
socket => $socket,
fileno => $fileno,
+ accepted => 0,
+ readfdset => undef,
+ accept_buffer => '',
};
}
@@ -71,6 +96,41 @@
my ($socket, $buf, $len, $offset) = \ (@_);
my $ssl = $$socket->_get_ssl();
+ if ($$socket->_is_server_side() && !$$socket->_is_accepted()) {
+ my $filenum_obj = $$socket->_get_filenum_obj();
+ if (!defined($filenum_obj->{readfdset})) {
+ vec($filenum_obj->{readfdset}, $filenum_obj->{fileno}, 1) = 1;
+ }
+ my $accept_buffer = $filenum_obj->{accept_buffer};
+ while (select($filenum_obj->{readfdset}, undef, undef, undef)) {
+ if (!vec($filenum_obj->{readfdset}, $filenum_obj->{fileno}, 1)) {
+ return;
+ }
+ my $ret = recv($filenum_obj->{socket}, $_,
+ SIZE_SSL23_HANDSHAKE , Socket::MSG_PEEK);
+ if (!defined($ret)) { # undef mean error
+ return;
+ }
+ if (length($accept_buffer) == length($_)) {
+ # nothing new, here we would like to make POE not call us again
+ # until new data has arrived.. XXX
+ return length($_);
+ }
+ $accept_buffer = $_;
+ if (length($accept_buffer) == SIZE_SSL23_HANDSHAKE ) {
+ my $resp = Net::SSLeay::accept($ssl);
+ if ($resp == -1) {
+ # handshake could not complete
+ die ("handshake failed");
+ }
+ $$socket->_accepted();
+ goto GO_ON;
+ }
+ }
+ return;
+ }
+
+ GO_ON:
# No offset. Replace the buffer.
unless (defined $$offset) {
$$buf = Net::SSLeay::read($ssl, $$len);