aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/socket.c
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2009-03-12 05:49:17 -0400
committerDavid S. Miller <davem@davemloft.net>2009-03-13 14:37:56 -0400
commit5e8f3f703ae4e4af65e2695e486b3cd198328863 (patch)
tree1927b01e884dbd5ddb1d4586ac08e4a14e0601eb /net/sctp/socket.c
parent3bcb1255bae39cae1b4d2660f2b5a6ab2f404c10 (diff)
sctp: simplify sctp listening code
sctp_inet_listen() call is split between UDP and TCP style. Looking at the code, the two functions are almost the same and can be merged into a single helper. This also fixes a bug that was fixed in the UDP function, but missed in the TCP function. 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.c152
1 files changed, 50 insertions, 102 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index bbd3cd238d7f..5fb3a8c9792e 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -5843,37 +5843,28 @@ static int sctp_get_port(struct sock *sk, unsigned short snum)
5843} 5843}
5844 5844
5845/* 5845/*
5846 * 3.1.3 listen() - UDP Style Syntax 5846 * Move a socket to LISTENING state.
5847 *
5848 * By default, new associations are not accepted for UDP style sockets.
5849 * An application uses listen() to mark a socket as being able to
5850 * accept new associations.
5851 */ 5847 */
5852SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog) 5848SCTP_STATIC int sctp_listen_start(struct sock *sk, int backlog)
5853{ 5849{
5854 struct sctp_sock *sp = sctp_sk(sk); 5850 struct sctp_sock *sp = sctp_sk(sk);
5855 struct sctp_endpoint *ep = sp->ep; 5851 struct sctp_endpoint *ep = sp->ep;
5852 struct crypto_hash *tfm = NULL;
5856 5853
5857 /* Only UDP style sockets that are not peeled off are allowed to 5854 /* Allocate HMAC for generating cookie. */
5858 * listen(). 5855 if (!sctp_sk(sk)->hmac && sctp_hmac_alg) {
5859 */ 5856 tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC);
5860 if (!sctp_style(sk, UDP)) 5857 if (IS_ERR(tfm)) {
5861 return -EINVAL; 5858 if (net_ratelimit()) {
5862 5859 printk(KERN_INFO
5863 /* If backlog is zero, disable listening. */ 5860 "SCTP: failed to load transform for %s: %ld\n",
5864 if (!backlog) { 5861 sctp_hmac_alg, PTR_ERR(tfm));
5865 if (sctp_sstate(sk, CLOSED)) 5862 }
5866 return 0; 5863 return -ENOSYS;
5867 5864 }
5868 sctp_unhash_endpoint(ep); 5865 sctp_sk(sk)->hmac = tfm;
5869 sk->sk_state = SCTP_SS_CLOSED;
5870 return 0;
5871 } 5866 }
5872 5867
5873 /* Return if we are already listening. */
5874 if (sctp_sstate(sk, LISTENING))
5875 return 0;
5876
5877 /* 5868 /*
5878 * 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()
5879 * call that allows new associations to be accepted, the system 5870 * call that allows new associations to be accepted, the system
@@ -5884,7 +5875,6 @@ SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog)
5884 * extensions draft, but follows the practice as seen in TCP 5875 * extensions draft, but follows the practice as seen in TCP
5885 * sockets. 5876 * sockets.
5886 * 5877 *
5887 * Additionally, turn off fastreuse flag since we are not listening
5888 */ 5878 */
5889 sk->sk_state = SCTP_SS_LISTENING; 5879 sk->sk_state = SCTP_SS_LISTENING;
5890 if (!ep->base.bind_addr.port) { 5880 if (!ep->base.bind_addr.port) {
@@ -5895,113 +5885,71 @@ SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog)
5895 sk->sk_state = SCTP_SS_CLOSED; 5885 sk->sk_state = SCTP_SS_CLOSED;
5896 return -EADDRINUSE; 5886 return -EADDRINUSE;
5897 } 5887 }
5898 sctp_sk(sk)->bind_hash->fastreuse = 0;
5899 } 5888 }
5900 5889
5901 sctp_hash_endpoint(ep);
5902 return 0;
5903}
5904
5905/*
5906 * 4.1.3 listen() - TCP Style Syntax
5907 *
5908 * Applications uses listen() to ready the SCTP endpoint for accepting
5909 * inbound associations.
5910 */
5911SCTP_STATIC int sctp_stream_listen(struct sock *sk, int backlog)
5912{
5913 struct sctp_sock *sp = sctp_sk(sk);
5914 struct sctp_endpoint *ep = sp->ep;
5915
5916 /* If backlog is zero, disable listening. */
5917 if (!backlog) {
5918 if (sctp_sstate(sk, CLOSED))
5919 return 0;
5920
5921 sctp_unhash_endpoint(ep);
5922 sk->sk_state = SCTP_SS_CLOSED;
5923 return 0;
5924 }
5925
5926 if (sctp_sstate(sk, LISTENING))
5927 return 0;
5928
5929 /*
5930 * If a bind() or sctp_bindx() is not called prior to a listen()
5931 * call that allows new associations to be accepted, the system
5932 * picks an ephemeral port and will choose an address set equivalent
5933 * to binding with a wildcard address.
5934 *
5935 * This is not currently spelled out in the SCTP sockets
5936 * extensions draft, but follows the practice as seen in TCP
5937 * sockets.
5938 */
5939 sk->sk_state = SCTP_SS_LISTENING;
5940 if (!ep->base.bind_addr.port) {
5941 if (sctp_autobind(sk))
5942 return -EAGAIN;
5943 } else
5944 sctp_sk(sk)->bind_hash->fastreuse = 0;
5945
5946 sk->sk_max_ack_backlog = backlog; 5890 sk->sk_max_ack_backlog = backlog;
5947 sctp_hash_endpoint(ep); 5891 sctp_hash_endpoint(ep);
5948 return 0; 5892 return 0;
5949} 5893}
5950 5894
5951/* 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 *
5952 * Move a socket to LISTENING state. 5907 * Move a socket to LISTENING state.
5953 */ 5908 */
5954int sctp_inet_listen(struct socket *sock, int backlog) 5909int sctp_inet_listen(struct socket *sock, int backlog)
5955{ 5910{
5956 struct sock *sk = sock->sk; 5911 struct sock *sk = sock->sk;
5957 struct crypto_hash *tfm = NULL; 5912 struct sctp_endpoint *ep = sctp_sk(sk)->ep;
5958 int err = -EINVAL; 5913 int err = -EINVAL;
5959 5914
5960 if (unlikely(backlog < 0)) 5915 if (unlikely(backlog < 0))
5961 goto out; 5916 return err;
5962 5917
5963 sctp_lock_sock(sk); 5918 sctp_lock_sock(sk);
5964 5919
5920 /* Peeled-off sockets are not allowed to listen(). */
5921 if (sctp_style(sk, UDP_HIGH_BANDWIDTH))
5922 goto out;
5923
5965 if (sock->state != SS_UNCONNECTED) 5924 if (sock->state != SS_UNCONNECTED)
5966 goto out; 5925 goto out;
5967 5926
5968 /* Allocate HMAC for generating cookie. */ 5927 /* If backlog is zero, disable listening. */
5969 if (!sctp_sk(sk)->hmac && sctp_hmac_alg) { 5928 if (!backlog) {
5970 tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); 5929 if (sctp_sstate(sk, CLOSED))
5971 if (IS_ERR(tfm)) {
5972 if (net_ratelimit()) {
5973 printk(KERN_INFO
5974 "SCTP: failed to load transform for %s: %ld\n",
5975 sctp_hmac_alg, PTR_ERR(tfm));
5976 }
5977 err = -ENOSYS;
5978 goto out; 5930 goto out;
5979 }
5980 }
5981 5931
5982 switch (sock->type) { 5932 err = 0;
5983 case SOCK_SEQPACKET: 5933 sctp_unhash_endpoint(ep);
5984 err = sctp_seqpacket_listen(sk, backlog); 5934 sk->sk_state = SCTP_SS_CLOSED;
5985 break; 5935 if (sk->sk_reuse)
5986 case SOCK_STREAM: 5936 sctp_sk(sk)->bind_hash->fastreuse = 1;
5987 err = sctp_stream_listen(sk, backlog); 5937 goto out;
5988 break;
5989 default:
5990 break;
5991 } 5938 }
5992 5939
5993 if (err) 5940 /* If we are already listening, just update the backlog */
5994 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 }
5995 5948
5996 /* Store away the transform reference. */ 5949 err = 0;
5997 if (!sctp_sk(sk)->hmac)
5998 sctp_sk(sk)->hmac = tfm;
5999out: 5950out:
6000 sctp_release_sock(sk); 5951 sctp_release_sock(sk);
6001 return err; 5952 return err;
6002cleanup:
6003 crypto_free_hash(tfm);
6004 goto out;
6005} 5953}
6006 5954
6007/* 5955/*