diff options
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r-- | net/sctp/socket.c | 267 |
1 files changed, 245 insertions, 22 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index a1d026f12b0e..11938fb20395 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -941,7 +941,7 @@ SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk, | |||
941 | default: | 941 | default: |
942 | err = -EINVAL; | 942 | err = -EINVAL; |
943 | break; | 943 | break; |
944 | }; | 944 | } |
945 | 945 | ||
946 | out: | 946 | out: |
947 | kfree(kaddrs); | 947 | kfree(kaddrs); |
@@ -2039,6 +2039,10 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval, | |||
2039 | * SPP_HB_DEMAND - Request a user initiated heartbeat | 2039 | * SPP_HB_DEMAND - Request a user initiated heartbeat |
2040 | * to be made immediately. | 2040 | * to be made immediately. |
2041 | * | 2041 | * |
2042 | * SPP_HB_TIME_IS_ZERO - Specify's that the time for | ||
2043 | * heartbeat delayis to be set to the value of 0 | ||
2044 | * milliseconds. | ||
2045 | * | ||
2042 | * SPP_PMTUD_ENABLE - This field will enable PMTU | 2046 | * SPP_PMTUD_ENABLE - This field will enable PMTU |
2043 | * discovery upon the specified address. Note that | 2047 | * discovery upon the specified address. Note that |
2044 | * if the address feild is empty then all addresses | 2048 | * if the address feild is empty then all addresses |
@@ -2081,13 +2085,30 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, | |||
2081 | return error; | 2085 | return error; |
2082 | } | 2086 | } |
2083 | 2087 | ||
2084 | if (params->spp_hbinterval) { | 2088 | /* Note that unless the spp_flag is set to SPP_HB_ENABLE the value of |
2085 | if (trans) { | 2089 | * this field is ignored. Note also that a value of zero indicates |
2086 | trans->hbinterval = msecs_to_jiffies(params->spp_hbinterval); | 2090 | * the current setting should be left unchanged. |
2087 | } else if (asoc) { | 2091 | */ |
2088 | asoc->hbinterval = msecs_to_jiffies(params->spp_hbinterval); | 2092 | if (params->spp_flags & SPP_HB_ENABLE) { |
2089 | } else { | 2093 | |
2090 | sp->hbinterval = params->spp_hbinterval; | 2094 | /* Re-zero the interval if the SPP_HB_TIME_IS_ZERO is |
2095 | * set. This lets us use 0 value when this flag | ||
2096 | * is set. | ||
2097 | */ | ||
2098 | if (params->spp_flags & SPP_HB_TIME_IS_ZERO) | ||
2099 | params->spp_hbinterval = 0; | ||
2100 | |||
2101 | if (params->spp_hbinterval || | ||
2102 | (params->spp_flags & SPP_HB_TIME_IS_ZERO)) { | ||
2103 | if (trans) { | ||
2104 | trans->hbinterval = | ||
2105 | msecs_to_jiffies(params->spp_hbinterval); | ||
2106 | } else if (asoc) { | ||
2107 | asoc->hbinterval = | ||
2108 | msecs_to_jiffies(params->spp_hbinterval); | ||
2109 | } else { | ||
2110 | sp->hbinterval = params->spp_hbinterval; | ||
2111 | } | ||
2091 | } | 2112 | } |
2092 | } | 2113 | } |
2093 | 2114 | ||
@@ -2104,7 +2125,12 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, | |||
2104 | } | 2125 | } |
2105 | } | 2126 | } |
2106 | 2127 | ||
2107 | if (params->spp_pathmtu) { | 2128 | /* When Path MTU discovery is disabled the value specified here will |
2129 | * be the "fixed" path mtu (i.e. the value of the spp_flags field must | ||
2130 | * include the flag SPP_PMTUD_DISABLE for this field to have any | ||
2131 | * effect). | ||
2132 | */ | ||
2133 | if ((params->spp_flags & SPP_PMTUD_DISABLE) && params->spp_pathmtu) { | ||
2108 | if (trans) { | 2134 | if (trans) { |
2109 | trans->pathmtu = params->spp_pathmtu; | 2135 | trans->pathmtu = params->spp_pathmtu; |
2110 | sctp_assoc_sync_pmtu(asoc); | 2136 | sctp_assoc_sync_pmtu(asoc); |
@@ -2135,7 +2161,11 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, | |||
2135 | } | 2161 | } |
2136 | } | 2162 | } |
2137 | 2163 | ||
2138 | if (params->spp_sackdelay) { | 2164 | /* Note that unless the spp_flag is set to SPP_SACKDELAY_ENABLE the |
2165 | * value of this field is ignored. Note also that a value of zero | ||
2166 | * indicates the current setting should be left unchanged. | ||
2167 | */ | ||
2168 | if ((params->spp_flags & SPP_SACKDELAY_ENABLE) && params->spp_sackdelay) { | ||
2139 | if (trans) { | 2169 | if (trans) { |
2140 | trans->sackdelay = | 2170 | trans->sackdelay = |
2141 | msecs_to_jiffies(params->spp_sackdelay); | 2171 | msecs_to_jiffies(params->spp_sackdelay); |
@@ -2163,7 +2193,11 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, | |||
2163 | } | 2193 | } |
2164 | } | 2194 | } |
2165 | 2195 | ||
2166 | if (params->spp_pathmaxrxt) { | 2196 | /* Note that unless the spp_flag is set to SPP_PMTUD_ENABLE the value |
2197 | * of this field is ignored. Note also that a value of zero | ||
2198 | * indicates the current setting should be left unchanged. | ||
2199 | */ | ||
2200 | if ((params->spp_flags & SPP_PMTUD_ENABLE) && params->spp_pathmaxrxt) { | ||
2167 | if (trans) { | 2201 | if (trans) { |
2168 | trans->pathmaxrxt = params->spp_pathmaxrxt; | 2202 | trans->pathmaxrxt = params->spp_pathmaxrxt; |
2169 | } else if (asoc) { | 2203 | } else if (asoc) { |
@@ -2255,7 +2289,7 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk, | |||
2255 | return 0; | 2289 | return 0; |
2256 | } | 2290 | } |
2257 | 2291 | ||
2258 | /* 7.1.24. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME) | 2292 | /* 7.1.23. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME) |
2259 | * | 2293 | * |
2260 | * This options will get or set the delayed ack timer. The time is set | 2294 | * This options will get or set the delayed ack timer. The time is set |
2261 | * in milliseconds. If the assoc_id is 0, then this sets or gets the | 2295 | * in milliseconds. If the assoc_id is 0, then this sets or gets the |
@@ -2792,6 +2826,102 @@ static int sctp_setsockopt_context(struct sock *sk, char __user *optval, | |||
2792 | return 0; | 2826 | return 0; |
2793 | } | 2827 | } |
2794 | 2828 | ||
2829 | /* | ||
2830 | * 7.1.24. Get or set fragmented interleave (SCTP_FRAGMENT_INTERLEAVE) | ||
2831 | * | ||
2832 | * This options will at a minimum specify if the implementation is doing | ||
2833 | * fragmented interleave. Fragmented interleave, for a one to many | ||
2834 | * socket, is when subsequent calls to receive a message may return | ||
2835 | * parts of messages from different associations. Some implementations | ||
2836 | * may allow you to turn this value on or off. If so, when turned off, | ||
2837 | * no fragment interleave will occur (which will cause a head of line | ||
2838 | * blocking amongst multiple associations sharing the same one to many | ||
2839 | * socket). When this option is turned on, then each receive call may | ||
2840 | * come from a different association (thus the user must receive data | ||
2841 | * with the extended calls (e.g. sctp_recvmsg) to keep track of which | ||
2842 | * association each receive belongs to. | ||
2843 | * | ||
2844 | * This option takes a boolean value. A non-zero value indicates that | ||
2845 | * fragmented interleave is on. A value of zero indicates that | ||
2846 | * fragmented interleave is off. | ||
2847 | * | ||
2848 | * Note that it is important that an implementation that allows this | ||
2849 | * option to be turned on, have it off by default. Otherwise an unaware | ||
2850 | * application using the one to many model may become confused and act | ||
2851 | * incorrectly. | ||
2852 | */ | ||
2853 | static int sctp_setsockopt_fragment_interleave(struct sock *sk, | ||
2854 | char __user *optval, | ||
2855 | int optlen) | ||
2856 | { | ||
2857 | int val; | ||
2858 | |||
2859 | if (optlen != sizeof(int)) | ||
2860 | return -EINVAL; | ||
2861 | if (get_user(val, (int __user *)optval)) | ||
2862 | return -EFAULT; | ||
2863 | |||
2864 | sctp_sk(sk)->frag_interleave = (val == 0) ? 0 : 1; | ||
2865 | |||
2866 | return 0; | ||
2867 | } | ||
2868 | |||
2869 | /* | ||
2870 | * 7.1.25. Set or Get the sctp partial delivery point | ||
2871 | * (SCTP_PARTIAL_DELIVERY_POINT) | ||
2872 | * This option will set or get the SCTP partial delivery point. This | ||
2873 | * point is the size of a message where the partial delivery API will be | ||
2874 | * invoked to help free up rwnd space for the peer. Setting this to a | ||
2875 | * lower value will cause partial delivery's to happen more often. The | ||
2876 | * calls argument is an integer that sets or gets the partial delivery | ||
2877 | * point. | ||
2878 | */ | ||
2879 | static int sctp_setsockopt_partial_delivery_point(struct sock *sk, | ||
2880 | char __user *optval, | ||
2881 | int optlen) | ||
2882 | { | ||
2883 | u32 val; | ||
2884 | |||
2885 | if (optlen != sizeof(u32)) | ||
2886 | return -EINVAL; | ||
2887 | if (get_user(val, (int __user *)optval)) | ||
2888 | return -EFAULT; | ||
2889 | |||
2890 | sctp_sk(sk)->pd_point = val; | ||
2891 | |||
2892 | return 0; /* is this the right error code? */ | ||
2893 | } | ||
2894 | |||
2895 | /* | ||
2896 | * 7.1.28. Set or Get the maximum burst (SCTP_MAX_BURST) | ||
2897 | * | ||
2898 | * This option will allow a user to change the maximum burst of packets | ||
2899 | * that can be emitted by this association. Note that the default value | ||
2900 | * is 4, and some implementations may restrict this setting so that it | ||
2901 | * can only be lowered. | ||
2902 | * | ||
2903 | * NOTE: This text doesn't seem right. Do this on a socket basis with | ||
2904 | * future associations inheriting the socket value. | ||
2905 | */ | ||
2906 | static int sctp_setsockopt_maxburst(struct sock *sk, | ||
2907 | char __user *optval, | ||
2908 | int optlen) | ||
2909 | { | ||
2910 | int val; | ||
2911 | |||
2912 | if (optlen != sizeof(int)) | ||
2913 | return -EINVAL; | ||
2914 | if (get_user(val, (int __user *)optval)) | ||
2915 | return -EFAULT; | ||
2916 | |||
2917 | if (val < 0) | ||
2918 | return -EINVAL; | ||
2919 | |||
2920 | sctp_sk(sk)->max_burst = val; | ||
2921 | |||
2922 | return 0; | ||
2923 | } | ||
2924 | |||
2795 | /* API 6.2 setsockopt(), getsockopt() | 2925 | /* API 6.2 setsockopt(), getsockopt() |
2796 | * | 2926 | * |
2797 | * Applications use setsockopt() and getsockopt() to set or retrieve | 2927 | * Applications use setsockopt() and getsockopt() to set or retrieve |
@@ -2871,6 +3001,9 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname, | |||
2871 | case SCTP_DELAYED_ACK_TIME: | 3001 | case SCTP_DELAYED_ACK_TIME: |
2872 | retval = sctp_setsockopt_delayed_ack_time(sk, optval, optlen); | 3002 | retval = sctp_setsockopt_delayed_ack_time(sk, optval, optlen); |
2873 | break; | 3003 | break; |
3004 | case SCTP_PARTIAL_DELIVERY_POINT: | ||
3005 | retval = sctp_setsockopt_partial_delivery_point(sk, optval, optlen); | ||
3006 | break; | ||
2874 | 3007 | ||
2875 | case SCTP_INITMSG: | 3008 | case SCTP_INITMSG: |
2876 | retval = sctp_setsockopt_initmsg(sk, optval, optlen); | 3009 | retval = sctp_setsockopt_initmsg(sk, optval, optlen); |
@@ -2906,11 +3039,16 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname, | |||
2906 | case SCTP_CONTEXT: | 3039 | case SCTP_CONTEXT: |
2907 | retval = sctp_setsockopt_context(sk, optval, optlen); | 3040 | retval = sctp_setsockopt_context(sk, optval, optlen); |
2908 | break; | 3041 | break; |
2909 | 3042 | case SCTP_FRAGMENT_INTERLEAVE: | |
3043 | retval = sctp_setsockopt_fragment_interleave(sk, optval, optlen); | ||
3044 | break; | ||
3045 | case SCTP_MAX_BURST: | ||
3046 | retval = sctp_setsockopt_maxburst(sk, optval, optlen); | ||
3047 | break; | ||
2910 | default: | 3048 | default: |
2911 | retval = -ENOPROTOOPT; | 3049 | retval = -ENOPROTOOPT; |
2912 | break; | 3050 | break; |
2913 | }; | 3051 | } |
2914 | 3052 | ||
2915 | sctp_release_sock(sk); | 3053 | sctp_release_sock(sk); |
2916 | 3054 | ||
@@ -3066,6 +3204,7 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
3066 | sp->default_timetolive = 0; | 3204 | sp->default_timetolive = 0; |
3067 | 3205 | ||
3068 | sp->default_rcv_context = 0; | 3206 | sp->default_rcv_context = 0; |
3207 | sp->max_burst = sctp_max_burst; | ||
3069 | 3208 | ||
3070 | /* Initialize default setup parameters. These parameters | 3209 | /* Initialize default setup parameters. These parameters |
3071 | * can be modified with the SCTP_INITMSG socket option or | 3210 | * can be modified with the SCTP_INITMSG socket option or |
@@ -3134,8 +3273,9 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
3134 | sp->pf = sctp_get_pf_specific(sk->sk_family); | 3273 | sp->pf = sctp_get_pf_specific(sk->sk_family); |
3135 | 3274 | ||
3136 | /* Control variables for partial data delivery. */ | 3275 | /* Control variables for partial data delivery. */ |
3137 | sp->pd_mode = 0; | 3276 | atomic_set(&sp->pd_mode, 0); |
3138 | skb_queue_head_init(&sp->pd_lobby); | 3277 | skb_queue_head_init(&sp->pd_lobby); |
3278 | sp->frag_interleave = 0; | ||
3139 | 3279 | ||
3140 | /* Create a per socket endpoint structure. Even if we | 3280 | /* Create a per socket endpoint structure. Even if we |
3141 | * change the data structure relationships, this may still | 3281 | * change the data structure relationships, this may still |
@@ -3642,7 +3782,7 @@ static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len, | |||
3642 | return 0; | 3782 | return 0; |
3643 | } | 3783 | } |
3644 | 3784 | ||
3645 | /* 7.1.24. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME) | 3785 | /* 7.1.23. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME) |
3646 | * | 3786 | * |
3647 | * This options will get or set the delayed ack timer. The time is set | 3787 | * This options will get or set the delayed ack timer. The time is set |
3648 | * in milliseconds. If the assoc_id is 0, then this sets or gets the | 3788 | * in milliseconds. If the assoc_id is 0, then this sets or gets the |
@@ -4536,6 +4676,77 @@ static int sctp_getsockopt_maxseg(struct sock *sk, int len, | |||
4536 | return 0; | 4676 | return 0; |
4537 | } | 4677 | } |
4538 | 4678 | ||
4679 | /* | ||
4680 | * 7.1.24. Get or set fragmented interleave (SCTP_FRAGMENT_INTERLEAVE) | ||
4681 | * (chapter and verse is quoted at sctp_setsockopt_fragment_interleave()) | ||
4682 | */ | ||
4683 | static int sctp_getsockopt_fragment_interleave(struct sock *sk, int len, | ||
4684 | char __user *optval, int __user *optlen) | ||
4685 | { | ||
4686 | int val; | ||
4687 | |||
4688 | if (len < sizeof(int)) | ||
4689 | return -EINVAL; | ||
4690 | |||
4691 | len = sizeof(int); | ||
4692 | |||
4693 | val = sctp_sk(sk)->frag_interleave; | ||
4694 | if (put_user(len, optlen)) | ||
4695 | return -EFAULT; | ||
4696 | if (copy_to_user(optval, &val, len)) | ||
4697 | return -EFAULT; | ||
4698 | |||
4699 | return 0; | ||
4700 | } | ||
4701 | |||
4702 | /* | ||
4703 | * 7.1.25. Set or Get the sctp partial delivery point | ||
4704 | * (chapter and verse is quoted at sctp_setsockopt_partial_delivery_point()) | ||
4705 | */ | ||
4706 | static int sctp_getsockopt_partial_delivery_point(struct sock *sk, int len, | ||
4707 | char __user *optval, | ||
4708 | int __user *optlen) | ||
4709 | { | ||
4710 | u32 val; | ||
4711 | |||
4712 | if (len < sizeof(u32)) | ||
4713 | return -EINVAL; | ||
4714 | |||
4715 | len = sizeof(u32); | ||
4716 | |||
4717 | val = sctp_sk(sk)->pd_point; | ||
4718 | if (put_user(len, optlen)) | ||
4719 | return -EFAULT; | ||
4720 | if (copy_to_user(optval, &val, len)) | ||
4721 | return -EFAULT; | ||
4722 | |||
4723 | return -ENOTSUPP; | ||
4724 | } | ||
4725 | |||
4726 | /* | ||
4727 | * 7.1.28. Set or Get the maximum burst (SCTP_MAX_BURST) | ||
4728 | * (chapter and verse is quoted at sctp_setsockopt_maxburst()) | ||
4729 | */ | ||
4730 | static int sctp_getsockopt_maxburst(struct sock *sk, int len, | ||
4731 | char __user *optval, | ||
4732 | int __user *optlen) | ||
4733 | { | ||
4734 | int val; | ||
4735 | |||
4736 | if (len < sizeof(int)) | ||
4737 | return -EINVAL; | ||
4738 | |||
4739 | len = sizeof(int); | ||
4740 | |||
4741 | val = sctp_sk(sk)->max_burst; | ||
4742 | if (put_user(len, optlen)) | ||
4743 | return -EFAULT; | ||
4744 | if (copy_to_user(optval, &val, len)) | ||
4745 | return -EFAULT; | ||
4746 | |||
4747 | return -ENOTSUPP; | ||
4748 | } | ||
4749 | |||
4539 | SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, | 4750 | SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, |
4540 | char __user *optval, int __user *optlen) | 4751 | char __user *optval, int __user *optlen) |
4541 | { | 4752 | { |
@@ -4648,10 +4859,21 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, | |||
4648 | case SCTP_CONTEXT: | 4859 | case SCTP_CONTEXT: |
4649 | retval = sctp_getsockopt_context(sk, len, optval, optlen); | 4860 | retval = sctp_getsockopt_context(sk, len, optval, optlen); |
4650 | break; | 4861 | break; |
4862 | case SCTP_FRAGMENT_INTERLEAVE: | ||
4863 | retval = sctp_getsockopt_fragment_interleave(sk, len, optval, | ||
4864 | optlen); | ||
4865 | break; | ||
4866 | case SCTP_PARTIAL_DELIVERY_POINT: | ||
4867 | retval = sctp_getsockopt_partial_delivery_point(sk, len, optval, | ||
4868 | optlen); | ||
4869 | break; | ||
4870 | case SCTP_MAX_BURST: | ||
4871 | retval = sctp_getsockopt_maxburst(sk, len, optval, optlen); | ||
4872 | break; | ||
4651 | default: | 4873 | default: |
4652 | retval = -ENOPROTOOPT; | 4874 | retval = -ENOPROTOOPT; |
4653 | break; | 4875 | break; |
4654 | }; | 4876 | } |
4655 | 4877 | ||
4656 | sctp_release_sock(sk); | 4878 | sctp_release_sock(sk); |
4657 | return retval; | 4879 | return retval; |
@@ -4976,7 +5198,8 @@ int sctp_inet_listen(struct socket *sock, int backlog) | |||
4976 | break; | 5198 | break; |
4977 | default: | 5199 | default: |
4978 | break; | 5200 | break; |
4979 | }; | 5201 | } |
5202 | |||
4980 | if (err) | 5203 | if (err) |
4981 | goto cleanup; | 5204 | goto cleanup; |
4982 | 5205 | ||
@@ -5239,7 +5462,7 @@ SCTP_STATIC int sctp_msghdr_parse(const struct msghdr *msg, | |||
5239 | 5462 | ||
5240 | default: | 5463 | default: |
5241 | return -EINVAL; | 5464 | return -EINVAL; |
5242 | }; | 5465 | } |
5243 | } | 5466 | } |
5244 | return 0; | 5467 | return 0; |
5245 | } | 5468 | } |
@@ -5742,9 +5965,9 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
5742 | * 3) Peeling off non-partial delivery; move pd_lobby to receive_queue. | 5965 | * 3) Peeling off non-partial delivery; move pd_lobby to receive_queue. |
5743 | */ | 5966 | */ |
5744 | skb_queue_head_init(&newsp->pd_lobby); | 5967 | skb_queue_head_init(&newsp->pd_lobby); |
5745 | sctp_sk(newsk)->pd_mode = assoc->ulpq.pd_mode; | 5968 | atomic_set(&sctp_sk(newsk)->pd_mode, assoc->ulpq.pd_mode); |
5746 | 5969 | ||
5747 | if (sctp_sk(oldsk)->pd_mode) { | 5970 | if (atomic_read(&sctp_sk(oldsk)->pd_mode)) { |
5748 | struct sk_buff_head *queue; | 5971 | struct sk_buff_head *queue; |
5749 | 5972 | ||
5750 | /* Decide which queue to move pd_lobby skbs to. */ | 5973 | /* Decide which queue to move pd_lobby skbs to. */ |
@@ -5770,7 +5993,7 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
5770 | * delivery to finish. | 5993 | * delivery to finish. |
5771 | */ | 5994 | */ |
5772 | if (assoc->ulpq.pd_mode) | 5995 | if (assoc->ulpq.pd_mode) |
5773 | sctp_clear_pd(oldsk); | 5996 | sctp_clear_pd(oldsk, NULL); |
5774 | 5997 | ||
5775 | } | 5998 | } |
5776 | 5999 | ||