NAME

Net::RNDC::Session - Helper package to manage the RNDC 4-packet session

SYNOPSIS

To use synchronously as a client:

use IO::Socket::INET;
use Net::RNDC::Session;

my $c = IO::Socket::INET->new(
  PeerAddr => '127.0.0.1:953',
) or die "Failed to create a socket: $@ ($!)";

# Our response
my $response;

my $session = Net::RNDC::Session->new(
  key         => 'abcd',
  command     => 'status',
  is_client   => 1,

  want_write =>  sub { my $s = shift; $c->send(shift); $s->next; },
  want_read  =>  sub { my $s = shift; my $b; $c->recv($b, 4096); $s->next($b); },
  want_finish => sub { my $s = shift; $response = shift; },
  want_error =>  sub { my $s = shift; my $err = shift; die "Error: $err\n"; },
);

# Since we call next() in want_read/want_write above, this will do everything
$session->start;

print "Response: $response\n";

To use asynchronously (for example, with IO::Async):

TBD

To use as a server:

TBD

To use asynchronously as a server:

TBD

DESCRIPTION

This package is intended to provide the logic for an RNDC client session which can used to run a single command against a remote server and get a response. See SESSION below for a description of the RNDC client session logic.

This package also supports running sessions as an RNDC server.

For simple use of the RNDC protocol, see Net::RNDC.

There is no socket logic here, that must be provided to this class through the constructor in the various want_* methods. This allows for synchronous/asynchronous use with a little work.

This package does generate and parse Net::RNDC::Packets, but the want_read and want_write methods allow you to peak at this data before it's parsed and before it's sent to the remote end to allow slightly more fine-grained control.

To manage the entire process yourself, use Net::RNDC::Packet.

SESSION

An RNDC client session (where one is sending commands to a remote nameserver expecting a response) contains 4 packets.

All packets contain a timestamp/expiracy timestamp to denote a packet validity window, as well as an HMAC-MD5 signature of the packets data using a shared private key, and a serial number to identify the packet.

  1. CLIENT->send(<opening packet>)

    The opening packet contains a '_data' section with an undef 'type'.

  2. SERVER->send(<nonce packet>)

    The server response packet contains a 'nonce' integer which should be copied into the next request.

  3. CLIENT->send(<command packet>)

    The nonce should be included in the command packet in the '_ctrl' section, and the command to be run on the remote section should be in the 'type' paramater of the '_data' section.

  4. SERVER->send(<response packet>)

    The response packet will contain an 'error' parameter in the '_data' section if something went wrong, otherwise the response will be in the 'text' parameter of the '_data' section.

If at any time the remote end disconnects prematurely, this may indicate any of the following (along with normal network issues):

  • The clocks are off

  • The key is incorrect

  • The window has expired

SEE ALSO

Net::RNDC - Simple RNDC communication.

Net::RNDC::Packet - Low level RNDC packet manipulation.

AUTHOR

Matthew Horsfall (alh) <WolfSage@gmail.com>

LICENSE

You may distribute this code under the same terms as Perl itself.