用于 tcp 哈希表的 5 个 turple(src ip、src port、dst ip、dst port、proto



我找到了一些函数样本来快速散列 5 个 turple,以识别 tcp 连接表中的双向流,以进行 tcp 流重组(sha/md5 太慢了......

例如

((size_t)(key.src.s_addr) * 59) ^
((size_t)(key.dst.s_addr)) ^
((size_t)(key.sport) << 16) ^
((size_t)(key.dport)) ^
((size_t)(key.proto));

或者这个,其中 K 是哈希表大小为 n 的键,并使用 exclusive-OR 运算符,其中 XOR 运算可以表示为

H(X) = k1⊕k2⊕...kn

或者以下 97 位 (32+32+16+16+16+1( 的 IPS/端口/原型是否提供足够的随机性而不会发生冲突

src ip 80.229.161.151 = 1357226391
dst ip 80.229.161.159 = 1357226399
src port 35555 
dst port 80
tcp 6
H(X) = 1357226391 * 97 ⊕ 1357226399 * 97 ⊕ 35555 * 97 ⊕ 80 * 97 ⊕ 6 * 97
hash key = 131654394123 ???

https://www.researchgate.net/publication/281571413_COMPARISON_OF_HASH_STRATEGIES_FOR_FLOW-BASED_LOAD_BALANCING

请有人解释一下我是否这样做正确吗?

或者指出我一些解释如何做到这一点的好论文?

底线是:这取决于。如果流量中的源 IP 和目标 IP 分布良好,并且端口分布良好,则对于哈希表来说,其中任何一个都可能很好。但是,如果您碰巧正在查看在一小组 IP 地址之间有许多连接或具有很少不同端口的网络流量,情况会变得更加棘手。

通常,对于哈希表,哈希的结果不需要是完美的。这并不是说您需要完全消除冲突,您只是不希望它们频繁发生,或者导致许多条目共享一小组哈希桶,而许多其他哈希桶未使用。但这在很大程度上取决于您的应用程序以及网络流量的来源。通常,最好尽量减少对输入和设计的依赖,以应对最坏的情况。

通常采用的一种方法来最大程度地减少此类冲突,方法是找到一个快速、有效、非加密的通用哈希,然后将元组中的所有地址和端口布置在一个连续的缓冲区中,在缓冲区上运行哈希函数并将结果折叠到哈希表索引中。

从下面的第一个链接是这个定义:

非加密哈希函数将字符串作为输入并计算整数输出。哈希函数的理想属性是输出均匀分布在可能输出的域中,特别是对于相似的输入。与加密哈希函数不同,这些函数的设计不是为了承受攻击者查找冲突的努力。

(为了澄清最后一句话,这些哈希函数确实最大限度地减少了冲突;只是没有努力使它们抵抗可能导致构造冲突的加密分析。

看看这些页面,其中包含有关"最新"发展的大量信息:

  • http://blog.reverberate.org/2012/01/state-of-hash-functions-2012.html
  • http://www.burtleburtle.net/bob/hash/doobs.html

一般来说,这些哈希将比临时 XOR 实现慢,但比 SHA 和 MD5 等加密哈希快得多。当然,哈希函数的速度是你必须做出判断的 - 但根据我的经验,获取TCP/IP 5元组的哈希作为哈希表的索引很少会成为一个显着的性能瓶颈。通常还有其他处理部分在性能方面更昂贵 - 特别是如果你要做TCP流重组:这将需要大量的缓冲区和内存管理,数据复制等。

使用通用哈希函数的另一个优点是:当您准备好添加 IPv6 支持时,不需要新算法。您只需布置一个更大的缓冲区,将 16 字节的 IPv6 地址复制到其中,然后运行相同的哈希函数。

另请参阅软件工程SE中的相关问题,该问题的优势是SO的"现场": https://softwareengineering.stackexchange.com/q/49550/261672

最新更新