Commit 5e8f3f703ae4e4af65e2695e486b3cd198328863

Authored by Vlad Yasevich
Committed by David S. Miller
1 parent 3bcb1255ba

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

... ... @@ -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 /*