Commit 52036a43 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

ipv6: dccp: handle ICMP messages on DCCP_NEW_SYN_RECV request sockets

dccp_v6_err() can restrict lookups to ehash table, and not to listeners.

Note this patch creates the infrastructure, but this means that ICMP
messages for request sockets are ignored until complete conversion.
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 85645bab
...@@ -85,11 +85,12 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -85,11 +85,12 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
return; return;
} }
sk = inet6_lookup(net, &dccp_hashinfo, sk = __inet6_lookup_established(net, &dccp_hashinfo,
&hdr->daddr, dh->dccph_dport, &hdr->daddr, dh->dccph_dport,
&hdr->saddr, dh->dccph_sport, inet6_iif(skb)); &hdr->saddr, ntohs(dh->dccph_sport),
inet6_iif(skb));
if (sk == NULL) { if (!sk) {
ICMP6_INC_STATS_BH(net, __in6_dev_get(skb->dev), ICMP6_INC_STATS_BH(net, __in6_dev_get(skb->dev),
ICMP6_MIB_INERRORS); ICMP6_MIB_INERRORS);
return; return;
...@@ -99,6 +100,9 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -99,6 +100,9 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
inet_twsk_put(inet_twsk(sk)); inet_twsk_put(inet_twsk(sk));
return; return;
} }
seq = dccp_hdr_seq(dh);
if (sk->sk_state == DCCP_NEW_SYN_RECV)
return dccp_req_err(sk, seq);
bh_lock_sock(sk); bh_lock_sock(sk);
if (sock_owned_by_user(sk)) if (sock_owned_by_user(sk))
...@@ -108,7 +112,6 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -108,7 +112,6 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
goto out; goto out;
dp = dccp_sk(sk); dp = dccp_sk(sk);
seq = dccp_hdr_seq(dh);
if ((1 << sk->sk_state) & ~(DCCPF_REQUESTING | DCCPF_LISTEN) && if ((1 << sk->sk_state) & ~(DCCPF_REQUESTING | DCCPF_LISTEN) &&
!between48(seq, dp->dccps_awl, dp->dccps_awh)) { !between48(seq, dp->dccps_awl, dp->dccps_awh)) {
NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS);
...@@ -149,34 +152,6 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, ...@@ -149,34 +152,6 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
/* Might be for an request_sock */ /* Might be for an request_sock */
switch (sk->sk_state) { switch (sk->sk_state) {
struct request_sock *req;
case DCCP_LISTEN:
if (sock_owned_by_user(sk))
goto out;
req = inet6_csk_search_req(sk, dh->dccph_dport,
&hdr->daddr, &hdr->saddr,
inet6_iif(skb));
if (!req)
goto out;
/*
* ICMPs are not backlogged, hence we cannot get an established
* socket here.
*/
WARN_ON(req->sk != NULL);
if (!between48(seq, dccp_rsk(req)->dreq_iss,
dccp_rsk(req)->dreq_gss)) {
NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS);
reqsk_put(req);
goto out;
}
inet_csk_reqsk_queue_drop(sk, req);
reqsk_put(req);
goto out;
case DCCP_REQUESTING: case DCCP_REQUESTING:
case DCCP_RESPOND: /* Cannot happen. case DCCP_RESPOND: /* Cannot happen.
It can, it SYNs are crossed. --ANK */ It can, it SYNs are crossed. --ANK */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment