diff options
Diffstat (limited to 'net/dccp/proto.c')
-rw-r--r-- | net/dccp/proto.c | 64 |
1 files changed, 44 insertions, 20 deletions
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index 72cbdcfc2c65..5ec47d9ee447 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c | |||
@@ -52,6 +52,9 @@ struct inet_hashinfo __cacheline_aligned dccp_hashinfo = { | |||
52 | 52 | ||
53 | EXPORT_SYMBOL_GPL(dccp_hashinfo); | 53 | EXPORT_SYMBOL_GPL(dccp_hashinfo); |
54 | 54 | ||
55 | /* the maximum queue length for tx in packets. 0 is no limit */ | ||
56 | int sysctl_dccp_tx_qlen __read_mostly = 5; | ||
57 | |||
55 | void dccp_set_state(struct sock *sk, const int state) | 58 | void dccp_set_state(struct sock *sk, const int state) |
56 | { | 59 | { |
57 | const int oldstate = sk->sk_state; | 60 | const int oldstate = sk->sk_state; |
@@ -212,6 +215,7 @@ int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized) | |||
212 | 215 | ||
213 | dccp_init_xmit_timers(sk); | 216 | dccp_init_xmit_timers(sk); |
214 | icsk->icsk_rto = DCCP_TIMEOUT_INIT; | 217 | icsk->icsk_rto = DCCP_TIMEOUT_INIT; |
218 | icsk->icsk_syn_retries = sysctl_dccp_request_retries; | ||
215 | sk->sk_state = DCCP_CLOSED; | 219 | sk->sk_state = DCCP_CLOSED; |
216 | sk->sk_write_space = dccp_write_space; | 220 | sk->sk_write_space = dccp_write_space; |
217 | icsk->icsk_sync_mss = dccp_sync_mss; | 221 | icsk->icsk_sync_mss = dccp_sync_mss; |
@@ -262,12 +266,12 @@ int dccp_destroy_sock(struct sock *sk) | |||
262 | 266 | ||
263 | EXPORT_SYMBOL_GPL(dccp_destroy_sock); | 267 | EXPORT_SYMBOL_GPL(dccp_destroy_sock); |
264 | 268 | ||
265 | static inline int dccp_listen_start(struct sock *sk) | 269 | static inline int dccp_listen_start(struct sock *sk, int backlog) |
266 | { | 270 | { |
267 | struct dccp_sock *dp = dccp_sk(sk); | 271 | struct dccp_sock *dp = dccp_sk(sk); |
268 | 272 | ||
269 | dp->dccps_role = DCCP_ROLE_LISTEN; | 273 | dp->dccps_role = DCCP_ROLE_LISTEN; |
270 | return inet_csk_listen_start(sk, TCP_SYNQ_HSIZE); | 274 | return inet_csk_listen_start(sk, backlog); |
271 | } | 275 | } |
272 | 276 | ||
273 | int dccp_disconnect(struct sock *sk, int flags) | 277 | int dccp_disconnect(struct sock *sk, int flags) |
@@ -451,9 +455,8 @@ out_free_val: | |||
451 | static int do_dccp_setsockopt(struct sock *sk, int level, int optname, | 455 | static int do_dccp_setsockopt(struct sock *sk, int level, int optname, |
452 | char __user *optval, int optlen) | 456 | char __user *optval, int optlen) |
453 | { | 457 | { |
454 | struct dccp_sock *dp; | 458 | struct dccp_sock *dp = dccp_sk(sk); |
455 | int err; | 459 | int val, err = 0; |
456 | int val; | ||
457 | 460 | ||
458 | if (optlen < sizeof(int)) | 461 | if (optlen < sizeof(int)) |
459 | return -EINVAL; | 462 | return -EINVAL; |
@@ -465,14 +468,11 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname, | |||
465 | return dccp_setsockopt_service(sk, val, optval, optlen); | 468 | return dccp_setsockopt_service(sk, val, optval, optlen); |
466 | 469 | ||
467 | lock_sock(sk); | 470 | lock_sock(sk); |
468 | dp = dccp_sk(sk); | ||
469 | err = 0; | ||
470 | |||
471 | switch (optname) { | 471 | switch (optname) { |
472 | case DCCP_SOCKOPT_PACKET_SIZE: | 472 | case DCCP_SOCKOPT_PACKET_SIZE: |
473 | dp->dccps_packet_size = val; | 473 | DCCP_WARN("sockopt(PACKET_SIZE) is deprecated: fix your app\n"); |
474 | err = 0; | ||
474 | break; | 475 | break; |
475 | |||
476 | case DCCP_SOCKOPT_CHANGE_L: | 476 | case DCCP_SOCKOPT_CHANGE_L: |
477 | if (optlen != sizeof(struct dccp_so_feat)) | 477 | if (optlen != sizeof(struct dccp_so_feat)) |
478 | err = -EINVAL; | 478 | err = -EINVAL; |
@@ -481,7 +481,6 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname, | |||
481 | (struct dccp_so_feat __user *) | 481 | (struct dccp_so_feat __user *) |
482 | optval); | 482 | optval); |
483 | break; | 483 | break; |
484 | |||
485 | case DCCP_SOCKOPT_CHANGE_R: | 484 | case DCCP_SOCKOPT_CHANGE_R: |
486 | if (optlen != sizeof(struct dccp_so_feat)) | 485 | if (optlen != sizeof(struct dccp_so_feat)) |
487 | err = -EINVAL; | 486 | err = -EINVAL; |
@@ -490,12 +489,26 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname, | |||
490 | (struct dccp_so_feat __user *) | 489 | (struct dccp_so_feat __user *) |
491 | optval); | 490 | optval); |
492 | break; | 491 | break; |
493 | 492 | case DCCP_SOCKOPT_SEND_CSCOV: /* sender side, RFC 4340, sec. 9.2 */ | |
493 | if (val < 0 || val > 15) | ||
494 | err = -EINVAL; | ||
495 | else | ||
496 | dp->dccps_pcslen = val; | ||
497 | break; | ||
498 | case DCCP_SOCKOPT_RECV_CSCOV: /* receiver side, RFC 4340 sec. 9.2.1 */ | ||
499 | if (val < 0 || val > 15) | ||
500 | err = -EINVAL; | ||
501 | else { | ||
502 | dp->dccps_pcrlen = val; | ||
503 | /* FIXME: add feature negotiation, | ||
504 | * ChangeL(MinimumChecksumCoverage, val) */ | ||
505 | } | ||
506 | break; | ||
494 | default: | 507 | default: |
495 | err = -ENOPROTOOPT; | 508 | err = -ENOPROTOOPT; |
496 | break; | 509 | break; |
497 | } | 510 | } |
498 | 511 | ||
499 | release_sock(sk); | 512 | release_sock(sk); |
500 | return err; | 513 | return err; |
501 | } | 514 | } |
@@ -569,12 +582,17 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname, | |||
569 | 582 | ||
570 | switch (optname) { | 583 | switch (optname) { |
571 | case DCCP_SOCKOPT_PACKET_SIZE: | 584 | case DCCP_SOCKOPT_PACKET_SIZE: |
572 | val = dp->dccps_packet_size; | 585 | DCCP_WARN("sockopt(PACKET_SIZE) is deprecated: fix your app\n"); |
573 | len = sizeof(dp->dccps_packet_size); | 586 | return 0; |
574 | break; | ||
575 | case DCCP_SOCKOPT_SERVICE: | 587 | case DCCP_SOCKOPT_SERVICE: |
576 | return dccp_getsockopt_service(sk, len, | 588 | return dccp_getsockopt_service(sk, len, |
577 | (__be32 __user *)optval, optlen); | 589 | (__be32 __user *)optval, optlen); |
590 | case DCCP_SOCKOPT_SEND_CSCOV: | ||
591 | val = dp->dccps_pcslen; | ||
592 | break; | ||
593 | case DCCP_SOCKOPT_RECV_CSCOV: | ||
594 | val = dp->dccps_pcrlen; | ||
595 | break; | ||
578 | case 128 ... 191: | 596 | case 128 ... 191: |
579 | return ccid_hc_rx_getsockopt(dp->dccps_hc_rx_ccid, sk, optname, | 597 | return ccid_hc_rx_getsockopt(dp->dccps_hc_rx_ccid, sk, optname, |
580 | len, (u32 __user *)optval, optlen); | 598 | len, (u32 __user *)optval, optlen); |
@@ -630,6 +648,13 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
630 | return -EMSGSIZE; | 648 | return -EMSGSIZE; |
631 | 649 | ||
632 | lock_sock(sk); | 650 | lock_sock(sk); |
651 | |||
652 | if (sysctl_dccp_tx_qlen && | ||
653 | (sk->sk_write_queue.qlen >= sysctl_dccp_tx_qlen)) { | ||
654 | rc = -EAGAIN; | ||
655 | goto out_release; | ||
656 | } | ||
657 | |||
633 | timeo = sock_sndtimeo(sk, noblock); | 658 | timeo = sock_sndtimeo(sk, noblock); |
634 | 659 | ||
635 | /* | 660 | /* |
@@ -788,7 +813,7 @@ int inet_dccp_listen(struct socket *sock, int backlog) | |||
788 | * FIXME: here it probably should be sk->sk_prot->listen_start | 813 | * FIXME: here it probably should be sk->sk_prot->listen_start |
789 | * see tcp_listen_start | 814 | * see tcp_listen_start |
790 | */ | 815 | */ |
791 | err = dccp_listen_start(sk); | 816 | err = dccp_listen_start(sk, backlog); |
792 | if (err) | 817 | if (err) |
793 | goto out; | 818 | goto out; |
794 | } | 819 | } |
@@ -1008,8 +1033,7 @@ static int __init dccp_init(void) | |||
1008 | } while (!dccp_hashinfo.ehash && --ehash_order > 0); | 1033 | } while (!dccp_hashinfo.ehash && --ehash_order > 0); |
1009 | 1034 | ||
1010 | if (!dccp_hashinfo.ehash) { | 1035 | if (!dccp_hashinfo.ehash) { |
1011 | printk(KERN_CRIT "Failed to allocate DCCP " | 1036 | DCCP_CRIT("Failed to allocate DCCP established hash table"); |
1012 | "established hash table\n"); | ||
1013 | goto out_free_bind_bucket_cachep; | 1037 | goto out_free_bind_bucket_cachep; |
1014 | } | 1038 | } |
1015 | 1039 | ||
@@ -1031,7 +1055,7 @@ static int __init dccp_init(void) | |||
1031 | } while (!dccp_hashinfo.bhash && --bhash_order >= 0); | 1055 | } while (!dccp_hashinfo.bhash && --bhash_order >= 0); |
1032 | 1056 | ||
1033 | if (!dccp_hashinfo.bhash) { | 1057 | if (!dccp_hashinfo.bhash) { |
1034 | printk(KERN_CRIT "Failed to allocate DCCP bind hash table\n"); | 1058 | DCCP_CRIT("Failed to allocate DCCP bind hash table"); |
1035 | goto out_free_dccp_ehash; | 1059 | goto out_free_dccp_ehash; |
1036 | } | 1060 | } |
1037 | 1061 | ||