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!

Reply via email to