Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
ed1deb70
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
ed1deb70
编写于
11月 11, 2010
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'dccp' of
git://eden-feed.erg.abdn.ac.uk/net-next-2.6
上级
72cdd1d9
b3d14bff
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
225 addition
and
236 deletion
+225
-236
net/dccp/ackvec.c
net/dccp/ackvec.c
+83
-168
net/dccp/ackvec.h
net/dccp/ackvec.h
+65
-50
net/dccp/ccids/ccid2.c
net/dccp/ccids/ccid2.c
+5
-8
net/dccp/dccp.h
net/dccp/dccp.h
+7
-4
net/dccp/input.c
net/dccp/input.c
+2
-4
net/dccp/options.c
net/dccp/options.c
+63
-2
未找到文件。
net/dccp/ackvec.c
浏览文件 @
ed1deb70
/*
* net/dccp/ackvec.c
*
* An implementation of the DCCP protocol
* An implementation of Ack Vectors for the DCCP protocol
* Copyright (c) 2007 University of Aberdeen, Scotland, UK
* Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
*
* This program is free software; you can redistribute it and/or modify it
...
...
@@ -23,173 +24,93 @@
static
struct
kmem_cache
*
dccp_ackvec_slab
;
static
struct
kmem_cache
*
dccp_ackvec_record_slab
;
st
atic
struct
dccp_ackvec_record
*
dccp_ackvec_record_new
(
void
)
st
ruct
dccp_ackvec
*
dccp_ackvec_alloc
(
const
gfp_t
priority
)
{
struct
dccp_ackvec_record
*
avr
=
kmem_cache_alloc
(
dccp_ackvec_record_slab
,
GFP_ATOMIC
);
if
(
avr
!=
NULL
)
INIT_LIST_HEAD
(
&
avr
->
avr_node
);
struct
dccp_ackvec
*
av
=
kmem_cache_zalloc
(
dccp_ackvec_slab
,
priority
);
return
avr
;
if
(
av
!=
NULL
)
{
av
->
av_buf_head
=
av
->
av_buf_tail
=
DCCPAV_MAX_ACKVEC_LEN
-
1
;
INIT_LIST_HEAD
(
&
av
->
av_records
);
}
return
av
;
}
static
void
dccp_ackvec_
record_delete
(
struct
dccp_ackvec_record
*
avr
)
static
void
dccp_ackvec_
purge_records
(
struct
dccp_ackvec
*
av
)
{
if
(
unlikely
(
avr
==
NULL
))
return
;
/* Check if deleting a linked record */
WARN_ON
(
!
list_empty
(
&
avr
->
avr_node
)
);
kmem_cache_free
(
dccp_ackvec_record_slab
,
avr
);
struct
dccp_ackvec_record
*
cur
,
*
next
;
list_for_each_entry_safe
(
cur
,
next
,
&
av
->
av_records
,
avr_node
)
kmem_cache_free
(
dccp_ackvec_record_slab
,
cur
);
INIT_LIST_HEAD
(
&
av
->
av_records
);
}
static
void
dccp_ackvec_insert_avr
(
struct
dccp_ackvec
*
av
,
struct
dccp_ackvec_record
*
avr
)
void
dccp_ackvec_free
(
struct
dccp_ackvec
*
av
)
{
/*
* AVRs are sorted by seqno. Since we are sending them in order, we
* just add the AVR at the head of the list.
* -sorbo.
*/
if
(
!
list_empty
(
&
av
->
av_records
))
{
const
struct
dccp_ackvec_record
*
head
=
list_entry
(
av
->
av_records
.
next
,
struct
dccp_ackvec_record
,
avr_node
);
BUG_ON
(
before48
(
avr
->
avr_ack_seqno
,
head
->
avr_ack_seqno
));
if
(
likely
(
av
!=
NULL
))
{
dccp_ackvec_purge_records
(
av
);
kmem_cache_free
(
dccp_ackvec_slab
,
av
);
}
list_add
(
&
avr
->
avr_node
,
&
av
->
av_records
);
}
int
dccp_insert_option_ackvec
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
/**
* dccp_ackvec_update_records - Record information about sent Ack Vectors
* @av: Ack Vector records to update
* @seqno: Sequence number of the packet carrying the Ack Vector just sent
* @nonce_sum: The sum of all buffer nonces contained in the Ack Vector
*/
int
dccp_ackvec_update_records
(
struct
dccp_ackvec
*
av
,
u64
seqno
,
u8
nonce_sum
)
{
struct
dccp_sock
*
dp
=
dccp_sk
(
sk
);
struct
dccp_ackvec
*
av
=
dp
->
dccps_hc_rx_ackvec
;
/* Figure out how many options do we need to represent the ackvec */
const
u8
nr_opts
=
DIV_ROUND_UP
(
av
->
av_vec_len
,
DCCP_SINGLE_OPT_MAXLEN
);
u16
len
=
av
->
av_vec_len
+
2
*
nr_opts
,
i
;
u32
elapsed_time
;
const
unsigned
char
*
tail
,
*
from
;
unsigned
char
*
to
;
struct
dccp_ackvec_record
*
avr
;
suseconds_t
delta
;
if
(
DCCP_SKB_CB
(
skb
)
->
dccpd_opt_len
+
len
>
DCCP_MAX_OPT_LEN
)
return
-
1
;
delta
=
ktime_us_delta
(
ktime_get_real
(),
av
->
av_time
);
elapsed_time
=
delta
/
10
;
if
(
elapsed_time
!=
0
&&
dccp_insert_option_elapsed_time
(
skb
,
elapsed_time
))
return
-
1
;
avr
=
dccp_ackvec_record_new
();
avr
=
kmem_cache_alloc
(
dccp_ackvec_record_slab
,
GFP_ATOMIC
);
if
(
avr
==
NULL
)
return
-
1
;
DCCP_SKB_CB
(
skb
)
->
dccpd_opt_len
+=
len
;
to
=
skb_push
(
skb
,
len
);
len
=
av
->
av_vec_len
;
from
=
av
->
av_buf
+
av
->
av_buf_head
;
tail
=
av
->
av_buf
+
DCCP_MAX_ACKVEC_LEN
;
for
(
i
=
0
;
i
<
nr_opts
;
++
i
)
{
int
copylen
=
len
;
if
(
len
>
DCCP_SINGLE_OPT_MAXLEN
)
copylen
=
DCCP_SINGLE_OPT_MAXLEN
;
*
to
++
=
DCCPO_ACK_VECTOR_0
;
*
to
++
=
copylen
+
2
;
/* Check if buf_head wraps */
if
(
from
+
copylen
>
tail
)
{
const
u16
tailsize
=
tail
-
from
;
memcpy
(
to
,
from
,
tailsize
);
to
+=
tailsize
;
len
-=
tailsize
;
copylen
-=
tailsize
;
from
=
av
->
av_buf
;
}
memcpy
(
to
,
from
,
copylen
);
from
+=
copylen
;
to
+=
copylen
;
len
-=
copylen
;
}
return
-
ENOBUFS
;
avr
->
avr_ack_seqno
=
seqno
;
avr
->
avr_ack_ptr
=
av
->
av_buf_head
;
avr
->
avr_ack_ackno
=
av
->
av_buf_ackno
;
avr
->
avr_ack_nonce
=
nonce_sum
;
avr
->
avr_ack_runlen
=
dccp_ackvec_runlen
(
av
->
av_buf
+
av
->
av_buf_head
);
/*
* From RFC 4340, A.2:
*
* For each acknowledgement it sends, the HC-Receiver will add an
* acknowledgement record. ack_seqno will equal the HC-Receiver
* sequence number it used for the ack packet; ack_ptr will equal
* buf_head; ack_ackno will equal buf_ackno; and ack_nonce will
* equal buf_nonce.
* When the buffer overflows, we keep no more than one record. This is
* the simplest way of disambiguating sender-Acks dating from before the
* overflow from sender-Acks which refer to after the overflow; a simple
* solution is preferable here since we are handling an exception.
*/
avr
->
avr_ack_seqno
=
DCCP_SKB_CB
(
skb
)
->
dccpd_seq
;
avr
->
avr_ack_ptr
=
av
->
av_buf_head
;
avr
->
avr_ack_ackno
=
av
->
av_buf_ackno
;
avr
->
avr_ack_nonce
=
av
->
av_buf_nonce
;
avr
->
avr_sent_len
=
av
->
av_vec_len
;
dccp_ackvec_insert_avr
(
av
,
avr
);
if
(
av
->
av_overflow
)
dccp_ackvec_purge_records
(
av
)
;
/*
* Since GSS is incremented for each packet, the list is automatically
* arranged in descending order of @ack_seqno.
*/
list_add
(
&
avr
->
avr_node
,
&
av
->
av_records
);
dccp_pr_debug
(
"%s ACK Vector 0, len=%d, ack_seqno=%llu, "
"ack_ackno=%llu
\n
"
,
dccp_role
(
sk
),
avr
->
avr_sent_len
,
dccp_pr_debug
(
"Added Vector, ack_seqno=%llu, ack_ackno=%llu (rl=%u)
\n
"
,
(
unsigned
long
long
)
avr
->
avr_ack_seqno
,
(
unsigned
long
long
)
avr
->
avr_ack_ackno
);
(
unsigned
long
long
)
avr
->
avr_ack_ackno
,
avr
->
avr_ack_runlen
);
return
0
;
}
struct
dccp_ackvec
*
dccp_ackvec_alloc
(
const
gfp_t
priority
)
{
struct
dccp_ackvec
*
av
=
kmem_cache_alloc
(
dccp_ackvec_slab
,
priority
);
if
(
av
!=
NULL
)
{
av
->
av_buf_head
=
DCCP_MAX_ACKVEC_LEN
-
1
;
av
->
av_buf_ackno
=
UINT48_MAX
+
1
;
av
->
av_buf_nonce
=
0
;
av
->
av_time
=
ktime_set
(
0
,
0
);
av
->
av_vec_len
=
0
;
INIT_LIST_HEAD
(
&
av
->
av_records
);
}
return
av
;
}
void
dccp_ackvec_free
(
struct
dccp_ackvec
*
av
)
/*
* Buffer index and length computation using modulo-buffersize arithmetic.
* Note that, as pointers move from right to left, head is `before' tail.
*/
static
inline
u16
__ackvec_idx_add
(
const
u16
a
,
const
u16
b
)
{
if
(
unlikely
(
av
==
NULL
))
return
;
if
(
!
list_empty
(
&
av
->
av_records
))
{
struct
dccp_ackvec_record
*
avr
,
*
next
;
list_for_each_entry_safe
(
avr
,
next
,
&
av
->
av_records
,
avr_node
)
{
list_del_init
(
&
avr
->
avr_node
);
dccp_ackvec_record_delete
(
avr
);
}
}
kmem_cache_free
(
dccp_ackvec_slab
,
av
);
return
(
a
+
b
)
%
DCCPAV_MAX_ACKVEC_LEN
;
}
static
inline
u8
dccp_ackvec_state
(
const
struct
dccp_ackvec
*
av
,
const
u32
index
)
static
inline
u16
__ackvec_idx_sub
(
const
u16
a
,
const
u16
b
)
{
return
av
->
av_buf
[
index
]
&
DCCP_ACKVEC_STATE_MASK
;
return
__ackvec_idx_add
(
a
,
DCCPAV_MAX_ACKVEC_LEN
-
b
)
;
}
static
inline
u8
dccp_ackvec_len
(
const
struct
dccp_ackvec
*
av
,
const
u32
index
)
u16
dccp_ackvec_buflen
(
const
struct
dccp_ackvec
*
av
)
{
return
av
->
av_buf
[
index
]
&
DCCP_ACKVEC_LEN_MASK
;
if
(
unlikely
(
av
->
av_overflow
))
return
DCCPAV_MAX_ACKVEC_LEN
;
return
__ackvec_idx_sub
(
av
->
av_buf_tail
,
av
->
av_buf_head
);
}
/*
...
...
@@ -204,7 +125,7 @@ static inline int dccp_ackvec_set_buf_head_state(struct dccp_ackvec *av,
long
gap
;
long
new_head
;
if
(
av
->
av_vec_len
+
packets
>
DCCP_MAX_ACKVEC_LEN
)
if
(
av
->
av_vec_len
+
packets
>
DCCP
AV
_MAX_ACKVEC_LEN
)
return
-
ENOBUFS
;
gap
=
packets
-
1
;
...
...
@@ -212,18 +133,18 @@ static inline int dccp_ackvec_set_buf_head_state(struct dccp_ackvec *av,
if
(
new_head
<
0
)
{
if
(
gap
>
0
)
{
memset
(
av
->
av_buf
,
DCCP
_ACKVEC_STATE
_NOT_RECEIVED
,
memset
(
av
->
av_buf
,
DCCP
AV
_NOT_RECEIVED
,
gap
+
new_head
+
1
);
gap
=
-
new_head
;
}
new_head
+=
DCCP_MAX_ACKVEC_LEN
;
new_head
+=
DCCP
AV
_MAX_ACKVEC_LEN
;
}
av
->
av_buf_head
=
new_head
;
if
(
gap
>
0
)
memset
(
av
->
av_buf
+
av
->
av_buf_head
+
1
,
DCCP
_ACKVEC_STATE
_NOT_RECEIVED
,
gap
);
DCCP
AV
_NOT_RECEIVED
,
gap
);
av
->
av_buf
[
av
->
av_buf_head
]
=
state
;
av
->
av_vec_len
+=
packets
;
...
...
@@ -236,6 +157,8 @@ static inline int dccp_ackvec_set_buf_head_state(struct dccp_ackvec *av,
int
dccp_ackvec_add
(
struct
dccp_ackvec
*
av
,
const
struct
sock
*
sk
,
const
u64
ackno
,
const
u8
state
)
{
u8
*
cur_head
=
av
->
av_buf
+
av
->
av_buf_head
,
*
buf_end
=
av
->
av_buf
+
DCCPAV_MAX_ACKVEC_LEN
;
/*
* Check at the right places if the buffer is full, if it is, tell the
* caller to start dropping packets till the HC-Sender acks our ACK
...
...
@@ -260,7 +183,7 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
/* See if this is the first ackno being inserted */
if
(
av
->
av_vec_len
==
0
)
{
av
->
av_buf
[
av
->
av_buf_head
]
=
state
;
*
cur_head
=
state
;
av
->
av_vec_len
=
1
;
}
else
if
(
after48
(
ackno
,
av
->
av_buf_ackno
))
{
const
u64
delta
=
dccp_delta_seqno
(
av
->
av_buf_ackno
,
ackno
);
...
...
@@ -269,10 +192,9 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
* Look if the state of this packet is the same as the
* previous ackno and if so if we can bump the head len.
*/
if
(
delta
==
1
&&
dccp_ackvec_state
(
av
,
av
->
av_buf_head
)
==
state
&&
dccp_ackvec_len
(
av
,
av
->
av_buf_head
)
<
DCCP_ACKVEC_LEN_MASK
)
av
->
av_buf
[
av
->
av_buf_head
]
++
;
if
(
delta
==
1
&&
dccp_ackvec_state
(
cur_head
)
==
state
&&
dccp_ackvec_runlen
(
cur_head
)
<
DCCPAV_MAX_RUNLEN
)
*
cur_head
+=
1
;
else
if
(
dccp_ackvec_set_buf_head_state
(
av
,
delta
,
state
))
return
-
ENOBUFS
;
}
else
{
...
...
@@ -285,21 +207,17 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
* could reduce the complexity of this scan.)
*/
u64
delta
=
dccp_delta_seqno
(
ackno
,
av
->
av_buf_ackno
);
u32
index
=
av
->
av_buf_head
;
while
(
1
)
{
const
u8
len
=
dccp_ackvec_len
(
av
,
index
);
const
u8
av_state
=
dccp_ackvec_state
(
av
,
index
);
const
u8
len
=
dccp_ackvec_runlen
(
cur_head
);
/*
* valid packets not yet in av_buf have a reserved
* entry, with a len equal to 0.
*/
if
(
av_state
==
DCCP_ACKVEC_STATE_NOT_RECEIVED
&&
len
==
0
&&
delta
==
0
)
{
/* Found our
reserved seat! */
if
(
*
cur_head
==
DCCPAV_NOT_RECEIVED
&&
delta
==
0
)
{
dccp_pr_debug
(
"Found %llu reserved seat!
\n
"
,
(
unsigned
long
long
)
ackno
);
av
->
av_buf
[
index
]
=
state
;
*
cur_head
=
state
;
goto
out
;
}
/* len == 0 means one packet */
...
...
@@ -307,13 +225,12 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
goto
out_duplicate
;
delta
-=
len
+
1
;
if
(
++
index
==
DCCP_MAX_ACKVEC_LEN
)
index
=
0
;
if
(
++
cur_head
==
buf_end
)
cur_head
=
av
->
av_buf
;
}
}
av
->
av_buf_ackno
=
ackno
;
av
->
av_time
=
ktime_get_real
();
out:
return
0
;
...
...
@@ -333,13 +250,13 @@ static void dccp_ackvec_throw_record(struct dccp_ackvec *av,
if
(
av
->
av_buf_head
<=
avr
->
avr_ack_ptr
)
av
->
av_vec_len
=
avr
->
avr_ack_ptr
-
av
->
av_buf_head
;
else
av
->
av_vec_len
=
DCCP_MAX_ACKVEC_LEN
-
1
-
av
->
av_vec_len
=
DCCP
AV
_MAX_ACKVEC_LEN
-
1
-
av
->
av_buf_head
+
avr
->
avr_ack_ptr
;
/* free records */
list_for_each_entry_safe_from
(
avr
,
next
,
&
av
->
av_records
,
avr_node
)
{
list_del
_init
(
&
avr
->
avr_node
);
dccp_ackvec_record_delete
(
avr
);
list_del
(
&
avr
->
avr_node
);
kmem_cache_free
(
dccp_ackvec_record_slab
,
avr
);
}
}
...
...
@@ -357,7 +274,7 @@ void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av, struct sock *sk,
if
(
ackno
==
avr
->
avr_ack_seqno
)
{
dccp_pr_debug
(
"%s ACK packet 0, len=%d, ack_seqno=%llu, "
"ack_ackno=%llu, ACKED!
\n
"
,
dccp_role
(
sk
),
1
,
dccp_role
(
sk
),
avr
->
avr_ack_runlen
,
(
unsigned
long
long
)
avr
->
avr_ack_seqno
,
(
unsigned
long
long
)
avr
->
avr_ack_ackno
);
dccp_ackvec_throw_record
(
av
,
avr
);
...
...
@@ -387,7 +304,7 @@ static void dccp_ackvec_check_rcv_ackvector(struct dccp_ackvec *av,
*/
avr
=
list_entry
(
av
->
av_records
.
next
,
struct
dccp_ackvec_record
,
avr_node
);
while
(
i
--
)
{
const
u8
rl
=
*
vector
&
DCCP_ACKVEC_LEN_MASK
;
const
u8
rl
=
dccp_ackvec_runlen
(
vector
)
;
u64
ackno_end_rl
;
dccp_set_seqno
(
&
ackno_end_rl
,
*
ackno
-
rl
);
...
...
@@ -404,8 +321,7 @@ static void dccp_ackvec_check_rcv_ackvector(struct dccp_ackvec *av,
break
;
found:
if
(
between48
(
avr
->
avr_ack_seqno
,
ackno_end_rl
,
*
ackno
))
{
const
u8
state
=
*
vector
&
DCCP_ACKVEC_STATE_MASK
;
if
(
state
!=
DCCP_ACKVEC_STATE_NOT_RECEIVED
)
{
if
(
dccp_ackvec_state
(
vector
)
!=
DCCPAV_NOT_RECEIVED
)
{
dccp_pr_debug
(
"%s ACK vector 0, len=%d, "
"ack_seqno=%llu, ack_ackno=%llu, "
"ACKED!
\n
"
,
...
...
@@ -448,10 +364,9 @@ int __init dccp_ackvec_init(void)
if
(
dccp_ackvec_slab
==
NULL
)
goto
out_err
;
dccp_ackvec_record_slab
=
kmem_cache_create
(
"dccp_ackvec_record"
,
sizeof
(
struct
dccp_ackvec_record
),
0
,
SLAB_HWCACHE_ALIGN
,
NULL
);
dccp_ackvec_record_slab
=
kmem_cache_create
(
"dccp_ackvec_record"
,
sizeof
(
struct
dccp_ackvec_record
),
0
,
SLAB_HWCACHE_ALIGN
,
NULL
);
if
(
dccp_ackvec_record_slab
==
NULL
)
goto
out_destroy_slab
;
...
...
net/dccp/ackvec.h
浏览文件 @
ed1deb70
...
...
@@ -3,9 +3,9 @@
/*
* net/dccp/ackvec.h
*
* An implementation of the DCCP protocol
* An implementation of Ack Vectors for the DCCP protocol
* Copyright (c) 2007 University of Aberdeen, Scotland, UK
* Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@mandriva.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
...
...
@@ -13,75 +13,89 @@
#include <linux/dccp.h>
#include <linux/compiler.h>
#include <linux/ktime.h>
#include <linux/list.h>
#include <linux/types.h>
/* We can spread an ack vector across multiple options */
#define DCCP_MAX_ACKVEC_LEN (DCCP_SINGLE_OPT_MAXLEN * 2)
/*
* Ack Vector buffer space is static, in multiples of %DCCP_SINGLE_OPT_MAXLEN,
* the maximum size of a single Ack Vector. Setting %DCCPAV_NUM_ACKVECS to 1
* will be sufficient for most cases of low Ack Ratios, using a value of 2 gives
* more headroom if Ack Ratio is higher or when the sender acknowledges slowly.
* The maximum value is bounded by the u16 types for indices and functions.
*/
#define DCCPAV_NUM_ACKVECS 2
#define DCCPAV_MAX_ACKVEC_LEN (DCCP_SINGLE_OPT_MAXLEN * DCCPAV_NUM_ACKVECS)
/* Estimated minimum average Ack Vector length - used for updating MPS */
#define DCCPAV_MIN_OPTLEN 16
#define DCCP_ACKVEC_STATE_RECEIVED 0
#define DCCP_ACKVEC_STATE_ECN_MARKED (1 << 6)
#define DCCP_ACKVEC_STATE_NOT_RECEIVED (3 << 6)
enum
dccp_ackvec_states
{
DCCPAV_RECEIVED
=
0x00
,
DCCPAV_ECN_MARKED
=
0x40
,
DCCPAV_RESERVED
=
0x80
,
DCCPAV_NOT_RECEIVED
=
0xC0
};
#define DCCPAV_MAX_RUNLEN 0x3F
#define DCCP_ACKVEC_STATE_MASK 0xC0
/* 11000000 */
#define DCCP_ACKVEC_LEN_MASK 0x3F
/* 00111111 */
static
inline
u8
dccp_ackvec_runlen
(
const
u8
*
cell
)
{
return
*
cell
&
DCCPAV_MAX_RUNLEN
;
}
/** struct dccp_ackvec - ack vector
*
* This data structure is the one defined in RFC 4340, Appendix A.
*
* @av_buf_head - circular buffer head
* @av_buf_tail - circular buffer tail
* @av_buf_ackno - ack # of the most recent packet acknowledgeable in the
* buffer (i.e. %av_buf_head)
* @av_buf_nonce - the one-bit sum of the ECN Nonces on all packets acked
* by the buffer with State 0
*
* Additionally, the HC-Receiver must keep some information about the
* Ack Vectors it has recently sent. For each packet sent carrying an
* Ack Vector, it remembers four variables:
static
inline
u8
dccp_ackvec_state
(
const
u8
*
cell
)
{
return
*
cell
&
~
DCCPAV_MAX_RUNLEN
;
}
/** struct dccp_ackvec - Ack Vector main data structure
*
*
@av_records - list of dccp_ackvec_record
*
@av_ack_nonce - the one-bit sum of the ECN Nonces for all State
0.
*
This implements a fixed-size circular buffer within an array and is largely
*
based on Appendix A of RFC 434
0.
*
* @av_time - the time in usecs
* @av_buf - circular buffer of acknowledgeable packets
* @av_buf: circular buffer storage area
* @av_buf_head: head index; begin of live portion in @av_buf
* @av_buf_tail: tail index; first index _after_ the live portion in @av_buf
* @av_buf_ackno: highest seqno of acknowledgeable packet recorded in @av_buf
* @av_tail_ackno: lowest seqno of acknowledgeable packet recorded in @av_buf
* @av_buf_nonce: ECN nonce sums, each covering subsequent segments of up to
* %DCCP_SINGLE_OPT_MAXLEN cells in the live portion of @av_buf
* @av_overflow: if 1 then buf_head == buf_tail indicates buffer wraparound
* @av_records: list of %dccp_ackvec_record (Ack Vectors sent previously)
* @av_veclen: length of the live portion of @av_buf
*/
struct
dccp_ackvec
{
u64
av_buf_ackno
;
struct
list_head
av_records
;
ktime_t
av_time
;
u8
av_buf
[
DCCPAV_MAX_ACKVEC_LEN
];
u16
av_buf_head
;
u16
av_buf_tail
;
u64
av_buf_ackno
:
48
;
u64
av_tail_ackno
:
48
;
bool
av_buf_nonce
[
DCCPAV_NUM_ACKVECS
];
u8
av_overflow
:
1
;
struct
list_head
av_records
;
u16
av_vec_len
;
u8
av_buf_nonce
;
u8
av_ack_nonce
;
u8
av_buf
[
DCCP_MAX_ACKVEC_LEN
];
};
/** struct dccp_ackvec_record -
ack vector record
/** struct dccp_ackvec_record -
Records information about sent Ack Vectors
*
* ACK vector record as defined in Appendix A of spec.
* These list entries define the additional information which the HC-Receiver
* keeps about recently-sent Ack Vectors; again refer to RFC 4340, Appendix A.
*
* The list is sorted by avr_ack_seqno
* @avr_node: the list node in @av_records
* @avr_ack_seqno: sequence number of the packet the Ack Vector was sent on
* @avr_ack_ackno: the Ack number that this record/Ack Vector refers to
* @avr_ack_ptr: pointer into @av_buf where this record starts
* @avr_ack_runlen: run length of @avr_ack_ptr at the time of sending
* @avr_ack_nonce: the sum of @av_buf_nonce's at the time this record was sent
*
* @avr_node - node in av_records
* @avr_ack_seqno - sequence number of the packet this record was sent on
* @avr_ack_ackno - sequence number being acknowledged
* @avr_ack_ptr - pointer into av_buf where this record starts
* @avr_ack_nonce - av_ack_nonce at the time this record was sent
* @avr_sent_len - lenght of the record in av_buf
* The list as a whole is sorted in descending order by @avr_ack_seqno.
*/
struct
dccp_ackvec_record
{
struct
list_head
avr_node
;
u64
avr_ack_seqno
;
u64
avr_ack_ackno
;
u64
avr_ack_seqno
:
48
;
u64
avr_ack_ackno
:
48
;
u16
avr_ack_ptr
;
u
16
avr_sent_
len
;
u8
avr_ack_nonce
;
u
8
avr_ack_run
len
;
u8
avr_ack_nonce
:
1
;
};
struct
sock
;
...
...
@@ -102,10 +116,11 @@ extern int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb,
u64
*
ackno
,
const
u8
opt
,
const
u8
*
value
,
const
u8
len
);
extern
int
dccp_insert_option_ackvec
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
);
extern
int
dccp_ackvec_update_records
(
struct
dccp_ackvec
*
av
,
u64
seq
,
u8
sum
);
extern
u16
dccp_ackvec_buflen
(
const
struct
dccp_ackvec
*
av
);
static
inline
int
dccp_ackvec_pending
(
const
struct
dccp_ackvec
*
av
)
static
inline
bool
dccp_ackvec_is_empty
(
const
struct
dccp_ackvec
*
av
)
{
return
av
->
av_
vec_len
;
return
av
->
av_
overflow
==
0
&&
av
->
av_buf_head
==
av
->
av_buf_tail
;
}
#endif
/* _ACKVEC_H */
net/dccp/ccids/ccid2.c
浏览文件 @
ed1deb70
...
...
@@ -513,8 +513,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
&
vector
,
&
veclen
))
!=
-
1
)
{
/* go through this ack vector */
while
(
veclen
--
)
{
const
u8
rl
=
*
vector
&
DCCP_ACKVEC_LEN_MASK
;
u64
ackno_end_rl
=
SUB48
(
ackno
,
rl
);
u64
ackno_end_rl
=
SUB48
(
ackno
,
dccp_ackvec_runlen
(
vector
));
ccid2_pr_debug
(
"ackvec start:%llu end:%llu
\n
"
,
(
unsigned
long
long
)
ackno
,
...
...
@@ -537,17 +536,15 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
* run length
*/
while
(
between48
(
seqp
->
ccid2s_seq
,
ackno_end_rl
,
ackno
))
{
const
u8
state
=
*
vector
&
DCCP_ACKVEC_STATE_MASK
;
const
u8
state
=
dccp_ackvec_state
(
vector
);
/* new packet received or marked */
if
(
state
!=
DCCP
_ACKVEC_STATE
_NOT_RECEIVED
&&
if
(
state
!=
DCCP
AV
_NOT_RECEIVED
&&
!
seqp
->
ccid2s_acked
)
{
if
(
state
==
DCCP_ACKVEC_STATE_ECN_MARKED
)
{
if
(
state
==
DCCPAV_ECN_MARKED
)
ccid2_congestion_event
(
sk
,
seqp
);
}
else
else
ccid2_new_ack
(
sk
,
seqp
,
&
maxincr
);
...
...
net/dccp/dccp.h
浏览文件 @
ed1deb70
...
...
@@ -457,12 +457,15 @@ static inline void dccp_update_gss(struct sock *sk, u64 seq)
dp
->
dccps_awh
=
dp
->
dccps_gss
;
}
static
inline
int
dccp_ackvec_pending
(
const
struct
sock
*
sk
)
{
return
dccp_sk
(
sk
)
->
dccps_hc_rx_ackvec
!=
NULL
&&
!
dccp_ackvec_is_empty
(
dccp_sk
(
sk
)
->
dccps_hc_rx_ackvec
);
}
static
inline
int
dccp_ack_pending
(
const
struct
sock
*
sk
)
{
const
struct
dccp_sock
*
dp
=
dccp_sk
(
sk
);
return
(
dp
->
dccps_hc_rx_ackvec
!=
NULL
&&
dccp_ackvec_pending
(
dp
->
dccps_hc_rx_ackvec
))
||
inet_csk_ack_scheduled
(
sk
);
return
dccp_ackvec_pending
(
sk
)
||
inet_csk_ack_scheduled
(
sk
);
}
extern
int
dccp_feat_finalise_settings
(
struct
dccp_sock
*
dp
);
...
...
net/dccp/input.c
浏览文件 @
ed1deb70
...
...
@@ -378,8 +378,7 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
if
(
dp
->
dccps_hc_rx_ackvec
!=
NULL
&&
dccp_ackvec_add
(
dp
->
dccps_hc_rx_ackvec
,
sk
,
DCCP_SKB_CB
(
skb
)
->
dccpd_seq
,
DCCP_ACKVEC_STATE_RECEIVED
))
DCCP_SKB_CB
(
skb
)
->
dccpd_seq
,
DCCPAV_RECEIVED
))
goto
discard
;
dccp_deliver_input_to_ccids
(
sk
,
skb
);
...
...
@@ -637,8 +636,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
if
(
dp
->
dccps_hc_rx_ackvec
!=
NULL
&&
dccp_ackvec_add
(
dp
->
dccps_hc_rx_ackvec
,
sk
,
DCCP_SKB_CB
(
skb
)
->
dccpd_seq
,
DCCP_ACKVEC_STATE_RECEIVED
))
DCCP_SKB_CB
(
skb
)
->
dccpd_seq
,
DCCPAV_RECEIVED
))
goto
discard
;
dccp_deliver_input_to_ccids
(
sk
,
skb
);
...
...
net/dccp/options.c
浏览文件 @
ed1deb70
...
...
@@ -340,6 +340,7 @@ static inline int dccp_elapsed_time_len(const u32 elapsed_time)
return
elapsed_time
==
0
?
0
:
elapsed_time
<=
0xFFFF
?
2
:
4
;
}
/* FIXME: This function is currently not used anywhere */
int
dccp_insert_option_elapsed_time
(
struct
sk_buff
*
skb
,
u32
elapsed_time
)
{
const
int
elapsed_time_len
=
dccp_elapsed_time_len
(
elapsed_time
);
...
...
@@ -424,6 +425,67 @@ static int dccp_insert_option_timestamp_echo(struct dccp_sock *dp,
return
0
;
}
static
int
dccp_insert_option_ackvec
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
)
{
struct
dccp_sock
*
dp
=
dccp_sk
(
sk
);
struct
dccp_ackvec
*
av
=
dp
->
dccps_hc_rx_ackvec
;
const
u16
buflen
=
dccp_ackvec_buflen
(
av
);
/* Figure out how many options do we need to represent the ackvec */
const
u8
nr_opts
=
DIV_ROUND_UP
(
buflen
,
DCCP_SINGLE_OPT_MAXLEN
);
u16
len
=
buflen
+
2
*
nr_opts
;
u8
i
,
nonce
=
0
;
const
unsigned
char
*
tail
,
*
from
;
unsigned
char
*
to
;
if
(
DCCP_SKB_CB
(
skb
)
->
dccpd_opt_len
+
len
>
DCCP_MAX_OPT_LEN
)
return
-
1
;
DCCP_SKB_CB
(
skb
)
->
dccpd_opt_len
+=
len
;
to
=
skb_push
(
skb
,
len
);
len
=
buflen
;
from
=
av
->
av_buf
+
av
->
av_buf_head
;
tail
=
av
->
av_buf
+
DCCPAV_MAX_ACKVEC_LEN
;
for
(
i
=
0
;
i
<
nr_opts
;
++
i
)
{
int
copylen
=
len
;
if
(
len
>
DCCP_SINGLE_OPT_MAXLEN
)
copylen
=
DCCP_SINGLE_OPT_MAXLEN
;
/*
* RFC 4340, 12.2: Encode the Nonce Echo for this Ack Vector via
* its type; ack_nonce is the sum of all individual buf_nonce's.
*/
nonce
^=
av
->
av_buf_nonce
[
i
];
*
to
++
=
DCCPO_ACK_VECTOR_0
+
av
->
av_buf_nonce
[
i
];
*
to
++
=
copylen
+
2
;
/* Check if buf_head wraps */
if
(
from
+
copylen
>
tail
)
{
const
u16
tailsize
=
tail
-
from
;
memcpy
(
to
,
from
,
tailsize
);
to
+=
tailsize
;
len
-=
tailsize
;
copylen
-=
tailsize
;
from
=
av
->
av_buf
;
}
memcpy
(
to
,
from
,
copylen
);
from
+=
copylen
;
to
+=
copylen
;
len
-=
copylen
;
}
/*
* Each sent Ack Vector is recorded in the list, as per A.2 of RFC 4340.
*/
if
(
dccp_ackvec_update_records
(
av
,
DCCP_SKB_CB
(
skb
)
->
dccpd_seq
,
nonce
))
return
-
ENOBUFS
;
return
0
;
}
/**
* dccp_insert_option_mandatory - Mandatory option (5.8.2)
* Note that since we are using skb_push, this function needs to be called
...
...
@@ -519,8 +581,7 @@ int dccp_insert_options(struct sock *sk, struct sk_buff *skb)
if
(
dccp_insert_option_timestamp
(
skb
))
return
-
1
;
}
else
if
(
dp
->
dccps_hc_rx_ackvec
!=
NULL
&&
dccp_ackvec_pending
(
dp
->
dccps_hc_rx_ackvec
)
&&
}
else
if
(
dccp_ackvec_pending
(
sk
)
&&
dccp_insert_option_ackvec
(
sk
,
skb
))
{
return
-
1
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录