Need help for passing data back and forth data over a persistent SSL TCP socket

[email protected] Fri, 21 Feb 2014 08:48:25 +0800
Newsgroups gmane.comp.lang.perl.poe
Message-ID <[email protected]>
Hi there,

I'm trying to write a POE based server/client combo that uses SSL authed 
persistent connections for comunication between a client and server.

Basically I have a server running that listens on port 2001. A client 
connects to the server. Sets up an SSL connection with client 
certificate auth and then what I _want_ to happen is that the client 
then (every 10 seconds) asks for new temperature data from the server 
and is served the current value. I have the client asking in a loop 
every 10 seconds but the server isn't triggering and responding past the 
first connection event. I'm not sure I'm doing this right (tm) can 
anyone help me? I have some inline comments in the code.

client :

#!/usr/bin/perl

### very simple connect to server with auth certs and when connected 
sends the "temp" command.
### then when it receives input it fires off Server input and wait 10 
then sends again. But
### should it trigger a input event again? I think I'm looping in POE 
incorrectly.

   use warnings;
   use strict;

   use POE qw(Component::Client::TCP Filter::SSL);

   POE::Component::Client::TCP->new(
     RemoteAddress => "localhost",
     RemotePort    => 2001,
     Filter        => [ "POE::Filter::SSL", crt => 'keys/client1.crt', 
key => 'keys/client1.key', client => 1 ],
     Connected     => sub {
         $_[HEAP]{server}->put("temp");

     },
     ServerInput   => sub {
         my $command = "temp";
       while(1) {
         print "from server: ".$_[ARG0]."\n";
         sleep (10);
         print "Sending to server : $command\n";
         $_[HEAP]{server}->put($command);
       }

     },
   );

   POE::Kernel->run();
   exit;


Server code :

#!/usr/bin/perl

   use strict;
   use warnings;
   use Socket;
   use POE qw(
     Wheel::SocketFactory
     Wheel::ReadWrite
     Driver::SysRW
     Filter::SSL
     Filter::Stackable
     Filter::HTTPD
   );


   POE::Session->create(
     inline_states => {
       _start       => sub {
         my $heap = $_[HEAP];
         $heap->{debug} = 1;
         if ($heap->{debug}) { print "Stating POE session and 
initialising socket\n"};
         $heap->{listener} = POE::Wheel::SocketFactory->new(
           BindAddress  => 'localhost',
           BindPort     => 2001,
           Reuse        => 'yes',
           SuccessEvent => 'socket_birth',
           FailureEvent => '_stop',
         );
         if ($heap->{debug}) { print "Socket initialised Waiting for 
connections\n"};
       },
       _stop => sub {
         if ($_[HEAP]->{debug}) { print "Socket Binding Failed!\n"};
         delete $_[HEAP]->{listener};
       },
       socket_birth => sub {
         my ($socket) = $_[ARG0];
         POE::Session->create(
           inline_states => {
             _start       => sub {
               my ($heap, $kernel, $connected_socket, $address, $port) = 
@_[HEAP, KERNEL, ARG0, ARG1, ARG2];
               $heap->{debug} = 1;
               if ($_[HEAP]->{debug}) { print "Creating SSL Object\n"};
               $heap->{sslfilter} = POE::Filter::SSL->new(
                  crt    => 'keys/server.crt',
                  key    => 'keys/server.key',
                  cacrt  => 'keys/ca.crt',
                  cipher => 'DHE-RSA-AES256-GCM-SHA384:AES256-SHA',
                  debug  => 1,
                  clientcert => 1
               );
               $heap->{socket_wheel} = POE::Wheel::ReadWrite->new(
                 Handle     => $connected_socket,
                 Driver     => POE::Driver::SysRW->new(),
                 Filter     => $heap->{sslfilter},
                 InputEvent => 'socket_input',
                 ErrorEvent => '_stop',
               );
               if ($_[HEAP]->{debug}) { print "Connection made!\n"};
         },
             socket_input => sub {
               my ($kernel, $heap, $buf) = @_[KERNEL, HEAP, ARG0];
               print "RECEIVE : $buf\n";
               my (@certid) = ($heap->{sslfilter}->clientCertIds());
               my $content = '';
               if ($_[HEAP]->{debug}) { print "Authing Client\n"};
               if ($heap->{sslfilter}->clientCertValid()) {
                 if ($_[HEAP]->{debug}) { print "Client Certificate 
Valid, Authorised\n"};
                         if ($buf eq "temp") {
                                 $content = 
`/home/pi/c0de/sht15/temp-munin.py`;
                         } else {
                                 $content = "Unknown request\n";
                         }
                 my $response = $content;
                 if ($_[HEAP]->{debug}) { print "Sending Client 
$content\n"};
                 $heap->{socket_wheel}->put($response);
                 return (1);
                 #$kernel->delay(_stop => 1);
               } else {
                 if ($_[HEAP]->{debug}) { print "Client Certificate 
Invalid, Rejecting connection\n"};
                 $content .= "INVALID CERT! Connection rejected!\n";
                 my $response = $content;
                 $heap->{socket_wheel}->put($response);
                 $kernel->delay(_stop => 1);
               }
             },
             _stop => sub {
               if ($_[HEAP]->{debug}) { print "Client Disconnected\n"};
               delete $_[HEAP]->{socket_wheel};
             }
           },
           args => [$socket],
         );
       }
     }
   );

   $poe_kernel->run();

Any help anyone can provide would be awesome. I want to avoid 
disconnecting and reconnecting ever time I want to get a reading. So 
once the connection is made I want to be able to just send a request and 
get an answer in an endless loop. I think this should work but can't 
figure out why.

Thanks!