* [PATCH 1/3][DCCP]: Do not process a packet twice when it's received in a state != DCCP_OPEN
@ 2006-01-02 16:53 Arnaldo Carvalho de Melo
2006-01-03 22:28 ` [PATCH 1/3][DCCP]: Do not process a packet twice when it's David S. Miller
0 siblings, 1 reply; 2+ messages in thread
From: Arnaldo Carvalho de Melo @ 2006-01-02 16:53 UTC (permalink / raw)
To: dccp
[-- Attachment #1: Type: text/plain, Size: 142 bytes --]
Hi David,
Please consider pulling from:
master.kernel.org:/pub/scm/linux/kernel/git/acme/net-2.6.16.git
Best Regards,
- Arnaldo
[-- Attachment #2: 1.patch --]
[-- Type: text/x-patch, Size: 4063 bytes --]
tree 66fbefd8cb4805458e537a3ea143006f8f242d8c
parent a90860f526898b77e91b6b38e8d266b0bcd6c443
author Arnaldo Carvalho de Melo <acme@mandriva.com> 1136217256 -0200
committer Arnaldo Carvalho de Melo <acme@mandriva.com> 1136217256 -0200
[DCCP]: Do not process a packet twice when it's received in a state != DCCP_OPEN.
When packets are received, the connection is either in DCCP_OPEN [fast-path] or
it isn't. If it's not [e.g. DCCP_PARTOPEN] upper layers will perform sanity
checks and parse options. If it is in DCCP_OPEN, dccp_rcv_established() will do
it. It is important not to re-parse options in dccp_rcv_established() when it
is not called from the fast-path. Else, fore example, the ack vector will be
added twice and the CCID will see the packet twice.
The solution is to always enfore sanity checks from the upper layers. When
packets arrive in the fast-path, sanity checks will be performed before calling
dccp_rcv_established().
Note(acme): I rewrote the patch to achieve the same result but keeping
dccp_rcv_established with the previous semantics and having it split into
__dccp_rcv_established, that doesn't does do any sanity check, code in state
!= DCCP_OPEN use this lighter version as they already do the sanity checks.
Signed-off-by: Andrea Bittau <a.bittau@cs.ucl.ac.uk>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
------------------------------------------------------------------------------
input.c | 56 ++++++++++++++++++++++++++++++++++----------------------
1 file changed, 34 insertions(+), 22 deletions(-)
------------------------------------------------------------------------------
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 55e921b..5e312b0 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -151,29 +151,12 @@ static int dccp_check_seqno(struct sock
return 0;
}
-int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
- const struct dccp_hdr *dh, const unsigned len)
+static inline int __dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
+ const struct dccp_hdr *dh,
+ const unsigned len)
{
struct dccp_sock *dp = dccp_sk(sk);
- if (dccp_check_seqno(sk, skb))
- goto discard;
-
- if (dccp_parse_options(sk, skb))
- goto discard;
-
- if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
- dccp_event_ack_recv(sk, skb);
-
- if (dp->dccps_options.dccpo_send_ack_vector &&
- dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
- DCCP_SKB_CB(skb)->dccpd_seq,
- DCCP_ACKVEC_STATE_RECEIVED))
- goto discard;
-
- ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
- ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
-
switch (dccp_hdr(skb)->dccph_type) {
case DCCP_PKT_DATAACK:
case DCCP_PKT_DATA:
@@ -250,6 +233,35 @@ discard:
return 0;
}
+int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
+ const struct dccp_hdr *dh, const unsigned len)
+{
+ struct dccp_sock *dp = dccp_sk(sk);
+
+ if (dccp_check_seqno(sk, skb))
+ goto discard;
+
+ if (dccp_parse_options(sk, skb))
+ goto discard;
+
+ if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
+ dccp_event_ack_recv(sk, skb);
+
+ if (dp->dccps_options.dccpo_send_ack_vector &&
+ dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
+ DCCP_SKB_CB(skb)->dccpd_seq,
+ DCCP_ACKVEC_STATE_RECEIVED))
+ goto discard;
+
+ ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
+ ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
+
+ return __dccp_rcv_established(sk, skb, dh, len);
+discard:
+ __kfree_skb(skb);
+ return 0;
+}
+
EXPORT_SYMBOL_GPL(dccp_rcv_established);
static int dccp_rcv_request_sent_state_process(struct sock *sk,
@@ -400,9 +412,9 @@ static int dccp_rcv_respond_partopen_sta
if (dh->dccph_type == DCCP_PKT_DATAACK ||
dh->dccph_type == DCCP_PKT_DATA) {
- dccp_rcv_established(sk, skb, dh, len);
+ __dccp_rcv_established(sk, skb, dh, len);
queued = 1; /* packet was queued
- (by dccp_rcv_established) */
+ (by __dccp_rcv_established) */
}
break;
}
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2006-01-03 22:28 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-01-02 16:53 [PATCH 1/3][DCCP]: Do not process a packet twice when it's received in a state != DCCP_OPEN Arnaldo Carvalho de Melo
2006-01-03 22:28 ` [PATCH 1/3][DCCP]: Do not process a packet twice when it's David S. Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox