diff options
author | Vlad Yasevich <vladislav.yasevich@hp.com> | 2007-03-23 14:32:00 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-04-26 01:28:00 -0400 |
commit | d49d91d79a8dc5e85108a5ae1c8eef23dec135c1 (patch) | |
tree | e98b53a69b310128a03a06fcc1dd9f94f7aa34b2 /net/sctp/socket.c | |
parent | b6e1331f3ce25a56edb956054eaf8011654686cb (diff) |
[SCTP]: Implement SCTP_PARTIAL_DELIVERY_POINT option.
This option induces partial delivery to run as soon
as the specified amount of data has been accumulated on
the association. However, we give preference to fully
reassembled messages over PD messages. In any case,
window and buffer is freed up.
Signed-off-by: Vlad Yasevich <vladislav.yasevich@.hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r-- | net/sctp/socket.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index b4be473c68b0..1e787a2d0b5f 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -2832,6 +2832,32 @@ static int sctp_setsockopt_fragment_interleave(struct sock *sk, | |||
2832 | return 0; | 2832 | return 0; |
2833 | } | 2833 | } |
2834 | 2834 | ||
2835 | /* | ||
2836 | * 7.1.25. Set or Get the sctp partial delivery point | ||
2837 | * (SCTP_PARTIAL_DELIVERY_POINT) | ||
2838 | * This option will set or get the SCTP partial delivery point. This | ||
2839 | * point is the size of a message where the partial delivery API will be | ||
2840 | * invoked to help free up rwnd space for the peer. Setting this to a | ||
2841 | * lower value will cause partial delivery's to happen more often. The | ||
2842 | * calls argument is an integer that sets or gets the partial delivery | ||
2843 | * point. | ||
2844 | */ | ||
2845 | static int sctp_setsockopt_partial_delivery_point(struct sock *sk, | ||
2846 | char __user *optval, | ||
2847 | int optlen) | ||
2848 | { | ||
2849 | u32 val; | ||
2850 | |||
2851 | if (optlen != sizeof(u32)) | ||
2852 | return -EINVAL; | ||
2853 | if (get_user(val, (int __user *)optval)) | ||
2854 | return -EFAULT; | ||
2855 | |||
2856 | sctp_sk(sk)->pd_point = val; | ||
2857 | |||
2858 | return 0; /* is this the right error code? */ | ||
2859 | } | ||
2860 | |||
2835 | /* API 6.2 setsockopt(), getsockopt() | 2861 | /* API 6.2 setsockopt(), getsockopt() |
2836 | * | 2862 | * |
2837 | * Applications use setsockopt() and getsockopt() to set or retrieve | 2863 | * Applications use setsockopt() and getsockopt() to set or retrieve |
@@ -2911,6 +2937,9 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname, | |||
2911 | case SCTP_DELAYED_ACK_TIME: | 2937 | case SCTP_DELAYED_ACK_TIME: |
2912 | retval = sctp_setsockopt_delayed_ack_time(sk, optval, optlen); | 2938 | retval = sctp_setsockopt_delayed_ack_time(sk, optval, optlen); |
2913 | break; | 2939 | break; |
2940 | case SCTP_PARTIAL_DELIVERY_POINT: | ||
2941 | retval = sctp_setsockopt_partial_delivery_point(sk, optval, optlen); | ||
2942 | break; | ||
2914 | 2943 | ||
2915 | case SCTP_INITMSG: | 2944 | case SCTP_INITMSG: |
2916 | retval = sctp_setsockopt_initmsg(sk, optval, optlen); | 2945 | retval = sctp_setsockopt_initmsg(sk, optval, optlen); |
@@ -4602,6 +4631,30 @@ static int sctp_getsockopt_fragment_interleave(struct sock *sk, int len, | |||
4602 | return 0; | 4631 | return 0; |
4603 | } | 4632 | } |
4604 | 4633 | ||
4634 | /* | ||
4635 | * 7.1.25. Set or Get the sctp partial delivery point | ||
4636 | * (chapter and verse is quoted at sctp_setsockopt_partial_delivery_point()) | ||
4637 | */ | ||
4638 | static int sctp_getsockopt_partial_delivery_point(struct sock *sk, int len, | ||
4639 | char __user *optval, | ||
4640 | int __user *optlen) | ||
4641 | { | ||
4642 | u32 val; | ||
4643 | |||
4644 | if (len < sizeof(u32)) | ||
4645 | return -EINVAL; | ||
4646 | |||
4647 | len = sizeof(u32); | ||
4648 | |||
4649 | val = sctp_sk(sk)->pd_point; | ||
4650 | if (put_user(len, optlen)) | ||
4651 | return -EFAULT; | ||
4652 | if (copy_to_user(optval, &val, len)) | ||
4653 | return -EFAULT; | ||
4654 | |||
4655 | return -ENOTSUPP; | ||
4656 | } | ||
4657 | |||
4605 | SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, | 4658 | SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, |
4606 | char __user *optval, int __user *optlen) | 4659 | char __user *optval, int __user *optlen) |
4607 | { | 4660 | { |
@@ -4718,6 +4771,10 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, | |||
4718 | retval = sctp_getsockopt_fragment_interleave(sk, len, optval, | 4771 | retval = sctp_getsockopt_fragment_interleave(sk, len, optval, |
4719 | optlen); | 4772 | optlen); |
4720 | break; | 4773 | break; |
4774 | case SCTP_PARTIAL_DELIVERY_POINT: | ||
4775 | retval = sctp_getsockopt_partial_delivery_point(sk, len, optval, | ||
4776 | optlen); | ||
4777 | break; | ||
4721 | default: | 4778 | default: |
4722 | retval = -ENOPROTOOPT; | 4779 | retval = -ENOPROTOOPT; |
4723 | break; | 4780 | break; |