[DCCP]: More precisely set reset_code when sending RESET packets
authorArnaldo Carvalho de Melo <acme@mandriva.com>
Fri, 16 Sep 2005 23:58:33 +0000 (16:58 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 16 Sep 2005 23:58:33 +0000 (16:58 -0700)
Moving the setting of DCCP_SKB_CB(skb)->dccpd_reset_code to the places
where events happen that trigger sending a RESET packet.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/dccp/input.c
net/dccp/ipv4.c

index c74034c..062e9f8 100644 (file)
@@ -384,9 +384,9 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
        }
 
 out_invalid_packet:
-       return 1; /* dccp_v4_do_rcv will send a reset, but...
-                    FIXME: the reset code should be
-                           DCCP_RESET_CODE_PACKET_ERROR */
+       /* dccp_v4_do_rcv will send a reset */
+       DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR;
+       return 1; 
 }
 
 static int dccp_rcv_respond_partopen_state_process(struct sock *sk,
@@ -433,6 +433,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                           struct dccp_hdr *dh, unsigned len)
 {
        struct dccp_sock *dp = dccp_sk(sk);
+       struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
        const int old_state = sk->sk_state;
        int queued = 0;
 
@@ -473,7 +474,8 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                if (dh->dccph_type == DCCP_PKT_RESET)
                        goto discard;
 
-               /* Caller (dccp_v4_do_rcv) will send Reset(No Connection)*/
+               /* Caller (dccp_v4_do_rcv) will send Reset */
+               dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION;
                return 1;
        }
 
@@ -487,8 +489,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                if (dccp_parse_options(sk, skb))
                        goto discard;
 
-               if (DCCP_SKB_CB(skb)->dccpd_ack_seq !=
-                   DCCP_PKT_WITHOUT_ACK_SEQ)
+               if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
                        dccp_event_ack_recv(sk, skb);
 
                ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
@@ -500,7 +501,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                 */
                if (dp->dccps_options.dccpo_send_ack_vector) {
                        if (dccp_ackpkts_add(dp->dccps_hc_rx_ackpkts, sk,
-                                            DCCP_SKB_CB(skb)->dccpd_seq,
+                                            dcb->dccpd_seq,
                                             DCCP_ACKPKTS_STATE_RECEIVED))
                                goto discard;
                        /*
@@ -551,8 +552,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                     dh->dccph_type == DCCP_PKT_REQUEST) ||
                    (sk->sk_state == DCCP_RESPOND &&
                     dh->dccph_type == DCCP_PKT_DATA)) {
-               dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq,
-                              DCCP_PKT_SYNC);
+               dccp_send_sync(sk, dcb->dccpd_seq, DCCP_PKT_SYNC);
                goto discard;
        } else if (dh->dccph_type == DCCP_PKT_CLOSEREQ) {
                dccp_rcv_closereq(sk, skb);
@@ -563,13 +563,13 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
        }
 
        if (unlikely(dh->dccph_type == DCCP_PKT_SYNC)) {
-               dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq,
-                              DCCP_PKT_SYNCACK);
+               dccp_send_sync(sk, dcb->dccpd_seq, DCCP_PKT_SYNCACK);
                goto discard;
        }
 
        switch (sk->sk_state) {
        case DCCP_CLOSED:
+               dcb->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION;
                return 1;
 
        case DCCP_REQUESTING:
index 2afaa46..e09907d 100644 (file)
@@ -669,12 +669,16 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
        struct dccp_request_sock *dreq;
        const __u32 saddr = skb->nh.iph->saddr;
        const __u32 daddr = skb->nh.iph->daddr;
+       struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
+       __u8 reset_code = DCCP_RESET_CODE_TOO_BUSY;
        struct dst_entry *dst = NULL;
 
        /* Never answer to DCCP_PKT_REQUESTs send to broadcast or multicast */
        if (((struct rtable *)skb->dst)->rt_flags &
-           (RTCF_BROADCAST | RTCF_MULTICAST))
+           (RTCF_BROADCAST | RTCF_MULTICAST)) {
+               reset_code = DCCP_RESET_CODE_NO_CONNECTION;
                goto drop;
+       }
 
        /*
         * TW buckets are converted to open requests without
@@ -718,7 +722,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
         * dccp_create_openreq_child.
         */
        dreq = dccp_rsk(req);
-       dreq->dreq_isr = DCCP_SKB_CB(skb)->dccpd_seq;
+       dreq->dreq_isr = dcb->dccpd_seq;
        dreq->dreq_iss = dccp_v4_init_sequence(sk, skb);
        dreq->dreq_service = dccp_hdr_request(skb)->dccph_req_service;
 
@@ -735,6 +739,7 @@ drop_and_free:
        __reqsk_free(req);
 drop:
        DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS);
+       dcb->dccpd_reset_code = reset_code;
        return -1;
 }
 
@@ -1005,7 +1010,6 @@ int dccp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
        return 0;
 
 reset:
-       DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION;
        dccp_v4_ctl_send_reset(skb);
 discard:
        kfree_skb(skb);