09-27-07 06:11 AM
OK this is actually very easy. The IO::Socket::SSL docs mention how
to do non-blocking correctly, but it looks like the package was taken
over and specifically improved in this arena around the time of this
original discussion. So who knows, maybe it wasn't clear how to do
this before now. Anyway, this simple patch fixes the issue and
doesn't change the requirements or need danga::socket updates. The
trick is to promote a normal IO::Socket::INET socket to an ssl socket
with IO::Socket::SSL->start_SSL() after the accept(). I'm making the
call in an eval, because if the start_SSL() call fails to establish
an ssl socket, the socket silently remains a plain old non-ssl socket
and would be handled the same as if you were missing the SSL module I
believe. Thoughts? Haven't gotten a chance to test it extensively,
but it looks to me like identical functionality. Here's the patch.
Let me apologize in advance in case my mail client screws this up.
Index: TCPListener.pm
========================================
===========================
--- TCPListener.pm (revision 699)
+++ TCPListener.pm (working copy)
@@ -11,7 +11,7 @@
no warnings qw(deprecated);
use base "Perlbal::Socket";
-use fields qw(service hostport);
+use fields qw(service hostport sslopts);
use Socket qw(IPPROTO_TCP SOL_SOCKET SO_SNDBUF);
# TCPListener
@@ -19,16 +19,12 @@
my ($class, $hostport, $service, $opts) = @_;
$opts ||= {};
- my $sockclass = $opts->{ssl} ? "IO::Socket::SSL" :
"IO::Socket::INET";
- my $sock = eval {
- $sockclass->new(
- LocalAddr => $hostport,
- Proto => IPPROTO_TCP,
- Listen => 1024,
- ReuseAddr => 1,
- ($opts->{ssl} ? %{$opts->{ssl}} : ()
),
- );
- };
+ my $sock = IO::Socket::INET->new(
+ LocalAddr => $hostport,
+ Proto => IPPROTO_TCP,
+ Listen => 1024,
+ ReuseAddr => 1,
+ );
return Perlbal::error("Error creating listening socket: " . ($@
|| $!))
unless $sock;
@@ -48,6 +44,7 @@
my $self = $class->SUPER::new($sock);
$self->{service} = $service;
$self->{hostport} = $hostport;
+ $self->{sslopts} = $opts->{ssl};
bless $self, ref $class || $class;
$self->watch_read(1);
return $self;
@@ -60,10 +57,10 @@
# accept as many connections as we can
while (my ($psock, $peeraddr) = $self->{sock}->accept) {
my $service_role = $self->{service}->role;
+ my ($pport, $pipr) = Socket::sockaddr_in($peeraddr);
+ my $pip = Socket::inet_ntoa($pipr);
if (Perlbal::DEBUG >= 1) {
- my ($pport, $pipr) = Socket::sockaddr_in($peeraddr);
- my $pip = Socket::inet_ntoa($pipr);
print "Got new conn: $psock ($pip:$pport) for
$service_role\n";
}
@@ -73,6 +70,19 @@
my $rv = setsockopt($psock, SOL_SOCKET, SO_SNDBUF, pack
("L", $sndbuf));
}
+ if ($self->{sslopts}) {
+ if (Perlbal::DEBUG >= 1) {
+ print "Promoting to SSL socket: $psock ($pip:$pport)
for $service_role\n";
+ }
+ eval {
+ IO::Socket::SSL->start_SSL(
+ $psock,
+ SSL_server => 1,
+ %{$self->{sslopts}}
+ );
+ };
+ }
+
if ($service_role eq "reverse_proxy") {
Perlbal::ClientProxy->new($self->{service}, $psock);
} elsif ($service_role eq "management") {
On Sep 25, 2007, at 10:40 PM, Brad Fitzpatrick wrote:
> On Tue, 25 Sep 2007, Robin H. Johnson wrote:
>
>
> That's it, but I can't recall if I ever fully got it working... it
> seems I
> would've released it if I had. Use with caution.
>
> - Brad
>
Greg Thornton
Senior Developer | Emma®
greg@myemma.com
800.595.4401 or 615.292.5888 x112
615.292.0777 (fax)
Emma helps organizations everywhere communicate & market in style.
Visit us online at http://www.myemma.com
P please consider the environment before printing this e-mail
[ Post a follow-up to this message ]
|