|
@@ -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,
|
|
|
|
- &hdr->daddr, dh->dccph_dport,
|
|
|
|
- &hdr->saddr, dh->dccph_sport, inet6_iif(skb));
|
|
|
|
|
|
+ sk = __inet6_lookup_established(net, &dccp_hashinfo,
|
|
|
|
+ &hdr->daddr, dh->dccph_dport,
|
|
|
|
+ &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,
|
|
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,
|
|
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,
|
|
|
|
|
|
/* 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 */
|