所以我试图从路由条目中返回一个最佳匹配接口。但是,它并不完全按照我想要的方式工作。我以应有的方式返回了 6 个值中的 5 个,但我很确定路由表中有一百万个条目,我的算法将不起作用。我正在使用二进制搜索来解决这个问题。但是,例如,我要返回的接口的 ipaddress 小于我作为参数传递的 ipaddress,则二进制搜索算法不起作用。结构如下所示:
struct routeEntry_t
{
uint32_t ipAddr;
uint32_t netMask;
int interface;
};
routeEntry_t routing_table[100000];
假设路由表如下所示:
{ 0x00000000, 0x00000000, 1 }, // [0]
{ 0x0A000000, 0xFF000000, 2 }, // [1]
{ 0x0A010000, 0xFFFF0000, 10 }, // [2]
{ 0x0D010100, 0xFFFFFF00, 4 }, // [3]
{ 0x0B100000, 0xFFFF0000, 3 }, // [4]
{ 0x0A010101, 0xFFFFFFFF, 5 }, // [5]
示例输入/输出:
- 常规搜索
输入:0x0D010101 输出:4(条目 [3])
输入:0x0B100505 输出:3(条目 [4])
- 要查找任意地址,它应该转到默认界面。
输入:0x0F0F0F0F 输出:1(条目 [0])
- 要查找与多个条目匹配的地址,请选择最佳匹配。
输入:0x0A010200 输出:10(条目 [2])
输入:0x0A050001 输出:2(条目 [1])
输入:0x0A010101 输出:5(条目 [5])
但我的输出看起来像 2、3、1、10、1、5。我不明白我在哪里搞砸了。你能解释一下我在哪里做错了吗?任何帮助都会很棒。提前致谢。然而,这就是我的算法的样子(假设条目已排序):
int interface(uint32_t ipAddr)
{ int 开始 = 0;
int end = SIZE-1;
int mid = 0;
vector<int> matched_entries;
vector<int>::iterator it;
matched_entries.reserve(SIZE);
it = matched_entries.begin();
if (start > end)
return -1;
while (start <= end)
{
mid = start + ((end-start)/2);
if (routing_table[mid].ipAddr == ipAddr)
return routing_table[mid].interface;
else if (routing_table[mid].ipAddr > ipAddr)
{
uint32_t result = routing_table[mid].netMask & ipAddr;
if (result == routing_table[mid].ipAddr)
{
matched_entries.push_back(mid);
}
end = mid-1;
}
else
{
uint32_t result = routing_table[mid].netMask & ipAddr;
if (result == routing_table[mid].ipAddr)
{
matched_entries.insert(it,mid);
}
start = mid+1;
}
}
int matched_ip = matched_entries.back();
if (routing_table[matched_ip].netMask & ipAddr)
return routing_table[matched_ip].interface;
else
return routing_table[0].interface;
}