diff options
Diffstat (limited to 'net/dccp')
-rw-r--r-- | net/dccp/ccids/ccid3.c | 12 | ||||
-rw-r--r-- | net/dccp/proto.c | 52 |
2 files changed, 54 insertions, 10 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 4ff6ede0f07..e22b0eefdbf 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -672,9 +672,9 @@ static int ccid3_hc_tx_init(struct sock *sk) memset(hctx, 0, sizeof(*hctx)); - if (dp->dccps_avg_packet_size >= TFRC_MIN_PACKET_SIZE && - dp->dccps_avg_packet_size <= TFRC_MAX_PACKET_SIZE) - hctx->ccid3hctx_s = (u16)dp->dccps_avg_packet_size; + if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE && + dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE) + hctx->ccid3hctx_s = dp->dccps_packet_size; else hctx->ccid3hctx_s = TFRC_STD_PACKET_SIZE; @@ -1058,9 +1058,9 @@ static int ccid3_hc_rx_init(struct sock *sk) memset(hcrx, 0, sizeof(*hcrx)); - if (dp->dccps_avg_packet_size >= TFRC_MIN_PACKET_SIZE && - dp->dccps_avg_packet_size <= TFRC_MAX_PACKET_SIZE) - hcrx->ccid3hcrx_s = (u16)dp->dccps_avg_packet_size; + if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE && + dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE) + hcrx->ccid3hcrx_s = dp->dccps_packet_size; else hcrx->ccid3hcrx_s = TFRC_STD_PACKET_SIZE; diff --git a/net/dccp/proto.c b/net/dccp/proto.c index f4da6561e40..18a0e69c9dc 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c @@ -205,23 +205,67 @@ int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg) int dccp_setsockopt(struct sock *sk, int level, int optname, char __user *optval, int optlen) { - dccp_pr_debug("entry\n"); + struct dccp_sock *dp; + int err; + int val; if (level != SOL_DCCP) return ip_setsockopt(sk, level, optname, optval, optlen); - return -EOPNOTSUPP; + if (optlen < sizeof(int)) + return -EINVAL; + + if (get_user(val, (int __user *)optval)) + return -EFAULT; + + lock_sock(sk); + + dp = dccp_sk(sk); + err = 0; + + switch (optname) { + case DCCP_SOCKOPT_PACKET_SIZE: + dp->dccps_packet_size = val; + break; + default: + err = -ENOPROTOOPT; + break; + } + + release_sock(sk); + return err; } int dccp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen) { - dccp_pr_debug("entry\n"); + struct dccp_sock *dp; + int val, len; if (level != SOL_DCCP) return ip_getsockopt(sk, level, optname, optval, optlen); - return -EOPNOTSUPP; + if (get_user(len, optlen)) + return -EFAULT; + + len = min_t(unsigned int, len, sizeof(int)); + if (len < 0) + return -EINVAL; + + dp = dccp_sk(sk); + + switch (optname) { + case DCCP_SOCKOPT_PACKET_SIZE: + val = dp->dccps_packet_size; + break; + default: + return -ENOPROTOOPT; + } + + if (put_user(len, optlen) || copy_to_user(optval, &val, len)) + return -EFAULT; + + return 0; } int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, |