Re: [exim] Round-robin dnslists?

Páxina inicial
Borrar esta mensaxe
Responder a esta mensaxe
Autor: MarkdV
Data:  
Para: Exim users
Asunto: Re: [exim] Round-robin dnslists?
John Horne wrote:
> On Tue, 2009-09-01 at 15:01 +0100, Mike Cardwell wrote:
>> John Horne wrote:
>>
>>> Anyone know if it is possible to configure the 'dnslists' condition in a
>>> round-robin order? I want to check to see if a sending host is listed on
>>> one of two RBL's, but don't necessarily want all the checks to go to the
>>> first listed RBL:
>>>
>>>        dnslists = rbl-a : rbl-b

>>>
>>> I would rather it alternated between the two, rather than testing
>>> 'rbl-a' all the time. Similar to the 'hosts_randomize' transport
>>> statement.
>> dnslists = ${if eq{${eval:$tod_epoch%2}}{1}{rbl-a:rbl-b}{rbl-b:rbl-a}}
>>
>> In the above example, the order depends on whether or not the number of
>> seconds since the epoch is odd or even. Would that be sufficient?
>>
> Ha! Good solution :-) Yes, that works fine. A simple test with some
> logging shows that each RBL is called, and over a period of time this
> works out closer to a 50/50 split. (I changed the 'eq' to an '=='
> though.)


Yeah I like this too, clever. But I was just thinking, what if you have
more then 2 list-items and more then 2 orders in which you want to try them?

I case anyone else was wondering the same thing, I came up with:

${extract{${eval:$tod_epoch%3+1}}{ }{rbl-a:rbl-b:rbl-c \
                                      rbl-b:rbl-c:rbl-a \
                                      rbl-c:rbl-a:rbl-b}}


This 'extracts' one of the three 'space-seperated' alternative
orderings. ($tod_epoch%3 yields a number beween 0-2, because this
variant of ${extract} is 1-based we add 1 to get a number between 1-3.)

Doubt I'll ever really want to but, what if... just for arguments
sake... you want a random order instead of round-robin and/or a
different order even for connections during the same second? If you can
stand a little ${perl..} you could use a function like this:

use List::Util 'shuffle';
sub rndlist {
     srand();
     return join(':', shuffle split(/:/, $_[0]));
}


Use this in an ACL like:

deny
dnslists = ${perl{rndlist}{rbl-a:rbl-b:rbl-c}}

The srand on every call is needed if you use the "perl_at_start" option
because the random-number generator might get initialized in the main
daemon and then generate the same sequence of random numbers (and thus
list order) for each connection (fork).

And if you do use perl then perl_at_start is highly recommended IMHO
because then you only incur the cost of having to start the interpreter
and parse/compile your code only once, when the daemon starts, instead
of every time you hit a ${perl..} string. But I digress...

Bye,
Mark.