TCP listen socket inet_lookup_listener
netstat -atnp |grep 8080 tcp 0 0 192.168.1.208:8080 0.0.0.0:* LISTEN 109094/server tcp6 0 0 :::8080 :::* LISTEN 109094/server
在linux 3.9 后引入reuseport 就引入如上问题。sk_A
和sk_B
同时侦听8080端口;有时tcp syn进入去查找listen socket时,希望匹配到192.168.1.208:8080的sock;
但是由于当前使用的是port进行hash;最后不是自己想要的!
所以必须对内核lookup listener 进行改造,当时使用的是ip+port进行hask;可以解决上述问题。
今天来看新内核linux 5.10 是怎样处理的
根据代码可知:直接hashtable中进行查找,但是使用ip+port进行hash,在匹配时;ip不对就直接返回
struct sock *__inet_lookup_listener(struct net *net, struct inet_hashinfo *hashinfo, struct sk_buff *skb, int doff, const __be32 saddr, __be16 sport, const __be32 daddr, const unsigned short hnum, const int dif, const int sdif) { struct inet_listen_hashbucket *ilb2; struct sock *result = NULL; unsigned int hash2; /* Lookup redirect from BPF */ if (static_branch_unlikely(&bpf_sk_lookup_enabled)) { result = inet_lookup_run_bpf(net, hashinfo, skb, doff, saddr, sport, daddr, hnum); if (result) goto done; } hash2 = ipv4_portaddr_hash(net, daddr, hnum); ilb2 = inet_lhash2_bucket(hashinfo, hash2); result = inet_lhash2_lookup(net, ilb2, skb, doff, saddr, sport, daddr, hnum, dif, sdif); if (result) goto done; /* Lookup lhash2 with INADDR_ANY */ hash2 = ipv4_portaddr_hash(net, htonl(INADDR_ANY), hnum); ilb2 = inet_lhash2_bucket(hashinfo, hash2); result = inet_lhash2_lookup(net, ilb2, skb, doff, saddr, sport, htonl(INADDR_ANY), hnum, dif, sdif); done: if (IS_ERR(result)) return NULL; return result; }
inet: Add a 2nd listener hashtable (port+addr) inet_connection_sock.h
inet: Add a 2nd listener hashtable (port+addr) inet_hashtables.h
inet: Add a 2nd listener hashtable (port+addr) inet_hashtables.c
net: tcp: prefer listeners bound to an address inet_hashtables.c
http代理服务器(3-4-7层代理)-网络事件库公共组件、内核kernel驱动 摄像头驱动 tcpip网络协议栈、netfilter、bridge 好像看过!!!!
但行好事 莫问前程
--身高体重180的胖子