[CCID 3]: New RX History Step 5 - CCID3 packet reception

This patch continues with the integration of the new RX history structure:
It takes care of
 1. recomputing p after the first loss occurred (RFC 3448, 6.1);
 2. marking history entries as `loss is indicated';
 3. sending the initial feedback (RFC 3448, 6.3)
    (Note: the state transition is now in ccid3_hc_rx_send_feedback());
 4. loss detection wrt NDUPACK (RFC 4342, 6.1).

Due to the amount of required changes, (4) was split into a subsequent patch.

Documentation on 
http://www.erg.abdn.ac.uk/users/gerrit/dccp/notes/ccid3_packet_reception/

Signed-off-by: Gerrit Renker <[EMAIL PROTECTED]>
---
 net/dccp/ccids/ccid3.c |  102 +++++++++++++++++++------------------------------
 1 file changed, 41 insertions(+), 61 deletions(-)

--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -685,6 +685,7 @@ static void ccid3_hc_rx_send_feedback(st
        case TFRC_RSTATE_NO_DATA:
                hcrx->ccid3hcrx_x_recv = 0;
                hcrx->ccid3hcrx_pinv   = ~0U;   /* see RFC 4342, 8.5 */
+               ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA);
                break;
        case TFRC_RSTATE_DATA:
                delta = ktime_delta(now, hcrx->ccid3hcrx_last_feedback);
@@ -886,13 +887,44 @@ detect_out:
 static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
 {
        struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
-       struct dccp_rx_hist_entry *packet;
-       struct timeval now;
-       u32 p_prev, loss;
        u32 sample, ndp = dccp_sk(sk)->dccps_options_received.dccpor_ndp,
            payload_size = skb->len - dccp_hdr(skb)->dccph_doff * 4;
        u8  is_data_packet = dccp_data_packet(skb), do_feedback = 0;
 
+       spin_lock(&hcrx->ccid3hcrx_hist.lock);
+
+       if (unlikely(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)) {
+               /* Handle initial feedback */
+               if (is_data_packet) {
+                       do_feedback = 1;
+                       ccid3_hc_rx_update_s(hcrx, payload_size);
+               }
+               goto update_records;
+       }
+
+       if (tfrc_rx_duplicate(&hcrx->ccid3hcrx_hist, skb))
+               goto done_receiving;
+
+       if (is_data_packet) {
+               ccid3_hc_rx_update_s(hcrx, payload_size);
+               hcrx->ccid3hcrx_bytes_recv += payload_size;
+       }
+
+       /*
+        *      Handle pending losses and otherwise check for new loss
+        */
+       if (tfrc_rx_loss_pending(&hcrx->ccid3hcrx_hist)) {
+               /*
+                * Loss Handling
+                *
+                * XXX: part of subsequent patch
+                */
+               goto done_receiving;
+       }
+
+       if (tfrc_rx_new_loss_indicated(&hcrx->ccid3hcrx_hist, skb, ndp))
+               goto update_records;
+
        /*
         *      Handle data packets: RTT sampling and monitoring p
         */
@@ -908,70 +940,18 @@ static void ccid3_hc_rx_packet_recv(stru
 
        }
 
-       packet = dccp_rx_hist_entry_new(ccid3_rx_hist, sk, ndp, skb, 
GFP_ATOMIC);
-       if (unlikely(packet == NULL)) {
-               DCCP_WARN("%s(%p), Not enough mem to add rx packet "
-                         "to history, consider it lost!\n", dccp_role(sk), sk);
-               return;
-       }
-
-       loss = ccid3_hc_rx_detect_loss(sk, packet);
-
-       ccid3_hc_rx_update_s(hcrx, payload_size);
-
-       switch (hcrx->ccid3hcrx_state) {
-       case TFRC_RSTATE_NO_DATA:
-               ccid3_pr_debug("%s(%p, state=%s), skb=%p, sending initial "
-                              "feedback\n", dccp_role(sk), sk,
-                              dccp_state_name(sk->sk_state), skb);
-               ccid3_hc_rx_send_feedback(sk, skb);
-               ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA);
-               return;
-       case TFRC_RSTATE_DATA:
-               hcrx->ccid3hcrx_bytes_recv += payload_size;
-               if (loss)
-                       break;
-
-/* XXX periodic feedback is resolved later on, the problem with the following
- *     code is that it introduces a second variable `_tstamp_last_ack'. A
- *     solution is presented later on in the patch set, for the moment, we
- *     comment this out.
-               dccp_timestamp(sk, &now);
-               if ((timeval_delta(&now, &hcrx->ccid3hcrx_tstamp_last_ack) -
-                    (suseconds_t)hcrx->ccid3hcrx_rtt) >= 0) {
-                       hcrx->ccid3hcrx_tstamp_last_ack = now;
-                       ccid3_hc_rx_send_feedback(sk);
-               }
-*/
-               return;
-       case TFRC_RSTATE_TERM:
-               DCCP_BUG("%s(%p) - Illegal state TERM", dccp_role(sk), sk);
-               return;
-       }
+       /* check if the periodic once-per-RTT feedback is due; RFC 4342, 10.3 */
+       if (SUB16(dccp_hdr(skb)->dccph_ccval, hcrx->ccid3hcrx_last_counter) > 3)
+               do_feedback = 1;
 
 update_records:
        tfrc_rx_hist_update(&hcrx->ccid3hcrx_hist, skb, ndp);
 
-       /* Dealing with packet loss */
-       ccid3_pr_debug("%s(%p, state=%s), data loss! Reacting...\n",
-                      dccp_role(sk), sk, dccp_state_name(sk->sk_state));
-
-       p_prev = hcrx->ccid3hcrx_p;
-
-       /* Calculate loss event rate */
-       if (!list_empty(&hcrx->ccid3hcrx_li_hist)) {
-               u32 i_mean = dccp_li_hist_calc_i_mean(&hcrx->ccid3hcrx_li_hist);
-
-               /* Scaling up by 1000000 as fixed decimal */
-               if (i_mean != 0)
-                       hcrx->ccid3hcrx_p = 1000000 / i_mean;
-       } else
-               DCCP_BUG("empty loss history");
+done_receiving:
+       spin_unlock(&hcrx->ccid3hcrx_hist.lock);
 
-       if (hcrx->ccid3hcrx_p > p_prev) {
+       if (do_feedback)
                ccid3_hc_rx_send_feedback(sk, skb);
-               return;
-       }
 }
 
 static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk)
-
To unsubscribe from this list: send the line "unsubscribe dccp" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to