[DCCP] options: Make dccp_insert_options & friends yell on error
And not the silly LIMIT_NETDEBUG and silently return without inserting the option requested. Also drop some old debugging messages associated to option insertion. Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
110bae4efb
commit
2d0817d11e
@@ -81,15 +81,16 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb)
|
|||||||
if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
|
if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
avr = dccp_ackvec_record_new();
|
|
||||||
if (avr == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
dccp_timestamp(sk, &now);
|
dccp_timestamp(sk, &now);
|
||||||
elapsed_time = timeval_delta(&now, &av->dccpav_time) / 10;
|
elapsed_time = timeval_delta(&now, &av->dccpav_time) / 10;
|
||||||
|
|
||||||
if (elapsed_time != 0)
|
if (elapsed_time != 0 &&
|
||||||
dccp_insert_option_elapsed_time(sk, skb, elapsed_time);
|
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;
|
DCCP_SKB_CB(skb)->dccpd_opt_len += len;
|
||||||
|
|
||||||
@@ -310,7 +311,6 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
|
|||||||
av->dccpav_buf_ackno = ackno;
|
av->dccpav_buf_ackno = ackno;
|
||||||
dccp_timestamp(sk, &av->dccpav_time);
|
dccp_timestamp(sk, &av->dccpav_time);
|
||||||
out:
|
out:
|
||||||
dccp_pr_debug("");
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_duplicate:
|
out_duplicate:
|
||||||
|
@@ -41,9 +41,9 @@ struct ccid_operations {
|
|||||||
unsigned char option,
|
unsigned char option,
|
||||||
unsigned char len, u16 idx,
|
unsigned char len, u16 idx,
|
||||||
unsigned char* value);
|
unsigned char* value);
|
||||||
void (*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_insert_options)(struct sock *sk,
|
int (*ccid_hc_tx_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);
|
||||||
@@ -146,18 +146,20 @@ static inline int ccid_hc_rx_parse_options(struct ccid *ccid, struct sock *sk,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ccid_hc_tx_insert_options(struct ccid *ccid, struct sock *sk,
|
static inline int ccid_hc_tx_insert_options(struct ccid *ccid, struct sock *sk,
|
||||||
struct sk_buff *skb)
|
struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
if (ccid->ccid_ops->ccid_hc_tx_insert_options != NULL)
|
if (ccid->ccid_ops->ccid_hc_tx_insert_options != NULL)
|
||||||
ccid->ccid_ops->ccid_hc_tx_insert_options(sk, skb);
|
return ccid->ccid_ops->ccid_hc_tx_insert_options(sk, skb);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void 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,
|
||||||
struct sk_buff *skb)
|
struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
if (ccid->ccid_ops->ccid_hc_rx_insert_options != NULL)
|
if (ccid->ccid_ops->ccid_hc_rx_insert_options != NULL)
|
||||||
ccid->ccid_ops->ccid_hc_rx_insert_options(sk, skb);
|
return ccid->ccid_ops->ccid_hc_rx_insert_options(sk, skb);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ccid_hc_rx_get_info(struct ccid *ccid, struct sock *sk,
|
static inline void ccid_hc_rx_get_info(struct ccid *ccid, struct sock *sk,
|
||||||
|
@@ -574,16 +574,15 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb)
|
static int ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
|
const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
|
||||||
|
|
||||||
BUG_ON(hctx == NULL);
|
BUG_ON(hctx == NULL);
|
||||||
|
|
||||||
if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
|
if (sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN)
|
||||||
return;
|
DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count;
|
||||||
|
return 0;
|
||||||
DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
|
static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
|
||||||
@@ -774,7 +773,7 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk)
|
|||||||
dccp_send_ack(sk);
|
dccp_send_ack(sk);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
|
static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
|
const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
|
||||||
__be32 x_recv, pinv;
|
__be32 x_recv, pinv;
|
||||||
@@ -782,23 +781,27 @@ static void ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
|
|||||||
BUG_ON(hcrx == NULL);
|
BUG_ON(hcrx == NULL);
|
||||||
|
|
||||||
if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
|
if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_last_counter;
|
DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_last_counter;
|
||||||
|
|
||||||
if (dccp_packet_without_ack(skb))
|
if (dccp_packet_without_ack(skb))
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
if (hcrx->ccid3hcrx_elapsed_time != 0)
|
|
||||||
dccp_insert_option_elapsed_time(sk, skb,
|
|
||||||
hcrx->ccid3hcrx_elapsed_time);
|
|
||||||
dccp_insert_option_timestamp(sk, skb);
|
|
||||||
x_recv = htonl(hcrx->ccid3hcrx_x_recv);
|
x_recv = htonl(hcrx->ccid3hcrx_x_recv);
|
||||||
pinv = htonl(hcrx->ccid3hcrx_pinv);
|
pinv = htonl(hcrx->ccid3hcrx_pinv);
|
||||||
dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE,
|
|
||||||
&pinv, sizeof(pinv));
|
if ((hcrx->ccid3hcrx_elapsed_time != 0 &&
|
||||||
dccp_insert_option(sk, skb, TFRC_OPT_RECEIVE_RATE,
|
dccp_insert_option_elapsed_time(sk, skb,
|
||||||
&x_recv, sizeof(x_recv));
|
hcrx->ccid3hcrx_elapsed_time)) ||
|
||||||
|
dccp_insert_option_timestamp(sk, skb) ||
|
||||||
|
dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE,
|
||||||
|
&pinv, sizeof(pinv)) ||
|
||||||
|
dccp_insert_option(sk, skb, TFRC_OPT_RECEIVE_RATE,
|
||||||
|
&x_recv, sizeof(x_recv)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calculate first loss interval
|
/* calculate first loss interval
|
||||||
|
@@ -326,13 +326,13 @@ static inline int dccp_ack_pending(const struct sock *sk)
|
|||||||
inet_csk_ack_scheduled(sk);
|
inet_csk_ack_scheduled(sk);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void dccp_insert_options(struct sock *sk, struct sk_buff *skb);
|
extern int dccp_insert_options(struct sock *sk, struct sk_buff *skb);
|
||||||
extern void dccp_insert_option_elapsed_time(struct sock *sk,
|
extern int dccp_insert_option_elapsed_time(struct sock *sk,
|
||||||
struct sk_buff *skb,
|
struct sk_buff *skb,
|
||||||
u32 elapsed_time);
|
u32 elapsed_time);
|
||||||
extern void dccp_insert_option_timestamp(struct sock *sk,
|
extern int dccp_insert_option_timestamp(struct sock *sk,
|
||||||
struct sk_buff *skb);
|
struct sk_buff *skb);
|
||||||
extern void dccp_insert_option(struct sock *sk, struct sk_buff *skb,
|
extern int dccp_insert_option(struct sock *sk, struct sk_buff *skb,
|
||||||
unsigned char option,
|
unsigned char option,
|
||||||
const void *value, unsigned char len);
|
const void *value, unsigned char len);
|
||||||
|
|
||||||
|
@@ -283,17 +283,14 @@ static inline int dccp_ndp_len(const int ndp)
|
|||||||
return likely(ndp <= 0xFF) ? 1 : ndp <= 0xFFFF ? 2 : 3;
|
return likely(ndp <= 0xFF) ? 1 : ndp <= 0xFFFF ? 2 : 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dccp_insert_option(struct sock *sk, struct sk_buff *skb,
|
int dccp_insert_option(struct sock *sk, struct sk_buff *skb,
|
||||||
const unsigned char option,
|
const unsigned char option,
|
||||||
const void *value, const unsigned char len)
|
const void *value, const unsigned char len)
|
||||||
{
|
{
|
||||||
unsigned char *to;
|
unsigned char *to;
|
||||||
|
|
||||||
if (DCCP_SKB_CB(skb)->dccpd_opt_len + len + 2 > DCCP_MAX_OPT_LEN) {
|
if (DCCP_SKB_CB(skb)->dccpd_opt_len + len + 2 > DCCP_MAX_OPT_LEN)
|
||||||
LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to insert "
|
return -1;
|
||||||
"%d option!\n", option);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DCCP_SKB_CB(skb)->dccpd_opt_len += len + 2;
|
DCCP_SKB_CB(skb)->dccpd_opt_len += len + 2;
|
||||||
|
|
||||||
@@ -302,11 +299,12 @@ void dccp_insert_option(struct sock *sk, struct sk_buff *skb,
|
|||||||
*to++ = len + 2;
|
*to++ = len + 2;
|
||||||
|
|
||||||
memcpy(to, value, len);
|
memcpy(to, value, len);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(dccp_insert_option);
|
EXPORT_SYMBOL_GPL(dccp_insert_option);
|
||||||
|
|
||||||
static void dccp_insert_option_ndp(struct sock *sk, struct sk_buff *skb)
|
static int dccp_insert_option_ndp(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct dccp_sock *dp = dccp_sk(sk);
|
struct dccp_sock *dp = dccp_sk(sk);
|
||||||
int ndp = dp->dccps_ndp_count;
|
int ndp = dp->dccps_ndp_count;
|
||||||
@@ -322,7 +320,7 @@ static void dccp_insert_option_ndp(struct sock *sk, struct sk_buff *skb)
|
|||||||
const int len = ndp_len + 2;
|
const int len = ndp_len + 2;
|
||||||
|
|
||||||
if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
|
if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
DCCP_SKB_CB(skb)->dccpd_opt_len += len;
|
DCCP_SKB_CB(skb)->dccpd_opt_len += len;
|
||||||
|
|
||||||
@@ -331,6 +329,8 @@ static void dccp_insert_option_ndp(struct sock *sk, struct sk_buff *skb)
|
|||||||
*ptr++ = len;
|
*ptr++ = len;
|
||||||
dccp_encode_value_var(ndp, ptr, ndp_len);
|
dccp_encode_value_var(ndp, ptr, ndp_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int dccp_elapsed_time_len(const u32 elapsed_time)
|
static inline int dccp_elapsed_time_len(const u32 elapsed_time)
|
||||||
@@ -338,27 +338,18 @@ static inline int dccp_elapsed_time_len(const u32 elapsed_time)
|
|||||||
return elapsed_time == 0 ? 0 : elapsed_time <= 0xFFFF ? 2 : 4;
|
return elapsed_time == 0 ? 0 : elapsed_time <= 0xFFFF ? 2 : 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dccp_insert_option_elapsed_time(struct sock *sk,
|
int dccp_insert_option_elapsed_time(struct sock *sk, struct sk_buff *skb,
|
||||||
struct sk_buff *skb,
|
u32 elapsed_time)
|
||||||
u32 elapsed_time)
|
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_IP_DCCP_DEBUG
|
|
||||||
struct dccp_sock *dp = dccp_sk(sk);
|
|
||||||
const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
|
|
||||||
"CLIENT TX opt: " : "server TX opt: ";
|
|
||||||
#endif
|
|
||||||
const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
|
const int elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
|
||||||
const int len = 2 + elapsed_time_len;
|
const int len = 2 + elapsed_time_len;
|
||||||
unsigned char *to;
|
unsigned char *to;
|
||||||
|
|
||||||
if (elapsed_time_len == 0)
|
if (elapsed_time_len == 0)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) {
|
if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
|
||||||
LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to "
|
return -1;
|
||||||
"insert elapsed time!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DCCP_SKB_CB(skb)->dccpd_opt_len += len;
|
DCCP_SKB_CB(skb)->dccpd_opt_len += len;
|
||||||
|
|
||||||
@@ -374,10 +365,7 @@ void dccp_insert_option_elapsed_time(struct sock *sk,
|
|||||||
memcpy(to, &var32, 4);
|
memcpy(to, &var32, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
dccp_pr_debug("%sELAPSED_TIME=%u, len=%d, seqno=%llu\n",
|
return 0;
|
||||||
debug_prefix, elapsed_time,
|
|
||||||
len,
|
|
||||||
(unsigned long long) DCCP_SKB_CB(skb)->dccpd_seq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(dccp_insert_option_elapsed_time);
|
EXPORT_SYMBOL_GPL(dccp_insert_option_elapsed_time);
|
||||||
@@ -398,7 +386,7 @@ void dccp_timestamp(const struct sock *sk, struct timeval *tv)
|
|||||||
|
|
||||||
EXPORT_SYMBOL_GPL(dccp_timestamp);
|
EXPORT_SYMBOL_GPL(dccp_timestamp);
|
||||||
|
|
||||||
void dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb)
|
int dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
__be32 now;
|
__be32 now;
|
||||||
@@ -408,19 +396,15 @@ void dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb)
|
|||||||
/* yes this will overflow but that is the point as we want a
|
/* yes this will overflow but that is the point as we want a
|
||||||
* 10 usec 32 bit timer which mean it wraps every 11.9 hours */
|
* 10 usec 32 bit timer which mean it wraps every 11.9 hours */
|
||||||
|
|
||||||
dccp_insert_option(sk, skb, DCCPO_TIMESTAMP, &now, sizeof(now));
|
return dccp_insert_option(sk, skb, DCCPO_TIMESTAMP, &now, sizeof(now));
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(dccp_insert_option_timestamp);
|
EXPORT_SYMBOL_GPL(dccp_insert_option_timestamp);
|
||||||
|
|
||||||
static void dccp_insert_option_timestamp_echo(struct sock *sk,
|
static int dccp_insert_option_timestamp_echo(struct sock *sk,
|
||||||
struct sk_buff *skb)
|
struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct dccp_sock *dp = dccp_sk(sk);
|
struct dccp_sock *dp = dccp_sk(sk);
|
||||||
#ifdef CONFIG_IP_DCCP_DEBUG
|
|
||||||
const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
|
|
||||||
"CLIENT TX opt: " : "server TX opt: ";
|
|
||||||
#endif
|
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
__be32 tstamp_echo;
|
__be32 tstamp_echo;
|
||||||
u32 elapsed_time;
|
u32 elapsed_time;
|
||||||
@@ -432,11 +416,8 @@ static void dccp_insert_option_timestamp_echo(struct sock *sk,
|
|||||||
elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
|
elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
|
||||||
len = 6 + elapsed_time_len;
|
len = 6 + elapsed_time_len;
|
||||||
|
|
||||||
if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) {
|
if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
|
||||||
LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small to insert "
|
return -1;
|
||||||
"timestamp echo!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DCCP_SKB_CB(skb)->dccpd_opt_len += len;
|
DCCP_SKB_CB(skb)->dccpd_opt_len += len;
|
||||||
|
|
||||||
@@ -456,14 +437,10 @@ static void dccp_insert_option_timestamp_echo(struct sock *sk,
|
|||||||
memcpy(to, &var32, 4);
|
memcpy(to, &var32, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
dccp_pr_debug("%sTIMESTAMP_ECHO=%u, len=%d, seqno=%llu\n",
|
|
||||||
debug_prefix, dp->dccps_timestamp_echo,
|
|
||||||
len,
|
|
||||||
(unsigned long long) DCCP_SKB_CB(skb)->dccpd_seq);
|
|
||||||
|
|
||||||
dp->dccps_timestamp_echo = 0;
|
dp->dccps_timestamp_echo = 0;
|
||||||
dp->dccps_timestamp_time.tv_sec = 0;
|
dp->dccps_timestamp_time.tv_sec = 0;
|
||||||
dp->dccps_timestamp_time.tv_usec = 0;
|
dp->dccps_timestamp_time.tv_usec = 0;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dccp_insert_feat_opt(struct sk_buff *skb, u8 type, u8 feat,
|
static int dccp_insert_feat_opt(struct sk_buff *skb, u8 type, u8 feat,
|
||||||
@@ -491,7 +468,7 @@ static int dccp_insert_feat_opt(struct sk_buff *skb, u8 type, u8 feat,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dccp_insert_feat(struct sock *sk, struct sk_buff *skb)
|
static int dccp_insert_options_feat(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct dccp_sock *dp = dccp_sk(sk);
|
struct dccp_sock *dp = dccp_sk(sk);
|
||||||
struct dccp_opt_pend *opt, *next;
|
struct dccp_opt_pend *opt, *next;
|
||||||
@@ -551,44 +528,48 @@ static void dccp_insert_feat(struct sock *sk, struct sk_buff *skb)
|
|||||||
inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
|
inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
|
||||||
inet_csk(sk)->icsk_rto, DCCP_RTO_MAX);
|
inet_csk(sk)->icsk_rto, DCCP_RTO_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dccp_insert_options(struct sock *sk, struct sk_buff *skb)
|
int dccp_insert_options(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
struct dccp_sock *dp = dccp_sk(sk);
|
struct dccp_sock *dp = dccp_sk(sk);
|
||||||
|
|
||||||
DCCP_SKB_CB(skb)->dccpd_opt_len = 0;
|
DCCP_SKB_CB(skb)->dccpd_opt_len = 0;
|
||||||
|
|
||||||
if (dp->dccps_options.dccpo_send_ndp_count)
|
if (dp->dccps_options.dccpo_send_ndp_count &&
|
||||||
dccp_insert_option_ndp(sk, skb);
|
dccp_insert_option_ndp(sk, skb))
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (!dccp_packet_without_ack(skb)) {
|
if (!dccp_packet_without_ack(skb)) {
|
||||||
if (dp->dccps_options.dccpo_send_ack_vector &&
|
if (dp->dccps_options.dccpo_send_ack_vector &&
|
||||||
dccp_ackvec_pending(dp->dccps_hc_rx_ackvec))
|
dccp_ackvec_pending(dp->dccps_hc_rx_ackvec) &&
|
||||||
dccp_insert_option_ackvec(sk, skb);
|
dccp_insert_option_ackvec(sk, skb))
|
||||||
if (dp->dccps_timestamp_echo != 0)
|
return -1;
|
||||||
dccp_insert_option_timestamp_echo(sk, skb);
|
|
||||||
|
if (dp->dccps_timestamp_echo != 0 &&
|
||||||
|
dccp_insert_option_timestamp_echo(sk, skb))
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dp->dccps_hc_rx_insert_options) {
|
if (dp->dccps_hc_rx_insert_options) {
|
||||||
ccid_hc_rx_insert_options(dp->dccps_hc_rx_ccid, sk, skb);
|
if (ccid_hc_rx_insert_options(dp->dccps_hc_rx_ccid, sk, skb))
|
||||||
|
return -1;
|
||||||
dp->dccps_hc_rx_insert_options = 0;
|
dp->dccps_hc_rx_insert_options = 0;
|
||||||
}
|
}
|
||||||
if (dp->dccps_hc_tx_insert_options) {
|
if (dp->dccps_hc_tx_insert_options) {
|
||||||
ccid_hc_tx_insert_options(dp->dccps_hc_tx_ccid, sk, skb);
|
if (ccid_hc_tx_insert_options(dp->dccps_hc_tx_ccid, sk, skb))
|
||||||
|
return -1;
|
||||||
dp->dccps_hc_tx_insert_options = 0;
|
dp->dccps_hc_tx_insert_options = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Feature negotiation */
|
/* Feature negotiation */
|
||||||
switch(DCCP_SKB_CB(skb)->dccpd_type) {
|
/* Data packets can't do feat negotiation */
|
||||||
/* Data packets can't do feat negotiation */
|
if (DCCP_SKB_CB(skb)->dccpd_type != DCCP_PKT_DATA &&
|
||||||
case DCCP_PKT_DATA:
|
DCCP_SKB_CB(skb)->dccpd_type != DCCP_PKT_DATAACK &&
|
||||||
case DCCP_PKT_DATAACK:
|
dccp_insert_options_feat(sk, skb))
|
||||||
break;
|
return -1;
|
||||||
default:
|
|
||||||
dccp_insert_feat(sk, skb);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* XXX: insert other options when appropriate */
|
/* XXX: insert other options when appropriate */
|
||||||
|
|
||||||
@@ -602,4 +583,6 @@ void dccp_insert_options(struct sock *sk, struct sk_buff *skb)
|
|||||||
DCCP_SKB_CB(skb)->dccpd_opt_len += padding;
|
DCCP_SKB_CB(skb)->dccpd_opt_len += padding;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -83,7 +83,11 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dcb->dccpd_seq = dp->dccps_gss;
|
dcb->dccpd_seq = dp->dccps_gss;
|
||||||
dccp_insert_options(sk, skb);
|
|
||||||
|
if (dccp_insert_options(sk, skb)) {
|
||||||
|
kfree_skb(skb);
|
||||||
|
return -EPROTO;
|
||||||
|
}
|
||||||
|
|
||||||
skb->h.raw = skb_push(skb, dccp_header_size);
|
skb->h.raw = skb_push(skb, dccp_header_size);
|
||||||
dh = dccp_hdr(skb);
|
dh = dccp_hdr(skb);
|
||||||
@@ -296,7 +300,11 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
|
|||||||
dreq = dccp_rsk(req);
|
dreq = dccp_rsk(req);
|
||||||
DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE;
|
DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE;
|
||||||
DCCP_SKB_CB(skb)->dccpd_seq = dreq->dreq_iss;
|
DCCP_SKB_CB(skb)->dccpd_seq = dreq->dreq_iss;
|
||||||
dccp_insert_options(sk, skb);
|
|
||||||
|
if (dccp_insert_options(sk, skb)) {
|
||||||
|
kfree_skb(skb);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
skb->h.raw = skb_push(skb, dccp_header_size);
|
skb->h.raw = skb_push(skb, dccp_header_size);
|
||||||
|
|
||||||
@@ -344,7 +352,11 @@ static struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst,
|
|||||||
DCCP_SKB_CB(skb)->dccpd_reset_code = code;
|
DCCP_SKB_CB(skb)->dccpd_reset_code = code;
|
||||||
DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESET;
|
DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESET;
|
||||||
DCCP_SKB_CB(skb)->dccpd_seq = dp->dccps_gss;
|
DCCP_SKB_CB(skb)->dccpd_seq = dp->dccps_gss;
|
||||||
dccp_insert_options(sk, skb);
|
|
||||||
|
if (dccp_insert_options(sk, skb)) {
|
||||||
|
kfree_skb(skb);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
skb->h.raw = skb_push(skb, dccp_header_size);
|
skb->h.raw = skb_push(skb, dccp_header_size);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user