diff options
author | Dmitry Torokhov <dtor@insightbb.com> | 2007-05-01 00:24:54 -0400 |
---|---|---|
committer | Dmitry Torokhov <dtor@insightbb.com> | 2007-05-01 00:24:54 -0400 |
commit | bc95f3669f5e6f63cf0b84fe4922c3c6dd4aa775 (patch) | |
tree | 427fcf2a7287c16d4b5aa6cbf494d59579a6a8b1 /net/sctp/socket.c | |
parent | 3d29cdff999c37b3876082278a8134a0642a02cd (diff) | |
parent | dc87c3985e9b442c60994308a96f887579addc39 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
drivers/usb/input/Makefile
drivers/usb/input/gtco.c
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r-- | net/sctp/socket.c | 417 |
1 files changed, 355 insertions, 62 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 536298c2eda2..2fc0a92caa78 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -627,6 +627,12 @@ int sctp_bindx_rem(struct sock *sk, struct sockaddr *addrs, int addrcnt) | |||
627 | retval = -EINVAL; | 627 | retval = -EINVAL; |
628 | goto err_bindx_rem; | 628 | goto err_bindx_rem; |
629 | } | 629 | } |
630 | |||
631 | if (!af->addr_valid(sa_addr, sp, NULL)) { | ||
632 | retval = -EADDRNOTAVAIL; | ||
633 | goto err_bindx_rem; | ||
634 | } | ||
635 | |||
630 | if (sa_addr->v4.sin_port != htons(bp->port)) { | 636 | if (sa_addr->v4.sin_port != htons(bp->port)) { |
631 | retval = -EINVAL; | 637 | retval = -EINVAL; |
632 | goto err_bindx_rem; | 638 | goto err_bindx_rem; |
@@ -935,7 +941,7 @@ SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk, | |||
935 | default: | 941 | default: |
936 | err = -EINVAL; | 942 | err = -EINVAL; |
937 | break; | 943 | break; |
938 | }; | 944 | } |
939 | 945 | ||
940 | out: | 946 | out: |
941 | kfree(kaddrs); | 947 | kfree(kaddrs); |
@@ -2033,6 +2039,10 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval, | |||
2033 | * SPP_HB_DEMAND - Request a user initiated heartbeat | 2039 | * SPP_HB_DEMAND - Request a user initiated heartbeat |
2034 | * to be made immediately. | 2040 | * to be made immediately. |
2035 | * | 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 | * | ||
2036 | * SPP_PMTUD_ENABLE - This field will enable PMTU | 2046 | * SPP_PMTUD_ENABLE - This field will enable PMTU |
2037 | * discovery upon the specified address. Note that | 2047 | * discovery upon the specified address. Note that |
2038 | * if the address feild is empty then all addresses | 2048 | * if the address feild is empty then all addresses |
@@ -2075,13 +2085,30 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, | |||
2075 | return error; | 2085 | return error; |
2076 | } | 2086 | } |
2077 | 2087 | ||
2078 | if (params->spp_hbinterval) { | 2088 | /* Note that unless the spp_flag is set to SPP_HB_ENABLE the value of |
2079 | if (trans) { | 2089 | * this field is ignored. Note also that a value of zero indicates |
2080 | trans->hbinterval = msecs_to_jiffies(params->spp_hbinterval); | 2090 | * the current setting should be left unchanged. |
2081 | } else if (asoc) { | 2091 | */ |
2082 | asoc->hbinterval = msecs_to_jiffies(params->spp_hbinterval); | 2092 | if (params->spp_flags & SPP_HB_ENABLE) { |
2083 | } else { | 2093 | |
2084 | 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 | } | ||
2085 | } | 2112 | } |
2086 | } | 2113 | } |
2087 | 2114 | ||
@@ -2098,7 +2125,12 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, | |||
2098 | } | 2125 | } |
2099 | } | 2126 | } |
2100 | 2127 | ||
2101 | 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) { | ||
2102 | if (trans) { | 2134 | if (trans) { |
2103 | trans->pathmtu = params->spp_pathmtu; | 2135 | trans->pathmtu = params->spp_pathmtu; |
2104 | sctp_assoc_sync_pmtu(asoc); | 2136 | sctp_assoc_sync_pmtu(asoc); |
@@ -2129,7 +2161,11 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, | |||
2129 | } | 2161 | } |
2130 | } | 2162 | } |
2131 | 2163 | ||
2132 | 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) { | ||
2133 | if (trans) { | 2169 | if (trans) { |
2134 | trans->sackdelay = | 2170 | trans->sackdelay = |
2135 | msecs_to_jiffies(params->spp_sackdelay); | 2171 | msecs_to_jiffies(params->spp_sackdelay); |
@@ -2157,7 +2193,11 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, | |||
2157 | } | 2193 | } |
2158 | } | 2194 | } |
2159 | 2195 | ||
2160 | 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) { | ||
2161 | if (trans) { | 2201 | if (trans) { |
2162 | trans->pathmaxrxt = params->spp_pathmaxrxt; | 2202 | trans->pathmaxrxt = params->spp_pathmaxrxt; |
2163 | } else if (asoc) { | 2203 | } else if (asoc) { |
@@ -2249,7 +2289,7 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk, | |||
2249 | return 0; | 2289 | return 0; |
2250 | } | 2290 | } |
2251 | 2291 | ||
2252 | /* 7.1.24. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME) | 2292 | /* 7.1.23. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME) |
2253 | * | 2293 | * |
2254 | * 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 |
2255 | * 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 |
@@ -2786,6 +2826,102 @@ static int sctp_setsockopt_context(struct sock *sk, char __user *optval, | |||
2786 | return 0; | 2826 | return 0; |
2787 | } | 2827 | } |
2788 | 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 | |||
2789 | /* API 6.2 setsockopt(), getsockopt() | 2925 | /* API 6.2 setsockopt(), getsockopt() |
2790 | * | 2926 | * |
2791 | * Applications use setsockopt() and getsockopt() to set or retrieve | 2927 | * Applications use setsockopt() and getsockopt() to set or retrieve |
@@ -2865,6 +3001,9 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname, | |||
2865 | case SCTP_DELAYED_ACK_TIME: | 3001 | case SCTP_DELAYED_ACK_TIME: |
2866 | retval = sctp_setsockopt_delayed_ack_time(sk, optval, optlen); | 3002 | retval = sctp_setsockopt_delayed_ack_time(sk, optval, optlen); |
2867 | break; | 3003 | break; |
3004 | case SCTP_PARTIAL_DELIVERY_POINT: | ||
3005 | retval = sctp_setsockopt_partial_delivery_point(sk, optval, optlen); | ||
3006 | break; | ||
2868 | 3007 | ||
2869 | case SCTP_INITMSG: | 3008 | case SCTP_INITMSG: |
2870 | retval = sctp_setsockopt_initmsg(sk, optval, optlen); | 3009 | retval = sctp_setsockopt_initmsg(sk, optval, optlen); |
@@ -2900,11 +3039,16 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname, | |||
2900 | case SCTP_CONTEXT: | 3039 | case SCTP_CONTEXT: |
2901 | retval = sctp_setsockopt_context(sk, optval, optlen); | 3040 | retval = sctp_setsockopt_context(sk, optval, optlen); |
2902 | break; | 3041 | break; |
2903 | 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; | ||
2904 | default: | 3048 | default: |
2905 | retval = -ENOPROTOOPT; | 3049 | retval = -ENOPROTOOPT; |
2906 | break; | 3050 | break; |
2907 | }; | 3051 | } |
2908 | 3052 | ||
2909 | sctp_release_sock(sk); | 3053 | sctp_release_sock(sk); |
2910 | 3054 | ||
@@ -3060,6 +3204,7 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
3060 | sp->default_timetolive = 0; | 3204 | sp->default_timetolive = 0; |
3061 | 3205 | ||
3062 | sp->default_rcv_context = 0; | 3206 | sp->default_rcv_context = 0; |
3207 | sp->max_burst = sctp_max_burst; | ||
3063 | 3208 | ||
3064 | /* Initialize default setup parameters. These parameters | 3209 | /* Initialize default setup parameters. These parameters |
3065 | * can be modified with the SCTP_INITMSG socket option or | 3210 | * can be modified with the SCTP_INITMSG socket option or |
@@ -3128,8 +3273,9 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) | |||
3128 | sp->pf = sctp_get_pf_specific(sk->sk_family); | 3273 | sp->pf = sctp_get_pf_specific(sk->sk_family); |
3129 | 3274 | ||
3130 | /* Control variables for partial data delivery. */ | 3275 | /* Control variables for partial data delivery. */ |
3131 | sp->pd_mode = 0; | 3276 | atomic_set(&sp->pd_mode, 0); |
3132 | skb_queue_head_init(&sp->pd_lobby); | 3277 | skb_queue_head_init(&sp->pd_lobby); |
3278 | sp->frag_interleave = 0; | ||
3133 | 3279 | ||
3134 | /* Create a per socket endpoint structure. Even if we | 3280 | /* Create a per socket endpoint structure. Even if we |
3135 | * change the data structure relationships, this may still | 3281 | * change the data structure relationships, this may still |
@@ -3636,7 +3782,7 @@ static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len, | |||
3636 | return 0; | 3782 | return 0; |
3637 | } | 3783 | } |
3638 | 3784 | ||
3639 | /* 7.1.24. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME) | 3785 | /* 7.1.23. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME) |
3640 | * | 3786 | * |
3641 | * 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 |
3642 | * 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 |
@@ -3841,7 +3987,7 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len, | |||
3841 | memcpy(&temp, &from->ipaddr, sizeof(temp)); | 3987 | memcpy(&temp, &from->ipaddr, sizeof(temp)); |
3842 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); | 3988 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); |
3843 | addrlen = sctp_get_af_specific(sk->sk_family)->sockaddr_len; | 3989 | addrlen = sctp_get_af_specific(sk->sk_family)->sockaddr_len; |
3844 | if(space_left < addrlen) | 3990 | if (space_left < addrlen) |
3845 | return -ENOMEM; | 3991 | return -ENOMEM; |
3846 | if (copy_to_user(to, &temp, addrlen)) | 3992 | if (copy_to_user(to, &temp, addrlen)) |
3847 | return -EFAULT; | 3993 | return -EFAULT; |
@@ -3930,8 +4076,9 @@ done: | |||
3930 | /* Helper function that copies local addresses to user and returns the number | 4076 | /* Helper function that copies local addresses to user and returns the number |
3931 | * of addresses copied. | 4077 | * of addresses copied. |
3932 | */ | 4078 | */ |
3933 | static int sctp_copy_laddrs_to_user_old(struct sock *sk, __u16 port, int max_addrs, | 4079 | static int sctp_copy_laddrs_old(struct sock *sk, __u16 port, |
3934 | void __user *to) | 4080 | int max_addrs, void *to, |
4081 | int *bytes_copied) | ||
3935 | { | 4082 | { |
3936 | struct list_head *pos, *next; | 4083 | struct list_head *pos, *next; |
3937 | struct sctp_sockaddr_entry *addr; | 4084 | struct sctp_sockaddr_entry *addr; |
@@ -3948,10 +4095,10 @@ static int sctp_copy_laddrs_to_user_old(struct sock *sk, __u16 port, int max_add | |||
3948 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk), | 4095 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk), |
3949 | &temp); | 4096 | &temp); |
3950 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; | 4097 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; |
3951 | if (copy_to_user(to, &temp, addrlen)) | 4098 | memcpy(to, &temp, addrlen); |
3952 | return -EFAULT; | ||
3953 | 4099 | ||
3954 | to += addrlen; | 4100 | to += addrlen; |
4101 | *bytes_copied += addrlen; | ||
3955 | cnt ++; | 4102 | cnt ++; |
3956 | if (cnt >= max_addrs) break; | 4103 | if (cnt >= max_addrs) break; |
3957 | } | 4104 | } |
@@ -3959,8 +4106,8 @@ static int sctp_copy_laddrs_to_user_old(struct sock *sk, __u16 port, int max_add | |||
3959 | return cnt; | 4106 | return cnt; |
3960 | } | 4107 | } |
3961 | 4108 | ||
3962 | static int sctp_copy_laddrs_to_user(struct sock *sk, __u16 port, | 4109 | static int sctp_copy_laddrs(struct sock *sk, __u16 port, void *to, |
3963 | void __user **to, size_t space_left) | 4110 | size_t space_left, int *bytes_copied) |
3964 | { | 4111 | { |
3965 | struct list_head *pos, *next; | 4112 | struct list_head *pos, *next; |
3966 | struct sctp_sockaddr_entry *addr; | 4113 | struct sctp_sockaddr_entry *addr; |
@@ -3977,14 +4124,14 @@ static int sctp_copy_laddrs_to_user(struct sock *sk, __u16 port, | |||
3977 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk), | 4124 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk), |
3978 | &temp); | 4125 | &temp); |
3979 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; | 4126 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; |
3980 | if(space_left<addrlen) | 4127 | if (space_left < addrlen) |
3981 | return -ENOMEM; | 4128 | return -ENOMEM; |
3982 | if (copy_to_user(*to, &temp, addrlen)) | 4129 | memcpy(to, &temp, addrlen); |
3983 | return -EFAULT; | ||
3984 | 4130 | ||
3985 | *to += addrlen; | 4131 | to += addrlen; |
3986 | cnt ++; | 4132 | cnt ++; |
3987 | space_left -= addrlen; | 4133 | space_left -= addrlen; |
4134 | bytes_copied += addrlen; | ||
3988 | } | 4135 | } |
3989 | 4136 | ||
3990 | return cnt; | 4137 | return cnt; |
@@ -4008,6 +4155,8 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len, | |||
4008 | int addrlen; | 4155 | int addrlen; |
4009 | rwlock_t *addr_lock; | 4156 | rwlock_t *addr_lock; |
4010 | int err = 0; | 4157 | int err = 0; |
4158 | void *addrs; | ||
4159 | int bytes_copied = 0; | ||
4011 | 4160 | ||
4012 | if (len != sizeof(struct sctp_getaddrs_old)) | 4161 | if (len != sizeof(struct sctp_getaddrs_old)) |
4013 | return -EINVAL; | 4162 | return -EINVAL; |
@@ -4035,6 +4184,15 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len, | |||
4035 | 4184 | ||
4036 | to = getaddrs.addrs; | 4185 | to = getaddrs.addrs; |
4037 | 4186 | ||
4187 | /* Allocate space for a local instance of packed array to hold all | ||
4188 | * the data. We store addresses here first and then put write them | ||
4189 | * to the user in one shot. | ||
4190 | */ | ||
4191 | addrs = kmalloc(sizeof(union sctp_addr) * getaddrs.addr_num, | ||
4192 | GFP_KERNEL); | ||
4193 | if (!addrs) | ||
4194 | return -ENOMEM; | ||
4195 | |||
4038 | sctp_read_lock(addr_lock); | 4196 | sctp_read_lock(addr_lock); |
4039 | 4197 | ||
4040 | /* If the endpoint is bound to 0.0.0.0 or ::0, get the valid | 4198 | /* If the endpoint is bound to 0.0.0.0 or ::0, get the valid |
@@ -4044,13 +4202,9 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len, | |||
4044 | addr = list_entry(bp->address_list.next, | 4202 | addr = list_entry(bp->address_list.next, |
4045 | struct sctp_sockaddr_entry, list); | 4203 | struct sctp_sockaddr_entry, list); |
4046 | if (sctp_is_any(&addr->a)) { | 4204 | if (sctp_is_any(&addr->a)) { |
4047 | cnt = sctp_copy_laddrs_to_user_old(sk, bp->port, | 4205 | cnt = sctp_copy_laddrs_old(sk, bp->port, |
4048 | getaddrs.addr_num, | 4206 | getaddrs.addr_num, |
4049 | to); | 4207 | addrs, &bytes_copied); |
4050 | if (cnt < 0) { | ||
4051 | err = cnt; | ||
4052 | goto unlock; | ||
4053 | } | ||
4054 | goto copy_getaddrs; | 4208 | goto copy_getaddrs; |
4055 | } | 4209 | } |
4056 | } | 4210 | } |
@@ -4060,22 +4214,29 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len, | |||
4060 | memcpy(&temp, &addr->a, sizeof(temp)); | 4214 | memcpy(&temp, &addr->a, sizeof(temp)); |
4061 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); | 4215 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); |
4062 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; | 4216 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; |
4063 | if (copy_to_user(to, &temp, addrlen)) { | 4217 | memcpy(addrs, &temp, addrlen); |
4064 | err = -EFAULT; | ||
4065 | goto unlock; | ||
4066 | } | ||
4067 | to += addrlen; | 4218 | to += addrlen; |
4219 | bytes_copied += addrlen; | ||
4068 | cnt ++; | 4220 | cnt ++; |
4069 | if (cnt >= getaddrs.addr_num) break; | 4221 | if (cnt >= getaddrs.addr_num) break; |
4070 | } | 4222 | } |
4071 | 4223 | ||
4072 | copy_getaddrs: | 4224 | copy_getaddrs: |
4225 | sctp_read_unlock(addr_lock); | ||
4226 | |||
4227 | /* copy the entire address list into the user provided space */ | ||
4228 | if (copy_to_user(to, addrs, bytes_copied)) { | ||
4229 | err = -EFAULT; | ||
4230 | goto error; | ||
4231 | } | ||
4232 | |||
4233 | /* copy the leading structure back to user */ | ||
4073 | getaddrs.addr_num = cnt; | 4234 | getaddrs.addr_num = cnt; |
4074 | if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs_old))) | 4235 | if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs_old))) |
4075 | err = -EFAULT; | 4236 | err = -EFAULT; |
4076 | 4237 | ||
4077 | unlock: | 4238 | error: |
4078 | sctp_read_unlock(addr_lock); | 4239 | kfree(addrs); |
4079 | return err; | 4240 | return err; |
4080 | } | 4241 | } |
4081 | 4242 | ||
@@ -4095,7 +4256,8 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, | |||
4095 | rwlock_t *addr_lock; | 4256 | rwlock_t *addr_lock; |
4096 | int err = 0; | 4257 | int err = 0; |
4097 | size_t space_left; | 4258 | size_t space_left; |
4098 | int bytes_copied; | 4259 | int bytes_copied = 0; |
4260 | void *addrs; | ||
4099 | 4261 | ||
4100 | if (len <= sizeof(struct sctp_getaddrs)) | 4262 | if (len <= sizeof(struct sctp_getaddrs)) |
4101 | return -EINVAL; | 4263 | return -EINVAL; |
@@ -4123,6 +4285,9 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, | |||
4123 | to = optval + offsetof(struct sctp_getaddrs,addrs); | 4285 | to = optval + offsetof(struct sctp_getaddrs,addrs); |
4124 | space_left = len - sizeof(struct sctp_getaddrs) - | 4286 | space_left = len - sizeof(struct sctp_getaddrs) - |
4125 | offsetof(struct sctp_getaddrs,addrs); | 4287 | offsetof(struct sctp_getaddrs,addrs); |
4288 | addrs = kmalloc(space_left, GFP_KERNEL); | ||
4289 | if (!addrs) | ||
4290 | return -ENOMEM; | ||
4126 | 4291 | ||
4127 | sctp_read_lock(addr_lock); | 4292 | sctp_read_lock(addr_lock); |
4128 | 4293 | ||
@@ -4133,11 +4298,11 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, | |||
4133 | addr = list_entry(bp->address_list.next, | 4298 | addr = list_entry(bp->address_list.next, |
4134 | struct sctp_sockaddr_entry, list); | 4299 | struct sctp_sockaddr_entry, list); |
4135 | if (sctp_is_any(&addr->a)) { | 4300 | if (sctp_is_any(&addr->a)) { |
4136 | cnt = sctp_copy_laddrs_to_user(sk, bp->port, | 4301 | cnt = sctp_copy_laddrs(sk, bp->port, addrs, |
4137 | &to, space_left); | 4302 | space_left, &bytes_copied); |
4138 | if (cnt < 0) { | 4303 | if (cnt < 0) { |
4139 | err = cnt; | 4304 | err = cnt; |
4140 | goto unlock; | 4305 | goto error; |
4141 | } | 4306 | } |
4142 | goto copy_getaddrs; | 4307 | goto copy_getaddrs; |
4143 | } | 4308 | } |
@@ -4148,26 +4313,31 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, | |||
4148 | memcpy(&temp, &addr->a, sizeof(temp)); | 4313 | memcpy(&temp, &addr->a, sizeof(temp)); |
4149 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); | 4314 | sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); |
4150 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; | 4315 | addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; |
4151 | if(space_left < addrlen) | 4316 | if (space_left < addrlen) { |
4152 | return -ENOMEM; /*fixme: right error?*/ | 4317 | err = -ENOMEM; /*fixme: right error?*/ |
4153 | if (copy_to_user(to, &temp, addrlen)) { | 4318 | goto error; |
4154 | err = -EFAULT; | ||
4155 | goto unlock; | ||
4156 | } | 4319 | } |
4320 | memcpy(addrs, &temp, addrlen); | ||
4157 | to += addrlen; | 4321 | to += addrlen; |
4322 | bytes_copied += addrlen; | ||
4158 | cnt ++; | 4323 | cnt ++; |
4159 | space_left -= addrlen; | 4324 | space_left -= addrlen; |
4160 | } | 4325 | } |
4161 | 4326 | ||
4162 | copy_getaddrs: | 4327 | copy_getaddrs: |
4328 | sctp_read_unlock(addr_lock); | ||
4329 | |||
4330 | if (copy_to_user(to, addrs, bytes_copied)) { | ||
4331 | err = -EFAULT; | ||
4332 | goto error; | ||
4333 | } | ||
4163 | if (put_user(cnt, &((struct sctp_getaddrs __user *)optval)->addr_num)) | 4334 | if (put_user(cnt, &((struct sctp_getaddrs __user *)optval)->addr_num)) |
4164 | return -EFAULT; | 4335 | return -EFAULT; |
4165 | bytes_copied = ((char __user *)to) - optval; | ||
4166 | if (put_user(bytes_copied, optlen)) | 4336 | if (put_user(bytes_copied, optlen)) |
4167 | return -EFAULT; | 4337 | return -EFAULT; |
4168 | 4338 | ||
4169 | unlock: | 4339 | error: |
4170 | sctp_read_unlock(addr_lock); | 4340 | kfree(addrs); |
4171 | return err; | 4341 | return err; |
4172 | } | 4342 | } |
4173 | 4343 | ||
@@ -4530,6 +4700,77 @@ static int sctp_getsockopt_maxseg(struct sock *sk, int len, | |||
4530 | return 0; | 4700 | return 0; |
4531 | } | 4701 | } |
4532 | 4702 | ||
4703 | /* | ||
4704 | * 7.1.24. Get or set fragmented interleave (SCTP_FRAGMENT_INTERLEAVE) | ||
4705 | * (chapter and verse is quoted at sctp_setsockopt_fragment_interleave()) | ||
4706 | */ | ||
4707 | static int sctp_getsockopt_fragment_interleave(struct sock *sk, int len, | ||
4708 | char __user *optval, int __user *optlen) | ||
4709 | { | ||
4710 | int val; | ||
4711 | |||
4712 | if (len < sizeof(int)) | ||
4713 | return -EINVAL; | ||
4714 | |||
4715 | len = sizeof(int); | ||
4716 | |||
4717 | val = sctp_sk(sk)->frag_interleave; | ||
4718 | if (put_user(len, optlen)) | ||
4719 | return -EFAULT; | ||
4720 | if (copy_to_user(optval, &val, len)) | ||
4721 | return -EFAULT; | ||
4722 | |||
4723 | return 0; | ||
4724 | } | ||
4725 | |||
4726 | /* | ||
4727 | * 7.1.25. Set or Get the sctp partial delivery point | ||
4728 | * (chapter and verse is quoted at sctp_setsockopt_partial_delivery_point()) | ||
4729 | */ | ||
4730 | static int sctp_getsockopt_partial_delivery_point(struct sock *sk, int len, | ||
4731 | char __user *optval, | ||
4732 | int __user *optlen) | ||
4733 | { | ||
4734 | u32 val; | ||
4735 | |||
4736 | if (len < sizeof(u32)) | ||
4737 | return -EINVAL; | ||
4738 | |||
4739 | len = sizeof(u32); | ||
4740 | |||
4741 | val = sctp_sk(sk)->pd_point; | ||
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 | |||
4750 | /* | ||
4751 | * 7.1.28. Set or Get the maximum burst (SCTP_MAX_BURST) | ||
4752 | * (chapter and verse is quoted at sctp_setsockopt_maxburst()) | ||
4753 | */ | ||
4754 | static int sctp_getsockopt_maxburst(struct sock *sk, int len, | ||
4755 | char __user *optval, | ||
4756 | int __user *optlen) | ||
4757 | { | ||
4758 | int val; | ||
4759 | |||
4760 | if (len < sizeof(int)) | ||
4761 | return -EINVAL; | ||
4762 | |||
4763 | len = sizeof(int); | ||
4764 | |||
4765 | val = sctp_sk(sk)->max_burst; | ||
4766 | if (put_user(len, optlen)) | ||
4767 | return -EFAULT; | ||
4768 | if (copy_to_user(optval, &val, len)) | ||
4769 | return -EFAULT; | ||
4770 | |||
4771 | return -ENOTSUPP; | ||
4772 | } | ||
4773 | |||
4533 | SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, | 4774 | SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, |
4534 | char __user *optval, int __user *optlen) | 4775 | char __user *optval, int __user *optlen) |
4535 | { | 4776 | { |
@@ -4642,10 +4883,21 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, | |||
4642 | case SCTP_CONTEXT: | 4883 | case SCTP_CONTEXT: |
4643 | retval = sctp_getsockopt_context(sk, len, optval, optlen); | 4884 | retval = sctp_getsockopt_context(sk, len, optval, optlen); |
4644 | break; | 4885 | break; |
4886 | case SCTP_FRAGMENT_INTERLEAVE: | ||
4887 | retval = sctp_getsockopt_fragment_interleave(sk, len, optval, | ||
4888 | optlen); | ||
4889 | break; | ||
4890 | case SCTP_PARTIAL_DELIVERY_POINT: | ||
4891 | retval = sctp_getsockopt_partial_delivery_point(sk, len, optval, | ||
4892 | optlen); | ||
4893 | break; | ||
4894 | case SCTP_MAX_BURST: | ||
4895 | retval = sctp_getsockopt_maxburst(sk, len, optval, optlen); | ||
4896 | break; | ||
4645 | default: | 4897 | default: |
4646 | retval = -ENOPROTOOPT; | 4898 | retval = -ENOPROTOOPT; |
4647 | break; | 4899 | break; |
4648 | }; | 4900 | } |
4649 | 4901 | ||
4650 | sctp_release_sock(sk); | 4902 | sctp_release_sock(sk); |
4651 | return retval; | 4903 | return retval; |
@@ -4970,7 +5222,8 @@ int sctp_inet_listen(struct socket *sock, int backlog) | |||
4970 | break; | 5222 | break; |
4971 | default: | 5223 | default: |
4972 | break; | 5224 | break; |
4973 | }; | 5225 | } |
5226 | |||
4974 | if (err) | 5227 | if (err) |
4975 | goto cleanup; | 5228 | goto cleanup; |
4976 | 5229 | ||
@@ -5233,7 +5486,7 @@ SCTP_STATIC int sctp_msghdr_parse(const struct msghdr *msg, | |||
5233 | 5486 | ||
5234 | default: | 5487 | default: |
5235 | return -EINVAL; | 5488 | return -EINVAL; |
5236 | }; | 5489 | } |
5237 | } | 5490 | } |
5238 | return 0; | 5491 | return 0; |
5239 | } | 5492 | } |
@@ -5638,6 +5891,36 @@ void sctp_wait_for_close(struct sock *sk, long timeout) | |||
5638 | finish_wait(sk->sk_sleep, &wait); | 5891 | finish_wait(sk->sk_sleep, &wait); |
5639 | } | 5892 | } |
5640 | 5893 | ||
5894 | static void sctp_sock_rfree_frag(struct sk_buff *skb) | ||
5895 | { | ||
5896 | struct sk_buff *frag; | ||
5897 | |||
5898 | if (!skb->data_len) | ||
5899 | goto done; | ||
5900 | |||
5901 | /* Don't forget the fragments. */ | ||
5902 | for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) | ||
5903 | sctp_sock_rfree_frag(frag); | ||
5904 | |||
5905 | done: | ||
5906 | sctp_sock_rfree(skb); | ||
5907 | } | ||
5908 | |||
5909 | static void sctp_skb_set_owner_r_frag(struct sk_buff *skb, struct sock *sk) | ||
5910 | { | ||
5911 | struct sk_buff *frag; | ||
5912 | |||
5913 | if (!skb->data_len) | ||
5914 | goto done; | ||
5915 | |||
5916 | /* Don't forget the fragments. */ | ||
5917 | for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) | ||
5918 | sctp_skb_set_owner_r_frag(frag, sk); | ||
5919 | |||
5920 | done: | ||
5921 | sctp_skb_set_owner_r(skb, sk); | ||
5922 | } | ||
5923 | |||
5641 | /* Populate the fields of the newsk from the oldsk and migrate the assoc | 5924 | /* Populate the fields of the newsk from the oldsk and migrate the assoc |
5642 | * and its messages to the newsk. | 5925 | * and its messages to the newsk. |
5643 | */ | 5926 | */ |
@@ -5692,10 +5975,10 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
5692 | sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) { | 5975 | sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) { |
5693 | event = sctp_skb2event(skb); | 5976 | event = sctp_skb2event(skb); |
5694 | if (event->asoc == assoc) { | 5977 | if (event->asoc == assoc) { |
5695 | sctp_sock_rfree(skb); | 5978 | sctp_sock_rfree_frag(skb); |
5696 | __skb_unlink(skb, &oldsk->sk_receive_queue); | 5979 | __skb_unlink(skb, &oldsk->sk_receive_queue); |
5697 | __skb_queue_tail(&newsk->sk_receive_queue, skb); | 5980 | __skb_queue_tail(&newsk->sk_receive_queue, skb); |
5698 | sctp_skb_set_owner_r(skb, newsk); | 5981 | sctp_skb_set_owner_r_frag(skb, newsk); |
5699 | } | 5982 | } |
5700 | } | 5983 | } |
5701 | 5984 | ||
@@ -5706,9 +5989,9 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
5706 | * 3) Peeling off non-partial delivery; move pd_lobby to receive_queue. | 5989 | * 3) Peeling off non-partial delivery; move pd_lobby to receive_queue. |
5707 | */ | 5990 | */ |
5708 | skb_queue_head_init(&newsp->pd_lobby); | 5991 | skb_queue_head_init(&newsp->pd_lobby); |
5709 | sctp_sk(newsk)->pd_mode = assoc->ulpq.pd_mode; | 5992 | atomic_set(&sctp_sk(newsk)->pd_mode, assoc->ulpq.pd_mode); |
5710 | 5993 | ||
5711 | if (sctp_sk(oldsk)->pd_mode) { | 5994 | if (atomic_read(&sctp_sk(oldsk)->pd_mode)) { |
5712 | struct sk_buff_head *queue; | 5995 | struct sk_buff_head *queue; |
5713 | 5996 | ||
5714 | /* Decide which queue to move pd_lobby skbs to. */ | 5997 | /* Decide which queue to move pd_lobby skbs to. */ |
@@ -5723,10 +6006,10 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
5723 | sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) { | 6006 | sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) { |
5724 | event = sctp_skb2event(skb); | 6007 | event = sctp_skb2event(skb); |
5725 | if (event->asoc == assoc) { | 6008 | if (event->asoc == assoc) { |
5726 | sctp_sock_rfree(skb); | 6009 | sctp_sock_rfree_frag(skb); |
5727 | __skb_unlink(skb, &oldsp->pd_lobby); | 6010 | __skb_unlink(skb, &oldsp->pd_lobby); |
5728 | __skb_queue_tail(queue, skb); | 6011 | __skb_queue_tail(queue, skb); |
5729 | sctp_skb_set_owner_r(skb, newsk); | 6012 | sctp_skb_set_owner_r_frag(skb, newsk); |
5730 | } | 6013 | } |
5731 | } | 6014 | } |
5732 | 6015 | ||
@@ -5734,8 +6017,18 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
5734 | * delivery to finish. | 6017 | * delivery to finish. |
5735 | */ | 6018 | */ |
5736 | if (assoc->ulpq.pd_mode) | 6019 | if (assoc->ulpq.pd_mode) |
5737 | sctp_clear_pd(oldsk); | 6020 | sctp_clear_pd(oldsk, NULL); |
6021 | |||
6022 | } | ||
6023 | |||
6024 | sctp_skb_for_each(skb, &assoc->ulpq.reasm, tmp) { | ||
6025 | sctp_sock_rfree_frag(skb); | ||
6026 | sctp_skb_set_owner_r_frag(skb, newsk); | ||
6027 | } | ||
5738 | 6028 | ||
6029 | sctp_skb_for_each(skb, &assoc->ulpq.lobby, tmp) { | ||
6030 | sctp_sock_rfree_frag(skb); | ||
6031 | sctp_skb_set_owner_r_frag(skb, newsk); | ||
5739 | } | 6032 | } |
5740 | 6033 | ||
5741 | /* Set the type of socket to indicate that it is peeled off from the | 6034 | /* Set the type of socket to indicate that it is peeled off from the |