Networking 计算到下一个可用IP地址的距离

Networking 计算到下一个可用IP地址的距离,networking,ip,ip-address,ipv6,subnet,Networking,Ip,Ip Address,Ipv6,Subnet,假设我想为2001:0DB8::/32范围内的人分配IPv6地址。大多数是按顺序给出的,但有些是非顺序的。此DB表显示已分配的地址 +-----------------------------------------+ | Address | +-----------------------------------------+ | 2001:0DB8:0000:0000:0000:0000:0000:0001 | | 2001:0

假设我想为2001:0DB8::/32范围内的人分配IPv6地址。大多数是按顺序给出的,但有些是非顺序的。此DB表显示已分配的地址

+-----------------------------------------+
|                 Address                 |
+-----------------------------------------+
| 2001:0DB8:0000:0000:0000:0000:0000:0001 |
| 2001:0DB8:0000:0000:0000:0000:0000:0002 |
| 2001:0DB8:0000:0000:0000:0000:0000:0003 |
| 2001:0DB8:0000:0000:0000:0000:0000:0009 |
| 2001:0DB8:0000:0000:0000:0000:0F00:0001 |
| 2001:0DB8:0000:0000:0000:0000:0F00:0002 |
+-----------------------------------------+
请注意,它是稀疏填充的-前3个地址被占用,然后有5个可用地址,直到下一个地址被占用,然后在另一个地址被占用之前有几百万个地址的间隙

我要做的是为用户分配下一个可用地址,从子网的开头开始。在本例中,从一开始就很容易,发现还没有2001:0DB8::4的记录,然后使用该记录。但最终,下一个可用地址可能距离子网的起始位置数千或数百万步。一次浏览一个数据库地址是个坏主意

我曾考虑在表中添加另一个字段,以便每个地址都指示其自身与列表中下一个地址之间的可用地址数:

+-----------------------------------------+--------------------+
|                 Address                 | Steps to next addr |
+-----------------------------------------+--------------------+
| 2001:0DB8:0000:0000:0000:0000:0000:0001 |                  1 |
| 2001:0DB8:0000:0000:0000:0000:0000:0002 |                  1 |
| 2001:0DB8:0000:0000:0000:0000:0000:0003 |                  6 |
| 2001:0DB8:0000:0000:0000:0000:0000:0009 |           15728632 |
| 2001:0DB8:0000:0000:0000:0000:0F00:0001 |                  2 |
| 2001:0DB8:0000:0000:0000:0000:0F00:0003 |                    |
+-----------------------------------------+--------------------+
但我不确定这对我有什么帮助。如果IP地址被分配在一个稀疏部分的中间,我仍然需要计算从那个地址到下一个地址的顺序,然后回到新地址之前的地址,并改正它的“下一步ADDR”。这似乎仍然是一个缓慢的过程


有更好的方法吗?

只要稍微调整一下您的方法就可以解决这个问题。我假设您希望在这里填补未使用的空白的原因是因为您有一个现有的人烟稀少的数据库,您希望更好地利用它

保留原始表,但单独存储
next\u address
字段(例如,在
Settings
表中)。首次部署代码时,下一个\u地址将从
2001:db8::1开始

您的
get\u next\u address()
函数将如下所示:

def initialise_settings():
    if not Settings.exists('next_address'):
         Settings.set('next_address', IPv6('2001:db8::1'))

def get_next_address():

    next = Settings.get('next_address')

    # Check for already filled rows -- breaks loop upon finding gap
    while Database.row_exists({'Address': next}):
        next += 1

    Settings.set('next_address', next + 1)
    return next

get_next_address() # 2001:db8::4
get_next_address() # 2001:db8::5
get_next_address() # 2001:db8::6
# ...
get_next_address() # 2001:db8::f00:0
get_next_address() # 2001:db8::f00:2
get_next_address() # 2001:db8::f00:4
get_next_address() # 2001:db8::f00:5

这是可以解决的,只要稍微调整你的方法在这里。我假设您希望在这里填补未使用的空白的原因是因为您有一个现有的人烟稀少的数据库,您希望更好地利用它

保留原始表,但单独存储
next\u address
字段(例如,在
Settings
表中)。首次部署代码时,下一个\u地址将从
2001:db8::1开始

您的
get\u next\u address()
函数将如下所示:

def initialise_settings():
    if not Settings.exists('next_address'):
         Settings.set('next_address', IPv6('2001:db8::1'))

def get_next_address():

    next = Settings.get('next_address')

    # Check for already filled rows -- breaks loop upon finding gap
    while Database.row_exists({'Address': next}):
        next += 1

    Settings.set('next_address', next + 1)
    return next

get_next_address() # 2001:db8::4
get_next_address() # 2001:db8::5
get_next_address() # 2001:db8::6
# ...
get_next_address() # 2001:db8::f00:0
get_next_address() # 2001:db8::f00:2
get_next_address() # 2001:db8::f00:4
get_next_address() # 2001:db8::f00:5

从一开始,这几乎肯定是一种分配IPv6地址的糟糕方式。我希望这仅仅是一个(构思拙劣的)家庭作业。@MichaelHampton我真的很感兴趣的是你如何最好地提出一个地址分配算法。可能是对这个问题的离题回答(因为它涉及到扩充一个已经存在的IPAM数据库),但希望看到它作为一个全新问题的答案。@JeremyVisser这就是DHCP的目的…@NathanC甚至不是同一个论点,伙计。这几乎肯定是一种糟糕的分配IPv6地址的方式。我希望这仅仅是一个(构思拙劣的)家庭作业。@MichaelHampton我真的很感兴趣的是你如何最好地提出一个地址分配算法。可能是对这个问题的离题回答(因为它涉及到扩充一个已经存在的IPAM数据库),但希望看到它作为一个全新问题的答案。@JeremyVisser这就是DHCP的目的…@NathanC甚至不是同一个论点,伙计。不去那里。是的,我继承了一个DB,分配策略不同。通常情况下,下一个可用IP地址是所需的,但是已经根据设备的MAC地址等因素分配了大量地址,等等。我想我理解您的解决方案——您存储的是实际的下一个可用地址,而不是下一个地址的步骤——但是,如果两个分配的地址之间存在数百万个地址的差距,下一个地址的计算不会仍然有很大的放缓吗?但至少在最初的运行中,这是不可避免的。如果您遇到一大块已经分配的地址,那么是的,需要时间来迭代。但我认为算法的简单性超过了缺点。你最终肯定会到达那里,而且这相对容易理解。易于理解带来了固有的可靠性。:-)是的,我继承了一个DB,其中分配策略不同。通常情况下,下一个可用IP地址是所需的,但是已经根据设备的MAC地址等因素分配了大量地址,等等。我想我理解您的解决方案——您存储的是实际的下一个可用地址,而不是下一个地址的步骤——但是,如果两个分配的地址之间存在数百万个地址的差距,下一个地址的计算不会仍然有很大的放缓吗?但至少在最初的运行中,这是不可避免的。如果您遇到一大块已经分配的地址,那么是的,需要时间来迭代。但我认为算法的简单性超过了缺点。你最终肯定会到达那里,而且这相对容易理解。易于理解带来了固有的可靠性。:-)