Author image John Eaglesham

NAME

DNS::ZoneSerialNumber - Manipulate DNS zone serial numbers.

SYNOPSIS

  use DNS::ZoneSerialNumber;
  my $zsn = DNS::ZoneSerialNumber->new(100);
  $zsn->increment();
  print "The new serial number is ", $zsn->serial, "\n";

DESCRIPTION

DNS::ZoneSerialNumber encapsulates a DNS zone serial number and provides RFC 1982, 1912, and 2136 compliant manipulation, comparison, and validation methods. This module automatically handles serial number overflows, underflows, and invalid comparisons, as well as simple increments and decrements.

METHODS

new

Constructor for the DNS::ZoneSerialNumber object. Accepts a single optional parameter, the serial number that the object should represent. If not specified, defaults to 1. If an invalid serial number is specified, the method will croak.

On success, returns the DNS::ZoneSerialNumber object.

valid

Accepts a single parameter, the serial number to test for validity.

Returns true or false depending representing whether or not the specified serial number represents a valid serial number. Valid serial numbers are positive integers between 1 and SERIAL_MAX (inclusive). See CONSTANTS for details.

Note: This method may be called statically or as an instance method.

serial

Accepts no parameters. Returns the represented serial number as a Perl scalar.

Note: In string or numeric context, a DNS::ZoneSerialNumber object will return an appropriate representation of its serial number automatically.

set

Accepts a single parameter, the new serial number. Returns the DNS::ZoneSerialNumber object with the updated serial number.

Sets the serial number represented by the object to the specified serial number. If the specified serial number is invalid the method will croak.

set_from_date

Accepts a single optional parameter, the revision count of the new date-based serial number. If an invalid revision count is specified (< 0 or > 99), the method will croak. Returns the DNS::ZoneSerialNumber with the updated serial number.

Sets the serial number represented by the object to a serial number based on the current date in the format specified by RFC 1912 (YYYYMMDDnn). This format allows for a two-digit revision count (nn) which defaults to "00" unless specified.

steps_to_set

Accepts a single parameter, the new serial number. If the specified serial number is invalid, the method will croak. In array context, returns an in-order array of DNS::ZoneSerialNumber objects representing the serial numbers that must be set in order to safely set the specified serial number. In scalar context the number of required steps is returned.

Due to the way RFC 1982 defines serial number comparisons, it is not possible to simply set a zone's serial number to any number considered less than the current serial number. If this is done, DNS servers will assume that the new serial number is older than the prior serial number. In order to set the serial number to a lower value without DNS servers believing the serial number is lower, it must first be set to a higher number (and eventually overflowed) and propagated out. This method generates the list of serial numbers that must be set, in order, to allow a serial number to be set to a lower value without DNS servers believing the serial number is older. On success, this method necessarily returns an array of 1 or 2 elements (or the numbers 1 or 2 in scalar context).

If the specified serial number is greater than or equal to the represented serial number, no additional steps are required and an array of a single element (or the number 1 in scalar context) is returned.

Please note that because this module always avoids the serial number 0, it may compute a different set of increments to arrive at the specified serial number than other tools.

For more information see RFC 1982.

incomparable

Accepts no parameters. Returns a DNS::ZoneSerialNumber object representing the incomparable value for the currently represented serial number.

See RFC 1982 for more information about incomparable serial numbers.

is_incomparable

Accepts a single parameter, the serial number against which the represented serial number should be checked for incomparability. If the specified serial number is invalid, the method will croak.

Returns true if the serial numbers are incomparable or false otherwise.

See RFC 1982 for more information about incomparable serial numbers.

next

Accepts a single optional parameter, the amount to increment by (n). If no parameter is specified, the amount defaults to 1. If an invalid amount is specified, the method will croak. Please see CONSTANTS for details. Returns the next nth serial number in sequence as a DNS::ZoneSerialNumber object. The currently represented serial number is unchanged.

If the serial number overflows the serial maximum it will automatically roll over through the serial minimum.

This method is also available as the overloaded operator "+". Please note that the protections against invalid increments can be circumvented via compound addition using the overloaded methods. For example, the following will succeed even though it results in an invalid increment due to the fact the addition was done in multiple steps:

 my $new_zsn = $zsn + DNS::ZoneSerialNumber::INCREMENT_MAX + 1;

However, the following will (correctly) generate an error:

 my $new_zsn = $zsn + ( DNS::ZoneSerialNumber::INCREMENT_MAX + 1 );

previous

Accepts a single optional parameter, the amount to decrement by (n). If no parameter is specified, the amount defaults to 1. If an invalid amount is specified, the method will croak. Please see CONSTANTS for details. Returns the prior nth serial number in sequence as a DNS::ZoneSerialNumber object. The currently represented serial number is unchanged.

