[erlang-questions] IP search optimization

Sid Muller sid5@REDACTED
Sat Nov 21 20:59:57 CET 2015


> Sent: Friday, November 20, 2015 at 3:52 PM
> From: "Geoff Cant" <nem@REDACTED>
> To: "Sid Muller" <sid5@REDACTED>
> Cc: Erlang <erlang-questions@REDACTED>
> Subject: Re: [erlang-questions] IP search optimization
>
> Hi Sid, are you writing an open source library for this functionality? I need exactly the same thing and was going to sit down to write it.
> 
> With CIDR blocks, you can always calculate the lower and upper address in a range.
> 
> > -type ip4() :: <<_:32/bits>>.
> > -type ip4_mask() :: 0..32.
> > -type ip4_cidr() :: {ip4(), ip4_mask()}.
> > -spec to_range(ip4_cidr()) -> {Low::ip4(), High::ip4()}.
> > to_range({<<CIDR:4/binary>>, Mask})
> >   when 0 =< Mask,
> >        Mask =< 32 ->
> >     HostBits = 32 - Mask,
> >     {<<CIDR:Mask/bits, 0:HostBits/integer>>,
> >      <<CIDR:Mask/bits, 16#FFFFFFFF:HostBits/integer>>}.
> 
> If you pre-convert your CIDR list into a range list, you can then select all the matching cidrs by comparing Low =< IP, IP =< High, and returning the CIDR with the largest mask (if you do longest-prefix wins), or the first in order if you’re doing an ordered CIDR match.
> 
> Pre-converting CIDR -> Range will let you use ets:select - and might be reasonably efficient in an ordered_set table if you’ve got large numbers of CIDRs. I think if your ets key is {Low, High}, and it’s an ordered_set table, the first result from a matching select will be the one with the longest Mask anyway (as {<<192,168,0,0>>, <<192,168,0,255>>} <  {<<192,168,0,0>>, <<192,168,255,255>>} — i.e. 192.168.0.0/24 < 192.168.0.0/16 when converted to a range tuple).
> 
> > IP = something,
> > Matching = ets:select(cidr_table, ets:fun2ms(fun (#record{range={Low, High}}) when Low =< IP, IP =< High) -> object() end)).
> 
> 
> Anyway - I’m either going to write something like this in the next couple of weeks, or use yours if it’s public and suitable :)

Hi Geoff,

check out Adam's response, the 9 liner prev() does the job really well.



More information about the erlang-questions mailing list