[DCCP] ccid3: Replace scaled division operations
[safe/jmp/linux-2.6] / net / dccp / input.c
index c81488f..7371a2f 100644 (file)
@@ -10,7 +10,6 @@
  *     2 of the License, or (at your option) any later version.
  */
 
-#include <linux/config.h>
 #include <linux/dccp.h>
 #include <linux/skbuff.h>
 
@@ -32,7 +31,7 @@ static void dccp_fin(struct sock *sk, struct sk_buff *skb)
 
 static void dccp_rcv_close(struct sock *sk, struct sk_buff *skb)
 {
-       dccp_v4_send_reset(sk, DCCP_RESET_CODE_CLOSED);
+       dccp_send_reset(sk, DCCP_RESET_CODE_CLOSED);
        dccp_fin(sk, skb);
        dccp_set_state(sk, DCCP_CLOSED);
        sk_wake_async(sk, 1, POLL_HUP);
@@ -56,11 +55,11 @@ static void dccp_rcv_closereq(struct sock *sk, struct sk_buff *skb)
        dccp_send_close(sk, 0);
 }
 
-static inline void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb)
+static void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb)
 {
        struct dccp_sock *dp = dccp_sk(sk);
 
-       if (dp->dccps_options.dccpo_send_ack_vector)
+       if (dccp_msk(sk)->dccpms_send_ack_vector)
                dccp_ackvec_check_rcv_ackno(dp->dccps_hc_rx_ackvec, sk,
                                            DCCP_SKB_CB(skb)->dccpd_ack_seq);
 }
@@ -129,21 +128,18 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb)
                     DCCP_PKT_WITHOUT_ACK_SEQ))
                        dp->dccps_gar = DCCP_SKB_CB(skb)->dccpd_ack_seq;
        } else {
-               LIMIT_NETDEBUG(KERN_WARNING "DCCP: Step 6 failed for %s packet, "
-                                           "(LSWL(%llu) <= P.seqno(%llu) <= S.SWH(%llu)) and "
-                                           "(P.ackno %s or LAWL(%llu) <= P.ackno(%llu) <= S.AWH(%llu), "
-                                           "sending SYNC...\n",
-                              dccp_packet_name(dh->dccph_type),
-                              (unsigned long long) lswl,
-                              (unsigned long long)
-                              DCCP_SKB_CB(skb)->dccpd_seq,
-                              (unsigned long long) dp->dccps_swh,
-                              (DCCP_SKB_CB(skb)->dccpd_ack_seq ==
+               DCCP_WARN("DCCP: Step 6 failed for %s packet, "
+                         "(LSWL(%llu) <= P.seqno(%llu) <= S.SWH(%llu)) and "
+                         "(P.ackno %s or LAWL(%llu) <= P.ackno(%llu) <= S.AWH(%llu), "
+                         "sending SYNC...\n",  dccp_packet_name(dh->dccph_type),
+                         (unsigned long long) lswl,
+                         (unsigned long long) DCCP_SKB_CB(skb)->dccpd_seq,
+                         (unsigned long long) dp->dccps_swh,
+                         (DCCP_SKB_CB(skb)->dccpd_ack_seq ==
                                DCCP_PKT_WITHOUT_ACK_SEQ) ? "doesn't exist" : "exists",
-                              (unsigned long long) lawl,
-                              (unsigned long long)
-                              DCCP_SKB_CB(skb)->dccpd_ack_seq,
-                              (unsigned long long) dp->dccps_awh);
+                         (unsigned long long) lawl,
+                         (unsigned long long) DCCP_SKB_CB(skb)->dccpd_ack_seq,
+                         (unsigned long long) dp->dccps_awh);
                dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, DCCP_PKT_SYNC);
                return -1;
        }
@@ -151,29 +147,11 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb)
        return 0;
 }
 
-int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
-                        const struct dccp_hdr *dh, const unsigned len)
+static 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:
@@ -235,11 +213,11 @@ send_sync:
                dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq,
                               DCCP_PKT_SYNCACK);
                /*
-                * From the draft:
+                * From RFC 4340, sec. 5.7
                 *
                 * As with DCCP-Ack packets, DCCP-Sync and DCCP-SyncAck packets
                 * MAY have non-zero-length application data areas, whose
-                * contents receivers MUST ignore.
+                * contents receivers MUST ignore.
                 */
                goto discard;
        }
@@ -250,6 +228,37 @@ 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 (dccp_msk(sk)->dccpms_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,
                                               struct sk_buff *skb,
                                               const struct dccp_hdr *dh,
@@ -286,6 +295,15 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
                        goto out_invalid_packet;
                }
 
+               if (dccp_parse_options(sk, skb))
+                       goto out_invalid_packet;
+
+                if (dccp_msk(sk)->dccpms_send_ack_vector &&
+                    dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
+                                    DCCP_SKB_CB(skb)->dccpd_seq,
+                                    DCCP_ACKVEC_STATE_RECEIVED))
+                        goto out_invalid_packet; /* FIXME: change error code */
+
                dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq;
                dccp_update_gsr(sk, dp->dccps_isr);
                /*
@@ -301,15 +319,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
                dccp_set_seqno(&dp->dccps_swl,
                               max48(dp->dccps_swl, dp->dccps_isr));
 
-               if (ccid_hc_rx_init(dp->dccps_hc_rx_ccid, sk) != 0 ||
-                   ccid_hc_tx_init(dp->dccps_hc_tx_ccid, sk) != 0) {
-                       ccid_hc_rx_exit(dp->dccps_hc_rx_ccid, sk);
-                       ccid_hc_tx_exit(dp->dccps_hc_tx_ccid, sk);
-                       /* FIXME: send appropriate RESET code */
-                       goto out_invalid_packet;
-               }
-
-               dccp_sync_mss(sk, dp->dccps_pmtu_cookie);
+               dccp_sync_mss(sk, icsk->icsk_pmtu_cookie);
 
                /*
                 *    Step 10: Process REQUEST state (second part)
@@ -398,9 +408,9 @@ static int dccp_rcv_respond_partopen_state_process(struct sock *sk,
 
                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;
        }
@@ -418,29 +428,25 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
 
        /*
         *  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 P.type == Request or P contains a valid Init Cookie option,
+        *            (* Must scan the packet's options to check for Init
+        *               Cookies.  Only Init Cookies are 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 Cookies
+        *            Initialize S.GAR := S.ISS
+        *            Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init
+        *            Cookies 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
         */
        if (sk->sk_state == DCCP_LISTEN) {
                if (dh->dccph_type == DCCP_PKT_REQUEST) {
@@ -472,14 +478,14 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                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);
-               ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
-
-               if (dp->dccps_options.dccpo_send_ack_vector &&
+               if (dccp_msk(sk)->dccpms_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);
        }
 
        /*
@@ -567,3 +573,5 @@ discard:
        }
        return 0;
 }
+
+EXPORT_SYMBOL_GPL(dccp_rcv_state_process);