[TFRC]: Insert and Update routines for the Loss Interval Database

This provides an `insert' function for the Loss Interval database. It only 
inserts
when a loss is new, i.e. either 
 * no loss record has been allocated before (uninitialised) or
 * the most recent loss is in a different RTT than the last one.

For this purpose, the test from  [RFC 4342, 10.2] is used.

Signed-off-by: Gerrit Renker <[EMAIL PROTECTED]>
---
 net/dccp/ccids/ccid3.c             |   47 ------------------------------------
 net/dccp/ccids/lib/loss_interval.c |   48 +++++++++++++++++++++++++++++++++++++
 net/dccp/ccids/lib/loss_interval.h |    2 +
 3 files changed, 50 insertions(+), 47 deletions(-)

--- a/net/dccp/ccids/lib/loss_interval.h
+++ b/net/dccp/ccids/lib/loss_interval.h
@@ -67,6 +67,8 @@ static inline u8 tfrc_lh_length(struct t
        return min(lh->counter, (u8)LIH_SIZE);
 }
 
+extern int  tfrc_lh_interval_add(struct tfrc_loss_hist *, struct tfrc_rx_hist 
*,
+                                u32 (*first_li)(struct sock *), struct sock *);
 extern u8   tfrc_lh_update_i_mean(struct tfrc_loss_hist *lh, struct sk_buff *);
 extern void tfrc_lh_cleanup(struct tfrc_loss_hist *lh);
 
--- a/net/dccp/ccids/lib/loss_interval.c
+++ b/net/dccp/ccids/lib/loss_interval.c
@@ -120,6 +120,54 @@ u8 tfrc_lh_update_i_mean(struct tfrc_los
 }
 EXPORT_SYMBOL_GPL(tfrc_lh_update_i_mean);
 
+/* Determine if `new_loss' does begin a new loss interval [RFC 4342, 10.2] */
+static inline u8 tfrc_lh_is_new_loss(struct tfrc_loss_interval *cur,
+                                    struct tfrc_rx_hist_entry *new_loss)
+{
+       return  dccp_delta_seqno(cur->li_seqno, new_loss->seqno) > 0
+           && (cur->li_is_closed || SUB16(new_loss->ccval, cur->li_ccval) > 4);
+}
+
+/** tfrc_lh_interval_add  -  Insert new record into the Loss Interval database
+ * @lh:                   Loss Interval database
+ * @rh:                   Receive history containing a fresh loss event
+ * @calc_first_li: Caller-dependent routine to compute length of first interval
+ * @sk:                   Used by @calc_first_li in caller-specific way 
(subtyping)
+ * Updates I_mean and returns 1 if a new interval has in fact been added to 
@lh.
+ */
+int tfrc_lh_interval_add(struct tfrc_loss_hist *lh, struct tfrc_rx_hist *rh,
+                        u32 (*calc_first_li)(struct sock *), struct sock *sk)
+{
+       struct tfrc_loss_interval *cur = tfrc_lh_peek(lh), *new;
+
+       if (cur != NULL && !tfrc_lh_is_new_loss(cur, loss_prev(rh)))
+               return 0;
+
+       new = tfrc_lh_demand_next(lh);
+       if (unlikely(new == NULL)) {
+               DCCP_CRIT("Cannot allocate/add loss record.");
+               return 0;
+       }
+
+       new->li_seqno     = loss_prev(rh)->seqno;
+       new->li_ccval     = loss_prev(rh)->ccval;
+       new->li_is_closed = 0;
+
+       if (++lh->counter == 1)
+               lh->i_mean = new->li_length = (*calc_first_li)(sk);
+       else {
+               cur->li_length = dccp_delta_seqno(cur->li_seqno, new->li_seqno);
+               new->li_length = dccp_delta_seqno(new->li_seqno,
+                                                 last_rcv(rh)->seqno);
+               if (lh->counter > (2*LIH_SIZE))
+                       lh->counter -= LIH_SIZE;
+
+               tfrc_lh_calc_i_mean(lh);
+       }
+       return 1;
+}
+EXPORT_SYMBOL_GPL(tfrc_lh_interval_add);
+
 int __init li_init(void)
 {
        tfrc_lh_slab = kmem_cache_create("tfrc_loss_history",
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -782,53 +782,6 @@ static u32 ccid3_hc_rx_calc_first_li(str
        return p == 0? ~0U : scaled_div(1, p);
 }
 
-static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
-{
-       struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
-       struct dccp_li_hist_entry *head;
-       u64 seq_temp;
-
-       if (list_empty(&hcrx->ccid3hcrx_li_hist)) {
-               if (!dccp_li_hist_interval_new(ccid3_li_hist,
-                  &hcrx->ccid3hcrx_li_hist, seq_loss, win_loss))
-                       return;
-
-               head = list_entry(hcrx->ccid3hcrx_li_hist.next,
-                  struct dccp_li_hist_entry, dccplih_node);
-               head->dccplih_interval = ccid3_hc_rx_calc_first_li(sk);
-       } else {
-               struct dccp_li_hist_entry *entry;
-               struct list_head *tail;
-
-               head = list_entry(hcrx->ccid3hcrx_li_hist.next,
-                  struct dccp_li_hist_entry, dccplih_node);
-               /* FIXME win count check removed as was wrong */
-               /* should make this check with receive history */
-               /* and compare there as per section 10.2 of RFC4342 */
-
-               /* new loss event detected */
-               /* calculate last interval length */
-               seq_temp = dccp_delta_seqno(head->dccplih_seqno, seq_loss);
-               entry = dccp_li_hist_entry_new(ccid3_li_hist, GFP_ATOMIC);
-
-               if (entry == NULL) {
-                       DCCP_BUG("out of memory - can not allocate entry");
-                       return;
-               }
-
-               list_add(&entry->dccplih_node, &hcrx->ccid3hcrx_li_hist);
-
-               tail = hcrx->ccid3hcrx_li_hist.prev;
-               list_del(tail);
-               kmem_cache_free(ccid3_li_hist->dccplih_slab, tail);
-
-               /* Create the newest interval */
-               entry->dccplih_seqno = seq_loss;
-               entry->dccplih_interval = seq_temp;
-               entry->dccplih_win_count = win_loss;
-       }
-}
-
 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);
-
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