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, |