aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/socket.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-04-06 03:02:57 -0400
committerIngo Molnar <mingo@elte.hu>2009-04-06 03:02:57 -0400
commitf541ae326fa120fa5c57433e4d9a133df212ce41 (patch)
treebdbd94ec72cfc601118051cb35e8617d55510177 /net/sctp/socket.c
parente255357764f92afcafafbd4879b222b8c752065a (diff)
parent0221c81b1b8eb0cbb6b30a0ced52ead32d2b4e4c (diff)
Merge branch 'linus' into perfcounters/core-v2
Merge reason: we have gathered quite a few conflicts, need to merge upstream Conflicts: arch/powerpc/kernel/Makefile arch/x86/ia32/ia32entry.S arch/x86/include/asm/hardirq.h arch/x86/include/asm/unistd_32.h arch/x86/include/asm/unistd_64.h arch/x86/kernel/cpu/common.c arch/x86/kernel/irq.c arch/x86/kernel/syscall_table_32.S arch/x86/mm/iomap_32.c include/linux/sched.h kernel/Makefile Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r--net/sctp/socket.c216
1 files changed, 100 insertions, 116 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index ff0a8f88de04..5fb3a8c9792e 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3069,9 +3069,6 @@ static int sctp_setsockopt_maxburst(struct sock *sk,
3069 int val; 3069 int val;
3070 int assoc_id = 0; 3070 int assoc_id = 0;
3071 3071
3072 if (optlen < sizeof(int))
3073 return -EINVAL;
3074
3075 if (optlen == sizeof(int)) { 3072 if (optlen == sizeof(int)) {
3076 printk(KERN_WARNING 3073 printk(KERN_WARNING
3077 "SCTP: Use of int in max_burst socket option deprecated\n"); 3074 "SCTP: Use of int in max_burst socket option deprecated\n");
@@ -3939,7 +3936,6 @@ SCTP_STATIC int sctp_do_peeloff(struct sctp_association *asoc,
3939{ 3936{
3940 struct sock *sk = asoc->base.sk; 3937 struct sock *sk = asoc->base.sk;
3941 struct socket *sock; 3938 struct socket *sock;
3942 struct inet_sock *inetsk;
3943 struct sctp_af *af; 3939 struct sctp_af *af;
3944 int err = 0; 3940 int err = 0;
3945 3941
@@ -3954,18 +3950,18 @@ SCTP_STATIC int sctp_do_peeloff(struct sctp_association *asoc,
3954 if (err < 0) 3950 if (err < 0)
3955 return err; 3951 return err;
3956 3952
3957 /* Populate the fields of the newsk from the oldsk and migrate the 3953 sctp_copy_sock(sock->sk, sk, asoc);
3958 * asoc to the newsk.
3959 */
3960 sctp_sock_migrate(sk, sock->sk, asoc, SCTP_SOCKET_UDP_HIGH_BANDWIDTH);
3961 3954
3962 /* Make peeled-off sockets more like 1-1 accepted sockets. 3955 /* Make peeled-off sockets more like 1-1 accepted sockets.
3963 * Set the daddr and initialize id to something more random 3956 * Set the daddr and initialize id to something more random
3964 */ 3957 */
3965 af = sctp_get_af_specific(asoc->peer.primary_addr.sa.sa_family); 3958 af = sctp_get_af_specific(asoc->peer.primary_addr.sa.sa_family);
3966 af->to_sk_daddr(&asoc->peer.primary_addr, sk); 3959 af->to_sk_daddr(&asoc->peer.primary_addr, sk);
3967 inetsk = inet_sk(sock->sk); 3960
3968 inetsk->id = asoc->next_tsn ^ jiffies; 3961 /* Populate the fields of the newsk from the oldsk and migrate the
3962 * asoc to the newsk.
3963 */
3964 sctp_sock_migrate(sk, sock->sk, asoc, SCTP_SOCKET_UDP_HIGH_BANDWIDTH);
3969 3965
3970 *sockp = sock; 3966 *sockp = sock;
3971 3967
@@ -5284,16 +5280,14 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len,
5284 struct sctp_sock *sp; 5280 struct sctp_sock *sp;
5285 struct sctp_association *asoc; 5281 struct sctp_association *asoc;
5286 5282
5287 if (len < sizeof(int))
5288 return -EINVAL;
5289
5290 if (len == sizeof(int)) { 5283 if (len == sizeof(int)) {
5291 printk(KERN_WARNING 5284 printk(KERN_WARNING
5292 "SCTP: Use of int in max_burst socket option deprecated\n"); 5285 "SCTP: Use of int in max_burst socket option deprecated\n");
5293 printk(KERN_WARNING 5286 printk(KERN_WARNING
5294 "SCTP: Use struct sctp_assoc_value instead\n"); 5287 "SCTP: Use struct sctp_assoc_value instead\n");
5295 params.assoc_id = 0; 5288 params.assoc_id = 0;
5296 } else if (len == sizeof (struct sctp_assoc_value)) { 5289 } else if (len >= sizeof(struct sctp_assoc_value)) {
5290 len = sizeof(struct sctp_assoc_value);
5297 if (copy_from_user(&params, optval, len)) 5291 if (copy_from_user(&params, optval, len))
5298 return -EFAULT; 5292 return -EFAULT;
5299 } else 5293 } else
@@ -5849,37 +5843,28 @@ static int sctp_get_port(struct sock *sk, unsigned short snum)
5849} 5843}
5850 5844
5851/* 5845/*
5852 * 3.1.3 listen() - UDP Style Syntax 5846 * Move a socket to LISTENING state.
5853 *
5854 * By default, new associations are not accepted for UDP style sockets.
5855 * An application uses listen() to mark a socket as being able to
5856 * accept new associations.
5857 */ 5847 */
5858SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog) 5848SCTP_STATIC int sctp_listen_start(struct sock *sk, int backlog)
5859{ 5849{
5860 struct sctp_sock *sp = sctp_sk(sk); 5850 struct sctp_sock *sp = sctp_sk(sk);
5861 struct sctp_endpoint *ep = sp->ep; 5851 struct sctp_endpoint *ep = sp->ep;
5852 struct crypto_hash *tfm = NULL;
5862 5853
5863 /* Only UDP style sockets that are not peeled off are allowed to 5854 /* Allocate HMAC for generating cookie. */
5864 * listen(). 5855 if (!sctp_sk(sk)->hmac && sctp_hmac_alg) {
5865 */ 5856 tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC);
5866 if (!sctp_style(sk, UDP)) 5857 if (IS_ERR(tfm)) {
5867 return -EINVAL; 5858 if (net_ratelimit()) {
5868 5859 printk(KERN_INFO
5869 /* If backlog is zero, disable listening. */ 5860 "SCTP: failed to load transform for %s: %ld\n",
5870 if (!backlog) { 5861 sctp_hmac_alg, PTR_ERR(tfm));
5871 if (sctp_sstate(sk, CLOSED)) 5862 }
5872 return 0; 5863 return -ENOSYS;
5873 5864 }
5874 sctp_unhash_endpoint(ep); 5865 sctp_sk(sk)->hmac = tfm;
5875 sk->sk_state = SCTP_SS_CLOSED;
5876 return 0;
5877 } 5866 }
5878 5867
5879 /* Return if we are already listening. */
5880 if (sctp_sstate(sk, LISTENING))
5881 return 0;
5882
5883 /* 5868 /*
5884 * If a bind() or sctp_bindx() is not called prior to a listen() 5869 * If a bind() or sctp_bindx() is not called prior to a listen()
5885 * call that allows new associations to be accepted, the system 5870 * call that allows new associations to be accepted, the system
@@ -5890,7 +5875,6 @@ SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog)
5890 * extensions draft, but follows the practice as seen in TCP 5875 * extensions draft, but follows the practice as seen in TCP
5891 * sockets. 5876 * sockets.
5892 * 5877 *
5893 * Additionally, turn off fastreuse flag since we are not listening
5894 */ 5878 */
5895 sk->sk_state = SCTP_SS_LISTENING; 5879 sk->sk_state = SCTP_SS_LISTENING;
5896 if (!ep->base.bind_addr.port) { 5880 if (!ep->base.bind_addr.port) {
@@ -5901,113 +5885,71 @@ SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog)
5901 sk->sk_state = SCTP_SS_CLOSED; 5885 sk->sk_state = SCTP_SS_CLOSED;
5902 return -EADDRINUSE; 5886 return -EADDRINUSE;
5903 } 5887 }
5904 sctp_sk(sk)->bind_hash->fastreuse = 0;
5905 } 5888 }
5906 5889
5907 sctp_hash_endpoint(ep);
5908 return 0;
5909}
5910
5911/*
5912 * 4.1.3 listen() - TCP Style Syntax
5913 *
5914 * Applications uses listen() to ready the SCTP endpoint for accepting
5915 * inbound associations.
5916 */
5917SCTP_STATIC int sctp_stream_listen(struct sock *sk, int backlog)
5918{
5919 struct sctp_sock *sp = sctp_sk(sk);
5920 struct sctp_endpoint *ep = sp->ep;
5921
5922 /* If backlog is zero, disable listening. */
5923 if (!backlog) {
5924 if (sctp_sstate(sk, CLOSED))
5925 return 0;
5926
5927 sctp_unhash_endpoint(ep);
5928 sk->sk_state = SCTP_SS_CLOSED;
5929 return 0;
5930 }
5931
5932 if (sctp_sstate(sk, LISTENING))
5933 return 0;
5934
5935 /*
5936 * If a bind() or sctp_bindx() is not called prior to a listen()
5937 * call that allows new associations to be accepted, the system
5938 * picks an ephemeral port and will choose an address set equivalent
5939 * to binding with a wildcard address.
5940 *
5941 * This is not currently spelled out in the SCTP sockets
5942 * extensions draft, but follows the practice as seen in TCP
5943 * sockets.
5944 */
5945 sk->sk_state = SCTP_SS_LISTENING;
5946 if (!ep->base.bind_addr.port) {
5947 if (sctp_autobind(sk))
5948 return -EAGAIN;
5949 } else
5950 sctp_sk(sk)->bind_hash->fastreuse = 0;
5951
5952 sk->sk_max_ack_backlog = backlog; 5890 sk->sk_max_ack_backlog = backlog;
5953 sctp_hash_endpoint(ep); 5891 sctp_hash_endpoint(ep);
5954 return 0; 5892 return 0;
5955} 5893}
5956 5894
5957/* 5895/*
5896 * 4.1.3 / 5.1.3 listen()
5897 *
5898 * By default, new associations are not accepted for UDP style sockets.
5899 * An application uses listen() to mark a socket as being able to
5900 * accept new associations.
5901 *
5902 * On TCP style sockets, applications use listen() to ready the SCTP
5903 * endpoint for accepting inbound associations.
5904 *
5905 * On both types of endpoints a backlog of '0' disables listening.
5906 *
5958 * Move a socket to LISTENING state. 5907 * Move a socket to LISTENING state.
5959 */ 5908 */
5960int sctp_inet_listen(struct socket *sock, int backlog) 5909int sctp_inet_listen(struct socket *sock, int backlog)
5961{ 5910{
5962 struct sock *sk = sock->sk; 5911 struct sock *sk = sock->sk;
5963 struct crypto_hash *tfm = NULL; 5912 struct sctp_endpoint *ep = sctp_sk(sk)->ep;
5964 int err = -EINVAL; 5913 int err = -EINVAL;
5965 5914
5966 if (unlikely(backlog < 0)) 5915 if (unlikely(backlog < 0))
5967 goto out; 5916 return err;
5968 5917
5969 sctp_lock_sock(sk); 5918 sctp_lock_sock(sk);
5970 5919
5920 /* Peeled-off sockets are not allowed to listen(). */
5921 if (sctp_style(sk, UDP_HIGH_BANDWIDTH))
5922 goto out;
5923
5971 if (sock->state != SS_UNCONNECTED) 5924 if (sock->state != SS_UNCONNECTED)
5972 goto out; 5925 goto out;
5973 5926
5974 /* Allocate HMAC for generating cookie. */ 5927 /* If backlog is zero, disable listening. */
5975 if (!sctp_sk(sk)->hmac && sctp_hmac_alg) { 5928 if (!backlog) {
5976 tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); 5929 if (sctp_sstate(sk, CLOSED))
5977 if (IS_ERR(tfm)) {
5978 if (net_ratelimit()) {
5979 printk(KERN_INFO
5980 "SCTP: failed to load transform for %s: %ld\n",
5981 sctp_hmac_alg, PTR_ERR(tfm));
5982 }
5983 err = -ENOSYS;
5984 goto out; 5930 goto out;
5985 }
5986 }
5987 5931
5988 switch (sock->type) { 5932 err = 0;
5989 case SOCK_SEQPACKET: 5933 sctp_unhash_endpoint(ep);
5990 err = sctp_seqpacket_listen(sk, backlog); 5934 sk->sk_state = SCTP_SS_CLOSED;
5991 break; 5935 if (sk->sk_reuse)
5992 case SOCK_STREAM: 5936 sctp_sk(sk)->bind_hash->fastreuse = 1;
5993 err = sctp_stream_listen(sk, backlog); 5937 goto out;
5994 break;
5995 default:
5996 break;
5997 } 5938 }
5998 5939
5999 if (err) 5940 /* If we are already listening, just update the backlog */
6000 goto cleanup; 5941 if (sctp_sstate(sk, LISTENING))
5942 sk->sk_max_ack_backlog = backlog;
5943 else {
5944 err = sctp_listen_start(sk, backlog);
5945 if (err)
5946 goto out;
5947 }
6001 5948
6002 /* Store away the transform reference. */ 5949 err = 0;
6003 if (!sctp_sk(sk)->hmac)
6004 sctp_sk(sk)->hmac = tfm;
6005out: 5950out:
6006 sctp_release_sock(sk); 5951 sctp_release_sock(sk);
6007 return err; 5952 return err;
6008cleanup:
6009 crypto_free_hash(tfm);
6010 goto out;
6011} 5953}
6012 5954
6013/* 5955/*
@@ -6700,6 +6642,48 @@ done:
6700 sctp_skb_set_owner_r(skb, sk); 6642 sctp_skb_set_owner_r(skb, sk);
6701} 6643}
6702 6644
6645void sctp_copy_sock(struct sock *newsk, struct sock *sk,
6646 struct sctp_association *asoc)
6647{
6648 struct inet_sock *inet = inet_sk(sk);
6649 struct inet_sock *newinet = inet_sk(newsk);
6650
6651 newsk->sk_type = sk->sk_type;
6652 newsk->sk_bound_dev_if = sk->sk_bound_dev_if;
6653 newsk->sk_flags = sk->sk_flags;
6654 newsk->sk_no_check = sk->sk_no_check;
6655 newsk->sk_reuse = sk->sk_reuse;
6656
6657 newsk->sk_shutdown = sk->sk_shutdown;
6658 newsk->sk_destruct = inet_sock_destruct;
6659 newsk->sk_family = sk->sk_family;
6660 newsk->sk_protocol = IPPROTO_SCTP;
6661 newsk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
6662 newsk->sk_sndbuf = sk->sk_sndbuf;
6663 newsk->sk_rcvbuf = sk->sk_rcvbuf;
6664 newsk->sk_lingertime = sk->sk_lingertime;
6665 newsk->sk_rcvtimeo = sk->sk_rcvtimeo;
6666 newsk->sk_sndtimeo = sk->sk_sndtimeo;
6667
6668 newinet = inet_sk(newsk);
6669
6670 /* Initialize sk's sport, dport, rcv_saddr and daddr for
6671 * getsockname() and getpeername()
6672 */
6673 newinet->sport = inet->sport;
6674 newinet->saddr = inet->saddr;
6675 newinet->rcv_saddr = inet->rcv_saddr;
6676 newinet->dport = htons(asoc->peer.port);
6677 newinet->pmtudisc = inet->pmtudisc;
6678 newinet->id = asoc->next_tsn ^ jiffies;
6679
6680 newinet->uc_ttl = inet->uc_ttl;
6681 newinet->mc_loop = 1;
6682 newinet->mc_ttl = 1;
6683 newinet->mc_index = 0;
6684 newinet->mc_list = NULL;
6685}
6686
6703/* Populate the fields of the newsk from the oldsk and migrate the assoc 6687/* Populate the fields of the newsk from the oldsk and migrate the assoc
6704 * and its messages to the newsk. 6688 * and its messages to the newsk.
6705 */ 6689 */