Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4e54064e authored by Vlad Yasevich's avatar Vlad Yasevich Committed by David S. Miller
Browse files

sctp: Allow only 1 listening socket with SO_REUSEADDR



When multiple socket bind to the same port with SO_REUSEADDR,
only 1 can be listining.

Signed-off-by: default avatarVlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 23b29ed8
Loading
Loading
Loading
Loading
+16 −9
Original line number Diff line number Diff line
@@ -377,19 +377,20 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
	if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
		return -EACCES;

	/* See if the address matches any of the addresses we may have
	 * already bound before checking against other endpoints.
	 */
	if (sctp_bind_addr_match(bp, addr, sp))
		return -EINVAL;

	/* Make sure we are allowed to bind here.
	 * The function sctp_get_port_local() does duplicate address
	 * detection.
	 */
	addr->v4.sin_port = htons(snum);
	if ((ret = sctp_get_port_local(sk, addr))) {
		if (ret == (long) sk) {
			/* This endpoint has a conflicting address. */
			return -EINVAL;
		} else {
		return -EADDRINUSE;
	}
	}

	/* Refresh ephemeral port.  */
	if (!bp->port)
@@ -5584,8 +5585,9 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
			struct sctp_endpoint *ep2;
			ep2 = sctp_sk(sk2)->ep;

			if (reuse && sk2->sk_reuse &&
			    sk2->sk_state != SCTP_SS_LISTENING)
			if (sk == sk2 ||
			    (reuse && sk2->sk_reuse &&
			     sk2->sk_state != SCTP_SS_LISTENING))
				continue;

			if (sctp_bind_addr_conflict(&ep2->base.bind_addr, addr,
@@ -5702,8 +5704,13 @@ SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog)
	if (!ep->base.bind_addr.port) {
		if (sctp_autobind(sk))
			return -EAGAIN;
	} else
	} else {
		if (sctp_get_port(sk, inet_sk(sk)->num)) {
			sk->sk_state = SCTP_SS_CLOSED;
			return -EADDRINUSE;
		}
		sctp_sk(sk)->bind_hash->fastreuse = 0;
	}

	sctp_hash_endpoint(ep);
	return 0;