The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

AnyEvent::PacketForwarder - Forward packets between two sockets

SYNOPSIS

  use AnyEvent::PacketForwarder;

  $watcher = packet_forwarder $in_fh, $out_fh, sub {
      if (defined $_[0]) {
          print("packet being forwarded:\n", hexdump($_[0]));
      }
      else {
         print("error from packet forwarder (fatal: $_[1]): $!");
      }
  }

DESCRIPTION

  *********************************************************
  *** This is a very early release, anything may change ***
  *********************************************************

This module allows to forwards packets from one socket (or pipe) to another one. The packets can be modified on the fly.

Under the hood this package implements a writing queue and combines it with a packet reader as provided by the module AnyEvent::PacketReader.

Export

The module exports the following subroutine:

$w = packet_forwarder $in, $out, $templ, $max_pkt_len, $queue_size, $cb

This function reads packets from the $in socket (or pipe) and writes them to the $out socket (or pipe).

The callback $cb is called every time a new packet is read with the full packet contents as its first argument. The callback can modify the packet in place jsut changing the value of ($_[0]).

The $templ argument defines the format of the packets (see "Unpack templates" in AnyEvent::PacketReader).

$max_pkt_len is the maximum acceptable packet length.

$queue_size is the maximum number of packets that can be queued for writing. Once the queue becomes full, the forwarder object stops reading new packets from $in until some packet is written to $out.

The arguments $templ, $max_pkt_len, $queue_size are optional and can be omited.

When some error happens the callback $cb is invoked with an undefined first argument. The cause of the error can be then retrieved from $!. A true value is passed as the second argument when the error is in the writing side.

The following code shows how to handle errors correctly:

  my $w;
  $w = packet_forwarder $in, $out,
           sub {
               if (defined $_[0]) {
                   print "packet received!\n";
                   ...
               }
               else {
                   shutdown($in, 0);
                   if ($_[1]) {
                       # write errors are fatal!
                       print "write failed: $!\n";
                       shutdown($out, 1);
                       undef $w; # let the forwarder go
                   }
                   else {
                       print "read failed: $!\n";
                   }
               }
           };

The module uses the following specific errors:

ENODATA

Indicates that no more data is available from the read side because of some error or because the remote side closed the socket and that the write queue has been exhausted.

You may have seen a non fatal error telling you that there was some problem (or EOF) from the read side before this one arrives.

SEE ALSO

AnyEvent, AnyEvent::Socket, AnyEvent::PacketReader.

The scripts contained on the examples directory.

AUTHOR

Salvador Fandiño, <sfandino@yahoo.com>

COPYRIGHT AND LICENSE

Copyright (C) 2013 by Qindel Formación y Servicios S.L.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.14.2 or, at your option, any later version of Perl 5 you may have available.