From 540a99b5d6d4e05e574030493a3bdbdf39b44ca5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 19 Apr 2012 14:37:58 +0200 Subject: [PATCH] --- yaml --- r: 306895 b: refs/heads/master c: fb3340594bd6630c27e31ddeff25b7002fb4558e h: refs/heads/master i: 306893: 1f09d5f3fdf44333f9f2584c400a97e5fab124d3 306891: 03b7373eed08006bda8a5167e72df1aeb9eab964 306887: c6cec591cfc3c2891b33e9538a01987cfec95676 306879: 011653652c516edc384a859655e7b5d211a083b8 v: v3 --- [refs] | 2 +- trunk/net/bluetooth/sco.c | 29 ++++++++++++++++++++++------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/[refs] b/[refs] index 7fc41e954a7c..4b2fff361710 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 8ed21f7eece54bb80eea5e31c3d9c6c7b6517e49 +refs/heads/master: fb3340594bd6630c27e31ddeff25b7002fb4558e diff --git a/trunk/net/bluetooth/sco.c b/trunk/net/bluetooth/sco.c index c75cd7b07d18..bf1af0b1497e 100644 --- a/trunk/net/bluetooth/sco.c +++ b/trunk/net/bluetooth/sco.c @@ -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;