Skip to content

Commit 5e8f3f7

Browse files
Vlad Yasevichdavem330
authored andcommitted
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 3bcb125 commit 5e8f3f7

File tree

1 file changed

+50
-102
lines changed

1 file changed

+50
-102
lines changed

net/sctp/socket.c

Lines changed: 50 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -5843,37 +5843,28 @@ static int sctp_get_port(struct sock *sk, unsigned short snum)
58435843
}
58445844

58455845
/*
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.
58515847
*/
5852-
SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog)
5848+
SCTP_STATIC int sctp_listen_start(struct sock *sk, int backlog)
58535849
{
58545850
struct sctp_sock *sp = sctp_sk(sk);
58555851
struct sctp_endpoint *ep = sp->ep;
5852+
struct crypto_hash *tfm = NULL;
58565853

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;
58715866
}
58725867

5873-
/* Return if we are already listening. */
5874-
if (sctp_sstate(sk, LISTENING))
5875-
return 0;
5876-
58775868
/*
58785869
* If a bind() or sctp_bindx() is not called prior to a listen()
58795870
* 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)
58845875
* extensions draft, but follows the practice as seen in TCP
58855876
* sockets.
58865877
*
5887-
* Additionally, turn off fastreuse flag since we are not listening
58885878
*/
58895879
sk->sk_state = SCTP_SS_LISTENING;
58905880
if (!ep->base.bind_addr.port) {
@@ -5895,113 +5885,71 @@ SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog)
58955885
sk->sk_state = SCTP_SS_CLOSED;
58965886
return -EADDRINUSE;
58975887
}
5898-
sctp_sk(sk)->bind_hash->fastreuse = 0;
58995888
}
59005889

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-
59465890
sk->sk_max_ack_backlog = backlog;
59475891
sctp_hash_endpoint(ep);
59485892
return 0;
59495893
}
59505894

59515895
/*
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+
*
59525907
* Move a socket to LISTENING state.
59535908
*/
59545909
int sctp_inet_listen(struct socket *sock, int backlog)
59555910
{
59565911
struct sock *sk = sock->sk;
5957-
struct crypto_hash *tfm = NULL;
5912+
struct sctp_endpoint *ep = sctp_sk(sk)->ep;
59585913
int err = -EINVAL;
59595914

59605915
if (unlikely(backlog < 0))
5961-
goto out;
5916+
return err;
59625917

59635918
sctp_lock_sock(sk);
59645919

5920+
/* Peeled-off sockets are not allowed to listen(). */
5921+
if (sctp_style(sk, UDP_HIGH_BANDWIDTH))
5922+
goto out;
5923+
59655924
if (sock->state != SS_UNCONNECTED)
59665925
goto out;
59675926

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))
59785930
goto out;
5979-
}
5980-
}
59815931

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;
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;
59915938
}
59925939

5993-
if (err)
5994-
goto cleanup;
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;
5947+
}
59955948

5996-
/* Store away the transform reference. */
5997-
if (!sctp_sk(sk)->hmac)
5998-
sctp_sk(sk)->hmac = tfm;
5949+
err = 0;
59995950
out:
60005951
sctp_release_sock(sk);
60015952
return err;
6002-
cleanup:
6003-
crypto_free_hash(tfm);
6004-
goto out;
60055953
}
60065954

60075955
/*

0 commit comments

Comments
 (0)