jsommers / pytricia

A library for fast IP address lookup in Python.
GNU Lesser General Public License v3.0
216 stars 22 forks source link

Error with some IPv6 addresses #19

Closed plison closed 1 year ago

plison commented 6 years ago

I'm experiencing a strange bug with IpV6 addresses:

pyt = pytricia.PyTricia()
pyt["2a03:2880:2130:cf05:face:b00c:0:1"] = "foo"
pyt["2a03:2880:f01c:2:face:b00c:0:1"] = "bar"
print(pyt.keys())

Gives the following (correct) answer: ['2a03:2880:f01c:2:face:b00c:0:1/128', '2a03:2880:2130:cf05:face:b00c:0:1/128']. But I get an error if I try to simply get the value of the one of these IPv6 addresses:

pyt["2a03:2880:f01c:2:face:b00c:0:1"]

which gives me: KeyError: 'Prefix not found.'

Any idea about what's happening?

jsommers commented 6 years ago

Thanks for the report --- I'll look into this.

cbuijs commented 6 years ago

Maybe related (don't want to hijack this thread) and not sure if this qualifies as "works as is" or is "broken":

>>> import pytricia
>>> a = pytricia.PyTricia(128)
>>> a['::/0'] = 'Whatever'
>>> '1.2.3.4' in a
True

Seems that all of the IPv6 space (::/0), includes IPv4 as well? Same results when using when one of below are present/added:

::/0
::/1
::/2
::/3
::/4
::/5
::/6
::/7

If one of above entries is present in the dict, any IPv4 address will match.

When checking the children of the IPv6 space, the IPv4 subnet is there:

>>> a['1.2.3.4'] = 'Whatever'
>>> a.children('::/0')
['1.2.3.4/32']

(Great work BTW!)

cbuijs commented 6 years ago

@plison Create the dict as follows and it will work:

pyt = pytricia.PyTricia(128)

(Add the 128).

You need to specify the maximum number of bits that will be (potentially) used, default is 32.

Neiby commented 6 years ago

I'm running into the same problem as OP. After building a tree using insert(), I have a function to find the parents of certain prefixes. Even though I know the prefix is in the tree, I get this:

KeyError: "Prefix doesn't exist."

I didn't have any issue with IPv4 using the same code, although I did specify 128 when instantiating the pytricia object.

When I do a test from the Python 3.6 command line with just a couple of prefixes, it works great. But in my script when I have many more prefixes, it fails. I'll keep at it, but so far I can't figure out what's going on.

gurubert commented 1 year ago

@plison Create the dict as follows and it will work:

pyt = pytricia.PyTricia(128)

(Add the 128).

You need to specify the maximum number of bits that will be (potentially) used, default is 32.

I can confirm that initializing the PyTricia object with 128 instead of 32 bit works (for me).

jsommers commented 1 year ago

Closing this as the original problem was incorrect initialization of PyTricia. Use pytricia.PyTricia(128) if you want to use v6.