if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
return -1;
- avr = dccp_ackvec_record_new();
- if (avr == NULL)
- return -1;
-
dccp_timestamp(sk, &now);
elapsed_time = timeval_delta(&now, &av->dccpav_time) / 10;
- if (elapsed_time != 0)
- dccp_insert_option_elapsed_time(sk, skb, elapsed_time);
+ if (elapsed_time != 0 &&
+ dccp_insert_option_elapsed_time(sk, skb, elapsed_time))
+ return -1;
+
+ avr = dccp_ackvec_record_new();
+ if (avr == NULL)
+ return -1;
DCCP_SKB_CB(skb)->dccpd_opt_len += len;
struct dccp_ackvec *av = kmem_cache_alloc(dccp_ackvec_slab, priority);
if (av != NULL) {
- av->dccpav_buf_head =
- av->dccpav_buf_tail = DCCP_MAX_ACKVEC_LEN - 1;
+ av->dccpav_buf_head = DCCP_MAX_ACKVEC_LEN - 1;
av->dccpav_buf_ackno = DCCP_MAX_SEQNO + 1;
av->dccpav_buf_nonce = av->dccpav_buf_nonce = 0;
av->dccpav_ack_ptr = 0;
av->dccpav_time.tv_sec = 0;
av->dccpav_time.tv_usec = 0;
- av->dccpav_sent_len = av->dccpav_vec_len = 0;
+ av->dccpav_vec_len = 0;
INIT_LIST_HEAD(&av->dccpav_records);
}
{
if (unlikely(av == NULL))
return;
- WARN_ON(!list_empty(&av->dccpav_records));
+
+ if (!list_empty(&av->dccpav_records)) {
+ struct dccp_ackvec_record *avr, *next;
+
+ list_for_each_entry_safe(avr, next, &av->dccpav_records,
+ dccpavr_node) {
+ list_del_init(&avr->dccpavr_node);
+ dccp_ackvec_record_delete(avr);
+ }
+ }
+
kmem_cache_free(dccp_ackvec_slab, av);
}
av->dccpav_buf_ackno = ackno;
dccp_timestamp(sk, &av->dccpav_time);
out:
- dccp_pr_debug("");
return 0;
out_duplicate:
{
struct dccp_ackvec_record *next;
- av->dccpav_buf_tail = avr->dccpavr_ack_ptr - 1;
- if (av->dccpav_buf_tail == 0)
- av->dccpav_buf_tail = DCCP_MAX_ACKVEC_LEN - 1;
-
- av->dccpav_vec_len -= avr->dccpavr_sent_len;
+ /* sort out vector length */
+ if (av->dccpav_buf_head <= avr->dccpavr_ack_ptr)
+ av->dccpav_vec_len = avr->dccpavr_ack_ptr - av->dccpav_buf_head;
+ else
+ av->dccpav_vec_len = DCCP_MAX_ACKVEC_LEN - 1
+ - av->dccpav_buf_head
+ + avr->dccpavr_ack_ptr;
/* free records */
list_for_each_entry_safe_from(avr, next, &av->dccpav_records,
break;
found:
if (between48(avr->dccpavr_ack_seqno, ackno_end_rl, ackno)) {
- const u8 state = (*vector &
- DCCP_ACKVEC_STATE_MASK) >> 6;
+ const u8 state = *vector & DCCP_ACKVEC_STATE_MASK;
if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED) {
#ifdef CONFIG_IP_DCCP_DEBUG
struct dccp_sock *dp = dccp_sk(sk);
(unsigned long long)
avr->dccpavr_ack_ackno);
dccp_ackvec_throw_record(av, avr);
+ break;
}
/*
* If it wasn't received, continue scanning... we might