summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo2005-08-14 01:36:01 +0200
committerDavid S. Miller2005-08-30 00:59:50 +0200
commit8649b0d4166e6e80ffa298e75abd8f2afdd491a6 (patch)
treee6024532d165f5dc9987fe38fb84cb2076c86100
parent[DCCP]: Introduce the DCCP Kernel hacking menu (diff)
downloadkernel-qcow2-linux-8649b0d4166e6e80ffa298e75abd8f2afdd491a6.tar.gz
kernel-qcow2-linux-8649b0d4166e6e80ffa298e75abd8f2afdd491a6.tar.xz
kernel-qcow2-linux-8649b0d4166e6e80ffa298e75abd8f2afdd491a6.zip
[DCCP]: Fix RESET handling in dccp_rcv_state_process
To avoid holding TIMEWAIT state for sockets in the LISTEN state. Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/dccp/input.c60
1 files changed, 42 insertions, 18 deletions
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 4b8638f153a5..9dadfc362511 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -402,7 +402,48 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
const int old_state = sk->sk_state;
int queued = 0;
- if (sk->sk_state != DCCP_LISTEN && sk->sk_state != DCCP_REQUESTING) {
+ /*
+ * Step 3: Process LISTEN state
+ * (Continuing from dccp_v4_do_rcv and dccp_v6_do_rcv)
+ *
+ * If S.state == LISTEN,
+ * If P.type == Request or P contains a valid Init Cookie
+ * option,
+ * * Must scan the packet's options to check for an Init
+ * Cookie. Only the Init Cookie is processed here,
+ * however; other options are processed in Step 8. This
+ * scan need only be performed if the endpoint uses Init
+ * Cookies *
+ * * Generate a new socket and switch to that socket *
+ * Set S := new socket for this port pair
+ * S.state = RESPOND
+ * Choose S.ISS (initial seqno) or set from Init Cookie
+ * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie
+ * Continue with S.state == RESPOND
+ * * A Response packet will be generated in Step 11 *
+ * Otherwise,
+ * Generate Reset(No Connection) unless P.type == Reset
+ * Drop packet and return
+ *
+ * NOTE: the check for the packet types is done in
+ * dccp_rcv_state_process
+ */
+ if (sk->sk_state == DCCP_LISTEN) {
+ if (dh->dccph_type == DCCP_PKT_REQUEST) {
+ if (dccp_v4_conn_request(sk, skb) < 0)
+ return 1;
+
+ /* FIXME: do congestion control initialization */
+ goto discard;
+ }
+ if (dh->dccph_type == DCCP_PKT_RESET)
+ goto discard;
+
+ /* Caller (dccp_v4_do_rcv) will send Reset(No Connection)*/
+ return 1;
+ }
+
+ if (sk->sk_state != DCCP_REQUESTING) {
if (dccp_check_seqno(sk, skb))
goto discard;
@@ -484,23 +525,6 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
case DCCP_CLOSED:
return 1;
- case DCCP_LISTEN:
- if (dh->dccph_type == DCCP_PKT_ACK ||
- dh->dccph_type == DCCP_PKT_DATAACK)
- return 1;
-
- if (dh->dccph_type == DCCP_PKT_RESET)
- goto discard;
-
- if (dh->dccph_type == DCCP_PKT_REQUEST) {
- if (dccp_v4_conn_request(sk, skb) < 0)
- return 1;
-
- /* FIXME: do congestion control initialization */
- goto discard;
- }
- goto discard;
-
case DCCP_REQUESTING:
/* FIXME: do congestion control initialization */