mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 03:36:19 +00:00
dccp: Lockless integration of CCID congestion-control plugins
Based on Arnaldo's earlier patch, this patch integrates the standardised CCID congestion control plugins (CCID-2 and CCID-3) of DCCP with dccp.ko: * enables a faster connection path by eliminating the need to always go through the CCID registration lock; * updates the implementation to use only a single array whose size equals the number of configured CCIDs instead of the maximum (256); * since the CCIDs are now fixed array elements, synchronization is no longer needed, simplifying use and implementation. CCID-2 is suggested as minimum for a basic DCCP implementation (RFC 4340, 10); CCID-3 is a standards-track CCID supported by RFC 4342 and RFC 5348. Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
6ea2fde13a
commit
ddebc973c5
11 changed files with 148 additions and 168 deletions
|
@ -1,7 +1,6 @@
|
||||||
menuconfig IP_DCCP
|
menuconfig IP_DCCP
|
||||||
tristate "The DCCP Protocol (EXPERIMENTAL)"
|
tristate "The DCCP Protocol (EXPERIMENTAL)"
|
||||||
depends on INET && EXPERIMENTAL
|
depends on INET && EXPERIMENTAL
|
||||||
select IP_DCCP_CCID2
|
|
||||||
---help---
|
---help---
|
||||||
Datagram Congestion Control Protocol (RFC 4340)
|
Datagram Congestion Control Protocol (RFC 4340)
|
||||||
|
|
||||||
|
@ -25,9 +24,6 @@ config INET_DCCP_DIAG
|
||||||
def_tristate y if (IP_DCCP = y && INET_DIAG = y)
|
def_tristate y if (IP_DCCP = y && INET_DIAG = y)
|
||||||
def_tristate m
|
def_tristate m
|
||||||
|
|
||||||
config IP_DCCP_ACKVEC
|
|
||||||
bool
|
|
||||||
|
|
||||||
source "net/dccp/ccids/Kconfig"
|
source "net/dccp/ccids/Kconfig"
|
||||||
|
|
||||||
menu "DCCP Kernel Hacking"
|
menu "DCCP Kernel Hacking"
|
||||||
|
|
|
@ -2,14 +2,19 @@ obj-$(CONFIG_IP_DCCP) += dccp.o dccp_ipv4.o
|
||||||
|
|
||||||
dccp-y := ccid.o feat.o input.o minisocks.o options.o output.o proto.o timer.o
|
dccp-y := ccid.o feat.o input.o minisocks.o options.o output.o proto.o timer.o
|
||||||
|
|
||||||
|
#
|
||||||
|
# CCID algorithms to be used by dccp.ko
|
||||||
|
#
|
||||||
|
# CCID-2 is default (RFC 4340, p. 77) and has Ack Vectors as dependency
|
||||||
|
dccp-y += ccids/ccid2.o ackvec.o
|
||||||
|
dccp-$(CONFIG_IP_DCCP_CCID3) += ccids/ccid3.o
|
||||||
|
|
||||||
dccp_ipv4-y := ipv4.o
|
dccp_ipv4-y := ipv4.o
|
||||||
|
|
||||||
# build dccp_ipv6 as module whenever either IPv6 or DCCP is a module
|
# build dccp_ipv6 as module whenever either IPv6 or DCCP is a module
|
||||||
obj-$(subst y,$(CONFIG_IP_DCCP),$(CONFIG_IPV6)) += dccp_ipv6.o
|
obj-$(subst y,$(CONFIG_IP_DCCP),$(CONFIG_IPV6)) += dccp_ipv6.o
|
||||||
dccp_ipv6-y := ipv6.o
|
dccp_ipv6-y := ipv6.o
|
||||||
|
|
||||||
dccp-$(CONFIG_IP_DCCP_ACKVEC) += ackvec.o
|
|
||||||
|
|
||||||
obj-$(CONFIG_INET_DCCP_DIAG) += dccp_diag.o
|
obj-$(CONFIG_INET_DCCP_DIAG) += dccp_diag.o
|
||||||
obj-$(CONFIG_NET_DCCPPROBE) += dccp_probe.o
|
obj-$(CONFIG_NET_DCCPPROBE) += dccp_probe.o
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ struct dccp_ackvec_record {
|
||||||
struct sock;
|
struct sock;
|
||||||
struct sk_buff;
|
struct sk_buff;
|
||||||
|
|
||||||
#ifdef CONFIG_IP_DCCP_ACKVEC
|
#ifndef ___OLD_INTERFACE_TO_BE_REMOVED___
|
||||||
extern int dccp_ackvec_init(void);
|
extern int dccp_ackvec_init(void);
|
||||||
extern void dccp_ackvec_exit(void);
|
extern void dccp_ackvec_exit(void);
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ static inline int dccp_ackvec_pending(const struct dccp_ackvec *av)
|
||||||
{
|
{
|
||||||
return av->av_vec_len;
|
return av->av_vec_len;
|
||||||
}
|
}
|
||||||
#else /* CONFIG_IP_DCCP_ACKVEC */
|
#else /* ___OLD_INTERFACE_TO_BE_REMOVED___ */
|
||||||
static inline int dccp_ackvec_init(void)
|
static inline int dccp_ackvec_init(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|
156
net/dccp/ccid.c
156
net/dccp/ccid.c
|
@ -13,6 +13,70 @@
|
||||||
|
|
||||||
#include "ccid.h"
|
#include "ccid.h"
|
||||||
|
|
||||||
|
static struct ccid_operations *ccids[] = {
|
||||||
|
&ccid2_ops,
|
||||||
|
#ifdef CONFIG_IP_DCCP_CCID3
|
||||||
|
&ccid3_ops,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ccid_operations *ccid_by_number(const u8 id)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(ccids); i++)
|
||||||
|
if (ccids[i]->ccid_id == id)
|
||||||
|
return ccids[i];
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check that up to @array_len members in @ccid_array are supported */
|
||||||
|
bool ccid_support_check(u8 const *ccid_array, u8 array_len)
|
||||||
|
{
|
||||||
|
while (array_len > 0)
|
||||||
|
if (ccid_by_number(ccid_array[--array_len]) == NULL)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ccid_get_builtin_ccids - Populate a list of built-in CCIDs
|
||||||
|
* @ccid_array: pointer to copy into
|
||||||
|
* @array_len: value to return length into
|
||||||
|
* This function allocates memory - caller must see that it is freed after use.
|
||||||
|
*/
|
||||||
|
int ccid_get_builtin_ccids(u8 **ccid_array, u8 *array_len)
|
||||||
|
{
|
||||||
|
*ccid_array = kmalloc(ARRAY_SIZE(ccids), gfp_any());
|
||||||
|
if (*ccid_array == NULL)
|
||||||
|
return -ENOBUFS;
|
||||||
|
|
||||||
|
for (*array_len = 0; *array_len < ARRAY_SIZE(ccids); *array_len += 1)
|
||||||
|
(*ccid_array)[*array_len] = ccids[*array_len]->ccid_id;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ccid_getsockopt_builtin_ccids(struct sock *sk, int len,
|
||||||
|
char __user *optval, int __user *optlen)
|
||||||
|
{
|
||||||
|
u8 *ccid_array, array_len;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (len < ARRAY_SIZE(ccids))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (ccid_get_builtin_ccids(&ccid_array, &array_len))
|
||||||
|
return -ENOBUFS;
|
||||||
|
|
||||||
|
if (put_user(array_len, optlen) ||
|
||||||
|
copy_to_user(optval, ccid_array, array_len))
|
||||||
|
err = -EFAULT;
|
||||||
|
|
||||||
|
kfree(ccid_array);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ___OLD_INTERFACE_TO_BE_REMOVED___
|
||||||
static u8 builtin_ccids[] = {
|
static u8 builtin_ccids[] = {
|
||||||
DCCPC_CCID2, /* CCID2 is supported by default */
|
DCCPC_CCID2, /* CCID2 is supported by default */
|
||||||
#if defined(CONFIG_IP_DCCP_CCID3) || defined(CONFIG_IP_DCCP_CCID3_MODULE)
|
#if defined(CONFIG_IP_DCCP_CCID3) || defined(CONFIG_IP_DCCP_CCID3_MODULE)
|
||||||
|
@ -62,6 +126,7 @@ static inline void ccids_read_unlock(void)
|
||||||
#define ccids_read_lock() do { } while(0)
|
#define ccids_read_lock() do { } while(0)
|
||||||
#define ccids_read_unlock() do { } while(0)
|
#define ccids_read_unlock() do { } while(0)
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* ___OLD_INTERFACE_TO_BE_REMOVED___ */
|
||||||
|
|
||||||
static struct kmem_cache *ccid_kmem_cache_create(int obj_size, const char *fmt,...)
|
static struct kmem_cache *ccid_kmem_cache_create(int obj_size, const char *fmt,...)
|
||||||
{
|
{
|
||||||
|
@ -93,6 +158,7 @@ static void ccid_kmem_cache_destroy(struct kmem_cache *slab)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ___OLD_INTERFACE_TO_BE_REMOVED___
|
||||||
/* check that up to @array_len members in @ccid_array are supported */
|
/* check that up to @array_len members in @ccid_array are supported */
|
||||||
bool ccid_support_check(u8 const *ccid_array, u8 array_len)
|
bool ccid_support_check(u8 const *ccid_array, u8 array_len)
|
||||||
{
|
{
|
||||||
|
@ -133,8 +199,9 @@ int ccid_getsockopt_builtin_ccids(struct sock *sk, int len,
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif /* ___OLD_INTERFACE_TO_BE_REMOVED___ */
|
||||||
|
|
||||||
int ccid_register(struct ccid_operations *ccid_ops)
|
static int ccid_activate(struct ccid_operations *ccid_ops)
|
||||||
{
|
{
|
||||||
int err = -ENOBUFS;
|
int err = -ENOBUFS;
|
||||||
|
|
||||||
|
@ -152,79 +219,40 @@ int ccid_register(struct ccid_operations *ccid_ops)
|
||||||
if (ccid_ops->ccid_hc_tx_slab == NULL)
|
if (ccid_ops->ccid_hc_tx_slab == NULL)
|
||||||
goto out_free_rx_slab;
|
goto out_free_rx_slab;
|
||||||
|
|
||||||
ccids_write_lock();
|
pr_info("CCID: Activated CCID %d (%s)\n",
|
||||||
err = -EEXIST;
|
|
||||||
if (ccids[ccid_ops->ccid_id] == NULL) {
|
|
||||||
ccids[ccid_ops->ccid_id] = ccid_ops;
|
|
||||||
err = 0;
|
|
||||||
}
|
|
||||||
ccids_write_unlock();
|
|
||||||
if (err != 0)
|
|
||||||
goto out_free_tx_slab;
|
|
||||||
|
|
||||||
pr_info("CCID: Registered CCID %d (%s)\n",
|
|
||||||
ccid_ops->ccid_id, ccid_ops->ccid_name);
|
ccid_ops->ccid_id, ccid_ops->ccid_name);
|
||||||
|
err = 0;
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
out_free_tx_slab:
|
|
||||||
ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
|
|
||||||
ccid_ops->ccid_hc_tx_slab = NULL;
|
|
||||||
goto out;
|
|
||||||
out_free_rx_slab:
|
out_free_rx_slab:
|
||||||
ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
|
ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
|
||||||
ccid_ops->ccid_hc_rx_slab = NULL;
|
ccid_ops->ccid_hc_rx_slab = NULL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(ccid_register);
|
static void ccid_deactivate(struct ccid_operations *ccid_ops)
|
||||||
|
|
||||||
int ccid_unregister(struct ccid_operations *ccid_ops)
|
|
||||||
{
|
{
|
||||||
ccids_write_lock();
|
|
||||||
ccids[ccid_ops->ccid_id] = NULL;
|
|
||||||
ccids_write_unlock();
|
|
||||||
|
|
||||||
ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
|
ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
|
||||||
ccid_ops->ccid_hc_tx_slab = NULL;
|
ccid_ops->ccid_hc_tx_slab = NULL;
|
||||||
ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
|
ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
|
||||||
ccid_ops->ccid_hc_rx_slab = NULL;
|
ccid_ops->ccid_hc_rx_slab = NULL;
|
||||||
|
|
||||||
pr_info("CCID: Unregistered CCID %d (%s)\n",
|
pr_info("CCID: Deactivated CCID %d (%s)\n",
|
||||||
ccid_ops->ccid_id, ccid_ops->ccid_name);
|
ccid_ops->ccid_id, ccid_ops->ccid_name);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(ccid_unregister);
|
|
||||||
|
|
||||||
struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, gfp_t gfp)
|
struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, gfp_t gfp)
|
||||||
{
|
{
|
||||||
struct ccid_operations *ccid_ops;
|
struct ccid_operations *ccid_ops = ccid_by_number(id);
|
||||||
struct ccid *ccid = NULL;
|
struct ccid *ccid = NULL;
|
||||||
|
|
||||||
ccids_read_lock();
|
|
||||||
#ifdef CONFIG_MODULES
|
|
||||||
if (ccids[id] == NULL) {
|
|
||||||
/* We only try to load if in process context */
|
|
||||||
ccids_read_unlock();
|
|
||||||
if (gfp & GFP_ATOMIC)
|
|
||||||
goto out;
|
|
||||||
request_module("net-dccp-ccid-%d", id);
|
|
||||||
ccids_read_lock();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
ccid_ops = ccids[id];
|
|
||||||
if (ccid_ops == NULL)
|
if (ccid_ops == NULL)
|
||||||
goto out_unlock;
|
goto out;
|
||||||
|
|
||||||
if (!try_module_get(ccid_ops->ccid_owner))
|
|
||||||
goto out_unlock;
|
|
||||||
|
|
||||||
ccids_read_unlock();
|
|
||||||
|
|
||||||
ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
|
ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
|
||||||
ccid_ops->ccid_hc_tx_slab, gfp);
|
ccid_ops->ccid_hc_tx_slab, gfp);
|
||||||
if (ccid == NULL)
|
if (ccid == NULL)
|
||||||
goto out_module_put;
|
goto out;
|
||||||
ccid->ccid_ops = ccid_ops;
|
ccid->ccid_ops = ccid_ops;
|
||||||
if (rx) {
|
if (rx) {
|
||||||
memset(ccid + 1, 0, ccid_ops->ccid_hc_rx_obj_size);
|
memset(ccid + 1, 0, ccid_ops->ccid_hc_rx_obj_size);
|
||||||
|
@ -239,15 +267,10 @@ struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, gfp_t gfp)
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
return ccid;
|
return ccid;
|
||||||
out_unlock:
|
|
||||||
ccids_read_unlock();
|
|
||||||
goto out;
|
|
||||||
out_free_ccid:
|
out_free_ccid:
|
||||||
kmem_cache_free(rx ? ccid_ops->ccid_hc_rx_slab :
|
kmem_cache_free(rx ? ccid_ops->ccid_hc_rx_slab :
|
||||||
ccid_ops->ccid_hc_tx_slab, ccid);
|
ccid_ops->ccid_hc_tx_slab, ccid);
|
||||||
ccid = NULL;
|
ccid = NULL;
|
||||||
out_module_put:
|
|
||||||
module_put(ccid_ops->ccid_owner);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,10 +293,6 @@ static void ccid_delete(struct ccid *ccid, struct sock *sk, int rx)
|
||||||
ccid_ops->ccid_hc_tx_exit(sk);
|
ccid_ops->ccid_hc_tx_exit(sk);
|
||||||
kmem_cache_free(ccid_ops->ccid_hc_tx_slab, ccid);
|
kmem_cache_free(ccid_ops->ccid_hc_tx_slab, ccid);
|
||||||
}
|
}
|
||||||
ccids_read_lock();
|
|
||||||
if (ccids[ccid_ops->ccid_id] != NULL)
|
|
||||||
module_put(ccid_ops->ccid_owner);
|
|
||||||
ccids_read_unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ccid_hc_rx_delete(struct ccid *ccid, struct sock *sk)
|
void ccid_hc_rx_delete(struct ccid *ccid, struct sock *sk)
|
||||||
|
@ -289,3 +308,28 @@ void ccid_hc_tx_delete(struct ccid *ccid, struct sock *sk)
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(ccid_hc_tx_delete);
|
EXPORT_SYMBOL_GPL(ccid_hc_tx_delete);
|
||||||
|
|
||||||
|
int __init ccid_initialize_builtins(void)
|
||||||
|
{
|
||||||
|
int i, err;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(ccids); i++) {
|
||||||
|
err = ccid_activate(ccids[i]);
|
||||||
|
if (err)
|
||||||
|
goto unwind_registrations;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
unwind_registrations:
|
||||||
|
while(--i >= 0)
|
||||||
|
ccid_deactivate(ccids[i]);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ccid_cleanup_builtins(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(ccids); i++)
|
||||||
|
ccid_deactivate(ccids[i]);
|
||||||
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@ struct tcp_info;
|
||||||
* @ccid_id: numerical CCID ID (up to %CCID_MAX, cf. table 5 in RFC 4340, 10.)
|
* @ccid_id: numerical CCID ID (up to %CCID_MAX, cf. table 5 in RFC 4340, 10.)
|
||||||
* @ccid_ccmps: the CCMPS including network/transport headers (0 when disabled)
|
* @ccid_ccmps: the CCMPS including network/transport headers (0 when disabled)
|
||||||
* @ccid_name: alphabetical identifier string for @ccid_id
|
* @ccid_name: alphabetical identifier string for @ccid_id
|
||||||
* @ccid_owner: module which implements/owns this CCID
|
|
||||||
* @ccid_hc_{r,t}x_slab: memory pool for the receiver/sender half-connection
|
* @ccid_hc_{r,t}x_slab: memory pool for the receiver/sender half-connection
|
||||||
* @ccid_hc_{r,t}x_obj_size: size of the receiver/sender half-connection socket
|
* @ccid_hc_{r,t}x_obj_size: size of the receiver/sender half-connection socket
|
||||||
*
|
*
|
||||||
|
@ -48,7 +47,6 @@ struct ccid_operations {
|
||||||
unsigned char ccid_id;
|
unsigned char ccid_id;
|
||||||
__u32 ccid_ccmps;
|
__u32 ccid_ccmps;
|
||||||
const char *ccid_name;
|
const char *ccid_name;
|
||||||
struct module *ccid_owner;
|
|
||||||
struct kmem_cache *ccid_hc_rx_slab,
|
struct kmem_cache *ccid_hc_rx_slab,
|
||||||
*ccid_hc_tx_slab;
|
*ccid_hc_tx_slab;
|
||||||
__u32 ccid_hc_rx_obj_size,
|
__u32 ccid_hc_rx_obj_size,
|
||||||
|
@ -90,8 +88,13 @@ struct ccid_operations {
|
||||||
int __user *optlen);
|
int __user *optlen);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int ccid_register(struct ccid_operations *ccid_ops);
|
extern struct ccid_operations ccid2_ops;
|
||||||
extern int ccid_unregister(struct ccid_operations *ccid_ops);
|
#ifdef CONFIG_IP_DCCP_CCID3
|
||||||
|
extern struct ccid_operations ccid3_ops;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern int ccid_initialize_builtins(void);
|
||||||
|
extern void ccid_cleanup_builtins(void);
|
||||||
|
|
||||||
struct ccid {
|
struct ccid {
|
||||||
struct ccid_operations *ccid_ops;
|
struct ccid_operations *ccid_ops;
|
||||||
|
|
|
@ -1,80 +1,52 @@
|
||||||
menu "DCCP CCIDs Configuration (EXPERIMENTAL)"
|
menu "DCCP CCIDs Configuration (EXPERIMENTAL)"
|
||||||
depends on EXPERIMENTAL
|
depends on EXPERIMENTAL
|
||||||
|
|
||||||
config IP_DCCP_CCID2
|
|
||||||
tristate "CCID2 (TCP-Like) (EXPERIMENTAL)"
|
|
||||||
def_tristate IP_DCCP
|
|
||||||
select IP_DCCP_ACKVEC
|
|
||||||
---help---
|
|
||||||
CCID 2, TCP-like Congestion Control, denotes Additive Increase,
|
|
||||||
Multiplicative Decrease (AIMD) congestion control with behavior
|
|
||||||
modelled directly on TCP, including congestion window, slow start,
|
|
||||||
timeouts, and so forth [RFC 2581]. CCID 2 achieves maximum
|
|
||||||
bandwidth over the long term, consistent with the use of end-to-end
|
|
||||||
congestion control, but halves its congestion window in response to
|
|
||||||
each congestion event. This leads to the abrupt rate changes
|
|
||||||
typical of TCP. Applications should use CCID 2 if they prefer
|
|
||||||
maximum bandwidth utilization to steadiness of rate. This is often
|
|
||||||
the case for applications that are not playing their data directly
|
|
||||||
to the user. For example, a hypothetical application that
|
|
||||||
transferred files over DCCP, using application-level retransmissions
|
|
||||||
for lost packets, would prefer CCID 2 to CCID 3. On-line games may
|
|
||||||
also prefer CCID 2. See RFC 4341 for further details.
|
|
||||||
|
|
||||||
CCID2 is the default CCID used by DCCP.
|
|
||||||
|
|
||||||
config IP_DCCP_CCID2_DEBUG
|
config IP_DCCP_CCID2_DEBUG
|
||||||
bool "CCID2 debugging messages"
|
bool "CCID-2 debugging messages"
|
||||||
depends on IP_DCCP_CCID2
|
---help---
|
||||||
---help---
|
Enable CCID-2 specific debugging messages.
|
||||||
Enable CCID2-specific debugging messages.
|
|
||||||
|
|
||||||
When compiling CCID2 as a module, this debugging output can
|
The debugging output can additionally be toggled by setting the
|
||||||
additionally be toggled by setting the ccid2_debug module
|
ccid2_debug parameter to 0 or 1.
|
||||||
parameter to 0 or 1.
|
|
||||||
|
|
||||||
If in doubt, say N.
|
If in doubt, say N.
|
||||||
|
|
||||||
config IP_DCCP_CCID3
|
config IP_DCCP_CCID3
|
||||||
tristate "CCID3 (TCP-Friendly) (EXPERIMENTAL)"
|
bool "CCID-3 (TCP-Friendly) (EXPERIMENTAL)"
|
||||||
def_tristate IP_DCCP
|
def_bool y if (IP_DCCP = y || IP_DCCP = m)
|
||||||
select IP_DCCP_TFRC_LIB
|
select IP_DCCP_TFRC_LIB
|
||||||
---help---
|
---help---
|
||||||
CCID 3 denotes TCP-Friendly Rate Control (TFRC), an equation-based
|
CCID-3 denotes TCP-Friendly Rate Control (TFRC), an equation-based
|
||||||
rate-controlled congestion control mechanism. TFRC is designed to
|
rate-controlled congestion control mechanism. TFRC is designed to
|
||||||
be reasonably fair when competing for bandwidth with TCP-like flows,
|
be reasonably fair when competing for bandwidth with TCP-like flows,
|
||||||
where a flow is "reasonably fair" if its sending rate is generally
|
where a flow is "reasonably fair" if its sending rate is generally
|
||||||
within a factor of two of the sending rate of a TCP flow under the
|
within a factor of two of the sending rate of a TCP flow under the
|
||||||
same conditions. However, TFRC has a much lower variation of
|
same conditions. However, TFRC has a much lower variation of
|
||||||
throughput over time compared with TCP, which makes CCID 3 more
|
throughput over time compared with TCP, which makes CCID-3 more
|
||||||
suitable than CCID 2 for applications such streaming media where a
|
suitable than CCID-2 for applications such streaming media where a
|
||||||
relatively smooth sending rate is of importance.
|
relatively smooth sending rate is of importance.
|
||||||
|
|
||||||
CCID 3 is further described in RFC 4342,
|
CCID-3 is further described in RFC 4342,
|
||||||
http://www.ietf.org/rfc/rfc4342.txt
|
http://www.ietf.org/rfc/rfc4342.txt
|
||||||
|
|
||||||
The TFRC congestion control algorithms were initially described in
|
The TFRC congestion control algorithms were initially described in
|
||||||
RFC 3448.
|
RFC 5448.
|
||||||
|
|
||||||
This text was extracted from RFC 4340 (sec. 10.2),
|
This text was extracted from RFC 4340 (sec. 10.2),
|
||||||
http://www.ietf.org/rfc/rfc4340.txt
|
http://www.ietf.org/rfc/rfc4340.txt
|
||||||
|
|
||||||
To compile this CCID as a module, choose M here: the module will be
|
|
||||||
called dccp_ccid3.
|
|
||||||
|
|
||||||
If in doubt, say M.
|
If in doubt, say N.
|
||||||
|
|
||||||
config IP_DCCP_CCID3_DEBUG
|
config IP_DCCP_CCID3_DEBUG
|
||||||
bool "CCID3 debugging messages"
|
bool "CCID-3 debugging messages"
|
||||||
depends on IP_DCCP_CCID3
|
depends on IP_DCCP_CCID3
|
||||||
---help---
|
---help---
|
||||||
Enable CCID3-specific debugging messages.
|
Enable CCID-3 specific debugging messages.
|
||||||
|
|
||||||
When compiling CCID3 as a module, this debugging output can
|
The debugging output can additionally be toggled by setting the
|
||||||
additionally be toggled by setting the ccid3_debug module
|
ccid3_debug parameter to 0 or 1.
|
||||||
parameter to 0 or 1.
|
|
||||||
|
|
||||||
If in doubt, say N.
|
If in doubt, say N.
|
||||||
|
|
||||||
config IP_DCCP_CCID3_RTO
|
config IP_DCCP_CCID3_RTO
|
||||||
int "Use higher bound for nofeedback timer"
|
int "Use higher bound for nofeedback timer"
|
||||||
|
|
|
@ -1,9 +1 @@
|
||||||
obj-$(CONFIG_IP_DCCP_CCID3) += dccp_ccid3.o
|
|
||||||
|
|
||||||
dccp_ccid3-y := ccid3.o
|
|
||||||
|
|
||||||
obj-$(CONFIG_IP_DCCP_CCID2) += dccp_ccid2.o
|
|
||||||
|
|
||||||
dccp_ccid2-y := ccid2.o
|
|
||||||
|
|
||||||
obj-y += lib/
|
obj-y += lib/
|
||||||
|
|
|
@ -768,10 +768,9 @@ static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ccid_operations ccid2 = {
|
struct ccid_operations ccid2_ops = {
|
||||||
.ccid_id = DCCPC_CCID2,
|
.ccid_id = DCCPC_CCID2,
|
||||||
.ccid_name = "TCP-like",
|
.ccid_name = "TCP-like",
|
||||||
.ccid_owner = THIS_MODULE,
|
|
||||||
.ccid_hc_tx_obj_size = sizeof(struct ccid2_hc_tx_sock),
|
.ccid_hc_tx_obj_size = sizeof(struct ccid2_hc_tx_sock),
|
||||||
.ccid_hc_tx_init = ccid2_hc_tx_init,
|
.ccid_hc_tx_init = ccid2_hc_tx_init,
|
||||||
.ccid_hc_tx_exit = ccid2_hc_tx_exit,
|
.ccid_hc_tx_exit = ccid2_hc_tx_exit,
|
||||||
|
@ -784,22 +783,5 @@ static struct ccid_operations ccid2 = {
|
||||||
|
|
||||||
#ifdef CONFIG_IP_DCCP_CCID2_DEBUG
|
#ifdef CONFIG_IP_DCCP_CCID2_DEBUG
|
||||||
module_param(ccid2_debug, bool, 0644);
|
module_param(ccid2_debug, bool, 0644);
|
||||||
MODULE_PARM_DESC(ccid2_debug, "Enable debug messages");
|
MODULE_PARM_DESC(ccid2_debug, "Enable CCID-2 debug messages");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static __init int ccid2_module_init(void)
|
|
||||||
{
|
|
||||||
return ccid_register(&ccid2);
|
|
||||||
}
|
|
||||||
module_init(ccid2_module_init);
|
|
||||||
|
|
||||||
static __exit void ccid2_module_exit(void)
|
|
||||||
{
|
|
||||||
ccid_unregister(&ccid2);
|
|
||||||
}
|
|
||||||
module_exit(ccid2_module_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Andrea Bittau <a.bittau@cs.ucl.ac.uk>");
|
|
||||||
MODULE_DESCRIPTION("DCCP TCP-Like (CCID2) CCID");
|
|
||||||
MODULE_LICENSE("GPL");
|
|
||||||
MODULE_ALIAS("net-dccp-ccid-2");
|
|
||||||
|
|
|
@ -940,10 +940,9 @@ static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ccid_operations ccid3 = {
|
struct ccid_operations ccid3_ops = {
|
||||||
.ccid_id = DCCPC_CCID3,
|
.ccid_id = DCCPC_CCID3,
|
||||||
.ccid_name = "TCP-Friendly Rate Control",
|
.ccid_name = "TCP-Friendly Rate Control",
|
||||||
.ccid_owner = THIS_MODULE,
|
|
||||||
.ccid_hc_tx_obj_size = sizeof(struct ccid3_hc_tx_sock),
|
.ccid_hc_tx_obj_size = sizeof(struct ccid3_hc_tx_sock),
|
||||||
.ccid_hc_tx_init = ccid3_hc_tx_init,
|
.ccid_hc_tx_init = ccid3_hc_tx_init,
|
||||||
.ccid_hc_tx_exit = ccid3_hc_tx_exit,
|
.ccid_hc_tx_exit = ccid3_hc_tx_exit,
|
||||||
|
@ -964,23 +963,5 @@ static struct ccid_operations ccid3 = {
|
||||||
|
|
||||||
#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
|
#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
|
||||||
module_param(ccid3_debug, bool, 0644);
|
module_param(ccid3_debug, bool, 0644);
|
||||||
MODULE_PARM_DESC(ccid3_debug, "Enable debug messages");
|
MODULE_PARM_DESC(ccid3_debug, "Enable CCID-3 debug messages");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static __init int ccid3_module_init(void)
|
|
||||||
{
|
|
||||||
return ccid_register(&ccid3);
|
|
||||||
}
|
|
||||||
module_init(ccid3_module_init);
|
|
||||||
|
|
||||||
static __exit void ccid3_module_exit(void)
|
|
||||||
{
|
|
||||||
ccid_unregister(&ccid3);
|
|
||||||
}
|
|
||||||
module_exit(ccid3_module_exit);
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Ian McDonald <ian.mcdonald@jandi.co.nz>, "
|
|
||||||
"Arnaldo Carvalho de Melo <acme@ghostprotocols.net>");
|
|
||||||
MODULE_DESCRIPTION("DCCP TFRC CCID3 CCID");
|
|
||||||
MODULE_LICENSE("GPL");
|
|
||||||
MODULE_ALIAS("net-dccp-ccid-3");
|
|
||||||
|
|
|
@ -432,10 +432,8 @@ static inline int dccp_ack_pending(const struct sock *sk)
|
||||||
{
|
{
|
||||||
const struct dccp_sock *dp = dccp_sk(sk);
|
const struct dccp_sock *dp = dccp_sk(sk);
|
||||||
return dp->dccps_timestamp_echo != 0 ||
|
return dp->dccps_timestamp_echo != 0 ||
|
||||||
#ifdef CONFIG_IP_DCCP_ACKVEC
|
|
||||||
(dp->dccps_hc_rx_ackvec != NULL &&
|
(dp->dccps_hc_rx_ackvec != NULL &&
|
||||||
dccp_ackvec_pending(dp->dccps_hc_rx_ackvec)) ||
|
dccp_ackvec_pending(dp->dccps_hc_rx_ackvec)) ||
|
||||||
#endif
|
|
||||||
inet_csk_ack_scheduled(sk);
|
inet_csk_ack_scheduled(sk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1118,9 +1118,15 @@ static int __init dccp_init(void)
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out_ackvec_exit;
|
goto out_ackvec_exit;
|
||||||
|
|
||||||
|
rc = ccid_initialize_builtins();
|
||||||
|
if (rc)
|
||||||
|
goto out_sysctl_exit;
|
||||||
|
|
||||||
dccp_timestamping_init();
|
dccp_timestamping_init();
|
||||||
out:
|
out:
|
||||||
return rc;
|
return rc;
|
||||||
|
out_sysctl_exit:
|
||||||
|
dccp_sysctl_exit();
|
||||||
out_ackvec_exit:
|
out_ackvec_exit:
|
||||||
dccp_ackvec_exit();
|
dccp_ackvec_exit();
|
||||||
out_free_dccp_mib:
|
out_free_dccp_mib:
|
||||||
|
@ -1143,6 +1149,7 @@ out_free_percpu:
|
||||||
|
|
||||||
static void __exit dccp_fini(void)
|
static void __exit dccp_fini(void)
|
||||||
{
|
{
|
||||||
|
ccid_cleanup_builtins();
|
||||||
dccp_mib_exit();
|
dccp_mib_exit();
|
||||||
free_pages((unsigned long)dccp_hashinfo.bhash,
|
free_pages((unsigned long)dccp_hashinfo.bhash,
|
||||||
get_order(dccp_hashinfo.bhash_size *
|
get_order(dccp_hashinfo.bhash_size *
|
||||||
|
|
Loading…
Reference in a new issue