calling overload methods from constructors

Liste des GroupesRevenir à clp misc 
Sujet : calling overload methods from constructors
De : rweikusat (at) *nospam* talktalk.net (Rainer Weikusat)
Groupes : comp.lang.perl.misc
Date : 03. Jul 2024, 22:44:56
Autres entêtes
Message-ID : <87le2ijjcn.fsf@doppelsaurus.mobileactivedefense.com>
User-Agent : Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux)
Issue I had to deal with recently: I have a class (traditional Perl-OO,
ie, a package) representing a layer 4 'flow' (source and destinaton
address, protocol, source and destination port) which will ultimatively
be used to block the specified flow on a Niagara packet broker. The class
ctor does duplicate detection by building a key string from its
parameters and looking for that in a hash as a second (suricata) alert
for the same flow shouldn't result in it being blocked twice (harmless,
but useless).

I was then asked to add "layer 3 blocking" to this
particular program, ie, block all communications between the specified
source and destination IP. This should also do duplicate detection in
the same way and future requests to block an l4 flow should be considered
duplicates if an l3 block for the source and destination addresses
already exists, in addition to the existing l4 duplicate detection. As
an l4 block is just an l3 block with protocol and ports added, the l3
block class should be a parent of the l4 block class as most of the code
is usable for both cases. After some headscratching, I came up with the
following solution:

The ctor of the l3 block class looks like this:

sub new
{
    my $class = shift;
    my ($self, $k, @w);

    $k = $class->new_key_if(\%blks, @_); #1
    return unless defined($k);

    $self = bless([], $class);
    $$self[KEY] = $k;
   
    @w = $::blk_q->put($self);
    $::poller->add_want($_) for @w;

    return $self;
}

The l4 block class just inherits this. The line marked with #1 does a
call of an overloaded method and passes whatever arguments were passed
to the ctor for it, ie, this will call the l3 block new_key_if method if
an l3 block object is being constructed and the l4 block new_key_if
method for an l4 block object. This method looks like this:

sub new_key_if
{
    my ($self, $blks, $src, $dst, $proto, $sport, $dport) = @_;
    my $k;

    $k = $self->SUPER::make_key($src, $dst);
    return if exists($$blks{$k});

    return $self->SUPER::new_key_if($blks, $src, $dst, $proto, $sport, $dport);
}

It invokes the superclass key construction method for l3 duplicate
detection and then, invokes the superclasss new_key_if with all its
parameters. This method is

sub new_key_if
{
    my ($self, $blks) = (shift, shift);
    my $k;

    $k = $self->make_key(@_);
    return if exists($$blks{$k});

    $$blks{$k} = 1;
    return $k;
}

This removes the first two arguments which are the invocant and a
reference to the duplicate detection hash. In then invokes the make_key
method with the remaining arguments. Depending on which kind of object
is being constructed, this will either build a l3 key or a l4 key. Apart
from that, the code is identical for both classes.

This means for object construction, I now have 17 lines of code shared
between both classes and a further 7 for the behaviour that's specific
to the l4 block class.

The crucial bits for implementing this are two Perl features:

1) Ability to call methods possibly overloaded by a subclass without a
class instance (blessed reference) by using the class name as invocant.

2) Ability of a subroutine ("method") to call another subroutine with
the arguments passed to it without knowing what these arguments actually
are (for the l4 case, 3 additional arguments are being passed the l3
code being reused for this is oblivious to).

Date Sujet#  Auteur
3 Jul 24 o calling overload methods from constructors1Rainer Weikusat

Haut de la page

Les messages affichés proviennent d'usenet.

NewsPortal