diff options
| -rw-r--r-- | include/linux/dccp.h | 7 | ||||
| -rw-r--r-- | net/dccp/ccids/ccid3.c | 12 | ||||
| -rw-r--r-- | net/dccp/proto.c | 52 |
3 files changed, 59 insertions, 12 deletions
diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 9e3a1370b906..007c290f74d4 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h | |||
| @@ -186,6 +186,9 @@ enum { | |||
| 186 | DCCPF_MAX_CCID_SPECIFIC = 255, | 186 | DCCPF_MAX_CCID_SPECIFIC = 255, |
| 187 | }; | 187 | }; |
| 188 | 188 | ||
| 189 | /* DCCP socket options */ | ||
| 190 | #define DCCP_SOCKOPT_PACKET_SIZE 1 | ||
| 191 | |||
| 189 | #ifdef __KERNEL__ | 192 | #ifdef __KERNEL__ |
| 190 | 193 | ||
| 191 | #include <linux/in.h> | 194 | #include <linux/in.h> |
| @@ -396,7 +399,7 @@ enum dccp_role { | |||
| 396 | * @dccps_timestamp_echo - latest timestamp received on a TIMESTAMP option | 399 | * @dccps_timestamp_echo - latest timestamp received on a TIMESTAMP option |
| 397 | * @dccps_ext_header_len - network protocol overhead (IP/IPv6 options) | 400 | * @dccps_ext_header_len - network protocol overhead (IP/IPv6 options) |
| 398 | * @dccps_pmtu_cookie - Last pmtu seen by socket | 401 | * @dccps_pmtu_cookie - Last pmtu seen by socket |
| 399 | * @dccps_avg_packet_size - FIXME: has to be set by the app thru some setsockopt or ioctl, CCID3 uses it | 402 | * @dccps_packet_size - Set thru setsockopt |
| 400 | * @dccps_role - Role of this sock, one of %dccp_role | 403 | * @dccps_role - Role of this sock, one of %dccp_role |
| 401 | * @dccps_ndp_count - number of Non Data Packets since last data packet | 404 | * @dccps_ndp_count - number of Non Data Packets since last data packet |
| 402 | * @dccps_hc_rx_ackpkts - receiver half connection acked packets | 405 | * @dccps_hc_rx_ackpkts - receiver half connection acked packets |
| @@ -417,7 +420,7 @@ struct dccp_sock { | |||
| 417 | unsigned long dccps_service; | 420 | unsigned long dccps_service; |
| 418 | struct timeval dccps_timestamp_time; | 421 | struct timeval dccps_timestamp_time; |
| 419 | __u32 dccps_timestamp_echo; | 422 | __u32 dccps_timestamp_echo; |
| 420 | __u32 dccps_avg_packet_size; | 423 | __u32 dccps_packet_size; |
| 421 | unsigned long dccps_ndp_count; | 424 | unsigned long dccps_ndp_count; |
| 422 | __u16 dccps_ext_header_len; | 425 | __u16 dccps_ext_header_len; |
| 423 | __u32 dccps_pmtu_cookie; | 426 | __u32 dccps_pmtu_cookie; |
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 4ff6ede0f07d..e22b0eefdbf9 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) | |||
| 672 | 672 | ||
| 673 | memset(hctx, 0, sizeof(*hctx)); | 673 | memset(hctx, 0, sizeof(*hctx)); |
| 674 | 674 | ||
| 675 | if (dp->dccps_avg_packet_size >= TFRC_MIN_PACKET_SIZE && | 675 | if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE && |
| 676 | dp->dccps_avg_packet_size <= TFRC_MAX_PACKET_SIZE) | 676 | dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE) |
| 677 | hctx->ccid3hctx_s = (u16)dp->dccps_avg_packet_size; | 677 | hctx->ccid3hctx_s = dp->dccps_packet_size; |
| 678 | else | 678 | else |
| 679 | hctx->ccid3hctx_s = TFRC_STD_PACKET_SIZE; | 679 | hctx->ccid3hctx_s = TFRC_STD_PACKET_SIZE; |
| 680 | 680 | ||
| @@ -1058,9 +1058,9 @@ static int ccid3_hc_rx_init(struct sock *sk) | |||
| 1058 | 1058 | ||
| 1059 | memset(hcrx, 0, sizeof(*hcrx)); | 1059 | memset(hcrx, 0, sizeof(*hcrx)); |
| 1060 | 1060 | ||
| 1061 | if (dp->dccps_avg_packet_size >= TFRC_MIN_PACKET_SIZE && | 1061 | if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE && |
| 1062 | dp->dccps_avg_packet_size <= TFRC_MAX_PACKET_SIZE) | 1062 | dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE) |
| 1063 | hcrx->ccid3hcrx_s = (u16)dp->dccps_avg_packet_size; | 1063 | hcrx->ccid3hcrx_s = dp->dccps_packet_size; |
| 1064 | else | 1064 | else |
| 1065 | hcrx->ccid3hcrx_s = TFRC_STD_PACKET_SIZE; | 1065 | hcrx->ccid3hcrx_s = TFRC_STD_PACKET_SIZE; |
| 1066 | 1066 | ||
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index f4da6561e40c..18a0e69c9dc7 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) | |||
| 205 | int dccp_setsockopt(struct sock *sk, int level, int optname, | 205 | int dccp_setsockopt(struct sock *sk, int level, int optname, |
| 206 | char __user *optval, int optlen) | 206 | char __user *optval, int optlen) |
| 207 | { | 207 | { |
| 208 | dccp_pr_debug("entry\n"); | 208 | struct dccp_sock *dp; |
| 209 | int err; | ||
| 210 | int val; | ||
| 209 | 211 | ||
| 210 | if (level != SOL_DCCP) | 212 | if (level != SOL_DCCP) |
| 211 | return ip_setsockopt(sk, level, optname, optval, optlen); | 213 | return ip_setsockopt(sk, level, optname, optval, optlen); |
| 212 | 214 | ||
| 213 | return -EOPNOTSUPP; | 215 | if (optlen < sizeof(int)) |
| 216 | return -EINVAL; | ||
| 217 | |||
| 218 | if (get_user(val, (int __user *)optval)) | ||
| 219 | return -EFAULT; | ||
| 220 | |||
| 221 | lock_sock(sk); | ||
| 222 | |||
| 223 | dp = dccp_sk(sk); | ||
| 224 | err = 0; | ||
| 225 | |||
| 226 | switch (optname) { | ||
| 227 | case DCCP_SOCKOPT_PACKET_SIZE: | ||
| 228 | dp->dccps_packet_size = val; | ||
| 229 | break; | ||
| 230 | default: | ||
| 231 | err = -ENOPROTOOPT; | ||
| 232 | break; | ||
| 233 | } | ||
| 234 | |||
| 235 | release_sock(sk); | ||
| 236 | return err; | ||
| 214 | } | 237 | } |
| 215 | 238 | ||
| 216 | int dccp_getsockopt(struct sock *sk, int level, int optname, | 239 | int dccp_getsockopt(struct sock *sk, int level, int optname, |
| 217 | char __user *optval, int __user *optlen) | 240 | char __user *optval, int __user *optlen) |
| 218 | { | 241 | { |
| 219 | dccp_pr_debug("entry\n"); | 242 | struct dccp_sock *dp; |
| 243 | int val, len; | ||
| 220 | 244 | ||
| 221 | if (level != SOL_DCCP) | 245 | if (level != SOL_DCCP) |
| 222 | return ip_getsockopt(sk, level, optname, optval, optlen); | 246 | return ip_getsockopt(sk, level, optname, optval, optlen); |
| 223 | 247 | ||
| 224 | return -EOPNOTSUPP; | 248 | if (get_user(len, optlen)) |
| 249 | return -EFAULT; | ||
| 250 | |||
| 251 | len = min_t(unsigned int, len, sizeof(int)); | ||
| 252 | if (len < 0) | ||
| 253 | return -EINVAL; | ||
| 254 | |||
| 255 | dp = dccp_sk(sk); | ||
| 256 | |||
| 257 | switch (optname) { | ||
| 258 | case DCCP_SOCKOPT_PACKET_SIZE: | ||
| 259 | val = dp->dccps_packet_size; | ||
| 260 | break; | ||
| 261 | default: | ||
| 262 | return -ENOPROTOOPT; | ||
| 263 | } | ||
| 264 | |||
| 265 | if (put_user(len, optlen) || copy_to_user(optval, &val, len)) | ||
| 266 | return -EFAULT; | ||
| 267 | |||
| 268 | return 0; | ||
| 225 | } | 269 | } |
| 226 | 270 | ||
| 227 | int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | 271 | int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, |
