提交 dc7b3eb9 编写于 作者: G Grzegorz Lyczba 提交者: Pablo Neira Ayuso

ipvs: Fix reuse connection if real server is dead

Expire cached connection for new TCP/SCTP connection if real
server is down. Otherwise, IPVS uses the dead server for the
reused connection, instead of a new working one.
Signed-off-by: NGrzegorz Lyczba <grzegorz.lyczba@gmail.com>
Acked-by: NHans Schillstrom <hans@schillstrom.com>
Acked-by: NJulian Anastasov <ja@ssi.bg>
Signed-off-by: NSimon Horman <horms@verge.net.au>
Signed-off-by: NPablo Neira Ayuso <pablo@netfilter.org>
上级 4f36ea6e
......@@ -1001,6 +1001,32 @@ static inline int is_tcp_reset(const struct sk_buff *skb, int nh_len)
return th->rst;
}
static inline bool is_new_conn(const struct sk_buff *skb,
struct ip_vs_iphdr *iph)
{
switch (iph->protocol) {
case IPPROTO_TCP: {
struct tcphdr _tcph, *th;
th = skb_header_pointer(skb, iph->len, sizeof(_tcph), &_tcph);
if (th == NULL)
return false;
return th->syn;
}
case IPPROTO_SCTP: {
sctp_chunkhdr_t *sch, schunk;
sch = skb_header_pointer(skb, iph->len + sizeof(sctp_sctphdr_t),
sizeof(schunk), &schunk);
if (sch == NULL)
return false;
return sch->type == SCTP_CID_INIT;
}
default:
return false;
}
}
/* Handle response packets: rewrite addresses and send away...
*/
static unsigned int
......@@ -1612,6 +1638,15 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
* Check if the packet belongs to an existing connection entry
*/
cp = pp->conn_in_get(af, skb, &iph, 0);
if (unlikely(sysctl_expire_nodest_conn(ipvs)) && cp && cp->dest &&
unlikely(!atomic_read(&cp->dest->weight)) && !iph.fragoffs &&
is_new_conn(skb, &iph)) {
ip_vs_conn_expire_now(cp);
__ip_vs_conn_put(cp);
cp = NULL;
}
if (unlikely(!cp) && !iph.fragoffs) {
/* No (second) fragments need to enter here, as nf_defrag_ipv6
* replayed fragment zero will already have created the cp
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册