non-blocking SSL update

Greg Thornton greg at myemma.com
Wed Sep 26 18:10:10 UTC 2007


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:
>
>> On Tue, Sep 25, 2007 at 03:53:21PM -0500, Greg Thornton wrote:
>>> Ok so where might one find Danga::Socket::SSL right now? Maybe I  
>>> just can't
>>> operate CPAN correctly, but it doesn't seem to be in there. I'd  
>>> LOVE to
>>> give this a shot. Granted I haven't touched perl in a while, but  
>>> it sounds
>>> like the hard part is done. Coincidentally I'd try to tackle the  
>>> OPTIONAL
>>> ssl dependency route described by Brad. Thanks dudes.
>> http://code.sixapart.com/svn/Danga-Socket-SSL/
>> I don't know if there is any more recent version. bradfitz might  
>> be able
>> to say more canonically.
>
> 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 at 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


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.danga.com/pipermail/perlbal/attachments/20070926/fd116730/attachment.htm


More information about the perlbal mailing list