[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