If the serial number underflows the serial minimum it will automatically roll over through the serial maximum.

This method is also available as the overloaded operator "-".

increment

Accepts a single optional parameter, the amount to increment by (n). If no parameter is specified, the amount defaults to 1. If an invalid amount is specified, the method will croak. Please see CONSTANTS for details. Sets the currently represented serial number to the nth next serial number in sequence and returns the DNS::ZoneSerialNumber object with the updated value.

If the serial number overflows the serial maximum it will automatically roll over through the serial minimum.

This method is also available as the overloaded operator "++".

decrement

Accepts a single optional parameter, the amount to decrement by (n). If no parameter is specified, the amount defaults to 1. If an invalid amount is specified, the method will croak. Please see CONSTANTS for details. Sets the currently represented serial number to the nth prior serial number in sequence and returns the DNS::ZoneSerialNumber object with the updated value.

If the serial number underflows the serial minimum it will automatically roll over through the serial maximum.

This method is also available as the overloaded operator "--".

compare

Accepts a single parameter, the serial number to be compared against the one represented by the DNS::ZoneSerialNumber object. If the supplied serial number is invalid, the method will croak.

This method's behavior is the same as the <=> operator, however in the case of incomparable numbers undef is returned. This method is also available as the overloaded operator "<=>".

Overloaded Comparison Methods

All of the following methods accept a single argument, the serial number to be compared against the one represented by the DNS::ZoneSerialNumber object. If the supplied serial number is invalid, the method will croak.

Each method true or false as a result of the comparison. In the case of incomparable numbers, false is returned by all methods except "ne (!=)". All of the following methods are also available as overloaded comparison operators.

The comparison is performed with the encapsulated serial number treated as the left operand. For example:

 $zsn->gt(100)

Is the equivalent of writing:

 $zsn > 100

The following methods are available:

gt (>)

gte (>=)

lt (<)

lte (<=)

eq (==)

ne (!=)

CONSTANTS

DNS::ZoneSerialNumber contains the following internal constants representing definitions and rules used by DNS::ZoneSerialNumber and RFC 1982. These constants are not exported but are available if accessed via the full namespace (eg, DNS::ZoneSerialNumber::SERIAL_BITS).

SERIAL_BITS

The number of bits used to represent a DNS zone serial number. Set at 32.

SERIAL_MAX

The maximum value a serial number of SERIAL_BITS size can store. Computed as:

 ( 2 ** SERIAL_MAX ) - 1

SERIAL_HALF

Approximately half the serial maximum value as used in RFC 1982 equality calculations. This value is used in serial number comparisons and in calculating incomparable serial numbers. Computed as:

 2 ** ( SERIAL_BITS - 1 )

INCREMENT_MAX

The maximum amount by which a serial number can be incremented in a single step. If incremented by more than this amount, the serial number would appear to have gone "backwards", see RFC 1982 for details. Computed as:

 ( 2 ** ( SERIAL_BITS - 1 ) ) - 1

SERIAL NUMBER 0

As per RFC 2136, the serial number 0 is not used and is skipped for all additive and subtractive calculations. For example, if a DNS::ZoneSerialNumber object representing the serial number SERIAL_MAX is then incremented by 1, the new serial number will be set to 1 rather than 0.

Comparisons will still take serial number 0 into account as expected.

INVALID COMPARISONS

The serial number logic provided by RFC 1982 defines two serial numbers with a difference of ( 2 ** SERIAL_MAX ) to be considered neither greater than, less than, nor equal to each other. The RFC provides no recommendations on how to handle comparisons of these numbers and suggests they not be compared directly or used together in the same environment. DNS::ZoneSerialNumber attempts to compare these serial numbers using the same logic that BIND uses: all comparison methods will return false for any comparison of these serial number pairs, except for "ne (!=)" which returns true, and compare (<=>) which returns undef.

OPERATOR OVERLOADING

DNS::ZoneSerialNumber provides overloaded operators for many of its provided methods. The author is currently unsure as to whether or not this is a good idea. If it proves to be problematic, the overloads may be removed (or made optional) in a future version.

CHANGES

1.01 - 20120120, jeagle

Minor documentation updates.

1.00 - 20120118, jeagle

Initial release to CPAN.

SEE ALSO

DNS::ZoneParse, Net::DNS, RFC 1982, RFC 1912, RFC 2136

AUTHOR

John Eaglesham

COPYRIGHT AND LICENSE

Copyright (C) 2011-2012 by John Eaglesham

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