Merge branch 'dccp' of git://eden-feed.erg.abdn.ac.uk/net-next-2.6
This commit is contained in:
@@ -165,8 +165,10 @@ enum {
|
|||||||
DCCPO_TIMESTAMP_ECHO = 42,
|
DCCPO_TIMESTAMP_ECHO = 42,
|
||||||
DCCPO_ELAPSED_TIME = 43,
|
DCCPO_ELAPSED_TIME = 43,
|
||||||
DCCPO_MAX = 45,
|
DCCPO_MAX = 45,
|
||||||
DCCPO_MIN_CCID_SPECIFIC = 128,
|
DCCPO_MIN_RX_CCID_SPECIFIC = 128, /* from sender to receiver */
|
||||||
DCCPO_MAX_CCID_SPECIFIC = 255,
|
DCCPO_MAX_RX_CCID_SPECIFIC = 191,
|
||||||
|
DCCPO_MIN_TX_CCID_SPECIFIC = 192, /* from receiver to sender */
|
||||||
|
DCCPO_MAX_TX_CCID_SPECIFIC = 255,
|
||||||
};
|
};
|
||||||
/* maximum size of a single TLV-encoded DCCP option (sans type/len bytes) */
|
/* maximum size of a single TLV-encoded DCCP option (sans type/len bytes) */
|
||||||
#define DCCP_SINGLE_OPT_MAXLEN 253
|
#define DCCP_SINGLE_OPT_MAXLEN 253
|
||||||
|
@@ -62,18 +62,14 @@ struct ccid_operations {
|
|||||||
void (*ccid_hc_tx_exit)(struct sock *sk);
|
void (*ccid_hc_tx_exit)(struct sock *sk);
|
||||||
void (*ccid_hc_rx_packet_recv)(struct sock *sk,
|
void (*ccid_hc_rx_packet_recv)(struct sock *sk,
|
||||||
struct sk_buff *skb);
|
struct sk_buff *skb);
|
||||||
int (*ccid_hc_rx_parse_options)(struct sock *sk,
|
int (*ccid_hc_rx_parse_options)(struct sock *sk, u8 pkt,
|
||||||
unsigned char option,
|
u8 opt, u8 *val, u8 len);
|
||||||
unsigned char len, u16 idx,
|
|
||||||
unsigned char* value);
|
|
||||||
int (*ccid_hc_rx_insert_options)(struct sock *sk,
|
int (*ccid_hc_rx_insert_options)(struct sock *sk,
|
||||||
struct sk_buff *skb);
|
struct sk_buff *skb);
|
||||||
void (*ccid_hc_tx_packet_recv)(struct sock *sk,
|
void (*ccid_hc_tx_packet_recv)(struct sock *sk,
|
||||||
struct sk_buff *skb);
|
struct sk_buff *skb);
|
||||||
int (*ccid_hc_tx_parse_options)(struct sock *sk,
|
int (*ccid_hc_tx_parse_options)(struct sock *sk, u8 pkt,
|
||||||
unsigned char option,
|
u8 opt, u8 *val, u8 len);
|
||||||
unsigned char len, u16 idx,
|
|
||||||
unsigned char* value);
|
|
||||||
int (*ccid_hc_tx_send_packet)(struct sock *sk,
|
int (*ccid_hc_tx_send_packet)(struct sock *sk,
|
||||||
struct sk_buff *skb);
|
struct sk_buff *skb);
|
||||||
void (*ccid_hc_tx_packet_sent)(struct sock *sk,
|
void (*ccid_hc_tx_packet_sent)(struct sock *sk,
|
||||||
@@ -168,27 +164,31 @@ static inline void ccid_hc_tx_packet_recv(struct ccid *ccid, struct sock *sk,
|
|||||||
ccid->ccid_ops->ccid_hc_tx_packet_recv(sk, skb);
|
ccid->ccid_ops->ccid_hc_tx_packet_recv(sk, skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ccid_hc_tx_parse_options - Parse CCID-specific options sent by the receiver
|
||||||
|
* @pkt: type of packet that @opt appears on (RFC 4340, 5.1)
|
||||||
|
* @opt: the CCID-specific option type (RFC 4340, 5.8 and 10.3)
|
||||||
|
* @val: value of @opt
|
||||||
|
* @len: length of @val in bytes
|
||||||
|
*/
|
||||||
static inline int ccid_hc_tx_parse_options(struct ccid *ccid, struct sock *sk,
|
static inline int ccid_hc_tx_parse_options(struct ccid *ccid, struct sock *sk,
|
||||||
unsigned char option,
|
u8 pkt, u8 opt, u8 *val, u8 len)
|
||||||
unsigned char len, u16 idx,
|
|
||||||
unsigned char* value)
|
|
||||||
{
|
{
|
||||||
int rc = 0;
|
if (ccid->ccid_ops->ccid_hc_tx_parse_options == NULL)
|
||||||
if (ccid->ccid_ops->ccid_hc_tx_parse_options != NULL)
|
return 0;
|
||||||
rc = ccid->ccid_ops->ccid_hc_tx_parse_options(sk, option, len, idx,
|
return ccid->ccid_ops->ccid_hc_tx_parse_options(sk, pkt, opt, val, len);
|
||||||
value);
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ccid_hc_rx_parse_options - Parse CCID-specific options sent by the sender
|
||||||
|
* Arguments are analogous to ccid_hc_tx_parse_options()
|
||||||
|
*/
|
||||||
static inline int ccid_hc_rx_parse_options(struct ccid *ccid, struct sock *sk,
|
static inline int ccid_hc_rx_parse_options(struct ccid *ccid, struct sock *sk,
|
||||||
unsigned char option,
|
u8 pkt, u8 opt, u8 *val, u8 len)
|
||||||
unsigned char len, u16 idx,
|
|
||||||
unsigned char* value)
|
|
||||||
{
|
{
|
||||||
int rc = 0;
|
if (ccid->ccid_ops->ccid_hc_rx_parse_options == NULL)
|
||||||
if (ccid->ccid_ops->ccid_hc_rx_parse_options != NULL)
|
return 0;
|
||||||
rc = ccid->ccid_ops->ccid_hc_rx_parse_options(sk, option, len, idx, value);
|
return ccid->ccid_ops->ccid_hc_rx_parse_options(sk, pkt, opt, val, len);
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int ccid_hc_rx_insert_options(struct ccid *ccid, struct sock *sk,
|
static inline int ccid_hc_rx_insert_options(struct ccid *ccid, struct sock *sk,
|
||||||
|
@@ -54,7 +54,6 @@ static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state)
|
|||||||
[TFRC_SSTATE_NO_SENT] = "NO_SENT",
|
[TFRC_SSTATE_NO_SENT] = "NO_SENT",
|
||||||
[TFRC_SSTATE_NO_FBACK] = "NO_FBACK",
|
[TFRC_SSTATE_NO_FBACK] = "NO_FBACK",
|
||||||
[TFRC_SSTATE_FBACK] = "FBACK",
|
[TFRC_SSTATE_FBACK] = "FBACK",
|
||||||
[TFRC_SSTATE_TERM] = "TERM",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return ccid3_state_names[state];
|
return ccid3_state_names[state];
|
||||||
@@ -208,10 +207,13 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
|
|||||||
ccid3_pr_debug("%s(%p, state=%s) - entry\n", dccp_role(sk), sk,
|
ccid3_pr_debug("%s(%p, state=%s) - entry\n", dccp_role(sk), sk,
|
||||||
ccid3_tx_state_name(hc->tx_state));
|
ccid3_tx_state_name(hc->tx_state));
|
||||||
|
|
||||||
|
/* Ignore and do not restart after leaving the established state */
|
||||||
|
if ((1 << sk->sk_state) & ~(DCCPF_OPEN | DCCPF_PARTOPEN))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* Reset feedback state to "no feedback received" */
|
||||||
if (hc->tx_state == TFRC_SSTATE_FBACK)
|
if (hc->tx_state == TFRC_SSTATE_FBACK)
|
||||||
ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
|
ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
|
||||||
else if (hc->tx_state != TFRC_SSTATE_NO_FBACK)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine new allowed sending rate X as per draft rfc3448bis-00, 4.4
|
* Determine new allowed sending rate X as per draft rfc3448bis-00, 4.4
|
||||||
@@ -287,8 +289,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
|
|||||||
if (unlikely(skb->len == 0))
|
if (unlikely(skb->len == 0))
|
||||||
return -EBADMSG;
|
return -EBADMSG;
|
||||||
|
|
||||||
switch (hc->tx_state) {
|
if (hc->tx_state == TFRC_SSTATE_NO_SENT) {
|
||||||
case TFRC_SSTATE_NO_SENT:
|
|
||||||
sk_reset_timer(sk, &hc->tx_no_feedback_timer, (jiffies +
|
sk_reset_timer(sk, &hc->tx_no_feedback_timer, (jiffies +
|
||||||
usecs_to_jiffies(TFRC_INITIAL_TIMEOUT)));
|
usecs_to_jiffies(TFRC_INITIAL_TIMEOUT)));
|
||||||
hc->tx_last_win_count = 0;
|
hc->tx_last_win_count = 0;
|
||||||
@@ -323,9 +324,8 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
|
|||||||
ccid3_update_send_interval(hc);
|
ccid3_update_send_interval(hc);
|
||||||
|
|
||||||
ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
|
ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
|
||||||
break;
|
|
||||||
case TFRC_SSTATE_NO_FBACK:
|
} else {
|
||||||
case TFRC_SSTATE_FBACK:
|
|
||||||
delay = ktime_us_delta(hc->tx_t_nom, now);
|
delay = ktime_us_delta(hc->tx_t_nom, now);
|
||||||
ccid3_pr_debug("delay=%ld\n", (long)delay);
|
ccid3_pr_debug("delay=%ld\n", (long)delay);
|
||||||
/*
|
/*
|
||||||
@@ -340,10 +340,6 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
|
|||||||
return (u32)delay / USEC_PER_MSEC;
|
return (u32)delay / USEC_PER_MSEC;
|
||||||
|
|
||||||
ccid3_hc_tx_update_win_count(hc, now);
|
ccid3_hc_tx_update_win_count(hc, now);
|
||||||
break;
|
|
||||||
case TFRC_SSTATE_TERM:
|
|
||||||
DCCP_BUG("%s(%p) - Illegal state TERM", dccp_role(sk), sk);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* prepare to send now (add options etc.) */
|
/* prepare to send now (add options etc.) */
|
||||||
@@ -369,21 +365,15 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more,
|
|||||||
static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
|
struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
|
||||||
struct ccid3_options_received *opt_recv = &hc->tx_options_received;
|
|
||||||
struct tfrc_tx_hist_entry *acked;
|
struct tfrc_tx_hist_entry *acked;
|
||||||
ktime_t now;
|
ktime_t now;
|
||||||
unsigned long t_nfb;
|
unsigned long t_nfb;
|
||||||
u32 pinv, r_sample;
|
u32 r_sample;
|
||||||
|
|
||||||
/* we are only interested in ACKs */
|
/* we are only interested in ACKs */
|
||||||
if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK ||
|
if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK ||
|
||||||
DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_DATAACK))
|
DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_DATAACK))
|
||||||
return;
|
return;
|
||||||
/* ... and only in the established state */
|
|
||||||
if (hc->tx_state != TFRC_SSTATE_FBACK &&
|
|
||||||
hc->tx_state != TFRC_SSTATE_NO_FBACK)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Locate the acknowledged packet in the TX history.
|
* Locate the acknowledged packet in the TX history.
|
||||||
*
|
*
|
||||||
@@ -403,17 +393,6 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
|||||||
r_sample = dccp_sample_rtt(sk, ktime_us_delta(now, acked->stamp));
|
r_sample = dccp_sample_rtt(sk, ktime_us_delta(now, acked->stamp));
|
||||||
hc->tx_rtt = tfrc_ewma(hc->tx_rtt, r_sample, 9);
|
hc->tx_rtt = tfrc_ewma(hc->tx_rtt, r_sample, 9);
|
||||||
|
|
||||||
/* Update receive rate in units of 64 * bytes/second */
|
|
||||||
hc->tx_x_recv = opt_recv->ccid3or_receive_rate;
|
|
||||||
hc->tx_x_recv <<= 6;
|
|
||||||
|
|
||||||
/* Update loss event rate (which is scaled by 1e6) */
|
|
||||||
pinv = opt_recv->ccid3or_loss_event_rate;
|
|
||||||
if (pinv == ~0U || pinv == 0) /* see RFC 4342, 8.5 */
|
|
||||||
hc->tx_p = 0;
|
|
||||||
else /* can not exceed 100% */
|
|
||||||
hc->tx_p = scaled_div(1, pinv);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update allowed sending rate X as per draft rfc3448bis-00, 4.2/3
|
* Update allowed sending rate X as per draft rfc3448bis-00, 4.2/3
|
||||||
*/
|
*/
|
||||||
@@ -481,30 +460,36 @@ done_computing_x:
|
|||||||
jiffies + usecs_to_jiffies(t_nfb));
|
jiffies + usecs_to_jiffies(t_nfb));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
|
static int ccid3_hc_tx_parse_options(struct sock *sk, u8 packet_type,
|
||||||
unsigned char len, u16 idx,
|
u8 option, u8 *optval, u8 optlen)
|
||||||
unsigned char *value)
|
|
||||||
{
|
{
|
||||||
struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
|
struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
|
||||||
struct ccid3_options_received *opt_recv = &hc->tx_options_received;
|
|
||||||
__be32 opt_val;
|
__be32 opt_val;
|
||||||
|
|
||||||
switch (option) {
|
switch (option) {
|
||||||
case TFRC_OPT_RECEIVE_RATE:
|
case TFRC_OPT_RECEIVE_RATE:
|
||||||
case TFRC_OPT_LOSS_EVENT_RATE:
|
case TFRC_OPT_LOSS_EVENT_RATE:
|
||||||
if (unlikely(len != 4)) {
|
/* Must be ignored on Data packets, cf. RFC 4342 8.3 and 8.5 */
|
||||||
|
if (packet_type == DCCP_PKT_DATA)
|
||||||
|
break;
|
||||||
|
if (unlikely(optlen != 4)) {
|
||||||
DCCP_WARN("%s(%p), invalid len %d for %u\n",
|
DCCP_WARN("%s(%p), invalid len %d for %u\n",
|
||||||
dccp_role(sk), sk, len, option);
|
dccp_role(sk), sk, optlen, option);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
opt_val = ntohl(get_unaligned((__be32 *)value));
|
opt_val = ntohl(get_unaligned((__be32 *)optval));
|
||||||
|
|
||||||
if (option == TFRC_OPT_RECEIVE_RATE) {
|
if (option == TFRC_OPT_RECEIVE_RATE) {
|
||||||
opt_recv->ccid3or_receive_rate = opt_val;
|
/* Receive Rate is kept in units of 64 bytes/second */
|
||||||
|
hc->tx_x_recv = opt_val;
|
||||||
|
hc->tx_x_recv <<= 6;
|
||||||
|
|
||||||
ccid3_pr_debug("%s(%p), RECEIVE_RATE=%u\n",
|
ccid3_pr_debug("%s(%p), RECEIVE_RATE=%u\n",
|
||||||
dccp_role(sk), sk, opt_val);
|
dccp_role(sk), sk, opt_val);
|
||||||
} else {
|
} else {
|
||||||
opt_recv->ccid3or_loss_event_rate = opt_val;
|
/* Update the fixpoint Loss Event Rate fraction */
|
||||||
|
hc->tx_p = tfrc_invert_loss_event_rate(opt_val);
|
||||||
|
|
||||||
ccid3_pr_debug("%s(%p), LOSS_EVENT_RATE=%u\n",
|
ccid3_pr_debug("%s(%p), LOSS_EVENT_RATE=%u\n",
|
||||||
dccp_role(sk), sk, opt_val);
|
dccp_role(sk), sk, opt_val);
|
||||||
}
|
}
|
||||||
@@ -527,9 +512,7 @@ static void ccid3_hc_tx_exit(struct sock *sk)
|
|||||||
{
|
{
|
||||||
struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
|
struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
|
||||||
|
|
||||||
ccid3_hc_tx_set_state(sk, TFRC_SSTATE_TERM);
|
|
||||||
sk_stop_timer(sk, &hc->tx_no_feedback_timer);
|
sk_stop_timer(sk, &hc->tx_no_feedback_timer);
|
||||||
|
|
||||||
tfrc_tx_hist_purge(&hc->tx_hist);
|
tfrc_tx_hist_purge(&hc->tx_hist);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -588,7 +571,6 @@ static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state)
|
|||||||
static const char *const ccid3_rx_state_names[] = {
|
static const char *const ccid3_rx_state_names[] = {
|
||||||
[TFRC_RSTATE_NO_DATA] = "NO_DATA",
|
[TFRC_RSTATE_NO_DATA] = "NO_DATA",
|
||||||
[TFRC_RSTATE_DATA] = "DATA",
|
[TFRC_RSTATE_DATA] = "DATA",
|
||||||
[TFRC_RSTATE_TERM] = "TERM",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return ccid3_rx_state_names[state];
|
return ccid3_rx_state_names[state];
|
||||||
@@ -614,14 +596,9 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk,
|
|||||||
{
|
{
|
||||||
struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk);
|
struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk);
|
||||||
struct dccp_sock *dp = dccp_sk(sk);
|
struct dccp_sock *dp = dccp_sk(sk);
|
||||||
ktime_t now;
|
ktime_t now = ktime_get_real();
|
||||||
s64 delta = 0;
|
s64 delta = 0;
|
||||||
|
|
||||||
if (unlikely(hc->rx_state == TFRC_RSTATE_TERM))
|
|
||||||
return;
|
|
||||||
|
|
||||||
now = ktime_get_real();
|
|
||||||
|
|
||||||
switch (fbtype) {
|
switch (fbtype) {
|
||||||
case CCID3_FBACK_INITIAL:
|
case CCID3_FBACK_INITIAL:
|
||||||
hc->rx_x_recv = 0;
|
hc->rx_x_recv = 0;
|
||||||
@@ -825,8 +802,6 @@ static void ccid3_hc_rx_exit(struct sock *sk)
|
|||||||
{
|
{
|
||||||
struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk);
|
struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk);
|
||||||
|
|
||||||
ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM);
|
|
||||||
|
|
||||||
tfrc_rx_hist_purge(&hc->rx_hist);
|
tfrc_rx_hist_purge(&hc->rx_hist);
|
||||||
tfrc_lh_cleanup(&hc->rx_li_hist);
|
tfrc_lh_cleanup(&hc->rx_li_hist);
|
||||||
}
|
}
|
||||||
@@ -851,8 +826,7 @@ static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
rx_info.tfrcrx_x_recv = hc->rx_x_recv;
|
rx_info.tfrcrx_x_recv = hc->rx_x_recv;
|
||||||
rx_info.tfrcrx_rtt = hc->rx_rtt;
|
rx_info.tfrcrx_rtt = hc->rx_rtt;
|
||||||
rx_info.tfrcrx_p = hc->rx_pinv == 0 ? ~0U :
|
rx_info.tfrcrx_p = tfrc_invert_loss_event_rate(hc->rx_pinv);
|
||||||
scaled_div(1, hc->rx_pinv);
|
|
||||||
len = sizeof(rx_info);
|
len = sizeof(rx_info);
|
||||||
val = &rx_info;
|
val = &rx_info;
|
||||||
break;
|
break;
|
||||||
|
@@ -67,17 +67,11 @@ enum ccid3_options {
|
|||||||
TFRC_OPT_RECEIVE_RATE = 194,
|
TFRC_OPT_RECEIVE_RATE = 194,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ccid3_options_received {
|
|
||||||
u32 ccid3or_loss_event_rate;
|
|
||||||
u32 ccid3or_receive_rate;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* TFRC sender states */
|
/* TFRC sender states */
|
||||||
enum ccid3_hc_tx_states {
|
enum ccid3_hc_tx_states {
|
||||||
TFRC_SSTATE_NO_SENT = 1,
|
TFRC_SSTATE_NO_SENT = 1,
|
||||||
TFRC_SSTATE_NO_FBACK,
|
TFRC_SSTATE_NO_FBACK,
|
||||||
TFRC_SSTATE_FBACK,
|
TFRC_SSTATE_FBACK,
|
||||||
TFRC_SSTATE_TERM,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -98,7 +92,6 @@ enum ccid3_hc_tx_states {
|
|||||||
* @tx_t_ld: Time last doubled during slow start
|
* @tx_t_ld: Time last doubled during slow start
|
||||||
* @tx_t_nom: Nominal send time of next packet
|
* @tx_t_nom: Nominal send time of next packet
|
||||||
* @tx_hist: Packet history
|
* @tx_hist: Packet history
|
||||||
* @tx_options_received: Parsed set of retrieved options
|
|
||||||
*/
|
*/
|
||||||
struct ccid3_hc_tx_sock {
|
struct ccid3_hc_tx_sock {
|
||||||
u64 tx_x;
|
u64 tx_x;
|
||||||
@@ -116,7 +109,6 @@ struct ccid3_hc_tx_sock {
|
|||||||
ktime_t tx_t_ld;
|
ktime_t tx_t_ld;
|
||||||
ktime_t tx_t_nom;
|
ktime_t tx_t_nom;
|
||||||
struct tfrc_tx_hist_entry *tx_hist;
|
struct tfrc_tx_hist_entry *tx_hist;
|
||||||
struct ccid3_options_received tx_options_received;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk)
|
static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk)
|
||||||
@@ -130,7 +122,6 @@ static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk)
|
|||||||
enum ccid3_hc_rx_states {
|
enum ccid3_hc_rx_states {
|
||||||
TFRC_RSTATE_NO_DATA = 1,
|
TFRC_RSTATE_NO_DATA = 1,
|
||||||
TFRC_RSTATE_DATA,
|
TFRC_RSTATE_DATA,
|
||||||
TFRC_RSTATE_TERM = 127,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -57,6 +57,7 @@ static inline u32 tfrc_ewma(const u32 avg, const u32 newval, const u8 weight)
|
|||||||
|
|
||||||
extern u32 tfrc_calc_x(u16 s, u32 R, u32 p);
|
extern u32 tfrc_calc_x(u16 s, u32 R, u32 p);
|
||||||
extern u32 tfrc_calc_x_reverse_lookup(u32 fvalue);
|
extern u32 tfrc_calc_x_reverse_lookup(u32 fvalue);
|
||||||
|
extern u32 tfrc_invert_loss_event_rate(u32 loss_event_rate);
|
||||||
|
|
||||||
extern int tfrc_tx_packet_history_init(void);
|
extern int tfrc_tx_packet_history_init(void);
|
||||||
extern void tfrc_tx_packet_history_exit(void);
|
extern void tfrc_tx_packet_history_exit(void);
|
||||||
|
@@ -687,3 +687,17 @@ u32 tfrc_calc_x_reverse_lookup(u32 fvalue)
|
|||||||
index = tfrc_binsearch(fvalue, 0);
|
index = tfrc_binsearch(fvalue, 0);
|
||||||
return (index + 1) * 1000000 / TFRC_CALC_X_ARRSIZE;
|
return (index + 1) * 1000000 / TFRC_CALC_X_ARRSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tfrc_invert_loss_event_rate - Compute p so that 10^6 corresponds to 100%
|
||||||
|
* When @loss_event_rate is large, there is a chance that p is truncated to 0.
|
||||||
|
* To avoid re-entering slow-start in that case, we set p = TFRC_SMALLEST_P > 0.
|
||||||
|
*/
|
||||||
|
u32 tfrc_invert_loss_event_rate(u32 loss_event_rate)
|
||||||
|
{
|
||||||
|
if (loss_event_rate == UINT_MAX) /* see RFC 4342, 8.5 */
|
||||||
|
return 0;
|
||||||
|
if (unlikely(loss_event_rate == 0)) /* map 1/0 into 100% */
|
||||||
|
return 1000000;
|
||||||
|
return max_t(u32, scaled_div(1, loss_event_rate), TFRC_SMALLEST_P);
|
||||||
|
}
|
||||||
|
@@ -96,18 +96,11 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CCID-Specific Options (from RFC 4340, sec. 10.3):
|
|
||||||
*
|
|
||||||
* Option numbers 128 through 191 are for options sent from the
|
|
||||||
* HC-Sender to the HC-Receiver; option numbers 192 through 255
|
|
||||||
* are for options sent from the HC-Receiver to the HC-Sender.
|
|
||||||
*
|
|
||||||
* CCID-specific options are ignored during connection setup, as
|
* CCID-specific options are ignored during connection setup, as
|
||||||
* negotiation may still be in progress (see RFC 4340, 10.3).
|
* negotiation may still be in progress (see RFC 4340, 10.3).
|
||||||
* The same applies to Ack Vectors, as these depend on the CCID.
|
* The same applies to Ack Vectors, as these depend on the CCID.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
if (dreq != NULL && (opt >= 128 ||
|
if (dreq != NULL && (opt >= DCCPO_MIN_RX_CCID_SPECIFIC ||
|
||||||
opt == DCCPO_ACK_VECTOR_0 || opt == DCCPO_ACK_VECTOR_1))
|
opt == DCCPO_ACK_VECTOR_0 || opt == DCCPO_ACK_VECTOR_1))
|
||||||
goto ignore_option;
|
goto ignore_option;
|
||||||
|
|
||||||
@@ -226,23 +219,15 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
|
|||||||
dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n",
|
dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n",
|
||||||
dccp_role(sk), elapsed_time);
|
dccp_role(sk), elapsed_time);
|
||||||
break;
|
break;
|
||||||
case 128 ... 191: {
|
case DCCPO_MIN_RX_CCID_SPECIFIC ... DCCPO_MAX_RX_CCID_SPECIFIC:
|
||||||
const u16 idx = value - options;
|
|
||||||
|
|
||||||
if (ccid_hc_rx_parse_options(dp->dccps_hc_rx_ccid, sk,
|
if (ccid_hc_rx_parse_options(dp->dccps_hc_rx_ccid, sk,
|
||||||
opt, len, idx,
|
pkt_type, opt, value, len))
|
||||||
value) != 0)
|
|
||||||
goto out_invalid_option;
|
goto out_invalid_option;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 192 ... 255: {
|
case DCCPO_MIN_TX_CCID_SPECIFIC ... DCCPO_MAX_TX_CCID_SPECIFIC:
|
||||||
const u16 idx = value - options;
|
|
||||||
|
|
||||||
if (ccid_hc_tx_parse_options(dp->dccps_hc_tx_ccid, sk,
|
if (ccid_hc_tx_parse_options(dp->dccps_hc_tx_ccid, sk,
|
||||||
opt, len, idx,
|
pkt_type, opt, value, len))
|
||||||
value) != 0)
|
|
||||||
goto out_invalid_option;
|
goto out_invalid_option;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DCCP_CRIT("DCCP(%p): option %d(len=%d) not "
|
DCCP_CRIT("DCCP(%p): option %d(len=%d) not "
|
||||||
|
Reference in New Issue
Block a user