Commit fb334059 authored by Marcel Holtmann's avatar Marcel Holtmann Committed by Gustavo Padovan

Bluetooth: Restrict to one SCO listening socket

The SCO sockets are only identified by its address. So only allow one
SCO socket in listening state per address or BDADDR_ANY.
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
Signed-off-by: default avatarGustavo Padovan <gustavo@padovan.org>
parent 8ed21f7e
......@@ -273,17 +273,20 @@ static inline void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
}
/* -------- Socket interface ---------- */
static struct sock *__sco_get_sock_by_addr(bdaddr_t *ba)
static struct sock *__sco_get_sock_listen_by_addr(bdaddr_t *ba)
{
struct sock *sk;
struct hlist_node *node;
struct sock *sk;
sk_for_each(sk, node, &sco_sk_list.head) {
if (sk->sk_state != BT_LISTEN)
continue;
sk_for_each(sk, node, &sco_sk_list.head)
if (!bacmp(&bt_sk(sk)->src, ba))
goto found;
sk = NULL;
found:
return sk;
return sk;
}
return NULL;
}
/* Find socket listening on source bdaddr.
......@@ -529,6 +532,7 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen
static int sco_sock_listen(struct socket *sock, int backlog)
{
struct sock *sk = sock->sk;
bdaddr_t *src = &bt_sk(sk)->src;
int err = 0;
BT_DBG("sk %p backlog %d", sk, backlog);
......@@ -545,10 +549,21 @@ static int sco_sock_listen(struct socket *sock, int backlog)
goto done;
}
write_lock(&sco_sk_list.lock);
if (__sco_get_sock_listen_by_addr(src)) {
err = -EADDRINUSE;
goto unlock;
}
sk->sk_max_ack_backlog = backlog;
sk->sk_ack_backlog = 0;
sk->sk_state = BT_LISTEN;
unlock:
write_unlock(&sco_sk_list.lock);
done:
release_sock(sk);
return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment