Commit 5e8f3f703ae4e4af65e2695e486b3cd198328863
Committed by
David S. Miller
1 parent
3bcb1255ba
Exists in
master
and in
7 other branches
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>
Showing 1 changed file with 50 additions and 102 deletions Side-by-side Diff
net/sctp/socket.c
... | ... | @@ -5843,37 +5843,28 @@ |
5843 | 5843 | } |
5844 | 5844 | |
5845 | 5845 | /* |
5846 | - * 3.1.3 listen() - UDP Style Syntax | |
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. | |
5846 | + * Move a socket to LISTENING state. | |
5851 | 5847 | */ |
5852 | -SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog) | |
5848 | +SCTP_STATIC int sctp_listen_start(struct sock *sk, int backlog) | |
5853 | 5849 | { |
5854 | 5850 | struct sctp_sock *sp = sctp_sk(sk); |
5855 | 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 | |
5858 | - * listen(). | |
5859 | - */ | |
5860 | - if (!sctp_style(sk, UDP)) | |
5861 | - return -EINVAL; | |
5862 | - | |
5863 | - /* If backlog is zero, disable listening. */ | |
5864 | - if (!backlog) { | |
5865 | - if (sctp_sstate(sk, CLOSED)) | |
5866 | - return 0; | |
5867 | - | |
5868 | - sctp_unhash_endpoint(ep); | |
5869 | - sk->sk_state = SCTP_SS_CLOSED; | |
5870 | - return 0; | |
5854 | + /* Allocate HMAC for generating cookie. */ | |
5855 | + if (!sctp_sk(sk)->hmac && sctp_hmac_alg) { | |
5856 | + tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); | |
5857 | + if (IS_ERR(tfm)) { | |
5858 | + if (net_ratelimit()) { | |
5859 | + printk(KERN_INFO | |
5860 | + "SCTP: failed to load transform for %s: %ld\n", | |
5861 | + sctp_hmac_alg, PTR_ERR(tfm)); | |
5862 | + } | |
5863 | + return -ENOSYS; | |
5864 | + } | |
5865 | + sctp_sk(sk)->hmac = tfm; | |
5871 | 5866 | } |
5872 | 5867 | |
5873 | - /* Return if we are already listening. */ | |
5874 | - if (sctp_sstate(sk, LISTENING)) | |
5875 | - return 0; | |
5876 | - | |
5877 | 5868 | /* |
5878 | 5869 | * If a bind() or sctp_bindx() is not called prior to a listen() |
5879 | 5870 | * call that allows new associations to be accepted, the system |
... | ... | @@ -5884,7 +5875,6 @@ |
5884 | 5875 | * extensions draft, but follows the practice as seen in TCP |
5885 | 5876 | * sockets. |
5886 | 5877 | * |
5887 | - * Additionally, turn off fastreuse flag since we are not listening | |
5888 | 5878 | */ |
5889 | 5879 | sk->sk_state = SCTP_SS_LISTENING; |
5890 | 5880 | if (!ep->base.bind_addr.port) { |
5891 | 5881 | |
5892 | 5882 | |
5893 | 5883 | |
5894 | 5884 | |
5895 | 5885 | |
5896 | 5886 | |
5897 | 5887 | |
5898 | 5888 | |
5899 | 5889 | |
5900 | 5890 | |
... | ... | @@ -5895,113 +5885,71 @@ |
5895 | 5885 | sk->sk_state = SCTP_SS_CLOSED; |
5896 | 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 | - */ | |
5911 | -SCTP_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 | 5890 | sk->sk_max_ack_backlog = backlog; |
5947 | 5891 | sctp_hash_endpoint(ep); |
5948 | 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 | 5907 | * Move a socket to LISTENING state. |
5953 | 5908 | */ |
5954 | 5909 | int sctp_inet_listen(struct socket *sock, int backlog) |
5955 | 5910 | { |
5956 | 5911 | struct sock *sk = sock->sk; |
5957 | - struct crypto_hash *tfm = NULL; | |
5912 | + struct sctp_endpoint *ep = sctp_sk(sk)->ep; | |
5958 | 5913 | int err = -EINVAL; |
5959 | 5914 | |
5960 | 5915 | if (unlikely(backlog < 0)) |
5961 | - goto out; | |
5916 | + return err; | |
5962 | 5917 | |
5963 | 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 | 5924 | if (sock->state != SS_UNCONNECTED) |
5966 | 5925 | goto out; |
5967 | 5926 | |
5968 | - /* Allocate HMAC for generating cookie. */ | |
5969 | - if (!sctp_sk(sk)->hmac && sctp_hmac_alg) { | |
5970 | - tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); | |
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; | |
5927 | + /* If backlog is zero, disable listening. */ | |
5928 | + if (!backlog) { | |
5929 | + if (sctp_sstate(sk, CLOSED)) | |
5978 | 5930 | goto out; |
5979 | - } | |
5931 | + | |
5932 | + err = 0; | |
5933 | + sctp_unhash_endpoint(ep); | |
5934 | + sk->sk_state = SCTP_SS_CLOSED; | |
5935 | + if (sk->sk_reuse) | |
5936 | + sctp_sk(sk)->bind_hash->fastreuse = 1; | |
5937 | + goto out; | |
5980 | 5938 | } |
5981 | 5939 | |
5982 | - switch (sock->type) { | |
5983 | - case SOCK_SEQPACKET: | |
5984 | - err = sctp_seqpacket_listen(sk, backlog); | |
5985 | - break; | |
5986 | - case SOCK_STREAM: | |
5987 | - err = sctp_stream_listen(sk, backlog); | |
5988 | - break; | |
5989 | - default: | |
5990 | - break; | |
5940 | + /* If we are already listening, just update the backlog */ | |
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; | |
5991 | 5947 | } |
5992 | 5948 | |
5993 | - if (err) | |
5994 | - goto cleanup; | |
5995 | - | |
5996 | - /* Store away the transform reference. */ | |
5997 | - if (!sctp_sk(sk)->hmac) | |
5998 | - sctp_sk(sk)->hmac = tfm; | |
5949 | + err = 0; | |
5999 | 5950 | out: |
6000 | 5951 | sctp_release_sock(sk); |
6001 | 5952 | return err; |
6002 | -cleanup: | |
6003 | - crypto_free_hash(tfm); | |
6004 | - goto out; | |
6005 | 5953 | } |
6006 | 5954 | |
6007 | 5955 | /* |